@@ -134,6 +134,34 @@ static void optimizeDiagnosticOpts(DiagnosticOptions &Opts,
134
134
Opts.Remarks .clear ();
135
135
}
136
136
137
+ static void optimizeCWD (CowCompilerInvocation &BuildInvocation, StringRef CWD) {
138
+ BuildInvocation.getMutFileSystemOpts ().WorkingDir .clear ();
139
+ if (BuildInvocation.getCodeGenOpts ().DwarfVersion ) {
140
+ // It is necessary to explicitly set the DebugCompilationDir
141
+ // to a common directory (e.g. root) if IgnoreCWD is true.
142
+ // When IgnoreCWD is true, the module's content should not
143
+ // depend on the current working directory. However, if dwarf
144
+ // information is needed (when CGOpts.DwarfVersion is
145
+ // non-zero), then CGOpts.DebugCompilationDir must be
146
+ // populated, because otherwise the current working directory
147
+ // will be automatically embedded in the dwarf information in
148
+ // the pcm, contradicting the assumption that it is safe to
149
+ // ignore the CWD. Thus in such cases,
150
+ // CGOpts.DebugCompilationDir is explicitly set to a common
151
+ // directory.
152
+ // FIXME: It is still excessive to create a copy of
153
+ // CodeGenOpts for each module. Since we do not modify the
154
+ // CodeGenOpts otherwise per module, the following code
155
+ // ends up generating identical CodeGenOpts for each module
156
+ // with DebugCompilationDir pointing to the root directory.
157
+ // We can optimize this away by creating a _single_ copy of
158
+ // CodeGenOpts whose DebugCompilationDir points to the root
159
+ // directory and reuse it across modules.
160
+ BuildInvocation.getMutCodeGenOpts ().DebugCompilationDir =
161
+ llvm::sys::path::root_path (CWD);
162
+ }
163
+ }
164
+
137
165
static std::vector<std::string> splitString (std::string S, char Separator) {
138
166
SmallVector<StringRef> Segments;
139
167
StringRef (S).split (Segments, Separator, /* MaxSplit=*/ -1 , /* KeepEmpty=*/ false );
@@ -534,14 +562,12 @@ static std::string getModuleContextHash(const ModuleDeps &MD,
534
562
HashBuilder.add (getClangFullRepositoryVersion ());
535
563
HashBuilder.add (serialization::VERSION_MAJOR, serialization::VERSION_MINOR);
536
564
llvm::ErrorOr<std::string> CWD = VFS.getCurrentWorkingDirectory ();
537
- auto &FSOpts = const_cast <FileSystemOptions &>(CI.getFileSystemOpts ());
538
565
if (CWD && !IgnoreCWD)
539
566
HashBuilder.add (*CWD);
540
- else
541
- FSOpts.WorkingDir .clear ();
542
567
543
568
// Save and restore options that should not affect the hash, e.g. the exact
544
569
// contents of input files, or prefix mappings.
570
+ auto &FSOpts = const_cast <FileSystemOptions &>(CI.getFileSystemOpts ());
545
571
auto &FEOpts = const_cast <FrontendOptions &>(CI.getFrontendOpts ());
546
572
auto &CASOpts = const_cast <CASOptions &>(CI.getCASOpts ());
547
573
llvm::SaveAndRestore RestoreCASFSRootID (FSOpts.CASFileSystemRootID , {});
@@ -594,9 +620,7 @@ static void checkCompileCacheKeyMatch(cas::ObjectStore &CAS,
594
620
#endif
595
621
596
622
void ModuleDepCollector::associateWithContextHash (
597
- const CowCompilerInvocation &CI, ModuleDeps &Deps) {
598
- bool IgnoreCWD = any (OptimizeArgs & ScanningOptimizations::IgnoreCWD) &&
599
- isSafeToIgnoreCWD (CI);
623
+ const CowCompilerInvocation &CI, bool IgnoreCWD, ModuleDeps &Deps) {
600
624
Deps.ID .ContextHash =
601
625
getModuleContextHash (Deps, CI, EagerLoadModules, IgnoreCWD,
602
626
ScanInstance.getVirtualFileSystem ());
@@ -810,6 +834,7 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
810
834
}
811
835
}
812
836
837
+ bool IgnoreCWD = false ;
813
838
CowCompilerInvocation CI =
814
839
MDC.getInvocationAdjustedForModuleBuildWithoutOutputs (
815
840
MD, [&](CowCompilerInvocation &BuildInvocation) {
@@ -819,10 +844,22 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
819
844
*MDC.ScanInstance .getASTReader (), *MF,
820
845
MDC.PrebuiltModuleVFSMap ,
821
846
MDC.OptimizeArgs );
847
+
822
848
if (any (MDC.OptimizeArgs & ScanningOptimizations::SystemWarnings))
823
849
optimizeDiagnosticOpts (
824
850
BuildInvocation.getMutDiagnosticOpts (),
825
851
BuildInvocation.getFrontendOpts ().IsSystemModule );
852
+
853
+ IgnoreCWD =
854
+ any (MDC.OptimizeArgs & ScanningOptimizations::IgnoreCWD) &&
855
+ isSafeToIgnoreCWD (BuildInvocation);
856
+ if (IgnoreCWD) {
857
+ llvm::ErrorOr<std::string> CWD =
858
+ MDC.ScanInstance .getVirtualFileSystem ()
859
+ .getCurrentWorkingDirectory ();
860
+ if (CWD)
861
+ optimizeCWD (BuildInvocation, *CWD);
862
+ }
826
863
});
827
864
828
865
auto &Diags = MDC.ScanInstance .getDiagnostics ();
@@ -837,7 +874,7 @@ ModuleDepCollectorPP::handleTopLevelModule(const Module *M) {
837
874
MD.ModuleCacheKey = Key->toString ();
838
875
}
839
876
840
- MDC.associateWithContextHash (CI, MD);
877
+ MDC.associateWithContextHash (CI, IgnoreCWD, MD);
841
878
842
879
// Finish the compiler invocation. Requires dependencies and the context hash.
843
880
MDC.addOutputPaths (CI, MD);
0 commit comments