aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Sema/AttributeList.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang/Sema/AttributeList.h')
-rw-r--r--include/clang/Sema/AttributeList.h233
1 files changed, 133 insertions, 100 deletions
diff --git a/include/clang/Sema/AttributeList.h b/include/clang/Sema/AttributeList.h
index d5f31779a635..508064def2ca 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