Skip to content

[clang] Add a CodeGen option to ignore compilation directories #149897

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions clang/include/clang/Basic/CodeGenOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
5 changes: 5 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1725,6 +1725,11 @@ def fcoverage_compilation_dir_EQ : Joined<["-"], "fcoverage-compilation-dir=">,
def ffile_compilation_dir_EQ : Joined<["-"], "ffile-compilation-dir=">, Group<f_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<f_Group>,
HelpText<"Ignore compilation directories">,
MarshallingInfoFlag<CodeGenOpts<"NoCompilationDir">>;
defm debug_info_for_profiling : BoolFOption<"debug-info-for-profiling",
CodeGenOpts<"DebugInfoForProfiling">, DefaultFalse,
PosFlag<SetTrue, [], [ClangOption, CC1Option],
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/CodeGen/CGDebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,9 @@ unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc, bool Force) {
}

StringRef CGDebugInfo::getCurrentDirname() {
if (CGM.getCodeGenOpts().NoCompilationDir)
return StringRef();

if (!CGM.getCodeGenOpts().DebugCompilationDir.empty())
return CGM.getCodeGenOpts().DebugCompilationDir;

Expand Down Expand Up @@ -3246,6 +3249,9 @@ llvm::DIModule *CGDebugInfo::getOrCreateModuleRef(ASTSourceDescriptor Mod,
std::string Remapped = remapDIPath(Path);
StringRef Relative(Remapped);
StringRef CompDir = TheCU->getDirectory();
if (CompDir.empty())
return Remapped;

if (Relative.consume_front(CompDir))
Relative.consume_front(llvm::sys::path::get_separator());

Expand Down
3 changes: 3 additions & 0 deletions clang/lib/CodeGen/CoverageMappingGen.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
2 changes: 2 additions & 0 deletions clang/lib/CodeGen/ObjectFilePCHContainerWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
30 changes: 6 additions & 24 deletions clang/lib/Tooling/DependencyScanning/ModuleDepCollector.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I believe this change still make sure that the pcms contains no working directory on the command line if CWD optimization is on. The change looks safe to me.

}

static std::vector<std::string> splitString(std::string S, char Separator) {
Expand Down Expand Up @@ -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;
}
}

Expand Down
11 changes: 8 additions & 3 deletions clang/test/ClangScanDeps/modules-debug-dir.c
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
// 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
// RUN: clang-scan-deps -compilation-database %t/cdb.json -format \
// 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",
Expand All @@ -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": [
7 changes: 7 additions & 0 deletions clang/test/CodeGen/debug-info-compilation-dir.c
Original file line number Diff line number Diff line change
Expand Up @@ -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: "")