Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 1
//===--- ASTNodeTraverser.h - Traversal of AST nodes ----------------------===//
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
// This file implements the AST traversal facilities.  Other users
10
// of this class may make use of the same traversal logic by inheriting it,
11
// similar to RecursiveASTVisitor.
12
//
13
//===----------------------------------------------------------------------===//
14
 
15
#ifndef LLVM_CLANG_AST_ASTNODETRAVERSER_H
16
#define LLVM_CLANG_AST_ASTNODETRAVERSER_H
17
 
18
#include "clang/AST/ASTTypeTraits.h"
19
#include "clang/AST/AttrVisitor.h"
20
#include "clang/AST/CommentVisitor.h"
21
#include "clang/AST/DeclVisitor.h"
22
#include "clang/AST/LocInfoType.h"
23
#include "clang/AST/StmtVisitor.h"
24
#include "clang/AST/TemplateArgumentVisitor.h"
25
#include "clang/AST/Type.h"
26
#include "clang/AST/TypeVisitor.h"
27
 
28
namespace clang {
29
 
30
class APValue;
31
 
32
/**
33
 
34
ASTNodeTraverser traverses the Clang AST for dumping purposes.
35
 
36
The `Derived::doGetNodeDelegate()` method is required to be an accessible member
37
which returns a reference of type `NodeDelegateType &` which implements the
38
following interface:
39
 
40
struct {
41
  template <typename Fn> void AddChild(Fn DoAddChild);
42
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild);
43
 
44
  void Visit(const comments::Comment *C, const comments::FullComment *FC);
45
  void Visit(const Attr *A);
46
  void Visit(const TemplateArgument &TA, SourceRange R = {},
47
             const Decl *From = nullptr, StringRef Label = {});
48
  void Visit(const Stmt *Node);
49
  void Visit(const Type *T);
50
  void Visit(QualType T);
51
  void Visit(const Decl *D);
52
  void Visit(const CXXCtorInitializer *Init);
53
  void Visit(const OMPClause *C);
54
  void Visit(const BlockDecl::Capture &C);
55
  void Visit(const GenericSelectionExpr::ConstAssociation &A);
56
  void Visit(const concepts::Requirement *R);
57
  void Visit(const APValue &Value, QualType Ty);
58
};
59
*/
60
template <typename Derived, typename NodeDelegateType>
61
class ASTNodeTraverser
62
    : public ConstDeclVisitor<Derived>,
63
      public ConstStmtVisitor<Derived>,
64
      public comments::ConstCommentVisitor<Derived, void,
65
                                           const comments::FullComment *>,
66
      public TypeVisitor<Derived>,
67
      public ConstAttrVisitor<Derived>,
68
      public ConstTemplateArgumentVisitor<Derived> {
69
 
70
  /// Indicates whether we should trigger deserialization of nodes that had
71
  /// not already been loaded.
72
  bool Deserialize = false;
73
 
74
  TraversalKind Traversal = TraversalKind::TK_AsIs;
75
 
76
  NodeDelegateType &getNodeDelegate() {
77
    return getDerived().doGetNodeDelegate();
78
  }
79
  Derived &getDerived() { return *static_cast<Derived *>(this); }
80
 
81
public:
82
  void setDeserialize(bool D) { Deserialize = D; }
83
  bool getDeserialize() const { return Deserialize; }
84
 
85
  void SetTraversalKind(TraversalKind TK) { Traversal = TK; }
86
  TraversalKind GetTraversalKind() const { return Traversal; }
87
 
88
  void Visit(const Decl *D) {
89
    if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isImplicit())
90
      return;
91
 
92
    getNodeDelegate().AddChild([=] {
93
      getNodeDelegate().Visit(D);
94
      if (!D)
95
        return;
96
 
97
      ConstDeclVisitor<Derived>::Visit(D);
98
 
99
      for (const auto &A : D->attrs())
100
        Visit(A);
101
 
102
      if (const comments::FullComment *Comment =
103
              D->getASTContext().getLocalCommentForDeclUncached(D))
104
        Visit(Comment, Comment);
105
 
106
      // Decls within functions are visited by the body.
107
      if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) {
108
        if (Traversal != TK_AsIs) {
109
          if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
110
            auto SK = CTSD->getSpecializationKind();
111
            if (SK == TSK_ExplicitInstantiationDeclaration ||
112
                SK == TSK_ExplicitInstantiationDefinition)
113
              return;
114
          }
115
        }
116
        if (const auto *DC = dyn_cast<DeclContext>(D))
117
          dumpDeclContext(DC);
118
      }
119
    });
