AttributeList.h revision 651f13cea278ec967336033dd032faef0e9fc2ec
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_ATTRLIST_H 16#define LLVM_CLANG_SEMA_ATTRLIST_H 17 18#include "clang/Basic/SourceLocation.h" 19#include "clang/Basic/VersionTuple.h" 20#include "clang/Sema/Ownership.h" 21#include "llvm/ADT/PointerUnion.h" 22#include "llvm/ADT/SmallVector.h" 23#include "llvm/ADT/Triple.h" 24#include "llvm/Support/Allocator.h" 25#include <cassert> 26 27namespace clang { 28 class ASTContext; 29 class IdentifierInfo; 30 class Expr; 31 32/// \brief Represents information about a change in availability for 33/// an entity, which is part of the encoding of the 'availability' 34/// attribute. 35struct AvailabilityChange { 36 /// \brief The location of the keyword indicating the kind of change. 37 SourceLocation KeywordLoc; 38 39 /// \brief The version number at which the change occurred. 40 VersionTuple Version; 41 42 /// \brief The source range covering the version number. 43 SourceRange VersionRange; 44 45 /// \brief Determine whether this availability change is valid. 46 bool isValid() const { return !Version.empty(); } 47}; 48 49/// \brief Wraps an identifier and optional source location for the identifier. 50struct IdentifierLoc { 51 SourceLocation Loc; 52 IdentifierInfo *Ident; 53 54 static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc, 55 IdentifierInfo *Ident); 56}; 57 58/// \brief A union of the various pointer types that can be passed to an 59/// AttributeList as an argument. 60typedef llvm::PointerUnion<Expr*, IdentifierLoc*> ArgsUnion; 61typedef llvm::SmallVector<ArgsUnion, 12U> ArgsVector; 62 63/// AttributeList - Represents a syntactic attribute. 64/// 65/// For a GNU attribute, there are four forms of this construct: 66/// 67/// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused. 68/// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused. 69/// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used. 70/// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used. 71/// 72class AttributeList { // TODO: This should really be called ParsedAttribute 73public: 74 /// The style used to specify an attribute. 75 enum Syntax { 76 /// __attribute__((...)) 77 AS_GNU, 78 /// [[...]] 79 AS_CXX11, 80 /// __declspec(...) 81 AS_Declspec, 82 /// __ptr16, alignas(...), etc. 83 AS_Keyword 84 }; 85 86private: 87 IdentifierInfo *AttrName; 88 IdentifierInfo *ScopeName; 89 SourceRange AttrRange; 90 SourceLocation ScopeLoc; 91 SourceLocation EllipsisLoc; 92 93 /// The number of expression arguments this attribute has. 94 /// The expressions themselves are stored after the object. 95 unsigned NumArgs : 16; 96 97 /// Corresponds to the Syntax enum. 98 unsigned SyntaxUsed : 2; 99 100 /// True if already diagnosed as invalid. 101 mutable unsigned Invalid : 1; 102 103 /// True if this attribute was used as a type attribute. 104 mutable unsigned UsedAsTypeAttr : 1; 105 106 /// True if this has the extra information associated with an 107 /// availability attribute. 108 unsigned IsAvailability : 1; 109 110 /// True if this has extra information associated with a 111 /// type_tag_for_datatype attribute. 112 unsigned IsTypeTagForDatatype : 1; 113 114 /// True if this has extra information associated with a 115 /// Microsoft __delcspec(property) attribute. 116 unsigned IsProperty : 1; 117 118 /// True if this has a ParsedType 119 unsigned HasParsedType : 1; 120 121 unsigned AttrKind : 8; 122 123 /// \brief The location of the 'unavailable' keyword in an 124 /// availability attribute. 125 SourceLocation UnavailableLoc; 126 127 const Expr *MessageExpr; 128 129 /// The next attribute in the current position. 130 AttributeList *NextInPosition; 131 132 /// The next attribute allocated in the current Pool. 133 AttributeList *NextInPool; 134 135 /// Arguments, if any, are stored immediately following the object. 136 ArgsUnion *getArgsBuffer() { 137 return reinterpret_cast<ArgsUnion*>(this+1); 138 } 139 ArgsUnion const *getArgsBuffer() const { 140 return reinterpret_cast<ArgsUnion const *>(this+1); 141 } 142 143 enum AvailabilitySlot { 144 IntroducedSlot, DeprecatedSlot, ObsoletedSlot 145 }; 146 147 /// Availability information is stored immediately following the arguments, 148 /// if any, at the end of the object. 149 AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) { 150 return reinterpret_cast<AvailabilityChange*>(getArgsBuffer() 151 + NumArgs)[index]; 152 } 153 const AvailabilityChange &getAvailabilitySlot(AvailabilitySlot index) const { 154 return reinterpret_cast<const AvailabilityChange*>(getArgsBuffer() 155 + NumArgs)[index]; 156 } 157 158public: 159 struct TypeTagForDatatypeData { 160 ParsedType *MatchingCType; 161 unsigned LayoutCompatible : 1; 162 unsigned MustBeNull : 1; 163 }; 164 struct PropertyData { 165 IdentifierInfo *GetterId, *SetterId; 166 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId) 167 : GetterId(getterId), SetterId(setterId) {} 168 }; 169 170private: 171 /// Type tag information is stored immediately following the arguments, if 172 /// any, at the end of the object. They are mutually exlusive with 173 /// availability slots. 174 TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() { 175 return *reinterpret_cast<TypeTagForDatatypeData*>(getArgsBuffer()+NumArgs); 176 } 177 178 const TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const { 179 return *reinterpret_cast<const TypeTagForDatatypeData*>(getArgsBuffer() 180 + NumArgs); 181 } 182 183 /// The type buffer immediately follows the object and are mutually exclusive 184 /// with arguments. 185 ParsedType &getTypeBuffer() { 186 return *reinterpret_cast<ParsedType *>(this + 1); 187 } 188 189 const ParsedType &getTypeBuffer() const { 190 return *reinterpret_cast<const ParsedType *>(this + 1); 191 } 192 193 /// The property data immediately follows the object is is mutually exclusive 194 /// with arguments. 195 PropertyData &getPropertyDataBuffer() { 196 assert(IsProperty); 197 return *reinterpret_cast<PropertyData*>(this + 1); 198 } 199 200 const PropertyData &getPropertyDataBuffer() const { 201 assert(IsProperty); 202 return *reinterpret_cast<const PropertyData*>(this + 1); 203 } 204 205 AttributeList(const AttributeList &) LLVM_DELETED_FUNCTION; 206 void operator=(const AttributeList &) LLVM_DELETED_FUNCTION; 207 void operator delete(void *) LLVM_DELETED_FUNCTION; 208 ~AttributeList() LLVM_DELETED_FUNCTION; 209 210 size_t allocated_size() const; 211 212 /// Constructor for attributes with expression arguments. 213 AttributeList(IdentifierInfo *attrName, SourceRange attrRange, 214 IdentifierInfo *scopeName, SourceLocation scopeLoc, 215 ArgsUnion *args, unsigned numArgs, 216 Syntax syntaxUsed, SourceLocation ellipsisLoc) 217 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), 218 ScopeLoc(scopeLoc), EllipsisLoc(ellipsisLoc), NumArgs(numArgs), 219 SyntaxUsed(syntaxUsed), Invalid(false), UsedAsTypeAttr(false), 220 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), 221 HasParsedType(false), NextInPosition(0), NextInPool(0) { 222 if (numArgs) memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion)); 223 AttrKind = getKind(getName(), getScopeName(), syntaxUsed); 224 } 225 226 /// Constructor for availability attributes. 227 AttributeList(IdentifierInfo *attrName, SourceRange attrRange, 228 IdentifierInfo *scopeName, SourceLocation scopeLoc, 229 IdentifierLoc *Parm, const AvailabilityChange &introduced, 230 const AvailabilityChange &deprecated, 231 const AvailabilityChange &obsoleted, 232 SourceLocation unavailable, 233 const Expr *messageExpr, 234 Syntax syntaxUsed) 235 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), 236 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), 237 Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), 238 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), 239 UnavailableLoc(unavailable), MessageExpr(messageExpr), 240 NextInPosition(0), NextInPool(0) { 241 ArgsUnion PVal(Parm); 242 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); 243 new (&getAvailabilitySlot(IntroducedSlot)) AvailabilityChange(introduced); 244 new (&getAvailabilitySlot(DeprecatedSlot)) AvailabilityChange(deprecated); 245 new (&getAvailabilitySlot(ObsoletedSlot)) AvailabilityChange(obsoleted); 246 AttrKind = getKind(getName(), getScopeName(), syntaxUsed); 247 } 248 249 /// Constructor for objc_bridge_related attributes. 250 AttributeList(IdentifierInfo *attrName, SourceRange attrRange, 251 IdentifierInfo *scopeName, SourceLocation scopeLoc, 252 IdentifierLoc *Parm1, 253 IdentifierLoc *Parm2, 254 IdentifierLoc *Parm3, 255 Syntax syntaxUsed) 256 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), 257 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(3), SyntaxUsed(syntaxUsed), 258 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), 259 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), 260 NextInPosition(0), NextInPool(0) { 261 ArgsVector Args; 262 Args.push_back(Parm1); 263 Args.push_back(Parm2); 264 Args.push_back(Parm3); 265 memcpy(getArgsBuffer(), &Args[0], 3 * sizeof(ArgsUnion)); 266 AttrKind = getKind(getName(), getScopeName(), syntaxUsed); 267 } 268 269 /// Constructor for type_tag_for_datatype attribute. 270 AttributeList(IdentifierInfo *attrName, SourceRange attrRange, 271 IdentifierInfo *scopeName, SourceLocation scopeLoc, 272 IdentifierLoc *ArgKind, ParsedType matchingCType, 273 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed) 274 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), 275 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(1), SyntaxUsed(syntaxUsed), 276 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), 277 IsTypeTagForDatatype(true), IsProperty(false), HasParsedType(false), 278 NextInPosition(NULL), NextInPool(NULL) { 279 ArgsUnion PVal(ArgKind); 280 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); 281 TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); 282 new (&ExtraData.MatchingCType) ParsedType(matchingCType); 283 ExtraData.LayoutCompatible = layoutCompatible; 284 ExtraData.MustBeNull = mustBeNull; 285 AttrKind = getKind(getName(), getScopeName(), syntaxUsed); 286 } 287 288 /// Constructor for attributes with a single type argument. 289 AttributeList(IdentifierInfo *attrName, SourceRange attrRange, 290 IdentifierInfo *scopeName, SourceLocation scopeLoc, 291 ParsedType typeArg, Syntax syntaxUsed) 292 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), 293 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), 294 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), 295 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true), 296 NextInPosition(0), NextInPool(0) { 297 new (&getTypeBuffer()) ParsedType(typeArg); 298 AttrKind = getKind(getName(), getScopeName(), syntaxUsed); 299 } 300 301 /// Constructor for microsoft __declspec(property) attribute. 302 AttributeList(IdentifierInfo *attrName, SourceRange attrRange, 303 IdentifierInfo *scopeName, SourceLocation scopeLoc, 304 IdentifierInfo *getterId, IdentifierInfo *setterId, 305 Syntax syntaxUsed) 306 : AttrName(attrName), ScopeName(scopeName), AttrRange(attrRange), 307 ScopeLoc(scopeLoc), EllipsisLoc(), NumArgs(0), SyntaxUsed(syntaxUsed), 308 Invalid(false), UsedAsTypeAttr(false), IsAvailability(false), 309 IsTypeTagForDatatype(false), IsProperty(true), HasParsedType(false), 310 NextInPosition(0), NextInPool(0) { 311 new (&getPropertyDataBuffer()) PropertyData(getterId, setterId); 312 AttrKind = getKind(getName(), getScopeName(), syntaxUsed); 313 } 314 315 friend class AttributePool; 316 friend class AttributeFactory; 317 318public: 319 enum Kind { 320 #define PARSED_ATTR(NAME) AT_##NAME, 321 #include "clang/Sema/AttrParsedAttrList.inc" 322 #undef PARSED_ATTR 323 IgnoredAttribute, 324 UnknownAttribute 325 }; 326 327 IdentifierInfo *getName() const { return AttrName; } 328 SourceLocation getLoc() const { return AttrRange.getBegin(); } 329 SourceRange getRange() const { return AttrRange; } 330 331 bool hasScope() const { return ScopeName; } 332 IdentifierInfo *getScopeName() const { return ScopeName; } 333 SourceLocation getScopeLoc() const { return ScopeLoc; } 334 335 bool hasParsedType() const { return HasParsedType; } 336 337 /// Is this the Microsoft __declspec(property) attribute? 338 bool isDeclspecPropertyAttribute() const { 339 return IsProperty; 340 } 341 342 bool isAlignasAttribute() const { 343 // FIXME: Use a better mechanism to determine this. 344 return getKind() == AT_Aligned && SyntaxUsed == AS_Keyword; 345 } 346 347 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; } 348 bool isCXX11Attribute() const { 349 return SyntaxUsed == AS_CXX11 || isAlignasAttribute(); 350 } 351 bool isKeywordAttribute() const { return SyntaxUsed == AS_Keyword; } 352 353 bool isInvalid() const { return Invalid; } 354 void setInvalid(bool b = true) const { Invalid = b; } 355 356 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; } 357 void setUsedAsTypeAttr() { UsedAsTypeAttr = true; } 358 359 bool isPackExpansion() const { return EllipsisLoc.isValid(); } 360 SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 361 362 Kind getKind() const { return Kind(AttrKind); } 363 static Kind getKind(const IdentifierInfo *Name, const IdentifierInfo *Scope, 364 Syntax SyntaxUsed); 365 366 AttributeList *getNext() const { return NextInPosition; } 367 void setNext(AttributeList *N) { NextInPosition = N; } 368 369 /// getNumArgs - Return the number of actual arguments to this attribute. 370 unsigned getNumArgs() const { return NumArgs; } 371 372 /// getArg - Return the specified argument. 373 ArgsUnion getArg(unsigned Arg) const { 374 assert(Arg < NumArgs && "Arg access out of range!"); 375 return getArgsBuffer()[Arg]; 376 } 377 378 bool isArgExpr(unsigned Arg) const { 379 return Arg < NumArgs && getArg(Arg).is<Expr*>(); 380 } 381 Expr *getArgAsExpr(unsigned Arg) const { 382 return getArg(Arg).get<Expr*>(); 383 } 384 385 bool isArgIdent(unsigned Arg) const { 386 return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>(); 387 } 388 IdentifierLoc *getArgAsIdent(unsigned Arg) const { 389 return getArg(Arg).get<IdentifierLoc*>(); 390 } 391 392 const AvailabilityChange &getAvailabilityIntroduced() const { 393 assert(getKind() == AT_Availability && "Not an availability attribute"); 394 return getAvailabilitySlot(IntroducedSlot); 395 } 396 397 const AvailabilityChange &getAvailabilityDeprecated() const { 398 assert(getKind() == AT_Availability && "Not an availability attribute"); 399 return getAvailabilitySlot(DeprecatedSlot); 400 } 401 402 const AvailabilityChange &getAvailabilityObsoleted() const { 403 assert(getKind() == AT_Availability && "Not an availability attribute"); 404 return getAvailabilitySlot(ObsoletedSlot); 405 } 406 407 SourceLocation getUnavailableLoc() const { 408 assert(getKind() == AT_Availability && "Not an availability attribute"); 409 return UnavailableLoc; 410 } 411 412 const Expr * getMessageExpr() const { 413 assert(getKind() == AT_Availability && "Not an availability attribute"); 414 return MessageExpr; 415 } 416 417 const ParsedType &getMatchingCType() const { 418 assert(getKind() == AT_TypeTagForDatatype && 419 "Not a type_tag_for_datatype attribute"); 420 return *getTypeTagForDatatypeDataSlot().MatchingCType; 421 } 422 423 bool getLayoutCompatible() const { 424 assert(getKind() == AT_TypeTagForDatatype && 425 "Not a type_tag_for_datatype attribute"); 426 return getTypeTagForDatatypeDataSlot().LayoutCompatible; 427 } 428 429 bool getMustBeNull() const { 430 assert(getKind() == AT_TypeTagForDatatype && 431 "Not a type_tag_for_datatype attribute"); 432 return getTypeTagForDatatypeDataSlot().MustBeNull; 433 } 434 435 const ParsedType &getTypeArg() const { 436 assert(HasParsedType && "Not a type attribute"); 437 return getTypeBuffer(); 438 } 439 440 const PropertyData &getPropertyData() const { 441 assert(isDeclspecPropertyAttribute() && "Not a __delcspec(property) attribute"); 442 return getPropertyDataBuffer(); 443 } 444 445 /// \brief Get an index into the attribute spelling list 446 /// defined in Attr.td. This index is used by an attribute 447 /// to pretty print itself. 448 unsigned getAttributeSpellingListIndex() const; 449 450 bool isTargetSpecificAttr() const; 451 bool isTypeAttr() const; 452 453 bool hasCustomParsing() const; 454 unsigned getMinArgs() const; 455 unsigned getMaxArgs() const; 456 bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const; 457 bool diagnoseLangOpts(class Sema &S) const; 458 bool existsInTarget(const llvm::Triple &T) const; 459 bool isKnownToGCC() const; 460 461 /// \brief If the parsed attribute has a semantic equivalent, and it would 462 /// have a semantic Spelling enumeration (due to having semantically-distinct 463 /// spelling variations), return the value of that semantic spelling. If the 464 /// parsed attribute does not have a semantic equivalent, or would not have 465 /// a Spelling enumeration, the value UINT_MAX is returned. 466 unsigned getSemanticSpelling() const; 467}; 468 469/// A factory, from which one makes pools, from which one creates 470/// individual attributes which are deallocated with the pool. 471/// 472/// Note that it's tolerably cheap to create and destroy one of 473/// these as long as you don't actually allocate anything in it. 474class AttributeFactory { 475public: 476 enum { 477 /// The required allocation size of an availability attribute, 478 /// which we want to ensure is a multiple of sizeof(void*). 479 AvailabilityAllocSize = 480 sizeof(AttributeList) 481 + ((3 * sizeof(AvailabilityChange) + sizeof(void*) + 482 sizeof(ArgsUnion) - 1) 483 / sizeof(void*) * sizeof(void*)), 484 TypeTagForDatatypeAllocSize = 485 sizeof(AttributeList) 486 + (sizeof(AttributeList::TypeTagForDatatypeData) + sizeof(void *) + 487 sizeof(ArgsUnion) - 1) 488 / sizeof(void*) * sizeof(void*), 489 PropertyAllocSize = 490 sizeof(AttributeList) 491 + (sizeof(AttributeList::PropertyData) + sizeof(void *) - 1) 492 / sizeof(void*) * sizeof(void*) 493 }; 494 495private: 496 enum { 497 /// The number of free lists we want to be sure to support 498 /// inline. This is just enough that availability attributes 499 /// don't surpass it. It's actually very unlikely we'll see an 500 /// attribute that needs more than that; on x86-64 you'd need 10 501 /// expression arguments, and on i386 you'd need 19. 502 InlineFreeListsCapacity = 503 1 + (AvailabilityAllocSize - sizeof(AttributeList)) / sizeof(void*) 504 }; 505 506 llvm::BumpPtrAllocator Alloc; 507 508 /// Free lists. The index is determined by the following formula: 509 /// (size - sizeof(AttributeList)) / sizeof(void*) 510 SmallVector<AttributeList*, InlineFreeListsCapacity> FreeLists; 511 512 // The following are the private interface used by AttributePool. 513 friend class AttributePool; 514 515 /// Allocate an attribute of the given size. 516 void *allocate(size_t size); 517 518 /// Reclaim all the attributes in the given pool chain, which is 519 /// non-empty. Note that the current implementation is safe 520 /// against reclaiming things which were not actually allocated 521 /// with the allocator, although of course it's important to make 522 /// sure that their allocator lives at least as long as this one. 523 void reclaimPool(AttributeList *head); 524 525public: 526 AttributeFactory(); 527 ~AttributeFactory(); 528}; 529 530class AttributePool { 531 AttributeFactory &Factory; 532 AttributeList *Head; 533 534 void *allocate(size_t size) { 535 return Factory.allocate(size); 536 } 537 538 AttributeList *add(AttributeList *attr) { 539 // We don't care about the order of the pool. 540 attr->NextInPool = Head; 541 Head = attr; 542 return attr; 543 } 544 545 void takePool(AttributeList *pool); 546 547public: 548 /// Create a new pool for a factory. 549 AttributePool(AttributeFactory &factory) : Factory(factory), Head(0) {} 550 551 /// Move the given pool's allocations to this pool. 552 AttributePool(AttributePool &pool) : Factory(pool.Factory), Head(pool.Head) { 553 pool.Head = 0; 554 } 555 556 AttributeFactory &getFactory() const { return Factory; } 557 558 void clear() { 559 if (Head) { 560 Factory.reclaimPool(Head); 561 Head = 0; 562 } 563 } 564 565 /// Take the given pool's allocations and add them to this pool. 566 void takeAllFrom(AttributePool &pool) { 567 if (pool.Head) { 568 takePool(pool.Head); 569 pool.Head = 0; 570 } 571 } 572 573 ~AttributePool() { 574 if (Head) Factory.reclaimPool(Head); 575 } 576 577 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, 578 IdentifierInfo *scopeName, SourceLocation scopeLoc, 579 ArgsUnion *args, unsigned numArgs, 580 AttributeList::Syntax syntax, 581 SourceLocation ellipsisLoc = SourceLocation()) { 582 void *memory = allocate(sizeof(AttributeList) 583 + numArgs * sizeof(ArgsUnion)); 584 return add(new (memory) AttributeList(attrName, attrRange, 585 scopeName, scopeLoc, 586 args, numArgs, syntax, 587 ellipsisLoc)); 588 } 589 590 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, 591 IdentifierInfo *scopeName, SourceLocation scopeLoc, 592 IdentifierLoc *Param, 593 const AvailabilityChange &introduced, 594 const AvailabilityChange &deprecated, 595 const AvailabilityChange &obsoleted, 596 SourceLocation unavailable, 597 const Expr *MessageExpr, 598 AttributeList::Syntax syntax) { 599 void *memory = allocate(AttributeFactory::AvailabilityAllocSize); 600 return add(new (memory) AttributeList(attrName, attrRange, 601 scopeName, scopeLoc, 602 Param, introduced, deprecated, 603 obsoleted, unavailable, MessageExpr, 604 syntax)); 605 } 606 607 AttributeList *create(IdentifierInfo *attrName, SourceRange attrRange, 608 IdentifierInfo *scopeName, SourceLocation scopeLoc, 609 IdentifierLoc *Param1, 610 IdentifierLoc *Param2, 611 IdentifierLoc *Param3, 612 AttributeList::Syntax syntax) { 613 size_t size = sizeof(AttributeList) + 3 * sizeof(ArgsUnion); 614 void *memory = allocate(size); 615 return add(new (memory) AttributeList(attrName, attrRange, 616 scopeName, scopeLoc, 617 Param1, Param2, Param3, 618 syntax)); 619 } 620 621 AttributeList *createTypeTagForDatatype( 622 IdentifierInfo *attrName, SourceRange attrRange, 623 IdentifierInfo *scopeName, SourceLocation scopeLoc, 624 IdentifierLoc *argumentKind, ParsedType matchingCType, 625 bool layoutCompatible, bool mustBeNull, 626 AttributeList::Syntax syntax) { 627 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize); 628 return add(new (memory) AttributeList(attrName, attrRange, 629 scopeName, scopeLoc, 630 argumentKind, matchingCType, 631 layoutCompatible, mustBeNull, 632 syntax)); 633 } 634 635 AttributeList *createTypeAttribute( 636 IdentifierInfo *attrName, SourceRange attrRange, 637 IdentifierInfo *scopeName, SourceLocation scopeLoc, 638 ParsedType typeArg, AttributeList::Syntax syntaxUsed) { 639 void *memory = allocate(sizeof(AttributeList) + sizeof(void *)); 640 return add(new (memory) AttributeList(attrName, attrRange, 641 scopeName, scopeLoc, 642 typeArg, syntaxUsed)); 643 } 644 645 AttributeList *createPropertyAttribute( 646 IdentifierInfo *attrName, SourceRange attrRange, 647 IdentifierInfo *scopeName, SourceLocation scopeLoc, 648 IdentifierInfo *getterId, IdentifierInfo *setterId, 649 AttributeList::Syntax syntaxUsed) { 650 void *memory = allocate(AttributeFactory::PropertyAllocSize); 651 return add(new (memory) AttributeList(attrName, attrRange, 652 scopeName, scopeLoc, 653 getterId, setterId, 654 syntaxUsed)); 655 } 656}; 657 658/// ParsedAttributes - A collection of parsed attributes. Currently 659/// we don't differentiate between the various attribute syntaxes, 660/// which is basically silly. 661/// 662/// Right now this is a very lightweight container, but the expectation 663/// is that this will become significantly more serious. 664class ParsedAttributes { 665public: 666 ParsedAttributes(AttributeFactory &factory) 667 : pool(factory), list(0) { 668 } 669 670 ParsedAttributes(const ParsedAttributes &) LLVM_DELETED_FUNCTION; 671 672 AttributePool &getPool() const { return pool; } 673 674 bool empty() const { return list == 0; } 675 676 void add(AttributeList *newAttr) { 677 assert(newAttr); 678 assert(newAttr->getNext() == 0); 679 newAttr->setNext(list); 680 list = newAttr; 681 } 682 683 void addAll(AttributeList *newList) { 684 if (!newList) return; 685 686 AttributeList *lastInNewList = newList; 687 while (AttributeList *next = lastInNewList->getNext()) 688 lastInNewList = next; 689 690 lastInNewList->setNext(list); 691 list = newList; 692 } 693 694 void set(AttributeList *newList) { 695 list = newList; 696 } 697 698 void takeAllFrom(ParsedAttributes &attrs) { 699 addAll(attrs.list); 700 attrs.list = 0; 701 pool.takeAllFrom(attrs.pool); 702 } 703 704 void clear() { list = 0; pool.clear(); } 705 AttributeList *getList() const { return list; } 706 707 /// Returns a reference to the attribute list. Try not to introduce 708 /// dependencies on this method, it may not be long-lived. 709 AttributeList *&getListRef() { return list; } 710 711 /// Add attribute with expression arguments. 712 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, 713 IdentifierInfo *scopeName, SourceLocation scopeLoc, 714 ArgsUnion *args, unsigned numArgs, 715 AttributeList::Syntax syntax, 716 SourceLocation ellipsisLoc = SourceLocation()) { 717 AttributeList *attr = 718 pool.create(attrName, attrRange, scopeName, scopeLoc, args, numArgs, 719 syntax, ellipsisLoc); 720 add(attr); 721 return attr; 722 } 723 724 /// Add availability attribute. 725 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, 726 IdentifierInfo *scopeName, SourceLocation scopeLoc, 727 IdentifierLoc *Param, 728 const AvailabilityChange &introduced, 729 const AvailabilityChange &deprecated, 730 const AvailabilityChange &obsoleted, 731 SourceLocation unavailable, 732 const Expr *MessageExpr, 733 AttributeList::Syntax syntax) { 734 AttributeList *attr = 735 pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced, 736 deprecated, obsoleted, unavailable, MessageExpr, syntax); 737 add(attr); 738 return attr; 739 } 740 741 /// Add objc_bridge_related attribute. 742 AttributeList *addNew(IdentifierInfo *attrName, SourceRange attrRange, 743 IdentifierInfo *scopeName, SourceLocation scopeLoc, 744 IdentifierLoc *Param1, 745 IdentifierLoc *Param2, 746 IdentifierLoc *Param3, 747 AttributeList::Syntax syntax) { 748 AttributeList *attr = 749 pool.create(attrName, attrRange, scopeName, scopeLoc, 750 Param1, Param2, Param3, syntax); 751 add(attr); 752 return attr; 753 } 754 755 /// Add type_tag_for_datatype attribute. 756 AttributeList *addNewTypeTagForDatatype( 757 IdentifierInfo *attrName, SourceRange attrRange, 758 IdentifierInfo *scopeName, SourceLocation scopeLoc, 759 IdentifierLoc *argumentKind, ParsedType matchingCType, 760 bool layoutCompatible, bool mustBeNull, 761 AttributeList::Syntax syntax) { 762 AttributeList *attr = 763 pool.createTypeTagForDatatype(attrName, attrRange, 764 scopeName, scopeLoc, 765 argumentKind, matchingCType, 766 layoutCompatible, mustBeNull, syntax); 767 add(attr); 768 return attr; 769 } 770 771 /// Add an attribute with a single type argument. 772 AttributeList * 773 addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, 774 IdentifierInfo *scopeName, SourceLocation scopeLoc, 775 ParsedType typeArg, AttributeList::Syntax syntaxUsed) { 776 AttributeList *attr = 777 pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc, 778 typeArg, syntaxUsed); 779 add(attr); 780 return attr; 781 } 782 783 /// Add microsoft __delspec(property) attribute. 784 AttributeList * 785 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, 786 IdentifierInfo *scopeName, SourceLocation scopeLoc, 787 IdentifierInfo *getterId, IdentifierInfo *setterId, 788 AttributeList::Syntax syntaxUsed) { 789 AttributeList *attr = 790 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc, 791 getterId, setterId, syntaxUsed); 792 add(attr); 793 return attr; 794 } 795 796private: 797 mutable AttributePool pool; 798 AttributeList *list; 799}; 800 801/// These constants match the enumerated choices of 802/// err_attribute_argument_n_type and err_attribute_argument_type. 803enum AttributeArgumentNType { 804 AANT_ArgumentIntOrBool, 805 AANT_ArgumentIntegerConstant, 806 AANT_ArgumentString, 807 AANT_ArgumentIdentifier 808}; 809 810/// These constants match the enumerated choices of 811/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 812enum AttributeDeclKind { 813 ExpectedFunction, 814 ExpectedUnion, 815 ExpectedVariableOrFunction, 816 ExpectedFunctionOrMethod, 817 ExpectedParameter, 818 ExpectedFunctionMethodOrBlock, 819 ExpectedFunctionMethodOrClass, 820 ExpectedFunctionMethodOrParameter, 821 ExpectedClass, 822 ExpectedVariable, 823 ExpectedMethod, 824 ExpectedVariableFunctionOrLabel, 825 ExpectedFieldOrGlobalVar, 826 ExpectedStruct, 827 ExpectedVariableFunctionOrTag, 828 ExpectedTLSVar, 829 ExpectedVariableOrField, 830 ExpectedVariableFieldOrTag, 831 ExpectedTypeOrNamespace, 832 ExpectedObjectiveCInterface, 833 ExpectedMethodOrProperty, 834 ExpectedStructOrUnion, 835 ExpectedStructOrUnionOrClass, 836 ExpectedType, 837 ExpectedObjCInstanceMethod, 838 ExpectedObjCInterfaceDeclInitMethod, 839 ExpectedFunctionVariableOrClass, 840 ExpectedObjectiveCProtocol, 841 ExpectedFunctionGlobalVarMethodOrProperty, 842 ExpectedStructOrTypedef 843}; 844 845} // end namespace clang 846 847#endif 848