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