120
  }
121
 
122
  void Visit(const Stmt *Node, StringRef Label = {}) {
123
    getNodeDelegate().AddChild(Label, [=] {
124
      const Stmt *S = Node;
125
 
126
      if (auto *E = dyn_cast_or_null<Expr>(S)) {
127
        switch (Traversal) {
128
        case TK_AsIs:
129
          break;
130
        case TK_IgnoreUnlessSpelledInSource:
131
          S = E->IgnoreUnlessSpelledInSource();
132
          break;
133
        }
134
      }
135
 
136
      getNodeDelegate().Visit(S);
137
 
138
      if (!S) {
139
        return;
140
      }
141
 
142
      ConstStmtVisitor<Derived>::Visit(S);
143
 
144
      // Some statements have custom mechanisms for dumping their children.
145
      if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S) ||
146
          isa<RequiresExpr>(S))
147
        return;
148
 
149
      if (Traversal == TK_IgnoreUnlessSpelledInSource &&
150
          isa<LambdaExpr, CXXForRangeStmt, CallExpr,
151
              CXXRewrittenBinaryOperator>(S))
152
        return;
153
 
154
      for (const Stmt *SubStmt : S->children())
155
        Visit(SubStmt);
156
    });
157
  }
158
 
159
  void Visit(QualType T) {
160
    SplitQualType SQT = T.split();
161
    if (!SQT.Quals.hasQualifiers())
162
      return Visit(SQT.Ty);
163
 
164
    getNodeDelegate().AddChild([=] {
165
      getNodeDelegate().Visit(T);
166
      Visit(T.split().Ty);
167
    });
168
  }
169
 
170
  void Visit(const Type *T) {
171
    getNodeDelegate().AddChild([=] {
172
      getNodeDelegate().Visit(T);
173
      if (!T)
174
        return;
175
      TypeVisitor<Derived>::Visit(T);
176
 
177
      QualType SingleStepDesugar =
178
          T->getLocallyUnqualifiedSingleStepDesugaredType();
179
      if (SingleStepDesugar != QualType(T, 0))
180
        Visit(SingleStepDesugar);
181
    });
182
  }
183
 
184
  void Visit(const Attr *A) {
185
    getNodeDelegate().AddChild([=] {
186
      getNodeDelegate().Visit(A);
187
      ConstAttrVisitor<Derived>::Visit(A);
188
    });
189
  }
190
 
191
  void Visit(const CXXCtorInitializer *Init) {
192
    if (Traversal == TK_IgnoreUnlessSpelledInSource && !Init->isWritten())
193
      return;
194
    getNodeDelegate().AddChild([=] {
195
      getNodeDelegate().Visit(Init);
196
      Visit(Init->getInit());
197
    });
198
  }
199
 
200
  void Visit(const TemplateArgument &A, SourceRange R = {},
201
             const Decl *From = nullptr, const char *Label = nullptr) {
202
    getNodeDelegate().AddChild([=] {
203
      getNodeDelegate().Visit(A, R, From, Label);
204
      ConstTemplateArgumentVisitor<Derived>::Visit(A);
205
    });
206
  }
207
 
208
  void Visit(const BlockDecl::Capture &C) {
209
    getNodeDelegate().AddChild([=] {
210
      getNodeDelegate().Visit(C);
211
      if (C.hasCopyExpr())
212
        Visit(C.getCopyExpr());
213
    });
214
  }
215
 
