forked from OSchip/llvm-project
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:
parent
b503705e0d
commit
28de7a9a1e
|
@ -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
|
||||
|
|
|
@ -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'}}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue