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