216
  void Visit(const OMPClause *C) {
217
    getNodeDelegate().AddChild([=] {
218
      getNodeDelegate().Visit(C);
219
      for (const auto *S : C->children())
220
        Visit(S);
221
    });
222
  }
223
 
224
  void Visit(const GenericSelectionExpr::ConstAssociation &A) {
225
    getNodeDelegate().AddChild([=] {
226
      getNodeDelegate().Visit(A);
227
      if (const TypeSourceInfo *TSI = A.getTypeSourceInfo())
228
        Visit(TSI->getType());
229
      Visit(A.getAssociationExpr());
230
    });
231
  }
232
 
233
  void Visit(const concepts::Requirement *R) {
234
    getNodeDelegate().AddChild([=] {
235
      getNodeDelegate().Visit(R);
236
      if (!R)
237
        return;
238
      if (auto *TR = dyn_cast<concepts::TypeRequirement>(R)) {
239
        if (!TR->isSubstitutionFailure())
240
          Visit(TR->getType()->getType().getTypePtr());
241
      } else if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) {
242
        if (!ER->isExprSubstitutionFailure())
243
          Visit(ER->getExpr());
244
        if (!ER->getReturnTypeRequirement().isEmpty())
245
          Visit(ER->getReturnTypeRequirement()
246
                    .getTypeConstraint()
247
                    ->getImmediatelyDeclaredConstraint());
248
      } else if (auto *NR = dyn_cast<concepts::NestedRequirement>(R)) {
249
        if (!NR->hasInvalidConstraint())
250
          Visit(NR->getConstraintExpr());
251
      }
252
    });
253
  }
254
 
255
  void Visit(const APValue &Value, QualType Ty) {
256
    getNodeDelegate().AddChild([=] { getNodeDelegate().Visit(Value, Ty); });
257
  }
258
 
259
  void Visit(const comments::Comment *C, const comments::FullComment *FC) {
260
    getNodeDelegate().AddChild([=] {
261
      getNodeDelegate().Visit(C, FC);
262
      if (!C) {
263
        return;
264
      }
265
      comments::ConstCommentVisitor<Derived, void,
266
                                    const comments::FullComment *>::visit(C,
267
                                                                          FC);
268
      for (comments::Comment::child_iterator I = C->child_begin(),
269
                                             E = C->child_end();
270
           I != E; ++I)
271
        Visit(*I, FC);
272
    });
273
  }
274
 
275
  void Visit(const DynTypedNode &N) {
276
    // FIXME: Improve this with a switch or a visitor pattern.
277
    if (const auto *D = N.get<Decl>())
278
      Visit(D);
279
    else if (const auto *S = N.get<Stmt>())
280
      Visit(S);
281
    else if (const auto *QT = N.get<QualType>())
282
      Visit(*QT);
283
    else if (const auto *T = N.get<Type>())
284
      Visit(T);
285
    else if (const auto *C = N.get<CXXCtorInitializer>())
286
      Visit(C);
287
    else if (const auto *C = N.get<OMPClause>())
288
      Visit(C);
289
    else if (const auto *T = N.get<TemplateArgument>())
290
      Visit(*T);
291
  }
292
 
293
  void dumpDeclContext(const DeclContext *DC) {
294
    if (!DC)
295
      return;
296
 
297
    for (const auto *D : (Deserialize ? DC->decls() : DC->noload_decls()))
298
      Visit(D);
299
  }
300
 
301
  void dumpTemplateParameters(const TemplateParameterList *TPL) {
302
    if (!TPL)
303
      return;
304
 
305
    for (const auto &TP : *TPL)
306
      Visit(TP);
307
 
308
    if (const Expr *RC = TPL->getRequiresClause())
309
      Visit(RC);
310
  }
311
 
312
  void
313
  dumpASTTemplateArgumentListInfo(const ASTTemplateArgumentListInfo *TALI) {
314
    if (!TALI)
315
      return;
316
 
317
    for (const auto &TA : TALI->arguments())
318
      dumpTemplateArgumentLoc(TA);
319
  }
