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/Support/Allocator.h"
30 /// \brief Represents information about a change in availability for
31 /// an entity, which is part of the encoding of the 'availability'
33 struct AvailabilityChange {
34 /// \brief The location of the keyword indicating the kind of change.
35 SourceLocation KeywordLoc;
37 /// \brief The version number at which the change occurred.
40 /// \brief The source range covering the version number.
41 SourceRange VersionRange;
43 /// \brief Determine whether this availability change is valid.
44 bool isValid() const { return !Version.empty(); }
47 /// AttributeList - Represents a syntactic attribute.
49 /// For a GNU attribute, there are four forms of this construct:
51 /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
52 /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
53 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
54 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
56 class AttributeList { // TODO: This should really be called ParsedAttribute
58 /// The style used to specify an attribute.
60 /// __attribute__((...))
66 /// __ptr16, alignas(...), etc.
70 IdentifierInfo *AttrName;
71 IdentifierInfo *ScopeName;
72 IdentifierInfo *ParmName;
73 SourceRange AttrRange;
74 SourceLocation ScopeLoc;
75 SourceLocation ParmLoc;
76 SourceLocation EllipsisLoc;
78 /// The number of expression arguments this attribute has.
79 /// The expressions themselves are stored after the object.
80 unsigned NumArgs : 16;
82 /// Corresponds to the Syntax enum.
83 unsigned SyntaxUsed : 2;
85 /// True if already diagnosed as invalid.
86 mutable unsigned Invalid : 1;
88 /// True if this attribute was used as a type attribute.
89 mutable unsigned UsedAsTypeAttr : 1;
91 /// True if this has the extra information associated with an
92 /// availability attribute.
93 unsigned IsAvailability : 1;
95 /// True if this has extra information associated with a
96 /// type_tag_for_datatype attribute.
97 unsigned IsTypeTagForDatatype : 1;
99 /// True if this has extra information associated with a
100 /// Microsoft __delcspec(property) attribute.
101 unsigned IsProperty : 1;
103 unsigned AttrKind : 8;
105 /// \brief The location of the 'unavailable' keyword in an
106 /// availability attribute.
107 SourceLocation UnavailableLoc;
109 const Expr *MessageExpr;
111 /// The next attribute in the current position.
112 AttributeList *NextInPosition;
114 /// The next attribute allocated in the current Pool.
115 AttributeList *NextInPool;
117 Expr **getArgsBuffer() {
118 return reinterpret_cast<Expr**>(this+1);
120 Expr * const *getArgsBuffer() const {
121 return reinterpret_cast<Expr* const *>(this+1);
124 enum AvailabilitySlot {
125 IntroducedSlot, DeprecatedSlot, ObsoletedSlot
128 AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {
129 return reinterpret_cast<AvailabilityChange*>(this+1)[index];
131 const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const {
132 return reinterpret_cast<const AvailabilityChange*>(this+1)[index];
136 struct TypeTagForDatatypeData {
137 ParsedType *MatchingCType;
138 unsigned LayoutCompatible : 1;
139 unsigned MustBeNull : 1;
141 struct PropertyData {
142 IdentifierInfo *GetterId, *SetterId;
143 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
144 : GetterId(getterId), SetterId(setterId) {}
148 TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
149 return *reinterpret_cast<TypeTagForDatatypeData *>(this + 1);
152 const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
153 return *reinterpret_cast<const TypeTagForDatatypeData *>(this + 1);
156 ParsedType &getTypeBuffer() {
157 return *reinterpret_cast<ParsedType *>(this + 1);
160 const ParsedType &getTypeBuffer() const {
161 return *reinterpret_cast<const ParsedType *>(this + 1);
164 PropertyData &getPropertyDataBuffer() {
166 return *reinterpret_cast<PropertyData*>(this + 1);
169 const PropertyData &getPropertyDataBuffer() const {
171 return *reinterpret_cast<const PropertyData*>(this + 1);
174 AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION;
175 void operator=(const AttributeList &) LLVM_DELETED_FUNCTION;
176 void operator delete(void *) LLVM_DELETED_FUNCTION;
177 ~AttributeList() LLVM_DELETED_FUNCTION;
179 size_t allocated_size() const;
181 /// Constructor for attributes with expression arguments.
182 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
183 IdentifierInfo *scopeName, SourceLocation scopeLoc,
184 IdentifierInfo *parmName, SourceLocation parmLoc,
185 Expr **args, unsigned numArgs,
186 Syntax syntaxUsed, SourceLocation ellipsisLoc)
187 : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
188 AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
189 EllipsisLoc(ellipsisLoc), NumArgs(numArgs), SyntaxUsed(syntaxUsed),
190 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
191 IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0),
193 if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(Expr*));
194 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
197 /// Constructor for availability attributes.
198 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
199 IdentifierInfo *scopeName, SourceLocation scopeLoc,
200 IdentifierInfo *parmName, SourceLocation parmLoc,
201 const AvailabilityChange &introduced,
202 const AvailabilityChange &deprecated,
203 const AvailabilityChange &obsoleted,
204 SourceLocation unavailable,
205 const Expr *messageExpr,
207 : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
208 AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc), EllipsisLoc(),
209 NumArgs(0), SyntaxUsed(syntaxUsed),
210 Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
211 IsTypeTagForDatatype(false), IsProperty(false),
212 UnavailableLoc(unavailable), MessageExpr(messageExpr),
213 NextInPosition(0), NextInPool(0) {
214 new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
215 new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
216 new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
217 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
220 /// Constructor for type_tag_for_datatype attribute.
221 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
222 IdentifierInfo *scopeName, SourceLocation scopeLoc,
223 IdentifierInfo *argumentKindName,
224 SourceLocation argumentKindLoc,
225 ParsedType matchingCType, bool layoutCompatible,
226 bool mustBeNull, Syntax syntaxUsed)
227 : AttrName(attrName), ScopeName(scopeName), ParmName(argumentKindName),
228 AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(argumentKindLoc),
229 EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
230 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
231 IsTypeTagForDatatype(true), IsProperty(false), NextInPosition(NULL),
233 TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
234 new (&ExtraData.MatchingCType) ParsedType(matchingCType);
235 ExtraData.LayoutCompatible = layoutCompatible;
236 ExtraData.MustBeNull = mustBeNull;
237 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
240 /// Constructor for attributes with a single type argument.
241 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
242 IdentifierInfo *scopeName, SourceLocation scopeLoc,
243 IdentifierInfo *parmName, SourceLocation parmLoc,
244 ParsedType typeArg, Syntax syntaxUsed)
245 : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
246 AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
247 EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), Invalid(false),
248 UsedAsTypeAttr(false), IsAvailability(false),
249 IsTypeTagForDatatype(false), IsProperty(false), NextInPosition(0),
251 new (&getTypeBuffer()) ParsedType(typeArg);
252 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
255 /// Constructor for microsoft __declspec(property) attribute.
256 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
257 IdentifierInfo *scopeName, SourceLocation scopeLoc,
258 IdentifierInfo *parmName, SourceLocation parmLoc,
259 IdentifierInfo *getterId, IdentifierInfo *setterId,
261 : AttrName(attrName), ScopeName(scopeName), ParmName(parmName),
262 AttrRange(attrRange), ScopeLoc(scopeLoc), ParmLoc(parmLoc),
263 SyntaxUsed(syntaxUsed),
264 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
265 IsTypeTagForDatatype(false), IsProperty(true), NextInPosition(0),
267 new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
268 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
271 friend class AttributePool;
272 friend class AttributeFactory;
276 #define PARSED_ATTR(NAME) AT_##NAME,
277 #include "clang/Sema/AttrParsedAttrList.inc"
283 IdentifierInfo *getName() const { return AttrName; }
284 SourceLocation getLoc() const { return AttrRange.getBegin(); }
285 SourceRange getRange() const { return AttrRange; }
287 bool hasScope() const { return ScopeName; }
288 IdentifierInfo *getScopeName() const { return ScopeName; }
289 SourceLocation getScopeLoc() const { return ScopeLoc; }
291 IdentifierInfo *getParameterName() const { return ParmName; }
292 SourceLocation getParameterLoc() const { return ParmLoc; }
294 /// Is this the Microsoft __declspec(property) attribute?
295 bool isDeclspecPropertyAttribute() const {
299 bool isAlignasAttribute() const {
300 // FIXME: Use a better mechanism to determine this.
301 return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword;
304 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
305 bool isCXX11Attribute() const {
306 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
308 bool isKeywordAttribute() const { return SyntaxUsed == AS_Keyword; }
310 bool isInvalid() const { return Invalid; }
311 void setInvalid(bool b = true) const { Invalid = b; }
313 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
314 void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
316 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
317 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
319 Kind getKind() const { return Kind(AttrKind); }
320 static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
323 AttributeList *getNext() const { return NextInPosition; }
324 void setNext(AttributeList *N) { NextInPosition = N; }
326 /// getNumArgs - Return the number of actual arguments to this attribute.
327 unsigned getNumArgs() const { return NumArgs; }
329 /// hasParameterOrArguments - Return true if this attribute has a parameter,
330 /// or has a non empty argument expression list.
331 bool hasParameterOrArguments() const { return ParmName || NumArgs; }
333 /// getArg - Return the specified argument.
334 Expr *getArg(unsigned Arg) const {
335 assert(Arg < NumArgs && "Arg access out of range!");
336 return getArgsBuffer()[Arg];
343 arg_iterator(Expr * const *x, unsigned idx) : X(x), Idx(idx) {}
345 arg_iterator& operator++() {
350 bool operator==(const arg_iterator& I) const {
352 "compared arg_iterators are for different argument lists");
356 bool operator!=(const arg_iterator& I) const {
357 return !operator==(I);
360 Expr* operator*() const {
364 unsigned getArgNum() const {
369 arg_iterator arg_begin() const {
370 return arg_iterator(getArgsBuffer(), 0);
373 arg_iterator arg_end() const {
374 return arg_iterator(getArgsBuffer(), NumArgs);
377 const AvailabilityChange &getAvailabilityIntroduced() const {
378 assert(getKind() == AT_Availability && "Not an availability attribute");
379 return getAvailabilitySlot(IntroducedSlot);
382 const AvailabilityChange &getAvailabilityDeprecated() const {
383 assert(getKind() == AT_Availability && "Not an availability attribute");
384 return getAvailabilitySlot(DeprecatedSlot);
387 const AvailabilityChange &getAvailabilityObsoleted() const {
388 assert(getKind() == AT_Availability && "Not an availability attribute");
389 return getAvailabilitySlot(ObsoletedSlot);
392 SourceLocation getUnavailableLoc() const {
393 assert(getKind() == AT_Availability && "Not an availability attribute");
394 return UnavailableLoc;
397 const Expr * getMessageExpr() const {
398 assert(getKind() == AT_Availability && "Not an availability attribute");
402 const ParsedType &getMatchingCType() const {
403 assert(getKind() == AT_TypeTagForDatatype &&
404 "Not a type_tag_for_datatype attribute");
405 return *getTypeTagForDatatypeDataSlot().MatchingCType;
408 bool getLayoutCompatible() const {
409 assert(getKind() == AT_TypeTagForDatatype &&
410 "Not a type_tag_for_datatype attribute");
411 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
414 bool getMustBeNull() const {
415 assert(getKind() == AT_TypeTagForDatatype &&
416 "Not a type_tag_for_datatype attribute");
417 return getTypeTagForDatatypeDataSlot().MustBeNull;
420 const ParsedType &getTypeArg() const {
421 assert(getKind() == AT_VecTypeHint && "Not a type attribute");
422 return getTypeBuffer();
425 const PropertyData &getPropertyData() const {
426 assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
427 return getPropertyDataBuffer();
430 /// \brief Get an index into the attribute spelling list
431 /// defined in Attr.td. This index is used by an attribute
432 /// to pretty print itself.
433 unsigned getAttributeSpellingListIndex() const;
436 /// A factory, from which one makes pools, from which one creates
437 /// individual attributes which are deallocated with the pool.
439 /// Note that it's tolerably cheap to create and destroy one of
440 /// these as long as you don't actually allocate anything in it.
441 class AttributeFactory {
444 /// The required allocation size of an availability attribute,
445 /// which we want to ensure is a multiple of sizeof(void*).
446 AvailabilityAllocSize =
447 sizeof(AttributeList)
448 + ((3 * sizeof(AvailabilityChange) + sizeof(void*) - 1)
449 / sizeof(void*) * sizeof(void*)),
450 TypeTagForDatatypeAllocSize =
451 sizeof(AttributeList)
452 + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) - 1)
453 / sizeof(void*) * sizeof(void*),
455 sizeof(AttributeList)
456 + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
457 / sizeof(void*) * sizeof(void*)
462 /// The number of free lists we want to be sure to support
463 /// inline. This is just enough that availability attributes
464 /// don't surpass it. It's actually very unlikely we'll see an
465 /// attribute that needs more than that; on x86-64 you'd need 10
466 /// expression arguments, and on i386 you'd need 19.
467 InlineFreeListsCapacity =
468 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
471 llvm::BumpPtrAllocator Alloc;
473 /// Free lists. The index is determined by the following formula:
474 /// (size - sizeof(AttributeList)) / sizeof(void*)
475 SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
477 // The following are the private interface used by AttributePool.
478 friend class AttributePool;
480 /// Allocate an attribute of the given size.
481 void *allocate(size_t size);
483 /// Reclaim all the attributes in the given pool chain, which is
484 /// non-empty. Note that the current implementation is safe
485 /// against reclaiming things which were not actually allocated
486 /// with the allocator, although of course it's important to make
487 /// sure that their allocator lives at least as long as this one.
488 void reclaimPool(AttributeList *head);
495 class AttributePool {
496 AttributeFactory &Factory;
499 void *allocate(size_t size) {
500 return Factory.allocate(size);
503 AttributeList *add(AttributeList *attr) {
504 // We don't care about the order of the pool.
505 attr->NextInPool = Head;
510 void takePool(AttributeList *pool);
513 /// Create a new pool for a factory.
514 AttributePool(AttributeFactory &factory) : Factory(factory), Head(0) {}
516 /// Move the given pool's allocations to this pool.
517 AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) {
521 AttributeFactory &getFactory() const { return Factory; }
525 Factory.reclaimPool(Head);
530 /// Take the given pool's allocations and add them to this pool.
531 void takeAllFrom(AttributePool &pool) {
539 if (Head) Factory.reclaimPool(Head);
542 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
543 IdentifierInfo *scopeName, SourceLocation scopeLoc,
544 IdentifierInfo *parmName, SourceLocation parmLoc,
545 Expr **args, unsigned numArgs,
546 AttributeList::Syntax syntax,
547 SourceLocation ellipsisLoc = SourceLocation()) {
548 void *memory = allocate(sizeof(AttributeList)
549 + numArgs * sizeof(Expr*));
550 return add(new (memory) AttributeList(attrName, attrRange,
553 args, numArgs, syntax,
557 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
558 IdentifierInfo *scopeName, SourceLocation scopeLoc,
559 IdentifierInfo *parmName, SourceLocation parmLoc,
560 const AvailabilityChange &introduced,
561 const AvailabilityChange &deprecated,
562 const AvailabilityChange &obsoleted,
563 SourceLocation unavailable,
564 const Expr *MessageExpr,
565 AttributeList::Syntax syntax) {
566 void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
567 return add(new (memory) AttributeList(attrName, attrRange,
570 introduced, deprecated, obsoleted,
571 unavailable, MessageExpr, syntax));
574 AttributeList *createIntegerAttribute(ASTContext &C, IdentifierInfo *Name,
575 SourceLocation TokLoc, int Arg);
577 AttributeList *createTypeTagForDatatype(
578 IdentifierInfo *attrName, SourceRange attrRange,
579 IdentifierInfo *scopeName, SourceLocation scopeLoc,
580 IdentifierInfo *argumentKindName,
581 SourceLocation argumentKindLoc,
582 ParsedType matchingCType, bool layoutCompatible,
583 bool mustBeNull, AttributeList::Syntax syntax) {
584 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
585 return add(new (memory) AttributeList(attrName, attrRange,
587 argumentKindName, argumentKindLoc,
588 matchingCType, layoutCompatible,
589 mustBeNull, syntax));
592 AttributeList *createTypeAttribute(
593 IdentifierInfo *attrName, SourceRange attrRange,
594 IdentifierInfo *scopeName, SourceLocation scopeLoc,
595 IdentifierInfo *parmName, SourceLocation parmLoc,
596 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
597 void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
598 return add(new (memory) AttributeList(attrName, attrRange,
601 typeArg, syntaxUsed));
604 AttributeList *createPropertyAttribute(
605 IdentifierInfo *attrName, SourceRange attrRange,
606 IdentifierInfo *scopeName, SourceLocation scopeLoc,
607 IdentifierInfo *parmName, SourceLocation parmLoc,
608 IdentifierInfo *getterId, IdentifierInfo *setterId,
609 AttributeList::Syntax syntaxUsed) {
610 void *memory = allocate(AttributeFactory::PropertyAllocSize);
611 return add(new (memory) AttributeList(attrName, attrRange,
619 /// addAttributeLists - Add two AttributeLists together
620 /// The right-hand list is appended to the left-hand list, if any
621 /// A pointer to the joined list is returned.
622 /// Note: the lists are not left unmodified.
623 inline AttributeList *addAttributeLists(AttributeList *Left,
624 AttributeList *Right) {
628 AttributeList *next = Left, *prev;
631 next = next->getNext();
633 prev->setNext(Right);
637 /// CXX11AttributeList - A wrapper around a C++11 attribute list.
638 /// Stores, in addition to the list proper, whether or not an actual list was
639 /// (as opposed to an empty list, which may be ill-formed in some places) and
640 /// the source range of the list.
641 struct CXX11AttributeList {
642 AttributeList *AttrList;
645 CXX11AttributeList (AttributeList *attrList, SourceRange range, bool hasAttr)
646 : AttrList(attrList), Range(range), HasAttr (hasAttr) {
648 CXX11AttributeList ()
649 : AttrList(0), Range(), HasAttr(false) {
653 /// ParsedAttributes - A collection of parsed attributes. Currently
654 /// we don't differentiate between the various attribute syntaxes,
655 /// which is basically silly.
657 /// Right now this is a very lightweight container, but the expectation
658 /// is that this will become significantly more serious.
659 class ParsedAttributes {
661 ParsedAttributes(AttributeFactory &factory)
662 : pool(factory), list(0) {
665 ParsedAttributes(ParsedAttributes &attrs)
666 : pool(attrs.pool), list(attrs.list) {
670 AttributePool &getPool() const { return pool; }
672 bool empty() const { return list == 0; }
674 void add(AttributeList *newAttr) {
676 assert(newAttr->getNext() == 0);
677 newAttr->setNext(list);
681 void addAll(AttributeList *newList) {
682 if (!newList) return;
684 AttributeList *lastInNewList = newList;
685 while (AttributeList *next = lastInNewList->getNext())
686 lastInNewList = next;
688 lastInNewList->setNext(list);
692 void set(AttributeList *newList) {
696 void takeAllFrom(ParsedAttributes &attrs) {
699 pool.takeAllFrom(attrs.pool);
702 void clear() { list = 0; pool.clear(); }
703 AttributeList *getList() const { return list; }
705 /// Returns a reference to the attribute list. Try not to introduce
706 /// dependencies on this method, it may not be long-lived.
707 AttributeList *&getListRef() { return list; }
709 /// Add attribute with expression arguments.
710 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
711 IdentifierInfo *scopeName, SourceLocation scopeLoc,
712 IdentifierInfo *parmName, SourceLocation parmLoc,
713 Expr **args, unsigned numArgs,
714 AttributeList::Syntax syntax,
715 SourceLocation ellipsisLoc = SourceLocation()) {
716 AttributeList *attr =
717 pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc,
718 args, numArgs, syntax, ellipsisLoc);
723 /// Add availability attribute.
724 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
725 IdentifierInfo *scopeName, SourceLocation scopeLoc,
726 IdentifierInfo *parmName, SourceLocation parmLoc,
727 const AvailabilityChange &introduced,
728 const AvailabilityChange &deprecated,
729 const AvailabilityChange &obsoleted,
730 SourceLocation unavailable,
731 const Expr *MessageExpr,
732 AttributeList::Syntax syntax) {
733 AttributeList *attr =
734 pool.create(attrName, attrRange, scopeName, scopeLoc, parmName, parmLoc,
735 introduced, deprecated, obsoleted, unavailable,
736 MessageExpr, syntax);
741 /// Add type_tag_for_datatype attribute.
742 AttributeList *addNewTypeTagForDatatype(
743 IdentifierInfo *attrName, SourceRange attrRange,
744 IdentifierInfo *scopeName, SourceLocation scopeLoc,
745 IdentifierInfo *argumentKindName,
746 SourceLocation argumentKindLoc,
747 ParsedType matchingCType, bool layoutCompatible,
748 bool mustBeNull, AttributeList::Syntax syntax) {
749 AttributeList *attr =
750 pool.createTypeTagForDatatype(attrName, attrRange,
752 argumentKindName, argumentKindLoc,
753 matchingCType, layoutCompatible,
759 /// Add an attribute with a single type argument.
761 addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
762 IdentifierInfo *scopeName, SourceLocation scopeLoc,
763 IdentifierInfo *parmName, SourceLocation parmLoc,
764 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
765 AttributeList *attr =
766 pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
767 parmName, parmLoc, typeArg, syntaxUsed);
772 /// Add microsoft __delspec(property) attribute.
774 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
775 IdentifierInfo *scopeName, SourceLocation scopeLoc,
776 IdentifierInfo *parmName, SourceLocation parmLoc,
777 IdentifierInfo *getterId, IdentifierInfo *setterId,
778 AttributeList::Syntax syntaxUsed) {
779 AttributeList *attr =
780 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
781 parmName, parmLoc, getterId, setterId,
787 AttributeList *addNewInteger(ASTContext &C, IdentifierInfo *name,
788 SourceLocation loc, int arg) {
789 AttributeList *attr =
790 pool.createIntegerAttribute(C, name, loc, arg);
797 mutable AttributePool pool;
801 } // end namespace clang