summaryrefslogtreecommitdiff
path: root/include/clang/AST/TextNodeDumper.h
blob: 0ff5a614a864d773c0ecf0fbf029d59771ac402a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
//===--- TextNodeDumper.h - Printing of AST nodes -------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file implements AST dumping of components of individual AST nodes.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_TEXTNODEDUMPER_H
#define LLVM_CLANG_AST_TEXTNODEDUMPER_H

#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTDumperUtils.h"
#include "clang/AST/AttrVisitor.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/CommentVisitor.h"
#include "clang/AST/DeclVisitor.h"
#include "clang/AST/ExprCXX.h"
#include "clang/AST/StmtVisitor.h"
#include "clang/AST/TemplateArgumentVisitor.h"
#include "clang/AST/TypeVisitor.h"

namespace clang {

class TextTreeStructure {
  raw_ostream &OS;
  const bool ShowColors;

  /// Pending[i] is an action to dump an entity at level i.
  llvm::SmallVector<std::function<void(bool IsLastChild)>, 32> Pending;

  /// Indicates whether we're at the top level.
  bool TopLevel = true;

  /// Indicates if we're handling the first child after entering a new depth.
  bool FirstChild = true;

  /// Prefix for currently-being-dumped entity.
  std::string Prefix;

public:
  /// Add a child of the current node.  Calls DoAddChild without arguments
  template <typename Fn> void AddChild(Fn DoAddChild) {
    return AddChild("", DoAddChild);
  }

  /// Add a child of the current node with an optional label.
  /// Calls DoAddChild without arguments.
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
    // If we're at the top level, there's nothing interesting to do; just
    // run the dumper.
    if (TopLevel) {
      TopLevel = false;
      DoAddChild();
      while (!Pending.empty()) {
        Pending.back()(true);
        Pending.pop_back();
      }
      Prefix.clear();
      OS << "\n";
      TopLevel = true;
      return;
    }

    // We need to capture an owning-string in the lambda because the lambda
    // is invoked in a deferred manner.
    std::string LabelStr = Label;
    auto DumpWithIndent = [this, DoAddChild, LabelStr](bool IsLastChild) {
      // Print out the appropriate tree structure and work out the prefix for
      // children of this node. For instance:
      //
      //   A        Prefix = ""
      //   |-B      Prefix = "| "
      //   | `-C    Prefix = "|   "
      //   `-D      Prefix = "  "
      //     |-E    Prefix = "  | "
      //     `-F    Prefix = "    "
      //   G        Prefix = ""
      //
      // Note that the first level gets no prefix.
      {
        OS << '\n';
        ColorScope Color(OS, ShowColors, IndentColor);
        OS << Prefix << (IsLastChild ? '`' : '|') << '-';
        if (!LabelStr.empty())
          OS << LabelStr << ": ";

        this->Prefix.push_back(IsLastChild ? ' ' : '|');
        this->Prefix.push_back(' ');
      }

      FirstChild = true;
      unsigned Depth = Pending.size();

      DoAddChild();

      // If any children are left, they're the last at their nesting level.
      // Dump those ones out now.
      while (Depth < Pending.size()) {
        Pending.back()(true);
        this->Pending.pop_back();
      }

      // Restore the old prefix.
      this->Prefix.resize(Prefix.size() - 2);
    };

    if (FirstChild) {
      Pending.push_back(std::move(DumpWithIndent));
    } else {
      Pending.back()(false);
      Pending.back() = std::move(DumpWithIndent);
    }
    FirstChild = false;
  }

  TextTreeStructure(raw_ostream &OS, bool ShowColors)
      : OS(OS), ShowColors(ShowColors) {}
};

