15 #ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H 16 #define LLVM_CLANG_SEMA_ATTRIBUTELIST_H 22 #include "llvm/ADT/PointerUnion.h" 23 #include "llvm/ADT/SmallVector.h" 24 #include "llvm/ADT/TinyPtrVector.h" 25 #include "llvm/Support/Allocator.h" 26 #include "llvm/Support/VersionTuple.h" 54 bool isValid()
const {
return !Version.empty(); }
60 IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
64 struct AvailabilityData {
65 AvailabilityChange
Changes[NumAvailabilitySlots];
69 AvailabilityData(
const AvailabilityChange &Introduced,
70 const AvailabilityChange &Deprecated,
71 const AvailabilityChange &Obsoleted,
72 SourceLocation Strict,
const Expr *ReplaceExpr)
73 : StrictLoc(Strict), Replacement(ReplaceExpr) {
74 Changes[IntroducedSlot] = Introduced;
75 Changes[DeprecatedSlot] = Deprecated;
76 Changes[ObsoletedSlot] = Obsoleted;
93 using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
143 unsigned AttrKind : 16;
147 unsigned NumArgs : 16;
150 unsigned SyntaxUsed : 3;
153 mutable unsigned Invalid : 1;
156 mutable unsigned UsedAsTypeAttr : 1;
160 unsigned IsAvailability : 1;
164 unsigned IsTypeTagForDatatype : 1;
168 unsigned IsProperty : 1;
171 unsigned HasParsedType : 1;
174 mutable unsigned HasProcessingCache : 1;
177 mutable unsigned ProcessingCache : 8;
183 const Expr *MessageExpr;
188 return reinterpret_cast<ArgsUnion const *
>(
this + 1);
193 AvailabilityData *getAvailabilityData() {
194 return reinterpret_cast<AvailabilityData*
>(getArgsBuffer() + NumArgs);
196 const AvailabilityData *getAvailabilityData()
const {
197 return reinterpret_cast<const AvailabilityData*
>(getArgsBuffer() + NumArgs);
210 : GetterId(getterId), SetterId(setterId) {}
222 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
223 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
224 SyntaxUsed(syntaxUsed), Invalid(
false), UsedAsTypeAttr(
false),
226 HasParsedType(
false), HasProcessingCache(
false) {
227 if (numArgs)
memcpy(getArgsBuffer(), args, numArgs *
sizeof(
ArgsUnion));
238 const Expr *replacementExpr)
239 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
240 ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(
false),
241 UsedAsTypeAttr(
false), IsAvailability(
true),
243 HasProcessingCache(
false), UnavailableLoc(unavailable),
244 MessageExpr(messageExpr) {
247 new (getAvailabilityData()) AvailabilityData(
248 introduced, deprecated, obsoleted, strict, replacementExpr);
257 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
258 ScopeLoc(scopeLoc), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(
false),
261 HasProcessingCache(
false) {
273 bool layoutCompatible,
bool mustBeNull,
Syntax syntaxUsed)
274 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
275 ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(
false),
277 IsTypeTagForDatatype(
true), IsProperty(
false), HasParsedType(
false),
278 HasProcessingCache(
false) {
292 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
293 ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(
false),
295 IsTypeTagForDatatype(
false), IsProperty(
false), HasParsedType(
true),
296 HasProcessingCache(
false) {
306 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
307 ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(
false),
309 IsTypeTagForDatatype(
false), IsProperty(
true), HasParsedType(
false),
310 HasProcessingCache(
false) {
311 new (&getPropertyDataBuffer())
PropertyData(getterId, setterId);
329 return *
reinterpret_cast<ParsedType *
>(
this + 1);
332 return *
reinterpret_cast<const ParsedType *
>(
this + 1);
343 return *
reinterpret_cast<const PropertyData*
>(
this + 1);
346 size_t allocated_size()
const;
353 void operator delete(
void *) =
delete;
356 #define PARSED_ATTR(NAME) AT_##NAME, 357 #include "clang/Sema/AttrParsedAttrList.inc" 380 return getKind() == AT_Aligned && isKeywordAttribute();
387 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
391 return SyntaxUsed == AS_C2x;
395 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
399 return SyntaxUsed == AS_ContextSensitiveKeyword;
408 assert(hasProcessingCache());
409 return ProcessingCache;
413 ProcessingCache = value;
414 HasProcessingCache =
true;
432 assert(Arg < NumArgs &&
"Arg access out of range!");
433 return getArgsBuffer()[Arg];
437 return Arg < NumArgs && getArg(Arg).is<
Expr*>();
441 return getArg(Arg).get<
Expr*>();
453 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
454 return getAvailabilityData()->Changes[IntroducedSlot];
458 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
459 return getAvailabilityData()->Changes[DeprecatedSlot];
463 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
464 return getAvailabilityData()->Changes[ObsoletedSlot];
468 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
469 return getAvailabilityData()->StrictLoc;
473 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
474 return UnavailableLoc;
478 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
483 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
484 return getAvailabilityData()->Replacement;
488 assert(
getKind() == AT_TypeTagForDatatype &&
489 "Not a type_tag_for_datatype attribute");
490 return *getTypeTagForDatatypeDataSlot().MatchingCType;
494 assert(
getKind() == AT_TypeTagForDatatype &&
495 "Not a type_tag_for_datatype attribute");
496 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
500 assert(
getKind() == AT_TypeTagForDatatype &&
501 "Not a type_tag_for_datatype attribute");
502 return getTypeTagForDatatypeDataSlot().MustBeNull;
506 assert(HasParsedType &&
"Not a type attribute");
507 return getTypeBuffer();
511 assert(isDeclspecPropertyAttribute() &&
"Not a __delcspec(property) attribute");
512 return getPropertyDataBuffer();
518 unsigned getAttributeSpellingListIndex()
const;
520 bool isTargetSpecificAttr()
const;
521 bool isTypeAttr()
const;
522 bool isStmtAttr()
const;
524 bool hasCustomParsing()
const;
525 unsigned getMinArgs()
const;
526 unsigned getMaxArgs()
const;
527 bool hasVariadicArg()
const;
528 bool diagnoseAppertainsTo(
class Sema &S,
const Decl *D)
const;
533 bool diagnoseLangOpts(
class Sema &S)
const;
535 bool isKnownToGCC()
const;
536 bool isSupportedByPragmaAttribute()
const;
543 unsigned getSemanticSpelling()
const;
557 AvailabilityAllocSize =
559 ((
sizeof(AvailabilityData) +
sizeof(
void *) +
sizeof(
ArgsUnion) - 1) /
560 sizeof(
void *) *
sizeof(
void *)),
563 sizeof(
void *) +
sizeof(
ArgsUnion) - 1) /
564 sizeof(
void *) *
sizeof(
void *),
568 sizeof(
void *) *
sizeof(
void *)
578 InlineFreeListsCapacity =
579 1 + (AvailabilityAllocSize -
sizeof(
ParsedAttr)) /
sizeof(
void *)
582 llvm::BumpPtrAllocator Alloc;
592 void *allocate(
size_t size);
611 llvm::TinyPtrVector<ParsedAttr *> Attrs;
613 void *allocate(
size_t size) {
614 return Factory.allocate(size);
618 Attrs.push_back(attr);
623 assert(llvm::is_contained(Attrs, attr) &&
624 "Can't take attribute from a pool that doesn't own it!");
625 Attrs.erase(llvm::find(Attrs, attr));
644 Factory.reclaimPool(*
this);
660 return add(
new (memory)
ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
661 args, numArgs, syntax, ellipsisLoc));
671 const Expr *ReplacementExpr) {
674 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
675 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
683 void *memory = allocate(size);
684 return add(
new (memory)
ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
685 Param1, Param2, Param3, syntax));
692 ParsedType matchingCType,
bool layoutCompatible,
695 return add(
new (memory)
ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
696 argumentKind, matchingCType,
697 layoutCompatible, mustBeNull, syntax));
705 void *memory = allocate(
sizeof(
ParsedAttr) +
sizeof(
void *));
706 return add(
new (memory)
ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
707 typeArg, syntaxUsed));
716 return add(
new (memory)
ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
717 getterId, setterId, syntaxUsed));
722 using VecTy = llvm::TinyPtrVector<ParsedAttr *>;
723 using SizeType = decltype(std::declval<VecTy>().size());
726 bool empty()
const {
return AttrList.empty(); }
727 SizeType
size()
const {
return AttrList.size(); }
733 AttrList.insert(AttrList.begin(), newAttr);
737 AttrList.push_back(newAttr);
741 assert(is_contained(AttrList, ToBeRemoved) &&
742 "Cannot remove attribute that isn't in the list");
743 AttrList.erase(llvm::find(AttrList, ToBeRemoved));
748 struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
749 std::random_access_iterator_tag,
752 iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
757 : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
758 std::random_access_iterator_tag,
768 AttrList.insert(AttrList.begin(), B.I, E.I);
772 AttrList.insert(AttrList.begin(), B.I, E.I);
776 AttrList.insert(AttrList.end(), B.I, E.I);
780 AttrList.insert(AttrList.end(), B.I, E.I);
813 pool.takeAllFrom(attrs.pool);
827 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
828 args, numArgs, syntax, ellipsisLoc);
841 const Expr *ReplacementExpr) {
843 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
844 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
854 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
855 Param1, Param2, Param3, syntax);
865 ParsedType matchingCType,
bool layoutCompatible,
867 ParsedAttr *attr = pool.createTypeTagForDatatype(
868 attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
869 layoutCompatible, mustBeNull, syntax);
879 ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
880 scopeLoc, typeArg, syntaxUsed);
892 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
893 getterId, setterId, syntaxUsed);
931 #endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H ParsedAttr * createTypeAttribute(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, ParsedAttr::Syntax syntaxUsed)
PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
ParsedAttr * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param1, IdentifierLoc *Param2, IdentifierLoc *Param3, ParsedAttr::Syntax syntax)
bool isAlignasAttribute() const
const_iterator end() const
bool isDeclspecAttribute() const
const_iterator(VecTy::const_iterator I)
unsigned LayoutCompatible
ParsedAttributes(AttributeFactory &factory)
llvm::PointerUnion< Expr *, IdentifierLoc * > ArgsUnion
A union of the various pointer types that can be passed to an ParsedAttr as an argument.
iterator(VecTy::iterator I)
The required allocation size of an availability attribute, which we want to ensure is a multiple of s...
Decl - This represents one declaration (or definition), e.g.
Expr * getArgAsExpr(unsigned Arg) const
bool getMustBeNull() const
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
bool hasParsedType() const
const_iterator begin() const
reference operator*() const
bool hasAttribute(ParsedAttr::Kind K) const
bool isCXX11Attribute() const
ParsedAttr & operator[](SizeType pos)
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
const ParsedType & getMatchingCType() const
One of these records is kept for each identifier that is lexed.
SubjectMatchRule
A list of all the recognized kinds of attributes.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this attribute.
AttributeArgumentNType
These constants match the enumerated choices of err_attribute_argument_n_type and err_attribute_argum...
void takeAllFrom(ParsedAttributes &attrs)
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...
void addAtEnd(ParsedAttr *newAttr)
VersionTuple Version
The version number at which the change occurred.
void setInvalid(bool b=true) const
bool isDeclspecPropertyAttribute() const
Is this the Microsoft __declspec(property) attribute?
Sema - This implements semantic analysis and AST building for C.
ParsedAttr * addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Syntax syntax)
Add type_tag_for_datatype attribute.
void addAllAtEnd(const_iterator B, const_iterator E)
Exposes information about the current target.
SourceLocation getScopeLoc() const
Expr - This represents one expression.
ParsedAttr * addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Syntax syntaxUsed)
Add microsoft __delspec(property) attribute.
bool isC2xAttribute() const
const AvailabilityChange & getAvailabilityObsoleted() const
IdentifierInfo * SetterId
ParsedAttr * 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, ParsedAttr::Syntax syntax, SourceLocation strict, const Expr *ReplacementExpr)
Add availability attribute.
AttributeFactory & getFactory() const
void addAllAtEnd(iterator B, iterator E)
void addAll(iterator B, iterator E)
SourceLocation KeywordLoc
The location of the keyword indicating the kind of change.
bool isValid() const
Determine whether this availability change is valid.
Wraps an identifier and optional source location for the identifier.
SourceRange VersionRange
The source range covering the version number.
bool getLayoutCompatible() const
ParsedType * MatchingCType
SourceLocation getEllipsisLoc() const
ParsedAttr * createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Syntax syntaxUsed)
void addAtStart(ParsedAttr *newAttr)
Encodes a location in the source.
const ParsedType & getTypeArg() const
void addAll(const_iterator B, const_iterator E)
Syntax
The style used to specify an attribute.
ParsedAttr - Represents a syntactic attribute.
const ParsedAttr & operator[](SizeType pos) const
bool hasProcessingCache() const
bool isUsedAsTypeAttr() const
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
Add attribute with expression arguments.
bool isContextSensitiveKeywordAttribute() const
bool isArgExpr(unsigned Arg) const
__DEVICE__ void * memcpy(void *__a, const void *__b, size_t __c)
SourceRange getRange() const
void setProcessingCache(unsigned value) const
ArgsUnion getArg(unsigned Arg) const
getArg - Return the specified argument.
Dataflow Directional Tag Classes.
bool isValid() const
Return true if this is a valid SourceLocation object.
const AvailabilityChange & getAvailabilityIntroduced() const
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
bool isKeywordAttribute() const
bool isPackExpansion() const
bool isMicrosoftAttribute() const
SourceLocation getLoc() const
const PropertyData & getPropertyData() const
void takeAllFrom(AttributePool &pool)
Take the given pool's allocations and add them to this pool.
SourceLocation getStrictLoc() const
ParsedAttr * create(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ArgsUnion *args, unsigned numArgs, ParsedAttr::Syntax syntax, SourceLocation ellipsisLoc=SourceLocation())
AttributePool(AttributeFactory &factory)
Create a new pool for a factory.
IdentifierInfo * getName() const
ParsedAttr * createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *argumentKind, ParsedType matchingCType, bool layoutCompatible, bool mustBeNull, ParsedAttr::Syntax syntax)
const AvailabilityChange & getAvailabilityDeprecated() const
ParsedAttr * addNew(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierLoc *Param1, IdentifierLoc *Param2, IdentifierLoc *Param3, ParsedAttr::Syntax syntax)
Add objc_bridge_related attribute.
ParsedAttr * addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, ParsedAttr::Syntax syntaxUsed)
Add an attribute with a single type argument.
Context-sensitive version of a keyword attribute.
Defines the clang::SourceLocation class and associated facilities.
A factory, from which one makes pools, from which one creates individual attributes which are dealloc...
ParsedAttr * 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, ParsedAttr::Syntax syntax, SourceLocation strict, const Expr *ReplacementExpr)
AvailabilityChange Changes[NumAvailabilitySlots]
AttributePool & getPool() const
const Expr * getMessageExpr() const
Defines the clang::TargetInfo interface.
static Decl::Kind getKind(const Decl *D)
static llvm::ImmutableListFactory< const FieldRegion * > Factory
bool isArgIdent(unsigned Arg) const
A trivial tuple used to represent a source range.
__ptr16, alignas(...), etc.
SourceLocation getBegin() const
SourceLocation getUnavailableLoc() const
ParsedAttributes - A collection of parsed attributes.
AttributeDeclKind
These constants match the enumerated choices of warn_attribute_wrong_decl_type and err_attribute_wron...
IdentifierLoc * getArgAsIdent(unsigned Arg) const
IdentifierInfo * getScopeName() const
unsigned getProcessingCache() const
const Expr * getReplacementExpr() const