diff options
Diffstat (limited to 'include/clang/Sema/AttributeList.h')
-rw-r--r-- | include/clang/Sema/AttributeList.h | 233 |
1 files changed, 133 insertions, 100 deletions
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h index d5f3177..508064d 100644 --- a/include/clang/Sema/AttributeList.h +++ b/include/clang/Sema/AttributeList.h @@ -19,6 +19,7 @@ #include "clang/Basic/VersionTuple.h" #include "clang/Sema/Ownership.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/PointerUnion.h" #include "llvm/Support/Allocator.h" #include <cassert> @@ -44,6 +45,20 @@ struct AvailabilityChange { bool isValid() const { return !Version.empty(); } }; +/// \brief Wraps an identifier and optional source location for the identifier. +struct IdentifierLoc { + SourceLocation Loc; + IdentifierInfo *Ident; + + static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc, + IdentifierInfo *Ident); +}; + +/// \brief A union of the various pointer types that can be passed to an +/// AttributeList as an argument. +typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion; +typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector; + /// AttributeList - Represents a syntactic attribute. /// /// For a GNU attribute, there are four forms of this construct: @@ -66,13 +81,12 @@ public: /// __ptr16, alignas(...), etc. AS_Keyword }; + private: IdentifierInfo *AttrName; IdentifierInfo *ScopeName; - IdentifierInfo *ParmName; SourceRange AttrRange; SourceLocation ScopeLoc; - SourceLocation ParmLoc; SourceLocation EllipsisLoc; /// The number of expression arguments this attribute has. @@ -100,6 +114,9 @@ private: /// Microsoft __delcspec(property) attribute. unsigned IsProperty : 1; + /// True if this has a ParsedType + unsigned HasParsedType : 1; + unsigned AttrKind : 8; /// \brief The location of the 'unavailable' keyword in an @@ -114,22 +131,27 @@ private: /// The next attribute allocated in the current Pool. AttributeList *NextInPool; - Expr **getArgsBuffer() { - return reinterpret_cast<Expr**>(this+1); + /// Arguments, if any, are stored immediately following the object. + ArgsUnion *getArgsBuffer() { + return reinterpret_cast<ArgsUnion*>(this+1); } - Expr * const *getArgsBuffer() const { - return reinterpret_cast<Expr* const *>(this+1); + ArgsUnion const *getArgsBuffer() const { + return reinterpret_cast<ArgsUnion const *>(this+1); } enum AvailabilitySlot { IntroducedSlot, DeprecatedSlot, ObsoletedSlot }; - AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) { - return reinterpret_cast<AvailabilityChange*>(this+1)[index]; + /// Availability information is stored immediately following the arguments, + /// if any, at the end of the object. + AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) { + return reinterpret_cast<AvailabilityChange*>(getArgsBuffer() + + NumArgs)[index]; } const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const { - return reinterpret_cast<const AvailabilityChange*>(this+1)[index]; + return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer() + + NumArgs)[index]; } public: @@ -145,14 +167,20 @@ public: }; private: + /// Type tag information is stored immediately following the arguments, if + /// any, at the end of the object. They are mutually exlusive with + /// availability slots. TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() { - return *reinterpret_cast<TypeTagForDatatypeData *>(this + 1); + return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs); } const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const { - return *reinterpret_cast<const TypeTagForDatatypeData *>(this + 1); + return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer() + + NumArgs); } + /// The type buffer immediately follows the object and are mutually exclusive + /// with arguments. ParsedType &getTypeBuffer() { return *reinterpret_cast<ParsedType *>(this + 1); } @@ -161,6 +189,8 @@ private: return *reinterpret_cast<const ParsedType *>(this + 1); } + /// The property data immediately follows the object is is mutually exclusive + /// with arguments. PropertyData &getPropertyDataBuffer() { assert(IsProperty); return *reinterpret_cast<PropertyData*>(this + 1); @@ -181,36 +211,34 @@ private: /// Constructor for attributes with expression arguments. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, - Expr **args, unsigned numArgs, + ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed, SourceLocation ellipsisLoc) - : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), - EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed), - Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0), - NextInPool(0) { - if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*)); + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs), + SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), + IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), + HasParsedType(false), NextInPosition(0), NextInPool(0) { + if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion)); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } /// Constructor for availability attributes. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, - const AvailabilityChange &introduced, + IdentifierLoc *Parm, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *messageExpr, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(), - NumArgs(0), SyntaxUsed(syntaxUsed), + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), - IsTypeTagForDatatype(false), IsProperty(false), + IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), UnavailableLoc(unavailable), MessageExpr(messageExpr), NextInPosition(0), NextInPool(0) { + ArgsUnion PVal(Parm); + memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); @@ -220,16 +248,15 @@ private: /// Constructor for type_tag_for_datatype attribute. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *argumentKindName, - SourceLocation argumentKindLoc, - ParsedType matchingCType, bool layoutCompatible, - bool mustBeNull, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), ParmName(argumentKindName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(argumentKindLoc), - EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), + IdentifierLoc *ArgKind, ParsedType matchingCType, + bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed) + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(true), IsProperty(false), NextInPosition(NULL), - NextInPool(NULL) { + IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false), + NextInPosition(NULL), NextInPool(NULL) { + ArgsUnion PVal(ArgKind); + memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); new (&ExtraData.MatchingCType) ParsedType(matchingCType); ExtraData.LayoutCompatible = layoutCompatible; @@ -240,14 +267,12 @@ private: /// 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), IsProperty(false), NextInPosition(0), - NextInPool(0) { + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), + Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), + IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true), + NextInPosition(0), NextInPool(0) { new (&getTypeBuffer()) ParsedType(typeArg); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -255,15 +280,13 @@ private: /// Constructor for microsoft __declspec(property) attribute. AttributeList(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, Syntax syntaxUsed) - : AttrName(attrName), ScopeName(scopeName), ParmName(parmName), - AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), - SyntaxUsed(syntaxUsed), + : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), + ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), - IsTypeTagForDatatype(false), IsProperty(true), NextInPosition(0), - NextInPool(0) { + IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), + NextInPosition(0), NextInPool(0) { new (&getPropertyDataBuffer()) PropertyData(getterId, setterId); AttrKind = getKind(getName(), getScopeName(), syntaxUsed); } @@ -288,8 +311,7 @@ public: IdentifierInfo *getScopeName() const { return ScopeName; } SourceLocation getScopeLoc() const { return ScopeLoc; } - IdentifierInfo *getParameterName() const { return ParmName; } - SourceLocation getParameterLoc() const { return ParmLoc; } + bool hasParsedType() const { return HasParsedType; } /// Is this the Microsoft __declspec(property) attribute? bool isDeclspecPropertyAttribute() const { @@ -326,21 +348,31 @@ public: /// getNumArgs - Return the number of actual arguments to this attribute. unsigned getNumArgs() const { return NumArgs; } - /// hasParameterOrArguments - Return true if this attribute has a parameter, - /// or has a non empty argument expression list. - bool hasParameterOrArguments() const { return ParmName || NumArgs; } - /// getArg - Return the specified argument. - Expr *getArg(unsigned Arg) const { + ArgsUnion getArg(unsigned Arg) const { assert(Arg < NumArgs && "Arg access out of range!"); return getArgsBuffer()[Arg]; } + bool isArgExpr(unsigned Arg) const { + return Arg < NumArgs && getArg(Arg).is<Expr*>(); + } + Expr *getArgAsExpr(unsigned Arg) const { + return getArg(Arg).get<Expr*>(); + } + + bool isArgIdent(unsigned Arg) const { + return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>(); + } + IdentifierLoc *getArgAsIdent(unsigned Arg) const { + return getArg(Arg).get<IdentifierLoc*>(); + } + class arg_iterator { - Expr * const *X; + ArgsUnion const *X; unsigned Idx; public: - arg_iterator(Expr * const *x, unsigned idx) : X(x), Idx(idx) {} + arg_iterator(ArgsUnion const *x, unsigned idx) : X(x), Idx(idx) {} arg_iterator& operator++() { ++Idx; @@ -357,7 +389,7 @@ public: return !operator==(I); } - Expr* operator*() const { + ArgsUnion operator*() const { return X[Idx]; } @@ -418,7 +450,7 @@ public: } const ParsedType &getTypeArg() const { - assert(getKind() == AT_VecTypeHint && "Not a type attribute"); + assert(HasParsedType && "Not a type attribute"); return getTypeBuffer(); } @@ -431,6 +463,10 @@ public: /// defined in Attr.td. This index is used by an attribute /// to pretty print itself. unsigned getAttributeSpellingListIndex() const; + + bool hasCustomParsing() const; + unsigned getMinArgs() const; + unsigned getMaxArgs() const; }; /// A factory, from which one makes pools, from which one creates @@ -445,11 +481,13 @@ public: /// which we want to ensure is a multiple of sizeof(void*). AvailabilityAllocSize = sizeof(AttributeList) - + ((3 * sizeof(AvailabilityChange) + sizeof(void*) - 1) + + ((3 * sizeof(AvailabilityChange) + sizeof(void*) + + sizeof(ArgsUnion) - 1) / sizeof(void*) * sizeof(void*)), TypeTagForDatatypeAllocSize = sizeof(AttributeList) - + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) - 1) + + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) + + sizeof(ArgsUnion) - 1) / sizeof(void*) * sizeof(void*), PropertyAllocSize = sizeof(AttributeList) @@ -541,22 +579,20 @@ public: AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, - Expr **args, unsigned numArgs, + ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc = SourceLocation()) { void *memory = allocate(sizeof(AttributeList) - + numArgs * sizeof(Expr*)); + + numArgs * sizeof(ArgsUnion)); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, args, numArgs, syntax, ellipsisLoc)); } AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, + IdentifierLoc *Param, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, @@ -566,9 +602,9 @@ public: void *memory = allocate(AttributeFactory::AvailabilityAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, - introduced, deprecated, obsoleted, - unavailable, MessageExpr, syntax)); + Param, introduced, deprecated, + obsoleted, unavailable, MessageExpr, + syntax)); } AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name, @@ -577,40 +613,35 @@ public: AttributeList *createTypeTagForDatatype( IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *argumentKindName, - SourceLocation argumentKindLoc, - ParsedType matchingCType, bool layoutCompatible, - bool mustBeNull, AttributeList::Syntax syntax) { + IdentifierLoc *argumentKind, ParsedType matchingCType, + bool layoutCompatible, bool mustBeNull, + AttributeList::Syntax syntax) { void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - argumentKindName, argumentKindLoc, - matchingCType, layoutCompatible, - mustBeNull, syntax)); + argumentKind, 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)); } AttributeList *createPropertyAttribute( IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, AttributeList::Syntax syntaxUsed) { void *memory = allocate(AttributeFactory::PropertyAllocSize); return add(new (memory) AttributeList(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, getterId, setterId, syntaxUsed)); } @@ -709,13 +740,12 @@ public: /// Add attribute with expression arguments. AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, - Expr **args, unsigned numArgs, + ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc = SourceLocation()) { AttributeList *attr = - pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, - args, numArgs, syntax, ellipsisLoc); + pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs, + syntax, ellipsisLoc); add(attr); return attr; } @@ -723,7 +753,7 @@ public: /// Add availability attribute. AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, + IdentifierLoc *Param, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, @@ -731,9 +761,8 @@ public: const Expr *MessageExpr, AttributeList::Syntax syntax) { AttributeList *attr = - pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc, - introduced, deprecated, obsoleted, unavailable, - MessageExpr, syntax); + pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced, + deprecated, obsoleted, unavailable, MessageExpr, syntax); add(attr); return attr; } @@ -742,16 +771,14 @@ public: AttributeList *addNewTypeTagForDatatype( IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *argumentKindName, - SourceLocation argumentKindLoc, - ParsedType matchingCType, bool layoutCompatible, - bool mustBeNull, AttributeList::Syntax syntax) { + IdentifierLoc *argumentKind, ParsedType matchingCType, + bool layoutCompatible, bool mustBeNull, + AttributeList::Syntax syntax) { AttributeList *attr = pool.createTypeTagForDatatype(attrName, attrRange, scopeName, scopeLoc, - argumentKindName, argumentKindLoc, - matchingCType, layoutCompatible, - mustBeNull, syntax); + argumentKind, matchingCType, + layoutCompatible, mustBeNull, syntax); add(attr); return attr; } @@ -760,11 +787,10 @@ public: 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); + typeArg, syntaxUsed); add(attr); return attr; } @@ -773,13 +799,11 @@ public: AttributeList * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, - IdentifierInfo *parmName, SourceLocation parmLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, AttributeList::Syntax syntaxUsed) { AttributeList *attr = pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc, - parmName, parmLoc, getterId, setterId, - syntaxUsed); + getterId, setterId, syntaxUsed); add(attr); return attr; } @@ -798,6 +822,15 @@ private: AttributeList *list; }; +/// These constants match the enumerated choices of +/// err_attribute_argument_n_type and err_attribute_argument_type. +enum AttributeArgumentNType { + AANT_ArgumentIntOrBool, + AANT_ArgumentIntegerConstant, + AANT_ArgumentString, + AANT_ArgumentIdentifier +}; + } // end namespace clang #endif |