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_ATTRLIST_H
16 #define LLVM_CLANG_SEMA_ATTRLIST_H
18 #include "clang/Basic/SourceLocation.h"
19 #include "clang/Basic/VersionTuple.h"
20 #include "clang/Sema/Ownership.h"
21 #include "llvm/ADT/SmallVector.h"
22 #include "llvm/ADT/PointerUnion.h"
23 #include "llvm/Support/Allocator.h"
31 /// \brief Represents information about a change in availability for
32 /// an entity, which is part of the encoding of the 'availability'
34 struct AvailabilityChange {
35 /// \brief The location of the keyword indicating the kind of change.
36 SourceLocation KeywordLoc;
38 /// \brief The version number at which the change occurred.
41 /// \brief The source range covering the version number.
42 SourceRange VersionRange;
44 /// \brief Determine whether this availability change is valid.
45 bool isValid() const { return !Version.empty(); }
48 /// \brief Wraps an identifier and optional source location for the identifier.
49 struct IdentifierLoc {
51 IdentifierInfo *Ident;
53 static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
54 IdentifierInfo *Ident);
57 /// \brief A union of the various pointer types that can be passed to an
58 /// AttributeList as an argument.
59 typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion;
60 typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector;
62 /// AttributeList - Represents a syntactic attribute.
64 /// For a GNU attribute, there are four forms of this construct:
66 /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
67 /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
68 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
69 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
71 class AttributeList { // TODO: This should really be called ParsedAttribute
73 /// The style used to specify an attribute.
75 /// __attribute__((...))
81 /// __ptr16, alignas(...), etc.
86 IdentifierInfo *AttrName;
87 IdentifierInfo *ScopeName;
88 SourceRange AttrRange;
89 SourceLocation ScopeLoc;
90 SourceLocation EllipsisLoc;
92 /// The number of expression arguments this attribute has.
93 /// The expressions themselves are stored after the object.
94 unsigned NumArgs : 16;
96 /// Corresponds to the Syntax enum.
97 unsigned SyntaxUsed : 2;
99 /// True if already diagnosed as invalid.
100 mutable unsigned Invalid : 1;
102 /// True if this attribute was used as a type attribute.
103 mutable unsigned UsedAsTypeAttr : 1;
105 /// True if this has the extra information associated with an
106 /// availability attribute.
107 unsigned IsAvailability : 1;
109 /// True if this has extra information associated with a
110 /// type_tag_for_datatype attribute.
111 unsigned IsTypeTagForDatatype : 1;
113 /// True if this has extra information associated with a
114 /// Microsoft __delcspec(property) attribute.
115 unsigned IsProperty : 1;
117 /// True if this has a ParsedType
118 unsigned HasParsedType : 1;
120 unsigned AttrKind : 8;
122 /// \brief The location of the 'unavailable' keyword in an
123 /// availability attribute.
124 SourceLocation UnavailableLoc;
126 const Expr *MessageExpr;
128 /// The next attribute in the current position.
129 AttributeList *NextInPosition;
131 /// The next attribute allocated in the current Pool.
132 AttributeList *NextInPool;
134 /// Arguments, if any, are stored immediately following the object.
135 ArgsUnion *getArgsBuffer() {
136 return reinterpret_cast<ArgsUnion*>(this+1);
138 ArgsUnion const *getArgsBuffer() const {
139 return reinterpret_cast<ArgsUnion const *>(this+1);
142 enum AvailabilitySlot {
143 IntroducedSlot, DeprecatedSlot, ObsoletedSlot
146 /// Availability information is stored immediately following the arguments,
147 /// if any, at the end of the object.
148 AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {
149 return reinterpret_cast<AvailabilityChange*>(getArgsBuffer()
152 const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const {
153 return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer()
158 struct TypeTagForDatatypeData {
159 ParsedType *MatchingCType;
160 unsigned LayoutCompatible : 1;
161 unsigned MustBeNull : 1;
163 struct PropertyData {
164 IdentifierInfo *GetterId, *SetterId;
165 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
166 : GetterId(getterId), SetterId(setterId) {}
170 /// Type tag information is stored immediately following the arguments, if
171 /// any, at the end of the object. They are mutually exlusive with
172 /// availability slots.
173 TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
174 return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
177 const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
178 return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
182 /// The type buffer immediately follows the object and are mutually exclusive
184 ParsedType &getTypeBuffer() {
185 return *reinterpret_cast<ParsedType *>(this + 1);
188 const ParsedType &getTypeBuffer() const {
189 return *reinterpret_cast<const ParsedType *>(this + 1);
192 /// The property data immediately follows the object is is mutually exclusive
194 PropertyData &getPropertyDataBuffer() {
196 return *reinterpret_cast<PropertyData*>(this + 1);
199 const PropertyData &getPropertyDataBuffer() const {
201 return *reinterpret_cast<const PropertyData*>(this + 1);
204 AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION;
205 void operator=(const AttributeList &) LLVM_DELETED_FUNCTION;
206 void operator delete(void *) LLVM_DELETED_FUNCTION;
207 ~AttributeList() LLVM_DELETED_FUNCTION;
209 size_t allocated_size() const;
211 /// Constructor for attributes with expression arguments.
212 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
213 IdentifierInfo *scopeName, SourceLocation scopeLoc,
214 ArgsUnion *args, unsigned numArgs,
215 Syntax syntaxUsed, SourceLocation ellipsisLoc)
216 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
217 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
218 SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
219 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
220 HasParsedType(false), NextInPosition(0), NextInPool(0) {
221 if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
222 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
225 /// Constructor for availability attributes.
226 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
227 IdentifierInfo *scopeName, SourceLocation scopeLoc,
228 IdentifierLoc *Parm, const AvailabilityChange &introduced,
229 const AvailabilityChange &deprecated,
230 const AvailabilityChange &obsoleted,
231 SourceLocation unavailable,
232 const Expr *messageExpr,
234 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
235 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
236 Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
237 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
238 UnavailableLoc(unavailable), MessageExpr(messageExpr),
239 NextInPosition(0), NextInPool(0) {
240 ArgsUnion PVal(Parm);
241 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
242 new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
243 new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
244 new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
245 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
248 /// Constructor for type_tag_for_datatype attribute.
249 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
250 IdentifierInfo *scopeName, SourceLocation scopeLoc,
251 IdentifierLoc *ArgKind, ParsedType matchingCType,
252 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
253 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
254 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
255 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
256 IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
257 NextInPosition(NULL), NextInPool(NULL) {
258 ArgsUnion PVal(ArgKind);
259 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
260 TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
261 new (&ExtraData.MatchingCType) ParsedType(matchingCType);
262 ExtraData.LayoutCompatible = layoutCompatible;
263 ExtraData.MustBeNull = mustBeNull;
264 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
267 /// Constructor for attributes with a single type argument.
268 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
269 IdentifierInfo *scopeName, SourceLocation scopeLoc,
270 ParsedType typeArg, Syntax syntaxUsed)
271 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
272 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
273 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
274 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
275 NextInPosition(0), NextInPool(0) {
276 new (&getTypeBuffer()) ParsedType(typeArg);
277 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
280 /// Constructor for microsoft __declspec(property) attribute.
281 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
282 IdentifierInfo *scopeName, SourceLocation scopeLoc,
283 IdentifierInfo *getterId, IdentifierInfo *setterId,
285 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
286 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
287 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
288 IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
289 NextInPosition(0), NextInPool(0) {
290 new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
291 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
294 friend class AttributePool;
295 friend class AttributeFactory;
299 #define PARSED_ATTR(NAME) AT_##NAME,
300 #include "clang/Sema/AttrParsedAttrList.inc"
306 IdentifierInfo *getName() const { return AttrName; }
307 SourceLocation getLoc() const { return AttrRange.getBegin(); }
308 SourceRange getRange() const { return AttrRange; }
310 bool hasScope() const { return ScopeName; }
311 IdentifierInfo *getScopeName() const { return ScopeName; }
312 SourceLocation getScopeLoc() const { return ScopeLoc; }
314 bool hasParsedType() const { return HasParsedType; }
316 /// Is this the Microsoft __declspec(property) attribute?
317 bool isDeclspecPropertyAttribute() const {
321 bool isAlignasAttribute() const {
322 // FIXME: Use a better mechanism to determine this.
323 return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword;
326 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
327 bool isCXX11Attribute() const {
328 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
330 bool isKeywordAttribute() const { return SyntaxUsed == AS_Keyword; }
332 bool isInvalid() const { return Invalid; }
333 void setInvalid(bool b = true) const { Invalid = b; }
335 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
336 void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
338 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
339 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
341 Kind getKind() const { return Kind(AttrKind); }
342 static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
345 AttributeList *getNext() const { return NextInPosition; }
346 void setNext(AttributeList *N) { NextInPosition = N; }
348 /// getNumArgs - Return the number of actual arguments to this attribute.
349 unsigned getNumArgs() const { return NumArgs; }
351 /// getArg - Return the specified argument.
352 ArgsUnion getArg(unsigned Arg) const {
353 assert(Arg < NumArgs && "Arg access out of range!");
354 return getArgsBuffer()[Arg];
357 bool isArgExpr(unsigned Arg) const {
358 return Arg < NumArgs && getArg(Arg).is<Expr*>();
360 Expr *getArgAsExpr(unsigned Arg) const {
361 return getArg(Arg).get<Expr*>();
364 bool isArgIdent(unsigned Arg) const {
365 return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
367 IdentifierLoc *getArgAsIdent(unsigned Arg) const {
368 return getArg(Arg).get<IdentifierLoc*>();
375 arg_iterator(ArgsUnion const *x, unsigned idx) : X(x), Idx(idx) {}
377 arg_iterator& operator++() {
382 bool operator==(const arg_iterator& I) const {
384 "compared arg_iterators are for different argument lists");
388 bool operator!=(const arg_iterator& I) const {
389 return !operator==(I);
392 ArgsUnion operator*() const {
396 unsigned getArgNum() const {
401 arg_iterator arg_begin() const {
402 return arg_iterator(getArgsBuffer(), 0);
405 arg_iterator arg_end() const {
406 return arg_iterator(getArgsBuffer(), NumArgs);
409 const AvailabilityChange &getAvailabilityIntroduced() const {
410 assert(getKind() == AT_Availability && "Not an availability attribute");
411 return getAvailabilitySlot(IntroducedSlot);
414 const AvailabilityChange &getAvailabilityDeprecated() const {
415 assert(getKind() == AT_Availability && "Not an availability attribute");
416 return getAvailabilitySlot(DeprecatedSlot);
419 const AvailabilityChange &getAvailabilityObsoleted() const {
420 assert(getKind() == AT_Availability && "Not an availability attribute");
421 return getAvailabilitySlot(ObsoletedSlot);
424 SourceLocation getUnavailableLoc() const {
425 assert(getKind() == AT_Availability && "Not an availability attribute");
426 return UnavailableLoc;
429 const Expr * getMessageExpr() const {
430 assert(getKind() == AT_Availability && "Not an availability attribute");
434 const ParsedType &getMatchingCType() const {
435 assert(getKind() == AT_TypeTagForDatatype &&
436 "Not a type_tag_for_datatype attribute");
437 return *getTypeTagForDatatypeDataSlot().MatchingCType;
440 bool getLayoutCompatible() const {
441 assert(getKind() == AT_TypeTagForDatatype &&
442 "Not a type_tag_for_datatype attribute");
443 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
446 bool getMustBeNull() const {
447 assert(getKind() == AT_TypeTagForDatatype &&
448 "Not a type_tag_for_datatype attribute");
449 return getTypeTagForDatatypeDataSlot().MustBeNull;
452 const ParsedType &getTypeArg() const {
453 assert(HasParsedType && "Not a type attribute");
454 return getTypeBuffer();
457 const PropertyData &getPropertyData() const {
458 assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
459 return getPropertyDataBuffer();
462 /// \brief Get an index into the attribute spelling list
463 /// defined in Attr.td. This index is used by an attribute
464 /// to pretty print itself.
465 unsigned getAttributeSpellingListIndex() const;
467 bool hasCustomParsing() const;
468 unsigned getMinArgs() const;
469 unsigned getMaxArgs() 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(0) {}
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 *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
611 SourceLocation TokLoc, int Arg);
613 AttributeList *createTypeTagForDatatype(
614 IdentifierInfo *attrName, SourceRange attrRange,
615 IdentifierInfo *scopeName, SourceLocation scopeLoc,
616 IdentifierLoc *argumentKind, ParsedType matchingCType,
617 bool layoutCompatible, bool mustBeNull,
618 AttributeList::Syntax syntax) {
619 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
620 return add(new (memory) AttributeList(attrName, attrRange,
622 argumentKind, matchingCType,
623 layoutCompatible, mustBeNull,
627 AttributeList *createTypeAttribute(
628 IdentifierInfo *attrName, SourceRange attrRange,
629 IdentifierInfo *scopeName, SourceLocation scopeLoc,
630 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
631 void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
632 return add(new (memory) AttributeList(attrName, attrRange,
634 typeArg, syntaxUsed));
637 AttributeList *createPropertyAttribute(
638 IdentifierInfo *attrName, SourceRange attrRange,
639 IdentifierInfo *scopeName, SourceLocation scopeLoc,
640 IdentifierInfo *getterId, IdentifierInfo *setterId,
641 AttributeList::Syntax syntaxUsed) {
642 void *memory = allocate(AttributeFactory::PropertyAllocSize);
643 return add(new (memory) AttributeList(attrName, attrRange,
650 /// addAttributeLists - Add two AttributeLists together
651 /// The right-hand list is appended to the left-hand list, if any
652 /// A pointer to the joined list is returned.
653 /// Note: the lists are not left unmodified.
654 inline AttributeList *addAttributeLists(AttributeList *Left,
655 AttributeList *Right) {
659 AttributeList *next = Left, *prev;
662 next = next->getNext();
664 prev->setNext(Right);
668 /// CXX11AttributeList - A wrapper around a C++11 attribute list.
669 /// Stores, in addition to the list proper, whether or not an actual list was
670 /// (as opposed to an empty list, which may be ill-formed in some places) and
671 /// the source range of the list.
672 struct CXX11AttributeList {
673 AttributeList *AttrList;
676 CXX11AttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
677 : AttrList(attrList), Range(range), HasAttr (hasAttr) {
679 CXX11AttributeList ()
680 : AttrList(0), Range(), HasAttr(false) {
684 /// ParsedAttributes - A collection of parsed attributes. Currently
685 /// we don't differentiate between the various attribute syntaxes,
686 /// which is basically silly.
688 /// Right now this is a very lightweight container, but the expectation
689 /// is that this will become significantly more serious.
690 class ParsedAttributes {
692 ParsedAttributes(AttributeFactory &factory)
693 : pool(factory), list(0) {
696 ParsedAttributes(ParsedAttributes &attrs)
697 : pool(attrs.pool), list(attrs.list) {
701 AttributePool &getPool() const { return pool; }
703 bool empty() const { return list == 0; }
705 void add(AttributeList *newAttr) {
707 assert(newAttr->getNext() == 0);
708 newAttr->setNext(list);
712 void addAll(AttributeList *newList) {
713 if (!newList) return;
715 AttributeList *lastInNewList = newList;
716 while (AttributeList *next = lastInNewList->getNext())
717 lastInNewList = next;
719 lastInNewList->setNext(list);
723 void set(AttributeList *newList) {
727 void takeAllFrom(ParsedAttributes &attrs) {
730 pool.takeAllFrom(attrs.pool);
733 void clear() { list = 0; pool.clear(); }
734 AttributeList *getList() const { return list; }
736 /// Returns a reference to the attribute list. Try not to introduce
737 /// dependencies on this method, it may not be long-lived.
738 AttributeList *&getListRef() { return list; }
740 /// Add attribute with expression arguments.
741 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
742 IdentifierInfo *scopeName, SourceLocation scopeLoc,
743 ArgsUnion *args, unsigned numArgs,
744 AttributeList::Syntax syntax,
745 SourceLocation ellipsisLoc = SourceLocation()) {
746 AttributeList *attr =
747 pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
748 syntax, ellipsisLoc);
753 /// Add availability attribute.
754 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
755 IdentifierInfo *scopeName, SourceLocation scopeLoc,
756 IdentifierLoc *Param,
757 const AvailabilityChange &introduced,
758 const AvailabilityChange &deprecated,
759 const AvailabilityChange &obsoleted,
760 SourceLocation unavailable,
761 const Expr *MessageExpr,
762 AttributeList::Syntax syntax) {
763 AttributeList *attr =
764 pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
765 deprecated, obsoleted, unavailable, MessageExpr, syntax);
770 /// Add type_tag_for_datatype attribute.
771 AttributeList *addNewTypeTagForDatatype(
772 IdentifierInfo *attrName, SourceRange attrRange,
773 IdentifierInfo *scopeName, SourceLocation scopeLoc,
774 IdentifierLoc *argumentKind, ParsedType matchingCType,
775 bool layoutCompatible, bool mustBeNull,
776 AttributeList::Syntax syntax) {
777 AttributeList *attr =
778 pool.createTypeTagForDatatype(attrName, attrRange,
780 argumentKind, matchingCType,
781 layoutCompatible, mustBeNull, syntax);
786 /// Add an attribute with a single type argument.
788 addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
789 IdentifierInfo *scopeName, SourceLocation scopeLoc,
790 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
791 AttributeList *attr =
792 pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
793 typeArg, syntaxUsed);
798 /// Add microsoft __delspec(property) attribute.
800 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
801 IdentifierInfo *scopeName, SourceLocation scopeLoc,
802 IdentifierInfo *getterId, IdentifierInfo *setterId,
803 AttributeList::Syntax syntaxUsed) {
804 AttributeList *attr =
805 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
806 getterId, setterId, syntaxUsed);
811 AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name,
812 SourceLocation loc, int arg) {
813 AttributeList *attr =
814 pool.createIntegerAttribute(C, name, loc, arg);
821 mutable AttributePool pool;
825 /// These constants match the enumerated choices of
826 /// err_attribute_argument_n_type and err_attribute_argument_type.
827 enum AttributeArgumentNType {
828 AANT_ArgumentIntOrBool,
829 AANT_ArgumentIntegerConstant,
831 AANT_ArgumentIdentifier
834 } // end namespace clang