From: Nick Lewycky Date: Fri, 21 Oct 2011 02:32:14 +0000 (+0000) Subject: Take DW_AT_comp_dir from $PWD when it's present and starts with a '/'. This is X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7c4fd9121f5885096fd3258d20a984e3f08f8603;p=clang Take DW_AT_comp_dir from $PWD when it's present and starts with a '/'. This is closer to what GCC does, except that GCC also checks that the inodes for $PWD and '.' match. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@142633 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index 7100725109..4b39d6ec55 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -110,6 +110,8 @@ def disable_llvm_verifier : Flag<"-disable-llvm-verifier">, HelpText<"Don't run the LLVM IR verifier pass">; def disable_red_zone : Flag<"-disable-red-zone">, HelpText<"Do not emit code that uses the red zone.">; +def fdebug_compilation_dir : Separate<"-fdebug-compilation-dir">, + HelpText<"The compilation directory to embed in the debug info.">; def dwarf_debug_flags : Separate<"-dwarf-debug-flags">, HelpText<"The string to embed in the Dwarf debug flags record.">; def fforbid_guard_variables : Flag<"-fforbid-guard-variables">, diff --git a/include/clang/Frontend/CodeGenOptions.h b/include/clang/Frontend/CodeGenOptions.h index ecfe49fa46..5b698889f6 100644 --- a/include/clang/Frontend/CodeGenOptions.h +++ b/include/clang/Frontend/CodeGenOptions.h @@ -115,6 +115,9 @@ public: /// Enable additional debugging information. std::string DebugPass; + /// The string to embed in debug information as the current working directory. + std::string DebugCompilationDir; + /// The string to embed in the debug information for the compile unit, if /// non-empty. std::string DwarfDebugFlags; diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp index d4b566bb20..2e1d12d8ce 100644 --- a/lib/CodeGen/CGDebugInfo.cpp +++ b/lib/CodeGen/CGDebugInfo.cpp @@ -250,6 +250,9 @@ unsigned CGDebugInfo::getColumnNumber(SourceLocation Loc) { } StringRef CGDebugInfo::getCurrentDirname() { + if (!CGM.getCodeGenOpts().DebugCompilationDir.empty()) + return CGM.getCodeGenOpts().DebugCompilationDir; + if (!CWDName.empty()) return CWDName; llvm::SmallString<256> CWD; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 2dcb61bfb2..ad32bc7d1b 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -1625,6 +1625,16 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (ShouldDisableDwarfDirectory(Args, getToolChain())) CmdArgs.push_back("-fno-dwarf-directory-asm"); + if (const char *pwd = ::getenv("PWD")) { + // GCC also verifies that stat(pwd) and stat(".") have the same inode + // number. Not doing those because stats are slow, but we could. + if (pwd[0] == '/') { + std::string CompDir = pwd; + CmdArgs.push_back("-fdebug-compilation-dir"); + CmdArgs.push_back(Args.MakeArgString(CompDir)); + } + } + if (Arg *A = Args.getLastArg(options::OPT_ftemplate_depth_)) { CmdArgs.push_back("-ftemplate-depth"); CmdArgs.push_back(A->getValue(Args)); diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 05d2e692e5..76ceb9b0a5 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -131,6 +131,10 @@ static void CodeGenOptsToArgs(const CodeGenOptions &Opts, Res.push_back("-disable-llvm-optzns"); if (Opts.DisableRedZone) Res.push_back("-disable-red-zone"); + if (!Opts.DebugCompilationDir.empty()) { + Res.push_back("-fdebug-compilation-dir"); + Res.push_back(Opts.DebugCompilationDir); + } if (!Opts.DwarfDebugFlags.empty()) { Res.push_back("-dwarf-debug-flags"); Res.push_back(Opts.DwarfDebugFlags); @@ -1071,6 +1075,7 @@ static void ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Opts.EmitGcovArcs = Args.hasArg(OPT_femit_coverage_data); Opts.EmitGcovNotes = Args.hasArg(OPT_femit_coverage_notes); Opts.CoverageFile = Args.getLastArgValue(OPT_coverage_file); + Opts.DebugCompilationDir = Args.getLastArgValue(OPT_fdebug_compilation_dir); if (Arg *A = Args.getLastArg(OPT_fobjc_dispatch_method_EQ)) { StringRef Name = A->getValue(Args); diff --git a/test/CodeGen/debug-info-compilation-dir.c b/test/CodeGen/debug-info-compilation-dir.c new file mode 100644 index 0000000000..4ffa1552ca --- /dev/null +++ b/test/CodeGen/debug-info-compilation-dir.c @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -fdebug-compilation-dir /nonsense -emit-llvm -g %s -o - | \ +// RUN: grep nonsense + +// RUN: %clang_cc1 -emit-llvm -g %s -o - | grep %S diff --git a/test/Driver/debug.c b/test/Driver/debug.c new file mode 100644 index 0000000000..2ed8921769 --- /dev/null +++ b/test/Driver/debug.c @@ -0,0 +1,8 @@ +// RUN: %clang -### -g %s -c 2>&1 | grep '"-fdebug-compilation-dir" "'%S'"' +// RUN: PWD=/foo %clang -### -g %s -c 2>&1 | grep '"-fdebug-compilation-dir" "/foo"' + +// This test uses grep instead of FileCheck so that we get %S -> dirname +// substitution. + +// "PWD=/foo gcc" wouldn't necessarily work. You would need to pick a different +// path to the same directory (try a symlink).