320
 
321
  void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A,
322
                               const Decl *From = nullptr,
323
                               const char *Label = nullptr) {
324
    Visit(A.getArgument(), A.getSourceRange(), From, Label);
325
  }
326
 
327
  void dumpTemplateArgumentList(const TemplateArgumentList &TAL) {
328
    for (unsigned i = 0, e = TAL.size(); i < e; ++i)
329
      Visit(TAL[i]);
330
  }
331
 
332
  void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) {
333
    if (!typeParams)
334
      return;
335
 
336
    for (const auto &typeParam : *typeParams) {
337
      Visit(typeParam);
338
    }
339
  }
340
 
341
  void VisitComplexType(const ComplexType *T) { Visit(T->getElementType()); }
342
  void VisitLocInfoType(const LocInfoType *T) {
343
    Visit(T->getTypeSourceInfo()->getType());
344
  }
345
  void VisitPointerType(const PointerType *T) { Visit(T->getPointeeType()); }
346
  void VisitBlockPointerType(const BlockPointerType *T) {
347
    Visit(T->getPointeeType());
348
  }
349
  void VisitReferenceType(const ReferenceType *T) {
350
    Visit(T->getPointeeType());
351
  }
352
  void VisitMemberPointerType(const MemberPointerType *T) {
353
    Visit(T->getClass());
354
    Visit(T->getPointeeType());
355
  }
356
  void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
357
  void VisitVariableArrayType(const VariableArrayType *T) {
358
    VisitArrayType(T);
359
    Visit(T->getSizeExpr());
360
  }
361
  void VisitDependentSizedArrayType(const DependentSizedArrayType *T) {
362
    Visit(T->getElementType());
363
    Visit(T->getSizeExpr());
364
  }
365
  void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T) {
366
    Visit(T->getElementType());
367
    Visit(T->getSizeExpr());
368
  }
369
  void VisitVectorType(const VectorType *T) { Visit(T->getElementType()); }
370
  void VisitFunctionType(const FunctionType *T) { Visit(T->getReturnType()); }
371
  void VisitFunctionProtoType(const FunctionProtoType *T) {
372
    VisitFunctionType(T);
373
    for (const QualType &PT : T->getParamTypes())
374
      Visit(PT);
375
  }
376
  void VisitTypeOfExprType(const TypeOfExprType *T) {
377
    Visit(T->getUnderlyingExpr());
378
  }
379
  void VisitDecltypeType(const DecltypeType *T) {
380
    Visit(T->getUnderlyingExpr());
381
  }
382
  void VisitUnaryTransformType(const UnaryTransformType *T) {
383
    Visit(T->getBaseType());
384
  }
385
  void VisitAttributedType(const AttributedType *T) {
386
    // FIXME: AttrKind
387
    Visit(T->getModifiedType());
388
  }
389
  void VisitBTFTagAttributedType(const BTFTagAttributedType *T) {
390
    Visit(T->getWrappedType());
391
  }
392
  void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *) {}
393
  void
394
  VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T) {
395
    Visit(T->getArgumentPack());
396
  }
397
  void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
398
    for (const auto &Arg : T->template_arguments())
399
      Visit(Arg);
400
  }
401
  void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) {
402
    Visit(T->getPointeeType());
403
  }
404
  void VisitAtomicType(const AtomicType *T) { Visit(T->getValueType()); }
405
  void VisitPipeType(const PipeType *T) { Visit(T->getElementType()); }
406
  void VisitAdjustedType(const AdjustedType *T) { Visit(T->getOriginalType()); }
407
  void VisitPackExpansionType(const PackExpansionType *T) {
408
    if (!T->isSugared())
409
      Visit(T->getPattern());
410
  }
411
  // FIXME: ElaboratedType, DependentNameType,
412
  // DependentTemplateSpecializationType, ObjCObjectType
413
 
414
  void VisitTypedefDecl(const TypedefDecl *D) { Visit(D->getUnderlyingType()); }
415
 
