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