summaryrefslogtreecommitdiffstats
path: root/clang/lib/AST
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST')
-rw-r--r--clang/lib/AST/ASTContext.cpp6
-rw-r--r--clang/lib/AST/Decl.cpp25
-rw-r--r--clang/lib/AST/DeclTemplate.cpp27
3 files changed, 51 insertions, 7 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 86b58177437..7683d5a1607 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -1806,6 +1806,12 @@ Decl *ASTContext::getCanonicalDecl(Decl *D) {
return const_cast<FunctionDecl *>(Function);
}
+ if (FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) {
+ while (FunTmpl->getPreviousDeclaration())
+ FunTmpl = FunTmpl->getPreviousDeclaration();
+ return FunTmpl;
+ }
+
if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
while (Var->getPreviousDeclaration())
Var = Var->getPreviousDeclaration();
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 725b06676e6..e25fe90b4df 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -372,11 +372,6 @@ void FunctionDecl::Destroy(ASTContext& C) {
C.Deallocate(ParamInfo);
- if (FunctionTemplateSpecializationInfo *Info
- = TemplateOrSpecialization
- .dyn_cast<FunctionTemplateSpecializationInfo*>())
- C.Deallocate(Info);
-
Decl::Destroy(C);
}
@@ -564,6 +559,18 @@ bool FunctionDecl::isExternGNUInline(ASTContext &Context) const {
return false;
}
+void
+FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) {
+ PreviousDeclaration = PrevDecl;
+
+ if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) {
+ FunctionTemplateDecl *PrevFunTmpl
+ = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0;
+ assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch");
+ FunTmpl->setPreviousDeclaration(PrevFunTmpl);
+ }
+}
+
/// getOverloadedOperator - Which C++ overloaded operator this
/// function represents, if any.
OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
@@ -595,15 +602,21 @@ FunctionDecl::getTemplateSpecializationArgs() const {
void
FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context,
FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs) {
+ const TemplateArgumentList *TemplateArgs,
+ void *InsertPos) {
FunctionTemplateSpecializationInfo *Info
= TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
if (!Info)
Info = new (Context) FunctionTemplateSpecializationInfo;
+ Info->Function = this;
Info->Template = Template;
Info->TemplateArguments = TemplateArgs;
TemplateOrSpecialization = Info;
+
+ // Insert this function template specialization into the set of known
+ // function template specialiations.
+ Template->getSpecializations().InsertNode(Info, InsertPos);
}
//===----------------------------------------------------------------------===//
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 165672d50f4..f1bd1b67d21 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -81,11 +81,36 @@ FunctionTemplateDecl *FunctionTemplateDecl::Create(ASTContext &C,
DeclContext *DC,
SourceLocation L,
DeclarationName Name,
- TemplateParameterList *Params,
+ TemplateParameterList *Params,
NamedDecl *Decl) {
return new (C) FunctionTemplateDecl(DC, L, Name, Params, Decl);
}
+void FunctionTemplateDecl::Destroy(ASTContext &C) {
+ if (Common *CommonPtr = CommonOrPrev.dyn_cast<Common*>()) {
+ for (llvm::FoldingSet<FunctionTemplateSpecializationInfo>::iterator
+ Spec = CommonPtr->Specializations.begin(),
+ SpecEnd = CommonPtr->Specializations.end();
+ Spec != SpecEnd; ++Spec)
+ C.Deallocate(&*Spec);
+ }
+
+ Decl::Destroy(C);
+}
+
+FunctionTemplateDecl::Common *FunctionTemplateDecl::getCommonPtr() {
+ // Find the first declaration of this function template.
+ FunctionTemplateDecl *First = this;
+ while (First->getPreviousDeclaration())
+ First = First->getPreviousDeclaration();
+
+ if (First->CommonOrPrev.isNull()) {
+ // FIXME: Allocate with the ASTContext
+ First->CommonOrPrev = new Common;
+ }
+ return First->CommonOrPrev.get<Common*>();
+}
+
//===----------------------------------------------------------------------===//
// ClassTemplateDecl Implementation
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud