16 #ifndef LLVM_CLANG_AST_ASTTYPETRAITS_H
17 #define LLVM_CLANG_AST_ASTTYPETRAITS_H
26 #include "llvm/ADT/DenseMapInfo.h"
27 #include "llvm/Support/AlignOf.h"
37 struct PrintingPolicy;
39 namespace ast_type_traits {
66 return KindId != NKI_None && KindId == Other.KindId;
70 bool isNone()
const {
return KindId == NKI_None; }
82 return KindId < Other.KindId;
107 return LHS.KindId == RHS.KindId;
114 return KindId > NKI_LastKindWithoutPointerIdentity;
123 NKI_TemplateArgument,
125 NKI_NestedNameSpecifierLoc,
128 NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
129 NKI_CXXCtorInitializer,
130 NKI_NestedNameSpecifier,
132 #define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
133 #include "clang/AST/DeclNodes.inc"
135 #define STMT(DERIVED, BASE) NKI_##DERIVED,
136 #include "clang/AST/StmtNodes.inc"
138 #define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
139 #include "clang/AST/TypeNodes.def"
150 static bool isBaseOf(NodeKindId
Base, NodeKindId Derived,
unsigned *Distance);
155 template <
class T>
struct KindToKindId {
156 static const NodeKindId Id = NKI_None;
159 struct KindToKindId<const T> : KindToKindId<T> {};
168 static const KindInfo AllKindInfo[NKI_NumberOfKinds];
173 #define KIND_TO_KIND_ID(Class) \
174 template <> struct ASTNodeKind::KindToKindId<Class> { \
175 static const NodeKindId Id = NKI_##Class; \
187 #define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
188 #include "clang/AST/DeclNodes.inc"
189 #define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
190 #include "clang/AST/StmtNodes.inc"
191 #define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
192 #include "clang/AST/TypeNodes.def"
193 #undef KIND_TO_KIND_ID
215 template <
typename T>
232 template <
typename T>
233 const T *
get()
const {
234 return BaseConverter<T>::get(NodeKind, Storage.buffer);
240 template <
typename T>
242 return BaseConverter<T>::getUnchecked(NodeKind, Storage.buffer);
254 ? *
reinterpret_cast<void *
const *
>(Storage.buffer)
275 if (!NodeKind.
isSame(Other.NodeKind))
276 return NodeKind < Other.NodeKind;
278 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
279 return getUnchecked<QualType>().getAsOpaquePtr() <
282 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind)) {
283 auto TLA = getUnchecked<TypeLoc>();
285 return std::make_pair(TLA.getType().getAsOpaquePtr(),
286 TLA.getOpaqueData()) <
287 std::make_pair(TLB.getType().getAsOpaquePtr(),
288 TLB.getOpaqueData());
291 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
293 auto NNSLA = getUnchecked<NestedNameSpecifierLoc>();
295 return std::make_pair(NNSLA.getNestedNameSpecifier(),
296 NNSLA.getOpaqueData()) <
297 std::make_pair(NNSLB.getNestedNameSpecifier(),
298 NNSLB.getOpaqueData());
307 if (!NodeKind.
isSame(Other.NodeKind))
311 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
314 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(NodeKind))
317 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind))
318 return getUnchecked<NestedNameSpecifierLoc>() ==
343 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isSame(Val.NodeKind)) {
345 return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
349 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
352 return llvm::hash_combine(NNSL.getNestedNameSpecifier(),
353 NNSL.getOpaqueData());
372 template <
typename T,
typename EnablerT =
void>
struct BaseConverter;
375 template <
typename T,
typename BaseT>
struct DynCastPtrConverter {
376 static const T *
get(
ASTNodeKind NodeKind,
const char Storage[]) {
377 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
381 static const T &
getUnchecked(ASTNodeKind NodeKind,
const char Storage[]) {
382 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
383 return *cast<T>(
static_cast<const BaseT *
>(
384 *
reinterpret_cast<const void *
const *
>(Storage)));
386 static DynTypedNode
create(
const BaseT &
Node) {
389 new (Result.Storage.buffer)
const void *(&Node);
395 template <
typename T>
struct PtrConverter {
396 static const T *
get(ASTNodeKind NodeKind,
const char Storage[]) {
397 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
401 static const T &
getUnchecked(ASTNodeKind NodeKind,
const char Storage[]) {
402 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
403 return *
static_cast<const T *
>(
404 *
reinterpret_cast<const void *
const *
>(Storage));
408 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
409 new (Result.Storage.buffer)
const void *(&Node);
415 template <
typename T>
struct ValueConverter {
416 static const T *
get(ASTNodeKind NodeKind,
const char Storage[]) {
417 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
418 return reinterpret_cast<const T *>(Storage);
421 static const T &
getUnchecked(ASTNodeKind NodeKind,
const char Storage[]) {
422 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
423 return *
reinterpret_cast<const T *
>(Storage);
427 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
428 new (Result.Storage.buffer) T(Node);
433 ASTNodeKind NodeKind;
443 llvm::AlignedCharArrayUnion<
const void *, TemplateArgument,
444 NestedNameSpecifierLoc, QualType,
448 template <
typename T>
449 struct DynTypedNode::BaseConverter<
450 T, typename std::enable_if<std::is_base_of<Decl, T>::value>
::type>
451 :
public DynCastPtrConverter<T, Decl> {};
453 template <
typename T>
454 struct DynTypedNode::BaseConverter<
455 T, typename std::enable_if<std::is_base_of<Stmt, T>::value>
::type>
456 :
public DynCastPtrConverter<T, Stmt> {};
458 template <
typename T>
459 struct DynTypedNode::BaseConverter<
460 T, typename std::enable_if<std::is_base_of<Type, T>::value>
::type>
461 :
public DynCastPtrConverter<T, Type> {};
464 struct DynTypedNode::BaseConverter<
468 struct DynTypedNode::BaseConverter<
472 struct DynTypedNode::BaseConverter<
476 struct DynTypedNode::BaseConverter<
477 TemplateName, void> :
public ValueConverter<TemplateName> {};
480 struct DynTypedNode::BaseConverter<
482 void> :
public ValueConverter<NestedNameSpecifierLoc> {};
486 void> :
public ValueConverter<QualType> {};
489 struct DynTypedNode::BaseConverter<
490 TypeLoc, void> :
public ValueConverter<TypeLoc> {};
496 template <
typename T,
typename EnablerT>
struct DynTypedNode::BaseConverter {
497 static const T *
get(
ASTNodeKind NodeKind,
const char Storage[]) {
bool operator!=(const DynTypedNode &Other) const
A (possibly-)qualified type.
static ASTNodeKind getFromNode(const Decl &D)
Construct an identifier for the dynamic type of the node.
static ASTNodeKind getTombstoneKey()
Stmt - This represents one statement.
static ASTNodeKind getEmptyKey()
Decl - This represents one declaration (or definition), e.g.
The base class of the type hierarchy.
static DynTypedNode getTombstoneKey()
Describes how types, statements, expressions, and declarations should be printed. ...
bool operator<(const ASTNodeKind &Other) const
Strict weak ordering for ASTNodeKind.
Base wrapper for a particular "section" of type source info.
A C++ nested-name-specifier augmented with source location information.
bool isNone() const
Returns true only for the default ASTNodeKind()
bool isBaseOf(ASTNodeKind Other, unsigned *Distance=nullptr) const
Returns true if this is a base kind of (or same as) Other.
ASTNodeKind()
Empty identifier. It matches nothing.
const T & getUnchecked() const
Retrieve the stored node as type T.
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified...
bool hasPointerIdentity() const
Check if the given ASTNodeKind identifies a type that offers pointer identity.
Forward declaration of all AST node types.
static unsigned getHashValue(const DynTypedNode &Val)
Hooks for using ASTNodeKind as a key in a DenseMap.
void dump(llvm::raw_ostream &OS, SourceManager &SM) const
Dumps the node to the given output stream.
Represents a C++ template name within the type system.
Defines the clang::TypeLoc interface and its subclasses.
static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived type between Kind1 and Kind2.
#define KIND_TO_KIND_ID(Class)
const void * getMemoizationData() const
Returns a pointer that identifies the stored AST node.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
StringRef asStringRef() const
String representation of the kind.
ASTNodeKind getNodeKind() const
static DynTypedNode create(const T &Node)
Creates a DynTypedNode from Node.
static unsigned getHashValue(const ASTNodeKind &Val)
ast_type_traits::DynTypedNode Node
if(T->getSizeExpr()) TRY_TO(TraverseStmt(T-> getSizeExpr()))
Represents a template argument.
static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived common ancestor between Kind1 and Kind2.
bool isSame(ASTNodeKind Other) const
Returns true if this and Other represent the same kind.
bool operator<(const DynTypedNode &Other) const
Imposes an order on DynTypedNode.
bool operator==(const DynTypedNode &Other) const
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
Hooks for using DynTypedNode as a key in a DenseMap.
A dynamically typed AST node container.
Represents a C++ base or member initializer.
SourceRange getSourceRange() const
For nodes which represent textual entities in the source code, return their SourceRange.
static DynTypedNode getEmptyKey()
raw_ostream & operator<<(raw_ostream &OS, ASTNodeKind K)
A trivial tuple used to represent a source range.
static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS)
static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS)
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const
Prints the node to the given output stream.
This class handles loading and caching of source files into memory.
static ASTNodeKind getFromNodeKind()
Construct an identifier for T.