File indexing completed on 2026-05-10 08:36:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013 #ifndef LLVM_CLANG_AST_ATTR_H
0014 #define LLVM_CLANG_AST_ATTR_H
0015
0016 #include "clang/AST/ASTFwd.h"
0017 #include "clang/AST/AttrIterator.h"
0018 #include "clang/AST/Decl.h"
0019 #include "clang/AST/Type.h"
0020 #include "clang/Basic/AttrKinds.h"
0021 #include "clang/Basic/AttributeCommonInfo.h"
0022 #include "clang/Basic/LLVM.h"
0023 #include "clang/Basic/LangOptions.h"
0024 #include "clang/Basic/OpenMPKinds.h"
0025 #include "clang/Basic/Sanitizers.h"
0026 #include "clang/Basic/SourceLocation.h"
0027 #include "clang/Support/Compiler.h"
0028 #include "llvm/Frontend/HLSL/HLSLResource.h"
0029 #include "llvm/Support/CodeGen.h"
0030 #include "llvm/Support/ErrorHandling.h"
0031 #include "llvm/Support/VersionTuple.h"
0032 #include "llvm/Support/raw_ostream.h"
0033 #include <algorithm>
0034 #include <cassert>
0035
0036 namespace clang {
0037 class ASTContext;
0038 class AttributeCommonInfo;
0039 class FunctionDecl;
0040 class OMPTraitInfo;
0041
0042
0043 class Attr : public AttributeCommonInfo {
0044 private:
0045 LLVM_PREFERRED_TYPE(attr::Kind)
0046 unsigned AttrKind : 16;
0047
0048 protected:
0049
0050
0051 LLVM_PREFERRED_TYPE(bool)
0052 unsigned Inherited : 1;
0053 LLVM_PREFERRED_TYPE(bool)
0054 unsigned IsPackExpansion : 1;
0055 LLVM_PREFERRED_TYPE(bool)
0056 unsigned Implicit : 1;
0057
0058
0059 LLVM_PREFERRED_TYPE(bool)
0060 unsigned IsLateParsed : 1;
0061 LLVM_PREFERRED_TYPE(bool)
0062 unsigned InheritEvenIfAlreadyPresent : 1;
0063
0064 void *operator new(size_t bytes) noexcept {
0065 llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
0066 }
0067 void operator delete(void *data) noexcept {
0068 llvm_unreachable("Attrs cannot be released with regular 'delete'.");
0069 }
0070
0071 public:
0072
0073 void *operator new(size_t Bytes, ASTContext &C,
0074 size_t Alignment = 8) noexcept {
0075 return ::operator new(Bytes, C, Alignment);
0076 }
0077 void operator delete(void *Ptr, ASTContext &C, size_t Alignment) noexcept {
0078 return ::operator delete(Ptr, C, Alignment);
0079 }
0080
0081 protected:
0082 Attr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
0083 attr::Kind AK, bool IsLateParsed)
0084 : AttributeCommonInfo(CommonInfo), AttrKind(AK), Inherited(false),
0085 IsPackExpansion(false), Implicit(false), IsLateParsed(IsLateParsed),
0086 InheritEvenIfAlreadyPresent(false) {}
0087
0088 public:
0089 attr::Kind getKind() const { return static_cast<attr::Kind>(AttrKind); }
0090
0091 unsigned getSpellingListIndex() const {
0092 return getAttributeSpellingListIndex();
0093 }
0094 const char *getSpelling() const;
0095
0096 SourceLocation getLocation() const { return getRange().getBegin(); }
0097
0098 bool isInherited() const { return Inherited; }
0099
0100
0101
0102 bool isImplicit() const { return Implicit; }
0103 void setImplicit(bool I) { Implicit = I; }
0104
0105 void setPackExpansion(bool PE) { IsPackExpansion = PE; }
0106 bool isPackExpansion() const { return IsPackExpansion; }
0107
0108
0109 Attr *clone(ASTContext &C) const;
0110
0111 bool isLateParsed() const { return IsLateParsed; }
0112
0113
0114 void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
0115
0116 static StringRef getDocumentation(attr::Kind);
0117 };
0118
0119 class TypeAttr : public Attr {
0120 protected:
0121 TypeAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
0122 attr::Kind AK, bool IsLateParsed)
0123 : Attr(Context, CommonInfo, AK, IsLateParsed) {}
0124
0125 public:
0126 static bool classof(const Attr *A) {
0127 return A->getKind() >= attr::FirstTypeAttr &&
0128 A->getKind() <= attr::LastTypeAttr;
0129 }
0130 };
0131
0132 class StmtAttr : public Attr {
0133 protected:
0134 StmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
0135 attr::Kind AK, bool IsLateParsed)
0136 : Attr(Context, CommonInfo, AK, IsLateParsed) {}
0137
0138 public:
0139 static bool classof(const Attr *A) {
0140 return A->getKind() >= attr::FirstStmtAttr &&
0141 A->getKind() <= attr::LastStmtAttr;
0142 }
0143 };
0144
0145 class InheritableAttr : public Attr {
0146 protected:
0147 InheritableAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
0148 attr::Kind AK, bool IsLateParsed,
0149 bool InheritEvenIfAlreadyPresent)
0150 : Attr(Context, CommonInfo, AK, IsLateParsed) {
0151 this->InheritEvenIfAlreadyPresent = InheritEvenIfAlreadyPresent;
0152 }
0153
0154 public:
0155 void setInherited(bool I) { Inherited = I; }
0156
0157
0158
0159 bool shouldInheritEvenIfAlreadyPresent() const {
0160 return InheritEvenIfAlreadyPresent;
0161 }
0162
0163
0164 static bool classof(const Attr *A) {
0165 return A->getKind() >= attr::FirstInheritableAttr &&
0166 A->getKind() <= attr::LastInheritableAttr;
0167 }
0168 };
0169
0170 class DeclOrStmtAttr : public InheritableAttr {
0171 protected:
0172 DeclOrStmtAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
0173 attr::Kind AK, bool IsLateParsed,
0174 bool InheritEvenIfAlreadyPresent)
0175 : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
0176 InheritEvenIfAlreadyPresent) {}
0177
0178 public:
0179 static bool classof(const Attr *A) {
0180 return A->getKind() >= attr::FirstDeclOrStmtAttr &&
0181 A->getKind() <= attr::LastDeclOrStmtAttr;
0182 }
0183 };
0184
0185 class InheritableParamAttr : public InheritableAttr {
0186 protected:
0187 InheritableParamAttr(ASTContext &Context,
0188 const AttributeCommonInfo &CommonInfo, attr::Kind AK,
0189 bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
0190 : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
0191 InheritEvenIfAlreadyPresent) {}
0192
0193 public:
0194
0195 static bool classof(const Attr *A) {
0196 return A->getKind() >= attr::FirstInheritableParamAttr &&
0197 A->getKind() <= attr::LastInheritableParamAttr;
0198 }
0199 };
0200
0201 class InheritableParamOrStmtAttr : public InheritableParamAttr {
0202 protected:
0203 InheritableParamOrStmtAttr(ASTContext &Context,
0204 const AttributeCommonInfo &CommonInfo,
0205 attr::Kind AK, bool IsLateParsed,
0206 bool InheritEvenIfAlreadyPresent)
0207 : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed,
0208 InheritEvenIfAlreadyPresent) {}
0209
0210 public:
0211
0212 static bool classof(const Attr *A) {
0213 return A->getKind() >= attr::FirstInheritableParamOrStmtAttr &&
0214 A->getKind() <= attr::LastInheritableParamOrStmtAttr;
0215 }
0216 };
0217
0218 class HLSLAnnotationAttr : public InheritableAttr {
0219 protected:
0220 HLSLAnnotationAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
0221 attr::Kind AK, bool IsLateParsed,
0222 bool InheritEvenIfAlreadyPresent)
0223 : InheritableAttr(Context, CommonInfo, AK, IsLateParsed,
0224 InheritEvenIfAlreadyPresent) {}
0225
0226 public:
0227
0228 static bool classof(const Attr *A) {
0229 return A->getKind() >= attr::FirstHLSLAnnotationAttr &&
0230 A->getKind() <= attr::LastHLSLAnnotationAttr;
0231 }
0232 };
0233
0234
0235
0236 class ParameterABIAttr : public InheritableParamAttr {
0237 protected:
0238 ParameterABIAttr(ASTContext &Context, const AttributeCommonInfo &CommonInfo,
0239 attr::Kind AK, bool IsLateParsed,
0240 bool InheritEvenIfAlreadyPresent)
0241 : InheritableParamAttr(Context, CommonInfo, AK, IsLateParsed,
0242 InheritEvenIfAlreadyPresent) {}
0243
0244 public:
0245 ParameterABI getABI() const;
0246
0247 static bool classof(const Attr *A) {
0248 return A->getKind() >= attr::FirstParameterABIAttr &&
0249 A->getKind() <= attr::LastParameterABIAttr;
0250 }
0251 };
0252
0253
0254
0255 class ParamIdx {
0256
0257 unsigned Idx : 30;
0258 LLVM_PREFERRED_TYPE(bool)
0259 unsigned HasThis : 1;
0260 LLVM_PREFERRED_TYPE(bool)
0261 unsigned IsValid : 1;
0262
0263 void assertComparable(const ParamIdx &I) const {
0264 assert(isValid() && I.isValid() &&
0265 "ParamIdx must be valid to be compared");
0266
0267
0268
0269
0270 assert(HasThis == I.HasThis &&
0271 "ParamIdx must be for the same function to be compared");
0272 }
0273
0274 public:
0275
0276
0277 ParamIdx() : Idx(0), HasThis(false), IsValid(false) {}
0278
0279
0280
0281
0282
0283
0284
0285 ParamIdx(unsigned Idx, const Decl *D)
0286 : Idx(Idx), HasThis(false), IsValid(true) {
0287 assert(Idx >= 1 && "Idx must be one-origin");
0288 if (const auto *FD = dyn_cast<FunctionDecl>(D))
0289 HasThis = FD->isCXXInstanceMember();
0290 }
0291
0292
0293
0294
0295
0296 typedef uint32_t SerialType;
0297
0298
0299
0300 SerialType serialize() const {
0301 return *reinterpret_cast<const SerialType *>(this);
0302 }
0303
0304
0305 static ParamIdx deserialize(SerialType S) {
0306
0307
0308 void *ParamIdxPtr = static_cast<void *>(&S);
0309 ParamIdx P(*static_cast<ParamIdx *>(ParamIdxPtr));
0310 assert((!P.IsValid || P.Idx >= 1) && "valid Idx must be one-origin");
0311 return P;
0312 }
0313
0314
0315 bool isValid() const { return IsValid; }
0316
0317
0318
0319
0320
0321
0322
0323 unsigned getSourceIndex() const {
0324 assert(isValid() && "ParamIdx must be valid");
0325 return Idx;
0326 }
0327
0328
0329
0330
0331
0332
0333
0334 unsigned getASTIndex() const {
0335 assert(isValid() && "ParamIdx must be valid");
0336 assert(Idx >= 1 + HasThis &&
0337 "stored index must be base-1 and not specify C++ implicit this");
0338 return Idx - 1 - HasThis;
0339 }
0340
0341
0342
0343
0344
0345 unsigned getLLVMIndex() const {
0346 assert(isValid() && "ParamIdx must be valid");
0347 assert(Idx >= 1 && "stored index must be base-1");
0348 return Idx - 1;
0349 }
0350
0351 bool operator==(const ParamIdx &I) const {
0352 assertComparable(I);
0353 return Idx == I.Idx;
0354 }
0355 bool operator!=(const ParamIdx &I) const {
0356 assertComparable(I);
0357 return Idx != I.Idx;
0358 }
0359 bool operator<(const ParamIdx &I) const {
0360 assertComparable(I);
0361 return Idx < I.Idx;
0362 }
0363 bool operator>(const ParamIdx &I) const {
0364 assertComparable(I);
0365 return Idx > I.Idx;
0366 }
0367 bool operator<=(const ParamIdx &I) const {
0368 assertComparable(I);
0369 return Idx <= I.Idx;
0370 }
0371 bool operator>=(const ParamIdx &I) const {
0372 assertComparable(I);
0373 return Idx >= I.Idx;
0374 }
0375 };
0376
0377 static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
0378 "ParamIdx does not fit its serialization type");
0379
0380 #include "clang/AST/Attrs.inc" // IWYU pragma: export
0381
0382 inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
0383 const Attr *At) {
0384 DB.AddTaggedVal(reinterpret_cast<uint64_t>(At), DiagnosticsEngine::ak_attr);
0385 return DB;
0386 }
0387
0388 inline ParameterABI ParameterABIAttr::getABI() const {
0389 switch (getKind()) {
0390 case attr::SwiftContext:
0391 return ParameterABI::SwiftContext;
0392 case attr::SwiftAsyncContext:
0393 return ParameterABI::SwiftAsyncContext;
0394 case attr::SwiftErrorResult:
0395 return ParameterABI::SwiftErrorResult;
0396 case attr::SwiftIndirectResult:
0397 return ParameterABI::SwiftIndirectResult;
0398 case attr::HLSLParamModifier: {
0399 const auto *A = cast<HLSLParamModifierAttr>(this);
0400 if (A->isOut())
0401 return ParameterABI::HLSLOut;
0402 if (A->isInOut())
0403 return ParameterABI::HLSLInOut;
0404 return ParameterABI::Ordinary;
0405 }
0406 default:
0407 llvm_unreachable("bad parameter ABI attribute kind");
0408 }
0409 }
0410 }
0411
0412 #endif