r300659 - Revert r300653 and r300650. The underlying commit fixes one issue with

Chandler Carruth via cfe-commits cfe-commits at lists.llvm.org
Tue Apr 18 22:25:13 PDT 2017


Author: chandlerc
Date: Wed Apr 19 00:25:13 2017
New Revision: 300659

URL: http://llvm.org/viewvc/llvm-project?rev=300659&view=rev
Log:
Revert r300653 and r300650. The underlying commit fixes one issue with
modules but exposes much more widespread issues. Example and more
information is on the review thread for r300650.

Original commit summary:
[modules] Properly look up the owning module for an instantiation of a merged template.

Modified:
    cfe/trunk/lib/AST/Decl.cpp
    cfe/trunk/lib/AST/DeclCXX.cpp
    cfe/trunk/lib/Sema/SemaLookup.cpp
    cfe/trunk/test/Modules/Inputs/template-default-args/a.h
    cfe/trunk/test/Modules/template-default-args.cpp

Modified: cfe/trunk/lib/AST/Decl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Decl.cpp?rev=300659&r1=300658&r2=300659&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Decl.cpp (original)
+++ cfe/trunk/lib/AST/Decl.cpp Wed Apr 19 00:25:13 2017
@@ -2251,14 +2251,6 @@ bool VarDecl::checkInitIsICE() const {
   return Eval->IsICE;
 }
 
-template<typename DeclT>
-static DeclT *getDefinitionOrSelf(DeclT *D) {
-  assert(D);
-  if (auto *Def = D->getDefinition())
-    return Def;
-  return D;
-}
-
 VarDecl *VarDecl::getTemplateInstantiationPattern() const {
   // If it's a variable template specialization, find the template or partial
   // specialization from which it was instantiated.
@@ -2270,7 +2262,7 @@ VarDecl *VarDecl::getTemplateInstantiati
           break;
         VTD = NewVTD;
       }
-      return getDefinitionOrSelf(VTD->getTemplatedDecl());
+      return VTD->getTemplatedDecl()->getDefinition();
     }
     if (auto *VTPSD =
             From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
@@ -2279,7 +2271,7 @@ VarDecl *VarDecl::getTemplateInstantiati
           break;
         VTPSD = NewVTPSD;
       }
-      return getDefinitionOrSelf<VarDecl>(VTPSD);
+      return VTPSD->getDefinition();
     }
   }
 
@@ -2288,18 +2280,23 @@ VarDecl *VarDecl::getTemplateInstantiati
       VarDecl *VD = getInstantiatedFromStaticDataMember();
       while (auto *NewVD = VD->getInstantiatedFromStaticDataMember())
         VD = NewVD;
-      return getDefinitionOrSelf(VD);
+      return VD->getDefinition();
     }
   }
 
   if (VarTemplateDecl *VarTemplate = getDescribedVarTemplate()) {
+
     while (VarTemplate->getInstantiatedFromMemberTemplate()) {
       if (VarTemplate->isMemberSpecialization())
         break;
       VarTemplate = VarTemplate->getInstantiatedFromMemberTemplate();
     }
 
-    return getDefinitionOrSelf(VarTemplate->getTemplatedDecl());
+    assert((!VarTemplate->getTemplatedDecl() ||
+            !isTemplateInstantiation(getTemplateSpecializationKind())) &&
+           "couldn't find pattern for variable instantiation");
+
+    return VarTemplate->getTemplatedDecl();
   }
   return nullptr;
 }
@@ -3203,12 +3200,9 @@ bool FunctionDecl::isTemplateInstantiati
    
 FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const {
   // Handle class scope explicit specialization special case.
-  if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization) {
-    if (auto *Spec = getClassScopeSpecializationPattern())
-      return getDefinitionOrSelf(Spec);
-    return nullptr;
-  }
-
+  if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization)
+    return getClassScopeSpecializationPattern();
+  
   // If this is a generic lambda call operator specialization, its 
   // instantiation pattern is always its primary template's pattern
   // even if its primary template was instantiated from another 
