jansvoboda11 updated this revision to Diff 345412.
jansvoboda11 added a comment.

Undo changes to `modules-full.cpp` test


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D102488/new/

https://reviews.llvm.org/D102488

Files:
  clang/include/clang/Lex/HeaderSearch.h
  clang/include/clang/Serialization/ASTBitCodes.h
  clang/include/clang/Serialization/ModuleFile.h
  clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
  clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
  clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
  clang/lib/Serialization/ASTReader.cpp
  clang/lib/Serialization/ASTWriter.cpp
  clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp
  clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
  clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
  clang/test/ClangScanDeps/Inputs/header-search-pruning/a/a.h
  clang/test/ClangScanDeps/Inputs/header-search-pruning/b/b.h
  clang/test/ClangScanDeps/Inputs/header-search-pruning/cdb.json
  clang/test/ClangScanDeps/Inputs/header-search-pruning/mod.h
  clang/test/ClangScanDeps/Inputs/header-search-pruning/module.modulemap
  clang/test/ClangScanDeps/header-search-pruning.cpp
  clang/tools/clang-scan-deps/ClangScanDeps.cpp

Index: clang/tools/clang-scan-deps/ClangScanDeps.cpp
===================================================================
--- clang/tools/clang-scan-deps/ClangScanDeps.cpp
+++ clang/tools/clang-scan-deps/ClangScanDeps.cpp
@@ -163,6 +163,11 @@
         "'-fmodule-file=', '-o', '-fmodule-map-file='."),
     llvm::cl::init(false), llvm::cl::cat(DependencyScannerCategory));
 
