File indexing completed on 2026-05-10 08:37:01
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_SEMA_PARSEDATTR_H
0015 #define LLVM_CLANG_SEMA_PARSEDATTR_H
0016
0017 #include "clang/Basic/AttrSubjectMatchRules.h"
0018 #include "clang/Basic/AttributeCommonInfo.h"
0019 #include "clang/Basic/Diagnostic.h"
0020 #include "clang/Basic/ParsedAttrInfo.h"
0021 #include "clang/Basic/SourceLocation.h"
0022 #include "clang/Sema/Ownership.h"
0023 #include "llvm/ADT/PointerUnion.h"
0024 #include "llvm/ADT/SmallVector.h"
0025 #include "llvm/Support/Allocator.h"
0026 #include "llvm/Support/VersionTuple.h"
0027 #include <bitset>
0028 #include <cassert>
0029 #include <cstddef>
0030 #include <cstring>
0031 #include <utility>
0032
0033 namespace clang {
0034
0035 class ASTContext;
0036 class Decl;
0037 class Expr;
0038 class IdentifierInfo;
0039 class LangOptions;
0040 class Sema;
0041 class Stmt;
0042 class TargetInfo;
0043 struct IdentifierLoc;
0044
0045
0046
0047
0048 struct AvailabilityChange {
0049
0050 SourceLocation KeywordLoc;
0051
0052
0053 VersionTuple Version;
0054
0055
0056 SourceRange VersionRange;
0057
0058
0059 bool isValid() const { return !Version.empty(); }
0060 };
0061
0062 namespace detail {
0063 enum AvailabilitySlot {
0064 IntroducedSlot, DeprecatedSlot, ObsoletedSlot, NumAvailabilitySlots
0065 };
0066
0067
0068 struct AvailabilityData {
0069 AvailabilityChange Changes[NumAvailabilitySlots];
0070 SourceLocation StrictLoc;
0071 const Expr *Replacement;
0072 const IdentifierLoc *EnvironmentLoc;
0073
0074 AvailabilityData(const AvailabilityChange &Introduced,
0075 const AvailabilityChange &Deprecated,
0076 const AvailabilityChange &Obsoleted, SourceLocation Strict,
0077 const Expr *ReplaceExpr, const IdentifierLoc *EnvironmentLoc)
0078 : StrictLoc(Strict), Replacement(ReplaceExpr),
0079 EnvironmentLoc(EnvironmentLoc) {
0080 Changes[IntroducedSlot] = Introduced;
0081 Changes[DeprecatedSlot] = Deprecated;
0082 Changes[ObsoletedSlot] = Obsoleted;
0083 }
0084 };
0085
0086 struct TypeTagForDatatypeData {
0087 ParsedType MatchingCType;
0088 LLVM_PREFERRED_TYPE(bool)
0089 unsigned LayoutCompatible : 1;
0090 LLVM_PREFERRED_TYPE(bool)
0091 unsigned MustBeNull : 1;
0092 };
0093 struct PropertyData {
0094 IdentifierInfo *GetterId, *SetterId;
0095
0096 PropertyData(IdentifierInfo *getterId, IdentifierInfo *setterId)
0097 : GetterId(getterId), SetterId(setterId) {}
0098 };
0099
0100 }
0101
0102
0103 struct IdentifierLoc {
0104 SourceLocation Loc;
0105 IdentifierInfo *Ident;
0106
0107 static IdentifierLoc *create(ASTContext &Ctx, SourceLocation Loc,
0108 IdentifierInfo *Ident);
0109 };
0110
0111
0112
0113 using ArgsUnion = llvm::PointerUnion<Expr *, IdentifierLoc *>;
0114 using ArgsVector = llvm::SmallVector<ArgsUnion, 12U>;
0115
0116
0117
0118
0119
0120
0121
0122
0123
0124
0125 class ParsedAttr final
0126 : public AttributeCommonInfo,
0127 private llvm::TrailingObjects<
0128 ParsedAttr, ArgsUnion, detail::AvailabilityData,
0129 detail::TypeTagForDatatypeData, ParsedType, detail::PropertyData> {
0130 friend TrailingObjects;
0131
0132 size_t numTrailingObjects(OverloadToken<ArgsUnion>) const { return NumArgs; }
0133 size_t numTrailingObjects(OverloadToken<detail::AvailabilityData>) const {
0134 return IsAvailability;
0135 }
0136 size_t
0137 numTrailingObjects(OverloadToken<detail::TypeTagForDatatypeData>) const {
0138 return IsTypeTagForDatatype;
0139 }
0140 size_t numTrailingObjects(OverloadToken<ParsedType>) const {
0141 return HasParsedType;
0142 }
0143 size_t numTrailingObjects(OverloadToken<detail::PropertyData>) const {
0144 return IsProperty;
0145 }
0146
0147 private:
0148 IdentifierInfo *MacroII = nullptr;
0149 SourceLocation MacroExpansionLoc;
0150 SourceLocation EllipsisLoc;
0151
0152
0153
0154 unsigned NumArgs : 16;
0155
0156
0157 LLVM_PREFERRED_TYPE(bool)
0158 mutable unsigned Invalid : 1;
0159
0160
0161 LLVM_PREFERRED_TYPE(bool)
0162 mutable unsigned UsedAsTypeAttr : 1;
0163
0164
0165
0166 LLVM_PREFERRED_TYPE(bool)
0167 unsigned IsAvailability : 1;
0168
0169
0170
0171 LLVM_PREFERRED_TYPE(bool)
0172 unsigned IsTypeTagForDatatype : 1;
0173
0174
0175
0176 LLVM_PREFERRED_TYPE(bool)
0177 unsigned IsProperty : 1;
0178
0179
0180 LLVM_PREFERRED_TYPE(bool)
0181 unsigned HasParsedType : 1;
0182
0183
0184 LLVM_PREFERRED_TYPE(bool)
0185 mutable unsigned HasProcessingCache : 1;
0186
0187
0188 mutable unsigned ProcessingCache : 8;
0189
0190
0191 LLVM_PREFERRED_TYPE(bool)
0192 mutable unsigned IsPragmaClangAttribute : 1;
0193
0194
0195
0196 SourceLocation UnavailableLoc;
0197
0198 const Expr *MessageExpr;
0199
0200 const ParsedAttrInfo &Info;
0201
0202 ArgsUnion *getArgsBuffer() { return getTrailingObjects<ArgsUnion>(); }
0203 ArgsUnion const *getArgsBuffer() const {
0204 return getTrailingObjects<ArgsUnion>();
0205 }
0206
0207 detail::AvailabilityData *getAvailabilityData() {
0208 return getTrailingObjects<detail::AvailabilityData>();
0209 }
0210 const detail::AvailabilityData *getAvailabilityData() const {
0211 return getTrailingObjects<detail::AvailabilityData>();
0212 }
0213
0214 private:
0215 friend class AttributeFactory;
0216 friend class AttributePool;
0217
0218
0219 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
0220 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0221 ArgsUnion *args, unsigned numArgs, Form formUsed,
0222 SourceLocation ellipsisLoc)
0223 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
0224 EllipsisLoc(ellipsisLoc), NumArgs(numArgs), Invalid(false),
0225 UsedAsTypeAttr(false), IsAvailability(false),
0226 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
0227 HasProcessingCache(false), IsPragmaClangAttribute(false),
0228 Info(ParsedAttrInfo::get(*this)) {
0229 if (numArgs)
0230 memcpy(getArgsBuffer(), args, numArgs * sizeof(ArgsUnion));
0231 }
0232
0233
0234 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
0235 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0236 IdentifierLoc *Parm, const AvailabilityChange &introduced,
0237 const AvailabilityChange &deprecated,
0238 const AvailabilityChange &obsoleted, SourceLocation unavailable,
0239 const Expr *messageExpr, Form formUsed, SourceLocation strict,
0240 const Expr *replacementExpr, const IdentifierLoc *environmentLoc)
0241 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
0242 NumArgs(1), Invalid(false), UsedAsTypeAttr(false), IsAvailability(true),
0243 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(false),
0244 HasProcessingCache(false), IsPragmaClangAttribute(false),
0245 UnavailableLoc(unavailable), MessageExpr(messageExpr),
0246 Info(ParsedAttrInfo::get(*this)) {
0247 ArgsUnion PVal(Parm);
0248 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
0249 new (getAvailabilityData())
0250 detail::AvailabilityData(introduced, deprecated, obsoleted, strict,
0251 replacementExpr, environmentLoc);
0252 }
0253
0254
0255 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
0256 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0257 IdentifierLoc *Parm1, IdentifierLoc *Parm2, IdentifierLoc *Parm3,
0258 Form formUsed)
0259 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
0260 NumArgs(3), Invalid(false), UsedAsTypeAttr(false),
0261 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(false),
0262 HasParsedType(false), HasProcessingCache(false),
0263 IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
0264 ArgsUnion *Args = getArgsBuffer();
0265 Args[0] = Parm1;
0266 Args[1] = Parm2;
0267 Args[2] = Parm3;
0268 }
0269
0270
0271 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
0272 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0273 IdentifierLoc *ArgKind, ParsedType matchingCType,
0274 bool layoutCompatible, bool mustBeNull, Form formUsed)
0275 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
0276 NumArgs(1), Invalid(false), UsedAsTypeAttr(false),
0277 IsAvailability(false), IsTypeTagForDatatype(true), IsProperty(false),
0278 HasParsedType(false), HasProcessingCache(false),
0279 IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
0280 ArgsUnion PVal(ArgKind);
0281 memcpy(getArgsBuffer(), &PVal, sizeof(ArgsUnion));
0282 detail::TypeTagForDatatypeData &ExtraData = getTypeTagForDatatypeDataSlot();
0283 new (&ExtraData.MatchingCType) ParsedType(matchingCType);
0284 ExtraData.LayoutCompatible = layoutCompatible;
0285 ExtraData.MustBeNull = mustBeNull;
0286 }
0287
0288
0289 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
0290 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0291 ParsedType typeArg, Form formUsed, SourceLocation ellipsisLoc)
0292 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
0293 EllipsisLoc(ellipsisLoc), NumArgs(0), Invalid(false),
0294 UsedAsTypeAttr(false), IsAvailability(false),
0295 IsTypeTagForDatatype(false), IsProperty(false), HasParsedType(true),
0296 HasProcessingCache(false), IsPragmaClangAttribute(false),
0297 Info(ParsedAttrInfo::get(*this)) {
0298 new (&getTypeBuffer()) ParsedType(typeArg);
0299 }
0300
0301
0302 ParsedAttr(IdentifierInfo *attrName, SourceRange attrRange,
0303 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0304 IdentifierInfo *getterId, IdentifierInfo *setterId, Form formUsed)
0305 : AttributeCommonInfo(attrName, scopeName, attrRange, scopeLoc, formUsed),
0306 NumArgs(0), Invalid(false), UsedAsTypeAttr(false),
0307 IsAvailability(false), IsTypeTagForDatatype(false), IsProperty(true),
0308 HasParsedType(false), HasProcessingCache(false),
0309 IsPragmaClangAttribute(false), Info(ParsedAttrInfo::get(*this)) {
0310 new (&getPropertyDataBuffer()) detail::PropertyData(getterId, setterId);
0311 }
0312
0313
0314
0315
0316 detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() {
0317 return *getTrailingObjects<detail::TypeTagForDatatypeData>();
0318 }
0319 const detail::TypeTagForDatatypeData &getTypeTagForDatatypeDataSlot() const {
0320 return *getTrailingObjects<detail::TypeTagForDatatypeData>();
0321 }
0322
0323
0324
0325 ParsedType &getTypeBuffer() { return *getTrailingObjects<ParsedType>(); }
0326 const ParsedType &getTypeBuffer() const {
0327 return *getTrailingObjects<ParsedType>();
0328 }
0329
0330
0331
0332 detail::PropertyData &getPropertyDataBuffer() {
0333 assert(IsProperty);
0334 return *getTrailingObjects<detail::PropertyData>();
0335 }
0336 const detail::PropertyData &getPropertyDataBuffer() const {
0337 assert(IsProperty);
0338 return *getTrailingObjects<detail::PropertyData>();
0339 }
0340
0341 size_t allocated_size() const;
0342
0343 public:
0344 ParsedAttr(const ParsedAttr &) = delete;
0345 ParsedAttr(ParsedAttr &&) = delete;
0346 ParsedAttr &operator=(const ParsedAttr &) = delete;
0347 ParsedAttr &operator=(ParsedAttr &&) = delete;
0348 ~ParsedAttr() = delete;
0349
0350 void operator delete(void *) = delete;
0351
0352 bool hasParsedType() const { return HasParsedType; }
0353
0354
0355 bool isDeclspecPropertyAttribute() const {
0356 return IsProperty;
0357 }
0358
0359 bool isInvalid() const { return Invalid; }
0360 void setInvalid(bool b = true) const { Invalid = b; }
0361
0362 bool hasProcessingCache() const { return HasProcessingCache; }
0363
0364 unsigned getProcessingCache() const {
0365 assert(hasProcessingCache());
0366 return ProcessingCache;
0367 }
0368
0369 void setProcessingCache(unsigned value) const {
0370 ProcessingCache = value;
0371 HasProcessingCache = true;
0372 }
0373
0374 bool isUsedAsTypeAttr() const { return UsedAsTypeAttr; }
0375 void setUsedAsTypeAttr(bool Used = true) { UsedAsTypeAttr = Used; }
0376
0377
0378 bool isPragmaClangAttribute() const { return IsPragmaClangAttribute; }
0379
0380 void setIsPragmaClangAttribute() { IsPragmaClangAttribute = true; }
0381
0382 bool isPackExpansion() const { return EllipsisLoc.isValid(); }
0383 SourceLocation getEllipsisLoc() const { return EllipsisLoc; }
0384
0385
0386 unsigned getNumArgs() const { return NumArgs; }
0387
0388
0389 ArgsUnion getArg(unsigned Arg) const {
0390 assert(Arg < NumArgs && "Arg access out of range!");
0391 return getArgsBuffer()[Arg];
0392 }
0393
0394 bool isArgExpr(unsigned Arg) const {
0395 return Arg < NumArgs && isa<Expr *>(getArg(Arg));
0396 }
0397
0398 Expr *getArgAsExpr(unsigned Arg) const { return cast<Expr *>(getArg(Arg)); }
0399
0400 bool isArgIdent(unsigned Arg) const {
0401 return Arg < NumArgs && isa<IdentifierLoc *>(getArg(Arg));
0402 }
0403
0404 IdentifierLoc *getArgAsIdent(unsigned Arg) const {
0405 return cast<IdentifierLoc *>(getArg(Arg));
0406 }
0407
0408 const AvailabilityChange &getAvailabilityIntroduced() const {
0409 assert(getParsedKind() == AT_Availability &&
0410 "Not an availability attribute");
0411 return getAvailabilityData()->Changes[detail::IntroducedSlot];
0412 }
0413
0414 const AvailabilityChange &getAvailabilityDeprecated() const {
0415 assert(getParsedKind() == AT_Availability &&
0416 "Not an availability attribute");
0417 return getAvailabilityData()->Changes[detail::DeprecatedSlot];
0418 }
0419
0420 const AvailabilityChange &getAvailabilityObsoleted() const {
0421 assert(getParsedKind() == AT_Availability &&
0422 "Not an availability attribute");
0423 return getAvailabilityData()->Changes[detail::ObsoletedSlot];
0424 }
0425
0426 SourceLocation getStrictLoc() const {
0427 assert(getParsedKind() == AT_Availability &&
0428 "Not an availability attribute");
0429 return getAvailabilityData()->StrictLoc;
0430 }
0431
0432 SourceLocation getUnavailableLoc() const {
0433 assert(getParsedKind() == AT_Availability &&
0434 "Not an availability attribute");
0435 return UnavailableLoc;
0436 }
0437
0438 const Expr * getMessageExpr() const {
0439 assert(getParsedKind() == AT_Availability &&
0440 "Not an availability attribute");
0441 return MessageExpr;
0442 }
0443
0444 const Expr *getReplacementExpr() const {
0445 assert(getParsedKind() == AT_Availability &&
0446 "Not an availability attribute");
0447 return getAvailabilityData()->Replacement;
0448 }
0449
0450 const IdentifierLoc *getEnvironment() const {
0451 assert(getParsedKind() == AT_Availability &&
0452 "Not an availability attribute");
0453 return getAvailabilityData()->EnvironmentLoc;
0454 }
0455
0456 const ParsedType &getMatchingCType() const {
0457 assert(getParsedKind() == AT_TypeTagForDatatype &&
0458 "Not a type_tag_for_datatype attribute");
0459 return getTypeTagForDatatypeDataSlot().MatchingCType;
0460 }
0461
0462 bool getLayoutCompatible() const {
0463 assert(getParsedKind() == AT_TypeTagForDatatype &&
0464 "Not a type_tag_for_datatype attribute");
0465 return getTypeTagForDatatypeDataSlot().LayoutCompatible;
0466 }
0467
0468 bool getMustBeNull() const {
0469 assert(getParsedKind() == AT_TypeTagForDatatype &&
0470 "Not a type_tag_for_datatype attribute");
0471 return getTypeTagForDatatypeDataSlot().MustBeNull;
0472 }
0473
0474 const ParsedType &getTypeArg() const {
0475 assert(HasParsedType && "Not a type attribute");
0476 return getTypeBuffer();
0477 }
0478
0479 IdentifierInfo *getPropertyDataGetter() const {
0480 assert(isDeclspecPropertyAttribute() &&
0481 "Not a __delcspec(property) attribute");
0482 return getPropertyDataBuffer().GetterId;
0483 }
0484
0485 IdentifierInfo *getPropertyDataSetter() const {
0486 assert(isDeclspecPropertyAttribute() &&
0487 "Not a __delcspec(property) attribute");
0488 return getPropertyDataBuffer().SetterId;
0489 }
0490
0491
0492
0493
0494 void setMacroIdentifier(IdentifierInfo *MacroName, SourceLocation Loc) {
0495 MacroII = MacroName;
0496 MacroExpansionLoc = Loc;
0497 }
0498
0499
0500 bool hasMacroIdentifier() const { return MacroII != nullptr; }
0501
0502
0503
0504 IdentifierInfo *getMacroIdentifier() const { return MacroII; }
0505
0506 SourceLocation getMacroExpansionLoc() const {
0507 assert(hasMacroIdentifier() && "Can only get the macro expansion location "
0508 "if this attribute has a macro identifier.");
0509 return MacroExpansionLoc;
0510 }
0511
0512
0513
0514 bool checkExactlyNumArgs(class Sema &S, unsigned Num) const;
0515
0516
0517 bool checkAtLeastNumArgs(class Sema &S, unsigned Num) const;
0518
0519
0520 bool checkAtMostNumArgs(class Sema &S, unsigned Num) const;
0521
0522 bool isTargetSpecificAttr() const;
0523 bool isTypeAttr() const;
0524 bool isStmtAttr() const;
0525
0526 bool hasCustomParsing() const;
0527 bool acceptsExprPack() const;
0528 bool isParamExpr(size_t N) const;
0529 unsigned getMinArgs() const;
0530 unsigned getMaxArgs() const;
0531 unsigned getNumArgMembers() const;
0532 bool hasVariadicArg() const;
0533 void handleAttrWithDelayedArgs(Sema &S, Decl *D) const;
0534 bool diagnoseAppertainsTo(class Sema &S, const Decl *D) const;
0535 bool diagnoseAppertainsTo(class Sema &S, const Stmt *St) const;
0536 bool diagnoseMutualExclusion(class Sema &S, const Decl *D) const;
0537
0538
0539
0540 bool diagnoseMutualExclusion(class Sema &S, const Stmt *St) const {
0541 return true;
0542 }
0543 bool appliesToDecl(const Decl *D, attr::SubjectMatchRule MatchRule) const;
0544 void getMatchRules(const LangOptions &LangOpts,
0545 SmallVectorImpl<std::pair<attr::SubjectMatchRule, bool>>
0546 &MatchRules) const;
0547 bool diagnoseLangOpts(class Sema &S) const;
0548 bool existsInTarget(const TargetInfo &Target) const;
0549 bool isKnownToGCC() const;
0550 bool isSupportedByPragmaAttribute() const;
0551
0552
0553
0554
0555
0556
0557
0558
0559
0560
0561
0562 bool slidesFromDeclToDeclSpecLegacyBehavior() const;
0563
0564
0565
0566
0567
0568
0569 unsigned getSemanticSpelling() const;
0570
0571
0572
0573 LangAS asOpenCLLangAS() const {
0574 switch (getParsedKind()) {
0575 case ParsedAttr::AT_OpenCLConstantAddressSpace:
0576 return LangAS::opencl_constant;
0577 case ParsedAttr::AT_OpenCLGlobalAddressSpace:
0578 return LangAS::opencl_global;
0579 case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
0580 return LangAS::opencl_global_device;
0581 case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
0582 return LangAS::opencl_global_host;
0583 case ParsedAttr::AT_OpenCLLocalAddressSpace:
0584 return LangAS::opencl_local;
0585 case ParsedAttr::AT_OpenCLPrivateAddressSpace:
0586 return LangAS::opencl_private;
0587 case ParsedAttr::AT_OpenCLGenericAddressSpace:
0588 return LangAS::opencl_generic;
0589 default:
0590 return LangAS::Default;
0591 }
0592 }
0593
0594
0595
0596 LangAS asSYCLLangAS() const {
0597 switch (getKind()) {
0598 case ParsedAttr::AT_OpenCLGlobalAddressSpace:
0599 return LangAS::sycl_global;
0600 case ParsedAttr::AT_OpenCLGlobalDeviceAddressSpace:
0601 return LangAS::sycl_global_device;
0602 case ParsedAttr::AT_OpenCLGlobalHostAddressSpace:
0603 return LangAS::sycl_global_host;
0604 case ParsedAttr::AT_OpenCLLocalAddressSpace:
0605 return LangAS::sycl_local;
0606 case ParsedAttr::AT_OpenCLPrivateAddressSpace:
0607 return LangAS::sycl_private;
0608 case ParsedAttr::AT_OpenCLGenericAddressSpace:
0609 default:
0610 return LangAS::Default;
0611 }
0612 }
0613
0614
0615
0616 LangAS asHLSLLangAS() const {
0617 switch (getParsedKind()) {
0618 case ParsedAttr::AT_HLSLGroupSharedAddressSpace:
0619 return LangAS::hlsl_groupshared;
0620 default:
0621 return LangAS::Default;
0622 }
0623 }
0624
0625 AttributeCommonInfo::Kind getKind() const {
0626 return AttributeCommonInfo::Kind(Info.AttrKind);
0627 }
0628 const ParsedAttrInfo &getInfo() const { return Info; }
0629 };
0630
0631 class AttributePool;
0632
0633
0634
0635
0636
0637 class AttributeFactory {
0638 public:
0639 enum {
0640 AvailabilityAllocSize =
0641 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
0642 detail::TypeTagForDatatypeData, ParsedType,
0643 detail::PropertyData>(1, 1, 0, 0, 0),
0644 TypeTagForDatatypeAllocSize =
0645 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
0646 detail::TypeTagForDatatypeData, ParsedType,
0647 detail::PropertyData>(1, 0, 1, 0, 0),
0648 PropertyAllocSize =
0649 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
0650 detail::TypeTagForDatatypeData, ParsedType,
0651 detail::PropertyData>(0, 0, 0, 0, 1),
0652 };
0653
0654 private:
0655 enum {
0656
0657
0658
0659
0660
0661 InlineFreeListsCapacity =
0662 1 + (AvailabilityAllocSize - sizeof(ParsedAttr)) / sizeof(void *)
0663 };
0664
0665 llvm::BumpPtrAllocator Alloc;
0666
0667
0668
0669 SmallVector<SmallVector<ParsedAttr *, 8>, InlineFreeListsCapacity> FreeLists;
0670
0671
0672 friend class AttributePool;
0673
0674
0675 void *allocate(size_t size);
0676
0677 void deallocate(ParsedAttr *AL);
0678
0679
0680
0681
0682
0683
0684 void reclaimPool(AttributePool &head);
0685
0686 public:
0687 AttributeFactory();
0688 ~AttributeFactory();
0689 };
0690
0691 class ParsedAttributesView;
0692 class AttributePool {
0693 friend class AttributeFactory;
0694 friend class ParsedAttributes;
0695 AttributeFactory &Factory;
0696 llvm::SmallVector<ParsedAttr *> Attrs;
0697
0698 void *allocate(size_t size) {
0699 return Factory.allocate(size);
0700 }
0701
0702 ParsedAttr *add(ParsedAttr *attr) {
0703 Attrs.push_back(attr);
0704 return attr;
0705 }
0706
0707 void remove(ParsedAttr *attr) {
0708 assert(llvm::is_contained(Attrs, attr) &&
0709 "Can't take attribute from a pool that doesn't own it!");
0710 Attrs.erase(llvm::find(Attrs, attr));
0711 }
0712
0713 void takePool(AttributePool &pool);
0714
0715 public:
0716
0717 AttributePool(AttributeFactory &factory) : Factory(factory) {}
0718
0719 AttributePool(const AttributePool &) = delete;
0720
0721
0722 AttributePool &operator=(const AttributePool &) = delete;
0723
0724 ~AttributePool() { Factory.reclaimPool(*this); }
0725
0726
0727 AttributePool(AttributePool &&pool) = default;
0728
0729
0730
0731 AttributePool &operator=(AttributePool &&pool) = delete;
0732
0733 AttributeFactory &getFactory() const { return Factory; }
0734
0735 void clear() {
0736 Factory.reclaimPool(*this);
0737 Attrs.clear();
0738 }
0739
0740
0741 void takeAllFrom(AttributePool &pool) {
0742 takePool(pool);
0743 pool.Attrs.clear();
0744 }
0745
0746
0747
0748 void takeFrom(ParsedAttributesView &List, AttributePool &Pool);
0749
0750 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
0751 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0752 ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form,
0753 SourceLocation ellipsisLoc = SourceLocation()) {
0754 void *memory = allocate(
0755 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
0756 detail::TypeTagForDatatypeData, ParsedType,
0757 detail::PropertyData>(numArgs, 0, 0, 0,
0758 0));
0759 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
0760 args, numArgs, form, ellipsisLoc));
0761 }
0762
0763 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
0764 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0765 IdentifierLoc *Param, const AvailabilityChange &introduced,
0766 const AvailabilityChange &deprecated,
0767 const AvailabilityChange &obsoleted,
0768 SourceLocation unavailable, const Expr *MessageExpr,
0769 ParsedAttr::Form form, SourceLocation strict,
0770 const Expr *ReplacementExpr,
0771 IdentifierLoc *EnvironmentLoc) {
0772 void *memory = allocate(AttributeFactory::AvailabilityAllocSize);
0773 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
0774 Param, introduced, deprecated, obsoleted,
0775 unavailable, MessageExpr, form, strict,
0776 ReplacementExpr, EnvironmentLoc));
0777 }
0778
0779 ParsedAttr *create(IdentifierInfo *attrName, SourceRange attrRange,
0780 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0781 IdentifierLoc *Param1, IdentifierLoc *Param2,
0782 IdentifierLoc *Param3, ParsedAttr::Form form) {
0783 void *memory = allocate(
0784 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
0785 detail::TypeTagForDatatypeData, ParsedType,
0786 detail::PropertyData>(3, 0, 0, 0, 0));
0787 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
0788 Param1, Param2, Param3, form));
0789 }
0790
0791 ParsedAttr *
0792 createTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
0793 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0794 IdentifierLoc *argumentKind,
0795 ParsedType matchingCType, bool layoutCompatible,
0796 bool mustBeNull, ParsedAttr::Form form) {
0797 void *memory = allocate(AttributeFactory::TypeTagForDatatypeAllocSize);
0798 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
0799 argumentKind, matchingCType,
0800 layoutCompatible, mustBeNull, form));
0801 }
0802
0803 ParsedAttr *createTypeAttribute(IdentifierInfo *attrName,
0804 SourceRange attrRange,
0805 IdentifierInfo *scopeName,
0806 SourceLocation scopeLoc, ParsedType typeArg,
0807 ParsedAttr::Form formUsed,
0808 SourceLocation ellipsisLoc) {
0809 void *memory = allocate(
0810 ParsedAttr::totalSizeToAlloc<ArgsUnion, detail::AvailabilityData,
0811 detail::TypeTagForDatatypeData, ParsedType,
0812 detail::PropertyData>(0, 0, 0, 1, 0));
0813 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
0814 typeArg, formUsed, ellipsisLoc));
0815 }
0816
0817 ParsedAttr *
0818 createPropertyAttribute(IdentifierInfo *attrName, SourceRange attrRange,
0819 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0820 IdentifierInfo *getterId, IdentifierInfo *setterId,
0821 ParsedAttr::Form formUsed) {
0822 void *memory = allocate(AttributeFactory::PropertyAllocSize);
0823 return add(new (memory) ParsedAttr(attrName, attrRange, scopeName, scopeLoc,
0824 getterId, setterId, formUsed));
0825 }
0826 };
0827
0828 class ParsedAttributesView {
0829 friend class AttributePool;
0830 using VecTy = llvm::SmallVector<ParsedAttr *>;
0831 using SizeType = decltype(std::declval<VecTy>().size());
0832
0833 public:
0834 SourceRange Range;
0835
0836 static const ParsedAttributesView &none() {
0837 static const ParsedAttributesView Attrs;
0838 return Attrs;
0839 }
0840
0841 bool empty() const { return AttrList.empty(); }
0842 SizeType size() const { return AttrList.size(); }
0843 ParsedAttr &operator[](SizeType pos) { return *AttrList[pos]; }
0844 const ParsedAttr &operator[](SizeType pos) const { return *AttrList[pos]; }
0845
0846 void addAtEnd(ParsedAttr *newAttr) {
0847 assert(newAttr);
0848 AttrList.push_back(newAttr);
0849 }
0850
0851 void remove(ParsedAttr *ToBeRemoved) {
0852 assert(is_contained(AttrList, ToBeRemoved) &&
0853 "Cannot remove attribute that isn't in the list");
0854 AttrList.erase(llvm::find(AttrList, ToBeRemoved));
0855 }
0856
0857 void clearListOnly() { AttrList.clear(); }
0858
0859 struct iterator : llvm::iterator_adaptor_base<iterator, VecTy::iterator,
0860 std::random_access_iterator_tag,
0861 ParsedAttr> {
0862 iterator() : iterator_adaptor_base(nullptr) {}
0863 iterator(VecTy::iterator I) : iterator_adaptor_base(I) {}
0864 reference operator*() const { return **I; }
0865 friend class ParsedAttributesView;
0866 };
0867 struct const_iterator
0868 : llvm::iterator_adaptor_base<const_iterator, VecTy::const_iterator,
0869 std::random_access_iterator_tag,
0870 ParsedAttr> {
0871 const_iterator() : iterator_adaptor_base(nullptr) {}
0872 const_iterator(VecTy::const_iterator I) : iterator_adaptor_base(I) {}
0873
0874 reference operator*() const { return **I; }
0875 friend class ParsedAttributesView;
0876 };
0877
0878 void addAll(iterator B, iterator E) {
0879 AttrList.insert(AttrList.begin(), B.I, E.I);
0880 }
0881
0882 void addAll(const_iterator B, const_iterator E) {
0883 AttrList.insert(AttrList.begin(), B.I, E.I);
0884 }
0885
0886 void addAllAtEnd(iterator B, iterator E) {
0887 AttrList.insert(AttrList.end(), B.I, E.I);
0888 }
0889
0890 void addAllAtEnd(const_iterator B, const_iterator E) {
0891 AttrList.insert(AttrList.end(), B.I, E.I);
0892 }
0893
0894 iterator begin() { return iterator(AttrList.begin()); }
0895 const_iterator begin() const { return const_iterator(AttrList.begin()); }
0896 iterator end() { return iterator(AttrList.end()); }
0897 const_iterator end() const { return const_iterator(AttrList.end()); }
0898
0899 ParsedAttr &front() {
0900 assert(!empty());
0901 return *AttrList.front();
0902 }
0903 const ParsedAttr &front() const {
0904 assert(!empty());
0905 return *AttrList.front();
0906 }
0907 ParsedAttr &back() {
0908 assert(!empty());
0909 return *AttrList.back();
0910 }
0911 const ParsedAttr &back() const {
0912 assert(!empty());
0913 return *AttrList.back();
0914 }
0915
0916 bool hasAttribute(ParsedAttr::Kind K) const {
0917 return llvm::any_of(AttrList, [K](const ParsedAttr *AL) {
0918 return AL->getParsedKind() == K;
0919 });
0920 }
0921
0922 const ParsedAttr *getMSPropertyAttr() const {
0923 auto It = llvm::find_if(AttrList, [](const ParsedAttr *AL) {
0924 return AL->isDeclspecPropertyAttribute();
0925 });
0926 if (It != AttrList.end())
0927 return *It;
0928 return nullptr;
0929 }
0930 bool hasMSPropertyAttr() const { return getMSPropertyAttr(); }
0931
0932 private:
0933 VecTy AttrList;
0934 };
0935
0936 struct ParsedAttributeArgumentsProperties {
0937 ParsedAttributeArgumentsProperties(uint32_t StringLiteralBits)
0938 : StringLiterals(StringLiteralBits) {}
0939 bool isStringLiteralArg(unsigned I) const {
0940
0941 if (I >= StringLiterals.size())
0942 return StringLiterals.test(StringLiterals.size() - 1);
0943 return StringLiterals.test(I);
0944 }
0945
0946 private:
0947 std::bitset<32> StringLiterals;
0948 };
0949
0950
0951
0952
0953
0954
0955
0956 class ParsedAttributes : public ParsedAttributesView {
0957 public:
0958 ParsedAttributes(AttributeFactory &factory) : pool(factory) {}
0959 ParsedAttributes(const ParsedAttributes &) = delete;
0960 ParsedAttributes &operator=(const ParsedAttributes &) = delete;
0961 ParsedAttributes(ParsedAttributes &&G) = default;
0962
0963 AttributePool &getPool() const { return pool; }
0964
0965 void takeAllFrom(ParsedAttributes &Other) {
0966 assert(&Other != this &&
0967 "ParsedAttributes can't take attributes from itself");
0968 addAll(Other.begin(), Other.end());
0969 Other.clearListOnly();
0970 pool.takeAllFrom(Other.pool);
0971 }
0972
0973 void takeOneFrom(ParsedAttributes &Other, ParsedAttr *PA) {
0974 assert(&Other != this &&
0975 "ParsedAttributes can't take attribute from itself");
0976 Other.getPool().remove(PA);
0977 Other.remove(PA);
0978 getPool().add(PA);
0979 addAtEnd(PA);
0980 }
0981
0982 void clear() {
0983 clearListOnly();
0984 pool.clear();
0985 Range = SourceRange();
0986 }
0987
0988
0989 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
0990 IdentifierInfo *scopeName, SourceLocation scopeLoc,
0991 ArgsUnion *args, unsigned numArgs, ParsedAttr::Form form,
0992 SourceLocation ellipsisLoc = SourceLocation()) {
0993 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
0994 args, numArgs, form, ellipsisLoc);
0995 addAtEnd(attr);
0996 return attr;
0997 }
0998
0999
1000 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
1001 IdentifierInfo *scopeName, SourceLocation scopeLoc,
1002 IdentifierLoc *Param, const AvailabilityChange &introduced,
1003 const AvailabilityChange &deprecated,
1004 const AvailabilityChange &obsoleted,
1005 SourceLocation unavailable, const Expr *MessageExpr,
1006 ParsedAttr::Form form, SourceLocation strict,
1007 const Expr *ReplacementExpr,
1008 IdentifierLoc *EnvironmentLoc) {
1009 ParsedAttr *attr =
1010 pool.create(attrName, attrRange, scopeName, scopeLoc, Param, introduced,
1011 deprecated, obsoleted, unavailable, MessageExpr, form,
1012 strict, ReplacementExpr, EnvironmentLoc);
1013 addAtEnd(attr);
1014 return attr;
1015 }
1016
1017
1018 ParsedAttr *addNew(IdentifierInfo *attrName, SourceRange attrRange,
1019 IdentifierInfo *scopeName, SourceLocation scopeLoc,
1020 IdentifierLoc *Param1, IdentifierLoc *Param2,
1021 IdentifierLoc *Param3, ParsedAttr::Form form) {
1022 ParsedAttr *attr = pool.create(attrName, attrRange, scopeName, scopeLoc,
1023 Param1, Param2, Param3, form);
1024 addAtEnd(attr);
1025 return attr;
1026 }
1027
1028
1029 ParsedAttr *
1030 addNewTypeTagForDatatype(IdentifierInfo *attrName, SourceRange attrRange,
1031 IdentifierInfo *scopeName, SourceLocation scopeLoc,
1032 IdentifierLoc *argumentKind,
1033 ParsedType matchingCType, bool layoutCompatible,
1034 bool mustBeNull, ParsedAttr::Form form) {
1035 ParsedAttr *attr = pool.createTypeTagForDatatype(
1036 attrName, attrRange, scopeName, scopeLoc, argumentKind, matchingCType,
1037 layoutCompatible, mustBeNull, form);
1038 addAtEnd(attr);
1039 return attr;
1040 }
1041
1042
1043 ParsedAttr *addNewTypeAttr(IdentifierInfo *attrName, SourceRange attrRange,
1044 IdentifierInfo *scopeName, SourceLocation scopeLoc,
1045 ParsedType typeArg, ParsedAttr::Form formUsed,
1046 SourceLocation ellipsisLoc = SourceLocation()) {
1047 ParsedAttr *attr =
1048 pool.createTypeAttribute(attrName, attrRange, scopeName, scopeLoc,
1049 typeArg, formUsed, ellipsisLoc);
1050 addAtEnd(attr);
1051 return attr;
1052 }
1053
1054
1055 ParsedAttr *
1056 addNewPropertyAttr(IdentifierInfo *attrName, SourceRange attrRange,
1057 IdentifierInfo *scopeName, SourceLocation scopeLoc,
1058 IdentifierInfo *getterId, IdentifierInfo *setterId,
1059 ParsedAttr::Form formUsed) {
1060 ParsedAttr *attr = pool.createPropertyAttribute(
1061 attrName, attrRange, scopeName, scopeLoc, getterId, setterId, formUsed);
1062 addAtEnd(attr);
1063 return attr;
1064 }
1065
1066 private:
1067 mutable AttributePool pool;
1068 };
1069
1070
1071
1072 void takeAndConcatenateAttrs(ParsedAttributes &First, ParsedAttributes &Second,
1073 ParsedAttributes &Result);
1074
1075
1076
1077 enum AttributeArgumentNType {
1078 AANT_ArgumentIntOrBool,
1079 AANT_ArgumentIntegerConstant,
1080 AANT_ArgumentString,
1081 AANT_ArgumentIdentifier,
1082 AANT_ArgumentConstantExpr,
1083 AANT_ArgumentBuiltinFunction,
1084 };
1085
1086
1087
1088 enum AttributeDeclKind {
1089 ExpectedFunction,
1090 ExpectedUnion,
1091 ExpectedVariableOrFunction,
1092 ExpectedFunctionOrMethod,
1093 ExpectedFunctionMethodOrBlock,
1094 ExpectedFunctionMethodOrParameter,
1095 ExpectedVariable,
1096 ExpectedVariableOrField,
1097 ExpectedVariableFieldOrTag,
1098 ExpectedTypeOrNamespace,
1099 ExpectedFunctionVariableOrClass,
1100 ExpectedKernelFunction,
1101 ExpectedFunctionWithProtoType,
1102 ExpectedForLoopStatement,
1103 ExpectedVirtualFunction,
1104 ExpectedParameterOrImplicitObjectParameter,
1105 ExpectedNonMemberFunction,
1106 ExpectedFunctionOrClassOrEnum,
1107 ExpectedClass,
1108 ExpectedTypedef,
1109 };
1110
1111 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1112 const ParsedAttr &At) {
1113 DB.AddTaggedVal(reinterpret_cast<uint64_t>(At.getAttrName()),
1114 DiagnosticsEngine::ak_identifierinfo);
1115 return DB;
1116 }
1117
1118 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1119 const ParsedAttr *At) {
1120 DB.AddTaggedVal(reinterpret_cast<uint64_t>(At->getAttrName()),
1121 DiagnosticsEngine::ak_identifierinfo);
1122 return DB;
1123 }
1124
1125
1126
1127
1128
1129
1130 template <
1131 typename ACI,
1132 std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
1133 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1134 const ACI &CI) {
1135 DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI.getAttrName()),
1136 DiagnosticsEngine::ak_identifierinfo);
1137 return DB;
1138 }
1139
1140 template <
1141 typename ACI,
1142 std::enable_if_t<std::is_same<ACI, AttributeCommonInfo>::value, int> = 0>
1143 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
1144 const ACI *CI) {
1145 DB.AddTaggedVal(reinterpret_cast<uint64_t>(CI->getAttrName()),
1146 DiagnosticsEngine::ak_identifierinfo);
1147 return DB;
1148 }
1149
1150 }
1151
1152 #endif