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