jansvoboda11 created this revision.
jansvoboda11 added reviewers: Bigcheese, dexonsmith, arphaman.
Herald added subscribers: kerbowa, nhaehnle, jvesely.
jansvoboda11 requested review of this revision.
Herald added projects: clang, LLVM.
Herald added subscribers: llvm-commits, cfe-commits.

The iteration over directory entries of a VFS is a bit unweildy, since it 
requires using a pair of `llvm::vfs::directory_iterator`, calling 
`llvm::vfs::directory_iterator::increment(std::error_code &)` and checking 
`std::error_code`. Currently, there are 13 instances of this pattern in the 
Clang codebase.

This patch simplifies iteration over directory entries by extracting the 
boilerplate into a macro.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D116659

Files:
  clang/lib/Driver/ToolChains/AMDGPU.cpp
  clang/lib/Driver/ToolChains/BareMetal.cpp
  clang/lib/Driver/ToolChains/Cuda.cpp
  clang/lib/Driver/ToolChains/Gnu.cpp
  clang/lib/Driver/ToolChains/MSVC.cpp
  clang/lib/Frontend/CompilerInstance.cpp
  clang/lib/Frontend/FrontendAction.cpp
  clang/lib/Lex/HeaderSearch.cpp
  clang/lib/Lex/ModuleMap.cpp
  clang/lib/Sema/SemaCodeComplete.cpp
  llvm/include/llvm/Support/VirtualFileSystem.h

Index: llvm/include/llvm/Support/VirtualFileSystem.h
===================================================================
--- llvm/include/llvm/Support/VirtualFileSystem.h
+++ llvm/include/llvm/Support/VirtualFileSystem.h
@@ -319,6 +319,13 @@
 /// that of the process.
 std::unique_ptr<FileSystem> createPhysicalFileSystem();
 
+/// Expands to a loop header that uses iterator named IT for iterating over
+/// entries of the directory DIR within the VFS.
+#define LLVM_VFS_DIR_FOREACH(VFS, DIR, IT)                                     \
+  std::error_code EC;                                                          \
+  for (llvm::vfs::directory_iterator IT = VFS.dir_begin(DIR, EC), End;         \
+       !EC && IT != End; IT = IT.increment(EC))
+
 /// A file system that allows overlaying one \p AbstractFileSystem on top
 /// of another.
 ///
Index: clang/lib/Sema/SemaCodeComplete.cpp
===================================================================
--- clang/lib/Sema/SemaCodeComplete.cpp
+++ clang/lib/Sema/SemaCodeComplete.cpp
@@ -9888,10 +9888,8 @@
     const bool isQt = Dirname.startswith("Qt") || Dirname == "ActiveQt";
     const bool ExtensionlessHeaders =
         IsSystem || isQt || Dir.endswith(".framework/Headers");
-    std::error_code EC;
     unsigned Count = 0;
