[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