summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST/Decl.cpp
diff options
context:
space:
mode:
authorVassil Vassilev <v.g.vassilev@gmail.com>2016-10-12 11:57:08 +0000
committerVassil Vassilev <v.g.vassilev@gmail.com>2016-10-12 11:57:08 +0000
commitbb8fe3175a6ac29a36a62ed53bbc96bbc6d5bbc5 (patch)
treedbaa612cc64edccf0fdf5e2ddc9bb34c0e7124b3 /clang/lib/AST/Decl.cpp
parent06cfa99268ecab69900300c237e010d01a0db881 (diff)
downloadbcm5719-llvm-bb8fe3175a6ac29a36a62ed53bbc96bbc6d5bbc5.tar.gz
bcm5719-llvm-bb8fe3175a6ac29a36a62ed53bbc96bbc6d5bbc5.zip
Reinstate r283887 and r283882.
Original message: "[modules] PR28752: Do not instantiate variable declarations which are not visible. https://reviews.llvm.org/D24508 Patch developed in collaboration with Richard Smith!" llvm-svn: 284008
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r--clang/lib/AST/Decl.cpp53
1 files changed, 53 insertions, 0 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index e330e31d47f..3d601ee40e0 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1926,6 +1926,9 @@ VarDecl::isThisDeclarationADefinition(ASTContext &C) const {
//
// FIXME: How do you declare (but not define) a partial specialization of
// a static data member template outside the containing class?
+ if (isThisDeclarationADemotedDefinition())
+ return DeclarationOnly;
+
if (isStaticDataMember()) {
if (isOutOfLine() &&
!(getCanonicalDecl()->isInline() &&
@@ -2250,6 +2253,56 @@ bool VarDecl::checkInitIsICE() const {
return Eval->IsICE;
}
+VarDecl *VarDecl::getTemplateInstantiationPattern() const {
+ // If it's a variable template specialization, find the template or partial
+ // specialization from which it was instantiated.
+ if (auto *VDTemplSpec = dyn_cast<VarTemplateSpecializationDecl>(this)) {
+ auto From = VDTemplSpec->getInstantiatedFrom();
+ if (auto *VTD = From.dyn_cast<VarTemplateDecl *>()) {
+ while (auto *NewVTD = VTD->getInstantiatedFromMemberTemplate()) {
+ if (NewVTD->isMemberSpecialization())
+ break;
+ VTD = NewVTD;
+ }
+ return VTD->getTemplatedDecl()->getDefinition();
+ }
+ if (auto *VTPSD =
+ From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) {
+ while (auto *NewVTPSD = VTPSD->getInstantiatedFromMember()) {
+ if (NewVTPSD->isMemberSpecialization())
+ break;
+ VTPSD = NewVTPSD;
+ }
+ return VTPSD->getDefinition();
+ }
+ }
+
+ if (MemberSpecializationInfo *MSInfo = getMemberSpecializationInfo()) {
+ if (isTemplateInstantiation(MSInfo->getTemplateSpecializationKind())) {
+ VarDecl *VD = getInstantiatedFromStaticDataMember();
+ while (auto *NewVD = VD->getInstantiatedFromStaticDataMember())
+ VD = NewVD;
+ return VD->getDefinition();
+ }
+ }
+
+ if (VarTemplateDecl *VarTemplate = getDescribedVarTemplate()) {
+
+ while (VarTemplate->getInstantiatedFromMemberTemplate()) {
+ if (VarTemplate->isMemberSpecialization())
+ break;
+ VarTemplate = VarTemplate->getInstantiatedFromMemberTemplate();
+ }
+
+ assert((!VarTemplate->getTemplatedDecl() ||
+ !isTemplateInstantiation(getTemplateSpecializationKind())) &&
+ "couldn't find pattern for variable instantiation");
+
+ return VarTemplate->getTemplatedDecl();
+ }
+ return nullptr;
+}
+
VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const {
if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo())
return cast<VarDecl>(MSI->getInstantiatedFrom());
OpenPOWER on IntegriCloud