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