1 //===--- TextNodeDumper.cpp - Printing of AST nodes -----------------------===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file implements AST dumping of components of individual AST nodes. 10 // 11 //===----------------------------------------------------------------------===// 12 13 #include "clang/AST/TextNodeDumper.h" 14 #include "clang/AST/DeclFriend.h" 15 #include "clang/AST/DeclOpenMP.h" 16 #include "clang/AST/DeclTemplate.h" 17 #include "clang/AST/LocInfoType.h" 18 19 using namespace clang; 20 21 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} 22 23 template <typename T> 24 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) { 25 const T *First = D->getFirstDecl(); 26 if (First != D) 27 OS << " first " << First; 28 } 29 30 template <typename T> 31 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) { 32 const T *Prev = D->getPreviousDecl(); 33 if (Prev) 34 OS << " prev " << Prev; 35 } 36 37 /// Dump the previous declaration in the redeclaration chain for a declaration, 38 /// if any. 39 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) { 40 switch (D->getKind()) { 41 #define DECL(DERIVED, BASE) \ 42 case Decl::DERIVED: \ 43 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D)); 44 #define ABSTRACT_DECL(DECL) 45 #include "clang/AST/DeclNodes.inc" 46 } 47 llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); 48 } 49 50 TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors, 51 const SourceManager *SM, 52 const PrintingPolicy &PrintPolicy, 53 const comments::CommandTraits *Traits) 54 : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors), SM(SM), 55 PrintPolicy(PrintPolicy), Traits(Traits) {} 56 57 void TextNodeDumper::Visit(const comments::Comment *C, 58 const comments::FullComment *FC) { 59 if (!C) { 60 ColorScope Color(OS, ShowColors, NullColor); 61 OS << "<<<NULL>>>"; 62 return; 63 } 64 65 { 66 ColorScope Color(OS, ShowColors, CommentColor); 67 OS << C->getCommentKindName(); 68 } 69 dumpPointer(C); 70 dumpSourceRange(C->getSourceRange()); 71 72 ConstCommentVisitor<TextNodeDumper, void, 73 const comments::FullComment *>::visit(C, FC); 74 } 75 76 void TextNodeDumper::Visit(const Attr *A) { 77 { 78 ColorScope Color(OS, ShowColors, AttrColor); 79 80 switch (A->getKind()) { 81 #define ATTR(X) \ 82 case attr::X: \ 83 OS << #X; \ 84 break; 85 #include "clang/Basic/AttrList.inc" 86 } 87 OS << "Attr"; 88 } 89 dumpPointer(A); 90 dumpSourceRange(A->getRange()); 91 if (A->isInherited()) 92 OS << " Inherited"; 93 if (A->isImplicit()) 94 OS << " Implicit"; 95 96 ConstAttrVisitor<TextNodeDumper>::Visit(A); 97 } 98 99 void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R, 100 const Decl *From, StringRef Label) { 101 OS << "TemplateArgument"; 102 if (R.isValid()) 103 dumpSourceRange(R); 104 105 if (From) 106 dumpDeclRef(From, Label); 107 108 ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA); 109 } 110 111 void TextNodeDumper::Visit(const Stmt *Node) { 112 if (!Node) { 113 ColorScope Color(OS, ShowColors, NullColor); 114 OS << "<<<NULL>>>"; 115 return; 116 } 117 { 118 ColorScope Color(OS, ShowColors, StmtColor); 119 OS << Node->getStmtClassName(); 120 } 121 dumpPointer(Node); 122 dumpSourceRange(Node->getSourceRange()); 123 124 if (const auto *E = dyn_cast<Expr>(Node)) { 125 dumpType(E->getType()); 126 127 { 128 ColorScope Color(OS, ShowColors, ValueKindColor); 129 switch (E->getValueKind()) { 130 case VK_RValue: 131 break; 132 case VK_LValue: 133 OS << " lvalue"; 134 break; 135 case VK_XValue: 136 OS << " xvalue"; 137 break; 138 } 139 } 140 141 { 142 ColorScope Color(OS, ShowColors, ObjectKindColor); 143 switch (E->getObjectKind()) { 144 case OK_Ordinary: 145 break; 146 case OK_BitField: 147 OS << " bitfield"; 148 break; 149 case OK_ObjCProperty: 150 OS << " objcproperty"; 151 break; 152 case OK_ObjCSubscript: 153 OS << " objcsubscript"; 154 break; 155 case OK_VectorComponent: 156 OS << " vectorcomponent"; 157 break; 158 } 159 } 160 } 161 162 ConstStmtVisitor<TextNodeDumper>::Visit(Node); 163 } 164 165 void TextNodeDumper::Visit(const Type *T) { 166 if (!T) { 167 ColorScope Color(OS, ShowColors, NullColor); 168 OS << "<<<NULL>>>"; 169 return; 170 } 171 if (isa<LocInfoType>(T)) { 172 { 173 ColorScope Color(OS, ShowColors, TypeColor); 174 OS << "LocInfo Type"; 175 } 176 dumpPointer(T); 177 return; 178 } 179 180 { 181 ColorScope Color(OS, ShowColors, TypeColor); 182 OS << T->getTypeClassName() << "Type"; 183 } 184 dumpPointer(T); 185 OS << " "; 186 dumpBareType(QualType(T, 0), false); 187 188 QualType SingleStepDesugar = 189 T->getLocallyUnqualifiedSingleStepDesugaredType(); 190 if (SingleStepDesugar != QualType(T, 0)) 191 OS << " sugar"; 192 193 if (T->isDependentType()) 194 OS << " dependent"; 195 else if (T->isInstantiationDependentType()) 196 OS << " instantiation_dependent"; 197 198 if (T->isVariablyModifiedType()) 199 OS << " variably_modified"; 200 if (T->containsUnexpandedParameterPack()) 201 OS << " contains_unexpanded_pack"; 202 if (T->isFromAST()) 203 OS << " imported"; 204 205 TypeVisitor<TextNodeDumper>::Visit(T); 206 } 207 208 void TextNodeDumper::Visit(QualType T) { 209 OS << "QualType"; 210 dumpPointer(T.getAsOpaquePtr()); 211 OS << " "; 212 dumpBareType(T, false); 213 OS << " " << T.split().Quals.getAsString(); 214 } 215 216 void TextNodeDumper::Visit(const Decl *D) { 217 if (!D) { 218 ColorScope Color(OS, ShowColors, NullColor); 219 OS << "<<<NULL>>>"; 220 return; 221 } 222 223 { 224 ColorScope Color(OS, ShowColors, DeclKindNameColor); 225 OS << D->getDeclKindName() << "Decl"; 226 } 227 dumpPointer(D); 228 if (D->getLexicalDeclContext() != D->getDeclContext()) 229 OS << " parent " << cast<Decl>(D->getDeclContext()); 230 dumpPreviousDecl(OS, D); 231 dumpSourceRange(D->getSourceRange()); 232 OS << ' '; 233 dumpLocation(D->getLocation()); 234 if (D->isFromASTFile()) 235 OS << " imported"; 236 if (Module *M = D->getOwningModule()) 237 OS << " in " << M->getFullModuleName(); 238 if (auto *ND = dyn_cast<NamedDecl>(D)) 239 for (Module *M : D->getASTContext().getModulesWithMergedDefinition( 240 const_cast<NamedDecl *>(ND))) 241 AddChild([=] { OS << "also in " << M->getFullModuleName(); }); 242 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 243 if (ND->isHidden()) 244 OS << " hidden"; 245 if (D->isImplicit()) 246 OS << " implicit"; 247 248 if (D->isUsed()) 249 OS << " used"; 250 else if (D->isThisDeclarationReferenced()) 251 OS << " referenced"; 252 253 if (D->isInvalidDecl()) 254 OS << " invalid"; 255 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) 256 if (FD->isConstexpr()) 257 OS << " constexpr"; 258 259 if (!isa<FunctionDecl>(*D)) { 260 const auto *MD = dyn_cast<ObjCMethodDecl>(D); 261 if (!MD || !MD->isThisDeclarationADefinition()) { 262 const auto *DC = dyn_cast<DeclContext>(D); 263 if (DC && DC->hasExternalLexicalStorage()) { 264 ColorScope Color(OS, ShowColors, UndeserializedColor); 265 OS << " <undeserialized declarations>"; 266 } 267 } 268 } 269 270 ConstDeclVisitor<TextNodeDumper>::Visit(D); 271 } 272 273 void TextNodeDumper::Visit(const CXXCtorInitializer *Init) { 274 OS << "CXXCtorInitializer"; 275 if (Init->isAnyMemberInitializer()) { 276 OS << ' '; 277 dumpBareDeclRef(Init->getAnyMember()); 278 } else if (Init->isBaseInitializer()) { 279 dumpType(QualType(Init->getBaseClass(), 0)); 280 } else if (Init->isDelegatingInitializer()) { 281 dumpType(Init->getTypeSourceInfo()->getType()); 282 } else { 283 llvm_unreachable("Unknown initializer type"); 284 } 285 } 286 287 void TextNodeDumper::Visit(const BlockDecl::Capture &C) { 288 OS << "capture"; 289 if (C.isByRef()) 290 OS << " byref"; 291 if (C.isNested()) 292 OS << " nested"; 293 if (C.getVariable()) { 294 OS << ' '; 295 dumpBareDeclRef(C.getVariable()); 296 } 297 } 298 299 void TextNodeDumper::Visit(const OMPClause *C) { 300 if (!C) { 301 ColorScope Color(OS, ShowColors, NullColor); 302 OS << "<<<NULL>>> OMPClause"; 303 return; 304 } 305 { 306 ColorScope Color(OS, ShowColors, AttrColor); 307 StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); 308 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() 309 << ClauseName.drop_front() << "Clause"; 310 } 311 dumpPointer(C); 312 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); 313 if (C->isImplicit()) 314 OS << " <implicit>"; 315 } 316 317 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) { 318 const TypeSourceInfo *TSI = A.getTypeSourceInfo(); 319 if (TSI) { 320 OS << "case "; 321 dumpType(TSI->getType()); 322 } else { 323 OS << "default"; 324 } 325 326 if (A.isSelected()) 327 OS << " selected"; 328 } 329 330 void TextNodeDumper::dumpPointer(const void *Ptr) { 331 ColorScope Color(OS, ShowColors, AddressColor); 332 OS << ' ' << Ptr; 333 } 334 335 void TextNodeDumper::dumpLocation(SourceLocation Loc) { 336 if (!SM) 337 return; 338 339 ColorScope Color(OS, ShowColors, LocationColor); 340 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); 341 342 // The general format we print out is filename:line:col, but we drop pieces 343 // that haven't changed since the last loc printed. 344 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); 345 346 if (PLoc.isInvalid()) { 347 OS << "<invalid sloc>"; 348 return; 349 } 350 351 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { 352 OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':' 353 << PLoc.getColumn(); 354 LastLocFilename = PLoc.getFilename(); 355 LastLocLine = PLoc.getLine(); 356 } else if (PLoc.getLine() != LastLocLine) { 357 OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn(); 358 LastLocLine = PLoc.getLine(); 359 } else { 360 OS << "col" << ':' << PLoc.getColumn(); 361 } 362 } 363 364 void TextNodeDumper::dumpSourceRange(SourceRange R) { 365 // Can't translate locations if a SourceManager isn't available. 366 if (!SM) 367 return; 368 369 OS << " <"; 370 dumpLocation(R.getBegin()); 371 if (R.getBegin() != R.getEnd()) { 372 OS << ", "; 373 dumpLocation(R.getEnd()); 374 } 375 OS << ">"; 376 377 // <t2.c:123:421[blah], t2.c:412:321> 378 } 379 380 void TextNodeDumper::dumpBareType(QualType T, bool Desugar) { 381 ColorScope Color(OS, ShowColors, TypeColor); 382 383 SplitQualType T_split = T.split(); 384 OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'"; 385 386 if (Desugar && !T.isNull()) { 387 // If the type is sugared, also dump a (shallow) desugared type. 388 SplitQualType D_split = T.getSplitDesugaredType(); 389 if (T_split != D_split) 390 OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'"; 391 } 392 } 393 394 void TextNodeDumper::dumpType(QualType T) { 395 OS << ' '; 396 dumpBareType(T); 397 } 398 399 void TextNodeDumper::dumpBareDeclRef(const Decl *D) { 400 if (!D) { 401 ColorScope Color(OS, ShowColors, NullColor); 402 OS << "<<<NULL>>>"; 403 return; 404 } 405 406 { 407 ColorScope Color(OS, ShowColors, DeclKindNameColor); 408 OS << D->getDeclKindName(); 409 } 410 dumpPointer(D); 411 412 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 413 ColorScope Color(OS, ShowColors, DeclNameColor); 414 OS << " '" << ND->getDeclName() << '\''; 415 } 416 417 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 418 dumpType(VD->getType()); 419 } 420 421 void TextNodeDumper::dumpName(const NamedDecl *ND) { 422 if (ND->getDeclName()) { 423 ColorScope Color(OS, ShowColors, DeclNameColor); 424 OS << ' ' << ND->getNameAsString(); 425 } 426 } 427 428 void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) { 429 switch (AS) { 430 case AS_none: 431 break; 432 case AS_public: 433 OS << "public"; 434 break; 435 case AS_protected: 436 OS << "protected"; 437 break; 438 case AS_private: 439 OS << "private"; 440 break; 441 } 442 } 443 444 void TextNodeDumper::dumpCXXTemporary(const CXXTemporary *Temporary) { 445 OS << "(CXXTemporary"; 446 dumpPointer(Temporary); 447 OS << ")"; 448 } 449 450 void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) { 451 if (!D) 452 return; 453 454 AddChild([=] { 455 if (!Label.empty()) 456 OS << Label << ' '; 457 dumpBareDeclRef(D); 458 }); 459 } 460 461 const char *TextNodeDumper::getCommandName(unsigned CommandID) { 462 if (Traits) 463 return Traits->getCommandInfo(CommandID)->Name; 464 const comments::CommandInfo *Info = 465 comments::CommandTraits::getBuiltinCommandInfo(CommandID); 466 if (Info) 467 return Info->Name; 468 return "<not a builtin command>"; 469 } 470 471 void TextNodeDumper::visitTextComment(const comments::TextComment *C, 472 const comments::FullComment *) { 473 OS << " Text=\"" << C->getText() << "\""; 474 } 475 476 void TextNodeDumper::visitInlineCommandComment( 477 const comments::InlineCommandComment *C, const comments::FullComment *) { 478 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 479 switch (C->getRenderKind()) { 480 case comments::InlineCommandComment::RenderNormal: 481 OS << " RenderNormal"; 482 break; 483 case comments::InlineCommandComment::RenderBold: 484 OS << " RenderBold"; 485 break; 486 case comments::InlineCommandComment::RenderMonospaced: 487 OS << " RenderMonospaced"; 488 break; 489 case comments::InlineCommandComment::RenderEmphasized: 490 OS << " RenderEmphasized"; 491 break; 492 } 493 494 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 495 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 496 } 497 498 void TextNodeDumper::visitHTMLStartTagComment( 499 const comments::HTMLStartTagComment *C, const comments::FullComment *) { 500 OS << " Name=\"" << C->getTagName() << "\""; 501 if (C->getNumAttrs() != 0) { 502 OS << " Attrs: "; 503 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { 504 const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 505 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; 506 } 507 } 508 if (C->isSelfClosing()) 509 OS << " SelfClosing"; 510 } 511 512 void TextNodeDumper::visitHTMLEndTagComment( 513 const comments::HTMLEndTagComment *C, const comments::FullComment *) { 514 OS << " Name=\"" << C->getTagName() << "\""; 515 } 516 517 void TextNodeDumper::visitBlockCommandComment( 518 const comments::BlockCommandComment *C, const comments::FullComment *) { 519 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 520 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 521 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 522 } 523 524 void TextNodeDumper::visitParamCommandComment( 525 const comments::ParamCommandComment *C, const comments::FullComment *FC) { 526 OS << " " 527 << comments::ParamCommandComment::getDirectionAsString(C->getDirection()); 528 529 if (C->isDirectionExplicit()) 530 OS << " explicitly"; 531 else 532 OS << " implicitly"; 533 534 if (C->hasParamName()) { 535 if (C->isParamIndexValid()) 536 OS << " Param=\"" << C->getParamName(FC) << "\""; 537 else 538 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 539 } 540 541 if (C->isParamIndexValid() && !C->isVarArgParam()) 542 OS << " ParamIndex=" << C->getParamIndex(); 543 } 544 545 void TextNodeDumper::visitTParamCommandComment( 546 const comments::TParamCommandComment *C, const comments::FullComment *FC) { 547 if (C->hasParamName()) { 548 if (C->isPositionValid()) 549 OS << " Param=\"" << C->getParamName(FC) << "\""; 550 else 551 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 552 } 553 554 if (C->isPositionValid()) { 555 OS << " Position=<"; 556 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { 557 OS << C->getIndex(i); 558 if (i != e - 1) 559 OS << ", "; 560 } 561 OS << ">"; 562 } 563 } 564 565 void TextNodeDumper::visitVerbatimBlockComment( 566 const comments::VerbatimBlockComment *C, const comments::FullComment *) { 567 OS << " Name=\"" << getCommandName(C->getCommandID()) 568 << "\"" 569 " CloseName=\"" 570 << C->getCloseName() << "\""; 571 } 572 573 void TextNodeDumper::visitVerbatimBlockLineComment( 574 const comments::VerbatimBlockLineComment *C, 575 const comments::FullComment *) { 576 OS << " Text=\"" << C->getText() << "\""; 577 } 578 579 void TextNodeDumper::visitVerbatimLineComment( 580 const comments::VerbatimLineComment *C, const comments::FullComment *) { 581 OS << " Text=\"" << C->getText() << "\""; 582 } 583 584 void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) { 585 OS << " null"; 586 } 587 588 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) { 589 OS << " type"; 590 dumpType(TA.getAsType()); 591 } 592 593 void TextNodeDumper::VisitDeclarationTemplateArgument( 594 const TemplateArgument &TA) { 595 OS << " decl"; 596 dumpDeclRef(TA.getAsDecl()); 597 } 598 599 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) { 600 OS << " nullptr"; 601 } 602 603 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) { 604 OS << " integral " << TA.getAsIntegral(); 605 } 606 607 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) { 608 OS << " template "; 609 TA.getAsTemplate().dump(OS); 610 } 611 612 void TextNodeDumper::VisitTemplateExpansionTemplateArgument( 613 const TemplateArgument &TA) { 614 OS << " template expansion "; 615 TA.getAsTemplateOrTemplatePattern().dump(OS); 616 } 617 618 void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) { 619 OS << " expr"; 620 } 621 622 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) { 623 OS << " pack"; 624 } 625 626 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { 627 if (Node->path_empty()) 628 return; 629 630 OS << " ("; 631 bool First = true; 632 for (CastExpr::path_const_iterator I = Node->path_begin(), 633 E = Node->path_end(); 634 I != E; ++I) { 635 const CXXBaseSpecifier *Base = *I; 636 if (!First) 637 OS << " -> "; 638 639 const CXXRecordDecl *RD = 640 cast<CXXRecordDecl>(Base->getType()->getAs<RecordType>()->getDecl()); 641 642 if (Base->isVirtual()) 643 OS << "virtual "; 644 OS << RD->getName(); 645 First = false; 646 } 647 648 OS << ')'; 649 } 650 651 void TextNodeDumper::VisitIfStmt(const IfStmt *Node) { 652 if (Node->hasInitStorage()) 653 OS << " has_init"; 654 if (Node->hasVarStorage()) 655 OS << " has_var"; 656 if (Node->hasElseStorage()) 657 OS << " has_else"; 658 } 659 660 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) { 661 if (Node->hasInitStorage()) 662 OS << " has_init"; 663 if (Node->hasVarStorage()) 664 OS << " has_var"; 665 } 666 667 void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) { 668 if (Node->hasVarStorage()) 669 OS << " has_var"; 670 } 671 672 void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) { 673 OS << " '" << Node->getName() << "'"; 674 } 675 676 void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) { 677 OS << " '" << Node->getLabel()->getName() << "'"; 678 dumpPointer(Node->getLabel()); 679 } 680 681 void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) { 682 if (Node->caseStmtIsGNURange()) 683 OS << " gnu_range"; 684 } 685 686 void TextNodeDumper::VisitCallExpr(const CallExpr *Node) { 687 if (Node->usesADL()) 688 OS << " adl"; 689 } 690 691 void TextNodeDumper::VisitCastExpr(const CastExpr *Node) { 692 OS << " <"; 693 { 694 ColorScope Color(OS, ShowColors, CastColor); 695 OS << Node->getCastKindName(); 696 } 697 dumpBasePath(OS, Node); 698 OS << ">"; 699 } 700 701 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) { 702 VisitCastExpr(Node); 703 if (Node->isPartOfExplicitCast()) 704 OS << " part_of_explicit_cast"; 705 } 706 707 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { 708 OS << " "; 709 dumpBareDeclRef(Node->getDecl()); 710 if (Node->getDecl() != Node->getFoundDecl()) { 711 OS << " ("; 712 dumpBareDeclRef(Node->getFoundDecl()); 713 OS << ")"; 714 } 715 } 716 717 void TextNodeDumper::VisitUnresolvedLookupExpr( 718 const UnresolvedLookupExpr *Node) { 719 OS << " ("; 720 if (!Node->requiresADL()) 721 OS << "no "; 722 OS << "ADL) = '" << Node->getName() << '\''; 723 724 UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(), 725 E = Node->decls_end(); 726 if (I == E) 727 OS << " empty"; 728 for (; I != E; ++I) 729 dumpPointer(*I); 730 } 731 732 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { 733 { 734 ColorScope Color(OS, ShowColors, DeclKindNameColor); 735 OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; 736 } 737 OS << "='" << *Node->getDecl() << "'"; 738 dumpPointer(Node->getDecl()); 739 if (Node->isFreeIvar()) 740 OS << " isFreeIvar"; 741 } 742 743 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { 744 OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind()); 745 } 746 747 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { 748 ColorScope Color(OS, ShowColors, ValueColor); 749 OS << " " << Node->getValue(); 750 } 751 752 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) { 753 bool isSigned = Node->getType()->isSignedIntegerType(); 754 ColorScope Color(OS, ShowColors, ValueColor); 755 OS << " " << Node->getValue().toString(10, isSigned); 756 } 757 758 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) { 759 ColorScope Color(OS, ShowColors, ValueColor); 760 OS << " " << Node->getValueAsString(/*Radix=*/10); 761 } 762 763 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { 764 ColorScope Color(OS, ShowColors, ValueColor); 765 OS << " " << Node->getValueAsApproximateDouble(); 766 } 767 768 void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) { 769 ColorScope Color(OS, ShowColors, ValueColor); 770 OS << " "; 771 Str->outputString(OS); 772 } 773 774 void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) { 775 if (auto *Field = ILE->getInitializedFieldInUnion()) { 776 OS << " field "; 777 dumpBareDeclRef(Field); 778 } 779 } 780 781 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) { 782 if (E->isResultDependent()) 783 OS << " result_dependent"; 784 } 785 786 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) { 787 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '" 788 << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 789 if (!Node->canOverflow()) 790 OS << " cannot overflow"; 791 } 792 793 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr( 794 const UnaryExprOrTypeTraitExpr *Node) { 795 switch (Node->getKind()) { 796 case UETT_SizeOf: 797 OS << " sizeof"; 798 break; 799 case UETT_AlignOf: 800 OS << " alignof"; 801 break; 802 case UETT_VecStep: 803 OS << " vec_step"; 804 break; 805 case UETT_OpenMPRequiredSimdAlign: 806 OS << " __builtin_omp_required_simd_align"; 807 break; 808 case UETT_PreferredAlignOf: 809 OS << " __alignof"; 810 break; 811 } 812 if (Node->isArgumentType()) 813 dumpType(Node->getArgumentType()); 814 } 815 816 void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) { 817 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); 818 dumpPointer(Node->getMemberDecl()); 819 } 820 821 void TextNodeDumper::VisitExtVectorElementExpr( 822 const ExtVectorElementExpr *Node) { 823 OS << " " << Node->getAccessor().getNameStart(); 824 } 825 826 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) { 827 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 828 } 829 830 void TextNodeDumper::VisitCompoundAssignOperator( 831 const CompoundAssignOperator *Node) { 832 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 833 << "' ComputeLHSTy="; 834 dumpBareType(Node->getComputationLHSType()); 835 OS << " ComputeResultTy="; 836 dumpBareType(Node->getComputationResultType()); 837 } 838 839 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { 840 OS << " " << Node->getLabel()->getName(); 841 dumpPointer(Node->getLabel()); 842 } 843 844 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) { 845 OS << " " << Node->getCastName() << "<" 846 << Node->getTypeAsWritten().getAsString() << ">" 847 << " <" << Node->getCastKindName(); 848 dumpBasePath(OS, Node); 849 OS << ">"; 850 } 851 852 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { 853 OS << " " << (Node->getValue() ? "true" : "false"); 854 } 855 856 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { 857 if (Node->isImplicit()) 858 OS << " implicit"; 859 OS << " this"; 860 } 861 862 void TextNodeDumper::VisitCXXFunctionalCastExpr( 863 const CXXFunctionalCastExpr *Node) { 864 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <" 865 << Node->getCastKindName() << ">"; 866 } 867 868 void TextNodeDumper::VisitCXXUnresolvedConstructExpr( 869 const CXXUnresolvedConstructExpr *Node) { 870 dumpType(Node->getTypeAsWritten()); 871 if (Node->isListInitialization()) 872 OS << " list"; 873 } 874 875 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { 876 CXXConstructorDecl *Ctor = Node->getConstructor(); 877 dumpType(Ctor->getType()); 878 if (Node->isElidable()) 879 OS << " elidable"; 880 if (Node->isListInitialization()) 881 OS << " list"; 882 if (Node->isStdInitListInitialization()) 883 OS << " std::initializer_list"; 884 if (Node->requiresZeroInitialization()) 885 OS << " zeroing"; 886 } 887 888 void TextNodeDumper::VisitCXXBindTemporaryExpr( 889 const CXXBindTemporaryExpr *Node) { 890 OS << " "; 891 dumpCXXTemporary(Node->getTemporary()); 892 } 893 894 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) { 895 if (Node->isGlobalNew()) 896 OS << " global"; 897 if (Node->isArray()) 898 OS << " array"; 899 if (Node->getOperatorNew()) { 900 OS << ' '; 901 dumpBareDeclRef(Node->getOperatorNew()); 902 } 903 // We could dump the deallocation function used in case of error, but it's 904 // usually not that interesting. 905 } 906 907 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) { 908 if (Node->isGlobalDelete()) 909 OS << " global"; 910 if (Node->isArrayForm()) 911 OS << " array"; 912 if (Node->getOperatorDelete()) { 913 OS << ' '; 914 dumpBareDeclRef(Node->getOperatorDelete()); 915 } 916 } 917 918 void TextNodeDumper::VisitMaterializeTemporaryExpr( 919 const MaterializeTemporaryExpr *Node) { 920 if (const ValueDecl *VD = Node->getExtendingDecl()) { 921 OS << " extended by "; 922 dumpBareDeclRef(VD); 923 } 924 } 925 926 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) { 927 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) 928 dumpDeclRef(Node->getObject(i), "cleanup"); 929 } 930 931 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) { 932 dumpPointer(Node->getPack()); 933 dumpName(Node->getPack()); 934 } 935 936 void TextNodeDumper::VisitCXXDependentScopeMemberExpr( 937 const CXXDependentScopeMemberExpr *Node) { 938 OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember(); 939 } 940 941 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { 942 OS << " selector="; 943 Node->getSelector().print(OS); 944 switch (Node->getReceiverKind()) { 945 case ObjCMessageExpr::Instance: 946 break; 947 948 case ObjCMessageExpr::Class: 949 OS << " class="; 950 dumpBareType(Node->getClassReceiver()); 951 break; 952 953 case ObjCMessageExpr::SuperInstance: 954 OS << " super (instance)"; 955 break; 956 957 case ObjCMessageExpr::SuperClass: 958 OS << " super (class)"; 959 break; 960 } 961 } 962 963 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { 964 if (auto *BoxingMethod = Node->getBoxingMethod()) { 965 OS << " selector="; 966 BoxingMethod->getSelector().print(OS); 967 } 968 } 969 970 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 971 if (!Node->getCatchParamDecl()) 972 OS << " catch all"; 973 } 974 975 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { 976 dumpType(Node->getEncodedType()); 977 } 978 979 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { 980 OS << " "; 981 Node->getSelector().print(OS); 982 } 983 984 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { 985 OS << ' ' << *Node->getProtocol(); 986 } 987 988 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { 989 if (Node->isImplicitProperty()) { 990 OS << " Kind=MethodRef Getter=\""; 991 if (Node->getImplicitPropertyGetter()) 992 Node->getImplicitPropertyGetter()->getSelector().print(OS); 993 else 994 OS << "(null)"; 995 996 OS << "\" Setter=\""; 997 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 998 Setter->getSelector().print(OS); 999 else 1000 OS << "(null)"; 1001 OS << "\""; 1002 } else { 1003 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() 1004 << '"'; 1005 } 1006 1007 if (Node->isSuperReceiver()) 1008 OS << " super"; 1009 1010 OS << " Messaging="; 1011 if (Node->isMessagingGetter() && Node->isMessagingSetter()) 1012 OS << "Getter&Setter"; 1013 else if (Node->isMessagingGetter()) 1014 OS << "Getter"; 1015 else if (Node->isMessagingSetter()) 1016 OS << "Setter"; 1017 } 1018 1019 void TextNodeDumper::VisitObjCSubscriptRefExpr( 1020 const ObjCSubscriptRefExpr *Node) { 1021 if (Node->isArraySubscriptRefExpr()) 1022 OS << " Kind=ArraySubscript GetterForArray=\""; 1023 else 1024 OS << " Kind=DictionarySubscript GetterForDictionary=\""; 1025 if (Node->getAtIndexMethodDecl()) 1026 Node->getAtIndexMethodDecl()->getSelector().print(OS); 1027 else 1028 OS << "(null)"; 1029 1030 if (Node->isArraySubscriptRefExpr()) 1031 OS << "\" SetterForArray=\""; 1032 else 1033 OS << "\" SetterForDictionary=\""; 1034 if (Node->setAtIndexMethodDecl()) 1035 Node->setAtIndexMethodDecl()->getSelector().print(OS); 1036 else 1037 OS << "(null)"; 1038 } 1039 1040 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { 1041 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 1042 } 1043 1044 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) { 1045 if (T->isSpelledAsLValue()) 1046 OS << " written as lvalue reference"; 1047 } 1048 1049 void TextNodeDumper::VisitArrayType(const ArrayType *T) { 1050 switch (T->getSizeModifier()) { 1051 case ArrayType::Normal: 1052 break; 1053 case ArrayType::Static: 1054 OS << " static"; 1055 break; 1056 case ArrayType::Star: 1057 OS << " *"; 1058 break; 1059 } 1060 OS << " " << T->getIndexTypeQualifiers().getAsString(); 1061 } 1062 1063 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) { 1064 OS << " " << T->getSize(); 1065 VisitArrayType(T); 1066 } 1067 1068 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) { 1069 OS << " "; 1070 dumpSourceRange(T->getBracketsRange()); 1071 VisitArrayType(T); 1072 } 1073 1074 void TextNodeDumper::VisitDependentSizedArrayType( 1075 const DependentSizedArrayType *T) { 1076 VisitArrayType(T); 1077 OS << " "; 1078 dumpSourceRange(T->getBracketsRange()); 1079 } 1080 1081 void TextNodeDumper::VisitDependentSizedExtVectorType( 1082 const DependentSizedExtVectorType *T) { 1083 OS << " "; 1084 dumpLocation(T->getAttributeLoc()); 1085 } 1086 1087 void TextNodeDumper::VisitVectorType(const VectorType *T) { 1088 switch (T->getVectorKind()) { 1089 case VectorType::GenericVector: 1090 break; 1091 case VectorType::AltiVecVector: 1092 OS << " altivec"; 1093 break; 1094 case VectorType::AltiVecPixel: 1095 OS << " altivec pixel"; 1096 break; 1097 case VectorType::AltiVecBool: 1098 OS << " altivec bool"; 1099 break; 1100 case VectorType::NeonVector: 1101 OS << " neon"; 1102 break; 1103 case VectorType::NeonPolyVector: 1104 OS << " neon poly"; 1105 break; 1106 } 1107 OS << " " << T->getNumElements(); 1108 } 1109 1110 void TextNodeDumper::VisitFunctionType(const FunctionType *T) { 1111 auto EI = T->getExtInfo(); 1112 if (EI.getNoReturn()) 1113 OS << " noreturn"; 1114 if (EI.getProducesResult()) 1115 OS << " produces_result"; 1116 if (EI.getHasRegParm()) 1117 OS << " regparm " << EI.getRegParm(); 1118 OS << " " << FunctionType::getNameForCallConv(EI.getCC()); 1119 } 1120 1121 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) { 1122 auto EPI = T->getExtProtoInfo(); 1123 if (EPI.HasTrailingReturn) 1124 OS << " trailing_return"; 1125 if (T->isConst()) 1126 OS << " const"; 1127 if (T->isVolatile()) 1128 OS << " volatile"; 1129 if (T->isRestrict()) 1130 OS << " restrict"; 1131 if (T->getExtProtoInfo().Variadic) 1132 OS << " variadic"; 1133 switch (EPI.RefQualifier) { 1134 case RQ_None: 1135 break; 1136 case RQ_LValue: 1137 OS << " &"; 1138 break; 1139 case RQ_RValue: 1140 OS << " &&"; 1141 break; 1142 } 1143 // FIXME: Exception specification. 1144 // FIXME: Consumed parameters. 1145 VisitFunctionType(T); 1146 } 1147 1148 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) { 1149 dumpDeclRef(T->getDecl()); 1150 } 1151 1152 void TextNodeDumper::VisitTypedefType(const TypedefType *T) { 1153 dumpDeclRef(T->getDecl()); 1154 } 1155 1156 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) { 1157 switch (T->getUTTKind()) { 1158 case UnaryTransformType::EnumUnderlyingType: 1159 OS << " underlying_type"; 1160 break; 1161 } 1162 } 1163 1164 void TextNodeDumper::VisitTagType(const TagType *T) { 1165 dumpDeclRef(T->getDecl()); 1166 } 1167 1168 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) { 1169 OS << " depth " << T->getDepth() << " index " << T->getIndex(); 1170 if (T->isParameterPack()) 1171 OS << " pack"; 1172 dumpDeclRef(T->getDecl()); 1173 } 1174 1175 void TextNodeDumper::VisitAutoType(const AutoType *T) { 1176 if (T->isDecltypeAuto()) 1177 OS << " decltype(auto)"; 1178 if (!T->isDeduced()) 1179 OS << " undeduced"; 1180 } 1181 1182 void TextNodeDumper::VisitTemplateSpecializationType( 1183 const TemplateSpecializationType *T) { 1184 if (T->isTypeAlias()) 1185 OS << " alias"; 1186 OS << " "; 1187 T->getTemplateName().dump(OS); 1188 } 1189 1190 void TextNodeDumper::VisitInjectedClassNameType( 1191 const InjectedClassNameType *T) { 1192 dumpDeclRef(T->getDecl()); 1193 } 1194 1195 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) { 1196 dumpDeclRef(T->getDecl()); 1197 } 1198 1199 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) { 1200 if (auto N = T->getNumExpansions()) 1201 OS << " expansions " << *N; 1202 } 1203 1204 void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); } 1205 1206 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) { 1207 dumpName(D); 1208 dumpType(D->getUnderlyingType()); 1209 if (D->isModulePrivate()) 1210 OS << " __module_private__"; 1211 } 1212 1213 void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) { 1214 if (D->isScoped()) { 1215 if (D->isScopedUsingClassTag()) 1216 OS << " class"; 1217 else 1218 OS << " struct"; 1219 } 1220 dumpName(D); 1221 if (D->isModulePrivate()) 1222 OS << " __module_private__"; 1223 if (D->isFixed()) 1224 dumpType(D->getIntegerType()); 1225 } 1226 1227 void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) { 1228 OS << ' ' << D->getKindName(); 1229 dumpName(D); 1230 if (D->isModulePrivate()) 1231 OS << " __module_private__"; 1232 if (D->isCompleteDefinition()) 1233 OS << " definition"; 1234 } 1235 1236 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { 1237 dumpName(D); 1238 dumpType(D->getType()); 1239 } 1240 1241 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { 1242 dumpName(D); 1243 dumpType(D->getType()); 1244 1245 for (const auto *Child : D->chain()) 1246 dumpDeclRef(Child); 1247 } 1248 1249 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) { 1250 dumpName(D); 1251 dumpType(D->getType()); 1252 1253 StorageClass SC = D->getStorageClass(); 1254 if (SC != SC_None) 1255 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 1256 if (D->isInlineSpecified()) 1257 OS << " inline"; 1258 if (D->isVirtualAsWritten()) 1259 OS << " virtual"; 1260 if (D->isModulePrivate()) 1261 OS << " __module_private__"; 1262 1263 if (D->isPure()) 1264 OS << " pure"; 1265 if (D->isDefaulted()) { 1266 OS << " default"; 1267 if (D->isDeleted()) 1268 OS << "_delete"; 1269 } 1270 if (D->isDeletedAsWritten()) 1271 OS << " delete"; 1272 if (D->isTrivial()) 1273 OS << " trivial"; 1274 1275 if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) { 1276 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 1277 switch (EPI.ExceptionSpec.Type) { 1278 default: 1279 break; 1280 case EST_Unevaluated: 1281 OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl; 1282 break; 1283 case EST_Uninstantiated: 1284 OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate; 1285 break; 1286 } 1287 } 1288 1289 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) { 1290 if (MD->size_overridden_methods() != 0) { 1291 auto dumpOverride = [=](const CXXMethodDecl *D) { 1292 SplitQualType T_split = D->getType().split(); 1293 OS << D << " " << D->getParent()->getName() 1294 << "::" << D->getNameAsString() << " '" 1295 << QualType::getAsString(T_split, PrintPolicy) << "'"; 1296 }; 1297 1298 AddChild([=] { 1299 auto Overrides = MD->overridden_methods(); 1300 OS << "Overrides: [ "; 1301 dumpOverride(*Overrides.begin()); 1302 for (const auto *Override : 1303 llvm::make_range(Overrides.begin() + 1, Overrides.end())) { 1304 OS << ", "; 1305 dumpOverride(Override); 1306 } 1307 OS << " ]"; 1308 }); 1309 } 1310 } 1311 1312 // Since NumParams comes from the FunctionProtoType of the FunctionDecl and 1313 // the Params are set later, it is possible for a dump during debugging to 1314 // encounter a FunctionDecl that has been created but hasn't been assigned 1315 // ParmVarDecls yet. 1316 if (!D->param_empty() && !D->param_begin()) 1317 OS << " <<<NULL params x " << D->getNumParams() << ">>>"; 1318 } 1319 1320 void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) { 1321 dumpName(D); 1322 dumpType(D->getType()); 1323 if (D->isMutable()) 1324 OS << " mutable"; 1325 if (D->isModulePrivate()) 1326 OS << " __module_private__"; 1327 } 1328 1329 void TextNodeDumper::VisitVarDecl(const VarDecl *D) { 1330 dumpName(D); 1331 dumpType(D->getType()); 1332 StorageClass SC = D->getStorageClass(); 1333 if (SC != SC_None) 1334 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 1335 switch (D->getTLSKind()) { 1336 case VarDecl::TLS_None: 1337 break; 1338 case VarDecl::TLS_Static: 1339 OS << " tls"; 1340 break; 1341 case VarDecl::TLS_Dynamic: 1342 OS << " tls_dynamic"; 1343 break; 1344 } 1345 if (D->isModulePrivate()) 1346 OS << " __module_private__"; 1347 if (D->isNRVOVariable()) 1348 OS << " nrvo"; 1349 if (D->isInline()) 1350 OS << " inline"; 1351 if (D->isConstexpr()) 1352 OS << " constexpr"; 1353 if (D->hasInit()) { 1354 switch (D->getInitStyle()) { 1355 case VarDecl::CInit: 1356 OS << " cinit"; 1357 break; 1358 case VarDecl::CallInit: 1359 OS << " callinit"; 1360 break; 1361 case VarDecl::ListInit: 1362 OS << " listinit"; 1363 break; 1364 } 1365 } 1366 } 1367 1368 void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) { 1369 dumpName(D); 1370 dumpType(D->getType()); 1371 } 1372 1373 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) { 1374 if (D->isNothrow()) 1375 OS << " nothrow"; 1376 } 1377 1378 void TextNodeDumper::VisitImportDecl(const ImportDecl *D) { 1379 OS << ' ' << D->getImportedModule()->getFullModuleName(); 1380 1381 for (Decl *InitD : 1382 D->getASTContext().getModuleInitializers(D->getImportedModule())) 1383 dumpDeclRef(InitD, "initializer"); 1384 } 1385 1386 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) { 1387 OS << ' '; 1388 switch (D->getCommentKind()) { 1389 case PCK_Unknown: 1390 llvm_unreachable("unexpected pragma comment kind"); 1391 case PCK_Compiler: 1392 OS << "compiler"; 1393 break; 1394 case PCK_ExeStr: 1395 OS << "exestr"; 1396 break; 1397 case PCK_Lib: 1398 OS << "lib"; 1399 break; 1400 case PCK_Linker: 1401 OS << "linker"; 1402 break; 1403 case PCK_User: 1404 OS << "user"; 1405 break; 1406 } 1407 StringRef Arg = D->getArg(); 1408 if (!Arg.empty()) 1409 OS << " \"" << Arg << "\""; 1410 } 1411 1412 void TextNodeDumper::VisitPragmaDetectMismatchDecl( 1413 const PragmaDetectMismatchDecl *D) { 1414 OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\""; 1415 } 1416 1417 void TextNodeDumper::VisitOMPDeclareReductionDecl( 1418 const OMPDeclareReductionDecl *D) { 1419 dumpName(D); 1420 dumpType(D->getType()); 1421 OS << " combiner"; 1422 dumpPointer(D->getCombiner()); 1423 if (const auto *Initializer = D->getInitializer()) { 1424 OS << " initializer"; 1425 dumpPointer(Initializer); 1426 switch (D->getInitializerKind()) { 1427 case OMPDeclareReductionDecl::DirectInit: 1428 OS << " omp_priv = "; 1429 break; 1430 case OMPDeclareReductionDecl::CopyInit: 1431 OS << " omp_priv ()"; 1432 break; 1433 case OMPDeclareReductionDecl::CallInit: 1434 break; 1435 } 1436 } 1437 } 1438 1439 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) { 1440 for (const auto *C : D->clauselists()) { 1441 AddChild([=] { 1442 if (!C) { 1443 ColorScope Color(OS, ShowColors, NullColor); 1444 OS << "<<<NULL>>> OMPClause"; 1445 return; 1446 } 1447 { 1448 ColorScope Color(OS, ShowColors, AttrColor); 1449 StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); 1450 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() 1451 << ClauseName.drop_front() << "Clause"; 1452 } 1453 dumpPointer(C); 1454 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); 1455 }); 1456 } 1457 } 1458 1459 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) { 1460 dumpName(D); 1461 dumpType(D->getType()); 1462 } 1463 1464 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 1465 dumpName(D); 1466 if (D->isInline()) 1467 OS << " inline"; 1468 if (!D->isOriginalNamespace()) 1469 dumpDeclRef(D->getOriginalNamespace(), "original"); 1470 } 1471 1472 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 1473 OS << ' '; 1474 dumpBareDeclRef(D->getNominatedNamespace()); 1475 } 1476 1477 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 1478 dumpName(D); 1479 dumpDeclRef(D->getAliasedNamespace()); 1480 } 1481 1482 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 1483 dumpName(D); 1484 dumpType(D->getUnderlyingType()); 1485 } 1486 1487 void TextNodeDumper::VisitTypeAliasTemplateDecl( 1488 const TypeAliasTemplateDecl *D) { 1489 dumpName(D); 1490 } 1491 1492 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 1493 VisitRecordDecl(D); 1494 if (!D->isCompleteDefinition()) 1495 return; 1496 1497 AddChild([=] { 1498 { 1499 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1500 OS << "DefinitionData"; 1501 } 1502 #define FLAG(fn, name) \ 1503 if (D->fn()) \ 1504 OS << " " #name; 1505 FLAG(isParsingBaseSpecifiers, parsing_base_specifiers); 1506 1507 FLAG(isGenericLambda, generic); 1508 FLAG(isLambda, lambda); 1509 1510 FLAG(canPassInRegisters, pass_in_registers); 1511 FLAG(isEmpty, empty); 1512 FLAG(isAggregate, aggregate); 1513 FLAG(isStandardLayout, standard_layout); 1514 FLAG(isTriviallyCopyable, trivially_copyable); 1515 FLAG(isPOD, pod); 1516 FLAG(isTrivial, trivial); 1517 FLAG(isPolymorphic, polymorphic); 1518 FLAG(isAbstract, abstract); 1519 FLAG(isLiteral, literal); 1520 1521 FLAG(hasUserDeclaredConstructor, has_user_declared_ctor); 1522 FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor); 1523 FLAG(hasMutableFields, has_mutable_fields); 1524 FLAG(hasVariantMembers, has_variant_members); 1525 FLAG(allowConstDefaultInit, can_const_default_init); 1526 1527 AddChild([=] { 1528 { 1529 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1530 OS << "DefaultConstructor"; 1531 } 1532 FLAG(hasDefaultConstructor, exists); 1533 FLAG(hasTrivialDefaultConstructor, trivial); 1534 FLAG(hasNonTrivialDefaultConstructor, non_trivial); 1535 FLAG(hasUserProvidedDefaultConstructor, user_provided); 1536 FLAG(hasConstexprDefaultConstructor, constexpr); 1537 FLAG(needsImplicitDefaultConstructor, needs_implicit); 1538 FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr); 1539 }); 1540 1541 AddChild([=] { 1542 { 1543 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1544 OS << "CopyConstructor"; 1545 } 1546 FLAG(hasSimpleCopyConstructor, simple); 1547 FLAG(hasTrivialCopyConstructor, trivial); 1548 FLAG(hasNonTrivialCopyConstructor, non_trivial); 1549 FLAG(hasUserDeclaredCopyConstructor, user_declared); 1550 FLAG(hasCopyConstructorWithConstParam, has_const_param); 1551 FLAG(needsImplicitCopyConstructor, needs_implicit); 1552 FLAG(needsOverloadResolutionForCopyConstructor, 1553 needs_overload_resolution); 1554 if (!D->needsOverloadResolutionForCopyConstructor()) 1555 FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted); 1556 FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param); 1557 }); 1558 1559 AddChild([=] { 1560 { 1561 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1562 OS << "MoveConstructor"; 1563 } 1564 FLAG(hasMoveConstructor, exists); 1565 FLAG(hasSimpleMoveConstructor, simple); 1566 FLAG(hasTrivialMoveConstructor, trivial); 1567 FLAG(hasNonTrivialMoveConstructor, non_trivial); 1568 FLAG(hasUserDeclaredMoveConstructor, user_declared); 1569 FLAG(needsImplicitMoveConstructor, needs_implicit); 1570 FLAG(needsOverloadResolutionForMoveConstructor, 1571 needs_overload_resolution); 1572 if (!D->needsOverloadResolutionForMoveConstructor()) 1573 FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted); 1574 }); 1575 1576 AddChild([=] { 1577 { 1578 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1579 OS << "CopyAssignment"; 1580 } 1581 FLAG(hasTrivialCopyAssignment, trivial); 1582 FLAG(hasNonTrivialCopyAssignment, non_trivial); 1583 FLAG(hasCopyAssignmentWithConstParam, has_const_param); 1584 FLAG(hasUserDeclaredCopyAssignment, user_declared); 1585 FLAG(needsImplicitCopyAssignment, needs_implicit); 1586 FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution); 1587 FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param); 1588 }); 1589 1590 AddChild([=] { 1591 { 1592 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1593 OS << "MoveAssignment"; 1594 } 1595 FLAG(hasMoveAssignment, exists); 1596 FLAG(hasSimpleMoveAssignment, simple); 1597 FLAG(hasTrivialMoveAssignment, trivial); 1598 FLAG(hasNonTrivialMoveAssignment, non_trivial); 1599 FLAG(hasUserDeclaredMoveAssignment, user_declared); 1600 FLAG(needsImplicitMoveAssignment, needs_implicit); 1601 FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution); 1602 }); 1603 1604 AddChild([=] { 1605 { 1606 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1607 OS << "Destructor"; 1608 } 1609 FLAG(hasSimpleDestructor, simple); 1610 FLAG(hasIrrelevantDestructor, irrelevant); 1611 FLAG(hasTrivialDestructor, trivial); 1612 FLAG(hasNonTrivialDestructor, non_trivial); 1613 FLAG(hasUserDeclaredDestructor, user_declared); 1614 FLAG(needsImplicitDestructor, needs_implicit); 1615 FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution); 1616 if (!D->needsOverloadResolutionForDestructor()) 1617 FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted); 1618 }); 1619 }); 1620 1621 for (const auto &I : D->bases()) { 1622 AddChild([=] { 1623 if (I.isVirtual()) 1624 OS << "virtual "; 1625 dumpAccessSpecifier(I.getAccessSpecifier()); 1626 dumpType(I.getType()); 1627 if (I.isPackExpansion()) 1628 OS << "..."; 1629 }); 1630 } 1631 } 1632 1633 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 1634 dumpName(D); 1635 } 1636 1637 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 1638 dumpName(D); 1639 } 1640 1641 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { 1642 dumpName(D); 1643 } 1644 1645 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { 1646 dumpName(D); 1647 } 1648 1649 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 1650 if (D->wasDeclaredWithTypename()) 1651 OS << " typename"; 1652 else 1653 OS << " class"; 1654 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 1655 if (D->isParameterPack()) 1656 OS << " ..."; 1657 dumpName(D); 1658 } 1659 1660 void TextNodeDumper::VisitNonTypeTemplateParmDecl( 1661 const NonTypeTemplateParmDecl *D) { 1662 dumpType(D->getType()); 1663 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 1664 if (D->isParameterPack()) 1665 OS << " ..."; 1666 dumpName(D); 1667 } 1668 1669 void TextNodeDumper::VisitTemplateTemplateParmDecl( 1670 const TemplateTemplateParmDecl *D) { 1671 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 1672 if (D->isParameterPack()) 1673 OS << " ..."; 1674 dumpName(D); 1675 } 1676 1677 void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) { 1678 OS << ' '; 1679 if (D->getQualifier()) 1680 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1681 OS << D->getNameAsString(); 1682 } 1683 1684 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl( 1685 const UnresolvedUsingTypenameDecl *D) { 1686 OS << ' '; 1687 if (D->getQualifier()) 1688 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1689 OS << D->getNameAsString(); 1690 } 1691 1692 void TextNodeDumper::VisitUnresolvedUsingValueDecl( 1693 const UnresolvedUsingValueDecl *D) { 1694 OS << ' '; 1695 if (D->getQualifier()) 1696 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1697 OS << D->getNameAsString(); 1698 dumpType(D->getType()); 1699 } 1700 1701 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 1702 OS << ' '; 1703 dumpBareDeclRef(D->getTargetDecl()); 1704 } 1705 1706 void TextNodeDumper::VisitConstructorUsingShadowDecl( 1707 const ConstructorUsingShadowDecl *D) { 1708 if (D->constructsVirtualBase()) 1709 OS << " virtual"; 1710 1711 AddChild([=] { 1712 OS << "target "; 1713 dumpBareDeclRef(D->getTargetDecl()); 1714 }); 1715 1716 AddChild([=] { 1717 OS << "nominated "; 1718 dumpBareDeclRef(D->getNominatedBaseClass()); 1719 OS << ' '; 1720 dumpBareDeclRef(D->getNominatedBaseClassShadowDecl()); 1721 }); 1722 1723 AddChild([=] { 1724 OS << "constructed "; 1725 dumpBareDeclRef(D->getConstructedBaseClass()); 1726 OS << ' '; 1727 dumpBareDeclRef(D->getConstructedBaseClassShadowDecl()); 1728 }); 1729 } 1730 1731 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 1732 switch (D->getLanguage()) { 1733 case LinkageSpecDecl::lang_c: 1734 OS << " C"; 1735 break; 1736 case LinkageSpecDecl::lang_cxx: 1737 OS << " C++"; 1738 break; 1739 } 1740 } 1741 1742 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 1743 OS << ' '; 1744 dumpAccessSpecifier(D->getAccess()); 1745 } 1746 1747 void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) { 1748 if (TypeSourceInfo *T = D->getFriendType()) 1749 dumpType(T->getType()); 1750 } 1751 1752 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 1753 dumpName(D); 1754 dumpType(D->getType()); 1755 if (D->getSynthesize()) 1756 OS << " synthesize"; 1757 1758 switch (D->getAccessControl()) { 1759 case ObjCIvarDecl::None: 1760 OS << " none"; 1761 break; 1762 case ObjCIvarDecl::Private: 1763 OS << " private"; 1764 break; 1765 case ObjCIvarDecl::Protected: 1766 OS << " protected"; 1767 break; 1768 case ObjCIvarDecl::Public: 1769 OS << " public"; 1770 break; 1771 case ObjCIvarDecl::Package: 1772 OS << " package"; 1773 break; 1774 } 1775 } 1776 1777 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 1778 if (D->isInstanceMethod()) 1779 OS << " -"; 1780 else 1781 OS << " +"; 1782 dumpName(D); 1783 dumpType(D->getReturnType()); 1784 1785 if (D->isVariadic()) 1786 OS << " variadic"; 1787 } 1788 1789 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) { 1790 dumpName(D); 1791 switch (D->getVariance()) { 1792 case ObjCTypeParamVariance::Invariant: 1793 break; 1794 1795 case ObjCTypeParamVariance::Covariant: 1796 OS << " covariant"; 1797 break; 1798 1799 case ObjCTypeParamVariance::Contravariant: 1800 OS << " contravariant"; 1801 break; 1802 } 1803 1804 if (D->hasExplicitBound()) 1805 OS << " bounded"; 1806 dumpType(D->getUnderlyingType()); 1807 } 1808 1809 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 1810 dumpName(D); 1811 dumpDeclRef(D->getClassInterface()); 1812 dumpDeclRef(D->getImplementation()); 1813 for (const auto *P : D->protocols()) 1814 dumpDeclRef(P); 1815 } 1816 1817 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 1818 dumpName(D); 1819 dumpDeclRef(D->getClassInterface()); 1820 dumpDeclRef(D->getCategoryDecl()); 1821 } 1822 1823 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 1824 dumpName(D); 1825 1826 for (const auto *Child : D->protocols()) 1827 dumpDeclRef(Child); 1828 } 1829 1830 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 1831 dumpName(D); 1832 dumpDeclRef(D->getSuperClass(), "super"); 1833 1834 dumpDeclRef(D->getImplementation()); 1835 for (const auto *Child : D->protocols()) 1836 dumpDeclRef(Child); 1837 } 1838 1839 void TextNodeDumper::VisitObjCImplementationDecl( 1840 const ObjCImplementationDecl *D) { 1841 dumpName(D); 1842 dumpDeclRef(D->getSuperClass(), "super"); 1843 dumpDeclRef(D->getClassInterface()); 1844 } 1845 1846 void TextNodeDumper::VisitObjCCompatibleAliasDecl( 1847 const ObjCCompatibleAliasDecl *D) { 1848 dumpName(D); 1849 dumpDeclRef(D->getClassInterface()); 1850 } 1851 1852 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 1853 dumpName(D); 1854 dumpType(D->getType()); 1855 1856 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 1857 OS << " required"; 1858 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1859 OS << " optional"; 1860 1861 ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes(); 1862 if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) { 1863 if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly) 1864 OS << " readonly"; 1865 if (Attrs & ObjCPropertyDecl::OBJC_PR_assign) 1866 OS << " assign"; 1867 if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite) 1868 OS << " readwrite"; 1869 if (Attrs & ObjCPropertyDecl::OBJC_PR_retain) 1870 OS << " retain"; 1871 if (Attrs & ObjCPropertyDecl::OBJC_PR_copy) 1872 OS << " copy"; 1873 if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) 1874 OS << " nonatomic"; 1875 if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic) 1876 OS << " atomic"; 1877 if (Attrs & ObjCPropertyDecl::OBJC_PR_weak) 1878 OS << " weak"; 1879 if (Attrs & ObjCPropertyDecl::OBJC_PR_strong) 1880 OS << " strong"; 1881 if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) 1882 OS << " unsafe_unretained"; 1883 if (Attrs & ObjCPropertyDecl::OBJC_PR_class) 1884 OS << " class"; 1885 if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) 1886 dumpDeclRef(D->getGetterMethodDecl(), "getter"); 1887 if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) 1888 dumpDeclRef(D->getSetterMethodDecl(), "setter"); 1889 } 1890 } 1891 1892 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 1893 dumpName(D->getPropertyDecl()); 1894 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1895 OS << " synthesize"; 1896 else 1897 OS << " dynamic"; 1898 dumpDeclRef(D->getPropertyDecl()); 1899 dumpDeclRef(D->getPropertyIvarDecl()); 1900 } 1901 1902 void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) { 1903 if (D->isVariadic()) 1904 OS << " variadic"; 1905 1906 if (D->capturesCXXThis()) 1907 OS << " captures_this"; 1908 } 1909