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