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/APValue.h" 15 #include "clang/AST/DeclFriend.h" 16 #include "clang/AST/DeclOpenMP.h" 17 #include "clang/AST/DeclTemplate.h" 18 #include "clang/AST/LocInfoType.h" 19 #include "clang/AST/Type.h" 20 #include "clang/Basic/Module.h" 21 #include "clang/Basic/SourceManager.h" 22 #include "clang/Basic/Specifiers.h" 23 #include "clang/Basic/TypeTraits.h" 24 #include "llvm/ADT/StringExtras.h" 25 26 #include <algorithm> 27 #include <utility> 28 29 using namespace clang; 30 31 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} 32 33 template <typename T> 34 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) { 35 const T *First = D->getFirstDecl(); 36 if (First != D) 37 OS << " first " << First; 38 } 39 40 template <typename T> 41 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) { 42 const T *Prev = D->getPreviousDecl(); 43 if (Prev) 44 OS << " prev " << Prev; 45 } 46 47 /// Dump the previous declaration in the redeclaration chain for a declaration, 48 /// if any. 49 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) { 50 switch (D->getKind()) { 51 #define DECL(DERIVED, BASE) \ 52 case Decl::DERIVED: \ 53 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D)); 54 #define ABSTRACT_DECL(DECL) 55 #include "clang/AST/DeclNodes.inc" 56 } 57 llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); 58 } 59 60 TextNodeDumper::TextNodeDumper(raw_ostream &OS, const ASTContext &Context, 61 bool ShowColors) 62 : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors), 63 Context(&Context), SM(&Context.getSourceManager()), 64 PrintPolicy(Context.getPrintingPolicy()), 65 Traits(&Context.getCommentCommandTraits()) {} 66 67 TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors) 68 : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors) {} 69 70 void TextNodeDumper::Visit(const comments::Comment *C, 71 const comments::FullComment *FC) { 72 if (!C) { 73 ColorScope Color(OS, ShowColors, NullColor); 74 OS << "<<<NULL>>>"; 75 return; 76 } 77 78 { 79 ColorScope Color(OS, ShowColors, CommentColor); 80 OS << C->getCommentKindName(); 81 } 82 dumpPointer(C); 83 dumpSourceRange(C->getSourceRange()); 84 85 ConstCommentVisitor<TextNodeDumper, void, 86 const comments::FullComment *>::visit(C, FC); 87 } 88 89 void TextNodeDumper::Visit(const Attr *A) { 90 { 91 ColorScope Color(OS, ShowColors, AttrColor); 92 93 switch (A->getKind()) { 94 #define ATTR(X) \ 95 case attr::X: \ 96 OS << #X; \ 97 break; 98 #include "clang/Basic/AttrList.inc" 99 } 100 OS << "Attr"; 101 } 102 dumpPointer(A); 103 dumpSourceRange(A->getRange()); 104 if (A->isInherited()) 105 OS << " Inherited"; 106 if (A->isImplicit()) 107 OS << " Implicit"; 108 109 ConstAttrVisitor<TextNodeDumper>::Visit(A); 110 } 111 112 void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R, 113 const Decl *From, StringRef Label) { 114 OS << "TemplateArgument"; 115 if (R.isValid()) 116 dumpSourceRange(R); 117 118 if (From) 119 dumpDeclRef(From, Label); 120 121 ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA); 122 } 123 124 void TextNodeDumper::Visit(const Stmt *Node) { 125 if (!Node) { 126 ColorScope Color(OS, ShowColors, NullColor); 127 OS << "<<<NULL>>>"; 128 return; 129 } 130 { 131 ColorScope Color(OS, ShowColors, StmtColor); 132 OS << Node->getStmtClassName(); 133 } 134 dumpPointer(Node); 135 dumpSourceRange(Node->getSourceRange()); 136 137 if (const auto *E = dyn_cast<Expr>(Node)) { 138 dumpType(E->getType()); 139 140 if (E->containsErrors()) { 141 ColorScope Color(OS, ShowColors, ErrorsColor); 142 OS << " contains-errors"; 143 } 144 145 { 146 ColorScope Color(OS, ShowColors, ValueKindColor); 147 switch (E->getValueKind()) { 148 case VK_PRValue: 149 break; 150 case VK_LValue: 151 OS << " lvalue"; 152 break; 153 case VK_XValue: 154 OS << " xvalue"; 155 break; 156 } 157 } 158 159 { 160 ColorScope Color(OS, ShowColors, ObjectKindColor); 161 switch (E->getObjectKind()) { 162 case OK_Ordinary: 163 break; 164 case OK_BitField: 165 OS << " bitfield"; 166 break; 167 case OK_ObjCProperty: 168 OS << " objcproperty"; 169 break; 170 case OK_ObjCSubscript: 171 OS << " objcsubscript"; 172 break; 173 case OK_VectorComponent: 174 OS << " vectorcomponent"; 175 break; 176 case OK_MatrixComponent: 177 OS << " matrixcomponent"; 178 break; 179 } 180 } 181 } 182 183 ConstStmtVisitor<TextNodeDumper>::Visit(Node); 184 } 185 186 void TextNodeDumper::Visit(const Type *T) { 187 if (!T) { 188 ColorScope Color(OS, ShowColors, NullColor); 189 OS << "<<<NULL>>>"; 190 return; 191 } 192 if (isa<LocInfoType>(T)) { 193 { 194 ColorScope Color(OS, ShowColors, TypeColor); 195 OS << "LocInfo Type"; 196 } 197 dumpPointer(T); 198 return; 199 } 200 201 { 202 ColorScope Color(OS, ShowColors, TypeColor); 203 OS << T->getTypeClassName() << "Type"; 204 } 205 dumpPointer(T); 206 OS << " "; 207 dumpBareType(QualType(T, 0), false); 208 209 QualType SingleStepDesugar = 210 T->getLocallyUnqualifiedSingleStepDesugaredType(); 211 if (SingleStepDesugar != QualType(T, 0)) 212 OS << " sugar"; 213 214 if (T->containsErrors()) { 215 ColorScope Color(OS, ShowColors, ErrorsColor); 216 OS << " contains-errors"; 217 } 218 219 if (T->isDependentType()) 220 OS << " dependent"; 221 else if (T->isInstantiationDependentType()) 222 OS << " instantiation_dependent"; 223 224 if (T->isVariablyModifiedType()) 225 OS << " variably_modified"; 226 if (T->containsUnexpandedParameterPack()) 227 OS << " contains_unexpanded_pack"; 228 if (T->isFromAST()) 229 OS << " imported"; 230 231 TypeVisitor<TextNodeDumper>::Visit(T); 232 } 233 234 void TextNodeDumper::Visit(QualType T) { 235 OS << "QualType"; 236 dumpPointer(T.getAsOpaquePtr()); 237 OS << " "; 238 dumpBareType(T, false); 239 OS << " " << T.split().Quals.getAsString(); 240 } 241 242 void TextNodeDumper::Visit(const Decl *D) { 243 if (!D) { 244 ColorScope Color(OS, ShowColors, NullColor); 245 OS << "<<<NULL>>>"; 246 return; 247 } 248 249 { 250 ColorScope Color(OS, ShowColors, DeclKindNameColor); 251 OS << D->getDeclKindName() << "Decl"; 252 } 253 dumpPointer(D); 254 if (D->getLexicalDeclContext() != D->getDeclContext()) 255 OS << " parent " << cast<Decl>(D->getDeclContext()); 256 dumpPreviousDecl(OS, D); 257 dumpSourceRange(D->getSourceRange()); 258 OS << ' '; 259 dumpLocation(D->getLocation()); 260 if (D->isFromASTFile()) 261 OS << " imported"; 262 if (Module *M = D->getOwningModule()) 263 OS << " in " << M->getFullModuleName(); 264 if (auto *ND = dyn_cast<NamedDecl>(D)) 265 for (Module *M : D->getASTContext().getModulesWithMergedDefinition( 266 const_cast<NamedDecl *>(ND))) 267 AddChild([=] { OS << "also in " << M->getFullModuleName(); }); 268 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 269 if (!ND->isUnconditionallyVisible()) 270 OS << " hidden"; 271 if (D->isImplicit()) 272 OS << " implicit"; 273 274 if (D->isUsed()) 275 OS << " used"; 276 else if (D->isThisDeclarationReferenced()) 277 OS << " referenced"; 278 279 if (D->isInvalidDecl()) 280 OS << " invalid"; 281 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 282 if (FD->isConstexprSpecified()) 283 OS << " constexpr"; 284 if (FD->isConsteval()) 285 OS << " consteval"; 286 } 287 288 if (!isa<FunctionDecl>(*D)) { 289 const auto *MD = dyn_cast<ObjCMethodDecl>(D); 290 if (!MD || !MD->isThisDeclarationADefinition()) { 291 const auto *DC = dyn_cast<DeclContext>(D); 292 if (DC && DC->hasExternalLexicalStorage()) { 293 ColorScope Color(OS, ShowColors, UndeserializedColor); 294 OS << " <undeserialized declarations>"; 295 } 296 } 297 } 298 299 ConstDeclVisitor<TextNodeDumper>::Visit(D); 300 } 301 302 void TextNodeDumper::Visit(const CXXCtorInitializer *Init) { 303 OS << "CXXCtorInitializer"; 304 if (Init->isAnyMemberInitializer()) { 305 OS << ' '; 306 dumpBareDeclRef(Init->getAnyMember()); 307 } else if (Init->isBaseInitializer()) { 308 dumpType(QualType(Init->getBaseClass(), 0)); 309 } else if (Init->isDelegatingInitializer()) { 310 dumpType(Init->getTypeSourceInfo()->getType()); 311 } else { 312 llvm_unreachable("Unknown initializer type"); 313 } 314 } 315 316 void TextNodeDumper::Visit(const BlockDecl::Capture &C) { 317 OS << "capture"; 318 if (C.isByRef()) 319 OS << " byref"; 320 if (C.isNested()) 321 OS << " nested"; 322 if (C.getVariable()) { 323 OS << ' '; 324 dumpBareDeclRef(C.getVariable()); 325 } 326 } 327 328 void TextNodeDumper::Visit(const OMPClause *C) { 329 if (!C) { 330 ColorScope Color(OS, ShowColors, NullColor); 331 OS << "<<<NULL>>> OMPClause"; 332 return; 333 } 334 { 335 ColorScope Color(OS, ShowColors, AttrColor); 336 StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind())); 337 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() 338 << ClauseName.drop_front() << "Clause"; 339 } 340 dumpPointer(C); 341 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); 342 if (C->isImplicit()) 343 OS << " <implicit>"; 344 } 345 346 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) { 347 const TypeSourceInfo *TSI = A.getTypeSourceInfo(); 348 if (TSI) { 349 OS << "case "; 350 dumpType(TSI->getType()); 351 } else { 352 OS << "default"; 353 } 354 355 if (A.isSelected()) 356 OS << " selected"; 357 } 358 359 void TextNodeDumper::Visit(const concepts::Requirement *R) { 360 if (!R) { 361 ColorScope Color(OS, ShowColors, NullColor); 362 OS << "<<<NULL>>> Requirement"; 363 return; 364 } 365 366 { 367 ColorScope Color(OS, ShowColors, StmtColor); 368 switch (R->getKind()) { 369 case concepts::Requirement::RK_Type: 370 OS << "TypeRequirement"; 371 break; 372 case concepts::Requirement::RK_Simple: 373 OS << "SimpleRequirement"; 374 break; 375 case concepts::Requirement::RK_Compound: 376 OS << "CompoundRequirement"; 377 break; 378 case concepts::Requirement::RK_Nested: 379 OS << "NestedRequirement"; 380 break; 381 } 382 } 383 384 dumpPointer(R); 385 386 if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) { 387 if (ER->hasNoexceptRequirement()) 388 OS << " noexcept"; 389 } 390 391 if (R->isDependent()) 392 OS << " dependent"; 393 else 394 OS << (R->isSatisfied() ? " satisfied" : " unsatisfied"); 395 if (R->containsUnexpandedParameterPack()) 396 OS << " contains_unexpanded_pack"; 397 } 398 399 static double GetApproxValue(const llvm::APFloat &F) { 400 llvm::APFloat V = F; 401 bool ignored; 402 V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven, 403 &ignored); 404 return V.convertToDouble(); 405 } 406 407 /// True if the \p APValue \p Value can be folded onto the current line. 408 static bool isSimpleAPValue(const APValue &Value) { 409 switch (Value.getKind()) { 410 case APValue::None: 411 case APValue::Indeterminate: 412 case APValue::Int: 413 case APValue::Float: 414 case APValue::FixedPoint: 415 case APValue::ComplexInt: 416 case APValue::ComplexFloat: 417 case APValue::LValue: 418 case APValue::MemberPointer: 419 case APValue::AddrLabelDiff: 420 return true; 421 case APValue::Vector: 422 case APValue::Array: 423 case APValue::Struct: 424 return false; 425 case APValue::Union: 426 return isSimpleAPValue(Value.getUnionValue()); 427 } 428 llvm_unreachable("unexpected APValue kind!"); 429 } 430 431 /// Dump the children of the \p APValue \p Value. 432 /// 433 /// \param[in] Value The \p APValue to visit 434 /// \param[in] Ty The \p QualType passed to \p Visit 435 /// 436 /// \param[in] IdxToChildFun A function mapping an \p APValue and an index 437 /// to one of the child of the \p APValue 438 /// 439 /// \param[in] NumChildren \p IdxToChildFun will be called on \p Value with 440 /// the indices in the range \p [0,NumChildren( 441 /// 442 /// \param[in] LabelSingular The label to use on a line with a single child 443 /// \param[in] LabelPlurial The label to use on a line with multiple children 444 void TextNodeDumper::dumpAPValueChildren( 445 const APValue &Value, QualType Ty, 446 const APValue &(*IdxToChildFun)(const APValue &, unsigned), 447 unsigned NumChildren, StringRef LabelSingular, StringRef LabelPlurial) { 448 // To save some vertical space we print up to MaxChildrenPerLine APValues 449 // considered to be simple (by isSimpleAPValue) on a single line. 450 constexpr unsigned MaxChildrenPerLine = 4; 451 unsigned I = 0; 452 while (I < NumChildren) { 453 unsigned J = I; 454 while (J < NumChildren) { 455 if (isSimpleAPValue(IdxToChildFun(Value, J)) && 456 (J - I < MaxChildrenPerLine)) { 457 ++J; 458 continue; 459 } 460 break; 461 } 462 463 J = std::max(I + 1, J); 464 465 // Print [I,J) on a single line. 466 AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() { 467 for (unsigned X = I; X < J; ++X) { 468 Visit(IdxToChildFun(Value, X), Ty); 469 if (X + 1 != J) 470 OS << ", "; 471 } 472 }); 473 I = J; 474 } 475 } 476 477 void TextNodeDumper::Visit(const APValue &Value, QualType Ty) { 478 ColorScope Color(OS, ShowColors, ValueKindColor); 479 switch (Value.getKind()) { 480 case APValue::None: 481 OS << "None"; 482 return; 483 case APValue::Indeterminate: 484 OS << "Indeterminate"; 485 return; 486 case APValue::Int: 487 OS << "Int "; 488 { 489 ColorScope Color(OS, ShowColors, ValueColor); 490 OS << Value.getInt(); 491 } 492 return; 493 case APValue::Float: 494 OS << "Float "; 495 { 496 ColorScope Color(OS, ShowColors, ValueColor); 497 OS << GetApproxValue(Value.getFloat()); 498 } 499 return; 500 case APValue::FixedPoint: 501 OS << "FixedPoint "; 502 { 503 ColorScope Color(OS, ShowColors, ValueColor); 504 OS << Value.getFixedPoint(); 505 } 506 return; 507 case APValue::Vector: { 508 unsigned VectorLength = Value.getVectorLength(); 509 OS << "Vector length=" << VectorLength; 510 511 dumpAPValueChildren( 512 Value, Ty, 513 [](const APValue &Value, unsigned Index) -> const APValue & { 514 return Value.getVectorElt(Index); 515 }, 516 VectorLength, "element", "elements"); 517 return; 518 } 519 case APValue::ComplexInt: 520 OS << "ComplexInt "; 521 { 522 ColorScope Color(OS, ShowColors, ValueColor); 523 OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag() 524 << 'i'; 525 } 526 return; 527 case APValue::ComplexFloat: 528 OS << "ComplexFloat "; 529 { 530 ColorScope Color(OS, ShowColors, ValueColor); 531 OS << GetApproxValue(Value.getComplexFloatReal()) << " + " 532 << GetApproxValue(Value.getComplexFloatImag()) << 'i'; 533 } 534 return; 535 case APValue::LValue: 536 (void)Context; 537 OS << "LValue <todo>"; 538 return; 539 case APValue::Array: { 540 unsigned ArraySize = Value.getArraySize(); 541 unsigned NumInitializedElements = Value.getArrayInitializedElts(); 542 OS << "Array size=" << ArraySize; 543 544 dumpAPValueChildren( 545 Value, Ty, 546 [](const APValue &Value, unsigned Index) -> const APValue & { 547 return Value.getArrayInitializedElt(Index); 548 }, 549 NumInitializedElements, "element", "elements"); 550 551 if (Value.hasArrayFiller()) { 552 AddChild("filler", [=] { 553 { 554 ColorScope Color(OS, ShowColors, ValueColor); 555 OS << ArraySize - NumInitializedElements << " x "; 556 } 557 Visit(Value.getArrayFiller(), Ty); 558 }); 559 } 560 561 return; 562 } 563 case APValue::Struct: { 564 OS << "Struct"; 565 566 dumpAPValueChildren( 567 Value, Ty, 568 [](const APValue &Value, unsigned Index) -> const APValue & { 569 return Value.getStructBase(Index); 570 }, 571 Value.getStructNumBases(), "base", "bases"); 572 573 dumpAPValueChildren( 574 Value, Ty, 575 [](const APValue &Value, unsigned Index) -> const APValue & { 576 return Value.getStructField(Index); 577 }, 578 Value.getStructNumFields(), "field", "fields"); 579 580 return; 581 } 582 case APValue::Union: { 583 OS << "Union"; 584 { 585 ColorScope Color(OS, ShowColors, ValueColor); 586 if (const FieldDecl *FD = Value.getUnionField()) 587 OS << " ." << *cast<NamedDecl>(FD); 588 } 589 // If the union value is considered to be simple, fold it into the 590 // current line to save some vertical space. 591 const APValue &UnionValue = Value.getUnionValue(); 592 if (isSimpleAPValue(UnionValue)) { 593 OS << ' '; 594 Visit(UnionValue, Ty); 595 } else { 596 AddChild([=] { Visit(UnionValue, Ty); }); 597 } 598 599 return; 600 } 601 case APValue::MemberPointer: 602 OS << "MemberPointer <todo>"; 603 return; 604 case APValue::AddrLabelDiff: 605 OS << "AddrLabelDiff <todo>"; 606 return; 607 } 608 llvm_unreachable("Unknown APValue kind!"); 609 } 610 611 void TextNodeDumper::dumpPointer(const void *Ptr) { 612 ColorScope Color(OS, ShowColors, AddressColor); 613 OS << ' ' << Ptr; 614 } 615 616 void TextNodeDumper::dumpLocation(SourceLocation Loc) { 617 if (!SM) 618 return; 619 620 ColorScope Color(OS, ShowColors, LocationColor); 621 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); 622 623 // The general format we print out is filename:line:col, but we drop pieces 624 // that haven't changed since the last loc printed. 625 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); 626 627 if (PLoc.isInvalid()) { 628 OS << "<invalid sloc>"; 629 return; 630 } 631 632 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { 633 OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':' 634 << PLoc.getColumn(); 635 LastLocFilename = PLoc.getFilename(); 636 LastLocLine = PLoc.getLine(); 637 } else if (PLoc.getLine() != LastLocLine) { 638 OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn(); 639 LastLocLine = PLoc.getLine(); 640 } else { 641 OS << "col" << ':' << PLoc.getColumn(); 642 } 643 } 644 645 void TextNodeDumper::dumpSourceRange(SourceRange R) { 646 // Can't translate locations if a SourceManager isn't available. 647 if (!SM) 648 return; 649 650 OS << " <"; 651 dumpLocation(R.getBegin()); 652 if (R.getBegin() != R.getEnd()) { 653 OS << ", "; 654 dumpLocation(R.getEnd()); 655 } 656 OS << ">"; 657 658 // <t2.c:123:421[blah], t2.c:412:321> 659 } 660 661 void TextNodeDumper::dumpBareType(QualType T, bool Desugar) { 662 ColorScope Color(OS, ShowColors, TypeColor); 663 664 SplitQualType T_split = T.split(); 665 OS << "'" << QualType::getAsString(T_split, PrintPolicy) << "'"; 666 667 if (Desugar && !T.isNull()) { 668 // If the type is sugared, also dump a (shallow) desugared type. 669 SplitQualType D_split = T.getSplitDesugaredType(); 670 if (T_split != D_split) 671 OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'"; 672 } 673 } 674 675 void TextNodeDumper::dumpType(QualType T) { 676 OS << ' '; 677 dumpBareType(T); 678 } 679 680 void TextNodeDumper::dumpBareDeclRef(const Decl *D) { 681 if (!D) { 682 ColorScope Color(OS, ShowColors, NullColor); 683 OS << "<<<NULL>>>"; 684 return; 685 } 686 687 { 688 ColorScope Color(OS, ShowColors, DeclKindNameColor); 689 OS << D->getDeclKindName(); 690 } 691 dumpPointer(D); 692 693 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 694 ColorScope Color(OS, ShowColors, DeclNameColor); 695 OS << " '" << ND->getDeclName() << '\''; 696 } 697 698 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 699 dumpType(VD->getType()); 700 } 701 702 void TextNodeDumper::dumpName(const NamedDecl *ND) { 703 if (ND->getDeclName()) { 704 ColorScope Color(OS, ShowColors, DeclNameColor); 705 OS << ' ' << ND->getDeclName(); 706 } 707 } 708 709 void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) { 710 const auto AccessSpelling = getAccessSpelling(AS); 711 if (AccessSpelling.empty()) 712 return; 713 OS << AccessSpelling; 714 } 715 716 void TextNodeDumper::dumpCleanupObject( 717 const ExprWithCleanups::CleanupObject &C) { 718 if (auto *BD = C.dyn_cast<BlockDecl *>()) 719 dumpDeclRef(BD, "cleanup"); 720 else if (auto *CLE = C.dyn_cast<CompoundLiteralExpr *>()) 721 AddChild([=] { 722 OS << "cleanup "; 723 { 724 ColorScope Color(OS, ShowColors, StmtColor); 725 OS << CLE->getStmtClassName(); 726 } 727 dumpPointer(CLE); 728 }); 729 else 730 llvm_unreachable("unexpected cleanup type"); 731 } 732 733 void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) { 734 if (!D) 735 return; 736 737 AddChild([=] { 738 if (!Label.empty()) 739 OS << Label << ' '; 740 dumpBareDeclRef(D); 741 }); 742 } 743 744 const char *TextNodeDumper::getCommandName(unsigned CommandID) { 745 if (Traits) 746 return Traits->getCommandInfo(CommandID)->Name; 747 const comments::CommandInfo *Info = 748 comments::CommandTraits::getBuiltinCommandInfo(CommandID); 749 if (Info) 750 return Info->Name; 751 return "<not a builtin command>"; 752 } 753 754 void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) { 755 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ 756 if (FPO.has##NAME##Override()) \ 757 OS << " " #NAME "=" << FPO.get##NAME##Override(); 758 #include "clang/Basic/FPOptions.def" 759 } 760 761 void TextNodeDumper::visitTextComment(const comments::TextComment *C, 762 const comments::FullComment *) { 763 OS << " Text=\"" << C->getText() << "\""; 764 } 765 766 void TextNodeDumper::visitInlineCommandComment( 767 const comments::InlineCommandComment *C, const comments::FullComment *) { 768 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 769 switch (C->getRenderKind()) { 770 case comments::InlineCommandComment::RenderNormal: 771 OS << " RenderNormal"; 772 break; 773 case comments::InlineCommandComment::RenderBold: 774 OS << " RenderBold"; 775 break; 776 case comments::InlineCommandComment::RenderMonospaced: 777 OS << " RenderMonospaced"; 778 break; 779 case comments::InlineCommandComment::RenderEmphasized: 780 OS << " RenderEmphasized"; 781 break; 782 case comments::InlineCommandComment::RenderAnchor: 783 OS << " RenderAnchor"; 784 break; 785 } 786 787 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 788 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 789 } 790 791 void TextNodeDumper::visitHTMLStartTagComment( 792 const comments::HTMLStartTagComment *C, const comments::FullComment *) { 793 OS << " Name=\"" << C->getTagName() << "\""; 794 if (C->getNumAttrs() != 0) { 795 OS << " Attrs: "; 796 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { 797 const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 798 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; 799 } 800 } 801 if (C->isSelfClosing()) 802 OS << " SelfClosing"; 803 } 804 805 void TextNodeDumper::visitHTMLEndTagComment( 806 const comments::HTMLEndTagComment *C, const comments::FullComment *) { 807 OS << " Name=\"" << C->getTagName() << "\""; 808 } 809 810 void TextNodeDumper::visitBlockCommandComment( 811 const comments::BlockCommandComment *C, const comments::FullComment *) { 812 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 813 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 814 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 815 } 816 817 void TextNodeDumper::visitParamCommandComment( 818 const comments::ParamCommandComment *C, const comments::FullComment *FC) { 819 OS << " " 820 << comments::ParamCommandComment::getDirectionAsString(C->getDirection()); 821 822 if (C->isDirectionExplicit()) 823 OS << " explicitly"; 824 else 825 OS << " implicitly"; 826 827 if (C->hasParamName()) { 828 if (C->isParamIndexValid()) 829 OS << " Param=\"" << C->getParamName(FC) << "\""; 830 else 831 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 832 } 833 834 if (C->isParamIndexValid() && !C->isVarArgParam()) 835 OS << " ParamIndex=" << C->getParamIndex(); 836 } 837 838 void TextNodeDumper::visitTParamCommandComment( 839 const comments::TParamCommandComment *C, const comments::FullComment *FC) { 840 if (C->hasParamName()) { 841 if (C->isPositionValid()) 842 OS << " Param=\"" << C->getParamName(FC) << "\""; 843 else 844 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 845 } 846 847 if (C->isPositionValid()) { 848 OS << " Position=<"; 849 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { 850 OS << C->getIndex(i); 851 if (i != e - 1) 852 OS << ", "; 853 } 854 OS << ">"; 855 } 856 } 857 858 void TextNodeDumper::visitVerbatimBlockComment( 859 const comments::VerbatimBlockComment *C, const comments::FullComment *) { 860 OS << " Name=\"" << getCommandName(C->getCommandID()) 861 << "\"" 862 " CloseName=\"" 863 << C->getCloseName() << "\""; 864 } 865 866 void TextNodeDumper::visitVerbatimBlockLineComment( 867 const comments::VerbatimBlockLineComment *C, 868 const comments::FullComment *) { 869 OS << " Text=\"" << C->getText() << "\""; 870 } 871 872 void TextNodeDumper::visitVerbatimLineComment( 873 const comments::VerbatimLineComment *C, const comments::FullComment *) { 874 OS << " Text=\"" << C->getText() << "\""; 875 } 876 877 void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) { 878 OS << " null"; 879 } 880 881 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) { 882 OS << " type"; 883 dumpType(TA.getAsType()); 884 } 885 886 void TextNodeDumper::VisitDeclarationTemplateArgument( 887 const TemplateArgument &TA) { 888 OS << " decl"; 889 dumpDeclRef(TA.getAsDecl()); 890 } 891 892 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &) { 893 OS << " nullptr"; 894 } 895 896 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) { 897 OS << " integral " << TA.getAsIntegral(); 898 } 899 900 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) { 901 OS << " template "; 902 TA.getAsTemplate().dump(OS); 903 } 904 905 void TextNodeDumper::VisitTemplateExpansionTemplateArgument( 906 const TemplateArgument &TA) { 907 OS << " template expansion "; 908 TA.getAsTemplateOrTemplatePattern().dump(OS); 909 } 910 911 void TextNodeDumper::VisitExpressionTemplateArgument(const TemplateArgument &) { 912 OS << " expr"; 913 } 914 915 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &) { 916 OS << " pack"; 917 } 918 919 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { 920 if (Node->path_empty()) 921 return; 922 923 OS << " ("; 924 bool First = true; 925 for (CastExpr::path_const_iterator I = Node->path_begin(), 926 E = Node->path_end(); 927 I != E; ++I) { 928 const CXXBaseSpecifier *Base = *I; 929 if (!First) 930 OS << " -> "; 931 932 const auto *RD = 933 cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl()); 934 935 if (Base->isVirtual()) 936 OS << "virtual "; 937 OS << RD->getName(); 938 First = false; 939 } 940 941 OS << ')'; 942 } 943 944 void TextNodeDumper::VisitIfStmt(const IfStmt *Node) { 945 if (Node->hasInitStorage()) 946 OS << " has_init"; 947 if (Node->hasVarStorage()) 948 OS << " has_var"; 949 if (Node->hasElseStorage()) 950 OS << " has_else"; 951 if (Node->isConstexpr()) 952 OS << " constexpr"; 953 if (Node->isConsteval()) { 954 OS << " "; 955 if (Node->isNegatedConsteval()) 956 OS << "!"; 957 OS << "consteval"; 958 } 959 } 960 961 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) { 962 if (Node->hasInitStorage()) 963 OS << " has_init"; 964 if (Node->hasVarStorage()) 965 OS << " has_var"; 966 } 967 968 void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) { 969 if (Node->hasVarStorage()) 970 OS << " has_var"; 971 } 972 973 void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) { 974 OS << " '" << Node->getName() << "'"; 975 if (Node->isSideEntry()) 976 OS << " side_entry"; 977 } 978 979 void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) { 980 OS << " '" << Node->getLabel()->getName() << "'"; 981 dumpPointer(Node->getLabel()); 982 } 983 984 void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) { 985 if (Node->caseStmtIsGNURange()) 986 OS << " gnu_range"; 987 } 988 989 void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) { 990 if (Node->hasAPValueResult()) 991 AddChild("value", 992 [=] { Visit(Node->getAPValueResult(), Node->getType()); }); 993 } 994 995 void TextNodeDumper::VisitCallExpr(const CallExpr *Node) { 996 if (Node->usesADL()) 997 OS << " adl"; 998 if (Node->hasStoredFPFeatures()) 999 printFPOptions(Node->getFPFeatures()); 1000 } 1001 1002 void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) { 1003 const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator()); 1004 if (OperatorSpelling) 1005 OS << " '" << OperatorSpelling << "'"; 1006 1007 VisitCallExpr(Node); 1008 } 1009 1010 void TextNodeDumper::VisitCastExpr(const CastExpr *Node) { 1011 OS << " <"; 1012 { 1013 ColorScope Color(OS, ShowColors, CastColor); 1014 OS << Node->getCastKindName(); 1015 } 1016 dumpBasePath(OS, Node); 1017 OS << ">"; 1018 if (Node->hasStoredFPFeatures()) 1019 printFPOptions(Node->getFPFeatures()); 1020 } 1021 1022 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) { 1023 VisitCastExpr(Node); 1024 if (Node->isPartOfExplicitCast()) 1025 OS << " part_of_explicit_cast"; 1026 } 1027 1028 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { 1029 OS << " "; 1030 dumpBareDeclRef(Node->getDecl()); 1031 if (Node->getDecl() != Node->getFoundDecl()) { 1032 OS << " ("; 1033 dumpBareDeclRef(Node->getFoundDecl()); 1034 OS << ")"; 1035 } 1036 switch (Node->isNonOdrUse()) { 1037 case NOUR_None: break; 1038 case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break; 1039 case NOUR_Constant: OS << " non_odr_use_constant"; break; 1040 case NOUR_Discarded: OS << " non_odr_use_discarded"; break; 1041 } 1042 } 1043 1044 void TextNodeDumper::VisitUnresolvedLookupExpr( 1045 const UnresolvedLookupExpr *Node) { 1046 OS << " ("; 1047 if (!Node->requiresADL()) 1048 OS << "no "; 1049 OS << "ADL) = '" << Node->getName() << '\''; 1050 1051 UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(), 1052 E = Node->decls_end(); 1053 if (I == E) 1054 OS << " empty"; 1055 for (; I != E; ++I) 1056 dumpPointer(*I); 1057 } 1058 1059 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { 1060 { 1061 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1062 OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; 1063 } 1064 OS << "='" << *Node->getDecl() << "'"; 1065 dumpPointer(Node->getDecl()); 1066 if (Node->isFreeIvar()) 1067 OS << " isFreeIvar"; 1068 } 1069 1070 void TextNodeDumper::VisitSYCLUniqueStableNameExpr( 1071 const SYCLUniqueStableNameExpr *Node) { 1072 dumpType(Node->getTypeSourceInfo()->getType()); 1073 } 1074 1075 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { 1076 OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind()); 1077 } 1078 1079 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { 1080 ColorScope Color(OS, ShowColors, ValueColor); 1081 OS << " " << Node->getValue(); 1082 } 1083 1084 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) { 1085 bool isSigned = Node->getType()->isSignedIntegerType(); 1086 ColorScope Color(OS, ShowColors, ValueColor); 1087 OS << " " << toString(Node->getValue(), 10, isSigned); 1088 } 1089 1090 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) { 1091 ColorScope Color(OS, ShowColors, ValueColor); 1092 OS << " " << Node->getValueAsString(/*Radix=*/10); 1093 } 1094 1095 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { 1096 ColorScope Color(OS, ShowColors, ValueColor); 1097 OS << " " << Node->getValueAsApproximateDouble(); 1098 } 1099 1100 void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) { 1101 ColorScope Color(OS, ShowColors, ValueColor); 1102 OS << " "; 1103 Str->outputString(OS); 1104 } 1105 1106 void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) { 1107 if (auto *Field = ILE->getInitializedFieldInUnion()) { 1108 OS << " field "; 1109 dumpBareDeclRef(Field); 1110 } 1111 } 1112 1113 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) { 1114 if (E->isResultDependent()) 1115 OS << " result_dependent"; 1116 } 1117 1118 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) { 1119 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '" 1120 << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1121 if (!Node->canOverflow()) 1122 OS << " cannot overflow"; 1123 if (Node->hasStoredFPFeatures()) 1124 printFPOptions(Node->getStoredFPFeatures()); 1125 } 1126 1127 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr( 1128 const UnaryExprOrTypeTraitExpr *Node) { 1129 OS << " " << getTraitSpelling(Node->getKind()); 1130 1131 if (Node->isArgumentType()) 1132 dumpType(Node->getArgumentType()); 1133 } 1134 1135 void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) { 1136 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); 1137 dumpPointer(Node->getMemberDecl()); 1138 switch (Node->isNonOdrUse()) { 1139 case NOUR_None: break; 1140 case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break; 1141 case NOUR_Constant: OS << " non_odr_use_constant"; break; 1142 case NOUR_Discarded: OS << " non_odr_use_discarded"; break; 1143 } 1144 } 1145 1146 void TextNodeDumper::VisitExtVectorElementExpr( 1147 const ExtVectorElementExpr *Node) { 1148 OS << " " << Node->getAccessor().getNameStart(); 1149 } 1150 1151 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) { 1152 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1153 if (Node->hasStoredFPFeatures()) 1154 printFPOptions(Node->getStoredFPFeatures()); 1155 } 1156 1157 void TextNodeDumper::VisitCompoundAssignOperator( 1158 const CompoundAssignOperator *Node) { 1159 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 1160 << "' ComputeLHSTy="; 1161 dumpBareType(Node->getComputationLHSType()); 1162 OS << " ComputeResultTy="; 1163 dumpBareType(Node->getComputationResultType()); 1164 if (Node->hasStoredFPFeatures()) 1165 printFPOptions(Node->getStoredFPFeatures()); 1166 } 1167 1168 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { 1169 OS << " " << Node->getLabel()->getName(); 1170 dumpPointer(Node->getLabel()); 1171 } 1172 1173 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) { 1174 OS << " " << Node->getCastName() << "<" 1175 << Node->getTypeAsWritten().getAsString() << ">" 1176 << " <" << Node->getCastKindName(); 1177 dumpBasePath(OS, Node); 1178 OS << ">"; 1179 } 1180 1181 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { 1182 OS << " " << (Node->getValue() ? "true" : "false"); 1183 } 1184 1185 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { 1186 if (Node->isImplicit()) 1187 OS << " implicit"; 1188 OS << " this"; 1189 } 1190 1191 void TextNodeDumper::VisitCXXFunctionalCastExpr( 1192 const CXXFunctionalCastExpr *Node) { 1193 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <" 1194 << Node->getCastKindName() << ">"; 1195 if (Node->hasStoredFPFeatures()) 1196 printFPOptions(Node->getFPFeatures()); 1197 } 1198 1199 void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) { 1200 VisitCXXNamedCastExpr(Node); 1201 if (Node->hasStoredFPFeatures()) 1202 printFPOptions(Node->getFPFeatures()); 1203 } 1204 1205 void TextNodeDumper::VisitCXXUnresolvedConstructExpr( 1206 const CXXUnresolvedConstructExpr *Node) { 1207 dumpType(Node->getTypeAsWritten()); 1208 if (Node->isListInitialization()) 1209 OS << " list"; 1210 } 1211 1212 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { 1213 CXXConstructorDecl *Ctor = Node->getConstructor(); 1214 dumpType(Ctor->getType()); 1215 if (Node->isElidable()) 1216 OS << " elidable"; 1217 if (Node->isListInitialization()) 1218 OS << " list"; 1219 if (Node->isStdInitListInitialization()) 1220 OS << " std::initializer_list"; 1221 if (Node->requiresZeroInitialization()) 1222 OS << " zeroing"; 1223 } 1224 1225 void TextNodeDumper::VisitCXXBindTemporaryExpr( 1226 const CXXBindTemporaryExpr *Node) { 1227 OS << " (CXXTemporary"; 1228 dumpPointer(Node); 1229 OS << ")"; 1230 } 1231 1232 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) { 1233 if (Node->isGlobalNew()) 1234 OS << " global"; 1235 if (Node->isArray()) 1236 OS << " array"; 1237 if (Node->getOperatorNew()) { 1238 OS << ' '; 1239 dumpBareDeclRef(Node->getOperatorNew()); 1240 } 1241 // We could dump the deallocation function used in case of error, but it's 1242 // usually not that interesting. 1243 } 1244 1245 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) { 1246 if (Node->isGlobalDelete()) 1247 OS << " global"; 1248 if (Node->isArrayForm()) 1249 OS << " array"; 1250 if (Node->getOperatorDelete()) { 1251 OS << ' '; 1252 dumpBareDeclRef(Node->getOperatorDelete()); 1253 } 1254 } 1255 1256 void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) { 1257 OS << " " << getTraitSpelling(Node->getTrait()); 1258 } 1259 1260 void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) { 1261 OS << " " << getTraitSpelling(Node->getTrait()); 1262 } 1263 1264 void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) { 1265 OS << " " << getTraitSpelling(Node->getTrait()); 1266 } 1267 1268 void TextNodeDumper::VisitMaterializeTemporaryExpr( 1269 const MaterializeTemporaryExpr *Node) { 1270 if (const ValueDecl *VD = Node->getExtendingDecl()) { 1271 OS << " extended by "; 1272 dumpBareDeclRef(VD); 1273 } 1274 } 1275 1276 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) { 1277 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) 1278 dumpCleanupObject(Node->getObject(i)); 1279 } 1280 1281 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) { 1282 dumpPointer(Node->getPack()); 1283 dumpName(Node->getPack()); 1284 } 1285 1286 void TextNodeDumper::VisitCXXDependentScopeMemberExpr( 1287 const CXXDependentScopeMemberExpr *Node) { 1288 OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember(); 1289 } 1290 1291 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { 1292 OS << " selector="; 1293 Node->getSelector().print(OS); 1294 switch (Node->getReceiverKind()) { 1295 case ObjCMessageExpr::Instance: 1296 break; 1297 1298 case ObjCMessageExpr::Class: 1299 OS << " class="; 1300 dumpBareType(Node->getClassReceiver()); 1301 break; 1302 1303 case ObjCMessageExpr::SuperInstance: 1304 OS << " super (instance)"; 1305 break; 1306 1307 case ObjCMessageExpr::SuperClass: 1308 OS << " super (class)"; 1309 break; 1310 } 1311 } 1312 1313 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { 1314 if (auto *BoxingMethod = Node->getBoxingMethod()) { 1315 OS << " selector="; 1316 BoxingMethod->getSelector().print(OS); 1317 } 1318 } 1319 1320 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 1321 if (!Node->getCatchParamDecl()) 1322 OS << " catch all"; 1323 } 1324 1325 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { 1326 dumpType(Node->getEncodedType()); 1327 } 1328 1329 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { 1330 OS << " "; 1331 Node->getSelector().print(OS); 1332 } 1333 1334 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { 1335 OS << ' ' << *Node->getProtocol(); 1336 } 1337 1338 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { 1339 if (Node->isImplicitProperty()) { 1340 OS << " Kind=MethodRef Getter=\""; 1341 if (Node->getImplicitPropertyGetter()) 1342 Node->getImplicitPropertyGetter()->getSelector().print(OS); 1343 else 1344 OS << "(null)"; 1345 1346 OS << "\" Setter=\""; 1347 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 1348 Setter->getSelector().print(OS); 1349 else 1350 OS << "(null)"; 1351 OS << "\""; 1352 } else { 1353 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() 1354 << '"'; 1355 } 1356 1357 if (Node->isSuperReceiver()) 1358 OS << " super"; 1359 1360 OS << " Messaging="; 1361 if (Node->isMessagingGetter() && Node->isMessagingSetter()) 1362 OS << "Getter&Setter"; 1363 else if (Node->isMessagingGetter()) 1364 OS << "Getter"; 1365 else if (Node->isMessagingSetter()) 1366 OS << "Setter"; 1367 } 1368 1369 void TextNodeDumper::VisitObjCSubscriptRefExpr( 1370 const ObjCSubscriptRefExpr *Node) { 1371 if (Node->isArraySubscriptRefExpr()) 1372 OS << " Kind=ArraySubscript GetterForArray=\""; 1373 else 1374 OS << " Kind=DictionarySubscript GetterForDictionary=\""; 1375 if (Node->getAtIndexMethodDecl()) 1376 Node->getAtIndexMethodDecl()->getSelector().print(OS); 1377 else 1378 OS << "(null)"; 1379 1380 if (Node->isArraySubscriptRefExpr()) 1381 OS << "\" SetterForArray=\""; 1382 else 1383 OS << "\" SetterForDictionary=\""; 1384 if (Node->setAtIndexMethodDecl()) 1385 Node->setAtIndexMethodDecl()->getSelector().print(OS); 1386 else 1387 OS << "(null)"; 1388 } 1389 1390 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { 1391 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 1392 } 1393 1394 void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) { 1395 OS << " "; 1396 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) { 1397 Visit(Node->getIteratorDecl(I)); 1398 OS << " = "; 1399 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I); 1400 OS << " begin "; 1401 Visit(Range.Begin); 1402 OS << " end "; 1403 Visit(Range.End); 1404 if (Range.Step) { 1405 OS << " step "; 1406 Visit(Range.Step); 1407 } 1408 } 1409 } 1410 1411 void TextNodeDumper::VisitConceptSpecializationExpr( 1412 const ConceptSpecializationExpr *Node) { 1413 OS << " "; 1414 dumpBareDeclRef(Node->getFoundDecl()); 1415 } 1416 1417 void TextNodeDumper::VisitRequiresExpr( 1418 const RequiresExpr *Node) { 1419 if (!Node->isValueDependent()) 1420 OS << (Node->isSatisfied() ? " satisfied" : " unsatisfied"); 1421 } 1422 1423 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) { 1424 if (T->isSpelledAsLValue()) 1425 OS << " written as lvalue reference"; 1426 } 1427 1428 void TextNodeDumper::VisitArrayType(const ArrayType *T) { 1429 switch (T->getSizeModifier()) { 1430 case ArrayType::Normal: 1431 break; 1432 case ArrayType::Static: 1433 OS << " static"; 1434 break; 1435 case ArrayType::Star: 1436 OS << " *"; 1437 break; 1438 } 1439 OS << " " << T->getIndexTypeQualifiers().getAsString(); 1440 } 1441 1442 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) { 1443 OS << " " << T->getSize(); 1444 VisitArrayType(T); 1445 } 1446 1447 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) { 1448 OS << " "; 1449 dumpSourceRange(T->getBracketsRange()); 1450 VisitArrayType(T); 1451 } 1452 1453 void TextNodeDumper::VisitDependentSizedArrayType( 1454 const DependentSizedArrayType *T) { 1455 VisitArrayType(T); 1456 OS << " "; 1457 dumpSourceRange(T->getBracketsRange()); 1458 } 1459 1460 void TextNodeDumper::VisitDependentSizedExtVectorType( 1461 const DependentSizedExtVectorType *T) { 1462 OS << " "; 1463 dumpLocation(T->getAttributeLoc()); 1464 } 1465 1466 void TextNodeDumper::VisitVectorType(const VectorType *T) { 1467 switch (T->getVectorKind()) { 1468 case VectorType::GenericVector: 1469 break; 1470 case VectorType::AltiVecVector: 1471 OS << " altivec"; 1472 break; 1473 case VectorType::AltiVecPixel: 1474 OS << " altivec pixel"; 1475 break; 1476 case VectorType::AltiVecBool: 1477 OS << " altivec bool"; 1478 break; 1479 case VectorType::NeonVector: 1480 OS << " neon"; 1481 break; 1482 case VectorType::NeonPolyVector: 1483 OS << " neon poly"; 1484 break; 1485 case VectorType::SveFixedLengthDataVector: 1486 OS << " fixed-length sve data vector"; 1487 break; 1488 case VectorType::SveFixedLengthPredicateVector: 1489 OS << " fixed-length sve predicate vector"; 1490 break; 1491 } 1492 OS << " " << T->getNumElements(); 1493 } 1494 1495 void TextNodeDumper::VisitFunctionType(const FunctionType *T) { 1496 auto EI = T->getExtInfo(); 1497 if (EI.getNoReturn()) 1498 OS << " noreturn"; 1499 if (EI.getProducesResult()) 1500 OS << " produces_result"; 1501 if (EI.getHasRegParm()) 1502 OS << " regparm " << EI.getRegParm(); 1503 OS << " " << FunctionType::getNameForCallConv(EI.getCC()); 1504 } 1505 1506 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) { 1507 auto EPI = T->getExtProtoInfo(); 1508 if (EPI.HasTrailingReturn) 1509 OS << " trailing_return"; 1510 if (T->isConst()) 1511 OS << " const"; 1512 if (T->isVolatile()) 1513 OS << " volatile"; 1514 if (T->isRestrict()) 1515 OS << " restrict"; 1516 if (T->getExtProtoInfo().Variadic) 1517 OS << " variadic"; 1518 switch (EPI.RefQualifier) { 1519 case RQ_None: 1520 break; 1521 case RQ_LValue: 1522 OS << " &"; 1523 break; 1524 case RQ_RValue: 1525 OS << " &&"; 1526 break; 1527 } 1528 // FIXME: Exception specification. 1529 // FIXME: Consumed parameters. 1530 VisitFunctionType(T); 1531 } 1532 1533 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) { 1534 dumpDeclRef(T->getDecl()); 1535 } 1536 1537 void TextNodeDumper::VisitUsingType(const UsingType *T) { 1538 dumpDeclRef(T->getFoundDecl()); 1539 } 1540 1541 void TextNodeDumper::VisitTypedefType(const TypedefType *T) { 1542 dumpDeclRef(T->getDecl()); 1543 } 1544 1545 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) { 1546 switch (T->getUTTKind()) { 1547 case UnaryTransformType::EnumUnderlyingType: 1548 OS << " underlying_type"; 1549 break; 1550 } 1551 } 1552 1553 void TextNodeDumper::VisitTagType(const TagType *T) { 1554 dumpDeclRef(T->getDecl()); 1555 } 1556 1557 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) { 1558 OS << " depth " << T->getDepth() << " index " << T->getIndex(); 1559 if (T->isParameterPack()) 1560 OS << " pack"; 1561 dumpDeclRef(T->getDecl()); 1562 } 1563 1564 void TextNodeDumper::VisitAutoType(const AutoType *T) { 1565 if (T->isDecltypeAuto()) 1566 OS << " decltype(auto)"; 1567 if (!T->isDeduced()) 1568 OS << " undeduced"; 1569 if (T->isConstrained()) { 1570 dumpDeclRef(T->getTypeConstraintConcept()); 1571 for (const auto &Arg : T->getTypeConstraintArguments()) 1572 VisitTemplateArgument(Arg); 1573 } 1574 } 1575 1576 void TextNodeDumper::VisitTemplateSpecializationType( 1577 const TemplateSpecializationType *T) { 1578 if (T->isTypeAlias()) 1579 OS << " alias"; 1580 OS << " "; 1581 T->getTemplateName().dump(OS); 1582 } 1583 1584 void TextNodeDumper::VisitInjectedClassNameType( 1585 const InjectedClassNameType *T) { 1586 dumpDeclRef(T->getDecl()); 1587 } 1588 1589 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) { 1590 dumpDeclRef(T->getDecl()); 1591 } 1592 1593 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) { 1594 if (auto N = T->getNumExpansions()) 1595 OS << " expansions " << *N; 1596 } 1597 1598 void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); } 1599 1600 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) { 1601 dumpName(D); 1602 dumpType(D->getUnderlyingType()); 1603 if (D->isModulePrivate()) 1604 OS << " __module_private__"; 1605 } 1606 1607 void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) { 1608 if (D->isScoped()) { 1609 if (D->isScopedUsingClassTag()) 1610 OS << " class"; 1611 else 1612 OS << " struct"; 1613 } 1614 dumpName(D); 1615 if (D->isModulePrivate()) 1616 OS << " __module_private__"; 1617 if (D->isFixed()) 1618 dumpType(D->getIntegerType()); 1619 } 1620 1621 void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) { 1622 OS << ' ' << D->getKindName(); 1623 dumpName(D); 1624 if (D->isModulePrivate()) 1625 OS << " __module_private__"; 1626 if (D->isCompleteDefinition()) 1627 OS << " definition"; 1628 } 1629 1630 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { 1631 dumpName(D); 1632 dumpType(D->getType()); 1633 } 1634 1635 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { 1636 dumpName(D); 1637 dumpType(D->getType()); 1638 1639 for (const auto *Child : D->chain()) 1640 dumpDeclRef(Child); 1641 } 1642 1643 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) { 1644 dumpName(D); 1645 dumpType(D->getType()); 1646 1647 StorageClass SC = D->getStorageClass(); 1648 if (SC != SC_None) 1649 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 1650 if (D->isInlineSpecified()) 1651 OS << " inline"; 1652 if (D->isVirtualAsWritten()) 1653 OS << " virtual"; 1654 if (D->isModulePrivate()) 1655 OS << " __module_private__"; 1656 1657 if (D->isPure()) 1658 OS << " pure"; 1659 if (D->isDefaulted()) { 1660 OS << " default"; 1661 if (D->isDeleted()) 1662 OS << "_delete"; 1663 } 1664 if (D->isDeletedAsWritten()) 1665 OS << " delete"; 1666 if (D->isTrivial()) 1667 OS << " trivial"; 1668 1669 if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) { 1670 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 1671 switch (EPI.ExceptionSpec.Type) { 1672 default: 1673 break; 1674 case EST_Unevaluated: 1675 OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl; 1676 break; 1677 case EST_Uninstantiated: 1678 OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate; 1679 break; 1680 } 1681 } 1682 1683 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) { 1684 if (MD->size_overridden_methods() != 0) { 1685 auto dumpOverride = [=](const CXXMethodDecl *D) { 1686 SplitQualType T_split = D->getType().split(); 1687 OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName() 1688 << " '" << QualType::getAsString(T_split, PrintPolicy) << "'"; 1689 }; 1690 1691 AddChild([=] { 1692 auto Overrides = MD->overridden_methods(); 1693 OS << "Overrides: [ "; 1694 dumpOverride(*Overrides.begin()); 1695 for (const auto *Override : 1696 llvm::make_range(Overrides.begin() + 1, Overrides.end())) { 1697 OS << ", "; 1698 dumpOverride(Override); 1699 } 1700 OS << " ]"; 1701 }); 1702 } 1703 } 1704 1705 // Since NumParams comes from the FunctionProtoType of the FunctionDecl and 1706 // the Params are set later, it is possible for a dump during debugging to 1707 // encounter a FunctionDecl that has been created but hasn't been assigned 1708 // ParmVarDecls yet. 1709 if (!D->param_empty() && !D->param_begin()) 1710 OS << " <<<NULL params x " << D->getNumParams() << ">>>"; 1711 } 1712 1713 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl( 1714 const LifetimeExtendedTemporaryDecl *D) { 1715 OS << " extended by "; 1716 dumpBareDeclRef(D->getExtendingDecl()); 1717 OS << " mangling "; 1718 { 1719 ColorScope Color(OS, ShowColors, ValueColor); 1720 OS << D->getManglingNumber(); 1721 } 1722 } 1723 1724 void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) { 1725 dumpName(D); 1726 dumpType(D->getType()); 1727 if (D->isMutable()) 1728 OS << " mutable"; 1729 if (D->isModulePrivate()) 1730 OS << " __module_private__"; 1731 } 1732 1733 void TextNodeDumper::VisitVarDecl(const VarDecl *D) { 1734 dumpName(D); 1735 dumpType(D->getType()); 1736 StorageClass SC = D->getStorageClass(); 1737 if (SC != SC_None) 1738 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 1739 switch (D->getTLSKind()) { 1740 case VarDecl::TLS_None: 1741 break; 1742 case VarDecl::TLS_Static: 1743 OS << " tls"; 1744 break; 1745 case VarDecl::TLS_Dynamic: 1746 OS << " tls_dynamic"; 1747 break; 1748 } 1749 if (D->isModulePrivate()) 1750 OS << " __module_private__"; 1751 if (D->isNRVOVariable()) 1752 OS << " nrvo"; 1753 if (D->isInline()) 1754 OS << " inline"; 1755 if (D->isConstexpr()) 1756 OS << " constexpr"; 1757 if (D->hasInit()) { 1758 switch (D->getInitStyle()) { 1759 case VarDecl::CInit: 1760 OS << " cinit"; 1761 break; 1762 case VarDecl::CallInit: 1763 OS << " callinit"; 1764 break; 1765 case VarDecl::ListInit: 1766 OS << " listinit"; 1767 break; 1768 } 1769 } 1770 if (D->needsDestruction(D->getASTContext())) 1771 OS << " destroyed"; 1772 if (D->isParameterPack()) 1773 OS << " pack"; 1774 1775 if (D->hasInit()) { 1776 const Expr *E = D->getInit(); 1777 // Only dump the value of constexpr VarDecls for now. 1778 if (E && !E->isValueDependent() && D->isConstexpr()) { 1779 const APValue *Value = D->evaluateValue(); 1780 if (Value) 1781 AddChild("value", [=] { Visit(*Value, E->getType()); }); 1782 } 1783 } 1784 } 1785 1786 void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) { 1787 dumpName(D); 1788 dumpType(D->getType()); 1789 } 1790 1791 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) { 1792 if (D->isNothrow()) 1793 OS << " nothrow"; 1794 } 1795 1796 void TextNodeDumper::VisitImportDecl(const ImportDecl *D) { 1797 OS << ' ' << D->getImportedModule()->getFullModuleName(); 1798 1799 for (Decl *InitD : 1800 D->getASTContext().getModuleInitializers(D->getImportedModule())) 1801 dumpDeclRef(InitD, "initializer"); 1802 } 1803 1804 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) { 1805 OS << ' '; 1806 switch (D->getCommentKind()) { 1807 case PCK_Unknown: 1808 llvm_unreachable("unexpected pragma comment kind"); 1809 case PCK_Compiler: 1810 OS << "compiler"; 1811 break; 1812 case PCK_ExeStr: 1813 OS << "exestr"; 1814 break; 1815 case PCK_Lib: 1816 OS << "lib"; 1817 break; 1818 case PCK_Linker: 1819 OS << "linker"; 1820 break; 1821 case PCK_User: 1822 OS << "user"; 1823 break; 1824 } 1825 StringRef Arg = D->getArg(); 1826 if (!Arg.empty()) 1827 OS << " \"" << Arg << "\""; 1828 } 1829 1830 void TextNodeDumper::VisitPragmaDetectMismatchDecl( 1831 const PragmaDetectMismatchDecl *D) { 1832 OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\""; 1833 } 1834 1835 void TextNodeDumper::VisitOMPExecutableDirective( 1836 const OMPExecutableDirective *D) { 1837 if (D->isStandaloneDirective()) 1838 OS << " openmp_standalone_directive"; 1839 } 1840 1841 void TextNodeDumper::VisitOMPDeclareReductionDecl( 1842 const OMPDeclareReductionDecl *D) { 1843 dumpName(D); 1844 dumpType(D->getType()); 1845 OS << " combiner"; 1846 dumpPointer(D->getCombiner()); 1847 if (const auto *Initializer = D->getInitializer()) { 1848 OS << " initializer"; 1849 dumpPointer(Initializer); 1850 switch (D->getInitializerKind()) { 1851 case OMPDeclareReductionDecl::DirectInit: 1852 OS << " omp_priv = "; 1853 break; 1854 case OMPDeclareReductionDecl::CopyInit: 1855 OS << " omp_priv ()"; 1856 break; 1857 case OMPDeclareReductionDecl::CallInit: 1858 break; 1859 } 1860 } 1861 } 1862 1863 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) { 1864 for (const auto *C : D->clauselists()) { 1865 AddChild([=] { 1866 if (!C) { 1867 ColorScope Color(OS, ShowColors, NullColor); 1868 OS << "<<<NULL>>> OMPClause"; 1869 return; 1870 } 1871 { 1872 ColorScope Color(OS, ShowColors, AttrColor); 1873 StringRef ClauseName( 1874 llvm::omp::getOpenMPClauseName(C->getClauseKind())); 1875 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() 1876 << ClauseName.drop_front() << "Clause"; 1877 } 1878 dumpPointer(C); 1879 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); 1880 }); 1881 } 1882 } 1883 1884 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) { 1885 dumpName(D); 1886 dumpType(D->getType()); 1887 } 1888 1889 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 1890 dumpName(D); 1891 if (D->isInline()) 1892 OS << " inline"; 1893 if (!D->isOriginalNamespace()) 1894 dumpDeclRef(D->getOriginalNamespace(), "original"); 1895 } 1896 1897 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 1898 OS << ' '; 1899 dumpBareDeclRef(D->getNominatedNamespace()); 1900 } 1901 1902 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 1903 dumpName(D); 1904 dumpDeclRef(D->getAliasedNamespace()); 1905 } 1906 1907 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 1908 dumpName(D); 1909 dumpType(D->getUnderlyingType()); 1910 } 1911 1912 void TextNodeDumper::VisitTypeAliasTemplateDecl( 1913 const TypeAliasTemplateDecl *D) { 1914 dumpName(D); 1915 } 1916 1917 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 1918 VisitRecordDecl(D); 1919 if (!D->isCompleteDefinition()) 1920 return; 1921 1922 AddChild([=] { 1923 { 1924 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1925 OS << "DefinitionData"; 1926 } 1927 #define FLAG(fn, name) \ 1928 if (D->fn()) \ 1929 OS << " " #name; 1930 FLAG(isParsingBaseSpecifiers, parsing_base_specifiers); 1931 1932 FLAG(isGenericLambda, generic); 1933 FLAG(isLambda, lambda); 1934 1935 FLAG(isAnonymousStructOrUnion, is_anonymous); 1936 FLAG(canPassInRegisters, pass_in_registers); 1937 FLAG(isEmpty, empty); 1938 FLAG(isAggregate, aggregate); 1939 FLAG(isStandardLayout, standard_layout); 1940 FLAG(isTriviallyCopyable, trivially_copyable); 1941 FLAG(isPOD, pod); 1942 FLAG(isTrivial, trivial); 1943 FLAG(isPolymorphic, polymorphic); 1944 FLAG(isAbstract, abstract); 1945 FLAG(isLiteral, literal); 1946 1947 FLAG(hasUserDeclaredConstructor, has_user_declared_ctor); 1948 FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor); 1949 FLAG(hasMutableFields, has_mutable_fields); 1950 FLAG(hasVariantMembers, has_variant_members); 1951 FLAG(allowConstDefaultInit, can_const_default_init); 1952 1953 AddChild([=] { 1954 { 1955 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1956 OS << "DefaultConstructor"; 1957 } 1958 FLAG(hasDefaultConstructor, exists); 1959 FLAG(hasTrivialDefaultConstructor, trivial); 1960 FLAG(hasNonTrivialDefaultConstructor, non_trivial); 1961 FLAG(hasUserProvidedDefaultConstructor, user_provided); 1962 FLAG(hasConstexprDefaultConstructor, constexpr); 1963 FLAG(needsImplicitDefaultConstructor, needs_implicit); 1964 FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr); 1965 }); 1966 1967 AddChild([=] { 1968 { 1969 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1970 OS << "CopyConstructor"; 1971 } 1972 FLAG(hasSimpleCopyConstructor, simple); 1973 FLAG(hasTrivialCopyConstructor, trivial); 1974 FLAG(hasNonTrivialCopyConstructor, non_trivial); 1975 FLAG(hasUserDeclaredCopyConstructor, user_declared); 1976 FLAG(hasCopyConstructorWithConstParam, has_const_param); 1977 FLAG(needsImplicitCopyConstructor, needs_implicit); 1978 FLAG(needsOverloadResolutionForCopyConstructor, 1979 needs_overload_resolution); 1980 if (!D->needsOverloadResolutionForCopyConstructor()) 1981 FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted); 1982 FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param); 1983 }); 1984 1985 AddChild([=] { 1986 { 1987 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1988 OS << "MoveConstructor"; 1989 } 1990 FLAG(hasMoveConstructor, exists); 1991 FLAG(hasSimpleMoveConstructor, simple); 1992 FLAG(hasTrivialMoveConstructor, trivial); 1993 FLAG(hasNonTrivialMoveConstructor, non_trivial); 1994 FLAG(hasUserDeclaredMoveConstructor, user_declared); 1995 FLAG(needsImplicitMoveConstructor, needs_implicit); 1996 FLAG(needsOverloadResolutionForMoveConstructor, 1997 needs_overload_resolution); 1998 if (!D->needsOverloadResolutionForMoveConstructor()) 1999 FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted); 2000 }); 2001 2002 AddChild([=] { 2003 { 2004 ColorScope Color(OS, ShowColors, DeclKindNameColor); 2005 OS << "CopyAssignment"; 2006 } 2007 FLAG(hasSimpleCopyAssignment, simple); 2008 FLAG(hasTrivialCopyAssignment, trivial); 2009 FLAG(hasNonTrivialCopyAssignment, non_trivial); 2010 FLAG(hasCopyAssignmentWithConstParam, has_const_param); 2011 FLAG(hasUserDeclaredCopyAssignment, user_declared); 2012 FLAG(needsImplicitCopyAssignment, needs_implicit); 2013 FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution); 2014 FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param); 2015 }); 2016 2017 AddChild([=] { 2018 { 2019 ColorScope Color(OS, ShowColors, DeclKindNameColor); 2020 OS << "MoveAssignment"; 2021 } 2022 FLAG(hasMoveAssignment, exists); 2023 FLAG(hasSimpleMoveAssignment, simple); 2024 FLAG(hasTrivialMoveAssignment, trivial); 2025 FLAG(hasNonTrivialMoveAssignment, non_trivial); 2026 FLAG(hasUserDeclaredMoveAssignment, user_declared); 2027 FLAG(needsImplicitMoveAssignment, needs_implicit); 2028 FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution); 2029 }); 2030 2031 AddChild([=] { 2032 { 2033 ColorScope Color(OS, ShowColors, DeclKindNameColor); 2034 OS << "Destructor"; 2035 } 2036 FLAG(hasSimpleDestructor, simple); 2037 FLAG(hasIrrelevantDestructor, irrelevant); 2038 FLAG(hasTrivialDestructor, trivial); 2039 FLAG(hasNonTrivialDestructor, non_trivial); 2040 FLAG(hasUserDeclaredDestructor, user_declared); 2041 FLAG(hasConstexprDestructor, constexpr); 2042 FLAG(needsImplicitDestructor, needs_implicit); 2043 FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution); 2044 if (!D->needsOverloadResolutionForDestructor()) 2045 FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted); 2046 }); 2047 }); 2048 2049 for (const auto &I : D->bases()) { 2050 AddChild([=] { 2051 if (I.isVirtual()) 2052 OS << "virtual "; 2053 dumpAccessSpecifier(I.getAccessSpecifier()); 2054 dumpType(I.getType()); 2055 if (I.isPackExpansion()) 2056 OS << "..."; 2057 }); 2058 } 2059 } 2060 2061 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 2062 dumpName(D); 2063 } 2064 2065 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 2066 dumpName(D); 2067 } 2068 2069 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { 2070 dumpName(D); 2071 } 2072 2073 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { 2074 dumpName(D); 2075 } 2076 2077 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 2078 if (const auto *TC = D->getTypeConstraint()) { 2079 OS << " "; 2080 dumpBareDeclRef(TC->getNamedConcept()); 2081 if (TC->getNamedConcept() != TC->getFoundDecl()) { 2082 OS << " ("; 2083 dumpBareDeclRef(TC->getFoundDecl()); 2084 OS << ")"; 2085 } 2086 } else if (D->wasDeclaredWithTypename()) 2087 OS << " typename"; 2088 else 2089 OS << " class"; 2090 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 2091 if (D->isParameterPack()) 2092 OS << " ..."; 2093 dumpName(D); 2094 } 2095 2096 void TextNodeDumper::VisitNonTypeTemplateParmDecl( 2097 const NonTypeTemplateParmDecl *D) { 2098 dumpType(D->getType()); 2099 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 2100 if (D->isParameterPack()) 2101 OS << " ..."; 2102 dumpName(D); 2103 } 2104 2105 void TextNodeDumper::VisitTemplateTemplateParmDecl( 2106 const TemplateTemplateParmDecl *D) { 2107 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 2108 if (D->isParameterPack()) 2109 OS << " ..."; 2110 dumpName(D); 2111 } 2112 2113 void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) { 2114 OS << ' '; 2115 if (D->getQualifier()) 2116 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 2117 OS << D->getDeclName(); 2118 } 2119 2120 void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) { 2121 OS << ' '; 2122 dumpBareDeclRef(D->getEnumDecl()); 2123 } 2124 2125 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl( 2126 const UnresolvedUsingTypenameDecl *D) { 2127 OS << ' '; 2128 if (D->getQualifier()) 2129 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 2130 OS << D->getDeclName(); 2131 } 2132 2133 void TextNodeDumper::VisitUnresolvedUsingValueDecl( 2134 const UnresolvedUsingValueDecl *D) { 2135 OS << ' '; 2136 if (D->getQualifier()) 2137 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 2138 OS << D->getDeclName(); 2139 dumpType(D->getType()); 2140 } 2141 2142 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 2143 OS << ' '; 2144 dumpBareDeclRef(D->getTargetDecl()); 2145 } 2146 2147 void TextNodeDumper::VisitConstructorUsingShadowDecl( 2148 const ConstructorUsingShadowDecl *D) { 2149 if (D->constructsVirtualBase()) 2150 OS << " virtual"; 2151 2152 AddChild([=] { 2153 OS << "target "; 2154 dumpBareDeclRef(D->getTargetDecl()); 2155 }); 2156 2157 AddChild([=] { 2158 OS << "nominated "; 2159 dumpBareDeclRef(D->getNominatedBaseClass()); 2160 OS << ' '; 2161 dumpBareDeclRef(D->getNominatedBaseClassShadowDecl()); 2162 }); 2163 2164 AddChild([=] { 2165 OS << "constructed "; 2166 dumpBareDeclRef(D->getConstructedBaseClass()); 2167 OS << ' '; 2168 dumpBareDeclRef(D->getConstructedBaseClassShadowDecl()); 2169 }); 2170 } 2171 2172 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 2173 switch (D->getLanguage()) { 2174 case LinkageSpecDecl::lang_c: 2175 OS << " C"; 2176 break; 2177 case LinkageSpecDecl::lang_cxx: 2178 OS << " C++"; 2179 break; 2180 } 2181 } 2182 2183 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 2184 OS << ' '; 2185 dumpAccessSpecifier(D->getAccess()); 2186 } 2187 2188 void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) { 2189 if (TypeSourceInfo *T = D->getFriendType()) 2190 dumpType(T->getType()); 2191 } 2192 2193 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 2194 dumpName(D); 2195 dumpType(D->getType()); 2196 if (D->getSynthesize()) 2197 OS << " synthesize"; 2198 2199 switch (D->getAccessControl()) { 2200 case ObjCIvarDecl::None: 2201 OS << " none"; 2202 break; 2203 case ObjCIvarDecl::Private: 2204 OS << " private"; 2205 break; 2206 case ObjCIvarDecl::Protected: 2207 OS << " protected"; 2208 break; 2209 case ObjCIvarDecl::Public: 2210 OS << " public"; 2211 break; 2212 case ObjCIvarDecl::Package: 2213 OS << " package"; 2214 break; 2215 } 2216 } 2217 2218 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 2219 if (D->isInstanceMethod()) 2220 OS << " -"; 2221 else 2222 OS << " +"; 2223 dumpName(D); 2224 dumpType(D->getReturnType()); 2225 2226 if (D->isVariadic()) 2227 OS << " variadic"; 2228 } 2229 2230 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) { 2231 dumpName(D); 2232 switch (D->getVariance()) { 2233 case ObjCTypeParamVariance::Invariant: 2234 break; 2235 2236 case ObjCTypeParamVariance::Covariant: 2237 OS << " covariant"; 2238 break; 2239 2240 case ObjCTypeParamVariance::Contravariant: 2241 OS << " contravariant"; 2242 break; 2243 } 2244 2245 if (D->hasExplicitBound()) 2246 OS << " bounded"; 2247 dumpType(D->getUnderlyingType()); 2248 } 2249 2250 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 2251 dumpName(D); 2252 dumpDeclRef(D->getClassInterface()); 2253 dumpDeclRef(D->getImplementation()); 2254 for (const auto *P : D->protocols()) 2255 dumpDeclRef(P); 2256 } 2257 2258 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 2259 dumpName(D); 2260 dumpDeclRef(D->getClassInterface()); 2261 dumpDeclRef(D->getCategoryDecl()); 2262 } 2263 2264 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 2265 dumpName(D); 2266 2267 for (const auto *Child : D->protocols()) 2268 dumpDeclRef(Child); 2269 } 2270 2271 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 2272 dumpName(D); 2273 dumpDeclRef(D->getSuperClass(), "super"); 2274 2275 dumpDeclRef(D->getImplementation()); 2276 for (const auto *Child : D->protocols()) 2277 dumpDeclRef(Child); 2278 } 2279 2280 void TextNodeDumper::VisitObjCImplementationDecl( 2281 const ObjCImplementationDecl *D) { 2282 dumpName(D); 2283 dumpDeclRef(D->getSuperClass(), "super"); 2284 dumpDeclRef(D->getClassInterface()); 2285 } 2286 2287 void TextNodeDumper::VisitObjCCompatibleAliasDecl( 2288 const ObjCCompatibleAliasDecl *D) { 2289 dumpName(D); 2290 dumpDeclRef(D->getClassInterface()); 2291 } 2292 2293 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 2294 dumpName(D); 2295 dumpType(D->getType()); 2296 2297 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 2298 OS << " required"; 2299 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 2300 OS << " optional"; 2301 2302 ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes(); 2303 if (Attrs != ObjCPropertyAttribute::kind_noattr) { 2304 if (Attrs & ObjCPropertyAttribute::kind_readonly) 2305 OS << " readonly"; 2306 if (Attrs & ObjCPropertyAttribute::kind_assign) 2307 OS << " assign"; 2308 if (Attrs & ObjCPropertyAttribute::kind_readwrite) 2309 OS << " readwrite"; 2310 if (Attrs & ObjCPropertyAttribute::kind_retain) 2311 OS << " retain"; 2312 if (Attrs & ObjCPropertyAttribute::kind_copy) 2313 OS << " copy"; 2314 if (Attrs & ObjCPropertyAttribute::kind_nonatomic) 2315 OS << " nonatomic"; 2316 if (Attrs & ObjCPropertyAttribute::kind_atomic) 2317 OS << " atomic"; 2318 if (Attrs & ObjCPropertyAttribute::kind_weak) 2319 OS << " weak"; 2320 if (Attrs & ObjCPropertyAttribute::kind_strong) 2321 OS << " strong"; 2322 if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained) 2323 OS << " unsafe_unretained"; 2324 if (Attrs & ObjCPropertyAttribute::kind_class) 2325 OS << " class"; 2326 if (Attrs & ObjCPropertyAttribute::kind_direct) 2327 OS << " direct"; 2328 if (Attrs & ObjCPropertyAttribute::kind_getter) 2329 dumpDeclRef(D->getGetterMethodDecl(), "getter"); 2330 if (Attrs & ObjCPropertyAttribute::kind_setter) 2331 dumpDeclRef(D->getSetterMethodDecl(), "setter"); 2332 } 2333 } 2334 2335 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 2336 dumpName(D->getPropertyDecl()); 2337 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 2338 OS << " synthesize"; 2339 else 2340 OS << " dynamic"; 2341 dumpDeclRef(D->getPropertyDecl()); 2342 dumpDeclRef(D->getPropertyIvarDecl()); 2343 } 2344 2345 void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) { 2346 if (D->isVariadic()) 2347 OS << " variadic"; 2348 2349 if (D->capturesCXXThis()) 2350 OS << " captures_this"; 2351 } 2352 2353 void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) { 2354 dumpName(D); 2355 } 2356