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/AttrSubjectMatchRules.h"
19 #include "clang/Basic/SourceLocation.h"
20 #include "clang/Basic/TargetInfo.h"
21 #include "clang/Basic/VersionTuple.h"
22 #include "clang/Sema/Ownership.h"
23 #include "llvm/ADT/PointerUnion.h"
24 #include "llvm/ADT/SmallVector.h"
25 #include "llvm/Support/Allocator.h"
33 /// \brief Represents information about a change in availability for
34 /// an entity, which is part of the encoding of the 'availability'
36 struct AvailabilityChange {
37 /// \brief The location of the keyword indicating the kind of change.
38 SourceLocation KeywordLoc;
40 /// \brief The version number at which the change occurred.
43 /// \brief The source range covering the version number.
44 SourceRange VersionRange;
46 /// \brief Determine whether this availability change is valid.
47 bool isValid() const { return !Version.empty(); }
51 enum AvailabilitySlot {
52 IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
55 /// Describes the trailing object for Availability attribute in AttributeList.
56 struct AvailabilityData {
57 AvailabilityChange Changes[NumAvailabilitySlots];
58 SourceLocation StrictLoc;
59 const Expr *Replacement;
60 AvailabilityData(const AvailabilityChange &Introduced,
61 const AvailabilityChange &Deprecated,
62 const AvailabilityChange &Obsoleted,
63 SourceLocation Strict, const Expr *ReplaceExpr)
64 : StrictLoc(Strict), Replacement(ReplaceExpr) {
65 Changes[IntroducedSlot] = Introduced;
66 Changes[DeprecatedSlot] = Deprecated;
67 Changes[ObsoletedSlot] = Obsoleted;
72 /// \brief Wraps an identifier and optional source location for the identifier.
73 struct IdentifierLoc {
75 IdentifierInfo *Ident;
77 static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
78 IdentifierInfo *Ident);
81 /// \brief A union of the various pointer types that can be passed to an
82 /// AttributeList as an argument.
83 typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion;
84 typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector;
86 /// AttributeList - Represents a syntactic attribute.
88 /// For a GNU attribute, there are four forms of this construct:
90 /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
91 /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
92 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
93 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
95 class AttributeList { // TODO: This should really be called ParsedAttribute
97 /// The style used to specify an attribute.
99 /// __attribute__((...))
107 /// [uuid("...")] class Foo
109 /// __ptr16, alignas(...), etc.
113 // Note TableGen depends on the order above. Do not add or change the order
114 // without adding related code to TableGen/ClangAttrEmitter.cpp.
115 /// Context-sensitive version of a keyword attribute.
116 AS_ContextSensitiveKeyword,
120 IdentifierInfo *AttrName;
121 IdentifierInfo *ScopeName;
122 SourceRange AttrRange;
123 SourceLocation ScopeLoc;
124 SourceLocation EllipsisLoc;
126 unsigned AttrKind : 16;
128 /// The number of expression arguments this attribute has.
129 /// The expressions themselves are stored after the object.
130 unsigned NumArgs : 16;
132 /// Corresponds to the Syntax enum.
133 unsigned SyntaxUsed : 3;
135 /// True if already diagnosed as invalid.
136 mutable unsigned Invalid : 1;
138 /// True if this attribute was used as a type attribute.
139 mutable unsigned UsedAsTypeAttr : 1;
141 /// True if this has the extra information associated with an
142 /// availability attribute.
143 unsigned IsAvailability : 1;
145 /// True if this has extra information associated with a
146 /// type_tag_for_datatype attribute.
147 unsigned IsTypeTagForDatatype : 1;
149 /// True if this has extra information associated with a
150 /// Microsoft __delcspec(property) attribute.
151 unsigned IsProperty : 1;
153 /// True if this has a ParsedType
154 unsigned HasParsedType : 1;
156 /// True if the processing cache is valid.
157 mutable unsigned HasProcessingCache : 1;
160 mutable unsigned ProcessingCache : 8;
162 /// \brief The location of the 'unavailable' keyword in an
163 /// availability attribute.
164 SourceLocation UnavailableLoc;
166 const Expr *MessageExpr;
168 /// The next attribute in the current position.
169 AttributeList *NextInPosition;
171 /// The next attribute allocated in the current Pool.
172 AttributeList *NextInPool;
174 /// Arguments, if any, are stored immediately following the object.
175 ArgsUnion *getArgsBuffer() { return reinterpret_cast<ArgsUnion *>(this + 1); }
176 ArgsUnion const *getArgsBuffer() const {
177 return reinterpret_cast<ArgsUnion const *>(this + 1);
180 /// Availability information is stored immediately following the arguments,
181 /// if any, at the end of the object.
182 AvailabilityData *getAvailabilityData() {
183 return reinterpret_cast<AvailabilityData*>(getArgsBuffer() + NumArgs);
185 const AvailabilityData *getAvailabilityData() const {
186 return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
190 struct TypeTagForDatatypeData {
191 ParsedType *MatchingCType;
192 unsigned LayoutCompatible : 1;
193 unsigned MustBeNull : 1;
195 struct PropertyData {
196 IdentifierInfo *GetterId, *SetterId;
197 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
198 : GetterId(getterId), SetterId(setterId) {}
202 /// Type tag information is stored immediately following the arguments, if
203 /// any, at the end of the object. They are mutually exlusive with
204 /// availability slots.
205 TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
206 return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
209 const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
210 return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
214 /// The type buffer immediately follows the object and are mutually exclusive
216 ParsedType &getTypeBuffer() {
217 return *reinterpret_cast<ParsedType *>(this + 1);
220 const ParsedType &getTypeBuffer() const {
221 return *reinterpret_cast<const ParsedType *>(this + 1);
224 /// The property data immediately follows the object is is mutually exclusive
226 PropertyData &getPropertyDataBuffer() {
228 return *reinterpret_cast<PropertyData*>(this + 1);
231 const PropertyData &getPropertyDataBuffer() const {
233 return *reinterpret_cast<const PropertyData*>(this + 1);
236 AttributeList(const AttributeList &) = delete;
237 void operator=(const AttributeList &) = delete;
238 void operator delete(void *) = delete;
239 ~AttributeList() = delete;
241 size_t allocated_size() const;
243 /// Constructor for attributes with expression arguments.
244 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
245 IdentifierInfo *scopeName, SourceLocation scopeLoc,
246 ArgsUnion *args, unsigned numArgs,
247 Syntax syntaxUsed, SourceLocation ellipsisLoc)
248 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
249 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
250 SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
251 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
252 HasParsedType(false), HasProcessingCache(false),
253 NextInPosition(nullptr), NextInPool(nullptr) {
254 if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
255 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
258 /// Constructor for availability attributes.
259 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
260 IdentifierInfo *scopeName, SourceLocation scopeLoc,
261 IdentifierLoc *Parm, const AvailabilityChange &introduced,
262 const AvailabilityChange &deprecated,
263 const AvailabilityChange &obsoleted,
264 SourceLocation unavailable,
265 const Expr *messageExpr,
266 Syntax syntaxUsed, SourceLocation strict,
267 const Expr *replacementExpr)
268 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
269 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
270 Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
271 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
272 HasProcessingCache(false), UnavailableLoc(unavailable),
273 MessageExpr(messageExpr), NextInPosition(nullptr), NextInPool(nullptr) {
274 ArgsUnion PVal(Parm);
275 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
276 new (getAvailabilityData()) AvailabilityData(
277 introduced, deprecated, obsoleted, strict, replacementExpr);
278 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
281 /// Constructor for objc_bridge_related attributes.
282 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
283 IdentifierInfo *scopeName, SourceLocation scopeLoc,
284 IdentifierLoc *Parm1,
285 IdentifierLoc *Parm2,
286 IdentifierLoc *Parm3,
288 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
289 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
290 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
291 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
292 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
293 ArgsUnion *Args = getArgsBuffer();
297 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
300 /// Constructor for type_tag_for_datatype attribute.
301 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
302 IdentifierInfo *scopeName, SourceLocation scopeLoc,
303 IdentifierLoc *ArgKind, ParsedType matchingCType,
304 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
305 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
306 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
307 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
308 IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
309 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
310 ArgsUnion PVal(ArgKind);
311 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
312 TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
313 new (&ExtraData.MatchingCType) ParsedType(matchingCType);
314 ExtraData.LayoutCompatible = layoutCompatible;
315 ExtraData.MustBeNull = mustBeNull;
316 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
319 /// Constructor for attributes with a single type argument.
320 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
321 IdentifierInfo *scopeName, SourceLocation scopeLoc,
322 ParsedType typeArg, Syntax syntaxUsed)
323 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
324 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
325 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
326 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
327 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr){
328 new (&getTypeBuffer()) ParsedType(typeArg);
329 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
332 /// Constructor for microsoft __declspec(property) attribute.
333 AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
334 IdentifierInfo *scopeName, SourceLocation scopeLoc,
335 IdentifierInfo *getterId, IdentifierInfo *setterId,
337 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
338 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
339 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
340 IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
341 HasProcessingCache(false), NextInPosition(nullptr), NextInPool(nullptr) {
342 new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
343 AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
346 friend class AttributePool;
347 friend class AttributeFactory;
351 #define PARSED_ATTR(NAME) AT_##NAME,
352 #include "clang/Sema/AttrParsedAttrList.inc"
358 IdentifierInfo *getName() const { return AttrName; }
359 SourceLocation getLoc() const { return AttrRange.getBegin(); }
360 SourceRange getRange() const { return AttrRange; }
362 bool hasScope() const { return ScopeName; }
363 IdentifierInfo *getScopeName() const { return ScopeName; }
364 SourceLocation getScopeLoc() const { return ScopeLoc; }
366 bool hasParsedType() const { return HasParsedType; }
368 /// Is this the Microsoft __declspec(property) attribute?
369 bool isDeclspecPropertyAttribute() const {
373 bool isAlignasAttribute() const {
374 // FIXME: Use a better mechanism to determine this.
375 return getKind() == AT_Aligned && isKeywordAttribute();
378 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
379 bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
380 bool isCXX11Attribute() const {
381 return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
383 bool isC2xAttribute() const {
384 return SyntaxUsed == AS_C2x;
386 bool isKeywordAttribute() const {
387 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
390 bool isContextSensitiveKeywordAttribute() const {
391 return SyntaxUsed == AS_ContextSensitiveKeyword;
394 bool isInvalid() const { return Invalid; }
395 void setInvalid(bool b = true) const { Invalid = b; }
397 bool hasProcessingCache() const { return HasProcessingCache; }
398 unsigned getProcessingCache() const {
399 assert(hasProcessingCache());
400 return ProcessingCache;
402 void setProcessingCache(unsigned value) const {
403 ProcessingCache = value;
404 HasProcessingCache = true;
407 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
408 void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
410 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
411 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
413 Kind getKind() const { return Kind(AttrKind); }
414 static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
417 AttributeList *getNext() const { return NextInPosition; }
418 void setNext(AttributeList *N) { NextInPosition = N; }
420 /// getNumArgs - Return the number of actual arguments to this attribute.
421 unsigned getNumArgs() const { return NumArgs; }
423 /// getArg - Return the specified argument.
424 ArgsUnion getArg(unsigned Arg) const {
425 assert(Arg < NumArgs && "Arg access out of range!");
426 return getArgsBuffer()[Arg];
429 bool isArgExpr(unsigned Arg) const {
430 return Arg < NumArgs && getArg(Arg).is<Expr*>();
432 Expr *getArgAsExpr(unsigned Arg) const {
433 return getArg(Arg).get<Expr*>();
436 bool isArgIdent(unsigned Arg) const {
437 return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
439 IdentifierLoc *getArgAsIdent(unsigned Arg) const {
440 return getArg(Arg).get<IdentifierLoc*>();
443 const AvailabilityChange &getAvailabilityIntroduced() const {
444 assert(getKind() == AT_Availability && "Not an availability attribute");
445 return getAvailabilityData()->Changes[IntroducedSlot];
448 const AvailabilityChange &getAvailabilityDeprecated() const {
449 assert(getKind() == AT_Availability && "Not an availability attribute");
450 return getAvailabilityData()->Changes[DeprecatedSlot];
453 const AvailabilityChange &getAvailabilityObsoleted() const {
454 assert(getKind() == AT_Availability && "Not an availability attribute");
455 return getAvailabilityData()->Changes[ObsoletedSlot];
458 SourceLocation getStrictLoc() const {
459 assert(getKind() == AT_Availability && "Not an availability attribute");
460 return getAvailabilityData()->StrictLoc;
463 SourceLocation getUnavailableLoc() const {
464 assert(getKind() == AT_Availability && "Not an availability attribute");
465 return UnavailableLoc;
468 const Expr * getMessageExpr() const {
469 assert(getKind() == AT_Availability && "Not an availability attribute");
473 const Expr *getReplacementExpr() const {
474 assert(getKind() == AT_Availability && "Not an availability attribute");
475 return getAvailabilityData()->Replacement;
478 const ParsedType &getMatchingCType() const {
479 assert(getKind() == AT_TypeTagForDatatype &&
480 "Not a type_tag_for_datatype attribute");
481 return *getTypeTagForDatatypeDataSlot().MatchingCType;
484 bool getLayoutCompatible() const {
485 assert(getKind() == AT_TypeTagForDatatype &&
486 "Not a type_tag_for_datatype attribute");
487 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
490 bool getMustBeNull() const {
491 assert(getKind() == AT_TypeTagForDatatype &&
492 "Not a type_tag_for_datatype attribute");
493 return getTypeTagForDatatypeDataSlot().MustBeNull;
496 const ParsedType &getTypeArg() const {
497 assert(HasParsedType && "Not a type attribute");
498 return getTypeBuffer();
501 const PropertyData &getPropertyData() const {
502 assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
503 return getPropertyDataBuffer();
506 /// \brief Get an index into the attribute spelling list
507 /// defined in Attr.td. This index is used by an attribute
508 /// to pretty print itself.
509 unsigned getAttributeSpellingListIndex() const;
511 bool isTargetSpecificAttr() const;
512 bool isTypeAttr() const;
513 bool isStmtAttr() const;
515 bool hasCustomParsing() const;
516 unsigned getMinArgs() const;
517 unsigned getMaxArgs() const;
518 bool hasVariadicArg() const;
519 bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
520 bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
521 void getMatchRules(const LangOptions &LangOpts,
522 SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
524 bool diagnoseLangOpts(class Sema &S) const;
525 bool existsInTarget(const TargetInfo &Target) const;
526 bool isKnownToGCC() const;
527 bool isSupportedByPragmaAttribute() const;
529 /// \brief If the parsed attribute has a semantic equivalent, and it would
530 /// have a semantic Spelling enumeration (due to having semantically-distinct
531 /// spelling variations), return the value of that semantic spelling. If the
532 /// parsed attribute does not have a semantic equivalent, or would not have
533 /// a Spelling enumeration, the value UINT_MAX is returned.
534 unsigned getSemanticSpelling() const;
537 /// A factory, from which one makes pools, from which one creates
538 /// individual attributes which are deallocated with the pool.
540 /// Note that it's tolerably cheap to create and destroy one of
541 /// these as long as you don't actually allocate anything in it.
542 class AttributeFactory {
545 /// The required allocation size of an availability attribute,
546 /// which we want to ensure is a multiple of sizeof(void*).
547 AvailabilityAllocSize =
548 sizeof(AttributeList)
549 + ((sizeof(AvailabilityData) + sizeof(void*) + sizeof(ArgsUnion) - 1)
550 / sizeof(void*) * sizeof(void*)),
551 TypeTagForDatatypeAllocSize =
552 sizeof(AttributeList)
553 + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
554 sizeof(ArgsUnion) - 1)
555 / sizeof(void*) * sizeof(void*),
557 sizeof(AttributeList)
558 + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
559 / sizeof(void*) * sizeof(void*)
564 /// The number of free lists we want to be sure to support
565 /// inline. This is just enough that availability attributes
566 /// don't surpass it. It's actually very unlikely we'll see an
567 /// attribute that needs more than that; on x86-64 you'd need 10
568 /// expression arguments, and on i386 you'd need 19.
569 InlineFreeListsCapacity =
570 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
573 llvm::BumpPtrAllocator Alloc;
575 /// Free lists. The index is determined by the following formula:
576 /// (size - sizeof(AttributeList)) / sizeof(void*)
577 SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
579 // The following are the private interface used by AttributePool.
580 friend class AttributePool;
582 /// Allocate an attribute of the given size.
583 void *allocate(size_t size);
585 /// Reclaim all the attributes in the given pool chain, which is
586 /// non-empty. Note that the current implementation is safe
587 /// against reclaiming things which were not actually allocated
588 /// with the allocator, although of course it's important to make
589 /// sure that their allocator lives at least as long as this one.
590 void reclaimPool(AttributeList *head);
597 class AttributePool {
598 AttributeFactory &Factory;
601 void *allocate(size_t size) {
602 return Factory.allocate(size);
605 AttributeList *add(AttributeList *attr) {
606 // We don't care about the order of the pool.
607 attr->NextInPool = Head;
612 void takePool(AttributeList *pool);
615 /// Create a new pool for a factory.
616 AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
618 AttributePool(const AttributePool &) = delete;
620 /// Move the given pool's allocations to this pool.
621 AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) {
625 AttributeFactory &getFactory() const { return Factory; }
629 Factory.reclaimPool(Head);
634 /// Take the given pool's allocations and add them to this pool.
635 void takeAllFrom(AttributePool &pool) {
643 if (Head) Factory.reclaimPool(Head);
646 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
647 IdentifierInfo *scopeName, SourceLocation scopeLoc,
648 ArgsUnion *args, unsigned numArgs,
649 AttributeList::Syntax syntax,
650 SourceLocation ellipsisLoc = SourceLocation()) {
651 void *memory = allocate(sizeof(AttributeList)
652 + numArgs * sizeof(ArgsUnion));
653 return add(new (memory) AttributeList(attrName, attrRange,
655 args, numArgs, syntax,
659 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
660 IdentifierInfo *scopeName, SourceLocation scopeLoc,
661 IdentifierLoc *Param,
662 const AvailabilityChange &introduced,
663 const AvailabilityChange &deprecated,
664 const AvailabilityChange &obsoleted,
665 SourceLocation unavailable,
666 const Expr *MessageExpr,
667 AttributeList::Syntax syntax,
668 SourceLocation strict, const Expr *ReplacementExpr) {
669 void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
670 return add(new (memory) AttributeList(attrName, attrRange,
672 Param, introduced, deprecated,
673 obsoleted, unavailable, MessageExpr,
674 syntax, strict, ReplacementExpr));
677 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
678 IdentifierInfo *scopeName, SourceLocation scopeLoc,
679 IdentifierLoc *Param1,
680 IdentifierLoc *Param2,
681 IdentifierLoc *Param3,
682 AttributeList::Syntax syntax) {
683 size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
684 void *memory = allocate(size);
685 return add(new (memory) AttributeList(attrName, attrRange,
687 Param1, Param2, Param3,
691 AttributeList *createTypeTagForDatatype(
692 IdentifierInfo *attrName, SourceRange attrRange,
693 IdentifierInfo *scopeName, SourceLocation scopeLoc,
694 IdentifierLoc *argumentKind, ParsedType matchingCType,
695 bool layoutCompatible, bool mustBeNull,
696 AttributeList::Syntax syntax) {
697 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
698 return add(new (memory) AttributeList(attrName, attrRange,
700 argumentKind, matchingCType,
701 layoutCompatible, mustBeNull,
705 AttributeList *createTypeAttribute(
706 IdentifierInfo *attrName, SourceRange attrRange,
707 IdentifierInfo *scopeName, SourceLocation scopeLoc,
708 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
709 void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
710 return add(new (memory) AttributeList(attrName, attrRange,
712 typeArg, syntaxUsed));
715 AttributeList *createPropertyAttribute(
716 IdentifierInfo *attrName, SourceRange attrRange,
717 IdentifierInfo *scopeName, SourceLocation scopeLoc,
718 IdentifierInfo *getterId, IdentifierInfo *setterId,
719 AttributeList::Syntax syntaxUsed) {
720 void *memory = allocate(AttributeFactory::PropertyAllocSize);
721 return add(new (memory) AttributeList(attrName, attrRange,
728 /// ParsedAttributes - A collection of parsed attributes. Currently
729 /// we don't differentiate between the various attribute syntaxes,
730 /// which is basically silly.
732 /// Right now this is a very lightweight container, but the expectation
733 /// is that this will become significantly more serious.
734 class ParsedAttributes {
736 ParsedAttributes(AttributeFactory &factory)
737 : pool(factory), list(nullptr) {
740 ParsedAttributes(const ParsedAttributes &) = delete;
742 AttributePool &getPool() const { return pool; }
744 bool empty() const { return list == nullptr; }
746 void add(AttributeList *newAttr) {
748 assert(newAttr->getNext() == nullptr);
749 newAttr->setNext(list);
753 void addAll(AttributeList *newList) {
754 if (!newList) return;
756 AttributeList *lastInNewList = newList;
757 while (AttributeList *next = lastInNewList->getNext())
758 lastInNewList = next;
760 lastInNewList->setNext(list);
764 void addAllAtEnd(AttributeList *newList) {
770 AttributeList *lastInList = list;
771 while (AttributeList *next = lastInList->getNext())
774 lastInList->setNext(newList);
777 void set(AttributeList *newList) {
781 void takeAllFrom(ParsedAttributes &attrs) {
783 attrs.list = nullptr;
784 pool.takeAllFrom(attrs.pool);
787 void clear() { list = nullptr; pool.clear(); }
788 AttributeList *getList() const { return list; }
790 void clearListOnly() { list = nullptr; }
792 /// Returns a reference to the attribute list. Try not to introduce
793 /// dependencies on this method, it may not be long-lived.
794 AttributeList *&getListRef() { return list; }
796 /// Add attribute with expression arguments.
797 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
798 IdentifierInfo *scopeName, SourceLocation scopeLoc,
799 ArgsUnion *args, unsigned numArgs,
800 AttributeList::Syntax syntax,
801 SourceLocation ellipsisLoc = SourceLocation()) {
802 AttributeList *attr =
803 pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
804 syntax, ellipsisLoc);
809 /// Add availability attribute.
810 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
811 IdentifierInfo *scopeName, SourceLocation scopeLoc,
812 IdentifierLoc *Param,
813 const AvailabilityChange &introduced,
814 const AvailabilityChange &deprecated,
815 const AvailabilityChange &obsoleted,
816 SourceLocation unavailable,
817 const Expr *MessageExpr,
818 AttributeList::Syntax syntax,
819 SourceLocation strict, const Expr *ReplacementExpr) {
820 AttributeList *attr =
821 pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
822 deprecated, obsoleted, unavailable, MessageExpr, syntax,
823 strict, ReplacementExpr);
828 /// Add objc_bridge_related attribute.
829 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
830 IdentifierInfo *scopeName, SourceLocation scopeLoc,
831 IdentifierLoc *Param1,
832 IdentifierLoc *Param2,
833 IdentifierLoc *Param3,
834 AttributeList::Syntax syntax) {
835 AttributeList *attr =
836 pool.create(attrName, attrRange, scopeName, scopeLoc,
837 Param1, Param2, Param3, syntax);
842 /// Add type_tag_for_datatype attribute.
843 AttributeList *addNewTypeTagForDatatype(
844 IdentifierInfo *attrName, SourceRange attrRange,
845 IdentifierInfo *scopeName, SourceLocation scopeLoc,
846 IdentifierLoc *argumentKind, ParsedType matchingCType,
847 bool layoutCompatible, bool mustBeNull,
848 AttributeList::Syntax syntax) {
849 AttributeList *attr =
850 pool.createTypeTagForDatatype(attrName, attrRange,
852 argumentKind, matchingCType,
853 layoutCompatible, mustBeNull, syntax);
858 /// Add an attribute with a single type argument.
860 addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
861 IdentifierInfo *scopeName, SourceLocation scopeLoc,
862 ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
863 AttributeList *attr =
864 pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
865 typeArg, syntaxUsed);
870 /// Add microsoft __delspec(property) attribute.
872 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
873 IdentifierInfo *scopeName, SourceLocation scopeLoc,
874 IdentifierInfo *getterId, IdentifierInfo *setterId,
875 AttributeList::Syntax syntaxUsed) {
876 AttributeList *attr =
877 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
878 getterId, setterId, syntaxUsed);
884 mutable AttributePool pool;
888 /// These constants match the enumerated choices of
889 /// err_attribute_argument_n_type and err_attribute_argument_type.
890 enum AttributeArgumentNType {
891 AANT_ArgumentIntOrBool,
892 AANT_ArgumentIntegerConstant,
894 AANT_ArgumentIdentifier
897 /// These constants match the enumerated choices of
898 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
899 enum AttributeDeclKind {
902 ExpectedVariableOrFunction,
903 ExpectedFunctionOrMethod,
904 ExpectedFunctionMethodOrBlock,
905 ExpectedFunctionMethodOrParameter,
907 ExpectedVariableOrField,
908 ExpectedVariableFieldOrTag,
909 ExpectedTypeOrNamespace,
910 ExpectedFunctionVariableOrClass,
911 ExpectedKernelFunction,
912 ExpectedFunctionWithProtoType,
913 ExpectedForMaybeUnused,
916 } // end namespace clang