416
  void VisitEnumConstantDecl(const EnumConstantDecl *D) {
417
    if (const Expr *Init = D->getInitExpr())
418
      Visit(Init);
419
  }
420
 
421
  void VisitFunctionDecl(const FunctionDecl *D) {
422
    if (const auto *FTSI = D->getTemplateSpecializationInfo())
423
      dumpTemplateArgumentList(*FTSI->TemplateArguments);
424
 
425
    if (D->param_begin())
426
      for (const auto *Parameter : D->parameters())
427
        Visit(Parameter);
428
 
429
    if (const Expr *TRC = D->getTrailingRequiresClause())
430
      Visit(TRC);
431
 
432
    if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isDefaulted())
433
      return;
434
 
435
    if (const auto *C = dyn_cast<CXXConstructorDecl>(D))
436
      for (const auto *I : C->inits())
437
        Visit(I);
438
 
439
    if (D->doesThisDeclarationHaveABody())
440
      Visit(D->getBody());
441
  }
442
 
443
  void VisitFieldDecl(const FieldDecl *D) {
444
    if (D->isBitField())
445
      Visit(D->getBitWidth());
446
    if (Expr *Init = D->getInClassInitializer())
447
      Visit(Init);
448
  }
449
 
450
  void VisitVarDecl(const VarDecl *D) {
451
    if (Traversal == TK_IgnoreUnlessSpelledInSource && D->isCXXForRangeDecl())
452
      return;
453
 
454
    if (D->hasInit())
455
      Visit(D->getInit());
456
  }
457
 
458
  void VisitDecompositionDecl(const DecompositionDecl *D) {
459
    VisitVarDecl(D);
460
    for (const auto *B : D->bindings())
461
      Visit(B);
462
  }
463
 
464
  void VisitBindingDecl(const BindingDecl *D) {
465
    if (Traversal == TK_IgnoreUnlessSpelledInSource)
466
      return;
467
 
468
    if (const auto *V = D->getHoldingVar())
469
      Visit(V);
470
 
471
    if (const auto *E = D->getBinding())
472
      Visit(E);
473
  }
474
 
475
  void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) {
476
    Visit(D->getAsmString());
477
  }
478
 
479
  void VisitTopLevelStmtDecl(const TopLevelStmtDecl *D) { Visit(D->getStmt()); }
480
 
481
  void VisitCapturedDecl(const CapturedDecl *D) { Visit(D->getBody()); }
482
 
483
  void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) {
484
    for (const auto *E : D->varlists())
485
      Visit(E);
486
  }
487
 
488
  void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) {
489
    Visit(D->getCombiner());
490
    if (const auto *Initializer = D->getInitializer())
491
      Visit(Initializer);
492
  }
493
 
494
  void VisitOMPDeclareMapperDecl(const OMPDeclareMapperDecl *D) {
495
    for (const auto *C : D->clauselists())
496
      Visit(C);
497
  }
498
 
499
  void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) {
500
    Visit(D->getInit());
501
  }
502
 
503
  void VisitOMPAllocateDecl(const OMPAllocateDecl *D) {
504
    for (const auto *E : D->varlists())
505
      Visit(E);
506
    for (const auto *C : D->clauselists())
507
      Visit(C);
508
  }
509
 
510
  template <typename SpecializationDecl>
511
  void dumpTemplateDeclSpecialization(const SpecializationDecl *D) {
512
    for (const auto *RedeclWithBadType : D->redecls()) {
513
      // FIXME: The redecls() range sometimes has elements of a less-specific
514
      // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
515
      // us TagDecls, and should give CXXRecordDecls).
516
      auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
517
      if (!Redecl) {
518
        // Found the injected-class-name for a class template. This will be
519
        // dumped as part of its surrounding class so we don't need to dump it
520
        // here.
521
        assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
522
               "expected an injected-class-name");
523
        continue;
524
      }
525
      Visit(Redecl);
526
    }
527
  }
528
 
529
  template <typename TemplateDecl>
