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