+static llvm::cl::opt<bool> OptimizeArgs(
+    "optimize-args",
+    llvm::cl::desc("Whether to optimize command-line arguments of modules."),
+    llvm::cl::init(false), llvm::cl::cat(DependencyScannerCategory));
+
 llvm::cl::opt<unsigned>
     NumThreads("j", llvm::cl::Optional,
                llvm::cl::desc("Number of worker threads to use (default: use "
@@ -357,7 +362,26 @@
 
 private:
   StringRef lookupPCMPath(ModuleID MID) {
-    return Modules[IndexedModuleID{MID, 0}].ImplicitModulePCMPath;
+    auto PCMPath = PCMPaths.insert({IndexedModuleID{MID, 0}, ""});
+    if (PCMPath.second)
+      PCMPath.first->second = constructPCMPath(lookupModuleDeps(MID));
+    return PCMPath.first->second;
+  }
+
+  /// Construct a path where to put the explicitly built PCM - essentially the
+  /// path to implicitly built PCM with the context hash replaced by the final
+  /// (potentially modified) context hash.
+  std::string constructPCMPath(const ModuleDeps &MD) const {
+    const std::string &ImplicitPCMPath = MD.ImplicitModulePCMPath;
+    StringRef Filename = llvm::sys::path::filename(ImplicitPCMPath);
+    StringRef ImplicitContextHashPath =
+        llvm::sys::path::parent_path(ImplicitPCMPath);
+    StringRef ModuleCachePath =
+        llvm::sys::path::parent_path(ImplicitContextHashPath);
+
+    SmallString<64> ExplicitPCMPath = ModuleCachePath;
+    llvm::sys::path::append(ExplicitPCMPath, MD.ID.ContextHash, Filename);
+    return std::string(ExplicitPCMPath);
   }
 
   const ModuleDeps &lookupModuleDeps(ModuleID MID) {
@@ -395,6 +419,8 @@
   std::mutex Lock;
   std::unordered_map<IndexedModuleID, ModuleDeps, IndexedModuleIDHasher>
       Modules;
+  std::unordered_map<IndexedModuleID, std::string, IndexedModuleIDHasher>
+      PCMPaths;
   std::vector<InputDeps> Inputs;
 };
 
@@ -554,7 +580,7 @@
   SharedStream DependencyOS(llvm::outs());
 
   DependencyScanningService Service(ScanMode, Format, ReuseFileManager,
-                                    SkipExcludedPPRanges);
+                                    SkipExcludedPPRanges, OptimizeArgs);
   llvm::ThreadPool Pool(llvm::hardware_concurrency(NumThreads));
   std::vector<std::unique_ptr<DependencyScanningTool>> WorkerTools;
   for (unsigned I = 0; I < Pool.getThreadCount(); ++I)
Index: clang/test/ClangScanDeps/header-search-pruning.cpp
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/header-search-pruning.cpp
@@ -0,0 +1,87 @@
+// RUN: rm -rf %t && mkdir -p %t
+// RUN: cp -r %S/Inputs/header-search-pruning/* %t
+// RUN: cp %S/header-search-pruning.cpp %t/header-search-pruning.cpp
+// RUN: sed -e "s|DIR|%t|g" -e "s|DEFINES|-DINCLUDE_A|g"             %S/Inputs/header-search-pruning/cdb.json > %t/cdb_a.json
+// RUN: sed -e "s|DIR|%t|g" -e "s|DEFINES|-DINCLUDE_B|g"             %S/Inputs/header-search-pruning/cdb.json > %t/cdb_b.json
+// RUN: sed -e "s|DIR|%t|g" -e "s|DEFINES|-DINCLUDE_A -DINCLUDE_B|g" %S/Inputs/header-search-pruning/cdb.json > %t/cdb_ab.json
+//
+// RUN: clang-scan-deps -compilation-database %t/cdb_a.json -format experimental-full -optimize-args >> %t/result_a.json
+// RUN: cat %t/result_a.json | sed 's/\\/\//g' | FileCheck --check-prefixes=CHECK_A %s
+//
+// RUN: clang-scan-deps -compilation-database %t/cdb_b.json -format experimental-full -optimize-args >> %t/result_b.json
+// RUN: cat %t/result_b.json | sed 's/\\/\//g' | FileCheck --check-prefixes=CHECK_B %s
+//
+// RUN: clang-scan-deps -compilation-database %t/cdb_ab.json -format experimental-full -optimize-args >> %t/result_ab.json
+// RUN: cat %t/result_ab.json | sed 's/\\/\//g' | FileCheck --check-prefixes=CHECK_AB %s
+
+#include "mod.h"
+
+// CHECK_A:        {
+// CHECK_A-NEXT:     "modules": [
+// CHECK_A-NEXT:       {
+// CHECK_A-NEXT:         "clang-module-deps": [],
+// CHECK_A-NEXT:         "clang-modulemap-file": "{{.*}}",
+// CHECK_A-NEXT:         "command-line": [
+// CHECK_A-NEXT:           "-cc1"
+// CHECK_A:                "-I"
+// CHECK_A:                "a"
+// CHECK_A-NOT:            "-I"
+// CHECK_A-NOT:            "b"
+// CHECK_A:              ],
+// CHECK_A-NEXT:         "context-hash": "[[HASH:.*]]",
+// CHECK_A-NEXT:         "file-deps": [
+// CHECK_A-NEXT:           "[[PREFIX:.*]]/a/a.h",
+// CHECK_A-NEXT:           "[[PREFIX]]/mod.h",
+// CHECK_A-NEXT:           "[[PREFIX]]/module.modulemap"
+// CHECK_A-NEXT:         ],
+// CHECK_A-NEXT:         "name": "mod"
+// CHECK_A-NEXT:       }
+// CHECK_A-NEXT:     ]
+// CHECK_A:        }
+
+// CHECK_B:        {
+// CHECK_B-NEXT:     "modules": [
+// CHECK_B-NEXT:       {
+// CHECK_B-NEXT:         "clang-module-deps": [],
+// CHECK_B-NEXT:         "clang-modulemap-file": "{{.*}}",
+// CHECK_B-NEXT:         "command-line": [
+// CHECK_B-NEXT:           "-cc1"
+// CHECK_B-NOT:            "-I"
+// CHECK_B-NOT:            "a"
+// CHECK_B:                "-I"
+// CHECK_B:                "b"
+// CHECK_B:              ],
+// CHECK_B-NEXT:         "context-hash": "[[HASH:.*]]",
+// CHECK_B-NEXT:         "file-deps": [
+// CHECK_B-NEXT:           "[[PREFIX:.*]]/b/b.h",
+// CHECK_B-NEXT:           "[[PREFIX]]/mod.h",
+// CHECK_B-NEXT:           "[[PREFIX]]/module.modulemap"
+// CHECK_B-NEXT:         ],
+// CHECK_B-NEXT:         "name": "mod"
+// CHECK_B-NEXT:       }
+// CHECK_B-NEXT:     ]
+// CHECK_B:        }
+
+// CHECK_AB:       {
+// CHECK_AB-NEXT:    "modules": [
+// CHECK_AB-NEXT:      {
+// CHECK_AB-NEXT:        "clang-module-deps": [],
+// CHECK_AB-NEXT:        "clang-modulemap-file": "{{.*}}",
+// CHECK_AB-NEXT:        "command-line": [
+// CHECK_AB-NEXT:          "-cc1"
+// CHECK_AB:               "-I"
+// CHECK_AB:               "a"
+// CHECK_AB:               "-I"
+// CHECK_AB:               "b"
+// CHECK_AB:             ],
+// CHECK_AB-NEXT:        "context-hash": "[[HASH:.*]]",
+// CHECK_AB-NEXT:        "file-deps": [
+// CHECK_AB-NEXT:          "[[PREFIX:.*]]/a/a.h",
+// CHECK_AB-NEXT:          "[[PREFIX:.*]]/b/b.h",
+// CHECK_AB-NEXT:          "[[PREFIX]]/mod.h",
+// CHECK_AB-NEXT:          "[[PREFIX]]/module.modulemap"
+// CHECK_AB-NEXT:        ],
+// CHECK_AB-NEXT:        "name": "mod"
+// CHECK_AB-NEXT:      }
+// CHECK_AB-NEXT:    ]
+// CHECK_AB:       }
Index: clang/test/ClangScanDeps/Inputs/header-search-pruning/module.modulemap
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/header-search-pruning/module.modulemap
@@ -0,0 +1,4 @@
+module mod {
+    header "mod.h"
+    export *
+}
Index: clang/test/ClangScanDeps/Inputs/header-search-pruning/mod.h
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/header-search-pruning/mod.h
@@ -0,0 +1,7 @@
+#ifdef INCLUDE_A
+#include "a.h"
+#endif
+
+#ifdef INCLUDE_B
+#include "b.h"
+#endif
Index: clang/test/ClangScanDeps/Inputs/header-search-pruning/cdb.json
===================================================================
--- /dev/null
+++ clang/test/ClangScanDeps/Inputs/header-search-pruning/cdb.json
@@ -0,0 +1,7 @@
+[
+  {
+    "directory": "DIR",
+    "command": "clang -E DIR/header-search-pruning.cpp -Ia -Ib DEFINES -fmodules -fcxx-modules -fmodules-cache-path=DIR/module-cache -fimplicit-modules -fmodule-map-file=DIR/module.modulemap",
+    "file": "DIR/header-search-pruning.cpp"
+  }
+]
Index: clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
===================================================================
--- clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
+++ clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
@@ -18,9 +18,19 @@
 using namespace tooling;
 using namespace dependencies;
 
-static CompilerInvocation
-makeInvocationForModuleBuildWithoutPaths(const ModuleDeps &Deps,
-                                         const CompilerInvocation &Invocation) {
+static void optimizeHeaderSearchOpts(HeaderSearchOptions &Opts,
+                                     const std::set<unsigned> &UsedEntryIdxs) {
+  std::vector<HeaderSearchOptions::Entry> &Entries = Opts.UserEntries;
+  std::vector<HeaderSearchOptions::Entry> OrigEntries(Entries);
+
+  Entries.clear();
+  for (unsigned Idx : UsedEntryIdxs)
+    Entries.push_back(OrigEntries[Idx]);
+}
+
+static CompilerInvocation makeInvocationForModuleBuildWithoutPaths(
+    const ModuleDeps &Deps, const CompilerInvocation &Invocation,
+    llvm::function_ref<void(CompilerInvocation &)> Optimize) {
   // Make a deep copy of the invocation.
   CompilerInvocation CI(Invocation);
 
@@ -35,6 +45,8 @@
   CI.getLangOpts()->ImplicitModules = false;
   CI.getHeaderSearchOpts().ImplicitModuleMaps = false;
 
+  Optimize(CI);
+
   return CI;
 }
 
@@ -189,8 +201,12 @@
         MD.FileDeps.insert(IF.getFile()->getName());
       });
 