530
  void dumpTemplateDecl(const TemplateDecl *D) {
531
    dumpTemplateParameters(D->getTemplateParameters());
532
 
533
    Visit(D->getTemplatedDecl());
534
 
535
    if (Traversal == TK_AsIs) {
536
      for (const auto *Child : D->specializations())
537
        dumpTemplateDeclSpecialization(Child);
538
    }
539
  }
540
 
541
  void VisitTypeAliasDecl(const TypeAliasDecl *D) {
542
    Visit(D->getUnderlyingType());
543
  }
544
 
545
  void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) {
546
    dumpTemplateParameters(D->getTemplateParameters());
547
    Visit(D->getTemplatedDecl());
548
  }
549
 
550
  void VisitStaticAssertDecl(const StaticAssertDecl *D) {
551
    Visit(D->getAssertExpr());
552
    Visit(D->getMessage());
553
  }
554
 
555
  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
556
    dumpTemplateDecl(D);
557
  }
558
 
559
  void VisitClassTemplateDecl(const ClassTemplateDecl *D) {
560
    dumpTemplateDecl(D);
561
  }
562
 
563
  void VisitClassTemplateSpecializationDecl(
564
      const ClassTemplateSpecializationDecl *D) {
565
    dumpTemplateArgumentList(D->getTemplateArgs());
566
  }
567
 
568
  void VisitClassTemplatePartialSpecializationDecl(
569
      const ClassTemplatePartialSpecializationDecl *D) {
570
    VisitClassTemplateSpecializationDecl(D);
571
    dumpTemplateParameters(D->getTemplateParameters());
572
  }
573
 
574
  void VisitClassScopeFunctionSpecializationDecl(
575
      const ClassScopeFunctionSpecializationDecl *D) {
576
    Visit(D->getSpecialization());
577
    dumpASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
578
  }
579
  void VisitVarTemplateDecl(const VarTemplateDecl *D) { dumpTemplateDecl(D); }
580
 
581
  void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) {
582
    dumpTemplateParameters(D->getTemplateParameters());
583
  }
584
 
585
  void
586
  VisitVarTemplateSpecializationDecl(const VarTemplateSpecializationDecl *D) {
587
    dumpTemplateArgumentList(D->getTemplateArgs());
588
    VisitVarDecl(D);
589
  }
590
 
591
  void VisitVarTemplatePartialSpecializationDecl(
592
      const VarTemplatePartialSpecializationDecl *D) {
593
    dumpTemplateParameters(D->getTemplateParameters());
594
    VisitVarTemplateSpecializationDecl(D);
595
  }
596
 
597
  void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) {
598
    if (const auto *TC = D->getTypeConstraint())
599
      Visit(TC->getImmediatelyDeclaredConstraint());
600
    if (D->hasDefaultArgument())
601
      Visit(D->getDefaultArgument(), SourceRange(),
602
            D->getDefaultArgStorage().getInheritedFrom(),
603
            D->defaultArgumentWasInherited() ? "inherited from" : "previous");
604
  }
605
 
606
  void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) {
607
    if (const auto *E = D->getPlaceholderTypeConstraint())
608
      Visit(E);
609
    if (D->hasDefaultArgument())
610
      Visit(D->getDefaultArgument(), SourceRange(),
611
            D->getDefaultArgStorage().getInheritedFrom(),
612
            D->defaultArgumentWasInherited() ? "inherited from" : "previous");
613
  }
614
 
615
  void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D) {
616
    dumpTemplateParameters(D->getTemplateParameters());
617
    if (D->hasDefaultArgument())
618
      dumpTemplateArgumentLoc(
619
          D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(),
620
          D->defaultArgumentWasInherited() ? "inherited from" : "previous");
621
  }
622
 
623
  void VisitConceptDecl(const ConceptDecl *D) {
624
    dumpTemplateParameters(D->getTemplateParameters());
625
    Visit(D->getConstraintExpr());
626
  }
627
 
