1 //===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===// 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 the AST dump methods, which dump out the 11 // AST in a form that exposes type details and other fields. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/Attr.h" 17 #include "clang/AST/CommentVisitor.h" 18 #include "clang/AST/DeclCXX.h" 19 #include "clang/AST/DeclLookups.h" 20 #include "clang/AST/DeclObjC.h" 21 #include "clang/AST/DeclVisitor.h" 22 #include "clang/AST/StmtVisitor.h" 23 #include "clang/AST/TypeVisitor.h" 24 #include "clang/Basic/Module.h" 25 #include "clang/Basic/SourceManager.h" 26 #include "llvm/Support/raw_ostream.h" 27 using namespace clang; 28 using namespace clang::comments; 29 30 //===----------------------------------------------------------------------===// 31 // ASTDumper Visitor 32 //===----------------------------------------------------------------------===// 33 34 namespace { 35 // Colors used for various parts of the AST dump 36 // Do not use bold yellow for any text. It is hard to read on white screens. 37 38 struct TerminalColor { 39 raw_ostream::Colors Color; 40 bool Bold; 41 }; 42 43 // Red - CastColor 44 // Green - TypeColor 45 // Bold Green - DeclKindNameColor, UndeserializedColor 46 // Yellow - AddressColor, LocationColor 47 // Blue - CommentColor, NullColor, IndentColor 48 // Bold Blue - AttrColor 49 // Bold Magenta - StmtColor 50 // Cyan - ValueKindColor, ObjectKindColor 51 // Bold Cyan - ValueColor, DeclNameColor 52 53 // Decl kind names (VarDecl, FunctionDecl, etc) 54 static const TerminalColor DeclKindNameColor = { raw_ostream::GREEN, true }; 55 // Attr names (CleanupAttr, GuardedByAttr, etc) 56 static const TerminalColor AttrColor = { raw_ostream::BLUE, true }; 57 // Statement names (DeclStmt, ImplicitCastExpr, etc) 58 static const TerminalColor StmtColor = { raw_ostream::MAGENTA, true }; 59 // Comment names (FullComment, ParagraphComment, TextComment, etc) 60 static const TerminalColor CommentColor = { raw_ostream::BLUE, false }; 61 62 // Type names (int, float, etc, plus user defined types) 63 static const TerminalColor TypeColor = { raw_ostream::GREEN, false }; 64 65 // Pointer address 66 static const TerminalColor AddressColor = { raw_ostream::YELLOW, false }; 67 // Source locations 68 static const TerminalColor LocationColor = { raw_ostream::YELLOW, false }; 69 70 // lvalue/xvalue 71 static const TerminalColor ValueKindColor = { raw_ostream::CYAN, false }; 72 // bitfield/objcproperty/objcsubscript/vectorcomponent 73 static const TerminalColor ObjectKindColor = { raw_ostream::CYAN, false }; 74 75 // Null statements 76 static const TerminalColor NullColor = { raw_ostream::BLUE, false }; 77 78 // Undeserialized entities 79 static const TerminalColor UndeserializedColor = { raw_ostream::GREEN, true }; 80 81 // CastKind from CastExpr's 82 static const TerminalColor CastColor = { raw_ostream::RED, false }; 83 84 // Value of the statement 85 static const TerminalColor ValueColor = { raw_ostream::CYAN, true }; 86 // Decl names 87 static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true }; 88 89 // Indents ( `, -. | ) 90 static const TerminalColor IndentColor = { raw_ostream::BLUE, false }; 91 92 class ASTDumper 93 : public ConstDeclVisitor<ASTDumper>, public ConstStmtVisitor<ASTDumper>, 94 public ConstCommentVisitor<ASTDumper>, public TypeVisitor<ASTDumper> { 95 raw_ostream &OS; 96 const CommandTraits *Traits; 97 const SourceManager *SM; 98 99 /// Pending[i] is an action to dump an entity at level i. 100 llvm::SmallVector<std::function<void(bool isLastChild)>, 32> Pending; 101 102 /// Indicates whether we're at the top level. 103 bool TopLevel; 104 105 /// Indicates if we're handling the first child after entering a new depth. 106 bool FirstChild; 107 108 /// Prefix for currently-being-dumped entity. 109 std::string Prefix; 110 111 /// Keep track of the last location we print out so that we can 112 /// print out deltas from then on out. 113 const char *LastLocFilename; 114 unsigned LastLocLine; 115 116 /// The \c FullComment parent of the comment being dumped. 117 const FullComment *FC; 118 119 bool ShowColors; 120 121 /// Dump a child of the current node. 122 template<typename Fn> void dumpChild(Fn doDumpChild) { 123 // If we're at the top level, there's nothing interesting to do; just 124 // run the dumper. 125 if (TopLevel) { 126 TopLevel = false; 127 doDumpChild(); 128 while (!Pending.empty()) { 129 Pending.back()(true); 130 Pending.pop_back(); 131 } 132 Prefix.clear(); 133 OS << "\n"; 134 TopLevel = true; 135 return; 136 } 137 138 const FullComment *OrigFC = FC; 139 auto dumpWithIndent = [this, doDumpChild, OrigFC](bool isLastChild) { 140 // Print out the appropriate tree structure and work out the prefix for 141 // children of this node. For instance: 142 // 143 // A Prefix = "" 144 // |-B Prefix = "| " 145 // | `-C Prefix = "| " 146 // `-D Prefix = " " 147 // |-E Prefix = " | " 148 // `-F Prefix = " " 149 // G Prefix = "" 150 // 151 // Note that the first level gets no prefix. 152 { 153 OS << '\n'; 154 ColorScope Color(*this, IndentColor); 155 OS << Prefix << (isLastChild ? '`' : '|') << '-'; 156 this->Prefix.push_back(isLastChild ? ' ' : '|'); 157 this->Prefix.push_back(' '); 158 } 159 160 FirstChild = true; 161 unsigned Depth = Pending.size(); 162 163 FC = OrigFC; 164 doDumpChild(); 165 166 // If any children are left, they're the last at their nesting level. 167 // Dump those ones out now. 168 while (Depth < Pending.size()) { 169 Pending.back()(true); 170 this->Pending.pop_back(); 171 } 172 173 // Restore the old prefix. 174 this->Prefix.resize(Prefix.size() - 2); 175 }; 176 177 if (FirstChild) { 178 Pending.push_back(std::move(dumpWithIndent)); 179 } else { 180 Pending.back()(false); 181 Pending.back() = std::move(dumpWithIndent); 182 } 183 FirstChild = false; 184 } 185 186 class ColorScope { 187 ASTDumper &Dumper; 188 public: 189 ColorScope(ASTDumper &Dumper, TerminalColor Color) 190 : Dumper(Dumper) { 191 if (Dumper.ShowColors) 192 Dumper.OS.changeColor(Color.Color, Color.Bold); 193 } 194 ~ColorScope() { 195 if (Dumper.ShowColors) 196 Dumper.OS.resetColor(); 197 } 198 }; 199 200 public: 201 ASTDumper(raw_ostream &OS, const CommandTraits *Traits, 202 const SourceManager *SM) 203 : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true), 204 LastLocFilename(""), LastLocLine(~0U), FC(nullptr), 205 ShowColors(SM && SM->getDiagnostics().getShowColors()) { } 206 207 ASTDumper(raw_ostream &OS, const CommandTraits *Traits, 208 const SourceManager *SM, bool ShowColors) 209 : OS(OS), Traits(Traits), SM(SM), TopLevel(true), FirstChild(true), 210 LastLocFilename(""), LastLocLine(~0U), 211 ShowColors(ShowColors) { } 212 213 void dumpDecl(const Decl *D); 214 void dumpStmt(const Stmt *S); 215 void dumpFullComment(const FullComment *C); 216 217 // Utilities 218 void dumpPointer(const void *Ptr); 219 void dumpSourceRange(SourceRange R); 220 void dumpLocation(SourceLocation Loc); 221 void dumpBareType(QualType T, bool Desugar = true); 222 void dumpType(QualType T); 223 void dumpTypeAsChild(QualType T); 224 void dumpTypeAsChild(const Type *T); 225 void dumpBareDeclRef(const Decl *Node); 226 void dumpDeclRef(const Decl *Node, const char *Label = nullptr); 227 void dumpName(const NamedDecl *D); 228 bool hasNodes(const DeclContext *DC); 229 void dumpDeclContext(const DeclContext *DC); 230 void dumpLookups(const DeclContext *DC, bool DumpDecls); 231 void dumpAttr(const Attr *A); 232 233 // C++ Utilities 234 void dumpAccessSpecifier(AccessSpecifier AS); 235 void dumpCXXCtorInitializer(const CXXCtorInitializer *Init); 236 void dumpTemplateParameters(const TemplateParameterList *TPL); 237 void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI); 238 void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A); 239 void dumpTemplateArgumentList(const TemplateArgumentList &TAL); 240 void dumpTemplateArgument(const TemplateArgument &A, 241 SourceRange R = SourceRange()); 242 243 // Types 244 void VisitComplexType(const ComplexType *T) { 245 dumpTypeAsChild(T->getElementType()); 246 } 247 void VisitPointerType(const PointerType *T) { 248 dumpTypeAsChild(T->getPointeeType()); 249 } 250 void VisitBlockPointerType(const BlockPointerType *T) { 251 dumpTypeAsChild(T->getPointeeType()); 252 } 253 void VisitReferenceType(const ReferenceType *T) { 254 dumpTypeAsChild(T->getPointeeType()); 255 } 256 void VisitRValueReferenceType(const ReferenceType *T) { 257 if (T->isSpelledAsLValue()) 258 OS << " written as lvalue reference"; 259 VisitReferenceType(T); 260 } 261 void VisitMemberPointerType(const MemberPointerType *T) { 262 dumpTypeAsChild(T->getClass()); 263 dumpTypeAsChild(T->getPointeeType()); 264 } 265 void VisitArrayType(const ArrayType *T) { 266 switch (T->getSizeModifier()) { 267 case ArrayType::Normal: break; 268 case ArrayType::Static: OS << " static"; break; 269 case ArrayType::Star: OS << " *"; break; 270 } 271 OS << " " << T->getIndexTypeQualifiers().getAsString(); 272 dumpTypeAsChild(T->getElementType()); 273 } 274 void VisitConstantArrayType(const ConstantArrayType *T) { 275 OS << " " << T->getSize(); 276 VisitArrayType(T); 277 } 278 void VisitVariableArrayType(const VariableArrayType *T) { 279 OS << " "; 280 dumpSourceRange(T->getBracketsRange()); 281 VisitArrayType(T); 282 dumpStmt(T->getSizeExpr()); 283 } 284 void VisitDependentSizedArrayType(const DependentSizedArrayType *T) { 285 VisitArrayType(T); 286 OS << " "; 287 dumpSourceRange(T->getBracketsRange()); 288 dumpStmt(T->getSizeExpr()); 289 } 290 void VisitDependentSizedExtVectorType( 291 const DependentSizedExtVectorType *T) { 292 OS << " "; 293 dumpLocation(T->getAttributeLoc()); 294 dumpTypeAsChild(T->getElementType()); 295 dumpStmt(T->getSizeExpr()); 296 } 297 void VisitVectorType(const VectorType *T) { 298 switch (T->getVectorKind()) { 299 case VectorType::GenericVector: break; 300 case VectorType::AltiVecVector: OS << " altivec"; break; 301 case VectorType::AltiVecPixel: OS << " altivec pixel"; break; 302 case VectorType::AltiVecBool: OS << " altivec bool"; break; 303 case VectorType::NeonVector: OS << " neon"; break; 304 case VectorType::NeonPolyVector: OS << " neon poly"; break; 305 } 306 OS << " " << T->getNumElements(); 307 dumpTypeAsChild(T->getElementType()); 308 } 309 void VisitFunctionType(const FunctionType *T) { 310 auto EI = T->getExtInfo(); 311 if (EI.getNoReturn()) OS << " noreturn"; 312 if (EI.getProducesResult()) OS << " produces_result"; 313 if (EI.getHasRegParm()) OS << " regparm " << EI.getRegParm(); 314 OS << " " << FunctionType::getNameForCallConv(EI.getCC()); 315 dumpTypeAsChild(T->getReturnType()); 316 } 317 void VisitFunctionProtoType(const FunctionProtoType *T) { 318 auto EPI = T->getExtProtoInfo(); 319 if (EPI.HasTrailingReturn) OS << " trailing_return"; 320 if (T->isConst()) OS << " const"; 321 if (T->isVolatile()) OS << " volatile"; 322 if (T->isRestrict()) OS << " restrict"; 323 switch (EPI.RefQualifier) { 324 case RQ_None: break; 325 case RQ_LValue: OS << " &"; break; 326 case RQ_RValue: OS << " &&"; break; 327 } 328 // FIXME: Exception specification. 329 // FIXME: Consumed parameters. 330 VisitFunctionType(T); 331 for (QualType PT : T->getParamTypes()) 332 dumpTypeAsChild(PT); 333 if (EPI.Variadic) 334 dumpChild([=] { OS << "..."; }); 335 } 336 void VisitUnresolvedUsingType(const UnresolvedUsingType *T) { 337 dumpDeclRef(T->getDecl()); 338 } 339 void VisitTypedefType(const TypedefType *T) { 340 dumpDeclRef(T->getDecl()); 341 } 342 void VisitTypeOfExprType(const TypeOfExprType *T) { 343 dumpStmt(T->getUnderlyingExpr()); 344 } 345 void VisitDecltypeType(const DecltypeType *T) { 346 dumpStmt(T->getUnderlyingExpr()); 347 } 348 void VisitUnaryTransformType(const UnaryTransformType *T) { 349 switch (T->getUTTKind()) { 350 case UnaryTransformType::EnumUnderlyingType: 351 OS << " underlying_type"; 352 break; 353 } 354 dumpTypeAsChild(T->getBaseType()); 355 } 356 void VisitTagType(const TagType *T) { 357 dumpDeclRef(T->getDecl()); 358 } 359 void VisitAttributedType(const AttributedType *T) { 360 // FIXME: AttrKind 361 dumpTypeAsChild(T->getModifiedType()); 362 } 363 void VisitTemplateTypeParmType(const TemplateTypeParmType *T) { 364 OS << " depth " << T->getDepth() << " index " << T->getIndex(); 365 if (T->isParameterPack()) OS << " pack"; 366 dumpDeclRef(T->getDecl()); 367 } 368 void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { 369 dumpTypeAsChild(T->getReplacedParameter()); 370 } 371 void VisitSubstTemplateTypeParmPackType( 372 const SubstTemplateTypeParmPackType *T) { 373 dumpTypeAsChild(T->getReplacedParameter()); 374 dumpTemplateArgument(T->getArgumentPack()); 375 } 376 void VisitAutoType(const AutoType *T) { 377 if (T->isDecltypeAuto()) OS << " decltype(auto)"; 378 if (!T->isDeduced()) 379 OS << " undeduced"; 380 } 381 void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { 382 if (T->isTypeAlias()) OS << " alias"; 383 OS << " "; T->getTemplateName().dump(OS); 384 for (auto &Arg : *T) 385 dumpTemplateArgument(Arg); 386 if (T->isTypeAlias()) 387 dumpTypeAsChild(T->getAliasedType()); 388 } 389 void VisitInjectedClassNameType(const InjectedClassNameType *T) { 390 dumpDeclRef(T->getDecl()); 391 } 392 void VisitObjCInterfaceType(const ObjCInterfaceType *T) { 393 dumpDeclRef(T->getDecl()); 394 } 395 void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { 396 dumpTypeAsChild(T->getPointeeType()); 397 } 398 void VisitAtomicType(const AtomicType *T) { 399 dumpTypeAsChild(T->getValueType()); 400 } 401 void VisitAdjustedType(const AdjustedType *T) { 402 dumpTypeAsChild(T->getOriginalType()); 403 } 404 void VisitPackExpansionType(const PackExpansionType *T) { 405 if (auto N = T->getNumExpansions()) OS << " expansions " << *N; 406 if (!T->isSugared()) 407 dumpTypeAsChild(T->getPattern()); 408 } 409 // FIXME: ElaboratedType, DependentNameType, 410 // DependentTemplateSpecializationType, ObjCObjectType 411 412 // Decls 413 void VisitLabelDecl(const LabelDecl *D); 414 void VisitTypedefDecl(const TypedefDecl *D); 415 void VisitEnumDecl(const EnumDecl *D); 416 void VisitRecordDecl(const RecordDecl *D); 417 void VisitEnumConstantDecl(const EnumConstantDecl *D); 418 void VisitIndirectFieldDecl(const IndirectFieldDecl *D); 419 void VisitFunctionDecl(const FunctionDecl *D); 420 void VisitFieldDecl(const FieldDecl *D); 421 void VisitVarDecl(const VarDecl *D); 422 void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D); 423 void VisitImportDecl(const ImportDecl *D); 424 425 // C++ Decls 426 void VisitNamespaceDecl(const NamespaceDecl *D); 427 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D); 428 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D); 429 void VisitTypeAliasDecl(const TypeAliasDecl *D); 430 void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D); 431 void VisitCXXRecordDecl(const CXXRecordDecl *D); 432 void VisitStaticAssertDecl(const StaticAssertDecl *D); 433 template<typename SpecializationDecl> 434 void VisitTemplateDeclSpecialization(const SpecializationDecl *D, 435 bool DumpExplicitInst, 436 bool DumpRefOnly); 437 template<typename TemplateDecl> 438 void VisitTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst); 439 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); 440 void VisitClassTemplateDecl(const ClassTemplateDecl *D); 441 void VisitClassTemplateSpecializationDecl( 442 const ClassTemplateSpecializationDecl *D); 443 void VisitClassTemplatePartialSpecializationDecl( 444 const ClassTemplatePartialSpecializationDecl *D); 445 void VisitClassScopeFunctionSpecializationDecl( 446 const ClassScopeFunctionSpecializationDecl *D); 447 void VisitVarTemplateDecl(const VarTemplateDecl *D); 448 void VisitVarTemplateSpecializationDecl( 449 const VarTemplateSpecializationDecl *D); 450 void VisitVarTemplatePartialSpecializationDecl( 451 const VarTemplatePartialSpecializationDecl *D); 452 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); 453 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); 454 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); 455 void VisitUsingDecl(const UsingDecl *D); 456 void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D); 457 void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D); 458 void VisitUsingShadowDecl(const UsingShadowDecl *D); 459 void VisitLinkageSpecDecl(const LinkageSpecDecl *D); 460 void VisitAccessSpecDecl(const AccessSpecDecl *D); 461 void VisitFriendDecl(const FriendDecl *D); 462 463 // ObjC Decls 464 void VisitObjCIvarDecl(const ObjCIvarDecl *D); 465 void VisitObjCMethodDecl(const ObjCMethodDecl *D); 466 void VisitObjCCategoryDecl(const ObjCCategoryDecl *D); 467 void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D); 468 void VisitObjCProtocolDecl(const ObjCProtocolDecl *D); 469 void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D); 470 void VisitObjCImplementationDecl(const ObjCImplementationDecl *D); 471 void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D); 472 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); 473 void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); 474 void VisitBlockDecl(const BlockDecl *D); 475 476 // Stmts. 477 void VisitStmt(const Stmt *Node); 478 void VisitDeclStmt(const DeclStmt *Node); 479 void VisitAttributedStmt(const AttributedStmt *Node); 480 void VisitLabelStmt(const LabelStmt *Node); 481 void VisitGotoStmt(const GotoStmt *Node); 482 void VisitCXXCatchStmt(const CXXCatchStmt *Node); 483 484 // Exprs 485 void VisitExpr(const Expr *Node); 486 void VisitCastExpr(const CastExpr *Node); 487 void VisitDeclRefExpr(const DeclRefExpr *Node); 488 void VisitPredefinedExpr(const PredefinedExpr *Node); 489 void VisitCharacterLiteral(const CharacterLiteral *Node); 490 void VisitIntegerLiteral(const IntegerLiteral *Node); 491 void VisitFloatingLiteral(const FloatingLiteral *Node); 492 void VisitStringLiteral(const StringLiteral *Str); 493 void VisitInitListExpr(const InitListExpr *ILE); 494 void VisitUnaryOperator(const UnaryOperator *Node); 495 void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *Node); 496 void VisitMemberExpr(const MemberExpr *Node); 497 void VisitExtVectorElementExpr(const ExtVectorElementExpr *Node); 498 void VisitBinaryOperator(const BinaryOperator *Node); 499 void VisitCompoundAssignOperator(const CompoundAssignOperator *Node); 500 void VisitAddrLabelExpr(const AddrLabelExpr *Node); 501 void VisitBlockExpr(const BlockExpr *Node); 502 void VisitOpaqueValueExpr(const OpaqueValueExpr *Node); 503 504 // C++ 505 void VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node); 506 void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node); 507 void VisitCXXThisExpr(const CXXThisExpr *Node); 508 void VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node); 509 void VisitCXXConstructExpr(const CXXConstructExpr *Node); 510 void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node); 511 void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node); 512 void VisitExprWithCleanups(const ExprWithCleanups *Node); 513 void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node); 514 void dumpCXXTemporary(const CXXTemporary *Temporary); 515 void VisitLambdaExpr(const LambdaExpr *Node) { 516 VisitExpr(Node); 517 dumpDecl(Node->getLambdaClass()); 518 } 519 520 // ObjC 521 void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node); 522 void VisitObjCEncodeExpr(const ObjCEncodeExpr *Node); 523 void VisitObjCMessageExpr(const ObjCMessageExpr *Node); 524 void VisitObjCBoxedExpr(const ObjCBoxedExpr *Node); 525 void VisitObjCSelectorExpr(const ObjCSelectorExpr *Node); 526 void VisitObjCProtocolExpr(const ObjCProtocolExpr *Node); 527 void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node); 528 void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node); 529 void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node); 530 void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node); 531 532 // Comments. 533 const char *getCommandName(unsigned CommandID); 534 void dumpComment(const Comment *C); 535 536 // Inline comments. 537 void visitTextComment(const TextComment *C); 538 void visitInlineCommandComment(const InlineCommandComment *C); 539 void visitHTMLStartTagComment(const HTMLStartTagComment *C); 540 void visitHTMLEndTagComment(const HTMLEndTagComment *C); 541 542 // Block comments. 543 void visitBlockCommandComment(const BlockCommandComment *C); 544 void visitParamCommandComment(const ParamCommandComment *C); 545 void visitTParamCommandComment(const TParamCommandComment *C); 546 void visitVerbatimBlockComment(const VerbatimBlockComment *C); 547 void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C); 548 void visitVerbatimLineComment(const VerbatimLineComment *C); 549 }; 550 } 551 552 //===----------------------------------------------------------------------===// 553 // Utilities 554 //===----------------------------------------------------------------------===// 555 556 void ASTDumper::dumpPointer(const void *Ptr) { 557 ColorScope Color(*this, AddressColor); 558 OS << ' ' << Ptr; 559 } 560 561 void ASTDumper::dumpLocation(SourceLocation Loc) { 562 if (!SM) 563 return; 564 565 ColorScope Color(*this, LocationColor); 566 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); 567 568 // The general format we print out is filename:line:col, but we drop pieces 569 // that haven't changed since the last loc printed. 570 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); 571 572 if (PLoc.isInvalid()) { 573 OS << "<invalid sloc>"; 574 return; 575 } 576 577 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { 578 OS << PLoc.getFilename() << ':' << PLoc.getLine() 579 << ':' << PLoc.getColumn(); 580 LastLocFilename = PLoc.getFilename(); 581 LastLocLine = PLoc.getLine(); 582 } else if (PLoc.getLine() != LastLocLine) { 583 OS << "line" << ':' << PLoc.getLine() 584 << ':' << PLoc.getColumn(); 585 LastLocLine = PLoc.getLine(); 586 } else { 587 OS << "col" << ':' << PLoc.getColumn(); 588 } 589 } 590 591 void ASTDumper::dumpSourceRange(SourceRange R) { 592 // Can't translate locations if a SourceManager isn't available. 593 if (!SM) 594 return; 595 596 OS << " <"; 597 dumpLocation(R.getBegin()); 598 if (R.getBegin() != R.getEnd()) { 599 OS << ", "; 600 dumpLocation(R.getEnd()); 601 } 602 OS << ">"; 603 604 // <t2.c:123:421[blah], t2.c:412:321> 605 606 } 607 608 void ASTDumper::dumpBareType(QualType T, bool Desugar) { 609 ColorScope Color(*this, TypeColor); 610 611 SplitQualType T_split = T.split(); 612 OS << "'" << QualType::getAsString(T_split) << "'"; 613 614 if (Desugar && !T.isNull()) { 615 // If the type is sugared, also dump a (shallow) desugared type. 616 SplitQualType D_split = T.getSplitDesugaredType(); 617 if (T_split != D_split) 618 OS << ":'" << QualType::getAsString(D_split) << "'"; 619 } 620 } 621 622 void ASTDumper::dumpType(QualType T) { 623 OS << ' '; 624 dumpBareType(T); 625 } 626 627 void ASTDumper::dumpTypeAsChild(QualType T) { 628 SplitQualType SQT = T.split(); 629 if (!SQT.Quals.hasQualifiers()) 630 return dumpTypeAsChild(SQT.Ty); 631 632 dumpChild([=] { 633 OS << "QualType"; 634 dumpPointer(T.getAsOpaquePtr()); 635 OS << " "; 636 dumpBareType(T, false); 637 OS << " " << T.split().Quals.getAsString(); 638 dumpTypeAsChild(T.split().Ty); 639 }); 640 } 641 642 void ASTDumper::dumpTypeAsChild(const Type *T) { 643 dumpChild([=] { 644 if (!T) { 645 ColorScope Color(*this, NullColor); 646 OS << "<<<NULL>>>"; 647 return; 648 } 649 650 { 651 ColorScope Color(*this, TypeColor); 652 OS << T->getTypeClassName() << "Type"; 653 } 654 dumpPointer(T); 655 OS << " "; 656 dumpBareType(QualType(T, 0), false); 657 658 QualType SingleStepDesugar = 659 T->getLocallyUnqualifiedSingleStepDesugaredType(); 660 if (SingleStepDesugar != QualType(T, 0)) 661 OS << " sugar"; 662 if (T->isDependentType()) 663 OS << " dependent"; 664 else if (T->isInstantiationDependentType()) 665 OS << " instantiation_dependent"; 666 if (T->isVariablyModifiedType()) 667 OS << " variably_modified"; 668 if (T->containsUnexpandedParameterPack()) 669 OS << " contains_unexpanded_pack"; 670 if (T->isFromAST()) 671 OS << " imported"; 672 673 TypeVisitor<ASTDumper>::Visit(T); 674 675 if (SingleStepDesugar != QualType(T, 0)) 676 dumpTypeAsChild(SingleStepDesugar); 677 }); 678 } 679 680 void ASTDumper::dumpBareDeclRef(const Decl *D) { 681 { 682 ColorScope Color(*this, DeclKindNameColor); 683 OS << D->getDeclKindName(); 684 } 685 dumpPointer(D); 686 687 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 688 ColorScope Color(*this, DeclNameColor); 689 OS << " '" << ND->getDeclName() << '\''; 690 } 691 692 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 693 dumpType(VD->getType()); 694 } 695 696 void ASTDumper::dumpDeclRef(const Decl *D, const char *Label) { 697 if (!D) 698 return; 699 700 dumpChild([=]{ 701 if (Label) 702 OS << Label << ' '; 703 dumpBareDeclRef(D); 704 }); 705 } 706 707 void ASTDumper::dumpName(const NamedDecl *ND) { 708 if (ND->getDeclName()) { 709 ColorScope Color(*this, DeclNameColor); 710 OS << ' ' << ND->getNameAsString(); 711 } 712 } 713 714 bool ASTDumper::hasNodes(const DeclContext *DC) { 715 if (!DC) 716 return false; 717 718 return DC->hasExternalLexicalStorage() || 719 DC->noload_decls_begin() != DC->noload_decls_end(); 720 } 721 722 void ASTDumper::dumpDeclContext(const DeclContext *DC) { 723 if (!DC) 724 return; 725 726 for (auto *D : DC->noload_decls()) 727 dumpDecl(D); 728 729 if (DC->hasExternalLexicalStorage()) { 730 dumpChild([=]{ 731 ColorScope Color(*this, UndeserializedColor); 732 OS << "<undeserialized declarations>"; 733 }); 734 } 735 } 736 737 void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) { 738 dumpChild([=] { 739 OS << "StoredDeclsMap "; 740 dumpBareDeclRef(cast<Decl>(DC)); 741 742 const DeclContext *Primary = DC->getPrimaryContext(); 743 if (Primary != DC) { 744 OS << " primary"; 745 dumpPointer(cast<Decl>(Primary)); 746 } 747 748 bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage(); 749 750 DeclContext::all_lookups_iterator I = Primary->noload_lookups_begin(), 751 E = Primary->noload_lookups_end(); 752 while (I != E) { 753 DeclarationName Name = I.getLookupName(); 754 DeclContextLookupResult R = *I++; 755 756 dumpChild([=] { 757 OS << "DeclarationName "; 758 { 759 ColorScope Color(*this, DeclNameColor); 760 OS << '\'' << Name << '\''; 761 } 762 763 for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end(); 764 RI != RE; ++RI) { 765 dumpChild([=] { 766 dumpBareDeclRef(*RI); 767 768 if ((*RI)->isHidden()) 769 OS << " hidden"; 770 771 // If requested, dump the redecl chain for this lookup. 772 if (DumpDecls) { 773 // Dump earliest decl first. 774 std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) { 775 if (Decl *Prev = D->getPreviousDecl()) 776 DumpWithPrev(Prev); 777 dumpDecl(D); 778 }; 779 DumpWithPrev(*RI); 780 } 781 }); 782 } 783 }); 784 } 785 786 if (HasUndeserializedLookups) { 787 dumpChild([=] { 788 ColorScope Color(*this, UndeserializedColor); 789 OS << "<undeserialized lookups>"; 790 }); 791 } 792 }); 793 } 794 795 void ASTDumper::dumpAttr(const Attr *A) { 796 dumpChild([=] { 797 { 798 ColorScope Color(*this, AttrColor); 799 800 switch (A->getKind()) { 801 #define ATTR(X) case attr::X: OS << #X; break; 802 #include "clang/Basic/AttrList.inc" 803 default: 804 llvm_unreachable("unexpected attribute kind"); 805 } 806 OS << "Attr"; 807 } 808 dumpPointer(A); 809 dumpSourceRange(A->getRange()); 810 if (A->isInherited()) 811 OS << " Inherited"; 812 if (A->isImplicit()) 813 OS << " Implicit"; 814 #include "clang/AST/AttrDump.inc" 815 }); 816 } 817 818 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} 819 820 template<typename T> 821 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) { 822 const T *First = D->getFirstDecl(); 823 if (First != D) 824 OS << " first " << First; 825 } 826 827 template<typename T> 828 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) { 829 const T *Prev = D->getPreviousDecl(); 830 if (Prev) 831 OS << " prev " << Prev; 832 } 833 834 /// Dump the previous declaration in the redeclaration chain for a declaration, 835 /// if any. 836 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) { 837 switch (D->getKind()) { 838 #define DECL(DERIVED, BASE) \ 839 case Decl::DERIVED: \ 840 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D)); 841 #define ABSTRACT_DECL(DECL) 842 #include "clang/AST/DeclNodes.inc" 843 } 844 llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); 845 } 846 847 //===----------------------------------------------------------------------===// 848 // C++ Utilities 849 //===----------------------------------------------------------------------===// 850 851 void ASTDumper::dumpAccessSpecifier(AccessSpecifier AS) { 852 switch (AS) { 853 case AS_none: 854 break; 855 case AS_public: 856 OS << "public"; 857 break; 858 case AS_protected: 859 OS << "protected"; 860 break; 861 case AS_private: 862 OS << "private"; 863 break; 864 } 865 } 866 867 void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) { 868 dumpChild([=] { 869 OS << "CXXCtorInitializer"; 870 if (Init->isAnyMemberInitializer()) { 871 OS << ' '; 872 dumpBareDeclRef(Init->getAnyMember()); 873 } else if (Init->isBaseInitializer()) { 874 dumpType(QualType(Init->getBaseClass(), 0)); 875 } else if (Init->isDelegatingInitializer()) { 876 dumpType(Init->getTypeSourceInfo()->getType()); 877 } else { 878 llvm_unreachable("Unknown initializer type"); 879 } 880 dumpStmt(Init->getInit()); 881 }); 882 } 883 884 void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) { 885 if (!TPL) 886 return; 887 888 for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end(); 889 I != E; ++I) 890 dumpDecl(*I); 891 } 892 893 void ASTDumper::dumpTemplateArgumentListInfo( 894 const TemplateArgumentListInfo &TALI) { 895 for (unsigned i = 0, e = TALI.size(); i < e; ++i) 896 dumpTemplateArgumentLoc(TALI[i]); 897 } 898 899 void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) { 900 dumpTemplateArgument(A.getArgument(), A.getSourceRange()); 901 } 902 903 void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { 904 for (unsigned i = 0, e = TAL.size(); i < e; ++i) 905 dumpTemplateArgument(TAL[i]); 906 } 907 908 void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) { 909 dumpChild([=] { 910 OS << "TemplateArgument"; 911 if (R.isValid()) 912 dumpSourceRange(R); 913 914 switch (A.getKind()) { 915 case TemplateArgument::Null: 916 OS << " null"; 917 break; 918 case TemplateArgument::Type: 919 OS << " type"; 920 dumpType(A.getAsType()); 921 break; 922 case TemplateArgument::Declaration: 923 OS << " decl"; 924 dumpDeclRef(A.getAsDecl()); 925 break; 926 case TemplateArgument::NullPtr: 927 OS << " nullptr"; 928 break; 929 case TemplateArgument::Integral: 930 OS << " integral " << A.getAsIntegral(); 931 break; 932 case TemplateArgument::Template: 933 OS << " template "; 934 A.getAsTemplate().dump(OS); 935 break; 936 case TemplateArgument::TemplateExpansion: 937 OS << " template expansion"; 938 A.getAsTemplateOrTemplatePattern().dump(OS); 939 break; 940 case TemplateArgument::Expression: 941 OS << " expr"; 942 dumpStmt(A.getAsExpr()); 943 break; 944 case TemplateArgument::Pack: 945 OS << " pack"; 946 for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end(); 947 I != E; ++I) 948 dumpTemplateArgument(*I); 949 break; 950 } 951 }); 952 } 953 954 //===----------------------------------------------------------------------===// 955 // Decl dumping methods. 956 //===----------------------------------------------------------------------===// 957 958 void ASTDumper::dumpDecl(const Decl *D) { 959 dumpChild([=] { 960 if (!D) { 961 ColorScope Color(*this, NullColor); 962 OS << "<<<NULL>>>"; 963 return; 964 } 965 966 { 967 ColorScope Color(*this, DeclKindNameColor); 968 OS << D->getDeclKindName() << "Decl"; 969 } 970 dumpPointer(D); 971 if (D->getLexicalDeclContext() != D->getDeclContext()) 972 OS << " parent " << cast<Decl>(D->getDeclContext()); 973 dumpPreviousDecl(OS, D); 974 dumpSourceRange(D->getSourceRange()); 975 OS << ' '; 976 dumpLocation(D->getLocation()); 977 if (Module *M = D->getOwningModule()) 978 OS << " in " << M->getFullModuleName(); 979 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 980 if (ND->isHidden()) 981 OS << " hidden"; 982 if (D->isImplicit()) 983 OS << " implicit"; 984 if (D->isUsed()) 985 OS << " used"; 986 else if (D->isThisDeclarationReferenced()) 987 OS << " referenced"; 988 if (D->isInvalidDecl()) 989 OS << " invalid"; 990 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 991 if (FD->isConstexpr()) 992 OS << " constexpr"; 993 994 995 ConstDeclVisitor<ASTDumper>::Visit(D); 996 997 for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); I != E; 998 ++I) 999 dumpAttr(*I); 1000 1001 if (const FullComment *Comment = 1002 D->getASTContext().getLocalCommentForDeclUncached(D)) 1003 dumpFullComment(Comment); 1004 1005 // Decls within functions are visited by the body. 1006 if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) && 1007 hasNodes(dyn_cast<DeclContext>(D))) 1008 dumpDeclContext(cast<DeclContext>(D)); 1009 }); 1010 } 1011 1012 void ASTDumper::VisitLabelDecl(const LabelDecl *D) { 1013 dumpName(D); 1014 } 1015 1016 void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) { 1017 dumpName(D); 1018 dumpType(D->getUnderlyingType()); 1019 if (D->isModulePrivate()) 1020 OS << " __module_private__"; 1021 } 1022 1023 void ASTDumper::VisitEnumDecl(const EnumDecl *D) { 1024 if (D->isScoped()) { 1025 if (D->isScopedUsingClassTag()) 1026 OS << " class"; 1027 else 1028 OS << " struct"; 1029 } 1030 dumpName(D); 1031 if (D->isModulePrivate()) 1032 OS << " __module_private__"; 1033 if (D->isFixed()) 1034 dumpType(D->getIntegerType()); 1035 } 1036 1037 void ASTDumper::VisitRecordDecl(const RecordDecl *D) { 1038 OS << ' ' << D->getKindName(); 1039 dumpName(D); 1040 if (D->isModulePrivate()) 1041 OS << " __module_private__"; 1042 if (D->isCompleteDefinition()) 1043 OS << " definition"; 1044 } 1045 1046 void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { 1047 dumpName(D); 1048 dumpType(D->getType()); 1049 if (const Expr *Init = D->getInitExpr()) 1050 dumpStmt(Init); 1051 } 1052 1053 void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { 1054 dumpName(D); 1055 dumpType(D->getType()); 1056 1057 for (auto *Child : D->chain()) 1058 dumpDeclRef(Child); 1059 } 1060 1061 void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { 1062 dumpName(D); 1063 dumpType(D->getType()); 1064 1065 StorageClass SC = D->getStorageClass(); 1066 if (SC != SC_None) 1067 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 1068 if (D->isInlineSpecified()) 1069 OS << " inline"; 1070 if (D->isVirtualAsWritten()) 1071 OS << " virtual"; 1072 if (D->isModulePrivate()) 1073 OS << " __module_private__"; 1074 1075 if (D->isPure()) 1076 OS << " pure"; 1077 else if (D->isDeletedAsWritten()) 1078 OS << " delete"; 1079 1080 if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) { 1081 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 1082 switch (EPI.ExceptionSpec.Type) { 1083 default: break; 1084 case EST_Unevaluated: 1085 OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl; 1086 break; 1087 case EST_Uninstantiated: 1088 OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate; 1089 break; 1090 } 1091 } 1092 1093 if (const FunctionTemplateSpecializationInfo *FTSI = 1094 D->getTemplateSpecializationInfo()) 1095 dumpTemplateArgumentList(*FTSI->TemplateArguments); 1096 1097 for (ArrayRef<NamedDecl *>::iterator 1098 I = D->getDeclsInPrototypeScope().begin(), 1099 E = D->getDeclsInPrototypeScope().end(); I != E; ++I) 1100 dumpDecl(*I); 1101 1102 if (!D->param_begin() && D->getNumParams()) 1103 dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; }); 1104 else 1105 for (FunctionDecl::param_const_iterator I = D->param_begin(), 1106 E = D->param_end(); 1107 I != E; ++I) 1108 dumpDecl(*I); 1109 1110 if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D)) 1111 for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), 1112 E = C->init_end(); 1113 I != E; ++I) 1114 dumpCXXCtorInitializer(*I); 1115 1116 if (D->doesThisDeclarationHaveABody()) 1117 dumpStmt(D->getBody()); 1118 } 1119 1120 void ASTDumper::VisitFieldDecl(const FieldDecl *D) { 1121 dumpName(D); 1122 dumpType(D->getType()); 1123 if (D->isMutable()) 1124 OS << " mutable"; 1125 if (D->isModulePrivate()) 1126 OS << " __module_private__"; 1127 1128 if (D->isBitField()) 1129 dumpStmt(D->getBitWidth()); 1130 if (Expr *Init = D->getInClassInitializer()) 1131 dumpStmt(Init); 1132 } 1133 1134 void ASTDumper::VisitVarDecl(const VarDecl *D) { 1135 dumpName(D); 1136 dumpType(D->getType()); 1137 StorageClass SC = D->getStorageClass(); 1138 if (SC != SC_None) 1139 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 1140 switch (D->getTLSKind()) { 1141 case VarDecl::TLS_None: break; 1142 case VarDecl::TLS_Static: OS << " tls"; break; 1143 case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break; 1144 } 1145 if (D->isModulePrivate()) 1146 OS << " __module_private__"; 1147 if (D->isNRVOVariable()) 1148 OS << " nrvo"; 1149 if (D->hasInit()) { 1150 switch (D->getInitStyle()) { 1151 case VarDecl::CInit: OS << " cinit"; break; 1152 case VarDecl::CallInit: OS << " callinit"; break; 1153 case VarDecl::ListInit: OS << " listinit"; break; 1154 } 1155 dumpStmt(D->getInit()); 1156 } 1157 } 1158 1159 void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { 1160 dumpStmt(D->getAsmString()); 1161 } 1162 1163 void ASTDumper::VisitImportDecl(const ImportDecl *D) { 1164 OS << ' ' << D->getImportedModule()->getFullModuleName(); 1165 } 1166 1167 //===----------------------------------------------------------------------===// 1168 // C++ Declarations 1169 //===----------------------------------------------------------------------===// 1170 1171 void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 1172 dumpName(D); 1173 if (D->isInline()) 1174 OS << " inline"; 1175 if (!D->isOriginalNamespace()) 1176 dumpDeclRef(D->getOriginalNamespace(), "original"); 1177 } 1178 1179 void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 1180 OS << ' '; 1181 dumpBareDeclRef(D->getNominatedNamespace()); 1182 } 1183 1184 void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 1185 dumpName(D); 1186 dumpDeclRef(D->getAliasedNamespace()); 1187 } 1188 1189 void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 1190 dumpName(D); 1191 dumpType(D->getUnderlyingType()); 1192 } 1193 1194 void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { 1195 dumpName(D); 1196 dumpTemplateParameters(D->getTemplateParameters()); 1197 dumpDecl(D->getTemplatedDecl()); 1198 } 1199 1200 void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 1201 VisitRecordDecl(D); 1202 if (!D->isCompleteDefinition()) 1203 return; 1204 1205 for (const auto &I : D->bases()) { 1206 dumpChild([=] { 1207 if (I.isVirtual()) 1208 OS << "virtual "; 1209 dumpAccessSpecifier(I.getAccessSpecifier()); 1210 dumpType(I.getType()); 1211 if (I.isPackExpansion()) 1212 OS << "..."; 1213 }); 1214 } 1215 } 1216 1217 void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) { 1218 dumpStmt(D->getAssertExpr()); 1219 dumpStmt(D->getMessage()); 1220 } 1221 1222 template<typename SpecializationDecl> 1223 void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D, 1224 bool DumpExplicitInst, 1225 bool DumpRefOnly) { 1226 bool DumpedAny = false; 1227 for (auto *RedeclWithBadType : D->redecls()) { 1228 // FIXME: The redecls() range sometimes has elements of a less-specific 1229 // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives 1230 // us TagDecls, and should give CXXRecordDecls). 1231 auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType); 1232 if (!Redecl) { 1233 // Found the injected-class-name for a class template. This will be dumped 1234 // as part of its surrounding class so we don't need to dump it here. 1235 assert(isa<CXXRecordDecl>(RedeclWithBadType) && 1236 "expected an injected-class-name"); 1237 continue; 1238 } 1239 1240 switch (Redecl->getTemplateSpecializationKind()) { 1241 case TSK_ExplicitInstantiationDeclaration: 1242 case TSK_ExplicitInstantiationDefinition: 1243 if (!DumpExplicitInst) 1244 break; 1245 // Fall through. 1246 case TSK_Undeclared: 1247 case TSK_ImplicitInstantiation: 1248 if (DumpRefOnly) 1249 dumpDeclRef(Redecl); 1250 else 1251 dumpDecl(Redecl); 1252 DumpedAny = true; 1253 break; 1254 case TSK_ExplicitSpecialization: 1255 break; 1256 } 1257 } 1258 1259 // Ensure we dump at least one decl for each specialization. 1260 if (!DumpedAny) 1261 dumpDeclRef(D); 1262 } 1263 1264 template<typename TemplateDecl> 1265 void ASTDumper::VisitTemplateDecl(const TemplateDecl *D, 1266 bool DumpExplicitInst) { 1267 dumpName(D); 1268 dumpTemplateParameters(D->getTemplateParameters()); 1269 1270 dumpDecl(D->getTemplatedDecl()); 1271 1272 for (auto *Child : D->specializations()) 1273 VisitTemplateDeclSpecialization(Child, DumpExplicitInst, 1274 !D->isCanonicalDecl()); 1275 } 1276 1277 void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 1278 // FIXME: We don't add a declaration of a function template specialization 1279 // to its context when it's explicitly instantiated, so dump explicit 1280 // instantiations when we dump the template itself. 1281 VisitTemplateDecl(D, true); 1282 } 1283 1284 void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 1285 VisitTemplateDecl(D, false); 1286 } 1287 1288 void ASTDumper::VisitClassTemplateSpecializationDecl( 1289 const ClassTemplateSpecializationDecl *D) { 1290 VisitCXXRecordDecl(D); 1291 dumpTemplateArgumentList(D->getTemplateArgs()); 1292 } 1293 1294 void ASTDumper::VisitClassTemplatePartialSpecializationDecl( 1295 const ClassTemplatePartialSpecializationDecl *D) { 1296 VisitClassTemplateSpecializationDecl(D); 1297 dumpTemplateParameters(D->getTemplateParameters()); 1298 } 1299 1300 void ASTDumper::VisitClassScopeFunctionSpecializationDecl( 1301 const ClassScopeFunctionSpecializationDecl *D) { 1302 dumpDeclRef(D->getSpecialization()); 1303 if (D->hasExplicitTemplateArgs()) 1304 dumpTemplateArgumentListInfo(D->templateArgs()); 1305 } 1306 1307 void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { 1308 VisitTemplateDecl(D, false); 1309 } 1310 1311 void ASTDumper::VisitVarTemplateSpecializationDecl( 1312 const VarTemplateSpecializationDecl *D) { 1313 dumpTemplateArgumentList(D->getTemplateArgs()); 1314 VisitVarDecl(D); 1315 } 1316 1317 void ASTDumper::VisitVarTemplatePartialSpecializationDecl( 1318 const VarTemplatePartialSpecializationDecl *D) { 1319 dumpTemplateParameters(D->getTemplateParameters()); 1320 VisitVarTemplateSpecializationDecl(D); 1321 } 1322 1323 void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 1324 if (D->wasDeclaredWithTypename()) 1325 OS << " typename"; 1326 else 1327 OS << " class"; 1328 if (D->isParameterPack()) 1329 OS << " ..."; 1330 dumpName(D); 1331 if (D->hasDefaultArgument()) 1332 dumpTemplateArgument(D->getDefaultArgument()); 1333 } 1334 1335 void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { 1336 dumpType(D->getType()); 1337 if (D->isParameterPack()) 1338 OS << " ..."; 1339 dumpName(D); 1340 if (D->hasDefaultArgument()) 1341 dumpTemplateArgument(D->getDefaultArgument()); 1342 } 1343 1344 void ASTDumper::VisitTemplateTemplateParmDecl( 1345 const TemplateTemplateParmDecl *D) { 1346 if (D->isParameterPack()) 1347 OS << " ..."; 1348 dumpName(D); 1349 dumpTemplateParameters(D->getTemplateParameters()); 1350 if (D->hasDefaultArgument()) 1351 dumpTemplateArgumentLoc(D->getDefaultArgument()); 1352 } 1353 1354 void ASTDumper::VisitUsingDecl(const UsingDecl *D) { 1355 OS << ' '; 1356 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1357 OS << D->getNameAsString(); 1358 } 1359 1360 void ASTDumper::VisitUnresolvedUsingTypenameDecl( 1361 const UnresolvedUsingTypenameDecl *D) { 1362 OS << ' '; 1363 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1364 OS << D->getNameAsString(); 1365 } 1366 1367 void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 1368 OS << ' '; 1369 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1370 OS << D->getNameAsString(); 1371 dumpType(D->getType()); 1372 } 1373 1374 void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 1375 OS << ' '; 1376 dumpBareDeclRef(D->getTargetDecl()); 1377 } 1378 1379 void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 1380 switch (D->getLanguage()) { 1381 case LinkageSpecDecl::lang_c: OS << " C"; break; 1382 case LinkageSpecDecl::lang_cxx: OS << " C++"; break; 1383 } 1384 } 1385 1386 void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 1387 OS << ' '; 1388 dumpAccessSpecifier(D->getAccess()); 1389 } 1390 1391 void ASTDumper::VisitFriendDecl(const FriendDecl *D) { 1392 if (TypeSourceInfo *T = D->getFriendType()) 1393 dumpType(T->getType()); 1394 else 1395 dumpDecl(D->getFriendDecl()); 1396 } 1397 1398 //===----------------------------------------------------------------------===// 1399 // Obj-C Declarations 1400 //===----------------------------------------------------------------------===// 1401 1402 void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 1403 dumpName(D); 1404 dumpType(D->getType()); 1405 if (D->getSynthesize()) 1406 OS << " synthesize"; 1407 1408 switch (D->getAccessControl()) { 1409 case ObjCIvarDecl::None: 1410 OS << " none"; 1411 break; 1412 case ObjCIvarDecl::Private: 1413 OS << " private"; 1414 break; 1415 case ObjCIvarDecl::Protected: 1416 OS << " protected"; 1417 break; 1418 case ObjCIvarDecl::Public: 1419 OS << " public"; 1420 break; 1421 case ObjCIvarDecl::Package: 1422 OS << " package"; 1423 break; 1424 } 1425 } 1426 1427 void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 1428 if (D->isInstanceMethod()) 1429 OS << " -"; 1430 else 1431 OS << " +"; 1432 dumpName(D); 1433 dumpType(D->getReturnType()); 1434 1435 if (D->isThisDeclarationADefinition()) { 1436 dumpDeclContext(D); 1437 } else { 1438 for (ObjCMethodDecl::param_const_iterator I = D->param_begin(), 1439 E = D->param_end(); 1440 I != E; ++I) 1441 dumpDecl(*I); 1442 } 1443 1444 if (D->isVariadic()) 1445 dumpChild([=] { OS << "..."; }); 1446 1447 if (D->hasBody()) 1448 dumpStmt(D->getBody()); 1449 } 1450 1451 void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 1452 dumpName(D); 1453 dumpDeclRef(D->getClassInterface()); 1454 dumpDeclRef(D->getImplementation()); 1455 for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), 1456 E = D->protocol_end(); 1457 I != E; ++I) 1458 dumpDeclRef(*I); 1459 } 1460 1461 void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 1462 dumpName(D); 1463 dumpDeclRef(D->getClassInterface()); 1464 dumpDeclRef(D->getCategoryDecl()); 1465 } 1466 1467 void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 1468 dumpName(D); 1469 1470 for (auto *Child : D->protocols()) 1471 dumpDeclRef(Child); 1472 } 1473 1474 void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 1475 dumpName(D); 1476 dumpDeclRef(D->getSuperClass(), "super"); 1477 1478 dumpDeclRef(D->getImplementation()); 1479 for (auto *Child : D->protocols()) 1480 dumpDeclRef(Child); 1481 } 1482 1483 void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { 1484 dumpName(D); 1485 dumpDeclRef(D->getSuperClass(), "super"); 1486 dumpDeclRef(D->getClassInterface()); 1487 for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), 1488 E = D->init_end(); 1489 I != E; ++I) 1490 dumpCXXCtorInitializer(*I); 1491 } 1492 1493 void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { 1494 dumpName(D); 1495 dumpDeclRef(D->getClassInterface()); 1496 } 1497 1498 void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 1499 dumpName(D); 1500 dumpType(D->getType()); 1501 1502 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 1503 OS << " required"; 1504 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1505 OS << " optional"; 1506 1507 ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes(); 1508 if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) { 1509 if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly) 1510 OS << " readonly"; 1511 if (Attrs & ObjCPropertyDecl::OBJC_PR_assign) 1512 OS << " assign"; 1513 if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite) 1514 OS << " readwrite"; 1515 if (Attrs & ObjCPropertyDecl::OBJC_PR_retain) 1516 OS << " retain"; 1517 if (Attrs & ObjCPropertyDecl::OBJC_PR_copy) 1518 OS << " copy"; 1519 if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) 1520 OS << " nonatomic"; 1521 if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic) 1522 OS << " atomic"; 1523 if (Attrs & ObjCPropertyDecl::OBJC_PR_weak) 1524 OS << " weak"; 1525 if (Attrs & ObjCPropertyDecl::OBJC_PR_strong) 1526 OS << " strong"; 1527 if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) 1528 OS << " unsafe_unretained"; 1529 if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) 1530 dumpDeclRef(D->getGetterMethodDecl(), "getter"); 1531 if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) 1532 dumpDeclRef(D->getSetterMethodDecl(), "setter"); 1533 } 1534 } 1535 1536 void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 1537 dumpName(D->getPropertyDecl()); 1538 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1539 OS << " synthesize"; 1540 else 1541 OS << " dynamic"; 1542 dumpDeclRef(D->getPropertyDecl()); 1543 dumpDeclRef(D->getPropertyIvarDecl()); 1544 } 1545 1546 void ASTDumper::VisitBlockDecl(const BlockDecl *D) { 1547 for (auto I : D->params()) 1548 dumpDecl(I); 1549 1550 if (D->isVariadic()) 1551 dumpChild([=]{ OS << "..."; }); 1552 1553 if (D->capturesCXXThis()) 1554 dumpChild([=]{ OS << "capture this"; }); 1555 1556 for (const auto &I : D->captures()) { 1557 dumpChild([=] { 1558 OS << "capture"; 1559 if (I.isByRef()) 1560 OS << " byref"; 1561 if (I.isNested()) 1562 OS << " nested"; 1563 if (I.getVariable()) { 1564 OS << ' '; 1565 dumpBareDeclRef(I.getVariable()); 1566 } 1567 if (I.hasCopyExpr()) 1568 dumpStmt(I.getCopyExpr()); 1569 }); 1570 } 1571 dumpStmt(D->getBody()); 1572 } 1573 1574 //===----------------------------------------------------------------------===// 1575 // Stmt dumping methods. 1576 //===----------------------------------------------------------------------===// 1577 1578 void ASTDumper::dumpStmt(const Stmt *S) { 1579 dumpChild([=] { 1580 if (!S) { 1581 ColorScope Color(*this, NullColor); 1582 OS << "<<<NULL>>>"; 1583 return; 1584 } 1585 1586 if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 1587 VisitDeclStmt(DS); 1588 return; 1589 } 1590 1591 ConstStmtVisitor<ASTDumper>::Visit(S); 1592 1593 for (Stmt::const_child_range CI = S->children(); CI; ++CI) 1594 dumpStmt(*CI); 1595 }); 1596 } 1597 1598 void ASTDumper::VisitStmt(const Stmt *Node) { 1599 { 1600 ColorScope Color(*this, StmtColor); 1601 OS << Node->getStmtClassName(); 1602 } 1603 dumpPointer(Node); 1604 dumpSourceRange(Node->getSourceRange()); 1605 } 1606 1607 void ASTDumper::VisitDeclStmt(const DeclStmt *Node) { 1608 VisitStmt(Node); 1609 for (DeclStmt::const_decl_iterator I = Node->decl_begin(), 1610 E = Node->decl_end(); 1611 I != E; ++I) 1612 dumpDecl(*I); 1613 } 1614 1615 void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) { 1616 VisitStmt(Node); 1617 for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(), 1618 E = Node->getAttrs().end(); 1619 I != E; ++I) 1620 dumpAttr(*I); 1621 } 1622 1623 void ASTDumper::VisitLabelStmt(const LabelStmt *Node) { 1624 VisitStmt(Node); 1625 OS << " '" << Node->getName() << "'"; 1626 } 1627 1628 void ASTDumper::VisitGotoStmt(const GotoStmt *Node) { 1629 VisitStmt(Node); 1630 OS << " '" << Node->getLabel()->getName() << "'"; 1631 dumpPointer(Node->getLabel()); 1632 } 1633 1634 void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) { 1635 VisitStmt(Node); 1636 dumpDecl(Node->getExceptionDecl()); 1637 } 1638 1639 //===----------------------------------------------------------------------===// 1640 // Expr dumping methods. 1641 //===----------------------------------------------------------------------===// 1642 1643 void ASTDumper::VisitExpr(const Expr *Node) { 1644 VisitStmt(Node); 1645 dumpType(Node->getType()); 1646 1647 { 1648 ColorScope Color(*this, ValueKindColor); 1649 switch (Node->getValueKind()) { 1650 case VK_RValue: 1651 break; 1652 case VK_LValue: 1653 OS << " lvalue"; 1654 break; 1655 case VK_XValue: 1656 OS << " xvalue"; 1657 break; 1658 } 1659 } 1660 1661 { 1662 ColorScope Color(*this, ObjectKindColor); 1663 switch (Node->getObjectKind()) { 1664 case OK_Ordinary: 1665 break; 1666 case OK_BitField: 1667 OS << " bitfield"; 1668 break; 1669 case OK_ObjCProperty: 1670 OS << " objcproperty"; 1671 break; 1672 case OK_ObjCSubscript: 1673 OS << " objcsubscript"; 1674 break; 1675 case OK_VectorComponent: 1676 OS << " vectorcomponent"; 1677 break; 1678 } 1679 } 1680 } 1681 1682 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { 1683 if (Node->path_empty()) 1684 return; 1685 1686 OS << " ("; 1687 bool First = true; 1688 for (CastExpr::path_const_iterator I = Node->path_begin(), 1689 E = Node->path_end(); 1690 I != E; ++I) { 1691 const CXXBaseSpecifier *Base = *I; 1692 if (!First) 1693 OS << " -> "; 1694 1695 const CXXRecordDecl *RD = 1696 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 1697 1698 if (Base->isVirtual()) 1699 OS << "virtual "; 1700 OS << RD->getName(); 1701 First = false; 1702 } 1703 1704 OS << ')'; 1705 } 1706 1707 void ASTDumper::VisitCastExpr(const CastExpr *Node) { 1708 VisitExpr(Node); 1709 OS << " <"; 1710 { 1711 ColorScope Color(*this, CastColor); 1712 OS << Node->getCastKindName(); 1713 } 1714 dumpBasePath(OS, Node); 1715 OS << ">"; 1716 } 1717 1718 void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { 1719 VisitExpr(Node); 1720 1721 OS << " "; 1722 dumpBareDeclRef(Node->getDecl()); 1723 if (Node->getDecl() != Node->getFoundDecl()) { 1724 OS << " ("; 1725 dumpBareDeclRef(Node->getFoundDecl()); 1726 OS << ")"; 1727 } 1728 } 1729 1730 void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) { 1731 VisitExpr(Node); 1732 OS << " ("; 1733 if (!Node->requiresADL()) 1734 OS << "no "; 1735 OS << "ADL) = '" << Node->getName() << '\''; 1736 1737 UnresolvedLookupExpr::decls_iterator 1738 I = Node->decls_begin(), E = Node->decls_end(); 1739 if (I == E) 1740 OS << " empty"; 1741 for (; I != E; ++I) 1742 dumpPointer(*I); 1743 } 1744 1745 void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { 1746 VisitExpr(Node); 1747 1748 { 1749 ColorScope Color(*this, DeclKindNameColor); 1750 OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; 1751 } 1752 OS << "='" << *Node->getDecl() << "'"; 1753 dumpPointer(Node->getDecl()); 1754 if (Node->isFreeIvar()) 1755 OS << " isFreeIvar"; 1756 } 1757 1758 void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { 1759 VisitExpr(Node); 1760 OS << " " << PredefinedExpr::getIdentTypeName(Node->getIdentType()); 1761 } 1762 1763 void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { 1764 VisitExpr(Node); 1765 ColorScope Color(*this, ValueColor); 1766 OS << " " << Node->getValue(); 1767 } 1768 1769 void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) { 1770 VisitExpr(Node); 1771 1772 bool isSigned = Node->getType()->isSignedIntegerType(); 1773 ColorScope Color(*this, ValueColor); 1774 OS << " " << Node->getValue().toString(10, isSigned); 1775 } 1776 1777 void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { 1778 VisitExpr(Node); 1779 ColorScope Color(*this, ValueColor); 1780 OS << " " << Node->getValueAsApproximateDouble(); 1781 } 1782 1783 void ASTDumper::VisitStringLiteral(const StringLiteral *Str) { 1784 VisitExpr(Str); 1785 ColorScope Color(*this, ValueColor); 1786 OS << " "; 1787 Str->outputString(OS); 1788 } 1789 1790 void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) { 1791 VisitExpr(ILE); 1792 if (auto *Filler = ILE->getArrayFiller()) { 1793 dumpChild([=] { 1794 OS << "array filler"; 1795 dumpStmt(Filler); 1796 }); 1797 } 1798 if (auto *Field = ILE->getInitializedFieldInUnion()) { 1799 OS << " field "; 1800 dumpBareDeclRef(Field); 1801 } 1802 } 1803 1804 void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) { 1805 VisitExpr(Node); 1806 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") 1807 << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1808 } 1809 1810 void ASTDumper::VisitUnaryExprOrTypeTraitExpr( 1811 const UnaryExprOrTypeTraitExpr *Node) { 1812 VisitExpr(Node); 1813 switch(Node->getKind()) { 1814 case UETT_SizeOf: 1815 OS << " sizeof"; 1816 break; 1817 case UETT_AlignOf: 1818 OS << " alignof"; 1819 break; 1820 case UETT_VecStep: 1821 OS << " vec_step"; 1822 break; 1823 } 1824 if (Node->isArgumentType()) 1825 dumpType(Node->getArgumentType()); 1826 } 1827 1828 void ASTDumper::VisitMemberExpr(const MemberExpr *Node) { 1829 VisitExpr(Node); 1830 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); 1831 dumpPointer(Node->getMemberDecl()); 1832 } 1833 1834 void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) { 1835 VisitExpr(Node); 1836 OS << " " << Node->getAccessor().getNameStart(); 1837 } 1838 1839 void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) { 1840 VisitExpr(Node); 1841 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1842 } 1843 1844 void ASTDumper::VisitCompoundAssignOperator( 1845 const CompoundAssignOperator *Node) { 1846 VisitExpr(Node); 1847 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 1848 << "' ComputeLHSTy="; 1849 dumpBareType(Node->getComputationLHSType()); 1850 OS << " ComputeResultTy="; 1851 dumpBareType(Node->getComputationResultType()); 1852 } 1853 1854 void ASTDumper::VisitBlockExpr(const BlockExpr *Node) { 1855 VisitExpr(Node); 1856 dumpDecl(Node->getBlockDecl()); 1857 } 1858 1859 void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { 1860 VisitExpr(Node); 1861 1862 if (Expr *Source = Node->getSourceExpr()) 1863 dumpStmt(Source); 1864 } 1865 1866 // GNU extensions. 1867 1868 void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { 1869 VisitExpr(Node); 1870 OS << " " << Node->getLabel()->getName(); 1871 dumpPointer(Node->getLabel()); 1872 } 1873 1874 //===----------------------------------------------------------------------===// 1875 // C++ Expressions 1876 //===----------------------------------------------------------------------===// 1877 1878 void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) { 1879 VisitExpr(Node); 1880 OS << " " << Node->getCastName() 1881 << "<" << Node->getTypeAsWritten().getAsString() << ">" 1882 << " <" << Node->getCastKindName(); 1883 dumpBasePath(OS, Node); 1884 OS << ">"; 1885 } 1886 1887 void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { 1888 VisitExpr(Node); 1889 OS << " " << (Node->getValue() ? "true" : "false"); 1890 } 1891 1892 void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { 1893 VisitExpr(Node); 1894 OS << " this"; 1895 } 1896 1897 void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) { 1898 VisitExpr(Node); 1899 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() 1900 << " <" << Node->getCastKindName() << ">"; 1901 } 1902 1903 void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { 1904 VisitExpr(Node); 1905 CXXConstructorDecl *Ctor = Node->getConstructor(); 1906 dumpType(Ctor->getType()); 1907 if (Node->isElidable()) 1908 OS << " elidable"; 1909 if (Node->requiresZeroInitialization()) 1910 OS << " zeroing"; 1911 } 1912 1913 void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) { 1914 VisitExpr(Node); 1915 OS << " "; 1916 dumpCXXTemporary(Node->getTemporary()); 1917 } 1918 1919 void 1920 ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) { 1921 VisitExpr(Node); 1922 if (const ValueDecl *VD = Node->getExtendingDecl()) { 1923 OS << " extended by "; 1924 dumpBareDeclRef(VD); 1925 } 1926 } 1927 1928 void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) { 1929 VisitExpr(Node); 1930 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) 1931 dumpDeclRef(Node->getObject(i), "cleanup"); 1932 } 1933 1934 void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { 1935 OS << "(CXXTemporary"; 1936 dumpPointer(Temporary); 1937 OS << ")"; 1938 } 1939 1940 //===----------------------------------------------------------------------===// 1941 // Obj-C Expressions 1942 //===----------------------------------------------------------------------===// 1943 1944 void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { 1945 VisitExpr(Node); 1946 OS << " selector="; 1947 Node->getSelector().print(OS); 1948 switch (Node->getReceiverKind()) { 1949 case ObjCMessageExpr::Instance: 1950 break; 1951 1952 case ObjCMessageExpr::Class: 1953 OS << " class="; 1954 dumpBareType(Node->getClassReceiver()); 1955 break; 1956 1957 case ObjCMessageExpr::SuperInstance: 1958 OS << " super (instance)"; 1959 break; 1960 1961 case ObjCMessageExpr::SuperClass: 1962 OS << " super (class)"; 1963 break; 1964 } 1965 } 1966 1967 void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { 1968 VisitExpr(Node); 1969 OS << " selector="; 1970 Node->getBoxingMethod()->getSelector().print(OS); 1971 } 1972 1973 void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 1974 VisitStmt(Node); 1975 if (const VarDecl *CatchParam = Node->getCatchParamDecl()) 1976 dumpDecl(CatchParam); 1977 else 1978 OS << " catch all"; 1979 } 1980 1981 void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { 1982 VisitExpr(Node); 1983 dumpType(Node->getEncodedType()); 1984 } 1985 1986 void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { 1987 VisitExpr(Node); 1988 1989 OS << " "; 1990 Node->getSelector().print(OS); 1991 } 1992 1993 void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { 1994 VisitExpr(Node); 1995 1996 OS << ' ' << *Node->getProtocol(); 1997 } 1998 1999 void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { 2000 VisitExpr(Node); 2001 if (Node->isImplicitProperty()) { 2002 OS << " Kind=MethodRef Getter=\""; 2003 if (Node->getImplicitPropertyGetter()) 2004 Node->getImplicitPropertyGetter()->getSelector().print(OS); 2005 else 2006 OS << "(null)"; 2007 2008 OS << "\" Setter=\""; 2009 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 2010 Setter->getSelector().print(OS); 2011 else 2012 OS << "(null)"; 2013 OS << "\""; 2014 } else { 2015 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"'; 2016 } 2017 2018 if (Node->isSuperReceiver()) 2019 OS << " super"; 2020 2021 OS << " Messaging="; 2022 if (Node->isMessagingGetter() && Node->isMessagingSetter()) 2023 OS << "Getter&Setter"; 2024 else if (Node->isMessagingGetter()) 2025 OS << "Getter"; 2026 else if (Node->isMessagingSetter()) 2027 OS << "Setter"; 2028 } 2029 2030 void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) { 2031 VisitExpr(Node); 2032 if (Node->isArraySubscriptRefExpr()) 2033 OS << " Kind=ArraySubscript GetterForArray=\""; 2034 else 2035 OS << " Kind=DictionarySubscript GetterForDictionary=\""; 2036 if (Node->getAtIndexMethodDecl()) 2037 Node->getAtIndexMethodDecl()->getSelector().print(OS); 2038 else 2039 OS << "(null)"; 2040 2041 if (Node->isArraySubscriptRefExpr()) 2042 OS << "\" SetterForArray=\""; 2043 else 2044 OS << "\" SetterForDictionary=\""; 2045 if (Node->setAtIndexMethodDecl()) 2046 Node->setAtIndexMethodDecl()->getSelector().print(OS); 2047 else 2048 OS << "(null)"; 2049 } 2050 2051 void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { 2052 VisitExpr(Node); 2053 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 2054 } 2055 2056 //===----------------------------------------------------------------------===// 2057 // Comments 2058 //===----------------------------------------------------------------------===// 2059 2060 const char *ASTDumper::getCommandName(unsigned CommandID) { 2061 if (Traits) 2062 return Traits->getCommandInfo(CommandID)->Name; 2063 const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID); 2064 if (Info) 2065 return Info->Name; 2066 return "<not a builtin command>"; 2067 } 2068 2069 void ASTDumper::dumpFullComment(const FullComment *C) { 2070 if (!C) 2071 return; 2072 2073 FC = C; 2074 dumpComment(C); 2075 FC = nullptr; 2076 } 2077 2078 void ASTDumper::dumpComment(const Comment *C) { 2079 dumpChild([=] { 2080 if (!C) { 2081 ColorScope Color(*this, NullColor); 2082 OS << "<<<NULL>>>"; 2083 return; 2084 } 2085 2086 { 2087 ColorScope Color(*this, CommentColor); 2088 OS << C->getCommentKindName(); 2089 } 2090 dumpPointer(C); 2091 dumpSourceRange(C->getSourceRange()); 2092 ConstCommentVisitor<ASTDumper>::visit(C); 2093 for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 2094 I != E; ++I) 2095 dumpComment(*I); 2096 }); 2097 } 2098 2099 void ASTDumper::visitTextComment(const TextComment *C) { 2100 OS << " Text=\"" << C->getText() << "\""; 2101 } 2102 2103 void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) { 2104 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2105 switch (C->getRenderKind()) { 2106 case InlineCommandComment::RenderNormal: 2107 OS << " RenderNormal"; 2108 break; 2109 case InlineCommandComment::RenderBold: 2110 OS << " RenderBold"; 2111 break; 2112 case InlineCommandComment::RenderMonospaced: 2113 OS << " RenderMonospaced"; 2114 break; 2115 case InlineCommandComment::RenderEmphasized: 2116 OS << " RenderEmphasized"; 2117 break; 2118 } 2119 2120 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2121 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2122 } 2123 2124 void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) { 2125 OS << " Name=\"" << C->getTagName() << "\""; 2126 if (C->getNumAttrs() != 0) { 2127 OS << " Attrs: "; 2128 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { 2129 const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 2130 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; 2131 } 2132 } 2133 if (C->isSelfClosing()) 2134 OS << " SelfClosing"; 2135 } 2136 2137 void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) { 2138 OS << " Name=\"" << C->getTagName() << "\""; 2139 } 2140 2141 void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) { 2142 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2143 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2144 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2145 } 2146 2147 void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) { 2148 OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection()); 2149 2150 if (C->isDirectionExplicit()) 2151 OS << " explicitly"; 2152 else 2153 OS << " implicitly"; 2154 2155 if (C->hasParamName()) { 2156 if (C->isParamIndexValid()) 2157 OS << " Param=\"" << C->getParamName(FC) << "\""; 2158 else 2159 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2160 } 2161 2162 if (C->isParamIndexValid() && !C->isVarArgParam()) 2163 OS << " ParamIndex=" << C->getParamIndex(); 2164 } 2165 2166 void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) { 2167 if (C->hasParamName()) { 2168 if (C->isPositionValid()) 2169 OS << " Param=\"" << C->getParamName(FC) << "\""; 2170 else 2171 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2172 } 2173 2174 if (C->isPositionValid()) { 2175 OS << " Position=<"; 2176 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { 2177 OS << C->getIndex(i); 2178 if (i != e - 1) 2179 OS << ", "; 2180 } 2181 OS << ">"; 2182 } 2183 } 2184 2185 void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) { 2186 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"" 2187 " CloseName=\"" << C->getCloseName() << "\""; 2188 } 2189 2190 void ASTDumper::visitVerbatimBlockLineComment( 2191 const VerbatimBlockLineComment *C) { 2192 OS << " Text=\"" << C->getText() << "\""; 2193 } 2194 2195 void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) { 2196 OS << " Text=\"" << C->getText() << "\""; 2197 } 2198 2199 //===----------------------------------------------------------------------===// 2200 // Type method implementations 2201 //===----------------------------------------------------------------------===// 2202 2203 void QualType::dump(const char *msg) const { 2204 if (msg) 2205 llvm::errs() << msg << ": "; 2206 dump(); 2207 } 2208 2209 LLVM_DUMP_METHOD void QualType::dump() const { 2210 ASTDumper Dumper(llvm::errs(), nullptr, nullptr); 2211 Dumper.dumpTypeAsChild(*this); 2212 } 2213 2214 LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); } 2215 2216 //===----------------------------------------------------------------------===// 2217 // Decl method implementations 2218 //===----------------------------------------------------------------------===// 2219 2220 LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); } 2221 2222 LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const { 2223 ASTDumper P(OS, &getASTContext().getCommentCommandTraits(), 2224 &getASTContext().getSourceManager()); 2225 P.dumpDecl(this); 2226 } 2227 2228 LLVM_DUMP_METHOD void Decl::dumpColor() const { 2229 ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(), 2230 &getASTContext().getSourceManager(), /*ShowColors*/true); 2231 P.dumpDecl(this); 2232 } 2233 2234 LLVM_DUMP_METHOD void DeclContext::dumpLookups() const { 2235 dumpLookups(llvm::errs()); 2236 } 2237 2238 LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS, 2239 bool DumpDecls) const { 2240 const DeclContext *DC = this; 2241 while (!DC->isTranslationUnit()) 2242 DC = DC->getParent(); 2243 ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); 2244 ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager()); 2245 P.dumpLookups(this, DumpDecls); 2246 } 2247 2248 //===----------------------------------------------------------------------===// 2249 // Stmt method implementations 2250 //===----------------------------------------------------------------------===// 2251 2252 LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const { 2253 dump(llvm::errs(), SM); 2254 } 2255 2256 LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const { 2257 ASTDumper P(OS, nullptr, &SM); 2258 P.dumpStmt(this); 2259 } 2260 2261 LLVM_DUMP_METHOD void Stmt::dump() const { 2262 ASTDumper P(llvm::errs(), nullptr, nullptr); 2263 P.dumpStmt(this); 2264 } 2265 2266 LLVM_DUMP_METHOD void Stmt::dumpColor() const { 2267 ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true); 2268 P.dumpStmt(this); 2269 } 2270 2271 //===----------------------------------------------------------------------===// 2272 // Comment method implementations 2273 //===----------------------------------------------------------------------===// 2274 2275 LLVM_DUMP_METHOD void Comment::dump() const { 2276 dump(llvm::errs(), nullptr, nullptr); 2277 } 2278 2279 LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const { 2280 dump(llvm::errs(), &Context.getCommentCommandTraits(), 2281 &Context.getSourceManager()); 2282 } 2283 2284 void Comment::dump(raw_ostream &OS, const CommandTraits *Traits, 2285 const SourceManager *SM) const { 2286 const FullComment *FC = dyn_cast<FullComment>(this); 2287 ASTDumper D(OS, Traits, SM); 2288 D.dumpFullComment(FC); 2289 } 2290 2291 LLVM_DUMP_METHOD void Comment::dumpColor() const { 2292 const FullComment *FC = dyn_cast<FullComment>(this); 2293 ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true); 2294 D.dumpFullComment(FC); 2295 } 2296