[cfe-commits] r97444 - in /cfe/trunk: include/clang/Basic/DiagnosticSemaKinds.td lib/Sema/Sema.h lib/Sema/SemaTemplateInstantiate.cpp lib/Sema/SemaTemplateInstantiateDecl.cpp lib/Sema/TreeTransform.h test/SemaTemplate/instantiate-complete.cpp

Douglas Gregor dgregor at apple.com
Mon Mar 1 07:56:25 PST 2010


Author: dgregor
Date: Mon Mar  1 09:56:25 2010
New Revision: 97444

URL: http://llvm.org/viewvc/llvm-project?rev=97444&view=rev
Log:
When looking for the instantiated declaration that corresponds to a
given declaration in a template, make sure that the context we're
searching through is complete. Fixes PR6376.

Modified:
    cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
    cfe/trunk/lib/Sema/Sema.h
    cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
    cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
    cfe/trunk/lib/Sema/TreeTransform.h
    cfe/trunk/test/SemaTemplate/instantiate-complete.cpp

Modified: cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td?rev=97444&r1=97443&r2=97444&view=diff
==============================================================================
--- cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td (original)
+++ cfe/trunk/include/clang/Basic/DiagnosticSemaKinds.td Mon Mar  1 09:56:25 2010
@@ -455,6 +455,8 @@
   "qualified member access refers to a member in %0">;
 def err_incomplete_member_access : Error<
   "member access into incomplete type %0">;
+def err_incomplete_type : Error<
+  "incomplete type %0 where a complete type is required">;
   
 // C++ class members
 def err_storageclass_invalid_for_member : Error<

Modified: cfe/trunk/lib/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/Sema.h?rev=97444&r1=97443&r2=97444&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/Sema.h (original)
+++ cfe/trunk/lib/Sema/Sema.h Mon Mar  1 09:56:25 2010
@@ -3539,9 +3539,9 @@
                                   const CXXConstructorDecl *Tmpl,
                             const MultiLevelTemplateArgumentList &TemplateArgs);
 
-  NamedDecl *FindInstantiatedDecl(NamedDecl *D,
+  NamedDecl *FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
                           const MultiLevelTemplateArgumentList &TemplateArgs);
-  DeclContext *FindInstantiatedContext(DeclContext *DC,
+  DeclContext *FindInstantiatedContext(SourceLocation Loc, DeclContext *DC,
                           const MultiLevelTemplateArgumentList &TemplateArgs);
 
   // Objective-C declarations.

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=97444&r1=97443&r2=97444&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Mon Mar  1 09:56:25 2010
@@ -540,7 +540,7 @@
       
     /// \brief Transform the given declaration by instantiating a reference to
     /// this declaration.
-    Decl *TransformDecl(Decl *D);
+    Decl *TransformDecl(SourceLocation Loc, Decl *D);
 
     /// \brief Transform the definition of the given declaration by
     /// instantiating it.
@@ -575,7 +575,7 @@
   };
 }
 
-Decl *TemplateInstantiator::TransformDecl(Decl *D) {
+Decl *TemplateInstantiator::TransformDecl(SourceLocation Loc, Decl *D) {
   if (!D)
     return 0;
 
@@ -600,7 +600,7 @@
     // template parameter.
   }
 
-  return SemaRef.FindInstantiatedDecl(cast<NamedDecl>(D), TemplateArgs);
+  return SemaRef.FindInstantiatedDecl(Loc, cast<NamedDecl>(D), TemplateArgs);
 }
 
 Decl *TemplateInstantiator::TransformDefinition(Decl *D) {
@@ -623,7 +623,7 @@
     if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
       QualType T = TemplateArgs(TTP->getDepth(), TTP->getIndex()).getAsType();
       if (T.isNull())
-        return cast_or_null<NamedDecl>(TransformDecl(D));
+        return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
       
       if (const TagType *Tag = T->getAs<TagType>())
         return Tag->getDecl();
@@ -634,7 +634,7 @@
     }
   }
   
-  return cast_or_null<NamedDecl>(TransformDecl(D));
+  return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
 }
 
 VarDecl *
