summaryrefslogtreecommitdiff
path: root/lib/AST/DeclTemplate.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/DeclTemplate.cpp')
-rw-r--r--lib/AST/DeclTemplate.cpp46
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;
}