diff options
author | Douglas Gregor <dgregor@apple.com> | 2011-06-03 14:28:43 +0000 |
---|---|---|
committer | Douglas Gregor <dgregor@apple.com> | 2011-06-03 14:28:43 +0000 |
commit | 28de7a9a1e7e39d01bd92b8e8575cb3c35b49b06 (patch) | |
tree | 83fe9fa6c65a32de089d31036b2967142cd649f9 /clang | |
parent | b503705e0d37fadb28287232ccadb4fdf7f546e5 (diff) | |
download | bcm5719-llvm-28de7a9a1e7e39d01bd92b8e8575cb3c35b49b06.tar.gz bcm5719-llvm-28de7a9a1e7e39d01bd92b8e8575cb3c35b49b06.zip |
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
Diffstat (limited to 'clang')
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 34 | ||||
-rw-r--r-- | clang/test/SemaTemplate/instantiate-init.cpp | 19 |
2 files changed, 41 insertions, 12 deletions
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 02bcb2b89e1..3c4e09ae869 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -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 diff --git a/clang/test/SemaTemplate/instantiate-init.cpp b/clang/test/SemaTemplate/instantiate-init.cpp index ce2c1633b14..f0ca9a5b21e 100644 --- a/clang/test/SemaTemplate/instantiate-init.cpp +++ b/clang/test/SemaTemplate/instantiate-init.cpp @@ -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'}} } } |