clang 17.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 inline ASTNodeKind getEmptyKey() { return ASTNodeKind(); }
113 // NKI_NumberOfKinds is not a valid value, so it is good for a
114 // tombstone key.
115 static inline ASTNodeKind getTombstoneKey() {
116 return ASTNodeKind(NKI_NumberOfKinds);
117 }
118 static unsigned getHashValue(const ASTNodeKind &Val) { return Val.KindId; }
119 static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS) {
120 return LHS.KindId == RHS.KindId;
121 }
122 };
123
124 /// Check if the given ASTNodeKind identifies a type that offers pointer
125 /// identity. This is useful for the fast path in DynTypedNode.
126 constexpr bool hasPointerIdentity() const {
127 return KindId > NKI_LastKindWithoutPointerIdentity;
128 }
129
130private:
131 /// Kind ids.
132 ///
133 /// Includes all possible base and derived kinds.
134 enum NodeKindId {
135 NKI_None,
136 NKI_TemplateArgument,
137 NKI_TemplateArgumentLoc,
138 NKI_LambdaCapture,
139 NKI_TemplateName,
140 NKI_NestedNameSpecifierLoc,
141 NKI_QualType,
142#define TYPELOC(CLASS, PARENT) NKI_##CLASS##TypeLoc,
143#include "clang/AST/TypeLocNodes.def"
144 NKI_TypeLoc,
145 NKI_LastKindWithoutPointerIdentity = NKI_TypeLoc,
146 NKI_CXXBaseSpecifier,
147 NKI_CXXCtorInitializer,
148 NKI_NestedNameSpecifier,
149 NKI_Decl,
150#define DECL(DERIVED, BASE) NKI_##DERIVED##Decl,
151#include "clang/AST/DeclNodes.inc"
152 NKI_Stmt,
153#define STMT(DERIVED, BASE) NKI_##DERIVED,
154#include "clang/AST/StmtNodes.inc"
155 NKI_Type,
156#define TYPE(DERIVED, BASE) NKI_##DERIVED##Type,
157#include "clang/AST/TypeNodes.inc"
158 NKI_OMPClause,
159#define GEN_CLANG_CLAUSE_CLASS
160#define CLAUSE_CLASS(Enum, Str, Class) NKI_##Class,
161#include "llvm/Frontend/OpenMP/OMP.inc"
162 NKI_Attr,
163#define ATTR(A) NKI_##A##Attr,
164#include "clang/Basic/AttrList.inc"
165 NKI_ObjCProtocolLoc,
166 NKI_NumberOfKinds
167 };
168
169 /// Use getFromNodeKind<T>() to construct the kind.
170 constexpr ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
171
172 /// Returns \c true if \c Base is a base kind of (or same as) \c
173 /// Derived.
174 static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
175
176 /// Returns \c true if \c Base is a base kind of (or same as) \c
177 /// Derived.
178 /// \param Distance If non-null, used to return the distance between \c Base
179 /// and \c Derived in the class hierarchy.
180 static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
181
182 /// Helper meta-function to convert a kind T to its enum value.
183 ///
184 /// This struct is specialized below for all known kinds.
185 template <class T> struct KindToKindId {
186 static const NodeKindId Id = NKI_None;
187 };
188 template <class T>
189 struct KindToKindId<const T> : KindToKindId<T> {};
190
191 /// Per kind info.
192 struct KindInfo {
193 /// The id of the parent kind, or None if it has no parent.
194 NodeKindId ParentId;
195 /// Name of the kind.
196 const char *Name;
197 };
198 static const KindInfo AllKindInfo[NKI_NumberOfKinds];
199
200 NodeKindId KindId;
201};
202
203#define KIND_TO_KIND_ID(Class) \
204 template <> struct ASTNodeKind::KindToKindId<Class> { \
205 static const NodeKindId Id = NKI_##Class; \
206 };
207KIND_TO_KIND_ID(CXXCtorInitializer)
208KIND_TO_KIND_ID(TemplateArgument)
209KIND_TO_KIND_ID(TemplateArgumentLoc)
210KIND_TO_KIND_ID(LambdaCapture)
211KIND_TO_KIND_ID(TemplateName)
212KIND_TO_KIND_ID(NestedNameSpecifier)
213KIND_TO_KIND_ID(NestedNameSpecifierLoc)
214KIND_TO_KIND_ID(QualType)
215#define TYPELOC(CLASS, PARENT) KIND_TO_KIND_ID(CLASS##TypeLoc)
216#include "clang/AST/TypeLocNodes.def"
217KIND_TO_KIND_ID(TypeLoc)
218KIND_TO_KIND_ID(Decl)
219KIND_TO_KIND_ID(Stmt)
220KIND_TO_KIND_ID(Type)
221KIND_TO_KIND_ID(OMPClause)
222KIND_TO_KIND_ID(Attr)
223KIND_TO_KIND_ID(ObjCProtocolLoc)
224KIND_TO_KIND_ID(CXXBaseSpecifier)
225#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
226#include "clang/AST/DeclNodes.inc"
227#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
228#include "clang/AST/StmtNodes.inc"
229#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
230#include "clang/AST/TypeNodes.inc"
231#define GEN_CLANG_CLAUSE_CLASS
232#define CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
233#include "llvm/Frontend/OpenMP/OMP.inc"
234#define ATTR(A) KIND_TO_KIND_ID(A##Attr)
235#include "clang/Basic/AttrList.inc"
236#undef KIND_TO_KIND_ID
237
238inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
239 OS << K.asStringRef();
240 return OS;
241}
242
243/// A dynamically typed AST node container.
244///
245/// Stores an AST node in a type safe way. This allows writing code that
246/// works with different kinds of AST nodes, despite the fact that they don't
247/// have a common base class.
248///
249/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
250/// and \c get<T>() to retrieve the node as type T if the types match.
251///
252/// See \c ASTNodeKind for which node base types are currently supported;
253/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
254/// the supported base types.
256public:
257 /// Creates a \c DynTypedNode from \c Node.
258 template <typename T>
259 static DynTypedNode create(const T &Node) {
260 return BaseConverter<T>::create(Node);
261 }
262
263 /// Retrieve the stored node as type \c T.
264 ///
265 /// Returns NULL if the stored node does not have a type that is
266 /// convertible to \c T.
267 ///
268 /// For types that have identity via their pointer in the AST
269 /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
270 /// pointer points to the referenced AST node.
271 /// For other types (like \c QualType) the value is stored directly
272 /// in the \c DynTypedNode, and the returned pointer points at
273 /// the storage inside DynTypedNode. For those nodes, do not
274 /// use the pointer outside the scope of the DynTypedNode.
275 template <typename T> const T *get() const {
276 return BaseConverter<T>::get(NodeKind, &Storage);
277 }
278
279 /// Retrieve the stored node as type \c T.
280 ///
281 /// Similar to \c get(), but asserts that the type is what we are expecting.
282 template <typename T>
283 const T &getUnchecked() const {
284 return BaseConverter<T>::getUnchecked(NodeKind, &Storage);
285 }
286
287 ASTNodeKind getNodeKind() const { return NodeKind; }
288
289 /// Returns a pointer that identifies the stored AST node.
290 ///
291 /// Note that this is not supported by all AST nodes. For AST nodes
292 /// that don't have a pointer-defined identity inside the AST, this
293 /// method returns NULL.
294 const void *getMemoizationData() const {
295 return NodeKind.hasPointerIdentity()
296 ? *reinterpret_cast<void *const *>(&Storage)
297 : nullptr;
298 }
299
300 /// Prints the node to the given output stream.
301 void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
302
303 /// Dumps the node to the given output stream.
304 void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
305
306 /// For nodes which represent textual entities in the source code,
307 /// return their SourceRange. For all other nodes, return SourceRange().
309
310 /// @{
311 /// Imposes an order on \c DynTypedNode.
312 ///
313 /// Supports comparison of nodes that support memoization.
314 /// FIXME: Implement comparison for other node types (currently
315 /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
316 bool operator<(const DynTypedNode &Other) const {
317 if (!NodeKind.isSame(Other.NodeKind))
318 return NodeKind < Other.NodeKind;
319
320 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
321 return getUnchecked<QualType>().getAsOpaquePtr() <
322 Other.getUnchecked<QualType>().getAsOpaquePtr();
323
324 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind)) {
325 auto TLA = getUnchecked<TypeLoc>();
326 auto TLB = Other.getUnchecked<TypeLoc>();
327 return std::make_pair(TLA.getType().getAsOpaquePtr(),
328 TLA.getOpaqueData()) <
329 std::make_pair(TLB.getType().getAsOpaquePtr(),
330 TLB.getOpaqueData());
331 }
332
333 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
334 NodeKind)) {
335 auto NNSLA = getUnchecked<NestedNameSpecifierLoc>();
336 auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>();
337 return std::make_pair(NNSLA.getNestedNameSpecifier(),
338 NNSLA.getOpaqueData()) <
339 std::make_pair(NNSLB.getNestedNameSpecifier(),
340 NNSLB.getOpaqueData());
341 }
342
343 assert(getMemoizationData() && Other.getMemoizationData());
344 return getMemoizationData() < Other.getMemoizationData();
345 }
346 bool operator==(const DynTypedNode &Other) const {
347 // DynTypedNode::create() stores the exact kind of the node in NodeKind.
348 // If they contain the same node, their NodeKind must be the same.
349 if (!NodeKind.isSame(Other.NodeKind))
350 return false;
351
352 // FIXME: Implement for other types.
353 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
354 return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
355
356 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind))
357 return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
358
359 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind))
360 return getUnchecked<NestedNameSpecifierLoc>() ==
361 Other.getUnchecked<NestedNameSpecifierLoc>();
362
363 assert(getMemoizationData() && Other.getMemoizationData());
364 return getMemoizationData() == Other.getMemoizationData();
365 }
366 bool operator!=(const DynTypedNode &Other) const {
367 return !operator==(Other);
368 }
369 /// @}
370
371 /// Hooks for using DynTypedNode as a key in a DenseMap.
373 static inline DynTypedNode getEmptyKey() {
376 return Node;
377 }
381 return Node;
382 }
383 static unsigned getHashValue(const DynTypedNode &Val) {
384 // FIXME: Add hashing support for the remaining types.
385 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(Val.NodeKind)) {
386 auto TL = Val.getUnchecked<TypeLoc>();
387 return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
388 TL.getOpaqueData());
389 }
390
391 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
392 Val.NodeKind)) {
393 auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>();
394 return llvm::hash_combine(NNSL.getNestedNameSpecifier(),
395 NNSL.getOpaqueData());
396 }
397
398 assert(Val.getMemoizationData());
399 return llvm::hash_value(Val.getMemoizationData());
400 }
401 static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
404 return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) &&
405 ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, Empty)) ||
406 (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, TombStone) &&
407 ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, TombStone)) ||
408 LHS == RHS;
409 }
410 };
411
412private:
413 /// Takes care of converting from and to \c T.
414 template <typename T, typename EnablerT = void> struct BaseConverter;
415
416 /// Converter that uses dyn_cast<T> from a stored BaseT*.
417 template <typename T, typename BaseT> struct DynCastPtrConverter {
418 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
419 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
420 return &getUnchecked(NodeKind, Storage);
421 return nullptr;
422 }
423 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
424 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
425 return *cast<T>(static_cast<const BaseT *>(
426 *reinterpret_cast<const void *const *>(Storage)));
427 }
428 static DynTypedNode create(const BaseT &Node) {
431 new (&Result.Storage) const void *(&Node);
432 return Result;
433 }
434 };
435
436 /// Converter that stores T* (by pointer).
437 template <typename T> struct PtrConverter {
438 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
439 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
440 return &getUnchecked(NodeKind, Storage);
441 return nullptr;
442 }
443 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
444 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
445 return *static_cast<const T *>(
446 *reinterpret_cast<const void *const *>(Storage));
447 }
448 static DynTypedNode create(const T &Node) {
450 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
451 new (&Result.Storage) const void *(&Node);
452 return Result;
453 }
454 };
455
456 /// Converter that stores T (by value).
457 template <typename T> struct ValueConverter {
458 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
459 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
460 return reinterpret_cast<const T *>(Storage);
461 return nullptr;
462 }
463 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
464 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
465 return *reinterpret_cast<const T *>(Storage);
466 }
467 static DynTypedNode create(const T &Node) {
469 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
470 new (&Result.Storage) T(Node);
471 return Result;
472 }
473 };
474
475 /// Converter that stores nodes by value. It must be possible to dynamically
476 /// cast the stored node within a type hierarchy without breaking (especially
477 /// through slicing).
478 template <typename T, typename BaseT,
479 typename = std::enable_if_t<(sizeof(T) == sizeof(BaseT))>>
480 struct DynCastValueConverter {
481 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
482 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
483 return &getUnchecked(NodeKind, Storage);
484 return nullptr;
485 }
486 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
487 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
488 return *static_cast<const T *>(reinterpret_cast<const BaseT *>(Storage));
489 }
490 static DynTypedNode create(const T &Node) {
493 new (&Result.Storage) T(Node);
494 return Result;
495 }
496 };
497
498 ASTNodeKind NodeKind;
499
500 /// Stores the data of the node.
501 ///
502 /// Note that we can store \c Decls, \c Stmts, \c Types,
503 /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
504 /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
505 /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs,
506 /// \c TemplateArguments and \c TemplateArgumentLocs on the other hand do not
507 /// have storage or unique pointers and thus need to be stored by value.
508 llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
509 TemplateArgumentLoc, NestedNameSpecifierLoc,
510 QualType, TypeLoc, ObjCProtocolLoc>
511 Storage;
512};
513
514template <typename T>
515struct DynTypedNode::BaseConverter<
516 T, std::enable_if_t<std::is_base_of<Decl, T>::value>>
517 : public DynCastPtrConverter<T, Decl> {};
518
519template <typename T>
520struct DynTypedNode::BaseConverter<
521 T, std::enable_if_t<std::is_base_of<Stmt, T>::value>>
522 : public DynCastPtrConverter<T, Stmt> {};
523
524template <typename T>
525struct DynTypedNode::BaseConverter<
526 T, std::enable_if_t<std::is_base_of<Type, T>::value>>
527 : public DynCastPtrConverter<T, Type> {};
528
529template <typename T>
530struct DynTypedNode::BaseConverter<
531 T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
532 : public DynCastPtrConverter<T, OMPClause> {};
533
534template <typename T>
535struct DynTypedNode::BaseConverter<
536 T, std::enable_if_t<std::is_base_of<Attr, T>::value>>
537 : public DynCastPtrConverter<T, Attr> {};
538
539template <>
540struct DynTypedNode::BaseConverter<
541 NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
542
543template <>
544struct DynTypedNode::BaseConverter<
545 CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
546
547template <>
548struct DynTypedNode::BaseConverter<
549 TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
550
551template <>
552struct DynTypedNode::BaseConverter<TemplateArgumentLoc, void>
553 : public ValueConverter<TemplateArgumentLoc> {};
554
555template <>
556struct DynTypedNode::BaseConverter<LambdaCapture, void>
557 : public ValueConverter<LambdaCapture> {};
558
559template <>
560struct DynTypedNode::BaseConverter<
561 TemplateName, void> : public ValueConverter<TemplateName> {};
562
563template <>
564struct DynTypedNode::BaseConverter<
566 void> : public ValueConverter<NestedNameSpecifierLoc> {};
567
568template <>
569struct DynTypedNode::BaseConverter<QualType,
570 void> : public ValueConverter<QualType> {};
571
572template <typename T>
573struct DynTypedNode::BaseConverter<
574 T, std::enable_if_t<std::is_base_of<TypeLoc, T>::value>>
575 : public DynCastValueConverter<T, TypeLoc> {};
576
577template <>
578struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void>
579 : public PtrConverter<CXXBaseSpecifier> {};
580
581template <>
582struct DynTypedNode::BaseConverter<ObjCProtocolLoc, void>
583 : public ValueConverter<ObjCProtocolLoc> {};
584
585// The only operation we allow on unsupported types is \c get.
586// This allows to conveniently use \c DynTypedNode when having an arbitrary
587// AST node that is not supported, but prevents misuse - a user cannot create
588// a DynTypedNode from arbitrary types.
589template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
590 static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
591 return NULL;
592 }
593};
594
595} // end namespace clang
596
597namespace llvm {
598
599template <>
600struct DenseMapInfo<clang::ASTNodeKind> : clang::ASTNodeKind::DenseMapInfo {};
601
602template <>
603struct DenseMapInfo<clang::DynTypedNode> : clang::DynTypedNode::DenseMapInfo {};
604
605} // end namespace llvm
606
607#endif
int Id
Definition: ASTDiff.cpp:190
Forward declaration of all AST node types.
DynTypedNode Node
#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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
Kind identifier.
Definition: ASTTypeTraits.h:51
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.
Definition: ASTTypeTraits.h:54
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.
Definition: ASTTypeTraits.h:92
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.
Definition: ASTTypeTraits.h:73
constexpr bool isNone() const
Returns true only for the default ASTNodeKind()
Definition: ASTTypeTraits.h:78
static constexpr ASTNodeKind getFromNodeKind()
Construct an identifier for T.
Definition: ASTTypeTraits.h:57
Attr - This represents one attribute.
Definition: Attr.h:40
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2259
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
A dynamically typed AST node container.
bool operator<(const DynTypedNode &Other) const
ASTNodeKind getNodeKind() const
SourceRange getSourceRange() const
For nodes which represent textual entities in the source code, return their SourceRange.
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.
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.
Definition: LambdaCapture.h:25
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.
Definition: OpenMPClause.h:55
A (possibly-)qualified type.
Definition: Type.h:736
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition: Stmt.h:72
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:484
Represents a template argument.
Definition: TemplateBase.h:60
Represents a C++ template name within the type system.
Definition: TemplateName.h:202
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:58
The base class of the type hierarchy.
Definition: Type.h:1568
DynTypedNode DynTypedNode
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions *Diags, bool MergeChildRecords=false)
Returns a DiagnosticConsumer that serializes diagnostics to a bitcode file.
NodeKind
A kind of a syntax node, used for implementing casts.
Definition: Nodes.h:32
const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)
Insertion operator for diagnostics.
TraversalKind
Defines how we descend a level in the AST when we pass through expressions.
Definition: ASTTypeTraits.h:38
@ TK_AsIs
Will traverse all child nodes.
Definition: ASTTypeTraits.h:40
@ TK_IgnoreUnlessSpelledInSource
Ignore AST nodes not written in the source.
Definition: ASTTypeTraits.h:43
@ C
Languages that the frontend can parse and compile.
@ Result
The result type of a method or function.
YAML serialization mapping.
Definition: Dominators.h:30
Definition: Format.h:4756
#define NULL
Definition: stddef.h:89
Hooks for using ASTNodeKind as a key in a DenseMap.
static ASTNodeKind getEmptyKey()
static unsigned getHashValue(const ASTNodeKind &Val)
static bool isEqual(const ASTNodeKind &LHS, const ASTNodeKind &RHS)
static ASTNodeKind getTombstoneKey()
Hooks for using DynTypedNode as a key in a DenseMap.
static unsigned getHashValue(const DynTypedNode &Val)
static DynTypedNode getEmptyKey()
static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS)
static DynTypedNode getTombstoneKey()
Describes how types, statements, expressions, and declarations should be printed.
Definition: PrettyPrinter.h:57