ASTDumper.cpp revision 280031
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" 27using namespace clang; 28using namespace clang::comments; 29 30//===----------------------------------------------------------------------===// 31// ASTDumper Visitor 32//===----------------------------------------------------------------------===// 33 34namespace { 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 556void ASTDumper::dumpPointer(const void *Ptr) { 557 ColorScope Color(*this, AddressColor); 558 OS << ' ' << Ptr; 559} 560 561void 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 591void 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 608void 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 622void ASTDumper::dumpType(QualType T) { 623 OS << ' '; 624 dumpBareType(T); 625} 626 627void 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 642void 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 680void 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 696void 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 707void ASTDumper::dumpName(const NamedDecl *ND) { 708 if (ND->getDeclName()) { 709 ColorScope Color(*this, DeclNameColor); 710 OS << ' ' << ND->getNameAsString(); 711 } 712} 713 714bool 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 722void 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 737void 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 795void 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 818static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} 819 820template<typename T> 821static 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 827template<typename T> 828static 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. 836static 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 851void 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 867void 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 884void 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 893void ASTDumper::dumpTemplateArgumentListInfo( 894 const TemplateArgumentListInfo &TALI) { 895 for (unsigned i = 0, e = TALI.size(); i < e; ++i) 896 dumpTemplateArgumentLoc(TALI[i]); 897} 898 899void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) { 900 dumpTemplateArgument(A.getArgument(), A.getSourceRange()); 901} 902 903void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { 904 for (unsigned i = 0, e = TAL.size(); i < e; ++i) 905 dumpTemplateArgument(TAL[i]); 906} 907 908void 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 958void 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 1012void ASTDumper::VisitLabelDecl(const LabelDecl *D) { 1013 dumpName(D); 1014} 1015 1016void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) { 1017 dumpName(D); 1018 dumpType(D->getUnderlyingType()); 1019 if (D->isModulePrivate()) 1020 OS << " __module_private__"; 1021} 1022 1023void 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 1037void 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 1046void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { 1047 dumpName(D); 1048 dumpType(D->getType()); 1049 if (const Expr *Init = D->getInitExpr()) 1050 dumpStmt(Init); 1051} 1052 1053void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { 1054 dumpName(D); 1055 dumpType(D->getType()); 1056 1057 for (auto *Child : D->chain()) 1058 dumpDeclRef(Child); 1059} 1060 1061void 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 for (FunctionDecl::param_const_iterator I = D->param_begin(), 1103 E = D->param_end(); 1104 I != E; ++I) 1105 dumpDecl(*I); 1106 1107 if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D)) 1108 for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), 1109 E = C->init_end(); 1110 I != E; ++I) 1111 dumpCXXCtorInitializer(*I); 1112 1113 if (D->doesThisDeclarationHaveABody()) 1114 dumpStmt(D->getBody()); 1115} 1116 1117void ASTDumper::VisitFieldDecl(const FieldDecl *D) { 1118 dumpName(D); 1119 dumpType(D->getType()); 1120 if (D->isMutable()) 1121 OS << " mutable"; 1122 if (D->isModulePrivate()) 1123 OS << " __module_private__"; 1124 1125 if (D->isBitField()) 1126 dumpStmt(D->getBitWidth()); 1127 if (Expr *Init = D->getInClassInitializer()) 1128 dumpStmt(Init); 1129} 1130 1131void ASTDumper::VisitVarDecl(const VarDecl *D) { 1132 dumpName(D); 1133 dumpType(D->getType()); 1134 StorageClass SC = D->getStorageClass(); 1135 if (SC != SC_None) 1136 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 1137 switch (D->getTLSKind()) { 1138 case VarDecl::TLS_None: break; 1139 case VarDecl::TLS_Static: OS << " tls"; break; 1140 case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break; 1141 } 1142 if (D->isModulePrivate()) 1143 OS << " __module_private__"; 1144 if (D->isNRVOVariable()) 1145 OS << " nrvo"; 1146 if (D->hasInit()) { 1147 switch (D->getInitStyle()) { 1148 case VarDecl::CInit: OS << " cinit"; break; 1149 case VarDecl::CallInit: OS << " callinit"; break; 1150 case VarDecl::ListInit: OS << " listinit"; break; 1151 } 1152 dumpStmt(D->getInit()); 1153 } 1154} 1155 1156void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { 1157 dumpStmt(D->getAsmString()); 1158} 1159 1160void ASTDumper::VisitImportDecl(const ImportDecl *D) { 1161 OS << ' ' << D->getImportedModule()->getFullModuleName(); 1162} 1163 1164//===----------------------------------------------------------------------===// 1165// C++ Declarations 1166//===----------------------------------------------------------------------===// 1167 1168void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 1169 dumpName(D); 1170 if (D->isInline()) 1171 OS << " inline"; 1172 if (!D->isOriginalNamespace()) 1173 dumpDeclRef(D->getOriginalNamespace(), "original"); 1174} 1175 1176void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 1177 OS << ' '; 1178 dumpBareDeclRef(D->getNominatedNamespace()); 1179} 1180 1181void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 1182 dumpName(D); 1183 dumpDeclRef(D->getAliasedNamespace()); 1184} 1185 1186void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 1187 dumpName(D); 1188 dumpType(D->getUnderlyingType()); 1189} 1190 1191void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { 1192 dumpName(D); 1193 dumpTemplateParameters(D->getTemplateParameters()); 1194 dumpDecl(D->getTemplatedDecl()); 1195} 1196 1197void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 1198 VisitRecordDecl(D); 1199 if (!D->isCompleteDefinition()) 1200 return; 1201 1202 for (const auto &I : D->bases()) { 1203 dumpChild([=] { 1204 if (I.isVirtual()) 1205 OS << "virtual "; 1206 dumpAccessSpecifier(I.getAccessSpecifier()); 1207 dumpType(I.getType()); 1208 if (I.isPackExpansion()) 1209 OS << "..."; 1210 }); 1211 } 1212} 1213 1214void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) { 1215 dumpStmt(D->getAssertExpr()); 1216 dumpStmt(D->getMessage()); 1217} 1218 1219template<typename SpecializationDecl> 1220void ASTDumper::VisitTemplateDeclSpecialization(const SpecializationDecl *D, 1221 bool DumpExplicitInst, 1222 bool DumpRefOnly) { 1223 bool DumpedAny = false; 1224 for (auto *RedeclWithBadType : D->redecls()) { 1225 // FIXME: The redecls() range sometimes has elements of a less-specific 1226 // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives 1227 // us TagDecls, and should give CXXRecordDecls). 1228 auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType); 1229 if (!Redecl) { 1230 // Found the injected-class-name for a class template. This will be dumped 1231 // as part of its surrounding class so we don't need to dump it here. 1232 assert(isa<CXXRecordDecl>(RedeclWithBadType) && 1233 "expected an injected-class-name"); 1234 continue; 1235 } 1236 1237 switch (Redecl->getTemplateSpecializationKind()) { 1238 case TSK_ExplicitInstantiationDeclaration: 1239 case TSK_ExplicitInstantiationDefinition: 1240 if (!DumpExplicitInst) 1241 break; 1242 // Fall through. 1243 case TSK_Undeclared: 1244 case TSK_ImplicitInstantiation: 1245 if (DumpRefOnly) 1246 dumpDeclRef(Redecl); 1247 else 1248 dumpDecl(Redecl); 1249 DumpedAny = true; 1250 break; 1251 case TSK_ExplicitSpecialization: 1252 break; 1253 } 1254 } 1255 1256 // Ensure we dump at least one decl for each specialization. 1257 if (!DumpedAny) 1258 dumpDeclRef(D); 1259} 1260 1261template<typename TemplateDecl> 1262void ASTDumper::VisitTemplateDecl(const TemplateDecl *D, 1263 bool DumpExplicitInst) { 1264 dumpName(D); 1265 dumpTemplateParameters(D->getTemplateParameters()); 1266 1267 dumpDecl(D->getTemplatedDecl()); 1268 1269 for (auto *Child : D->specializations()) 1270 VisitTemplateDeclSpecialization(Child, DumpExplicitInst, 1271 !D->isCanonicalDecl()); 1272} 1273 1274void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 1275 // FIXME: We don't add a declaration of a function template specialization 1276 // to its context when it's explicitly instantiated, so dump explicit 1277 // instantiations when we dump the template itself. 1278 VisitTemplateDecl(D, true); 1279} 1280 1281void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 1282 VisitTemplateDecl(D, false); 1283} 1284 1285void ASTDumper::VisitClassTemplateSpecializationDecl( 1286 const ClassTemplateSpecializationDecl *D) { 1287 VisitCXXRecordDecl(D); 1288 dumpTemplateArgumentList(D->getTemplateArgs()); 1289} 1290 1291void ASTDumper::VisitClassTemplatePartialSpecializationDecl( 1292 const ClassTemplatePartialSpecializationDecl *D) { 1293 VisitClassTemplateSpecializationDecl(D); 1294 dumpTemplateParameters(D->getTemplateParameters()); 1295} 1296 1297void ASTDumper::VisitClassScopeFunctionSpecializationDecl( 1298 const ClassScopeFunctionSpecializationDecl *D) { 1299 dumpDeclRef(D->getSpecialization()); 1300 if (D->hasExplicitTemplateArgs()) 1301 dumpTemplateArgumentListInfo(D->templateArgs()); 1302} 1303 1304void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { 1305 VisitTemplateDecl(D, false); 1306} 1307 1308void ASTDumper::VisitVarTemplateSpecializationDecl( 1309 const VarTemplateSpecializationDecl *D) { 1310 dumpTemplateArgumentList(D->getTemplateArgs()); 1311 VisitVarDecl(D); 1312} 1313 1314void ASTDumper::VisitVarTemplatePartialSpecializationDecl( 1315 const VarTemplatePartialSpecializationDecl *D) { 1316 dumpTemplateParameters(D->getTemplateParameters()); 1317 VisitVarTemplateSpecializationDecl(D); 1318} 1319 1320void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 1321 if (D->wasDeclaredWithTypename()) 1322 OS << " typename"; 1323 else 1324 OS << " class"; 1325 if (D->isParameterPack()) 1326 OS << " ..."; 1327 dumpName(D); 1328 if (D->hasDefaultArgument()) 1329 dumpTemplateArgument(D->getDefaultArgument()); 1330} 1331 1332void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { 1333 dumpType(D->getType()); 1334 if (D->isParameterPack()) 1335 OS << " ..."; 1336 dumpName(D); 1337 if (D->hasDefaultArgument()) 1338 dumpTemplateArgument(D->getDefaultArgument()); 1339} 1340 1341void ASTDumper::VisitTemplateTemplateParmDecl( 1342 const TemplateTemplateParmDecl *D) { 1343 if (D->isParameterPack()) 1344 OS << " ..."; 1345 dumpName(D); 1346 dumpTemplateParameters(D->getTemplateParameters()); 1347 if (D->hasDefaultArgument()) 1348 dumpTemplateArgumentLoc(D->getDefaultArgument()); 1349} 1350 1351void ASTDumper::VisitUsingDecl(const UsingDecl *D) { 1352 OS << ' '; 1353 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1354 OS << D->getNameAsString(); 1355} 1356 1357void ASTDumper::VisitUnresolvedUsingTypenameDecl( 1358 const UnresolvedUsingTypenameDecl *D) { 1359 OS << ' '; 1360 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1361 OS << D->getNameAsString(); 1362} 1363 1364void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 1365 OS << ' '; 1366 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1367 OS << D->getNameAsString(); 1368 dumpType(D->getType()); 1369} 1370 1371void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 1372 OS << ' '; 1373 dumpBareDeclRef(D->getTargetDecl()); 1374} 1375 1376void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 1377 switch (D->getLanguage()) { 1378 case LinkageSpecDecl::lang_c: OS << " C"; break; 1379 case LinkageSpecDecl::lang_cxx: OS << " C++"; break; 1380 } 1381} 1382 1383void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 1384 OS << ' '; 1385 dumpAccessSpecifier(D->getAccess()); 1386} 1387 1388void ASTDumper::VisitFriendDecl(const FriendDecl *D) { 1389 if (TypeSourceInfo *T = D->getFriendType()) 1390 dumpType(T->getType()); 1391 else 1392 dumpDecl(D->getFriendDecl()); 1393} 1394 1395//===----------------------------------------------------------------------===// 1396// Obj-C Declarations 1397//===----------------------------------------------------------------------===// 1398 1399void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 1400 dumpName(D); 1401 dumpType(D->getType()); 1402 if (D->getSynthesize()) 1403 OS << " synthesize"; 1404 1405 switch (D->getAccessControl()) { 1406 case ObjCIvarDecl::None: 1407 OS << " none"; 1408 break; 1409 case ObjCIvarDecl::Private: 1410 OS << " private"; 1411 break; 1412 case ObjCIvarDecl::Protected: 1413 OS << " protected"; 1414 break; 1415 case ObjCIvarDecl::Public: 1416 OS << " public"; 1417 break; 1418 case ObjCIvarDecl::Package: 1419 OS << " package"; 1420 break; 1421 } 1422} 1423 1424void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 1425 if (D->isInstanceMethod()) 1426 OS << " -"; 1427 else 1428 OS << " +"; 1429 dumpName(D); 1430 dumpType(D->getReturnType()); 1431 1432 if (D->isThisDeclarationADefinition()) { 1433 dumpDeclContext(D); 1434 } else { 1435 for (ObjCMethodDecl::param_const_iterator I = D->param_begin(), 1436 E = D->param_end(); 1437 I != E; ++I) 1438 dumpDecl(*I); 1439 } 1440 1441 if (D->isVariadic()) 1442 dumpChild([=] { OS << "..."; }); 1443 1444 if (D->hasBody()) 1445 dumpStmt(D->getBody()); 1446} 1447 1448void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 1449 dumpName(D); 1450 dumpDeclRef(D->getClassInterface()); 1451 dumpDeclRef(D->getImplementation()); 1452 for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), 1453 E = D->protocol_end(); 1454 I != E; ++I) 1455 dumpDeclRef(*I); 1456} 1457 1458void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 1459 dumpName(D); 1460 dumpDeclRef(D->getClassInterface()); 1461 dumpDeclRef(D->getCategoryDecl()); 1462} 1463 1464void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 1465 dumpName(D); 1466 1467 for (auto *Child : D->protocols()) 1468 dumpDeclRef(Child); 1469} 1470 1471void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 1472 dumpName(D); 1473 dumpDeclRef(D->getSuperClass(), "super"); 1474 1475 dumpDeclRef(D->getImplementation()); 1476 for (auto *Child : D->protocols()) 1477 dumpDeclRef(Child); 1478} 1479 1480void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { 1481 dumpName(D); 1482 dumpDeclRef(D->getSuperClass(), "super"); 1483 dumpDeclRef(D->getClassInterface()); 1484 for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), 1485 E = D->init_end(); 1486 I != E; ++I) 1487 dumpCXXCtorInitializer(*I); 1488} 1489 1490void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { 1491 dumpName(D); 1492 dumpDeclRef(D->getClassInterface()); 1493} 1494 1495void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 1496 dumpName(D); 1497 dumpType(D->getType()); 1498 1499 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 1500 OS << " required"; 1501 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1502 OS << " optional"; 1503 1504 ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes(); 1505 if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) { 1506 if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly) 1507 OS << " readonly"; 1508 if (Attrs & ObjCPropertyDecl::OBJC_PR_assign) 1509 OS << " assign"; 1510 if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite) 1511 OS << " readwrite"; 1512 if (Attrs & ObjCPropertyDecl::OBJC_PR_retain) 1513 OS << " retain"; 1514 if (Attrs & ObjCPropertyDecl::OBJC_PR_copy) 1515 OS << " copy"; 1516 if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) 1517 OS << " nonatomic"; 1518 if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic) 1519 OS << " atomic"; 1520 if (Attrs & ObjCPropertyDecl::OBJC_PR_weak) 1521 OS << " weak"; 1522 if (Attrs & ObjCPropertyDecl::OBJC_PR_strong) 1523 OS << " strong"; 1524 if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) 1525 OS << " unsafe_unretained"; 1526 if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) 1527 dumpDeclRef(D->getGetterMethodDecl(), "getter"); 1528 if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) 1529 dumpDeclRef(D->getSetterMethodDecl(), "setter"); 1530 } 1531} 1532 1533void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 1534 dumpName(D->getPropertyDecl()); 1535 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1536 OS << " synthesize"; 1537 else 1538 OS << " dynamic"; 1539 dumpDeclRef(D->getPropertyDecl()); 1540 dumpDeclRef(D->getPropertyIvarDecl()); 1541} 1542 1543void ASTDumper::VisitBlockDecl(const BlockDecl *D) { 1544 for (auto I : D->params()) 1545 dumpDecl(I); 1546 1547 if (D->isVariadic()) 1548 dumpChild([=]{ OS << "..."; }); 1549 1550 if (D->capturesCXXThis()) 1551 dumpChild([=]{ OS << "capture this"; }); 1552 1553 for (const auto &I : D->captures()) { 1554 dumpChild([=] { 1555 OS << "capture"; 1556 if (I.isByRef()) 1557 OS << " byref"; 1558 if (I.isNested()) 1559 OS << " nested"; 1560 if (I.getVariable()) { 1561 OS << ' '; 1562 dumpBareDeclRef(I.getVariable()); 1563 } 1564 if (I.hasCopyExpr()) 1565 dumpStmt(I.getCopyExpr()); 1566 }); 1567 } 1568 dumpStmt(D->getBody()); 1569} 1570 1571//===----------------------------------------------------------------------===// 1572// Stmt dumping methods. 1573//===----------------------------------------------------------------------===// 1574 1575void ASTDumper::dumpStmt(const Stmt *S) { 1576 dumpChild([=] { 1577 if (!S) { 1578 ColorScope Color(*this, NullColor); 1579 OS << "<<<NULL>>>"; 1580 return; 1581 } 1582 1583 if (const DeclStmt *DS = dyn_cast<DeclStmt>(S)) { 1584 VisitDeclStmt(DS); 1585 return; 1586 } 1587 1588 ConstStmtVisitor<ASTDumper>::Visit(S); 1589 1590 for (Stmt::const_child_range CI = S->children(); CI; ++CI) 1591 dumpStmt(*CI); 1592 }); 1593} 1594 1595void ASTDumper::VisitStmt(const Stmt *Node) { 1596 { 1597 ColorScope Color(*this, StmtColor); 1598 OS << Node->getStmtClassName(); 1599 } 1600 dumpPointer(Node); 1601 dumpSourceRange(Node->getSourceRange()); 1602} 1603 1604void ASTDumper::VisitDeclStmt(const DeclStmt *Node) { 1605 VisitStmt(Node); 1606 for (DeclStmt::const_decl_iterator I = Node->decl_begin(), 1607 E = Node->decl_end(); 1608 I != E; ++I) 1609 dumpDecl(*I); 1610} 1611 1612void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) { 1613 VisitStmt(Node); 1614 for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(), 1615 E = Node->getAttrs().end(); 1616 I != E; ++I) 1617 dumpAttr(*I); 1618} 1619 1620void ASTDumper::VisitLabelStmt(const LabelStmt *Node) { 1621 VisitStmt(Node); 1622 OS << " '" << Node->getName() << "'"; 1623} 1624 1625void ASTDumper::VisitGotoStmt(const GotoStmt *Node) { 1626 VisitStmt(Node); 1627 OS << " '" << Node->getLabel()->getName() << "'"; 1628 dumpPointer(Node->getLabel()); 1629} 1630 1631void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) { 1632 VisitStmt(Node); 1633 dumpDecl(Node->getExceptionDecl()); 1634} 1635 1636//===----------------------------------------------------------------------===// 1637// Expr dumping methods. 1638//===----------------------------------------------------------------------===// 1639 1640void ASTDumper::VisitExpr(const Expr *Node) { 1641 VisitStmt(Node); 1642 dumpType(Node->getType()); 1643 1644 { 1645 ColorScope Color(*this, ValueKindColor); 1646 switch (Node->getValueKind()) { 1647 case VK_RValue: 1648 break; 1649 case VK_LValue: 1650 OS << " lvalue"; 1651 break; 1652 case VK_XValue: 1653 OS << " xvalue"; 1654 break; 1655 } 1656 } 1657 1658 { 1659 ColorScope Color(*this, ObjectKindColor); 1660 switch (Node->getObjectKind()) { 1661 case OK_Ordinary: 1662 break; 1663 case OK_BitField: 1664 OS << " bitfield"; 1665 break; 1666 case OK_ObjCProperty: 1667 OS << " objcproperty"; 1668 break; 1669 case OK_ObjCSubscript: 1670 OS << " objcsubscript"; 1671 break; 1672 case OK_VectorComponent: 1673 OS << " vectorcomponent"; 1674 break; 1675 } 1676 } 1677} 1678 1679static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { 1680 if (Node->path_empty()) 1681 return; 1682 1683 OS << " ("; 1684 bool First = true; 1685 for (CastExpr::path_const_iterator I = Node->path_begin(), 1686 E = Node->path_end(); 1687 I != E; ++I) { 1688 const CXXBaseSpecifier *Base = *I; 1689 if (!First) 1690 OS << " -> "; 1691 1692 const CXXRecordDecl *RD = 1693 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 1694 1695 if (Base->isVirtual()) 1696 OS << "virtual "; 1697 OS << RD->getName(); 1698 First = false; 1699 } 1700 1701 OS << ')'; 1702} 1703 1704void ASTDumper::VisitCastExpr(const CastExpr *Node) { 1705 VisitExpr(Node); 1706 OS << " <"; 1707 { 1708 ColorScope Color(*this, CastColor); 1709 OS << Node->getCastKindName(); 1710 } 1711 dumpBasePath(OS, Node); 1712 OS << ">"; 1713} 1714 1715void ASTDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { 1716 VisitExpr(Node); 1717 1718 OS << " "; 1719 dumpBareDeclRef(Node->getDecl()); 1720 if (Node->getDecl() != Node->getFoundDecl()) { 1721 OS << " ("; 1722 dumpBareDeclRef(Node->getFoundDecl()); 1723 OS << ")"; 1724 } 1725} 1726 1727void ASTDumper::VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *Node) { 1728 VisitExpr(Node); 1729 OS << " ("; 1730 if (!Node->requiresADL()) 1731 OS << "no "; 1732 OS << "ADL) = '" << Node->getName() << '\''; 1733 1734 UnresolvedLookupExpr::decls_iterator 1735 I = Node->decls_begin(), E = Node->decls_end(); 1736 if (I == E) 1737 OS << " empty"; 1738 for (; I != E; ++I) 1739 dumpPointer(*I); 1740} 1741 1742void ASTDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { 1743 VisitExpr(Node); 1744 1745 { 1746 ColorScope Color(*this, DeclKindNameColor); 1747 OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; 1748 } 1749 OS << "='" << *Node->getDecl() << "'"; 1750 dumpPointer(Node->getDecl()); 1751 if (Node->isFreeIvar()) 1752 OS << " isFreeIvar"; 1753} 1754 1755void ASTDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { 1756 VisitExpr(Node); 1757 OS << " " << PredefinedExpr::getIdentTypeName(Node->getIdentType()); 1758} 1759 1760void ASTDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { 1761 VisitExpr(Node); 1762 ColorScope Color(*this, ValueColor); 1763 OS << " " << Node->getValue(); 1764} 1765 1766void ASTDumper::VisitIntegerLiteral(const IntegerLiteral *Node) { 1767 VisitExpr(Node); 1768 1769 bool isSigned = Node->getType()->isSignedIntegerType(); 1770 ColorScope Color(*this, ValueColor); 1771 OS << " " << Node->getValue().toString(10, isSigned); 1772} 1773 1774void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { 1775 VisitExpr(Node); 1776 ColorScope Color(*this, ValueColor); 1777 OS << " " << Node->getValueAsApproximateDouble(); 1778} 1779 1780void ASTDumper::VisitStringLiteral(const StringLiteral *Str) { 1781 VisitExpr(Str); 1782 ColorScope Color(*this, ValueColor); 1783 OS << " "; 1784 Str->outputString(OS); 1785} 1786 1787void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) { 1788 VisitExpr(ILE); 1789 if (auto *Filler = ILE->getArrayFiller()) { 1790 dumpChild([=] { 1791 OS << "array filler"; 1792 dumpStmt(Filler); 1793 }); 1794 } 1795 if (auto *Field = ILE->getInitializedFieldInUnion()) { 1796 OS << " field "; 1797 dumpBareDeclRef(Field); 1798 } 1799} 1800 1801void ASTDumper::VisitUnaryOperator(const UnaryOperator *Node) { 1802 VisitExpr(Node); 1803 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") 1804 << " '" << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1805} 1806 1807void ASTDumper::VisitUnaryExprOrTypeTraitExpr( 1808 const UnaryExprOrTypeTraitExpr *Node) { 1809 VisitExpr(Node); 1810 switch(Node->getKind()) { 1811 case UETT_SizeOf: 1812 OS << " sizeof"; 1813 break; 1814 case UETT_AlignOf: 1815 OS << " alignof"; 1816 break; 1817 case UETT_VecStep: 1818 OS << " vec_step"; 1819 break; 1820 } 1821 if (Node->isArgumentType()) 1822 dumpType(Node->getArgumentType()); 1823} 1824 1825void ASTDumper::VisitMemberExpr(const MemberExpr *Node) { 1826 VisitExpr(Node); 1827 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); 1828 dumpPointer(Node->getMemberDecl()); 1829} 1830 1831void ASTDumper::VisitExtVectorElementExpr(const ExtVectorElementExpr *Node) { 1832 VisitExpr(Node); 1833 OS << " " << Node->getAccessor().getNameStart(); 1834} 1835 1836void ASTDumper::VisitBinaryOperator(const BinaryOperator *Node) { 1837 VisitExpr(Node); 1838 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1839} 1840 1841void ASTDumper::VisitCompoundAssignOperator( 1842 const CompoundAssignOperator *Node) { 1843 VisitExpr(Node); 1844 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 1845 << "' ComputeLHSTy="; 1846 dumpBareType(Node->getComputationLHSType()); 1847 OS << " ComputeResultTy="; 1848 dumpBareType(Node->getComputationResultType()); 1849} 1850 1851void ASTDumper::VisitBlockExpr(const BlockExpr *Node) { 1852 VisitExpr(Node); 1853 dumpDecl(Node->getBlockDecl()); 1854} 1855 1856void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { 1857 VisitExpr(Node); 1858 1859 if (Expr *Source = Node->getSourceExpr()) 1860 dumpStmt(Source); 1861} 1862 1863// GNU extensions. 1864 1865void ASTDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { 1866 VisitExpr(Node); 1867 OS << " " << Node->getLabel()->getName(); 1868 dumpPointer(Node->getLabel()); 1869} 1870 1871//===----------------------------------------------------------------------===// 1872// C++ Expressions 1873//===----------------------------------------------------------------------===// 1874 1875void ASTDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) { 1876 VisitExpr(Node); 1877 OS << " " << Node->getCastName() 1878 << "<" << Node->getTypeAsWritten().getAsString() << ">" 1879 << " <" << Node->getCastKindName(); 1880 dumpBasePath(OS, Node); 1881 OS << ">"; 1882} 1883 1884void ASTDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { 1885 VisitExpr(Node); 1886 OS << " " << (Node->getValue() ? "true" : "false"); 1887} 1888 1889void ASTDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { 1890 VisitExpr(Node); 1891 OS << " this"; 1892} 1893 1894void ASTDumper::VisitCXXFunctionalCastExpr(const CXXFunctionalCastExpr *Node) { 1895 VisitExpr(Node); 1896 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() 1897 << " <" << Node->getCastKindName() << ">"; 1898} 1899 1900void ASTDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { 1901 VisitExpr(Node); 1902 CXXConstructorDecl *Ctor = Node->getConstructor(); 1903 dumpType(Ctor->getType()); 1904 if (Node->isElidable()) 1905 OS << " elidable"; 1906 if (Node->requiresZeroInitialization()) 1907 OS << " zeroing"; 1908} 1909 1910void ASTDumper::VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *Node) { 1911 VisitExpr(Node); 1912 OS << " "; 1913 dumpCXXTemporary(Node->getTemporary()); 1914} 1915 1916void 1917ASTDumper::VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *Node) { 1918 VisitExpr(Node); 1919 if (const ValueDecl *VD = Node->getExtendingDecl()) { 1920 OS << " extended by "; 1921 dumpBareDeclRef(VD); 1922 } 1923} 1924 1925void ASTDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) { 1926 VisitExpr(Node); 1927 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) 1928 dumpDeclRef(Node->getObject(i), "cleanup"); 1929} 1930 1931void ASTDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { 1932 OS << "(CXXTemporary"; 1933 dumpPointer(Temporary); 1934 OS << ")"; 1935} 1936 1937//===----------------------------------------------------------------------===// 1938// Obj-C Expressions 1939//===----------------------------------------------------------------------===// 1940 1941void ASTDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { 1942 VisitExpr(Node); 1943 OS << " selector="; 1944 Node->getSelector().print(OS); 1945 switch (Node->getReceiverKind()) { 1946 case ObjCMessageExpr::Instance: 1947 break; 1948 1949 case ObjCMessageExpr::Class: 1950 OS << " class="; 1951 dumpBareType(Node->getClassReceiver()); 1952 break; 1953 1954 case ObjCMessageExpr::SuperInstance: 1955 OS << " super (instance)"; 1956 break; 1957 1958 case ObjCMessageExpr::SuperClass: 1959 OS << " super (class)"; 1960 break; 1961 } 1962} 1963 1964void ASTDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { 1965 VisitExpr(Node); 1966 OS << " selector="; 1967 Node->getBoxingMethod()->getSelector().print(OS); 1968} 1969 1970void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 1971 VisitStmt(Node); 1972 if (const VarDecl *CatchParam = Node->getCatchParamDecl()) 1973 dumpDecl(CatchParam); 1974 else 1975 OS << " catch all"; 1976} 1977 1978void ASTDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { 1979 VisitExpr(Node); 1980 dumpType(Node->getEncodedType()); 1981} 1982 1983void ASTDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { 1984 VisitExpr(Node); 1985 1986 OS << " "; 1987 Node->getSelector().print(OS); 1988} 1989 1990void ASTDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { 1991 VisitExpr(Node); 1992 1993 OS << ' ' << *Node->getProtocol(); 1994} 1995 1996void ASTDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { 1997 VisitExpr(Node); 1998 if (Node->isImplicitProperty()) { 1999 OS << " Kind=MethodRef Getter=\""; 2000 if (Node->getImplicitPropertyGetter()) 2001 Node->getImplicitPropertyGetter()->getSelector().print(OS); 2002 else 2003 OS << "(null)"; 2004 2005 OS << "\" Setter=\""; 2006 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 2007 Setter->getSelector().print(OS); 2008 else 2009 OS << "(null)"; 2010 OS << "\""; 2011 } else { 2012 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() <<'"'; 2013 } 2014 2015 if (Node->isSuperReceiver()) 2016 OS << " super"; 2017 2018 OS << " Messaging="; 2019 if (Node->isMessagingGetter() && Node->isMessagingSetter()) 2020 OS << "Getter&Setter"; 2021 else if (Node->isMessagingGetter()) 2022 OS << "Getter"; 2023 else if (Node->isMessagingSetter()) 2024 OS << "Setter"; 2025} 2026 2027void ASTDumper::VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *Node) { 2028 VisitExpr(Node); 2029 if (Node->isArraySubscriptRefExpr()) 2030 OS << " Kind=ArraySubscript GetterForArray=\""; 2031 else 2032 OS << " Kind=DictionarySubscript GetterForDictionary=\""; 2033 if (Node->getAtIndexMethodDecl()) 2034 Node->getAtIndexMethodDecl()->getSelector().print(OS); 2035 else 2036 OS << "(null)"; 2037 2038 if (Node->isArraySubscriptRefExpr()) 2039 OS << "\" SetterForArray=\""; 2040 else 2041 OS << "\" SetterForDictionary=\""; 2042 if (Node->setAtIndexMethodDecl()) 2043 Node->setAtIndexMethodDecl()->getSelector().print(OS); 2044 else 2045 OS << "(null)"; 2046} 2047 2048void ASTDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { 2049 VisitExpr(Node); 2050 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 2051} 2052 2053//===----------------------------------------------------------------------===// 2054// Comments 2055//===----------------------------------------------------------------------===// 2056 2057const char *ASTDumper::getCommandName(unsigned CommandID) { 2058 if (Traits) 2059 return Traits->getCommandInfo(CommandID)->Name; 2060 const CommandInfo *Info = CommandTraits::getBuiltinCommandInfo(CommandID); 2061 if (Info) 2062 return Info->Name; 2063 return "<not a builtin command>"; 2064} 2065 2066void ASTDumper::dumpFullComment(const FullComment *C) { 2067 if (!C) 2068 return; 2069 2070 FC = C; 2071 dumpComment(C); 2072 FC = nullptr; 2073} 2074 2075void ASTDumper::dumpComment(const Comment *C) { 2076 dumpChild([=] { 2077 if (!C) { 2078 ColorScope Color(*this, NullColor); 2079 OS << "<<<NULL>>>"; 2080 return; 2081 } 2082 2083 { 2084 ColorScope Color(*this, CommentColor); 2085 OS << C->getCommentKindName(); 2086 } 2087 dumpPointer(C); 2088 dumpSourceRange(C->getSourceRange()); 2089 ConstCommentVisitor<ASTDumper>::visit(C); 2090 for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 2091 I != E; ++I) 2092 dumpComment(*I); 2093 }); 2094} 2095 2096void ASTDumper::visitTextComment(const TextComment *C) { 2097 OS << " Text=\"" << C->getText() << "\""; 2098} 2099 2100void ASTDumper::visitInlineCommandComment(const InlineCommandComment *C) { 2101 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2102 switch (C->getRenderKind()) { 2103 case InlineCommandComment::RenderNormal: 2104 OS << " RenderNormal"; 2105 break; 2106 case InlineCommandComment::RenderBold: 2107 OS << " RenderBold"; 2108 break; 2109 case InlineCommandComment::RenderMonospaced: 2110 OS << " RenderMonospaced"; 2111 break; 2112 case InlineCommandComment::RenderEmphasized: 2113 OS << " RenderEmphasized"; 2114 break; 2115 } 2116 2117 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2118 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2119} 2120 2121void ASTDumper::visitHTMLStartTagComment(const HTMLStartTagComment *C) { 2122 OS << " Name=\"" << C->getTagName() << "\""; 2123 if (C->getNumAttrs() != 0) { 2124 OS << " Attrs: "; 2125 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { 2126 const HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 2127 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; 2128 } 2129 } 2130 if (C->isSelfClosing()) 2131 OS << " SelfClosing"; 2132} 2133 2134void ASTDumper::visitHTMLEndTagComment(const HTMLEndTagComment *C) { 2135 OS << " Name=\"" << C->getTagName() << "\""; 2136} 2137 2138void ASTDumper::visitBlockCommandComment(const BlockCommandComment *C) { 2139 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 2140 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 2141 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 2142} 2143 2144void ASTDumper::visitParamCommandComment(const ParamCommandComment *C) { 2145 OS << " " << ParamCommandComment::getDirectionAsString(C->getDirection()); 2146 2147 if (C->isDirectionExplicit()) 2148 OS << " explicitly"; 2149 else 2150 OS << " implicitly"; 2151 2152 if (C->hasParamName()) { 2153 if (C->isParamIndexValid()) 2154 OS << " Param=\"" << C->getParamName(FC) << "\""; 2155 else 2156 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2157 } 2158 2159 if (C->isParamIndexValid() && !C->isVarArgParam()) 2160 OS << " ParamIndex=" << C->getParamIndex(); 2161} 2162 2163void ASTDumper::visitTParamCommandComment(const TParamCommandComment *C) { 2164 if (C->hasParamName()) { 2165 if (C->isPositionValid()) 2166 OS << " Param=\"" << C->getParamName(FC) << "\""; 2167 else 2168 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 2169 } 2170 2171 if (C->isPositionValid()) { 2172 OS << " Position=<"; 2173 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { 2174 OS << C->getIndex(i); 2175 if (i != e - 1) 2176 OS << ", "; 2177 } 2178 OS << ">"; 2179 } 2180} 2181 2182void ASTDumper::visitVerbatimBlockComment(const VerbatimBlockComment *C) { 2183 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\"" 2184 " CloseName=\"" << C->getCloseName() << "\""; 2185} 2186 2187void ASTDumper::visitVerbatimBlockLineComment( 2188 const VerbatimBlockLineComment *C) { 2189 OS << " Text=\"" << C->getText() << "\""; 2190} 2191 2192void ASTDumper::visitVerbatimLineComment(const VerbatimLineComment *C) { 2193 OS << " Text=\"" << C->getText() << "\""; 2194} 2195 2196//===----------------------------------------------------------------------===// 2197// Type method implementations 2198//===----------------------------------------------------------------------===// 2199 2200void QualType::dump(const char *msg) const { 2201 if (msg) 2202 llvm::errs() << msg << ": "; 2203 dump(); 2204} 2205 2206LLVM_DUMP_METHOD void QualType::dump() const { 2207 ASTDumper Dumper(llvm::errs(), nullptr, nullptr); 2208 Dumper.dumpTypeAsChild(*this); 2209} 2210 2211LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); } 2212 2213//===----------------------------------------------------------------------===// 2214// Decl method implementations 2215//===----------------------------------------------------------------------===// 2216 2217LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); } 2218 2219LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS) const { 2220 ASTDumper P(OS, &getASTContext().getCommentCommandTraits(), 2221 &getASTContext().getSourceManager()); 2222 P.dumpDecl(this); 2223} 2224 2225LLVM_DUMP_METHOD void Decl::dumpColor() const { 2226 ASTDumper P(llvm::errs(), &getASTContext().getCommentCommandTraits(), 2227 &getASTContext().getSourceManager(), /*ShowColors*/true); 2228 P.dumpDecl(this); 2229} 2230 2231LLVM_DUMP_METHOD void DeclContext::dumpLookups() const { 2232 dumpLookups(llvm::errs()); 2233} 2234 2235LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS, 2236 bool DumpDecls) const { 2237 const DeclContext *DC = this; 2238 while (!DC->isTranslationUnit()) 2239 DC = DC->getParent(); 2240 ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); 2241 ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager()); 2242 P.dumpLookups(this, DumpDecls); 2243} 2244 2245//===----------------------------------------------------------------------===// 2246// Stmt method implementations 2247//===----------------------------------------------------------------------===// 2248 2249LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const { 2250 dump(llvm::errs(), SM); 2251} 2252 2253LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const { 2254 ASTDumper P(OS, nullptr, &SM); 2255 P.dumpStmt(this); 2256} 2257 2258LLVM_DUMP_METHOD void Stmt::dump() const { 2259 ASTDumper P(llvm::errs(), nullptr, nullptr); 2260 P.dumpStmt(this); 2261} 2262 2263LLVM_DUMP_METHOD void Stmt::dumpColor() const { 2264 ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true); 2265 P.dumpStmt(this); 2266} 2267 2268//===----------------------------------------------------------------------===// 2269// Comment method implementations 2270//===----------------------------------------------------------------------===// 2271 2272LLVM_DUMP_METHOD void Comment::dump() const { 2273 dump(llvm::errs(), nullptr, nullptr); 2274} 2275 2276LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const { 2277 dump(llvm::errs(), &Context.getCommentCommandTraits(), 2278 &Context.getSourceManager()); 2279} 2280 2281void Comment::dump(raw_ostream &OS, const CommandTraits *Traits, 2282 const SourceManager *SM) const { 2283 const FullComment *FC = dyn_cast<FullComment>(this); 2284 ASTDumper D(OS, Traits, SM); 2285 D.dumpFullComment(FC); 2286} 2287 2288LLVM_DUMP_METHOD void Comment::dumpColor() const { 2289 const FullComment *FC = dyn_cast<FullComment>(this); 2290 ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true); 2291 D.dumpFullComment(FC); 2292} 2293