diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index cdeedd5b4eac6..9ec2784f6ce1c 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -231,6 +231,9 @@ class CodeGenOptions : public CodeGenOptionsBase { /// The string to embed in coverage mapping as the current working directory. std::string CoverageCompilationDir; + /// No compilation directory, ignore debug/coverage compilation directory. + bool NoCompilationDir; + /// The string to embed in the debug information for the compile unit, if /// non-empty. std::string DwarfDebugFlags; diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index e30c152cbce2e..1307e8a6e9e12 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -1725,6 +1725,11 @@ def fcoverage_compilation_dir_EQ : Joined<["-"], "fcoverage-compilation-dir=">, def ffile_compilation_dir_EQ : Joined<["-"], "ffile-compilation-dir=">, Group, Visibility<[ClangOption, CLOption, DXCOption]>, HelpText<"The compilation directory to embed in the debug info and coverage mapping.">; +def fno_compilation_dir: Flag<["-"], "fno-compilation-dir">, + Visibility<[ClangOption, CC1Option]>, + Group, + HelpText<"Ignore compilation directories">, + MarshallingInfoFlag>; defm debug_info_for_profiling : BoolFOption<"debug-info-for-profiling", CodeGenOpts<"DebugInfoForProfiling">, DefaultFalse, PosFlaggetDirectory(); + if (CompDir.empty()) + return Remapped; + if (Relative.consume_front(CompDir)) Relative.consume_front(llvm::sys::path::get_separator()); diff --git a/clang/lib/CodeGen/CoverageMappingGen.cpp b/clang/lib/CodeGen/CoverageMappingGen.cpp index 4aafac349e3e9..0e90908c8db7b 100644 --- a/clang/lib/CodeGen/CoverageMappingGen.cpp +++ b/clang/lib/CodeGen/CoverageMappingGen.cpp @@ -2449,6 +2449,9 @@ CoverageMappingModuleGen::CoverageMappingModuleGen( : CGM(CGM), SourceInfo(SourceInfo) {} std::string CoverageMappingModuleGen::getCurrentDirname() { + if (CGM.getCodeGenOpts().NoCompilationDir) + return {}; + if (!CGM.getCodeGenOpts().CoverageCompilationDir.empty()) return CGM.getCodeGenOpts().CoverageCompilationDir; diff --git a/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp index 95971e57086e7..a5be5bbee753b 100644 --- a/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp +++ b/clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp @@ -164,6 +164,8 @@ class PCHContainerGenerator : public ASTConsumer { CodeGenOpts.DwarfVersion = CI.getCodeGenOpts().DwarfVersion; CodeGenOpts.DebugCompilationDir = CI.getInvocation().getCodeGenOpts().DebugCompilationDir; + CodeGenOpts.NoCompilationDir = + CI.getInvocation().getCodeGenOpts().NoCompilationDir; CodeGenOpts.DebugPrefixMap = CI.getInvocation().getCodeGenOpts().DebugPrefixMap; CodeGenOpts.DebugStrictDwarf = CI.getCodeGenOpts().DebugStrictDwarf; diff --git a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp index 37f8b945d785e..7226e06db9092 100644 --- a/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp +++ b/clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp @@ -144,30 +144,9 @@ static void optimizeDiagnosticOpts(DiagnosticOptions &Opts, static void optimizeCWD(CowCompilerInvocation &BuildInvocation, StringRef CWD) { BuildInvocation.getMutFileSystemOpts().WorkingDir.clear(); - if (BuildInvocation.getCodeGenOpts().DwarfVersion) { - // It is necessary to explicitly set the DebugCompilationDir - // to a common directory (e.g. root) if IgnoreCWD is true. - // When IgnoreCWD is true, the module's content should not - // depend on the current working directory. However, if dwarf - // information is needed (when CGOpts.DwarfVersion is - // non-zero), then CGOpts.DebugCompilationDir must be - // populated, because otherwise the current working directory - // will be automatically embedded in the dwarf information in - // the pcm, contradicting the assumption that it is safe to - // ignore the CWD. Thus in such cases, - // CGOpts.DebugCompilationDir is explicitly set to a common - // directory. - // FIXME: It is still excessive to create a copy of - // CodeGenOpts for each module. Since we do not modify the - // CodeGenOpts otherwise per module, the following code - // ends up generating identical CodeGenOpts for each module - // with DebugCompilationDir pointing to the root directory. - // We can optimize this away by creating a _single_ copy of - // CodeGenOpts whose DebugCompilationDir points to the root - // directory and reuse it across modules. - BuildInvocation.getMutCodeGenOpts().DebugCompilationDir = - llvm::sys::path::root_path(CWD); - } + // To avoid clang inferring working directory from CWD, set to ignore + // compilation directory. + BuildInvocation.getMutCodeGenOpts().NoCompilationDir = true; } static std::vector splitString(std::string S, char Separator) { @@ -222,6 +201,9 @@ void dependencies::resetBenignCodeGenOptions(frontend::ActionKind ProgramAction, CGOpts.ProfileInstrumentUsePath.clear(); CGOpts.SampleProfileFile.clear(); CGOpts.ProfileRemappingFile.clear(); + // To avoid clang inferring compilation directory from CWD, set + // -no-compilation-dir option. + CGOpts.NoCompilationDir = true; } } diff --git a/clang/test/ClangScanDeps/modules-debug-dir.c b/clang/test/ClangScanDeps/modules-debug-dir.c index c4fb4982ed791..041f68fcae9a4 100644 --- a/clang/test/ClangScanDeps/modules-debug-dir.c +++ b/clang/test/ClangScanDeps/modules-debug-dir.c @@ -1,5 +1,3 @@ -// REQUIRES: shell - // RUN: rm -rf %t // RUN: split-file %s %t // RUN: sed -e "s|DIR|%/t|g" %t/cdb.json.in > %t/cdb.json @@ -7,6 +5,12 @@ // RUN: experimental-full -optimize-args=all > %t/result.json // RUN: cat %t/result.json | sed 's:\\\\\?:/:g' | FileCheck %s +// RUN: %deps-to-rsp %t/result.json --module-name=mod > %t/mod.rsp +// RUN: %clang @%t/mod.rsp -o %t/mod.pcm +// RUN: llvm-dwarfdump --debug-info %t/mod.pcm | FileCheck %s --check-prefix=DWARF +// DWARF: DW_TAG_compile_unit +// DWARF-NOT: DW_AT_comp_dir + //--- cdb.json.in [{ "directory": "DIR", @@ -28,5 +32,6 @@ module mod { // directory when current working directory optimization is in effect. // CHECK: "modules": [ // CHECK: "command-line": [ -// CHECK: "-fdebug-compilation-dir={{\/|.*:(\\)?}}", +// CHECK: "-fno-compilation-dir" +// CHECK-NOT: -fdebug-compilation-dir // CHECK: "translation-units": [ diff --git a/clang/test/CodeGen/debug-info-compilation-dir.c b/clang/test/CodeGen/debug-info-compilation-dir.c index b49a0f5751f8e..bdcf8d10763dd 100644 --- a/clang/test/CodeGen/debug-info-compilation-dir.c +++ b/clang/test/CodeGen/debug-info-compilation-dir.c @@ -7,3 +7,10 @@ // RUN: %clang_cc1 -emit-llvm -debug-info-kind=limited %s -o - | FileCheck -check-prefix=CHECK-DIR %s // CHECK-DIR: CodeGen +/// Test path remapping. +// RUN: %clang_cc1 -fdebug-compilation-dir %S -main-file-name %s -emit-llvm -debug-info-kind=limited %s -o - | FileCheck -check-prefix=CHECK-ABS %s +// CHECK-ABS: DIFile(filename: "{{.*}}debug-info-compilation-dir.c", directory: "{{.*}}CodeGen") + +// RUN: %clang_cc1 -fno-compilation-dir -main-file-name %s -emit-llvm -debug-info-kind=limited %s -o - | FileCheck -check-prefix=CHECK-NOMAP %s +// CHECK-NOMAP: DIFile(filename: "{{.*}}debug-info-compilation-dir.c", directory: "") +