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 27 namespace clang { 28 29 class 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 45 public: 46 /// Add a child of the current node. Calls DoAddChild without arguments AddChild(Fn DoAddChild)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. AddChild(StringRef Label,Fn DoAddChild)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 TextTreeStructure(raw_ostream & OS,bool ShowColors)121 TextTreeStructure(raw_ostream &OS, bool ShowColors) 122 : OS(OS), ShowColors(ShowColors) {} 123 }; 124 125 class 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 151 public: 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