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