1 //===--- TextNodeDumper.h - Printing of AST nodes -------------------------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements AST dumping of components of individual AST nodes.
11 //===----------------------------------------------------------------------===//
13 #ifndef LLVM_CLANG_AST_TEXTNODEDUMPER_H
14 #define LLVM_CLANG_AST_TEXTNODEDUMPER_H
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/TypeVisitor.h"
33 class TextTreeStructure {
35 const bool ShowColors;
37 /// Pending[i] is an action to dump an entity at level i.
38 llvm::SmallVector<std::function<void(bool IsLastChild)>, 32> Pending;
40 /// Indicates whether we're at the top level.
43 /// Indicates if we're handling the first child after entering a new depth.
44 bool FirstChild = true;
46 /// Prefix for currently-being-dumped entity.
50 /// Add a child of the current node. Calls DoAddChild without arguments
51 template <typename Fn> void AddChild(Fn DoAddChild) {
52 return AddChild("", DoAddChild);
55 /// Add a child of the current node with an optional label.
56 /// Calls DoAddChild without arguments.
57 template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
58 // If we're at the top level, there's nothing interesting to do; just
63 while (!Pending.empty()) {
73 auto DumpWithIndent = [this, DoAddChild,
74 Label(Label.str())](bool IsLastChild) {
75 // Print out the appropriate tree structure and work out the prefix for
76 // children of this node. For instance:
80 // | `-C Prefix = "| "
86 // Note that the first level gets no prefix.
89 ColorScope Color(OS, ShowColors, IndentColor);
90 OS << Prefix << (IsLastChild ? '`' : '|') << '-';
94 this->Prefix.push_back(IsLastChild ? ' ' : '|');
95 this->Prefix.push_back(' ');
99 unsigned Depth = Pending.size();
103 // If any children are left, they're the last at their nesting level.
104 // Dump those ones out now.
105 while (Depth < Pending.size()) {
106 Pending.back()(true);
107 this->Pending.pop_back();
110 // Restore the old prefix.
111 this->Prefix.resize(Prefix.size() - 2);
115 Pending.push_back(std::move(DumpWithIndent));
117 Pending.back()(false);
118 Pending.back() = std::move(DumpWithIndent);
123 TextTreeStructure(raw_ostream &OS, bool ShowColors)
124 : OS(OS), ShowColors(ShowColors) {}
128 : public TextTreeStructure,
129 public comments::ConstCommentVisitor<TextNodeDumper, void,
130 const comments::FullComment *>,
131 public ConstAttrVisitor<TextNodeDumper>,
132 public ConstTemplateArgumentVisitor<TextNodeDumper>,
133 public ConstStmtVisitor<TextNodeDumper>,
134 public TypeVisitor<TextNodeDumper>,
135 public ConstDeclVisitor<TextNodeDumper> {
137 const bool ShowColors;
139 /// Keep track of the last location we print out so that we can
140 /// print out deltas from then on out.
141 const char *LastLocFilename = "";
142 unsigned LastLocLine = ~0U;
144 /// \p Context, \p SM, and \p Traits can be null. This is because we want
145 /// to be able to call \p dump() in a debugger without having to pass the
146 /// \p ASTContext to \p dump. Not all parts of the AST dump output will be
147 /// available without the \p ASTContext.
148 const ASTContext *Context = nullptr;
149 const SourceManager *SM = nullptr;
151 /// The policy to use for printing; can be defaulted.
152 PrintingPolicy PrintPolicy = LangOptions();
154 const comments::CommandTraits *Traits = nullptr;
156 const char *getCommandName(unsigned CommandID);
157 void printFPOptions(FPOptionsOverride FPO);
159 void dumpAPValueChildren(const APValue &Value, QualType Ty,
160 const APValue &(*IdxToChildFun)(const APValue &,
162 unsigned NumChildren, StringRef LabelSingular,
163 StringRef LabelPlurial);
166 TextNodeDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors);
167 TextNodeDumper(raw_ostream &OS, bool ShowColors);
169 void Visit(const comments::Comment *C, const comments::FullComment *FC);
171 void Visit(const Attr *A);
173 void Visit(const TemplateArgument &TA, SourceRange R,
174 const Decl *From = nullptr, StringRef Label = {});
176 void Visit(const Stmt *Node);
178 void Visit(const Type *T);
180 void Visit(QualType T);
182 void Visit(const Decl *D);
184 void Visit(const CXXCtorInitializer *Init);
186 void Visit(const OMPClause *C);
188 void Visit(const BlockDecl::Capture &C);
190 void Visit(const GenericSelectionExpr::ConstAssociation &A);
192 void Visit(const concepts::Requirement *R);
194 void Visit(const APValue &Value, QualType Ty);
196 void dumpPointer(const void *Ptr);
197 void dumpLocation(SourceLocation Loc);
198 void dumpSourceRange(SourceRange R);
199 void dumpBareType(QualType T, bool Desugar = true);
200 void dumpType(QualType T);
201 void dumpBareDeclRef(const Decl *D);
202 void dumpName(const NamedDecl *ND);
203 void dumpAccessSpecifier(AccessSpecifier AS);
204 void dumpCleanupObject(const ExprWithCleanups::CleanupObject &C);
206 void dumpDeclRef(const Decl *D, StringRef Label = {});
208 void visitTextComment(const comments::TextComment *C,
209 const comments::FullComment *);
210 void visitInlineCommandComment(const comments::InlineCommandComment *C,
211 const comments::FullComment *);
212 void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C,
213 const comments::FullComment *);
214 void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C,
215 const comments::FullComment *);
216 void visitBlockCommandComment(const comments::BlockCommandComment *C,
217 const comments::FullComment *);
218 void visitParamCommandComment(const comments::ParamCommandComment *C,
219 const comments::FullComment *FC);
220 void visitTParamCommandComment(const comments::TParamCommandComment *C,
221 const comments::FullComment *FC);
222 void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C,
223 const comments::FullComment *);
225 visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C,
226 const comments::FullComment *);
227 void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
228 const comments::FullComment *);
230 // Implements Visit methods for Attrs.
231 #include "clang/AST/AttrTextNodeDump.inc"
233 void VisitNullTemplateArgument(const TemplateArgument &TA);
234 void VisitTypeTemplateArgument(const TemplateArgument &TA);
235 void VisitDeclarationTemplateArgument(const TemplateArgument &TA);
236 void VisitNullPtrTemplateArgument(const TemplateArgument &TA);
237 void VisitIntegralTemplateArgument(const TemplateArgument &TA);
238 void VisitTemplateTemplateArgument(const TemplateArgument &TA);
239 void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA);
240 void VisitExpressionTemplateArgument(const TemplateArgument &TA);
241 void VisitPackTemplateArgument(const TemplateArgument &TA);
243 void VisitIfStmt(const IfStmt *Node);
244 void VisitSwitchStmt(const SwitchStmt *Node);
245 void VisitWhileStmt(const WhileStmt *Node);
246 void VisitLabelStmt(const LabelStmt *Node);
247 void VisitGotoStmt(const GotoStmt *Node);
248 void VisitCaseStmt(const CaseStmt *Node);
249 void VisitConstantExpr(const ConstantExpr *Node);
250 void VisitCallExpr(const CallExpr *Node);
251 void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node);
252 void VisitCastExpr(const CastExpr *Node);
253 void VisitImplicitCastExpr(const ImplicitCastExpr *Node);
254 void VisitDeclRefExpr(const DeclRefExpr *Node);
255 void VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *Node);
256 void VisitPredefinedExpr(const PredefinedExpr *Node);
257 void VisitCharacterLiteral(const CharacterLiteral *Node);
258 void VisitIntegerLiteral(const IntegerLiteral *Node);
259 void VisitFixedPointLiteral(const FixedPointLiteral *Node);
260 void VisitFloatingLiteral(const FloatingLiteral *Node);
261 void VisitStringLiteral(const StringLiteral *Str);
262 void VisitInitListExpr(const InitListExpr *ILE);
263 void VisitGenericSelectionExpr(const GenericSelectionExpr *E);
264 void VisitUnaryOperator(const UnaryOperator *Node);
265 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node);
266 void VisitMemberExpr(const MemberExpr *Node);
267 void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node);
268 void VisitBinaryOperator(const BinaryOperator *Node);
269 void VisitCompoundAssignOperator(const CompoundAssignOperator *Node);
270 void VisitAddrLabelExpr(const AddrLabelExpr *Node);
271 void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node);
272 void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node);
273 void VisitCXXThisExpr(const CXXThisExpr *Node);
274 void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node);
275 void VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node);
276 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node);
277 void VisitCXXConstructExpr(const CXXConstructExpr *Node);
278 void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node);
279 void VisitCXXNewExpr(const CXXNewExpr *Node);
280 void VisitCXXDeleteExpr(const CXXDeleteExpr *Node);
281 void VisitTypeTraitExpr(const TypeTraitExpr *Node);
282 void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node);
283 void VisitExpressionTraitExpr(const ExpressionTraitExpr *Node);
284 void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node);
285 void VisitExprWithCleanups(const ExprWithCleanups *Node);
286 void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node);
287 void VisitSizeOfPackExpr(const SizeOfPackExpr *Node);
289 VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *Node);
290 void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node);
291 void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node);
292 void VisitObjCMessageExpr(const ObjCMessageExpr *Node);
293 void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node);
294 void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node);
295 void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node);
296 void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node);
297 void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node);
298 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node);
299 void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node);
300 void VisitOMPIteratorExpr(const OMPIteratorExpr *Node);
301 void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *Node);
302 void VisitRequiresExpr(const RequiresExpr *Node);
304 void VisitRValueReferenceType(const ReferenceType *T);
305 void VisitArrayType(const ArrayType *T);
306 void VisitConstantArrayType(const ConstantArrayType *T);
307 void VisitVariableArrayType(const VariableArrayType *T);
308 void VisitDependentSizedArrayType(const DependentSizedArrayType *T);
309 void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T);
310 void VisitVectorType(const VectorType *T);
311 void VisitFunctionType(const FunctionType *T);
312 void VisitFunctionProtoType(const FunctionProtoType *T);
313 void VisitUnresolvedUsingType(const UnresolvedUsingType *T);
314 void VisitTypedefType(const TypedefType *T);
315 void VisitUnaryTransformType(const UnaryTransformType *T);
316 void VisitTagType(const TagType *T);
317 void VisitTemplateTypeParmType(const TemplateTypeParmType *T);
318 void VisitAutoType(const AutoType *T);
319 void VisitTemplateSpecializationType(const TemplateSpecializationType *T);
320 void VisitInjectedClassNameType(const InjectedClassNameType *T);
321 void VisitObjCInterfaceType(const ObjCInterfaceType *T);
322 void VisitPackExpansionType(const PackExpansionType *T);
324 void VisitLabelDecl(const LabelDecl *D);
325 void VisitTypedefDecl(const TypedefDecl *D);
326 void VisitEnumDecl(const EnumDecl *D);
327 void VisitRecordDecl(const RecordDecl *D);
328 void VisitEnumConstantDecl(const EnumConstantDecl *D);
329 void VisitIndirectFieldDecl(const IndirectFieldDecl *D);
330 void VisitFunctionDecl(const FunctionDecl *D);
331 void VisitFieldDecl(const FieldDecl *D);
332 void VisitVarDecl(const VarDecl *D);
333 void VisitBindingDecl(const BindingDecl *D);
334 void VisitCapturedDecl(const CapturedDecl *D);
335 void VisitImportDecl(const ImportDecl *D);
336 void VisitPragmaCommentDecl(const PragmaCommentDecl *D);
337 void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D);
338 void VisitOMPExecutableDirective(const OMPExecutableDirective *D);
339 void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D);
340 void VisitOMPRequiresDecl(const OMPRequiresDecl *D);
341 void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D);
342 void VisitNamespaceDecl(const NamespaceDecl *D);
343 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D);
344 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D);
345 void VisitTypeAliasDecl(const TypeAliasDecl *D);
346 void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D);
347 void VisitCXXRecordDecl(const CXXRecordDecl *D);
348 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D);
349 void VisitClassTemplateDecl(const ClassTemplateDecl *D);
350 void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D);
351 void VisitVarTemplateDecl(const VarTemplateDecl *D);
352 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
353 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
354 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
355 void VisitUsingDecl(const UsingDecl *D);
356 void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D);
357 void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D);
358 void VisitUsingEnumDecl(const UsingEnumDecl *D);
359 void VisitUsingShadowDecl(const UsingShadowDecl *D);
360 void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D);
361 void VisitLinkageSpecDecl(const LinkageSpecDecl *D);
362 void VisitAccessSpecDecl(const AccessSpecDecl *D);
363 void VisitFriendDecl(const FriendDecl *D);
364 void VisitObjCIvarDecl(const ObjCIvarDecl *D);
365 void VisitObjCMethodDecl(const ObjCMethodDecl *D);
366 void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
367 void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
368 void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
369 void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
370 void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
371 void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
372 void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
373 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
374 void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
375 void VisitBlockDecl(const BlockDecl *D);
376 void VisitConceptDecl(const ConceptDecl *D);
378 VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D);
383 #endif // LLVM_CLANG_AST_TEXTNODEDUMPER_H