class TextNodeDumper
    : public TextTreeStructure,
      public comments::ConstCommentVisitor<TextNodeDumper, void,
                                           const comments::FullComment *>,
      public ConstAttrVisitor<TextNodeDumper>,
      public ConstTemplateArgumentVisitor<TextNodeDumper>,
      public ConstStmtVisitor<TextNodeDumper>,
      public TypeVisitor<TextNodeDumper>,
      public ConstDeclVisitor<TextNodeDumper> {
  raw_ostream &OS;
  const bool ShowColors;

  /// Keep track of the last location we print out so that we can
  /// print out deltas from then on out.
  const char *LastLocFilename = "";
  unsigned LastLocLine = ~0U;

  const SourceManager *SM;

  /// The policy to use for printing; can be defaulted.
  PrintingPolicy PrintPolicy;

  const comments::CommandTraits *Traits;

  const char *getCommandName(unsigned CommandID);

public:
  TextNodeDumper(raw_ostream &OS, bool ShowColors, const SourceManager *SM,
                 const PrintingPolicy &PrintPolicy,
                 const comments::CommandTraits *Traits);

  void Visit(const comments::Comment *C, const comments::FullComment *FC);

  void Visit(const Attr *A);

  void Visit(const TemplateArgument &TA, SourceRange R,
             const Decl *From = nullptr, StringRef Label = {});

  void Visit(const Stmt *Node);

  void Visit(const Type *T);

  void Visit(QualType T);

  void Visit(const Decl *D);

  void Visit(const CXXCtorInitializer *Init);

  void Visit(const OMPClause *C);

  void Visit(const BlockDecl::Capture &C);

  void Visit(const GenericSelectionExpr::ConstAssociation &A);

  void dumpPointer(const void *Ptr);
  void dumpLocation(SourceLocation Loc);
  void dumpSourceRange(SourceRange R);
  void dumpBareType(QualType T, bool Desugar = true);
  void dumpType(QualType T);
  void dumpBareDeclRef(const Decl *D);
  void dumpName(const NamedDecl *ND);
  void dumpAccessSpecifier(AccessSpecifier AS);

  void dumpDeclRef(const Decl *D, StringRef Label = {});

  void visitTextComment(const comments::TextComment *C,
                        const comments::FullComment *);
  void visitInlineCommandComment(const comments::InlineCommandComment *C,
                                 const comments::FullComment *);
  void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C,
                                const comments::FullComment *);
  void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C,
                              const comments::FullComment *);
  void visitBlockCommandComment(const comments::BlockCommandComment *C,
                                const comments::FullComment *);
  void visitParamCommandComment(const comments::ParamCommandComment *C,
                                const comments::FullComment *FC);
  void visitTParamCommandComment(const comments::TParamCommandComment *C,
                                 const comments::FullComment *FC);
  void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C,
                                 const comments::FullComment *);
  void
  visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C,
                                const comments::FullComment *);
  void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
                                const comments::FullComment *);

