1 //===--- TextNodeDumper.h - Printing of AST nodes -------------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements AST dumping of components of individual AST nodes. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_CLANG_AST_TEXTNODEDUMPER_H 15 #define LLVM_CLANG_AST_TEXTNODEDUMPER_H 16 17 #include "clang/AST/ASTContext.h" 18 #include "clang/AST/ASTDumperUtils.h" 19 #include "clang/AST/AttrVisitor.h" 20 #include "clang/AST/CommentCommandTraits.h" 21 #include "clang/AST/CommentVisitor.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 raw_ostream &OS; 134 const bool ShowColors; 135 136 /// Keep track of the last location we print out so that we can 137 /// print out deltas from then on out. 138 const char *LastLocFilename = ""; 139 unsigned LastLocLine = ~0U; 140 141 const SourceManager *SM; 142 143 /// The policy to use for printing; can be defaulted. 144 PrintingPolicy PrintPolicy; 145 146 const comments::CommandTraits *Traits; 147 148 const char *getCommandName(unsigned CommandID); 149 150 public: 151 TextNodeDumper(raw_ostream &OS, bool ShowColors, const SourceManager *SM, 152 const PrintingPolicy &PrintPolicy, 153 const comments::CommandTraits *Traits); 154 155 void Visit(const comments::Comment *C, const comments::FullComment *FC); 156 157 void Visit(const Attr *A); 158 159 void Visit(const TemplateArgument &TA, SourceRange R, 160 const Decl *From = nullptr, StringRef Label = {}); 161 162 void Visit(const Stmt *Node); 163 164 void Visit(const Type *T); 165 166 void Visit(QualType T); 167 168 void Visit(const Decl *D); 169 170 void Visit(const CXXCtorInitializer *Init); 171 172 void Visit(const OMPClause *C); 173 174 void Visit(const BlockDecl::Capture &C); 175 176 void dumpPointer(const void *Ptr); 177 void dumpLocation(SourceLocation Loc); 178 void dumpSourceRange(SourceRange R); 179 void dumpBareType(QualType T, bool Desugar = true); 180 void dumpType(QualType T); 181 void dumpBareDeclRef(const Decl *D); 182 void dumpName(const NamedDecl *ND); 183 void dumpAccessSpecifier(AccessSpecifier AS); 184 185 void dumpDeclRef(const Decl *D, StringRef Label = {}); 186 187 void visitTextComment(const comments::TextComment *C, 188 const comments::FullComment *); 189 void visitInlineCommandComment(const comments::InlineCommandComment *C, 190 const comments::FullComment *); 191 void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C, 192 const comments::FullComment *); 193 void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C, 194 const comments::FullComment *); 195 void visitBlockCommandComment(const comments::BlockCommandComment *C, 196 const comments::FullComment *); 197 void visitParamCommandComment(const comments::ParamCommandComment *C, 198 const comments::FullComment *FC); 199 void visitTParamCommandComment(const comments::TParamCommandComment *C, 200 const comments::FullComment *FC); 201 void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C, 202 const comments::FullComment *); 203 void 204 visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C, 205 const comments::FullComment *); 206 void visitVerbatimLineComment(const comments::VerbatimLineComment *C, 207 const comments::FullComment *); 208 209 // Implements Visit methods for Attrs. 210 #include "clang/AST/AttrTextNodeDump.inc" 211 212 void VisitNullTemplateArgument(const TemplateArgument &TA); 213 void VisitTypeTemplateArgument(const TemplateArgument &TA); 214 void VisitDeclarationTemplateArgument(const TemplateArgument &TA); 215 void VisitNullPtrTemplateArgument(const TemplateArgument &TA); 216 void VisitIntegralTemplateArgument(const TemplateArgument &TA); 217 void VisitTemplateTemplateArgument(const TemplateArgument &TA); 218 void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA); 219 void VisitExpressionTemplateArgument(const TemplateArgument &TA); 220 void VisitPackTemplateArgument(const TemplateArgument &TA); 221 222 void VisitIfStmt(const IfStmt *Node); 223 void VisitSwitchStmt(const SwitchStmt *Node); 224 void VisitWhileStmt(const WhileStmt *Node); 225 void VisitLabelStmt(const LabelStmt *Node); 226 void VisitGotoStmt(const GotoStmt *Node); 227 void VisitCaseStmt(const CaseStmt *Node); 228 void VisitCallExpr(const CallExpr *Node); 229 void VisitCastExpr(const CastExpr *Node); 230 void VisitImplicitCastExpr(const ImplicitCastExpr *Node); 231 void VisitDeclRefExpr(const DeclRefExpr *Node); 232 void VisitPredefinedExpr(const PredefinedExpr *Node); 233 void VisitCharacterLiteral(const CharacterLiteral *Node); 234 void VisitIntegerLiteral(const IntegerLiteral *Node); 235 void VisitFixedPointLiteral(const FixedPointLiteral *Node); 236 void VisitFloatingLiteral(const FloatingLiteral *Node); 237 void VisitStringLiteral(const StringLiteral *Str); 238 void VisitInitListExpr(const InitListExpr *ILE); 239 void VisitUnaryOperator(const UnaryOperator *Node); 240 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node); 241 void VisitMemberExpr(const MemberExpr *Node); 242 void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node); 243 void VisitBinaryOperator(const BinaryOperator *Node); 244 void VisitCompoundAssignOperator(const CompoundAssignOperator *Node); 245 void VisitAddrLabelExpr(const AddrLabelExpr *Node); 246 void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node); 247 void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node); 248 void VisitCXXThisExpr(const CXXThisExpr *Node); 249 void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node); 250 void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *Node); 251 void VisitCXXConstructExpr(const CXXConstructExpr *Node); 252 void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node); 253 void VisitCXXNewExpr(const CXXNewExpr *Node); 254 void VisitCXXDeleteExpr(const CXXDeleteExpr *Node); 255 void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node); 256 void VisitExprWithCleanups(const ExprWithCleanups *Node); 257 void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node); 258 void VisitSizeOfPackExpr(const SizeOfPackExpr *Node); 259 void 260 VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *Node); 261 void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node); 262 void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node); 263 void VisitObjCMessageExpr(const ObjCMessageExpr *Node); 264 void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node); 265 void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node); 266 void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node); 267 void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node); 268 void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); 269 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); 270 void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); 271 272 void VisitRValueReferenceType(const ReferenceType *T); 273 void VisitArrayType(const ArrayType *T); 274 void VisitConstantArrayType(const ConstantArrayType *T); 275 void VisitVariableArrayType(const VariableArrayType *T); 276 void VisitDependentSizedArrayType(const DependentSizedArrayType *T); 277 void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *T); 278 void VisitVectorType(const VectorType *T); 279 void VisitFunctionType(const FunctionType *T); 280 void VisitFunctionProtoType(const FunctionProtoType *T); 281 void VisitUnresolvedUsingType(const UnresolvedUsingType *T); 282 void VisitTypedefType(const TypedefType *T); 283 void VisitUnaryTransformType(const UnaryTransformType *T); 284 void VisitTagType(const TagType *T); 285 void VisitTemplateTypeParmType(const TemplateTypeParmType *T); 286 void VisitAutoType(const AutoType *T); 287 void VisitTemplateSpecializationType(const TemplateSpecializationType *T); 288 void VisitInjectedClassNameType(const InjectedClassNameType *T); 289 void VisitObjCInterfaceType(const ObjCInterfaceType *T); 290 void VisitPackExpansionType(const PackExpansionType *T); 291 292 private: 293 void dumpCXXTemporary(const CXXTemporary *Temporary); 294 }; 295 296 } // namespace clang 297 298 #endif // LLVM_CLANG_AST_TEXTNODEDUMPER_H 299