@@ -724,7 +724,8 @@
     // Find the instantiation of the template argument.  This is
     // required for nested templates.
     VD = cast_or_null<ValueDecl>(
-                              getSema().FindInstantiatedDecl(VD, TemplateArgs));
+                            getSema().FindInstantiatedDecl(E->getLocation(),
+                                                           VD, TemplateArgs));
     if (!VD)
       return SemaRef.ExprError();
 

Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp?rev=97444&r1=97443&r2=97444&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiateDecl.cpp Mon Mar  1 09:56:25 2010
@@ -162,7 +162,8 @@
     Typedef->setInvalidDecl();
 
   if (TypedefDecl *Prev = D->getPreviousDeclaration()) {
-    NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(Prev, TemplateArgs);
+    NamedDecl *InstPrev = SemaRef.FindInstantiatedDecl(D->getLocation(), Prev,
+                                                       TemplateArgs);
     Typedef->setPreviousDeclaration(cast<TypedefDecl>(InstPrev));
   }
 
@@ -433,7 +434,8 @@
     // Hack to make this work almost well pending a rewrite.
     if (ND->getDeclContext()->isRecord()) {
       if (!ND->getDeclContext()->isDependentContext()) {
-        NewND = SemaRef.FindInstantiatedDecl(ND, TemplateArgs);
+        NewND = SemaRef.FindInstantiatedDecl(D->getLocation(), ND, 
+                                             TemplateArgs);
       } else {
         // FIXME: Hack to avoid crashing when incorrectly trying to instantiate
         // templated friend declarations. This doesn't produce a correct AST;
@@ -699,7 +701,8 @@
   if (D->isInjectedClassName())
     PrevDecl = cast<CXXRecordDecl>(Owner);
   else if (D->getPreviousDeclaration()) {
-    NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getPreviousDeclaration(),
+    NamedDecl *Prev = SemaRef.FindInstantiatedDecl(D->getLocation(),
+                                                   D->getPreviousDeclaration(),
                                                    TemplateArgs);
     if (!Prev) return 0;
     PrevDecl = cast<CXXRecordDecl>(Prev);
@@ -772,7 +775,8 @@
   if (D->getDeclContext()->isFunctionOrMethod())
     DC = Owner;
   else
-    DC = SemaRef.FindInstantiatedContext(D->getDeclContext(), TemplateArgs);
+    DC = SemaRef.FindInstantiatedContext(D->getLocation(), D->getDeclContext(), 
+                                         TemplateArgs);
 
   FunctionDecl *Function =
       FunctionDecl::Create(SemaRef.Context, DC, D->getLocation(),
@@ -1228,7 +1232,8 @@
          I != E; ++I) {
     UsingShadowDecl *Shadow = *I;
     NamedDecl *InstTarget =
-      cast<NamedDecl>(SemaRef.FindInstantiatedDecl(Shadow->getTargetDecl(),
+      cast<NamedDecl>(SemaRef.FindInstantiatedDecl(Shadow->getLocation(),
+                                                   Shadow->getTargetDecl(),
                                                    TemplateArgs));
 
     if (CheckRedeclaration &&
@@ -1922,9 +1927,11 @@
 
       // Is this an anonymous union?
       if (FieldDecl *UnionInit = Init->getAnonUnionMember())
-        Member = cast<FieldDecl>(FindInstantiatedDecl(UnionInit, TemplateArgs));
+        Member = cast<FieldDecl>(FindInstantiatedDecl(Init->getMemberLocation(),
+                                                      UnionInit, TemplateArgs));
       else
-        Member = cast<FieldDecl>(FindInstantiatedDecl(Init->getMember(),
+        Member = cast<FieldDecl>(FindInstantiatedDecl(Init->getMemberLocation(),
+                                                      Init->getMember(),
                                                       TemplateArgs));
 
       NewInit = BuildMemberInitializer(Member, (Expr **)NewArgs.data(),
@@ -2154,10 +2161,10 @@
 /// within the current instantiation.
 ///
 /// \returns NULL if there was an error
-DeclContext *Sema::FindInstantiatedContext(DeclContext* DC,
+DeclContext *Sema::FindInstantiatedContext(SourceLocation Loc, DeclContext* DC,
                           const MultiLevelTemplateArgumentList &TemplateArgs) {
   if (NamedDecl *D = dyn_cast<NamedDecl>(DC)) {
-    Decl* ID = FindInstantiatedDecl(D, TemplateArgs);
+    Decl* ID = FindInstantiatedDecl(Loc, D, TemplateArgs);
     return cast_or_null<DeclContext>(ID);
   } else return DC;
 }
@@ -2188,7 +2195,7 @@
 /// X<T>::<Kind>::KnownValue) to its instantiation
 /// (X<int>::<Kind>::KnownValue). InstantiateCurrentDeclRef() performs
 /// this mapping from within the instantiation of X<int>.
-NamedDecl *Sema::FindInstantiatedDecl(NamedDecl *D,
+NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
                           const MultiLevelTemplateArgumentList &TemplateArgs) {
   DeclContext *ParentDC = D->getDeclContext();
   if (isa<ParmVarDecl>(D) || isa<NonTypeTemplateParmDecl>(D) ||
@@ -2275,7 +2282,7 @@
   if (!ParentDC->isDependentContext())
     return D;
   
-  ParentDC = FindInstantiatedContext(ParentDC, TemplateArgs);
+  ParentDC = FindInstantiatedContext(Loc, ParentDC, TemplateArgs);
   if (!ParentDC)
     return 0;
 
@@ -2283,6 +2290,20 @@
     // We performed some kind of instantiation in the parent context,
     // so now we need to look into the instantiated parent context to
     // find the instantiation of the declaration D.
+
+    // If our context is a class template specialization, we may need
+    // to instantiate it before performing lookup into that context.
+    if (ClassTemplateSpecializationDecl *Spec
+                       = dyn_cast<ClassTemplateSpecializationDecl>(ParentDC)) {
+      if (!Spec->isDependentContext()) {
+        QualType T = Context.getTypeDeclType(Spec);
+        if (const TagType *Tag = T->getAs<TagType>())
+          if (!Tag->isBeingDefined() &&
+              RequireCompleteType(Loc, T, diag::err_incomplete_type))
+            return 0;
+      }
+    }
+
     NamedDecl *Result = 0;
     if (D->getDeclName()) {
       DeclContext::lookup_result Found = ParentDC->lookup(D->getDeclName());

Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=97444&r1=97443&r2=97444&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Mon Mar  1 09:56:25 2010
@@ -237,13 +237,15 @@
   ///
   /// By default, acts as the identity function on declarations. Subclasses
   /// may override this function to provide alternate behavior.
-  Decl *TransformDecl(Decl *D) { return D; }
+  Decl *TransformDecl(SourceLocation Loc, Decl *D) { return D; }
 
   /// \brief Transform the definition of the given declaration.
   ///
   /// By default, invokes TransformDecl() to transform the declaration.
   /// Subclasses may override this function to provide alternate behavior.
-  Decl *TransformDefinition(Decl *D) { return getDerived().TransformDecl(D); }
+  Decl *TransformDefinition(SourceLocation Loc, Decl *D) { 
+    return getDerived().TransformDecl(D); 
+  }
 
   /// \brief Transform the given declaration, which was the first part of a
   /// nested-name-specifier in a member access expression.
@@ -255,7 +257,7 @@
   /// By default, invokes TransformDecl() to transform the declaration.
   /// Subclasses may override this function to provide alternate behavior.
   NamedDecl *TransformFirstQualifierInScope(NamedDecl *D, SourceLocation Loc) { 
-    return cast_or_null<NamedDecl>(getDerived().TransformDecl(D)); 
+    return cast_or_null<NamedDecl>(getDerived().TransformDecl(Loc, D)); 
   }
   
   /// \brief Transform the given nested-name-specifier.
@@ -1745,7 +1747,8 @@
   case NestedNameSpecifier::Namespace: {
     NamespaceDecl *NS
       = cast_or_null<NamespaceDecl>(
-                            getDerived().TransformDecl(NNS->getAsNamespace()));
+                                    getDerived().TransformDecl(Range.getBegin(),
+                                                       NNS->getAsNamespace()));
     if (!getDerived().AlwaysRebuild() &&
         Prefix == NNS->getPrefix() &&
         NS == NNS->getAsNamespace())
@@ -1822,6 +1825,8 @@
 TemplateName
 TreeTransform<Derived>::TransformTemplateName(TemplateName Name,
                                               QualType ObjectType) {
+  SourceLocation Loc = getDerived().getBaseLocation();
+
   if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
     NestedNameSpecifier *NNS
       = getDerived().TransformNestedNameSpecifier(QTN->getQualifier(),
@@ -1832,7 +1837,7 @@
 
     if (TemplateDecl *Template = QTN->getTemplateDecl()) {
       TemplateDecl *TransTemplate
-        = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
+        = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Loc, Template));
       if (!TransTemplate)
         return TemplateName();
 
@@ -1872,7 +1877,7 @@
 
   if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
     TemplateDecl *TransTemplate
-      = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Template));
+      = cast_or_null<TemplateDecl>(getDerived().TransformDecl(Loc, Template));
     if (!TransTemplate)
       return TemplateName();
 
@@ -1949,7 +1954,7 @@
     if (NamedDecl *ND = dyn_cast<NamedDecl>(Arg.getAsDecl()))
       Name = ND->getDeclName();
     TemporaryBase Rebase(*this, Input.getLocation(), Name);
-    Decl *D = getDerived().TransformDecl(Arg.getAsDecl());
+    Decl *D = getDerived().TransformDecl(Input.getLocation(), Arg.getAsDecl());
     if (!D) return true;
 
     Expr *SourceExpr = Input.getSourceDeclExpression();
@@ -2618,7 +2623,7 @@
                                                  UnresolvedUsingTypeLoc TL,
                                                      QualType ObjectType) {
   UnresolvedUsingType *T = TL.getTypePtr();
-  Decl *D = getDerived().TransformDecl(T->getDecl());
+  Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
   if (!D)
     return QualType();
 
@@ -2643,7 +2648,8 @@
                                                       QualType ObjectType) {
   TypedefType *T = TL.getTypePtr();
   TypedefDecl *Typedef
-    = cast_or_null<TypedefDecl>(getDerived().TransformDecl(T->getDecl()));
+    = cast_or_null<TypedefDecl>(getDerived().TransformDecl(TL.getNameLoc(),
+                                                           T->getDecl()));
   if (!Typedef)
     return QualType();
 
@@ -2748,7 +2754,8 @@
                                                      QualType ObjectType) {
   RecordType *T = TL.getTypePtr();
   RecordDecl *Record
-    = cast_or_null<RecordDecl>(getDerived().TransformDecl(T->getDecl()));
+    = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
+                                                          T->getDecl()));
   if (!Record)
     return QualType();
 
@@ -2772,7 +2779,8 @@
                                                    QualType ObjectType) {
   EnumType *T = TL.getTypePtr();
   EnumDecl *Enum
-    = cast_or_null<EnumDecl>(getDerived().TransformDecl(T->getDecl()));
+    = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
+                                                        T->getDecl()));
   if (!Enum)
     return QualType();
 
@@ -3588,7 +3596,8 @@
   }
 
   ValueDecl *ND
-    = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getDecl()));
+    = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getLocation(),
+                                                         E->getDecl()));
   if (!ND)
     return SemaRef.ExprError();
 
@@ -3797,7 +3806,8 @@
   }
 
   ValueDecl *Member
-    = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberDecl()));
+    = cast_or_null<ValueDecl>(getDerived().TransformDecl(E->getMemberLoc(),
+                                                         E->getMemberDecl()));
   if (!Member)
     return SemaRef.ExprError();
 
@@ -4521,7 +4531,8 @@
 Sema::OwningExprResult
 TreeTransform<Derived>::TransformCXXDefaultArgExpr(CXXDefaultArgExpr *E) {
   ParmVarDecl *Param
-    = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getParam()));
+    = cast_or_null<ParmVarDecl>(getDerived().TransformDecl(E->getLocStart(),
+                                                           E->getParam()));
   if (!Param)
     return SemaRef.ExprError();
 
