clang: include/clang/AST/ASTTypeTraits.h Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15#ifndef LLVM_CLANG_AST_ASTTYPETRAITS_H
16#define LLVM_CLANG_AST_ASTTYPETRAITS_H
17
25#include "llvm/ADT/DenseMapInfo.h"
26#include "llvm/Support/AlignOf.h"
27
28namespace llvm {
29class raw_ostream;
30}
31
33
34struct PrintingPolicy;
35
36
37
39
41
42
45
46
47
48
49
50
52public:
53
55
56
59 }
60
61
62
70
71
72
74 return KindId != NKI_None && KindId == Other.KindId;
75 }
76
77
78 constexpr bool isNone() const { return KindId == NKI_None; }
79
80
82
83
84
85
87
88
90
91
93 return KindId < Other.KindId;
94 }
95
96
97
98
100
101
102
103
106
108
109
111
113
114
117 }
120 return LHS.KindId == RHS.KindId;
121 }
122 };
123
124
125
127 return KindId > NKI_LastKindWithoutPointerIdentity;
128 }
129
130private:
131
132
133
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
171 constexpr ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
172
173
174
175 static bool isBaseOf(NodeKindId Base, NodeKindId Derived);
176
177
178
179
180
181 static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
182
183
184
185
186 template struct KindToKindId {
187 static const NodeKindId Id = NKI_None;
188 };
189 template
190 struct KindToKindId<const T> : KindToKindId {};
191
192
193 struct KindInfo {
194
195 NodeKindId ParentId;
196
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 { \
206 static const NodeKindId Id = NKI_##Class; \
207 };
216#define TYPELOC(CLASS, PARENT) KIND_TO_KIND_ID(CLASS##TypeLoc)
217#include "clang/AST/TypeLocNodes.def"
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
242 return OS;
243}
244
245
246
247
248
249
250
251
252
253
254
255
256
258public:
259
260 template
262 return BaseConverter::create(Node);
263 }
264
265
266
267
268
269
270
271
272
273
274
275
276
277 template const T *get() const {
278 return BaseConverter::get(NodeKind, &Storage);
279 }
280
281
282
283
284 template
286 return BaseConverter::getUnchecked(NodeKind, &Storage);
287 }
288
290
291
292
293
294
295
298 ? *reinterpret_cast<void *const *>(&Storage)
299 : nullptr;
300 }
301
302
304
305
306 void dump(llvm::raw_ostream &OS, const ASTContext &Context) const;
307
308
309
311
312
313
314
315
316
317
320 return NodeKind < Other.NodeKind;
321
322 if (ASTNodeKind::getFromNodeKind().isSame(NodeKind))
323 return getUnchecked().getAsOpaquePtr() <
325
326 if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind)) {
327 auto TLA = getUnchecked();
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().isSame(
336 NodeKind)) {
337 auto NNSLA = getUnchecked();
339 return std::make_pair(NNSLA.getNestedNameSpecifier(),
340 NNSLA.getOpaqueData()) <
341 std::make_pair(NNSLB.getNestedNameSpecifier(),
342 NNSLB.getOpaqueData());
343 }
344
347 }
349
350
352 return false;
353
354
355 if (ASTNodeKind::getFromNodeKind().isSame(NodeKind))
356 return getUnchecked() == Other.getUnchecked<QualType>();
357
358 if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind))
359 return getUnchecked() == Other.getUnchecked<TypeLoc>();
360
361 if (ASTNodeKind::getFromNodeKind().isSame(NodeKind))
362 return getUnchecked() ==
364
367 }
370 }
371
372
373
379 }
384 }
386
387 if (ASTNodeKind::getFromNodeKind().isBaseOf(Val.NodeKind)) {
389 return llvm::hash_combine(TL.getType().getAsOpaquePtr(),
390 TL.getOpaqueData());
391 }
392
393 if (ASTNodeKind::getFromNodeKind().isSame(
394 Val.NodeKind)) {
396 return llvm::hash_combine(NNSL.getNestedNameSpecifier(),
397 NNSL.getOpaqueData());
398 }
399
402 }
410 LHS == RHS;
411 }
412 };
413
414private:
415
416 template <typename T, typename EnablerT = void> struct BaseConverter;
417
418
419 template <typename T, typename BaseT> struct DynCastPtrConverter {
420 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
421 if (ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind))
423 return nullptr;
424 }
425 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
426 assert(ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind));
427 return *cast(static_cast<const BaseT *>(
428 *reinterpret_cast<const void *const *>(Storage)));
429 }
433 new (&Result.Storage) const void *(&Node);
435 }
436 };
437
438
439 template struct PtrConverter {
440 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
441 if (ASTNodeKind::getFromNodeKind().isSame(NodeKind))
443 return nullptr;
444 }
445 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
446 assert(ASTNodeKind::getFromNodeKind().isSame(NodeKind));
447 return *static_cast<const T *>(
448 *reinterpret_cast<const void *const *>(Storage));
449 }
452 Result.NodeKind = ASTNodeKind::getFromNodeKind();
453 new (&Result.Storage) const void *(&Node);
455 }
456 };
457
458
459 template struct ValueConverter {
460 static const T *get(ASTNodeKind NodeKind, const void *Storage) {
461 if (ASTNodeKind::getFromNodeKind().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().isSame(NodeKind));
467 return *reinterpret_cast<const T *>(Storage);
468 }
471 Result.NodeKind = ASTNodeKind::getFromNodeKind();
474 }
475 };
476
477
478
479
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().isBaseOf(NodeKind))
486 return nullptr;
487 }
488 static const T &getUnchecked(ASTNodeKind NodeKind, const void *Storage) {
489 assert(ASTNodeKind::getFromNodeKind().isBaseOf(NodeKind));
490 return *static_cast<const T *>(reinterpret_cast<const BaseT *>(Storage));
491 }
497 }
498 };
499
501
502
503
504
505
506
507
508
509
510 llvm::AlignedCharArrayUnion<const void *, TemplateArgument,
511 TemplateArgumentLoc, NestedNameSpecifierLoc,
512 QualType, TypeLoc, ObjCProtocolLoc>
514};
515
516template
517struct DynTypedNode::BaseConverter<
518 T, std::enable_if_t<std::is_base_of<Decl, T>::value>>
519 : public DynCastPtrConverter<T, Decl> {};
520
521template
522struct DynTypedNode::BaseConverter<
523 T, std::enable_if_t<std::is_base_of<Stmt, T>::value>>
524 : public DynCastPtrConverter<T, Stmt> {};
525
526template
527struct DynTypedNode::BaseConverter<
528 T, std::enable_if_t<std::is_base_of<Type, T>::value>>
529 : public DynCastPtrConverter<T, Type> {};
530
531template
532struct DynTypedNode::BaseConverter<
533 T, std::enable_if_t<std::is_base_of<OMPClause, T>::value>>
534 : public DynCastPtrConverter<T, OMPClause> {};
535
536template
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 {};
544
545template <>
546struct DynTypedNode::BaseConverter<
547 CXXCtorInitializer, void> : public PtrConverter {};
548
549template <>
550struct DynTypedNode::BaseConverter<
551 TemplateArgument, void> : public ValueConverter {};
552
553template <>
555 : public ValueConverter {};
556
557template <>
559 : public ValueConverter {};
560
561template <>
562struct DynTypedNode::BaseConverter<
563 TemplateName, void> : public ValueConverter {};
564
565template <>
566struct DynTypedNode::BaseConverter<
568 void> : public ValueConverter {};
569
570template <>
571struct DynTypedNode::BaseConverter<QualType,
572 void> : public ValueConverter {};
573
574template
575struct DynTypedNode::BaseConverter<
576 T, std::enable_if_t<std::is_base_of<TypeLoc, T>::value>>
577 : public DynCastValueConverter<T, TypeLoc> {};
578
579template <>
581 : public PtrConverter {};
582
583template <>
585 : public ValueConverter {};
586
587template <>
589 : public PtrConverter {};
590
591
592
593
594
595template <typename T, typename EnablerT> struct DynTypedNode::BaseConverter {
596 static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
598 }
599};
600
601}
602
603namespace llvm {
604
605template <>
607
608template <>
610
611}
612
613#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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
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.
Represents a base class of a C++ class.
Represents a C++ base or member initializer.
A reference to a concept and its template args, as it appears in the code.
Decl - This represents one declaration (or definition), e.g.
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.
A C++ nested-name-specifier augmented with source location information.
Represents a C++ nested name specifier, such as "\::std::vector::".
This is a basic class for representing single OpenMP clause.
A (possibly-)qualified type.
A trivial tuple used to represent a source range.
Stmt - This represents one statement.
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.
The base class of the type hierarchy.
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.
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.
@ 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.
const FunctionProtoType * T
@ Other
Other implicit parameter.
Diagnostic wrappers for TextAPI types for error reporting.
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.