New patch addressing Richard's feedback.

http://reviews.llvm.org/D3555

Files:
  include/clang/Sema/Sema.h
  lib/Parse/ParseTemplate.cpp
  lib/Sema/SemaDeclCXX.cpp
  test/Parser/DelayedTemplateParsing.cpp
Index: include/clang/Sema/Sema.h
===================================================================
--- include/clang/Sema/Sema.h
+++ include/clang/Sema/Sema.h
@@ -4886,6 +4886,7 @@
   void ActOnReenterCXXMethodParameter(Scope *S, ParmVarDecl *Param);
   void ActOnReenterTemplateScope(Scope *S, Decl *Template);
   void ActOnReenterDeclaratorTemplateScope(Scope *S, DeclaratorDecl *D);
+  void ActOnReenterRecordTemplateScope(Scope *S, CXXRecordDecl *RD);
   void ActOnStartDelayedMemberDeclarations(Scope *S, Decl *Record);
   void ActOnStartDelayedCXXMethodDeclaration(Scope *S, Decl *Method);
   void ActOnDelayedCXXMethodParameter(Scope *S, Decl *Param);
Index: lib/Parse/ParseTemplate.cpp
===================================================================
--- lib/Parse/ParseTemplate.cpp
+++ lib/Parse/ParseTemplate.cpp
@@ -1255,28 +1255,33 @@
           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;
+    } else if (CXXRecordDecl *RD = dyn_cast_or_null<CXXRecordDecl>(*II)) {
+      if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate()) {
+        TemplateParamScopeStack.push_back(new ParseScope(this,
+              Scope::TemplateParamScope, /*EnteredScope*/true));
+        Actions.ActOnReenterTemplateScope(getCurScope(), CTD);
+        ++CurTemplateDepthTracker;
+      }
+
+      bool HasTemplateParams = RD->getNumTemplateParameterLists() > 0;
+
       TemplateParamScopeStack.push_back(
-          new ParseScope(this, Scope::TemplateParamScope, 
-                        /*ManageScope*/IsClassTemplate));
-      Actions.ActOnReenterTemplateScope(getCurScope(),
-                                        MD->getDescribedClassTemplate());
-      if (IsClassTemplate) 
+          new ParseScope(this, Scope::TemplateParamScope,
+                         /*EnteredScope*/HasTemplateParams));
+      if (HasTemplateParams) {
+        Actions.ActOnReenterRecordTemplateScope(getCurScope(), RD);
         ++CurTemplateDepthTracker;
+      }
     }
     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>(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.ActOnReenterDeclaratorTemplateScope(getCurScope(), FunD);
+    CurTemplateDepthTracker.addDepth(NumLists);
   }
   Actions.ActOnReenterTemplateScope(getCurScope(), LPT.D);
   ++CurTemplateDepthTracker;
Index: lib/Sema/SemaDeclCXX.cpp
===================================================================
--- lib/Sema/SemaDeclCXX.cpp
+++ lib/Sema/SemaDeclCXX.cpp
@@ -5984,9 +5984,9 @@
   if (!D)
     return;
 
-  int NumParamList = D->getNumTemplateParameterLists();
-  for (int i = 0; i < NumParamList; i++) {
-    TemplateParameterList* Params = D->getTemplateParameterList(i);
+  unsigned NumParamList = D->getNumTemplateParameterLists();
+  for (unsigned i = 0; i < NumParamList; i++) {
+    TemplateParameterList *Params = D->getTemplateParameterList(i);
     for (TemplateParameterList::iterator Param = Params->begin(),
                                       ParamEnd = Params->end();
           Param != ParamEnd; ++Param) {
@@ -5999,6 +5999,22 @@
   }
 }
 
+void Sema::ActOnReenterRecordTemplateScope(Scope *S, CXXRecordDecl *RD) {
+  if (!RD)
+    return;
+
+  unsigned NumParamLists = RD->getNumTemplateParameterLists();
+  for (unsigned i = 0; i < NumParamLists; ++i) {
+    TemplateParameterList *Params = RD->getTemplateParameterList(i);
+    for (NamedDecl *Param : *Params) {
+      if (Param->getDeclName()) {
+        S->AddDecl(Param);
+        IdResolver.AddDecl(Param);
+      }
+    }
+  }
+}
+
 void Sema::ActOnReenterTemplateScope(Scope *S, Decl *D) {
   if (!D)
     return;
Index: test/Parser/DelayedTemplateParsing.cpp
===================================================================
--- test/Parser/DelayedTemplateParsing.cpp
+++ test/Parser/DelayedTemplateParsing.cpp
@@ -123,3 +123,47 @@
 
 template <typename T>
 auto invalidTrailingRetType() -> Bogus {} // expected-error {{unknown type name 'Bogus'}}
+
+namespace PR19613 {
+
+struct HeapTypeConfig {
+  static void from_bitset();
+};
+
+template <class Config>
+struct TypeImpl  {
+  struct BitsetType;
+
+  static void Any() {
+    BitsetType::New();
+  }
+};
+
+template<class Config>
+struct TypeImpl<Config>::BitsetType {
+  static void New() {
+    Config::from_bitset();
+  }
+};
+
+static void f() {
+  TypeImpl<HeapTypeConfig>::Any();
+}
+
+template<typename A> struct S {
+  template<typename B> struct T;
+};
+template<typename A> template<typename B> struct S<A>::T {
+  template<typename C, typename D> struct U;
+  template<typename C> struct U<C, C> {
+    template<typename E> static int f() {
+      return sizeof(A) + sizeof(B) + sizeof(C) + sizeof(E);
+    }
+  };
+};
+
+static void g() {
+  S<int>::T<int>::U<int,int>::f<int>();
+}
+
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to