15 #ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H 16 #define LLVM_CLANG_SEMA_ATTRIBUTELIST_H 23 #include "llvm/ADT/PointerUnion.h" 24 #include "llvm/ADT/SmallVector.h" 25 #include "llvm/Support/Allocator.h" 52 IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
56 struct AvailabilityData {
57 AvailabilityChange
Changes[NumAvailabilitySlots];
60 AvailabilityData(
const AvailabilityChange &Introduced,
61 const AvailabilityChange &Deprecated,
62 const AvailabilityChange &Obsoleted,
63 SourceLocation Strict,
const Expr *ReplaceExpr)
64 : StrictLoc(Strict), Replacement(ReplaceExpr) {
65 Changes[IntroducedSlot] = Introduced;
66 Changes[DeprecatedSlot] = Deprecated;
67 Changes[ObsoletedSlot] = Obsoleted;
83 typedef llvm::PointerUnion<Expr*, IdentifierLoc*>
ArgsUnion;
126 unsigned AttrKind : 16;
130 unsigned NumArgs : 16;
133 unsigned SyntaxUsed : 3;
136 mutable unsigned Invalid : 1;
139 mutable unsigned UsedAsTypeAttr : 1;
143 unsigned IsAvailability : 1;
147 unsigned IsTypeTagForDatatype : 1;
151 unsigned IsProperty : 1;
154 unsigned HasParsedType : 1;
157 mutable unsigned HasProcessingCache : 1;
160 mutable unsigned ProcessingCache : 8;
166 const Expr *MessageExpr;
175 ArgsUnion *getArgsBuffer() {
return reinterpret_cast<ArgsUnion *
>(
this + 1); }
176 ArgsUnion
const *getArgsBuffer()
const {
177 return reinterpret_cast<ArgsUnion
const *
>(
this + 1);
182 AvailabilityData *getAvailabilityData() {
183 return reinterpret_cast<AvailabilityData*
>(getArgsBuffer() + NumArgs);
185 const AvailabilityData *getAvailabilityData()
const {
186 return reinterpret_cast<const AvailabilityData*
>(getArgsBuffer() + NumArgs);
198 : GetterId(getterId), SetterId(setterId) {}
217 return *
reinterpret_cast<ParsedType *
>(
this + 1);
221 return *
reinterpret_cast<const ParsedType *
>(
this + 1);
233 return *
reinterpret_cast<const PropertyData*
>(
this + 1);
238 void operator delete(
void *) =
delete;
241 size_t allocated_size()
const;
246 ArgsUnion *args,
unsigned numArgs,
248 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
249 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
250 SyntaxUsed(syntaxUsed), Invalid(
false), UsedAsTypeAttr(
false),
251 IsAvailability(
false), IsTypeTagForDatatype(
false), IsProperty(
false),
252 HasParsedType(
false), HasProcessingCache(
false),
253 NextInPosition(
nullptr), NextInPool(
nullptr) {
254 if (numArgs) memcpy(getArgsBuffer(), args, numArgs *
sizeof(ArgsUnion));
255 AttrKind =
getKind(getName(), getScopeName(), syntaxUsed);
265 const Expr *messageExpr,
267 const Expr *replacementExpr)
268 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
269 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
270 Invalid(
false), UsedAsTypeAttr(
false), IsAvailability(
true),
271 IsTypeTagForDatatype(
false), IsProperty(
false), HasParsedType(
false),
272 HasProcessingCache(
false), UnavailableLoc(unavailable),
273 MessageExpr(messageExpr), NextInPosition(
nullptr), NextInPool(
nullptr) {
274 ArgsUnion PVal(Parm);
275 memcpy(getArgsBuffer(), &PVal,
sizeof(ArgsUnion));
276 new (getAvailabilityData()) AvailabilityData(
277 introduced, deprecated, obsoleted, strict, replacementExpr);
278 AttrKind =
getKind(getName(), getScopeName(), syntaxUsed);
288 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
289 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
290 Invalid(
false), UsedAsTypeAttr(
false), IsAvailability(
false),
291 IsTypeTagForDatatype(
false), IsProperty(
false), HasParsedType(
false),
292 HasProcessingCache(
false), NextInPosition(
nullptr), NextInPool(
nullptr) {
293 ArgsUnion *Args = getArgsBuffer();
297 AttrKind =
getKind(getName(), getScopeName(), syntaxUsed);
304 bool layoutCompatible,
bool mustBeNull,
Syntax syntaxUsed)
305 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
306 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
307 Invalid(
false), UsedAsTypeAttr(
false), IsAvailability(
false),
308 IsTypeTagForDatatype(
true), IsProperty(
false), HasParsedType(
false),
309 HasProcessingCache(
false), NextInPosition(
nullptr), NextInPool(
nullptr) {
310 ArgsUnion PVal(ArgKind);
311 memcpy(getArgsBuffer(), &PVal,
sizeof(ArgsUnion));
316 AttrKind =
getKind(getName(), getScopeName(), syntaxUsed);
323 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
324 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
325 Invalid(
false), UsedAsTypeAttr(
false), IsAvailability(
false),
326 IsTypeTagForDatatype(
false), IsProperty(
false), HasParsedType(
true),
327 HasProcessingCache(
false), NextInPosition(
nullptr), NextInPool(
nullptr){
329 AttrKind =
getKind(getName(), getScopeName(), syntaxUsed);
337 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
338 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
339 Invalid(
false), UsedAsTypeAttr(
false), IsAvailability(
false),
340 IsTypeTagForDatatype(
false), IsProperty(
true), HasParsedType(
false),
341 HasProcessingCache(
false), NextInPosition(
nullptr), NextInPool(
nullptr) {
342 new (&getPropertyDataBuffer())
PropertyData(getterId, setterId);
343 AttrKind =
getKind(getName(), getScopeName(), syntaxUsed);
351 #define PARSED_ATTR(NAME) AT_##NAME, 352 #include "clang/Sema/AttrParsedAttrList.inc" 375 return getKind() == AT_Aligned && isKeywordAttribute();
381 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
384 return SyntaxUsed == AS_C2x;
387 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
391 return SyntaxUsed == AS_ContextSensitiveKeyword;
399 assert(hasProcessingCache());
400 return ProcessingCache;
403 ProcessingCache = value;
404 HasProcessingCache =
true;
425 assert(Arg < NumArgs &&
"Arg access out of range!");
426 return getArgsBuffer()[Arg];
430 return Arg < NumArgs && getArg(Arg).is<
Expr*>();
433 return getArg(Arg).get<
Expr*>();
444 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
445 return getAvailabilityData()->Changes[IntroducedSlot];
449 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
450 return getAvailabilityData()->Changes[DeprecatedSlot];
454 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
455 return getAvailabilityData()->Changes[ObsoletedSlot];
459 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
460 return getAvailabilityData()->StrictLoc;
464 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
465 return UnavailableLoc;
469 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
474 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
475 return getAvailabilityData()->Replacement;
479 assert(
getKind() == AT_TypeTagForDatatype &&
480 "Not a type_tag_for_datatype attribute");
481 return *getTypeTagForDatatypeDataSlot().MatchingCType;
485 assert(
getKind() == AT_TypeTagForDatatype &&
486 "Not a type_tag_for_datatype attribute");
487 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
491 assert(
getKind() == AT_TypeTagForDatatype &&
492 "Not a type_tag_for_datatype attribute");
493 return getTypeTagForDatatypeDataSlot().MustBeNull;
497 assert(HasParsedType &&
"Not a type attribute");
498 return getTypeBuffer();
502 assert(isDeclspecPropertyAttribute() &&
"Not a __delcspec(property) attribute");
503 return getPropertyDataBuffer();
509 unsigned getAttributeSpellingListIndex()
const;
511 bool isTargetSpecificAttr()
const;
512 bool isTypeAttr()
const;
513 bool isStmtAttr()
const;
515 bool hasCustomParsing()
const;
516 unsigned getMinArgs()
const;
517 unsigned getMaxArgs()
const;
518 bool hasVariadicArg()
const;
519 bool diagnoseAppertainsTo(
class Sema &S,
const Decl *D)
const;
524 bool diagnoseLangOpts(
class Sema &S)
const;
525 bool existsInTarget(
const TargetInfo &Target)
const;
526 bool isKnownToGCC()
const;
527 bool isSupportedByPragmaAttribute()
const;
534 unsigned getSemanticSpelling()
const;
547 AvailabilityAllocSize =
549 + ((
sizeof(AvailabilityData) +
sizeof(
void*) +
sizeof(ArgsUnion) - 1)
550 /
sizeof(
void*) *
sizeof(
void*)),
551 TypeTagForDatatypeAllocSize =
555 /
sizeof(
void*) *
sizeof(
void*),
559 /
sizeof(
void*) *
sizeof(
void*)
569 InlineFreeListsCapacity =
570 1 + (AvailabilityAllocSize -
sizeof(
AttributeList)) /
sizeof(
void*)
573 llvm::BumpPtrAllocator Alloc;
583 void *allocate(
size_t size);
601 void *allocate(
size_t size) {
602 return Factory.allocate(size);
607 attr->NextInPool = Head;
629 Factory.reclaimPool(Head);
643 if (Head) Factory.reclaimPool(Head);
648 ArgsUnion *args,
unsigned numArgs,
652 + numArgs *
sizeof(ArgsUnion));
655 args, numArgs, syntax,
666 const Expr *MessageExpr,
672 Param, introduced, deprecated,
673 obsoleted, unavailable, MessageExpr,
674 syntax, strict, ReplacementExpr));
684 void *memory = allocate(size);
687 Param1, Param2, Param3,
695 bool layoutCompatible,
bool mustBeNull,
700 argumentKind, matchingCType,
701 layoutCompatible, mustBeNull,
709 void *memory = allocate(
sizeof(
AttributeList) +
sizeof(
void *));
712 typeArg, syntaxUsed));
737 : pool(factory), list(nullptr) {
744 bool empty()
const {
return list ==
nullptr; }
748 assert(newAttr->
getNext() ==
nullptr);
754 if (!newList)
return;
758 lastInNewList = next;
783 attrs.list =
nullptr;
784 pool.takeAllFrom(attrs.pool);
787 void clear() { list =
nullptr; pool.clear(); }
799 ArgsUnion *args,
unsigned numArgs,
803 pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
804 syntax, ellipsisLoc);
817 const Expr *MessageExpr,
821 pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
822 deprecated, obsoleted, unavailable, MessageExpr, syntax,
823 strict, ReplacementExpr);
836 pool.create(attrName, attrRange, scopeName, scopeLoc,
837 Param1, Param2, Param3, syntax);
847 bool layoutCompatible,
bool mustBeNull,
850 pool.createTypeTagForDatatype(attrName, attrRange,
852 argumentKind, matchingCType,
853 layoutCompatible, mustBeNull, syntax);
864 pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
865 typeArg, syntaxUsed);
877 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
878 getterId, setterId, syntaxUsed);
bool isAlignasAttribute() const
AttributeList * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, AttributeList::Syntax syntaxUsed)
Add microsoft __delspec(property) attribute.
void setProcessingCache(unsigned value) const
bool isUsedAsTypeAttr() const
const Expr * getMessageExpr() const
Represents a version number in the form major[.minor[.subminor[.build]]].
AttributeList * getNext() const
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
ParsedAttributes(AttributeFactory &factory)
const AvailabilityChange & getAvailabilityIntroduced() const
AttributeList * createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, AttributeList::Syntax syntaxUsed)
unsigned getProcessingCache() const
Decl - This represents one declaration (or definition), e.g.
bool getMustBeNull() const
AttributeList * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr, AttributeList::Syntax syntax, SourceLocation strict, const Expr *ReplacementExpr)
bool isArgIdent(unsigned Arg) const
AttributeList * getList() const
void addAll(AttributeList *newList)
SourceLocation getLoc() const
__ptr16, alignas(...), etc.
One of these records is kept for each identifier that is lexed.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
SubjectMatchRule
A list of all the recognized kinds of attributes.
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an AttributeList as an argument...
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
ArgsUnion getArg(unsigned Arg) const
getArg - Return the specified argument.
const PropertyData & getPropertyData() const
AttributeList * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, AttributeList::Syntax syntaxUsed)
Add an attribute with a single type argument.
AttributeList * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param1, IdentifierLoc *Param2, IdentifierLoc *Param3, AttributeList::Syntax syntax)
SourceLocation getScopeLoc() const
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
bool getLayoutCompatible() const
bool isDeclspecPropertyAttribute() const
Is this the Microsoft __declspec(property) attribute?
ParsedType * MatchingCType
AttributeArgumentNType
These constants match the enumerated choices of err_attribute_argument_n_type and err_attribute_argum...
bool isKeywordAttribute() const
void takeAllFrom(ParsedAttributes &attrs)
IdentifierLoc * getArgAsIdent(unsigned Arg) const
Scope - A scope is a transient data structure that is used while parsing the program.
Represents information about a change in availability for an entity, which is part of the encoding of...
AvailabilityChange Changes[NumAvailabilitySlots]
AttributeList * createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, AttributeList::Syntax syntax)
VersionTuple Version
The version number at which the change occurred.
unsigned LayoutCompatible
Sema - This implements semantic analysis and AST building for C.
Exposes information about the current target.
Expr - This represents one expression.
void addAllAtEnd(AttributeList *newList)
AttributeFactory & getFactory() const
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
bool isValid() const
Determine whether this availability change is valid.
const AvailabilityChange & getAvailabilityObsoleted() const
Wraps an identifier and optional source location for the identifier.
bool isCXX11Attribute() const
SourceRange VersionRange
The source range covering the version number.
AttributeList * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
bool hasParsedType() const
SourceRange getRange() const
bool isC2xAttribute() const
Context-sensitive version of a keyword attribute.
IdentifierInfo * SetterId
bool empty() const
Determine whether this version information is empty (e.g., all version components are zero)...
AttributeList * createTypeAttribute(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, AttributeList::Syntax syntaxUsed)
Encodes a location in the source.
bool isContextSensitiveKeywordAttribute() const
SourceLocation getUnavailableLoc() const
IdentifierInfo * getScopeName() const
const ParsedType & getMatchingCType() const
bool isDeclspecAttribute() const
llvm::SmallVector< ArgsUnion, 12U > ArgsVector
AttributeList * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param, const AvailabilityChange &introduced, const AvailabilityChange &deprecated, const AvailabilityChange &obsoleted, SourceLocation unavailable, const Expr *MessageExpr, AttributeList::Syntax syntax, SourceLocation strict, const Expr *ReplacementExpr)
Add availability attribute.
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
bool isMicrosoftAttribute() const
bool hasProcessingCache() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
Expr * getArgAsExpr(unsigned Arg) const
void takeAllFrom(AttributePool &pool)
Take the given pool's allocations and add them to this pool.
AttributePool(AttributeFactory &factory)
Create a new pool for a factory.
const AvailabilityChange & getAvailabilityDeprecated() const
IdentifierInfo * getName() const
void add(AttributeList *newAttr)
Syntax
The style used to specify an attribute.
const ParsedType & getTypeArg() const
bool isPackExpansion() const
bool isArgExpr(unsigned Arg) const
void setNext(AttributeList *N)
void setInvalid(bool b=true) const
AttributeList * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, AttributeList::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
const Expr * getReplacementExpr() const
SourceLocation getStrictLoc() const
Defines the clang::SourceLocation class and associated facilities.
The required allocation size of an availability attribute, which we want to ensure is a multiple of s...
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
SourceLocation getEllipsisLoc() const
AttributePool(AttributePool &&pool)
Move the given pool's allocations to this pool.
AttributePool & getPool() const
Defines the clang::TargetInfo interface.
Defines the clang::VersionTuple class, which represents a version in the form major[.minor[.subminor]].
static Decl::Kind getKind(const Decl *D)
A trivial tuple used to represent a source range.
AttributeList * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param1, IdentifierLoc *Param2, IdentifierLoc *Param3, AttributeList::Syntax syntax)
Add objc_bridge_related attribute.
SourceLocation getBegin() const
ParsedAttributes - A collection of parsed attributes.
AttributeDeclKind
These constants match the enumerated choices of warn_attribute_wrong_decl_type and err_attribute_wron...
AttributeList *& getListRef()
Returns a reference to the attribute list.
AttributeList * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, AttributeList::Syntax syntax)
Add type_tag_for_datatype attribute.
AttributeList - Represents a syntactic attribute.