628
  void VisitImplicitConceptSpecializationDecl(
629
      const ImplicitConceptSpecializationDecl *CSD) {
630
    for (const TemplateArgument &Arg : CSD->getTemplateArguments())
631
      Visit(Arg);
632
  }
633
 
634
  void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *CSE) {
635
    Visit(CSE->getSpecializationDecl());
636
    if (CSE->hasExplicitTemplateArgs())
637
      for (const auto &ArgLoc : CSE->getTemplateArgsAsWritten()->arguments())
638
        dumpTemplateArgumentLoc(ArgLoc);
639
  }
640
 
641
  void VisitUsingShadowDecl(const UsingShadowDecl *D) {
642
    if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
643
      Visit(TD->getTypeForDecl());
644
  }
645
 
646
  void VisitFriendDecl(const FriendDecl *D) {
647
    if (D->getFriendType()) {
648
      // Traverse any CXXRecordDecl owned by this type, since
649
      // it will not be in the parent context:
650
      if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
651
        if (auto *TD = ET->getOwnedTagDecl())
652
          Visit(TD);
653
    } else {
654
      Visit(D->getFriendDecl());
655
    }
656
  }
657
 
658
  void VisitObjCMethodDecl(const ObjCMethodDecl *D) {
659
    if (D->isThisDeclarationADefinition())
660
      dumpDeclContext(D);
661
    else
662
      for (const ParmVarDecl *Parameter : D->parameters())
663
        Visit(Parameter);
664
 
665
    if (D->hasBody())
666
      Visit(D->getBody());
667
  }
668
 
669
  void VisitObjCCategoryDecl(const ObjCCategoryDecl *D) {
670
    dumpObjCTypeParamList(D->getTypeParamList());
671
  }
672
 
673
  void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) {
674
    dumpObjCTypeParamList(D->getTypeParamListAsWritten());
675
  }
676
 
677
  void VisitObjCImplementationDecl(const ObjCImplementationDecl *D) {
678
    for (const auto &I : D->inits())
679
      Visit(I);
680
  }
681
 
682
  void VisitBlockDecl(const BlockDecl *D) {
683
    for (const auto &I : D->parameters())
684
      Visit(I);
685
 
686
    for (const auto &I : D->captures())
687
      Visit(I);
688
    Visit(D->getBody());
689
  }
690
 
691
  void VisitDeclStmt(const DeclStmt *Node) {
692
    for (const auto &D : Node->decls())
693
      Visit(D);
694
  }
695
 
696
  void VisitAttributedStmt(const AttributedStmt *Node) {
697
    for (const auto *A : Node->getAttrs())
698
      Visit(A);
699
  }
700
 
701
  void VisitCXXCatchStmt(const CXXCatchStmt *Node) {
702
    Visit(Node->getExceptionDecl());
703
  }
704
 
705
  void VisitCapturedStmt(const CapturedStmt *Node) {
706
    Visit(Node->getCapturedDecl());
707
  }
708
 
709
  void VisitOMPExecutableDirective(const OMPExecutableDirective *Node) {
710
    for (const auto *C : Node->clauses())
711
      Visit(C);
712
  }
713
 
714
  void VisitInitListExpr(const InitListExpr *ILE) {
715
    if (auto *Filler = ILE->getArrayFiller()) {
716
      Visit(Filler, "array_filler");
717
    }
718
  }
719
 
720
  void VisitCXXParenListInitExpr(const CXXParenListInitExpr *PLIE) {
721
    if (auto *Filler = PLIE->getArrayFiller()) {
722
      Visit(Filler, "array_filler");
723
    }
724
  }
725
 
726
  void VisitBlockExpr(const BlockExpr *Node) { Visit(Node->getBlockDecl()); }
727
 
728
  void VisitOpaqueValueExpr(const OpaqueValueExpr *Node) {
729
    if (Expr *Source = Node->getSourceExpr())
730
      Visit(Source);
731
  }
732
 
733
  void VisitGenericSelectionExpr(const GenericSelectionExpr *E) {
734
    Visit(E->getControllingExpr());
735
    Visit(E->getControllingExpr()->getType()); // FIXME: remove
736
 
737
    for (const auto Assoc : E->associations()) {
738
      Visit(Assoc);
739
    }
740
  }