@@ -4592,7 +4603,8 @@
   CXXConstructorDecl *Constructor = 0;
   if (E->getConstructor()) {
     Constructor = cast_or_null<CXXConstructorDecl>(
-                               getDerived().TransformDecl(E->getConstructor()));
+                                   getDerived().TransformDecl(E->getLocStart(),
+                                                         E->getConstructor()));
     if (!Constructor)
       return SemaRef.ExprError();
   }
@@ -4600,7 +4612,8 @@
   FunctionDecl *OperatorNew = 0;
   if (E->getOperatorNew()) {
     OperatorNew = cast_or_null<FunctionDecl>(
-                               getDerived().TransformDecl(E->getOperatorNew()));
+                                 getDerived().TransformDecl(E->getLocStart(),
+                                                         E->getOperatorNew()));
     if (!OperatorNew)
       return SemaRef.ExprError();
   }
@@ -4608,7 +4621,8 @@
   FunctionDecl *OperatorDelete = 0;
   if (E->getOperatorDelete()) {
     OperatorDelete = cast_or_null<FunctionDecl>(
-                           getDerived().TransformDecl(E->getOperatorDelete()));
+                                   getDerived().TransformDecl(E->getLocStart(),
+                                                       E->getOperatorDelete()));
     if (!OperatorDelete)
       return SemaRef.ExprError();
   }
