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/ADT/TinyPtrVector.h" 26 #include "llvm/Support/Allocator.h" 27 #include "llvm/Support/VersionTuple.h" 55 bool isValid()
const {
return !Version.empty(); }
73 : StrictLoc(Strict), Replacement(ReplaceExpr) {
89 : GetterId(getterId), SetterId(setterId) {}
105 using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
119 ParsedAttr, ArgsUnion, detail::AvailabilityData,
120 detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData> {
123 size_t numTrailingObjects(OverloadToken<ArgsUnion>)
const {
return NumArgs; }
124 size_t numTrailingObjects(OverloadToken<detail::AvailabilityData>)
const {
125 return IsAvailability;
128 numTrailingObjects(OverloadToken<detail::TypeTagForDatatypeData>)
const {
129 return IsTypeTagForDatatype;
131 size_t numTrailingObjects(OverloadToken<ParsedType>)
const {
132 return HasParsedType;
134 size_t numTrailingObjects(OverloadToken<detail::PropertyData>)
const {
175 unsigned AttrKind : 16;
179 unsigned NumArgs : 16;
182 unsigned SyntaxUsed : 3;
185 mutable unsigned Invalid : 1;
188 mutable unsigned UsedAsTypeAttr : 1;
192 unsigned IsAvailability : 1;
196 unsigned IsTypeTagForDatatype : 1;
200 unsigned IsProperty : 1;
203 unsigned HasParsedType : 1;
206 mutable unsigned HasProcessingCache : 1;
209 mutable unsigned ProcessingCache : 8;
215 const Expr *MessageExpr;
217 ArgsUnion *getArgsBuffer() {
return getTrailingObjects<ArgsUnion>(); }
219 return getTrailingObjects<ArgsUnion>();
223 return getTrailingObjects<detail::AvailabilityData>();
226 return getTrailingObjects<detail::AvailabilityData>();
238 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
239 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
240 SyntaxUsed(syntaxUsed), Invalid(
false), UsedAsTypeAttr(
false),
242 HasParsedType(
false), HasProcessingCache(
false) {
243 if (numArgs)
memcpy(getArgsBuffer(), args, numArgs *
sizeof(
ArgsUnion));
254 const Expr *replacementExpr)
255 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
256 ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(
false),
257 UsedAsTypeAttr(
false), IsAvailability(
true),
259 HasProcessingCache(
false), UnavailableLoc(unavailable),
260 MessageExpr(messageExpr) {
264 introduced, deprecated, obsoleted, strict, replacementExpr);
273 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
274 ScopeLoc(scopeLoc), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(
false),
277 HasProcessingCache(
false) {
289 bool layoutCompatible,
bool mustBeNull,
Syntax syntaxUsed)
290 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
291 ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(
false),
293 IsTypeTagForDatatype(
true), IsProperty(
false), HasParsedType(
false),
294 HasProcessingCache(
false) {
308 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
309 ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(
false),
311 IsTypeTagForDatatype(
false), IsProperty(
false), HasParsedType(
true),
312 HasProcessingCache(
false) {
322 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
323 ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(
false),
325 IsTypeTagForDatatype(
false), IsProperty(
true), HasParsedType(
false),
326 HasProcessingCache(
false) {
335 return *getTrailingObjects<detail::TypeTagForDatatypeData>();
338 return *getTrailingObjects<detail::TypeTagForDatatypeData>();
343 ParsedType &getTypeBuffer() {
return *getTrailingObjects<ParsedType>(); }
345 return *getTrailingObjects<ParsedType>();
352 return *getTrailingObjects<detail::PropertyData>();
356 return *getTrailingObjects<detail::PropertyData>();
359 size_t allocated_size()
const;
368 void operator delete(
void *) =
delete;
371 #define PARSED_ATTR(NAME) AT_##NAME, 372 #include "clang/Sema/AttrParsedAttrList.inc" 388 (ScopeName->
isStr(
"gnu") || ScopeName->
isStr(
"__gnu__"));
400 return getKind() == AT_Aligned && isKeywordAttribute();
407 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
411 return SyntaxUsed == AS_C2x;
415 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
419 return SyntaxUsed == AS_ContextSensitiveKeyword;
428 assert(hasProcessingCache());
429 return ProcessingCache;
433 ProcessingCache = value;
434 HasProcessingCache =
true;
452 assert(Arg < NumArgs &&
"Arg access out of range!");
453 return getArgsBuffer()[Arg];
457 return Arg < NumArgs && getArg(Arg).is<
Expr*>();
461 return getArg(Arg).get<
Expr*>();
473 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
478 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
483 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
488 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
489 return getAvailabilityData()->StrictLoc;
493 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
494 return UnavailableLoc;
498 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
503 assert(
getKind() == AT_Availability &&
"Not an availability attribute");
504 return getAvailabilityData()->Replacement;
508 assert(
getKind() == AT_TypeTagForDatatype &&
509 "Not a type_tag_for_datatype attribute");
510 return getTypeTagForDatatypeDataSlot().MatchingCType;
514 assert(
getKind() == AT_TypeTagForDatatype &&
515 "Not a type_tag_for_datatype attribute");
516 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
520 assert(
getKind() == AT_TypeTagForDatatype &&
521 "Not a type_tag_for_datatype attribute");
522 return getTypeTagForDatatypeDataSlot().MustBeNull;
526 assert(HasParsedType &&
"Not a type attribute");
527 return getTypeBuffer();
531 assert(isDeclspecPropertyAttribute() &&
532 "Not a __delcspec(property) attribute");
533 return getPropertyDataBuffer().GetterId;
537 assert(isDeclspecPropertyAttribute() &&
538 "Not a __delcspec(property) attribute");
539 return getPropertyDataBuffer().SetterId;
545 unsigned getAttributeSpellingListIndex()
const;
547 bool isTargetSpecificAttr()
const;
548 bool isTypeAttr()
const;
549 bool isStmtAttr()
const;
551 bool hasCustomParsing()
const;
552 unsigned getMinArgs()
const;
553 unsigned getMaxArgs()
const;
554 bool hasVariadicArg()
const;
555 bool diagnoseAppertainsTo(
class Sema &S,
const Decl *D)
const;
560 bool diagnoseLangOpts(
class Sema &S)
const;
562 bool isKnownToGCC()
const;
563 bool isSupportedByPragmaAttribute()
const;
570 unsigned getSemanticSpelling()
const;
582 AvailabilityAllocSize =
586 TypeTagForDatatypeAllocSize =
587 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
588 detail::TypeTagForDatatypeData, ParsedType,
589 detail::PropertyData>(1, 0, 1, 0, 0),
591 ParsedAttr::totalSizeToAlloc<
ArgsUnion, detail::AvailabilityData,
593 detail::PropertyData>(0, 0, 0, 0, 1),
603 InlineFreeListsCapacity =
604 1 + (AvailabilityAllocSize -
sizeof(
ParsedAttr)) /
sizeof(
void *)
607 llvm::BumpPtrAllocator Alloc;
617 void *allocate(
size_t size);
636 llvm::TinyPtrVector<ParsedAttr *> Attrs;
638 void *allocate(
size_t size) {
639 return Factory.allocate(size);
643 Attrs.push_back(attr);
648 assert(llvm::is_contained(Attrs, attr) &&
649 "Can't take attribute from a pool that doesn't own it!");
650 Attrs.erase(llvm::find(Attrs, attr));
669 Factory.reclaimPool(*
this);
689 void *memory = allocate(
690 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
691 detail::TypeTagForDatatypeData, ParsedType,
694 return add(
new (memory)
ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
695 args, numArgs, syntax, ellipsisLoc));
705 const Expr *ReplacementExpr) {
708 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
709 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
716 void *memory = allocate(
720 return add(
new (memory)
ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
721 Param1, Param2, Param3, syntax));
728 ParsedType matchingCType,
bool layoutCompatible,
731 return add(
new (memory)
ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
732 argumentKind, matchingCType,
733 layoutCompatible, mustBeNull, syntax));
741 void *memory = allocate(
745 return add(
new (memory)
ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
746 typeArg, syntaxUsed));
755 return add(
new (memory)
ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
756 getterId, setterId, syntaxUsed));
761 using VecTy = llvm::TinyPtrVector<ParsedAttr *>;
762 using SizeType = decltype(std::declval<VecTy>().size());
765 bool empty()
const {
return AttrList.empty(); }
766 SizeType
size()
const {
return AttrList.size(); }
772 AttrList.push_back(newAttr);
776 assert(is_contained(AttrList, ToBeRemoved) &&
777 "Cannot remove attribute that isn't in the list");
778 AttrList.erase(llvm::find(AttrList, ToBeRemoved));
783 struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
784 std::random_access_iterator_tag,
787 iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
792 : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
793 std::random_access_iterator_tag,
803 AttrList.insert(AttrList.begin(), B.I, E.I);
807 AttrList.insert(AttrList.begin(), B.I, E.I);
811 AttrList.insert(AttrList.end(), B.I, E.I);
815 AttrList.insert(AttrList.end(), B.I, E.I);
825 return *AttrList.front();
829 return *AttrList.front();
833 return *AttrList.back();
837 return *AttrList.back();
865 pool.takeAllFrom(attrs.pool);
879 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
880 args, numArgs, syntax, ellipsisLoc);
893 const Expr *ReplacementExpr) {
895 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
896 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
906 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
907 Param1, Param2, Param3, syntax);
917 ParsedType matchingCType,
bool layoutCompatible,
919 ParsedAttr *attr = pool.createTypeTagForDatatype(
920 attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
921 layoutCompatible, mustBeNull, syntax);
931 ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
932 scopeLoc, typeArg, syntaxUsed);
944 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
945 getterId, setterId, syntaxUsed);
1011 #endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H ParsedAttr * createTypeAttribute(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, ParsedType typeArg, ParsedAttr::Syntax syntaxUsed)
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)
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)
Decl - This represents one declaration (or definition), e.g.
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const
Expr * getArgAsExpr(unsigned Arg) const
const DiagnosticBuilder & operator<<(const DiagnosticBuilder &DB, const Attr *At)
bool getMustBeNull() const
The l-value was an access to a declared entity or something equivalently strong, like the address of ...
bool hasParsedType() const
IdentifierInfo * getPropertyDataGetter() const
const_iterator begin() const
reference operator*() const
bool hasAttribute(ParsedAttr::Kind K) const
IdentifierInfo * getPropertyDataSetter() 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
void AddTaggedVal(intptr_t V, DiagnosticsEngine::ArgumentKind Kind) const
One of these records is kept for each identifier that is lexed.
SubjectMatchRule
A list of all the recognized kinds of attributes.
bool isStr(const char(&Str)[StrLen]) const
Return true if this is the identifier for the specified string.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const ParsedAttr & front() const
unsigned LayoutCompatible
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)
Defines the Diagnostic-related interfaces.
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.
A little helper class used to produce diagnostics.
AvailabilityData(const AvailabilityChange &Introduced, const AvailabilityChange &Deprecated, const AvailabilityChange &Obsoleted, SourceLocation Strict, const Expr *ReplaceExpr)
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
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
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
SourceLocation getEllipsisLoc() const
ParsedAttr * createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange, IdentifierInfo *scopeName, SourceLocation scopeLoc, IdentifierInfo *getterId, IdentifierInfo *setterId, ParsedAttr::Syntax syntaxUsed)
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 & back() const
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)
Describes the trailing object for Availability attribute in ParsedAttr.
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
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)
AttributePool & getPool() const
const Expr * getMessageExpr() const
Defines the clang::TargetInfo interface.
static Decl::Kind getKind(const Decl *D)
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
IdentifierInfo * SetterId
unsigned getProcessingCache() const
const Expr * getReplacementExpr() const
PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)