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/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"
     26 #include <cassert>
     27 
     28 namespace clang {
     29   class ASTContext;
     30   class IdentifierInfo;
     31   class Expr;
     32 
     33 /// \brief Represents information about a change in availability for
     34 /// an entity, which is part of the encoding of the 'availability'
     35 /// attribute.
     36 struct AvailabilityChange {
     37   /// \brief The location of the keyword indicating the kind of change.
     38   SourceLocation KeywordLoc;
     39 
     40   /// \brief The version number at which the change occurred.
     41   VersionTuple Version;
     42 
     43   /// \brief The source range covering the version number.
     44   SourceRange VersionRange;
     45 
     46   /// \brief Determine whether this availability change is valid.
     47   bool isValid() const { return !Version.empty(); }
     48 };
     49 
     50 namespace {
     51 enum AvailabilitySlot {
     52   IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
     53 };
     54 
     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;
     68   }
     69 };
     70 }
     71 
     72 /// \brief Wraps an identifier and optional source location for the identifier.
     73 struct IdentifierLoc {
     74   SourceLocation Loc;
     75   IdentifierInfo *Ident;
     76 
     77   static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
     78                                IdentifierInfo *Ident);
     79 };
     80 
     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;
     85 
     86 /// AttributeList - Represents a syntactic attribute.
     87 ///
     88 /// For a GNU attribute, there are four forms of this construct:
     89 ///
     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.
     94 ///
     95 class AttributeList { // TODO: This should really be called ParsedAttribute
     96 public:
     97   /// The style used to specify an attribute.
     98   enum Syntax {
     99     /// __attribute__((...))
    100     AS_GNU,
    101     /// [[...]]
    102     AS_CXX11,
    103     /// [[...]]
    104     AS_C2x,
    105     /// __declspec(...)
    106     AS_Declspec,
    107     /// [uuid("...")] class Foo
    108     AS_Microsoft,
    109     /// __ptr16, alignas(...), etc.
    110     AS_Keyword,
    111     /// #pragma ...
    112     AS_Pragma,
    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,
    117   };
    118 
    119 private:
    120   IdentifierInfo *AttrName;
    121   IdentifierInfo *ScopeName;
    122   SourceRange AttrRange;
    123   SourceLocation ScopeLoc;
    124   SourceLocation EllipsisLoc;
    125 
    126   unsigned AttrKind : 16;
    127 
    128   /// The number of expression arguments this attribute has.
    129   /// The expressions themselves are stored after the object.
    130   unsigned NumArgs : 16;
    131 
    132   /// Corresponds to the Syntax enum.
    133   unsigned SyntaxUsed : 3;
    134 
    135   /// True if already diagnosed as invalid.
    136   mutable unsigned Invalid : 1;
    137 
    138   /// True if this attribute was used as a type attribute.
    139   mutable unsigned UsedAsTypeAttr : 1;
    140 
    141   /// True if this has the extra information associated with an
    142   /// availability attribute.
    143   unsigned IsAvailability : 1;
    144 
    145   /// True if this has extra information associated with a
    146   /// type_tag_for_datatype attribute.
    147   unsigned IsTypeTagForDatatype : 1;
    148 
    149   /// True if this has extra information associated with a
    150   /// Microsoft __delcspec(property) attribute.
    151   unsigned IsProperty : 1;
    152 
    153   /// True if this has a ParsedType
    154   unsigned HasParsedType : 1;
    155 
    156   /// True if the processing cache is valid.
    157   mutable unsigned HasProcessingCache : 1;
    158 
    159   /// A cached value.
    160   mutable unsigned ProcessingCache : 8;
    161 
    162   /// \brief The location of the 'unavailable' keyword in an
    163   /// availability attribute.
    164   SourceLocation UnavailableLoc;
    165 
    166   const Expr *MessageExpr;
    167 
    168   /// The next attribute in the current position.
    169   AttributeList *NextInPosition;
    170 
    171   /// The next attribute allocated in the current Pool.
    172   AttributeList *NextInPool;
    173 
    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);
    178   }
    179 
    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);
    184   }
    185   const AvailabilityData *getAvailabilityData() const {
    186     return reinterpret_cast<const AvailabilityData*>(getArgsBuffer() + NumArgs);
    187   }
    188 
    189 public:
    190   struct TypeTagForDatatypeData {
    191     ParsedType *MatchingCType;
    192     unsigned LayoutCompatible : 1;
    193     unsigned MustBeNull : 1;
    194   };
    195   struct PropertyData {
    196     IdentifierInfo *GetterId, *SetterId;
    197     PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
    198     : GetterId(getterId), SetterId(setterId) {}
    199   };
    200 
    201 private:
    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);
    207   }
    208 
    209   const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
    210     return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
    211                                                             + NumArgs);
    212   }
    213 
    214   /// The type buffer immediately follows the object and are mutually exclusive
    215   /// with arguments.
    216   ParsedType &getTypeBuffer() {
    217     return *reinterpret_cast<ParsedType *>(this + 1);
    218   }
    219 
    220   const ParsedType &getTypeBuffer() const {
    221     return *reinterpret_cast<const ParsedType *>(this + 1);
    222   }
    223 
    224   /// The property data immediately follows the object is is mutually exclusive
    225   /// with arguments.
    226   PropertyData &getPropertyDataBuffer() {
    227     assert(IsProperty);
    228     return *reinterpret_cast<PropertyData*>(this + 1);
    229   }
    230 
    231   const PropertyData &getPropertyDataBuffer() const {
    232     assert(IsProperty);
    233     return *reinterpret_cast<const PropertyData*>(this + 1);
    234   }
    235 
    236   AttributeList(const AttributeList &) = delete;
    237   void operator=(const AttributeList &) = delete;
    238   void operator delete(void *) = delete;
    239   ~AttributeList() = delete;
    240 
    241   size_t allocated_size() const;
    242 
    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);
    256   }
    257 
    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);
    279   }
    280 
    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,
    287                 Syntax syntaxUsed)
    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();
    294     Args[0] = Parm1;
    295     Args[1] = Parm2;
    296     Args[2] = Parm3;
    297     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
    298   }
    299 
    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);
    317   }
    318 
    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);
    330   }
    331 
    332   /// Constructor for microsoft __declspec(property) attribute.
    333   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
    334                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
    335                 IdentifierInfo *getterId, IdentifierInfo *setterId,
    336                 Syntax syntaxUsed)
    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);
    344   }
    345 
    346   friend class AttributePool;
    347   friend class AttributeFactory;
    348 
    349 public:
    350   enum Kind {
    351     #define PARSED_ATTR(NAME) AT_##NAME,
    352     #include "clang/Sema/AttrParsedAttrList.inc"
    353     #undef PARSED_ATTR
    354     IgnoredAttribute,
    355     UnknownAttribute
    356   };
    357 
    358   IdentifierInfo *getName() const { return AttrName; }
    359   SourceLocation getLoc() const { return AttrRange.getBegin(); }
    360   SourceRange getRange() const { return AttrRange; }
    361 
    362   bool hasScope() const { return ScopeName; }
    363   IdentifierInfo *getScopeName() const { return ScopeName; }
    364   SourceLocation getScopeLoc() const { return ScopeLoc; }
    365 
    366   bool hasParsedType() const { return HasParsedType; }
    367 
    368   /// Is this the Microsoft __declspec(property) attribute?
    369   bool isDeclspecPropertyAttribute() const  {
    370     return IsProperty;
    371   }
    372 
    373   bool isAlignasAttribute() const {
    374     // FIXME: Use a better mechanism to determine this.
    375     return getKind() == AT_Aligned && isKeywordAttribute();
    376   }
    377 
    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();
    382   }
    383   bool isC2xAttribute() const {
    384     return SyntaxUsed == AS_C2x;
    385   }
    386   bool isKeywordAttribute() const {
    387     return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
    388   }
    389 
    390   bool isContextSensitiveKeywordAttribute() const {
    391     return SyntaxUsed == AS_ContextSensitiveKeyword;
    392   }
    393 
    394   bool isInvalid() const { return Invalid; }
    395   void setInvalid(bool b = true) const { Invalid = b; }
    396 
    397   bool hasProcessingCache() const { return HasProcessingCache; }
    398   unsigned getProcessingCache() const {
    399     assert(hasProcessingCache());
    400     return ProcessingCache;
    401   }
    402   void setProcessingCache(unsigned value) const {
    403     ProcessingCache = value;
    404     HasProcessingCache = true;
    405   }
    406 
    407   bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
    408   void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
    409 
    410   bool isPackExpansion() const { return EllipsisLoc.isValid(); }
    411   SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
    412 
    413   Kind getKind() const { return Kind(AttrKind); }
    414   static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
    415                       Syntax SyntaxUsed);
    416 
    417   AttributeList *getNext() const { return NextInPosition; }
    418   void setNext(AttributeList *N) { NextInPosition = N; }
    419 
    420   /// getNumArgs - Return the number of actual arguments to this attribute.
    421   unsigned getNumArgs() const { return NumArgs; }
    422 
    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];
    427   }
    428 
    429   bool isArgExpr(unsigned Arg) const {
    430     return Arg < NumArgs && getArg(Arg).is<Expr*>();
    431   }
    432   Expr *getArgAsExpr(unsigned Arg) const {
    433     return getArg(Arg).get<Expr*>();
    434   }
    435 
    436   bool isArgIdent(unsigned Arg) const {
    437     return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
    438   }
    439   IdentifierLoc *getArgAsIdent(unsigned Arg) const {
    440     return getArg(Arg).get<IdentifierLoc*>();
    441   }
    442 
    443   const AvailabilityChange &getAvailabilityIntroduced() const {
    444     assert(getKind() == AT_Availability && "Not an availability attribute");
    445     return getAvailabilityData()->Changes[IntroducedSlot];
    446   }
    447 
    448   const AvailabilityChange &getAvailabilityDeprecated() const {
    449     assert(getKind() == AT_Availability && "Not an availability attribute");
    450     return getAvailabilityData()->Changes[DeprecatedSlot];
    451   }
    452 
    453   const AvailabilityChange &getAvailabilityObsoleted() const {
    454     assert(getKind() == AT_Availability && "Not an availability attribute");
    455     return getAvailabilityData()->Changes[ObsoletedSlot];
    456   }
    457 
    458   SourceLocation getStrictLoc() const {
    459     assert(getKind() == AT_Availability && "Not an availability attribute");
    460     return getAvailabilityData()->StrictLoc;
    461   }
    462 
    463   SourceLocation getUnavailableLoc() const {
    464     assert(getKind() == AT_Availability && "Not an availability attribute");
    465     return UnavailableLoc;
    466   }
    467 
    468   const Expr * getMessageExpr() const {
    469     assert(getKind() == AT_Availability && "Not an availability attribute");
    470     return MessageExpr;
    471   }
    472 
    473   const Expr *getReplacementExpr() const {
    474     assert(getKind() == AT_Availability && "Not an availability attribute");
    475     return getAvailabilityData()->Replacement;
    476   }
    477 
    478   const ParsedType &getMatchingCType() const {
    479     assert(getKind() == AT_TypeTagForDatatype &&
    480            "Not a type_tag_for_datatype attribute");
    481     return *getTypeTagForDatatypeDataSlot().MatchingCType;
    482   }
    483 
    484   bool getLayoutCompatible() const {
    485     assert(getKind() == AT_TypeTagForDatatype &&
    486            "Not a type_tag_for_datatype attribute");
    487     return getTypeTagForDatatypeDataSlot().LayoutCompatible;
    488   }
    489 
    490   bool getMustBeNull() const {
    491     assert(getKind() == AT_TypeTagForDatatype &&
    492            "Not a type_tag_for_datatype attribute");
    493     return getTypeTagForDatatypeDataSlot().MustBeNull;
    494   }
    495 
    496   const ParsedType &getTypeArg() const {
    497     assert(HasParsedType && "Not a type attribute");
    498     return getTypeBuffer();
    499   }
    500 
    501   const PropertyData &getPropertyData() const {
    502     assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
    503     return getPropertyDataBuffer();
    504   }
    505 
    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;
    510 
    511   bool isTargetSpecificAttr() const;
    512   bool isTypeAttr() const;
    513   bool isStmtAttr() const;
    514 
    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>>
    523                          &MatchRules) const;
    524   bool diagnoseLangOpts(class Sema &S) const;
    525   bool existsInTarget(const TargetInfo &Target) const;
    526   bool isKnownToGCC() const;
    527   bool isSupportedByPragmaAttribute() const;
    528 
    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;
    535 };
    536 
    537 /// A factory, from which one makes pools, from which one creates
    538 /// individual attributes which are deallocated with the pool.
    539 ///
    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 {
    543 public:
    544   enum {
    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*),
    556     PropertyAllocSize =
    557       sizeof(AttributeList)
    558       + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
    559         / sizeof(void*) * sizeof(void*)
    560   };
    561 
    562 private:
    563   enum {
    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*)
    571   };
    572 
    573   llvm::BumpPtrAllocator Alloc;
    574 
    575   /// Free lists.  The index is determined by the following formula:
    576   ///   (size - sizeof(AttributeList)) / sizeof(void*)
    577   SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
    578 
    579   // The following are the private interface used by AttributePool.
    580   friend class AttributePool;
    581 
    582   /// Allocate an attribute of the given size.
    583   void *allocate(size_t size);
    584 
    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);
    591 
    592 public:
    593   AttributeFactory();
    594   ~AttributeFactory();
    595 };
    596 
    597 class AttributePool {
    598   AttributeFactory &Factory;
    599   AttributeList *Head;
    600 
    601   void *allocate(size_t size) {
    602     return Factory.allocate(size);
    603   }
    604 
    605   AttributeList *add(AttributeList *attr) {
    606     // We don't care about the order of the pool.
    607     attr->NextInPool = Head;
    608     Head = attr;
    609     return attr;
    610   }
    611 
    612   void takePool(AttributeList *pool);
    613 
    614 public:
    615   /// Create a new pool for a factory.
    616   AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
    617 
    618   AttributePool(const AttributePool &) = delete;
    619 
    620   /// Move the given pool's allocations to this pool.
    621   AttributePool(AttributePool &&pool) : Factory(pool.Factory), Head(pool.Head) {
    622     pool.Head = nullptr;
    623   }
    624 
    625   AttributeFactory &getFactory() const { return Factory; }
    626 
    627   void clear() {
    628     if (Head) {
    629       Factory.reclaimPool(Head);
    630       Head = nullptr;
    631     }
    632   }
    633 
    634   /// Take the given pool's allocations and add them to this pool.
    635   void takeAllFrom(AttributePool &pool) {
    636     if (pool.Head) {
    637       takePool(pool.Head);
    638       pool.Head = nullptr;
    639     }
    640   }
    641 
    642   ~AttributePool() {
    643     if (Head) Factory.reclaimPool(Head);
    644   }
    645 
    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,
    654                                           scopeName, scopeLoc,
    655                                           args, numArgs, syntax,
    656                                           ellipsisLoc));
    657   }
    658 
    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,
    671                                           scopeName, scopeLoc,
    672                                           Param, introduced, deprecated,
    673                                           obsoleted, unavailable, MessageExpr,
    674                                           syntax, strict, ReplacementExpr));
    675   }
    676 
    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,
    686                                           scopeName, scopeLoc,
    687                                           Param1, Param2, Param3,
    688                                           syntax));
    689   }
    690 
    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,
    699                                           scopeName, scopeLoc,
    700                                           argumentKind, matchingCType,
    701                                           layoutCompatible, mustBeNull,
    702                                           syntax));
    703   }
    704 
    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,
    711                                           scopeName, scopeLoc,
    712                                           typeArg, syntaxUsed));
    713   }
    714 
    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,
    722                                           scopeName, scopeLoc,
    723                                           getterId, setterId,
    724                                           syntaxUsed));
    725   }
    726 };
    727 
    728 /// ParsedAttributes - A collection of parsed attributes.  Currently
    729 /// we don't differentiate between the various attribute syntaxes,
    730 /// which is basically silly.
    731 ///
    732 /// Right now this is a very lightweight container, but the expectation
    733 /// is that this will become significantly more serious.
    734 class ParsedAttributes {
    735 public:
    736   ParsedAttributes(AttributeFactory &factory)
    737     : pool(factory), list(nullptr) {
    738   }
    739 
    740   ParsedAttributes(const ParsedAttributes &) = delete;
    741 
    742   AttributePool &getPool() const { return pool; }
    743 
    744   bool empty() const { return list == nullptr; }
    745 
    746   void add(AttributeList *newAttr) {
    747     assert(newAttr);
    748     assert(newAttr->getNext() == nullptr);
    749     newAttr->setNext(list);
    750     list = newAttr;
    751   }
    752 
    753   void addAll(AttributeList *newList) {
    754     if (!newList) return;
    755 
    756     AttributeList *lastInNewList = newList;
    757     while (AttributeList *next = lastInNewList->getNext())
    758       lastInNewList = next;
    759 
    760     lastInNewList->setNext(list);
    761     list = newList;
    762   }
    763 
    764   void addAllAtEnd(AttributeList *newList) {
    765     if (!list) {
    766       list = newList;
    767       return;
    768     }
    769 
    770     AttributeList *lastInList = list;
    771     while (AttributeList *next = lastInList->getNext())
    772       lastInList = next;
    773 
    774     lastInList->setNext(newList);
    775   }
    776 
    777   void set(AttributeList *newList) {
    778     list = newList;
    779   }
    780 
    781   void takeAllFrom(ParsedAttributes &attrs) {
    782     addAll(attrs.list);
    783     attrs.list = nullptr;
    784     pool.takeAllFrom(attrs.pool);
    785   }
    786 
    787   void clear() { list = nullptr; pool.clear(); }
    788   AttributeList *getList() const { return list; }
    789 
    790   void clearListOnly() { list = nullptr; }
    791 
    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; }
    795 
    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);
    805     add(attr);
    806     return attr;
    807   }
    808 
    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);
    824     add(attr);
    825     return attr;
    826   }
    827 
    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);
    838     add(attr);
    839     return attr;
    840   }
    841 
    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,
    851                                     scopeName, scopeLoc,
    852                                     argumentKind, matchingCType,
    853                                     layoutCompatible, mustBeNull, syntax);
    854     add(attr);
    855     return attr;
    856   }
    857 
    858   /// Add an attribute with a single type argument.
    859   AttributeList *
    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);
    866     add(attr);
    867     return attr;
    868   }
    869 
    870   /// Add microsoft __delspec(property) attribute.
    871   AttributeList *
    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);
    879     add(attr);
    880     return attr;
    881   }
    882 
    883 private:
    884   mutable AttributePool pool;
    885   AttributeList *list;
    886 };
    887 
    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,
    893   AANT_ArgumentString,
    894   AANT_ArgumentIdentifier
    895 };
    896 
    897 /// These constants match the enumerated choices of
    898 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
    899 enum AttributeDeclKind {
    900   ExpectedFunction,
    901   ExpectedUnion,
    902   ExpectedVariableOrFunction,
    903   ExpectedFunctionOrGlobalVar,
    904   ExpectedFunctionVariableOrObjCInterface,
    905   ExpectedFunctionOrMethod,
    906   ExpectedParameter,
    907   ExpectedFunctionMethodOrBlock,
    908   ExpectedFunctionMethodOrClass,
    909   ExpectedFunctionMethodOrParameter,
    910   ExpectedFunctionMethodOrGlobalVar,
    911   ExpectedClass,
    912   ExpectedEnum,
    913   ExpectedVariable,
    914   ExpectedMethod,
    915   ExpectedFieldOrGlobalVar,
    916   ExpectedStruct,
    917   ExpectedParameterOrTypedef,
    918   ExpectedVariableOrTypedef,
    919   ExpectedTLSVar,
    920   ExpectedVariableOrField,
    921   ExpectedVariableFieldOrTag,
    922   ExpectedTypeOrNamespace,
    923   ExpectedObjectiveCInterface,
    924   ExpectedMethodOrProperty,
    925   ExpectedFunctionOrMethodOrProperty,
    926   ExpectedStructOrUnion,
    927   ExpectedStructOrUnionOrClass,
    928   ExpectedType,
    929   ExpectedObjCInstanceMethod,
    930   ExpectedObjCInterfaceDeclInitMethod,
    931   ExpectedFunctionVariableOrClass,
    932   ExpectedFunctionVariableClassOrObjCInterface,
    933   ExpectedObjectiveCProtocol,
    934   ExpectedStaticOrTLSVar,
    935   ExpectedFunctionGlobalVarMethodOrProperty,
    936   ExpectedStructOrUnionOrTypedef,
    937   ExpectedStructOrTypedef,
    938   ExpectedObjectiveCInterfaceOrProtocol,
    939   ExpectedKernelFunction,
    940   ExpectedFunctionWithProtoType,
    941   ExpectedVariableEnumFieldOrTypedef,
    942   ExpectedFunctionMethodEnumOrClass,
    943   ExpectedStructClassVariableFunctionOrInlineNamespace,
    944   ExpectedForMaybeUnused,
    945   ExpectedEnumOrClass,
    946   ExpectedNamedDecl,
    947 };
    948 
    949 }  // end namespace clang
    950 
    951 #endif
    952