@@ -4682,7 +4696,8 @@
   FunctionDecl *OperatorDelete = 0;
   if (E->getOperatorDelete()) {
     OperatorDelete = cast_or_null<FunctionDecl>(
-                            getDerived().TransformDecl(E->getOperatorDelete()));
+                                   getDerived().TransformDecl(E->getLocStart(),
+                                                       E->getOperatorDelete()));
     if (!OperatorDelete)
       return SemaRef.ExprError();
   }
@@ -4794,7 +4809,9 @@
   // Transform all the decls.
   for (UnresolvedLookupExpr::decls_iterator I = Old->decls_begin(),
          E = Old->decls_end(); I != E; ++I) {
-    NamedDecl *InstD = static_cast<NamedDecl*>(getDerived().TransformDecl(*I));
+    NamedDecl *InstD = static_cast<NamedDecl*>(
+                                 getDerived().TransformDecl(Old->getNameLoc(),
+                                                            *I));
     if (!InstD) {
       // Silently ignore these if a UsingShadowDecl instantiated to nothing.
       // This can happen because of dependent hiding.
@@ -4933,7 +4950,8 @@
 
   CXXConstructorDecl *Constructor
     = cast_or_null<CXXConstructorDecl>(
-                              getDerived().TransformDecl(E->getConstructor()));
+                                getDerived().TransformDecl(E->getLocStart(),
+                                                         E->getConstructor()));
   if (!Constructor)
     return SemaRef.ExprError();
 
@@ -5013,7 +5031,8 @@
 
   CXXConstructorDecl *Constructor
     = cast_or_null<CXXConstructorDecl>(
-                            getDerived().TransformDecl(E->getConstructor()));
+                                  getDerived().TransformDecl(E->getLocStart(), 
+                                                         E->getConstructor()));
   if (!Constructor)
     return SemaRef.ExprError();
 
