Home | History | Annotate | Download | only in Sema
      1 //===--- AttributeList.h - Parsed attribute sets ----------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // This file defines the AttributeList class, which is used to collect
     11 // parsed attributes.
     12 //
     13 //===----------------------------------------------------------------------===//
     14 
     15 #ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H
     16 #define LLVM_CLANG_SEMA_ATTRIBUTELIST_H
     17 
     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"
     25 #include <cassert>
     26 
     27 namespace clang {
     28   class ASTContext;
     29   class IdentifierInfo;
     30   class Expr;
     31 
     32 /// \brief Represents information about a change in availability for
     33 /// an entity, which is part of the encoding of the 'availability'
     34 /// attribute.
     35 struct AvailabilityChange {
     36   /// \brief The location of the keyword indicating the kind of change.
     37   SourceLocation KeywordLoc;
     38 
     39   /// \brief The version number at which the change occurred.
     40   VersionTuple Version;
     41 
     42   /// \brief The source range covering the version number.
     43   SourceRange VersionRange;
     44 
     45   /// \brief Determine whether this availability change is valid.
     46   bool isValid() const { return !Version.empty(); }
     47 };
     48 
     49 namespace {
     50 enum AvailabilitySlot {
     51   IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
     52 };
     53 
     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;
     67   }
     68 };
     69 }
     70 
     71 /// \brief Wraps an identifier and optional source location for the identifier.
     72 struct IdentifierLoc {
     73   SourceLocation Loc;
     74   IdentifierInfo *Ident;
     75 
     76   static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
     77                                IdentifierInfo *Ident);
     78 };
     79 
     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;
     84 
     85 /// AttributeList - Represents a syntactic attribute.
     86 ///
     87 /// For a GNU attribute, there are four forms of this construct:
     88 ///
     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.
     93 ///
     94 class AttributeList { // TODO: This should really be called ParsedAttribute
     95 public:
     96   /// The style used to specify an attribute.
     97   enum Syntax {
     98     /// __attribute__((...))
     99     AS_GNU,
    100     /// [[...]]
    101     AS_CXX11,
    102     /// __declspec(...)
    103     AS_Declspec,
    104     /// __ptr16, alignas(...), etc.
    105     AS_Keyword,
    106     /// Context-sensitive version of a keyword attribute.
    107     AS_ContextSensitiveKeyword,
    108     /// #pragma ...
    109     AS_Pragma
    110   };
    111 
    112 private:
    113   IdentifierInfo *AttrName;
    114   IdentifierInfo *ScopeName;
    115   SourceRange AttrRange;
    116   SourceLocation ScopeLoc;
    117   SourceLocation EllipsisLoc;
    118 
    119   unsigned AttrKind : 16;
    120 
    121   /// The number of expression arguments this attribute has.
    122   /// The expressions themselves are stored after the object.
    123   unsigned NumArgs : 16;
    124 
    125   /// Corresponds to the Syntax enum.
    126   unsigned SyntaxUsed : 3;
    127 
    128   /// True if already diagnosed as invalid.
    129   mutable unsigned Invalid : 1;
    130 
    131   /// True if this attribute was used as a type attribute.
    132   mutable unsigned UsedAsTypeAttr : 1;
    133 
    134   /// True if this has the extra information associated with an
    135   /// availability attribute.
    136   unsigned IsAvailability : 1;
    137 
    138   /// True if this has extra information associated with a
    139   /// type_tag_for_datatype attribute.
    140   unsigned IsTypeTagForDatatype : 1;
    141 
    142   /// True if this has extra information associated with a
    143   /// Microsoft __delcspec(property) attribute.
    144   unsigned IsProperty : 1;
    145 
    146   /// True if this has a ParsedType
    147   unsigned HasParsedType : 1;
    148 
    149   /// True if the processing cache is valid.
    150   mutable unsigned HasProcessingCache : 1;
    151 
    152   /// A cached value.
    153   mutable unsigned ProcessingCache : 8;
    154 
    155   /// \brief The location of the 'unavailable' keyword in an
    156   /// availability attribute.
    157   SourceLocation UnavailableLoc;
    158 
    159   const Expr *MessageExpr;
    160 
    161   /// The next attribute in the current position.
    162   AttributeList *NextInPosition;
    163 
    164   /// The next attribute allocated in the current Pool.
    165   AttributeList *NextInPool;
    166 
    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);
    171   }
    172 
    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);
    177   }
    178   const AvailabilityData *getAvailabilityData() const {
    179     return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
    180   }
    181 
    182 public:
    183   struct TypeTagForDatatypeData {
    184     ParsedType *MatchingCType;
    185     unsigned LayoutCompatible : 1;
    186     unsigned MustBeNull : 1;
    187   };
    188   struct PropertyData {
    189     IdentifierInfo *GetterId, *SetterId;
    190     PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
    191     : GetterId(getterId), SetterId(setterId) {}
    192   };
    193 
    194 private:
    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);
    200   }
    201 
    202   const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
    203     return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
    204                                                             + NumArgs);
    205   }
    206 
    207   /// The type buffer immediately follows the object and are mutually exclusive
    208   /// with arguments.
    209   ParsedType &getTypeBuffer() {
    210     return *reinterpret_cast<ParsedType *>(this + 1);
    211   }
    212 
    213   const ParsedType &getTypeBuffer() const {
    214     return *reinterpret_cast<const ParsedType *>(this + 1);
    215   }
    216 
    217   /// The property data immediately follows the object is is mutually exclusive
    218   /// with arguments.
    219   PropertyData &getPropertyDataBuffer() {
    220     assert(IsProperty);
    221     return *reinterpret_cast<PropertyData*>(this + 1);
    222   }
    223 
    224   const PropertyData &getPropertyDataBuffer() const {
    225     assert(IsProperty);
    226     return *reinterpret_cast<const PropertyData*>(this + 1);
    227   }
    228 
    229   AttributeList(const AttributeList &) = delete;
    230   void operator=(const AttributeList &) = delete;
    231   void operator delete(void *) = delete;
    232   ~AttributeList() = delete;
    233 
    234   size_t allocated_size() const;
    235 
    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);
    249   }
    250 
    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);
    272   }
    273 
    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,
    280                 Syntax syntaxUsed)
    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();
    287     Args[0] = Parm1;
    288     Args[1] = Parm2;
    289     Args[2] = Parm3;
    290     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
    291   }
    292 
    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);
    310   }
    311 
    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);
    323   }
    324 
    325   /// Constructor for microsoft __declspec(property) attribute.
    326   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
    327                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
    328                 IdentifierInfo *getterId, IdentifierInfo *setterId,
    329                 Syntax syntaxUsed)
    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);
    337   }
    338 
    339   friend class AttributePool;
    340   friend class AttributeFactory;
    341 
    342 public:
    343   enum Kind {
    344     #define PARSED_ATTR(NAME) AT_##NAME,
    345     #include "clang/Sema/AttrParsedAttrList.inc"
    346     #undef PARSED_ATTR
    347     IgnoredAttribute,
    348     UnknownAttribute
    349   };
    350 
    351   IdentifierInfo *getName() const { return AttrName; }
    352   SourceLocation getLoc() const { return AttrRange.getBegin(); }
    353   SourceRange getRange() const { return AttrRange; }
    354 
    355   bool hasScope() const { return ScopeName; }
    356   IdentifierInfo *getScopeName() const { return ScopeName; }
    357   SourceLocation getScopeLoc() const { return ScopeLoc; }
    358 
    359   bool hasParsedType() const { return HasParsedType; }
    360 
    361   /// Is this the Microsoft __declspec(property) attribute?
    362   bool isDeclspecPropertyAttribute() const  {
    363     return IsProperty;
    364   }
    365 
    366   bool isAlignasAttribute() const {
    367     // FIXME: Use a better mechanism to determine this.
    368     return getKind() == AT_Aligned && isKeywordAttribute();
    369   }
    370 
    371   bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
    372   bool isCXX11Attribute() const {
    373     return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
    374   }
    375   bool isKeywordAttribute() const {
    376     return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
    377   }
    378 
    379   bool isContextSensitiveKeywordAttribute() const {
    380     return SyntaxUsed == AS_ContextSensitiveKeyword;
    381   }
    382 
    383   bool isInvalid() const { return Invalid; }
    384   void setInvalid(bool b = true) const { Invalid = b; }
    385 
    386   bool hasProcessingCache() const { return HasProcessingCache; }
    387   unsigned getProcessingCache() const {
    388     assert(hasProcessingCache());
    389     return ProcessingCache;
    390   }
    391   void setProcessingCache(unsigned value) const {
    392     ProcessingCache = value;
    393     HasProcessingCache = true;
    394   }
    395 
    396   bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
    397   void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
    398 
    399   bool isPackExpansion() const { return EllipsisLoc.isValid(); }
    400   SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
    401 
    402   Kind getKind() const { return Kind(AttrKind); }
    403   static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
    404                       Syntax SyntaxUsed);
    405 
    406   AttributeList *getNext() const { return NextInPosition; }
    407   void setNext(AttributeList *N) { NextInPosition = N; }
    408 
    409   /// getNumArgs - Return the number of actual arguments to this attribute.
    410   unsigned getNumArgs() const { return NumArgs; }
    411 
    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];
    416   }
    417 
    418   bool isArgExpr(unsigned Arg) const {
    419     return Arg < NumArgs && getArg(Arg).is<Expr*>();
    420   }
    421   Expr *getArgAsExpr(unsigned Arg) const {
    422     return getArg(Arg).get<Expr*>();
    423   }
    424 
    425   bool isArgIdent(unsigned Arg) const {
    426     return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
    427   }
    428   IdentifierLoc *getArgAsIdent(unsigned Arg) const {
    429     return getArg(Arg).get<IdentifierLoc*>();
    430   }
    431 
    432   const AvailabilityChange &getAvailabilityIntroduced() const {
    433     assert(getKind() == AT_Availability && "Not an availability attribute");
    434     return getAvailabilityData()->Changes[IntroducedSlot];
    435   }
    436 
    437   const AvailabilityChange &getAvailabilityDeprecated() const {
    438     assert(getKind() == AT_Availability && "Not an availability attribute");
    439     return getAvailabilityData()->Changes[DeprecatedSlot];
    440   }
    441 
    442   const AvailabilityChange &getAvailabilityObsoleted() const {
    443     assert(getKind() == AT_Availability && "Not an availability attribute");
    444     return getAvailabilityData()->Changes[ObsoletedSlot];
    445   }
    446 
    447   SourceLocation getStrictLoc() const {
    448     assert(getKind() == AT_Availability && "Not an availability attribute");
    449     return getAvailabilityData()->StrictLoc;
    450   }
    451 
    452   SourceLocation getUnavailableLoc() const {
    453     assert(getKind() == AT_Availability && "Not an availability attribute");
    454     return UnavailableLoc;
    455   }
    456 
    457   const Expr * getMessageExpr() const {
    458     assert(getKind() == AT_Availability && "Not an availability attribute");
    459     return MessageExpr;
    460   }
    461 
    462   const Expr *getReplacementExpr() const {
    463     assert(getKind() == AT_Availability && "Not an availability attribute");
    464     return getAvailabilityData()->Replacement;
    465   }
    466 
    467   const ParsedType &getMatchingCType() const {
    468     assert(getKind() == AT_TypeTagForDatatype &&
    469            "Not a type_tag_for_datatype attribute");
    470     return *getTypeTagForDatatypeDataSlot().MatchingCType;
    471   }
    472 
    473   bool getLayoutCompatible() const {
    474     assert(getKind() == AT_TypeTagForDatatype &&
    475            "Not a type_tag_for_datatype attribute");
    476     return getTypeTagForDatatypeDataSlot().LayoutCompatible;
    477   }
    478 
    479   bool getMustBeNull() const {
    480     assert(getKind() == AT_TypeTagForDatatype &&
    481            "Not a type_tag_for_datatype attribute");
    482     return getTypeTagForDatatypeDataSlot().MustBeNull;
    483   }
    484 
    485   const ParsedType &getTypeArg() const {
    486     assert(HasParsedType && "Not a type attribute");
    487     return getTypeBuffer();
    488   }
    489 
    490   const PropertyData &getPropertyData() const {
    491     assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
    492     return getPropertyDataBuffer();
    493   }
    494 
    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;
    499 
    500   bool isTargetSpecificAttr() const;
    501   bool isTypeAttr() const;
    502   bool isStmtAttr() const;
    503 
    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;
    512 
    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;
    519 };
    520 
    521 /// A factory, from which one makes pools, from which one creates
    522 /// individual attributes which are deallocated with the pool.
    523 ///
    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 {
    527 public:
    528   enum {
    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*),
    540     PropertyAllocSize =
    541       sizeof(AttributeList)
    542       + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
    543         / sizeof(void*) * sizeof(void*)
    544   };
    545 
    546 private:
    547   enum {
    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*)
    555   };
    556 
    557   llvm::BumpPtrAllocator Alloc;
    558 
    559   /// Free lists.  The index is determined by the following formula:
    560   ///   (size - sizeof(AttributeList)) / sizeof(void*)
    561   SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
    562 
    563   // The following are the private interface used by AttributePool.
    564   friend class AttributePool;
    565 
    566   /// Allocate an attribute of the given size.
    567   void *allocate(size_t size);
    568 
    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);
    575 
    576 public:
    577   AttributeFactory();
    578   ~AttributeFactory();
    579 };
    580 
    581 class AttributePool {
    582   AttributeFactory &Factory;
    583   AttributeList *Head;
    584 
    585   void *allocate(size_t size) {
    586     return Factory.allocate(size);
    587   }
    588 
    589   AttributeList *add(AttributeList *attr) {
    590     // We don't care about the order of the pool.
    591     attr->NextInPool = Head;
    592     Head = attr;
    593     return attr;
    594   }
    595 
    596   void takePool(AttributeList *pool);
    597 
    598 public:
    599   /// Create a new pool for a factory.
    600   AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
    601 
    602   AttributePool(const AttributePool &) = delete;
    603 
    604   /// Move the given pool's allocations to this pool.
    605   AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) {
    606     pool.Head = nullptr;
    607   }
    608 
    609   AttributeFactory &getFactory() const { return Factory; }
    610 
    611   void clear() {
    612     if (Head) {
    613       Factory.reclaimPool(Head);
    614       Head = nullptr;
    615     }
    616   }
    617 
    618   /// Take the given pool's allocations and add them to this pool.
    619   void takeAllFrom(AttributePool &pool) {
    620     if (pool.Head) {
    621       takePool(pool.Head);
    622       pool.Head = nullptr;
    623     }
    624   }
    625 
    626   ~AttributePool() {
    627     if (Head) Factory.reclaimPool(Head);
    628   }
    629 
    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,
    638                                           scopeName, scopeLoc,
    639                                           args, numArgs, syntax,
    640                                           ellipsisLoc));
    641   }
    642 
    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,
    655                                           scopeName, scopeLoc,
    656                                           Param, introduced, deprecated,
    657                                           obsoleted, unavailable, MessageExpr,
    658                                           syntax, strict, ReplacementExpr));
    659   }
    660 
    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,
    670                                           scopeName, scopeLoc,
    671                                           Param1, Param2, Param3,
    672                                           syntax));
    673   }
    674 
    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,
    683                                           scopeName, scopeLoc,
    684                                           argumentKind, matchingCType,
    685                                           layoutCompatible, mustBeNull,
    686                                           syntax));
    687   }
    688 
    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,
    695                                           scopeName, scopeLoc,
    696                                           typeArg, syntaxUsed));
    697   }
    698 
    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,
    706                                           scopeName, scopeLoc,
    707                                           getterId, setterId,
    708                                           syntaxUsed));
    709   }
    710 };
    711 
    712 /// ParsedAttributes - A collection of parsed attributes.  Currently
    713 /// we don't differentiate between the various attribute syntaxes,
    714 /// which is basically silly.
    715 ///
    716 /// Right now this is a very lightweight container, but the expectation
    717 /// is that this will become significantly more serious.
    718 class ParsedAttributes {
    719 public:
    720   ParsedAttributes(AttributeFactory &factory)
    721     : pool(factory), list(nullptr) {
    722   }
    723 
    724   ParsedAttributes(const ParsedAttributes &) = delete;
    725 
    726   AttributePool &getPool() const { return pool; }
    727 
    728   bool empty() const { return list == nullptr; }
    729 
    730   void add(AttributeList *newAttr) {
    731     assert(newAttr);
    732     assert(newAttr->getNext() == nullptr);
    733     newAttr->setNext(list);
    734     list = newAttr;
    735   }
    736 
    737   void addAll(AttributeList *newList) {
    738     if (!newList) return;
    739 
    740     AttributeList *lastInNewList = newList;
    741     while (AttributeList *next = lastInNewList->getNext())
    742       lastInNewList = next;
    743 
    744     lastInNewList->setNext(list);
    745     list = newList;
    746   }
    747 
    748   void set(AttributeList *newList) {
    749     list = newList;
    750   }
    751 
    752   void takeAllFrom(ParsedAttributes &attrs) {
    753     addAll(attrs.list);
    754     attrs.list = nullptr;
    755     pool.takeAllFrom(attrs.pool);
    756   }
    757 
    758   void clear() { list = nullptr; pool.clear(); }
    759   AttributeList *getList() const { return list; }
    760 
    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; }
    764 
    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);
    774     add(attr);
    775     return attr;
    776   }
    777 
    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);
    793     add(attr);
    794     return attr;
    795   }
    796 
    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);
    807     add(attr);
    808     return attr;
    809   }
    810 
    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,
    820                                     scopeName, scopeLoc,
    821                                     argumentKind, matchingCType,
    822                                     layoutCompatible, mustBeNull, syntax);
    823     add(attr);
    824     return attr;
    825   }
    826 
    827   /// Add an attribute with a single type argument.
    828   AttributeList *
    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);
    835     add(attr);
    836     return attr;
    837   }
    838 
    839   /// Add microsoft __delspec(property) attribute.
    840   AttributeList *
    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);
    848     add(attr);
    849     return attr;
    850   }
    851 
    852 private:
    853   mutable AttributePool pool;
    854   AttributeList *list;
    855 };
    856 
    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,
    862   AANT_ArgumentString,
    863   AANT_ArgumentIdentifier
    864 };
    865 
    866 /// These constants match the enumerated choices of
    867 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
    868 enum AttributeDeclKind {
    869   ExpectedFunction,
    870   ExpectedUnion,
    871   ExpectedVariableOrFunction,
    872   ExpectedFunctionOrMethod,
    873   ExpectedParameter,
    874   ExpectedFunctionMethodOrBlock,
    875   ExpectedFunctionMethodOrClass,
    876   ExpectedFunctionMethodOrParameter,
    877   ExpectedClass,
    878   ExpectedEnum,
    879   ExpectedVariable,
    880   ExpectedMethod,
    881   ExpectedFieldOrGlobalVar,
    882   ExpectedStruct,
    883   ExpectedParameterOrTypedef,
    884   ExpectedVariableOrTypedef,
    885   ExpectedTLSVar,
    886   ExpectedVariableOrField,
    887   ExpectedVariableFieldOrTag,
    888   ExpectedTypeOrNamespace,
    889   ExpectedObjectiveCInterface,
    890   ExpectedMethodOrProperty,
    891   ExpectedStructOrUnion,
    892   ExpectedStructOrUnionOrClass,
    893   ExpectedType,
    894   ExpectedObjCInstanceMethod,
    895   ExpectedObjCInterfaceDeclInitMethod,
    896   ExpectedFunctionVariableOrClass,
    897   ExpectedObjectiveCProtocol,
    898   ExpectedFunctionGlobalVarMethodOrProperty,
    899   ExpectedStructOrUnionOrTypedef,
    900   ExpectedStructOrTypedef,
    901   ExpectedObjectiveCInterfaceOrProtocol,
    902   ExpectedKernelFunction,
    903   ExpectedFunctionWithProtoType,
    904   ExpectedVariableEnumFieldOrTypedef,
    905   ExpectedFunctionMethodEnumOrClass,
    906   ExpectedStructClassVariableFunctionOrInlineNamespace,
    907   ExpectedForMaybeUnused
    908 };
    909 
    910 }  // end namespace clang
    911 
    912 #endif
    913