llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang @llvm/pr-subscribers-clang-driver Author: Utkarsh Saxena (usx95) <details> <summary>Changes</summary> Reverts https://github.com/llvm/llvm-project/pull/99731 Remove accidentally added temporary file. Also fix uninitialized read of line number. --- Patch is 27.02 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/99757.diff 12 Files Affected: - (modified) clang/docs/ReleaseNotes.rst (+3) - (modified) clang/include/clang/Driver/Options.td (+4) - (modified) clang/include/clang/Frontend/FrontendOptions.h (+7-1) - (modified) clang/lib/Driver/ToolChains/Clang.cpp (+1) - (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+8-3) - (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+8-3) - (modified) clang/test/Driver/ftime-trace-sections.cpp (+1-1) - (modified) clang/test/Driver/ftime-trace.cpp (+20-19) - (modified) clang/tools/driver/cc1_main.cpp (+2-1) - (modified) clang/unittests/Support/TimeProfilerTest.cpp (+96-27) - (modified) llvm/include/llvm/Support/TimeProfiler.h (+22-1) - (modified) llvm/lib/Support/TimeProfiler.cpp (+53-8) ``````````diff diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index aa91663260755..7ac6ed934290d 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -750,6 +750,9 @@ Improvements to Clang's time-trace - Clang now specifies that using ``auto`` in a lambda parameter is a C++14 extension when appropriate. (`#46059: <https://github.com/llvm/llvm-project/issues/46059>`_). +- Clang now adds source file infomation for template instantiations as ``event["args"]["filename"]``. This + added behind an option ``-ftime-trace-verbose``. This is expected to increase the size of trace by 2-3 times. + Improvements to Coverage Mapping -------------------------------- diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 8707e71f2a319..9c6cebd77ff0a 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -3998,6 +3998,10 @@ def ftime_trace_granularity_EQ : Joined<["-"], "ftime-trace-granularity=">, Grou HelpText<"Minimum time granularity (in microseconds) traced by time profiler">, Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, MarshallingInfoInt<FrontendOpts<"TimeTraceGranularity">, "500u">; +def ftime_trace_verbose : Joined<["-"], "ftime-trace-verbose">, Group<f_Group>, + HelpText<"Make time trace capture verbose event details (e.g. source filenames). This can increase the size of the output by 2-3 times">, + Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, + MarshallingInfoFlag<FrontendOpts<"TimeTraceVerbose">>; def ftime_trace_EQ : Joined<["-"], "ftime-trace=">, Group<f_Group>, HelpText<"Similar to -ftime-trace. Specify the JSON file or a directory which will contain the JSON file">, Visibility<[ClangOption, CC1Option, CLOption, DXCOption]>, diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index 5e5034fe01eb5..8241925c98476 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -580,6 +580,11 @@ class FrontendOptions { /// Minimum time granularity (in microseconds) traced by time profiler. unsigned TimeTraceGranularity; + /// Make time trace capture verbose event details (e.g. source filenames). + /// This can increase the size of the output by 2-3 times. + LLVM_PREFERRED_TYPE(bool) + unsigned TimeTraceVerbose : 1; + /// Path which stores the output files for -ftime-trace std::string TimeTracePath; @@ -601,7 +606,8 @@ class FrontendOptions { EmitSymbolGraph(false), EmitExtensionSymbolGraphs(false), EmitSymbolGraphSymbolLabelsForTesting(false), EmitPrettySymbolGraphs(false), GenReducedBMI(false), - UseClangIRPipeline(false), TimeTraceGranularity(500) {} + UseClangIRPipeline(false), TimeTraceGranularity(500), + TimeTraceVerbose(false) {} /// getInputKindForExtension - Return the appropriate input kind for a file /// extension. For example, "c" would return Language::C. diff --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp index c9f0fe0a3d60f..f7b987bf810c1 100644 --- a/clang/lib/Driver/ToolChains/Clang.cpp +++ b/clang/lib/Driver/ToolChains/Clang.cpp @@ -6757,6 +6757,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, if (const char *Name = C.getTimeTraceFile(&JA)) { CmdArgs.push_back(Args.MakeArgString("-ftime-trace=" + Twine(Name))); Args.AddLastArg(CmdArgs, options::OPT_ftime_trace_granularity_EQ); + Args.AddLastArg(CmdArgs, options::OPT_ftime_trace_verbose); } if (Arg *A = Args.getLastArg(options::OPT_ftrapv_handler_EQ)) { diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp index a7bc6749c5852..725b62db5e80a 100644 --- a/clang/lib/Sema/SemaTemplateInstantiate.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp @@ -3426,11 +3426,16 @@ Sema::InstantiateClass(SourceLocation PointOfInstantiation, return true; llvm::TimeTraceScope TimeScope("InstantiateClass", [&]() { - std::string Name; - llvm::raw_string_ostream OS(Name); + llvm::TimeTraceMetadata M; + llvm::raw_string_ostream OS(M.Detail); Instantiation->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - return Name; + if (llvm::isTimeTraceVerbose()) { + auto Loc = SourceMgr.getExpansionLoc(Instantiation->getLocation()); + M.File = SourceMgr.getFilename(Loc); + M.Line = SourceMgr.getExpansionLineNumber(Loc); + } + return M; }); Pattern = PatternDef; diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp index 97161febc15f7..a12d2eff1d2c8 100644 --- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp +++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -4966,11 +4966,16 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation, } llvm::TimeTraceScope TimeScope("InstantiateFunction", [&]() { - std::string Name; - llvm::raw_string_ostream OS(Name); + llvm::TimeTraceMetadata M; + llvm::raw_string_ostream OS(M.Detail); Function->getNameForDiagnostic(OS, getPrintingPolicy(), /*Qualified=*/true); - return Name; + if (llvm::isTimeTraceVerbose()) { + auto Loc = SourceMgr.getExpansionLoc(Function->getLocation()); + M.File = SourceMgr.getFilename(Loc); + M.Line = SourceMgr.getExpansionLineNumber(Loc); + } + return M; }); // If we're performing recursive template instantiation, create our own diff --git a/clang/test/Driver/ftime-trace-sections.cpp b/clang/test/Driver/ftime-trace-sections.cpp index 0c16052bc0c3a..da7109b9d81a6 100644 --- a/clang/test/Driver/ftime-trace-sections.cpp +++ b/clang/test/Driver/ftime-trace-sections.cpp @@ -1,5 +1,5 @@ // RUN: rm -rf %t && mkdir %t && cd %t -// RUN: %clangxx -S -ftime-trace -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: %python %S/ftime-trace-sections.py < out.json template <typename T> diff --git a/clang/test/Driver/ftime-trace.cpp b/clang/test/Driver/ftime-trace.cpp index 5fe63de915a71..60c5885704b58 100644 --- a/clang/test/Driver/ftime-trace.cpp +++ b/clang/test/Driver/ftime-trace.cpp @@ -1,18 +1,18 @@ // RUN: rm -rf %t && mkdir -p %t && cd %t -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat out.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=new-name.json -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=new-name.json -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat new-name.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s // RUN: mkdir dir1 dir2 -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir1 -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir1 -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat dir1/out.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s -// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir2/ -ftime-trace-granularity=0 -o out %s +// RUN: %clangxx -S -no-canonical-prefixes -ftime-trace=dir2/ -ftime-trace-granularity=0 -ftime-trace-verbose -o out %s // RUN: cat dir2/out.json \ // RUN: | %python -c 'import json, sys; json.dump(json.loads(sys.stdin.read()), sys.stdout, sort_keys=True, indent=2)' \ // RUN: | FileCheck %s @@ -34,32 +34,33 @@ // RUN: mkdir d e f && cp %s d/a.cpp && touch d/b.c /// TODO: Support -fno-integrated-as. -// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -fintegrated-as d/a.cpp -o e/a.o 2>&1 | FileCheck %s --check-prefix=COMPILE1 -// COMPILE1: -cc1{{.*}} "-ftime-trace=e/a.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose -fintegrated-as d/a.cpp -o e/a.o 2>&1 | FileCheck %s --check-prefix=COMPILE1 +// COMPILE1: -cc1{{.*}} "-ftime-trace=e/a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" -// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=COMPILE2 -// COMPILE2: -cc1{{.*}} "-ftime-trace=f/a.json" "-ftime-trace-granularity=0" -// COMPILE2: -cc1{{.*}} "-ftime-trace=f/b.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -c -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=COMPILE2 +// COMPILE2: -cc1{{.*}} "-ftime-trace=f/a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// COMPILE2: -cc1{{.*}} "-ftime-trace=f/b.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" /// -o specifies the link output. Create ${output}-${basename}.json. -// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -o e/x 2>&1 | FileCheck %s --check-prefix=LINK1 -// LINK1: -cc1{{.*}} "-ftime-trace=e/x-a.json" "-ftime-trace-granularity=0" -// LINK1: -cc1{{.*}} "-ftime-trace=e/x-b.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o e/x 2>&1 | FileCheck %s --check-prefix=LINK1 +// LINK1: -cc1{{.*}} "-ftime-trace=e/x-a.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// LINK1: -cc1{{.*}} "-ftime-trace=e/x-b.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" /// -dumpdir is f/g, not ending with a path separator. We create f/g${basename}.json. -// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 d/a.cpp d/b.c -o e/x -dumpdir f/g 2>&1 | FileCheck %s --check-prefix=LINK2 -// LINK2: -cc1{{.*}} "-ftime-trace=f/ga.json" "-ftime-trace-granularity=0" -// LINK2: -cc1{{.*}} "-ftime-trace=f/gb.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -ftime-trace -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o e/x -dumpdir f/g 2>&1 | FileCheck %s --check-prefix=LINK2 +// LINK2: -cc1{{.*}} "-ftime-trace=f/ga.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// LINK2: -cc1{{.*}} "-ftime-trace=f/gb.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" -// RUN: %clang -### -ftime-trace=e -ftime-trace-granularity=0 d/a.cpp d/b.c -o f/x -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=LINK3 -// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}a-{{[^.]*}}.json" "-ftime-trace-granularity=0" -// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}b-{{[^.]*}}.json" "-ftime-trace-granularity=0" +// RUN: %clang -### -ftime-trace=e -ftime-trace-granularity=0 -ftime-trace-verbose d/a.cpp d/b.c -o f/x -dumpdir f/ 2>&1 | FileCheck %s --check-prefix=LINK3 +// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}a-{{[^.]*}}.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" +// LINK3: -cc1{{.*}} "-ftime-trace=e{{/|\\\\}}b-{{[^.]*}}.json" "-ftime-trace-granularity=0" "-ftime-trace-verbose" -// RUN: %clang -### -ftime-trace -ftime-trace=e -ftime-trace-granularity=1 -xassembler d/a.cpp 2>&1 | \ +// RUN: %clang -### -ftime-trace -ftime-trace=e -ftime-trace-granularity=1 -ftime-trace-verbose -xassembler d/a.cpp 2>&1 | \ // RUN: FileCheck %s --check-prefix=UNUSED // UNUSED: warning: argument unused during compilation: '-ftime-trace' // UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace=e' // UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace-granularity=1' +// UNUSED-NEXT: warning: argument unused during compilation: '-ftime-trace-verbose' // UNUSED-NOT: warning: template <typename T> diff --git a/clang/tools/driver/cc1_main.cpp b/clang/tools/driver/cc1_main.cpp index c2ccb47a15bc8..f5e5fad36573e 100644 --- a/clang/tools/driver/cc1_main.cpp +++ b/clang/tools/driver/cc1_main.cpp @@ -241,7 +241,8 @@ int cc1_main(ArrayRef<const char *> Argv, const char *Argv0, void *MainAddr) { if (!Clang->getFrontendOpts().TimeTracePath.empty()) { llvm::timeTraceProfilerInitialize( - Clang->getFrontendOpts().TimeTraceGranularity, Argv0); + Clang->getFrontendOpts().TimeTraceGranularity, Argv0, + Clang->getFrontendOpts().TimeTraceVerbose); } // --print-supported-cpus takes priority over the actual compilation. if (Clang->getFrontendOpts().PrintSupportedCPUs) diff --git a/clang/unittests/Support/TimeProfilerTest.cpp b/clang/unittests/Support/TimeProfilerTest.cpp index 5f3950ff033f1..56d880cffde61 100644 --- a/clang/unittests/Support/TimeProfilerTest.cpp +++ b/clang/unittests/Support/TimeProfilerTest.cpp @@ -10,11 +10,15 @@ #include "clang/Frontend/FrontendActions.h" #include "clang/Lex/PreprocessorOptions.h" +#include "llvm/ADT/StringMap.h" #include "llvm/Support/JSON.h" +#include "llvm/Support/Path.h" #include "llvm/Support/TimeProfiler.h" +#include "llvm/Support/VirtualFileSystem.h" #include <stack> #include "gtest/gtest.h" +#include <tuple> using namespace clang; using namespace llvm; @@ -23,7 +27,8 @@ namespace { // Should be called before testing. void setupProfiler() { - timeTraceProfilerInitialize(/*TimeTraceGranularity=*/0, "test"); + timeTraceProfilerInitialize(/*TimeTraceGranularity=*/0, "test", + /*TimeTraceVerbose=*/true); } // Should be called after `compileFromString()`. @@ -38,14 +43,24 @@ std::string teardownProfiler() { // Returns true if code compiles successfully. // We only parse AST here. This is enough for constexpr evaluation. -bool compileFromString(StringRef Code, StringRef Standard, StringRef FileName) { +bool compileFromString(StringRef Code, StringRef Standard, StringRef File, + llvm::StringMap<std::string> Headers = {}) { CompilerInstance Compiler; Compiler.createDiagnostics(); + llvm::IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> FS( + new llvm::vfs::InMemoryFileSystem()); + FS->addFile(File, 0, MemoryBuffer::getMemBuffer(Code)); + for (const auto &Header : Headers) { + FS->addFile(Header.getKey(), 0, + MemoryBuffer::getMemBuffer(Header.getValue())); + } + llvm::IntrusiveRefCntPtr<FileManager> Files( + new FileManager(FileSystemOptions(), FS)); + Compiler.setFileManager(Files.get()); + auto Invocation = std::make_shared<CompilerInvocation>(); - Invocation->getPreprocessorOpts().addRemappedFile( - FileName, MemoryBuffer::getMemBuffer(Code).release()); - const char *Args[] = {Standard.data(), FileName.data()}; + std::vector<const char *> Args = {Standard.data(), File.data()}; CompilerInvocation::CreateFromArgs(*Invocation, Args, Compiler.getDiagnostics()); Compiler.setInvocation(std::move(Invocation)); @@ -60,13 +75,28 @@ bool compileFromString(StringRef Code, StringRef Standard, StringRef FileName) { return Compiler.ExecuteAction(Action); } +std::string GetMetadata(json::Object *Event) { + std::string Metadata; + llvm::raw_string_ostream OS(Metadata); + if (json::Object *Args = Event->getObject("args")) { + if (auto Detail = Args->getString("detail")) + OS << Detail; + // Use only filename to not include os-specific path separators. + if (auto File = Args->getString("file")) + OS << ", " << llvm::sys::path::filename(*File); + if (auto Line = Args->getInteger("line")) + OS << ":" << *Line; + } + return Metadata; +} + // Returns pretty-printed trace graph. std::string buildTraceGraph(StringRef Json) { struct EventRecord { int64_t TimestampBegin; int64_t TimestampEnd; - StringRef Name; - StringRef Detail; + std::string Name; + std::string Metadata; }; std::vector<EventRecord> Events; @@ -81,10 +111,13 @@ std::string buildTraceGraph(StringRef Json) { int64_t TimestampBegin = TraceEventObj->getInteger("ts").value_or(0); int64_t TimestampEnd = TimestampBegin + TraceEventObj->getInteger("dur").value_or(0); - StringRef Name = TraceEventObj->getString("name").value_or(""); - StringRef Detail = ""; - if (json::Object *Args = TraceEventObj->getObject("args")) - Detail = Args->getString("detail").value_or(""); + std::string Name = TraceEventObj->getString("name").value_or("").str(); + std::string Metadata = GetMetadata(TraceEventObj); + + // Source events are asynchronous events and may not perfectly nest the + // synchronous events. Skip testing them. + if (Name == "Source") + continue; // This is a "summary" event, like "Total PerformPendingInstantiations", // skip it @@ -92,7 +125,7 @@ std::string buildTraceGraph(StringRef Json) { continue; Events.emplace_back( - EventRecord{TimestampBegin, TimestampEnd, Name, Detail}); + EventRecord{TimestampBegin, TimestampEnd, Name, Metadata}); } // There can be nested events that are very fast, for example: @@ -132,9 +165,9 @@ std::string buildTraceGraph(StringRef Json) { Stream << "| "; } Stream.write(Event.Name.data(), Event.Name.size()); - if (!Event.Detail.empty()) { + if (!Event.Metadata.empty()) { Stream << " ("; - Stream.write(Event.Detail.data(), Event.Detail.size()); + Stream.write(Event.Metadata.data(), Event.Metadata.size()); Stream << ")"; } Stream << "\n"; @@ -145,7 +178,7 @@ std::string buildTraceGraph(StringRef Json) { } // namespace TEST(TimeProfilerTest, ConstantEvaluationCxx20) { - constexpr StringRef Code = R"( + std::string Code = R"( void print(double value); namespace slow_namespace { @@ -175,8 +208,7 @@ constexpr int slow_init_list[] = {1, 1, 2, 3, 5, 8, 13, 21}; // 25th line setupProfiler(); ASSERT_TRUE(compileFromString(Code, "-std=c++20", "test.cc")); std::string Json = teardownProfiler(); - std::string TraceGraph = buildTraceGraph(Json); - ASSERT_TRUE(TraceGraph == R"( + ASSERT_EQ(R"( Frontend | ParseDeclarationOrFunctionDefinition (test.cc:2:1) | ParseDeclarationOrFunctionDefinition (test.cc:6:1) @@ -202,14 +234,54 @@ Frontend | ParseDeclarationOrFunctionDefinition (test.cc:25:1) | | EvaluateAsInitializer (slow_init_list) | PerformPendingInstantiations -)"); +)", + buildTraceGraph(Json)); +} + +TEST(TimeProfilerTest, TemplateInstantiations) { + std::string B_H = R"( + template <typename T> + T fooB(T t) { + return T(); + } - // NOTE: If this test is failing, run this test with - // `llvm::errs() << TraceGraph;` and change the assert above. + #define MacroTemp(x) template <typename T> void foo##x(T) { T(); } + )"; + + std::string A_H = R"( + #include "b.h" + + MacroTemp(MTA) + + template <typename T> + void fooA(T t) { fooB(t); fooMTA(t); } + )"; + std::string Code = R"( + #include "a.h" + void user() { fooA(0); } + )"; + + setupProfiler(); + ASSERT_TRUE(compileFromString(Code, "-std=c++20", "test.cc", + /*Headers=*/{{"a.h", A_H}, {"b.h", B_H}})); + std::string Json = teardownProfiler(); + ASSERT_EQ(R"( +Frontend +| ParseFunctionDefinition (fooB) +| ParseFunctionDefinition (fooMTA) +| ParseFunctionDefinition (fooA) +| ParseDeclarationOrFunctionDefinition (test.cc:3:5) +| | ParseFunctionDefinition (user) +| PerformPendingInstantiations +| | InstantiateFunction (fooA<int>, a.h:7) +| | | InstantiateFunction (fooB<int>, b.h:3) +| | | InstantiateFunction (fooMTA<int>, a.h:4) +)", + buildTraceGraph(Json)); } TEST(TimeProfilerTest, ConstantEvaluationC99) { - constexpr StringRef Code = R"( + std::string Code = R"( struct { short quantval[4]; // 3rd line } value; @@ -218,15 +290,12 @@ struct { setupProfiler(); ASSERT_TRUE(compileFromString(Code, "-std=c99", "test.c")); std::string Json = teardownProfiler(); - std::string TraceGraph = buildTraceGraph(Json); - ASSERT_TRUE(TraceGraph == R"( + ASSERT_EQ(R"( Frontend | ParseDeclarationOrFunctionDefinition (test.c:2:1) | | isIntegerCons... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/99757 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits