clang 22.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().
310 SourceRange getSourceRange(bool IncludeQualifier = false) const;
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().getAsVoidPointer(),
340 NNSLA.getOpaqueData()) <
341 std::make_pair(NNSLB.getNestedNameSpecifier().getAsVoidPointer(),
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(
397 NNSL.getNestedNameSpecifier().getAsVoidPointer(),
398 NNSL.getOpaqueData());
399 }
400
401 assert(Val.getMemoizationData());
403 }
404 static bool isEqual(const DynTypedNode &LHS, const DynTypedNode &RHS) {
407 return (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, Empty) &&
409 (ASTNodeKind::DenseMapInfo::isEqual(LHS.NodeKind, TombStone) &&
410 ASTNodeKind::DenseMapInfo::isEqual(RHS.NodeKind, TombStone)) ||
411 LHS == RHS;
412 }
413 };
414
415private:
416 /// Takes care of converting from and to \c T.
417 template <typename T, typename EnablerT = void> struct BaseConverter;
418
419 /// Converter that uses dyn_cast<T> from a stored BaseT*.
420 template <typename T, typename BaseT> struct DynCastPtrConverter {
421 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
422 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(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>().isBaseOf(NodeKind));
428 return *cast<T>(static_cast<const BaseT *>(
429 *reinterpret_cast<const void *const *>(Storage)));
430 }
431 static DynTypedNode create(const BaseT &Node) {
434 new (&Result.Storage) const void *(&Node);
435 return Result;
436 }
437 };
438
439 /// Converter that stores T* (by pointer).
440 template <typename T> struct PtrConverter {
441 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
442 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
443 return &getUnchecked(NodeKind, Storage);
444 return nullptr;
445 }
446 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
447 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
448 return *static_cast<const T *>(
449 *reinterpret_cast<const void *const *>(Storage));
450 }
451 static DynTypedNode create(const T &Node) {
453 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
454 new (&Result.Storage) const void *(&Node);
455 return Result;
456 }
457 };
458
459 /// Converter that stores T (by value).
460 template <typename T> struct ValueConverter {
461 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
462 if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
463 return reinterpret_cast<const T *>(Storage);
464 return nullptr;
465 }
466 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
467 assert(ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind));
468 return *reinterpret_cast<const T *>(Storage);
469 }
470 static DynTypedNode create(const T &Node) {
472 Result.NodeKind = ASTNodeKind::getFromNodeKind<T>();
473 new (&Result.Storage) T(Node);
474 return Result;
475 }
476 };
477
478 /// Converter that stores nodes by value. It must be possible to dynamically
479 /// cast the stored node within a type hierarchy without breaking (especially
480 /// through slicing).
481 template <typename T, typename BaseT,
482 typename = std::enable_if_t<(sizeof(T) == sizeof(BaseT))>>
483 struct DynCastValueConverter {
484 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
485 if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
486 return &getUnchecked(NodeKind, Storage);
487 return nullptr;
488 }
489 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
490 assert(ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind));
491 return *static_cast<const T *>(reinterpret_cast<const BaseT *>(Storage));
492 }
493 static DynTypedNode create(const T &Node) {
496 new (&Result.Storage) T(Node);
497 return Result;
498 }
499 };
500
501 ASTNodeKind NodeKind;
502
503 /// Stores the data of the node.
504 ///
505 /// Note that we can store \c Decls, \c Stmts, \c Types,
506 /// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
507 /// guaranteed to be unique pointers pointing to dedicated storage in the AST.
508 /// \c QualTypes, \c NestedNameSpecifierLocs, \c TypeLocs,
509 /// \c TemplateArguments and \c TemplateArgumentLocs on the other hand do not
510 /// have storage or unique pointers and thus need to be stored by value.
511 llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
512 TemplateArgumentLoc, NestedNameSpecifierLoc,
513 QualType, TypeLoc, ObjCProtocolLoc>
514 Storage;
515};
516
517template <typename T>
518struct DynTypedNode::BaseConverter<
519 T, std::enable_if_t<std::is_base_of<Decl, T>::value>>
520 : public DynCastPtrConverter<T, Decl> {};
521
522template <typename T>
523struct DynTypedNode::BaseConverter<
524 T, std::enable_if_t<std::is_base_of<Stmt, T>::value>>
525 : public DynCastPtrConverter<T, Stmt> {};
526
527template <typename T>
528struct DynTypedNode::BaseConverter<
529 T, std::enable_if_t<std::is_base_of<Type, T>::value>>
530 : public DynCastPtrConverter<T, Type> {};
531
532template <typename T>
533struct DynTypedNode::BaseConverter<
534 T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
535 : public DynCastPtrConverter<T, OMPClause> {};
536
537template <typename T>
538struct DynTypedNode::BaseConverter<
539 T, std::enable_if_t<std::is_base_of<Attr, T>::value>>
540 : public DynCastPtrConverter<T, Attr> {};
541
542template <>
543struct DynTypedNode::BaseConverter<NestedNameSpecifier, void>
544 : public ValueConverter<NestedNameSpecifier> {};
545
546template <>
547struct DynTypedNode::BaseConverter<
548 CXXCtorInitializer, void> : public PtrConverter<CXXCtorInitializer> {};
549
550template <>
551struct DynTypedNode::BaseConverter<
552 TemplateArgument, void> : public ValueConverter<TemplateArgument> {};
553
554template <>
555struct DynTypedNode::BaseConverter<TemplateArgumentLoc, void>
556 : public ValueConverter<TemplateArgumentLoc> {};
557
558template <>
559struct DynTypedNode::BaseConverter<LambdaCapture, void>
560 : public ValueConverter<LambdaCapture> {};
561
562template <>
563struct DynTypedNode::BaseConverter<
564 TemplateName, void> : public ValueConverter<TemplateName> {};
565
566template <>
567struct DynTypedNode::BaseConverter<
569 void> : public ValueConverter<NestedNameSpecifierLoc> {};
570
571template <>
572struct DynTypedNode::BaseConverter<QualType,
573 void> : public ValueConverter<QualType> {};
574
575template <typename T>
576struct DynTypedNode::BaseConverter<
577 T, std::enable_if_t<std::is_base_of<TypeLoc, T>::value>>
578 : public DynCastValueConverter<T, TypeLoc> {};
579
580template <>
581struct DynTypedNode::BaseConverter<CXXBaseSpecifier, void>
582 : public PtrConverter<CXXBaseSpecifier> {};
583
584template <>
585struct DynTypedNode::BaseConverter<ObjCProtocolLoc, void>
586 : public ValueConverter<ObjCProtocolLoc> {};
587
588template <>
589struct DynTypedNode::BaseConverter<ConceptReference, void>
590 : public PtrConverter<ConceptReference> {};
591
592// The only operation we allow on unsupported types is \c get.
593// This allows to conveniently use \c DynTypedNode when having an arbitrary
594// AST node that is not supported, but prevents misuse - a user cannot create
595// a DynTypedNode from arbitrary types.
596template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
597 static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
598 return NULL;
599 }
600};
601
602} // end namespace clang
603
604namespace llvm {
605
606template <>
607struct DenseMapInfo<clang::ASTNodeKind> : clang::ASTNodeKind::DenseMapInfo {};
608
609template <>
610struct DenseMapInfo<clang::DynTypedNode> : clang::DynTypedNode::DenseMapInfo {};
611
612} // end namespace llvm
613
614#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:1179
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:188
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:44
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a C++ base or member initializer.
Definition: DeclCXX.h:2369
A reference to a concept and its template args, as it appears in the code.
Definition: ASTConcept.h:126
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.
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: TypeBase.h:937
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
Definition: Stmt.h:85
Location wrapper for a TemplateArgument.
Definition: TemplateBase.h:528
Represents a template argument.
Definition: TemplateBase.h:61
Represents a C++ template name within the type system.
Definition: TemplateName.h:222
Base wrapper for a particular "section" of type source info.
Definition: TypeLoc.h:59
The base class of the type hierarchy.
Definition: TypeBase.h:1833
DynTypedNode DynTypedNode
std::unique_ptr< DiagnosticConsumer > create(StringRef OutputFile, DiagnosticOptions &DiagOpts, 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