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