clang API Documentation
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