// Implements Visit methods for Attrs.
#include "clang/AST/AttrTextNodeDump.inc"

  void VisitNullTemplateArgument(const TemplateArgument &TA);
  void VisitTypeTemplateArgument(const TemplateArgument &TA);
  void VisitDeclarationTemplateArgument(const TemplateArgument &TA);
  void VisitNullPtrTemplateArgument(const TemplateArgument &TA);
  void VisitIntegralTemplateArgument(const TemplateArgument &TA);
  void VisitTemplateTemplateArgument(const TemplateArgument &TA);
  void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA);
  void VisitExpressionTemplateArgument(const TemplateArgument &TA);
  void VisitPackTemplateArgument(const TemplateArgument &TA);

  void VisitIfStmt(const IfStmt *Node);
  void VisitSwitchStmt(const SwitchStmt *Node);
  void VisitWhileStmt(const WhileStmt *Node);
  void VisitLabelStmt(const LabelStmt *Node);
  void VisitGotoStmt(const GotoStmt *Node);
  void VisitCaseStmt(const CaseStmt *Node);
  void VisitConstantExpr(const ConstantExpr *Node);
  void VisitCallExpr(const CallExpr *Node);
  void VisitCastExpr(const CastExpr *Node);
  void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
  void VisitDeclRefExpr(const DeclRefExpr *Node);
  void VisitPredefinedExpr(const PredefinedExpr *Node);
  void VisitCharacterLiteral(const CharacterLiteral *Node);
  void VisitIntegerLiteral(const IntegerLiteral *Node);
  void VisitFixedPointLiteral(const FixedPointLiteral *Node);
  void VisitFloatingLiteral(const FloatingLiteral *Node);
  void VisitStringLiteral(const StringLiteral *Str);
  void VisitInitListExpr(const InitListExpr *ILE);
  void VisitGenericSelectionExpr(const GenericSelectionExpr *E);
  void VisitUnaryOperator(const UnaryOperator *Node);
  void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
  void VisitMemberExpr(const MemberExpr *Node);
  void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
  void VisitBinaryOperator(const BinaryOperator *Node);
  void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
  void VisitAddrLabelExpr(const AddrLabelExpr *Node);
  void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
  void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
  void VisitCXXThisExpr(const CXXThisExpr *Node);
  void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
  void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node);
  void VisitCXXConstructExpr(const CXXConstructExpr *Node);
  void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
  void VisitCXXNewExpr(const CXXNewExpr *Node);
  void VisitCXXDeleteExpr(const CXXDeleteExpr *Node);
  void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
  void VisitExprWithCleanups(const ExprWithCleanups *Node);
  void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
  void VisitSizeOfPackExpr(const SizeOfPackExpr *Node);
  void
  VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *Node);
  void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
  void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
  void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
  void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
  void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
  void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
  void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
  void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
  void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
  void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);

  void VisitRValueReferenceType(const ReferenceType *T);
  void VisitArrayType(const ArrayType *T);
  void VisitConstantArrayType(const ConstantArrayType *T);
  void VisitVariableArrayType(const VariableArrayType *T);
  void VisitDependentSizedArrayType(const DependentSizedArrayType *T);
  void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T);
  void VisitVectorType(const VectorType *T);
  void VisitFunctionType(const FunctionType *T);
  void VisitFunctionProtoType(const FunctionProtoType *T);
  void VisitUnresolvedUsingType(const UnresolvedUsingType *T);
  void VisitTypedefType(const TypedefType *T);
  void VisitUnaryTransformType(const UnaryTransformType *T);
  void VisitTagType(const TagType *T);
  void VisitTemplateTypeParmType(const TemplateTypeParmType *T);
  void VisitAutoType(const AutoType *T);
  void VisitTemplateSpecializationType(const TemplateSpecializationType *T);
  void VisitInjectedClassNameType(const InjectedClassNameType *T);
  void VisitObjCInterfaceType(const ObjCInterfaceType *T);
  void VisitPackExpansionType(const PackExpansionType *T);

  void VisitLabelDecl(const LabelDecl *D);
  void VisitTypedefDecl(const TypedefDecl *D);
  void VisitEnumDecl(const EnumDecl *D);
  void VisitRecordDecl(const RecordDecl *D);
  void VisitEnumConstantDecl(const EnumConstantDecl *D);
  void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
  void VisitFunctionDecl(const FunctionDecl *D);
  void VisitFieldDecl(const FieldDecl *D);
  void VisitVarDecl(const VarDecl *D);
  void VisitBindingDecl(const BindingDecl *D);
  void VisitCapturedDecl(const CapturedDecl *D);
  void VisitImportDecl(const ImportDecl *D);
  void VisitPragmaCommentDecl(const PragmaCommentDecl *D);
  void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D);
  void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
  void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D);
  void VisitOMPRequiresDecl(const OMPRequiresDecl *D);
  void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D);
  void VisitNamespaceDecl(const NamespaceDecl *D);
  void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
  void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
  void VisitTypeAliasDecl(const TypeAliasDecl *D);
  void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
  void VisitCXXRecordDecl(const CXXRecordDecl *D);
  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
  void VisitClassTemplateDecl(const ClassTemplateDecl *D);
  void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D);
  void VisitVarTemplateDecl(const VarTemplateDecl *D);
  void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
  void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
  void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
  void VisitUsingDecl(const UsingDecl *D);
  void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
  void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
  void VisitUsingShadowDecl(const UsingShadowDecl *D);
  void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D);
  void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
  void VisitAccessSpecDecl(const AccessSpecDecl *D);
  void VisitFriendDecl(const FriendDecl *D);
  void VisitObjCIvarDecl(const ObjCIvarDecl *D);
  void VisitObjCMethodDecl(const ObjCMethodDecl *D);
  void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
  void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
  void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
  void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
  void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
  void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
  void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
  void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
  void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
  void VisitBlockDecl(const BlockDecl *D);
  void VisitConceptDecl(const ConceptDecl *D);
};

} // namespace clang

#endif // LLVM_CLANG_AST_TEXTNODEDUMPER_H