r180702 - Properly reenter multiple contexts when parsing a late-parsed function template

Richard Smith richard-llvm at metafoo.co.uk
Mon Apr 29 01:53:40 PDT 2013


Author: rsmith
Date: Mon Apr 29 03:53:40 2013
New Revision: 180702

URL: http://llvm.org/viewvc/llvm-project?rev=180702&view=rev
Log:
Properly reenter multiple contexts when parsing a late-parsed function template
within a dependent context. Patch by Will Wilson (+clang-format)!

Modified:
    cfe/trunk/lib/Parse/ParseTemplate.cpp
    cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp

Modified: cfe/trunk/lib/Parse/ParseTemplate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Parse/ParseTemplate.cpp?rev=180702&r1=180701&r2=180702&view=diff
==============================================================================
--- cfe/trunk/lib/Parse/ParseTemplate.cpp (original)
+++ cfe/trunk/lib/Parse/ParseTemplate.cpp Mon Apr 29 03:53:40 2013
@@ -1259,43 +1259,41 @@ void Parser::ParseLateTemplatedFuncDef(L
   Sema::ContextRAII GlobalSavedContext(Actions, Actions.CurContext);
 
   SmallVector<ParseScope*, 4> TemplateParamScopeStack;
-  DeclaratorDecl* Declarator = dyn_cast<DeclaratorDecl>(FD);
-  if (Declarator && Declarator->getNumTemplateParameterLists() != 0) {
-    TemplateParamScopeStack.push_back(new ParseScope(this, Scope::TemplateParamScope));
-    Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);
-    Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
-  } else {
-    // Get the list of DeclContext to reenter.
-    SmallVector<DeclContext*, 4> DeclContextToReenter;
-    DeclContext *DD = FD->getLexicalParent();
-    while (DD && !DD->isTranslationUnit()) {
-      DeclContextToReenter.push_back(DD);
-      DD = DD->getLexicalParent();
-    }
 
-    // Reenter template scopes from outmost to innermost.
-    SmallVector<DeclContext*, 4>::reverse_iterator II =
-    DeclContextToReenter.rbegin();
-    for (; II != DeclContextToReenter.rend(); ++II) {
-      if (ClassTemplatePartialSpecializationDecl* MD =
-                dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(*II)) {
-        TemplateParamScopeStack.push_back(new ParseScope(this,
-                                                   Scope::TemplateParamScope));
-        Actions.ActOnReenterTemplateScope(getCurScope(), MD);
-      } else if (CXXRecordDecl* MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
-        TemplateParamScopeStack.push_back(new ParseScope(this,
-                                                    Scope::TemplateParamScope,
-                                       MD->getDescribedClassTemplate() != 0 ));
-        Actions.ActOnReenterTemplateScope(getCurScope(),
-                                          MD->getDescribedClassTemplate());
-      }
-      TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope));
-      Actions.PushDeclContext(Actions.getCurScope(), *II);
+  // Get the list of DeclContexts to reenter.
+  SmallVector<DeclContext*, 4> DeclContextsToReenter;
+  DeclContext *DD = FD->getLexicalParent();
+  while (DD && !DD->isTranslationUnit()) {
+    DeclContextsToReenter.push_back(DD);
+    DD = DD->getLexicalParent();
+  }
+
+  // Reenter template scopes from outermost to innermost.
+  SmallVector<DeclContext*, 4>::reverse_iterator II =
+      DeclContextsToReenter.rbegin();
+  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);
+    } else if (CXXRecordDecl *MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
+      bool ManageScope = MD->getDescribedClassTemplate() != 0;
+      TemplateParamScopeStack.push_back(
+          new ParseScope(this, Scope::TemplateParamScope, ManageScope));
+      Actions.ActOnReenterTemplateScope(getCurScope(),
+                                        MD->getDescribedClassTemplate());
     }
-    TemplateParamScopeStack.push_back(new ParseScope(this,
-                                      Scope::TemplateParamScope));
-    Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
+    TemplateParamScopeStack.push_back(new ParseScope(this, Scope::DeclScope));
+    Actions.PushDeclContext(Actions.getCurScope(), *II);
   }
+  TemplateParamScopeStack.push_back(
+      new ParseScope(this, Scope::TemplateParamScope));
+
+  DeclaratorDecl *Declarator = dyn_cast<DeclaratorDecl>(FD);
+  if (Declarator && Declarator->getNumTemplateParameterLists() != 0)
+    Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);
+  Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
 
   assert(!LMT.Toks.empty() && "Empty body!");
 

Modified: cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp?rev=180702&r1=180701&r2=180702&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp (original)
+++ cfe/trunk/test/SemaTemplate/ms-function-specialization-class-scope.cpp Mon Apr 29 03:53:40 2013
@@ -1,4 +1,5 @@
 // RUN: %clang_cc1 -fms-extensions -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s
 
 
 class A {





More information about the cfe-commits mailing list