1 //======- ParsedAttr.h - Parsed attribute sets ------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file defines the ParsedAttr class, which is used to collect
13 //===----------------------------------------------------------------------===//
15 #ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H
16 #define LLVM_CLANG_SEMA_ATTRIBUTELIST_H
18 #include "clang/Basic/AttrSubjectMatchRules.h"
19 #include "clang/Basic/SourceLocation.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Sema/Ownership.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"
40 /// Represents information about a change in availability for
41 /// an entity, which is part of the encoding of the 'availability'
43 struct AvailabilityChange {
44 /// The location of the keyword indicating the kind of change.
45 SourceLocation KeywordLoc;
47 /// The version number at which the change occurred.
50 /// The source range covering the version number.
51 SourceRange VersionRange;
53 /// Determine whether this availability change is valid.
54 bool isValid() const { return !Version.empty(); }
59 enum AvailabilitySlot {
60 IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
63 /// Describes the trailing object for Availability attribute in ParsedAttr.
64 struct AvailabilityData {
65 AvailabilityChange Changes[NumAvailabilitySlots];
66 SourceLocation StrictLoc;
67 const Expr *Replacement;
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;
82 /// Wraps an identifier and optional source location for the identifier.
83 struct IdentifierLoc {
85 IdentifierInfo *Ident;
87 static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
88 IdentifierInfo *Ident);
91 /// A union of the various pointer types that can be passed to an
92 /// ParsedAttr as an argument.
93 using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
94 using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>;
96 /// ParsedAttr - Represents a syntactic attribute.
98 /// For a GNU attribute, there are four forms of this construct:
100 /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
101 /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
102 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
103 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
105 class ParsedAttr { // TODO: This should really be called ParsedAttribute
107 /// The style used to specify an attribute.
109 /// __attribute__((...))
121 /// [uuid("...")] class Foo
124 /// __ptr16, alignas(...), etc.
130 // Note TableGen depends on the order above. Do not add or change the order
131 // without adding related code to TableGen/ClangAttrEmitter.cpp.
132 /// Context-sensitive version of a keyword attribute.
133 AS_ContextSensitiveKeyword,
137 IdentifierInfo *AttrName;
138 IdentifierInfo *ScopeName;
139 SourceRange AttrRange;
140 SourceLocation ScopeLoc;
141 SourceLocation EllipsisLoc;
143 unsigned AttrKind : 16;
145 /// The number of expression arguments this attribute has.
146 /// The expressions themselves are stored after the object.
147 unsigned NumArgs : 16;
149 /// Corresponds to the Syntax enum.
150 unsigned SyntaxUsed : 3;
152 /// True if already diagnosed as invalid.
153 mutable unsigned Invalid : 1;
155 /// True if this attribute was used as a type attribute.
156 mutable unsigned UsedAsTypeAttr : 1;
158 /// True if this has the extra information associated with an
159 /// availability attribute.
160 unsigned IsAvailability : 1;
162 /// True if this has extra information associated with a
163 /// type_tag_for_datatype attribute.
164 unsigned IsTypeTagForDatatype : 1;
166 /// True if this has extra information associated with a
167 /// Microsoft __delcspec(property) attribute.
168 unsigned IsProperty : 1;
170 /// True if this has a ParsedType
171 unsigned HasParsedType : 1;
173 /// True if the processing cache is valid.
174 mutable unsigned HasProcessingCache : 1;
177 mutable unsigned ProcessingCache : 8;
179 /// The location of the 'unavailable' keyword in an
180 /// availability attribute.
181 SourceLocation UnavailableLoc;
183 const Expr *MessageExpr;
185 /// Arguments, if any, are stored immediately following the object.
186 ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
187 ArgsUnion const *getArgsBuffer() const {
188 return reinterpret_cast<ArgsUnion const *>(this + 1);
191 /// Availability information is stored immediately following the arguments,
192 /// if any, at the end of the object.
193 AvailabilityData *getAvailabilityData() {
194 return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs);
196 const AvailabilityData *getAvailabilityData() const {
197 return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
201 struct TypeTagForDatatypeData {
202 ParsedType *MatchingCType;
203 unsigned LayoutCompatible : 1;
204 unsigned MustBeNull : 1;
206 struct PropertyData {
207 IdentifierInfo *GetterId, *SetterId;
209 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
210 : GetterId(getterId), SetterId(setterId) {}
214 friend class AttributeFactory;
215 friend class AttributePool;
217 /// Constructor for attributes with expression arguments.
218 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
219 IdentifierInfo *scopeName, SourceLocation scopeLoc,
220 ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed,
221 SourceLocation ellipsisLoc)
222 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
223 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
224 SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
225 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
226 HasParsedType(false), HasProcessingCache(false) {
227 if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
228 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
231 /// Constructor for availability attributes.
232 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
233 IdentifierInfo *scopeName, SourceLocation scopeLoc,
234 IdentifierLoc *Parm, const AvailabilityChange &introduced,
235 const AvailabilityChange &deprecated,
236 const AvailabilityChange &obsoleted, SourceLocation unavailable,
237 const Expr *messageExpr, Syntax syntaxUsed, SourceLocation strict,
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),
242 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
243 HasProcessingCache(false), UnavailableLoc(unavailable),
244 MessageExpr(messageExpr) {
245 ArgsUnion PVal(Parm);
246 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
247 new (getAvailabilityData()) AvailabilityData(
248 introduced, deprecated, obsoleted, strict, replacementExpr);
249 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
252 /// Constructor for objc_bridge_related attributes.
253 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
254 IdentifierInfo *scopeName, SourceLocation scopeLoc,
255 IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3,
257 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
258 ScopeLoc(scopeLoc), NumArgs(3), SyntaxUsed(syntaxUsed), Invalid(false),
259 UsedAsTypeAttr(false), IsAvailability(false),
260 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
261 HasProcessingCache(false) {
262 ArgsUnion *Args = getArgsBuffer();
266 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
269 /// Constructor for type_tag_for_datatype attribute.
270 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
271 IdentifierInfo *scopeName, SourceLocation scopeLoc,
272 IdentifierLoc *ArgKind, ParsedType matchingCType,
273 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
274 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
275 ScopeLoc(scopeLoc), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
276 UsedAsTypeAttr(false), IsAvailability(false),
277 IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
278 HasProcessingCache(false) {
279 ArgsUnion PVal(ArgKind);
280 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
281 TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
282 new (&ExtraData.MatchingCType) ParsedType(matchingCType);
283 ExtraData.LayoutCompatible = layoutCompatible;
284 ExtraData.MustBeNull = mustBeNull;
285 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
288 /// Constructor for attributes with a single type argument.
289 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
290 IdentifierInfo *scopeName, SourceLocation scopeLoc,
291 ParsedType typeArg, Syntax syntaxUsed)
292 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
293 ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
294 UsedAsTypeAttr(false), IsAvailability(false),
295 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
296 HasProcessingCache(false) {
297 new (&getTypeBuffer()) ParsedType(typeArg);
298 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
301 /// Constructor for microsoft __declspec(property) attribute.
302 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
303 IdentifierInfo *scopeName, SourceLocation scopeLoc,
304 IdentifierInfo *getterId, IdentifierInfo *setterId,
306 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
307 ScopeLoc(scopeLoc), NumArgs(0), SyntaxUsed(syntaxUsed), Invalid(false),
308 UsedAsTypeAttr(false), IsAvailability(false),
309 IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
310 HasProcessingCache(false) {
311 new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
312 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
315 /// Type tag information is stored immediately following the arguments, if
316 /// any, at the end of the object. They are mutually exclusive with
317 /// availability slots.
318 TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
319 return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
321 const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
322 return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
326 /// The type buffer immediately follows the object and are mutually exclusive
328 ParsedType &getTypeBuffer() {
329 return *reinterpret_cast<ParsedType *>(this + 1);
331 const ParsedType &getTypeBuffer() const {
332 return *reinterpret_cast<const ParsedType *>(this + 1);
335 /// The property data immediately follows the object is is mutually exclusive
337 PropertyData &getPropertyDataBuffer() {
339 return *reinterpret_cast<PropertyData*>(this + 1);
341 const PropertyData &getPropertyDataBuffer() const {
343 return *reinterpret_cast<const PropertyData*>(this + 1);
346 size_t allocated_size() const;
349 ParsedAttr(const ParsedAttr &) = delete;
350 ParsedAttr &operator=(const ParsedAttr &) = delete;
351 ~ParsedAttr() = delete;
353 void operator delete(void *) = delete;
356 #define PARSED_ATTR(NAME) AT_##NAME,
357 #include "clang/Sema/AttrParsedAttrList.inc"
363 IdentifierInfo *getName() const { return AttrName; }
364 SourceLocation getLoc() const { return AttrRange.getBegin(); }
365 SourceRange getRange() const { return AttrRange; }
367 bool hasScope() const { return ScopeName; }
368 IdentifierInfo *getScopeName() const { return ScopeName; }
369 SourceLocation getScopeLoc() const { return ScopeLoc; }
371 bool hasParsedType() const { return HasParsedType; }
373 /// Is this the Microsoft __declspec(property) attribute?
374 bool isDeclspecPropertyAttribute() const {
378 bool isAlignasAttribute() const {
379 // FIXME: Use a better mechanism to determine this.
380 return getKind() == AT_Aligned && isKeywordAttribute();
383 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
384 bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
386 bool isCXX11Attribute() const {
387 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
390 bool isC2xAttribute() const {
391 return SyntaxUsed == AS_C2x;
394 bool isKeywordAttribute() const {
395 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
398 bool isContextSensitiveKeywordAttribute() const {
399 return SyntaxUsed == AS_ContextSensitiveKeyword;
402 bool isInvalid() const { return Invalid; }
403 void setInvalid(bool b = true) const { Invalid = b; }
405 bool hasProcessingCache() const { return HasProcessingCache; }
407 unsigned getProcessingCache() const {
408 assert(hasProcessingCache());
409 return ProcessingCache;
412 void setProcessingCache(unsigned value) const {
413 ProcessingCache = value;
414 HasProcessingCache = true;
417 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
418 void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
420 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
421 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
423 Kind getKind() const { return Kind(AttrKind); }
424 static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
427 /// getNumArgs - Return the number of actual arguments to this attribute.
428 unsigned getNumArgs() const { return NumArgs; }
430 /// getArg - Return the specified argument.
431 ArgsUnion getArg(unsigned Arg) const {
432 assert(Arg < NumArgs && "Arg access out of range!");
433 return getArgsBuffer()[Arg];
436 bool isArgExpr(unsigned Arg) const {
437 return Arg < NumArgs && getArg(Arg).is<Expr*>();
440 Expr *getArgAsExpr(unsigned Arg) const {
441 return getArg(Arg).get<Expr*>();
444 bool isArgIdent(unsigned Arg) const {
445 return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
448 IdentifierLoc *getArgAsIdent(unsigned Arg) const {
449 return getArg(Arg).get<IdentifierLoc*>();
452 const AvailabilityChange &getAvailabilityIntroduced() const {
453 assert(getKind() == AT_Availability && "Not an availability attribute");
454 return getAvailabilityData()->Changes[IntroducedSlot];
457 const AvailabilityChange &getAvailabilityDeprecated() const {
458 assert(getKind() == AT_Availability && "Not an availability attribute");
459 return getAvailabilityData()->Changes[DeprecatedSlot];
462 const AvailabilityChange &getAvailabilityObsoleted() const {
463 assert(getKind() == AT_Availability && "Not an availability attribute");
464 return getAvailabilityData()->Changes[ObsoletedSlot];
467 SourceLocation getStrictLoc() const {
468 assert(getKind() == AT_Availability && "Not an availability attribute");
469 return getAvailabilityData()->StrictLoc;
472 SourceLocation getUnavailableLoc() const {
473 assert(getKind() == AT_Availability && "Not an availability attribute");
474 return UnavailableLoc;
477 const Expr * getMessageExpr() const {
478 assert(getKind() == AT_Availability && "Not an availability attribute");
482 const Expr *getReplacementExpr() const {
483 assert(getKind() == AT_Availability && "Not an availability attribute");
484 return getAvailabilityData()->Replacement;
487 const ParsedType &getMatchingCType() const {
488 assert(getKind() == AT_TypeTagForDatatype &&
489 "Not a type_tag_for_datatype attribute");
490 return *getTypeTagForDatatypeDataSlot().MatchingCType;
493 bool getLayoutCompatible() const {
494 assert(getKind() == AT_TypeTagForDatatype &&
495 "Not a type_tag_for_datatype attribute");
496 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
499 bool getMustBeNull() const {
500 assert(getKind() == AT_TypeTagForDatatype &&
501 "Not a type_tag_for_datatype attribute");
502 return getTypeTagForDatatypeDataSlot().MustBeNull;
505 const ParsedType &getTypeArg() const {
506 assert(HasParsedType && "Not a type attribute");
507 return getTypeBuffer();
510 const PropertyData &getPropertyData() const {
511 assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
512 return getPropertyDataBuffer();
515 /// Get an index into the attribute spelling list
516 /// defined in Attr.td. This index is used by an attribute
517 /// to pretty print itself.
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;
529 bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
530 void getMatchRules(const LangOptions &LangOpts,
531 SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
533 bool diagnoseLangOpts(class Sema &S) const;
534 bool existsInTarget(const TargetInfo &Target) const;
535 bool isKnownToGCC() const;
536 bool isSupportedByPragmaAttribute() const;
538 /// If the parsed attribute has a semantic equivalent, and it would
539 /// have a semantic Spelling enumeration (due to having semantically-distinct
540 /// spelling variations), return the value of that semantic spelling. If the
541 /// parsed attribute does not have a semantic equivalent, or would not have
542 /// a Spelling enumeration, the value UINT_MAX is returned.
543 unsigned getSemanticSpelling() const;
547 /// A factory, from which one makes pools, from which one creates
548 /// individual attributes which are deallocated with the pool.
550 /// Note that it's tolerably cheap to create and destroy one of
551 /// these as long as you don't actually allocate anything in it.
552 class AttributeFactory {
555 /// The required allocation size of an availability attribute,
556 /// which we want to ensure is a multiple of sizeof(void*).
557 AvailabilityAllocSize =
559 ((sizeof(AvailabilityData) + sizeof(void *) + sizeof(ArgsUnion) - 1) /
560 sizeof(void *) * sizeof(void *)),
561 TypeTagForDatatypeAllocSize = sizeof(ParsedAttr) +
562 (sizeof(ParsedAttr::TypeTagForDatatypeData) +
563 sizeof(void *) + sizeof(ArgsUnion) - 1) /
564 sizeof(void *) * sizeof(void *),
567 (sizeof(ParsedAttr::PropertyData) + sizeof(void *) - 1) /
568 sizeof(void *) * sizeof(void *)
573 /// The number of free lists we want to be sure to support
574 /// inline. This is just enough that availability attributes
575 /// don't surpass it. It's actually very unlikely we'll see an
576 /// attribute that needs more than that; on x86-64 you'd need 10
577 /// expression arguments, and on i386 you'd need 19.
578 InlineFreeListsCapacity =
579 1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *)
582 llvm::BumpPtrAllocator Alloc;
584 /// Free lists. The index is determined by the following formula:
585 /// (size - sizeof(ParsedAttr)) / sizeof(void*)
586 SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists;
588 // The following are the private interface used by AttributePool.
589 friend class AttributePool;
591 /// Allocate an attribute of the given size.
592 void *allocate(size_t size);
594 void deallocate(ParsedAttr *AL);
596 /// Reclaim all the attributes in the given pool chain, which is
597 /// non-empty. Note that the current implementation is safe
598 /// against reclaiming things which were not actually allocated
599 /// with the allocator, although of course it's important to make
600 /// sure that their allocator lives at least as long as this one.
601 void reclaimPool(AttributePool &head);
608 class AttributePool {
609 friend class AttributeFactory;
610 AttributeFactory &Factory;
611 llvm::TinyPtrVector<ParsedAttr *> Attrs;
613 void *allocate(size_t size) {
614 return Factory.allocate(size);
617 ParsedAttr *add(ParsedAttr *attr) {
618 Attrs.push_back(attr);
622 void remove(ParsedAttr *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));
628 void takePool(AttributePool &pool);
631 /// Create a new pool for a factory.
632 AttributePool(AttributeFactory &factory) : Factory(factory) {}
634 AttributePool(const AttributePool &) = delete;
636 ~AttributePool() { Factory.reclaimPool(*this); }
638 /// Move the given pool's allocations to this pool.
639 AttributePool(AttributePool &&pool) = default;
641 AttributeFactory &getFactory() const { return Factory; }
644 Factory.reclaimPool(*this);
648 /// Take the given pool's allocations and add them to this pool.
649 void takeAllFrom(AttributePool &pool) {
654 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
655 IdentifierInfo *scopeName, SourceLocation scopeLoc,
656 ArgsUnion *args, unsigned numArgs,
657 ParsedAttr::Syntax syntax,
658 SourceLocation ellipsisLoc = SourceLocation()) {
659 void *memory = allocate(sizeof(ParsedAttr) + numArgs * sizeof(ArgsUnion));
660 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
661 args, numArgs, syntax, ellipsisLoc));
664 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
665 IdentifierInfo *scopeName, SourceLocation scopeLoc,
666 IdentifierLoc *Param, const AvailabilityChange &introduced,
667 const AvailabilityChange &deprecated,
668 const AvailabilityChange &obsoleted,
669 SourceLocation unavailable, const Expr *MessageExpr,
670 ParsedAttr::Syntax syntax, SourceLocation strict,
671 const Expr *ReplacementExpr) {
672 void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
673 return add(new (memory) ParsedAttr(
674 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
675 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr));
678 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
679 IdentifierInfo *scopeName, SourceLocation scopeLoc,
680 IdentifierLoc *Param1, IdentifierLoc *Param2,
681 IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
682 size_t size = sizeof(ParsedAttr) + 3 * sizeof(ArgsUnion);
683 void *memory = allocate(size);
684 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
685 Param1, Param2, Param3, syntax));
689 createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
690 IdentifierInfo *scopeName, SourceLocation scopeLoc,
691 IdentifierLoc *argumentKind,
692 ParsedType matchingCType, bool layoutCompatible,
693 bool mustBeNull, ParsedAttr::Syntax syntax) {
694 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
695 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
696 argumentKind, matchingCType,
697 layoutCompatible, mustBeNull, syntax));
700 ParsedAttr *createTypeAttribute(IdentifierInfo *attrName,
701 SourceRange attrRange,
702 IdentifierInfo *scopeName,
703 SourceLocation scopeLoc, ParsedType typeArg,
704 ParsedAttr::Syntax syntaxUsed) {
705 void *memory = allocate(sizeof(ParsedAttr) + sizeof(void *));
706 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
707 typeArg, syntaxUsed));
711 createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange,
712 IdentifierInfo *scopeName, SourceLocation scopeLoc,
713 IdentifierInfo *getterId, IdentifierInfo *setterId,
714 ParsedAttr::Syntax syntaxUsed) {
715 void *memory = allocate(AttributeFactory::PropertyAllocSize);
716 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
717 getterId, setterId, syntaxUsed));
721 class ParsedAttributesView {
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(); }
728 ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; }
729 const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; }
731 void addAtStart(ParsedAttr *newAttr) {
733 AttrList.insert(AttrList.begin(), newAttr);
735 void addAtEnd(ParsedAttr *newAttr) {
737 AttrList.push_back(newAttr);
740 void remove(ParsedAttr *ToBeRemoved) {
741 assert(is_contained(AttrList, ToBeRemoved) &&
742 "Cannot remove attribute that isn't in the list");
743 AttrList.erase(llvm::find(AttrList, ToBeRemoved));
746 void clearListOnly() { AttrList.clear(); }
748 struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
749 std::random_access_iterator_tag,
751 iterator() : iterator_adaptor_base(nullptr) {}
752 iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
753 reference operator*() { return **I; }
754 friend class ParsedAttributesView;
756 struct const_iterator
757 : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
758 std::random_access_iterator_tag,
760 const_iterator() : iterator_adaptor_base(nullptr) {}
761 const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {}
763 reference operator*() const { return **I; }
764 friend class ParsedAttributesView;
767 void addAll(iterator B, iterator E) {
768 AttrList.insert(AttrList.begin(), B.I, E.I);
771 void addAll(const_iterator B, const_iterator E) {
772 AttrList.insert(AttrList.begin(), B.I, E.I);
775 void addAllAtEnd(iterator B, iterator E) {
776 AttrList.insert(AttrList.end(), B.I, E.I);
779 void addAllAtEnd(const_iterator B, const_iterator E) {
780 AttrList.insert(AttrList.end(), B.I, E.I);
783 iterator begin() { return iterator(AttrList.begin()); }
784 const_iterator begin() const { return const_iterator(AttrList.begin()); }
785 iterator end() { return iterator(AttrList.end()); }
786 const_iterator end() const { return const_iterator(AttrList.end()); }
788 bool hasAttribute(ParsedAttr::Kind K) const {
790 AttrList, [K](const ParsedAttr *AL) { return AL->getKind() == K; });
797 /// ParsedAttributes - A collection of parsed attributes. Currently
798 /// we don't differentiate between the various attribute syntaxes,
799 /// which is basically silly.
801 /// Right now this is a very lightweight container, but the expectation
802 /// is that this will become significantly more serious.
803 class ParsedAttributes : public ParsedAttributesView {
805 ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
806 ParsedAttributes(const ParsedAttributes &) = delete;
808 AttributePool &getPool() const { return pool; }
810 void takeAllFrom(ParsedAttributes &attrs) {
811 addAll(attrs.begin(), attrs.end());
812 attrs.clearListOnly();
813 pool.takeAllFrom(attrs.pool);
821 /// Add attribute with expression arguments.
822 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
823 IdentifierInfo *scopeName, SourceLocation scopeLoc,
824 ArgsUnion *args, unsigned numArgs,
825 ParsedAttr::Syntax syntax,
826 SourceLocation ellipsisLoc = SourceLocation()) {
827 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
828 args, numArgs, syntax, ellipsisLoc);
833 /// Add availability attribute.
834 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
835 IdentifierInfo *scopeName, SourceLocation scopeLoc,
836 IdentifierLoc *Param, const AvailabilityChange &introduced,
837 const AvailabilityChange &deprecated,
838 const AvailabilityChange &obsoleted,
839 SourceLocation unavailable, const Expr *MessageExpr,
840 ParsedAttr::Syntax syntax, SourceLocation strict,
841 const Expr *ReplacementExpr) {
842 ParsedAttr *attr = pool.create(
843 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated,
844 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr);
849 /// Add objc_bridge_related attribute.
850 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
851 IdentifierInfo *scopeName, SourceLocation scopeLoc,
852 IdentifierLoc *Param1, IdentifierLoc *Param2,
853 IdentifierLoc *Param3, ParsedAttr::Syntax syntax) {
854 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
855 Param1, Param2, Param3, syntax);
860 /// Add type_tag_for_datatype attribute.
862 addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
863 IdentifierInfo *scopeName, SourceLocation scopeLoc,
864 IdentifierLoc *argumentKind,
865 ParsedType matchingCType, bool layoutCompatible,
866 bool mustBeNull, ParsedAttr::Syntax syntax) {
867 ParsedAttr *attr = pool.createTypeTagForDatatype(
868 attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
869 layoutCompatible, mustBeNull, syntax);
874 /// Add an attribute with a single type argument.
875 ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
876 IdentifierInfo *scopeName, SourceLocation scopeLoc,
878 ParsedAttr::Syntax syntaxUsed) {
879 ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName,
880 scopeLoc, typeArg, syntaxUsed);
885 /// Add microsoft __delspec(property) attribute.
887 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
888 IdentifierInfo *scopeName, SourceLocation scopeLoc,
889 IdentifierInfo *getterId, IdentifierInfo *setterId,
890 ParsedAttr::Syntax syntaxUsed) {
892 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
893 getterId, setterId, syntaxUsed);
899 mutable AttributePool pool;
902 /// These constants match the enumerated choices of
903 /// err_attribute_argument_n_type and err_attribute_argument_type.
904 enum AttributeArgumentNType {
905 AANT_ArgumentIntOrBool,
906 AANT_ArgumentIntegerConstant,
908 AANT_ArgumentIdentifier
911 /// These constants match the enumerated choices of
912 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
913 enum AttributeDeclKind {
916 ExpectedVariableOrFunction,
917 ExpectedFunctionOrMethod,
918 ExpectedFunctionMethodOrBlock,
919 ExpectedFunctionMethodOrParameter,
921 ExpectedVariableOrField,
922 ExpectedVariableFieldOrTag,
923 ExpectedTypeOrNamespace,
924 ExpectedFunctionVariableOrClass,
925 ExpectedKernelFunction,
926 ExpectedFunctionWithProtoType,
931 #endif // LLVM_CLANG_SEMA_ATTRIBUTELIST_H