r324808 - [Templight] Template Instantiation Observer

Gabor Horvath via cfe-commits cfe-commits at lists.llvm.org
Sat Feb 10 06:04:46 PST 2018


Author: xazax
Date: Sat Feb 10 06:04:45 2018
New Revision: 324808

URL: http://llvm.org/viewvc/llvm-project?rev=324808&view=rev
Log:
[Templight] Template Instantiation Observer

This patch adds a base-class called TemplateInstantiationObserver which gets
notified whenever a template instantiation is entered or exited during
semantic analysis. This is a base class used to implement the template
profiling and debugging tool called
Templight (https://github.com/mikael-s-persson/templight).

The patch also makes a few more changes:

* ActiveTemplateInstantiation class is moved out of the Sema class (so it can be used with inclusion of Sema.h).
* CreateFrontendAction function in front-end utilities is given external linkage (not longer a hidden static function).
* TemplateInstObserverChain data member added to Sema class to hold the list of template-inst observers.
* Notifications to the template-inst observer are added at the key places where templates are instantiated.

Patch by: Abel Sinkovics!

Differential Revision: https://reviews.llvm.org/D5767

Added:
    cfe/trunk/include/clang/Sema/TemplateInstCallback.h
    cfe/trunk/test/Templight/
    cfe/trunk/test/Templight/templight-deduced-func.cpp
    cfe/trunk/test/Templight/templight-default-arg-inst.cpp
    cfe/trunk/test/Templight/templight-default-func-arg.cpp
    cfe/trunk/test/Templight/templight-default-template-arg.cpp
    cfe/trunk/test/Templight/templight-exception-spec-func.cpp
    cfe/trunk/test/Templight/templight-explicit-template-arg.cpp
    cfe/trunk/test/Templight/templight-memoization.cpp
    cfe/trunk/test/Templight/templight-nested-memoization.cpp
    cfe/trunk/test/Templight/templight-nested-template-instantiation.cpp
    cfe/trunk/test/Templight/templight-one-instantiation.cpp
    cfe/trunk/test/Templight/templight-prior-template-arg.cpp
Modified:
    cfe/trunk/include/clang/Driver/CC1Options.td
    cfe/trunk/include/clang/Frontend/FrontendActions.h
    cfe/trunk/include/clang/Frontend/FrontendOptions.h
    cfe/trunk/include/clang/FrontendTool/Utils.h
    cfe/trunk/include/clang/Sema/Sema.h
    cfe/trunk/lib/Frontend/CompilerInvocation.cpp
    cfe/trunk/lib/Frontend/FrontendActions.cpp
    cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
    cfe/trunk/lib/Parse/ParseAST.cpp
    cfe/trunk/lib/Sema/Sema.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/SemaType.cpp

Modified: cfe/trunk/include/clang/Driver/CC1Options.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/CC1Options.td?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Driver/CC1Options.td (original)
+++ cfe/trunk/include/clang/Driver/CC1Options.td Sat Feb 10 06:04:45 2018
@@ -533,6 +533,8 @@ def ast_dump : Flag<["-"], "ast-dump">,
   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">,

Modified: cfe/trunk/include/clang/Frontend/FrontendActions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendActions.h?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendActions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendActions.h Sat Feb 10 06:04:45 2018
@@ -167,6 +167,14 @@ public:
   bool hasCodeCompletionSupport() const override { return false; }
 };
 
