r219552 - [modules] When instantiating a class member, don't expect to find the previous

Richard Smith richard-llvm at metafoo.co.uk
Fri Oct 10 17:37:17 PDT 2014


Author: rsmith
Date: Fri Oct 10 19:37:16 2014
New Revision: 219552

URL: http://llvm.org/viewvc/llvm-project?rev=219552&view=rev
Log:
[modules] When instantiating a class member, don't expect to find the previous
declaration in the instantiation if the previous declaration came from another
definition of the class template that got merged into the pattern definition.

Modified:
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/test/Modules/Inputs/cxx-templates-a.h
    cfe/trunk/test/Modules/Inputs/cxx-templates-c.h
    cfe/trunk/test/Modules/cxx-templates.cpp

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=219552&r1=219551&r2=219552&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Fri Oct 10 19:37:16 2014
@@ -261,6 +261,24 @@ void Sema::InstantiateAttrs(const MultiL
   }
 }
 
+/// Get the previous declaration of a declaration for the purposes of template
+/// instantiation. If this finds a previous declaration, then the previous
+/// declaration of the instantiation of D should be an instantiation of the
+/// result of this function.
+template<typename DeclT>
+static DeclT *getPreviousDeclForInstantiation(DeclT *D) {
+  DeclT *Result = D->getPreviousDecl();
+
+  // If the declaration is within a class, and the previous declaration was
+  // merged from a different definition of that class, then we don't have a
+  // previous declaration for the purpose of template instantiation.
+  if (Result && isa<CXXRecordDecl>(D->getDeclContext()) &&
+      D->getLexicalDeclContext() != Result->getLexicalDeclContext())
+    return nullptr;
+
+  return Result;
+}
+
 Decl *
 TemplateDeclInstantiator::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
   llvm_unreachable("Translation units cannot be instantiated");
@@ -347,7 +365,7 @@ Decl *TemplateDeclInstantiator::Instanti
     }
   }
 
-  if (TypedefNameDecl *Prev = D->getPreviousDecl()) {
+  if (TypedefNameDecl *Prev = getPreviousDeclForInstantiation(D)) {
     NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev,
                                                        TemplateArgs);
     if (!InstPrev)
@@ -370,13 +388,15 @@ Decl *TemplateDeclInstantiator::Instanti
 
 Decl *TemplateDeclInstantiator::VisitTypedefDecl(TypedefDecl *D) {
   Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/false);
-  Owner->addDecl(Typedef);
+  if (Typedef)
+    Owner->addDecl(Typedef);
   return Typedef;
 }
 
 Decl *TemplateDeclInstantiator::VisitTypeAliasDecl(TypeAliasDecl *D) {
   Decl *Typedef = InstantiateTypedefNameDecl(D, /*IsTypeAlias=*/true);
-  Owner->addDecl(Typedef);
+  if (Typedef)
+    Owner->addDecl(Typedef);
   return Typedef;
 }
 
@@ -394,7 +414,7 @@ TemplateDeclInstantiator::VisitTypeAlias
   TypeAliasDecl *Pattern = D->getTemplatedDecl();
 
   TypeAliasTemplateDecl *PrevAliasTemplate = nullptr;