@@ -5221,7 +5240,9 @@
   // Transform all the decls.
   for (UnresolvedMemberExpr::decls_iterator I = Old->decls_begin(),
          E = Old->decls_end(); I != E; ++I) {
-    NamedDecl *InstD = static_cast<NamedDecl*>(getDerived().TransformDecl(*I));
+    NamedDecl *InstD = static_cast<NamedDecl*>(
+                                getDerived().TransformDecl(Old->getMemberLoc(),
+                                                           *I));
     if (!InstD) {
       // Silently ignore these if a UsingShadowDecl instantiated to nothing.
       // This can happen because of dependent hiding.
@@ -5319,7 +5340,8 @@
 TreeTransform<Derived>::TransformObjCProtocolExpr(ObjCProtocolExpr *E) {
   ObjCProtocolDecl *Protocol
     = cast_or_null<ObjCProtocolDecl>(
-                                getDerived().TransformDecl(E->getProtocol()));
+                                 getDerived().TransformDecl(E->getLocStart(),
+                                                            E->getProtocol()));
   if (!Protocol)
     return SemaRef.ExprError();
 

Modified: cfe/trunk/test/SemaTemplate/instantiate-complete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaTemplate/instantiate-complete.cpp?rev=97444&r1=97443&r2=97444&view=diff
==============================================================================
--- cfe/trunk/test/SemaTemplate/instantiate-complete.cpp (original)
+++ cfe/trunk/test/SemaTemplate/instantiate-complete.cpp Mon Mar  1 09:56:25 2010
@@ -66,3 +66,20 @@
 void enum_constructors(X1<float> &x1) {
   X3<X1<float> > x3 = x1;
 }
+
+namespace PR6376 {
+  template<typename T, typename U> struct W { };
+
+  template<typename T>
+  struct X {
+    template<typename U>
+    struct apply {
+      typedef W<T, U> type;
+    };
+  };
+  
+  template<typename T, typename U>
+  struct Y : public X<T>::template apply<U>::type { };
+
+  template struct Y<int, float>;
+}





More information about the cfe-commits mailing list