-    for (auto It = FS.dir_begin(Dir, EC);
-         !EC && It != llvm::vfs::directory_iterator(); It.increment(EC)) {
+    LLVM_VFS_DIR_FOREACH(FS, Dir, It) {
       if (++Count == 2500) // If we happen to hit a huge directory,
         break;             // bail out early so we're not too slow.
       StringRef Filename = llvm::sys::path::filename(It->path());
Index: clang/lib/Lex/ModuleMap.cpp
===================================================================
--- clang/lib/Lex/ModuleMap.cpp
+++ clang/lib/Lex/ModuleMap.cpp
@@ -1057,16 +1057,12 @@
   Result->InferExportWildcard = true;
 
   // Look for subframeworks.
-  std::error_code EC;
   SmallString<128> SubframeworksDirName
     = StringRef(FrameworkDir->getName());
   llvm::sys::path::append(SubframeworksDirName, "Frameworks");
   llvm::sys::path::native(SubframeworksDirName);
   llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
-  for (llvm::vfs::directory_iterator
-           Dir = FS.dir_begin(SubframeworksDirName, EC),
-           DirEnd;
-       Dir != DirEnd && !EC; Dir.increment(EC)) {
+  LLVM_VFS_DIR_FOREACH(FS, SubframeworksDirName, Dir) {
     if (!StringRef(Dir->path()).endswith(".framework"))
       continue;
 
Index: clang/lib/Lex/HeaderSearch.cpp
===================================================================
--- clang/lib/Lex/HeaderSearch.cpp
+++ clang/lib/Lex/HeaderSearch.cpp
@@ -1740,16 +1740,13 @@
     for (unsigned Idx = 0, N = SearchDirs.size(); Idx != N; ++Idx) {
       bool IsSystem = SearchDirs[Idx].isSystemHeaderDirectory();
       if (SearchDirs[Idx].isFramework()) {
-        std::error_code EC;
         SmallString<128> DirNative;
         llvm::sys::path::native(SearchDirs[Idx].getFrameworkDir()->getName(),
                                 DirNative);
 
         // Search each of the ".framework" directories to load them as modules.
         llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
-        for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
-                                           DirEnd;
-             Dir != DirEnd && !EC; Dir.increment(EC)) {
+        LLVM_VFS_DIR_FOREACH(FS, DirNative, Dir) {
           if (llvm::sys::path::extension(Dir->path()) != ".framework")
             continue;
 
@@ -1809,14 +1806,12 @@
   if (SearchDir.haveSearchedAllModuleMaps())
     return;
 
-  std::error_code EC;
   SmallString<128> Dir = SearchDir.getDir()->getName();
   FileMgr.makeAbsolutePath(Dir);
   SmallString<128> DirNative;
   llvm::sys::path::native(Dir, DirNative);
   llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
-  for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
-       Dir != DirEnd && !EC; Dir.increment(EC)) {
+  LLVM_VFS_DIR_FOREACH(FS, DirNative, Dir) {
     bool IsFramework = llvm::sys::path::extension(Dir->path()) == ".framework";
     if (IsFramework == SearchDir.isFramework())
       loadModuleMapFile(Dir->path(), SearchDir.isSystemHeaderDirectory(),
Index: clang/lib/Frontend/FrontendAction.cpp
===================================================================
--- clang/lib/Frontend/FrontendAction.cpp
+++ clang/lib/Frontend/FrontendAction.cpp
@@ -753,14 +753,10 @@
     StringRef PCHInclude = PPOpts.ImplicitPCHInclude;
     std::string SpecificModuleCachePath = CI.getSpecificModuleCachePath();
     if (auto PCHDir = FileMgr.getDirectory(PCHInclude)) {
-      std::error_code EC;
       SmallString<128> DirNative;
       llvm::sys::path::native((*PCHDir)->getName(), DirNative);
       bool Found = false;
-      llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
-      for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC),
-                                         DirEnd;
-           Dir != DirEnd && !EC; Dir.increment(EC)) {
+      LLVM_VFS_DIR_FOREACH(FileMgr.getVirtualFileSystem(), DirNative, Dir) {
         // Check whether this is an acceptable AST file.
         if (ASTReader::isAcceptableASTFile(
                 Dir->path(), FileMgr, CI.getPCHContainerReader(),
Index: clang/lib/Frontend/CompilerInstance.cpp
===================================================================
--- clang/lib/Frontend/CompilerInstance.cpp
+++ clang/lib/Frontend/CompilerInstance.cpp
@@ -237,13 +237,11 @@
     return;
   }
 
-  std::error_code EC;
   SmallString<128> DirNative;
   llvm::sys::path::native((*PCHDir)->getName(), DirNative);
   llvm::vfs::FileSystem &FS = FileMgr.getVirtualFileSystem();
   SimpleASTReaderListener Validator(CI.getPreprocessor());
-  for (llvm::vfs::directory_iterator Dir = FS.dir_begin(DirNative, EC), DirEnd;
-       Dir != DirEnd && !EC; Dir.increment(EC)) {
+  LLVM_VFS_DIR_FOREACH(FS, DirNative, Dir) {
     // Check whether this is an AST file. ASTReader::isAcceptableASTFile is not
     // used here since we're not interested in validating the PCH at this time,
     // but only to check whether this is a file containing an AST.
Index: clang/lib/Driver/ToolChains/MSVC.cpp
===================================================================
--- clang/lib/Driver/ToolChains/MSVC.cpp
+++ clang/lib/Driver/ToolChains/MSVC.cpp
@@ -135,10 +135,7 @@
   std::string Highest;
   llvm::VersionTuple HighestTuple;
 
-  std::error_code EC;
-  for (llvm::vfs::directory_iterator DirIt = VFS.dir_begin(Directory, EC),
-                                     DirEnd;
-       !EC && DirIt != DirEnd; DirIt.increment(EC)) {
+  LLVM_VFS_DIR_FOREACH(VFS, Directory, DirIt) {
     auto Status = VFS.status(DirIt->path());
     if (!Status || !Status->isDirectory())
       continue;
Index: clang/lib/Driver/ToolChains/Gnu.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Gnu.cpp
+++ clang/lib/Driver/ToolChains/Gnu.cpp
@@ -2016,10 +2016,7 @@
     // /usr/gcc/<version> as a prefix.
 
     std::string PrefixDir = SysRoot.str() + "/usr/gcc";
-    std::error_code EC;
-    for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(PrefixDir, EC),
-                                       LE;
-         !EC && LI != LE; LI = LI.increment(EC)) {
+    LLVM_VFS_DIR_FOREACH(D.getVFS(), PrefixDir, LI) {
       StringRef VersionText = llvm::sys::path::filename(LI->path());
       GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
 
@@ -2528,11 +2525,7 @@
       continue;
 
     StringRef LibSuffix = Suffix.LibSuffix;
-    std::error_code EC;
-    for (llvm::vfs::directory_iterator
-             LI = D.getVFS().dir_begin(LibDir + "/" + LibSuffix, EC),
-             LE;
-         !EC && LI != LE; LI = LI.increment(EC)) {
+    LLVM_VFS_DIR_FOREACH(D.getVFS(), LibDir + "/" + LibSuffix, LI) {
       StringRef VersionText = llvm::sys::path::filename(LI->path());
       GCCVersion CandidateVersion = GCCVersion::Parse(VersionText);
       if (CandidateVersion.Major != -1) // Filter obviously bad entries.
Index: clang/lib/Driver/ToolChains/Cuda.cpp
===================================================================
--- clang/lib/Driver/ToolChains/Cuda.cpp
+++ clang/lib/Driver/ToolChains/Cuda.cpp
@@ -227,10 +227,7 @@
         }
       }
     } else {
-      std::error_code EC;
-      for (llvm::vfs::directory_iterator LI = FS.dir_begin(LibDevicePath, EC),
-                                         LE;
-           !EC && LI != LE; LI = LI.increment(EC)) {
+      LLVM_VFS_DIR_FOREACH(FS, LibDevicePath, LI) {
         StringRef FilePath = LI->path();
         StringRef FileName = llvm::sys::path::filename(FilePath);
         // Process all bitcode filenames that look like
Index: clang/lib/Driver/ToolChains/BareMetal.cpp
===================================================================
--- clang/lib/Driver/ToolChains/BareMetal.cpp
+++ clang/lib/Driver/ToolChains/BareMetal.cpp
@@ -247,13 +247,9 @@
   case ToolChain::CST_Libstdcxx: {
     SmallString<128> Dir(SysRoot);
     llvm::sys::path::append(Dir, "include", "c++");
-    std::error_code EC;
     Generic_GCC::GCCVersion Version = {"", -1, -1, -1, "", "", ""};
     // Walk the subdirs, and find the one with the newest gcc version:
-    for (llvm::vfs::directory_iterator
-             LI = getDriver().getVFS().dir_begin(Dir.str(), EC),
-             LE;
-         !EC && LI != LE; LI = LI.increment(EC)) {
+    LLVM_VFS_DIR_FOREACH(getDriver().getVFS(), Dir.str(), LI) {
       StringRef VersionText = llvm::sys::path::filename(LI->path());
       auto CandidateVersion = Generic_GCC::GCCVersion::Parse(VersionText);
       if (CandidateVersion.Major == -1)
Index: clang/lib/Driver/ToolChains/AMDGPU.cpp
===================================================================
--- clang/lib/Driver/ToolChains/AMDGPU.cpp
+++ clang/lib/Driver/ToolChains/AMDGPU.cpp
@@ -40,12 +40,9 @@
                                            StringRef PackageName) {
   if (!Cand.isSPACK())
     return {};
-  std::error_code EC;
   std::string Prefix = Twine(PackageName + "-" + Cand.SPACKReleaseStr).str();
   llvm::SmallVector<llvm::SmallString<0>> SubDirs;
-  for (llvm::vfs::directory_iterator File = D.getVFS().dir_begin(Cand.Path, EC),
-                                     FileEnd;
-       File != FileEnd && !EC; File.increment(EC)) {
+  LLVM_VFS_DIR_FOREACH(D.getVFS(), Cand.Path, File) {
     llvm::StringRef FileName = llvm::sys::path::filename(File->path());
     if (FileName.startswith(Prefix)) {
       SubDirs.push_back(FileName);
@@ -77,9 +74,7 @@
   const StringRef Suffix(".bc");
   const StringRef Suffix2(".amdgcn.bc");
 
-  std::error_code EC;
-  for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(Path, EC), LE;
-       !EC && LI != LE; LI = LI.increment(EC)) {
+  LLVM_VFS_DIR_FOREACH(D.getVFS(), Path, LI) {
     StringRef FilePath = LI->path();
     StringRef FileName = llvm::sys::path::filename(FilePath);
     if (!FileName.endswith(Suffix))
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
  • [PATCH] D116659: [... Jan Svoboda via Phabricator via cfe-commits

Reply via email to