From: Nate Begeman Date: Tue, 13 Nov 2007 22:14:47 +0000 (+0000) Subject: Give AST-walk passes a way to access DeclSpec attributes on functions and X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=1b4e251f6d73997732f64e550a2b9cb5ac945c78;p=clang Give AST-walk passes a way to access DeclSpec attributes on functions and variables. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@44073 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/Parse/ParseDecl.cpp b/Parse/ParseDecl.cpp index 0437c202f3..5feb40b0d9 100644 --- a/Parse/ParseDecl.cpp +++ b/Parse/ParseDecl.cpp @@ -1393,7 +1393,11 @@ void Parser::ParseParenDeclarator(Declarator &D) { } ParamInfo.push_back(DeclaratorChunk::ParamInfo(ParmII, - ParmDecl.getIdentifierLoc(), ParamTy.Val, ParmDecl.getInvalidType())); + ParmDecl.getIdentifierLoc(), ParamTy.Val, ParmDecl.getInvalidType(), + ParmDecl.getDeclSpec().getAttributes())); + + // Ownership of DeclSpec has been handed off to ParamInfo. + DS.clearAttributes(); // If the next token is a comma, consume it and keep reading arguments. if (Tok.isNot(tok::comma)) break; diff --git a/Sema/SemaDecl.cpp b/Sema/SemaDecl.cpp index 6ae36c8c2b..1540b7caae 100644 --- a/Sema/SemaDecl.cpp +++ b/Sema/SemaDecl.cpp @@ -615,7 +615,11 @@ Sema::ActOnDeclarator(Scope *S, Declarator &D, DeclTy *lastDecl) { FunctionDecl *NewFD = new FunctionDecl(D.getIdentifierLoc(), II, R, SC, D.getDeclSpec().isInlineSpecified(), - LastDeclarator); + LastDeclarator, + D.getDeclSpec().getAttributes()); + + // Transfer ownership of DeclSpec attributes to FunctionDecl + D.getDeclSpec().clearAttributes(); // Merge the decl with the existing one if appropriate. if (PrevDecl) { @@ -838,7 +842,7 @@ Sema::ActOnParamDeclarator(struct DeclaratorChunk::ParamInfo &PI, Scope *FnScope parmDeclType = Context.getPointerType(parmDeclType); ParmVarDecl *New = new ParmVarDecl(PI.IdentLoc, II, parmDeclType, - VarDecl::None, 0); + VarDecl::None, 0, PI.AttrList); if (PI.InvalidType) New->setInvalidDecl(); diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index ba302b90e1..04e919caad 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -14,8 +14,9 @@ #ifndef LLVM_CLANG_AST_DECL_H #define LLVM_CLANG_AST_DECL_H -#include "clang/Basic/SourceLocation.h" #include "clang/AST/Type.h" +#include "clang/Basic/SourceLocation.h" +#include "clang/Parse/AttributeList.h" #include "llvm/ADT/APSInt.h" #include "llvm/Bitcode/SerializationFwd.h" @@ -27,7 +28,6 @@ namespace clang { class Expr; class Stmt; class FunctionDecl; -class AttributeList; class IdentifierInfo; /// Decl - This represents one declaration (or definition), e.g. a variable, @@ -249,14 +249,21 @@ protected: /// an enum constant. class ValueDecl : public ScopedDecl { QualType DeclType; + + /// Attributes - Linked list of attributes that are attached to this + /// function. + AttributeList *Attributes; protected: ValueDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, - ScopedDecl *PrevDecl) : ScopedDecl(DK, L, Id, PrevDecl), DeclType(T) {} + ScopedDecl *PrevDecl, AttributeList *A = 0) + : ScopedDecl(DK, L, Id, PrevDecl), DeclType(T), Attributes(A) {} public: QualType getType() const { return DeclType; } void setType(QualType newType) { DeclType = newType; } QualType getCanonicalType() const { return DeclType.getCanonicalType(); } + AttributeList *getAttributes() const { return Attributes; } + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() >= ValueFirst && D->getKind() <= ValueLast; @@ -323,8 +330,8 @@ public: static bool classof(const VarDecl *D) { return true; } protected: VarDecl(Kind DK, SourceLocation L, IdentifierInfo *Id, QualType T, - StorageClass SC, ScopedDecl *PrevDecl) - : ValueDecl(DK, L, Id, T, PrevDecl), Init(0), + StorageClass SC, ScopedDecl *PrevDecl, AttributeList *A = 0) + : ValueDecl(DK, L, Id, T, PrevDecl, A), Init(0), objcDeclQualifier(OBJC_TQ_None) { SClass = SC; } private: Expr *Init; @@ -354,8 +361,8 @@ protected: class BlockVarDecl : public VarDecl { public: BlockVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, - ScopedDecl *PrevDecl) - : VarDecl(BlockVar, L, Id, T, S, PrevDecl) {} + ScopedDecl *PrevDecl, AttributeList *A = 0) + : VarDecl(BlockVar, L, Id, T, S, PrevDecl, A) {} // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == BlockVar; } @@ -375,8 +382,8 @@ protected: class FileVarDecl : public VarDecl { public: FileVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, - ScopedDecl *PrevDecl) - : VarDecl(FileVar, L, Id, T, S, PrevDecl) {} + ScopedDecl *PrevDecl, AttributeList *A = 0) + : VarDecl(FileVar, L, Id, T, S, PrevDecl, A) {} // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == FileVar; } @@ -393,8 +400,8 @@ protected: class ParmVarDecl : public VarDecl { public: ParmVarDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S, - ScopedDecl *PrevDecl) - : VarDecl(ParmVar, L, Id, T, S, PrevDecl) {} + ScopedDecl *PrevDecl, AttributeList *A = 0) + : VarDecl(ParmVar, L, Id, T, S, PrevDecl, A) {} // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == ParmVar; } @@ -416,8 +423,8 @@ public: }; FunctionDecl(SourceLocation L, IdentifierInfo *Id, QualType T, StorageClass S = None, bool isInline = false, - ScopedDecl *PrevDecl = 0) - : ValueDecl(Function, L, Id, T, PrevDecl), + ScopedDecl *PrevDecl = 0, AttributeList *Attrs = 0) + : ValueDecl(Function, L, Id, T, PrevDecl, Attrs), ParamInfo(0), Body(0), DeclChain(0), SClass(S), IsInline(isInline) {} virtual ~FunctionDecl(); diff --git a/include/clang/Parse/DeclSpec.h b/include/clang/Parse/DeclSpec.h index 75381dff31..b247fb2b62 100644 --- a/include/clang/Parse/DeclSpec.h +++ b/include/clang/Parse/DeclSpec.h @@ -252,6 +252,7 @@ public: AttrList = alist; } AttributeList *getAttributes() const { return AttrList; } + void clearAttributes() { AttrList = 0; } llvm::SmallVector *getProtocolQualifiers() const { return ProtocolQualifiers; @@ -388,12 +389,12 @@ struct DeclaratorChunk { SourceLocation IdentLoc; Action::TypeTy *TypeInfo; bool InvalidType; - // FIXME: this also needs an attribute list. + AttributeList *AttrList; ParamInfo() {} ParamInfo(IdentifierInfo *ident, SourceLocation iloc, Action::TypeTy *typ, - bool flag = false) - : Ident(ident), IdentLoc(iloc), TypeInfo(typ), InvalidType(flag) { - } + bool flag = false, AttributeList *AL = 0) + : Ident(ident), IdentLoc(iloc), TypeInfo(typ), InvalidType(flag), + AttrList(AL) {} }; struct FunctionTypeInfo { @@ -496,7 +497,7 @@ struct DeclaratorChunk { /// Instances of this class should be a transient object that lives on the /// stack, not objects that are allocated in large quantities on the heap. class Declarator { - const DeclSpec &DS; + DeclSpec &DS; IdentifierInfo *Identifier; SourceLocation IdentifierLoc; @@ -527,7 +528,7 @@ private: // attributes. AttributeList *AttrList; public: - Declarator(const DeclSpec &ds, TheContext C) + Declarator(DeclSpec &ds, TheContext C) : DS(ds), Identifier(0), Context(C), InvalidType(false), AttrList(0) { } @@ -537,7 +538,7 @@ public: /// getDeclSpec - Return the declaration-specifier that this declarator was /// declared with. - const DeclSpec &getDeclSpec() const { return DS; } + DeclSpec &getDeclSpec() const { return DS; } TheContext getContext() const { return Context; }