-  if (Pattern->getPreviousDecl()) {
+  if (getPreviousDeclForInstantiation<TypedefNameDecl>(Pattern)) {
     DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());
     if (!Found.empty()) {
       PrevAliasTemplate = dyn_cast<TypeAliasTemplateDecl>(Found.front());
@@ -714,9 +734,9 @@ Decl *TemplateDeclInstantiator::VisitSta
 
 Decl *TemplateDeclInstantiator::VisitEnumDecl(EnumDecl *D) {
   EnumDecl *PrevDecl = nullptr;
-  if (D->getPreviousDecl()) {
+  if (EnumDecl *PatternPrev = getPreviousDeclForInstantiation(D)) {
     NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(),
-                                                   D->getPreviousDecl(),
+                                                   PatternPrev,
                                                    TemplateArgs);
     if (!Prev) return nullptr;
     PrevDecl = cast<EnumDecl>(Prev);
@@ -878,7 +898,7 @@ Decl *TemplateDeclInstantiator::VisitCla
   CXXRecordDecl *PrevDecl = nullptr;
   ClassTemplateDecl *PrevClassTemplate = nullptr;
 
-  if (!isFriend && Pattern->getPreviousDecl()) {
+  if (!isFriend && getPreviousDeclForInstantiation(Pattern)) {
     DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());
     if (!Found.empty()) {
       PrevClassTemplate = dyn_cast<ClassTemplateDecl>(Found.front());
@@ -1072,7 +1092,7 @@ Decl *TemplateDeclInstantiator::VisitVar
   VarDecl *Pattern = D->getTemplatedDecl();
   VarTemplateDecl *PrevVarTemplate = nullptr;
 
-  if (Pattern->getPreviousDecl()) {
+  if (getPreviousDeclForInstantiation(Pattern)) {
     DeclContext::lookup_result Found = Owner->lookup(Pattern->getDeclName());
     if (!Found.empty())
       PrevVarTemplate = dyn_cast<VarTemplateDecl>(Found.front());
@@ -1182,7 +1202,7 @@ TemplateDeclInstantiator::VisitFunctionT
   if (!isFriend) {
     Owner->addDecl(InstTemplate);
   } else if (InstTemplate->getDeclContext()->isRecord() &&
-             !D->getPreviousDecl()) {
+             !getPreviousDeclForInstantiation(D)) {
     SemaRef.CheckFriendAccess(InstTemplate);
   }
 
@@ -1193,9 +1213,9 @@ Decl *TemplateDeclInstantiator::VisitCXX
   CXXRecordDecl *PrevDecl = nullptr;
   if (D->isInjectedClassName())
     PrevDecl = cast<CXXRecordDecl>(Owner);
-  else if (D->getPreviousDecl()) {
+  else if (CXXRecordDecl *PatternPrev = getPreviousDeclForInstantiation(D)) {
     NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(),
-                                                   D->getPreviousDecl(),
+                                                   PatternPrev,
                                                    TemplateArgs);
     if (!Prev) return nullptr;
     PrevDecl = cast<CXXRecordDecl>(Prev);
@@ -2259,7 +2279,8 @@ Decl *TemplateDeclInstantiator::VisitUsi
     if (CheckRedeclaration) {
       if (SemaRef.CheckUsingShadowDecl(NewUD, InstTarget, Prev, PrevDecl))
         continue;
-    } else if (UsingShadowDecl *OldPrev = Shadow->getPreviousDecl()) {
+    } else if (UsingShadowDecl *OldPrev =
+                   getPreviousDeclForInstantiation(Shadow)) {
       PrevDecl = cast_or_null<UsingShadowDecl>(SemaRef.FindInstantiatedDecl(
           Shadow->getLocation(), OldPrev, TemplateArgs));
     }

Modified: cfe/trunk/test/Modules/Inputs/cxx-templates-a.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-a.h?rev=219552&r1=219551&r2=219552&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-a.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-a.h Fri Oct 10 19:37:16 2014
@@ -97,3 +97,5 @@ struct MergeAnonUnionMember {
   union { int t1; } values;
 };
 inline MergeAnonUnionMember<> maum_a() { return {}; }
+
+template<typename T> struct DontWalkPreviousDeclAfterMerging { struct Inner { typedef T type; }; };

Modified: cfe/trunk/test/Modules/Inputs/cxx-templates-c.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/cxx-templates-c.h?rev=219552&r1=219551&r2=219552&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/cxx-templates-c.h (original)
+++ cfe/trunk/test/Modules/Inputs/cxx-templates-c.h Fri Oct 10 19:37:16 2014
@@ -18,3 +18,6 @@ struct MergeAnonUnionMember {
   union { int t1; } values;
 };
 inline MergeAnonUnionMember<> maum_c() { return {}; }
+
+template<typename T> struct DontWalkPreviousDeclAfterMerging { struct Inner { typedef T type; }; };
+typedef DontWalkPreviousDeclAfterMerging<char>::Inner dwpdam_typedef;

Modified: cfe/trunk/test/Modules/cxx-templates.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/cxx-templates.cpp?rev=219552&r1=219551&r2=219552&view=diff
==============================================================================
--- cfe/trunk/test/Modules/cxx-templates.cpp (original)
+++ cfe/trunk/test/Modules/cxx-templates.cpp Fri Oct 10 19:37:16 2014
@@ -145,6 +145,9 @@ MergeSpecializations<bool>::explicitly_s
 #endif
 
 MergeAnonUnionMember<> maum_main;
+typedef DontWalkPreviousDeclAfterMerging<int> dwpdam_typedef_2;
+dwpdam_typedef::type dwpdam_typedef_use;
+DontWalkPreviousDeclAfterMerging<int>::Inner::type dwpdam;
 
 using AliasTemplateMergingTest = WithAliasTemplate<int>::X<char>;
 





More information about the cfe-commits mailing list