scott.linder created this revision. scott.linder added reviewers: echristo, arsenm, aprantl. Herald added subscribers: cfe-commits, JDevlieghere, nhaehnle, wdng.
In DWARFv5 the Line Number Program Header is extensible, allowing values with new content types. In this extension source is embedded directly in the line tables of the DWARFv5 line debug section. Add new flag (-g[no-]embed-source) to Driver and CC1 which indicates that source should be passed through to LLVM during CodeGen. Depends on LLVM review https://reviews.llvm.org/D42765 Repository: rC Clang https://reviews.llvm.org/D42766 Files: docs/ClangCommandLineReference.rst include/clang/Driver/Options.td include/clang/Frontend/CodeGenOptions.def lib/CodeGen/CGDebugInfo.cpp lib/CodeGen/CGDebugInfo.h lib/Driver/ToolChains/AMDGPU.h lib/Driver/ToolChains/Clang.cpp lib/Frontend/CompilerInvocation.cpp test/CodeGen/Inputs/debug-info-embed-source.c test/CodeGen/debug-info-embed-source.c test/Driver/amdgpu-toolchain.c test/Driver/debug-options.c
Index: test/Driver/debug-options.c =================================================================== --- test/Driver/debug-options.c +++ test/Driver/debug-options.c @@ -245,3 +245,13 @@ // RUN: %clang -### %s 2>&1 | FileCheck -check-prefix=NOMACRO %s // MACRO: "-debug-info-macro" // NOMACRO-NOT: "-debug-info-macro" +// +// RUN: %clang -### -gdwarf-5 -gembed-source %s 2>&1 | FileCheck -check-prefix=GEMBED_5 %s +// RUN: %clang -### -gdwarf-2 -gembed-source %s 2>&1 | FileCheck -check-prefix=GEMBED_2 %s +// RUN: %clang -### -gdwarf-5 -gno-embed-source %s 2>&1 | FileCheck -check-prefix=NOGEMBED_5 %s +// RUN: %clang -### -gdwarf-2 -gno-embed-source %s 2>&1 | FileCheck -check-prefix=NOGEMBED_2 %s +// +// GEMBED_5: "-gembed-source" +// GEMBED_2: error: invalid argument '-gembed-source' only allowed with '-gdwarf-5' +// NOGEMBED_5-NOT: "-gembed-source" +// NOGEMBED_2-NOT: error: invalid argument '-gembed-source' only allowed with '-gdwarf-5' Index: test/Driver/amdgpu-toolchain.c =================================================================== --- test/Driver/amdgpu-toolchain.c +++ test/Driver/amdgpu-toolchain.c @@ -3,4 +3,4 @@ // AS_LINK: ld.lld{{.*}} "-shared" // RUN: %clang -### -g -target amdgcn--amdhsa -mcpu=kaveri %s 2>&1 | FileCheck -check-prefix=DWARF_VER %s -// DWARF_VER: "-dwarf-version=2" +// DWARF_VER: "-dwarf-version=5" Index: test/CodeGen/debug-info-embed-source.c =================================================================== --- /dev/null +++ test/CodeGen/debug-info-embed-source.c @@ -0,0 +1,5 @@ +// RUN: %clang_cc1 -debug-info-kind=limited -emit-llvm %p/Inputs/debug-info-embed-source.c -o - | FileCheck %s --check-prefix=NOEMBED +// RUN: %clang_cc1 -gembed-source -debug-info-kind=limited -emit-llvm %p/Inputs/debug-info-embed-source.c -o - | FileCheck %s --check-prefix=EMBED + +// NOEMBED-NOT: !DIFile({{.*}}source: +// EMBED: !DIFile({{.*}}source: "void foo() { }\0A" Index: test/CodeGen/Inputs/debug-info-embed-source.c =================================================================== --- /dev/null +++ test/CodeGen/Inputs/debug-info-embed-source.c @@ -0,0 +1 @@ +void foo() { } Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -545,6 +545,7 @@ Opts.DebugTypeExtRefs = Args.hasArg(OPT_dwarf_ext_refs); Opts.DebugExplicitImport = Args.hasArg(OPT_dwarf_explicit_import); Opts.DebugFwdTemplateParams = Args.hasArg(OPT_debug_forward_template_params); + Opts.EmbedSource = Args.hasArg(OPT_gembed_source); for (const auto &Arg : Args.getAllArgValues(OPT_fdebug_prefix_map_EQ)) Opts.DebugPrefixMap.insert(StringRef(Arg).split('=')); Index: lib/Driver/ToolChains/Clang.cpp =================================================================== --- lib/Driver/ToolChains/Clang.cpp +++ lib/Driver/ToolChains/Clang.cpp @@ -3017,6 +3017,17 @@ if (DebugInfoKind == codegenoptions::LimitedDebugInfo && NeedFullDebug) DebugInfoKind = codegenoptions::FullDebugInfo; + if (Args.hasFlag(options::OPT_gembed_source, options::OPT_gno_embed_source, false)) { + // Source embedding is a DWARFv5 extension. By now we have checked if a + // DWARF version was stated explicitly, and have otherwise fallen back to + // the target default, so if this is still not at least 5 we emit an error. + if (DWARFVersion < 5) + D.Diag(diag::err_drv_argument_only_allowed_with) + << Args.getLastArg(options::OPT_gembed_source)->getAsString(Args) + << "-gdwarf-5"; + CmdArgs.push_back("-gembed-source"); + } + RenderDebugEnablingArgs(Args, CmdArgs, DebugInfoKind, DWARFVersion, DebuggerTuning); Index: lib/Driver/ToolChains/AMDGPU.h =================================================================== --- lib/Driver/ToolChains/AMDGPU.h +++ lib/Driver/ToolChains/AMDGPU.h @@ -56,7 +56,7 @@ public: AMDGPUToolChain(const Driver &D, const llvm::Triple &Triple, const llvm::opt::ArgList &Args); - unsigned GetDefaultDwarfVersion() const override { return 2; } + unsigned GetDefaultDwarfVersion() const override { return 5; } bool IsIntegratedAssemblerDefault() const override { return true; } llvm::opt::DerivedArgList * TranslateArgs(const llvm::opt::DerivedArgList &Args, StringRef BoundArch, Index: lib/CodeGen/CGDebugInfo.h =================================================================== --- lib/CodeGen/CGDebugInfo.h +++ lib/CodeGen/CGDebugInfo.h @@ -485,6 +485,9 @@ llvm::DIFile::ChecksumKind computeChecksum(FileID FID, SmallString<32> &Checksum) const; + /// Get the source of the given file ID. + Optional<StringRef> getSource(const SourceManager &SM, FileID FID); + /// Get the file debug info descriptor for the input location. llvm::DIFile *getOrCreateFile(SourceLocation Loc); Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -385,23 +385,30 @@ return llvm::DIFile::CSK_MD5; } +Optional<StringRef> CGDebugInfo::getSource(const SourceManager &SM, FileID FID) { + if (!CGM.getCodeGenOpts().EmbedSource) + return None; + + bool SourceInvalid = false; + StringRef Source = SM.getBufferData(FID, &SourceInvalid); + + if (SourceInvalid) + return None; + + return Source; +} + llvm::DIFile *CGDebugInfo::getOrCreateFile(SourceLocation Loc) { if (!Loc.isValid()) // If Location is not valid then use main input file. - return DBuilder.createFile(remapDIPath(TheCU->getFilename()), - remapDIPath(TheCU->getDirectory()), - TheCU->getFile()->getChecksumKind(), - TheCU->getFile()->getChecksum()); + return getOrCreateMainFile(); SourceManager &SM = CGM.getContext().getSourceManager(); PresumedLoc PLoc = SM.getPresumedLoc(Loc); if (PLoc.isInvalid() || StringRef(PLoc.getFilename()).empty()) // If the location is not valid then use main input file. - return DBuilder.createFile(remapDIPath(TheCU->getFilename()), - remapDIPath(TheCU->getDirectory()), - TheCU->getFile()->getChecksumKind(), - TheCU->getFile()->getChecksum()); + return getOrCreateMainFile(); // Cache the results. const char *fname = PLoc.getFilename(); @@ -419,7 +426,8 @@ llvm::DIFile *F = DBuilder.createFile(remapDIPath(PLoc.getFilename()), remapDIPath(getCurrentDirname()), - CSKind, Checksum); + CSKind, Checksum, + getSource(SM, SM.getFileID(Loc))); DIFileCache[fname].reset(F); return F; @@ -429,7 +437,8 @@ return DBuilder.createFile(remapDIPath(TheCU->getFilename()), remapDIPath(TheCU->getDirectory()), TheCU->getFile()->getChecksumKind(), - TheCU->getFile()->getChecksum()); + TheCU->getFile()->getChecksum(), + CGM.getCodeGenOpts().EmbedSource ? TheCU->getSource() : None); } std::string CGDebugInfo::remapDIPath(StringRef Path) const { @@ -558,7 +567,9 @@ TheCU = DBuilder.createCompileUnit( LangTag, DBuilder.createFile(remapDIPath(MainFileName), - remapDIPath(getCurrentDirname()), CSKind, Checksum), + remapDIPath(getCurrentDirname()), + CSKind, Checksum, + getSource(SM, SM.getMainFileID())), Producer, LO.Optimize || CGOpts.PrepareForLTO || CGOpts.EmitSummaryIndex, CGOpts.DwarfDebugFlags, RuntimeVers, CGOpts.EnableSplitDwarf ? "" : CGOpts.SplitDwarfFile, EmissionKind, @@ -2108,6 +2119,7 @@ : ~1ULL; llvm::DIBuilder DIB(CGM.getModule()); DIB.createCompileUnit(TheCU->getSourceLanguage(), + // TODO: Support "Source" from external AST providers? DIB.createFile(Mod.getModuleName(), Mod.getPath()), TheCU->getProducer(), true, StringRef(), 0, Mod.getASTFile(), llvm::DICompileUnit::FullDebug, Index: include/clang/Frontend/CodeGenOptions.def =================================================================== --- include/clang/Frontend/CodeGenOptions.def +++ include/clang/Frontend/CodeGenOptions.def @@ -313,6 +313,9 @@ CODEGENOPT(NoPLT, 1, 0) +/// Whether to embed source in DWARF debug line section. +CODEGENOPT(EmbedSource, 1, 0) + #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT Index: include/clang/Driver/Options.td =================================================================== --- include/clang/Driver/Options.td +++ include/clang/Driver/Options.td @@ -1677,6 +1677,11 @@ HelpText<"DWARF debug sections compression type">; def gz_EQ : Joined<["-"], "gz=">, Group<g_flags_Group>, HelpText<"DWARF debug sections compression type">; +def gembed_source : Flag<["-"], "gembed-source">, Group<g_flags_Group>, Flags<[CC1Option]>, + HelpText<"Embed source text in DWARF debug sections">; +def gno_embed_source : Flag<["-"], "gno-embed-source">, Group<g_flags_Group>, + Flags<[DriverOption]>, + HelpText<"Restore the default behavior of not embedding source text in DWARF debug sections">; def headerpad__max__install__names : Joined<["-"], "headerpad_max_install_names">; def help : Flag<["-", "--"], "help">, Flags<[CC1Option,CC1AsOption]>, HelpText<"Display available options">; Index: docs/ClangCommandLineReference.rst =================================================================== --- docs/ClangCommandLineReference.rst +++ docs/ClangCommandLineReference.rst @@ -2555,6 +2555,10 @@ .. option:: -gdwarf-aranges +.. option:: -gembed-source + +.. option:: -gno-embed-source + .. option:: -ggnu-pubnames .. option:: -grecord-gcc-switches, -gno-record-gcc-switches
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits