clang API Documentation

AttributeList.h
Go to the documentation of this file.
00001 //===--- AttributeList.h - Parsed attribute sets ----------------*- C++ -*-===//
00002 //
00003 //                     The LLVM Compiler Infrastructure
00004 //
00005 // This file is distributed under the University of Illinois Open Source
00006 // License. See LICENSE.TXT for details.
00007 //
00008 //===----------------------------------------------------------------------===//
00009 //
00010 // This file defines the AttributeList class, which is used to collect
00011 // parsed attributes.
00012 //
00013 //===----------------------------------------------------------------------===//
00014 
00015 #ifndef LLVM_CLANG_SEMA_ATTRIBUTELIST_H
00016 #define LLVM_CLANG_SEMA_ATTRIBUTELIST_H
00017 
00018 #include "clang/Basic/SourceLocation.h"
00019 #include "clang/Basic/VersionTuple.h"
00020 #include "clang/Sema/Ownership.h"
00021 #include "llvm/ADT/PointerUnion.h"
00022 #include "llvm/ADT/SmallVector.h"
00023 #include "llvm/ADT/Triple.h"
00024 #include "llvm/Support/Allocator.h"
00025 #include <cassert>
00026 
00027 namespace clang {
00028   class ASTContext;
00029   class IdentifierInfo;
00030   class Expr;
00031 
00032 /// \brief Represents information about a change in availability for
00033 /// an entity, which is part of the encoding of the 'availability'
00034 /// attribute.
00035 struct AvailabilityChange {
00036   /// \brief The location of the keyword indicating the kind of change.
00037   SourceLocation KeywordLoc;
00038 
00039   /// \brief The version number at which the change occurred.
00040   VersionTuple Version;
00041 
00042   /// \brief The source range covering the version number.
00043   SourceRange VersionRange;
00044 
00045   /// \brief Determine whether this availability change is valid.
00046   bool isValid() const { return !Version.empty(); }
00047 };
00048 
00049 /// \brief Wraps an identifier and optional source location for the identifier.
00050 struct IdentifierLoc {
00051   SourceLocation Loc;
00052   IdentifierInfo *Ident;
00053 
00054   static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
00055                                IdentifierInfo *Ident);
00056 };
00057 
00058 /// \brief A union of the various pointer types that can be passed to an
00059 /// AttributeList as an argument.
00060 typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion;
00061 typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector;
00062 
00063 /// AttributeList - Represents a syntactic attribute.
00064 ///
00065 /// For a GNU attribute, there are four forms of this construct:
00066 ///
00067 /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused.
00068 /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused.
00069 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used.
00070 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used.
00071 ///
00072 class AttributeList { // TODO: This should really be called ParsedAttribute
00073 public:
00074   /// The style used to specify an attribute.
00075   enum Syntax {
00076     /// __attribute__((...))
00077     AS_GNU,
00078     /// [[...]]
00079     AS_CXX11,
00080     /// __declspec(...)
00081     AS_Declspec,
00082     /// __ptr16, alignas(...), etc.
00083     AS_Keyword,
00084     /// #pragma ...
00085     AS_Pragma
00086   };
00087 
00088 private:
00089   IdentifierInfo *AttrName;
00090   IdentifierInfo *ScopeName;
00091   SourceRange AttrRange;
00092   SourceLocation ScopeLoc;
00093   SourceLocation EllipsisLoc;
00094 
00095   /// The number of expression arguments this attribute has.
00096   /// The expressions themselves are stored after the object.
00097   unsigned NumArgs : 16;
00098 
00099   /// Corresponds to the Syntax enum.
00100   unsigned SyntaxUsed : 2;
00101 
00102   /// True if already diagnosed as invalid.
00103   mutable unsigned Invalid : 1;
00104 
00105   /// True if this attribute was used as a type attribute.
00106   mutable unsigned UsedAsTypeAttr : 1;
00107 
00108   /// True if this has the extra information associated with an
00109   /// availability attribute.
00110   unsigned IsAvailability : 1;
00111 
00112   /// True if this has extra information associated with a
00113   /// type_tag_for_datatype attribute.
00114   unsigned IsTypeTagForDatatype : 1;
00115 
00116   /// True if this has extra information associated with a
00117   /// Microsoft __delcspec(property) attribute.
00118   unsigned IsProperty : 1;
00119 
00120   /// True if this has a ParsedType
00121   unsigned HasParsedType : 1;
00122 
00123   unsigned AttrKind : 8;
00124 
00125   /// \brief The location of the 'unavailable' keyword in an
00126   /// availability attribute.
00127   SourceLocation UnavailableLoc;
00128   
00129   const Expr *MessageExpr;
00130 
00131   /// The next attribute in the current position.
00132   AttributeList *NextInPosition;
00133 
00134   /// The next attribute allocated in the current Pool.
00135   AttributeList *NextInPool;
00136 
00137   /// Arguments, if any, are stored immediately following the object.
00138   ArgsUnion *getArgsBuffer() {
00139     return reinterpret_cast<ArgsUnion*>(this+1);
00140   }
00141   ArgsUnion const *getArgsBuffer() const {
00142     return reinterpret_cast<ArgsUnion const *>(this+1);
00143   }
00144 
00145   enum AvailabilitySlot {
00146     IntroducedSlot, DeprecatedSlot, ObsoletedSlot
00147   };
00148 
00149   /// Availability information is stored immediately following the arguments,
00150   /// if any, at the end of the object.
00151   AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) {    
00152     return reinterpret_cast<AvailabilityChange*>(getArgsBuffer()
00153                                                  + NumArgs)[index];
00154   }
00155   const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const {
00156     return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer()
00157                                                        + NumArgs)[index];
00158   }
00159 
00160 public:
00161   struct TypeTagForDatatypeData {
00162     ParsedType *MatchingCType;
00163     unsigned LayoutCompatible : 1;
00164     unsigned MustBeNull : 1;
00165   };
00166   struct PropertyData {
00167     IdentifierInfo *GetterId, *SetterId;
00168     PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
00169     : GetterId(getterId), SetterId(setterId) {}
00170   };
00171 
00172 private:
00173   /// Type tag information is stored immediately following the arguments, if
00174   /// any, at the end of the object.  They are mutually exlusive with
00175   /// availability slots.
00176   TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
00177     return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs);
00178   }
00179 
00180   const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
00181     return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer()
00182                                                             + NumArgs);
00183   }
00184 
00185   /// The type buffer immediately follows the object and are mutually exclusive
00186   /// with arguments.
00187   ParsedType &getTypeBuffer() {
00188     return *reinterpret_cast<ParsedType *>(this + 1);
00189   }
00190 
00191   const ParsedType &getTypeBuffer() const {
00192     return *reinterpret_cast<const ParsedType *>(this + 1);
00193   }
00194 
00195   /// The property data immediately follows the object is is mutually exclusive
00196   /// with arguments.
00197   PropertyData &getPropertyDataBuffer() {
00198     assert(IsProperty);
00199     return *reinterpret_cast<PropertyData*>(this + 1);
00200   }
00201 
00202   const PropertyData &getPropertyDataBuffer() const {
00203     assert(IsProperty);
00204     return *reinterpret_cast<const PropertyData*>(this + 1);
00205   }
00206 
00207   AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION;
00208   void operator=(const AttributeList &) LLVM_DELETED_FUNCTION;
00209   void operator delete(void *) LLVM_DELETED_FUNCTION;
00210   ~AttributeList() LLVM_DELETED_FUNCTION;
00211 
00212   size_t allocated_size() const;
00213 
00214   /// Constructor for attributes with expression arguments.
00215   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
00216                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
00217                 ArgsUnion *args, unsigned numArgs,
00218                 Syntax syntaxUsed, SourceLocation ellipsisLoc)
00219     : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
00220       ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs),
00221       SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false),
00222       IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
00223       HasParsedType(false), NextInPosition(nullptr), NextInPool(nullptr) {
00224     if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
00225     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
00226   }
00227 
00228   /// Constructor for availability attributes.
00229   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
00230                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
00231                 IdentifierLoc *Parm, const AvailabilityChange &introduced,
00232                 const AvailabilityChange &deprecated,
00233                 const AvailabilityChange &obsoleted,
00234                 SourceLocation unavailable, 
00235                 const Expr *messageExpr,
00236                 Syntax syntaxUsed)
00237     : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
00238       ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
00239       Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
00240       IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
00241       UnavailableLoc(unavailable), MessageExpr(messageExpr),
00242       NextInPosition(nullptr), NextInPool(nullptr) {
00243     ArgsUnion PVal(Parm);
00244     memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
00245     new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced);
00246     new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated);
00247     new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted);
00248     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
00249   }
00250 
00251   /// Constructor for objc_bridge_related attributes.
00252   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
00253                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
00254                 IdentifierLoc *Parm1,
00255                 IdentifierLoc *Parm2,
00256                 IdentifierLoc *Parm3,
00257                 Syntax syntaxUsed)
00258   : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
00259     ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed),
00260     Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
00261     IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
00262     NextInPosition(nullptr), NextInPool(nullptr) {
00263     ArgsVector Args;
00264     Args.push_back(Parm1);
00265     Args.push_back(Parm2);
00266     Args.push_back(Parm3);
00267     memcpy(getArgsBuffer(), &Args[0], 3 * sizeof(ArgsUnion));
00268     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
00269   }
00270   
00271   /// Constructor for type_tag_for_datatype attribute.
00272   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
00273                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
00274                 IdentifierLoc *ArgKind, ParsedType matchingCType,
00275                 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed)
00276     : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
00277       ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed),
00278       Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
00279       IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false),
00280       NextInPosition(nullptr), NextInPool(nullptr) {
00281     ArgsUnion PVal(ArgKind);
00282     memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
00283     TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
00284     new (&ExtraData.MatchingCType) ParsedType(matchingCType);
00285     ExtraData.LayoutCompatible = layoutCompatible;
00286     ExtraData.MustBeNull = mustBeNull;
00287     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
00288   }
00289 
00290   /// Constructor for attributes with a single type argument.
00291   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
00292                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
00293                 ParsedType typeArg, Syntax syntaxUsed)
00294       : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
00295         ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
00296         Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
00297         IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
00298         NextInPosition(nullptr), NextInPool(nullptr) {
00299     new (&getTypeBuffer()) ParsedType(typeArg);
00300     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
00301   }
00302 
00303   /// Constructor for microsoft __declspec(property) attribute.
00304   AttributeList(IdentifierInfo *attrName, SourceRange attrRange,
00305                 IdentifierInfo *scopeName, SourceLocation scopeLoc,
00306                 IdentifierInfo *getterId, IdentifierInfo *setterId,
00307                 Syntax syntaxUsed)
00308     : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange),
00309       ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed),
00310       Invalid(false), UsedAsTypeAttr(false), IsAvailability(false),
00311       IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false),
00312       NextInPosition(nullptr), NextInPool(nullptr) {
00313     new (&getPropertyDataBuffer()) PropertyData(getterId, setterId);
00314     AttrKind = getKind(getName(), getScopeName(), syntaxUsed);
00315   }
00316 
00317   friend class AttributePool;
00318   friend class AttributeFactory;
00319 
00320 public:
00321   enum Kind {           
00322     #define PARSED_ATTR(NAME) AT_##NAME,
00323     #include "clang/Sema/AttrParsedAttrList.inc"
00324     #undef PARSED_ATTR
00325     IgnoredAttribute,
00326     UnknownAttribute
00327   };
00328 
00329   IdentifierInfo *getName() const { return AttrName; }
00330   SourceLocation getLoc() const { return AttrRange.getBegin(); }
00331   SourceRange getRange() const { return AttrRange; }
00332   
00333   bool hasScope() const { return ScopeName; }
00334   IdentifierInfo *getScopeName() const { return ScopeName; }
00335   SourceLocation getScopeLoc() const { return ScopeLoc; }
00336   
00337   bool hasParsedType() const { return HasParsedType; }
00338 
00339   /// Is this the Microsoft __declspec(property) attribute?
00340   bool isDeclspecPropertyAttribute() const  {
00341     return IsProperty;
00342   }
00343 
00344   bool isAlignasAttribute() const {
00345     // FIXME: Use a better mechanism to determine this.
00346     return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword;
00347   }
00348 
00349   bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
00350   bool isCXX11Attribute() const {
00351     return SyntaxUsed == AS_CXX11 || isAlignasAttribute();
00352   }
00353   bool isKeywordAttribute() const { return SyntaxUsed == AS_Keyword; }
00354 
00355   bool isInvalid() const { return Invalid; }
00356   void setInvalid(bool b = true) const { Invalid = b; }
00357 
00358   bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
00359   void setUsedAsTypeAttr() { UsedAsTypeAttr = true; }
00360 
00361   bool isPackExpansion() const { return EllipsisLoc.isValid(); }
00362   SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
00363 
00364   Kind getKind() const { return Kind(AttrKind); }
00365   static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope,
00366                       Syntax SyntaxUsed);
00367 
00368   AttributeList *getNext() const { return NextInPosition; }
00369   void setNext(AttributeList *N) { NextInPosition = N; }
00370 
00371   /// getNumArgs - Return the number of actual arguments to this attribute.
00372   unsigned getNumArgs() const { return NumArgs; }
00373 
00374   /// getArg - Return the specified argument.
00375   ArgsUnion getArg(unsigned Arg) const {
00376     assert(Arg < NumArgs && "Arg access out of range!");
00377     return getArgsBuffer()[Arg];
00378   }
00379 
00380   bool isArgExpr(unsigned Arg) const {
00381     return Arg < NumArgs && getArg(Arg).is<Expr*>();
00382   }
00383   Expr *getArgAsExpr(unsigned Arg) const {
00384     return getArg(Arg).get<Expr*>();
00385   }
00386 
00387   bool isArgIdent(unsigned Arg) const {
00388     return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>();
00389   }
00390   IdentifierLoc *getArgAsIdent(unsigned Arg) const {
00391     return getArg(Arg).get<IdentifierLoc*>();
00392   }
00393 
00394   const AvailabilityChange &getAvailabilityIntroduced() const {
00395     assert(getKind() == AT_Availability && "Not an availability attribute");
00396     return getAvailabilitySlot(IntroducedSlot);
00397   }
00398 
00399   const AvailabilityChange &getAvailabilityDeprecated() const {
00400     assert(getKind() == AT_Availability && "Not an availability attribute");
00401     return getAvailabilitySlot(DeprecatedSlot);
00402   }
00403 
00404   const AvailabilityChange &getAvailabilityObsoleted() const {
00405     assert(getKind() == AT_Availability && "Not an availability attribute");
00406     return getAvailabilitySlot(ObsoletedSlot);
00407   }
00408 
00409   SourceLocation getUnavailableLoc() const {
00410     assert(getKind() == AT_Availability && "Not an availability attribute");
00411     return UnavailableLoc;
00412   }
00413   
00414   const Expr * getMessageExpr() const {
00415     assert(getKind() == AT_Availability && "Not an availability attribute");
00416     return MessageExpr;
00417   }
00418 
00419   const ParsedType &getMatchingCType() const {
00420     assert(getKind() == AT_TypeTagForDatatype &&
00421            "Not a type_tag_for_datatype attribute");
00422     return *getTypeTagForDatatypeDataSlot().MatchingCType;
00423   }
00424 
00425   bool getLayoutCompatible() const {
00426     assert(getKind() == AT_TypeTagForDatatype &&
00427            "Not a type_tag_for_datatype attribute");
00428     return getTypeTagForDatatypeDataSlot().LayoutCompatible;
00429   }
00430 
00431   bool getMustBeNull() const {
00432     assert(getKind() == AT_TypeTagForDatatype &&
00433            "Not a type_tag_for_datatype attribute");
00434     return getTypeTagForDatatypeDataSlot().MustBeNull;
00435   }
00436 
00437   const ParsedType &getTypeArg() const {
00438     assert(HasParsedType && "Not a type attribute");
00439     return getTypeBuffer();
00440   }
00441 
00442   const PropertyData &getPropertyData() const {
00443     assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute");
00444     return getPropertyDataBuffer();
00445   }
00446 
00447   /// \brief Get an index into the attribute spelling list
00448   /// defined in Attr.td. This index is used by an attribute
00449   /// to pretty print itself.
00450   unsigned getAttributeSpellingListIndex() const;
00451 
00452   bool isTargetSpecificAttr() const;
00453   bool isTypeAttr() const;
00454 
00455   bool hasCustomParsing() const;
00456   unsigned getMinArgs() const;
00457   unsigned getMaxArgs() const;
00458   bool hasVariadicArg() const;
00459   bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
00460   bool diagnoseLangOpts(class Sema &S) const;
00461   bool existsInTarget(const llvm::Triple &T) const;
00462   bool isKnownToGCC() const;
00463 
00464   /// \brief If the parsed attribute has a semantic equivalent, and it would
00465   /// have a semantic Spelling enumeration (due to having semantically-distinct
00466   /// spelling variations), return the value of that semantic spelling. If the
00467   /// parsed attribute does not have a semantic equivalent, or would not have
00468   /// a Spelling enumeration, the value UINT_MAX is returned.
00469   unsigned getSemanticSpelling() const;
00470 };
00471 
00472 /// A factory, from which one makes pools, from which one creates
00473 /// individual attributes which are deallocated with the pool.
00474 ///
00475 /// Note that it's tolerably cheap to create and destroy one of
00476 /// these as long as you don't actually allocate anything in it.
00477 class AttributeFactory {
00478 public:
00479   enum {
00480     /// The required allocation size of an availability attribute,
00481     /// which we want to ensure is a multiple of sizeof(void*).
00482     AvailabilityAllocSize =
00483       sizeof(AttributeList)
00484       + ((3 * sizeof(AvailabilityChange) + sizeof(void*) +
00485          sizeof(ArgsUnion) - 1)
00486          / sizeof(void*) * sizeof(void*)),
00487     TypeTagForDatatypeAllocSize =
00488       sizeof(AttributeList)
00489       + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) +
00490          sizeof(ArgsUnion) - 1)
00491         / sizeof(void*) * sizeof(void*),
00492     PropertyAllocSize =
00493       sizeof(AttributeList)
00494       + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1)
00495         / sizeof(void*) * sizeof(void*)
00496   };
00497 
00498 private:
00499   enum {
00500     /// The number of free lists we want to be sure to support
00501     /// inline.  This is just enough that availability attributes
00502     /// don't surpass it.  It's actually very unlikely we'll see an
00503     /// attribute that needs more than that; on x86-64 you'd need 10
00504     /// expression arguments, and on i386 you'd need 19.
00505     InlineFreeListsCapacity =
00506       1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*)
00507   };
00508 
00509   llvm::BumpPtrAllocator Alloc;
00510 
00511   /// Free lists.  The index is determined by the following formula:
00512   ///   (size - sizeof(AttributeList)) / sizeof(void*)
00513   SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists;
00514 
00515   // The following are the private interface used by AttributePool.
00516   friend class AttributePool;
00517 
00518   /// Allocate an attribute of the given size.
00519   void *allocate(size_t size);
00520 
00521   /// Reclaim all the attributes in the given pool chain, which is
00522   /// non-empty.  Note that the current implementation is safe
00523   /// against reclaiming things which were not actually allocated
00524   /// with the allocator, although of course it's important to make
00525   /// sure that their allocator lives at least as long as this one.
00526   void reclaimPool(AttributeList *head);
00527 
00528 public:
00529   AttributeFactory();
00530   ~AttributeFactory();
00531 };
00532 
00533 class AttributePool {
00534   AttributeFactory &Factory;
00535   AttributeList *Head;
00536 
00537   void *allocate(size_t size) {
00538     return Factory.allocate(size);
00539   }
00540 
00541   AttributeList *add(AttributeList *attr) {
00542     // We don't care about the order of the pool.
00543     attr->NextInPool = Head;
00544     Head = attr;
00545     return attr;
00546   }
00547 
00548   void takePool(AttributeList *pool);
00549 
00550 public:
00551   /// Create a new pool for a factory.
00552   AttributePool(AttributeFactory &factory) : Factory(factory), Head(nullptr) {}
00553 
00554   /// Move the given pool's allocations to this pool.
00555   AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) {
00556     pool.Head = nullptr;
00557   }
00558 
00559   AttributeFactory &getFactory() const { return Factory; }
00560 
00561   void clear() {
00562     if (Head) {
00563       Factory.reclaimPool(Head);
00564       Head = nullptr;
00565     }
00566   }
00567 
00568   /// Take the given pool's allocations and add them to this pool.
00569   void takeAllFrom(AttributePool &pool) {
00570     if (pool.Head) {
00571       takePool(pool.Head);
00572       pool.Head = nullptr;
00573     }
00574   }
00575 
00576   ~AttributePool() {
00577     if (Head) Factory.reclaimPool(Head);
00578   }
00579 
00580   AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
00581                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
00582                         ArgsUnion *args, unsigned numArgs,
00583                         AttributeList::Syntax syntax,
00584                         SourceLocation ellipsisLoc = SourceLocation()) {
00585     void *memory = allocate(sizeof(AttributeList)
00586                             + numArgs * sizeof(ArgsUnion));
00587     return add(new (memory) AttributeList(attrName, attrRange,
00588                                           scopeName, scopeLoc,
00589                                           args, numArgs, syntax,
00590                                           ellipsisLoc));
00591   }
00592 
00593   AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
00594                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
00595                         IdentifierLoc *Param,
00596                         const AvailabilityChange &introduced,
00597                         const AvailabilityChange &deprecated,
00598                         const AvailabilityChange &obsoleted,
00599                         SourceLocation unavailable,
00600                         const Expr *MessageExpr,
00601                         AttributeList::Syntax syntax) {
00602     void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
00603     return add(new (memory) AttributeList(attrName, attrRange,
00604                                           scopeName, scopeLoc,
00605                                           Param, introduced, deprecated,
00606                                           obsoleted, unavailable, MessageExpr,
00607                                           syntax));
00608   }
00609 
00610   AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange,
00611                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
00612                         IdentifierLoc *Param1,
00613                         IdentifierLoc *Param2,
00614                         IdentifierLoc *Param3,
00615                         AttributeList::Syntax syntax) {
00616     size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion);
00617     void *memory = allocate(size);
00618     return add(new (memory) AttributeList(attrName, attrRange,
00619                                           scopeName, scopeLoc,
00620                                           Param1, Param2, Param3,
00621                                           syntax));
00622   }
00623 
00624   AttributeList *createTypeTagForDatatype(
00625                     IdentifierInfo *attrName, SourceRange attrRange,
00626                     IdentifierInfo *scopeName, SourceLocation scopeLoc,
00627                     IdentifierLoc *argumentKind, ParsedType matchingCType,
00628                     bool layoutCompatible, bool mustBeNull,
00629                     AttributeList::Syntax syntax) {
00630     void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
00631     return add(new (memory) AttributeList(attrName, attrRange,
00632                                           scopeName, scopeLoc,
00633                                           argumentKind, matchingCType,
00634                                           layoutCompatible, mustBeNull,
00635                                           syntax));
00636   }
00637 
00638   AttributeList *createTypeAttribute(
00639                     IdentifierInfo *attrName, SourceRange attrRange,
00640                     IdentifierInfo *scopeName, SourceLocation scopeLoc,
00641                     ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
00642     void *memory = allocate(sizeof(AttributeList) + sizeof(void *));
00643     return add(new (memory) AttributeList(attrName, attrRange,
00644                                           scopeName, scopeLoc,
00645                                           typeArg, syntaxUsed));
00646   }
00647 
00648   AttributeList *createPropertyAttribute(
00649                     IdentifierInfo *attrName, SourceRange attrRange,
00650                     IdentifierInfo *scopeName, SourceLocation scopeLoc,
00651                     IdentifierInfo *getterId, IdentifierInfo *setterId,
00652                     AttributeList::Syntax syntaxUsed) {
00653     void *memory = allocate(AttributeFactory::PropertyAllocSize);
00654     return add(new (memory) AttributeList(attrName, attrRange,
00655                                           scopeName, scopeLoc,
00656                                           getterId, setterId,
00657                                           syntaxUsed));
00658   }
00659 };
00660 
00661 /// ParsedAttributes - A collection of parsed attributes.  Currently
00662 /// we don't differentiate between the various attribute syntaxes,
00663 /// which is basically silly.
00664 ///
00665 /// Right now this is a very lightweight container, but the expectation
00666 /// is that this will become significantly more serious.
00667 class ParsedAttributes {
00668 public:
00669   ParsedAttributes(AttributeFactory &factory)
00670     : pool(factory), list(nullptr) {
00671   }
00672 
00673   ParsedAttributes(const ParsedAttributes &) LLVM_DELETED_FUNCTION;
00674 
00675   AttributePool &getPool() const { return pool; }
00676 
00677   bool empty() const { return list == nullptr; }
00678 
00679   void add(AttributeList *newAttr) {
00680     assert(newAttr);
00681     assert(newAttr->getNext() == nullptr);
00682     newAttr->setNext(list);
00683     list = newAttr;
00684   }
00685 
00686   void addAll(AttributeList *newList) {
00687     if (!newList) return;
00688 
00689     AttributeList *lastInNewList = newList;
00690     while (AttributeList *next = lastInNewList->getNext())
00691       lastInNewList = next;
00692 
00693     lastInNewList->setNext(list);
00694     list = newList;
00695   }
00696 
00697   void set(AttributeList *newList) {
00698     list = newList;
00699   }
00700 
00701   void takeAllFrom(ParsedAttributes &attrs) {
00702     addAll(attrs.list);
00703     attrs.list = nullptr;
00704     pool.takeAllFrom(attrs.pool);
00705   }
00706 
00707   void clear() { list = nullptr; pool.clear(); }
00708   AttributeList *getList() const { return list; }
00709 
00710   /// Returns a reference to the attribute list.  Try not to introduce
00711   /// dependencies on this method, it may not be long-lived.
00712   AttributeList *&getListRef() { return list; }
00713 
00714   /// Add attribute with expression arguments.
00715   AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
00716                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
00717                         ArgsUnion *args, unsigned numArgs,
00718                         AttributeList::Syntax syntax,
00719                         SourceLocation ellipsisLoc = SourceLocation()) {
00720     AttributeList *attr =
00721       pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs,
00722                   syntax, ellipsisLoc);
00723     add(attr);
00724     return attr;
00725   }
00726 
00727   /// Add availability attribute.
00728   AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
00729                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
00730                         IdentifierLoc *Param,
00731                         const AvailabilityChange &introduced,
00732                         const AvailabilityChange &deprecated,
00733                         const AvailabilityChange &obsoleted,
00734                         SourceLocation unavailable,
00735                         const Expr *MessageExpr,
00736                         AttributeList::Syntax syntax) {
00737     AttributeList *attr =
00738       pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
00739                   deprecated, obsoleted, unavailable, MessageExpr, syntax);
00740     add(attr);
00741     return attr;
00742   }
00743 
00744   /// Add objc_bridge_related attribute.
00745   AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange,
00746                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
00747                         IdentifierLoc *Param1,
00748                         IdentifierLoc *Param2,
00749                         IdentifierLoc *Param3,
00750                         AttributeList::Syntax syntax) {
00751     AttributeList *attr =
00752       pool.create(attrName, attrRange, scopeName, scopeLoc,
00753                   Param1, Param2, Param3, syntax);
00754     add(attr);
00755     return attr;
00756   }
00757 
00758   /// Add type_tag_for_datatype attribute.
00759   AttributeList *addNewTypeTagForDatatype(
00760                         IdentifierInfo *attrName, SourceRange attrRange,
00761                         IdentifierInfo *scopeName, SourceLocation scopeLoc,
00762                         IdentifierLoc *argumentKind, ParsedType matchingCType,
00763                         bool layoutCompatible, bool mustBeNull,
00764                         AttributeList::Syntax syntax) {
00765     AttributeList *attr =
00766       pool.createTypeTagForDatatype(attrName, attrRange,
00767                                     scopeName, scopeLoc,
00768                                     argumentKind, matchingCType,
00769                                     layoutCompatible, mustBeNull, syntax);
00770     add(attr);
00771     return attr;
00772   }
00773 
00774   /// Add an attribute with a single type argument.
00775   AttributeList *
00776   addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
00777                  IdentifierInfo *scopeName, SourceLocation scopeLoc,
00778                  ParsedType typeArg, AttributeList::Syntax syntaxUsed) {
00779     AttributeList *attr =
00780         pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
00781                                  typeArg, syntaxUsed);
00782     add(attr);
00783     return attr;
00784   }
00785 
00786   /// Add microsoft __delspec(property) attribute.
00787   AttributeList *
00788   addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
00789                  IdentifierInfo *scopeName, SourceLocation scopeLoc,
00790                  IdentifierInfo *getterId, IdentifierInfo *setterId,
00791                  AttributeList::Syntax syntaxUsed) {
00792     AttributeList *attr =
00793         pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc,
00794                                      getterId, setterId, syntaxUsed);
00795     add(attr);
00796     return attr;
00797   }
00798 
00799 private:
00800   mutable AttributePool pool;
00801   AttributeList *list;
00802 };
00803 
00804 /// These constants match the enumerated choices of
00805 /// err_attribute_argument_n_type and err_attribute_argument_type.
00806 enum AttributeArgumentNType {
00807   AANT_ArgumentIntOrBool,
00808   AANT_ArgumentIntegerConstant,
00809   AANT_ArgumentString,
00810   AANT_ArgumentIdentifier
00811 };
00812 
00813 /// These constants match the enumerated choices of
00814 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type.
00815 enum AttributeDeclKind {
00816   ExpectedFunction,
00817   ExpectedUnion,
00818   ExpectedVariableOrFunction,
00819   ExpectedFunctionOrMethod,
00820   ExpectedParameter,
00821   ExpectedFunctionMethodOrBlock,
00822   ExpectedFunctionMethodOrClass,
00823   ExpectedFunctionMethodOrParameter,
00824   ExpectedClass,
00825   ExpectedVariable,
00826   ExpectedMethod,
00827   ExpectedVariableFunctionOrLabel,
00828   ExpectedFieldOrGlobalVar,
00829   ExpectedStruct,
00830   ExpectedVariableOrTypedef,
00831   ExpectedTLSVar,
00832   ExpectedVariableOrField,
00833   ExpectedVariableFieldOrTag,
00834   ExpectedTypeOrNamespace,
00835   ExpectedObjectiveCInterface,
00836   ExpectedMethodOrProperty,
00837   ExpectedStructOrUnion,
00838   ExpectedStructOrUnionOrClass,
00839   ExpectedType,
00840   ExpectedObjCInstanceMethod,
00841   ExpectedObjCInterfaceDeclInitMethod,
00842   ExpectedFunctionVariableOrClass,
00843   ExpectedObjectiveCProtocol,
00844   ExpectedFunctionGlobalVarMethodOrProperty,
00845   ExpectedStructOrTypedef,
00846   ExpectedObjectiveCInterfaceOrProtocol
00847 };
00848 
00849 }  // end namespace clang
00850 
00851 #endif