clang 24.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_NestedNameSpecifier,
135 NKI_NestedNameSpecifierLoc,
136 NKI_QualType,
137#define TYPELOC(CLASS, PARENT) NKI_##CLASS##TypeLoc,
138#include "clang/AST/TypeLocNodes.def"
139 NKI_TypeLoc,
140 NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
141 NKI_CXXBaseSpecifier,
142 NKI_CXXCtorInitializer,
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 and \c Type) 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 /// FIXME: Implement comparison for TemplateName, LambdaCapture,
312 /// TemplateArgument, and TemplateArgumentLoc.
313 bool operator<(const DynTypedNode &Other) const {
314 if (!NodeKind.isSame(Other.NodeKind))
315 return NodeKind < Other.NodeKind;
316
317 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
318 return getUnchecked<QualType>().getAsOpaquePtr() <
319 Other.getUnchecked<QualType>().getAsOpaquePtr();
320
321 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind)) {
322 auto TLA = getUnchecked<TypeLoc>();
323 auto TLB = Other.getUnchecked<TypeLoc>();
324 return std::make_pair(TLA.getType().getAsOpaquePtr(),
325 TLA.getOpaqueData()) <
326 std::make_pair(TLB.getType().getAsOpaquePtr(),
327 TLB.getOpaqueData());
328 }
329
331 NodeKind)) {
333 auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>();
334 return std::make_pair(NNSLA.getNestedNameSpecifier().getAsVoidPointer(),
335 NNSLA.getOpaqueData()) <
336 std::make_pair(NNSLB.getNestedNameSpecifier().getAsVoidPointer(),
337 NNSLB.getOpaqueData());
338 }
339
341 return getUnchecked<NestedNameSpecifier>().getAsVoidPointer() <
342 Other.getUnchecked<NestedNameSpecifier>().getAsVoidPointer();
343
344 assert(getMemoizationData() && Other.getMemoizationData());
345 return getMemoizationData() < Other.getMemoizationData();
346 }
347 bool operator==(const DynTypedNode &Other) const {
348 // DynTypedNode::create() stores the exact kind of the node in NodeKind.
349 // If they contain the same node, their NodeKind must be the same.
350 if (!NodeKind.isSame(Other.NodeKind))
351 return false;
352
353 // FIXME: Implement for other types.
354 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
355 return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
356
357 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind))
358 return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
359
362 Other.getUnchecked<NestedNameSpecifierLoc>();
363
366 Other.getUnchecked<NestedNameSpecifier>();
367
368 assert(getMemoizationData() && Other.getMemoizationData());
369 return getMemoizationData() == Other.getMemoizationData();
370 }
371 bool operator!=(const DynTypedNode &Other) const {
372 return !operator==(Other);
373 }
374 /// @}
375
376 /// Hooks for using DynTypedNode as a key in a DenseMap.
378 static unsigned getHashValue(const DynTypedNode &Val) {
379 // FIXME: Add hashing support for the remaining types.
380 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(Val.NodeKind)) {
381 auto TL = Val.getUnchecked<TypeLoc>();
382 return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
383 TL.getOpaqueData());
384 }
385
387 Val.NodeKind)) {
388 auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>();
389 return llvm::hash_combine(
390 NNSL.getNestedNameSpecifier().getAsVoidPointer(),
391 NNSL.getOpaqueData());
392 }
393
395 Val.NodeKind))
396 return llvm::DenseMapInfo<NestedNameSpecifier>::getHashValue(
398
399 assert(Val.getMemoizationData());
401 }
402 static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
403 return LHS == RHS;
404 }
405 };
406
407private:
408 /// Takes care of converting from and to \c T.
409 template <typename T, typename EnablerT = void> struct BaseConverter;
410
411 /// Converter that uses dyn_cast<T> from a stored BaseT*.
412 template <typename T, typename BaseT> struct DynCastPtrConverter {
413 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
414 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
415 return &getUnchecked(NodeKind, Storage);
416 return nullptr;
417 }
418 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
419 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
420 return *cast<T>(static_cast<const BaseT *>(
421 *reinterpret_cast<const void *const *>(Storage)));
422 }
423 static DynTypedNode create(const BaseT &Node) {
425 Result.NodeKind = ASTNodeKind::getFromNode(Node);
426 new (&Result.Storage) const void *(&Node);
427 return Result;
428 }
429 };
430
431 /// Converter that stores T* (by pointer).
432 template <typename T> struct PtrConverter {
433 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
434 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
435 return &getUnchecked(NodeKind, Storage);
436 return nullptr;
437 }
438 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
439 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
440 return *static_cast<const T *>(
441 *reinterpret_cast<const void *const *>(Storage));
442 }
443 static DynTypedNode create(const T &Node) {
446 new (&Result.Storage) const void *(&Node);
447 return Result;
448 }
449 };
450
451 /// Converter that stores T (by value).
452 template <typename T> struct ValueConverter {
453 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
454 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
455 return reinterpret_cast<const T *>(Storage);
456 return nullptr;
457 }
458 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
459 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
460 return *reinterpret_cast<const T *>(Storage);
461 }
462 static DynTypedNode create(const T &Node) {
465 new (&Result.Storage) T(Node);
466 return Result;
467 }
468 };
469
470 /// Converter that stores nodes by value. It must be possible to dynamically
471 /// cast the stored node within a type hierarchy without breaking (especially
472 /// through slicing).
473 template <typename T, typename BaseT,
474 typename = std::enable_if_t<(sizeof(T) == sizeof(BaseT))>>
475 struct DynCastValueConverter {
476 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
477 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
478 return &getUnchecked(NodeKind, Storage);
479 return nullptr;
480 }
481 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
482 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
483 return *static_cast<const T *>(reinterpret_cast<const BaseT *>(Storage));
484 }
485 static DynTypedNode create(const T &Node) {
487 Result.NodeKind = ASTNodeKind::getFromNode(Node);
488 new (&Result.Storage) T(Node);
489 return Result;
490 }
491 };
492
493 ASTNodeKind NodeKind;
494
495 /// Stores the data of the node.
496 ///
497 /// Note that we can store \c Decls, \c Stmts, \c Types and
498 /// \c CXXCtorInitializer by pointer as they are guaranteed to be unique
499 /// pointers pointing to dedicated storage in the AST.
500 /// \c QualTypes, \c NestedNameSpecifiers, \c NestedNameSpecifierLocs,
501 /// \c TypeLocs, \c TemplateArguments and \c TemplateArgumentLocs on the other
502 /// hand do not have storage or unique pointers and thus need to be stored by
503 /// value.
504 llvm::AlignedCharArrayUnion<
505 const void *, TemplateArgument, TemplateArgumentLoc, NestedNameSpecifier,
506 NestedNameSpecifierLoc, QualType, TypeLoc, ObjCProtocolLoc>
507 Storage;
508};
509
510template <typename T>
511struct DynTypedNode::BaseConverter<
512 T, std::enable_if_t<std::is_base_of<Decl, T>::value>>
513 : public DynCastPtrConverter<T, Decl> {};
514
515template <typename T>
516struct DynTypedNode::BaseConverter<
517 T, std::enable_if_t<std::is_base_of<Stmt, T>::value>>
518 : public DynCastPtrConverter<T, Stmt> {};
519
520template <typename T>
521struct DynTypedNode::BaseConverter<
522 T, std::enable_if_t<std::is_base_of<Type, T>::value>>
523 : public DynCastPtrConverter<T, Type> {};
524
525template <typename T>
526struct DynTypedNode::BaseConverter<
527 T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
528 : public DynCastPtrConverter<T, OMPClause> {};
529
530template <typename T>
531struct DynTypedNode::BaseConverter<
532 T, std::enable_if_t<std::is_base_of<Attr, T>::value>>
533 : public DynCastPtrConverter<T, Attr> {};
534
535template <>
536struct DynTypedNode::BaseConverter<NestedNameSpecifier, void>
537 : public ValueConverter<NestedNameSpecifier> {};
538
539template <>
540struct DynTypedNode::BaseConverter<
541 CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
542
543template <>
544struct DynTypedNode::BaseConverter<
545 TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
546
547template <>
548struct DynTypedNode::BaseConverter<TemplateArgumentLoc, void>
549 : public ValueConverter<TemplateArgumentLoc> {};
550
551template <>
552struct DynTypedNode::BaseConverter<LambdaCapture, void>
553 : public ValueConverter<LambdaCapture> {};
554
555template <>
556struct DynTypedNode::BaseConverter<
557 TemplateName, void> : public ValueConverter<TemplateName> {};
558
559template <>
560struct DynTypedNode::BaseConverter<
562 void> : public ValueConverter<NestedNameSpecifierLoc> {};
563
564template <>
565struct DynTypedNode::BaseConverter<QualType,
566 void> : public ValueConverter<QualType> {};
567
568template <typename T>
569struct DynTypedNode::BaseConverter<
570 T, std::enable_if_t<std::is_base_of<TypeLoc, T>::value>>
571 : public DynCastValueConverter<T, TypeLoc> {};
572
573template <>
574struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void>
575 : public PtrConverter<CXXBaseSpecifier> {};
576
577template <>
578struct DynTypedNode::BaseConverter<ObjCProtocolLoc, void>
579 : public ValueConverter<ObjCProtocolLoc> {};
580
581template <>
582struct DynTypedNode::BaseConverter<ConceptReference, void>
583 : public PtrConverter<ConceptReference> {};
584
585template <>
586struct DynTypedNode::BaseConverter<OffsetOfNode, void>
587 : public PtrConverter<OffsetOfNode> {};
588
589// The only operation we allow on unsupported types is \c get.
590// This allows to conveniently use \c DynTypedNode when having an arbitrary
591// AST node that is not supported, but prevents misuse - a user cannot create
592// a DynTypedNode from arbitrary types.
593template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
594 static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
595 return NULL;
596 }
597};
598
599} // end namespace clang
600
601namespace llvm {
602
603template <>
604struct DenseMapInfo<clang::ASTNodeKind> : clang::ASTNodeKind::DenseMapInfo {};
605
606template <>
607struct DenseMapInfo<clang::DynTypedNode> : clang::DynTypedNode::DenseMapInfo {};
608
609} // end namespace llvm
610
611#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:245
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:47
Represents a base class of a C++ class.
Definition DeclCXX.h:146
Represents a C++ base or member initializer.
Definition DeclCXX.h:2407
A reference to a concept and its template args, as it appears in the code.
Definition ASTConcept.h:127
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:2490
A (possibly-)qualified type.
Definition TypeBase.h:938
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition Stmt.h:85
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:1879
DynTypedNode DynTypedNode
Top level wrappers for InstallAPI frontend operations.
@ 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:906
const FunctionProtoType * T
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:1787
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.