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 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, HelpText<"DWARF debug sections compression type">; +def gembed_source : Flag<["-"], "gembed-source">, Group, Flags<[CC1Option]>, + HelpText<"Embed source text in DWARF debug sections">; +def gno_embed_source : Flag<["-"], "gno-embed-source">, 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: 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: 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 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 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: 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/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/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: test/CodeGen/Inputs/debug-info-embed-source.c =================================================================== --- /dev/null +++ test/CodeGen/Inputs/debug-info-embed-source.c @@ -0,0 +1 @@ +void foo() { } 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/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/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'