+class TemplightDumpAction : public ASTFrontendAction {
+protected:
+  std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
+                                                 StringRef InFile) override;
+
+  void ExecuteAction() override;
+};
+
 /**
  * \brief Frontend action adaptor that merges ASTs together.
  *

Modified: cfe/trunk/include/clang/Frontend/FrontendOptions.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Frontend/FrontendOptions.h?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Frontend/FrontendOptions.h (original)
+++ cfe/trunk/include/clang/Frontend/FrontendOptions.h Sat Feb 10 06:04:45 2018
@@ -58,6 +58,7 @@ namespace frontend {
     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.
   };

Modified: cfe/trunk/include/clang/FrontendTool/Utils.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/FrontendTool/Utils.h?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/include/clang/FrontendTool/Utils.h (original)
+++ cfe/trunk/include/clang/FrontendTool/Utils.h Sat Feb 10 06:04:45 2018
@@ -15,9 +15,18 @@
 #ifndef LLVM_CLANG_FRONTENDTOOL_UTILS_H
 #define LLVM_CLANG_FRONTENDTOOL_UTILS_H
 
+#include <memory>
+
 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<FrontendAction> CreateFrontendAction(CompilerInstance &CI);
 
 /// ExecuteCompilerInvocation - Execute the given actions described by the
 /// compiler invocation object in the given compiler instance.

Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Sat Feb 10 06:04:45 2018
@@ -172,6 +172,7 @@ namespace clang {
   class TemplateArgumentList;
   class TemplateArgumentLoc;
   class TemplateDecl;
+  class TemplateInstantiationCallback;
   class TemplateParameterList;
   class TemplatePartialOrderingContext;
   class TemplateTemplateParmDecl;
@@ -7127,6 +7128,12 @@ public:
       /// 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?
@@ -7235,6 +7242,14 @@ public:
   // 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<std::unique_ptr<TemplateInstantiationCallback>>
+      TemplateInstCallbacks;
+
   /// \brief The current index into pack expansion arguments that will be
   /// used for substitution of parameter packs.
   ///

Added: cfe/trunk/include/clang/Sema/TemplateInstCallback.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/TemplateInstCallback.h?rev=324808&view=auto
==============================================================================
--- cfe/trunk/include/clang/Sema/TemplateInstCallback.h (added)
+++ cfe/trunk/include/clang/Sema/TemplateInstCallback.h Sat Feb 10 06:04:45 2018
@@ -0,0 +1,83 @@
+//===- 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() = default;
+
+  /// \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 <class TemplateInstantiationCallbackPtrs>
+void initialize(TemplateInstantiationCallbackPtrs &Callbacks,
+                const Sema &TheSema) {
+  for (auto &C : Callbacks) {
+    if (C)
+      C->initialize(TheSema);
+  }
+}
+
+template <class TemplateInstantiationCallbackPtrs>
+void finalize(TemplateInstantiationCallbackPtrs &Callbacks,
+              const Sema &TheSema) {
+  for (auto &C : Callbacks) {
+    if (C)
+      C->finalize(TheSema);
+  }
+}
+
+template <class TemplateInstantiationCallbackPtrs>
+void atTemplateBegin(TemplateInstantiationCallbackPtrs &Callbacks,
+                     const Sema &TheSema,
+                     const Sema::CodeSynthesisContext &Inst) {
+  for (auto &C : Callbacks) {
+    if (C)
+      C->atTemplateBegin(TheSema, Inst);
+  }
+}
+
+template <class TemplateInstantiationCallbackPtrs>
+void atTemplateEnd(TemplateInstantiationCallbackPtrs &Callbacks,
+                   const Sema &TheSema,
+                   const Sema::CodeSynthesisContext &Inst) {
+  for (auto &C : Callbacks) {
+    if (C)
+      C->atTemplateEnd(TheSema, Inst);
+  }
+}
+
+} // namespace clang
+
+#endif

Modified: cfe/trunk/lib/Frontend/CompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/CompilerInvocation.cpp?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/CompilerInvocation.cpp (original)
+++ cfe/trunk/lib/Frontend/CompilerInvocation.cpp Sat Feb 10 06:04:45 2018
@@ -1358,6 +1358,8 @@ static InputKind ParseFrontendArgs(Front
       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:
@@ -2620,6 +2622,7 @@ static bool isStrictlyPreprocessorAction
   case frontend::RewriteObjC:
   case frontend::RewriteTest:
   case frontend::RunAnalysis:
+  case frontend::TemplightDump:
   case frontend::MigrateSource:
     return false;
 

Modified: cfe/trunk/lib/Frontend/FrontendActions.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/FrontendActions.cpp?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/FrontendActions.cpp (original)
+++ cfe/trunk/lib/Frontend/FrontendActions.cpp Sat Feb 10 06:04:45 2018
@@ -18,17 +18,36 @@
 #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"
 #include "llvm/Support/MemoryBuffer.h"
 #include "llvm/Support/Path.h"
 #include "llvm/Support/raw_ostream.h"
+#include "llvm/Support/YAMLTraits.h"
 #include <memory>
 #include <system_error>
 
 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));
+}
+} // namespace
+
 //===----------------------------------------------------------------------===//
 // Custom Actions
 //===----------------------------------------------------------------------===//
@@ -262,6 +281,140 @@ void VerifyPCHAction::ExecuteAction() {
 }
 
 namespace {
+struct TemplightEntry {
+  std::string Name;
+  std::string Kind;
+  std::string Event;
+  std::string DefinitionLocation;
+  std::string PointOfInstantiation;
+};
+} // namespace
+
+namespace llvm {
+namespace yaml {
+template <> struct MappingTraits<TemplightEntry> {
+  static void mapping(IO &io, TemplightEntry &fields) {
+    io.mapRequired("name", fields.Name);
+    io.mapRequired("kind", fields.Kind);
+    io.mapRequired("event", fields.Event);
+    io.mapRequired("orig", fields.DefinitionLocation);
+    io.mapRequired("poi", fields.PointOfInstantiation);
+  }
+};
+} // namespace yaml
+} // namespace llvm
+
+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<true>(llvm::outs(), TheSema, Inst);
+  }
+
+  virtual void atTemplateEnd(const Sema &TheSema,
+                             const CodeSynthesisContext &Inst) override {
+    displayTemplightEntry<false>(llvm::outs(), 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 <bool BeginInstantiation>
+  static void displayTemplightEntry(llvm::raw_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<BeginInstantiation>(TheSema, Inst);
+      llvm::yaml::EmptyContext Context;
+      llvm::yaml::yamlize(YO, Entry, true, Context);
+    }
+    Out << "---" << YAML << "\n";
+  }
+
+  template <bool BeginInstantiation>
+  static TemplightEntry getTemplightEntry(const Sema &TheSema,
+                                          const CodeSynthesisContext &Inst) {
+    TemplightEntry Entry;
+    Entry.Kind = toString(Inst.Kind);
+    Entry.Event = BeginInstantiation ? "Begin" : "End";
+    if (auto *NamedTemplate = dyn_cast_or_null<NamedDecl>(Inst.Entity)) {
+      llvm::raw_string_ostream OS(Entry.Name);
+      NamedTemplate->getNameForDiagnostic(OS, TheSema.getLangOpts(), true);
+      const PresumedLoc DefLoc = 
+        TheSema.getSourceManager().getPresumedLoc(Inst.Entity->getLocation());
+      if(!DefLoc.isInvalid())
+        Entry.DefinitionLocation = std::string(DefLoc.getFilename()) + ":" +
+                                   std::to_string(DefLoc.getLine()) + ":" +
+                                   std::to_string(DefLoc.getColumn());
+    }
+    const PresumedLoc PoiLoc =
+        TheSema.getSourceManager().getPresumedLoc(Inst.PointOfInstantiation);
+    if (!PoiLoc.isInvalid()) {
+      Entry.PointOfInstantiation = std::string(PoiLoc.getFilename()) + ":" +
+                                   std::to_string(PoiLoc.getLine()) + ":" +
+                                   std::to_string(PoiLoc.getColumn());
+    }
+    return Entry;
+  }
+};
+} // namespace
+
+std::unique_ptr<ASTConsumer>
+TemplightDumpAction::CreateASTConsumer(CompilerInstance &CI, StringRef InFile) {
+  return llvm::make_unique<ASTConsumer>();
+}
+
+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<DefaultTemplateInstCallback>());
+  ASTFrontendAction::ExecuteAction();
+}
+
+namespace {
   /// \brief AST reader listener that dumps module information for a module
   /// file.
   class DumpModuleInfoListener : public ASTReaderListener {

Modified: cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp (original)
+++ cfe/trunk/lib/FrontendTool/ExecuteCompilerInvocation.cpp Sat Feb 10 06:04:45 2018
@@ -32,6 +32,8 @@
 using namespace clang;
 using namespace llvm::opt;
 
+namespace clang {
+
 static std::unique_ptr<FrontendAction>
 CreateFrontendBaseAction(CompilerInstance &CI) {
   using namespace clang::frontend;
@@ -63,6 +65,7 @@ CreateFrontendBaseAction(CompilerInstanc
   case ParseSyntaxOnly:        return llvm::make_unique<SyntaxOnlyAction>();
   case ModuleFileInfo:         return llvm::make_unique<DumpModuleInfoAction>();
   case VerifyPCH:              return llvm::make_unique<VerifyPCHAction>();
+  case TemplightDump:          return llvm::make_unique<TemplightDumpAction>();
 
   case PluginAction: {
     for (FrontendPluginRegistry::iterator it =
@@ -122,7 +125,7 @@ CreateFrontendBaseAction(CompilerInstanc
 #endif
 }
 
-static std::unique_ptr<FrontendAction>
+std::unique_ptr<FrontendAction>
 CreateFrontendAction(CompilerInstance &CI) {
   // Create the underlying action.
   std::unique_ptr<FrontendAction> Act = CreateFrontendBaseAction(CI);
@@ -173,7 +176,7 @@ CreateFrontendAction(CompilerInstance &C
   return Act;
 }
 
-bool clang::ExecuteCompilerInvocation(CompilerInstance *Clang) {
+bool ExecuteCompilerInvocation(CompilerInstance *Clang) {
   // Honor -help.
   if (Clang->getFrontendOpts().ShowHelp) {
     std::unique_ptr<OptTable> Opts = driver::createDriverOptTable();
@@ -254,3 +257,5 @@ bool clang::ExecuteCompilerInvocation(Co
     BuryPointer(std::move(Act));
   return Success;
 }
+
+} //namespace clang 

Modified: cfe/trunk/lib/Parse/ParseAST.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseAST.cpp?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseAST.cpp (original)
+++ cfe/trunk/lib/Parse/ParseAST.cpp Sat Feb 10 06:04:45 2018
@@ -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 <cstdio>
 #include <memory>
@@ -121,6 +122,10 @@ void clang::ParseAST(Sema &S, bool Print
   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<Parser> ParseOP(
@@ -158,6 +163,13 @@ void clang::ParseAST(Sema &S, bool Print
   
   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";

Modified: cfe/trunk/lib/Sema/Sema.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.cpp?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.cpp (original)
+++ cfe/trunk/lib/Sema/Sema.cpp Sat Feb 10 06:04:45 2018
@@ -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;

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Sat Feb 10 06:04:45 2018
@@ -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,10 @@ bool Sema::CodeSynthesisContext::isInsta
   case DeclaringSpecialMember:
   case DefiningSynthesizedFunction:
     return false;
+       
+  // This function should never be called when Kind's value is Memoization.
+  case Memoization:
+    break;
   }
 
   llvm_unreachable("Invalid SynthesisKind!");
@@ -235,6 +240,7 @@ Sema::InstantiatingTemplate::Instantiati
         !SemaRef.InstantiatingSpecializations
              .insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind))
              .second;
+    atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, Inst);
   }
 }
 
@@ -394,8 +400,10 @@ void Sema::InstantiatingTemplate::Clear(
           std::make_pair(Active.Entity, Active.Kind));
     }
 
-    SemaRef.popCodeSynthesisContext();
+    atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef,
+                  SemaRef.CodeSynthesisContexts.back());
 
+    SemaRef.popCodeSynthesisContext();
     Invalid = true;
   }
 }
@@ -626,7 +634,7 @@ void Sema::PrintInstantiationStack() {
         << cast<CXXRecordDecl>(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<CXXMethodDecl>(Active->Entity);
       auto CSM = MD ? getSpecialMember(MD) : CXXInvalid;
@@ -637,6 +645,10 @@ void Sema::PrintInstantiationStack() {
       }
       break;
     }
+
+    case CodeSynthesisContext::Memoization:
+      break;
+    }
   }
 }
 
@@ -682,6 +694,9 @@ Optional<TemplateDeductionInfo *> Sema::
       // 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

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Sat Feb 10 06:04:45 2018
@@ -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;
 
@@ -3648,8 +3649,10 @@ TemplateDeclInstantiator::InitFunctionIn
       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);
     }
   }
 

Modified: cfe/trunk/lib/Sema/SemaType.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaType.cpp?rev=324808&r1=324807&r2=324808&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaType.cpp (original)
+++ cfe/trunk/lib/Sema/SemaType.cpp Sat Feb 10 06:04:45 2018
@@ -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"
@@ -7565,6 +7566,14 @@ bool Sema::RequireCompleteTypeImpl(Sourc
         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;

Added: cfe/trunk/test/Templight/templight-deduced-func.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Templight/templight-deduced-func.cpp?rev=324808&view=auto
==============================================================================
--- cfe/trunk/test/Templight/templight-deduced-func.cpp (added)
+++ cfe/trunk/test/Templight/templight-deduced-func.cpp Sat Feb 10 06:04:45 2018
@@ -0,0 +1,44 @@
+// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s
+
+template <class T>
+int foo(T){return 0;}
+
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+foo$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-deduced-func.cpp:4:5'}}
+// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:44:12'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+foo$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-deduced-func.cpp:4:5'}}
+// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:44:12'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-deduced-func.cpp:4:5'}}
+// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:44:12'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-deduced-func.cpp:4:5'}}
+// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:44:12'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-deduced-func.cpp:4:5'}}
+// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:44:12'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-deduced-func.cpp:4:5'}}
+// CHECK: {{^poi:[ ]+'.*templight-deduced-func.cpp:44:12'$}}
+int gvar = foo(0);

Added: cfe/trunk/test/Templight/templight-default-arg-inst.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Templight/templight-default-arg-inst.cpp?rev=324808&view=auto
==============================================================================
--- cfe/trunk/test/Templight/templight-default-arg-inst.cpp (added)
+++ cfe/trunk/test/Templight/templight-default-arg-inst.cpp Sat Feb 10 06:04:45 2018
@@ -0,0 +1,82 @@
+// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s
+template<class T, class U = T>
+class A {};
+
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A::U'$}}
+// CHECK: {{^kind:[ ]+DefaultTemplateArgumentInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:2:25'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:1'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A::U'$}}
+// CHECK: {{^kind:[ ]+DefaultTemplateArgumentInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:2:25'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:1'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A::U'$}}
+// CHECK: {{^kind:[ ]+DefaultTemplateArgumentChecking$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:2:25'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:6'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A::U'$}}
+// CHECK: {{^kind:[ ]+DefaultTemplateArgumentChecking$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:2:25'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:6'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int, int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:8'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int, int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:8'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int, int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:8'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int, int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:8'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int, int>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:8'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int, int>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:8'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int, int>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:8'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int, int>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-arg-inst.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-arg-inst.cpp:82:8'$}}
+A<int> a;

Added: cfe/trunk/test/Templight/templight-default-func-arg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Templight/templight-default-func-arg.cpp?rev=324808&view=auto
==============================================================================
--- cfe/trunk/test/Templight/templight-default-func-arg.cpp (added)
+++ cfe/trunk/test/Templight/templight-default-func-arg.cpp Sat Feb 10 06:04:45 2018
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -std=c++14 -templight-dump %s 2>&1 | FileCheck %s
+template <class T>
+void foo(T b = 0) {};
+
+int main()
+{
+
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+foo$}}
+// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-func-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:72:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+foo$}}
+// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-func-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:72:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+foo$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-func-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:72:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+foo$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-func-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:72:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-func-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:72:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-func-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:72:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+b$}}
+// CHECK: {{^kind:[ ]+DefaultFunctionArgumentInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-func-arg.cpp:3:12'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:72:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+b$}}
+// CHECK: {{^kind:[ ]+DefaultFunctionArgumentInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-func-arg.cpp:3:12'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:72:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-func-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:72:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-func-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-func-arg.cpp:72:3'$}}
+  foo<int>();
+}

Added: cfe/trunk/test/Templight/templight-default-template-arg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Templight/templight-default-template-arg.cpp?rev=324808&view=auto
==============================================================================
--- cfe/trunk/test/Templight/templight-default-template-arg.cpp (added)
+++ cfe/trunk/test/Templight/templight-default-template-arg.cpp Sat Feb 10 06:04:45 2018
@@ -0,0 +1,69 @@
+// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s
+template <class T = int>
+class A {};
+
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A::T'$}}
+// CHECK: {{^kind:[ ]+DefaultTemplateArgumentChecking$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-template-arg.cpp:2:17'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:69:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A::T'$}}
+// CHECK: {{^kind:[ ]+DefaultTemplateArgumentChecking$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-template-arg.cpp:2:17'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:69:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-template-arg.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:69:5'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-template-arg.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:69:5'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-template-arg.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:69:5'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-template-arg.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:69:5'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-template-arg.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:69:5'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-template-arg.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:69:5'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-template-arg.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:69:5'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'A<int>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-default-template-arg.cpp:3:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-default-template-arg.cpp:69:5'$}}
+A<> a;

Added: cfe/trunk/test/Templight/templight-exception-spec-func.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Templight/templight-exception-spec-func.cpp?rev=324808&view=auto
==============================================================================
--- cfe/trunk/test/Templight/templight-exception-spec-func.cpp (added)
+++ cfe/trunk/test/Templight/templight-exception-spec-func.cpp Sat Feb 10 06:04:45 2018
@@ -0,0 +1,73 @@
+// RUN: %clang_cc1 -templight-dump -std=c++14 %s 2>&1 | FileCheck %s
+template <bool B>
+void f() noexcept(B) {}
+
+int main()
+{
+
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+f$}}
+// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-exception-spec-func.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:72:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+f$}}
+// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-exception-spec-func.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:72:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+f$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-exception-spec-func.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:72:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+f$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-exception-spec-func.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:72:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'f<false>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-exception-spec-func.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:72:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'f<false>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-exception-spec-func.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:72:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'f<false>'$}}
+// CHECK: {{^kind:[ ]+ExceptionSpecInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-exception-spec-func.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:72:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'f<false>'$}}
+// CHECK: {{^kind:[ ]+ExceptionSpecInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-exception-spec-func.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:72:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'f<false>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-exception-spec-func.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:72:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'f<false>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-exception-spec-func.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-exception-spec-func.cpp:72:3'$}}
+  f<false>();
+}

Added: cfe/trunk/test/Templight/templight-explicit-template-arg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Templight/templight-explicit-template-arg.cpp?rev=324808&view=auto
==============================================================================
--- cfe/trunk/test/Templight/templight-explicit-template-arg.cpp (added)
+++ cfe/trunk/test/Templight/templight-explicit-template-arg.cpp Sat Feb 10 06:04:45 2018
@@ -0,0 +1,59 @@
+// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s
+template <class T>
+void f(){}
+
+int main()
+{
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+f$}}
+// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-explicit-template-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:58:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+f$}}
+// CHECK: {{^kind:[ ]+ExplicitTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-explicit-template-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:58:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+f$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-explicit-template-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:58:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+f$}}
+// CHECK: {{^kind:[ ]+DeducedTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-explicit-template-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:58:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'f<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-explicit-template-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:58:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'f<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-explicit-template-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:58:3'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'f<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-explicit-template-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:58:3'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'f<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-explicit-template-arg.cpp:3:6'}}
+// CHECK: {{^poi:[ ]+'.*templight-explicit-template-arg.cpp:58:3'$}}
+  f<int>();
+}

Added: cfe/trunk/test/Templight/templight-memoization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Templight/templight-memoization.cpp?rev=324808&view=auto
==============================================================================
--- cfe/trunk/test/Templight/templight-memoization.cpp (added)
+++ cfe/trunk/test/Templight/templight-memoization.cpp Sat Feb 10 06:04:45 2018
@@ -0,0 +1,42 @@
+// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s
+
+template <class T>
+struct foo {};
+
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-memoization.cpp:18:10'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-memoization.cpp:18:10'$}}
+foo<int> x;
+
+// CHECK-LABEL: {{^---$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK-LABEL: {{^---$}}
+
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-memoization.cpp:41:10'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-memoization.cpp:41:10'$}}
+foo<int> y;
+

Added: cfe/trunk/test/Templight/templight-nested-memoization.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Templight/templight-nested-memoization.cpp?rev=324808&view=auto
==============================================================================
--- cfe/trunk/test/Templight/templight-nested-memoization.cpp (added)
+++ cfe/trunk/test/Templight/templight-nested-memoization.cpp Sat Feb 10 06:04:45 2018
@@ -0,0 +1,174 @@
+// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s
+
+template <int N>
+struct fib
+{
+  static const int value = fib<N-1>::value + fib<N-2>::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: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:173:8'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<4>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:173:8'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<4>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:173:8'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<3>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<3>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<3>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<2>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<2>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<2>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<1>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:16:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<1>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:16:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<0>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:10:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<0>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:10:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<2>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<2>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<2>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<1>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:16:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<1>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:16:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<3>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<3>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<3>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:28'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<2>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'fib<2>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:6:46'$}}
+// CHECK-LABEL: {{^---$}}
+//
+// CHECK: {{^name:[ ]+'fib<4>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-memoization.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-memoization.cpp:173:8'$}}
+fib<4> x;
+

Added: cfe/trunk/test/Templight/templight-nested-template-instantiation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Templight/templight-nested-template-instantiation.cpp?rev=324808&view=auto
==============================================================================
--- cfe/trunk/test/Templight/templight-nested-template-instantiation.cpp (added)
+++ cfe/trunk/test/Templight/templight-nested-template-instantiation.cpp Sat Feb 10 06:04:45 2018
@@ -0,0 +1,84 @@
+// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s
+
+template <int N>
+struct foo : foo<N - 1> {};
+
+template <>
+struct foo<0> {};
+
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<2>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:84:8'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<2>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:84:8'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<2>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:84:8'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<1>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<1>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<1>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<0>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:7:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<0>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:7:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<1>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<1>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<1>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:4:14'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<2>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-nested-template-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-nested-template-instantiation.cpp:84:8'$}}
+foo<2> x;

Added: cfe/trunk/test/Templight/templight-one-instantiation.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Templight/templight-one-instantiation.cpp?rev=324808&view=auto
==============================================================================
--- cfe/trunk/test/Templight/templight-one-instantiation.cpp (added)
+++ cfe/trunk/test/Templight/templight-one-instantiation.cpp Sat Feb 10 06:04:45 2018
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s
+
+template <class T>
+struct foo {};
+
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-one-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-one-instantiation.cpp:18:10'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'foo<int>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-one-instantiation.cpp:4:8'}}
+// CHECK: {{^poi:[ ]+'.*templight-one-instantiation.cpp:18:10'$}}
+foo<int> x;

Added: cfe/trunk/test/Templight/templight-prior-template-arg.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Templight/templight-prior-template-arg.cpp?rev=324808&view=auto
==============================================================================
--- cfe/trunk/test/Templight/templight-prior-template-arg.cpp (added)
+++ cfe/trunk/test/Templight/templight-prior-template-arg.cpp Sat Feb 10 06:04:45 2018
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -templight-dump %s 2>&1 | FileCheck %s
+template<class T>
+class A {};
+
+template <template <class Inner> class Outer>
+class B {};
+
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'B::Outer'$}}
+// CHECK: {{^kind:[ ]+PriorTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:5:40'}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:1'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'B::Outer'$}}
+// CHECK: {{^kind:[ ]+PriorTemplateArgumentSubstitution$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:5:40'}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:1'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'B<A>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'B<A>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'B<A>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'B<A>'$}}
+// CHECK: {{^kind:[ ]+TemplateInstantiation$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'B<A>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'B<A>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
+//
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'B<A>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+Begin$}}
+// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
+// CHECK-LABEL: {{^---$}}
+// CHECK: {{^name:[ ]+'B<A>'$}}
+// CHECK: {{^kind:[ ]+Memoization$}}
+// CHECK: {{^event:[ ]+End$}}
+// CHECK: {{^orig:[ ]+'.*templight-prior-template-arg.cpp:6:7'}}
+// CHECK: {{^poi:[ ]+'.*templight-prior-template-arg.cpp:72:6'$}}
+B<A> b;




More information about the cfe-commits mailing list