TextNodeDumper.h revision 360784
1//===--- TextNodeDumper.h - Printing 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 AST dumping of components of individual AST nodes.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_CLANG_AST_TEXTNODEDUMPER_H
14#define LLVM_CLANG_AST_TEXTNODEDUMPER_H
15
16#include "clang/AST/ASTContext.h"
17#include "clang/AST/ASTDumperUtils.h"
18#include "clang/AST/AttrVisitor.h"
19#include "clang/AST/CommentCommandTraits.h"
20#include "clang/AST/CommentVisitor.h"
21#include "clang/AST/DeclVisitor.h"
22#include "clang/AST/ExprCXX.h"
23#include "clang/AST/StmtVisitor.h"
24#include "clang/AST/TemplateArgumentVisitor.h"
25#include "clang/AST/TypeVisitor.h"
26
27namespace clang {
28
29class TextTreeStructure {
30  raw_ostream &OS;
31  const bool ShowColors;
32
33  /// Pending[i] is an action to dump an entity at level i.
34  llvm::SmallVector<std::function<void(bool IsLastChild)>, 32> Pending;
35
36  /// Indicates whether we're at the top level.
37  bool TopLevel = true;
38
39  /// Indicates if we're handling the first child after entering a new depth.
40  bool FirstChild = true;
41
42  /// Prefix for currently-being-dumped entity.
43  std::string Prefix;
44
45public:
46  /// Add a child of the current node.  Calls DoAddChild without arguments
47  template <typename Fn> void AddChild(Fn DoAddChild) {
48    return AddChild("", DoAddChild);
49  }
50
51  /// Add a child of the current node with an optional label.
52  /// Calls DoAddChild without arguments.
53  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
54    // If we're at the top level, there's nothing interesting to do; just
55    // run the dumper.
56    if (TopLevel) {
57      TopLevel = false;
58      DoAddChild();
59      while (!Pending.empty()) {
60        Pending.back()(true);
61        Pending.pop_back();
62      }
63      Prefix.clear();
64      OS << "\n";
65      TopLevel = true;
66      return;
67    }
68
69    // We need to capture an owning-string in the lambda because the lambda
70    // is invoked in a deferred manner.
71    std::string LabelStr = Label;
72    auto DumpWithIndent = [this, DoAddChild, LabelStr](bool IsLastChild) {
73      // Print out the appropriate tree structure and work out the prefix for
74      // children of this node. For instance:
75      //
76      //   A        Prefix = ""
77      //   |-B      Prefix = "| "
78      //   | `-C    Prefix = "|   "
79      //   `-D      Prefix = "  "
80      //     |-E    Prefix = "  | "
81      //     `-F    Prefix = "    "
82      //   G        Prefix = ""
83      //
84      // Note that the first level gets no prefix.
85      {
86        OS << '\n';
87        ColorScope Color(OS, ShowColors, IndentColor);
88        OS << Prefix << (IsLastChild ? '`' : '|') << '-';
89        if (!LabelStr.empty())
90          OS << LabelStr << ": ";
91
92        this->Prefix.push_back(IsLastChild ? ' ' : '|');
93        this->Prefix.push_back(' ');
94      }
95
96      FirstChild = true;
97      unsigned Depth = Pending.size();
98
99      DoAddChild();
100
101      // If any children are left, they're the last at their nesting level.
102      // Dump those ones out now.
103      while (Depth < Pending.size()) {
104        Pending.back()(true);
105        this->Pending.pop_back();
106      }
107
108      // Restore the old prefix.
109      this->Prefix.resize(Prefix.size() - 2);
110    };
111
112    if (FirstChild) {
113      Pending.push_back(std::move(DumpWithIndent));
114    } else {
115      Pending.back()(false);
116      Pending.back() = std::move(DumpWithIndent);
117    }
118    FirstChild = false;
119  }
120
121  TextTreeStructure(raw_ostream &OS, bool ShowColors)
122      : OS(OS), ShowColors(ShowColors) {}
123};
124
125class TextNodeDumper
126    : public TextTreeStructure,
127      public comments::ConstCommentVisitor<TextNodeDumper, void,
128                                           const comments::FullComment *>,
129      public ConstAttrVisitor<TextNodeDumper>,
130      public ConstTemplateArgumentVisitor<TextNodeDumper>,
131      public ConstStmtVisitor<TextNodeDumper>,
132      public TypeVisitor<TextNodeDumper>,
133      public ConstDeclVisitor<TextNodeDumper> {
134  raw_ostream &OS;
135  const bool ShowColors;
136
137  /// Keep track of the last location we print out so that we can
138  /// print out deltas from then on out.
139  const char *LastLocFilename = "";
140  unsigned LastLocLine = ~0U;
141
142  const SourceManager *SM;
143
144  /// The policy to use for printing; can be defaulted.
145  PrintingPolicy PrintPolicy;
146
147  const comments::CommandTraits *Traits;
148
149  const char *getCommandName(unsigned CommandID);
150
151public:
152  TextNodeDumper(raw_ostream &OS, bool ShowColors, const SourceManager *SM,
153                 const PrintingPolicy &PrintPolicy,
154                 const comments::CommandTraits *Traits);
155
156  void Visit(const comments::Comment *C, const comments::FullComment *FC);
157
158  void Visit(const Attr *A);
159
160  void Visit(const TemplateArgument &TA, SourceRange R,
161             const Decl *From = nullptr, StringRef Label = {});
162
163  void Visit(const Stmt *Node);
164
165  void Visit(const Type *T);
166
167  void Visit(QualType T);
168
169  void Visit(const Decl *D);
170
171  void Visit(const CXXCtorInitializer *Init);
172
173  void Visit(const OMPClause *C);
174
175  void Visit(const BlockDecl::Capture &C);
176
177  void Visit(const GenericSelectionExpr::ConstAssociation &A);
178
179  void dumpPointer(const void *Ptr);
180  void dumpLocation(SourceLocation Loc);
181  void dumpSourceRange(SourceRange R);
182  void dumpBareType(QualType T, bool Desugar = true);
183  void dumpType(QualType T);
184  void dumpBareDeclRef(const Decl *D);
185  void dumpName(const NamedDecl *ND);
186  void dumpAccessSpecifier(AccessSpecifier AS);
187
188  void dumpDeclRef(const Decl *D, StringRef Label = {});
189
190  void visitTextComment(const comments::TextComment *C,
191                        const comments::FullComment *);
192  void visitInlineCommandComment(const comments::InlineCommandComment *C,
193                                 const comments::FullComment *);
194  void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C,
195                                const comments::FullComment *);
196  void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C,
197                              const comments::FullComment *);
198  void visitBlockCommandComment(const comments::BlockCommandComment *C,
199                                const comments::FullComment *);
200  void visitParamCommandComment(const comments::ParamCommandComment *C,
201                                const comments::FullComment *FC);
202  void visitTParamCommandComment(const comments::TParamCommandComment *C,
203                                 const comments::FullComment *FC);
204  void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C,
205                                 const comments::FullComment *);
206  void
207  visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C,
208                                const comments::FullComment *);
209  void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
210                                const comments::FullComment *);
211
212// Implements Visit methods for Attrs.
213#include "clang/AST/AttrTextNodeDump.inc"
214
215  void VisitNullTemplateArgument(const TemplateArgument &TA);
216  void VisitTypeTemplateArgument(const TemplateArgument &TA);
217  void VisitDeclarationTemplateArgument(const TemplateArgument &TA);
218  void VisitNullPtrTemplateArgument(const TemplateArgument &TA);
219  void VisitIntegralTemplateArgument(const TemplateArgument &TA);
220  void VisitTemplateTemplateArgument(const TemplateArgument &TA);
221  void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA);
222  void VisitExpressionTemplateArgument(const TemplateArgument &TA);
223  void VisitPackTemplateArgument(const TemplateArgument &TA);
224
225  void VisitIfStmt(const IfStmt *Node);
226  void VisitSwitchStmt(const SwitchStmt *Node);
227  void VisitWhileStmt(const WhileStmt *Node);
228  void VisitLabelStmt(const LabelStmt *Node);
229  void VisitGotoStmt(const GotoStmt *Node);
230  void VisitCaseStmt(const CaseStmt *Node);
231  void VisitConstantExpr(const ConstantExpr *Node);
232  void VisitCallExpr(const CallExpr *Node);
233  void VisitCastExpr(const CastExpr *Node);
234  void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
235  void VisitDeclRefExpr(const DeclRefExpr *Node);
236  void VisitPredefinedExpr(const PredefinedExpr *Node);
237  void VisitCharacterLiteral(const CharacterLiteral *Node);
238  void VisitIntegerLiteral(const IntegerLiteral *Node);
239  void VisitFixedPointLiteral(const FixedPointLiteral *Node);
240  void VisitFloatingLiteral(const FloatingLiteral *Node);
241  void VisitStringLiteral(const StringLiteral *Str);
242  void VisitInitListExpr(const InitListExpr *ILE);
243  void VisitGenericSelectionExpr(const GenericSelectionExpr *E);
244  void VisitUnaryOperator(const UnaryOperator *Node);
245  void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
246  void VisitMemberExpr(const MemberExpr *Node);
247  void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
248  void VisitBinaryOperator(const BinaryOperator *Node);
249  void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
250  void VisitAddrLabelExpr(const AddrLabelExpr *Node);
251  void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
252  void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
253  void VisitCXXThisExpr(const CXXThisExpr *Node);
254  void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
255  void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node);
256  void VisitCXXConstructExpr(const CXXConstructExpr *Node);
257  void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
258  void VisitCXXNewExpr(const CXXNewExpr *Node);
259  void VisitCXXDeleteExpr(const CXXDeleteExpr *Node);
260  void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
261  void VisitExprWithCleanups(const ExprWithCleanups *Node);
262  void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
263  void VisitSizeOfPackExpr(const SizeOfPackExpr *Node);
264  void
265  VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *Node);
266  void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
267  void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
268  void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
269  void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
270  void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
271  void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
272  void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
273  void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
274  void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
275  void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
276
277  void VisitRValueReferenceType(const ReferenceType *T);
278  void VisitArrayType(const ArrayType *T);
279  void VisitConstantArrayType(const ConstantArrayType *T);
280  void VisitVariableArrayType(const VariableArrayType *T);
281  void VisitDependentSizedArrayType(const DependentSizedArrayType *T);
282  void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T);
283  void VisitVectorType(const VectorType *T);
284  void VisitFunctionType(const FunctionType *T);
285  void VisitFunctionProtoType(const FunctionProtoType *T);
286  void VisitUnresolvedUsingType(const UnresolvedUsingType *T);
287  void VisitTypedefType(const TypedefType *T);
288  void VisitUnaryTransformType(const UnaryTransformType *T);
289  void VisitTagType(const TagType *T);
290  void VisitTemplateTypeParmType(const TemplateTypeParmType *T);
291  void VisitAutoType(const AutoType *T);
292  void VisitTemplateSpecializationType(const TemplateSpecializationType *T);
293  void VisitInjectedClassNameType(const InjectedClassNameType *T);
294  void VisitObjCInterfaceType(const ObjCInterfaceType *T);
295  void VisitPackExpansionType(const PackExpansionType *T);
296
297  void VisitLabelDecl(const LabelDecl *D);
298  void VisitTypedefDecl(const TypedefDecl *D);
299  void VisitEnumDecl(const EnumDecl *D);
300  void VisitRecordDecl(const RecordDecl *D);
301  void VisitEnumConstantDecl(const EnumConstantDecl *D);
302  void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
303  void VisitFunctionDecl(const FunctionDecl *D);
304  void VisitFieldDecl(const FieldDecl *D);
305  void VisitVarDecl(const VarDecl *D);
306  void VisitBindingDecl(const BindingDecl *D);
307  void VisitCapturedDecl(const CapturedDecl *D);
308  void VisitImportDecl(const ImportDecl *D);
309  void VisitPragmaCommentDecl(const PragmaCommentDecl *D);
310  void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D);
311  void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
312  void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D);
313  void VisitOMPRequiresDecl(const OMPRequiresDecl *D);
314  void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D);
315  void VisitNamespaceDecl(const NamespaceDecl *D);
316  void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
317  void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
318  void VisitTypeAliasDecl(const TypeAliasDecl *D);
319  void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
320  void VisitCXXRecordDecl(const CXXRecordDecl *D);
321  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
322  void VisitClassTemplateDecl(const ClassTemplateDecl *D);
323  void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D);
324  void VisitVarTemplateDecl(const VarTemplateDecl *D);
325  void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
326  void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
327  void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
328  void VisitUsingDecl(const UsingDecl *D);
329  void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
330  void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
331  void VisitUsingShadowDecl(const UsingShadowDecl *D);
332  void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D);
333  void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
334  void VisitAccessSpecDecl(const AccessSpecDecl *D);
335  void VisitFriendDecl(const FriendDecl *D);
336  void VisitObjCIvarDecl(const ObjCIvarDecl *D);
337  void VisitObjCMethodDecl(const ObjCMethodDecl *D);
338  void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
339  void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
340  void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
341  void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
342  void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
343  void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
344  void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
345  void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
346  void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
347  void VisitBlockDecl(const BlockDecl *D);
348  void VisitConceptDecl(const ConceptDecl *D);
349  void
350  VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D);
351};
352
353} // namespace clang
354
355#endif // LLVM_CLANG_AST_TEXTNODEDUMPER_H
356