summaryrefslogtreecommitdiff
path: root/lib/AST/Decl.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r--lib/AST/Decl.cpp272
1 files changed, 101 insertions, 171 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp
index 149938fc5c86..b7be02d74533 100644
--- a/lib/AST/Decl.cpp
+++ b/lib/AST/Decl.cpp
@@ -97,8 +97,14 @@ static Linkage getLinkageForTemplateArgumentList(const TemplateArgument *Args,
return L;
}
+static Linkage
+getLinkageForTemplateArgumentList(const TemplateArgumentList &TArgs) {
+ return getLinkageForTemplateArgumentList(TArgs.getFlatArgumentList(),
+ TArgs.flat_size());
+}
+
static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
- assert(D->getDeclContext()->getLookupContext()->isFileContext() &&
+ assert(D->getDeclContext()->getRedeclContext()->isFileContext() &&
"Not a name having namespace scope");
ASTContext &Context = D->getASTContext();
@@ -110,7 +116,7 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
// (This bullet corresponds to C99 6.2.2p3.)
if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
// Explicitly declared static.
- if (Var->getStorageClass() == VarDecl::Static)
+ if (Var->getStorageClass() == SC_Static)
return InternalLinkage;
// - an object or reference that is explicitly declared const
@@ -119,8 +125,8 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
// (there is no equivalent in C99)
if (Context.getLangOptions().CPlusPlus &&
Var->getType().isConstant(Context) &&
- Var->getStorageClass() != VarDecl::Extern &&
- Var->getStorageClass() != VarDecl::PrivateExtern) {
+ Var->getStorageClass() != SC_Extern &&
+ Var->getStorageClass() != SC_PrivateExtern) {
bool FoundExtern = false;
for (const VarDecl *PrevVar = Var->getPreviousDeclaration();
PrevVar && !FoundExtern;
@@ -143,7 +149,7 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
Function = cast<FunctionDecl>(D);
// Explicitly declared static.
- if (Function->getStorageClass() == FunctionDecl::Static)
+ if (Function->getStorageClass() == SC_Static)
return InternalLinkage;
} else if (const FieldDecl *Field = dyn_cast<FieldDecl>(D)) {
// - a data member of an anonymous union.
@@ -159,8 +165,8 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
// - an object or reference, unless it has internal linkage; or
if (const VarDecl *Var = dyn_cast<VarDecl>(D)) {
if (!Context.getLangOptions().CPlusPlus &&
- (Var->getStorageClass() == VarDecl::Extern ||
- Var->getStorageClass() == VarDecl::PrivateExtern)) {
+ (Var->getStorageClass() == SC_Extern ||
+ Var->getStorageClass() == SC_PrivateExtern)) {
// C99 6.2.2p4:
// For an identifier declared with the storage-class specifier
// extern in a scope in which a prior declaration of that
@@ -194,9 +200,9 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
// as if it were declared with the storage-class specifier
// extern.
if (!Context.getLangOptions().CPlusPlus &&
- (Function->getStorageClass() == FunctionDecl::Extern ||
- Function->getStorageClass() == FunctionDecl::PrivateExtern ||
- Function->getStorageClass() == FunctionDecl::None)) {
+ (Function->getStorageClass() == SC_Extern ||
+ Function->getStorageClass() == SC_PrivateExtern ||
+ Function->getStorageClass() == SC_None)) {
// C99 6.2.2p4:
// For an identifier declared with the storage-class specifier
// extern in a scope in which a prior declaration of that
@@ -219,10 +225,7 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
= Function->getTemplateSpecializationInfo()) {
Linkage L = SpecInfo->getTemplate()->getLinkage();
const TemplateArgumentList &TemplateArgs = *SpecInfo->TemplateArguments;
- L = minLinkage(L,
- getLinkageForTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size()));
+ L = minLinkage(L, getLinkageForTemplateArgumentList(TemplateArgs));
return L;
}
@@ -245,9 +248,7 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
if (const ClassTemplateSpecializationDecl *Spec
= dyn_cast<ClassTemplateSpecializationDecl>(Tag)) {
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
- Linkage L = getLinkageForTemplateArgumentList(
- TemplateArgs.getFlatArgumentList(),
- TemplateArgs.flat_size());
+ Linkage L = getLinkageForTemplateArgumentList(TemplateArgs);
return minLinkage(L, Spec->getSpecializedTemplate()->getLinkage());
}
@@ -279,6 +280,47 @@ static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) {
return NoLinkage;
}
+static Linkage getLinkageForClassMember(const NamedDecl *D) {
+ if (!(isa<CXXMethodDecl>(D) ||
+ isa<VarDecl>(D) ||
+ (isa<TagDecl>(D) &&
+ (D->getDeclName() || cast<TagDecl>(D)->getTypedefForAnonDecl()))))
+ return NoLinkage;
+
+ // Class members only have linkage if their class has external linkage.
+ Linkage L = cast<RecordDecl>(D->getDeclContext())->getLinkage();
+ if (!isExternalLinkage(L)) return NoLinkage;
+
+ // If the class already has unique-external linkage, we can't improve.
+ if (L == UniqueExternalLinkage) return UniqueExternalLinkage;
+
+ // If this is a method template specialization, use the linkage for
+ // the template parameters and arguments.
+ if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) {
+ if (FunctionTemplateSpecializationInfo *SpecInfo
+ = MD->getTemplateSpecializationInfo()) {
+ Linkage ArgLinkage =
+ getLinkageForTemplateArgumentList(*SpecInfo->TemplateArguments);
+ Linkage ParamLinkage =
+ getLinkageForTemplateParameterList(
+ SpecInfo->getTemplate()->getTemplateParameters());
+ return minLinkage(ArgLinkage, ParamLinkage);
+ }
+
+ // Similarly for member class template specializations.
+ } else if (const ClassTemplateSpecializationDecl *Spec
+ = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
+ Linkage ArgLinkage =
+ getLinkageForTemplateArgumentList(Spec->getTemplateArgs());
+ Linkage ParamLinkage =
+ getLinkageForTemplateParameterList(
+ Spec->getSpecializedTemplate()->getTemplateParameters());
+ return minLinkage(ArgLinkage, ParamLinkage);
+ }
+
+ return ExternalLinkage;
+}
+
Linkage NamedDecl::getLinkage() const {
// Objective-C: treat all Objective-C declarations as having external
@@ -303,7 +345,7 @@ Linkage NamedDecl::getLinkage() const {
}
// Handle linkage for namespace-scope names.
- if (getDeclContext()->getLookupContext()->isFileContext())
+ if (getDeclContext()->getRedeclContext()->isFileContext())
if (Linkage L = getLinkageForNamespaceScopeDecl(this))
return L;
@@ -314,14 +356,8 @@ Linkage NamedDecl::getLinkage() const {
// that the class or enumeration has the typedef name for linkage
// purposes (7.1.3), has external linkage if the name of the class
// has external linkage.
- if (getDeclContext()->isRecord() &&
- (isa<CXXMethodDecl>(this) || isa<VarDecl>(this) ||
- (isa<TagDecl>(this) &&
- (getDeclName() || cast<TagDecl>(this)->getTypedefForAnonDecl())))) {
- Linkage L = cast<RecordDecl>(getDeclContext())->getLinkage();
- if (isExternalLinkage(L))
- return L;
- }
+ if (getDeclContext()->isRecord())
+ return getLinkageForClassMember(this);
// C++ [basic.link]p6:
// The name of a function declared in block scope and the name of
@@ -347,8 +383,8 @@ Linkage NamedDecl::getLinkage() const {
}
if (const VarDecl *Var = dyn_cast<VarDecl>(this))
- if (Var->getStorageClass() == VarDecl::Extern ||
- Var->getStorageClass() == VarDecl::PrivateExtern) {
+ if (Var->getStorageClass() == SC_Extern ||
+ Var->getStorageClass() == SC_PrivateExtern) {
if (Var->getPreviousDeclaration())
if (Linkage L = Var->getPreviousDeclaration()->getLinkage())
return L;
@@ -531,13 +567,6 @@ static SourceLocation getTemplateOrInnerLocStart(const DeclT *decl) {
return decl->getInnerLocStart();
}
-DeclaratorDecl::~DeclaratorDecl() {}
-void DeclaratorDecl::Destroy(ASTContext &C) {
- if (hasExtInfo())
- C.Deallocate(getExtInfo());
- ValueDecl::Destroy(C);
-}
-
SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const {
TypeSourceInfo *TSI = getTypeSourceInfo();
if (TSI) return TSI->getTypeLoc().getBeginLoc();
@@ -602,24 +631,18 @@ QualifierInfo::setTemplateParameterListsInfo(ASTContext &Context,
}
}
-void QualifierInfo::Destroy(ASTContext &Context) {
- // FIXME: Deallocate template parameter lists themselves!
- if (TemplParamLists)
- Context.Deallocate(TemplParamLists);
-}
-
//===----------------------------------------------------------------------===//
// VarDecl Implementation
//===----------------------------------------------------------------------===//
const char *VarDecl::getStorageClassSpecifierString(StorageClass SC) {
switch (SC) {
- case VarDecl::None: break;
- case VarDecl::Auto: return "auto"; break;
- case VarDecl::Extern: return "extern"; break;
- case VarDecl::PrivateExtern: return "__private_extern__"; break;
- case VarDecl::Register: return "register"; break;
- case VarDecl::Static: return "static"; break;
+ case SC_None: break;
+ case SC_Auto: return "auto"; break;
+ case SC_Extern: return "extern"; break;
+ case SC_PrivateExtern: return "__private_extern__"; break;
+ case SC_Register: return "register"; break;
+ case SC_Static: return "static"; break;
}
assert(0 && "Invalid storage class");
@@ -632,22 +655,6 @@ VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L,
return new (C) VarDecl(Var, DC, L, Id, T, TInfo, S, SCAsWritten);
}
-void VarDecl::Destroy(ASTContext& C) {
- Expr *Init = getInit();
- if (Init) {
- Init->Destroy(C);
- if (EvaluatedStmt *Eval = this->Init.dyn_cast<EvaluatedStmt *>()) {
- Eval->~EvaluatedStmt();
- C.Deallocate(Eval);
- }
- }
- this->~VarDecl();
- DeclaratorDecl::Destroy(C);
-}
-
-VarDecl::~VarDecl() {
-}
-
SourceLocation VarDecl::getInnerLocStart() const {
SourceLocation Start = getTypeSpecStartLoc();
if (Start.isInvalid())
@@ -665,14 +672,14 @@ bool VarDecl::isExternC() const {
ASTContext &Context = getASTContext();
if (!Context.getLangOptions().CPlusPlus)
return (getDeclContext()->isTranslationUnit() &&
- getStorageClass() != Static) ||
+ getStorageClass() != SC_Static) ||
(getDeclContext()->isFunctionOrMethod() && hasExternalStorage());
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;
+ return getStorageClass() != SC_Static;
break;
}
@@ -717,8 +724,8 @@ VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const {
if (hasExternalStorage())
return DeclarationOnly;
- if (getStorageClassAsWritten() == Extern ||
- getStorageClassAsWritten() == PrivateExtern) {
+ if (getStorageClassAsWritten() == SC_Extern ||
+ getStorageClassAsWritten() == SC_PrivateExtern) {
for (const VarDecl *PrevVar = getPreviousDeclaration();
PrevVar; PrevVar = PrevVar->getPreviousDeclaration()) {
if (PrevVar->getLinkage() == InternalLinkage && PrevVar->hasInit())
@@ -912,28 +919,6 @@ SourceRange ParmVarDecl::getDefaultArgRange() const {
// FunctionDecl Implementation
//===----------------------------------------------------------------------===//
-void FunctionDecl::Destroy(ASTContext& C) {
- if (Body && Body.isOffset())
- Body.get(C.getExternalSource())->Destroy(C);
-
- for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
- (*I)->Destroy(C);
-
- FunctionTemplateSpecializationInfo *FTSInfo
- = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>();
- if (FTSInfo)
- C.Deallocate(FTSInfo);
-
- MemberSpecializationInfo *MSInfo
- = TemplateOrSpecialization.dyn_cast<MemberSpecializationInfo*>();
- if (MSInfo)
- C.Deallocate(MSInfo);
-
- C.Deallocate(ParamInfo);
-
- DeclaratorDecl::Destroy(C);
-}
-
void FunctionDecl::getNameForDiagnostic(std::string &S,
const PrintingPolicy &Policy,
bool Qualified) const {
@@ -984,7 +969,7 @@ void FunctionDecl::setBody(Stmt *B) {
bool FunctionDecl::isMain() const {
ASTContext &Context = getASTContext();
return !Context.getLangOptions().Freestanding &&
- getDeclContext()->getLookupContext()->isTranslationUnit() &&
+ getDeclContext()->getRedeclContext()->isTranslationUnit() &&
getIdentifier() && getIdentifier()->isStr("main");
}
@@ -993,17 +978,20 @@ bool FunctionDecl::isExternC() const {
// In C, any non-static, non-overloadable function has external
// linkage.
if (!Context.getLangOptions().CPlusPlus)
- return getStorageClass() != Static && !getAttr<OverloadableAttr>();
+ return getStorageClass() != SC_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 &&
+ return getStorageClass() != SC_Static &&
!getAttr<OverloadableAttr>();
break;
}
+
+ if (DC->isRecord())
+ break;
}
return false;
@@ -1013,7 +1001,7 @@ bool FunctionDecl::isGlobal() const {
if (const CXXMethodDecl *Method = dyn_cast<CXXMethodDecl>(this))
return Method->isStatic();
- if (getStorageClass() == Static)
+ if (getStorageClass() == SC_Static)
return false;
for (const DeclContext *DC = getDeclContext();
@@ -1072,7 +1060,7 @@ unsigned FunctionDecl::getBuiltinID() const {
// function or whether it just has the same name.
// If this is a static function, it's not a builtin.
- if (getStorageClass() == Static)
+ if (getStorageClass() == SC_Static)
return 0;
// If this function is at translation-unit scope and we're not in
@@ -1206,7 +1194,7 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
for (redecl_iterator Redecl = redecls_begin(), RedeclEnd = redecls_end();
Redecl != RedeclEnd;
++Redecl) {
- if (Redecl->isInlineSpecified() && Redecl->getStorageClass() != Extern)
+ if (Redecl->isInlineSpecified() && Redecl->getStorageClass() != SC_Extern)
return true;
}
@@ -1225,7 +1213,7 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const {
if (!Redecl->getLexicalDeclContext()->isTranslationUnit())
continue;
- if (!Redecl->isInlineSpecified() || Redecl->getStorageClass() == Extern)
+ if (!Redecl->isInlineSpecified() || Redecl->getStorageClass() == SC_Extern)
return true; // Not an inline definition
}
@@ -1400,14 +1388,15 @@ FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template,
if (InsertPos)
Template->getSpecializations().InsertNode(Info, InsertPos);
else {
- // Try to insert the new node. If there is an existing node, remove it
- // first.
+ // Try to insert the new node. If there is an existing node, leave it, the
+ // set will contain the canonical decls while
+ // FunctionTemplateDecl::findSpecialization will return
+ // the most recent redeclarations.
FunctionTemplateSpecializationInfo *Existing
= Template->getSpecializations().GetOrInsertNode(Info);
- if (Existing) {
- Template->getSpecializations().RemoveNode(Existing);
- Template->getSpecializations().GetOrInsertNode(Info);
- }
+ (void)Existing;
+ assert((!Existing || Existing->Function->isCanonicalDecl()) &&
+ "Set is supposed to only contain canonical decls");
}
}
@@ -1564,12 +1553,6 @@ bool FieldDecl::isAnonymousStructOrUnion() const {
// TagDecl Implementation
//===----------------------------------------------------------------------===//
-void TagDecl::Destroy(ASTContext &C) {
- if (hasExtInfo())
- C.Deallocate(getExtInfo());
- TypeDecl::Destroy(C);
-}
-
SourceLocation TagDecl::getOuterLocStart() const {
return getTemplateOrInnerLocStart(this);
}
@@ -1590,14 +1573,7 @@ void TagDecl::setTypedefForAnonDecl(TypedefDecl *TDD) {
}
void TagDecl::startDefinition() {
- if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
- TagT->decl.setPointer(this);
- TagT->decl.setInt(1);
- } else if (InjectedClassNameType *Injected
- = const_cast<InjectedClassNameType *>(
- TypeForDecl->getAs<InjectedClassNameType>())) {
- Injected->Decl = cast<CXXRecordDecl>(this);
- }
+ IsBeingDefined = true;
if (isa<CXXRecordDecl>(this)) {
CXXRecordDecl *D = cast<CXXRecordDecl>(this);
@@ -1614,17 +1590,7 @@ void TagDecl::completeDefinition() {
"definition completed but not started");
IsDefinition = true;
- if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) {
- assert(TagT->decl.getPointer() == this &&
- "Attempt to redefine a tag definition?");
- TagT->decl.setInt(0);
- } else if (InjectedClassNameType *Injected
- = const_cast<InjectedClassNameType *>(
- TypeForDecl->getAs<InjectedClassNameType>())) {
- assert(Injected->Decl == this &&
- "Attempt to redefine a class template definition?");
- (void)Injected;
- }
+ IsBeingDefined = false;
}
TagDecl* TagDecl::getDefinition() const {
@@ -1675,10 +1641,6 @@ EnumDecl *EnumDecl::Create(ASTContext &C, EmptyShell Empty) {
return new (C) EnumDecl(0, SourceLocation(), 0, 0, SourceLocation());
}
-void EnumDecl::Destroy(ASTContext& C) {
- TagDecl::Destroy(C);
-}
-
void EnumDecl::completeDefinition(QualType NewType,
QualType NewPromotionType,
unsigned NumPositiveBits,
@@ -1719,13 +1681,6 @@ RecordDecl *RecordDecl::Create(ASTContext &C, EmptyShell Empty) {
SourceLocation());
}
-RecordDecl::~RecordDecl() {
-}
-
-void RecordDecl::Destroy(ASTContext& C) {
- TagDecl::Destroy(C);
-}
-
bool RecordDecl::isInjectedClassName() const {
return isImplicit() && getDeclName() && getDeclContext()->isRecord() &&
cast<RecordDecl>(getDeclContext())->getDeclName() == getDeclName();
@@ -1753,20 +1708,6 @@ ValueDecl *RecordDecl::getAnonymousStructOrUnionObject() {
// BlockDecl Implementation
//===----------------------------------------------------------------------===//
-BlockDecl::~BlockDecl() {
-}
-
-void BlockDecl::Destroy(ASTContext& C) {
- if (Body)
- Body->Destroy(C);
-
- for (param_iterator I=param_begin(), E=param_end(); I!=E; ++I)
- (*I)->Destroy(C);
-
- C.Deallocate(ParamInfo);
- Decl::Destroy(C);
-}
-
void BlockDecl::setParams(ParmVarDecl **NewParamInfo,
unsigned NParms) {
assert(ParamInfo == 0 && "Already has param info!");
@@ -1798,27 +1739,17 @@ NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) NamespaceDecl(DC, L, Id);
}
-void NamespaceDecl::Destroy(ASTContext& C) {
- // NamespaceDecl uses "NextDeclarator" to chain namespace declarations
- // together. They are all top-level Decls.
-
- this->~NamespaceDecl();
- Decl::Destroy(C);
-}
-
-
ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L, IdentifierInfo *Id, QualType T) {
return new (C) ImplicitParamDecl(ImplicitParam, DC, L, Id, T);
}
FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation L,
- DeclarationName N, QualType T,
- TypeSourceInfo *TInfo,
+ const DeclarationNameInfo &NameInfo,
+ QualType T, TypeSourceInfo *TInfo,
StorageClass S, StorageClass SCAsWritten,
bool isInline, bool hasWrittenPrototype) {
- FunctionDecl *New = new (C) FunctionDecl(Function, DC, L, N, T, TInfo,
+ FunctionDecl *New = new (C) FunctionDecl(Function, DC, NameInfo, T, TInfo,
S, SCAsWritten, isInline);
New->HasWrittenPrototype = hasWrittenPrototype;
return New;
@@ -1835,9 +1766,11 @@ EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD,
return new (C) EnumConstantDecl(CD, L, Id, T, E, V);
}
-void EnumConstantDecl::Destroy(ASTContext& C) {
- if (Init) Init->Destroy(C);
- ValueDecl::Destroy(C);
+SourceRange EnumConstantDecl::getSourceRange() const {
+ SourceLocation End = getLocation();
+ if (Init)
+ End = Init->getLocEnd();
+ return SourceRange(getLocation(), End);
}
TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
@@ -1846,9 +1779,6 @@ TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC,
return new (C) TypedefDecl(DC, L, Id, TInfo);
}
-// Anchor TypedefDecl's vtable here.
-TypedefDecl::~TypedefDecl() {}
-
FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC,
SourceLocation L,
StringLiteral *Str) {