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