From 7783bfc066776a63d6a2cd28329d4d149647bfdc Mon Sep 17 00:00:00 2001 From: Sebastian Redl Date: Tue, 26 Jan 2010 22:01:41 +0000 Subject: [PATCH] Bring some semblance of order into Decl.h and Decl.cpp. While at it, fix some typo comments and remove an unused and unimplemented function prototype. No functionality change. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@94599 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/Decl.h | 212 +++++++++-------- lib/AST/Decl.cpp | 482 ++++++++++++++++++++------------------- 2 files changed, 352 insertions(+), 342 deletions(-) diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 5416c65306..6489a32a10 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -474,13 +474,113 @@ public: SourceLocation L, IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S); - virtual ~VarDecl(); virtual void Destroy(ASTContext& C); + virtual ~VarDecl(); + + virtual SourceRange getSourceRange() const; StorageClass getStorageClass() const { return (StorageClass)SClass; } void setStorageClass(StorageClass SC) { SClass = SC; } - virtual SourceRange getSourceRange() const; + void setThreadSpecified(bool T) { ThreadSpecified = T; } + bool isThreadSpecified() const { + return ThreadSpecified; + } + + /// hasLocalStorage - Returns true if a variable with function scope + /// is a non-static local variable. + bool hasLocalStorage() const { + if (getStorageClass() == None) + return !isFileVarDecl(); + + // Return true for: Auto, Register. + // Return false for: Extern, Static, PrivateExtern. + + return getStorageClass() <= Register; + } + + /// hasExternStorage - Returns true if a variable has extern or + /// __private_extern__ storage. + bool hasExternalStorage() const { + return getStorageClass() == Extern || getStorageClass() == PrivateExtern; + } + + /// hasGlobalStorage - Returns true for all variables that do not + /// have local storage. This includs all global variables as well + /// as static variables declared within a function. + bool hasGlobalStorage() const { return !hasLocalStorage(); } + + /// \brief Determines whether this variable is a variable with + /// external, C linkage. + bool isExternC() const; + + /// isBlockVarDecl - Returns true for local variable declarations. Note that + /// this includes static variables inside of functions. + /// + /// void foo() { int x; static int y; extern int z; } + /// + bool isBlockVarDecl() const { + if (getKind() != Decl::Var) + return false; + if (const DeclContext *DC = getDeclContext()) + return DC->getLookupContext()->isFunctionOrMethod(); + return false; + } + + /// \brief Determines whether this is a static data member. + /// + /// This will only be true in C++, and applies to, e.g., the + /// variable 'x' in: + /// \code + /// struct S { + /// static int x; + /// }; + /// \endcode + bool isStaticDataMember() const { + return getDeclContext()->isRecord(); + } + + virtual VarDecl *getCanonicalDecl(); + const VarDecl *getCanonicalDecl() const { + return const_cast(this)->getCanonicalDecl(); + } + + /// \brief Retrieve the definition of this variable, which may come + /// from a previous declaration. Def will be set to the VarDecl that + /// contains the initializer, and the result will be that + /// initializer. + const Expr *getDefinition(const VarDecl *&Def) const; + + const Expr *getDefinition() const { + const VarDecl* Definition; + return getDefinition(Definition); + } + + /// \brief Determine whether this is or was instantiated from an out-of-line + /// definition of a static data member. + bool isOutOfLine() const; + + /// \brief If this is a static data member, find its out-of-line definition. + VarDecl *getOutOfLineDefinition(); + + /// isFileVarDecl - Returns true for file scoped variable declaration. + bool isFileVarDecl() const { + if (getKind() != Decl::Var) + return false; + if (const DeclContext *Ctx = getDeclContext()) { + Ctx = Ctx->getLookupContext(); + if (isa(Ctx) || isa(Ctx) ) + return true; + } + if (isStaticDataMember()) + return true; + + return false; + } + + /// \brief Determine whether this is a tentative definition of a + /// variable in C. + bool isTentativeDefinition(ASTContext &Context) const; const Expr *getInit() const { if (Init.isNull()) @@ -614,22 +714,6 @@ public: Eval->IsICE = IsICE; } - /// \brief Retrieve the definition of this variable, which may come - /// from a previous declaration. Def will be set to the VarDecl that - /// contains the initializer, and the result will be that - /// initializer. - const Expr *getDefinition(const VarDecl *&Def) const; - - const Expr *getDefinition() const { - const VarDecl* Definition; - return getDefinition(Definition); - } - - void setThreadSpecified(bool T) { ThreadSpecified = T; } - bool isThreadSpecified() const { - return ThreadSpecified; - } - void setCXXDirectInitializer(bool T) { HasCXXDirectInit = T; } /// hasCXXDirectInitializer - If true, the initializer was a direct @@ -653,67 +737,6 @@ public: void setDeclaredInCondition(bool InCondition) { DeclaredInCondition = InCondition; } - - virtual VarDecl *getCanonicalDecl(); - const VarDecl *getCanonicalDecl() const { - return const_cast(this)->getCanonicalDecl(); - } - - /// hasLocalStorage - Returns true if a variable with function scope - /// is a non-static local variable. - bool hasLocalStorage() const { - if (getStorageClass() == None) - return !isFileVarDecl(); - - // Return true for: Auto, Register. - // Return false for: Extern, Static, PrivateExtern. - - return getStorageClass() <= Register; - } - - /// hasExternStorage - Returns true if a variable has extern or - /// __private_extern__ storage. - bool hasExternalStorage() const { - return getStorageClass() == Extern || getStorageClass() == PrivateExtern; - } - - /// hasGlobalStorage - Returns true for all variables that do not - /// have local storage. This includs all global variables as well - /// as static variables declared within a function. - bool hasGlobalStorage() const { return !hasLocalStorage(); } - - /// isBlockVarDecl - Returns true for local variable declarations. Note that - /// this includes static variables inside of functions. - /// - /// void foo() { int x; static int y; extern int z; } - /// - bool isBlockVarDecl() const { - if (getKind() != Decl::Var) - return false; - if (const DeclContext *DC = getDeclContext()) - return DC->getLookupContext()->isFunctionOrMethod(); - return false; - } - - /// \brief Determines whether this is a static data member. - /// - /// This will only be true in C++, and applies to, e.g., the - /// variable 'x' in: - /// \code - /// struct S { - /// static int x; - /// }; - /// \endcode - bool isStaticDataMember() const { - return getDeclContext()->isRecord(); - } - - /// \brief Determine whether this is or was instantiated from an out-of-line - /// definition of a static data member. - bool isOutOfLine() const; - - /// \brief If this is a static data member, find its out-of-line definition. - VarDecl *getOutOfLineDefinition(); /// \brief If this variable is an instantiated static data member of a /// class template specialization, returns the templated static data member @@ -733,29 +756,6 @@ public: /// data member of a class template, set the template specialiation kind. void setTemplateSpecializationKind(TemplateSpecializationKind TSK, SourceLocation PointOfInstantiation = SourceLocation()); - - /// isFileVarDecl - Returns true for file scoped variable declaration. - bool isFileVarDecl() const { - if (getKind() != Decl::Var) - return false; - if (const DeclContext *Ctx = getDeclContext()) { - Ctx = Ctx->getLookupContext(); - if (isa(Ctx) || isa(Ctx) ) - return true; - } - if (isStaticDataMember()) - return true; - - return false; - } - - /// \brief Determine whether this is a tentative definition of a - /// variable in C. - bool isTentativeDefinition(ASTContext &Context) const; - - /// \brief Determines whether this variable is a variable with - /// external, C linkage. - bool isExternC() const; // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { @@ -1101,8 +1101,6 @@ public: unsigned getBuiltinID() const; - unsigned getNumParmVarDeclsFromType() const; - // Iterator access to formal parameters. unsigned param_size() const { return getNumParams(); } typedef ParmVarDecl **param_iterator; @@ -1115,7 +1113,7 @@ public: param_const_iterator param_end() const { return ParamInfo+param_size(); } /// getNumParams - Return the number of parameters this function must have - /// based on its functiontype. This is the length of the PararmInfo array + /// based on its FunctionType. This is the length of the ParamInfo array /// after it has been created. unsigned getNumParams() const; @@ -1564,6 +1562,8 @@ public: /// there is no TagDecl that defines the struct/union/class/enum. TagDecl* getDefinition(ASTContext& C) const; + void setDefinition(bool V) { IsDefinition = V; } + const char *getKindName() const { return ElaboratedType::getNameForTagKind(getTagKind()); } @@ -1599,8 +1599,6 @@ public: static TagDecl *castFromDeclContext(const DeclContext *DC) { return static_cast(const_cast(DC)); } - - void setDefinition(bool V) { IsDefinition = V; } }; /// EnumDecl - Represents an enum. As an extension, we allow forward-declared diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 794b14a1f4..46f7117f2c 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -43,205 +43,6 @@ TypeLoc TypeSourceInfo::getTypeLoc() const { return TypeLoc(Ty, (void*)(this + 1)); } -//===----------------------------------------------------------------------===// -// 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); -} - -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; -} - -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(Arg)) - return E->getSubExpr(); - - return Arg; -} - -unsigned ParmVarDecl::getNumDefaultArgTemporaries() const { - if (const CXXExprWithTemporaries *E = - dyn_cast(getInit())) - return E->getNumTemporaries(); - - return 0; -} - -CXXTemporary *ParmVarDecl::getDefaultArgTemporary(unsigned i) { - assert(getNumDefaultArgTemporaries() && - "Default arguments does not have any temporaries!"); - - CXXExprWithTemporaries *E = cast(getInit()); - return E->getTemporary(i); -} - -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()) { - Eval->~EvaluatedStmt(); - C.Deallocate(Eval); - } - - Init = I; -} - -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(DC)) { - if (Linkage->getLanguage() == LinkageSpecDecl::lang_c) - return getStorageClass() != Static; - - break; - } - - if (DC->isFunctionOrMethod()) - return false; - } - - return false; -} - -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()) - 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 //===----------------------------------------------------------------------===// @@ -606,6 +407,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 +453,45 @@ 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(DC)) { + if (Linkage->getLanguage() == LinkageSpecDecl::lang_c) + return getStorageClass() != Static; + + break; + } + + if (DC->isFunctionOrMethod()) + return false; + } + + return false; +} + +VarDecl *VarDecl::getCanonicalDecl() { + return getFirstDeclaration(); +} + +const Expr *VarDecl::getDefinition(const VarDecl *&Def) const { + redecl_iterator I = redecls_begin(), E = redecls_end(); + while (I != E && !I->getInit()) + ++I; + + if (I != E) { + Def = *I; + return I->getInit(); + } + return 0; +} + bool VarDecl::isOutOfLine() const { if (!isStaticDataMember()) return false; @@ -667,6 +521,24 @@ VarDecl *VarDecl::getOutOfLineDefinition() { return 0; } +bool VarDecl::isTentativeDefinition(ASTContext &Context) const { + if (!isFileVarDecl() || Context.getLangOptions().CPlusPlus) + return false; + + const VarDecl *Def = 0; + return (!getDefinition(Def) && + (getStorageClass() == None || getStorageClass() == Static)); +} + +void VarDecl::setInit(ASTContext &C, Expr *I) { + if (EvaluatedStmt *Eval = Init.dyn_cast()) { + Eval->~EvaluatedStmt(); + C.Deallocate(Eval); + } + + Init = I; +} + VarDecl *VarDecl::getInstantiatedFromStaticDataMember() const { if (MemberSpecializationInfo *MSI = getMemberSpecializationInfo()) return cast(MSI->getInstantiatedFrom()); @@ -697,29 +569,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(Arg)) + return E->getSubExpr(); + + return Arg; +} + +unsigned ParmVarDecl::getNumDefaultArgTemporaries() const { + if (const CXXExprWithTemporaries *E = + dyn_cast(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(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 +722,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. /// @@ -1014,26 +930,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 { @@ -1253,6 +1149,26 @@ bool FunctionDecl::isOutOfLine() const { return false; } +//===----------------------------------------------------------------------===// +// 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()) + return Record->getDecl()->isAnonymousStructOrUnion(); + + return false; +} + //===----------------------------------------------------------------------===// // TagDecl Implementation //===----------------------------------------------------------------------===// @@ -1304,6 +1220,31 @@ 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(ASTContext &C, + QualType NewType, + QualType NewPromotionType) { + assert(!isDefinition() && "Cannot redefine enums!"); + IntegerType = NewType; + PromotionType = NewPromotionType; + TagDecl::completeDefinition(); +} + //===----------------------------------------------------------------------===// // RecordDecl Implementation //===----------------------------------------------------------------------===// @@ -1380,3 +1321,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); +} -- 2.50.1