[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
llvm-svn: 324808
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 45fd2d3..65183b4 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -37,6 +37,7 @@
#include "clang/Sema/SemaConsumer.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/TemplateDeduction.h"
+#include "clang/Sema/TemplateInstCallback.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallSet.h"
using namespace clang;
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 313d99c..489d026 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -25,6 +25,7 @@
#include "clang/Sema/PrettyDeclStackTrace.h"
#include "clang/Sema/Template.h"
#include "clang/Sema/TemplateDeduction.h"
+#include "clang/Sema/TemplateInstCallback.h"
using namespace clang;
using namespace sema;
@@ -199,6 +200,10 @@
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 @@
!SemaRef.InstantiatingSpecializations
.insert(std::make_pair(Inst.Entity->getCanonicalDecl(), Inst.Kind))
.second;
+ atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, Inst);
}
}
@@ -394,8 +400,10 @@
std::make_pair(Active.Entity, Active.Kind));
}
- SemaRef.popCodeSynthesisContext();
+ atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef,
+ SemaRef.CodeSynthesisContexts.back());
+ SemaRef.popCodeSynthesisContext();
Invalid = true;
}
}
@@ -626,7 +634,7 @@
<< 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 @@
}
break;
}
+
+ 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
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index b8b7440..15b53ca 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -23,6 +23,7 @@
#include "clang/Sema/Lookup.h"
#include "clang/Sema/PrettyDeclStackTrace.h"
#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateInstCallback.h"
using namespace clang;
@@ -3648,8 +3649,10 @@
assert(FunTmpl->getTemplatedDecl() == Tmpl &&
"Deduction from the wrong function template?");
(void) FunTmpl;
+ atTemplateEnd(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst);
ActiveInst.Kind = ActiveInstType::TemplateInstantiation;
ActiveInst.Entity = New;
+ atTemplateBegin(SemaRef.TemplateInstCallbacks, SemaRef, ActiveInst);
}
}
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 8219d4d..8f3b359 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -31,6 +31,7 @@
#include "clang/Sema/ScopeInfo.h"
#include "clang/Sema/SemaInternal.h"
#include "clang/Sema/Template.h"
+#include "clang/Sema/TemplateInstCallback.h"
#include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringSwitch.h"
@@ -7565,6 +7566,14 @@
diagnoseMissingImport(Loc, SuggestedDef, MissingImportKind::Definition,
/*Recover*/TreatAsComplete);
return !TreatAsComplete;
+ } else if (Def && !TemplateInstCallbacks.empty()) {
+ CodeSynthesisContext TempInst;
+ TempInst.Kind = CodeSynthesisContext::Memoization;
+ TempInst.Template = Def;
+ TempInst.Entity = Def;
+ TempInst.PointOfInstantiation = Loc;
+ atTemplateBegin(TemplateInstCallbacks, *this, TempInst);
+ atTemplateEnd(TemplateInstCallbacks, *this, TempInst);
}
return false;