[PATCH] -fdelayed-template-parsing: handle cases where a late-parsed function is not a direct member of a template, but rather nested inside a class that's a member of a template (PR19613)
Richard Smith
richard at metafoo.co.uk
Thu May 1 15:17:39 PDT 2014
Thanks, that looks nicer.
================
Comment at: lib/Parse/ParseTemplate.cpp:1252
@@ -1251,17 +1251,3 @@
for (; II != DeclContextsToReenter.rend(); ++II) {
- if (ClassTemplatePartialSpecializationDecl *MD =
- dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(*II)) {
- TemplateParamScopeStack.push_back(
- new ParseScope(this, Scope::TemplateParamScope));
- Actions.ActOnReenterTemplateScope(getCurScope(), MD);
- ++CurTemplateDepthTracker;
- } else if (CXXRecordDecl *MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
- bool IsClassTemplate = MD->getDescribedClassTemplate() != 0;
- TemplateParamScopeStack.push_back(
- new ParseScope(this, Scope::TemplateParamScope,
- /*ManageScope*/IsClassTemplate));
- Actions.ActOnReenterTemplateScope(getCurScope(),
- MD->getDescribedClassTemplate());
- if (IsClassTemplate)
- ++CurTemplateDepthTracker;
- }
+ Decl *D = dyn_cast<Decl>(*II);
+
----------------
`cast`, not `dyn_cast`, please.
================
Comment at: lib/Parse/ParseTemplate.cpp:1266-1270
@@ -1273,10 +1265,7 @@
- DeclaratorDecl *Declarator = dyn_cast<DeclaratorDecl>(FunD);
- const unsigned DeclaratorNumTemplateParameterLists =
- (Declarator ? Declarator->getNumTemplateParameterLists() : 0);
- if (Declarator && DeclaratorNumTemplateParameterLists != 0) {
- Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);
- CurTemplateDepthTracker.addDepth(DeclaratorNumTemplateParameterLists);
+ if (unsigned NumLists = FunD->getNumTemplateParameterLists()) {
+ Actions.ActOnReenterTemplateScope(getCurScope(), FunD);
+ CurTemplateDepthTracker.addDepth(NumLists);
}
Actions.ActOnReenterTemplateScope(getCurScope(), LPT.D);
++CurTemplateDepthTracker;
----------------
Can you push the function template case into `ActOnReenterTemplateScope` too?
================
Comment at: lib/Sema/SemaDeclCXX.cpp:6000
@@ -6001,13 +5999,3 @@
-void Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) {
- if (!D)
- return;
-
- TemplateParameterList *Params = 0;
- if (TemplateDecl *Template = dyn_cast<TemplateDecl>(D))
- Params = Template->getTemplateParameters();
- else if (ClassTemplatePartialSpecializationDecl *PartialSpec
- = dyn_cast<ClassTemplatePartialSpecializationDecl>(D))
- Params = PartialSpec->getTemplateParameters();
- else
- return;
+ if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D)) {
+ for (unsigned i = 0; i < RD->getNumTemplateParameterLists(); ++i)
----------------
You should handle all `TagDecl`s here, not just `CXXRecordDecl`s. Under the resolution of DR1607, this is valid:
template<typename T> struct A {
enum class E;
};
template<typename T> enum class A<T>::E {
n = (true ? 0 : [] {
struct Q { Q() { /* delay parsed */ } } q;
return 0;
}())
};
... and instantiating `A<T>::E` will instantiate the default constructor of `Q` (note, we currently reject this because we went for a more conservative tentative fix for issue 1607).
http://reviews.llvm.org/D3555
More information about the cfe-commits
mailing list