Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 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/TypeVisitor.h" |
||
28 | |||
29 | namespace clang { |
||
30 | |||
31 | class APValue; |
||
32 | |||
33 | class TextTreeStructure { |
||
34 | raw_ostream &OS; |
||
35 | const bool ShowColors; |
||
36 | |||
37 | /// Pending[i] is an action to dump an entity at level i. |
||
38 | llvm::SmallVector<std::function<void(bool IsLastChild)>, 32> Pending; |
||
39 | |||
40 | /// Indicates whether we're at the top level. |
||
41 | bool TopLevel = true; |
||
42 | |||
43 | /// Indicates if we're handling the first child after entering a new depth. |
||
44 | bool FirstChild = true; |
||
45 | |||
46 | /// Prefix for currently-being-dumped entity. |
||
47 | std::string Prefix; |
||
48 | |||
49 | public: |
||
50 | /// Add a child of the current node. Calls DoAddChild without arguments |
||
51 | template <typename Fn> void AddChild(Fn DoAddChild) { |
||
52 | return AddChild("", DoAddChild); |
||
53 | } |
||
54 | |||
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 |
||
59 | // run the dumper. |
||
60 | if (TopLevel) { |
||
61 | TopLevel = false; |
||
62 | DoAddChild(); |
||
63 | while (!Pending.empty()) { |
||
64 | Pending.back()(true); |
||
65 | Pending.pop_back(); |
||
66 | } |
||
67 | Prefix.clear(); |
||
68 | OS << "\n"; |
||
69 | TopLevel = true; |
||
70 | return; |
||
71 | } |
||
72 | |||
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: |
||
77 | // |
||
78 | // A Prefix = "" |
||
79 | // |-B Prefix = "| " |
||
80 | // | `-C Prefix = "| " |
||
81 | // `-D Prefix = " " |
||
82 | // |-E Prefix = " | " |
||
83 | // `-F Prefix = " " |
||
84 | // G Prefix = "" |
||
85 | // |
||
86 | // Note that the first level gets no prefix. |
||
87 | { |
||
88 | OS << '\n'; |
||
89 | ColorScope Color(OS, ShowColors, IndentColor); |
||
90 | OS << Prefix << (IsLastChild ? '`' : '|') << '-'; |
||
91 | if (!Label.empty()) |
||
92 | OS << Label << ": "; |
||
93 | |||
94 | this->Prefix.push_back(IsLastChild ? ' ' : '|'); |
||
95 | this->Prefix.push_back(' '); |
||
96 | } |
||
97 | |||
98 | FirstChild = true; |
||
99 | unsigned Depth = Pending.size(); |
||
100 | |||
101 | DoAddChild(); |
||
102 | |||
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(); |
||
108 | } |
||
109 | |||
110 | // Restore the old prefix. |
||
111 | this->Prefix.resize(Prefix.size() - 2); |
||
112 | }; |
||
113 | |||
114 | if (FirstChild) { |
||
115 | Pending.push_back(std::move(DumpWithIndent)); |
||
116 | } else { |
||
117 | Pending.back()(false); |
||
118 | Pending.back() = std::move(DumpWithIndent); |
||
119 | } |
||
120 | FirstChild = false; |
||
121 | } |
||
122 | |||
123 | TextTreeStructure(raw_ostream &OS, bool ShowColors) |
||
124 | : OS(OS), ShowColors(ShowColors) {} |
||
125 | }; |
||
126 | |||
127 | class TextNodeDumper |
||
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> { |
||
136 | raw_ostream &OS; |
||
137 | const bool ShowColors; |
||
138 | |||
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; |
||
143 | |||
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; |
||
150 | |||
151 | /// The policy to use for printing; can be defaulted. |
||
152 | PrintingPolicy PrintPolicy = LangOptions(); |
||
153 | |||
154 | const comments::CommandTraits *Traits = nullptr; |
||
155 | |||
156 | const char *getCommandName(unsigned CommandID); |
||
157 | void printFPOptions(FPOptionsOverride FPO); |
||
158 | |||
159 | void dumpAPValueChildren(const APValue &Value, QualType Ty, |
||
160 | const APValue &(*IdxToChildFun)(const APValue &, |
||
161 | unsigned), |
||
162 | unsigned NumChildren, StringRef LabelSingular, |
||
163 | StringRef LabelPlurial); |
||
164 | |||
165 | public: |
||
166 | TextNodeDumper(raw_ostream &OS, const ASTContext &Context, bool ShowColors); |
||
167 | TextNodeDumper(raw_ostream &OS, bool ShowColors); |
||
168 | |||
169 | void Visit(const comments::Comment *C, const comments::FullComment *FC); |
||
170 | |||
171 | void Visit(const Attr *A); |
||
172 | |||
173 | void Visit(const TemplateArgument &TA, SourceRange R, |
||
174 | const Decl *From = nullptr, StringRef Label = {}); |
||
175 | |||
176 | void Visit(const Stmt *Node); |
||
177 | |||
178 | void Visit(const Type *T); |
||
179 | |||
180 | void Visit(QualType T); |
||
181 | |||
182 | void Visit(const Decl *D); |
||
183 | |||
184 | void Visit(const CXXCtorInitializer *Init); |
||
185 | |||
186 | void Visit(const OMPClause *C); |
||
187 | |||
188 | void Visit(const BlockDecl::Capture &C); |
||
189 | |||
190 | void Visit(const GenericSelectionExpr::ConstAssociation &A); |
||
191 | |||
192 | void Visit(const concepts::Requirement *R); |
||
193 | |||
194 | void Visit(const APValue &Value, QualType Ty); |
||
195 | |||
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); |
||
205 | |||
206 | void dumpDeclRef(const Decl *D, StringRef Label = {}); |
||
207 | |||
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 *); |
||
224 | void |
||
225 | visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C, |
||
226 | const comments::FullComment *); |
||
227 | void visitVerbatimLineComment(const comments::VerbatimLineComment *C, |
||
228 | const comments::FullComment *); |
||
229 | |||
230 | // Implements Visit methods for Attrs. |
||
231 | #include "clang/AST/AttrTextNodeDump.inc" |
||
232 | |||
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); |
||
242 | |||
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 VisitCompoundStmt(const CompoundStmt *Node); |
||
250 | void VisitConstantExpr(const ConstantExpr *Node); |
||
251 | void VisitCallExpr(const CallExpr *Node); |
||
252 | void VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node); |
||
253 | void VisitCastExpr(const CastExpr *Node); |
||
254 | void VisitImplicitCastExpr(const ImplicitCastExpr *Node); |
||
255 | void VisitDeclRefExpr(const DeclRefExpr *Node); |
||
256 | void VisitSYCLUniqueStableNameExpr(const SYCLUniqueStableNameExpr *Node); |
||
257 | void VisitPredefinedExpr(const PredefinedExpr *Node); |
||
258 | void VisitCharacterLiteral(const CharacterLiteral *Node); |
||
259 | void VisitIntegerLiteral(const IntegerLiteral *Node); |
||
260 | void VisitFixedPointLiteral(const FixedPointLiteral *Node); |
||
261 | void VisitFloatingLiteral(const FloatingLiteral *Node); |
||
262 | void VisitStringLiteral(const StringLiteral *Str); |
||
263 | void VisitInitListExpr(const InitListExpr *ILE); |
||
264 | void VisitGenericSelectionExpr(const GenericSelectionExpr *E); |
||
265 | void VisitUnaryOperator(const UnaryOperator *Node); |
||
266 | void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node); |
||
267 | void VisitMemberExpr(const MemberExpr *Node); |
||
268 | void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node); |
||
269 | void VisitBinaryOperator(const BinaryOperator *Node); |
||
270 | void VisitCompoundAssignOperator(const CompoundAssignOperator *Node); |
||
271 | void VisitAddrLabelExpr(const AddrLabelExpr *Node); |
||
272 | void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node); |
||
273 | void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node); |
||
274 | void VisitCXXThisExpr(const CXXThisExpr *Node); |
||
275 | void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node); |
||
276 | void VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node); |
||
277 | void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node); |
||
278 | void VisitCXXConstructExpr(const CXXConstructExpr *Node); |
||
279 | void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node); |
||
280 | void VisitCXXNewExpr(const CXXNewExpr *Node); |
||
281 | void VisitCXXDeleteExpr(const CXXDeleteExpr *Node); |
||
282 | void VisitTypeTraitExpr(const TypeTraitExpr *Node); |
||
283 | void VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node); |
||
284 | void VisitExpressionTraitExpr(const ExpressionTraitExpr *Node); |
||
285 | void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node); |
||
286 | void VisitExprWithCleanups(const ExprWithCleanups *Node); |
||
287 | void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node); |
||
288 | void VisitSizeOfPackExpr(const SizeOfPackExpr *Node); |
||
289 | void |
||
290 | VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *Node); |
||
291 | void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node); |
||
292 | void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node); |
||
293 | void VisitObjCMessageExpr(const ObjCMessageExpr *Node); |
||
294 | void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node); |
||
295 | void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node); |
||
296 | void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node); |
||
297 | void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node); |
||
298 | void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); |
||
299 | void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); |
||
300 | void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); |
||
301 | void VisitOMPIteratorExpr(const OMPIteratorExpr *Node); |
||
302 | void VisitConceptSpecializationExpr(const ConceptSpecializationExpr *Node); |
||
303 | void VisitRequiresExpr(const RequiresExpr *Node); |
||
304 | |||
305 | void VisitRValueReferenceType(const ReferenceType *T); |
||
306 | void VisitArrayType(const ArrayType *T); |
||
307 | void VisitConstantArrayType(const ConstantArrayType *T); |
||
308 | void VisitVariableArrayType(const VariableArrayType *T); |
||
309 | void VisitDependentSizedArrayType(const DependentSizedArrayType *T); |
||
310 | void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T); |
||
311 | void VisitVectorType(const VectorType *T); |
||
312 | void VisitFunctionType(const FunctionType *T); |
||
313 | void VisitFunctionProtoType(const FunctionProtoType *T); |
||
314 | void VisitUnresolvedUsingType(const UnresolvedUsingType *T); |
||
315 | void VisitUsingType(const UsingType *T); |
||
316 | void VisitTypedefType(const TypedefType *T); |
||
317 | void VisitUnaryTransformType(const UnaryTransformType *T); |
||
318 | void VisitTagType(const TagType *T); |
||
319 | void VisitTemplateTypeParmType(const TemplateTypeParmType *T); |
||
320 | void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T); |
||
321 | void |
||
322 | VisitSubstTemplateTypeParmPackType(const SubstTemplateTypeParmPackType *T); |
||
323 | void VisitAutoType(const AutoType *T); |
||
324 | void VisitDeducedTemplateSpecializationType( |
||
325 | const DeducedTemplateSpecializationType *T); |
||
326 | void VisitTemplateSpecializationType(const TemplateSpecializationType *T); |
||
327 | void VisitInjectedClassNameType(const InjectedClassNameType *T); |
||
328 | void VisitObjCInterfaceType(const ObjCInterfaceType *T); |
||
329 | void VisitPackExpansionType(const PackExpansionType *T); |
||
330 | |||
331 | void VisitLabelDecl(const LabelDecl *D); |
||
332 | void VisitTypedefDecl(const TypedefDecl *D); |
||
333 | void VisitEnumDecl(const EnumDecl *D); |
||
334 | void VisitRecordDecl(const RecordDecl *D); |
||
335 | void VisitEnumConstantDecl(const EnumConstantDecl *D); |
||
336 | void VisitIndirectFieldDecl(const IndirectFieldDecl *D); |
||
337 | void VisitFunctionDecl(const FunctionDecl *D); |
||
338 | void VisitFieldDecl(const FieldDecl *D); |
||
339 | void VisitVarDecl(const VarDecl *D); |
||
340 | void VisitBindingDecl(const BindingDecl *D); |
||
341 | void VisitCapturedDecl(const CapturedDecl *D); |
||
342 | void VisitImportDecl(const ImportDecl *D); |
||
343 | void VisitPragmaCommentDecl(const PragmaCommentDecl *D); |
||
344 | void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D); |
||
345 | void VisitOMPExecutableDirective(const OMPExecutableDirective *D); |
||
346 | void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D); |
||
347 | void VisitOMPRequiresDecl(const OMPRequiresDecl *D); |
||
348 | void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D); |
||
349 | void VisitNamespaceDecl(const NamespaceDecl *D); |
||
350 | void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D); |
||
351 | void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D); |
||
352 | void VisitTypeAliasDecl(const TypeAliasDecl *D); |
||
353 | void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D); |
||
354 | void VisitCXXRecordDecl(const CXXRecordDecl *D); |
||
355 | void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); |
||
356 | void VisitClassTemplateDecl(const ClassTemplateDecl *D); |
||
357 | void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D); |
||
358 | void VisitVarTemplateDecl(const VarTemplateDecl *D); |
||
359 | void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); |
||
360 | void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); |
||
361 | void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); |
||
362 | void VisitUsingDecl(const UsingDecl *D); |
||
363 | void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D); |
||
364 | void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D); |
||
365 | void VisitUsingEnumDecl(const UsingEnumDecl *D); |
||
366 | void VisitUsingShadowDecl(const UsingShadowDecl *D); |
||
367 | void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D); |
||
368 | void VisitLinkageSpecDecl(const LinkageSpecDecl *D); |
||
369 | void VisitAccessSpecDecl(const AccessSpecDecl *D); |
||
370 | void VisitFriendDecl(const FriendDecl *D); |
||
371 | void VisitObjCIvarDecl(const ObjCIvarDecl *D); |
||
372 | void VisitObjCMethodDecl(const ObjCMethodDecl *D); |
||
373 | void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D); |
||
374 | void VisitObjCCategoryDecl(const ObjCCategoryDecl *D); |
||
375 | void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D); |
||
376 | void VisitObjCProtocolDecl(const ObjCProtocolDecl *D); |
||
377 | void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D); |
||
378 | void VisitObjCImplementationDecl(const ObjCImplementationDecl *D); |
||
379 | void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D); |
||
380 | void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); |
||
381 | void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); |
||
382 | void VisitBlockDecl(const BlockDecl *D); |
||
383 | void VisitConceptDecl(const ConceptDecl *D); |
||
384 | void |
||
385 | VisitLifetimeExtendedTemporaryDecl(const LifetimeExtendedTemporaryDecl *D); |
||
386 | void VisitHLSLBufferDecl(const HLSLBufferDecl *D); |
||
387 | }; |
||
388 | |||
389 | } // namespace clang |
||
390 | |||
391 | #endif // LLVM_CLANG_AST_TEXTNODEDUMPER_H |