diff options
author | Vassil Vassilev <v.g.vassilev@gmail.com> | 2016-10-11 13:57:36 +0000 |
---|---|---|
committer | Vassil Vassilev <v.g.vassilev@gmail.com> | 2016-10-11 13:57:36 +0000 |
commit | 4b3e7388d1a90f3e20a90d5624fe54dccca2610f (patch) | |
tree | e0456da083480b6cfbeb8876c417f63657291aed /clang/lib/AST/Decl.cpp | |
parent | 092cfc597f11a8544c6a9616bbae3e1f727838e0 (diff) | |
download | bcm5719-llvm-4b3e7388d1a90f3e20a90d5624fe54dccca2610f.tar.gz bcm5719-llvm-4b3e7388d1a90f3e20a90d5624fe54dccca2610f.zip |
[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: 283882
Diffstat (limited to 'clang/lib/AST/Decl.cpp')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 53 |
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()); |