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/TargetInfo.h"
20 #include "clang/Basic/VersionTuple.h"
21 #include "clang/Sema/Ownership.h"
22 #include "llvm/ADT/PointerUnion.h"
23 #include "llvm/ADT/SmallVector.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(); }
50 enum AvailabilitySlot {
51 IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
54 /// Describes the trailing object for Availability attribute in AttributeList.
55 struct AvailabilityData {
56 AvailabilityChange Changes[NumAvailabilitySlots];
57 SourceLocation StrictLoc;
58 const Expr *Replacement;
59 AvailabilityData(const AvailabilityChange &Introduced,
60 const AvailabilityChange &Deprecated,
61 const AvailabilityChange &Obsoleted,
62 SourceLocation Strict, const Expr *ReplaceExpr)
63 : StrictLoc(Strict), Replacement(ReplaceExpr) {
64 Changes[IntroducedSlot] = Introduced;
65 Changes[DeprecatedSlot] = Deprecated;
66 Changes[ObsoletedSlot] = Obsoleted;
71 /// \brief Wraps an identifier and optional source location for the identifier.
72 struct IdentifierLoc {
74 IdentifierInfo *Ident;
76 static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
77 IdentifierInfo *Ident);
80 /// \brief A union of the various pointer types that can be passed to an
81 /// AttributeList as an argument.
82 typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion;
83 typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector;
85 /// AttributeList - Represents a syntactic attribute.
87 /// For a GNU attribute, there are four forms of this construct:
89 /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
90 /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
91 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
92 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
94 class AttributeList { // TODO: This should really be called ParsedAttribute
96 /// The style used to specify an attribute.
98 /// __attribute__((...))
104 /// __ptr16, alignas(...), etc.
106 /// Context-sensitive version of a keyword attribute.
107 AS_ContextSensitiveKeyword,
113 IdentifierInfo *AttrName;
114 IdentifierInfo *ScopeName;
115 SourceRange AttrRange;
116 SourceLocation ScopeLoc;
117 SourceLocation EllipsisLoc;
119 unsigned AttrKind : 16;
121 /// The number of expression arguments this attribute has.
122 /// The expressions themselves are stored after the object.
123 unsigned NumArgs : 16;
125 /// Corresponds to the Syntax enum.
126 unsigned SyntaxUsed : 3;
128 /// True if already diagnosed as invalid.
129 mutable unsigned Invalid : 1;
131 /// True if this attribute was used as a type attribute.
132 mutable unsigned UsedAsTypeAttr : 1;
134 /// True if this has the extra information associated with an
135 /// availability attribute.
136 unsigned IsAvailability : 1;
138 /// True if this has extra information associated with a
139 /// type_tag_for_datatype attribute.
140 unsigned IsTypeTagForDatatype : 1;
142 /// True if this has extra information associated with a
143 /// Microsoft __delcspec(property) attribute.
144 unsigned IsProperty : 1;
146 /// True if this has a ParsedType
147 unsigned HasParsedType : 1;
149 /// True if the processing cache is valid.
150 mutable unsigned HasProcessingCache : 1;
153 mutable unsigned ProcessingCache : 8;
155 /// \brief The location of the 'unavailable' keyword in an
156 /// availability attribute.
157 SourceLocation UnavailableLoc;
159 const Expr *MessageExpr;
161 /// The next attribute in the current position.
162 AttributeList *NextInPosition;
164 /// The next attribute allocated in the current Pool.
165 AttributeList *NextInPool;
167 /// Arguments, if any, are stored immediately following the object.
168 ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
169 ArgsUnion const *getArgsBuffer() const {
170 return reinterpret_cast<ArgsUnion const *>(this + 1);
173 /// Availability information is stored immediately following the arguments,
174 /// if any, at the end of the object.
175 AvailabilityData *getAvailabilityData() {
176 return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs);
178 const AvailabilityData *getAvailabilityData() const {
179 return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
183 struct TypeTagForDatatypeData {
184 ParsedType *MatchingCType;
185 unsigned LayoutCompatible : 1;
186 unsigned MustBeNull : 1;
188 struct PropertyData {
189 IdentifierInfo *GetterId, *SetterId;
190 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
191 : GetterId(getterId), SetterId(setterId) {}
195 /// Type tag information is stored immediately following the arguments, if
196 /// any, at the end of the object. They are mutually exlusive with
197 /// availability slots.
198 TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
199 return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
202 const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
203 return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
207 /// The type buffer immediately follows the object and are mutually exclusive
209 ParsedType &getTypeBuffer() {
210 return *reinterpret_cast<ParsedType *>(this + 1);
213 const ParsedType &getTypeBuffer() const {
214 return *reinterpret_cast<const ParsedType *>(this + 1);
217 /// The property data immediately follows the object is is mutually exclusive
219 PropertyData &getPropertyDataBuffer() {
221 return *reinterpret_cast<PropertyData*>(this + 1);
224 const PropertyData &getPropertyDataBuffer() const {
226 return *reinterpret_cast<const PropertyData*>(this + 1);
229 AttributeList(const AttributeList &) = delete;
230 void operator=(const AttributeList &) = delete;
231 void operator delete(void *) = delete;
232 ~AttributeList() = delete;
234 size_t allocated_size() const;
236 /// Constructor for attributes with expression arguments.
237 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
238 IdentifierInfo *scopeName, SourceLocation scopeLoc,
239 ArgsUnion *args, unsigned numArgs,
240 Syntax syntaxUsed, SourceLocation ellipsisLoc)
241 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
242 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
243 SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
244 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
245 HasParsedType(false), HasProcessingCache(false),
246 NextInPosition(nullptr), NextInPool(nullptr) {
247 if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
248 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
251 /// Constructor for availability attributes.
252 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
253 IdentifierInfo *scopeName, SourceLocation scopeLoc,
254 IdentifierLoc *Parm, const AvailabilityChange &introduced,
255 const AvailabilityChange &deprecated,
256 const AvailabilityChange &obsoleted,
257 SourceLocation unavailable,
258 const Expr *messageExpr,
259 Syntax syntaxUsed, SourceLocation strict,
260 const Expr *replacementExpr)
261 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
262 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
263 Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
264 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
265 HasProcessingCache(false), UnavailableLoc(unavailable),
266 MessageExpr(messageExpr), NextInPosition(nullptr), NextInPool(nullptr) {
267 ArgsUnion PVal(Parm);
268 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
269 new (getAvailabilityData()) AvailabilityData(
270 introduced, deprecated, obsoleted, strict, replacementExpr);
271 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
274 /// Constructor for objc_bridge_related attributes.
275 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
276 IdentifierInfo *scopeName, SourceLocation scopeLoc,
277 IdentifierLoc *Parm1,
278 IdentifierLoc *Parm2,
279 IdentifierLoc *Parm3,
281 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
282 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
283 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
284 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
285 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
286 ArgsUnion *Args = getArgsBuffer();
290 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
293 /// Constructor for type_tag_for_datatype attribute.
294 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
295 IdentifierInfo *scopeName, SourceLocation scopeLoc,
296 IdentifierLoc *ArgKind, ParsedType matchingCType,
297 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
298 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
299 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
300 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
301 IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
302 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
303 ArgsUnion PVal(ArgKind);
304 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
305 TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
306 new (&ExtraData.MatchingCType) ParsedType(matchingCType);
307 ExtraData.LayoutCompatible = layoutCompatible;
308 ExtraData.MustBeNull = mustBeNull;
309 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
312 /// Constructor for attributes with a single type argument.
313 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
314 IdentifierInfo *scopeName, SourceLocation scopeLoc,
315 ParsedType typeArg, Syntax syntaxUsed)
316 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
317 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
318 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
319 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
320 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr){
321 new (&getTypeBuffer()) ParsedType(typeArg);
322 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
325 /// Constructor for microsoft __declspec(property) attribute.
326 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
327 IdentifierInfo *scopeName, SourceLocation scopeLoc,
328 IdentifierInfo *getterId, IdentifierInfo *setterId,
330 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
331 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
332 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
333 IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
334 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
335 new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
336 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
339 friend class AttributePool;
340 friend class AttributeFactory;
344 #define PARSED_ATTR(NAME) AT_##NAME,
345 #include "clang/Sema/AttrParsedAttrList.inc"
351 IdentifierInfo *getName() const { return AttrName; }
352 SourceLocation getLoc() const { return AttrRange.getBegin(); }
353 SourceRange getRange() const { return AttrRange; }
355 bool hasScope() const { return ScopeName; }
356 IdentifierInfo *getScopeName() const { return ScopeName; }
357 SourceLocation getScopeLoc() const { return ScopeLoc; }
359 bool hasParsedType() const { return HasParsedType; }
361 /// Is this the Microsoft __declspec(property) attribute?
362 bool isDeclspecPropertyAttribute() const {
366 bool isAlignasAttribute() const {
367 // FIXME: Use a better mechanism to determine this.
368 return getKind() == AT_Aligned && isKeywordAttribute();
371 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
372 bool isCXX11Attribute() const {
373 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
375 bool isKeywordAttribute() const {
376 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
379 bool isContextSensitiveKeywordAttribute() const {
380 return SyntaxUsed == AS_ContextSensitiveKeyword;
383 bool isInvalid() const { return Invalid; }
384 void setInvalid(bool b = true) const { Invalid = b; }
386 bool hasProcessingCache() const { return HasProcessingCache; }
387 unsigned getProcessingCache() const {
388 assert(hasProcessingCache());
389 return ProcessingCache;
391 void setProcessingCache(unsigned value) const {
392 ProcessingCache = value;
393 HasProcessingCache = true;
396 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
397 void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
399 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
400 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
402 Kind getKind() const { return Kind(AttrKind); }
403 static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
406 AttributeList *getNext() const { return NextInPosition; }
407 void setNext(AttributeList *N) { NextInPosition = N; }
409 /// getNumArgs - Return the number of actual arguments to this attribute.
410 unsigned getNumArgs() const { return NumArgs; }
412 /// getArg - Return the specified argument.
413 ArgsUnion getArg(unsigned Arg) const {
414 assert(Arg < NumArgs && "Arg access out of range!");
415 return getArgsBuffer()[Arg];
418 bool isArgExpr(unsigned Arg) const {
419 return Arg < NumArgs && getArg(Arg).is<Expr*>();
421 Expr *getArgAsExpr(unsigned Arg) const {
422 return getArg(Arg).get<Expr*>();
425 bool isArgIdent(unsigned Arg) const {
426 return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
428 IdentifierLoc *getArgAsIdent(unsigned Arg) const {
429 return getArg(Arg).get<IdentifierLoc*>();
432 const AvailabilityChange &getAvailabilityIntroduced() const {
433 assert(getKind() == AT_Availability && "Not an availability attribute");
434 return getAvailabilityData()->Changes[IntroducedSlot];
437 const AvailabilityChange &getAvailabilityDeprecated() const {
438 assert(getKind() == AT_Availability && "Not an availability attribute");
439 return getAvailabilityData()->Changes[DeprecatedSlot];
442 const AvailabilityChange &getAvailabilityObsoleted() const {
443 assert(getKind() == AT_Availability && "Not an availability attribute");
444 return getAvailabilityData()->Changes[ObsoletedSlot];
447 SourceLocation getStrictLoc() const {
448 assert(getKind() == AT_Availability && "Not an availability attribute");
449 return getAvailabilityData()->StrictLoc;
452 SourceLocation getUnavailableLoc() const {
453 assert(getKind() == AT_Availability && "Not an availability attribute");
454 return UnavailableLoc;
457 const Expr * getMessageExpr() const {
458 assert(getKind() == AT_Availability && "Not an availability attribute");
462 const Expr *getReplacementExpr() const {
463 assert(getKind() == AT_Availability && "Not an availability attribute");
464 return getAvailabilityData()->Replacement;
467 const ParsedType &getMatchingCType() const {
468 assert(getKind() == AT_TypeTagForDatatype &&
469 "Not a type_tag_for_datatype attribute");
470 return *getTypeTagForDatatypeDataSlot().MatchingCType;
473 bool getLayoutCompatible() const {
474 assert(getKind() == AT_TypeTagForDatatype &&
475 "Not a type_tag_for_datatype attribute");
476 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
479 bool getMustBeNull() const {
480 assert(getKind() == AT_TypeTagForDatatype &&
481 "Not a type_tag_for_datatype attribute");
482 return getTypeTagForDatatypeDataSlot().MustBeNull;
485 const ParsedType &getTypeArg() const {
486 assert(HasParsedType && "Not a type attribute");
487 return getTypeBuffer();
490 const PropertyData &getPropertyData() const {
491 assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
492 return getPropertyDataBuffer();
495 /// \brief Get an index into the attribute spelling list
496 /// defined in Attr.td. This index is used by an attribute
497 /// to pretty print itself.
498 unsigned getAttributeSpellingListIndex() const;
500 bool isTargetSpecificAttr() const;
501 bool isTypeAttr() const;
502 bool isStmtAttr() const;
504 bool hasCustomParsing() const;
505 unsigned getMinArgs() const;
506 unsigned getMaxArgs() const;
507 bool hasVariadicArg() const;
508 bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
509 bool diagnoseLangOpts(class Sema &S) const;
510 bool existsInTarget(const TargetInfo &Target) const;
511 bool isKnownToGCC() const;
513 /// \brief If the parsed attribute has a semantic equivalent, and it would
514 /// have a semantic Spelling enumeration (due to having semantically-distinct
515 /// spelling variations), return the value of that semantic spelling. If the
516 /// parsed attribute does not have a semantic equivalent, or would not have
517 /// a Spelling enumeration, the value UINT_MAX is returned.
518 unsigned getSemanticSpelling() const;
521 /// A factory, from which one makes pools, from which one creates
522 /// individual attributes which are deallocated with the pool.
524 /// Note that it's tolerably cheap to create and destroy one of
525 /// these as long as you don't actually allocate anything in it.
526 class AttributeFactory {
529 /// The required allocation size of an availability attribute,
530 /// which we want to ensure is a multiple of sizeof(void*).
531 AvailabilityAllocSize =
532 sizeof(AttributeList)
533 + ((sizeof(AvailabilityData) + sizeof(void*) + sizeof(ArgsUnion) - 1)
534 / sizeof(void*) * sizeof(void*)),
535 TypeTagForDatatypeAllocSize =
536 sizeof(AttributeList)
537 + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
538 sizeof(ArgsUnion) - 1)
539 / sizeof(void*) * sizeof(void*),
541 sizeof(AttributeList)
542 + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
543 / sizeof(void*) * sizeof(void*)
548 /// The number of free lists we want to be sure to support
549 /// inline. This is just enough that availability attributes
550 /// don't surpass it. It's actually very unlikely we'll see an
551 /// attribute that needs more than that; on x86-64 you'd need 10
552 /// expression arguments, and on i386 you'd need 19.
553 InlineFreeListsCapacity =
554 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
557 llvm::BumpPtrAllocator Alloc;
559 /// Free lists. The index is determined by the following formula:
560 /// (size - sizeof(AttributeList)) / sizeof(void*)
561 SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
563 // The following are the private interface used by AttributePool.
564 friend class AttributePool;
566 /// Allocate an attribute of the given size.
567 void *allocate(size_t size);
569 /// Reclaim all the attributes in the given pool chain, which is
570 /// non-empty. Note that the current implementation is safe
571 /// against reclaiming things which were not actually allocated
572 /// with the allocator, although of course it's important to make
573 /// sure that their allocator lives at least as long as this one.
574 void reclaimPool(AttributeList *head);
581 class AttributePool {
582 AttributeFactory &Factory;
585 void *allocate(size_t size) {
586 return Factory.allocate(size);
589 AttributeList *add(AttributeList *attr) {
590 // We don't care about the order of the pool.
591 attr->NextInPool = Head;
596 void takePool(AttributeList *pool);
599 /// Create a new pool for a factory.
600 AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
602 AttributePool(const AttributePool &) = delete;
604 /// Move the given pool's allocations to this pool.
605 AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) {
609 AttributeFactory &getFactory() const { return Factory; }
613 Factory.reclaimPool(Head);
618 /// Take the given pool's allocations and add them to this pool.
619 void takeAllFrom(AttributePool &pool) {
627 if (Head) Factory.reclaimPool(Head);
630 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
631 IdentifierInfo *scopeName, SourceLocation scopeLoc,
632 ArgsUnion *args, unsigned numArgs,
633 AttributeList::Syntax syntax,
634 SourceLocation ellipsisLoc = SourceLocation()) {
635 void *memory = allocate(sizeof(AttributeList)
636 + numArgs * sizeof(ArgsUnion));
637 return add(new (memory) AttributeList(attrName, attrRange,
639 args, numArgs, syntax,
643 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
644 IdentifierInfo *scopeName, SourceLocation scopeLoc,
645 IdentifierLoc *Param,
646 const AvailabilityChange &introduced,
647 const AvailabilityChange &deprecated,
648 const AvailabilityChange &obsoleted,
649 SourceLocation unavailable,
650 const Expr *MessageExpr,
651 AttributeList::Syntax syntax,
652 SourceLocation strict, const Expr *ReplacementExpr) {
653 void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
654 return add(new (memory) AttributeList(attrName, attrRange,
656 Param, introduced, deprecated,
657 obsoleted, unavailable, MessageExpr,
658 syntax, strict, ReplacementExpr));
661 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
662 IdentifierInfo *scopeName, SourceLocation scopeLoc,
663 IdentifierLoc *Param1,
664 IdentifierLoc *Param2,
665 IdentifierLoc *Param3,
666 AttributeList::Syntax syntax) {
667 size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
668 void *memory = allocate(size);
669 return add(new (memory) AttributeList(attrName, attrRange,
671 Param1, Param2, Param3,
675 AttributeList *createTypeTagForDatatype(
676 IdentifierInfo *attrName, SourceRange attrRange,
677 IdentifierInfo *scopeName, SourceLocation scopeLoc,
678 IdentifierLoc *argumentKind, ParsedType matchingCType,
679 bool layoutCompatible, bool mustBeNull,
680 AttributeList::Syntax syntax) {
681 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
682 return add(new (memory) AttributeList(attrName, attrRange,
684 argumentKind, matchingCType,
685 layoutCompatible, mustBeNull,
689 AttributeList *createTypeAttribute(
690 IdentifierInfo *attrName, SourceRange attrRange,
691 IdentifierInfo *scopeName, SourceLocation scopeLoc,
692 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
693 void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
694 return add(new (memory) AttributeList(attrName, attrRange,
696 typeArg, syntaxUsed));
699 AttributeList *createPropertyAttribute(
700 IdentifierInfo *attrName, SourceRange attrRange,
701 IdentifierInfo *scopeName, SourceLocation scopeLoc,
702 IdentifierInfo *getterId, IdentifierInfo *setterId,
703 AttributeList::Syntax syntaxUsed) {
704 void *memory = allocate(AttributeFactory::PropertyAllocSize);
705 return add(new (memory) AttributeList(attrName, attrRange,
712 /// ParsedAttributes - A collection of parsed attributes. Currently
713 /// we don't differentiate between the various attribute syntaxes,
714 /// which is basically silly.
716 /// Right now this is a very lightweight container, but the expectation
717 /// is that this will become significantly more serious.
718 class ParsedAttributes {
720 ParsedAttributes(AttributeFactory &factory)
721 : pool(factory), list(nullptr) {
724 ParsedAttributes(const ParsedAttributes &) = delete;
726 AttributePool &getPool() const { return pool; }
728 bool empty() const { return list == nullptr; }
730 void add(AttributeList *newAttr) {
732 assert(newAttr->getNext() == nullptr);
733 newAttr->setNext(list);
737 void addAll(AttributeList *newList) {
738 if (!newList) return;
740 AttributeList *lastInNewList = newList;
741 while (AttributeList *next = lastInNewList->getNext())
742 lastInNewList = next;
744 lastInNewList->setNext(list);
748 void set(AttributeList *newList) {
752 void takeAllFrom(ParsedAttributes &attrs) {
754 attrs.list = nullptr;
755 pool.takeAllFrom(attrs.pool);
758 void clear() { list = nullptr; pool.clear(); }
759 AttributeList *getList() const { return list; }
761 /// Returns a reference to the attribute list. Try not to introduce
762 /// dependencies on this method, it may not be long-lived.
763 AttributeList *&getListRef() { return list; }
765 /// Add attribute with expression arguments.
766 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
767 IdentifierInfo *scopeName, SourceLocation scopeLoc,
768 ArgsUnion *args, unsigned numArgs,
769 AttributeList::Syntax syntax,
770 SourceLocation ellipsisLoc = SourceLocation()) {
771 AttributeList *attr =
772 pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
773 syntax, ellipsisLoc);
778 /// Add availability attribute.
779 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
780 IdentifierInfo *scopeName, SourceLocation scopeLoc,
781 IdentifierLoc *Param,
782 const AvailabilityChange &introduced,
783 const AvailabilityChange &deprecated,
784 const AvailabilityChange &obsoleted,
785 SourceLocation unavailable,
786 const Expr *MessageExpr,
787 AttributeList::Syntax syntax,
788 SourceLocation strict, const Expr *ReplacementExpr) {
789 AttributeList *attr =
790 pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
791 deprecated, obsoleted, unavailable, MessageExpr, syntax,
792 strict, ReplacementExpr);
797 /// Add objc_bridge_related attribute.
798 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
799 IdentifierInfo *scopeName, SourceLocation scopeLoc,
800 IdentifierLoc *Param1,
801 IdentifierLoc *Param2,
802 IdentifierLoc *Param3,
803 AttributeList::Syntax syntax) {
804 AttributeList *attr =
805 pool.create(attrName, attrRange, scopeName, scopeLoc,
806 Param1, Param2, Param3, syntax);
811 /// Add type_tag_for_datatype attribute.
812 AttributeList *addNewTypeTagForDatatype(
813 IdentifierInfo *attrName, SourceRange attrRange,
814 IdentifierInfo *scopeName, SourceLocation scopeLoc,
815 IdentifierLoc *argumentKind, ParsedType matchingCType,
816 bool layoutCompatible, bool mustBeNull,
817 AttributeList::Syntax syntax) {
818 AttributeList *attr =
819 pool.createTypeTagForDatatype(attrName, attrRange,
821 argumentKind, matchingCType,
822 layoutCompatible, mustBeNull, syntax);
827 /// Add an attribute with a single type argument.
829 addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
830 IdentifierInfo *scopeName, SourceLocation scopeLoc,
831 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
832 AttributeList *attr =
833 pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
834 typeArg, syntaxUsed);
839 /// Add microsoft __delspec(property) attribute.
841 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
842 IdentifierInfo *scopeName, SourceLocation scopeLoc,
843 IdentifierInfo *getterId, IdentifierInfo *setterId,
844 AttributeList::Syntax syntaxUsed) {
845 AttributeList *attr =
846 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
847 getterId, setterId, syntaxUsed);
853 mutable AttributePool pool;
857 /// These constants match the enumerated choices of
858 /// err_attribute_argument_n_type and err_attribute_argument_type.
859 enum AttributeArgumentNType {
860 AANT_ArgumentIntOrBool,
861 AANT_ArgumentIntegerConstant,
863 AANT_ArgumentIdentifier
866 /// These constants match the enumerated choices of
867 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
868 enum AttributeDeclKind {
871 ExpectedVariableOrFunction,
872 ExpectedFunctionVariableOrObjCInterface,
873 ExpectedFunctionOrMethod,
875 ExpectedFunctionMethodOrBlock,
876 ExpectedFunctionMethodOrClass,
877 ExpectedFunctionMethodOrParameter,
882 ExpectedFieldOrGlobalVar,
884 ExpectedParameterOrTypedef,
885 ExpectedVariableOrTypedef,
887 ExpectedVariableOrField,
888 ExpectedVariableFieldOrTag,
889 ExpectedTypeOrNamespace,
890 ExpectedObjectiveCInterface,
891 ExpectedMethodOrProperty,
892 ExpectedStructOrUnion,
893 ExpectedStructOrUnionOrClass,
895 ExpectedObjCInstanceMethod,
896 ExpectedObjCInterfaceDeclInitMethod,
897 ExpectedFunctionVariableOrClass,
898 ExpectedFunctionVariableClassOrObjCInterface,
899 ExpectedObjectiveCProtocol,
900 ExpectedFunctionGlobalVarMethodOrProperty,
901 ExpectedStructOrUnionOrTypedef,
902 ExpectedStructOrTypedef,
903 ExpectedObjectiveCInterfaceOrProtocol,
904 ExpectedKernelFunction,
905 ExpectedFunctionWithProtoType,
906 ExpectedVariableEnumFieldOrTypedef,
907 ExpectedFunctionMethodEnumOrClass,
908 ExpectedStructClassVariableFunctionOrInlineNamespace,
909 ExpectedForMaybeUnused
912 } // end namespace clang