Index: include/clang/Driver/CC1Options.td =================================================================== --- include/clang/Driver/CC1Options.td +++ include/clang/Driver/CC1Options.td @@ -517,6 +517,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,9 +15,14 @@ #ifndef LLVM_CLANG_FRONTENDTOOL_UTILS_H #define LLVM_CLANG_FRONTENDTOOL_UTILS_H +#include + namespace clang { class CompilerInstance; +class FrontendAction; + +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 TemplateInstantiationCallbacks; class TemplateParameterList; class TemplatePartialOrderingContext; class TemplateTemplateParmDecl; @@ -7065,6 +7066,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? @@ -7173,6 +7180,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::unique_ptr TemplateInstCallbacksChain; + /// \brief The current index into pack expansion arguments that will be /// used for substitution of parameter packs. /// Index: include/clang/Sema/TemplateInstCallbacks.h =================================================================== --- /dev/null +++ include/clang/Sema/TemplateInstCallbacks.h @@ -0,0 +1,94 @@ +//===- TemplateInstCallbacks.h - Template Instantiation Callbacks - 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 TemplateInstantiationCallbacks class, which is the +// base class for callbacks that will be notified at template instantiations. +// +//===---------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_TEMPLATE_INST_CALLBACKS_H +#define LLVM_CLANG_TEMPLATE_INST_CALLBACKS_H + +#include "clang/Basic/SourceLocation.h" +#include "clang/Sema/Sema.h" + +#include "llvm/Support/Compiler.h" +#include + +namespace clang { + +/// \brief This is a base class for callbacks that will be notified at every +/// template instantiation. +class TemplateInstantiationCallbacks { +public: + + /// \brief Called before doing AST-parsing. + void initialize(const Sema &TheSema) { + this->initializeImpl(TheSema); + if (NextCallbacks) + NextCallbacks->initialize(TheSema); + }; + + /// \brief Called after AST-parsing is completed. + void finalize(const Sema &TheSema) { + this->finalizeImpl(TheSema); + if (NextCallbacks) + NextCallbacks->finalize(TheSema); + }; + + /// \brief Called when instantiation of a template just began. + void atTemplateBegin(const Sema &TheSema, + const Sema::CodeSynthesisContext &Inst) { + this->atTemplateBeginImpl(TheSema, Inst); + if (NextCallbacks) + NextCallbacks->atTemplateBegin(TheSema, Inst); + }; + + /// \brief Called when instantiation of a template is just about to end. + void atTemplateEnd(const Sema &TheSema, + const Sema::CodeSynthesisContext &Inst) { + this->atTemplateEndImpl(TheSema, Inst); + if (NextCallbacks) + NextCallbacks->atTemplateEnd(TheSema, Inst); + }; + + virtual ~TemplateInstantiationCallbacks() { }; + + /// \brief Appends a new observer to the end of this list. + /// \note This function uses a tail-call recursion. + static void appendNewCallbacks( + std::unique_ptr &CurrentChain, + TemplateInstantiationCallbacks *NewCallbacks) { + if (!CurrentChain) { + CurrentChain.reset(NewCallbacks); + return; + }; + appendNewCallbacks(CurrentChain->NextCallbacks, NewCallbacks); + }; + +protected: + + /// \brief Called before doing AST-parsing. + virtual void initializeImpl(const Sema &TheSema) { }; + /// \brief Called after AST-parsing is completed. + virtual void finalizeImpl(const Sema &TheSema) { }; + + /// \brief Called when instantiation of a template just began. + virtual void atTemplateBeginImpl(const Sema &TheSema, + const Sema::CodeSynthesisContext &Inst) {}; + /// \brief Called when instantiation of a template is just about to end. + virtual void atTemplateEndImpl(const Sema &TheSema, + const Sema::CodeSynthesisContext &Inst) {}; + + std::unique_ptr NextCallbacks; +}; + +} + +#endif Index: lib/Frontend/CompilerInvocation.cpp =================================================================== --- lib/Frontend/CompilerInvocation.cpp +++ lib/Frontend/CompilerInvocation.cpp @@ -1273,6 +1273,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: @@ -2498,6 +2500,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,12 +18,15 @@ #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" +#include "clang/Sema/TemplateInstCallbacks.h" #include "clang/Serialization/ASTReader.h" #include "clang/Serialization/ASTWriter.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" +#include "llvm/Support/YAMLTraits.h" +#include #include #include @@ -256,6 +259,149 @@ } 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 DefaultTemplateInstCallbacks : public TemplateInstantiationCallbacks { + using CodeSynthesisContext = Sema::CodeSynthesisContext; + protected: + virtual void atTemplateBeginImpl(const Sema &TheSema, + const CodeSynthesisContext &Inst) override + { + DisplayTemplightEntry(std::cout, TheSema, Inst); + } + + virtual void atTemplateEndImpl(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. + if (hasCodeCompletionSupport() && + !CI.getFrontendOpts().CodeCompletionAt.FileName.empty()) + CI.createCodeCompletionConsumer(); + + // Use a code completion consumer? + CodeCompleteConsumer *CompletionConsumer = nullptr; + if (CI.hasCodeCompletionConsumer()) + CompletionConsumer = &CI.getCodeCompletionConsumer(); + + if (!CI.hasSema()) + CI.createSema(getTranslationUnitKind(), CompletionConsumer); + //<<-------------------------------------------------------------- + + TemplateInstantiationCallbacks::appendNewCallbacks( + CI.getSema().TemplateInstCallbacksChain, + new DefaultTemplateInstCallbacks()); + 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/TemplateInstCallbacks.h" #include "llvm/Support/CrashRecoveryContext.h" #include #include @@ -121,6 +122,11 @@ bool OldCollectStats = PrintStats; std::swap(OldCollectStats, S.CollectStats); + // Initialize the template instantiation observer chain. + // FIXME: See note on "finalize" below. + if (S.TemplateInstCallbacksChain) + S.TemplateInstCallbacksChain->initialize(S); + ASTConsumer *Consumer = &S.getASTConsumer(); std::unique_ptr ParseOP( @@ -158,6 +164,14 @@ 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: + if (S.TemplateInstCallbacksChain) + S.TemplateInstCallbacksChain->finalize(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/TemplateInstCallbacks.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/TemplateInstCallbacks.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,8 @@ !SemaRef.InstantiatingSpecializations .insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind)) .second; + if (SemaRef.TemplateInstCallbacksChain) + SemaRef.TemplateInstCallbacksChain->atTemplateBegin(SemaRef, Inst); } } @@ -394,8 +400,11 @@ std::make_pair(Active.Entity, Active.Kind)); } - SemaRef.popCodeSynthesisContext(); + if (SemaRef.TemplateInstCallbacksChain) + SemaRef.TemplateInstCallbacksChain->atTemplateEnd( + SemaRef, SemaRef.CodeSynthesisContexts.back()); + SemaRef.popCodeSynthesisContext(); Invalid = true; } } @@ -626,7 +635,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 +644,9 @@ diag::note_member_synthesized_at) << CSM << Context.getTagDeclType(MD->getParent()); } + } + + case CodeSynthesisContext::Memoization: break; } } @@ -682,6 +694,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/TemplateInstCallbacks.h" using namespace clang; @@ -3649,8 +3650,12 @@ assert(FunTmpl->getTemplatedDecl() == Tmpl && "Deduction from the wrong function template?"); (void) FunTmpl; + if (SemaRef.TemplateInstCallbacksChain) + SemaRef.TemplateInstCallbacksChain->atTemplateEnd(SemaRef, ActiveInst); ActiveInst.Kind = ActiveInstType::TemplateInstantiation; ActiveInst.Entity = New; + if (SemaRef.TemplateInstCallbacksChain) + SemaRef.TemplateInstCallbacksChain->atTemplateBegin(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/TemplateInstCallbacks.h" #include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringSwitch.h" @@ -7275,6 +7276,14 @@ diagnoseMissingImport(Loc, SuggestedDef, MissingImportKind::Definition, /*Recover*/TreatAsComplete); return !TreatAsComplete; + } else if (Def && TemplateInstCallbacksChain) { + CodeSynthesisContext TempInst; + TempInst.Kind = CodeSynthesisContext::Memoization; + TempInst.Template = Def; + TempInst.Entity = Def; + TempInst.PointOfInstantiation = Loc; + TemplateInstCallbacksChain->atTemplateBegin(*this, TempInst); + TemplateInstCallbacksChain->atTemplateEnd(*this, TempInst); } return false; Index: test/Sema/templight-deduced-func.cpp =================================================================== --- /dev/null +++ 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 =================================================================== --- /dev/null +++ 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 =================================================================== --- /dev/null +++ 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 =================================================================== --- /dev/null +++ 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 =================================================================== --- /dev/null +++ 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 =================================================================== --- /dev/null +++ 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 =================================================================== --- /dev/null +++ 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 =================================================================== --- /dev/null +++ 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 =================================================================== --- /dev/null +++ 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 =================================================================== --- /dev/null +++ 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 =================================================================== --- /dev/null +++ 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