llvmorg-github-actions[bot] wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-hlsl Author: Vladislav Dzhidzhoev (dzhidzhoev) <details> <summary>Changes</summary> Add HLSL debug metadata emission for DXIL by embedding non-system source files (including included headers) into dx.source.contents, recording the main file name and user defines, and serializing the dxc-style command line into dx.source.args. This metadata nodes are needed for emitting SRCI part of a debug DXContainer in llc. Introduce -fdx-record-command-line option to cc1 to carry the escaped driver command line into cc1. Introduce -fdx-no-source-metadata CodeGen option to cc1, to be able to disable dx.source metadata nodes emission. This comes in handy for writing debug info tests, so that CHECK-NOT lines do not match themselves in LLVM IR. For example, without this option, in `clang/test/CodeGenHLSL/debug/source-language.hlsl`, CHECK-V4-NOT line gets a match on the line with dx.source.contents node. --- Patch is 27.25 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/199689.diff 23 Files Affected: - (modified) clang/include/clang/Basic/CodeGenOptions.def (+3) - (modified) clang/include/clang/Basic/CodeGenOptions.h (+4) - (modified) clang/include/clang/Driver/CommonArgs.h (+2-2) - (modified) clang/include/clang/Options/OptionUtils.h (+4) - (modified) clang/include/clang/Options/Options.td (+13) - (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+111) - (modified) clang/lib/CodeGen/CMakeLists.txt (+1) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+7-1) - (modified) clang/lib/Driver/ToolChains/CommonArgs.cpp (+5-2) - (modified) clang/lib/Driver/ToolChains/Flang.cpp (+3-1) - (modified) clang/lib/Options/OptionUtils.cpp (+32) - (added) clang/test/CodeGenHLSL/Inputs/a.hlsl (+10) - (added) clang/test/CodeGenHLSL/Inputs/b.hlsl (+3) - (added) clang/test/CodeGenHLSL/SysInputs/c.hlsl (+3) - (modified) clang/test/CodeGenHLSL/debug/source-language.hlsl (+4) - (added) clang/test/CodeGenHLSL/dx-source-metadata-disabled.hlsl (+12) - (added) clang/test/CodeGenHLSL/dx-source-metadata-includes.hlsl (+21) - (added) clang/test/CodeGenHLSL/dx-source-metadata-mailformed-command-line.hlsl (+10) - (added) clang/test/CodeGenHLSL/dx-source-metadata.hlsl (+28) - (modified) clang/test/CodeGenHLSL/lit.local.cfg (+1) - (modified) clang/test/Driver/dxc_debug.hlsl (+4-1) - (modified) clang/unittests/Driver/CMakeLists.txt (+2) - (added) clang/unittests/Driver/EscapedCommandLineTest.cpp (+135) ``````````diff diff --git a/clang/include/clang/Basic/CodeGenOptions.def b/clang/include/clang/Basic/CodeGenOptions.def index aa36de6edecbf..b121e7cb46601 100644 --- a/clang/include/clang/Basic/CodeGenOptions.def +++ b/clang/include/clang/Basic/CodeGenOptions.def @@ -520,6 +520,9 @@ CODEGENOPT(ResMayAlias, 1, 0, Benign) /// Assume that all resources are bound if enabled CODEGENOPT(AllResourcesBound, 1, 0, Benign) +/// Do not embed dx.source.* metadata in HLSL modules. +CODEGENOPT(DisableDXSourceMetadata, 1, 0, Benign) + /// Controls how unwind v2 (epilog) information should be generated for x64 /// Windows. ENUM_CODEGENOPT(WinX64EHUnwindV2, WinX64EHUnwindV2Mode, diff --git a/clang/include/clang/Basic/CodeGenOptions.h b/clang/include/clang/Basic/CodeGenOptions.h index e43112b4bb98b..33991827eb061 100644 --- a/clang/include/clang/Basic/CodeGenOptions.h +++ b/clang/include/clang/Basic/CodeGenOptions.h @@ -268,6 +268,10 @@ class CodeGenOptions : public CodeGenOptionsBase { /// if non-empty. std::string RecordCommandLine; + /// The string containing the commandline for the dx.source.args metadata, + /// if non-empty. + std::string HLSLRecordCommandLine; + llvm::SmallVector<std::pair<std::string, std::string>, 0> DebugPrefixMap; /// Prefix replacement map for source-based code coverage to remap source diff --git a/clang/include/clang/Driver/CommonArgs.h b/clang/include/clang/Driver/CommonArgs.h index 0af1b89425227..51ae3b13b5550 100644 --- a/clang/include/clang/Driver/CommonArgs.h +++ b/clang/include/clang/Driver/CommonArgs.h @@ -275,8 +275,8 @@ const char *renderEscapedCommandLine(const ToolChain &TC, /// line options that were passed. bool shouldRecordCommandLine(const ToolChain &TC, const llvm::opt::ArgList &Args, - bool &FRecordCommandLine, - bool &GRecordCommandLine); + bool &FRecordCommandLine, bool &GRecordCommandLine, + bool &DXRecordCommandLine); void renderGlobalISelOptions(const Driver &D, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, diff --git a/clang/include/clang/Options/OptionUtils.h b/clang/include/clang/Options/OptionUtils.h index 02c9c27554db1..4305cdd134bf4 100644 --- a/clang/include/clang/Options/OptionUtils.h +++ b/clang/include/clang/Options/OptionUtils.h @@ -77,6 +77,10 @@ std::string GetResourcesPath(StringRef BinaryPath); /// executable), for finding the builtin compiler path. std::string GetResourcesPath(const char *Argv0, void *MainAddr); +/// Parse a space-separated command line with escaped spaces and backslashes. +llvm::Expected<llvm::SmallVector<llvm::SmallString<8>>> +parseEscapedCommandLine(const char *CommandLine); + } // namespace clang #endif // LLVM_CLANG_OPTIONS_OPTIONUTILS_H diff --git a/clang/include/clang/Options/Options.td b/clang/include/clang/Options/Options.td index 753e3ac1b74a5..f448a986038cb 100644 --- a/clang/include/clang/Options/Options.td +++ b/clang/include/clang/Options/Options.td @@ -9670,6 +9670,19 @@ def dxc_rootsig_define : Alias<fdx_rootsignature_define>, Group<dxc_Group>, Visibility<[DXCOption]>; +def dxc_record_command_line + : Separate<["-"], "fdx-record-command-line">, + Group<dxc_Group>, + Visibility<[CC1Option]>, + MarshallingInfoString<CodeGenOpts<"HLSLRecordCommandLine">>, + HelpText< + "Command line arguments to embed in the dx.source.args metadata">; +def dxc_no_source_metadata + : Flag<["-"], "fdx-no-source-metadata">, + Group<dxc_Group>, + Visibility<[CC1Option]>, + MarshallingInfoFlag<CodeGenOpts<"DisableDXSourceMetadata">>, + HelpText<"Do not embed source info metadata in HLSL modules">; def hlsl_entrypoint : Option<["-"], "hlsl-entry", KIND_SEPARATE>, Group<dxc_Group>, Visibility<[ClangOption, CC1Option]>, diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp index 98d65715d45b9..a21b96f4acb7c 100644 --- a/clang/lib/CodeGen/CGHLSLRuntime.cpp +++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp @@ -27,8 +27,11 @@ #include "clang/AST/RecursiveASTVisitor.h" #include "clang/AST/Type.h" #include "clang/Basic/DiagnosticFrontend.h" +#include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetOptions.h" +#include "clang/Options/OptionUtils.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/STLExtras.h" #include "llvm/ADT/ScopeExit.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/SmallVector.h" @@ -45,6 +48,7 @@ #include "llvm/Support/Alignment.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FormatVariadic.h" +#include "llvm/Support/Path.h" #include <cstdint> #include <optional> @@ -189,6 +193,109 @@ findAssociatedResourceDeclForStruct(ASTContext &AST, const MemberExpr *ME) { return nullptr; } +void addSourceInfo(CodeGenModule &CGM, llvm::Module &M) { + auto &SM = CGM.getContext().getSourceManager(); + auto &Macros = CGM.getPreprocessorOpts().Macros; + auto &Ctx = M.getContext(); + + // Names and content of shader source code files. + llvm::NamedMDNode *DXContents = + M.getOrInsertNamedMetadata("dx.source.contents"); + auto addFile = [&](const std::pair<StringRef, StringRef> &NameContent) { + llvm::MDTuple *FileInfo = + llvm::MDNode::get(Ctx, {llvm::MDString::get(Ctx, NameContent.first), + llvm::MDString::get(Ctx, NameContent.second)}); + DXContents->addOperand(FileInfo); + }; + + bool Invalid = false; + const SrcMgr::SLocEntry *MainLocEntry = + &SM.getSLocEntry(SM.getMainFileID(), &Invalid); + assert(!Invalid && "Main file SLocEntry must not be invalid!"); + const SrcMgr::ContentCache &MainCCEntry = + MainLocEntry->getFile().getContentCache(); + + SmallVector<std::pair<std::string, StringRef>> Files; + std::optional<SmallString<256>> MainFileName; + Files.reserve(SM.local_sloc_entry_size()); + for (unsigned I : llvm::seq(SM.local_sloc_entry_size())) { + const SrcMgr::SLocEntry &LocEntry = SM.getLocalSLocEntry(I); + if (!LocEntry.isFile()) + continue; + + const SrcMgr::FileInfo &FInfo = LocEntry.getFile(); + if (isSystem(FInfo.getFileCharacteristic())) + continue; + + const SrcMgr::ContentCache &CCEntry = FInfo.getContentCache(); + OptionalFileEntryRef FEntry = CCEntry.OrigEntry; + if (!FEntry) + continue; + + llvm::SmallString<256> Path = FEntry->getName(); + llvm::sys::path::native(Path); + std::optional<llvm::MemoryBufferRef> Buffer = CCEntry.getBufferOrNone( + SM.getDiagnostics(), SM.getFileManager(), SourceLocation()); + if (!Buffer) { + unsigned ID = SM.getDiagnostics().getCustomDiagID( + clang::DiagnosticsEngine::Warning, + "failed to embed source for \"%0\" into dx.source.contents"); + SM.getDiagnostics().Report(ID) << Path; + continue; + } + + if (&MainCCEntry != &CCEntry) { + Files.emplace_back(Path, Buffer->getBuffer()); + } else { + // Main file should be at first position. + addFile(std::make_pair(Path, Buffer->getBuffer())); + MainFileName.emplace(Path); + } + } + assert(MainFileName && "Main file not found."); + + // Files other that main one should be sorted by name. + llvm::sort(Files); +#ifndef NDEBUG + for (unsigned I = 1; I < Files.size(); ++I) + assert((Files[I - 1].first != Files[I].first) && + "duplicate files in dx.source.contents"); +#endif + llvm::for_each(Files, addFile); + + SmallVector<llvm::Metadata *> Defines; + Defines.reserve(Macros.size()); + for (const auto &Macro : Macros) { + // Ignore undefs. + if (!Macro.second) + Defines.emplace_back(llvm::MDString::get(Ctx, Macro.first)); + } + M.getOrInsertNamedMetadata("dx.source.defines") + ->addOperand(llvm::MDNode::get(Ctx, Defines)); + + if (!CGM.getCodeGenOpts().MainFileName.empty()) + llvm::sys::path::native(CGM.getCodeGenOpts().MainFileName, *MainFileName); + M.getOrInsertNamedMetadata("dx.source.mainFileName") + ->addOperand( + llvm::MDNode::get(Ctx, llvm::MDString::get(Ctx, *MainFileName))); + + auto ParsedArgs = clang::parseEscapedCommandLine( + CGM.getCodeGenOpts().HLSLRecordCommandLine.c_str()); + if (!ParsedArgs) { + unsigned DiagID = CGM.getDiags().getCustomDiagID( + DiagnosticsEngine::Error, "invalid escaped command line: %0"); + CGM.getDiags().Report(DiagID) << llvm::toString(ParsedArgs.takeError()); + return; + } + SmallVector<llvm::Metadata *> Args; + Args.reserve(ParsedArgs->size()); + if (!ParsedArgs->empty()) + for (const auto &Arg : llvm::drop_begin(*ParsedArgs)) + Args.push_back(llvm::MDString::get(Ctx, Arg)); + M.getOrInsertNamedMetadata("dx.source.args") + ->addOperand(llvm::MDNode::get(Ctx, Args)); +} + // Find array variable declaration from DeclRef expression static const ValueDecl *getArrayDecl(ASTContext &AST, const Expr *E) { E = E->IgnoreImpCasts(); @@ -576,6 +683,10 @@ void CGHLSLRuntime::finishCodeGen() { Triple T(M.getTargetTriple()); if (T.getArch() == Triple::ArchType::dxil) addDxilValVersion(TargetOpts.DxilValidatorVersion, M); + if (!CodeGenOpts.DisableDXSourceMetadata && + CodeGenOpts.getDebugInfo() >= + llvm::codegenoptions::DebugInfoKind::DebugInfoConstructor) + addSourceInfo(CGM, M); if (CodeGenOpts.ResMayAlias) M.setModuleFlag(llvm::Module::ModFlagBehavior::Error, "dx.resmayalias", 1); if (CodeGenOpts.AllResourcesBound) diff --git a/clang/lib/CodeGen/CMakeLists.txt b/clang/lib/CodeGen/CMakeLists.txt index 117438c616ab5..54498de279f42 100644 --- a/clang/lib/CodeGen/CMakeLists.txt +++ b/clang/lib/CodeGen/CMakeLists.txt @@ -173,5 +173,6 @@ add_clang_library(clangCodeGen clangBasic clangFrontend clangLex + clangOptions clangSerialization ) diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index 8d8e00bbaf7d0..1372798b45cb9 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -8058,7 +8058,9 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // By default, -gno-record-gcc-switches is set on and no recording. auto GRecordSwitches = false; auto FRecordSwitches = false; - if (shouldRecordCommandLine(TC, Args, FRecordSwitches, GRecordSwitches)) { + bool DXRecordSwitches = false; + if (shouldRecordCommandLine(TC, Args, FRecordSwitches, GRecordSwitches, + DXRecordSwitches)) { auto FlagsArgString = renderEscapedCommandLine(TC, Args); if (TC.UseDwarfDebugFlags() || GRecordSwitches) { CmdArgs.push_back("-dwarf-debug-flags"); @@ -8068,6 +8070,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-record-command-line"); CmdArgs.push_back(FlagsArgString); } + if (DXRecordSwitches) { + CmdArgs.push_back("-fdx-record-command-line"); + CmdArgs.push_back(FlagsArgString); + } } // Host-side offloading compilation receives all device-side outputs. Include diff --git a/clang/lib/Driver/ToolChains/CommonArgs.cpp b/clang/lib/Driver/ToolChains/CommonArgs.cpp index 2ef7c1506e18d..dae0c67ad69c9 100644 --- a/clang/lib/Driver/ToolChains/CommonArgs.cpp +++ b/clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -3338,7 +3338,8 @@ const char *tools::renderEscapedCommandLine(const ToolChain &TC, bool tools::shouldRecordCommandLine(const ToolChain &TC, const llvm::opt::ArgList &Args, bool &FRecordCommandLine, - bool &GRecordCommandLine) { + bool &GRecordCommandLine, + bool &DXRecordCommandLine) { const Driver &D = TC.getDriver(); const llvm::Triple &Triple = TC.getEffectiveTriple(); const std::string &TripleStr = Triple.getTriple(); @@ -3349,13 +3350,15 @@ bool tools::shouldRecordCommandLine(const ToolChain &TC, GRecordCommandLine = Args.hasFlag(options::OPT_grecord_command_line, options::OPT_gno_record_command_line, false); + DXRecordCommandLine = Triple.isDXIL() && Args.hasArg(options::OPT_g_Flag); if (FRecordCommandLine && !Triple.isOSBinFormatELF() && !Triple.isOSBinFormatXCOFF() && !Triple.isOSBinFormatMachO()) D.Diag(diag::err_drv_unsupported_opt_for_target) << Args.getLastArg(options::OPT_frecord_command_line)->getAsString(Args) << TripleStr; - return FRecordCommandLine || TC.UseDwarfDebugFlags() || GRecordCommandLine; + return FRecordCommandLine || TC.UseDwarfDebugFlags() || GRecordCommandLine || + DXRecordCommandLine; } void tools::renderGlobalISelOptions(const Driver &D, const ArgList &Args, diff --git a/clang/lib/Driver/ToolChains/Flang.cpp b/clang/lib/Driver/ToolChains/Flang.cpp index 4c722a2e021eb..3620961b4c3b1 100644 --- a/clang/lib/Driver/ToolChains/Flang.cpp +++ b/clang/lib/Driver/ToolChains/Flang.cpp @@ -1284,7 +1284,9 @@ void Flang::ConstructJob(Compilation &C, const JobAction &JA, bool FRecordCmdLine = false; bool GRecordCmdLine = false; - if (shouldRecordCommandLine(TC, Args, FRecordCmdLine, GRecordCmdLine)) { + bool DXRecordCmdLine = false; + if (shouldRecordCommandLine(TC, Args, FRecordCmdLine, GRecordCmdLine, + DXRecordCmdLine)) { const char *CmdLine = renderEscapedCommandLine(TC, Args); if (FRecordCmdLine) { CmdArgs.push_back("-record-command-line"); diff --git a/clang/lib/Options/OptionUtils.cpp b/clang/lib/Options/OptionUtils.cpp index e5aefa012f679..77f89552e852a 100644 --- a/clang/lib/Options/OptionUtils.cpp +++ b/clang/lib/Options/OptionUtils.cpp @@ -244,3 +244,35 @@ std::string clang::GetResourcesPath(const char *Argv0, void *MainAddr) { llvm::sys::fs::getMainExecutable(Argv0, MainAddr); return GetResourcesPath(ClangExecutable); } + +static bool isSpaceOrNull(char c) { return !c || c == ' '; } + +static Expected<const char *> unescapeUntilSpace(const char *Arg, + SmallVectorImpl<char> &Res) { + for (; !isSpaceOrNull(*Arg); ++Arg) { + if (*Arg == '\\') { + ++Arg; + if (*Arg != '\\' && *Arg != ' ') + return llvm::createStringError( + llvm::inconvertibleErrorCode(), + "only escaped backslashes and spaces are supported"); + } + Res.push_back(*Arg); + } + return Arg; +} + +Expected<SmallVector<SmallString<8>>> +clang::parseEscapedCommandLine(const char *CommandLine) { + SmallVector<SmallString<8>> Res; + while (*CommandLine) { + Expected<const char *> ArgEnd = + unescapeUntilSpace(CommandLine, Res.emplace_back()); + if (!ArgEnd) + return ArgEnd.takeError(); + CommandLine = *ArgEnd; + if (*CommandLine == ' ') + ++CommandLine; + } + return Res; +} diff --git a/clang/test/CodeGenHLSL/Inputs/a.hlsl b/clang/test/CodeGenHLSL/Inputs/a.hlsl new file mode 100644 index 0000000000000..9c132672dea82 --- /dev/null +++ b/clang/test/CodeGenHLSL/Inputs/a.hlsl @@ -0,0 +1,10 @@ +#ifndef GUARD +#define GUARD + +#include "b.hlsl" + +float helper1_add(float a, float b) { + return a + b; +} + +#endif diff --git a/clang/test/CodeGenHLSL/Inputs/b.hlsl b/clang/test/CodeGenHLSL/Inputs/b.hlsl new file mode 100644 index 0000000000000..798909fa50569 --- /dev/null +++ b/clang/test/CodeGenHLSL/Inputs/b.hlsl @@ -0,0 +1,3 @@ +float helper2_mul(float a, float b) { + return a * b; +} diff --git a/clang/test/CodeGenHLSL/SysInputs/c.hlsl b/clang/test/CodeGenHLSL/SysInputs/c.hlsl new file mode 100644 index 0000000000000..30223007e1920 --- /dev/null +++ b/clang/test/CodeGenHLSL/SysInputs/c.hlsl @@ -0,0 +1,3 @@ +float sys_helper(float a, float b) { + return a * b; +} diff --git a/clang/test/CodeGenHLSL/debug/source-language.hlsl b/clang/test/CodeGenHLSL/debug/source-language.hlsl index f1e63d17724ee..83099b288853f 100644 --- a/clang/test/CodeGenHLSL/debug/source-language.hlsl +++ b/clang/test/CodeGenHLSL/debug/source-language.hlsl @@ -5,24 +5,28 @@ // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -emit-llvm \ // RUN: -disable-llvm-passes -hlsl-entry main \ // RUN: -debug-info-kind=standalone -dwarf-version=4 -o - %s \ +// RUN: -fdx-no-source-metadata \ // RUN: | FileCheck %s --check-prefix=CHECK-V4 // SPIR-V target, DWARFv4 // RUN: %clang_cc1 -triple spirv-unknown-vulkan-compute -x hlsl -emit-llvm \ // RUN: -disable-llvm-passes -hlsl-entry main \ // RUN: -debug-info-kind=standalone -dwarf-version=4 -o - %s \ +// RUN: -fdx-no-source-metadata \ // RUN: | FileCheck %s --check-prefix=CHECK-V4 // DXIL target, DWARFv6 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-compute -x hlsl -emit-llvm \ // RUN: -disable-llvm-passes -hlsl-entry main \ // RUN: -debug-info-kind=standalone -dwarf-version=6 -o - %s \ +// RUN: -fdx-no-source-metadata \ // RUN: | FileCheck %s --check-prefix=CHECK-V6 // SPIR-V target, DWARFv6 // RUN: %clang_cc1 -triple spirv-unknown-vulkan-compute -x hlsl -emit-llvm \ // RUN: -disable-llvm-passes -hlsl-entry main \ // RUN: -debug-info-kind=standalone -dwarf-version=6 -o - %s \ +// RUN: -fdx-no-source-metadata \ // RUN: | FileCheck %s --check-prefix=CHECK-V6 // CHECK-V4: !DICompileUnit(language: DW_LANG_HLSL, diff --git a/clang/test/CodeGenHLSL/dx-source-metadata-disabled.hlsl b/clang/test/CodeGenHLSL/dx-source-metadata-disabled.hlsl new file mode 100644 index 0000000000000..aa26a49feeef6 --- /dev/null +++ b/clang/test/CodeGenHLSL/dx-source-metadata-disabled.hlsl @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm \ +// RUN: -debug-info-kind=constructor -fdx-no-source-metadata -o - \ +// RUN: -disable-llvm-passes %s | FileCheck %s + +// CHECK-NOT: !dx.source.contents +// CHECK-NOT: !dx.source.defines +// CHECK-NOT: !dx.source.mainFileName +// CHECK-NOT: !dx.source.args + +float foo(float a, float b) { + return a + b; +} diff --git a/clang/test/CodeGenHLSL/dx-source-metadata-includes.hlsl b/clang/test/CodeGenHLSL/dx-source-metadata-includes.hlsl new file mode 100644 index 0000000000000..65861f5a50fdc --- /dev/null +++ b/clang/test/CodeGenHLSL/dx-source-metadata-includes.hlsl @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm \ +// RUN: -debug-info-kind=constructor -I %S/Inputs -isystem %S/SysInputs \ +// RUN: -o - %s | FileCheck %s + +#include "a.hlsl" +#include "a.hlsl" +#include <c.hlsl> + +// The main file appears first in dx.source.contents; included files are +// appended in sorted order afterwards. Duplicate and system includes are ignored. + +// CHECK: !dx.source.contents = !{![[MAIN:[0-9]+]], ![[H1:[0-9]+]], ![[H2:[0-9]+]]} +// CHECK: !dx.source.mainFileName = !{![[MAIN_FILE_NAME:[0-9]+]]} +// CHECK: ![[MAIN]] = !{!"{{.*[\\/]dx-source-metadata-includes.hlsl}}", !"{{.*}}"} +// CHECK: ![[H1]] = !{!"{{.*[\\/]a.hlsl}}", !"{{.*}}"} +// CHECK: ![[H2]] = !{!"{{.*[\\/]b.hlsl}}", !"{{.*}}"} +// CHECK: ![[MAIN_FILE_NAME]] = !{!"{{.*[\\/]dx-source-metadata-includes.hlsl}}"} + +float foo(float a, float b) { + return helper1_add(a, b) + helper2_mul(a, b) + sys_helper(a, b); +} diff --git a/clang/test/CodeGenHLSL/dx-source-metadata-mailformed-command-line.hlsl b/clang/test/CodeGenHLSL/dx-source-metadata-mailformed-command-line.hlsl new file mode 100644 index 0000000000000..b6557503ab118 --- /dev/null +++ b/clang/test/CodeGenHLSL/dx-source-metadata-mailformed-command-line.hlsl @@ -0,0 +1,10 @@ +// RUN: not %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm \ +// RUN: -debug-info-kind=constructor \ +// RUN: -fdx-record-command-line "clang_dxc \\" \ +// RUN: -o - %s 2>&1 | FileCheck %s + +// CHECK: error: invalid escaped command line: only escaped backslashes and spaces are supported + +float foo(float a, float b) { + return a + b; +} diff --git a/clang/test/CodeGenHLSL/dx-source-metadata.hlsl b/clang/test/CodeGenHLSL/dx-source-metadata.hlsl new file mode 100644 index 0000000000000..c523f36cc69b6 --- /dev/null +++ b/clang/test/CodeGenHLSL/dx-source-metadata.hlsl @@ -0,0 +1,28 @@ +// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -x hlsl -emit-llvm \ +// RUN: -debug-info-kind=constructor -DUSER_DEF0=42 -DUSER_DEF1=43 -... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/199689 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
