clang 23.0.0git
ASTTypeTraits.h
Go to the documentation of this file.
1//===--- ASTTypeTraits.h ----------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Provides a dynamic type identifier and a dynamically typed node container
10// that can be used to store an AST base node at runtime in the same storage in
11// a type safe way.
12//
13//===----------------------------------------------------------------------===//
14
15#ifndef LLVM_CLANG_AST_ASTTYPETRAITS_H
16#define LLVM_CLANG_AST_ASTTYPETRAITS_H
17
18#include "clang/AST/ASTFwd.h"
19#include "clang/AST/DeclCXX.h"
23#include "clang/AST/TypeLoc.h"
24#include "clang/Basic/LLVM.h"
25#include "llvm/ADT/DenseMapInfo.h"
26#include "llvm/Support/AlignOf.h"
27
28namespace llvm {
29class raw_ostream;
30} // namespace llvm
31
32namespace clang {
33
34struct PrintingPolicy;
35
36/// Defines how we descend a level in the AST when we pass
37/// through expressions.
39 /// Will traverse all child nodes.
41
42 /// Ignore AST nodes not written in the source
44};
45
46/// Kind identifier.
47///
48/// It can be constructed from any node kind and allows for runtime type
49/// hierarchy checks.
50/// Use getFromNodeKind<T>() to construct them.
52public:
53 /// Empty identifier. It matches nothing.
54 constexpr ASTNodeKind() : KindId(NKI_None) {}
55
56 /// Construct an identifier for T.
57 template <class T> static constexpr ASTNodeKind getFromNodeKind() {
58 return ASTNodeKind(KindToKindId<T>::Id);
59 }
60
61 /// \{
62 /// Construct an identifier for the dynamic type of the node
63 static ASTNodeKind getFromNode(const Decl &D);
64 static ASTNodeKind getFromNode(const Stmt &S);
65 static ASTNodeKind getFromNode(const Type &T);
66 static ASTNodeKind getFromNode(const TypeLoc &T);
68 static ASTNodeKind getFromNode(const OMPClause &C);
69 static ASTNodeKind getFromNode(const Attr &A);
70 /// \}
71
72 /// Returns \c true if \c this and \c Other represent the same kind.
73 constexpr bool isSame(ASTNodeKind Other) const {
74 return KindId != NKI_None && KindId == Other.KindId;
75 }
76
77 /// Returns \c true only for the default \c ASTNodeKind()
78 constexpr bool isNone() const { return KindId == NKI_None; }
79
80 /// Returns \c true if \c this is a base kind of (or same as) \c Other.
81 bool isBaseOf(ASTNodeKind Other) const;
82
83 /// Returns \c true if \c this is a base kind of (or same as) \c Other.
84 /// \param Distance If non-null, used to return the distance between \c this
85 /// and \c Other in the class hierarchy.
86 bool isBaseOf(ASTNodeKind Other, unsigned *Distance) const;
87
88 /// String representation of the kind.
89 StringRef asStringRef() const;
90
91 /// Strict weak ordering for ASTNodeKind.
92 constexpr bool operator<(const ASTNodeKind &Other) const {
93 return KindId < Other.KindId;
94 }
95
96 /// Return the most derived type between \p Kind1 and \p Kind2.
97 ///
98 /// Return ASTNodeKind() if they are not related.
100
101 /// Return the most derived common ancestor between Kind1 and Kind2.
102 ///
103 /// Return ASTNodeKind() if they are not related.
105 ASTNodeKind Kind2);
106
108
109 /// Hooks for using ASTNodeKind as a key in a DenseMap.
111 // ASTNodeKind() is a good empty key because it is represented as a 0.
112 static unsigned getHashValue(const ASTNodeKind &Val) { return Val.KindId; }
113 static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS) {
114 return LHS.KindId == RHS.KindId;
115 }
116 };
117
118 /// Check if the given ASTNodeKind identifies a type that offers pointer
119 /// identity. This is useful for the fast path in DynTypedNode.
120 constexpr bool hasPointerIdentity() const {
121 return KindId > NKI_LastKindWithoutPointerIdentity;
122 }
123
124private:
125 /// Kind ids.
126 ///
127 /// Includes all possible base and derived kinds.
128 enum NodeKindId {
129 NKI_None,
130 NKI_TemplateArgument,
131 NKI_TemplateArgumentLoc,
132 NKI_LambdaCapture,
133 NKI_TemplateName,
134 NKI_NestedNameSpecifierLoc,
135 NKI_QualType,
136#define TYPELOC(CLASS, PARENT) NKI_##CLASS##TypeLoc,
137#include "clang/AST/TypeLocNodes.def"
138 NKI_TypeLoc,
139 NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
140 NKI_CXXBaseSpecifier,
141 NKI_CXXCtorInitializer,
142 NKI_NestedNameSpecifier,
143 NKI_Decl,
144#define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
145#include "clang/AST/DeclNodes.inc"
146 NKI_Stmt,
147#define STMT(DERIVED, BASE) NKI_##DERIVED,
148#include "clang/AST/StmtNodes.inc"
149 NKI_Type,
150#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
151#include "clang/AST/TypeNodes.inc"
152 NKI_OMPClause,
153#define GEN_CLANG_CLAUSE_CLASS
154#define CLAUSE_CLASS(Enum, Str, Class) NKI_##Class,
155#include "llvm/Frontend/OpenMP/OMP.inc"
156 NKI_Attr,
157#define ATTR(A) NKI_##A##Attr,
158#include "clang/Basic/AttrList.inc"
159 NKI_ObjCProtocolLoc,
160 NKI_ConceptReference,
161 NKI_OffsetOfNode,
162 NKI_NumberOfKinds
163 };
164
165 /// Use getFromNodeKind<T>() to construct the kind.
166 constexpr ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
167
168 /// Returns \c true if \c Base is a base kind of (or same as) \c
169 /// Derived.
170 static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
171
172 /// Returns \c true if \c Base is a base kind of (or same as) \c
173 /// Derived.
174 /// \param Distance If non-null, used to return the distance between \c Base
175 /// and \c Derived in the class hierarchy.
176 static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
177
178 /// Helper meta-function to convert a kind T to its enum value.
179 ///
180 /// This struct is specialized below for all known kinds.
181 template <class T> struct KindToKindId {
182 static const NodeKindId Id = NKI_None;
183 };
184 template <class T>
185 struct KindToKindId<const T> : KindToKindId<T> {};
186
187 /// Per kind info.
188 struct KindInfo {
189 /// The id of the parent kind, or None if it has no parent.
190 NodeKindId ParentId;
191 /// Name of the kind.
192 const char *Name;
193 };
194 static const KindInfo AllKindInfo[NKI_NumberOfKinds];
195
196 NodeKindId KindId;
197};
198
199#define KIND_TO_KIND_ID(Class) \
200 template <> struct ASTNodeKind::KindToKindId<Class> { \
201 static const NodeKindId Id = NKI_##Class; \
202 };
203KIND_TO_KIND_ID(CXXCtorInitializer)
204KIND_TO_KIND_ID(TemplateArgument)
205KIND_TO_KIND_ID(TemplateArgumentLoc)
206KIND_TO_KIND_ID(LambdaCapture)
208KIND_TO_KIND_ID(NestedNameSpecifier)
209KIND_TO_KIND_ID(NestedNameSpecifierLoc)
210KIND_TO_KIND_ID(QualType)
211#define TYPELOC(CLASS, PARENT) KIND_TO_KIND_ID(CLASS##TypeLoc)
212#include "clang/AST/TypeLocNodes.def"
213KIND_TO_KIND_ID(TypeLoc)
214KIND_TO_KIND_ID(Decl)
215KIND_TO_KIND_ID(Stmt)
216KIND_TO_KIND_ID(Type)
218KIND_TO_KIND_ID(Attr)
219KIND_TO_KIND_ID(ObjCProtocolLoc)
220KIND_TO_KIND_ID(CXXBaseSpecifier)
221KIND_TO_KIND_ID(ConceptReference)
222KIND_TO_KIND_ID(OffsetOfNode)
223#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
224#include "clang/AST/DeclNodes.inc"
225#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
226#include "clang/AST/StmtNodes.inc"
227#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
228#include "clang/AST/TypeNodes.inc"
229#define GEN_CLANG_CLAUSE_CLASS
230#define CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
231#include "llvm/Frontend/OpenMP/OMP.inc"
232#define ATTR(A) KIND_TO_KIND_ID(A##Attr)
233#include "clang/Basic/AttrList.inc"
234#undef KIND_TO_KIND_ID
235
236inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
237 OS << K.asStringRef();
238 return OS;
239}
240
241/// A dynamically typed AST node container.
242///
243/// Stores an AST node in a type safe way. This allows writing code that
244/// works with different kinds of AST nodes, despite the fact that they don't
245/// have a common base class.
246///
247/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
248/// and \c get<T>() to retrieve the node as type T if the types match.
249///
250/// See \c ASTNodeKind for which node base types are currently supported;
251/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
252/// the supported base types.
254public:
255 /// Creates a \c DynTypedNode from \c Node.
256 template <typename T>
257 static DynTypedNode create(const T &Node) {
258 return BaseConverter<T>::create(Node);
259 }
260
261 /// Retrieve the stored node as type \c T.
262 ///
263 /// Returns NULL if the stored node does not have a type that is
264 /// convertible to \c T.
265 ///
266 /// For types that have identity via their pointer in the AST
267 /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
268 /// pointer points to the referenced AST node.
269 /// For other types (like \c QualType) the value is stored directly
270 /// in the \c DynTypedNode, and the returned pointer points at
271 /// the storage inside DynTypedNode. For those nodes, do not
272 /// use the pointer outside the scope of the DynTypedNode.
273 template <typename T> const T *get() const {
274 return BaseConverter<T>::get(NodeKind, &Storage);
275 }
276
277 /// Retrieve the stored node as type \c T.
278 ///
279 /// Similar to \c get(), but asserts that the type is what we are expecting.
280 template <typename T>
281 const T &getUnchecked() const {
282 return BaseConverter<T>::getUnchecked(NodeKind, &Storage);
283 }
284
285 ASTNodeKind getNodeKind() const { return NodeKind; }
286
287 /// Returns a pointer that identifies the stored AST node.
288 ///
289 /// Note that this is not supported by all AST nodes. For AST nodes
290 /// that don't have a pointer-defined identity inside the AST, this
291 /// method returns NULL.
292 const void *getMemoizationData() const {
293 return NodeKind.hasPointerIdentity()
294 ? *reinterpret_cast<void *const *>(&Storage)
295 : nullptr;
296 }
297
298 /// Prints the node to the given output stream.
299 void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
300
301 /// Dumps the node to the given output stream.
302 void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
303
304 /// For nodes which represent textual entities in the source code,
305 /// return their SourceRange. For all other nodes, return SourceRange().
306 SourceRange getSourceRange(bool IncludeQualifier = false) const;
307
308 /// @{
309 /// Imposes an order on \c DynTypedNode.
310 ///
311 /// Supports comparison of nodes that support memoization.
312 /// FIXME: Implement comparison for other node types (currently
313 /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
314 bool operator<(const DynTypedNode &Other) const {
315 if (!NodeKind.isSame(Other.NodeKind))
316 return NodeKind < Other.NodeKind;
317
318 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
319 return getUnchecked<QualType>().getAsOpaquePtr() <
320 Other.getUnchecked<QualType>().getAsOpaquePtr();
321
322 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind)) {
323 auto TLA = getUnchecked<TypeLoc>();
324 auto TLB = Other.getUnchecked<TypeLoc>();
325 return std::make_pair(TLA.getType().getAsOpaquePtr(),
326 TLA.getOpaqueData()) <
327 std::make_pair(TLB.getType().getAsOpaquePtr(),
328 TLB.getOpaqueData());
329 }
330
332 NodeKind)) {
334 auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>();
335 return std::make_pair(NNSLA.getNestedNameSpecifier().getAsVoidPointer(),
336 NNSLA.getOpaqueData()) <
337 std::make_pair(NNSLB.getNestedNameSpecifier().getAsVoidPointer(),
338 NNSLB.getOpaqueData());
339 }
340
341 assert(getMemoizationData() && Other.getMemoizationData());
342 return getMemoizationData() < Other.getMemoizationData();
343 }
344 bool operator==(const DynTypedNode &Other) const {
345 // DynTypedNode::create() stores the exact kind of the node in NodeKind.
346 // If they contain the same node, their NodeKind must be the same.
347 if (!NodeKind.isSame(Other.NodeKind))
348 return false;
349
350 // FIXME: Implement for other types.
351 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
352 return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
353
354 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind))
355 return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
356
359 Other.getUnchecked<NestedNameSpecifierLoc>();
360
361 assert(getMemoizationData() && Other.getMemoizationData());
362 return getMemoizationData() == Other.getMemoizationData();
363 }
364 bool operator!=(const DynTypedNode &Other) const {
365 return !operator==(Other);
366 }
367 /// @}
368
369 /// Hooks for using DynTypedNode as a key in a DenseMap.
371 static unsigned getHashValue(const DynTypedNode &Val) {
372 // FIXME: Add hashing support for the remaining types.
373 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(Val.NodeKind)) {
374 auto TL = Val.getUnchecked<TypeLoc>();
375 return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
376 TL.getOpaqueData());
377 }
378
380 Val.NodeKind)) {
381 auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>();
382 return llvm::hash_combine(
383 NNSL.getNestedNameSpecifier().getAsVoidPointer(),
384 NNSL.getOpaqueData());
385 }
386
387 assert(Val.getMemoizationData());
389 }
390 static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
391 return LHS == RHS;
392 }
393 };
394
395private:
396 /// Takes care of converting from and to \c T.
397 template <typename T, typename EnablerT = void> struct BaseConverter;
398
399 /// Converter that uses dyn_cast<T> from a stored BaseT*.
400 template <typename T, typename BaseT> struct DynCastPtrConverter {
401 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
402 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
403 return &getUnchecked(NodeKind, Storage);
404 return nullptr;
405 }
406 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
407 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
408 return *cast<T>(static_cast<const BaseT *>(
409 *reinterpret_cast<const void *const *>(Storage)));
410 }
411 static DynTypedNode create(const BaseT &Node) {
413 Result.NodeKind = ASTNodeKind::getFromNode(Node);
414 new (&Result.Storage) const void *(&Node);
415 return Result;
416 }
417 };
418
419 /// Converter that stores T* (by pointer).
420 template <typename T> struct PtrConverter {
421 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
422 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
423 return &getUnchecked(NodeKind, Storage);
424 return nullptr;
425 }
426 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
427 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
428 return *static_cast<const T *>(
429 *reinterpret_cast<const void *const *>(Storage));
430 }
431 static DynTypedNode create(const T &Node) {
434 new (&Result.Storage) const void *(&Node);
435 return Result;
436 }
437 };
438
439 /// Converter that stores T (by value).
440 template <typename T> struct ValueConverter {
441 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
442 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
443 return reinterpret_cast<const T *>(Storage);
444 return nullptr;
445 }
446 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
447 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
448 return *reinterpret_cast<const T *>(Storage);
449 }
450 static DynTypedNode create(const T &Node) {
453 new (&Result.Storage) T(Node);
454 return Result;
455 }
456 };
457
458 /// Converter that stores nodes by value. It must be possible to dynamically
459 /// cast the stored node within a type hierarchy without breaking (especially
460 /// through slicing).
461 template <typename T, typename BaseT,
462 typename = std::enable_if_t<(sizeof(T) == sizeof(BaseT))>>
463 struct DynCastValueConverter {
464 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
465 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
466 return &getUnchecked(NodeKind, Storage);
467 return nullptr;
468 }
469 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
470 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
471 return *static_cast<const T *>(reinterpret_cast<const BaseT *>(Storage));
472 }
473 static DynTypedNode create(const T &Node) {
475 Result.NodeKind = ASTNodeKind::getFromNode(Node);
476 new (&Result.Storage) T(Node);
477 return Result;
478 }
479 };
480
481 ASTNodeKind NodeKind;
482
483 /// Stores the data of the node.
484 ///
485 /// Note that we can store \c Decls, \c Stmts, \c Types,
486 /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
487 /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
488 /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs,
489 /// \c TemplateArguments and \c TemplateArgumentLocs on the other hand do not
490 /// have storage or unique pointers and thus need to be stored by value.
491 llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
492 TemplateArgumentLoc, NestedNameSpecifierLoc,
493 QualType, TypeLoc, ObjCProtocolLoc>
494 Storage;
495};
496
497template <typename T>
498struct DynTypedNode::BaseConverter<
499 T, std::enable_if_t<std::is_base_of<Decl, T>::value>>
500 : public DynCastPtrConverter<T, Decl> {};
501
502template <typename T>
503struct DynTypedNode::BaseConverter<
504 T, std::enable_if_t<std::is_base_of<Stmt, T>::value>>
505 : public DynCastPtrConverter<T, Stmt> {};
506
507template <typename T>
508struct DynTypedNode::BaseConverter<
509 T, std::enable_if_t<std::is_base_of<Type, T>::value>>
510 : public DynCastPtrConverter<T, Type> {};
511
512template <typename T>
513struct DynTypedNode::BaseConverter<
514 T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
515 : public DynCastPtrConverter<T, OMPClause> {};
516
517template <typename T>
518struct DynTypedNode::BaseConverter<
519 T, std::enable_if_t<std::is_base_of<Attr, T>::value>>
520 : public DynCastPtrConverter<T, Attr> {};
521
522template <>
523struct DynTypedNode::BaseConverter<NestedNameSpecifier, void>
524 : public ValueConverter<NestedNameSpecifier> {};
525
526template <>
527struct DynTypedNode::BaseConverter<
528 CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
529
530template <>
531struct DynTypedNode::BaseConverter<
532 TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
533
534template <>
535struct DynTypedNode::BaseConverter<TemplateArgumentLoc, void>
536 : public ValueConverter<TemplateArgumentLoc> {};
537
538template <>
539struct DynTypedNode::BaseConverter<LambdaCapture, void>
540 : public ValueConverter<LambdaCapture> {};
541
542template <>
543struct DynTypedNode::BaseConverter<
544 TemplateName, void> : public ValueConverter<TemplateName> {};
545
546template <>
547struct DynTypedNode::BaseConverter<
549 void> : public ValueConverter<NestedNameSpecifierLoc> {};
550
551template <>
552struct DynTypedNode::BaseConverter<QualType,
553 void> : public ValueConverter<QualType> {};
554
555template <typename T>
556struct DynTypedNode::BaseConverter<
557 T, std::enable_if_t<std::is_base_of<TypeLoc, T>::value>>
558 : public DynCastValueConverter<T, TypeLoc> {};
559
560template <>
561struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void>
562 : public PtrConverter<CXXBaseSpecifier> {};
563
564template <>
565struct DynTypedNode::BaseConverter<ObjCProtocolLoc, void>
566 : public ValueConverter<ObjCProtocolLoc> {};
567
568template <>
569struct DynTypedNode::BaseConverter<ConceptReference, void>
570 : public PtrConverter<ConceptReference> {};
571
572template <>
573struct DynTypedNode::BaseConverter<OffsetOfNode, void>
574 : public PtrConverter<OffsetOfNode> {};
575
576// The only operation we allow on unsupported types is \c get.
577// This allows to conveniently use \c DynTypedNode when having an arbitrary
578// AST node that is not supported, but prevents misuse - a user cannot create
579// a DynTypedNode from arbitrary types.
580template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
581 static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
582 return NULL;
583 }
584};
585
586} // end namespace clang
587
588namespace llvm {
589
590template <>
591struct DenseMapInfo<clang::ASTNodeKind> : clang::ASTNodeKind::DenseMapInfo {};
592
593template <>
594struct DenseMapInfo<clang::DynTypedNode> : clang::DynTypedNode::DenseMapInfo {};
595
596} // end namespace llvm
597
598#endif
Forward declaration of all AST node types.
#define KIND_TO_KIND_ID(Class)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.
Defines the LambdaCapture class.
Defines the clang::TypeLoc interface and its subclasses.
#define NULL
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:223
Kind identifier.
static ASTNodeKind getFromNode(const LambdaCapture &L)
StringRef asStringRef() const
String representation of the kind.
bool isBaseOf(ASTNodeKind Other) const
Returns true if this is a base kind of (or same as) Other.
constexpr ASTNodeKind()
Empty identifier. It matches nothing.
ASTNodeKind getCladeKind() const
constexpr bool hasPointerIdentity() const
Check if the given ASTNodeKind identifies a type that offers pointer identity.
constexpr bool operator<(const ASTNodeKind &Other) const
Strict weak ordering for ASTNodeKind.
static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived common ancestor between Kind1 and Kind2.
static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2)
Return the most derived type between Kind1 and Kind2.
static ASTNodeKind getFromNode(const Decl &D)
constexpr bool isSame(ASTNodeKind Other) const
Returns true if this and Other represent the same kind.
constexpr bool isNone() const
Returns true only for the default ASTNodeKind()
static constexpr ASTNodeKind getFromNodeKind()
Construct an identifier for T.
Attr - This represents one attribute.
Definition Attr.h:46
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents a C++ base or member initializer.
Definition DeclCXX.h:2385
A reference to a concept and its template args, as it appears in the code.
Definition ASTConcept.h:130
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
A dynamically typed AST node container.
bool operator<(const DynTypedNode &Other) const
ASTNodeKind getNodeKind() const
bool operator==(const DynTypedNode &Other) const
bool operator!=(const DynTypedNode &Other) const
const T * get() const
Retrieve the stored node as type T.
const T & getUnchecked() const
Retrieve the stored node as type T.
static DynTypedNode create(const T &Node)
Creates a DynTypedNode from Node.
const void * getMemoizationData() const
Returns a pointer that identifies the stored AST node.
void dump(llvm::raw_ostream &OS, const ASTContext &Context) const
Dumps the node to the given output stream.
SourceRange getSourceRange(bool IncludeQualifier=false) const
For nodes which represent textual entities in the source code, return their SourceRange.
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const
Prints the node to the given output stream.
Describes the capture of a variable or of this, or of a C++1y init-capture.
A C++ nested-name-specifier augmented with source location information.
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
This is a basic class for representing single OpenMP clause.
Helper class for OffsetOfExpr.
Definition Expr.h:2424
A (possibly-)qualified type.
Definition TypeBase.h:937
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition Stmt.h:86
Location wrapper for a TemplateArgument.
Represents a template argument.
Represents a C++ template name within the type system.
Base wrapper for a particular "section" of type source info.
Definition TypeLoc.h:59
The base class of the type hierarchy.
Definition TypeBase.h:1875
DynTypedNode DynTypedNode
The JSON file list parser is used to communicate input to InstallAPI.
@ TemplateName
The identifier is a template name. FIXME: Add an annotation for that.
Definition Parser.h:61
TraversalKind
Defines how we descend a level in the AST when we pass through expressions.
@ TK_AsIs
Will traverse all child nodes.
@ TK_IgnoreUnlessSpelledInSource
Ignore AST nodes not written in the source.
@ Result
The result type of a method or function.
Definition TypeBase.h:905
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)
Insertion operator for diagnostics.
U cast(CodeGen::Address addr)
Definition Address.h:327
@ Other
Other implicit parameter.
Definition Decl.h:1763
Diagnostic wrappers for TextAPI types for error reporting.
Definition Dominators.h:30
hash_code hash_value(const clang::dependencies::ModuleID &ID)
Hooks for using ASTNodeKind as a key in a DenseMap.
static unsigned getHashValue(const ASTNodeKind &Val)
static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS)
Hooks for using DynTypedNode as a key in a DenseMap.
static unsigned getHashValue(const DynTypedNode &Val)
static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS)
Describes how types, statements, expressions, and declarations should be printed.