741
 
742
  void VisitRequiresExpr(const RequiresExpr *E) {
743
    for (auto *D : E->getLocalParameters())
744
      Visit(D);
745
    for (auto *R : E->getRequirements())
746
      Visit(R);
747
  }
748
 
749
  void VisitLambdaExpr(const LambdaExpr *Node) {
750
    if (Traversal == TK_IgnoreUnlessSpelledInSource) {
751
      for (unsigned I = 0, N = Node->capture_size(); I != N; ++I) {
752
        const auto *C = Node->capture_begin() + I;
753
        if (!C->isExplicit())
754
          continue;
755
        if (Node->isInitCapture(C))
756
          Visit(C->getCapturedVar());
757
        else
758
          Visit(Node->capture_init_begin()[I]);
759
      }
760
      dumpTemplateParameters(Node->getTemplateParameterList());
761
      for (const auto *P : Node->getCallOperator()->parameters())
762
        Visit(P);
763
      Visit(Node->getBody());
764
    } else {
765
      return Visit(Node->getLambdaClass());
766
    }
767
  }
768
 
769
  void VisitSizeOfPackExpr(const SizeOfPackExpr *Node) {
770
    if (Node->isPartiallySubstituted())
771
      for (const auto &A : Node->getPartialArguments())
772
        Visit(A);
773
  }
774
 
775
  void VisitSubstNonTypeTemplateParmExpr(const SubstNonTypeTemplateParmExpr *E) {
776
    Visit(E->getParameter());
777
  }
778
  void VisitSubstNonTypeTemplateParmPackExpr(
779
      const SubstNonTypeTemplateParmPackExpr *E) {
780
    Visit(E->getParameterPack());
781
    Visit(E->getArgumentPack());
782
  }
783
 
784
  void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) {
785
    if (const VarDecl *CatchParam = Node->getCatchParamDecl())
786
      Visit(CatchParam);
787
  }
788
 
789
  void VisitCXXForRangeStmt(const CXXForRangeStmt *Node) {
790
    if (Traversal == TK_IgnoreUnlessSpelledInSource) {
791
      Visit(Node->getInit());
792
      Visit(Node->getLoopVariable());
793
      Visit(Node->getRangeInit());
794
      Visit(Node->getBody());
795
    }
796
  }
797
 
798
  void VisitCallExpr(const CallExpr *Node) {
799
    for (const auto *Child :
800
         make_filter_range(Node->children(), [this](const Stmt *Child) {
801
           if (Traversal != TK_IgnoreUnlessSpelledInSource)
802
             return false;
803
           return !isa<CXXDefaultArgExpr>(Child);
804
         })) {
805
      Visit(Child);
806
    }
807
  }
808
 
809
  void VisitCXXRewrittenBinaryOperator(const CXXRewrittenBinaryOperator *Node) {
810
    if (Traversal == TK_IgnoreUnlessSpelledInSource) {
811
      Visit(Node->getLHS());
812
      Visit(Node->getRHS());
813
    } else {
814
      ConstStmtVisitor<Derived>::VisitCXXRewrittenBinaryOperator(Node);
815
    }
816
  }
817
 
818
  void VisitExpressionTemplateArgument(const TemplateArgument &TA) {
819
    Visit(TA.getAsExpr());
820
  }
821
 
822
  void VisitTypeTemplateArgument(const TemplateArgument &TA) {
823
    Visit(TA.getAsType());
824
  }
825
 
826
  void VisitPackTemplateArgument(const TemplateArgument &TA) {
827
    for (const auto &TArg : TA.pack_elements())
828
      Visit(TArg);
829
  }
830
 
831
  // Implements Visit methods for Attrs.
832
#include "clang/AST/AttrNodeTraverse.inc"
833
};
834
 
835
} // namespace clang
836
 
837
#endif // LLVM_CLANG_AST_ASTNODETRAVERSER_H