Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -523,6 +523,8 @@ HelpText<"Build ASTs and then debug dump them">; def ast_dump_all : Flag<["-"], "ast-dump-all">, HelpText<"Build ASTs and then debug dump them, forcing deserialization">; +def templight_dump : Flag<["-"], "templight-dump">, + HelpText<"Dump templight information to stdout">; def ast_dump_lookups : Flag<["-"], "ast-dump-lookups">, HelpText<"Build ASTs and then debug dump their name lookup tables">; def ast_view : Flag<["-"], "ast-view">, Index: include/clang/Frontend/FrontendActions.h =================================================================== --- include/clang/Frontend/FrontendActions.h +++ include/clang/Frontend/FrontendActions.h @@ -162,6 +162,14 @@ bool hasCodeCompletionSupport() const override { return false; } }; +class TemplightDumpAction : public ASTFrontendAction { +protected: + std::unique_ptr CreateASTConsumer(CompilerInstance &CI, + StringRef InFile) override; + + void ExecuteAction() override; +}; + /** * \brief Frontend action adaptor that merges ASTs together. * Index: include/clang/Frontend/FrontendOptions.h =================================================================== --- include/clang/Frontend/FrontendOptions.h +++ include/clang/Frontend/FrontendOptions.h @@ -58,6 +58,7 @@ RewriteObjC, ///< ObjC->C Rewriter. RewriteTest, ///< Rewriter playground RunAnalysis, ///< Run one or more source code analyses. + TemplightDump, ///< Dump template instantiations MigrateSource, ///< Run migrator. RunPreprocessorOnly ///< Just lex, no output. }; Index: include/clang/FrontendTool/Utils.h =================================================================== --- include/clang/FrontendTool/Utils.h +++ include/clang/FrontendTool/Utils.h @@ -15,10 +15,19 @@ #ifndef LLVM_CLANG_FRONTENDTOOL_UTILS_H #define LLVM_CLANG_FRONTENDTOOL_UTILS_H +#include + namespace clang { class CompilerInstance; +class FrontendAction; +/// Construct the FrontendAction of a compiler invocation based on the +/// options specified for the compiler invocation. +/// +/// \return - The created FrontendAction object +std::unique_ptr CreateFrontendAction(CompilerInstance &CI); + /// ExecuteCompilerInvocation - Execute the given actions described by the /// compiler invocation object in the given compiler instance. /// Index: include/clang/Sema/Sema.h =================================================================== --- include/clang/Sema/Sema.h +++ include/clang/Sema/Sema.h @@ -172,6 +172,7 @@ class TemplateArgumentList; class TemplateArgumentLoc; class TemplateDecl; + class TemplateInstantiationCallback; class TemplateParameterList; class TemplatePartialOrderingContext; class TemplateTemplateParmDecl; @@ -7103,6 +7104,12 @@ /// We are defining a synthesized function (such as a defaulted special /// member). DefiningSynthesizedFunction, + + /// Added for Template instantiation observation + /// Memoization means we are _not_ instantiating a template because + /// it is already instantiated (but we entered a context where we + /// would have had to if it was not already instantiated). + Memoization } Kind; /// \brief Was the enclosing context a non-instantiation SFINAE context? @@ -7211,6 +7218,13 @@ // FIXME: Does this belong in Sema? It's tough to implement it anywhere else. unsigned LastEmittedCodeSynthesisContextDepth = 0; + /// \brief The template instantiation callbacks to trace or track + /// instantiations (objects can be chained). + /// + /// This callbacks is used to print, trace or track template + /// instantiations as they are being constructed. + std::vector> TemplateInstCallbacks; + /// \brief The current index into pack expansion arguments that will be /// used for substitution of parameter packs. /// Index: include/clang/Sema/TemplateInstCallback.h =================================================================== --- include/clang/Sema/TemplateInstCallback.h +++ include/clang/Sema/TemplateInstCallback.h @@ -0,0 +1,93 @@ +//===- TemplateInstCallback.h - Template Instantiation Callback - C++ --===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===---------------------------------------------------------------------===// +// +// This file defines the TemplateInstantiationCallback class, which is the +// base class for callbacks that will be notified at template instantiations. +// +//===---------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TEMPLATE_INST_CALLBACK_H +#define LLVM_CLANG_TEMPLATE_INST_CALLBACK_H + +#include "clang/Sema/Sema.h" + +namespace clang { + +/// \brief This is a base class for callbacks that will be notified at every +/// template instantiation. +class TemplateInstantiationCallback { +public: + virtual ~TemplateInstantiationCallback() {} + + /// \brief Called before doing AST-parsing. + virtual void initialize(const Sema &TheSema) = 0; + + /// \brief Called after AST-parsing is completed. + virtual void finalize(const Sema &TheSema) = 0; + + /// \brief Called when instantiation of a template just began. + virtual void atTemplateBegin(const Sema &TheSema, + const Sema::CodeSynthesisContext &Inst) = 0; + + /// \brief Called when instantiation of a template is just about to end. + virtual void atTemplateEnd(const Sema &TheSema, + const Sema::CodeSynthesisContext &Inst) = 0; +}; + +template +void initialize(TemplateInstantiationCallbackPtrs& Callbacks_, const Sema &TheSema) +{ + for (auto& C : Callbacks_) + { + if (C) + { + C->initialize(TheSema); + } + } +} + +template +void finalize(TemplateInstantiationCallbackPtrs& Callbacks_, const Sema &TheSema) +{ + for (auto& C : Callbacks_) + { + if (C) + { + C->finalize(TheSema); + } + } +} + +template +void atTemplateBegin(TemplateInstantiationCallbackPtrs& Callbacks_, const Sema &TheSema, const Sema::CodeSynthesisContext &Inst) +{ + for (auto& C : Callbacks_) + { + if (C) + { + C->atTemplateBegin(TheSema, Inst); + } + } +} + +template +void atTemplateEnd(TemplateInstantiationCallbackPtrs& Callbacks_, const Sema &TheSema, const Sema::CodeSynthesisContext &Inst) +{ + for (auto& C : Callbacks_) + { + if (C) + { + C->atTemplateEnd(TheSema, Inst); + } + } +} + +} + +#endif Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1277,6 +1277,8 @@ Opts.ProgramAction = frontend::PrintPreamble; break; case OPT_E: Opts.ProgramAction = frontend::PrintPreprocessedInput; break; + case OPT_templight_dump: + Opts.ProgramAction = frontend::TemplightDump; break; case OPT_rewrite_macros: Opts.ProgramAction = frontend::RewriteMacros; break; case OPT_rewrite_objc: @@ -2517,6 +2519,7 @@ case frontend::RewriteObjC: case frontend::RewriteTest: case frontend::RunAnalysis: + case frontend::TemplightDump: case frontend::MigrateSource: return false; Index: lib/Frontend/FrontendActions.cpp =================================================================== --- lib/Frontend/FrontendActions.cpp +++ lib/Frontend/FrontendActions.cpp @@ -18,6 +18,7 @@ #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" +#include "clang/Sema/TemplateInstCallback.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" #include "llvm/Support/FileSystem.h" @@ -24,11 +25,33 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/YAMLTraits.h" +#include #include #include using namespace clang; +namespace +{ + CodeCompleteConsumer* GetCodeCompletionConsumer(CompilerInstance& CI) + { + return CI.hasCodeCompletionConsumer() ? + &CI.getCodeCompletionConsumer() : nullptr; + } + + void EnsureSemaIsCreated(CompilerInstance& CI, FrontendAction& Action) + { + if (Action.hasCodeCompletionSupport() && + !CI.getFrontendOpts().CodeCompletionAt.FileName.empty()) + CI.createCodeCompletionConsumer(); + + if (!CI.hasSema()) + CI.createSema(Action.getTranslationUnitKind(), + GetCodeCompletionConsumer(CI)); + } +} + //===----------------------------------------------------------------------===// // Custom Actions //===----------------------------------------------------------------------===// @@ -256,6 +279,141 @@ } namespace { + struct TemplightEntry + { + std::string Name; + std::string Kind; + std::string Event; + std::string PointOfInstantiation; + }; +} + +namespace llvm { +namespace yaml { + template <> + struct MappingTraits { + static void mapping(IO &io, + TemplightEntry &fields) { + io.mapRequired("name", fields.Name); + io.mapRequired("kind", fields.Kind); + io.mapRequired("event", fields.Event); + io.mapRequired("poi", fields.PointOfInstantiation); + } + }; +} +} + +namespace { + class DefaultTemplateInstCallback : public TemplateInstantiationCallback { + using CodeSynthesisContext = Sema::CodeSynthesisContext; + public: + virtual void initialize(const Sema &) {} + + virtual void finalize(const Sema &) {} + + virtual void atTemplateBegin(const Sema &TheSema, + const CodeSynthesisContext &Inst) override + { + DisplayTemplightEntry(std::cout, TheSema, Inst); + } + + virtual void atTemplateEnd(const Sema &TheSema, + const CodeSynthesisContext &Inst) override + { + DisplayTemplightEntry(std::cout, TheSema, Inst); + } + private: + static std::string ToString( + CodeSynthesisContext::SynthesisKind Kind) { + switch (Kind) { + case CodeSynthesisContext::TemplateInstantiation: + return "TemplateInstantiation"; + case CodeSynthesisContext::DefaultTemplateArgumentInstantiation: + return "DefaultTemplateArgumentInstantiation"; + case CodeSynthesisContext::DefaultFunctionArgumentInstantiation: + return "DefaultFunctionArgumentInstantiation"; + case CodeSynthesisContext::ExplicitTemplateArgumentSubstitution: + return "ExplicitTemplateArgumentSubstitution"; + case CodeSynthesisContext::DeducedTemplateArgumentSubstitution: + return "DeducedTemplateArgumentSubstitution"; + case CodeSynthesisContext::PriorTemplateArgumentSubstitution: + return "PriorTemplateArgumentSubstitution"; + case CodeSynthesisContext::DefaultTemplateArgumentChecking: + return "DefaultTemplateArgumentChecking"; + case CodeSynthesisContext::ExceptionSpecInstantiation: + return "ExceptionSpecInstantiation"; + case CodeSynthesisContext::DeclaringSpecialMember: + return "DeclaringSpecialMember"; + case CodeSynthesisContext::DefiningSynthesizedFunction: + return "DefiningSynthesizedFunction"; + case CodeSynthesisContext::Memoization: + return "Memoization"; + } + return ""; + } + + template + static void DisplayTemplightEntry(std::ostream &Out, const Sema &TheSema, + const CodeSynthesisContext &Inst) + { + std::string YAML; + { + llvm::raw_string_ostream OS(YAML); + llvm::yaml::Output YO(OS); + TemplightEntry Entry = + GetTemplightEntry(TheSema, Inst); + llvm::yaml::EmptyContext Context; + llvm::yaml::yamlize(YO, Entry, true, Context); + } + Out << "---" << YAML << "\n"; + } + + template + static TemplightEntry GetTemplightEntry(const Sema &TheSema, + const CodeSynthesisContext &Inst) + { + TemplightEntry Entry; + Entry.Kind = ToString(Inst.Kind); + Entry.Event = BeginInstantiation ? "Begin" : "End"; + if (NamedDecl* NamedTemplate = dyn_cast_or_null(Inst.Entity)) + { + llvm::raw_string_ostream OS(Entry.Name); + NamedTemplate->getNameForDiagnostic(OS, TheSema.getLangOpts(), true); + } + const PresumedLoc Loc = + TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation); + if (!Loc.isInvalid()) + { + Entry.PointOfInstantiation = + std::string(Loc.getFilename()) + + ":" + std::to_string(Loc.getLine()) + + ":" + std::to_string(Loc.getColumn()); + } + return Entry; + } + }; +} + +std::unique_ptr +TemplightDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) { + return llvm::make_unique(); +} + +void TemplightDumpAction::ExecuteAction() { + CompilerInstance &CI = getCompilerInstance(); + + // This part is normally done by ASTFrontEndAction, but needs to happen + // before Templight observers can be created + // FIXME: Move the truncation aspect of this into Sema, we delayed this till + // here so the source manager would be initialized. + EnsureSemaIsCreated(CI, *this); + + CI.getSema().TemplateInstCallbacks.push_back( + llvm::make_unique()); + ASTFrontendAction::ExecuteAction(); +} + +namespace { /// \brief AST reader listener that dumps module information for a module /// file. class DumpModuleInfoListener : public ASTReaderListener { Index: lib/FrontendTool/ExecuteCompilerInvocation.cpp =================================================================== --- lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -32,6 +32,8 @@ using namespace clang; using namespace llvm::opt; +namespace clang { + static std::unique_ptr CreateFrontendBaseAction(CompilerInstance &CI) { using namespace clang::frontend; @@ -63,6 +65,7 @@ case ParseSyntaxOnly: return llvm::make_unique(); case ModuleFileInfo: return llvm::make_unique(); case VerifyPCH: return llvm::make_unique(); + case TemplightDump: return llvm::make_unique(); case PluginAction: { for (FrontendPluginRegistry::iterator it = @@ -122,7 +125,7 @@ #endif } -static std::unique_ptr +std::unique_ptr CreateFrontendAction(CompilerInstance &CI) { // Create the underlying action. std::unique_ptr Act = CreateFrontendBaseAction(CI); @@ -173,7 +176,7 @@ return Act; } -bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) { +bool ExecuteCompilerInvocation(CompilerInstance *Clang) { // Honor -help. if (Clang->getFrontendOpts().ShowHelp) { std::unique_ptr Opts = driver::createDriverOptTable(); @@ -254,3 +257,5 @@ BuryPointer(std::move(Act)); return Success; } + +} Index: lib/Parse/ParseAST.cpp =================================================================== --- lib/Parse/ParseAST.cpp +++ lib/Parse/ParseAST.cpp @@ -21,6 +21,7 @@ #include "clang/Sema/CodeCompleteConsumer.h" #include "clang/Sema/Sema.h" #include "clang/Sema/SemaConsumer.h" +#include "clang/Sema/TemplateInstCallback.h" #include "llvm/Support/CrashRecoveryContext.h" #include #include @@ -121,6 +122,10 @@ bool OldCollectStats = PrintStats; std::swap(OldCollectStats, S.CollectStats); + // Initialize the template instantiation observer chain. + // FIXME: See note on "finalize" below. + initialize(S.TemplateInstCallbacks, S); + ASTConsumer *Consumer = &S.getASTConsumer(); std::unique_ptr ParseOP( @@ -158,6 +163,13 @@ Consumer->HandleTranslationUnit(S.getASTContext()); + // Finalize the template instantiation observer chain. + // FIXME: This (and init.) should be done in the Sema class, but because + // Sema does not have a reliable "Finalize" function (it has a + // destructor, but it is not guaranteed to be called ("-disable-free")). + // So, do the initialization above and do the finalization here: + finalize(S.TemplateInstCallbacks, S); + std::swap(OldCollectStats, S.CollectStats); if (PrintStats) { llvm::errs() << "\nSTATISTICS:\n"; Index: lib/Sema/Sema.cpp =================================================================== --- lib/Sema/Sema.cpp +++ lib/Sema/Sema.cpp @@ -37,6 +37,7 @@ #include "clang/Sema/SemaConsumer.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/TemplateDeduction.h" +#include "clang/Sema/TemplateInstCallback.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SmallSet.h" using namespace clang; Index: lib/Sema/SemaTemplateInstantiate.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiate.cpp +++ lib/Sema/SemaTemplateInstantiate.cpp @@ -25,6 +25,7 @@ #include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Template.h" #include "clang/Sema/TemplateDeduction.h" +#include "clang/Sema/TemplateInstCallback.h" using namespace clang; using namespace sema; @@ -199,6 +200,9 @@ case DeclaringSpecialMember: case DefiningSynthesizedFunction: return false; + + case Memoization: + break; } llvm_unreachable("Invalid SynthesisKind!"); @@ -235,6 +239,7 @@ !SemaRef.InstantiatingSpecializations .insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind)) .second; + atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, Inst); } } @@ -394,8 +399,10 @@ std::make_pair(Active.Entity, Active.Kind)); } + atTemplateEnd(SemaRef.TemplateInstCallbacks, + SemaRef, SemaRef.CodeSynthesisContexts.back()); + SemaRef.popCodeSynthesisContext(); - Invalid = true; } } @@ -626,7 +633,7 @@ << cast(Active->Entity) << Active->SpecialMember; break; - case CodeSynthesisContext::DefiningSynthesizedFunction: + case CodeSynthesisContext::DefiningSynthesizedFunction: { // FIXME: For synthesized members other than special members, produce a note. auto *MD = dyn_cast(Active->Entity); auto CSM = MD ? getSpecialMember(MD) : CXXInvalid; @@ -635,6 +642,9 @@ diag::note_member_synthesized_at) << CSM << Context.getTagDeclType(MD->getParent()); } + } + + case CodeSynthesisContext::Memoization: break; } } @@ -682,6 +692,9 @@ // This happens in a context unrelated to template instantiation, so // there is no SFINAE. return None; + + case CodeSynthesisContext::Memoization: + break; } // The inner context was transparent for SFINAE. If it occurred within a Index: lib/Sema/SemaTemplateInstantiateDecl.cpp =================================================================== --- lib/Sema/SemaTemplateInstantiateDecl.cpp +++ lib/Sema/SemaTemplateInstantiateDecl.cpp @@ -23,6 +23,7 @@ #include "clang/Sema/Lookup.h" #include "clang/Sema/PrettyDeclStackTrace.h" #include "clang/Sema/Template.h" +#include "clang/Sema/TemplateInstCallback.h" using namespace clang; @@ -3653,8 +3654,10 @@ assert(FunTmpl->getTemplatedDecl() == Tmpl && "Deduction from the wrong function template?"); (void) FunTmpl; + atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst); ActiveInst.Kind = ActiveInstType::TemplateInstantiation; ActiveInst.Entity = New; + atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst); } } Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -31,6 +31,7 @@ #include "clang/Sema/ScopeInfo.h" #include "clang/Sema/SemaInternal.h" #include "clang/Sema/Template.h" +#include "clang/Sema/TemplateInstCallback.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" @@ -7524,6 +7525,14 @@ diagnoseMissingImport(Loc, SuggestedDef, MissingImportKind::Definition, /*Recover*/TreatAsComplete); return !TreatAsComplete; + } else if (Def && !TemplateInstCallbacks.empty()) { + CodeSynthesisContext TempInst; + TempInst.Kind = CodeSynthesisContext::Memoization; + TempInst.Template = Def; + TempInst.Entity = Def; + TempInst.PointOfInstantiation = Loc; + atTemplateBegin(TemplateInstCallbacks, *this, TempInst); + atTemplateEnd(TemplateInstCallbacks, *this, TempInst); } return false; Index: test/Sema/templight-deduced-func.cpp =================================================================== --- test/Sema/templight-deduced-func.cpp +++ test/Sema/templight-deduced-func.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s + +template +int foo(T){return 0;} + +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+foo$}} +// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:}}[[@LINE+28]]{{:12'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+foo$}} +// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:}}[[@LINE+23]]{{:12'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:}}[[@LINE+17]]{{:12'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:}}[[@LINE+12]]{{:12'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:}}[[@LINE+6]]{{:12'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:}}[[@LINE+1]]{{:12'$}} +int gvar = foo(0); Index: test/Sema/templight-default-arg-inst.cpp =================================================================== --- test/Sema/templight-default-arg-inst.cpp +++ test/Sema/templight-default-arg-inst.cpp @@ -0,0 +1,70 @@ +// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s +template +class A {}; + +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A::U'$}} +// CHECK: {{^kind:[ ]+DefaultTemplateArgumentInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+61]]{{:1'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A::U'$}} +// CHECK: {{^kind:[ ]+DefaultTemplateArgumentInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+56]]{{:1'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A::U'$}} +// CHECK: {{^kind:[ ]+DefaultTemplateArgumentChecking$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+50]]{{:6'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A::U'$}} +// CHECK: {{^kind:[ ]+DefaultTemplateArgumentChecking$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+45]]{{:6'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+39]]{{:8'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+34]]{{:8'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+28]]{{:8'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+23]]{{:8'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+17]]{{:8'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+12]]{{:8'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+6]]{{:8'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:}}[[@LINE+1]]{{:8'$}} +A a; Index: test/Sema/templight-default-func-arg.cpp =================================================================== --- test/Sema/templight-default-func-arg.cpp +++ test/Sema/templight-default-func-arg.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -std=c++14 -templight-dump %s 2>&1 | FileCheck %s +template +void foo(T b = 0) {}; + +int main() +{ + +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+foo$}} +// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:}}[[@LINE+50]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+foo$}} +// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:}}[[@LINE+45]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+foo$}} +// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:}}[[@LINE+39]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+foo$}} +// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:}}[[@LINE+34]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:}}[[@LINE+28]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:}}[[@LINE+23]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+b$}} +// CHECK: {{^kind:[ ]+DefaultFunctionArgumentInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:}}[[@LINE+17]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+b$}} +// CHECK: {{^kind:[ ]+DefaultFunctionArgumentInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:}}[[@LINE+12]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:}}[[@LINE+6]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:}}[[@LINE+1]]{{:3'$}} + foo(); +} Index: test/Sema/templight-default-template-arg.cpp =================================================================== --- test/Sema/templight-default-template-arg.cpp +++ test/Sema/templight-default-template-arg.cpp @@ -0,0 +1,59 @@ +// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s +template +class A {}; + +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A::T'$}} +// CHECK: {{^kind:[ ]+DefaultTemplateArgumentChecking$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:}}[[@LINE+50]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A::T'$}} +// CHECK: {{^kind:[ ]+DefaultTemplateArgumentChecking$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:}}[[@LINE+45]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:}}[[@LINE+39]]{{:5'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:}}[[@LINE+34]]{{:5'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:}}[[@LINE+28]]{{:5'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:}}[[@LINE+23]]{{:5'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:}}[[@LINE+17]]{{:5'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:}}[[@LINE+12]]{{:5'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:}}[[@LINE+6]]{{:5'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'A'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:}}[[@LINE+1]]{{:5'$}} +A<> a; Index: test/Sema/templight-exception-spec-func.cpp =================================================================== --- test/Sema/templight-exception-spec-func.cpp +++ test/Sema/templight-exception-spec-func.cpp @@ -0,0 +1,63 @@ +// RUN: %clang_cc1 -templight-dump -std=c++14 %s 2>&1 | FileCheck %s +template +void f() noexcept(B) {} + +int main() +{ + +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+f$}} +// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:}}[[@LINE+50]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+f$}} +// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:}}[[@LINE+45]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+f$}} +// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:}}[[@LINE+39]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+f$}} +// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:}}[[@LINE+34]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'f'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:}}[[@LINE+28]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'f'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:}}[[@LINE+23]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'f'$}} +// CHECK: {{^kind:[ ]+ExceptionSpecInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:}}[[@LINE+17]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'f'$}} +// CHECK: {{^kind:[ ]+ExceptionSpecInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:}}[[@LINE+12]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'f'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:}}[[@LINE+6]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'f'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:}}[[@LINE+1]]{{:3'$}} + f(); +} Index: test/Sema/templight-explicit-template-arg.cpp =================================================================== --- test/Sema/templight-explicit-template-arg.cpp +++ test/Sema/templight-explicit-template-arg.cpp @@ -0,0 +1,51 @@ +// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s +template +void f(){} + +int main() +{ +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+f$}} +// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:}}[[@LINE+39]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+f$}} +// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:}}[[@LINE+34]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+f$}} +// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:}}[[@LINE+28]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+f$}} +// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:}}[[@LINE+23]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'f'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:}}[[@LINE+17]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'f'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:}}[[@LINE+12]]{{:3'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'f'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:}}[[@LINE+6]]{{:3'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'f'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:}}[[@LINE+1]]{{:3'$}} + f(); +} Index: test/Sema/templight-memoization.cpp =================================================================== --- test/Sema/templight-memoization.cpp +++ test/Sema/templight-memoization.cpp @@ -0,0 +1,38 @@ +// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s + +template +struct foo {}; + +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-memoization.cpp:}}[[@LINE+6]]{{:10'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-memoization.cpp:}}[[@LINE+1]]{{:10'$}} +foo x; + +// CHECK-LABEL: {{^---$}} +// CHECK-LABEL: {{^---$}} +// CHECK-LABEL: {{^---$}} +// CHECK-LABEL: {{^---$}} +// CHECK-LABEL: {{^---$}} +// CHECK-LABEL: {{^---$}} +// CHECK-LABEL: {{^---$}} +// CHECK-LABEL: {{^---$}} +// CHECK-LABEL: {{^---$}} + +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-memoization.cpp:}}[[@LINE+6]]{{:10'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-memoization.cpp:}}[[@LINE+1]]{{:10'$}} +foo y; + Index: test/Sema/templight-nested-memoization.cpp =================================================================== --- test/Sema/templight-nested-memoization.cpp +++ test/Sema/templight-nested-memoization.cpp @@ -0,0 +1,150 @@ +// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s + +template +struct fib +{ + static const int value = fib::value + fib::value; +}; + +template <> +struct fib<0> +{ + static const int value = 1; +}; + +template <> +struct fib<1> +{ + static const int value = 1; +}; + +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<4>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:}}[[@LINE+124]]{{:8'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<4>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:}}[[@LINE+119]]{{:8'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<4>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:}}[[@LINE+114]]{{:8'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<3>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<3>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<3>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<2>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<2>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<2>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} + +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<1>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<1>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<0>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<0>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<2>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<2>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<2>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<1>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<1>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<3>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<3>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<3>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<2>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'fib<2>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}} +// CHECK-LABEL: {{^---$}} +// +// CHECK: {{^name:[ ]+'fib<4>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:}}[[@LINE+1]]{{:8'$}} +fib<4> x; + Index: test/Sema/templight-nested-template-instantiation.cpp =================================================================== --- test/Sema/templight-nested-template-instantiation.cpp +++ test/Sema/templight-nested-template-instantiation.cpp @@ -0,0 +1,72 @@ +// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s + +template +struct foo : foo {}; + +template <> +struct foo<0> {}; + +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<2>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:}}[[@LINE+59]]{{:8'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<2>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:}}[[@LINE+54]]{{:8'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<2>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:}}[[@LINE+49]]{{:8'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<1>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<1>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<1>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<0>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<0>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}} +// +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<1>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<1>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<1>'$}} +// CHECK: {{^kind:[ ]+Memoization$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo<2>'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:}}[[@LINE+1]]{{:8'$}} +foo<2> x; Index: test/Sema/templight-one-instantiation.cpp =================================================================== --- test/Sema/templight-one-instantiation.cpp +++ test/Sema/templight-one-instantiation.cpp @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s + +template +struct foo {}; + +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+Begin$}} +// CHECK: {{^poi:[ ]+'.*templight-one-instantiation.cpp:}}[[@LINE+6]]{{:10'$}} +// CHECK-LABEL: {{^---$}} +// CHECK: {{^name:[ ]+'foo'$}} +// CHECK: {{^kind:[ ]+TemplateInstantiation$}} +// CHECK: {{^event:[ ]+End$}} +// CHECK: {{^poi:[ ]+'.*templight-one-instantiation.cpp:}}[[@LINE+1]]{{:10'$}} +foo x; Index: test/Sema/templight-prior-template-arg.cpp =================================================================== --- test/Sema/templight-prior-template-arg.cpp +++ test/Sema/templight-prior-template-arg.cpp @@ -0,0 +1,62 @@ +// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s +template +class A {}; + +template