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.
84 /// Context-sensitive version of a keyword attribute.
85 AS_ContextSensitiveKeyword,
91 IdentifierInfo *AttrName;
92 IdentifierInfo *ScopeName;
93 SourceRange AttrRange;
94 SourceLocation ScopeLoc;
95 SourceLocation EllipsisLoc;
97 /// The number of expression arguments this attribute has.
98 /// The expressions themselves are stored after the object.
99 unsigned NumArgs : 15;
101 /// Corresponds to the Syntax enum.
102 unsigned SyntaxUsed : 3;
104 /// True if already diagnosed as invalid.
105 mutable unsigned Invalid : 1;
107 /// True if this attribute was used as a type attribute.
108 mutable unsigned UsedAsTypeAttr : 1;
110 /// True if this has the extra information associated with an
111 /// availability attribute.
112 unsigned IsAvailability : 1;
114 /// True if this has extra information associated with a
115 /// type_tag_for_datatype attribute.
116 unsigned IsTypeTagForDatatype : 1;
118 /// True if this has extra information associated with a
119 /// Microsoft __delcspec(property) attribute.
120 unsigned IsProperty : 1;
122 /// True if this has a ParsedType
123 unsigned HasParsedType : 1;
125 unsigned AttrKind : 8;
127 /// \brief The location of the 'unavailable' keyword in an
128 /// availability attribute.
129 SourceLocation UnavailableLoc;
131 const Expr *MessageExpr;
133 /// The next attribute in the current position.
134 AttributeList *NextInPosition;
136 /// The next attribute allocated in the current Pool.
137 AttributeList *NextInPool;
139 /// Arguments, if any, are stored immediately following the object.
140 ArgsUnion *getArgsBuffer() {
141 return reinterpret_cast<ArgsUnion*>(this+1);
143 ArgsUnion const *getArgsBuffer() const {
144 return reinterpret_cast<ArgsUnion const *>(this+1);
147 enum AvailabilitySlot {
148 IntroducedSlot, DeprecatedSlot, ObsoletedSlot
151 /// Availability information is stored immediately following the arguments,
152 /// if any, at the end of the object.
153 AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {
154 return reinterpret_cast<AvailabilityChange*>(getArgsBuffer()
157 const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const {
158 return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer()
163 struct TypeTagForDatatypeData {
164 ParsedType *MatchingCType;
165 unsigned LayoutCompatible : 1;
166 unsigned MustBeNull : 1;
168 struct PropertyData {
169 IdentifierInfo *GetterId, *SetterId;
170 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
171 : GetterId(getterId), SetterId(setterId) {}
175 /// Type tag information is stored immediately following the arguments, if
176 /// any, at the end of the object. They are mutually exlusive with
177 /// availability slots.
178 TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
179 return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
182 const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
183 return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
187 /// The type buffer immediately follows the object and are mutually exclusive
189 ParsedType &getTypeBuffer() {
190 return *reinterpret_cast<ParsedType *>(this + 1);
193 const ParsedType &getTypeBuffer() const {
194 return *reinterpret_cast<const ParsedType *>(this + 1);
197 /// The property data immediately follows the object is is mutually exclusive
199 PropertyData &getPropertyDataBuffer() {
201 return *reinterpret_cast<PropertyData*>(this + 1);
204 const PropertyData &getPropertyDataBuffer() const {
206 return *reinterpret_cast<const PropertyData*>(this + 1);
209 AttributeList(const AttributeList &) = delete;
210 void operator=(const AttributeList &) = delete;
211 void operator delete(void *) = delete;
212 ~AttributeList() = delete;
214 size_t allocated_size() const;
216 /// Constructor for attributes with expression arguments.
217 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
218 IdentifierInfo *scopeName, SourceLocation scopeLoc,
219 ArgsUnion *args, unsigned numArgs,
220 Syntax syntaxUsed, SourceLocation ellipsisLoc)
221 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
222 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
223 SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
224 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
225 HasParsedType(false), NextInPosition(nullptr), NextInPool(nullptr) {
226 if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
227 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
230 /// Constructor for availability attributes.
231 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
232 IdentifierInfo *scopeName, SourceLocation scopeLoc,
233 IdentifierLoc *Parm, const AvailabilityChange &introduced,
234 const AvailabilityChange &deprecated,
235 const AvailabilityChange &obsoleted,
236 SourceLocation unavailable,
237 const Expr *messageExpr,
239 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
240 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
241 Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
242 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
243 UnavailableLoc(unavailable), MessageExpr(messageExpr),
244 NextInPosition(nullptr), NextInPool(nullptr) {
245 ArgsUnion PVal(Parm);
246 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
247 new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
248 new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
249 new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
250 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
253 /// Constructor for objc_bridge_related attributes.
254 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
255 IdentifierInfo *scopeName, SourceLocation scopeLoc,
256 IdentifierLoc *Parm1,
257 IdentifierLoc *Parm2,
258 IdentifierLoc *Parm3,
260 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
261 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
262 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
263 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
264 NextInPosition(nullptr), NextInPool(nullptr) {
266 Args.push_back(Parm1);
267 Args.push_back(Parm2);
268 Args.push_back(Parm3);
269 memcpy(getArgsBuffer(), &Args[0], 3 * sizeof(ArgsUnion));
270 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
273 /// Constructor for type_tag_for_datatype attribute.
274 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
275 IdentifierInfo *scopeName, SourceLocation scopeLoc,
276 IdentifierLoc *ArgKind, ParsedType matchingCType,
277 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
278 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
279 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
280 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
281 IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
282 NextInPosition(nullptr), NextInPool(nullptr) {
283 ArgsUnion PVal(ArgKind);
284 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
285 TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
286 new (&ExtraData.MatchingCType) ParsedType(matchingCType);
287 ExtraData.LayoutCompatible = layoutCompatible;
288 ExtraData.MustBeNull = mustBeNull;
289 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
292 /// Constructor for attributes with a single type argument.
293 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
294 IdentifierInfo *scopeName, SourceLocation scopeLoc,
295 ParsedType typeArg, Syntax syntaxUsed)
296 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
297 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
298 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
299 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
300 NextInPosition(nullptr), NextInPool(nullptr) {
301 new (&getTypeBuffer()) ParsedType(typeArg);
302 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
305 /// Constructor for microsoft __declspec(property) attribute.
306 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
307 IdentifierInfo *scopeName, SourceLocation scopeLoc,
308 IdentifierInfo *getterId, IdentifierInfo *setterId,
310 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
311 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
312 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
313 IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
314 NextInPosition(nullptr), NextInPool(nullptr) {
315 new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
316 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
319 friend class AttributePool;
320 friend class AttributeFactory;
324 #define PARSED_ATTR(NAME) AT_##NAME,
325 #include "clang/Sema/AttrParsedAttrList.inc"
331 IdentifierInfo *getName() const { return AttrName; }
332 SourceLocation getLoc() const { return AttrRange.getBegin(); }
333 SourceRange getRange() const { return AttrRange; }
335 bool hasScope() const { return ScopeName; }
336 IdentifierInfo *getScopeName() const { return ScopeName; }
337 SourceLocation getScopeLoc() const { return ScopeLoc; }
339 bool hasParsedType() const { return HasParsedType; }
341 /// Is this the Microsoft __declspec(property) attribute?
342 bool isDeclspecPropertyAttribute() const {
346 bool isAlignasAttribute() const {
347 // FIXME: Use a better mechanism to determine this.
348 return getKind() == AT_Aligned && isKeywordAttribute();
351 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
352 bool isCXX11Attribute() const {
353 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
355 bool isKeywordAttribute() const {
356 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
359 bool isContextSensitiveKeywordAttribute() const {
360 return SyntaxUsed == AS_ContextSensitiveKeyword;
363 bool isInvalid() const { return Invalid; }
364 void setInvalid(bool b = true) const { Invalid = b; }
366 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
367 void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
369 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
370 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
372 Kind getKind() const { return Kind(AttrKind); }
373 static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
376 AttributeList *getNext() const { return NextInPosition; }
377 void setNext(AttributeList *N) { NextInPosition = N; }
379 /// getNumArgs - Return the number of actual arguments to this attribute.
380 unsigned getNumArgs() const { return NumArgs; }
382 /// getArg - Return the specified argument.
383 ArgsUnion getArg(unsigned Arg) const {
384 assert(Arg < NumArgs && "Arg access out of range!");
385 return getArgsBuffer()[Arg];
388 bool isArgExpr(unsigned Arg) const {
389 return Arg < NumArgs && getArg(Arg).is<Expr*>();
391 Expr *getArgAsExpr(unsigned Arg) const {
392 return getArg(Arg).get<Expr*>();
395 bool isArgIdent(unsigned Arg) const {
396 return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
398 IdentifierLoc *getArgAsIdent(unsigned Arg) const {
399 return getArg(Arg).get<IdentifierLoc*>();
402 const AvailabilityChange &getAvailabilityIntroduced() const {
403 assert(getKind() == AT_Availability && "Not an availability attribute");
404 return getAvailabilitySlot(IntroducedSlot);
407 const AvailabilityChange &getAvailabilityDeprecated() const {
408 assert(getKind() == AT_Availability && "Not an availability attribute");
409 return getAvailabilitySlot(DeprecatedSlot);
412 const AvailabilityChange &getAvailabilityObsoleted() const {
413 assert(getKind() == AT_Availability && "Not an availability attribute");
414 return getAvailabilitySlot(ObsoletedSlot);
417 SourceLocation getUnavailableLoc() const {
418 assert(getKind() == AT_Availability && "Not an availability attribute");
419 return UnavailableLoc;
422 const Expr * getMessageExpr() const {
423 assert(getKind() == AT_Availability && "Not an availability attribute");
427 const ParsedType &getMatchingCType() const {
428 assert(getKind() == AT_TypeTagForDatatype &&
429 "Not a type_tag_for_datatype attribute");
430 return *getTypeTagForDatatypeDataSlot().MatchingCType;
433 bool getLayoutCompatible() const {
434 assert(getKind() == AT_TypeTagForDatatype &&
435 "Not a type_tag_for_datatype attribute");
436 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
439 bool getMustBeNull() const {
440 assert(getKind() == AT_TypeTagForDatatype &&
441 "Not a type_tag_for_datatype attribute");
442 return getTypeTagForDatatypeDataSlot().MustBeNull;
445 const ParsedType &getTypeArg() const {
446 assert(HasParsedType && "Not a type attribute");
447 return getTypeBuffer();
450 const PropertyData &getPropertyData() const {
451 assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
452 return getPropertyDataBuffer();
455 /// \brief Get an index into the attribute spelling list
456 /// defined in Attr.td. This index is used by an attribute
457 /// to pretty print itself.
458 unsigned getAttributeSpellingListIndex() const;
460 bool isTargetSpecificAttr() const;
461 bool isTypeAttr() const;
463 bool hasCustomParsing() const;
464 unsigned getMinArgs() const;
465 unsigned getMaxArgs() const;
466 bool hasVariadicArg() const;
467 bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
468 bool diagnoseLangOpts(class Sema &S) const;
469 bool existsInTarget(const llvm::Triple &T) const;
470 bool isKnownToGCC() const;
472 /// \brief If the parsed attribute has a semantic equivalent, and it would
473 /// have a semantic Spelling enumeration (due to having semantically-distinct
474 /// spelling variations), return the value of that semantic spelling. If the
475 /// parsed attribute does not have a semantic equivalent, or would not have
476 /// a Spelling enumeration, the value UINT_MAX is returned.
477 unsigned getSemanticSpelling() const;
480 /// A factory, from which one makes pools, from which one creates
481 /// individual attributes which are deallocated with the pool.
483 /// Note that it's tolerably cheap to create and destroy one of
484 /// these as long as you don't actually allocate anything in it.
485 class AttributeFactory {
488 /// The required allocation size of an availability attribute,
489 /// which we want to ensure is a multiple of sizeof(void*).
490 AvailabilityAllocSize =
491 sizeof(AttributeList)
492 + ((3 * sizeof(AvailabilityChange) + sizeof(void*) +
493 sizeof(ArgsUnion) - 1)
494 / sizeof(void*) * sizeof(void*)),
495 TypeTagForDatatypeAllocSize =
496 sizeof(AttributeList)
497 + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
498 sizeof(ArgsUnion) - 1)
499 / sizeof(void*) * sizeof(void*),
501 sizeof(AttributeList)
502 + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
503 / sizeof(void*) * sizeof(void*)
508 /// The number of free lists we want to be sure to support
509 /// inline. This is just enough that availability attributes
510 /// don't surpass it. It's actually very unlikely we'll see an
511 /// attribute that needs more than that; on x86-64 you'd need 10
512 /// expression arguments, and on i386 you'd need 19.
513 InlineFreeListsCapacity =
514 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
517 llvm::BumpPtrAllocator Alloc;
519 /// Free lists. The index is determined by the following formula:
520 /// (size - sizeof(AttributeList)) / sizeof(void*)
521 SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
523 // The following are the private interface used by AttributePool.
524 friend class AttributePool;
526 /// Allocate an attribute of the given size.
527 void *allocate(size_t size);
529 /// Reclaim all the attributes in the given pool chain, which is
530 /// non-empty. Note that the current implementation is safe
531 /// against reclaiming things which were not actually allocated
532 /// with the allocator, although of course it's important to make
533 /// sure that their allocator lives at least as long as this one.
534 void reclaimPool(AttributeList *head);
541 class AttributePool {
542 AttributeFactory &Factory;
545 void *allocate(size_t size) {
546 return Factory.allocate(size);
549 AttributeList *add(AttributeList *attr) {
550 // We don't care about the order of the pool.
551 attr->NextInPool = Head;
556 void takePool(AttributeList *pool);
559 /// Create a new pool for a factory.
560 AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
562 /// Move the given pool's allocations to this pool.
563 AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) {
567 AttributeFactory &getFactory() const { return Factory; }
571 Factory.reclaimPool(Head);
576 /// Take the given pool's allocations and add them to this pool.
577 void takeAllFrom(AttributePool &pool) {
585 if (Head) Factory.reclaimPool(Head);
588 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
589 IdentifierInfo *scopeName, SourceLocation scopeLoc,
590 ArgsUnion *args, unsigned numArgs,
591 AttributeList::Syntax syntax,
592 SourceLocation ellipsisLoc = SourceLocation()) {
593 void *memory = allocate(sizeof(AttributeList)
594 + numArgs * sizeof(ArgsUnion));
595 return add(new (memory) AttributeList(attrName, attrRange,
597 args, numArgs, syntax,
601 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
602 IdentifierInfo *scopeName, SourceLocation scopeLoc,
603 IdentifierLoc *Param,
604 const AvailabilityChange &introduced,
605 const AvailabilityChange &deprecated,
606 const AvailabilityChange &obsoleted,
607 SourceLocation unavailable,
608 const Expr *MessageExpr,
609 AttributeList::Syntax syntax) {
610 void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
611 return add(new (memory) AttributeList(attrName, attrRange,
613 Param, introduced, deprecated,
614 obsoleted, unavailable, MessageExpr,
618 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
619 IdentifierInfo *scopeName, SourceLocation scopeLoc,
620 IdentifierLoc *Param1,
621 IdentifierLoc *Param2,
622 IdentifierLoc *Param3,
623 AttributeList::Syntax syntax) {
624 size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
625 void *memory = allocate(size);
626 return add(new (memory) AttributeList(attrName, attrRange,
628 Param1, Param2, Param3,
632 AttributeList *createTypeTagForDatatype(
633 IdentifierInfo *attrName, SourceRange attrRange,
634 IdentifierInfo *scopeName, SourceLocation scopeLoc,
635 IdentifierLoc *argumentKind, ParsedType matchingCType,
636 bool layoutCompatible, bool mustBeNull,
637 AttributeList::Syntax syntax) {
638 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
639 return add(new (memory) AttributeList(attrName, attrRange,
641 argumentKind, matchingCType,
642 layoutCompatible, mustBeNull,
646 AttributeList *createTypeAttribute(
647 IdentifierInfo *attrName, SourceRange attrRange,
648 IdentifierInfo *scopeName, SourceLocation scopeLoc,
649 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
650 void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
651 return add(new (memory) AttributeList(attrName, attrRange,
653 typeArg, syntaxUsed));
656 AttributeList *createPropertyAttribute(
657 IdentifierInfo *attrName, SourceRange attrRange,
658 IdentifierInfo *scopeName, SourceLocation scopeLoc,
659 IdentifierInfo *getterId, IdentifierInfo *setterId,
660 AttributeList::Syntax syntaxUsed) {
661 void *memory = allocate(AttributeFactory::PropertyAllocSize);
662 return add(new (memory) AttributeList(attrName, attrRange,
669 /// ParsedAttributes - A collection of parsed attributes. Currently
670 /// we don't differentiate between the various attribute syntaxes,
671 /// which is basically silly.
673 /// Right now this is a very lightweight container, but the expectation
674 /// is that this will become significantly more serious.
675 class ParsedAttributes {
677 ParsedAttributes(AttributeFactory &factory)
678 : pool(factory), list(nullptr) {
681 ParsedAttributes(const ParsedAttributes &) = delete;
683 AttributePool &getPool() const { return pool; }
685 bool empty() const { return list == nullptr; }
687 void add(AttributeList *newAttr) {
689 assert(newAttr->getNext() == nullptr);
690 newAttr->setNext(list);
694 void addAll(AttributeList *newList) {
695 if (!newList) return;
697 AttributeList *lastInNewList = newList;
698 while (AttributeList *next = lastInNewList->getNext())
699 lastInNewList = next;
701 lastInNewList->setNext(list);
705 void set(AttributeList *newList) {
709 void takeAllFrom(ParsedAttributes &attrs) {
711 attrs.list = nullptr;
712 pool.takeAllFrom(attrs.pool);
715 void clear() { list = nullptr; pool.clear(); }
716 AttributeList *getList() const { return list; }
718 /// Returns a reference to the attribute list. Try not to introduce
719 /// dependencies on this method, it may not be long-lived.
720 AttributeList *&getListRef() { return list; }
722 /// Add attribute with expression arguments.
723 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
724 IdentifierInfo *scopeName, SourceLocation scopeLoc,
725 ArgsUnion *args, unsigned numArgs,
726 AttributeList::Syntax syntax,
727 SourceLocation ellipsisLoc = SourceLocation()) {
728 AttributeList *attr =
729 pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
730 syntax, ellipsisLoc);
735 /// Add availability attribute.
736 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
737 IdentifierInfo *scopeName, SourceLocation scopeLoc,
738 IdentifierLoc *Param,
739 const AvailabilityChange &introduced,
740 const AvailabilityChange &deprecated,
741 const AvailabilityChange &obsoleted,
742 SourceLocation unavailable,
743 const Expr *MessageExpr,
744 AttributeList::Syntax syntax) {
745 AttributeList *attr =
746 pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
747 deprecated, obsoleted, unavailable, MessageExpr, syntax);
752 /// Add objc_bridge_related attribute.
753 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
754 IdentifierInfo *scopeName, SourceLocation scopeLoc,
755 IdentifierLoc *Param1,
756 IdentifierLoc *Param2,
757 IdentifierLoc *Param3,
758 AttributeList::Syntax syntax) {
759 AttributeList *attr =
760 pool.create(attrName, attrRange, scopeName, scopeLoc,
761 Param1, Param2, Param3, syntax);
766 /// Add type_tag_for_datatype attribute.
767 AttributeList *addNewTypeTagForDatatype(
768 IdentifierInfo *attrName, SourceRange attrRange,
769 IdentifierInfo *scopeName, SourceLocation scopeLoc,
770 IdentifierLoc *argumentKind, ParsedType matchingCType,
771 bool layoutCompatible, bool mustBeNull,
772 AttributeList::Syntax syntax) {
773 AttributeList *attr =
774 pool.createTypeTagForDatatype(attrName, attrRange,
776 argumentKind, matchingCType,
777 layoutCompatible, mustBeNull, syntax);
782 /// Add an attribute with a single type argument.
784 addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
785 IdentifierInfo *scopeName, SourceLocation scopeLoc,
786 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
787 AttributeList *attr =
788 pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
789 typeArg, syntaxUsed);
794 /// Add microsoft __delspec(property) attribute.
796 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
797 IdentifierInfo *scopeName, SourceLocation scopeLoc,
798 IdentifierInfo *getterId, IdentifierInfo *setterId,
799 AttributeList::Syntax syntaxUsed) {
800 AttributeList *attr =
801 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
802 getterId, setterId, syntaxUsed);
808 mutable AttributePool pool;
812 /// These constants match the enumerated choices of
813 /// err_attribute_argument_n_type and err_attribute_argument_type.
814 enum AttributeArgumentNType {
815 AANT_ArgumentIntOrBool,
816 AANT_ArgumentIntegerConstant,
818 AANT_ArgumentIdentifier
821 /// These constants match the enumerated choices of
822 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
823 enum AttributeDeclKind {
826 ExpectedVariableOrFunction,
827 ExpectedFunctionOrMethod,
829 ExpectedFunctionMethodOrBlock,
830 ExpectedFunctionMethodOrClass,
831 ExpectedFunctionMethodOrParameter,
836 ExpectedVariableFunctionOrLabel,
837 ExpectedFieldOrGlobalVar,
839 ExpectedVariableOrTypedef,
841 ExpectedVariableOrField,
842 ExpectedVariableFieldOrTag,
843 ExpectedTypeOrNamespace,
844 ExpectedObjectiveCInterface,
845 ExpectedMethodOrProperty,
846 ExpectedStructOrUnion,
847 ExpectedStructOrUnionOrClass,
849 ExpectedObjCInstanceMethod,
850 ExpectedObjCInterfaceDeclInitMethod,
851 ExpectedFunctionVariableOrClass,
852 ExpectedObjectiveCProtocol,
853 ExpectedFunctionGlobalVarMethodOrProperty,
854 ExpectedStructOrUnionOrTypedef,
855 ExpectedStructOrTypedef,
856 ExpectedObjectiveCInterfaceOrProtocol,
857 ExpectedKernelFunction
860 } // end namespace clang