diff options
Diffstat (limited to 'include/clang/Sema/AttributeList.h')
-rw-r--r-- | include/clang/Sema/AttributeList.h | 123 |
1 files changed, 97 insertions, 26 deletions
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index 2e8b0c0..0f0d218 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -15,11 +15,11 @@ #ifndef LLVM_CLANG_SEMA_ATTRLIST_H #define LLVM_CLANG_SEMA_ATTRLIST_H -#include "llvm/Support/Allocator.h" -#include "llvm/ADT/SmallVector.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/VersionTuple.h" #include "clang/Sema/Ownership.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/Support/Allocator.h" #include <cassert> namespace clang { @@ -44,8 +44,9 @@ struct AvailabilityChange { bool isValid() const { return !Version.empty(); } }; -/// AttributeList - Represents GCC's __attribute__ declaration. There are -/// 4 forms of this construct...they are: +/// AttributeList - Represents a syntactic attribute. +/// +/// For a GNU attribute, there are four forms of this construct: /// /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused. /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused. @@ -56,12 +57,14 @@ class AttributeList { // TODO: This should really be called ParsedAttribute public: /// The style used to specify an attribute. enum Syntax { + /// __attribute__((...)) AS_GNU, + /// [[...]] AS_CXX11, + /// __declspec(...) AS_Declspec, - // eg) __w64, __ptr32, etc. It is implied that an MSTypespec is also - // a declspec. - AS_MSTypespec + /// __ptr16, alignas(...), etc. + AS_Keyword }; private: IdentifierInfo *AttrName; @@ -70,6 +73,7 @@ private: SourceRange AttrRange; SourceLocation ScopeLoc; SourceLocation ParmLoc; + SourceLocation EllipsisLoc; /// The number of expression arguments this attribute has. /// The expressions themselves are stored after the object. @@ -140,6 +144,14 @@ private: return *reinterpret_cast<const TypeTagForDatatypeData *>(this + 1); } + ParsedType &getTypeBuffer() { + return *reinterpret_cast<ParsedType *>(this + 1); + } + + const ParsedType &getTypeBuffer() const { + return *reinterpret_cast<const ParsedType *>(this + 1); + } + AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION; void operator=(const AttributeList &) LLVM_DELETED_FUNCTION; void operator delete(void *) LLVM_DELETED_FUNCTION; @@ -152,11 +164,11 @@ private: IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, Expr **args, unsigned numArgs, - Syntax syntaxUsed) + Syntax syntaxUsed, SourceLocation ellipsisLoc) : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), - NumArgs(numArgs), SyntaxUsed(syntaxUsed), Invalid(false), - UsedAsTypeAttr(false), IsAvailability(false), + EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed), + Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) { if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*)); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); @@ -173,7 +185,7 @@ private: const Expr *messageExpr, Syntax syntaxUsed) : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), + AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), IsTypeTagForDatatype(false), @@ -194,7 +206,7 @@ private: bool mustBeNull, Syntax syntaxUsed) : AttrName(attrName), ScopeName(scopeName), ParmName(argumentKindName), AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(argumentKindLoc), - NumArgs(0), SyntaxUsed(syntaxUsed), + EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), IsTypeTagForDatatype(true), NextInPosition(NULL), NextInPool(NULL) { TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); @@ -204,6 +216,20 @@ private: AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } + /// Constructor for attributes with a single type argument. + AttributeList(IdentifierInfo *attrName, SourceRange attrRange, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + ParsedType typeArg, Syntax syntaxUsed) + : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), + AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), + EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), + UsedAsTypeAttr(false), IsAvailability(false), + IsTypeTagForDatatype(false), NextInPosition(0), NextInPool(0) { + new (&getTypeBuffer()) ParsedType(typeArg); + AttrKind = getKind(getName(), getScopeName(), syntaxUsed); + } + friend class AttributePool; friend class AttributeFactory; @@ -227,12 +253,16 @@ public: IdentifierInfo *getParameterName() const { return ParmName; } SourceLocation getParameterLoc() const { return ParmLoc; } - /// Returns true if the attribute is a pure __declspec or a synthesized - /// declspec representing a type specification (like __w64 or __ptr32). - bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec || - SyntaxUsed == AS_MSTypespec; } - bool isCXX0XAttribute() const { return SyntaxUsed == AS_CXX11; } - bool isMSTypespecAttribute() const { return SyntaxUsed == AS_MSTypespec; } + bool isAlignasAttribute() const { + // FIXME: Use a better mechanism to determine this. + return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword; + } + + bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; } + bool isCXX11Attribute() const { + return SyntaxUsed == AS_CXX11 || isAlignasAttribute(); + } + bool isKeywordAttribute() const { return SyntaxUsed == AS_Keyword; } bool isInvalid() const { return Invalid; } void setInvalid(bool b = true) const { Invalid = b; } @@ -240,6 +270,9 @@ public: bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; } void setUsedAsTypeAttr() { UsedAsTypeAttr = true; } + bool isPackExpansion() const { return EllipsisLoc.isValid(); } + SourceLocation getEllipsisLoc() const { return EllipsisLoc; } + Kind getKind() const { return Kind(AttrKind); } static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope, Syntax SyntaxUsed); @@ -340,6 +373,16 @@ public: "Not a type_tag_for_datatype attribute"); return getTypeTagForDatatypeDataSlot().MustBeNull; } + + const ParsedType &getTypeArg() const { + assert(getKind() == AT_VecTypeHint && "Not a type attribute"); + return getTypeBuffer(); + } + + /// \brief Get an index into the attribute spelling list + /// defined in Attr.td. This index is used by an attribute + /// to pretty print itself. + unsigned getAttributeSpellingListIndex() const; }; /// A factory, from which one makes pools, from which one creates @@ -448,13 +491,15 @@ public: IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, Expr **args, unsigned numArgs, - AttributeList::Syntax syntax) { + AttributeList::Syntax syntax, + SourceLocation ellipsisLoc = SourceLocation()) { void *memory = allocate(sizeof(AttributeList) + numArgs * sizeof(Expr*)); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, - args, numArgs, syntax)); + args, numArgs, syntax, + ellipsisLoc)); } AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, @@ -491,6 +536,18 @@ public: matchingCType, layoutCompatible, mustBeNull, syntax)); } + + AttributeList *createTypeAttribute( + IdentifierInfo *attrName, SourceRange attrRange, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + ParsedType typeArg, AttributeList::Syntax syntaxUsed) { + void *memory = allocate(sizeof(AttributeList) + sizeof(void *)); + return add(new (memory) AttributeList(attrName, attrRange, + scopeName, scopeLoc, + parmName, parmLoc, + typeArg, syntaxUsed)); + } }; /// addAttributeLists - Add two AttributeLists together @@ -511,18 +568,18 @@ inline AttributeList *addAttributeLists(AttributeList *Left, return Left; } -/// CXX0XAttributeList - A wrapper around a C++0x attribute list. +/// CXX11AttributeList - A wrapper around a C++11 attribute list. /// Stores, in addition to the list proper, whether or not an actual list was /// (as opposed to an empty list, which may be ill-formed in some places) and /// the source range of the list. -struct CXX0XAttributeList { +struct CXX11AttributeList { AttributeList *AttrList; SourceRange Range; bool HasAttr; - CXX0XAttributeList (AttributeList *attrList, SourceRange range, bool hasAttr) + CXX11AttributeList (AttributeList *attrList, SourceRange range, bool hasAttr) : AttrList(attrList), Range(range), HasAttr (hasAttr) { } - CXX0XAttributeList () + CXX11AttributeList () : AttrList(0), Range(), HasAttr(false) { } }; @@ -588,10 +645,11 @@ public: IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *parmName, SourceLocation parmLoc, Expr **args, unsigned numArgs, - AttributeList::Syntax syntax) { + AttributeList::Syntax syntax, + SourceLocation ellipsisLoc = SourceLocation()) { AttributeList *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, - args, numArgs, syntax); + args, numArgs, syntax, ellipsisLoc); add(attr); return attr; } @@ -632,6 +690,19 @@ public: return attr; } + /// Add an attribute with a single type argument. + AttributeList * + addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, + IdentifierInfo *scopeName, SourceLocation scopeLoc, + IdentifierInfo *parmName, SourceLocation parmLoc, + ParsedType typeArg, AttributeList::Syntax syntaxUsed) { + AttributeList *attr = + pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc, + parmName, parmLoc, typeArg, syntaxUsed); + add(attr); + return attr; + } + AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name, SourceLocation loc, int arg) { AttributeList *attr = |