clang 20.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_ConceptReference,
167 NKI_NumberOfKinds
168 };
169
170 /// Use getFromNodeKind<T>() to construct the kind.
171 constexpr ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
172
173 /// Returns \c true if \c Base is a base kind of (or same as) \c
174 /// Derived.
175 static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
176
177 /// Returns \c true if \c Base is a base kind of (or same as) \c
178 /// Derived.
179 /// \param Distance If non-null, used to return the distance between \c Base
180 /// and \c Derived in the class hierarchy.
181 static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
182
183 /// Helper meta-function to convert a kind T to its enum value.
184 ///
185 /// This struct is specialized below for all known kinds.
186 template <class T> struct KindToKindId {
187 static const NodeKindId Id = NKI_None;
188 };
189 template <class T>
190 struct KindToKindId<const T> : KindToKindId<T> {};
191
192 /// Per kind info.
193 struct KindInfo {
194 /// The id of the parent kind, or None if it has no parent.
195 NodeKindId ParentId;
196 /// Name of the kind.
197 const char *Name;
198 };
199 static const KindInfo AllKindInfo[NKI_NumberOfKinds];
200
201 NodeKindId KindId;
202};
203
204#define KIND_TO_KIND_ID(Class) \
205 template <> struct ASTNodeKind::KindToKindId<Class> { \
206 static const NodeKindId Id = NKI_##Class; \
207 };
208KIND_TO_KIND_ID(CXXCtorInitializer)
209KIND_TO_KIND_ID(TemplateArgument)
210KIND_TO_KIND_ID(TemplateArgumentLoc)
211KIND_TO_KIND_ID(LambdaCapture)
212KIND_TO_KIND_ID(TemplateName)
213KIND_TO_KIND_ID(NestedNameSpecifier)
214KIND_TO_KIND_ID(NestedNameSpecifierLoc)
215KIND_TO_KIND_ID(QualType)
216#define TYPELOC(CLASS, PARENT) KIND_TO_KIND_ID(CLASS##TypeLoc)
217#include "clang/AST/TypeLocNodes.def"
218KIND_TO_KIND_ID(TypeLoc)
219KIND_TO_KIND_ID(Decl)
220KIND_TO_KIND_ID(Stmt)
221KIND_TO_KIND_ID(Type)
222KIND_TO_KIND_ID(OMPClause)
223KIND_TO_KIND_ID(Attr)
224KIND_TO_KIND_ID(ObjCProtocolLoc)
225KIND_TO_KIND_ID(CXXBaseSpecifier)
226KIND_TO_KIND_ID(ConceptReference)
227#define DECL(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Decl)
228#include "clang/AST/DeclNodes.inc"
229#define STMT(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED)
230#include "clang/AST/StmtNodes.inc"
231#define TYPE(DERIVED, BASE) KIND_TO_KIND_ID(DERIVED##Type)
232#include "clang/AST/TypeNodes.inc"
233#define GEN_CLANG_CLAUSE_CLASS
234#define CLAUSE_CLASS(Enum, Str, Class) KIND_TO_KIND_ID(Class)
235#include "llvm/Frontend/OpenMP/OMP.inc"
236#define ATTR(A) KIND_TO_KIND_ID(A##Attr)
237#include "clang/Basic/AttrList.inc"
238#undef KIND_TO_KIND_ID
239
240inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
241 OS << K.asStringRef();
242 return OS;
243}
244
245/// A dynamically typed AST node container.
246///
247/// Stores an AST node in a type safe way. This allows writing code that
248/// works with different kinds of AST nodes, despite the fact that they don't
249/// have a common base class.
250///
251/// Use \c create(Node) to create a \c DynTypedNode from an AST node,
252/// and \c get<T>() to retrieve the node as type T if the types match.
253///
254/// See \c ASTNodeKind for which node base types are currently supported;
255/// You can create DynTypedNodes for all nodes in the inheritance hierarchy of
256/// the supported base types.
258public:
259 /// Creates a \c DynTypedNode from \c Node.
260 template <typename T>
261 static DynTypedNode create(const T &Node) {
262 return BaseConverter<T>::create(Node);
263 }
264
265 /// Retrieve the stored node as type \c T.
266 ///
267 /// Returns NULL if the stored node does not have a type that is
268 /// convertible to \c T.
269 ///
270 /// For types that have identity via their pointer in the AST
271 /// (like \c Stmt, \c Decl, \c Type and \c NestedNameSpecifier) the returned
272 /// pointer points to the referenced AST node.
273 /// For other types (like \c QualType) the value is stored directly
274 /// in the \c DynTypedNode, and the returned pointer points at
275 /// the storage inside DynTypedNode. For those nodes, do not
276 /// use the pointer outside the scope of the DynTypedNode.
277 template <typename T> const T *get() const {
278 return BaseConverter<T>::get(NodeKind, &Storage);
279 }
280
281 /// Retrieve the stored node as type \c T.
282 ///
283 /// Similar to \c get(), but asserts that the type is what we are expecting.
284 template <typename T>
285 const T &getUnchecked() const {
286 return BaseConverter<T>::getUnchecked(NodeKind, &Storage);
287 }
288
289 ASTNodeKind getNodeKind() const { return NodeKind; }
290
291 /// Returns a pointer that identifies the stored AST node.
292 ///
293 /// Note that this is not supported by all AST nodes. For AST nodes
294 /// that don't have a pointer-defined identity inside the AST, this
295 /// method returns NULL.
296 const void *getMemoizationData() const {
297 return NodeKind.hasPointerIdentity()
298 ? *reinterpret_cast<void *const *>(&Storage)
299 : nullptr;
300 }
301
302 /// Prints the node to the given output stream.
303 void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
304
305 /// Dumps the node to the given output stream.
306 void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
307
308 /// For nodes which represent textual entities in the source code,
309 /// return their SourceRange. For all other nodes, return SourceRange().
311
312 /// @{
313 /// Imposes an order on \c DynTypedNode.
314 ///
315 /// Supports comparison of nodes that support memoization.
316 /// FIXME: Implement comparison for other node types (currently
317 /// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
318 bool operator<(const DynTypedNode &Other) const {
319 if (!NodeKind.isSame(Other.NodeKind))
320 return NodeKind < Other.NodeKind;
321
322 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
323 return getUnchecked<QualType>().getAsOpaquePtr() <
324 Other.getUnchecked<QualType>().getAsOpaquePtr();
325
326 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind)) {
327 auto TLA = getUnchecked<TypeLoc>();
328 auto TLB = Other.getUnchecked<TypeLoc>();
329 return std::make_pair(TLA.getType().getAsOpaquePtr(),
330 TLA.getOpaqueData()) <
331 std::make_pair(TLB.getType().getAsOpaquePtr(),
332 TLB.getOpaqueData());
333 }
334
335 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
336 NodeKind)) {
337 auto NNSLA = getUnchecked<NestedNameSpecifierLoc>();
338 auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>();
339 return std::make_pair(NNSLA.getNestedNameSpecifier(),
340 NNSLA.getOpaqueData()) <
341 std::make_pair(NNSLB.getNestedNameSpecifier(),
342 NNSLB.getOpaqueData());
343 }
344
345 assert(getMemoizationData() && Other.getMemoizationData());
346 return getMemoizationData() < Other.getMemoizationData();
347 }
348 bool operator==(const DynTypedNode &Other) const {
349 // DynTypedNode::create() stores the exact kind of the node in NodeKind.
350 // If they contain the same node, their NodeKind must be the same.
351 if (!NodeKind.isSame(Other.NodeKind))
352 return false;
353
354 // FIXME: Implement for other types.
355 if (ASTNodeKind::getFromNodeKind<QualType>().isSame(NodeKind))
356 return getUnchecked<QualType>() == Other.getUnchecked<QualType>();
357
358 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(NodeKind))
359 return getUnchecked<TypeLoc>() == Other.getUnchecked<TypeLoc>();
360
361 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(NodeKind))
362 return getUnchecked<NestedNameSpecifierLoc>() ==
363 Other.getUnchecked<NestedNameSpecifierLoc>();
364
365 assert(getMemoizationData() && Other.getMemoizationData());
366 return getMemoizationData() == Other.getMemoizationData();
367 }
368 bool operator!=(const DynTypedNode &Other) const {
369 return !operator==(Other);
370 }
371 /// @}
372
373 /// Hooks for using DynTypedNode as a key in a DenseMap.
375 static inline DynTypedNode getEmptyKey() {
378 return Node;
379 }
383 return Node;
384 }
385 static unsigned getHashValue(const DynTypedNode &Val) {
386 // FIXME: Add hashing support for the remaining types.
387 if (ASTNodeKind::getFromNodeKind<TypeLoc>().isBaseOf(Val.NodeKind)) {
388 auto TL = Val.getUnchecked<TypeLoc>();
389 return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
390 TL.getOpaqueData());
391 }
392
393 if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
394 Val.NodeKind)) {
395 auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>();
396 return llvm::hash_combine(NNSL.getNestedNameSpecifier(),
397 NNSL.getOpaqueData());
398 }
399
400 assert(Val.getMemoizationData());
402 }
403 static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
406 return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) &&
408 (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, TombStone) &&
409 ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, TombStone)) ||
410 LHS == RHS;
411 }
412 };
413
414private:
415 /// Takes care of converting from and to \c T.
416 template <typename T, typename EnablerT = void> struct BaseConverter;
417
418 /// Converter that uses dyn_cast<T> from a stored BaseT*.
419 template <typename T, typename BaseT> struct DynCastPtrConverter {
420 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
421 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
422 return &getUnchecked(NodeKind, Storage);
423 return nullptr;
424 }
425 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
426 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
427 return *cast<T>(static_cast<const BaseT *>(
428 *reinterpret_cast<const void *const *>(Storage)));
429 }
430 static DynTypedNode create(const BaseT &Node) {
433 new (&Result.Storage) const void *(&Node);
434 return Result;
435 }
436 };
437
438 /// Converter that stores T* (by pointer).
439 template <typename T> struct PtrConverter {
440 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
441 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
442 return &getUnchecked(NodeKind, Storage);
443 return nullptr;
444 }
445 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
446 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
447 return *static_cast<const T *>(
448 *reinterpret_cast<const void *const *>(Storage));
449 }
450 static DynTypedNode create(const T &Node) {
452 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
453 new (&Result.Storage) const void *(&Node);
454 return Result;
455 }
456 };
457
458 /// Converter that stores T (by value).
459 template <typename T> struct ValueConverter {
460 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
461 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
462 return reinterpret_cast<const T *>(Storage);
463 return nullptr;
464 }
465 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
466 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
467 return *reinterpret_cast<const T *>(Storage);
468 }
469 static DynTypedNode create(const T &Node) {
471 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
472 new (&Result.Storage) T(Node);
473 return Result;
474 }
475 };
476
477 /// Converter that stores nodes by value. It must be possible to dynamically
478 /// cast the stored node within a type hierarchy without breaking (especially
479 /// through slicing).
480 template <typename T, typename BaseT,
481 typename = std::enable_if_t<(sizeof(T) == sizeof(BaseT))>>
482 struct DynCastValueConverter {
483 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
484 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
485 return &getUnchecked(NodeKind, Storage);
486 return nullptr;
487 }
488 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
489 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
490 return *static_cast<const T *>(reinterpret_cast<const BaseT *>(Storage));
491 }
492 static DynTypedNode create(const T &Node) {
495 new (&Result.Storage) T(Node);
496 return Result;
497 }
498 };
499
500 ASTNodeKind NodeKind;
501
502 /// Stores the data of the node.
503 ///
504 /// Note that we can store \c Decls, \c Stmts, \c Types,
505 /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
506 /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
507 /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs,
508 /// \c TemplateArguments and \c TemplateArgumentLocs on the other hand do not
509 /// have storage or unique pointers and thus need to be stored by value.
510 llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
511 TemplateArgumentLoc, NestedNameSpecifierLoc,
512 QualType, TypeLoc, ObjCProtocolLoc>
513 Storage;
514};
515
516template <typename T>
517struct DynTypedNode::BaseConverter<
518 T, std::enable_if_t<std::is_base_of<Decl, T>::value>>
519 : public DynCastPtrConverter<T, Decl> {};
520
521template <typename T>
522struct DynTypedNode::BaseConverter<
523 T, std::enable_if_t<std::is_base_of<Stmt, T>::value>>
524 : public DynCastPtrConverter<T, Stmt> {};
525
526template <typename T>
527struct DynTypedNode::BaseConverter<
528 T, std::enable_if_t<std::is_base_of<Type, T>::value>>
529 : public DynCastPtrConverter<T, Type> {};
530
531template <typename T>
532struct DynTypedNode::BaseConverter<
533 T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
534 : public DynCastPtrConverter<T, OMPClause> {};
535
536template <typename T>
537struct DynTypedNode::BaseConverter<
538 T, std::enable_if_t<std::is_base_of<Attr, T>::value>>
539 : public DynCastPtrConverter<T, Attr> {};
540
541template <>
542struct DynTypedNode::BaseConverter<
543 NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
544
545template <>
546struct DynTypedNode::BaseConverter<
547 CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
548
549template <>
550struct DynTypedNode::BaseConverter<
551 TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
552
553template <>
554struct DynTypedNode::BaseConverter<TemplateArgumentLoc, void>
555 : public ValueConverter<TemplateArgumentLoc> {};
556
557template <>
558struct DynTypedNode::BaseConverter<LambdaCapture, void>
559 : public ValueConverter<LambdaCapture> {};
560
561template <>
562struct DynTypedNode::BaseConverter<
563 TemplateName, void> : public ValueConverter<TemplateName> {};
564
565template <>
566struct DynTypedNode::BaseConverter<
568 void> : public ValueConverter<NestedNameSpecifierLoc> {};
569
570template <>
571struct DynTypedNode::BaseConverter<QualType,
572 void> : public ValueConverter<QualType> {};
573
574template <typename T>
575struct DynTypedNode::BaseConverter<
576 T, std::enable_if_t<std::is_base_of<TypeLoc, T>::value>>
577 : public DynCastValueConverter<T, TypeLoc> {};
578
579template <>
580struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void>
581 : public PtrConverter<CXXBaseSpecifier> {};
582
583template <>
584struct DynTypedNode::BaseConverter<ObjCProtocolLoc, void>
585 : public ValueConverter<ObjCProtocolLoc> {};
586
587template <>
588struct DynTypedNode::BaseConverter<ConceptReference, void>
589 : public PtrConverter<ConceptReference> {};
590
591// The only operation we allow on unsupported types is \c get.
592// This allows to conveniently use \c DynTypedNode when having an arbitrary
593// AST node that is not supported, but prevents misuse - a user cannot create
594// a DynTypedNode from arbitrary types.
595template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
596 static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
597 return NULL;
598 }
599};
600
601} // end namespace clang
602
603namespace llvm {
604
605template <>
606struct DenseMapInfo<clang::ASTNodeKind> : clang::ASTNodeKind::DenseMapInfo {};
607
608template <>
609struct DenseMapInfo<clang::DynTypedNode> : clang::DynTypedNode::DenseMapInfo {};
610
611} // end namespace llvm
612
613#endif
Forward declaration of all AST node types.
DynTypedNode Node
#define KIND_TO_KIND_ID(Class)
const Decl * D
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.
uint32_t Id
Definition: SemaARM.cpp:1144
Defines the clang::TypeLoc interface and its subclasses.
#define NULL
Definition: __stddef_null.h:26
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:187
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:42
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2304
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:124
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
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:941
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition: Stmt.h:84
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:524
Represents a template argument.
Definition: TemplateBase.h:61
Represents a C++ template name within the type system.
Definition: TemplateName.h:203
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:59
The base class of the type hierarchy.
Definition: Type.h:1829
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
The JSON file list parser is used to communicate input to InstallAPI.
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
@ Result
The result type of a method or function.
const FunctionProtoType * T
@ Other
Other implicit parameter.
Diagnostic wrappers for TextAPI types for error reporting.
Definition: Dominators.h:30
hash_code hash_value(const clang::tooling::dependencies::ModuleID &ID)
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