-  MD.Invocation =
-      makeInvocationForModuleBuildWithoutPaths(MD, Instance.getInvocation());
+  MD.Invocation = makeInvocationForModuleBuildWithoutPaths(
+      MD, Instance.getInvocation(), [&](CompilerInvocation &CI) {
+        if (MDC.OptimizeArgs)
+          optimizeHeaderSearchOpts(CI.getHeaderSearchOpts(),
+                                   MF->UsedHeaderSearchPathIdxs);
+      });
   MD.ID.ContextHash = MD.Invocation.getModuleHash();
 
   llvm::DenseSet<const Module *> AddedModules;
@@ -222,8 +238,9 @@
 
 ModuleDepCollector::ModuleDepCollector(
     std::unique_ptr<DependencyOutputOptions> Opts, CompilerInstance &I,
-    DependencyConsumer &C)
-    : Instance(I), Consumer(C), Opts(std::move(Opts)) {}
+    DependencyConsumer &C, bool OptimizeArgs)
+    : Instance(I), Consumer(C), OptimizeArgs(OptimizeArgs),
+      Opts(std::move(Opts)) {}
 
 void ModuleDepCollector::attachToPreprocessor(Preprocessor &PP) {
   PP.addPPCallbacks(std::make_unique<ModuleDepCollectorPP>(Instance, *this));
Index: clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
===================================================================
--- clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
+++ clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp
@@ -52,10 +52,10 @@
       StringRef WorkingDirectory, DependencyConsumer &Consumer,
       llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS,
       ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings,
-      ScanningOutputFormat Format)
+      ScanningOutputFormat Format, bool OptimizeArgs)
       : WorkingDirectory(WorkingDirectory), Consumer(Consumer),
