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