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/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 : 16;
99 /// Corresponds to the Syntax enum.
100 unsigned SyntaxUsed : 2;
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 &) LLVM_DELETED_FUNCTION;
208 void operator=(const AttributeList &) LLVM_DELETED_FUNCTION;
209 void operator delete(void *) LLVM_DELETED_FUNCTION;
210 ~AttributeList() LLVM_DELETED_FUNCTION;
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 diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
459 bool diagnoseLangOpts(class Sema &S) const;
460 bool existsInTarget(const llvm::Triple &T) const;
461 bool isKnownToGCC() const;
463 /// \brief If the parsed attribute has a semantic equivalent, and it would
464 /// have a semantic Spelling enumeration (due to having semantically-distinct
465 /// spelling variations), return the value of that semantic spelling. If the
466 /// parsed attribute does not have a semantic equivalent, or would not have
467 /// a Spelling enumeration, the value UINT_MAX is returned.
468 unsigned getSemanticSpelling() const;
471 /// A factory, from which one makes pools, from which one creates
472 /// individual attributes which are deallocated with the pool.
474 /// Note that it's tolerably cheap to create and destroy one of
475 /// these as long as you don't actually allocate anything in it.
476 class AttributeFactory {
479 /// The required allocation size of an availability attribute,
480 /// which we want to ensure is a multiple of sizeof(void*).
481 AvailabilityAllocSize =
482 sizeof(AttributeList)
483 + ((3 * sizeof(AvailabilityChange) + sizeof(void*) +
484 sizeof(ArgsUnion) - 1)
485 / sizeof(void*) * sizeof(void*)),
486 TypeTagForDatatypeAllocSize =
487 sizeof(AttributeList)
488 + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
489 sizeof(ArgsUnion) - 1)
490 / sizeof(void*) * sizeof(void*),
492 sizeof(AttributeList)
493 + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
494 / sizeof(void*) * sizeof(void*)
499 /// The number of free lists we want to be sure to support
500 /// inline. This is just enough that availability attributes
501 /// don't surpass it. It's actually very unlikely we'll see an
502 /// attribute that needs more than that; on x86-64 you'd need 10
503 /// expression arguments, and on i386 you'd need 19.
504 InlineFreeListsCapacity =
505 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
508 llvm::BumpPtrAllocator Alloc;
510 /// Free lists. The index is determined by the following formula:
511 /// (size - sizeof(AttributeList)) / sizeof(void*)
512 SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
514 // The following are the private interface used by AttributePool.
515 friend class AttributePool;
517 /// Allocate an attribute of the given size.
518 void *allocate(size_t size);
520 /// Reclaim all the attributes in the given pool chain, which is
521 /// non-empty. Note that the current implementation is safe
522 /// against reclaiming things which were not actually allocated
523 /// with the allocator, although of course it's important to make
524 /// sure that their allocator lives at least as long as this one.
525 void reclaimPool(AttributeList *head);
532 class AttributePool {
533 AttributeFactory &Factory;
536 void *allocate(size_t size) {
537 return Factory.allocate(size);
540 AttributeList *add(AttributeList *attr) {
541 // We don't care about the order of the pool.
542 attr->NextInPool = Head;
547 void takePool(AttributeList *pool);
550 /// Create a new pool for a factory.
551 AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
553 /// Move the given pool's allocations to this pool.
554 AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) {
558 AttributeFactory &getFactory() const { return Factory; }
562 Factory.reclaimPool(Head);
567 /// Take the given pool's allocations and add them to this pool.
568 void takeAllFrom(AttributePool &pool) {
576 if (Head) Factory.reclaimPool(Head);
579 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
580 IdentifierInfo *scopeName, SourceLocation scopeLoc,
581 ArgsUnion *args, unsigned numArgs,
582 AttributeList::Syntax syntax,
583 SourceLocation ellipsisLoc = SourceLocation()) {
584 void *memory = allocate(sizeof(AttributeList)
585 + numArgs * sizeof(ArgsUnion));
586 return add(new (memory) AttributeList(attrName, attrRange,
588 args, numArgs, syntax,
592 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
593 IdentifierInfo *scopeName, SourceLocation scopeLoc,
594 IdentifierLoc *Param,
595 const AvailabilityChange &introduced,
596 const AvailabilityChange &deprecated,
597 const AvailabilityChange &obsoleted,
598 SourceLocation unavailable,
599 const Expr *MessageExpr,
600 AttributeList::Syntax syntax) {
601 void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
602 return add(new (memory) AttributeList(attrName, attrRange,
604 Param, introduced, deprecated,
605 obsoleted, unavailable, MessageExpr,
609 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
610 IdentifierInfo *scopeName, SourceLocation scopeLoc,
611 IdentifierLoc *Param1,
612 IdentifierLoc *Param2,
613 IdentifierLoc *Param3,
614 AttributeList::Syntax syntax) {
615 size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
616 void *memory = allocate(size);
617 return add(new (memory) AttributeList(attrName, attrRange,
619 Param1, Param2, Param3,
623 AttributeList *createTypeTagForDatatype(
624 IdentifierInfo *attrName, SourceRange attrRange,
625 IdentifierInfo *scopeName, SourceLocation scopeLoc,
626 IdentifierLoc *argumentKind, ParsedType matchingCType,
627 bool layoutCompatible, bool mustBeNull,
628 AttributeList::Syntax syntax) {
629 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
630 return add(new (memory) AttributeList(attrName, attrRange,
632 argumentKind, matchingCType,
633 layoutCompatible, mustBeNull,
637 AttributeList *createTypeAttribute(
638 IdentifierInfo *attrName, SourceRange attrRange,
639 IdentifierInfo *scopeName, SourceLocation scopeLoc,
640 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
641 void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
642 return add(new (memory) AttributeList(attrName, attrRange,
644 typeArg, syntaxUsed));
647 AttributeList *createPropertyAttribute(
648 IdentifierInfo *attrName, SourceRange attrRange,
649 IdentifierInfo *scopeName, SourceLocation scopeLoc,
650 IdentifierInfo *getterId, IdentifierInfo *setterId,
651 AttributeList::Syntax syntaxUsed) {
652 void *memory = allocate(AttributeFactory::PropertyAllocSize);
653 return add(new (memory) AttributeList(attrName, attrRange,
660 /// ParsedAttributes - A collection of parsed attributes. Currently
661 /// we don't differentiate between the various attribute syntaxes,
662 /// which is basically silly.
664 /// Right now this is a very lightweight container, but the expectation
665 /// is that this will become significantly more serious.
666 class ParsedAttributes {
668 ParsedAttributes(AttributeFactory &factory)
669 : pool(factory), list(nullptr) {
672 ParsedAttributes(const ParsedAttributes &) LLVM_DELETED_FUNCTION;
674 AttributePool &getPool() const { return pool; }
676 bool empty() const { return list == nullptr; }
678 void add(AttributeList *newAttr) {
680 assert(newAttr->getNext() == nullptr);
681 newAttr->setNext(list);
685 void addAll(AttributeList *newList) {
686 if (!newList) return;
688 AttributeList *lastInNewList = newList;
689 while (AttributeList *next = lastInNewList->getNext())
690 lastInNewList = next;
692 lastInNewList->setNext(list);
696 void set(AttributeList *newList) {
700 void takeAllFrom(ParsedAttributes &attrs) {
702 attrs.list = nullptr;
703 pool.takeAllFrom(attrs.pool);
706 void clear() { list = nullptr; pool.clear(); }
707 AttributeList *getList() const { return list; }
709 /// Returns a reference to the attribute list. Try not to introduce
710 /// dependencies on this method, it may not be long-lived.
711 AttributeList *&getListRef() { return list; }
713 /// Add attribute with expression arguments.
714 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
715 IdentifierInfo *scopeName, SourceLocation scopeLoc,
716 ArgsUnion *args, unsigned numArgs,
717 AttributeList::Syntax syntax,
718 SourceLocation ellipsisLoc = SourceLocation()) {
719 AttributeList *attr =
720 pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
721 syntax, ellipsisLoc);
726 /// Add availability attribute.
727 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
728 IdentifierInfo *scopeName, SourceLocation scopeLoc,
729 IdentifierLoc *Param,
730 const AvailabilityChange &introduced,
731 const AvailabilityChange &deprecated,
732 const AvailabilityChange &obsoleted,
733 SourceLocation unavailable,
734 const Expr *MessageExpr,
735 AttributeList::Syntax syntax) {
736 AttributeList *attr =
737 pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
738 deprecated, obsoleted, unavailable, MessageExpr, syntax);
743 /// Add objc_bridge_related attribute.
744 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
745 IdentifierInfo *scopeName, SourceLocation scopeLoc,
746 IdentifierLoc *Param1,
747 IdentifierLoc *Param2,
748 IdentifierLoc *Param3,
749 AttributeList::Syntax syntax) {
750 AttributeList *attr =
751 pool.create(attrName, attrRange, scopeName, scopeLoc,
752 Param1, Param2, Param3, syntax);
757 /// Add type_tag_for_datatype attribute.
758 AttributeList *addNewTypeTagForDatatype(
759 IdentifierInfo *attrName, SourceRange attrRange,
760 IdentifierInfo *scopeName, SourceLocation scopeLoc,
761 IdentifierLoc *argumentKind, ParsedType matchingCType,
762 bool layoutCompatible, bool mustBeNull,
763 AttributeList::Syntax syntax) {
764 AttributeList *attr =
765 pool.createTypeTagForDatatype(attrName, attrRange,
767 argumentKind, matchingCType,
768 layoutCompatible, mustBeNull, syntax);
773 /// Add an attribute with a single type argument.
775 addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
776 IdentifierInfo *scopeName, SourceLocation scopeLoc,
777 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
778 AttributeList *attr =
779 pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
780 typeArg, syntaxUsed);
785 /// Add microsoft __delspec(property) attribute.
787 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
788 IdentifierInfo *scopeName, SourceLocation scopeLoc,
789 IdentifierInfo *getterId, IdentifierInfo *setterId,
790 AttributeList::Syntax syntaxUsed) {
791 AttributeList *attr =
792 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
793 getterId, setterId, syntaxUsed);
799 mutable AttributePool pool;
803 /// These constants match the enumerated choices of
804 /// err_attribute_argument_n_type and err_attribute_argument_type.
805 enum AttributeArgumentNType {
806 AANT_ArgumentIntOrBool,
807 AANT_ArgumentIntegerConstant,
809 AANT_ArgumentIdentifier
812 /// These constants match the enumerated choices of
813 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
814 enum AttributeDeclKind {
817 ExpectedVariableOrFunction,
818 ExpectedFunctionOrMethod,
820 ExpectedFunctionMethodOrBlock,
821 ExpectedFunctionMethodOrClass,
822 ExpectedFunctionMethodOrParameter,
826 ExpectedVariableFunctionOrLabel,
827 ExpectedFieldOrGlobalVar,
829 ExpectedVariableFunctionOrTag,
831 ExpectedVariableOrField,
832 ExpectedVariableFieldOrTag,
833 ExpectedTypeOrNamespace,
834 ExpectedObjectiveCInterface,
835 ExpectedMethodOrProperty,
836 ExpectedStructOrUnion,
837 ExpectedStructOrUnionOrClass,
839 ExpectedObjCInstanceMethod,
840 ExpectedObjCInterfaceDeclInitMethod,
841 ExpectedFunctionVariableOrClass,
842 ExpectedObjectiveCProtocol,
843 ExpectedFunctionGlobalVarMethodOrProperty,
844 ExpectedStructOrTypedef,
845 ExpectedObjectiveCInterfaceOrProtocol
848 } // end namespace clang