File indexing completed on 2026-05-10 08:36:29
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_CLANG_AST_ASTTYPETRAITS_H
0016 #define LLVM_CLANG_AST_ASTTYPETRAITS_H
0017
0018 #include "clang/AST/ASTFwd.h"
0019 #include "clang/AST/DeclCXX.h"
0020 #include "clang/AST/LambdaCapture.h"
0021 #include "clang/AST/NestedNameSpecifier.h"
0022 #include "clang/AST/TemplateBase.h"
0023 #include "clang/AST/TypeLoc.h"
0024 #include "clang/Basic/LLVM.h"
0025 #include "llvm/ADT/DenseMapInfo.h"
0026 #include "llvm/Support/AlignOf.h"
0027
0028 namespace llvm {
0029 class raw_ostream;
0030 }
0031
0032 namespace clang {
0033
0034 struct PrintingPolicy;
0035
0036
0037
0038 enum TraversalKind {
0039
0040 TK_AsIs,
0041
0042
0043 TK_IgnoreUnlessSpelledInSource
0044 };
0045
0046
0047
0048
0049
0050
0051 class ASTNodeKind {
0052 public:
0053
0054 constexpr ASTNodeKind() : KindId(NKI_None) {}
0055
0056
0057 template <class T> static constexpr ASTNodeKind getFromNodeKind() {
0058 return ASTNodeKind(KindToKindId<T>::Id);
0059 }
0060
0061
0062
0063 static ASTNodeKind getFromNode(const Decl &D);
0064 static ASTNodeKind getFromNode(const Stmt &S);
0065 static ASTNodeKind getFromNode(const Type &T);
0066 static ASTNodeKind getFromNode(const TypeLoc &T);
0067 static ASTNodeKind getFromNode(const LambdaCapture &L);
0068 static ASTNodeKind getFromNode(const OMPClause &C);
0069 static ASTNodeKind getFromNode(const Attr &A);
0070
0071
0072
0073 constexpr bool isSame(ASTNodeKind Other) const {
0074 return KindId != NKI_None && KindId == Other.KindId;
0075 }
0076
0077
0078 constexpr bool isNone() const { return KindId == NKI_None; }
0079
0080
0081 bool isBaseOf(ASTNodeKind Other) const;
0082
0083
0084
0085
0086 bool isBaseOf(ASTNodeKind Other, unsigned *Distance) const;
0087
0088
0089 StringRef asStringRef() const;
0090
0091
0092 constexpr bool operator<(const ASTNodeKind &Other) const {
0093 return KindId < Other.KindId;
0094 }
0095
0096
0097
0098
0099 static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2);
0100
0101
0102
0103
0104 static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1,
0105 ASTNodeKind Kind2);
0106
0107 ASTNodeKind getCladeKind() const;
0108
0109
0110 struct DenseMapInfo {
0111
0112 static inline ASTNodeKind getEmptyKey() { return ASTNodeKind(); }
0113
0114
0115 static inline ASTNodeKind getTombstoneKey() {
0116 return ASTNodeKind(NKI_NumberOfKinds);
0117 }
0118 static unsigned getHashValue(const ASTNodeKind &Val) { return Val.KindId; }
0119 static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS) {
0120 return LHS.KindId == RHS.KindId;
0121 }
0122 };
0123
0124
0125
0126 constexpr bool hasPointerIdentity() const {
0127 return KindId > NKI_LastKindWithoutPointerIdentity;
0128 }
0129
0130 private:
0131
0132
0133
0134 enum NodeKindId {
0135 NKI_None,
0136 NKI_TemplateArgument,
0137 NKI_TemplateArgumentLoc,
0138 NKI_LambdaCapture,
0139 NKI_TemplateName,
0140 NKI_NestedNameSpecifierLoc,
0141 NKI_QualType,
0142 #define TYPELOC(CLASS, PARENT) NKI_##CLASS##TypeLoc,
0143 #include "clang/AST/TypeLocNodes.def"
0144 NKI_TypeLoc,
0145 NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
0146 NKI_CXXBaseSpecifier,
0147 NKI_CXXCtorInitializer,
0148 NKI_NestedNameSpecifier,
0149 NKI_Decl,
0150 #define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
0151 #include "clang/AST/DeclNodes.inc"
0152 NKI_Stmt,
0153 #define STMT(DERIVED, BASE) NKI_##DERIVED,
0154 #include "clang/AST/StmtNodes.inc"
0155 NKI_Type,
0156 #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
0157 #include "clang/AST/TypeNodes.inc"
0158 NKI_OMPClause,
0159 #define GEN_CLANG_CLAUSE_CLASS
0160 #define CLAUSE_CLASS(Enum, Str, Class) NKI_##Class,
0161 #include "llvm/Frontend/OpenMP/OMP.inc"
0162 NKI_Attr,
0163 #define ATTR(A) NKI_##A##Attr,
0164 #include "clang/Basic/AttrList.inc"
0165 NKI_ObjCProtocolLoc,
0166 NKI_ConceptReference,
0167 NKI_NumberOfKinds
0168 };
0169
0170
0171 constexpr ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
0172
0173
0174
0175 static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
0176
0177
0178
0179
0180
0181 static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
0182
0183
0184
0185
0186 template <class T> struct KindToKindId {
0187 static const NodeKindId Id = NKI_None;
0188 };
0189 template <class T>
0190 struct KindToKindId<const T> : KindToKindId<T> {};
0191
0192
0193 struct KindInfo {
0194
0195 NodeKindId ParentId;
0196
0197 const char *Name;
0198 };
0199 static const KindInfo AllKindInfo[NKI_NumberOfKinds];
0200
0201 NodeKindId KindId;
0202 };
0203
0204 #define KIND_TO_KIND_ID(Class) \
0205 template <> struct ASTNodeKind::KindToKindId<Class> { \
0206 static const NodeKindId Id = NKI_##Class; \
0207 };
0208 KIND_TO_KIND_ID(CXXCtorInitializer)
0209 KIND_TO_KIND_ID(TemplateArgument)
0210 KIND_TO_KIND_ID(TemplateArgumentLoc)
0211 KIND_TO_KIND_ID(LambdaCapture)
0212 KIND_TO_KIND_ID(TemplateName)
0213 KIND_TO_KIND_ID(NestedNameSpecifier)
0214 KIND_TO_KIND_ID(NestedNameSpecifierLoc)
0215 KIND_TO_KIND_ID(QualType)
0216 #define TYPELOC(CLASS, PARENT) KIND_TO_KIND_ID(CLASS##TypeLoc)
0217 #include "clang/AST/TypeLocNodes.def"
0218 KIND_TO_KIND_ID(TypeLoc)
0219 KIND_TO_KIND_ID(Decl)
0220 KIND_TO_KIND_ID(Stmt)
0221 KIND_TO_KIND_ID(Type)
0222 KIND_TO_KIND_ID(OMPClause)
0223 KIND_TO_KIND_ID(Attr)
0224 KIND_TO_KIND_ID(ObjCProtocolLoc)
0225 KIND_TO_KIND_ID(CXXBaseSpecifier)
0226 KIND_TO_KIND_ID(ConceptReference)
0227 #define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
0228 #include "clang/AST/DeclNodes.inc"
0229 #define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
0230 #include "clang/AST/StmtNodes.inc"
0231 #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
0232 #include "clang/AST/TypeNodes.inc"
0233 #define GEN_CLANG_CLAUSE_CLASS
0234 #define CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
0235 #include "llvm/Frontend/OpenMP/OMP.inc"
0236 #define ATTR(A) KIND_TO_KIND_ID(A##Attr)
0237 #include "clang/Basic/AttrList.inc"
0238 #undef KIND_TO_KIND_ID
0239
0240 inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
0241 OS << K.asStringRef();
0242 return OS;
0243 }
0244
0245
0246
0247
0248
0249
0250
0251
0252
0253
0254
0255
0256
0257 class DynTypedNode {
0258 public:
0259
0260 template <typename T>
0261 static DynTypedNode create(const T &Node) {
0262 return BaseConverter<T>::create(Node);
0263 }
0264
0265
0266
0267
0268
0269
0270
0271
0272
0273
0274
0275
0276
0277 template <typename T> const T *get() const {
0278 return BaseConverter<T>::get(NodeKind, &Storage);
0279 }
0280
0281
0282
0283
0284 template <typename T>
0285 const T &getUnchecked() const {
0286 return BaseConverter<T>::getUnchecked(NodeKind, &Storage);
0287 }
0288
0289 ASTNodeKind getNodeKind() const { return NodeKind; }
0290
0291
0292
0293
0294
0295
0296 const void *getMemoizationData() const {
0297 return NodeKind.hasPointerIdentity()
0298 ? *reinterpret_cast<void *const *>(&Storage)
0299 : nullptr;
0300 }
0301
0302
0303 void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
0304
0305
0306 void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
0307
0308
0309
0310 SourceRange getSourceRange() const;
0311
0312
0313
0314
0315
0316
0317
0318 bool operator<(const DynTypedNode &Other) const {
0319 if (!NodeKind.isSame(Other.NodeKind))
0320 return NodeKind < Other.NodeKind;
0321
0322 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
0323 return getUnchecked<QualType>().getAsOpaquePtr() <
0324 Other.getUnchecked<QualType>().getAsOpaquePtr();
0325
0326 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind)) {
0327 auto TLA = getUnchecked<TypeLoc>();
0328 auto TLB = Other.getUnchecked<TypeLoc>();
0329 return std::make_pair(TLA.getType().getAsOpaquePtr(),
0330 TLA.getOpaqueData()) <
0331 std::make_pair(TLB.getType().getAsOpaquePtr(),
0332 TLB.getOpaqueData());
0333 }
0334
0335 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
0336 NodeKind)) {
0337 auto NNSLA = getUnchecked<NestedNameSpecifierLoc>();
0338 auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>();
0339 return std::make_pair(NNSLA.getNestedNameSpecifier(),
0340 NNSLA.getOpaqueData()) <
0341 std::make_pair(NNSLB.getNestedNameSpecifier(),
0342 NNSLB.getOpaqueData());
0343 }
0344
0345 assert(getMemoizationData() && Other.getMemoizationData());
0346 return getMemoizationData() < Other.getMemoizationData();
0347 }
0348 bool operator==(const DynTypedNode &Other) const {
0349
0350
0351 if (!NodeKind.isSame(Other.NodeKind))
0352 return false;
0353
0354
0355 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
0356 return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
0357
0358 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind))
0359 return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
0360
0361 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind))
0362 return getUnchecked<NestedNameSpecifierLoc>() ==
0363 Other.getUnchecked<NestedNameSpecifierLoc>();
0364
0365 assert(getMemoizationData() && Other.getMemoizationData());
0366 return getMemoizationData() == Other.getMemoizationData();
0367 }
0368 bool operator!=(const DynTypedNode &Other) const {
0369 return !operator==(Other);
0370 }
0371
0372
0373
0374 struct DenseMapInfo {
0375 static inline DynTypedNode getEmptyKey() {
0376 DynTypedNode Node;
0377 Node.NodeKind = ASTNodeKind::DenseMapInfo::getEmptyKey();
0378 return Node;
0379 }
0380 static inline DynTypedNode getTombstoneKey() {
0381 DynTypedNode Node;
0382 Node.NodeKind = ASTNodeKind::DenseMapInfo::getTombstoneKey();
0383 return Node;
0384 }
0385 static unsigned getHashValue(const DynTypedNode &Val) {
0386
0387 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(Val.NodeKind)) {
0388 auto TL = Val.getUnchecked<TypeLoc>();
0389 return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
0390 TL.getOpaqueData());
0391 }
0392
0393 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
0394 Val.NodeKind)) {
0395 auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>();
0396 return llvm::hash_combine(NNSL.getNestedNameSpecifier(),
0397 NNSL.getOpaqueData());
0398 }
0399
0400 assert(Val.getMemoizationData());
0401 return llvm::hash_value(Val.getMemoizationData());
0402 }
0403 static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
0404 auto Empty = ASTNodeKind::DenseMapInfo::getEmptyKey();
0405 auto TombStone = ASTNodeKind::DenseMapInfo::getTombstoneKey();
0406 return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) &&
0407 ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, Empty)) ||
0408 (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, TombStone) &&
0409 ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, TombStone)) ||
0410 LHS == RHS;
0411 }
0412 };
0413
0414 private:
0415
0416 template <typename T, typename EnablerT = void> struct BaseConverter;
0417
0418
0419 template <typename T, typename BaseT> struct DynCastPtrConverter {
0420 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
0421 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
0422 return &getUnchecked(NodeKind, Storage);
0423 return nullptr;
0424 }
0425 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
0426 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
0427 return *cast<T>(static_cast<const BaseT *>(
0428 *reinterpret_cast<const void *const *>(Storage)));
0429 }
0430 static DynTypedNode create(const BaseT &Node) {
0431 DynTypedNode Result;
0432 Result.NodeKind = ASTNodeKind::getFromNode(Node);
0433 new (&Result.Storage) const void *(&Node);
0434 return Result;
0435 }
0436 };
0437
0438
0439 template <typename T> struct PtrConverter {
0440 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
0441 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
0442 return &getUnchecked(NodeKind, Storage);
0443 return nullptr;
0444 }
0445 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
0446 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
0447 return *static_cast<const T *>(
0448 *reinterpret_cast<const void *const *>(Storage));
0449 }
0450 static DynTypedNode create(const T &Node) {
0451 DynTypedNode Result;
0452 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
0453 new (&Result.Storage) const void *(&Node);
0454 return Result;
0455 }
0456 };
0457
0458
0459 template <typename T> struct ValueConverter {
0460 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
0461 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
0462 return reinterpret_cast<const T *>(Storage);
0463 return nullptr;
0464 }
0465 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
0466 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
0467 return *reinterpret_cast<const T *>(Storage);
0468 }
0469 static DynTypedNode create(const T &Node) {
0470 DynTypedNode Result;
0471 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
0472 new (&Result.Storage) T(Node);
0473 return Result;
0474 }
0475 };
0476
0477
0478
0479
0480 template <typename T, typename BaseT,
0481 typename = std::enable_if_t<(sizeof(T) == sizeof(BaseT))>>
0482 struct DynCastValueConverter {
0483 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
0484 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
0485 return &getUnchecked(NodeKind, Storage);
0486 return nullptr;
0487 }
0488 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
0489 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
0490 return *static_cast<const T *>(reinterpret_cast<const BaseT *>(Storage));
0491 }
0492 static DynTypedNode create(const T &Node) {
0493 DynTypedNode Result;
0494 Result.NodeKind = ASTNodeKind::getFromNode(Node);
0495 new (&Result.Storage) T(Node);
0496 return Result;
0497 }
0498 };
0499
0500 ASTNodeKind NodeKind;
0501
0502
0503
0504
0505
0506
0507
0508
0509
0510 llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
0511 TemplateArgumentLoc, NestedNameSpecifierLoc,
0512 QualType, TypeLoc, ObjCProtocolLoc>
0513 Storage;
0514 };
0515
0516 template <typename T>
0517 struct DynTypedNode::BaseConverter<
0518 T, std::enable_if_t<std::is_base_of<Decl, T>::value>>
0519 : public DynCastPtrConverter<T, Decl> {};
0520
0521 template <typename T>
0522 struct DynTypedNode::BaseConverter<
0523 T, std::enable_if_t<std::is_base_of<Stmt, T>::value>>
0524 : public DynCastPtrConverter<T, Stmt> {};
0525
0526 template <typename T>
0527 struct DynTypedNode::BaseConverter<
0528 T, std::enable_if_t<std::is_base_of<Type, T>::value>>
0529 : public DynCastPtrConverter<T, Type> {};
0530
0531 template <typename T>
0532 struct DynTypedNode::BaseConverter<
0533 T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
0534 : public DynCastPtrConverter<T, OMPClause> {};
0535
0536 template <typename T>
0537 struct DynTypedNode::BaseConverter<
0538 T, std::enable_if_t<std::is_base_of<Attr, T>::value>>
0539 : public DynCastPtrConverter<T, Attr> {};
0540
0541 template <>
0542 struct DynTypedNode::BaseConverter<
0543 NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
0544
0545 template <>
0546 struct DynTypedNode::BaseConverter<
0547 CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
0548
0549 template <>
0550 struct DynTypedNode::BaseConverter<
0551 TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
0552
0553 template <>
0554 struct DynTypedNode::BaseConverter<TemplateArgumentLoc, void>
0555 : public ValueConverter<TemplateArgumentLoc> {};
0556
0557 template <>
0558 struct DynTypedNode::BaseConverter<LambdaCapture, void>
0559 : public ValueConverter<LambdaCapture> {};
0560
0561 template <>
0562 struct DynTypedNode::BaseConverter<
0563 TemplateName, void> : public ValueConverter<TemplateName> {};
0564
0565 template <>
0566 struct DynTypedNode::BaseConverter<
0567 NestedNameSpecifierLoc,
0568 void> : public ValueConverter<NestedNameSpecifierLoc> {};
0569
0570 template <>
0571 struct DynTypedNode::BaseConverter<QualType,
0572 void> : public ValueConverter<QualType> {};
0573
0574 template <typename T>
0575 struct DynTypedNode::BaseConverter<
0576 T, std::enable_if_t<std::is_base_of<TypeLoc, T>::value>>
0577 : public DynCastValueConverter<T, TypeLoc> {};
0578
0579 template <>
0580 struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void>
0581 : public PtrConverter<CXXBaseSpecifier> {};
0582
0583 template <>
0584 struct DynTypedNode::BaseConverter<ObjCProtocolLoc, void>
0585 : public ValueConverter<ObjCProtocolLoc> {};
0586
0587 template <>
0588 struct DynTypedNode::BaseConverter<ConceptReference, void>
0589 : public PtrConverter<ConceptReference> {};
0590
0591
0592
0593
0594
0595 template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
0596 static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
0597 return NULL;
0598 }
0599 };
0600
0601 }
0602
0603 namespace llvm {
0604
0605 template <>
0606 struct DenseMapInfo<clang::ASTNodeKind> : clang::ASTNodeKind::DenseMapInfo {};
0607
0608 template <>
0609 struct DenseMapInfo<clang::DynTypedNode> : clang::DynTypedNode::DenseMapInfo {};
0610
0611 }
0612
0613 #endif