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