@@ -3220,10 +3214,16 @@ FunctionDecl *FunctionDecl::getTemplateI
 
   if (isGenericLambdaCallOperatorSpecialization(
           dyn_cast<CXXMethodDecl>(this))) {
-    assert(getPrimaryTemplate() && "not a generic lambda call operator?");
-    return getDefinitionOrSelf(getPrimaryTemplate()->getTemplatedDecl());
+    assert(getPrimaryTemplate() && "A generic lambda specialization must be "
+                                   "generated from a primary call operator "
+                                   "template");
+    assert(getPrimaryTemplate()->getTemplatedDecl()->getBody() &&
+           "A generic lambda call operator template must always have a body - "
+           "even if instantiated from a prototype (i.e. as written) member "
+           "template");
+    return getPrimaryTemplate()->getTemplatedDecl();
   }
-
+  
   if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) {
     while (Primary->getInstantiatedFromMemberTemplate()) {
       // If we have hit a point where the user provided a specialization of
@@ -3232,14 +3232,11 @@ FunctionDecl *FunctionDecl::getTemplateI
         break;
       Primary = Primary->getInstantiatedFromMemberTemplate();
     }
-
-    return getDefinitionOrSelf(Primary->getTemplatedDecl());
+    
+    return Primary->getTemplatedDecl();
   } 
-
-  if (auto *MFD = getInstantiatedFromMemberFunction())
-    return getDefinitionOrSelf(MFD);
-
-  return nullptr;
+    
+  return getInstantiatedFromMemberFunction();
 }
 
 FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
@@ -3783,7 +3780,7 @@ EnumDecl *EnumDecl::getTemplateInstantia
       EnumDecl *ED = getInstantiatedFromMemberEnum();
       while (auto *NewED = ED->getInstantiatedFromMemberEnum())
         ED = NewED;
-      return getDefinitionOrSelf(ED);
+      return ED;
     }
   }
 

Modified: cfe/trunk/lib/AST/DeclCXX.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/DeclCXX.cpp?rev=300659&r1=300658&r2=300659&view=diff
==============================================================================
--- cfe/trunk/lib/AST/DeclCXX.cpp (original)
+++ cfe/trunk/lib/AST/DeclCXX.cpp Wed Apr 19 00:25:13 2017
@@ -1364,13 +1364,6 @@ CXXRecordDecl::setTemplateSpecialization
 }
 
 const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const {
-  auto GetDefinitionOrSelf =
-      [](const CXXRecordDecl *D) -> const CXXRecordDecl * {
-    if (auto *Def = D->getDefinition())
-      return Def;
-    return D;
-  };
-
   // If it's a class template specialization, find the template or partial
   // specialization from which it was instantiated.
   if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) {
@@ -1381,7 +1374,7 @@ const CXXRecordDecl *CXXRecordDecl::getT
           break;
         CTD = NewCTD;
       }
-      return GetDefinitionOrSelf(CTD->getTemplatedDecl());
+      return CTD->getTemplatedDecl()->getDefinition();
     }
     if (auto *CTPSD =
             From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) {
@@ -1390,7 +1383,7 @@ const CXXRecordDecl *CXXRecordDecl::getT
           break;
         CTPSD = NewCTPSD;
       }
-      return GetDefinitionOrSelf(CTPSD);
+      return CTPSD->getDefinition();
     }
   }
 
@@ -1399,7 +1392,7 @@ const CXXRecordDecl *CXXRecordDecl::getT
       const CXXRecordDecl *RD = this;
       while (auto *NewRD = RD->getInstantiatedFromMemberClass())
         RD = NewRD;
-      return GetDefinitionOrSelf(RD);
+      return RD->getDefinition();
     }
   }
 

Modified: cfe/trunk/lib/Sema/SemaLookup.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaLookup.cpp?rev=300659&r1=300658&r2=300659&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaLookup.cpp (original)
+++ cfe/trunk/lib/Sema/SemaLookup.cpp Wed Apr 19 00:25:13 2017
@@ -1326,6 +1326,12 @@ bool Sema::CppLookupName(LookupResult &R
   return !R.empty();
 }
 
