diff options
Diffstat (limited to 'lib/AST/DeclTemplate.cpp')
-rw-r--r-- | lib/AST/DeclTemplate.cpp | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/lib/AST/DeclTemplate.cpp b/lib/AST/DeclTemplate.cpp index 848427e7f9d9e..76f29dac1647d 100644 --- a/lib/AST/DeclTemplate.cpp +++ b/lib/AST/DeclTemplate.cpp @@ -149,6 +149,8 @@ void *allocateDefaultArgStorageChain(const ASTContext &C) { // RedeclarableTemplateDecl Implementation //===----------------------------------------------------------------------===// +void RedeclarableTemplateDecl::anchor() {} + RedeclarableTemplateDecl::CommonBase *RedeclarableTemplateDecl::getCommonPtr() const { if (Common) return Common; @@ -300,6 +302,40 @@ ArrayRef<TemplateArgument> FunctionTemplateDecl::getInjectedTemplateArgs() { return llvm::makeArrayRef(CommonPtr->InjectedArgs, Params->size()); } +void FunctionTemplateDecl::mergePrevDecl(FunctionTemplateDecl *Prev) { + using Base = RedeclarableTemplateDecl; + + // If we haven't created a common pointer yet, then it can just be created + // with the usual method. + if (!Base::Common) + return; + + Common *ThisCommon = static_cast<Common *>(Base::Common); + Common *PrevCommon = nullptr; + SmallVector<FunctionTemplateDecl *, 8> PreviousDecls; + for (; Prev; Prev = Prev->getPreviousDecl()) { + if (Prev->Base::Common) { + PrevCommon = static_cast<Common *>(Prev->Base::Common); + break; + } + PreviousDecls.push_back(Prev); + } + + // If the previous redecl chain hasn't created a common pointer yet, then just + // use this common pointer. + if (!PrevCommon) { + for (auto *D : PreviousDecls) + D->Base::Common = ThisCommon; + return; + } + + // Ensure we don't leak any important state. + assert(ThisCommon->Specializations.size() == 0 && + "Can't merge incompatible declarations!"); + + Base::Common = PrevCommon; +} + //===----------------------------------------------------------------------===// // ClassTemplateDecl Implementation //===----------------------------------------------------------------------===// @@ -473,7 +509,7 @@ SourceLocation TemplateTypeParmDecl::getDefaultArgumentLoc() const { SourceRange TemplateTypeParmDecl::getSourceRange() const { if (hasDefaultArgument() && !defaultArgumentWasInherited()) - return SourceRange(getLocStart(), + return SourceRange(getBeginLoc(), getDefaultArgumentInfo()->getTypeLoc().getEndLoc()); else return TypeDecl::getSourceRange(); @@ -712,7 +748,7 @@ ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK, new (Context, DC) ClassTemplateSpecializationDecl( Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc, SpecializedTemplate, Args, PrevDecl); - Result->MayHaveOutOfDateDef = false; + Result->setMayHaveOutOfDateDef(false); Context.getTypeDeclType(Result, PrevDecl); return Result; @@ -723,7 +759,7 @@ ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { auto *Result = new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization); - Result->MayHaveOutOfDateDef = false; + Result->setMayHaveOutOfDateDef(false); return Result; } @@ -830,7 +866,7 @@ Create(ASTContext &Context, TagKind TK,DeclContext *DC, Params, SpecializedTemplate, Args, ASTArgInfos, PrevDecl); Result->setSpecializationKind(TSK_ExplicitSpecialization); - Result->MayHaveOutOfDateDef = false; + Result->setMayHaveOutOfDateDef(false); Context.getInjectedClassNameType(Result, CanonInjectedType); return Result; @@ -840,7 +876,7 @@ ClassTemplatePartialSpecializationDecl * ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C, unsigned ID) { auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C); - Result->MayHaveOutOfDateDef = false; + Result->setMayHaveOutOfDateDef(false); return Result; } |