Improve the instantiation of static data members in

Sema::RequireCompleteExprType() a bit more, setting the point of
instantiation if needed, and skipping explicit specializations entirely.

llvm-svn: 132547
This commit is contained in:
Douglas Gregor 2011-06-03 14:28:43 +00:00
parent b503705e0d
commit 28de7a9a1e
2 changed files with 41 additions and 12 deletions

View File

@ -15,6 +15,7 @@
#include "clang/Sema/Template.h"
#include "clang/Basic/OpenCL.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTMutationListener.h"
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/DeclObjC.h"
#include "clang/AST/DeclTemplate.h"
@ -3277,14 +3278,31 @@ bool Sema::RequireCompleteExprType(Expr *E, const PartialDiagnostic &PD,
if (VarDecl *Var = dyn_cast<VarDecl>(DRE->getDecl())) {
if (Var->isStaticDataMember() &&
Var->getInstantiatedFromStaticDataMember()) {
InstantiateStaticDataMemberDefinition(E->getExprLoc(), Var);
// Update the type to the newly instantiated definition's type both
// here and within the expression.
if (VarDecl *Def = Var->getDefinition()) {
DRE->setDecl(Def);
T = Def->getType();
DRE->setType(T);
E->setType(T);
MemberSpecializationInfo *MSInfo = Var->getMemberSpecializationInfo();
assert(MSInfo && "Missing member specialization information?");
if (MSInfo->getTemplateSpecializationKind()
!= TSK_ExplicitSpecialization) {
// If we don't already have a point of instantiation, this is it.
if (MSInfo->getPointOfInstantiation().isInvalid()) {
MSInfo->setPointOfInstantiation(E->getLocStart());
// This is a modification of an existing AST node. Notify
// listeners.
if (ASTMutationListener *L = getASTMutationListener())
L->StaticDataMemberInstantiated(Var);
}
InstantiateStaticDataMemberDefinition(E->getExprLoc(), Var);
// Update the type to the newly instantiated definition's type both
// here and within the expression.
if (VarDecl *Def = Var->getDefinition()) {
DRE->setDecl(Def);
T = Def->getType();
DRE->setType(T);
E->setType(T);
}
}
// We still go on to try to complete the type independently, as it

View File

@ -78,21 +78,32 @@ namespace PR7985 {
template<int N> struct integral_c { };
template <typename T, int N>
integral_c<N> array_lengthof(T (&x)[N]) { return integral_c<N>(); }
integral_c<N> array_lengthof(T (&x)[N]) { return integral_c<N>(); } // expected-note 2{{candidate template ignored: failed template argument deduction}}
template<typename T>
struct Data {
int x;
T x;
};
template<typename T>
struct Description {
static const Data data[];
static const Data<T> data[];
};
template<typename T>
const Data Description<T>::data[] = {{ 0 }};
const Data<T> Description<T>::data[] = {{ 1 }}; // expected-error{{cannot initialize a member subobject of type 'int *' with an rvalue of type 'int'}}
template<>
Data<float*> Description<float*>::data[];
void test() {
integral_c<1> ic1 = array_lengthof(Description<int>::data);
(void)sizeof(array_lengthof(Description<float>::data));
sizeof(array_lengthof( // expected-error{{no matching function for call to 'array_lengthof'}}
Description<int*>::data // expected-note{{in instantiation of static data member 'PR7985::Description<int *>::data' requested here}}
));
array_lengthof(Description<float*>::data); // expected-error{{no matching function for call to 'array_lengthof'}}
}
}