1 //======- ParsedAttr.h - Parsed attribute sets ------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file defines the ParsedAttr class, which is used to collect 10 // parsed attributes. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_SEMA_PARSEDATTR_H 15 #define LLVM_CLANG_SEMA_PARSEDATTR_H 16 17 #include "clang/Basic/AttrSubjectMatchRules.h" 18 #include "clang/Basic/AttributeCommonInfo.h" 19 #include "clang/Basic/Diagnostic.h" 20 #include "clang/Basic/SourceLocation.h" 21 #include "clang/Sema/Ownership.h" 22 #include "llvm/ADT/PointerUnion.h" 23 #include "llvm/ADT/SmallVector.h" 24 #include "llvm/Support/Allocator.h" 25 #include "llvm/Support/Registry.h" 26 #include "llvm/Support/VersionTuple.h" 27 #include <cassert> 28 #include <cstddef> 29 #include <cstring> 30 #include <utility> 31 32 namespace clang { 33 34 class ASTContext; 35 class Decl; 36 class Expr; 37 class IdentifierInfo; 38 class LangOptions; 39 class ParsedAttr; 40 class Sema; 41 class Stmt; 42 class TargetInfo; 43 44 struct ParsedAttrInfo { 45 /// Corresponds to the Kind enum. 46 unsigned AttrKind : 16; 47 /// The number of required arguments of this attribute. 48 unsigned NumArgs : 4; 49 /// The number of optional arguments of this attributes. 50 unsigned OptArgs : 4; 51 /// The number of non-fake arguments specified in the attribute definition. 52 unsigned NumArgMembers : 4; 53 /// True if the parsing does not match the semantic content. 54 unsigned HasCustomParsing : 1; 55 // True if this attribute accepts expression parameter pack expansions. 56 unsigned AcceptsExprPack : 1; 57 /// True if this attribute is only available for certain targets. 58 unsigned IsTargetSpecific : 1; 59 /// True if this attribute applies to types. 60 unsigned IsType : 1; 61 /// True if this attribute applies to statements. 62 unsigned IsStmt : 1; 63 /// True if this attribute has any spellings that are known to gcc. 64 unsigned IsKnownToGCC : 1; 65 /// True if this attribute is supported by #pragma clang attribute. 66 unsigned IsSupportedByPragmaAttribute : 1; 67 /// The syntaxes supported by this attribute and how they're spelled. 68 struct Spelling { 69 AttributeCommonInfo::Syntax Syntax; 70 const char *NormalizedFullName; 71 }; 72 ArrayRef<Spelling> Spellings; 73 // The names of the known arguments of this attribute. 74 ArrayRef<const char *> ArgNames; 75 76 protected: 77 constexpr ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind = 78 AttributeCommonInfo::NoSemaHandlerAttribute) 79 : AttrKind(AttrKind), NumArgs(0), OptArgs(0), NumArgMembers(0), 80 HasCustomParsing(0), AcceptsExprPack(0), IsTargetSpecific(0), IsType(0), 81 IsStmt(0), IsKnownToGCC(0), IsSupportedByPragmaAttribute(0) {} 82 83 constexpr ParsedAttrInfo(AttributeCommonInfo::Kind AttrKind, unsigned NumArgs, 84 unsigned OptArgs, unsigned NumArgMembers, 85 unsigned HasCustomParsing, unsigned AcceptsExprPack, 86 unsigned IsTargetSpecific, unsigned IsType, 87 unsigned IsStmt, unsigned IsKnownToGCC, 88 unsigned IsSupportedByPragmaAttribute, 89 ArrayRef<Spelling> Spellings, 90 ArrayRef<const char *> ArgNames) 91 : AttrKind(AttrKind), NumArgs(NumArgs), OptArgs(OptArgs), 92 NumArgMembers(NumArgMembers), HasCustomParsing(HasCustomParsing), 93 AcceptsExprPack(AcceptsExprPack), IsTargetSpecific(IsTargetSpecific), 94 IsType(IsType), IsStmt(IsStmt), IsKnownToGCC(IsKnownToGCC), 95 IsSupportedByPragmaAttribute(IsSupportedByPragmaAttribute), 96 Spellings(Spellings), ArgNames(ArgNames) {} 97 98 public: 99 virtual ~ParsedAttrInfo() = default; 100 101 /// Check if this attribute appertains to D, and issue a diagnostic if not. 102 virtual bool diagAppertainsToDecl(Sema &S, const ParsedAttr &Attr, 103 const Decl *D) const { 104 return true; 105 } 106 /// Check if this attribute appertains to St, and issue a diagnostic if not. 107 virtual bool diagAppertainsToStmt(Sema &S, const ParsedAttr &Attr, 108 const Stmt *St) const { 109 return true; 110 } 111 /// Check if the given attribute is mutually exclusive with other attributes 112 /// already applied to the given declaration. 113 virtual bool diagMutualExclusion(Sema &S, const ParsedAttr &A, 114 const Decl *D) const { 115 return true; 116 } 117 /// Check if this attribute is allowed by the language we are compiling. 118 virtual bool acceptsLangOpts(const LangOptions &LO) const { return true; } 119 120 /// Check if this attribute is allowed when compiling for the given target. 121 virtual bool existsInTarget(const TargetInfo &Target) const { 122 return true; 123 } 124 /// Convert the spelling index of Attr to a semantic spelling enum value. 125 virtual unsigned 126 spellingIndexToSemanticSpelling(const ParsedAttr &Attr) const { 127 return UINT_MAX; 128 } 129 /// Returns true if the specified parameter index for this attribute in 130 /// Attr.td is an ExprArgument or VariadicExprArgument, or a subclass thereof; 131 /// returns false otherwise. 132 virtual bool isParamExpr(size_t N) const { return false; } 133 /// Populate Rules with the match rules of this attribute. 134 virtual void getPragmaAttributeMatchRules( 135 llvm::SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> &Rules, 136 const LangOptions &LangOpts) const { 137 } 138 enum AttrHandling { 139 NotHandled, 140 AttributeApplied, 141 AttributeNotApplied 142 }; 143 /// If this ParsedAttrInfo knows how to handle this ParsedAttr applied to this 144 /// Decl then do so and return either AttributeApplied if it was applied or 145 /// AttributeNotApplied if it wasn't. Otherwise return NotHandled. 146 virtual AttrHandling handleDeclAttribute(Sema &S, Decl *D, 147 const ParsedAttr &Attr) const { 148 return NotHandled; 149 } 150 151 static const ParsedAttrInfo &get(const AttributeCommonInfo &A); 152 static ArrayRef<const ParsedAttrInfo *> getAllBuiltin(); 153 }; 154 155 typedef llvm::Registry<ParsedAttrInfo> ParsedAttrInfoRegistry; 156 157 /// Represents information about a change in availability for 158 /// an entity, which is part of the encoding of the 'availability' 159 /// attribute. 160 struct AvailabilityChange { 161 /// The location of the keyword indicating the kind of change. 162 SourceLocation KeywordLoc; 163 164 /// The version number at which the change occurred. 165 VersionTuple Version; 166 167 /// The source range covering the version number. 168 SourceRange VersionRange; 169 170 /// Determine whether this availability change is valid. 171 bool isValid() const { return !Version.empty(); } 172 }; 173 174 namespace detail { 175 enum AvailabilitySlot { 176 IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots 177 }; 178 179 /// Describes the trailing object for Availability attribute in ParsedAttr. 180 struct AvailabilityData { 181 AvailabilityChange Changes[NumAvailabilitySlots]; 182 SourceLocation StrictLoc; 183 const Expr *Replacement; 184 185 AvailabilityData(const AvailabilityChange &Introduced, 186 const AvailabilityChange &Deprecated, 187 const AvailabilityChange &Obsoleted, 188 SourceLocation Strict, const Expr *ReplaceExpr) 189 : StrictLoc(Strict), Replacement(ReplaceExpr) { 190 Changes[IntroducedSlot] = Introduced; 191 Changes[DeprecatedSlot] = Deprecated; 192 Changes[ObsoletedSlot] = Obsoleted; 193 } 194 }; 195 196 struct TypeTagForDatatypeData { 197 ParsedType MatchingCType; 198 unsigned LayoutCompatible : 1; 199 unsigned MustBeNull : 1; 200 }; 201 struct PropertyData { 202 IdentifierInfo *GetterId, *SetterId; 203 204 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId) 205 : GetterId(getterId), SetterId(setterId) {} 206 }; 207 208 } // namespace 209 210 /// Wraps an identifier and optional source location for the identifier. 211 struct IdentifierLoc { 212 SourceLocation Loc; 213 IdentifierInfo *Ident; 214 215 static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc, 216 IdentifierInfo *Ident); 217 }; 218 219 /// A union of the various pointer types that can be passed to an 220 /// ParsedAttr as an argument. 221 using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>; 222 using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>; 223 224 /// ParsedAttr - Represents a syntactic attribute. 225 /// 226 /// For a GNU attribute, there are four forms of this construct: 227 /// 228 /// 1: __attribute__(( const )). ParmName/Args/NumArgs will all be unused. 229 /// 2: __attribute__(( mode(byte) )). ParmName used, Args/NumArgs unused. 230 /// 3: __attribute__(( format(printf, 1, 2) )). ParmName/Args/NumArgs all used. 231 /// 4: __attribute__(( aligned(16) )). ParmName is unused, Args/Num used. 232 /// 233 class ParsedAttr final 234 : public AttributeCommonInfo, 235 private llvm::TrailingObjects< 236 ParsedAttr, ArgsUnion, detail::AvailabilityData, 237 detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData> { 238 friend TrailingObjects; 239 240 size_t numTrailingObjects(OverloadToken<ArgsUnion>) const { return NumArgs; } 241 size_t numTrailingObjects(OverloadToken<detail::AvailabilityData>) const { 242 return IsAvailability; 243 } 244 size_t 245 numTrailingObjects(OverloadToken<detail::TypeTagForDatatypeData>) const { 246 return IsTypeTagForDatatype; 247 } 248 size_t numTrailingObjects(OverloadToken<ParsedType>) const { 249 return HasParsedType; 250 } 251 size_t numTrailingObjects(OverloadToken<detail::PropertyData>) const { 252 return IsProperty; 253 } 254 255 private: 256 IdentifierInfo *MacroII = nullptr; 257 SourceLocation MacroExpansionLoc; 258 SourceLocation EllipsisLoc; 259 260 /// The number of expression arguments this attribute has. 261 /// The expressions themselves are stored after the object. 262 unsigned NumArgs : 16; 263 264 /// True if already diagnosed as invalid. 265 mutable unsigned Invalid : 1; 266 267 /// True if this attribute was used as a type attribute. 268 mutable unsigned UsedAsTypeAttr : 1; 269 270 /// True if this has the extra information associated with an 271 /// availability attribute. 272 unsigned IsAvailability : 1; 273 274 /// True if this has extra information associated with a 275 /// type_tag_for_datatype attribute. 276 unsigned IsTypeTagForDatatype : 1; 277 278 /// True if this has extra information associated with a 279 /// Microsoft __delcspec(property) attribute. 280 unsigned IsProperty : 1; 281 282 /// True if this has a ParsedType 283 unsigned HasParsedType : 1; 284 285 /// True if the processing cache is valid. 286 mutable unsigned HasProcessingCache : 1; 287 288 /// A cached value. 289 mutable unsigned ProcessingCache : 8; 290 291 /// True if the attribute is specified using '#pragma clang attribute'. 292 mutable unsigned IsPragmaClangAttribute : 1; 293 294 /// The location of the 'unavailable' keyword in an 295 /// availability attribute. 296 SourceLocation UnavailableLoc; 297 298 const Expr *MessageExpr; 299 300 const ParsedAttrInfo &Info; 301 302 ArgsUnion *getArgsBuffer() { return getTrailingObjects<ArgsUnion>(); } 303 ArgsUnion const *getArgsBuffer() const { 304 return getTrailingObjects<ArgsUnion>(); 305 } 306 307 detail::AvailabilityData *getAvailabilityData() { 308 return getTrailingObjects<detail::AvailabilityData>(); 309 } 310 const detail::AvailabilityData *getAvailabilityData() const { 311 return getTrailingObjects<detail::AvailabilityData>(); 312 } 313 314 private: 315 friend class AttributeFactory; 316 friend class AttributePool; 317 318 /// Constructor for attributes with expression arguments. 319 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, 320 IdentifierInfo *scopeName, SourceLocation scopeLoc, 321 ArgsUnion *args, unsigned numArgs, Syntax syntaxUsed, 322 SourceLocation ellipsisLoc) 323 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, 324 syntaxUsed), 325 EllipsisLoc(ellipsisLoc), NumArgs(numArgs), Invalid(false), 326 UsedAsTypeAttr(false), IsAvailability(false), 327 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), 328 HasProcessingCache(false), IsPragmaClangAttribute(false), 329 Info(ParsedAttrInfo::get(*this)) { 330 if (numArgs) 331 memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion)); 332 } 333 334 /// Constructor for availability attributes. 335 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, 336 IdentifierInfo *scopeName, SourceLocation scopeLoc, 337 IdentifierLoc *Parm, const AvailabilityChange &introduced, 338 const AvailabilityChange &deprecated, 339 const AvailabilityChange &obsoleted, SourceLocation unavailable, 340 const Expr *messageExpr, Syntax syntaxUsed, SourceLocation strict, 341 const Expr *replacementExpr) 342 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, 343 syntaxUsed), 344 NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true), 345 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false), 346 HasProcessingCache(false), IsPragmaClangAttribute(false), 347 UnavailableLoc(unavailable), MessageExpr(messageExpr), 348 Info(ParsedAttrInfo::get(*this)) { 349 ArgsUnion PVal(Parm); 350 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); 351 new (getAvailabilityData()) detail::AvailabilityData( 352 introduced, deprecated, obsoleted, strict, replacementExpr); 353 } 354 355 /// Constructor for objc_bridge_related attributes. 356 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, 357 IdentifierInfo *scopeName, SourceLocation scopeLoc, 358 IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3, 359 Syntax syntaxUsed) 360 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, 361 syntaxUsed), 362 NumArgs(3), Invalid(false), UsedAsTypeAttr(false), 363 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), 364 HasParsedType(false), HasProcessingCache(false), 365 IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) { 366 ArgsUnion *Args = getArgsBuffer(); 367 Args[0] = Parm1; 368 Args[1] = Parm2; 369 Args[2] = Parm3; 370 } 371 372 /// Constructor for type_tag_for_datatype attribute. 373 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, 374 IdentifierInfo *scopeName, SourceLocation scopeLoc, 375 IdentifierLoc *ArgKind, ParsedType matchingCType, 376 bool layoutCompatible, bool mustBeNull, Syntax syntaxUsed) 377 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, 378 syntaxUsed), 379 NumArgs(1), Invalid(false), UsedAsTypeAttr(false), 380 IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false), 381 HasParsedType(false), HasProcessingCache(false), 382 IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) { 383 ArgsUnion PVal(ArgKind); 384 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion)); 385 detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot(); 386 new (&ExtraData.MatchingCType) ParsedType(matchingCType); 387 ExtraData.LayoutCompatible = layoutCompatible; 388 ExtraData.MustBeNull = mustBeNull; 389 } 390 391 /// Constructor for attributes with a single type argument. 392 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, 393 IdentifierInfo *scopeName, SourceLocation scopeLoc, 394 ParsedType typeArg, Syntax syntaxUsed) 395 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, 396 syntaxUsed), 397 NumArgs(0), Invalid(false), UsedAsTypeAttr(false), 398 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false), 399 HasParsedType(true), HasProcessingCache(false), 400 IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) { 401 new (&getTypeBuffer()) ParsedType(typeArg); 402 } 403 404 /// Constructor for microsoft __declspec(property) attribute. 405 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange, 406 IdentifierInfo *scopeName, SourceLocation scopeLoc, 407 IdentifierInfo *getterId, IdentifierInfo *setterId, 408 Syntax syntaxUsed) 409 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, 410 syntaxUsed), 411 NumArgs(0), Invalid(false), UsedAsTypeAttr(false), 412 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true), 413 HasParsedType(false), HasProcessingCache(false), 414 IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) { 415 new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId); 416 } 417 418 /// Type tag information is stored immediately following the arguments, if 419 /// any, at the end of the object. They are mutually exclusive with 420 /// availability slots. 421 detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() { 422 return *getTrailingObjects<detail::TypeTagForDatatypeData>(); 423 } 424 const detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const { 425 return *getTrailingObjects<detail::TypeTagForDatatypeData>(); 426 } 427 428 /// The type buffer immediately follows the object and are mutually exclusive 429 /// with arguments. 430 ParsedType &getTypeBuffer() { return *getTrailingObjects<ParsedType>(); } 431 const ParsedType &getTypeBuffer() const { 432 return *getTrailingObjects<ParsedType>(); 433 } 434 435 /// The property data immediately follows the object is is mutually exclusive 436 /// with arguments. 437 detail::PropertyData &getPropertyDataBuffer() { 438 assert(IsProperty); 439 return *getTrailingObjects<detail::PropertyData>(); 440 } 441 const detail::PropertyData &getPropertyDataBuffer() const { 442 assert(IsProperty); 443 return *getTrailingObjects<detail::PropertyData>(); 444 } 445 446 size_t allocated_size() const; 447 448 public: 449 ParsedAttr(const ParsedAttr &) = delete; 450 ParsedAttr(ParsedAttr &&) = delete; 451 ParsedAttr &operator=(const ParsedAttr &) = delete; 452 ParsedAttr &operator=(ParsedAttr &&) = delete; 453 ~ParsedAttr() = delete; 454 455 void operator delete(void *) = delete; 456 457 bool hasParsedType() const { return HasParsedType; } 458 459 /// Is this the Microsoft __declspec(property) attribute? 460 bool isDeclspecPropertyAttribute() const { 461 return IsProperty; 462 } 463 464 bool isInvalid() const { return Invalid; } 465 void setInvalid(bool b = true) const { Invalid = b; } 466 467 bool hasProcessingCache() const { return HasProcessingCache; } 468 469 unsigned getProcessingCache() const { 470 assert(hasProcessingCache()); 471 return ProcessingCache; 472 } 473 474 void setProcessingCache(unsigned value) const { 475 ProcessingCache = value; 476 HasProcessingCache = true; 477 } 478 479 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; } 480 void setUsedAsTypeAttr(bool Used = true) { UsedAsTypeAttr = Used; } 481 482 /// True if the attribute is specified using '#pragma clang attribute'. 483 bool isPragmaClangAttribute() const { return IsPragmaClangAttribute; } 484 485 void setIsPragmaClangAttribute() { IsPragmaClangAttribute = true; } 486 487 bool isPackExpansion() const { return EllipsisLoc.isValid(); } 488 SourceLocation getEllipsisLoc() const { return EllipsisLoc; } 489 490 /// getNumArgs - Return the number of actual arguments to this attribute. 491 unsigned getNumArgs() const { return NumArgs; } 492 493 /// getArg - Return the specified argument. 494 ArgsUnion getArg(unsigned Arg) const { 495 assert(Arg < NumArgs && "Arg access out of range!"); 496 return getArgsBuffer()[Arg]; 497 } 498 499 bool isArgExpr(unsigned Arg) const { 500 return Arg < NumArgs && getArg(Arg).is<Expr*>(); 501 } 502 503 Expr *getArgAsExpr(unsigned Arg) const { 504 return getArg(Arg).get<Expr*>(); 505 } 506 507 bool isArgIdent(unsigned Arg) const { 508 return Arg < NumArgs && getArg(Arg).is<IdentifierLoc*>(); 509 } 510 511 IdentifierLoc *getArgAsIdent(unsigned Arg) const { 512 return getArg(Arg).get<IdentifierLoc*>(); 513 } 514 515 const AvailabilityChange &getAvailabilityIntroduced() const { 516 assert(getParsedKind() == AT_Availability && 517 "Not an availability attribute"); 518 return getAvailabilityData()->Changes[detail::IntroducedSlot]; 519 } 520 521 const AvailabilityChange &getAvailabilityDeprecated() const { 522 assert(getParsedKind() == AT_Availability && 523 "Not an availability attribute"); 524 return getAvailabilityData()->Changes[detail::DeprecatedSlot]; 525 } 526 527 const AvailabilityChange &getAvailabilityObsoleted() const { 528 assert(getParsedKind() == AT_Availability && 529 "Not an availability attribute"); 530 return getAvailabilityData()->Changes[detail::ObsoletedSlot]; 531 } 532 533 SourceLocation getStrictLoc() const { 534 assert(getParsedKind() == AT_Availability && 535 "Not an availability attribute"); 536 return getAvailabilityData()->StrictLoc; 537 } 538 539 SourceLocation getUnavailableLoc() const { 540 assert(getParsedKind() == AT_Availability && 541 "Not an availability attribute"); 542 return UnavailableLoc; 543 } 544 545 const Expr * getMessageExpr() const { 546 assert(getParsedKind() == AT_Availability && 547 "Not an availability attribute"); 548 return MessageExpr; 549 } 550 551 const Expr *getReplacementExpr() const { 552 assert(getParsedKind() == AT_Availability && 553 "Not an availability attribute"); 554 return getAvailabilityData()->Replacement; 555 } 556 557 const ParsedType &getMatchingCType() const { 558 assert(getParsedKind() == AT_TypeTagForDatatype && 559 "Not a type_tag_for_datatype attribute"); 560 return getTypeTagForDatatypeDataSlot().MatchingCType; 561 } 562 563 bool getLayoutCompatible() const { 564 assert(getParsedKind() == AT_TypeTagForDatatype && 565 "Not a type_tag_for_datatype attribute"); 566 return getTypeTagForDatatypeDataSlot().LayoutCompatible; 567 } 568 569 bool getMustBeNull() const { 570 assert(getParsedKind() == AT_TypeTagForDatatype && 571 "Not a type_tag_for_datatype attribute"); 572 return getTypeTagForDatatypeDataSlot().MustBeNull; 573 } 574 575 const ParsedType &getTypeArg() const { 576 assert(HasParsedType && "Not a type attribute"); 577 return getTypeBuffer(); 578 } 579 580 IdentifierInfo *getPropertyDataGetter() const { 581 assert(isDeclspecPropertyAttribute() && 582 "Not a __delcspec(property) attribute"); 583 return getPropertyDataBuffer().GetterId; 584 } 585 586 IdentifierInfo *getPropertyDataSetter() const { 587 assert(isDeclspecPropertyAttribute() && 588 "Not a __delcspec(property) attribute"); 589 return getPropertyDataBuffer().SetterId; 590 } 591 592 /// Set the macro identifier info object that this parsed attribute was 593 /// declared in if it was declared in a macro. Also set the expansion location 594 /// of the macro. 595 void setMacroIdentifier(IdentifierInfo *MacroName, SourceLocation Loc) { 596 MacroII = MacroName; 597 MacroExpansionLoc = Loc; 598 } 599 600 /// Returns true if this attribute was declared in a macro. 601 bool hasMacroIdentifier() const { return MacroII != nullptr; } 602 603 /// Return the macro identifier if this attribute was declared in a macro. 604 /// nullptr is returned if it was not declared in a macro. 605 IdentifierInfo *getMacroIdentifier() const { return MacroII; } 606 607 SourceLocation getMacroExpansionLoc() const { 608 assert(hasMacroIdentifier() && "Can only get the macro expansion location " 609 "if this attribute has a macro identifier."); 610 return MacroExpansionLoc; 611 } 612 613 /// Check if the attribute has exactly as many args as Num. May output an 614 /// error. Returns false if a diagnostic is produced. 615 bool checkExactlyNumArgs(class Sema &S, unsigned Num) const; 616 /// Check if the attribute has at least as many args as Num. May output an 617 /// error. Returns false if a diagnostic is produced. 618 bool checkAtLeastNumArgs(class Sema &S, unsigned Num) const; 619 /// Check if the attribute has at most as many args as Num. May output an 620 /// error. Returns false if a diagnostic is produced. 621 bool checkAtMostNumArgs(class Sema &S, unsigned Num) const; 622 623 bool isTargetSpecificAttr() const; 624 bool isTypeAttr() const; 625 bool isStmtAttr() const; 626 627 bool hasCustomParsing() const; 628 bool acceptsExprPack() const; 629 bool isParamExpr(size_t N) const; 630 unsigned getMinArgs() const; 631 unsigned getMaxArgs() const; 632 unsigned getNumArgMembers() const; 633 bool hasVariadicArg() const; 634 void handleAttrWithDelayedArgs(Sema &S, Decl *D) const; 635 bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const; 636 bool diagnoseAppertainsTo(class Sema &S, const Stmt *St) const; 637 bool diagnoseMutualExclusion(class Sema &S, const Decl *D) const; 638 // This function stub exists for parity with the declaration checking code so 639 // that checkCommonAttributeFeatures() can work generically on declarations 640 // or statements. 641 bool diagnoseMutualExclusion(class Sema &S, const Stmt *St) const { 642 return true; 643 } 644 bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const; 645 void getMatchRules(const LangOptions &LangOpts, 646 SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>> 647 &MatchRules) const; 648 bool diagnoseLangOpts(class Sema &S) const; 649 bool existsInTarget(const TargetInfo &Target) const; 650 bool isKnownToGCC() const; 651 bool isSupportedByPragmaAttribute() const; 652 653 /// Returns whether a [[]] attribute, if specified ahead of a declaration, 654 /// should be applied to the decl-specifier-seq instead (i.e. whether it 655 /// "slides" to the decl-specifier-seq). 656 /// 657 /// By the standard, attributes specified before the declaration always 658 /// appertain to the declaration, but historically we have allowed some of 659 /// these attributes to slide to the decl-specifier-seq, so we need to keep 660 /// supporting this behavior. 661 /// 662 /// This may only be called if isStandardAttributeSyntax() returns true. 663 bool slidesFromDeclToDeclSpecLegacyBehavior() const; 664 665 /// If the parsed attribute has a semantic equivalent, and it would 666 /// have a semantic Spelling enumeration (due to having semantically-distinct 667 /// spelling variations), return the value of that semantic spelling. If the 668 /// parsed attribute does not have a semantic equivalent, or would not have 669 /// a Spelling enumeration, the value UINT_MAX is returned. 670 unsigned getSemanticSpelling() const; 671 672 /// If this is an OpenCL address space attribute, returns its representation 673 /// in LangAS, otherwise returns default address space. 674 LangAS asOpenCLLangAS() const { 675 switch (getParsedKind()) { 676 case ParsedAttr::AT_OpenCLConstantAddressSpace: 677 return LangAS::opencl_constant; 678 case ParsedAttr::AT_OpenCLGlobalAddressSpace: 679 return LangAS::opencl_global; 680 case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace: 681 return LangAS::opencl_global_device; 682 case ParsedAttr::AT_OpenCLGlobalHostAddressSpace: 683 return LangAS::opencl_global_host; 684 case ParsedAttr::AT_OpenCLLocalAddressSpace: 685 return LangAS::opencl_local; 686 case ParsedAttr::AT_OpenCLPrivateAddressSpace: 687 return LangAS::opencl_private; 688 case ParsedAttr::AT_OpenCLGenericAddressSpace: 689 return LangAS::opencl_generic; 690 default: 691 return LangAS::Default; 692 } 693 } 694 695 /// If this is an OpenCL address space attribute, returns its SYCL 696 /// representation in LangAS, otherwise returns default address space. 697 LangAS asSYCLLangAS() const { 698 switch (getKind()) { 699 case ParsedAttr::AT_OpenCLGlobalAddressSpace: 700 return LangAS::sycl_global; 701 case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace: 702 return LangAS::sycl_global_device; 703 case ParsedAttr::AT_OpenCLGlobalHostAddressSpace: 704 return LangAS::sycl_global_host; 705 case ParsedAttr::AT_OpenCLLocalAddressSpace: 706 return LangAS::sycl_local; 707 case ParsedAttr::AT_OpenCLPrivateAddressSpace: 708 return LangAS::sycl_private; 709 case ParsedAttr::AT_OpenCLGenericAddressSpace: 710 default: 711 return LangAS::Default; 712 } 713 } 714 715 AttributeCommonInfo::Kind getKind() const { 716 return AttributeCommonInfo::Kind(Info.AttrKind); 717 } 718 const ParsedAttrInfo &getInfo() const { return Info; } 719 }; 720 721 class AttributePool; 722 /// A factory, from which one makes pools, from which one creates 723 /// individual attributes which are deallocated with the pool. 724 /// 725 /// Note that it's tolerably cheap to create and destroy one of 726 /// these as long as you don't actually allocate anything in it. 727 class AttributeFactory { 728 public: 729 enum { 730 AvailabilityAllocSize = 731 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 732 detail::TypeTagForDatatypeData, ParsedType, 733 detail::PropertyData>(1, 1, 0, 0, 0), 734 TypeTagForDatatypeAllocSize = 735 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 736 detail::TypeTagForDatatypeData, ParsedType, 737 detail::PropertyData>(1, 0, 1, 0, 0), 738 PropertyAllocSize = 739 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 740 detail::TypeTagForDatatypeData, ParsedType, 741 detail::PropertyData>(0, 0, 0, 0, 1), 742 }; 743 744 private: 745 enum { 746 /// The number of free lists we want to be sure to support 747 /// inline. This is just enough that availability attributes 748 /// don't surpass it. It's actually very unlikely we'll see an 749 /// attribute that needs more than that; on x86-64 you'd need 10 750 /// expression arguments, and on i386 you'd need 19. 751 InlineFreeListsCapacity = 752 1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *) 753 }; 754 755 llvm::BumpPtrAllocator Alloc; 756 757 /// Free lists. The index is determined by the following formula: 758 /// (size - sizeof(ParsedAttr)) / sizeof(void*) 759 SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists; 760 761 // The following are the private interface used by AttributePool. 762 friend class AttributePool; 763 764 /// Allocate an attribute of the given size. 765 void *allocate(size_t size); 766 767 void deallocate(ParsedAttr *AL); 768 769 /// Reclaim all the attributes in the given pool chain, which is 770 /// non-empty. Note that the current implementation is safe 771 /// against reclaiming things which were not actually allocated 772 /// with the allocator, although of course it's important to make 773 /// sure that their allocator lives at least as long as this one. 774 void reclaimPool(AttributePool &head); 775 776 public: 777 AttributeFactory(); 778 ~AttributeFactory(); 779 }; 780 781 class AttributePool { 782 friend class AttributeFactory; 783 friend class ParsedAttributes; 784 AttributeFactory &Factory; 785 llvm::SmallVector<ParsedAttr *> Attrs; 786 787 void *allocate(size_t size) { 788 return Factory.allocate(size); 789 } 790 791 ParsedAttr *add(ParsedAttr *attr) { 792 Attrs.push_back(attr); 793 return attr; 794 } 795 796 void remove(ParsedAttr *attr) { 797 assert(llvm::is_contained(Attrs, attr) && 798 "Can't take attribute from a pool that doesn't own it!"); 799 Attrs.erase(llvm::find(Attrs, attr)); 800 } 801 802 void takePool(AttributePool &pool); 803 804 public: 805 /// Create a new pool for a factory. 806 AttributePool(AttributeFactory &factory) : Factory(factory) {} 807 808 AttributePool(const AttributePool &) = delete; 809 810 ~AttributePool() { Factory.reclaimPool(*this); } 811 812 /// Move the given pool's allocations to this pool. 813 AttributePool(AttributePool &&pool) = default; 814 815 AttributeFactory &getFactory() const { return Factory; } 816 817 void clear() { 818 Factory.reclaimPool(*this); 819 Attrs.clear(); 820 } 821 822 /// Take the given pool's allocations and add them to this pool. 823 void takeAllFrom(AttributePool &pool) { 824 takePool(pool); 825 pool.Attrs.clear(); 826 } 827 828 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange, 829 IdentifierInfo *scopeName, SourceLocation scopeLoc, 830 ArgsUnion *args, unsigned numArgs, 831 ParsedAttr::Syntax syntax, 832 SourceLocation ellipsisLoc = SourceLocation()) { 833 size_t temp = 834 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 835 detail::TypeTagForDatatypeData, ParsedType, 836 detail::PropertyData>(numArgs, 0, 0, 0, 0); 837 (void)temp; 838 void *memory = allocate( 839 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 840 detail::TypeTagForDatatypeData, ParsedType, 841 detail::PropertyData>(numArgs, 0, 0, 0, 842 0)); 843 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, 844 args, numArgs, syntax, ellipsisLoc)); 845 } 846 847 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange, 848 IdentifierInfo *scopeName, SourceLocation scopeLoc, 849 IdentifierLoc *Param, const AvailabilityChange &introduced, 850 const AvailabilityChange &deprecated, 851 const AvailabilityChange &obsoleted, 852 SourceLocation unavailable, const Expr *MessageExpr, 853 ParsedAttr::Syntax syntax, SourceLocation strict, 854 const Expr *ReplacementExpr) { 855 void *memory = allocate(AttributeFactory::AvailabilityAllocSize); 856 return add(new (memory) ParsedAttr( 857 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated, 858 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr)); 859 } 860 861 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange, 862 IdentifierInfo *scopeName, SourceLocation scopeLoc, 863 IdentifierLoc *Param1, IdentifierLoc *Param2, 864 IdentifierLoc *Param3, ParsedAttr::Syntax syntax) { 865 void *memory = allocate( 866 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 867 detail::TypeTagForDatatypeData, ParsedType, 868 detail::PropertyData>(3, 0, 0, 0, 0)); 869 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, 870 Param1, Param2, Param3, syntax)); 871 } 872 873 ParsedAttr * 874 createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, 875 IdentifierInfo *scopeName, SourceLocation scopeLoc, 876 IdentifierLoc *argumentKind, 877 ParsedType matchingCType, bool layoutCompatible, 878 bool mustBeNull, ParsedAttr::Syntax syntax) { 879 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize); 880 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, 881 argumentKind, matchingCType, 882 layoutCompatible, mustBeNull, syntax)); 883 } 884 885 ParsedAttr *createTypeAttribute(IdentifierInfo *attrName, 886 SourceRange attrRange, 887 IdentifierInfo *scopeName, 888 SourceLocation scopeLoc, ParsedType typeArg, 889 ParsedAttr::Syntax syntaxUsed) { 890 void *memory = allocate( 891 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 892 detail::TypeTagForDatatypeData, ParsedType, 893 detail::PropertyData>(0, 0, 0, 1, 0)); 894 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, 895 typeArg, syntaxUsed)); 896 } 897 898 ParsedAttr * 899 createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange, 900 IdentifierInfo *scopeName, SourceLocation scopeLoc, 901 IdentifierInfo *getterId, IdentifierInfo *setterId, 902 ParsedAttr::Syntax syntaxUsed) { 903 void *memory = allocate(AttributeFactory::PropertyAllocSize); 904 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, 905 getterId, setterId, syntaxUsed)); 906 } 907 }; 908 909 class ParsedAttributesView { 910 using VecTy = llvm::SmallVector<ParsedAttr *>; 911 using SizeType = decltype(std::declval<VecTy>().size()); 912 913 public: 914 SourceRange Range; 915 916 static const ParsedAttributesView &none() { 917 static const ParsedAttributesView Attrs; 918 return Attrs; 919 } 920 921 bool empty() const { return AttrList.empty(); } 922 SizeType size() const { return AttrList.size(); } 923 ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; } 924 const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; } 925 926 void addAtEnd(ParsedAttr *newAttr) { 927 assert(newAttr); 928 AttrList.push_back(newAttr); 929 } 930 931 void remove(ParsedAttr *ToBeRemoved) { 932 assert(is_contained(AttrList, ToBeRemoved) && 933 "Cannot remove attribute that isn't in the list"); 934 AttrList.erase(llvm::find(AttrList, ToBeRemoved)); 935 } 936 937 void clearListOnly() { AttrList.clear(); } 938 939 struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator, 940 std::random_access_iterator_tag, 941 ParsedAttr> { 942 iterator() : iterator_adaptor_base(nullptr) {} 943 iterator(VecTy::iterator I) : iterator_adaptor_base(I) {} 944 reference operator*() const { return **I; } 945 friend class ParsedAttributesView; 946 }; 947 struct const_iterator 948 : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator, 949 std::random_access_iterator_tag, 950 ParsedAttr> { 951 const_iterator() : iterator_adaptor_base(nullptr) {} 952 const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {} 953 954 reference operator*() const { return **I; } 955 friend class ParsedAttributesView; 956 }; 957 958 void addAll(iterator B, iterator E) { 959 AttrList.insert(AttrList.begin(), B.I, E.I); 960 } 961 962 void addAll(const_iterator B, const_iterator E) { 963 AttrList.insert(AttrList.begin(), B.I, E.I); 964 } 965 966 void addAllAtEnd(iterator B, iterator E) { 967 AttrList.insert(AttrList.end(), B.I, E.I); 968 } 969 970 void addAllAtEnd(const_iterator B, const_iterator E) { 971 AttrList.insert(AttrList.end(), B.I, E.I); 972 } 973 974 iterator begin() { return iterator(AttrList.begin()); } 975 const_iterator begin() const { return const_iterator(AttrList.begin()); } 976 iterator end() { return iterator(AttrList.end()); } 977 const_iterator end() const { return const_iterator(AttrList.end()); } 978 979 ParsedAttr &front() { 980 assert(!empty()); 981 return *AttrList.front(); 982 } 983 const ParsedAttr &front() const { 984 assert(!empty()); 985 return *AttrList.front(); 986 } 987 ParsedAttr &back() { 988 assert(!empty()); 989 return *AttrList.back(); 990 } 991 const ParsedAttr &back() const { 992 assert(!empty()); 993 return *AttrList.back(); 994 } 995 996 bool hasAttribute(ParsedAttr::Kind K) const { 997 return llvm::any_of(AttrList, [K](const ParsedAttr *AL) { 998 return AL->getParsedKind() == K; 999 }); 1000 } 1001 1002 private: 1003 VecTy AttrList; 1004 }; 1005 1006 /// ParsedAttributes - A collection of parsed attributes. Currently 1007 /// we don't differentiate between the various attribute syntaxes, 1008 /// which is basically silly. 1009 /// 1010 /// Right now this is a very lightweight container, but the expectation 1011 /// is that this will become significantly more serious. 1012 class ParsedAttributes : public ParsedAttributesView { 1013 public: 1014 ParsedAttributes(AttributeFactory &factory) : pool(factory) {} 1015 ParsedAttributes(const ParsedAttributes &) = delete; 1016 1017 AttributePool &getPool() const { return pool; } 1018 1019 void takeAllFrom(ParsedAttributes &Other) { 1020 assert(&Other != this && 1021 "ParsedAttributes can't take attributes from itself"); 1022 addAll(Other.begin(), Other.end()); 1023 Other.clearListOnly(); 1024 pool.takeAllFrom(Other.pool); 1025 } 1026 1027 void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA) { 1028 assert(&Other != this && 1029 "ParsedAttributes can't take attribute from itself"); 1030 Other.getPool().remove(PA); 1031 Other.remove(PA); 1032 getPool().add(PA); 1033 addAtEnd(PA); 1034 } 1035 1036 void clear() { 1037 clearListOnly(); 1038 pool.clear(); 1039 Range = SourceRange(); 1040 } 1041 1042 /// Add attribute with expression arguments. 1043 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange, 1044 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1045 ArgsUnion *args, unsigned numArgs, 1046 ParsedAttr::Syntax syntax, 1047 SourceLocation ellipsisLoc = SourceLocation()) { 1048 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, 1049 args, numArgs, syntax, ellipsisLoc); 1050 addAtEnd(attr); 1051 return attr; 1052 } 1053 1054 /// Add availability attribute. 1055 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange, 1056 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1057 IdentifierLoc *Param, const AvailabilityChange &introduced, 1058 const AvailabilityChange &deprecated, 1059 const AvailabilityChange &obsoleted, 1060 SourceLocation unavailable, const Expr *MessageExpr, 1061 ParsedAttr::Syntax syntax, SourceLocation strict, 1062 const Expr *ReplacementExpr) { 1063 ParsedAttr *attr = pool.create( 1064 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated, 1065 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr); 1066 addAtEnd(attr); 1067 return attr; 1068 } 1069 1070 /// Add objc_bridge_related attribute. 1071 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange, 1072 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1073 IdentifierLoc *Param1, IdentifierLoc *Param2, 1074 IdentifierLoc *Param3, ParsedAttr::Syntax syntax) { 1075 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, 1076 Param1, Param2, Param3, syntax); 1077 addAtEnd(attr); 1078 return attr; 1079 } 1080 1081 /// Add type_tag_for_datatype attribute. 1082 ParsedAttr * 1083 addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, 1084 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1085 IdentifierLoc *argumentKind, 1086 ParsedType matchingCType, bool layoutCompatible, 1087 bool mustBeNull, ParsedAttr::Syntax syntax) { 1088 ParsedAttr *attr = pool.createTypeTagForDatatype( 1089 attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType, 1090 layoutCompatible, mustBeNull, syntax); 1091 addAtEnd(attr); 1092 return attr; 1093 } 1094 1095 /// Add an attribute with a single type argument. 1096 ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, 1097 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1098 ParsedType typeArg, 1099 ParsedAttr::Syntax syntaxUsed) { 1100 ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName, 1101 scopeLoc, typeArg, syntaxUsed); 1102 addAtEnd(attr); 1103 return attr; 1104 } 1105 1106 /// Add microsoft __delspec(property) attribute. 1107 ParsedAttr * 1108 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, 1109 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1110 IdentifierInfo *getterId, IdentifierInfo *setterId, 1111 ParsedAttr::Syntax syntaxUsed) { 1112 ParsedAttr *attr = 1113 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc, 1114 getterId, setterId, syntaxUsed); 1115 addAtEnd(attr); 1116 return attr; 1117 } 1118 1119 private: 1120 mutable AttributePool pool; 1121 }; 1122 1123 /// Consumes the attributes from `First` and `Second` and concatenates them into 1124 /// `Result`. Sets `Result.Range` to the combined range of `First` and `Second`. 1125 void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second, 1126 ParsedAttributes &Result); 1127 1128 /// These constants match the enumerated choices of 1129 /// err_attribute_argument_n_type and err_attribute_argument_type. 1130 enum AttributeArgumentNType { 1131 AANT_ArgumentIntOrBool, 1132 AANT_ArgumentIntegerConstant, 1133 AANT_ArgumentString, 1134 AANT_ArgumentIdentifier, 1135 AANT_ArgumentConstantExpr, 1136 AANT_ArgumentBuiltinFunction, 1137 }; 1138 1139 /// These constants match the enumerated choices of 1140 /// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 1141 enum AttributeDeclKind { 1142 ExpectedFunction, 1143 ExpectedUnion, 1144 ExpectedVariableOrFunction, 1145 ExpectedFunctionOrMethod, 1146 ExpectedFunctionMethodOrBlock, 1147 ExpectedFunctionMethodOrParameter, 1148 ExpectedVariable, 1149 ExpectedVariableOrField, 1150 ExpectedVariableFieldOrTag, 1151 ExpectedTypeOrNamespace, 1152 ExpectedFunctionVariableOrClass, 1153 ExpectedKernelFunction, 1154 ExpectedFunctionWithProtoType, 1155 }; 1156 1157 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 1158 const ParsedAttr &At) { 1159 DB.AddTaggedVal(reinterpret_cast<uint64_t>(At.getAttrName()), 1160 DiagnosticsEngine::ak_identifierinfo); 1161 return DB; 1162 } 1163 1164 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 1165 const ParsedAttr *At) { 1166 DB.AddTaggedVal(reinterpret_cast<uint64_t>(At->getAttrName()), 1167 DiagnosticsEngine::ak_identifierinfo); 1168 return DB; 1169 } 1170 1171 /// AttributeCommonInfo has a non-explicit constructor which takes an 1172 /// SourceRange as its only argument, this constructor has many uses so making 1173 /// it explicit is hard. This constructor causes ambiguity with 1174 /// DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, SourceRange R). 1175 /// We use SFINAE to disable any conversion and remove any ambiguity. 1176 template <typename ACI, 1177 typename std::enable_if_t< 1178 std::is_same<ACI, AttributeCommonInfo>::value, int> = 0> 1179 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 1180 const ACI &CI) { 1181 DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI.getAttrName()), 1182 DiagnosticsEngine::ak_identifierinfo); 1183 return DB; 1184 } 1185 1186 template <typename ACI, 1187 typename std::enable_if_t< 1188 std::is_same<ACI, AttributeCommonInfo>::value, int> = 0> 1189 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 1190 const ACI* CI) { 1191 DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI->getAttrName()), 1192 DiagnosticsEngine::ak_identifierinfo); 1193 return DB; 1194 } 1195 1196 } // namespace clang 1197 1198 #endif // LLVM_CLANG_SEMA_PARSEDATTR_H 1199