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