forked from OSchip/llvm-project
variable templates updated for PCH serialization... Still working on test cases...
llvm-svn: 188249
This commit is contained in:
parent
db8d300035
commit
a11bd8a7dc
|
@ -2722,6 +2722,8 @@ public:
|
|||
return getTemplatedDecl()->isThisDeclarationADefinition();
|
||||
}
|
||||
|
||||
VarTemplateDecl *getDefinition();
|
||||
|
||||
/// \brief Create a variable template node.
|
||||
static VarTemplateDecl *Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L, DeclarationName Name,
|
||||
|
|
|
@ -963,6 +963,16 @@ void VarTemplateDecl::DeallocateCommon(void *Ptr) {
|
|||
static_cast<Common *>(Ptr)->~Common();
|
||||
}
|
||||
|
||||
VarTemplateDecl *VarTemplateDecl::getDefinition() {
|
||||
VarTemplateDecl *CurD = this;
|
||||
while (CurD) {
|
||||
if (CurD->isThisDeclarationADefinition())
|
||||
return CurD;
|
||||
CurD = CurD->getPreviousDecl();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
VarTemplateDecl *VarTemplateDecl::Create(ASTContext &C, DeclContext *DC,
|
||||
SourceLocation L, DeclarationName Name,
|
||||
TemplateParameterList *Params,
|
||||
|
|
|
@ -3481,11 +3481,22 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
|
|||
llvm::PointerUnion<VarTemplateDecl *,
|
||||
VarTemplatePartialSpecializationDecl *> PatternPtr =
|
||||
VarSpec->getSpecializedTemplateOrPartial();
|
||||
if (PatternPtr.is<VarTemplatePartialSpecializationDecl *>())
|
||||
if (PatternPtr.is<VarTemplatePartialSpecializationDecl *>()) {
|
||||
PatternDecl = cast<VarDecl>(
|
||||
PatternPtr.get<VarTemplatePartialSpecializationDecl *>());
|
||||
else
|
||||
PatternDecl = (PatternPtr.get<VarTemplateDecl *>())->getTemplatedDecl();
|
||||
|
||||
// Find actual definition
|
||||
if (VarDecl *Def = PatternDecl->getDefinition(getASTContext()))
|
||||
PatternDecl = Def;
|
||||
} else {
|
||||
VarTemplateDecl *PatternTemplate = PatternPtr.get<VarTemplateDecl *>();
|
||||
|
||||
// Find actual definition
|
||||
if (VarTemplateDecl *Def = PatternTemplate->getDefinition())
|
||||
PatternTemplate = Def;
|
||||
|
||||
PatternDecl = PatternTemplate->getTemplatedDecl();
|
||||
}
|
||||
assert(PatternDecl && "instantiating a non-template");
|
||||
}
|
||||
|
||||
|
|
|
@ -735,6 +735,7 @@ void ASTDeclWriter::VisitVarDecl(VarDecl *D) {
|
|||
D->getInitStyle() == VarDecl::CInit &&
|
||||
D->getInit() == 0 &&
|
||||
!isa<ParmVarDecl>(D) &&
|
||||
!isa<VarTemplateSpecializationDecl>(D) &&
|
||||
!D->isConstexpr() &&
|
||||
!SpecInfo)
|
||||
AbbrevToUse = Writer.getDeclVarAbbrev();
|
||||
|
|
|
@ -0,0 +1,172 @@
|
|||
// No PCH:
|
||||
// RUN: %clang_cc1 -pedantic -std=c++1y -include %s -include %s -verify %s -DNONPCH
|
||||
// RUN: %clang_cc1 -pedantic -std=c++1y -include %s -include %s -verify %s -DNONPCH -DERROR
|
||||
//
|
||||
// With PCH:
|
||||
// RUN: %clang_cc1 -pedantic -std=c++1y -emit-pch %s -o %t.a -DHEADER1
|
||||
// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.a -emit-pch %s -o %t.b -DHEADER2
|
||||
// RUN: %clang_cc1 -pedantic -std=c++1y -include-pch %t.b -verify %s -DHEADERUSE
|
||||
|
||||
#ifndef ERROR
|
||||
// expected-no-diagnostics
|
||||
#endif
|
||||
|
||||
#ifdef NONPCH
|
||||
#if !defined(HEADER1)
|
||||
#define HEADER1
|
||||
#undef HEADER2
|
||||
#undef HEADERUSE
|
||||
#elif !defined(HEADER2)
|
||||
#define HEADER2
|
||||
#undef HEADERUSE
|
||||
#else
|
||||
#define HEADERUSE
|
||||
#undef HEADER1
|
||||
#undef HEADER2
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// *** HEADER1: First header file
|
||||
#if defined(HEADER1) && !defined(HEADER2) && !defined(HEADERUSE)
|
||||
|
||||
template<typename T> T var0a = T();
|
||||
template<typename T> extern T var0b;
|
||||
|
||||
namespace join {
|
||||
template<typename T> T va = T(100);
|
||||
template<typename T> extern T vb;
|
||||
|
||||
namespace diff_types {
|
||||
#ifdef ERROR
|
||||
template<typename T> extern float err0;
|
||||
template<typename T> extern T err1;
|
||||
#endif
|
||||
template<typename T> extern T def;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace spec {
|
||||
template<typename T> constexpr T va = T(10);
|
||||
template<> constexpr float va<float> = 1.5;
|
||||
template constexpr int va<int>;
|
||||
|
||||
template<typename T> T vb = T();
|
||||
template<> constexpr float vb<float> = 1.5;
|
||||
|
||||
template<typename T> T vc = T();
|
||||
|
||||
template<typename T> constexpr T vd = T(10);
|
||||
template<typename T> T* vd<T> = new T();
|
||||
}
|
||||
|
||||
namespace spec_join1 {
|
||||
template<typename T> T va = T(10);
|
||||
template<> extern float va<float>;
|
||||
extern template int va<int>;
|
||||
|
||||
template<typename T> T vb = T(10);
|
||||
template<> extern float vb<float>;
|
||||
|
||||
template<typename T> T vc = T(10);
|
||||
|
||||
template<typename T> T vd = T(10);
|
||||
template<typename T> extern T* vd<T>;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// *** HEADER2: Second header file -- including HEADER1
|
||||
#if defined(HEADER2) && !defined(HEADERUSE)
|
||||
|
||||
namespace join {
|
||||
template<typename T> extern T va;
|
||||
template<> constexpr float va<float> = 2.5;
|
||||
|
||||
template<typename T> T vb = T(100);
|
||||
|
||||
namespace diff_types {
|
||||
#ifdef ERROR
|
||||
template<typename T> extern T err0; // expected-error {{redefinition of 'err0' with a different type: 'T' vs 'float'}} // expected-note@42 {{previous definition is here}}
|
||||
template<typename T> extern float err1; // expected-error {{redefinition of 'err1' with a different type: 'float' vs 'T'}} // expected-note@43 {{previous definition is here}}
|
||||
#endif
|
||||
template<typename T> extern T def;
|
||||
}
|
||||
}
|
||||
|
||||
namespace spec_join1 {
|
||||
template<typename T> extern T va;
|
||||
template<> float va<float> = 1.5;
|
||||
extern template int va<int>;
|
||||
|
||||
template<> float vb<float> = 1.5;
|
||||
template int vb<int>;
|
||||
|
||||
template<> float vc<float> = 1.5;
|
||||
template int vc<int>;
|
||||
|
||||
template<typename T> extern T vd;
|
||||
template<typename T> T* vd<T> = new T();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// *** HEADERUSE: File using both header files -- including HEADER2
|
||||
#ifdef HEADERUSE
|
||||
|
||||
template int var0a<int>;
|
||||
float fvara = var0a<float>;
|
||||
|
||||
template<typename T> extern T var0a;
|
||||
|
||||
template<typename T> T var0b = T();
|
||||
template int var0b<int>;
|
||||
float fvarb = var0b<float>;
|
||||
|
||||
namespace join {
|
||||
template const int va<const int>;
|
||||
template<> const int va<int> = 50;
|
||||
static_assert(va<float> == 2.5, "");
|
||||
static_assert(va<int> == 50, "");
|
||||
|
||||
template<> constexpr float vb<float> = 2.5;
|
||||
template const int vb<const int>;
|
||||
static_assert(vb<float> == 2.5, "");
|
||||
static_assert(vb<const int> == 100, "");
|
||||
|
||||
namespace diff_types {
|
||||
template<typename T> T def = T();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
namespace spec {
|
||||
static_assert(va<float> == 1.5, "");
|
||||
static_assert(va<int> == 10, "");
|
||||
|
||||
template<typename T> T* vb<T> = new T();
|
||||
int* intpb = vb<int>;
|
||||
static_assert(vb<float> == 1.5, "");
|
||||
|
||||
template<typename T> T* vc<T> = new T();
|
||||
template<> constexpr float vc<float> = 1.5;
|
||||
int* intpc = vc<int>;
|
||||
static_assert(vc<float> == 1.5, "");
|
||||
|
||||
char* intpd = vd<char>;
|
||||
}
|
||||
|
||||
namespace spec_join1 {
|
||||
template int va<int>;
|
||||
int a = va<int>;
|
||||
|
||||
template<typename T> extern T vb;
|
||||
int b = vb<int>;
|
||||
|
||||
int* intpb = vd<int>;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
|
@ -14,6 +14,11 @@ T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
|
|||
template<typename T>
|
||||
CONST T cpi = T(3.1415926535897932385); // expected-note {{template is declared here}}
|
||||
|
||||
template<typename T> extern CONST T vc;
|
||||
#ifdef CXX11
|
||||
// expected-error@-2 {{constexpr variable declaration must be a definition}}
|
||||
#endif
|
||||
|
||||
namespace use_in_top_level_funcs {
|
||||
|
||||
void good() {
|
||||
|
|
Loading…
Reference in New Issue