File indexing completed on 2026-05-10 08:36:48
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014 #ifndef LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
0015 #define LLVM_CLANG_BASIC_ATTRIBUTECOMMONINFO_H
0016
0017 #include "clang/Basic/SourceLocation.h"
0018 #include "clang/Basic/TokenKinds.h"
0019
0020 namespace clang {
0021
0022 class ASTRecordWriter;
0023 class IdentifierInfo;
0024
0025 class AttributeCommonInfo {
0026 public:
0027
0028 enum Syntax {
0029
0030 AS_GNU = 1,
0031
0032
0033 AS_CXX11,
0034
0035
0036 AS_C23,
0037
0038
0039 AS_Declspec,
0040
0041
0042 AS_Microsoft,
0043
0044
0045 AS_Keyword,
0046
0047
0048 AS_Pragma,
0049
0050
0051
0052
0053 AS_ContextSensitiveKeyword,
0054
0055
0056 AS_HLSLAnnotation,
0057
0058
0059
0060 AS_Implicit
0061 };
0062 enum Kind {
0063 #define PARSED_ATTR(NAME) AT_##NAME,
0064 #include "clang/Basic/AttrParsedAttrList.inc"
0065 #undef PARSED_ATTR
0066 NoSemaHandlerAttribute,
0067 IgnoredAttribute,
0068 UnknownAttribute,
0069 };
0070 enum class Scope { NONE, CLANG, GNU, MSVC, OMP, HLSL, GSL, RISCV };
0071 enum class AttrArgsInfo {
0072 None,
0073 Optional,
0074 Required,
0075 };
0076
0077 private:
0078 const IdentifierInfo *AttrName = nullptr;
0079 const IdentifierInfo *ScopeName = nullptr;
0080 SourceRange AttrRange;
0081 const SourceLocation ScopeLoc;
0082
0083 LLVM_PREFERRED_TYPE(Kind)
0084 unsigned AttrKind : 16;
0085
0086 LLVM_PREFERRED_TYPE(Syntax)
0087 unsigned SyntaxUsed : 4;
0088 LLVM_PREFERRED_TYPE(bool)
0089 unsigned SpellingIndex : 4;
0090 LLVM_PREFERRED_TYPE(bool)
0091 unsigned IsAlignas : 1;
0092 LLVM_PREFERRED_TYPE(bool)
0093 unsigned IsRegularKeywordAttribute : 1;
0094
0095 protected:
0096 static constexpr unsigned SpellingNotCalculated = 0xf;
0097
0098 public:
0099
0100
0101 class Form {
0102 public:
0103 constexpr Form(Syntax SyntaxUsed, unsigned SpellingIndex, bool IsAlignas,
0104 bool IsRegularKeywordAttribute)
0105 : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingIndex),
0106 IsAlignas(IsAlignas),
0107 IsRegularKeywordAttribute(IsRegularKeywordAttribute) {}
0108 constexpr Form(tok::TokenKind Tok)
0109 : SyntaxUsed(AS_Keyword), SpellingIndex(SpellingNotCalculated),
0110 IsAlignas(Tok == tok::kw_alignas),
0111 IsRegularKeywordAttribute(tok::isRegularKeywordAttribute(Tok)) {}
0112
0113 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
0114 unsigned getSpellingIndex() const { return SpellingIndex; }
0115 bool isAlignas() const { return IsAlignas; }
0116 bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
0117
0118 static Form GNU() { return AS_GNU; }
0119 static Form CXX11() { return AS_CXX11; }
0120 static Form C23() { return AS_C23; }
0121 static Form Declspec() { return AS_Declspec; }
0122 static Form Microsoft() { return AS_Microsoft; }
0123 static Form Keyword(bool IsAlignas, bool IsRegularKeywordAttribute) {
0124 return Form(AS_Keyword, SpellingNotCalculated, IsAlignas,
0125 IsRegularKeywordAttribute);
0126 }
0127 static Form Pragma() { return AS_Pragma; }
0128 static Form ContextSensitiveKeyword() { return AS_ContextSensitiveKeyword; }
0129 static Form HLSLAnnotation() { return AS_HLSLAnnotation; }
0130 static Form Implicit() { return AS_Implicit; }
0131
0132 private:
0133 constexpr Form(Syntax SyntaxUsed)
0134 : SyntaxUsed(SyntaxUsed), SpellingIndex(SpellingNotCalculated),
0135 IsAlignas(0), IsRegularKeywordAttribute(0) {}
0136
0137 LLVM_PREFERRED_TYPE(Syntax)
0138 unsigned SyntaxUsed : 4;
0139 unsigned SpellingIndex : 4;
0140 LLVM_PREFERRED_TYPE(bool)
0141 unsigned IsAlignas : 1;
0142 LLVM_PREFERRED_TYPE(bool)
0143 unsigned IsRegularKeywordAttribute : 1;
0144 };
0145
0146 AttributeCommonInfo(const IdentifierInfo *AttrName,
0147 const IdentifierInfo *ScopeName, SourceRange AttrRange,
0148 SourceLocation ScopeLoc, Kind AttrKind, Form FormUsed)
0149 : AttrName(AttrName), ScopeName(ScopeName), AttrRange(AttrRange),
0150 ScopeLoc(ScopeLoc), AttrKind(AttrKind),
0151 SyntaxUsed(FormUsed.getSyntax()),
0152 SpellingIndex(FormUsed.getSpellingIndex()),
0153 IsAlignas(FormUsed.isAlignas()),
0154 IsRegularKeywordAttribute(FormUsed.isRegularKeywordAttribute()) {
0155 assert(SyntaxUsed >= AS_GNU && SyntaxUsed <= AS_Implicit &&
0156 "Invalid syntax!");
0157 }
0158
0159 AttributeCommonInfo(const IdentifierInfo *AttrName,
0160 const IdentifierInfo *ScopeName, SourceRange AttrRange,
0161 SourceLocation ScopeLoc, Form FormUsed)
0162 : AttributeCommonInfo(
0163 AttrName, ScopeName, AttrRange, ScopeLoc,
0164 getParsedKind(AttrName, ScopeName, FormUsed.getSyntax()),
0165 FormUsed) {}
0166
0167 AttributeCommonInfo(const IdentifierInfo *AttrName, SourceRange AttrRange,
0168 Form FormUsed)
0169 : AttributeCommonInfo(AttrName, nullptr, AttrRange, SourceLocation(),
0170 FormUsed) {}
0171
0172 AttributeCommonInfo(SourceRange AttrRange, Kind K, Form FormUsed)
0173 : AttributeCommonInfo(nullptr, nullptr, AttrRange, SourceLocation(), K,
0174 FormUsed) {}
0175
0176 AttributeCommonInfo(AttributeCommonInfo &&) = default;
0177 AttributeCommonInfo(const AttributeCommonInfo &) = default;
0178
0179 Kind getParsedKind() const { return Kind(AttrKind); }
0180 Syntax getSyntax() const { return Syntax(SyntaxUsed); }
0181 Form getForm() const {
0182 return Form(getSyntax(), SpellingIndex, IsAlignas,
0183 IsRegularKeywordAttribute);
0184 }
0185 const IdentifierInfo *getAttrName() const { return AttrName; }
0186 void setAttrName(const IdentifierInfo *AttrNameII) { AttrName = AttrNameII; }
0187 SourceLocation getLoc() const { return AttrRange.getBegin(); }
0188 SourceRange getRange() const { return AttrRange; }
0189 void setRange(SourceRange R) { AttrRange = R; }
0190
0191 bool hasScope() const { return ScopeName; }
0192 const IdentifierInfo *getScopeName() const { return ScopeName; }
0193 SourceLocation getScopeLoc() const { return ScopeLoc; }
0194
0195
0196
0197
0198 std::string getNormalizedFullName() const;
0199
0200 bool isDeclspecAttribute() const { return SyntaxUsed == AS_Declspec; }
0201 bool isMicrosoftAttribute() const { return SyntaxUsed == AS_Microsoft; }
0202
0203 bool isGNUScope() const;
0204 bool isClangScope() const;
0205
0206 bool isCXX11Attribute() const { return SyntaxUsed == AS_CXX11 || IsAlignas; }
0207
0208 bool isC23Attribute() const { return SyntaxUsed == AS_C23; }
0209
0210 bool isAlignas() const {
0211
0212
0213
0214
0215
0216 return (getParsedKind() == AT_Aligned && isKeywordAttribute());
0217 }
0218
0219
0220
0221 bool isStandardAttributeSyntax() const {
0222 return isCXX11Attribute() || isC23Attribute();
0223 }
0224
0225 bool isGNUAttribute() const { return SyntaxUsed == AS_GNU; }
0226
0227 bool isKeywordAttribute() const {
0228 return SyntaxUsed == AS_Keyword || SyntaxUsed == AS_ContextSensitiveKeyword;
0229 }
0230
0231 bool isRegularKeywordAttribute() const { return IsRegularKeywordAttribute; }
0232
0233 bool isContextSensitiveKeywordAttribute() const {
0234 return SyntaxUsed == AS_ContextSensitiveKeyword;
0235 }
0236
0237 unsigned getAttributeSpellingListIndex() const {
0238 assert((isAttributeSpellingListCalculated() || AttrName) &&
0239 "Spelling cannot be found");
0240 return isAttributeSpellingListCalculated()
0241 ? SpellingIndex
0242 : calculateAttributeSpellingListIndex();
0243 }
0244 void setAttributeSpellingListIndex(unsigned V) { SpellingIndex = V; }
0245
0246 static Kind getParsedKind(const IdentifierInfo *Name,
0247 const IdentifierInfo *Scope, Syntax SyntaxUsed);
0248
0249 static AttrArgsInfo getCXX11AttrArgsInfo(const IdentifierInfo *Name);
0250
0251 private:
0252
0253
0254
0255 unsigned calculateAttributeSpellingListIndex() const;
0256
0257 friend class clang::ASTRecordWriter;
0258
0259 unsigned getAttributeSpellingListIndexRaw() const { return SpellingIndex; }
0260
0261 protected:
0262 bool isAttributeSpellingListCalculated() const {
0263 return SpellingIndex != SpellingNotCalculated;
0264 }
0265 };
0266
0267 inline bool doesKeywordAttributeTakeArgs(tok::TokenKind Kind) {
0268 switch (Kind) {
0269 default:
0270 return false;
0271 #define KEYWORD_ATTRIBUTE(NAME, HASARG, ...) \
0272 case tok::kw_##NAME: \
0273 return HASARG;
0274 #include "clang/Basic/RegularKeywordAttrInfo.inc"
0275 #undef KEYWORD_ATTRIBUTE
0276 }
0277 }
0278
0279 }
0280
0281 #endif