-        DepFS(std::move(DepFS)), PPSkipMappings(PPSkipMappings),
-        Format(Format) {}
+        DepFS(std::move(DepFS)), PPSkipMappings(PPSkipMappings), Format(Format),
+        OptimizeArgs(OptimizeArgs) {}
 
   bool runInvocation(std::shared_ptr<CompilerInvocation> Invocation,
                      FileManager *FileMgr,
@@ -121,7 +121,7 @@
       break;
     case ScanningOutputFormat::Full:
       Compiler.addDependencyCollector(std::make_shared<ModuleDepCollector>(
-          std::move(Opts), Compiler, Consumer));
+          std::move(Opts), Compiler, Consumer, OptimizeArgs));
       break;
     }
 
@@ -145,13 +145,14 @@
   llvm::IntrusiveRefCntPtr<DependencyScanningWorkerFilesystem> DepFS;
   ExcludedPreprocessorDirectiveSkipMapping *PPSkipMappings;
   ScanningOutputFormat Format;
+  bool OptimizeArgs;
 };
 
 } // end anonymous namespace
 
 DependencyScanningWorker::DependencyScanningWorker(
     DependencyScanningService &Service)
-    : Format(Service.getFormat()) {
+    : Format(Service.getFormat()), OptimizeArgs(Service.canOptimizeArgs()) {
   DiagOpts = new DiagnosticOptions();
   PCHContainerOps = std::make_shared<PCHContainerOperations>();
   RealFS = llvm::vfs::createPhysicalFileSystem();
@@ -194,7 +195,7 @@
     Tool.setPrintErrorMessage(false);
     Tool.setDiagnosticConsumer(&DC);
     DependencyScanningAction Action(WorkingDirectory, Consumer, DepFS,
-                                    PPSkipMappings.get(), Format);
+                                    PPSkipMappings.get(), Format, OptimizeArgs);
     return !Tool.run(&Action);
   });
 }
