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