1 //===--- AttributeList.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 AttributeList 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/Basic/VersionTuple.h"
22 #include "clang/Sema/Ownership.h"
23 #include "llvm/ADT/PointerUnion.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/Support/Allocator.h"
33 /// \brief Represents information about a change in availability for
34 /// an entity, which is part of the encoding of the 'availability'
36 struct AvailabilityChange {
37 /// \brief The location of the keyword indicating the kind of change.
38 SourceLocation KeywordLoc;
40 /// \brief The version number at which the change occurred.
43 /// \brief The source range covering the version number.
44 SourceRange VersionRange;
46 /// \brief Determine whether this availability change is valid.
47 bool isValid() const { return !Version.empty(); }
51 enum AvailabilitySlot {
52 IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
55 /// Describes the trailing object for Availability attribute in AttributeList.
56 struct AvailabilityData {
57 AvailabilityChange Changes[NumAvailabilitySlots];
58 SourceLocation StrictLoc;
59 const Expr *Replacement;
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;
72 /// \brief Wraps an identifier and optional source location for the identifier.
73 struct IdentifierLoc {
75 IdentifierInfo *Ident;
77 static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
78 IdentifierInfo *Ident);
81 /// \brief A union of the various pointer types that can be passed to an
82 /// AttributeList as an argument.
83 typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion;
84 typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector;
86 /// AttributeList - Represents a syntactic attribute.
88 /// For a GNU attribute, there are four forms of this construct:
90 /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
91 /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
92 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
93 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
95 class AttributeList { // TODO: This should really be called ParsedAttribute
97 /// The style used to specify an attribute.
99 /// __attribute__((...))
105 /// [uuid("...")] class Foo
107 /// __ptr16, alignas(...), etc.
109 /// Context-sensitive version of a keyword attribute.
110 AS_ContextSensitiveKeyword,
116 IdentifierInfo *AttrName;
117 IdentifierInfo *ScopeName;
118 SourceRange AttrRange;
119 SourceLocation ScopeLoc;
120 SourceLocation EllipsisLoc;
122 unsigned AttrKind : 16;
124 /// The number of expression arguments this attribute has.
125 /// The expressions themselves are stored after the object.
126 unsigned NumArgs : 16;
128 /// Corresponds to the Syntax enum.
129 unsigned SyntaxUsed : 3;
131 /// True if already diagnosed as invalid.
132 mutable unsigned Invalid : 1;
134 /// True if this attribute was used as a type attribute.
135 mutable unsigned UsedAsTypeAttr : 1;
137 /// True if this has the extra information associated with an
138 /// availability attribute.
139 unsigned IsAvailability : 1;
141 /// True if this has extra information associated with a
142 /// type_tag_for_datatype attribute.
143 unsigned IsTypeTagForDatatype : 1;
145 /// True if this has extra information associated with a
146 /// Microsoft __delcspec(property) attribute.
147 unsigned IsProperty : 1;
149 /// True if this has a ParsedType
150 unsigned HasParsedType : 1;
152 /// True if the processing cache is valid.
153 mutable unsigned HasProcessingCache : 1;
156 mutable unsigned ProcessingCache : 8;
158 /// \brief The location of the 'unavailable' keyword in an
159 /// availability attribute.
160 SourceLocation UnavailableLoc;
162 const Expr *MessageExpr;
164 /// The next attribute in the current position.
165 AttributeList *NextInPosition;
167 /// The next attribute allocated in the current Pool.
168 AttributeList *NextInPool;
170 /// Arguments, if any, are stored immediately following the object.
171 ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
172 ArgsUnion const *getArgsBuffer() const {
173 return reinterpret_cast<ArgsUnion const *>(this + 1);
176 /// Availability information is stored immediately following the arguments,
177 /// if any, at the end of the object.
178 AvailabilityData *getAvailabilityData() {
179 return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs);
181 const AvailabilityData *getAvailabilityData() const {
182 return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
186 struct TypeTagForDatatypeData {
187 ParsedType *MatchingCType;
188 unsigned LayoutCompatible : 1;
189 unsigned MustBeNull : 1;
191 struct PropertyData {
192 IdentifierInfo *GetterId, *SetterId;
193 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
194 : GetterId(getterId), SetterId(setterId) {}
198 /// Type tag information is stored immediately following the arguments, if
199 /// any, at the end of the object. They are mutually exlusive with
200 /// availability slots.
201 TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
202 return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
205 const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
206 return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
210 /// The type buffer immediately follows the object and are mutually exclusive
212 ParsedType &getTypeBuffer() {
213 return *reinterpret_cast<ParsedType *>(this + 1);
216 const ParsedType &getTypeBuffer() const {
217 return *reinterpret_cast<const ParsedType *>(this + 1);
220 /// The property data immediately follows the object is is mutually exclusive
222 PropertyData &getPropertyDataBuffer() {
224 return *reinterpret_cast<PropertyData*>(this + 1);
227 const PropertyData &getPropertyDataBuffer() const {
229 return *reinterpret_cast<const PropertyData*>(this + 1);
232 AttributeList(const AttributeList &) = delete;
233 void operator=(const AttributeList &) = delete;
234 void operator delete(void *) = delete;
235 ~AttributeList() = delete;
237 size_t allocated_size() const;
239 /// Constructor for attributes with expression arguments.
240 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
241 IdentifierInfo *scopeName, SourceLocation scopeLoc,
242 ArgsUnion *args, unsigned numArgs,
243 Syntax syntaxUsed, SourceLocation ellipsisLoc)
244 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
245 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
246 SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
247 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
248 HasParsedType(false), HasProcessingCache(false),
249 NextInPosition(nullptr), NextInPool(nullptr) {
250 if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
251 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
254 /// Constructor for availability attributes.
255 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
256 IdentifierInfo *scopeName, SourceLocation scopeLoc,
257 IdentifierLoc *Parm, const AvailabilityChange &introduced,
258 const AvailabilityChange &deprecated,
259 const AvailabilityChange &obsoleted,
260 SourceLocation unavailable,
261 const Expr *messageExpr,
262 Syntax syntaxUsed, SourceLocation strict,
263 const Expr *replacementExpr)
264 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
265 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
266 Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
267 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
268 HasProcessingCache(false), UnavailableLoc(unavailable),
269 MessageExpr(messageExpr), NextInPosition(nullptr), NextInPool(nullptr) {
270 ArgsUnion PVal(Parm);
271 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
272 new (getAvailabilityData()) AvailabilityData(
273 introduced, deprecated, obsoleted, strict, replacementExpr);
274 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
277 /// Constructor for objc_bridge_related attributes.
278 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
279 IdentifierInfo *scopeName, SourceLocation scopeLoc,
280 IdentifierLoc *Parm1,
281 IdentifierLoc *Parm2,
282 IdentifierLoc *Parm3,
284 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
285 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
286 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
287 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
288 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
289 ArgsUnion *Args = getArgsBuffer();
293 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
296 /// Constructor for type_tag_for_datatype attribute.
297 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
298 IdentifierInfo *scopeName, SourceLocation scopeLoc,
299 IdentifierLoc *ArgKind, ParsedType matchingCType,
300 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
301 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
302 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
303 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
304 IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
305 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
306 ArgsUnion PVal(ArgKind);
307 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
308 TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
309 new (&ExtraData.MatchingCType) ParsedType(matchingCType);
310 ExtraData.LayoutCompatible = layoutCompatible;
311 ExtraData.MustBeNull = mustBeNull;
312 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
315 /// Constructor for attributes with a single type argument.
316 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
317 IdentifierInfo *scopeName, SourceLocation scopeLoc,
318 ParsedType typeArg, Syntax syntaxUsed)
319 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
320 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
321 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
322 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
323 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr){
324 new (&getTypeBuffer()) ParsedType(typeArg);
325 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
328 /// Constructor for microsoft __declspec(property) attribute.
329 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
330 IdentifierInfo *scopeName, SourceLocation scopeLoc,
331 IdentifierInfo *getterId, IdentifierInfo *setterId,
333 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
334 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
335 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
336 IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
337 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
338 new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
339 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
342 friend class AttributePool;
343 friend class AttributeFactory;
347 #define PARSED_ATTR(NAME) AT_##NAME,
348 #include "clang/Sema/AttrParsedAttrList.inc"
354 IdentifierInfo *getName() const { return AttrName; }
355 SourceLocation getLoc() const { return AttrRange.getBegin(); }
356 SourceRange getRange() const { return AttrRange; }
358 bool hasScope() const { return ScopeName; }
359 IdentifierInfo *getScopeName() const { return ScopeName; }
360 SourceLocation getScopeLoc() const { return ScopeLoc; }
362 bool hasParsedType() const { return HasParsedType; }
364 /// Is this the Microsoft __declspec(property) attribute?
365 bool isDeclspecPropertyAttribute() const {
369 bool isAlignasAttribute() const {
370 // FIXME: Use a better mechanism to determine this.
371 return getKind() == AT_Aligned && isKeywordAttribute();
374 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
375 bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
376 bool isCXX11Attribute() const {
377 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
379 bool isKeywordAttribute() const {
380 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
383 bool isContextSensitiveKeywordAttribute() const {
384 return SyntaxUsed == AS_ContextSensitiveKeyword;
387 bool isInvalid() const { return Invalid; }
388 void setInvalid(bool b = true) const { Invalid = b; }
390 bool hasProcessingCache() const { return HasProcessingCache; }
391 unsigned getProcessingCache() const {
392 assert(hasProcessingCache());
393 return ProcessingCache;
395 void setProcessingCache(unsigned value) const {
396 ProcessingCache = value;
397 HasProcessingCache = true;
400 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
401 void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
403 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
404 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
406 Kind getKind() const { return Kind(AttrKind); }
407 static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
410 AttributeList *getNext() const { return NextInPosition; }
411 void setNext(AttributeList *N) { NextInPosition = N; }
413 /// getNumArgs - Return the number of actual arguments to this attribute.
414 unsigned getNumArgs() const { return NumArgs; }
416 /// getArg - Return the specified argument.
417 ArgsUnion getArg(unsigned Arg) const {
418 assert(Arg < NumArgs && "Arg access out of range!");
419 return getArgsBuffer()[Arg];
422 bool isArgExpr(unsigned Arg) const {
423 return Arg < NumArgs && getArg(Arg).is<Expr*>();
425 Expr *getArgAsExpr(unsigned Arg) const {
426 return getArg(Arg).get<Expr*>();
429 bool isArgIdent(unsigned Arg) const {
430 return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
432 IdentifierLoc *getArgAsIdent(unsigned Arg) const {
433 return getArg(Arg).get<IdentifierLoc*>();
436 const AvailabilityChange &getAvailabilityIntroduced() const {
437 assert(getKind() == AT_Availability && "Not an availability attribute");
438 return getAvailabilityData()->Changes[IntroducedSlot];
441 const AvailabilityChange &getAvailabilityDeprecated() const {
442 assert(getKind() == AT_Availability && "Not an availability attribute");
443 return getAvailabilityData()->Changes[DeprecatedSlot];
446 const AvailabilityChange &getAvailabilityObsoleted() const {
447 assert(getKind() == AT_Availability && "Not an availability attribute");
448 return getAvailabilityData()->Changes[ObsoletedSlot];
451 SourceLocation getStrictLoc() const {
452 assert(getKind() == AT_Availability && "Not an availability attribute");
453 return getAvailabilityData()->StrictLoc;
456 SourceLocation getUnavailableLoc() const {
457 assert(getKind() == AT_Availability && "Not an availability attribute");
458 return UnavailableLoc;
461 const Expr * getMessageExpr() const {
462 assert(getKind() == AT_Availability && "Not an availability attribute");
466 const Expr *getReplacementExpr() const {
467 assert(getKind() == AT_Availability && "Not an availability attribute");
468 return getAvailabilityData()->Replacement;
471 const ParsedType &getMatchingCType() const {
472 assert(getKind() == AT_TypeTagForDatatype &&
473 "Not a type_tag_for_datatype attribute");
474 return *getTypeTagForDatatypeDataSlot().MatchingCType;
477 bool getLayoutCompatible() const {
478 assert(getKind() == AT_TypeTagForDatatype &&
479 "Not a type_tag_for_datatype attribute");
480 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
483 bool getMustBeNull() const {
484 assert(getKind() == AT_TypeTagForDatatype &&
485 "Not a type_tag_for_datatype attribute");
486 return getTypeTagForDatatypeDataSlot().MustBeNull;
489 const ParsedType &getTypeArg() const {
490 assert(HasParsedType && "Not a type attribute");
491 return getTypeBuffer();
494 const PropertyData &getPropertyData() const {
495 assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
496 return getPropertyDataBuffer();
499 /// \brief Get an index into the attribute spelling list
500 /// defined in Attr.td. This index is used by an attribute
501 /// to pretty print itself.
502 unsigned getAttributeSpellingListIndex() const;
504 bool isTargetSpecificAttr() const;
505 bool isTypeAttr() const;
506 bool isStmtAttr() const;
508 bool hasCustomParsing() const;
509 unsigned getMinArgs() const;
510 unsigned getMaxArgs() const;
511 bool hasVariadicArg() const;
512 bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
513 bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
514 void getMatchRules(const LangOptions &LangOpts,
515 SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
517 bool diagnoseLangOpts(class Sema &S) const;
518 bool existsInTarget(const TargetInfo &Target) const;
519 bool isKnownToGCC() const;
520 bool isSupportedByPragmaAttribute() const;
522 /// \brief If the parsed attribute has a semantic equivalent, and it would
523 /// have a semantic Spelling enumeration (due to having semantically-distinct
524 /// spelling variations), return the value of that semantic spelling. If the
525 /// parsed attribute does not have a semantic equivalent, or would not have
526 /// a Spelling enumeration, the value UINT_MAX is returned.
527 unsigned getSemanticSpelling() const;
530 /// A factory, from which one makes pools, from which one creates
531 /// individual attributes which are deallocated with the pool.
533 /// Note that it's tolerably cheap to create and destroy one of
534 /// these as long as you don't actually allocate anything in it.
535 class AttributeFactory {
538 /// The required allocation size of an availability attribute,
539 /// which we want to ensure is a multiple of sizeof(void*).
540 AvailabilityAllocSize =
541 sizeof(AttributeList)
542 + ((sizeof(AvailabilityData) + sizeof(void*) + sizeof(ArgsUnion) - 1)
543 / sizeof(void*) * sizeof(void*)),
544 TypeTagForDatatypeAllocSize =
545 sizeof(AttributeList)
546 + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
547 sizeof(ArgsUnion) - 1)
548 / sizeof(void*) * sizeof(void*),
550 sizeof(AttributeList)
551 + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
552 / sizeof(void*) * sizeof(void*)
557 /// The number of free lists we want to be sure to support
558 /// inline. This is just enough that availability attributes
559 /// don't surpass it. It's actually very unlikely we'll see an
560 /// attribute that needs more than that; on x86-64 you'd need 10
561 /// expression arguments, and on i386 you'd need 19.
562 InlineFreeListsCapacity =
563 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
566 llvm::BumpPtrAllocator Alloc;
568 /// Free lists. The index is determined by the following formula:
569 /// (size - sizeof(AttributeList)) / sizeof(void*)
570 SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
572 // The following are the private interface used by AttributePool.
573 friend class AttributePool;
575 /// Allocate an attribute of the given size.
576 void *allocate(size_t size);
578 /// Reclaim all the attributes in the given pool chain, which is
579 /// non-empty. Note that the current implementation is safe
580 /// against reclaiming things which were not actually allocated
581 /// with the allocator, although of course it's important to make
582 /// sure that their allocator lives at least as long as this one.
583 void reclaimPool(AttributeList *head);
590 class AttributePool {
591 AttributeFactory &Factory;
594 void *allocate(size_t size) {
595 return Factory.allocate(size);
598 AttributeList *add(AttributeList *attr) {
599 // We don't care about the order of the pool.
600 attr->NextInPool = Head;
605 void takePool(AttributeList *pool);
608 /// Create a new pool for a factory.
609 AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
611 AttributePool(const AttributePool &) = delete;
613 /// Move the given pool's allocations to this pool.
614 AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) {
618 AttributeFactory &getFactory() const { return Factory; }
622 Factory.reclaimPool(Head);
627 /// Take the given pool's allocations and add them to this pool.
628 void takeAllFrom(AttributePool &pool) {
636 if (Head) Factory.reclaimPool(Head);
639 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
640 IdentifierInfo *scopeName, SourceLocation scopeLoc,
641 ArgsUnion *args, unsigned numArgs,
642 AttributeList::Syntax syntax,
643 SourceLocation ellipsisLoc = SourceLocation()) {
644 void *memory = allocate(sizeof(AttributeList)
645 + numArgs * sizeof(ArgsUnion));
646 return add(new (memory) AttributeList(attrName, attrRange,
648 args, numArgs, syntax,
652 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
653 IdentifierInfo *scopeName, SourceLocation scopeLoc,
654 IdentifierLoc *Param,
655 const AvailabilityChange &introduced,
656 const AvailabilityChange &deprecated,
657 const AvailabilityChange &obsoleted,
658 SourceLocation unavailable,
659 const Expr *MessageExpr,
660 AttributeList::Syntax syntax,
661 SourceLocation strict, const Expr *ReplacementExpr) {
662 void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
663 return add(new (memory) AttributeList(attrName, attrRange,
665 Param, introduced, deprecated,
666 obsoleted, unavailable, MessageExpr,
667 syntax, strict, ReplacementExpr));
670 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
671 IdentifierInfo *scopeName, SourceLocation scopeLoc,
672 IdentifierLoc *Param1,
673 IdentifierLoc *Param2,
674 IdentifierLoc *Param3,
675 AttributeList::Syntax syntax) {
676 size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
677 void *memory = allocate(size);
678 return add(new (memory) AttributeList(attrName, attrRange,
680 Param1, Param2, Param3,
684 AttributeList *createTypeTagForDatatype(
685 IdentifierInfo *attrName, SourceRange attrRange,
686 IdentifierInfo *scopeName, SourceLocation scopeLoc,
687 IdentifierLoc *argumentKind, ParsedType matchingCType,
688 bool layoutCompatible, bool mustBeNull,
689 AttributeList::Syntax syntax) {
690 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
691 return add(new (memory) AttributeList(attrName, attrRange,
693 argumentKind, matchingCType,
694 layoutCompatible, mustBeNull,
698 AttributeList *createTypeAttribute(
699 IdentifierInfo *attrName, SourceRange attrRange,
700 IdentifierInfo *scopeName, SourceLocation scopeLoc,
701 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
702 void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
703 return add(new (memory) AttributeList(attrName, attrRange,
705 typeArg, syntaxUsed));
708 AttributeList *createPropertyAttribute(
709 IdentifierInfo *attrName, SourceRange attrRange,
710 IdentifierInfo *scopeName, SourceLocation scopeLoc,
711 IdentifierInfo *getterId, IdentifierInfo *setterId,
712 AttributeList::Syntax syntaxUsed) {
713 void *memory = allocate(AttributeFactory::PropertyAllocSize);
714 return add(new (memory) AttributeList(attrName, attrRange,
721 /// ParsedAttributes - A collection of parsed attributes. Currently
722 /// we don't differentiate between the various attribute syntaxes,
723 /// which is basically silly.
725 /// Right now this is a very lightweight container, but the expectation
726 /// is that this will become significantly more serious.
727 class ParsedAttributes {
729 ParsedAttributes(AttributeFactory &factory)
730 : pool(factory), list(nullptr) {
733 ParsedAttributes(const ParsedAttributes &) = delete;
735 AttributePool &getPool() const { return pool; }
737 bool empty() const { return list == nullptr; }
739 void add(AttributeList *newAttr) {
741 assert(newAttr->getNext() == nullptr);
742 newAttr->setNext(list);
746 void addAll(AttributeList *newList) {
747 if (!newList) return;
749 AttributeList *lastInNewList = newList;
750 while (AttributeList *next = lastInNewList->getNext())
751 lastInNewList = next;
753 lastInNewList->setNext(list);
757 void addAllAtEnd(AttributeList *newList) {
763 AttributeList *lastInList = list;
764 while (AttributeList *next = lastInList->getNext())
767 lastInList->setNext(newList);
770 void set(AttributeList *newList) {
774 void takeAllFrom(ParsedAttributes &attrs) {
776 attrs.list = nullptr;
777 pool.takeAllFrom(attrs.pool);
780 void clear() { list = nullptr; pool.clear(); }
781 AttributeList *getList() const { return list; }
783 void clearListOnly() { list = nullptr; }
785 /// Returns a reference to the attribute list. Try not to introduce
786 /// dependencies on this method, it may not be long-lived.
787 AttributeList *&getListRef() { return list; }
789 /// Add attribute with expression arguments.
790 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
791 IdentifierInfo *scopeName, SourceLocation scopeLoc,
792 ArgsUnion *args, unsigned numArgs,
793 AttributeList::Syntax syntax,
794 SourceLocation ellipsisLoc = SourceLocation()) {
795 AttributeList *attr =
796 pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
797 syntax, ellipsisLoc);
802 /// Add availability attribute.
803 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
804 IdentifierInfo *scopeName, SourceLocation scopeLoc,
805 IdentifierLoc *Param,
806 const AvailabilityChange &introduced,
807 const AvailabilityChange &deprecated,
808 const AvailabilityChange &obsoleted,
809 SourceLocation unavailable,
810 const Expr *MessageExpr,
811 AttributeList::Syntax syntax,
812 SourceLocation strict, const Expr *ReplacementExpr) {
813 AttributeList *attr =
814 pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
815 deprecated, obsoleted, unavailable, MessageExpr, syntax,
816 strict, ReplacementExpr);
821 /// Add objc_bridge_related attribute.
822 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
823 IdentifierInfo *scopeName, SourceLocation scopeLoc,
824 IdentifierLoc *Param1,
825 IdentifierLoc *Param2,
826 IdentifierLoc *Param3,
827 AttributeList::Syntax syntax) {
828 AttributeList *attr =
829 pool.create(attrName, attrRange, scopeName, scopeLoc,
830 Param1, Param2, Param3, syntax);
835 /// Add type_tag_for_datatype attribute.
836 AttributeList *addNewTypeTagForDatatype(
837 IdentifierInfo *attrName, SourceRange attrRange,
838 IdentifierInfo *scopeName, SourceLocation scopeLoc,
839 IdentifierLoc *argumentKind, ParsedType matchingCType,
840 bool layoutCompatible, bool mustBeNull,
841 AttributeList::Syntax syntax) {
842 AttributeList *attr =
843 pool.createTypeTagForDatatype(attrName, attrRange,
845 argumentKind, matchingCType,
846 layoutCompatible, mustBeNull, syntax);
851 /// Add an attribute with a single type argument.
853 addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
854 IdentifierInfo *scopeName, SourceLocation scopeLoc,
855 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
856 AttributeList *attr =
857 pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
858 typeArg, syntaxUsed);
863 /// Add microsoft __delspec(property) attribute.
865 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
866 IdentifierInfo *scopeName, SourceLocation scopeLoc,
867 IdentifierInfo *getterId, IdentifierInfo *setterId,
868 AttributeList::Syntax syntaxUsed) {
869 AttributeList *attr =
870 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
871 getterId, setterId, syntaxUsed);
877 mutable AttributePool pool;
881 /// These constants match the enumerated choices of
882 /// err_attribute_argument_n_type and err_attribute_argument_type.
883 enum AttributeArgumentNType {
884 AANT_ArgumentIntOrBool,
885 AANT_ArgumentIntegerConstant,
887 AANT_ArgumentIdentifier
890 /// These constants match the enumerated choices of
891 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
892 enum AttributeDeclKind {
895 ExpectedVariableOrFunction,
896 ExpectedFunctionOrGlobalVar,
897 ExpectedFunctionVariableOrObjCInterface,
898 ExpectedFunctionOrMethod,
900 ExpectedFunctionMethodOrBlock,
901 ExpectedFunctionMethodOrClass,
902 ExpectedFunctionMethodOrParameter,
903 ExpectedFunctionMethodOrGlobalVar,
908 ExpectedFieldOrGlobalVar,
910 ExpectedParameterOrTypedef,
911 ExpectedVariableOrTypedef,
913 ExpectedVariableOrField,
914 ExpectedVariableFieldOrTag,
915 ExpectedTypeOrNamespace,
916 ExpectedObjectiveCInterface,
917 ExpectedMethodOrProperty,
918 ExpectedFunctionOrMethodOrProperty,
919 ExpectedStructOrUnion,
920 ExpectedStructOrUnionOrClass,
922 ExpectedObjCInstanceMethod,
923 ExpectedObjCInterfaceDeclInitMethod,
924 ExpectedFunctionVariableOrClass,
925 ExpectedFunctionVariableClassOrObjCInterface,
926 ExpectedObjectiveCProtocol,
927 ExpectedStaticOrTLSVar,
928 ExpectedFunctionGlobalVarMethodOrProperty,
929 ExpectedStructOrUnionOrTypedef,
930 ExpectedStructOrTypedef,
931 ExpectedObjectiveCInterfaceOrProtocol,
932 ExpectedKernelFunction,
933 ExpectedFunctionWithProtoType,
934 ExpectedVariableEnumFieldOrTypedef,
935 ExpectedFunctionMethodEnumOrClass,
936 ExpectedStructClassVariableFunctionOrInlineNamespace,
937 ExpectedForMaybeUnused,
942 } // end namespace clang