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