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 32namespace clang { 33 34class ASTContext; 35class Decl; 36class Expr; 37class IdentifierInfo; 38class LangOptions; 39class ParsedAttr; 40class Sema; 41class Stmt; 42class TargetInfo; 43 44struct 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 76protected: 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 98public: 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 155typedef 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. 160struct 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 174namespace detail { 175enum AvailabilitySlot { 176 IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots 177}; 178 179/// Describes the trailing object for Availability attribute in ParsedAttr. 180struct 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 196struct TypeTagForDatatypeData { 197 ParsedType MatchingCType; 198 unsigned LayoutCompatible : 1; 199 unsigned MustBeNull : 1; 200}; 201struct 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. 211struct 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. 221using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>; 222using 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/// 233class 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 255private: 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 314private: 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 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 448public: 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 /// If this is an HLSL address space attribute, returns its representation 716 /// in LangAS, otherwise returns default address space. 717 LangAS asHLSLLangAS() const { 718 switch (getParsedKind()) { 719 case ParsedAttr::AT_HLSLGroupSharedAddressSpace: 720 return LangAS::hlsl_groupshared; 721 default: 722 return LangAS::Default; 723 } 724 } 725 726 AttributeCommonInfo::Kind getKind() const { 727 return AttributeCommonInfo::Kind(Info.AttrKind); 728 } 729 const ParsedAttrInfo &getInfo() const { return Info; } 730}; 731 732class AttributePool; 733/// A factory, from which one makes pools, from which one creates 734/// individual attributes which are deallocated with the pool. 735/// 736/// Note that it's tolerably cheap to create and destroy one of 737/// these as long as you don't actually allocate anything in it. 738class AttributeFactory { 739public: 740 enum { 741 AvailabilityAllocSize = 742 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 743 detail::TypeTagForDatatypeData, ParsedType, 744 detail::PropertyData>(1, 1, 0, 0, 0), 745 TypeTagForDatatypeAllocSize = 746 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 747 detail::TypeTagForDatatypeData, ParsedType, 748 detail::PropertyData>(1, 0, 1, 0, 0), 749 PropertyAllocSize = 750 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 751 detail::TypeTagForDatatypeData, ParsedType, 752 detail::PropertyData>(0, 0, 0, 0, 1), 753 }; 754 755private: 756 enum { 757 /// The number of free lists we want to be sure to support 758 /// inline. This is just enough that availability attributes 759 /// don't surpass it. It's actually very unlikely we'll see an 760 /// attribute that needs more than that; on x86-64 you'd need 10 761 /// expression arguments, and on i386 you'd need 19. 762 InlineFreeListsCapacity = 763 1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *) 764 }; 765 766 llvm::BumpPtrAllocator Alloc; 767 768 /// Free lists. The index is determined by the following formula: 769 /// (size - sizeof(ParsedAttr)) / sizeof(void*) 770 SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists; 771 772 // The following are the private interface used by AttributePool. 773 friend class AttributePool; 774 775 /// Allocate an attribute of the given size. 776 void *allocate(size_t size); 777 778 void deallocate(ParsedAttr *AL); 779 780 /// Reclaim all the attributes in the given pool chain, which is 781 /// non-empty. Note that the current implementation is safe 782 /// against reclaiming things which were not actually allocated 783 /// with the allocator, although of course it's important to make 784 /// sure that their allocator lives at least as long as this one. 785 void reclaimPool(AttributePool &head); 786 787public: 788 AttributeFactory(); 789 ~AttributeFactory(); 790}; 791 792class AttributePool { 793 friend class AttributeFactory; 794 friend class ParsedAttributes; 795 AttributeFactory &Factory; 796 llvm::SmallVector<ParsedAttr *> Attrs; 797 798 void *allocate(size_t size) { 799 return Factory.allocate(size); 800 } 801 802 ParsedAttr *add(ParsedAttr *attr) { 803 Attrs.push_back(attr); 804 return attr; 805 } 806 807 void remove(ParsedAttr *attr) { 808 assert(llvm::is_contained(Attrs, attr) && 809 "Can't take attribute from a pool that doesn't own it!"); 810 Attrs.erase(llvm::find(Attrs, attr)); 811 } 812 813 void takePool(AttributePool &pool); 814 815public: 816 /// Create a new pool for a factory. 817 AttributePool(AttributeFactory &factory) : Factory(factory) {} 818 819 AttributePool(const AttributePool &) = delete; 820 821 ~AttributePool() { Factory.reclaimPool(*this); } 822 823 /// Move the given pool's allocations to this pool. 824 AttributePool(AttributePool &&pool) = default; 825 826 AttributeFactory &getFactory() const { return Factory; } 827 828 void clear() { 829 Factory.reclaimPool(*this); 830 Attrs.clear(); 831 } 832 833 /// Take the given pool's allocations and add them to this pool. 834 void takeAllFrom(AttributePool &pool) { 835 takePool(pool); 836 pool.Attrs.clear(); 837 } 838 839 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange, 840 IdentifierInfo *scopeName, SourceLocation scopeLoc, 841 ArgsUnion *args, unsigned numArgs, 842 ParsedAttr::Syntax syntax, 843 SourceLocation ellipsisLoc = SourceLocation()) { 844 size_t temp = 845 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 846 detail::TypeTagForDatatypeData, ParsedType, 847 detail::PropertyData>(numArgs, 0, 0, 0, 0); 848 (void)temp; 849 void *memory = allocate( 850 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 851 detail::TypeTagForDatatypeData, ParsedType, 852 detail::PropertyData>(numArgs, 0, 0, 0, 853 0)); 854 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, 855 args, numArgs, syntax, ellipsisLoc)); 856 } 857 858 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange, 859 IdentifierInfo *scopeName, SourceLocation scopeLoc, 860 IdentifierLoc *Param, const AvailabilityChange &introduced, 861 const AvailabilityChange &deprecated, 862 const AvailabilityChange &obsoleted, 863 SourceLocation unavailable, const Expr *MessageExpr, 864 ParsedAttr::Syntax syntax, SourceLocation strict, 865 const Expr *ReplacementExpr) { 866 void *memory = allocate(AttributeFactory::AvailabilityAllocSize); 867 return add(new (memory) ParsedAttr( 868 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated, 869 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr)); 870 } 871 872 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange, 873 IdentifierInfo *scopeName, SourceLocation scopeLoc, 874 IdentifierLoc *Param1, IdentifierLoc *Param2, 875 IdentifierLoc *Param3, ParsedAttr::Syntax syntax) { 876 void *memory = allocate( 877 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 878 detail::TypeTagForDatatypeData, ParsedType, 879 detail::PropertyData>(3, 0, 0, 0, 0)); 880 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, 881 Param1, Param2, Param3, syntax)); 882 } 883 884 ParsedAttr * 885 createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, 886 IdentifierInfo *scopeName, SourceLocation scopeLoc, 887 IdentifierLoc *argumentKind, 888 ParsedType matchingCType, bool layoutCompatible, 889 bool mustBeNull, ParsedAttr::Syntax syntax) { 890 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize); 891 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, 892 argumentKind, matchingCType, 893 layoutCompatible, mustBeNull, syntax)); 894 } 895 896 ParsedAttr *createTypeAttribute(IdentifierInfo *attrName, 897 SourceRange attrRange, 898 IdentifierInfo *scopeName, 899 SourceLocation scopeLoc, ParsedType typeArg, 900 ParsedAttr::Syntax syntaxUsed) { 901 void *memory = allocate( 902 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData, 903 detail::TypeTagForDatatypeData, ParsedType, 904 detail::PropertyData>(0, 0, 0, 1, 0)); 905 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, 906 typeArg, syntaxUsed)); 907 } 908 909 ParsedAttr * 910 createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange, 911 IdentifierInfo *scopeName, SourceLocation scopeLoc, 912 IdentifierInfo *getterId, IdentifierInfo *setterId, 913 ParsedAttr::Syntax syntaxUsed) { 914 void *memory = allocate(AttributeFactory::PropertyAllocSize); 915 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc, 916 getterId, setterId, syntaxUsed)); 917 } 918}; 919 920class ParsedAttributesView { 921 using VecTy = llvm::SmallVector<ParsedAttr *>; 922 using SizeType = decltype(std::declval<VecTy>().size()); 923 924public: 925 SourceRange Range; 926 927 static const ParsedAttributesView &none() { 928 static const ParsedAttributesView Attrs; 929 return Attrs; 930 } 931 932 bool empty() const { return AttrList.empty(); } 933 SizeType size() const { return AttrList.size(); } 934 ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; } 935 const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; } 936 937 void addAtEnd(ParsedAttr *newAttr) { 938 assert(newAttr); 939 AttrList.push_back(newAttr); 940 } 941 942 void remove(ParsedAttr *ToBeRemoved) { 943 assert(is_contained(AttrList, ToBeRemoved) && 944 "Cannot remove attribute that isn't in the list"); 945 AttrList.erase(llvm::find(AttrList, ToBeRemoved)); 946 } 947 948 void clearListOnly() { AttrList.clear(); } 949 950 struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator, 951 std::random_access_iterator_tag, 952 ParsedAttr> { 953 iterator() : iterator_adaptor_base(nullptr) {} 954 iterator(VecTy::iterator I) : iterator_adaptor_base(I) {} 955 reference operator*() const { return **I; } 956 friend class ParsedAttributesView; 957 }; 958 struct const_iterator 959 : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator, 960 std::random_access_iterator_tag, 961 ParsedAttr> { 962 const_iterator() : iterator_adaptor_base(nullptr) {} 963 const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {} 964 965 reference operator*() const { return **I; } 966 friend class ParsedAttributesView; 967 }; 968 969 void addAll(iterator B, iterator E) { 970 AttrList.insert(AttrList.begin(), B.I, E.I); 971 } 972 973 void addAll(const_iterator B, const_iterator E) { 974 AttrList.insert(AttrList.begin(), B.I, E.I); 975 } 976 977 void addAllAtEnd(iterator B, iterator E) { 978 AttrList.insert(AttrList.end(), B.I, E.I); 979 } 980 981 void addAllAtEnd(const_iterator B, const_iterator E) { 982 AttrList.insert(AttrList.end(), B.I, E.I); 983 } 984 985 iterator begin() { return iterator(AttrList.begin()); } 986 const_iterator begin() const { return const_iterator(AttrList.begin()); } 987 iterator end() { return iterator(AttrList.end()); } 988 const_iterator end() const { return const_iterator(AttrList.end()); } 989 990 ParsedAttr &front() { 991 assert(!empty()); 992 return *AttrList.front(); 993 } 994 const ParsedAttr &front() const { 995 assert(!empty()); 996 return *AttrList.front(); 997 } 998 ParsedAttr &back() { 999 assert(!empty()); 1000 return *AttrList.back(); 1001 } 1002 const ParsedAttr &back() const { 1003 assert(!empty()); 1004 return *AttrList.back(); 1005 } 1006 1007 bool hasAttribute(ParsedAttr::Kind K) const { 1008 return llvm::any_of(AttrList, [K](const ParsedAttr *AL) { 1009 return AL->getParsedKind() == K; 1010 }); 1011 } 1012 1013private: 1014 VecTy AttrList; 1015}; 1016 1017/// ParsedAttributes - A collection of parsed attributes. Currently 1018/// we don't differentiate between the various attribute syntaxes, 1019/// which is basically silly. 1020/// 1021/// Right now this is a very lightweight container, but the expectation 1022/// is that this will become significantly more serious. 1023class ParsedAttributes : public ParsedAttributesView { 1024public: 1025 ParsedAttributes(AttributeFactory &factory) : pool(factory) {} 1026 ParsedAttributes(const ParsedAttributes &) = delete; 1027 1028 AttributePool &getPool() const { return pool; } 1029 1030 void takeAllFrom(ParsedAttributes &Other) { 1031 assert(&Other != this && 1032 "ParsedAttributes can't take attributes from itself"); 1033 addAll(Other.begin(), Other.end()); 1034 Other.clearListOnly(); 1035 pool.takeAllFrom(Other.pool); 1036 } 1037 1038 void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA) { 1039 assert(&Other != this && 1040 "ParsedAttributes can't take attribute from itself"); 1041 Other.getPool().remove(PA); 1042 Other.remove(PA); 1043 getPool().add(PA); 1044 addAtEnd(PA); 1045 } 1046 1047 void clear() { 1048 clearListOnly(); 1049 pool.clear(); 1050 Range = SourceRange(); 1051 } 1052 1053 /// Add attribute with expression arguments. 1054 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange, 1055 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1056 ArgsUnion *args, unsigned numArgs, 1057 ParsedAttr::Syntax syntax, 1058 SourceLocation ellipsisLoc = SourceLocation()) { 1059 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, 1060 args, numArgs, syntax, ellipsisLoc); 1061 addAtEnd(attr); 1062 return attr; 1063 } 1064 1065 /// Add availability attribute. 1066 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange, 1067 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1068 IdentifierLoc *Param, const AvailabilityChange &introduced, 1069 const AvailabilityChange &deprecated, 1070 const AvailabilityChange &obsoleted, 1071 SourceLocation unavailable, const Expr *MessageExpr, 1072 ParsedAttr::Syntax syntax, SourceLocation strict, 1073 const Expr *ReplacementExpr) { 1074 ParsedAttr *attr = pool.create( 1075 attrName, attrRange, scopeName, scopeLoc, Param, introduced, deprecated, 1076 obsoleted, unavailable, MessageExpr, syntax, strict, ReplacementExpr); 1077 addAtEnd(attr); 1078 return attr; 1079 } 1080 1081 /// Add objc_bridge_related attribute. 1082 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange, 1083 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1084 IdentifierLoc *Param1, IdentifierLoc *Param2, 1085 IdentifierLoc *Param3, ParsedAttr::Syntax syntax) { 1086 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc, 1087 Param1, Param2, Param3, syntax); 1088 addAtEnd(attr); 1089 return attr; 1090 } 1091 1092 /// Add type_tag_for_datatype attribute. 1093 ParsedAttr * 1094 addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange, 1095 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1096 IdentifierLoc *argumentKind, 1097 ParsedType matchingCType, bool layoutCompatible, 1098 bool mustBeNull, ParsedAttr::Syntax syntax) { 1099 ParsedAttr *attr = pool.createTypeTagForDatatype( 1100 attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType, 1101 layoutCompatible, mustBeNull, syntax); 1102 addAtEnd(attr); 1103 return attr; 1104 } 1105 1106 /// Add an attribute with a single type argument. 1107 ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange, 1108 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1109 ParsedType typeArg, 1110 ParsedAttr::Syntax syntaxUsed) { 1111 ParsedAttr *attr = pool.createTypeAttribute(attrName, attrRange, scopeName, 1112 scopeLoc, typeArg, syntaxUsed); 1113 addAtEnd(attr); 1114 return attr; 1115 } 1116 1117 /// Add microsoft __delspec(property) attribute. 1118 ParsedAttr * 1119 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange, 1120 IdentifierInfo *scopeName, SourceLocation scopeLoc, 1121 IdentifierInfo *getterId, IdentifierInfo *setterId, 1122 ParsedAttr::Syntax syntaxUsed) { 1123 ParsedAttr *attr = 1124 pool.createPropertyAttribute(attrName, attrRange, scopeName, scopeLoc, 1125 getterId, setterId, syntaxUsed); 1126 addAtEnd(attr); 1127 return attr; 1128 } 1129 1130private: 1131 mutable AttributePool pool; 1132}; 1133 1134/// Consumes the attributes from `First` and `Second` and concatenates them into 1135/// `Result`. Sets `Result.Range` to the combined range of `First` and `Second`. 1136void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second, 1137 ParsedAttributes &Result); 1138 1139/// These constants match the enumerated choices of 1140/// err_attribute_argument_n_type and err_attribute_argument_type. 1141enum AttributeArgumentNType { 1142 AANT_ArgumentIntOrBool, 1143 AANT_ArgumentIntegerConstant, 1144 AANT_ArgumentString, 1145 AANT_ArgumentIdentifier, 1146 AANT_ArgumentConstantExpr, 1147 AANT_ArgumentBuiltinFunction, 1148}; 1149 1150/// These constants match the enumerated choices of 1151/// warn_attribute_wrong_decl_type and err_attribute_wrong_decl_type. 1152enum AttributeDeclKind { 1153 ExpectedFunction, 1154 ExpectedUnion, 1155 ExpectedVariableOrFunction, 1156 ExpectedFunctionOrMethod, 1157 ExpectedFunctionMethodOrBlock, 1158 ExpectedFunctionMethodOrParameter, 1159 ExpectedVariable, 1160 ExpectedVariableOrField, 1161 ExpectedVariableFieldOrTag, 1162 ExpectedTypeOrNamespace, 1163 ExpectedFunctionVariableOrClass, 1164 ExpectedKernelFunction, 1165 ExpectedFunctionWithProtoType, 1166}; 1167 1168inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 1169 const ParsedAttr &At) { 1170 DB.AddTaggedVal(reinterpret_cast<uint64_t>(At.getAttrName()), 1171 DiagnosticsEngine::ak_identifierinfo); 1172 return DB; 1173} 1174 1175inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 1176 const ParsedAttr *At) { 1177 DB.AddTaggedVal(reinterpret_cast<uint64_t>(At->getAttrName()), 1178 DiagnosticsEngine::ak_identifierinfo); 1179 return DB; 1180} 1181 1182/// AttributeCommonInfo has a non-explicit constructor which takes an 1183/// SourceRange as its only argument, this constructor has many uses so making 1184/// it explicit is hard. This constructor causes ambiguity with 1185/// DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB, SourceRange R). 1186/// We use SFINAE to disable any conversion and remove any ambiguity. 1187template < 1188 typename ACI, 1189 std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0> 1190inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 1191 const ACI &CI) { 1192 DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI.getAttrName()), 1193 DiagnosticsEngine::ak_identifierinfo); 1194 return DB; 1195} 1196 1197template < 1198 typename ACI, 1199 std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0> 1200inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB, 1201 const ACI *CI) { 1202 DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI->getAttrName()), 1203 DiagnosticsEngine::ak_identifierinfo); 1204 return DB; 1205} 1206 1207} // namespace clang 1208 1209#endif // LLVM_CLANG_SEMA_PARSEDATTR_H 1210