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