Index: clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp
===================================================================
--- clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp
+++ clang/lib/Tooling/DependencyScanning/DependencyScanningService.cpp
@@ -14,6 +14,6 @@
 
 DependencyScanningService::DependencyScanningService(
     ScanningMode Mode, ScanningOutputFormat Format, bool ReuseFileManager,
-    bool SkipExcludedPPRanges)
+    bool SkipExcludedPPRanges, bool OptimizeArgs)
     : Mode(Mode), Format(Format), ReuseFileManager(ReuseFileManager),
-      SkipExcludedPPRanges(SkipExcludedPPRanges) {}
+      SkipExcludedPPRanges(SkipExcludedPPRanges), OptimizeArgs(OptimizeArgs) {}
Index: clang/lib/Serialization/ASTWriter.cpp
===================================================================
--- clang/lib/Serialization/ASTWriter.cpp
+++ clang/lib/Serialization/ASTWriter.cpp
@@ -1097,6 +1097,16 @@
   // Write out the diagnostic/pragma mappings.
   WritePragmaDiagnosticMappings(Diags, /* isModule = */ WritingModule);
 
+  Record.clear();
+
+  // Used search path indices.
+  auto UsedSearchPathIdxs = PP.getHeaderSearchInfo().GetUsedSearchPathIdxs();
+  Record.push_back(UsedSearchPathIdxs.size());
+  for (unsigned Idx : UsedSearchPathIdxs)
+    Record.push_back(Idx);
+
+  Stream.EmitRecord(USED_HEADER_SEARCH_PATHS, Record);
+
   // Leave the options block.
   Stream.ExitBlock();
   return Signature;
Index: clang/lib/Serialization/ASTReader.cpp
===================================================================
--- clang/lib/Serialization/ASTReader.cpp
+++ clang/lib/Serialization/ASTReader.cpp
@@ -4795,6 +4795,14 @@
         F->PragmaDiagMappings.insert(F->PragmaDiagMappings.end(),
                                      Record.begin(), Record.end());
       break;
+    case USED_HEADER_SEARCH_PATHS:
+      if (F) {
+        unsigned Idx = 0;
+        unsigned Count = Record[Idx++];
+        for (unsigned I = 0; I < Count; ++I)
+          F->UsedHeaderSearchPathIdxs.insert(Record[Idx++]);
+      }
+      break;
     }
   }
 }
Index: clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
===================================================================
--- clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
+++ clang/include/clang/Tooling/DependencyScanning/ModuleDepCollector.h
@@ -20,6 +20,7 @@
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringSet.h"
 #include "llvm/Support/raw_ostream.h"
+#include <set>
 #include <string>
 #include <unordered_map>
 
@@ -158,7 +159,8 @@
 class ModuleDepCollector final : public DependencyCollector {
 public:
   ModuleDepCollector(std::unique_ptr<DependencyOutputOptions> Opts,
-                     CompilerInstance &I, DependencyConsumer &C);
+                     CompilerInstance &I, DependencyConsumer &C,
+                     bool OptimizeArgs);
 
   void attachToPreprocessor(Preprocessor &PP) override;
   void attachToASTReader(ASTReader &R) override;
@@ -170,6 +172,8 @@
   CompilerInstance &Instance;
   /// The consumer of collected dependency information.
   DependencyConsumer &Consumer;
+  /// Whether to optimize the modules' command-line arguments.
+  bool OptimizeArgs;
   /// Path to the main source file.
   std::string MainFile;
   /// Hash identifying the compilation conditions of the current TU.
Index: clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
===================================================================
--- clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
+++ clang/include/clang/Tooling/DependencyScanning/DependencyScanningWorker.h
@@ -77,6 +77,7 @@
   /// worker. If null, the file manager will not be reused.
   llvm::IntrusiveRefCntPtr<FileManager> Files;
   ScanningOutputFormat Format;
+  bool OptimizeArgs;
 };
 
 } // end namespace dependencies
Index: clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
===================================================================
--- clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
+++ clang/include/clang/Tooling/DependencyScanning/DependencyScanningService.h
@@ -48,7 +48,8 @@
 public:
   DependencyScanningService(ScanningMode Mode, ScanningOutputFormat Format,
                             bool ReuseFileManager = true,
-                            bool SkipExcludedPPRanges = true);
+                            bool SkipExcludedPPRanges = true,
+                            bool OptimizeArgs = false);
 
   ScanningMode getMode() const { return Mode; }
 
@@ -58,6 +59,8 @@
 
   bool canSkipExcludedPPRanges() const { return SkipExcludedPPRanges; }
 
+  bool canOptimizeArgs() const { return OptimizeArgs; }
+
   DependencyScanningFilesystemSharedCache &getSharedCache() {
     return SharedCache;
   }
@@ -70,6 +73,7 @@
   /// ranges by bumping the buffer pointer in the lexer instead of lexing the
   /// tokens in the range until reaching the corresponding directive.
   const bool SkipExcludedPPRanges;
+  const bool OptimizeArgs;
   /// The global file system cache.
   DependencyScanningFilesystemSharedCache SharedCache;
 };
Index: clang/include/clang/Serialization/ModuleFile.h
===================================================================
--- clang/include/clang/Serialization/ModuleFile.h
+++ clang/include/clang/Serialization/ModuleFile.h
@@ -30,6 +30,7 @@
 #include <cassert>
 #include <cstdint>
 #include <memory>
+#include <set>
 #include <string>
 #include <vector>
 
@@ -173,6 +174,10 @@
   /// unique module files based on AST contents.
   ASTFileSignature ASTBlockHash;
 
+  /// The indices of header search paths that were actually used when building
+  /// the module file.
+  std::set<unsigned> UsedHeaderSearchPathIdxs;
+
   /// Whether this module has been directly imported by the
   /// user.
   bool DirectlyImported = false;
Index: clang/include/clang/Serialization/ASTBitCodes.h
===================================================================
--- clang/include/clang/Serialization/ASTBitCodes.h
+++ clang/include/clang/Serialization/ASTBitCodes.h
@@ -402,6 +402,10 @@
 
   /// Record code for \#pragma diagnostic mappings.
   DIAG_PRAGMA_MAPPINGS,
+
+  /// Record code for indices of header search paths that were actually used
+  /// when building the module.
+  USED_HEADER_SEARCH_PATHS,
 };
 
 /// Record code for extension blocks.
Index: clang/include/clang/Lex/HeaderSearch.h
===================================================================
--- clang/include/clang/Lex/HeaderSearch.h
+++ clang/include/clang/Lex/HeaderSearch.h
@@ -21,12 +21,13 @@
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringMap.h"
-#include "llvm/ADT/StringSet.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/StringSet.h"
 #include "llvm/Support/Allocator.h"
 #include <cassert>
 #include <cstddef>
 #include <memory>
+#include <set>
 #include <string>
 #include <utility>
 #include <vector>
@@ -290,6 +291,15 @@
     SystemDirIdx++;
   }
 
+  /// Return indices of used search paths.
+  std::set<unsigned> GetUsedSearchPathIdxs() const {
+    std::set<unsigned> UsedSearchPathIdxs;
+    for (const auto &Entry : LookupFileCache)
+      if (Entry.second.HitIdx < SearchDirs.size())
+        UsedSearchPathIdxs.insert(Entry.second.HitIdx);
+    return UsedSearchPathIdxs;
+  }
+
   /// Set the list of system header prefixes.
   void SetSystemHeaderPrefixes(ArrayRef<std::pair<std::string, bool>> P) {
     SystemHeaderPrefixes.assign(P.begin(), P.end());
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to