diff options
Diffstat (limited to 'clang/lib')
-rw-r--r-- | clang/lib/AST/Decl.cpp | 55 | ||||
-rw-r--r-- | clang/lib/AST/DeclCXX.cpp | 13 | ||||
-rw-r--r-- | clang/lib/Sema/SemaLookup.cpp | 22 |
3 files changed, 46 insertions, 44 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp index 5fe07065212..2b22e5bb50a 100644 --- a/clang/lib/AST/Decl.cpp +++ b/clang/lib/AST/Decl.cpp @@ -2251,14 +2251,6 @@ bool VarDecl::checkInitIsICE() const { return Eval->IsICE; } -template<typename DeclT> -static DeclT *getDefinitionOrSelf(DeclT *D) { - assert(D); - if (auto *Def = D->getDefinition()) - return Def; - return D; -} - VarDecl *VarDecl::getTemplateInstantiationPattern() const { // If it's a variable template specialization, find the template or partial // specialization from which it was instantiated. @@ -2270,7 +2262,7 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const { break; VTD = NewVTD; } - return getDefinitionOrSelf(VTD->getTemplatedDecl()); + return VTD->getTemplatedDecl()->getDefinition(); } if (auto *VTPSD = From.dyn_cast<VarTemplatePartialSpecializationDecl *>()) { @@ -2279,7 +2271,7 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const { break; VTPSD = NewVTPSD; } - return getDefinitionOrSelf<VarDecl>(VTPSD); + return VTPSD->getDefinition(); } } @@ -2288,18 +2280,23 @@ VarDecl *VarDecl::getTemplateInstantiationPattern() const { VarDecl *VD = getInstantiatedFromStaticDataMember(); while (auto *NewVD = VD->getInstantiatedFromStaticDataMember()) VD = NewVD; - return getDefinitionOrSelf(VD); + return VD->getDefinition(); } } if (VarTemplateDecl *VarTemplate = getDescribedVarTemplate()) { + while (VarTemplate->getInstantiatedFromMemberTemplate()) { if (VarTemplate->isMemberSpecialization()) break; VarTemplate = VarTemplate->getInstantiatedFromMemberTemplate(); } - return getDefinitionOrSelf(VarTemplate->getTemplatedDecl()); + assert((!VarTemplate->getTemplatedDecl() || + !isTemplateInstantiation(getTemplateSpecializationKind())) && + "couldn't find pattern for variable instantiation"); + + return VarTemplate->getTemplatedDecl(); } return nullptr; } @@ -3203,12 +3200,9 @@ bool FunctionDecl::isTemplateInstantiation() const { FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const { // Handle class scope explicit specialization special case. - if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { - if (auto *Spec = getClassScopeSpecializationPattern()) - return getDefinitionOrSelf(Spec); - return nullptr; - } - + if (getTemplateSpecializationKind() == TSK_ExplicitSpecialization) + return getClassScopeSpecializationPattern(); + // If this is a generic lambda call operator specialization, its // instantiation pattern is always its primary template's pattern // even if its primary template was instantiated from another @@ -3220,10 +3214,16 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const { if (isGenericLambdaCallOperatorSpecialization( dyn_cast<CXXMethodDecl>(this))) { - assert(getPrimaryTemplate() && "not a generic lambda call operator?"); - return getDefinitionOrSelf(getPrimaryTemplate()->getTemplatedDecl()); + assert(getPrimaryTemplate() && "A generic lambda specialization must be " + "generated from a primary call operator " + "template"); + assert(getPrimaryTemplate()->getTemplatedDecl()->getBody() && + "A generic lambda call operator template must always have a body - " + "even if instantiated from a prototype (i.e. as written) member " + "template"); + return getPrimaryTemplate()->getTemplatedDecl(); } - + if (FunctionTemplateDecl *Primary = getPrimaryTemplate()) { while (Primary->getInstantiatedFromMemberTemplate()) { // If we have hit a point where the user provided a specialization of @@ -3232,14 +3232,11 @@ FunctionDecl *FunctionDecl::getTemplateInstantiationPattern() const { break; Primary = Primary->getInstantiatedFromMemberTemplate(); } - - return getDefinitionOrSelf(Primary->getTemplatedDecl()); + + return Primary->getTemplatedDecl(); } - - if (auto *MFD = getInstantiatedFromMemberFunction()) - return getDefinitionOrSelf(MFD); - - return nullptr; + + return getInstantiatedFromMemberFunction(); } FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const { @@ -3783,7 +3780,7 @@ EnumDecl *EnumDecl::getTemplateInstantiationPattern() const { EnumDecl *ED = getInstantiatedFromMemberEnum(); while (auto *NewED = ED->getInstantiatedFromMemberEnum()) ED = NewED; - return getDefinitionOrSelf(ED); + return ED; } } diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp index dd8f768c571..2e5cec9c108 100644 --- a/clang/lib/AST/DeclCXX.cpp +++ b/clang/lib/AST/DeclCXX.cpp @@ -1364,13 +1364,6 @@ CXXRecordDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK) { } const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { - auto GetDefinitionOrSelf = - [](const CXXRecordDecl *D) -> const CXXRecordDecl * { - if (auto *Def = D->getDefinition()) - return Def; - return D; - }; - // If it's a class template specialization, find the template or partial // specialization from which it was instantiated. if (auto *TD = dyn_cast<ClassTemplateSpecializationDecl>(this)) { @@ -1381,7 +1374,7 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { break; CTD = NewCTD; } - return GetDefinitionOrSelf(CTD->getTemplatedDecl()); + return CTD->getTemplatedDecl()->getDefinition(); } if (auto *CTPSD = From.dyn_cast<ClassTemplatePartialSpecializationDecl *>()) { @@ -1390,7 +1383,7 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { break; CTPSD = NewCTPSD; } - return GetDefinitionOrSelf(CTPSD); + return CTPSD->getDefinition(); } } @@ -1399,7 +1392,7 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const { const CXXRecordDecl *RD = this; while (auto *NewRD = RD->getInstantiatedFromMemberClass()) RD = NewRD; - return GetDefinitionOrSelf(RD); + return RD->getDefinition(); } } diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp index 0ac3eebcf29..e4d420f3683 100644 --- a/clang/lib/Sema/SemaLookup.cpp +++ b/clang/lib/Sema/SemaLookup.cpp @@ -1326,6 +1326,12 @@ bool Sema::CppLookupName(LookupResult &R, Scope *S) { return !R.empty(); } +/// \brief Find the declaration that a class temploid member specialization was +/// instantiated from, or the member itself if it is an explicit specialization. +static Decl *getInstantiatedFrom(Decl *D, MemberSpecializationInfo *MSInfo) { + return MSInfo->isExplicitSpecialization() ? D : MSInfo->getInstantiatedFrom(); +} + Module *Sema::getOwningModule(Decl *Entity) { // If it's imported, grab its owning module. Module *M = Entity->getImportedOwningModule(); @@ -1407,14 +1413,20 @@ static Module *getDefiningModule(Sema &S, Decl *Entity) { if (CXXRecordDecl *Pattern = RD->getTemplateInstantiationPattern()) Entity = Pattern; } else if (EnumDecl *ED = dyn_cast<EnumDecl>(Entity)) { - if (auto *Pattern = ED->getTemplateInstantiationPattern()) - Entity = Pattern; + if (MemberSpecializationInfo *MSInfo = ED->getMemberSpecializationInfo()) + Entity = getInstantiatedFrom(ED, MSInfo); } else if (VarDecl *VD = dyn_cast<VarDecl>(Entity)) { - if (VarDecl *Pattern = VD->getTemplateInstantiationPattern()) - Entity = Pattern; + // FIXME: Map from variable template specializations back to the template. + if (MemberSpecializationInfo *MSInfo = VD->getMemberSpecializationInfo()) + Entity = getInstantiatedFrom(VD, MSInfo); } - return S.getOwningModule(Entity); + // Walk up to the containing context. That might also have been instantiated + // from a template. + DeclContext *Context = Entity->getDeclContext(); + if (Context->isFileContext()) + return S.getOwningModule(Entity); + return getDefiningModule(S, cast<Decl>(Context)); } llvm::DenseSet<Module*> &Sema::getLookupModules() { |