+/// \brief Find the declaration that a class temploid member specialization was
+/// instantiated from, or the member itself if it is an explicit specialization.
+static Decl *getInstantiatedFrom(Decl *D, MemberSpecializationInfo *MSInfo) {
+  return MSInfo->isExplicitSpecialization() ? D : MSInfo->getInstantiatedFrom();
+}
+
 Module *Sema::getOwningModule(Decl *Entity) {
   // If it's imported, grab its owning module.
   Module *M = Entity->getImportedOwningModule();
@@ -1407,14 +1413,20 @@ static Module *getDefiningModule(Sema &S
     if (CXXRecordDecl *Pattern = RD->getTemplateInstantiationPattern())
       Entity = Pattern;
   } else if (EnumDecl *ED = dyn_cast<EnumDecl>(Entity)) {
-    if (auto *Pattern = ED->getTemplateInstantiationPattern())
-      Entity = Pattern;
+    if (MemberSpecializationInfo *MSInfo = ED->getMemberSpecializationInfo())
+      Entity = getInstantiatedFrom(ED, MSInfo);
   } else if (VarDecl *VD = dyn_cast<VarDecl>(Entity)) {
-    if (VarDecl *Pattern = VD->getTemplateInstantiationPattern())
-      Entity = Pattern;
+    // FIXME: Map from variable template specializations back to the template.
+    if (MemberSpecializationInfo *MSInfo = VD->getMemberSpecializationInfo())
+      Entity = getInstantiatedFrom(VD, MSInfo);
   }
 
-  return S.getOwningModule(Entity);
+  // Walk up to the containing context. That might also have been instantiated
+  // from a template.
+  DeclContext *Context = Entity->getDeclContext();
+  if (Context->isFileContext())
+    return S.getOwningModule(Entity);
+  return getDefiningModule(S, cast<Decl>(Context));
 }
 
 llvm::DenseSet<Module*> &Sema::getLookupModules() {

Modified: cfe/trunk/test/Modules/Inputs/template-default-args/a.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/Inputs/template-default-args/a.h?rev=300659&r1=300658&r2=300659&view=diff
==============================================================================
--- cfe/trunk/test/Modules/Inputs/template-default-args/a.h (original)
+++ cfe/trunk/test/Modules/Inputs/template-default-args/a.h Wed Apr 19 00:25:13 2017
@@ -14,11 +14,3 @@ struct FriendL {
   template<typename T> friend struct L;
 };
 END
-
-namespace DeferredLookup {
-  template<typename T, typename U = T> using X = U;
-  template<typename T> void f() { (void) X<T>(); }
-  template<typename T> int n = X<T>();
-  template<typename T> struct S { X<T> xt; enum E : int; };
-  template<typename T> enum S<T>::E : int { a = X<T>() };
-}

Modified: cfe/trunk/test/Modules/template-default-args.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Modules/template-default-args.cpp?rev=300659&r1=300658&r2=300659&view=diff
==============================================================================
--- cfe/trunk/test/Modules/template-default-args.cpp (original)
+++ cfe/trunk/test/Modules/template-default-args.cpp Wed Apr 19 00:25:13 2017
@@ -44,18 +44,3 @@ H<> h; // expected-error {{default argum
 I<> i;
 L<> *l;
 END
-
-namespace DeferredLookup {
-  template<typename T, typename U = T> using X = U;
-  template<typename T> void f() { (void) X<T>(); }
-  template<typename T> int n = X<T>(); // expected-warning {{extension}}
-  template<typename T> struct S { X<T> xt; enum E : int; };
-  template<typename T> enum S<T>::E : int { a = X<T>() };
-
-  void test() {
-    f<int>();
-    n<int> = 1;
-    S<int> s;
-    S<int>::E e = S<int>::E::a;
-  }
-}




More information about the cfe-commits mailing list