[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