summaryrefslogtreecommitdiffstats
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp94
1 files changed, 73 insertions, 21 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 5382ab5..3d02150 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -41,7 +41,7 @@ void Attr::Destroy(ASTContext &C) {
TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) {
- return new (C) TranslationUnitDecl();
+ return new (C) TranslationUnitDecl(C);
}
NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
@@ -226,8 +226,7 @@ std::string NamedDecl::getQualifiedNameAsString() const {
if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(Ctx)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- PrintingPolicy Policy;
- Policy.CPlusPlus = true;
+ PrintingPolicy Policy(getASTContext().getLangOptions());
std::string TemplateArgsStr
= TemplateSpecializationType::PrintTemplateArgumentList(
TemplateArgs.getFlatArgumentList(),
@@ -372,20 +371,15 @@ void FunctionDecl::Destroy(ASTContext& C) {
C.Deallocate(ParamInfo);
- if (TemplateSpecializationInfo *Info
- = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>())
- C.Deallocate(Info);
-
Decl::Destroy(C);
}
-Stmt *FunctionDecl::getBody(ASTContext &Context,
- const FunctionDecl *&Definition) const {
+Stmt *FunctionDecl::getBody(const FunctionDecl *&Definition) const {
for (const FunctionDecl *FD = this; FD != 0; FD = FD->PreviousDeclaration) {
if (FD->Body) {
Definition = FD;
- return FD->Body.get(Context.getExternalSource());
+ return FD->Body.get(getASTContext().getExternalSource());
}
}
@@ -417,14 +411,14 @@ bool FunctionDecl::isExternC(ASTContext &Context) const {
// In C, any non-static, non-overloadable function has external
// linkage.
if (!Context.getLangOptions().CPlusPlus)
- return getStorageClass() != Static && !getAttr<OverloadableAttr>(Context);
+ return getStorageClass() != Static && !getAttr<OverloadableAttr>();
for (const DeclContext *DC = getDeclContext(); !DC->isTranslationUnit();
DC = DC->getParent()) {
if (const LinkageSpecDecl *Linkage = dyn_cast<LinkageSpecDecl>(DC)) {
if (Linkage->getLanguage() == LinkageSpecDecl::lang_c)
return getStorageClass() != Static &&
- !getAttr<OverloadableAttr>(Context);
+ !getAttr<OverloadableAttr>();
break;
}
@@ -489,7 +483,7 @@ unsigned FunctionDecl::getBuiltinID(ASTContext &Context) const {
if (isa<LinkageSpecDecl>(getDeclContext()) &&
cast<LinkageSpecDecl>(getDeclContext())->getLanguage()
== LinkageSpecDecl::lang_c &&
- !getAttr<OverloadableAttr>(Context))
+ !getAttr<OverloadableAttr>())
return BuiltinID;
// Not a builtin
@@ -540,12 +534,12 @@ unsigned FunctionDecl::getMinRequiredArguments() const {
}
bool FunctionDecl::hasActiveGNUInlineAttribute(ASTContext &Context) const {
- if (!isInline() || !hasAttr<GNUInlineAttr>(Context))
+ if (!isInline() || !hasAttr<GNUInlineAttr>())
return false;
for (const FunctionDecl *FD = getPreviousDeclaration(); FD;
FD = FD->getPreviousDeclaration()) {
- if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>(Context))
+ if (FD->isInline() && !FD->hasAttr<GNUInlineAttr>())
return false;
}
@@ -557,12 +551,24 @@ bool FunctionDecl::isExternGNUInline(ASTContext &Context) const {
return false;
for (const FunctionDecl *FD = this; FD; FD = FD->getPreviousDeclaration())
- if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>(Context))
+ if (FD->getStorageClass() == Extern && FD->hasAttr<GNUInlineAttr>())
return true;
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 {
@@ -572,18 +578,64 @@ OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const {
return OO_None;
}
+FunctionTemplateDecl *FunctionDecl::getPrimaryTemplate() const {
+ if (FunctionTemplateSpecializationInfo *Info
+ = TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
+ return Info->Template.getPointer();
+ }
+ return 0;
+}
+
+const TemplateArgumentList *
+FunctionDecl::getTemplateSpecializationArgs() const {
+ if (FunctionTemplateSpecializationInfo *Info
+ = TemplateOrSpecialization
+ .dyn_cast<FunctionTemplateSpecializationInfo*>()) {
+ return Info->TemplateArguments;
+ }
+ return 0;
+}
+
void
FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context,
FunctionTemplateDecl *Template,
- const TemplateArgumentList *TemplateArgs) {
- TemplateSpecializationInfo *Info
- = TemplateOrSpecialization.dyn_cast<TemplateSpecializationInfo*>();
+ const TemplateArgumentList *TemplateArgs,
+ void *InsertPos) {
+ FunctionTemplateSpecializationInfo *Info
+ = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
if (!Info)
- Info = new (Context) TemplateSpecializationInfo;
+ Info = new (Context) FunctionTemplateSpecializationInfo;
- Info->Template = Template;
+ Info->Function = this;
+ Info->Template.setPointer(Template);
+ Info->Template.setInt(0); // Implicit instantiation, unless told otherwise
Info->TemplateArguments = TemplateArgs;
TemplateOrSpecialization = Info;
+
+ // Insert this function template specialization into the set of known
+ // function template specialiations.
+ Template->getSpecializations().InsertNode(Info, InsertPos);
+}
+
+bool FunctionDecl::isExplicitSpecialization() const {
+ // FIXME: check this property for explicit specializations of member
+ // functions of class templates.
+ FunctionTemplateSpecializationInfo *Info
+ = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
+ if (!Info)
+ return false;
+
+ return Info->isExplicitSpecialization();
+}
+
+void FunctionDecl::setExplicitSpecialization(bool ES) {
+ // FIXME: set this property for explicit specializations of member functions
+ // of class templates.
+ FunctionTemplateSpecializationInfo *Info
+ = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
+ if (Info)
+ Info->setExplicitSpecialization(ES);
}
//===----------------------------------------------------------------------===//
OpenPOWER on IntegriCloud