diff --git a/clang/include/clang/Lex/PreprocessorOptions.h b/clang/include/clang/Lex/PreprocessorOptions.h --- a/clang/include/clang/Lex/PreprocessorOptions.h +++ b/clang/include/clang/Lex/PreprocessorOptions.h @@ -69,6 +69,9 @@ std::vector Includes; std::vector MacroIncludes; + /// Perform extra checks when loading PCM files for mutable file systems. + bool ModulesCheckRelocated = true; + /// Initialize the preprocessor with the compiler and target specific /// predefines. bool UsePredefines = true; diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp --- a/clang/lib/Serialization/ASTReader.cpp +++ b/clang/lib/Serialization/ASTReader.cpp @@ -2990,6 +2990,9 @@ BaseDirectoryAsWritten = Blob; assert(!F.ModuleName.empty() && "MODULE_DIRECTORY found before MODULE_NAME"); + F.BaseDirectory = std::string(Blob); + if (!PP.getPreprocessorOpts().ModulesCheckRelocated) + break; // If we've already loaded a module map file covering this module, we may // have a better path for it (relative to the current build). Module *M = PP.getHeaderSearchInfo().lookupModule( @@ -3011,8 +3014,6 @@ } } F.BaseDirectory = std::string(M->Directory->getName()); - } else { - F.BaseDirectory = std::string(Blob); } break; } @@ -3990,7 +3991,8 @@ // usable header search context. assert(!F.ModuleName.empty() && "MODULE_NAME should come before MODULE_MAP_FILE"); - if (F.Kind == MK_ImplicitModule && ModuleMgr.begin()->Kind != MK_MainFile) { + if (PP.getPreprocessorOpts().ModulesCheckRelocated && + F.Kind == MK_ImplicitModule && ModuleMgr.begin()->Kind != MK_MainFile) { // An implicitly-loaded module file should have its module listed in some // module map file that we've already loaded. Module *M = diff --git a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp --- a/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp +++ b/clang/lib/Tooling/DependencyScanning/DependencyScanningWorker.cpp @@ -253,6 +253,9 @@ // context hashing. ScanInstance.getHeaderSearchOpts().ModulesStrictContextHash = true; + // Avoid some checks and module map parsing when loading PCM files. + ScanInstance.getPreprocessorOpts().ModulesCheckRelocated = false; + std::unique_ptr Action; if (ModuleName) diff --git a/clang/test/ClangScanDeps/header-search-pruning-transitive.c b/clang/test/ClangScanDeps/header-search-pruning-transitive.c --- a/clang/test/ClangScanDeps/header-search-pruning-transitive.c +++ b/clang/test/ClangScanDeps/header-search-pruning-transitive.c @@ -72,8 +72,8 @@ // CHECK: ], // CHECK-NEXT: "context-hash": "[[HASH_X:.*]]", // CHECK-NEXT: "file-deps": [ -// CHECK-NEXT: "[[PREFIX]]/./X.h", -// CHECK-NEXT: "[[PREFIX]]/./module.modulemap" +// CHECK-NEXT: "[[PREFIX]]/X.h", +// CHECK-NEXT: "[[PREFIX]]/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "name": "X" // CHECK-NEXT: }, @@ -84,11 +84,11 @@ // CHECK: ], // CHECK-NEXT: "context-hash": "[[HASH_Y_WITH_A]]", // CHECK-NEXT: "file-deps": [ -// CHECK-NEXT: "[[PREFIX]]/./Y.h", -// CHECK-NEXT: "[[PREFIX]]/./a/a.h", -// CHECK-NEXT: "[[PREFIX]]/./begin/begin.h", -// CHECK-NEXT: "[[PREFIX]]/./end/end.h", -// CHECK-NEXT: "[[PREFIX]]/./module.modulemap" +// CHECK-NEXT: "[[PREFIX]]/Y.h", +// CHECK-NEXT: "[[PREFIX]]/a/a.h", +// CHECK-NEXT: "[[PREFIX]]/begin/begin.h", +// CHECK-NEXT: "[[PREFIX]]/end/end.h", +// CHECK-NEXT: "[[PREFIX]]/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "name": "Y" // CHECK-NEXT: } @@ -126,8 +126,8 @@ // also has a different context hash from the first version of module X. // CHECK-NOT: "context-hash": "[[HASH_X]]", // CHECK: "file-deps": [ -// CHECK-NEXT: "[[PREFIX]]/./X.h", -// CHECK-NEXT: "[[PREFIX]]/./module.modulemap" +// CHECK-NEXT: "[[PREFIX]]/X.h", +// CHECK-NEXT: "[[PREFIX]]/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "name": "X" // CHECK-NEXT: }, @@ -138,10 +138,10 @@ // CHECK: ], // CHECK-NEXT: "context-hash": "[[HASH_Y_WITHOUT_A]]", // CHECK-NEXT: "file-deps": [ -// CHECK-NEXT: "[[PREFIX]]/./Y.h", -// CHECK-NEXT: "[[PREFIX]]/./begin/begin.h", -// CHECK-NEXT: "[[PREFIX]]/./end/end.h", -// CHECK-NEXT: "[[PREFIX]]/./module.modulemap" +// CHECK-NEXT: "[[PREFIX]]/Y.h", +// CHECK-NEXT: "[[PREFIX]]/begin/begin.h", +// CHECK-NEXT: "[[PREFIX]]/end/end.h", +// CHECK-NEXT: "[[PREFIX]]/module.modulemap" // CHECK-NEXT: ], // CHECK-NEXT: "name": "Y" // CHECK-NEXT: }