diff options
author | rdivacky <rdivacky@FreeBSD.org> | 2010-02-16 09:31:36 +0000 |
---|---|---|
committer | rdivacky <rdivacky@FreeBSD.org> | 2010-02-16 09:31:36 +0000 |
commit | fd035e6496665b1f1197868e21cb0a4594e8db6e (patch) | |
tree | 53010172e19c77ea447bcd89e117cda052ab52e0 /lib/AST/Decl.cpp | |
parent | 2fce988e86bc01829142e4362d4eff1af0925147 (diff) | |
download | FreeBSD-src-fd035e6496665b1f1197868e21cb0a4594e8db6e.zip FreeBSD-src-fd035e6496665b1f1197868e21cb0a4594e8db6e.tar.gz |
Update clang to r96341.
Diffstat (limited to 'lib/AST/Decl.cpp')
-rw-r--r-- | lib/AST/Decl.cpp | 734 |
1 files changed, 467 insertions, 267 deletions
diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 794b14a..5acb82f 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -29,224 +29,81 @@ using namespace clang; -void Attr::Destroy(ASTContext &C) { - if (Next) { - Next->Destroy(C); - Next = 0; - } - this->~Attr(); - C.Deallocate((void*)this); -} - /// \brief Return the TypeLoc wrapper for the type source info. TypeLoc TypeSourceInfo::getTypeLoc() const { return TypeLoc(Ty, (void*)(this + 1)); } //===----------------------------------------------------------------------===// -// Decl Allocation/Deallocation Method Implementations +// NamedDecl Implementation //===----------------------------------------------------------------------===// +/// \brief Get the most restrictive linkage for the types in the given +/// template parameter list. +static Linkage +getLinkageForTemplateParameterList(const TemplateParameterList *Params) { + Linkage L = ExternalLinkage; + for (TemplateParameterList::const_iterator P = Params->begin(), + PEnd = Params->end(); + P != PEnd; ++P) { + if (NonTypeTemplateParmDecl *NTTP = dyn_cast<NonTypeTemplateParmDecl>(*P)) + if (!NTTP->getType()->isDependentType()) { + L = minLinkage(L, NTTP->getType()->getLinkage()); + continue; + } -TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { - return new (C) TranslationUnitDecl(C); -} - -NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id) { - 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(); - C.Deallocate((void *)this); -} - - -ImplicitParamDecl *ImplicitParamDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, QualType T) { - return new (C) ImplicitParamDecl(ImplicitParam, DC, L, Id, T); -} - -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; + if (TemplateTemplateParmDecl *TTP + = dyn_cast<TemplateTemplateParmDecl>(*P)) { + L = minLinkage(L, + getLinkageForTemplateParameterList(TTP->getTemplateParameters())); + } } - assert(0 && "Invalid storage class"); - return 0; -} - -ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - QualType T, TypeSourceInfo *TInfo, - StorageClass S, Expr *DefArg) { - return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo, S, DefArg); -} - -Expr *ParmVarDecl::getDefaultArg() { - assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!"); - assert(!hasUninstantiatedDefaultArg() && - "Default argument is not yet instantiated!"); - - Expr *Arg = getInit(); - if (CXXExprWithTemporaries *E = dyn_cast_or_null<CXXExprWithTemporaries>(Arg)) - return E->getSubExpr(); - - return Arg; -} - -unsigned ParmVarDecl::getNumDefaultArgTemporaries() const { - if (const CXXExprWithTemporaries *E = - dyn_cast<CXXExprWithTemporaries>(getInit())) - return E->getNumTemporaries(); - - return 0; + return L; } -CXXTemporary *ParmVarDecl::getDefaultArgTemporary(unsigned i) { - assert(getNumDefaultArgTemporaries() && - "Default arguments does not have any temporaries!"); - - CXXExprWithTemporaries *E = cast<CXXExprWithTemporaries>(getInit()); - return E->getTemporary(i); -} +/// \brief Get the most restrictive linkage for the types and +/// declarations in the given template argument list. +static Linkage getLinkageForTemplateArgumentList(const TemplateArgument *Args, + unsigned NumArgs) { + Linkage L = ExternalLinkage; -SourceRange ParmVarDecl::getDefaultArgRange() const { - if (const Expr *E = getInit()) - return E->getSourceRange(); - - if (hasUninstantiatedDefaultArg()) - return getUninstantiatedDefaultArg()->getSourceRange(); - - return SourceRange(); -} - -void VarDecl::setInit(ASTContext &C, Expr *I) { - if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) { - Eval->~EvaluatedStmt(); - C.Deallocate(Eval); - } - - Init = I; -} + for (unsigned I = 0; I != NumArgs; ++I) { + switch (Args[I].getKind()) { + case TemplateArgument::Null: + case TemplateArgument::Integral: + case TemplateArgument::Expression: + break; + + case TemplateArgument::Type: + L = minLinkage(L, Args[I].getAsType()->getLinkage()); + break; -bool VarDecl::isExternC() const { - ASTContext &Context = getASTContext(); - if (!Context.getLangOptions().CPlusPlus) - return (getDeclContext()->isTranslationUnit() && - getStorageClass() != Static) || - (getDeclContext()->isFunctionOrMethod() && hasExternalStorage()); + case TemplateArgument::Declaration: + if (NamedDecl *ND = dyn_cast<NamedDecl>(Args[I].getAsDecl())) + L = minLinkage(L, ND->getLinkage()); + if (ValueDecl *VD = dyn_cast<ValueDecl>(Args[I].getAsDecl())) + L = minLinkage(L, VD->getType()->getLinkage()); + break; - 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; + case TemplateArgument::Template: + if (TemplateDecl *Template + = Args[I].getAsTemplate().getAsTemplateDecl()) + L = minLinkage(L, Template->getLinkage()); + break; + case TemplateArgument::Pack: + L = minLinkage(L, + getLinkageForTemplateArgumentList(Args[I].pack_begin(), + Args[I].pack_size())); break; } - - if (DC->isFunctionOrMethod()) - return false; } - return false; + return L; } -FunctionDecl *FunctionDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - DeclarationName N, QualType T, - TypeSourceInfo *TInfo, - StorageClass S, bool isInline, - bool hasWrittenPrototype) { - FunctionDecl *New - = new (C) FunctionDecl(Function, DC, L, N, T, TInfo, S, isInline); - New->HasWrittenPrototype = hasWrittenPrototype; - return New; -} - -BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { - return new (C) BlockDecl(DC, L); -} - -FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, QualType T, - TypeSourceInfo *TInfo, Expr *BW, bool Mutable) { - return new (C) FieldDecl(Decl::Field, DC, L, Id, T, TInfo, BW, Mutable); -} - -bool FieldDecl::isAnonymousStructOrUnion() const { - if (!isImplicit() || getDeclName()) - return false; - - if (const RecordType *Record = getType()->getAs<RecordType>()) - return Record->getDecl()->isAnonymousStructOrUnion(); - - return false; -} - -EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, - SourceLocation L, - IdentifierInfo *Id, QualType T, - Expr *E, const llvm::APSInt &V) { - return new (C) EnumConstantDecl(CD, L, Id, T, E, V); -} - -void EnumConstantDecl::Destroy(ASTContext& C) { - if (Init) Init->Destroy(C); - Decl::Destroy(C); -} - -TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, IdentifierInfo *Id, - TypeSourceInfo *TInfo) { - return new (C) TypedefDecl(DC, L, Id, TInfo); -} - -// Anchor TypedefDecl's vtable here. -TypedefDecl::~TypedefDecl() {} - -EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, - IdentifierInfo *Id, SourceLocation TKL, - EnumDecl *PrevDecl) { - EnumDecl *Enum = new (C) EnumDecl(DC, L, Id, PrevDecl, TKL); - C.getTypeDeclType(Enum, PrevDecl); - return Enum; -} - -void EnumDecl::Destroy(ASTContext& C) { - Decl::Destroy(C); -} - -void EnumDecl::completeDefinition(ASTContext &C, - QualType NewType, - QualType NewPromotionType) { - assert(!isDefinition() && "Cannot redefine enums!"); - IntegerType = NewType; - PromotionType = NewPromotionType; - TagDecl::completeDefinition(); -} - -FileScopeAsmDecl *FileScopeAsmDecl::Create(ASTContext &C, DeclContext *DC, - SourceLocation L, - StringLiteral *Str) { - return new (C) FileScopeAsmDecl(DC, L, Str); -} - -//===----------------------------------------------------------------------===// -// NamedDecl Implementation -//===----------------------------------------------------------------------===// - -static NamedDecl::Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { +static Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { assert(D->getDeclContext()->getLookupContext()->isFileContext() && "Not a name having namespace scope"); ASTContext &Context = D->getASTContext(); @@ -260,7 +117,7 @@ static NamedDecl::Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { if (const VarDecl *Var = dyn_cast<VarDecl>(D)) { // Explicitly declared static. if (Var->getStorageClass() == VarDecl::Static) - return NamedDecl::InternalLinkage; + return InternalLinkage; // - an object or reference that is explicitly declared const // and neither explicitly declared extern nor previously @@ -274,13 +131,16 @@ static NamedDecl::Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { for (const VarDecl *PrevVar = Var->getPreviousDeclaration(); PrevVar && !FoundExtern; PrevVar = PrevVar->getPreviousDeclaration()) - if (PrevVar->getLinkage() == NamedDecl::ExternalLinkage) + if (isExternalLinkage(PrevVar->getLinkage())) FoundExtern = true; if (!FoundExtern) - return NamedDecl::InternalLinkage; + return InternalLinkage; } } else if (isa<FunctionDecl>(D) || isa<FunctionTemplateDecl>(D)) { + // C++ [temp]p4: + // A non-member function template can have internal linkage; any + // other template name shall have external linkage. const FunctionDecl *Function = 0; if (const FunctionTemplateDecl *FunTmpl = dyn_cast<FunctionTemplateDecl>(D)) @@ -290,11 +150,11 @@ static NamedDecl::Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { // Explicitly declared static. if (Function->getStorageClass() == FunctionDecl::Static) - return NamedDecl::InternalLinkage; + return InternalLinkage; } else if (const FieldDecl *Field = dyn_cast<FieldDecl>(D)) { // - a data member of an anonymous union. if (cast<RecordDecl>(Field->getDeclContext())->isAnonymousStructOrUnion()) - return NamedDecl::InternalLinkage; + return InternalLinkage; } // C++ [basic.link]p4: @@ -317,7 +177,7 @@ static NamedDecl::Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { // is visible, or if the prior declaration specifies no // linkage, then the identifier has external linkage. if (const VarDecl *PrevVar = Var->getPreviousDeclaration()) { - if (NamedDecl::Linkage L = PrevVar->getLinkage()) + if (Linkage L = PrevVar->getLinkage()) return L; } } @@ -326,7 +186,10 @@ static NamedDecl::Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { // If the declaration of an identifier for an object has file // scope and no storage-class specifier, its linkage is // external. - return NamedDecl::ExternalLinkage; + if (Var->isInAnonymousNamespace()) + return UniqueExternalLinkage; + + return ExternalLinkage; } // - a function, unless it has internal linkage; or @@ -350,12 +213,26 @@ static NamedDecl::Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { // is visible, or if the prior declaration specifies no // linkage, then the identifier has external linkage. if (const FunctionDecl *PrevFunc = Function->getPreviousDeclaration()) { - if (NamedDecl::Linkage L = PrevFunc->getLinkage()) + if (Linkage L = PrevFunc->getLinkage()) return L; } } - return NamedDecl::ExternalLinkage; + if (Function->isInAnonymousNamespace()) + return UniqueExternalLinkage; + + if (FunctionTemplateSpecializationInfo *SpecInfo + = Function->getTemplateSpecializationInfo()) { + Linkage L = SpecInfo->getTemplate()->getLinkage(); + const TemplateArgumentList &TemplateArgs = *SpecInfo->TemplateArguments; + L = minLinkage(L, + getLinkageForTemplateArgumentList( + TemplateArgs.getFlatArgumentList(), + TemplateArgs.flat_size())); + return L; + } + + return ExternalLinkage; } // - a named class (Clause 9), or an unnamed class defined in a @@ -365,29 +242,50 @@ static NamedDecl::Linkage getLinkageForNamespaceScopeDecl(const NamedDecl *D) { // defined in a typedef declaration in which the enumeration // has the typedef name for linkage purposes (7.1.3); or if (const TagDecl *Tag = dyn_cast<TagDecl>(D)) - if (Tag->getDeclName() || Tag->getTypedefForAnonDecl()) - return NamedDecl::ExternalLinkage; + if (Tag->getDeclName() || Tag->getTypedefForAnonDecl()) { + if (Tag->isInAnonymousNamespace()) + return UniqueExternalLinkage; + + // If this is a class template specialization, consider the + // linkage of the template and template arguments. + if (const ClassTemplateSpecializationDecl *Spec + = dyn_cast<ClassTemplateSpecializationDecl>(Tag)) { + const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs(); + Linkage L = getLinkageForTemplateArgumentList( + TemplateArgs.getFlatArgumentList(), + TemplateArgs.flat_size()); + return minLinkage(L, Spec->getSpecializedTemplate()->getLinkage()); + } + + return ExternalLinkage; + } // - an enumerator belonging to an enumeration with external linkage; - if (isa<EnumConstantDecl>(D)) - if (cast<NamedDecl>(D->getDeclContext())->getLinkage() - == NamedDecl::ExternalLinkage) - return NamedDecl::ExternalLinkage; + if (isa<EnumConstantDecl>(D)) { + Linkage L = cast<NamedDecl>(D->getDeclContext())->getLinkage(); + if (isExternalLinkage(L)) + return L; + } // - a template, unless it is a function template that has // internal linkage (Clause 14); - if (isa<TemplateDecl>(D)) - return NamedDecl::ExternalLinkage; + if (const TemplateDecl *Template = dyn_cast<TemplateDecl>(D)) { + if (D->isInAnonymousNamespace()) + return UniqueExternalLinkage; + + return getLinkageForTemplateParameterList( + Template->getTemplateParameters()); + } // - a namespace (7.3), unless it is declared within an unnamed // namespace. if (isa<NamespaceDecl>(D) && !D->isInAnonymousNamespace()) - return NamedDecl::ExternalLinkage; + return ExternalLinkage; - return NamedDecl::NoLinkage; + return NoLinkage; } -NamedDecl::Linkage NamedDecl::getLinkage() const { +Linkage NamedDecl::getLinkage() const { // Handle linkage for namespace-scope names. if (getDeclContext()->getLookupContext()->isFileContext()) if (Linkage L = getLinkageForNamespaceScopeDecl(this)) @@ -403,9 +301,11 @@ NamedDecl::Linkage NamedDecl::getLinkage() const { if (getDeclContext()->isRecord() && (isa<CXXMethodDecl>(this) || isa<VarDecl>(this) || (isa<TagDecl>(this) && - (getDeclName() || cast<TagDecl>(this)->getTypedefForAnonDecl()))) && - cast<RecordDecl>(getDeclContext())->getLinkage() == ExternalLinkage) - return ExternalLinkage; + (getDeclName() || cast<TagDecl>(this)->getTypedefForAnonDecl())))) { + Linkage L = cast<RecordDecl>(getDeclContext())->getLinkage(); + if (isExternalLinkage(L)) + return L; + } // C++ [basic.link]p6: // The name of a function declared in block scope and the name of @@ -424,6 +324,9 @@ NamedDecl::Linkage NamedDecl::getLinkage() const { if (Linkage L = Function->getPreviousDeclaration()->getLinkage()) return L; + if (Function->isInAnonymousNamespace()) + return UniqueExternalLinkage; + return ExternalLinkage; } @@ -434,6 +337,9 @@ NamedDecl::Linkage NamedDecl::getLinkage() const { if (Linkage L = Var->getPreviousDeclaration()->getLinkage()) return L; + if (Var->isInAnonymousNamespace()) + return UniqueExternalLinkage; + return ExternalLinkage; } } @@ -441,7 +347,7 @@ NamedDecl::Linkage NamedDecl::getLinkage() const { // C++ [basic.link]p6: // Names not covered by these rules have no linkage. return NoLinkage; -} + } std::string NamedDecl::getQualifiedNameAsString() const { return getQualifiedNameAsString(getASTContext().getLangOptions()); @@ -606,6 +512,20 @@ SourceLocation DeclaratorDecl::getTypeSpecStartLoc() const { // 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; + } + + assert(0 && "Invalid storage class"); + return 0; +} + VarDecl *VarDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S) { @@ -638,6 +558,127 @@ SourceRange VarDecl::getSourceRange() const { return SourceRange(Start, getLocation()); } +bool VarDecl::isExternC() const { + ASTContext &Context = getASTContext(); + if (!Context.getLangOptions().CPlusPlus) + return (getDeclContext()->isTranslationUnit() && + getStorageClass() != 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; + + break; + } + + if (DC->isFunctionOrMethod()) + return false; + } + + return false; +} + +VarDecl *VarDecl::getCanonicalDecl() { + return getFirstDeclaration(); +} + +VarDecl::DefinitionKind VarDecl::isThisDeclarationADefinition() const { + // C++ [basic.def]p2: + // A declaration is a definition unless [...] it contains the 'extern' + // specifier or a linkage-specification and neither an initializer [...], + // it declares a static data member in a class declaration [...]. + // C++ [temp.expl.spec]p15: + // An explicit specialization of a static data member of a template is a + // definition if the declaration includes an initializer; otherwise, it is + // a declaration. + if (isStaticDataMember()) { + if (isOutOfLine() && (hasInit() || + getTemplateSpecializationKind() != TSK_ExplicitSpecialization)) + return Definition; + else + return DeclarationOnly; + } + // C99 6.7p5: + // A definition of an identifier is a declaration for that identifier that + // [...] causes storage to be reserved for that object. + // Note: that applies for all non-file-scope objects. + // C99 6.9.2p1: + // If the declaration of an identifier for an object has file scope and an + // initializer, the declaration is an external definition for the identifier + if (hasInit()) + return Definition; + // AST for 'extern "C" int foo;' is annotated with 'extern'. + if (hasExternalStorage()) + return DeclarationOnly; + + // C99 6.9.2p2: + // A declaration of an object that has file scope without an initializer, + // and without a storage class specifier or the scs 'static', constitutes + // a tentative definition. + // No such thing in C++. + if (!getASTContext().getLangOptions().CPlusPlus && isFileVarDecl()) + return TentativeDefinition; + + // What's left is (in C, block-scope) declarations without initializers or + // external storage. These are definitions. + return Definition; +} + +VarDecl *VarDecl::getActingDefinition() { + DefinitionKind Kind = isThisDeclarationADefinition(); + if (Kind != TentativeDefinition) + return 0; + + VarDecl *LastTentative = false; + VarDecl *First = getFirstDeclaration(); + for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end(); + I != E; ++I) { + Kind = (*I)->isThisDeclarationADefinition(); + if (Kind == Definition) + return 0; + else if (Kind == TentativeDefinition) + LastTentative = *I; + } + return LastTentative; +} + +bool VarDecl::isTentativeDefinitionNow() const { + DefinitionKind Kind = isThisDeclarationADefinition(); + if (Kind != TentativeDefinition) + return false; + + for (redecl_iterator I = redecls_begin(), E = redecls_end(); I != E; ++I) { + if ((*I)->isThisDeclarationADefinition() == Definition) + return false; + } + return true; +} + +VarDecl *VarDecl::getDefinition() { + VarDecl *First = getFirstDeclaration(); + for (redecl_iterator I = First->redecls_begin(), E = First->redecls_end(); + I != E; ++I) { + if ((*I)->isThisDeclarationADefinition() == Definition) + return *I; + } + return 0; +} + +const Expr *VarDecl::getAnyInitializer(const VarDecl *&D) const { + redecl_iterator I = redecls_begin(), E = redecls_end(); + while (I != E && !I->getInit()) + ++I; + + if (I != E) { + D = *I; + return I->getInit(); + } + return 0; +} + bool VarDecl::isOutOfLine() const { if (!isStaticDataMember()) return false; @@ -667,6 +708,15 @@ VarDecl *VarDecl::getOutOfLineDefinition() { return 0; } +void VarDecl::setInit(Expr *I) { + if (EvaluatedStmt *Eval = Init.dyn_cast<EvaluatedStmt *>()) { + Eval->~EvaluatedStmt(); + getASTContext().Deallocate(Eval); + } + + Init = I; +} + VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const { if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) return cast<VarDecl>(MSI->getInstantiatedFrom()); @@ -675,8 +725,7 @@ VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const { } TemplateSpecializationKind VarDecl::getTemplateSpecializationKind() const { - if (MemberSpecializationInfo *MSI - = getASTContext().getInstantiatedFromStaticDataMember(this)) + if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) return MSI->getTemplateSpecializationKind(); return TSK_Undeclared; @@ -697,29 +746,53 @@ void VarDecl::setTemplateSpecializationKind(TemplateSpecializationKind TSK, MSI->setPointOfInstantiation(PointOfInstantiation); } -bool VarDecl::isTentativeDefinition(ASTContext &Context) const { - if (!isFileVarDecl() || Context.getLangOptions().CPlusPlus) - return false; +//===----------------------------------------------------------------------===// +// ParmVarDecl Implementation +//===----------------------------------------------------------------------===// - const VarDecl *Def = 0; - return (!getDefinition(Def) && - (getStorageClass() == None || getStorageClass() == Static)); +ParmVarDecl *ParmVarDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, + QualType T, TypeSourceInfo *TInfo, + StorageClass S, Expr *DefArg) { + return new (C) ParmVarDecl(ParmVar, DC, L, Id, T, TInfo, S, DefArg); } -const Expr *VarDecl::getDefinition(const VarDecl *&Def) const { - redecl_iterator I = redecls_begin(), E = redecls_end(); - while (I != E && !I->getInit()) - ++I; +Expr *ParmVarDecl::getDefaultArg() { + assert(!hasUnparsedDefaultArg() && "Default argument is not yet parsed!"); + assert(!hasUninstantiatedDefaultArg() && + "Default argument is not yet instantiated!"); + + Expr *Arg = getInit(); + if (CXXExprWithTemporaries *E = dyn_cast_or_null<CXXExprWithTemporaries>(Arg)) + return E->getSubExpr(); + + return Arg; +} + +unsigned ParmVarDecl::getNumDefaultArgTemporaries() const { + if (const CXXExprWithTemporaries *E = + dyn_cast<CXXExprWithTemporaries>(getInit())) + return E->getNumTemporaries(); - if (I != E) { - Def = *I; - return I->getInit(); - } return 0; } -VarDecl *VarDecl::getCanonicalDecl() { - return getFirstDeclaration(); +CXXTemporary *ParmVarDecl::getDefaultArgTemporary(unsigned i) { + assert(getNumDefaultArgTemporaries() && + "Default arguments does not have any temporaries!"); + + CXXExprWithTemporaries *E = cast<CXXExprWithTemporaries>(getInit()); + return E->getTemporary(i); +} + +SourceRange ParmVarDecl::getDefaultArgRange() const { + if (const Expr *E = getInit()) + return E->getSourceRange(); + + if (hasUninstantiatedDefaultArg()) + return getUninstantiatedDefaultArg()->getSourceRange(); + + return SourceRange(); } //===----------------------------------------------------------------------===// @@ -826,6 +899,26 @@ bool FunctionDecl::isGlobal() const { return true; } +void +FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) { + redeclarable_base::setPreviousDeclaration(PrevDecl); + + if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) { + FunctionTemplateDecl *PrevFunTmpl + = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0; + assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch"); + FunTmpl->setPreviousDeclaration(PrevFunTmpl); + } +} + +const FunctionDecl *FunctionDecl::getCanonicalDecl() const { + return getFirstDeclaration(); +} + +FunctionDecl *FunctionDecl::getCanonicalDecl() { + return getFirstDeclaration(); +} + /// \brief Returns a value indicating whether this function /// corresponds to a builtin function. /// @@ -882,14 +975,13 @@ unsigned FunctionDecl::getNumParams() const { } -void FunctionDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, - unsigned NumParams) { +void FunctionDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NumParams) { assert(ParamInfo == 0 && "Already has param info!"); assert(NumParams == getNumParams() && "Parameter count mismatch!"); // Zero params -> null pointer. if (NumParams) { - void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams); + void *Mem = getASTContext().Allocate(sizeof(ParmVarDecl*)*NumParams); ParamInfo = new (Mem) ParmVarDecl*[NumParams]; memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); @@ -1014,26 +1106,6 @@ bool FunctionDecl::isInlineDefinitionExternallyVisible() const { return false; } -void -FunctionDecl::setPreviousDeclaration(FunctionDecl *PrevDecl) { - redeclarable_base::setPreviousDeclaration(PrevDecl); - - if (FunctionTemplateDecl *FunTmpl = getDescribedFunctionTemplate()) { - FunctionTemplateDecl *PrevFunTmpl - = PrevDecl? PrevDecl->getDescribedFunctionTemplate() : 0; - assert((!PrevDecl || PrevFunTmpl) && "Function/function template mismatch"); - FunTmpl->setPreviousDeclaration(PrevFunTmpl); - } -} - -const FunctionDecl *FunctionDecl::getCanonicalDecl() const { - return getFirstDeclaration(); -} - -FunctionDecl *FunctionDecl::getCanonicalDecl() { - return getFirstDeclaration(); -} - /// getOverloadedOperator - Which C++ overloaded operator this /// function represents, if any. OverloadedOperatorKind FunctionDecl::getOverloadedOperator() const { @@ -1146,8 +1218,7 @@ FunctionDecl::getTemplateSpecializationArgs() const { } void -FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context, - FunctionTemplateDecl *Template, +FunctionDecl::setFunctionTemplateSpecialization(FunctionTemplateDecl *Template, const TemplateArgumentList *TemplateArgs, void *InsertPos, TemplateSpecializationKind TSK) { @@ -1156,7 +1227,7 @@ FunctionDecl::setFunctionTemplateSpecialization(ASTContext &Context, FunctionTemplateSpecializationInfo *Info = TemplateOrSpecialization.dyn_cast<FunctionTemplateSpecializationInfo*>(); if (!Info) - Info = new (Context) FunctionTemplateSpecializationInfo; + Info = new (getASTContext()) FunctionTemplateSpecializationInfo; Info->Function = this; Info->Template.setPointer(Template); @@ -1254,6 +1325,26 @@ bool FunctionDecl::isOutOfLine() const { } //===----------------------------------------------------------------------===// +// FieldDecl Implementation +//===----------------------------------------------------------------------===// + +FieldDecl *FieldDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, + IdentifierInfo *Id, QualType T, + TypeSourceInfo *TInfo, Expr *BW, bool Mutable) { + return new (C) FieldDecl(Decl::Field, DC, L, Id, T, TInfo, BW, Mutable); +} + +bool FieldDecl::isAnonymousStructOrUnion() const { + if (!isImplicit() || getDeclName()) + return false; + + if (const RecordType *Record = getType()->getAs<RecordType>()) + return Record->getDecl()->isAnonymousStructOrUnion(); + + return false; +} + +//===----------------------------------------------------------------------===// // TagDecl Implementation //===----------------------------------------------------------------------===// @@ -1271,9 +1362,23 @@ void TagDecl::startDefinition() { TagT->decl.setPointer(this); TagT->decl.setInt(1); } + + if (isa<CXXRecordDecl>(this)) { + CXXRecordDecl *D = cast<CXXRecordDecl>(this); + struct CXXRecordDecl::DefinitionData *Data = + new (getASTContext()) struct CXXRecordDecl::DefinitionData(D); + do { + D->DefinitionData = Data; + D = cast_or_null<CXXRecordDecl>(D->getPreviousDeclaration()); + } while (D); + } } void TagDecl::completeDefinition() { + assert((!isa<CXXRecordDecl>(this) || + cast<CXXRecordDecl>(this)->hasDefinition()) && + "definition completed but not started"); + IsDefinition = true; if (TagType *TagT = const_cast<TagType *>(TypeForDecl->getAs<TagType>())) { assert(TagT->decl.getPointer() == this && @@ -1282,7 +1387,7 @@ void TagDecl::completeDefinition() { } } -TagDecl* TagDecl::getDefinition(ASTContext& C) const { +TagDecl* TagDecl::getDefinition() const { if (isDefinition()) return const_cast<TagDecl *>(this); @@ -1305,6 +1410,30 @@ TagDecl::TagKind TagDecl::getTagKindForTypeSpec(unsigned TypeSpec) { } //===----------------------------------------------------------------------===// +// EnumDecl Implementation +//===----------------------------------------------------------------------===// + +EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L, + IdentifierInfo *Id, SourceLocation TKL, + EnumDecl *PrevDecl) { + EnumDecl *Enum = new (C) EnumDecl(DC, L, Id, PrevDecl, TKL); + C.getTypeDeclType(Enum, PrevDecl); + return Enum; +} + +void EnumDecl::Destroy(ASTContext& C) { + Decl::Destroy(C); +} + +void EnumDecl::completeDefinition(QualType NewType, + QualType NewPromotionType) { + assert(!isDefinition() && "Cannot redefine enums!"); + IntegerType = NewType; + PromotionType = NewPromotionType; + TagDecl::completeDefinition(); +} + +//===----------------------------------------------------------------------===// // RecordDecl Implementation //===----------------------------------------------------------------------===// @@ -1341,7 +1470,7 @@ bool RecordDecl::isInjectedClassName() const { /// completeDefinition - Notes that the definition of this type is now /// complete. -void RecordDecl::completeDefinition(ASTContext& C) { +void RecordDecl::completeDefinition() { assert(!isDefinition() && "Cannot redefine record!"); TagDecl::completeDefinition(); } @@ -1364,14 +1493,14 @@ void BlockDecl::Destroy(ASTContext& C) { Decl::Destroy(C); } -void BlockDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, +void BlockDecl::setParams(ParmVarDecl **NewParamInfo, unsigned NParms) { assert(ParamInfo == 0 && "Already has param info!"); // Zero params -> null pointer. if (NParms) { NumParams = NParms; - void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams); + void *Mem = getASTContext().Allocate(sizeof(ParmVarDecl*)*NumParams); ParamInfo = new (Mem) ParmVarDecl*[NumParams]; memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); } @@ -1380,3 +1509,74 @@ void BlockDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, unsigned BlockDecl::getNumParams() const { return NumParams; } + + +//===----------------------------------------------------------------------===// +// Other Decl Allocation/Deallocation Method Implementations +//===----------------------------------------------------------------------===// + +TranslationUnitDecl *TranslationUnitDecl::Create(ASTContext &C) { + return new (C) TranslationUnitDecl(C); +} + +NamespaceDecl *NamespaceDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id) { + 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(); + C.Deallocate((void *)this); +} + + +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, + StorageClass S, bool isInline, + bool hasWrittenPrototype) { + FunctionDecl *New + = new (C) FunctionDecl(Function, DC, L, N, T, TInfo, S, isInline); + New->HasWrittenPrototype = hasWrittenPrototype; + return New; +} + +BlockDecl *BlockDecl::Create(ASTContext &C, DeclContext *DC, SourceLocation L) { + return new (C) BlockDecl(DC, L); +} + +EnumConstantDecl *EnumConstantDecl::Create(ASTContext &C, EnumDecl *CD, + SourceLocation L, + IdentifierInfo *Id, QualType T, + Expr *E, const llvm::APSInt &V) { + return new (C) EnumConstantDecl(CD, L, Id, T, E, V); +} + +void EnumConstantDecl::Destroy(ASTContext& C) { + if (Init) Init->Destroy(C); + Decl::Destroy(C); +} + +TypedefDecl *TypedefDecl::Create(ASTContext &C, DeclContext *DC, + SourceLocation L, IdentifierInfo *Id, + TypeSourceInfo *TInfo) { + 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) { + return new (C) FileScopeAsmDecl(DC, L, Str); +} |