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/SourceLocation.h"
19 #include "clang/Basic/VersionTuple.h"
20 #include "clang/Sema/Ownership.h"
21 #include "llvm/ADT/PointerUnion.h"
22 #include "llvm/ADT/SmallVector.h"
23 #include "llvm/ADT/Triple.h"
24 #include "llvm/Support/Allocator.h"
32 /// \brief Represents information about a change in availability for
33 /// an entity, which is part of the encoding of the 'availability'
35 struct AvailabilityChange {
36 /// \brief The location of the keyword indicating the kind of change.
37 SourceLocation KeywordLoc;
39 /// \brief The version number at which the change occurred.
42 /// \brief The source range covering the version number.
43 SourceRange VersionRange;
45 /// \brief Determine whether this availability change is valid.
46 bool isValid() const { return !Version.empty(); }
49 /// \brief Wraps an identifier and optional source location for the identifier.
50 struct IdentifierLoc {
52 IdentifierInfo *Ident;
54 static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
55 IdentifierInfo *Ident);
58 /// \brief A union of the various pointer types that can be passed to an
59 /// AttributeList as an argument.
60 typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion;
61 typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector;
63 /// AttributeList - Represents a syntactic attribute.
65 /// For a GNU attribute, there are four forms of this construct:
67 /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
68 /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
69 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
70 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
72 class AttributeList { // TODO: This should really be called ParsedAttribute
74 /// The style used to specify an attribute.
76 /// __attribute__((...))
82 /// __ptr16, alignas(...), etc.
89 IdentifierInfo *AttrName;
90 IdentifierInfo *ScopeName;
91 SourceRange AttrRange;
92 SourceLocation ScopeLoc;
93 SourceLocation EllipsisLoc;
95 /// The number of expression arguments this attribute has.
96 /// The expressions themselves are stored after the object.
97 unsigned NumArgs : 15;
99 /// Corresponds to the Syntax enum.
100 unsigned SyntaxUsed : 3;
102 /// True if already diagnosed as invalid.
103 mutable unsigned Invalid : 1;
105 /// True if this attribute was used as a type attribute.
106 mutable unsigned UsedAsTypeAttr : 1;
108 /// True if this has the extra information associated with an
109 /// availability attribute.
110 unsigned IsAvailability : 1;
112 /// True if this has extra information associated with a
113 /// type_tag_for_datatype attribute.
114 unsigned IsTypeTagForDatatype : 1;
116 /// True if this has extra information associated with a
117 /// Microsoft __delcspec(property) attribute.
118 unsigned IsProperty : 1;
120 /// True if this has a ParsedType
121 unsigned HasParsedType : 1;
123 unsigned AttrKind : 8;
125 /// \brief The location of the 'unavailable' keyword in an
126 /// availability attribute.
127 SourceLocation UnavailableLoc;
129 const Expr *MessageExpr;
131 /// The next attribute in the current position.
132 AttributeList *NextInPosition;
134 /// The next attribute allocated in the current Pool.
135 AttributeList *NextInPool;
137 /// Arguments, if any, are stored immediately following the object.
138 ArgsUnion *getArgsBuffer() {
139 return reinterpret_cast<ArgsUnion*>(this+1);
141 ArgsUnion const *getArgsBuffer() const {
142 return reinterpret_cast<ArgsUnion const *>(this+1);
145 enum AvailabilitySlot {
146 IntroducedSlot, DeprecatedSlot, ObsoletedSlot
149 /// Availability information is stored immediately following the arguments,
150 /// if any, at the end of the object.
151 AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {
152 return reinterpret_cast<AvailabilityChange*>(getArgsBuffer()
155 const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const {
156 return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer()
161 struct TypeTagForDatatypeData {
162 ParsedType *MatchingCType;
163 unsigned LayoutCompatible : 1;
164 unsigned MustBeNull : 1;
166 struct PropertyData {
167 IdentifierInfo *GetterId, *SetterId;
168 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
169 : GetterId(getterId), SetterId(setterId) {}
173 /// Type tag information is stored immediately following the arguments, if
174 /// any, at the end of the object. They are mutually exlusive with
175 /// availability slots.
176 TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
177 return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
180 const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
181 return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
185 /// The type buffer immediately follows the object and are mutually exclusive
187 ParsedType &getTypeBuffer() {
188 return *reinterpret_cast<ParsedType *>(this + 1);
191 const ParsedType &getTypeBuffer() const {
192 return *reinterpret_cast<const ParsedType *>(this + 1);
195 /// The property data immediately follows the object is is mutually exclusive
197 PropertyData &getPropertyDataBuffer() {
199 return *reinterpret_cast<PropertyData*>(this + 1);
202 const PropertyData &getPropertyDataBuffer() const {
204 return *reinterpret_cast<const PropertyData*>(this + 1);
207 AttributeList(const AttributeList &) = delete;
208 void operator=(const AttributeList &) = delete;
209 void operator delete(void *) = delete;
210 ~AttributeList() = delete;
212 size_t allocated_size() const;
214 /// Constructor for attributes with expression arguments.
215 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
216 IdentifierInfo *scopeName, SourceLocation scopeLoc,
217 ArgsUnion *args, unsigned numArgs,
218 Syntax syntaxUsed, SourceLocation ellipsisLoc)
219 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
220 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
221 SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
222 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
223 HasParsedType(false), NextInPosition(nullptr), NextInPool(nullptr) {
224 if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
225 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
228 /// Constructor for availability attributes.
229 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
230 IdentifierInfo *scopeName, SourceLocation scopeLoc,
231 IdentifierLoc *Parm, const AvailabilityChange &introduced,
232 const AvailabilityChange &deprecated,
233 const AvailabilityChange &obsoleted,
234 SourceLocation unavailable,
235 const Expr *messageExpr,
237 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
238 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
239 Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
240 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
241 UnavailableLoc(unavailable), MessageExpr(messageExpr),
242 NextInPosition(nullptr), NextInPool(nullptr) {
243 ArgsUnion PVal(Parm);
244 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
245 new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
246 new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
247 new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
248 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
251 /// Constructor for objc_bridge_related attributes.
252 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
253 IdentifierInfo *scopeName, SourceLocation scopeLoc,
254 IdentifierLoc *Parm1,
255 IdentifierLoc *Parm2,
256 IdentifierLoc *Parm3,
258 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
259 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
260 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
261 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
262 NextInPosition(nullptr), NextInPool(nullptr) {
264 Args.push_back(Parm1);
265 Args.push_back(Parm2);
266 Args.push_back(Parm3);
267 memcpy(getArgsBuffer(), &Args[0], 3 * sizeof(ArgsUnion));
268 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
271 /// Constructor for type_tag_for_datatype attribute.
272 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
273 IdentifierInfo *scopeName, SourceLocation scopeLoc,
274 IdentifierLoc *ArgKind, ParsedType matchingCType,
275 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
276 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
277 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
278 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
279 IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
280 NextInPosition(nullptr), NextInPool(nullptr) {
281 ArgsUnion PVal(ArgKind);
282 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
283 TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
284 new (&ExtraData.MatchingCType) ParsedType(matchingCType);
285 ExtraData.LayoutCompatible = layoutCompatible;
286 ExtraData.MustBeNull = mustBeNull;
287 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
290 /// Constructor for attributes with a single type argument.
291 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
292 IdentifierInfo *scopeName, SourceLocation scopeLoc,
293 ParsedType typeArg, Syntax syntaxUsed)
294 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
295 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
296 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
297 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
298 NextInPosition(nullptr), NextInPool(nullptr) {
299 new (&getTypeBuffer()) ParsedType(typeArg);
300 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
303 /// Constructor for microsoft __declspec(property) attribute.
304 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
305 IdentifierInfo *scopeName, SourceLocation scopeLoc,
306 IdentifierInfo *getterId, IdentifierInfo *setterId,
308 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
309 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
310 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
311 IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
312 NextInPosition(nullptr), NextInPool(nullptr) {
313 new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
314 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
317 friend class AttributePool;
318 friend class AttributeFactory;
322 #define PARSED_ATTR(NAME) AT_##NAME,
323 #include "clang/Sema/AttrParsedAttrList.inc"
329 IdentifierInfo *getName() const { return AttrName; }
330 SourceLocation getLoc() const { return AttrRange.getBegin(); }
331 SourceRange getRange() const { return AttrRange; }
333 bool hasScope() const { return ScopeName; }
334 IdentifierInfo *getScopeName() const { return ScopeName; }
335 SourceLocation getScopeLoc() const { return ScopeLoc; }
337 bool hasParsedType() const { return HasParsedType; }
339 /// Is this the Microsoft __declspec(property) attribute?
340 bool isDeclspecPropertyAttribute() const {
344 bool isAlignasAttribute() const {
345 // FIXME: Use a better mechanism to determine this.
346 return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword;
349 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
350 bool isCXX11Attribute() const {
351 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
353 bool isKeywordAttribute() const { return SyntaxUsed == AS_Keyword; }
355 bool isInvalid() const { return Invalid; }
356 void setInvalid(bool b = true) const { Invalid = b; }
358 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
359 void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
361 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
362 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
364 Kind getKind() const { return Kind(AttrKind); }
365 static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
368 AttributeList *getNext() const { return NextInPosition; }
369 void setNext(AttributeList *N) { NextInPosition = N; }
371 /// getNumArgs - Return the number of actual arguments to this attribute.
372 unsigned getNumArgs() const { return NumArgs; }
374 /// getArg - Return the specified argument.
375 ArgsUnion getArg(unsigned Arg) const {
376 assert(Arg < NumArgs && "Arg access out of range!");
377 return getArgsBuffer()[Arg];
380 bool isArgExpr(unsigned Arg) const {
381 return Arg < NumArgs && getArg(Arg).is<Expr*>();
383 Expr *getArgAsExpr(unsigned Arg) const {
384 return getArg(Arg).get<Expr*>();
387 bool isArgIdent(unsigned Arg) const {
388 return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
390 IdentifierLoc *getArgAsIdent(unsigned Arg) const {
391 return getArg(Arg).get<IdentifierLoc*>();
394 const AvailabilityChange &getAvailabilityIntroduced() const {
395 assert(getKind() == AT_Availability && "Not an availability attribute");
396 return getAvailabilitySlot(IntroducedSlot);
399 const AvailabilityChange &getAvailabilityDeprecated() const {
400 assert(getKind() == AT_Availability && "Not an availability attribute");
401 return getAvailabilitySlot(DeprecatedSlot);
404 const AvailabilityChange &getAvailabilityObsoleted() const {
405 assert(getKind() == AT_Availability && "Not an availability attribute");
406 return getAvailabilitySlot(ObsoletedSlot);
409 SourceLocation getUnavailableLoc() const {
410 assert(getKind() == AT_Availability && "Not an availability attribute");
411 return UnavailableLoc;
414 const Expr * getMessageExpr() const {
415 assert(getKind() == AT_Availability && "Not an availability attribute");
419 const ParsedType &getMatchingCType() const {
420 assert(getKind() == AT_TypeTagForDatatype &&
421 "Not a type_tag_for_datatype attribute");
422 return *getTypeTagForDatatypeDataSlot().MatchingCType;
425 bool getLayoutCompatible() const {
426 assert(getKind() == AT_TypeTagForDatatype &&
427 "Not a type_tag_for_datatype attribute");
428 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
431 bool getMustBeNull() const {
432 assert(getKind() == AT_TypeTagForDatatype &&
433 "Not a type_tag_for_datatype attribute");
434 return getTypeTagForDatatypeDataSlot().MustBeNull;
437 const ParsedType &getTypeArg() const {
438 assert(HasParsedType && "Not a type attribute");
439 return getTypeBuffer();
442 const PropertyData &getPropertyData() const {
443 assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
444 return getPropertyDataBuffer();
447 /// \brief Get an index into the attribute spelling list
448 /// defined in Attr.td. This index is used by an attribute
449 /// to pretty print itself.
450 unsigned getAttributeSpellingListIndex() const;
452 bool isTargetSpecificAttr() const;
453 bool isTypeAttr() const;
455 bool hasCustomParsing() const;
456 unsigned getMinArgs() const;
457 unsigned getMaxArgs() const;
458 bool hasVariadicArg() const;
459 bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
460 bool diagnoseLangOpts(class Sema &S) const;
461 bool existsInTarget(const llvm::Triple &T) const;
462 bool isKnownToGCC() const;
464 /// \brief If the parsed attribute has a semantic equivalent, and it would
465 /// have a semantic Spelling enumeration (due to having semantically-distinct
466 /// spelling variations), return the value of that semantic spelling. If the
467 /// parsed attribute does not have a semantic equivalent, or would not have
468 /// a Spelling enumeration, the value UINT_MAX is returned.
469 unsigned getSemanticSpelling() const;
472 /// A factory, from which one makes pools, from which one creates
473 /// individual attributes which are deallocated with the pool.
475 /// Note that it's tolerably cheap to create and destroy one of
476 /// these as long as you don't actually allocate anything in it.
477 class AttributeFactory {
480 /// The required allocation size of an availability attribute,
481 /// which we want to ensure is a multiple of sizeof(void*).
482 AvailabilityAllocSize =
483 sizeof(AttributeList)
484 + ((3 * sizeof(AvailabilityChange) + sizeof(void*) +
485 sizeof(ArgsUnion) - 1)
486 / sizeof(void*) * sizeof(void*)),
487 TypeTagForDatatypeAllocSize =
488 sizeof(AttributeList)
489 + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
490 sizeof(ArgsUnion) - 1)
491 / sizeof(void*) * sizeof(void*),
493 sizeof(AttributeList)
494 + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
495 / sizeof(void*) * sizeof(void*)
500 /// The number of free lists we want to be sure to support
501 /// inline. This is just enough that availability attributes
502 /// don't surpass it. It's actually very unlikely we'll see an
503 /// attribute that needs more than that; on x86-64 you'd need 10
504 /// expression arguments, and on i386 you'd need 19.
505 InlineFreeListsCapacity =
506 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
509 llvm::BumpPtrAllocator Alloc;
511 /// Free lists. The index is determined by the following formula:
512 /// (size - sizeof(AttributeList)) / sizeof(void*)
513 SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
515 // The following are the private interface used by AttributePool.
516 friend class AttributePool;
518 /// Allocate an attribute of the given size.
519 void *allocate(size_t size);
521 /// Reclaim all the attributes in the given pool chain, which is
522 /// non-empty. Note that the current implementation is safe
523 /// against reclaiming things which were not actually allocated
524 /// with the allocator, although of course it's important to make
525 /// sure that their allocator lives at least as long as this one.
526 void reclaimPool(AttributeList *head);
533 class AttributePool {
534 AttributeFactory &Factory;
537 void *allocate(size_t size) {
538 return Factory.allocate(size);
541 AttributeList *add(AttributeList *attr) {
542 // We don't care about the order of the pool.
543 attr->NextInPool = Head;
548 void takePool(AttributeList *pool);
551 /// Create a new pool for a factory.
552 AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
554 /// Move the given pool's allocations to this pool.
555 AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) {
559 AttributeFactory &getFactory() const { return Factory; }
563 Factory.reclaimPool(Head);
568 /// Take the given pool's allocations and add them to this pool.
569 void takeAllFrom(AttributePool &pool) {
577 if (Head) Factory.reclaimPool(Head);
580 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
581 IdentifierInfo *scopeName, SourceLocation scopeLoc,
582 ArgsUnion *args, unsigned numArgs,
583 AttributeList::Syntax syntax,
584 SourceLocation ellipsisLoc = SourceLocation()) {
585 void *memory = allocate(sizeof(AttributeList)
586 + numArgs * sizeof(ArgsUnion));
587 return add(new (memory) AttributeList(attrName, attrRange,
589 args, numArgs, syntax,
593 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
594 IdentifierInfo *scopeName, SourceLocation scopeLoc,
595 IdentifierLoc *Param,
596 const AvailabilityChange &introduced,
597 const AvailabilityChange &deprecated,
598 const AvailabilityChange &obsoleted,
599 SourceLocation unavailable,
600 const Expr *MessageExpr,
601 AttributeList::Syntax syntax) {
602 void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
603 return add(new (memory) AttributeList(attrName, attrRange,
605 Param, introduced, deprecated,
606 obsoleted, unavailable, MessageExpr,
610 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
611 IdentifierInfo *scopeName, SourceLocation scopeLoc,
612 IdentifierLoc *Param1,
613 IdentifierLoc *Param2,
614 IdentifierLoc *Param3,
615 AttributeList::Syntax syntax) {
616 size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
617 void *memory = allocate(size);
618 return add(new (memory) AttributeList(attrName, attrRange,
620 Param1, Param2, Param3,
624 AttributeList *createTypeTagForDatatype(
625 IdentifierInfo *attrName, SourceRange attrRange,
626 IdentifierInfo *scopeName, SourceLocation scopeLoc,
627 IdentifierLoc *argumentKind, ParsedType matchingCType,
628 bool layoutCompatible, bool mustBeNull,
629 AttributeList::Syntax syntax) {
630 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
631 return add(new (memory) AttributeList(attrName, attrRange,
633 argumentKind, matchingCType,
634 layoutCompatible, mustBeNull,
638 AttributeList *createTypeAttribute(
639 IdentifierInfo *attrName, SourceRange attrRange,
640 IdentifierInfo *scopeName, SourceLocation scopeLoc,
641 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
642 void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
643 return add(new (memory) AttributeList(attrName, attrRange,
645 typeArg, syntaxUsed));
648 AttributeList *createPropertyAttribute(
649 IdentifierInfo *attrName, SourceRange attrRange,
650 IdentifierInfo *scopeName, SourceLocation scopeLoc,
651 IdentifierInfo *getterId, IdentifierInfo *setterId,
652 AttributeList::Syntax syntaxUsed) {
653 void *memory = allocate(AttributeFactory::PropertyAllocSize);
654 return add(new (memory) AttributeList(attrName, attrRange,
661 /// ParsedAttributes - A collection of parsed attributes. Currently
662 /// we don't differentiate between the various attribute syntaxes,
663 /// which is basically silly.
665 /// Right now this is a very lightweight container, but the expectation
666 /// is that this will become significantly more serious.
667 class ParsedAttributes {
669 ParsedAttributes(AttributeFactory &factory)
670 : pool(factory), list(nullptr) {
673 ParsedAttributes(const ParsedAttributes &) = delete;
675 AttributePool &getPool() const { return pool; }
677 bool empty() const { return list == nullptr; }
679 void add(AttributeList *newAttr) {
681 assert(newAttr->getNext() == nullptr);
682 newAttr->setNext(list);
686 void addAll(AttributeList *newList) {
687 if (!newList) return;
689 AttributeList *lastInNewList = newList;
690 while (AttributeList *next = lastInNewList->getNext())
691 lastInNewList = next;
693 lastInNewList->setNext(list);
697 void set(AttributeList *newList) {
701 void takeAllFrom(ParsedAttributes &attrs) {
703 attrs.list = nullptr;
704 pool.takeAllFrom(attrs.pool);
707 void clear() { list = nullptr; pool.clear(); }
708 AttributeList *getList() const { return list; }
710 /// Returns a reference to the attribute list. Try not to introduce
711 /// dependencies on this method, it may not be long-lived.
712 AttributeList *&getListRef() { return list; }
714 /// Add attribute with expression arguments.
715 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
716 IdentifierInfo *scopeName, SourceLocation scopeLoc,
717 ArgsUnion *args, unsigned numArgs,
718 AttributeList::Syntax syntax,
719 SourceLocation ellipsisLoc = SourceLocation()) {
720 AttributeList *attr =
721 pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
722 syntax, ellipsisLoc);
727 /// Add availability attribute.
728 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
729 IdentifierInfo *scopeName, SourceLocation scopeLoc,
730 IdentifierLoc *Param,
731 const AvailabilityChange &introduced,
732 const AvailabilityChange &deprecated,
733 const AvailabilityChange &obsoleted,
734 SourceLocation unavailable,
735 const Expr *MessageExpr,
736 AttributeList::Syntax syntax) {
737 AttributeList *attr =
738 pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
739 deprecated, obsoleted, unavailable, MessageExpr, syntax);
744 /// Add objc_bridge_related attribute.
745 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
746 IdentifierInfo *scopeName, SourceLocation scopeLoc,
747 IdentifierLoc *Param1,
748 IdentifierLoc *Param2,
749 IdentifierLoc *Param3,
750 AttributeList::Syntax syntax) {
751 AttributeList *attr =
752 pool.create(attrName, attrRange, scopeName, scopeLoc,
753 Param1, Param2, Param3, syntax);
758 /// Add type_tag_for_datatype attribute.
759 AttributeList *addNewTypeTagForDatatype(
760 IdentifierInfo *attrName, SourceRange attrRange,
761 IdentifierInfo *scopeName, SourceLocation scopeLoc,
762 IdentifierLoc *argumentKind, ParsedType matchingCType,
763 bool layoutCompatible, bool mustBeNull,
764 AttributeList::Syntax syntax) {
765 AttributeList *attr =
766 pool.createTypeTagForDatatype(attrName, attrRange,
768 argumentKind, matchingCType,
769 layoutCompatible, mustBeNull, syntax);
774 /// Add an attribute with a single type argument.
776 addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
777 IdentifierInfo *scopeName, SourceLocation scopeLoc,
778 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
779 AttributeList *attr =
780 pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
781 typeArg, syntaxUsed);
786 /// Add microsoft __delspec(property) attribute.
788 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
789 IdentifierInfo *scopeName, SourceLocation scopeLoc,
790 IdentifierInfo *getterId, IdentifierInfo *setterId,
791 AttributeList::Syntax syntaxUsed) {
792 AttributeList *attr =
793 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
794 getterId, setterId, syntaxUsed);
800 mutable AttributePool pool;
804 /// These constants match the enumerated choices of
805 /// err_attribute_argument_n_type and err_attribute_argument_type.
806 enum AttributeArgumentNType {
807 AANT_ArgumentIntOrBool,
808 AANT_ArgumentIntegerConstant,
810 AANT_ArgumentIdentifier
813 /// These constants match the enumerated choices of
814 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
815 enum AttributeDeclKind {
818 ExpectedVariableOrFunction,
819 ExpectedFunctionOrMethod,
821 ExpectedFunctionMethodOrBlock,
822 ExpectedFunctionMethodOrClass,
823 ExpectedFunctionMethodOrParameter,
828 ExpectedVariableFunctionOrLabel,
829 ExpectedFieldOrGlobalVar,
831 ExpectedVariableOrTypedef,
833 ExpectedVariableOrField,
834 ExpectedVariableFieldOrTag,
835 ExpectedTypeOrNamespace,
836 ExpectedObjectiveCInterface,
837 ExpectedMethodOrProperty,
838 ExpectedStructOrUnion,
839 ExpectedStructOrUnionOrClass,
841 ExpectedObjCInstanceMethod,
842 ExpectedObjCInterfaceDeclInitMethod,
843 ExpectedFunctionVariableOrClass,
844 ExpectedObjectiveCProtocol,
845 ExpectedFunctionGlobalVarMethodOrProperty,
846 ExpectedStructOrUnionOrTypedef,
847 ExpectedStructOrTypedef,
848 ExpectedObjectiveCInterfaceOrProtocol,
849 ExpectedKernelFunction
852 } // end namespace clang