]> granicus.if.org Git - clang/commitdiff
[microsoft] Fix a bug in -fdelayed-template-parsing mode where we were not reentering...
authorFrancois Pichet <pichet2000@gmail.com>
Thu, 22 Sep 2011 22:14:56 +0000 (22:14 +0000)
committerFrancois Pichet <pichet2000@gmail.com>
Thu, 22 Sep 2011 22:14:56 +0000 (22:14 +0000)
The solution is to create a new ParseScope(Scope::TemplateParamScope) for each template scope that we want to reenter. (from the outmost to the innermost scope)

This fixes some errors when parsing MFC code with clang.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140344 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Parse/ParseTemplate.cpp
test/Parser/DelayedTemplateParsing.cpp

index f9fe3563b499e8f42aebb8c74becdd82fe7e9104..955f61c492009c7809f1d4e3bb63f88e37105deb 100644 (file)
@@ -1159,6 +1159,7 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) {
     FD = cast<FunctionDecl>(LMT.D);
   
   // Reinject the template parameters.
+  SmallVector<ParseScope*, 4> TemplateParamScopeStack;
   DeclaratorDecl* Declarator = dyn_cast<DeclaratorDecl>(FD);
   if (Declarator && Declarator->getNumTemplateParameterLists() != 0) {
     Actions.ActOnReenterDeclaratorTemplateScope(getCurScope(), Declarator);
@@ -1166,17 +1167,31 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) {
   } else {
     Actions.ActOnReenterTemplateScope(getCurScope(), LMT.D);
 
+    // Get the list of DeclContext to reenter.
+    SmallVector<DeclContext*, 4> DeclContextToReenter;
     DeclContext *DD = FD->getLexicalParent();
     while (DD && DD->isRecord()) {
-      if (ClassTemplatePartialSpecializationDecl* MD =
-                  dyn_cast_or_null<ClassTemplatePartialSpecializationDecl>(DD))
-          Actions.ActOnReenterTemplateScope(getCurScope(), MD);
-      else if (CXXRecordDecl* MD = dyn_cast_or_null<CXXRecordDecl>(DD))
-          Actions.ActOnReenterTemplateScope(getCurScope(),
-                                            MD->getDescribedClassTemplate());
-
+      DeclContextToReenter.push_back(DD);
       DD = DD->getLexicalParent();
     }
+
+    // Reenter the DeclContext 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,\r
+                                                   Scope::TemplateParamScope));\r
+        Actions.ActOnReenterTemplateScope(getCurScope(), MD);
+      } else if (CXXRecordDecl* MD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
+        TemplateParamScopeStack.push_back(new ParseScope(this,\r
+                                                    Scope::TemplateParamScope,\r
+                                       MD->getDescribedClassTemplate() != 0 ));\r
+        Actions.ActOnReenterTemplateScope(getCurScope(),
+                                          MD->getDescribedClassTemplate());
+      }
+    }
   }
   assert(!LMT.Toks.empty() && "Empty body!");
 
@@ -1207,21 +1222,25 @@ void Parser::ParseLateTemplatedFuncDef(LateParsedTemplatedFunction &LMT) {
 
   if (Tok.is(tok::kw_try)) {
     ParseFunctionTryBlock(LMT.D, FnScope);
-    return;
-  }
-  if (Tok.is(tok::colon)) {
-    ParseConstructorInitializer(LMT.D);
+  } else {
+    if (Tok.is(tok::colon))
+      ParseConstructorInitializer(LMT.D);
+    else
+      Actions.ActOnDefaultCtorInitializers(LMT.D);
 
-    // Error recovery.
-    if (!Tok.is(tok::l_brace)) {
+    if (Tok.is(tok::l_brace)) {
+      ParseFunctionStatementBody(LMT.D, FnScope);
+      Actions.MarkAsLateParsedTemplate(FD, false);
+    } else
       Actions.ActOnFinishFunctionBody(LMT.D, 0);
-      return;
-    }
-  } else
-    Actions.ActOnDefaultCtorInitializers(LMT.D);
+  }
 
-  ParseFunctionStatementBody(LMT.D, FnScope);
-  Actions.MarkAsLateParsedTemplate(FD, false);
+  // Exit scopes.
+  FnScope.Exit();
+  SmallVector<ParseScope*, 4>::reverse_iterator I =
+   TemplateParamScopeStack.rbegin();
+  for (; I != TemplateParamScopeStack.rend(); ++I)
+    delete *I;
 
   DeclGroupPtrTy grp = Actions.ConvertDeclToDeclGroup(LMT.D);
   if (grp)
index b447fff2f1c03f229eb153a9c68675d802978bf4..b02c4026c048eaa5c7afc9403a8ddb6ae15eba6b 100644 (file)
@@ -1,11 +1,11 @@
-// RUN: %clang_cc1 -fdelayed-template-parsing -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fms-extensions -fdelayed-template-parsing -fsyntax-only -verify %s
 
 template <class T>
 class A {
    void foo() {
        undeclared();
    }
-      void foo2();
+   void foo2();
 };
 
 template <class T>
@@ -40,3 +40,22 @@ void undeclared()
 
 template <class T> void foo5() {} //expected-note {{previous definition is here}} 
 template <class T> void foo5() {} // expected-error {{redefinition of 'foo5'}}
+
+              
+
+namespace Inner_Outer_same_template_param_name {              
+
+template <class T>
+class Outmost {
+public:
+    template <class T>
+    class Inner {
+    public:
+        void f() {
+            T* var;
+        }
+   };
+};
+
+}
+