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/NestedNameSpecifier.h" 20 #include "clang/AST/Type.h" 21 #include "clang/AST/TypeLocVisitor.h" 22 #include "clang/Basic/Module.h" 23 #include "clang/Basic/SourceManager.h" 24 #include "clang/Basic/Specifiers.h" 25 #include "clang/Basic/TypeTraits.h" 26 #include "llvm/ADT/StringExtras.h" 27 28 #include <algorithm> 29 #include <utility> 30 31 using namespace clang; 32 33 static void dumpPreviousDeclImpl(raw_ostream &OS, ...) {} 34 35 template <typename T> 36 static void dumpPreviousDeclImpl(raw_ostream &OS, const Mergeable<T> *D) { 37 const T *First = D->getFirstDecl(); 38 if (First != D) 39 OS << " first " << First; 40 } 41 42 template <typename T> 43 static void dumpPreviousDeclImpl(raw_ostream &OS, const Redeclarable<T> *D) { 44 const T *Prev = D->getPreviousDecl(); 45 if (Prev) 46 OS << " prev " << Prev; 47 } 48 49 /// Dump the previous declaration in the redeclaration chain for a declaration, 50 /// if any. 51 static void dumpPreviousDecl(raw_ostream &OS, const Decl *D) { 52 switch (D->getKind()) { 53 #define DECL(DERIVED, BASE) \ 54 case Decl::DERIVED: \ 55 return dumpPreviousDeclImpl(OS, cast<DERIVED##Decl>(D)); 56 #define ABSTRACT_DECL(DECL) 57 #include "clang/AST/DeclNodes.inc" 58 } 59 llvm_unreachable("Decl that isn't part of DeclNodes.inc!"); 60 } 61 62 TextNodeDumper::TextNodeDumper(raw_ostream &OS, const ASTContext &Context, 63 bool ShowColors) 64 : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors), 65 Context(&Context), SM(&Context.getSourceManager()), 66 PrintPolicy(Context.getPrintingPolicy()), 67 Traits(&Context.getCommentCommandTraits()) {} 68 69 TextNodeDumper::TextNodeDumper(raw_ostream &OS, bool ShowColors) 70 : TextTreeStructure(OS, ShowColors), OS(OS), ShowColors(ShowColors) {} 71 72 void TextNodeDumper::Visit(const comments::Comment *C, 73 const comments::FullComment *FC) { 74 if (!C) { 75 ColorScope Color(OS, ShowColors, NullColor); 76 OS << "<<<NULL>>>"; 77 return; 78 } 79 80 { 81 ColorScope Color(OS, ShowColors, CommentColor); 82 OS << C->getCommentKindName(); 83 } 84 dumpPointer(C); 85 dumpSourceRange(C->getSourceRange()); 86 87 ConstCommentVisitor<TextNodeDumper, void, 88 const comments::FullComment *>::visit(C, FC); 89 } 90 91 void TextNodeDumper::Visit(const Attr *A) { 92 { 93 ColorScope Color(OS, ShowColors, AttrColor); 94 95 switch (A->getKind()) { 96 #define ATTR(X) \ 97 case attr::X: \ 98 OS << #X; \ 99 break; 100 #include "clang/Basic/AttrList.inc" 101 } 102 OS << "Attr"; 103 } 104 dumpPointer(A); 105 dumpSourceRange(A->getRange()); 106 if (A->isInherited()) 107 OS << " Inherited"; 108 if (A->isImplicit()) 109 OS << " Implicit"; 110 111 ConstAttrVisitor<TextNodeDumper>::Visit(A); 112 } 113 114 void TextNodeDumper::Visit(const TemplateArgument &TA, SourceRange R, 115 const Decl *From, StringRef Label) { 116 OS << "TemplateArgument"; 117 if (R.isValid()) 118 dumpSourceRange(R); 119 120 if (From) 121 dumpDeclRef(From, Label); 122 123 ConstTemplateArgumentVisitor<TextNodeDumper>::Visit(TA); 124 } 125 126 void TextNodeDumper::Visit(const Stmt *Node) { 127 if (!Node) { 128 ColorScope Color(OS, ShowColors, NullColor); 129 OS << "<<<NULL>>>"; 130 return; 131 } 132 { 133 ColorScope Color(OS, ShowColors, StmtColor); 134 OS << Node->getStmtClassName(); 135 } 136 dumpPointer(Node); 137 dumpSourceRange(Node->getSourceRange()); 138 139 if (const auto *E = dyn_cast<Expr>(Node)) { 140 dumpType(E->getType()); 141 142 if (E->containsErrors()) { 143 ColorScope Color(OS, ShowColors, ErrorsColor); 144 OS << " contains-errors"; 145 } 146 147 { 148 ColorScope Color(OS, ShowColors, ValueKindColor); 149 switch (E->getValueKind()) { 150 case VK_PRValue: 151 break; 152 case VK_LValue: 153 OS << " lvalue"; 154 break; 155 case VK_XValue: 156 OS << " xvalue"; 157 break; 158 } 159 } 160 161 { 162 ColorScope Color(OS, ShowColors, ObjectKindColor); 163 switch (E->getObjectKind()) { 164 case OK_Ordinary: 165 break; 166 case OK_BitField: 167 OS << " bitfield"; 168 break; 169 case OK_ObjCProperty: 170 OS << " objcproperty"; 171 break; 172 case OK_ObjCSubscript: 173 OS << " objcsubscript"; 174 break; 175 case OK_VectorComponent: 176 OS << " vectorcomponent"; 177 break; 178 case OK_MatrixComponent: 179 OS << " matrixcomponent"; 180 break; 181 } 182 } 183 } 184 185 ConstStmtVisitor<TextNodeDumper>::Visit(Node); 186 } 187 188 void TextNodeDumper::Visit(const Type *T) { 189 if (!T) { 190 ColorScope Color(OS, ShowColors, NullColor); 191 OS << "<<<NULL>>>"; 192 return; 193 } 194 if (isa<LocInfoType>(T)) { 195 { 196 ColorScope Color(OS, ShowColors, TypeColor); 197 OS << "LocInfo Type"; 198 } 199 dumpPointer(T); 200 return; 201 } 202 203 { 204 ColorScope Color(OS, ShowColors, TypeColor); 205 OS << T->getTypeClassName() << "Type"; 206 } 207 dumpPointer(T); 208 OS << " "; 209 dumpBareType(QualType(T, 0), false); 210 211 QualType SingleStepDesugar = 212 T->getLocallyUnqualifiedSingleStepDesugaredType(); 213 if (SingleStepDesugar != QualType(T, 0)) 214 OS << " sugar"; 215 216 if (T->containsErrors()) { 217 ColorScope Color(OS, ShowColors, ErrorsColor); 218 OS << " contains-errors"; 219 } 220 221 if (T->isDependentType()) 222 OS << " dependent"; 223 else if (T->isInstantiationDependentType()) 224 OS << " instantiation_dependent"; 225 226 if (T->isVariablyModifiedType()) 227 OS << " variably_modified"; 228 if (T->containsUnexpandedParameterPack()) 229 OS << " contains_unexpanded_pack"; 230 if (T->isFromAST()) 231 OS << " imported"; 232 233 TypeVisitor<TextNodeDumper>::Visit(T); 234 } 235 236 void TextNodeDumper::Visit(QualType T) { 237 OS << "QualType"; 238 dumpPointer(T.getAsOpaquePtr()); 239 OS << " "; 240 dumpBareType(T, false); 241 OS << " " << T.split().Quals.getAsString(); 242 } 243 244 void TextNodeDumper::Visit(TypeLoc TL) { 245 if (!TL) { 246 ColorScope Color(OS, ShowColors, NullColor); 247 OS << "<<<NULL>>>"; 248 return; 249 } 250 251 { 252 ColorScope Color(OS, ShowColors, TypeColor); 253 OS << (TL.getTypeLocClass() == TypeLoc::Qualified 254 ? "Qualified" 255 : TL.getType()->getTypeClassName()) 256 << "TypeLoc"; 257 } 258 dumpSourceRange(TL.getSourceRange()); 259 OS << ' '; 260 dumpBareType(TL.getType(), /*Desugar=*/false); 261 262 TypeLocVisitor<TextNodeDumper>::Visit(TL); 263 } 264 265 void TextNodeDumper::Visit(const Decl *D) { 266 if (!D) { 267 ColorScope Color(OS, ShowColors, NullColor); 268 OS << "<<<NULL>>>"; 269 return; 270 } 271 272 { 273 ColorScope Color(OS, ShowColors, DeclKindNameColor); 274 OS << D->getDeclKindName() << "Decl"; 275 } 276 dumpPointer(D); 277 if (D->getLexicalDeclContext() != D->getDeclContext()) 278 OS << " parent " << cast<Decl>(D->getDeclContext()); 279 dumpPreviousDecl(OS, D); 280 dumpSourceRange(D->getSourceRange()); 281 OS << ' '; 282 dumpLocation(D->getLocation()); 283 if (D->isFromASTFile()) 284 OS << " imported"; 285 if (Module *M = D->getOwningModule()) 286 OS << " in " << M->getFullModuleName(); 287 if (auto *ND = dyn_cast<NamedDecl>(D)) 288 for (Module *M : D->getASTContext().getModulesWithMergedDefinition( 289 const_cast<NamedDecl *>(ND))) 290 AddChild([=] { OS << "also in " << M->getFullModuleName(); }); 291 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) 292 if (!ND->isUnconditionallyVisible()) 293 OS << " hidden"; 294 if (D->isImplicit()) 295 OS << " implicit"; 296 297 if (D->isUsed()) 298 OS << " used"; 299 else if (D->isThisDeclarationReferenced()) 300 OS << " referenced"; 301 302 if (D->isInvalidDecl()) 303 OS << " invalid"; 304 if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) { 305 if (FD->isConstexprSpecified()) 306 OS << " constexpr"; 307 if (FD->isConsteval()) 308 OS << " consteval"; 309 else if (FD->isImmediateFunction()) 310 OS << " immediate"; 311 if (FD->isMultiVersion()) 312 OS << " multiversion"; 313 } 314 315 if (!isa<FunctionDecl>(*D)) { 316 const auto *MD = dyn_cast<ObjCMethodDecl>(D); 317 if (!MD || !MD->isThisDeclarationADefinition()) { 318 const auto *DC = dyn_cast<DeclContext>(D); 319 if (DC && DC->hasExternalLexicalStorage()) { 320 ColorScope Color(OS, ShowColors, UndeserializedColor); 321 OS << " <undeserialized declarations>"; 322 } 323 } 324 } 325 326 switch (D->getFriendObjectKind()) { 327 case Decl::FOK_None: 328 break; 329 case Decl::FOK_Declared: 330 OS << " friend"; 331 break; 332 case Decl::FOK_Undeclared: 333 OS << " friend_undeclared"; 334 break; 335 } 336 337 ConstDeclVisitor<TextNodeDumper>::Visit(D); 338 } 339 340 void TextNodeDumper::Visit(const CXXCtorInitializer *Init) { 341 OS << "CXXCtorInitializer"; 342 if (Init->isAnyMemberInitializer()) { 343 OS << ' '; 344 dumpBareDeclRef(Init->getAnyMember()); 345 } else if (Init->isBaseInitializer()) { 346 dumpType(QualType(Init->getBaseClass(), 0)); 347 } else if (Init->isDelegatingInitializer()) { 348 dumpType(Init->getTypeSourceInfo()->getType()); 349 } else { 350 llvm_unreachable("Unknown initializer type"); 351 } 352 } 353 354 void TextNodeDumper::Visit(const BlockDecl::Capture &C) { 355 OS << "capture"; 356 if (C.isByRef()) 357 OS << " byref"; 358 if (C.isNested()) 359 OS << " nested"; 360 if (C.getVariable()) { 361 OS << ' '; 362 dumpBareDeclRef(C.getVariable()); 363 } 364 } 365 366 void TextNodeDumper::Visit(const OMPClause *C) { 367 if (!C) { 368 ColorScope Color(OS, ShowColors, NullColor); 369 OS << "<<<NULL>>> OMPClause"; 370 return; 371 } 372 { 373 ColorScope Color(OS, ShowColors, AttrColor); 374 StringRef ClauseName(llvm::omp::getOpenMPClauseName(C->getClauseKind())); 375 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() 376 << ClauseName.drop_front() << "Clause"; 377 } 378 dumpPointer(C); 379 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); 380 if (C->isImplicit()) 381 OS << " <implicit>"; 382 } 383 384 void TextNodeDumper::VisitOpenACCAsteriskSizeExpr( 385 const OpenACCAsteriskSizeExpr *E) { 386 // Nothing to do here, only location exists, and that is printed elsewhere. 387 } 388 389 void TextNodeDumper::Visit(const OpenACCClause *C) { 390 if (!C) { 391 ColorScope Color(OS, ShowColors, NullColor); 392 OS << "<<<NULL>>> OpenACCClause"; 393 return; 394 } 395 { 396 ColorScope Color(OS, ShowColors, AttrColor); 397 OS << C->getClauseKind(); 398 399 // Handle clauses with parens for types that have no children, likely 400 // because there is no sub expression. 401 switch (C->getClauseKind()) { 402 case OpenACCClauseKind::Default: 403 OS << '(' << cast<OpenACCDefaultClause>(C)->getDefaultClauseKind() << ')'; 404 break; 405 case OpenACCClauseKind::Async: 406 case OpenACCClauseKind::Auto: 407 case OpenACCClauseKind::Attach: 408 case OpenACCClauseKind::Copy: 409 case OpenACCClauseKind::PCopy: 410 case OpenACCClauseKind::PresentOrCopy: 411 case OpenACCClauseKind::Host: 412 case OpenACCClauseKind::If: 413 case OpenACCClauseKind::IfPresent: 414 case OpenACCClauseKind::Independent: 415 case OpenACCClauseKind::Detach: 416 case OpenACCClauseKind::Delete: 417 case OpenACCClauseKind::Device: 418 case OpenACCClauseKind::DeviceNum: 419 case OpenACCClauseKind::DefaultAsync: 420 case OpenACCClauseKind::DevicePtr: 421 case OpenACCClauseKind::Finalize: 422 case OpenACCClauseKind::FirstPrivate: 423 case OpenACCClauseKind::NoCreate: 424 case OpenACCClauseKind::NumGangs: 425 case OpenACCClauseKind::NumWorkers: 426 case OpenACCClauseKind::Present: 427 case OpenACCClauseKind::Private: 428 case OpenACCClauseKind::Self: 429 case OpenACCClauseKind::Seq: 430 case OpenACCClauseKind::Tile: 431 case OpenACCClauseKind::Worker: 432 case OpenACCClauseKind::UseDevice: 433 case OpenACCClauseKind::Vector: 434 case OpenACCClauseKind::VectorLength: 435 // The condition expression will be printed as a part of the 'children', 436 // but print 'clause' here so it is clear what is happening from the dump. 437 OS << " clause"; 438 break; 439 case OpenACCClauseKind::Gang: { 440 OS << " clause"; 441 // print the list of all GangKinds, so that there is some sort of 442 // relationship to the expressions listed afterwards. 443 auto *GC = cast<OpenACCGangClause>(C); 444 445 for (unsigned I = 0; I < GC->getNumExprs(); ++I) { 446 OS << " " << GC->getExpr(I).first; 447 } 448 break; 449 } 450 case OpenACCClauseKind::Collapse: 451 OS << " clause"; 452 if (cast<OpenACCCollapseClause>(C)->hasForce()) 453 OS << ": force"; 454 break; 455 456 case OpenACCClauseKind::CopyIn: 457 case OpenACCClauseKind::PCopyIn: 458 case OpenACCClauseKind::PresentOrCopyIn: 459 OS << " clause"; 460 if (cast<OpenACCCopyInClause>(C)->isReadOnly()) 461 OS << " : readonly"; 462 break; 463 case OpenACCClauseKind::CopyOut: 464 case OpenACCClauseKind::PCopyOut: 465 case OpenACCClauseKind::PresentOrCopyOut: 466 OS << " clause"; 467 if (cast<OpenACCCopyOutClause>(C)->isZero()) 468 OS << " : zero"; 469 break; 470 case OpenACCClauseKind::Create: 471 case OpenACCClauseKind::PCreate: 472 case OpenACCClauseKind::PresentOrCreate: 473 OS << " clause"; 474 if (cast<OpenACCCreateClause>(C)->isZero()) 475 OS << " : zero"; 476 break; 477 case OpenACCClauseKind::Wait: 478 OS << " clause"; 479 if (cast<OpenACCWaitClause>(C)->hasDevNumExpr()) 480 OS << " has devnum"; 481 if (cast<OpenACCWaitClause>(C)->hasQueuesTag()) 482 OS << " has queues tag"; 483 break; 484 case OpenACCClauseKind::DeviceType: 485 case OpenACCClauseKind::DType: 486 OS << "("; 487 llvm::interleaveComma( 488 cast<OpenACCDeviceTypeClause>(C)->getArchitectures(), OS, 489 [&](const DeviceTypeArgument &Arch) { 490 if (Arch.first == nullptr) 491 OS << "*"; 492 else 493 OS << Arch.first->getName(); 494 }); 495 OS << ")"; 496 break; 497 case OpenACCClauseKind::Reduction: 498 OS << " clause Operator: " 499 << cast<OpenACCReductionClause>(C)->getReductionOp(); 500 break; 501 default: 502 // Nothing to do here. 503 break; 504 } 505 } 506 dumpPointer(C); 507 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); 508 } 509 510 void TextNodeDumper::Visit(const GenericSelectionExpr::ConstAssociation &A) { 511 const TypeSourceInfo *TSI = A.getTypeSourceInfo(); 512 if (TSI) { 513 OS << "case "; 514 dumpType(TSI->getType()); 515 } else { 516 OS << "default"; 517 } 518 519 if (A.isSelected()) 520 OS << " selected"; 521 } 522 523 void TextNodeDumper::Visit(const ConceptReference *R) { 524 if (!R) { 525 ColorScope Color(OS, ShowColors, NullColor); 526 OS << "<<<NULL>>> ConceptReference"; 527 return; 528 } 529 530 OS << "ConceptReference"; 531 dumpPointer(R); 532 dumpSourceRange(R->getSourceRange()); 533 OS << ' '; 534 dumpBareDeclRef(R->getNamedConcept()); 535 } 536 537 void TextNodeDumper::Visit(const concepts::Requirement *R) { 538 if (!R) { 539 ColorScope Color(OS, ShowColors, NullColor); 540 OS << "<<<NULL>>> Requirement"; 541 return; 542 } 543 544 { 545 ColorScope Color(OS, ShowColors, StmtColor); 546 switch (R->getKind()) { 547 case concepts::Requirement::RK_Type: 548 OS << "TypeRequirement"; 549 break; 550 case concepts::Requirement::RK_Simple: 551 OS << "SimpleRequirement"; 552 break; 553 case concepts::Requirement::RK_Compound: 554 OS << "CompoundRequirement"; 555 break; 556 case concepts::Requirement::RK_Nested: 557 OS << "NestedRequirement"; 558 break; 559 } 560 } 561 562 dumpPointer(R); 563 564 if (auto *ER = dyn_cast<concepts::ExprRequirement>(R)) { 565 if (ER->hasNoexceptRequirement()) 566 OS << " noexcept"; 567 } 568 569 if (R->isDependent()) 570 OS << " dependent"; 571 else 572 OS << (R->isSatisfied() ? " satisfied" : " unsatisfied"); 573 if (R->containsUnexpandedParameterPack()) 574 OS << " contains_unexpanded_pack"; 575 } 576 577 static double GetApproxValue(const llvm::APFloat &F) { 578 llvm::APFloat V = F; 579 bool ignored; 580 V.convert(llvm::APFloat::IEEEdouble(), llvm::APFloat::rmNearestTiesToEven, 581 &ignored); 582 return V.convertToDouble(); 583 } 584 585 /// True if the \p APValue \p Value can be folded onto the current line. 586 static bool isSimpleAPValue(const APValue &Value) { 587 switch (Value.getKind()) { 588 case APValue::None: 589 case APValue::Indeterminate: 590 case APValue::Int: 591 case APValue::Float: 592 case APValue::FixedPoint: 593 case APValue::ComplexInt: 594 case APValue::ComplexFloat: 595 case APValue::LValue: 596 case APValue::MemberPointer: 597 case APValue::AddrLabelDiff: 598 return true; 599 case APValue::Vector: 600 case APValue::Array: 601 case APValue::Struct: 602 return false; 603 case APValue::Union: 604 return isSimpleAPValue(Value.getUnionValue()); 605 } 606 llvm_unreachable("unexpected APValue kind!"); 607 } 608 609 /// Dump the children of the \p APValue \p Value. 610 /// 611 /// \param[in] Value The \p APValue to visit 612 /// \param[in] Ty The \p QualType passed to \p Visit 613 /// 614 /// \param[in] IdxToChildFun A function mapping an \p APValue and an index 615 /// to one of the child of the \p APValue 616 /// 617 /// \param[in] NumChildren \p IdxToChildFun will be called on \p Value with 618 /// the indices in the range \p [0,NumChildren( 619 /// 620 /// \param[in] LabelSingular The label to use on a line with a single child 621 /// \param[in] LabelPlurial The label to use on a line with multiple children 622 void TextNodeDumper::dumpAPValueChildren( 623 const APValue &Value, QualType Ty, 624 const APValue &(*IdxToChildFun)(const APValue &, unsigned), 625 unsigned NumChildren, StringRef LabelSingular, StringRef LabelPlurial) { 626 // To save some vertical space we print up to MaxChildrenPerLine APValues 627 // considered to be simple (by isSimpleAPValue) on a single line. 628 constexpr unsigned MaxChildrenPerLine = 4; 629 unsigned I = 0; 630 while (I < NumChildren) { 631 unsigned J = I; 632 while (J < NumChildren) { 633 if (isSimpleAPValue(IdxToChildFun(Value, J)) && 634 (J - I < MaxChildrenPerLine)) { 635 ++J; 636 continue; 637 } 638 break; 639 } 640 641 J = std::max(I + 1, J); 642 643 // Print [I,J) on a single line. 644 AddChild(J - I > 1 ? LabelPlurial : LabelSingular, [=]() { 645 for (unsigned X = I; X < J; ++X) { 646 Visit(IdxToChildFun(Value, X), Ty); 647 if (X + 1 != J) 648 OS << ", "; 649 } 650 }); 651 I = J; 652 } 653 } 654 655 void TextNodeDumper::Visit(const APValue &Value, QualType Ty) { 656 ColorScope Color(OS, ShowColors, ValueKindColor); 657 switch (Value.getKind()) { 658 case APValue::None: 659 OS << "None"; 660 return; 661 case APValue::Indeterminate: 662 OS << "Indeterminate"; 663 return; 664 case APValue::Int: 665 OS << "Int "; 666 { 667 ColorScope Color(OS, ShowColors, ValueColor); 668 OS << Value.getInt(); 669 } 670 return; 671 case APValue::Float: 672 OS << "Float "; 673 { 674 ColorScope Color(OS, ShowColors, ValueColor); 675 OS << GetApproxValue(Value.getFloat()); 676 } 677 return; 678 case APValue::FixedPoint: 679 OS << "FixedPoint "; 680 { 681 ColorScope Color(OS, ShowColors, ValueColor); 682 OS << Value.getFixedPoint(); 683 } 684 return; 685 case APValue::Vector: { 686 unsigned VectorLength = Value.getVectorLength(); 687 OS << "Vector length=" << VectorLength; 688 689 dumpAPValueChildren( 690 Value, Ty, 691 [](const APValue &Value, unsigned Index) -> const APValue & { 692 return Value.getVectorElt(Index); 693 }, 694 VectorLength, "element", "elements"); 695 return; 696 } 697 case APValue::ComplexInt: 698 OS << "ComplexInt "; 699 { 700 ColorScope Color(OS, ShowColors, ValueColor); 701 OS << Value.getComplexIntReal() << " + " << Value.getComplexIntImag() 702 << 'i'; 703 } 704 return; 705 case APValue::ComplexFloat: 706 OS << "ComplexFloat "; 707 { 708 ColorScope Color(OS, ShowColors, ValueColor); 709 OS << GetApproxValue(Value.getComplexFloatReal()) << " + " 710 << GetApproxValue(Value.getComplexFloatImag()) << 'i'; 711 } 712 return; 713 case APValue::LValue: { 714 (void)Context; 715 OS << "LValue Base="; 716 APValue::LValueBase B = Value.getLValueBase(); 717 if (B.isNull()) 718 OS << "null"; 719 else if (const auto *BE = B.dyn_cast<const Expr *>()) { 720 OS << BE->getStmtClassName() << ' '; 721 dumpPointer(BE); 722 } else { 723 const auto *VDB = B.get<const ValueDecl *>(); 724 OS << VDB->getDeclKindName() << "Decl"; 725 dumpPointer(VDB); 726 } 727 OS << ", Null=" << Value.isNullPointer() 728 << ", Offset=" << Value.getLValueOffset().getQuantity() 729 << ", HasPath=" << Value.hasLValuePath(); 730 if (Value.hasLValuePath()) { 731 OS << ", PathLength=" << Value.getLValuePath().size(); 732 OS << ", Path=("; 733 llvm::ListSeparator Sep; 734 for (const auto &PathEntry : Value.getLValuePath()) { 735 // We're printing all entries as array indices because don't have the 736 // type information here to do anything else. 737 OS << Sep << PathEntry.getAsArrayIndex(); 738 } 739 OS << ")"; 740 } 741 return; 742 } 743 case APValue::Array: { 744 unsigned ArraySize = Value.getArraySize(); 745 unsigned NumInitializedElements = Value.getArrayInitializedElts(); 746 OS << "Array size=" << ArraySize; 747 748 dumpAPValueChildren( 749 Value, Ty, 750 [](const APValue &Value, unsigned Index) -> const APValue & { 751 return Value.getArrayInitializedElt(Index); 752 }, 753 NumInitializedElements, "element", "elements"); 754 755 if (Value.hasArrayFiller()) { 756 AddChild("filler", [=] { 757 { 758 ColorScope Color(OS, ShowColors, ValueColor); 759 OS << ArraySize - NumInitializedElements << " x "; 760 } 761 Visit(Value.getArrayFiller(), Ty); 762 }); 763 } 764 765 return; 766 } 767 case APValue::Struct: { 768 OS << "Struct"; 769 770 dumpAPValueChildren( 771 Value, Ty, 772 [](const APValue &Value, unsigned Index) -> const APValue & { 773 return Value.getStructBase(Index); 774 }, 775 Value.getStructNumBases(), "base", "bases"); 776 777 dumpAPValueChildren( 778 Value, Ty, 779 [](const APValue &Value, unsigned Index) -> const APValue & { 780 return Value.getStructField(Index); 781 }, 782 Value.getStructNumFields(), "field", "fields"); 783 784 return; 785 } 786 case APValue::Union: { 787 OS << "Union"; 788 { 789 ColorScope Color(OS, ShowColors, ValueColor); 790 if (const FieldDecl *FD = Value.getUnionField()) 791 OS << " ." << *cast<NamedDecl>(FD); 792 } 793 // If the union value is considered to be simple, fold it into the 794 // current line to save some vertical space. 795 const APValue &UnionValue = Value.getUnionValue(); 796 if (isSimpleAPValue(UnionValue)) { 797 OS << ' '; 798 Visit(UnionValue, Ty); 799 } else { 800 AddChild([=] { Visit(UnionValue, Ty); }); 801 } 802 803 return; 804 } 805 case APValue::MemberPointer: 806 OS << "MemberPointer <todo>"; 807 return; 808 case APValue::AddrLabelDiff: 809 OS << "AddrLabelDiff <todo>"; 810 return; 811 } 812 llvm_unreachable("Unknown APValue kind!"); 813 } 814 815 void TextNodeDumper::dumpPointer(const void *Ptr) { 816 ColorScope Color(OS, ShowColors, AddressColor); 817 OS << ' ' << Ptr; 818 } 819 820 void TextNodeDumper::dumpLocation(SourceLocation Loc) { 821 if (!SM) 822 return; 823 824 ColorScope Color(OS, ShowColors, LocationColor); 825 SourceLocation SpellingLoc = SM->getSpellingLoc(Loc); 826 827 // The general format we print out is filename:line:col, but we drop pieces 828 // that haven't changed since the last loc printed. 829 PresumedLoc PLoc = SM->getPresumedLoc(SpellingLoc); 830 831 if (PLoc.isInvalid()) { 832 OS << "<invalid sloc>"; 833 return; 834 } 835 836 if (strcmp(PLoc.getFilename(), LastLocFilename) != 0) { 837 OS << PLoc.getFilename() << ':' << PLoc.getLine() << ':' 838 << PLoc.getColumn(); 839 LastLocFilename = PLoc.getFilename(); 840 LastLocLine = PLoc.getLine(); 841 } else if (PLoc.getLine() != LastLocLine) { 842 OS << "line" << ':' << PLoc.getLine() << ':' << PLoc.getColumn(); 843 LastLocLine = PLoc.getLine(); 844 } else { 845 OS << "col" << ':' << PLoc.getColumn(); 846 } 847 } 848 849 void TextNodeDumper::dumpSourceRange(SourceRange R) { 850 // Can't translate locations if a SourceManager isn't available. 851 if (!SM) 852 return; 853 854 OS << " <"; 855 dumpLocation(R.getBegin()); 856 if (R.getBegin() != R.getEnd()) { 857 OS << ", "; 858 dumpLocation(R.getEnd()); 859 } 860 OS << ">"; 861 862 // <t2.c:123:421[blah], t2.c:412:321> 863 } 864 865 void TextNodeDumper::dumpBareType(QualType T, bool Desugar) { 866 ColorScope Color(OS, ShowColors, TypeColor); 867 868 SplitQualType T_split = T.split(); 869 std::string T_str = QualType::getAsString(T_split, PrintPolicy); 870 OS << "'" << T_str << "'"; 871 872 if (Desugar && !T.isNull()) { 873 // If the type is sugared, also dump a (shallow) desugared type when 874 // it is visibly different. 875 SplitQualType D_split = T.getSplitDesugaredType(); 876 if (T_split != D_split) { 877 std::string D_str = QualType::getAsString(D_split, PrintPolicy); 878 if (T_str != D_str) 879 OS << ":'" << QualType::getAsString(D_split, PrintPolicy) << "'"; 880 } 881 } 882 } 883 884 void TextNodeDumper::dumpType(QualType T) { 885 OS << ' '; 886 dumpBareType(T); 887 } 888 889 void TextNodeDumper::dumpBareDeclRef(const Decl *D) { 890 if (!D) { 891 ColorScope Color(OS, ShowColors, NullColor); 892 OS << "<<<NULL>>>"; 893 return; 894 } 895 896 { 897 ColorScope Color(OS, ShowColors, DeclKindNameColor); 898 OS << D->getDeclKindName(); 899 } 900 dumpPointer(D); 901 902 if (const NamedDecl *ND = dyn_cast<NamedDecl>(D)) { 903 ColorScope Color(OS, ShowColors, DeclNameColor); 904 if (DeclarationName Name = ND->getDeclName()) 905 OS << " '" << Name << '\''; 906 else 907 switch (ND->getKind()) { 908 case Decl::Decomposition: { 909 auto *DD = cast<DecompositionDecl>(ND); 910 OS << " first_binding '" << DD->bindings()[0]->getDeclName() << '\''; 911 break; 912 } 913 case Decl::Field: { 914 auto *FD = cast<FieldDecl>(ND); 915 OS << " field_index " << FD->getFieldIndex(); 916 break; 917 } 918 case Decl::ParmVar: { 919 auto *PD = cast<ParmVarDecl>(ND); 920 OS << " depth " << PD->getFunctionScopeDepth() << " index " 921 << PD->getFunctionScopeIndex(); 922 break; 923 } 924 case Decl::TemplateTypeParm: { 925 auto *TD = cast<TemplateTypeParmDecl>(ND); 926 OS << " depth " << TD->getDepth() << " index " << TD->getIndex(); 927 break; 928 } 929 case Decl::NonTypeTemplateParm: { 930 auto *TD = cast<NonTypeTemplateParmDecl>(ND); 931 OS << " depth " << TD->getDepth() << " index " << TD->getIndex(); 932 break; 933 } 934 default: 935 // Var, Namespace, (CXX)Record: Nothing else besides source location. 936 dumpSourceRange(ND->getSourceRange()); 937 break; 938 } 939 } 940 941 if (const ValueDecl *VD = dyn_cast<ValueDecl>(D)) 942 dumpType(VD->getType()); 943 } 944 945 void TextNodeDumper::dumpName(const NamedDecl *ND) { 946 if (ND->getDeclName()) { 947 ColorScope Color(OS, ShowColors, DeclNameColor); 948 OS << ' ' << ND->getDeclName(); 949 } 950 } 951 952 void TextNodeDumper::dumpAccessSpecifier(AccessSpecifier AS) { 953 const auto AccessSpelling = getAccessSpelling(AS); 954 if (AccessSpelling.empty()) 955 return; 956 OS << AccessSpelling; 957 } 958 959 void TextNodeDumper::dumpCleanupObject( 960 const ExprWithCleanups::CleanupObject &C) { 961 if (auto *BD = C.dyn_cast<BlockDecl *>()) 962 dumpDeclRef(BD, "cleanup"); 963 else if (auto *CLE = C.dyn_cast<CompoundLiteralExpr *>()) 964 AddChild([=] { 965 OS << "cleanup "; 966 { 967 ColorScope Color(OS, ShowColors, StmtColor); 968 OS << CLE->getStmtClassName(); 969 } 970 dumpPointer(CLE); 971 }); 972 else 973 llvm_unreachable("unexpected cleanup type"); 974 } 975 976 void clang::TextNodeDumper::dumpTemplateSpecializationKind( 977 TemplateSpecializationKind TSK) { 978 switch (TSK) { 979 case TSK_Undeclared: 980 break; 981 case TSK_ImplicitInstantiation: 982 OS << " implicit_instantiation"; 983 break; 984 case TSK_ExplicitSpecialization: 985 OS << " explicit_specialization"; 986 break; 987 case TSK_ExplicitInstantiationDeclaration: 988 OS << " explicit_instantiation_declaration"; 989 break; 990 case TSK_ExplicitInstantiationDefinition: 991 OS << " explicit_instantiation_definition"; 992 break; 993 } 994 } 995 996 void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier *NNS) { 997 if (!NNS) 998 return; 999 1000 AddChild([=] { 1001 OS << "NestedNameSpecifier"; 1002 1003 switch (NNS->getKind()) { 1004 case NestedNameSpecifier::Identifier: 1005 OS << " Identifier"; 1006 OS << " '" << NNS->getAsIdentifier()->getName() << "'"; 1007 break; 1008 case NestedNameSpecifier::Namespace: 1009 OS << " "; // "Namespace" is printed as the decl kind. 1010 dumpBareDeclRef(NNS->getAsNamespace()); 1011 break; 1012 case NestedNameSpecifier::NamespaceAlias: 1013 OS << " "; // "NamespaceAlias" is printed as the decl kind. 1014 dumpBareDeclRef(NNS->getAsNamespaceAlias()); 1015 break; 1016 case NestedNameSpecifier::TypeSpec: 1017 OS << " TypeSpec"; 1018 dumpType(QualType(NNS->getAsType(), 0)); 1019 break; 1020 case NestedNameSpecifier::TypeSpecWithTemplate: 1021 OS << " TypeSpecWithTemplate"; 1022 dumpType(QualType(NNS->getAsType(), 0)); 1023 break; 1024 case NestedNameSpecifier::Global: 1025 OS << " Global"; 1026 break; 1027 case NestedNameSpecifier::Super: 1028 OS << " Super"; 1029 break; 1030 } 1031 1032 dumpNestedNameSpecifier(NNS->getPrefix()); 1033 }); 1034 } 1035 1036 void TextNodeDumper::dumpDeclRef(const Decl *D, StringRef Label) { 1037 if (!D) 1038 return; 1039 1040 AddChild([=] { 1041 if (!Label.empty()) 1042 OS << Label << ' '; 1043 dumpBareDeclRef(D); 1044 }); 1045 } 1046 1047 void TextNodeDumper::dumpTemplateArgument(const TemplateArgument &TA) { 1048 llvm::SmallString<128> Str; 1049 { 1050 llvm::raw_svector_ostream SS(Str); 1051 TA.print(PrintPolicy, SS, /*IncludeType=*/true); 1052 } 1053 OS << " '" << Str << "'"; 1054 1055 if (!Context) 1056 return; 1057 1058 if (TemplateArgument CanonTA = Context->getCanonicalTemplateArgument(TA); 1059 !CanonTA.structurallyEquals(TA)) { 1060 llvm::SmallString<128> CanonStr; 1061 { 1062 llvm::raw_svector_ostream SS(CanonStr); 1063 CanonTA.print(PrintPolicy, SS, /*IncludeType=*/true); 1064 } 1065 if (CanonStr != Str) 1066 OS << ":'" << CanonStr << "'"; 1067 } 1068 } 1069 1070 const char *TextNodeDumper::getCommandName(unsigned CommandID) { 1071 if (Traits) 1072 return Traits->getCommandInfo(CommandID)->Name; 1073 const comments::CommandInfo *Info = 1074 comments::CommandTraits::getBuiltinCommandInfo(CommandID); 1075 if (Info) 1076 return Info->Name; 1077 return "<not a builtin command>"; 1078 } 1079 1080 void TextNodeDumper::printFPOptions(FPOptionsOverride FPO) { 1081 #define OPTION(NAME, TYPE, WIDTH, PREVIOUS) \ 1082 if (FPO.has##NAME##Override()) \ 1083 OS << " " #NAME "=" << FPO.get##NAME##Override(); 1084 #include "clang/Basic/FPOptions.def" 1085 } 1086 1087 void TextNodeDumper::visitTextComment(const comments::TextComment *C, 1088 const comments::FullComment *) { 1089 OS << " Text=\"" << C->getText() << "\""; 1090 } 1091 1092 void TextNodeDumper::visitInlineCommandComment( 1093 const comments::InlineCommandComment *C, const comments::FullComment *) { 1094 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 1095 switch (C->getRenderKind()) { 1096 case comments::InlineCommandRenderKind::Normal: 1097 OS << " RenderNormal"; 1098 break; 1099 case comments::InlineCommandRenderKind::Bold: 1100 OS << " RenderBold"; 1101 break; 1102 case comments::InlineCommandRenderKind::Monospaced: 1103 OS << " RenderMonospaced"; 1104 break; 1105 case comments::InlineCommandRenderKind::Emphasized: 1106 OS << " RenderEmphasized"; 1107 break; 1108 case comments::InlineCommandRenderKind::Anchor: 1109 OS << " RenderAnchor"; 1110 break; 1111 } 1112 1113 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 1114 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 1115 } 1116 1117 void TextNodeDumper::visitHTMLStartTagComment( 1118 const comments::HTMLStartTagComment *C, const comments::FullComment *) { 1119 OS << " Name=\"" << C->getTagName() << "\""; 1120 if (C->getNumAttrs() != 0) { 1121 OS << " Attrs: "; 1122 for (unsigned i = 0, e = C->getNumAttrs(); i != e; ++i) { 1123 const comments::HTMLStartTagComment::Attribute &Attr = C->getAttr(i); 1124 OS << " \"" << Attr.Name << "=\"" << Attr.Value << "\""; 1125 } 1126 } 1127 if (C->isSelfClosing()) 1128 OS << " SelfClosing"; 1129 } 1130 1131 void TextNodeDumper::visitHTMLEndTagComment( 1132 const comments::HTMLEndTagComment *C, const comments::FullComment *) { 1133 OS << " Name=\"" << C->getTagName() << "\""; 1134 } 1135 1136 void TextNodeDumper::visitBlockCommandComment( 1137 const comments::BlockCommandComment *C, const comments::FullComment *) { 1138 OS << " Name=\"" << getCommandName(C->getCommandID()) << "\""; 1139 for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) 1140 OS << " Arg[" << i << "]=\"" << C->getArgText(i) << "\""; 1141 } 1142 1143 void TextNodeDumper::visitParamCommandComment( 1144 const comments::ParamCommandComment *C, const comments::FullComment *FC) { 1145 OS << " " 1146 << comments::ParamCommandComment::getDirectionAsString(C->getDirection()); 1147 1148 if (C->isDirectionExplicit()) 1149 OS << " explicitly"; 1150 else 1151 OS << " implicitly"; 1152 1153 if (C->hasParamName()) { 1154 if (C->isParamIndexValid()) 1155 OS << " Param=\"" << C->getParamName(FC) << "\""; 1156 else 1157 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 1158 } 1159 1160 if (C->isParamIndexValid() && !C->isVarArgParam()) 1161 OS << " ParamIndex=" << C->getParamIndex(); 1162 } 1163 1164 void TextNodeDumper::visitTParamCommandComment( 1165 const comments::TParamCommandComment *C, const comments::FullComment *FC) { 1166 if (C->hasParamName()) { 1167 if (C->isPositionValid()) 1168 OS << " Param=\"" << C->getParamName(FC) << "\""; 1169 else 1170 OS << " Param=\"" << C->getParamNameAsWritten() << "\""; 1171 } 1172 1173 if (C->isPositionValid()) { 1174 OS << " Position=<"; 1175 for (unsigned i = 0, e = C->getDepth(); i != e; ++i) { 1176 OS << C->getIndex(i); 1177 if (i != e - 1) 1178 OS << ", "; 1179 } 1180 OS << ">"; 1181 } 1182 } 1183 1184 void TextNodeDumper::visitVerbatimBlockComment( 1185 const comments::VerbatimBlockComment *C, const comments::FullComment *) { 1186 OS << " Name=\"" << getCommandName(C->getCommandID()) 1187 << "\"" 1188 " CloseName=\"" 1189 << C->getCloseName() << "\""; 1190 } 1191 1192 void TextNodeDumper::visitVerbatimBlockLineComment( 1193 const comments::VerbatimBlockLineComment *C, 1194 const comments::FullComment *) { 1195 OS << " Text=\"" << C->getText() << "\""; 1196 } 1197 1198 void TextNodeDumper::visitVerbatimLineComment( 1199 const comments::VerbatimLineComment *C, const comments::FullComment *) { 1200 OS << " Text=\"" << C->getText() << "\""; 1201 } 1202 1203 void TextNodeDumper::VisitNullTemplateArgument(const TemplateArgument &) { 1204 OS << " null"; 1205 } 1206 1207 void TextNodeDumper::VisitTypeTemplateArgument(const TemplateArgument &TA) { 1208 OS << " type"; 1209 dumpTemplateArgument(TA); 1210 } 1211 1212 void TextNodeDumper::VisitDeclarationTemplateArgument( 1213 const TemplateArgument &TA) { 1214 OS << " decl"; 1215 dumpTemplateArgument(TA); 1216 dumpDeclRef(TA.getAsDecl()); 1217 } 1218 1219 void TextNodeDumper::VisitNullPtrTemplateArgument(const TemplateArgument &TA) { 1220 OS << " nullptr"; 1221 dumpTemplateArgument(TA); 1222 } 1223 1224 void TextNodeDumper::VisitIntegralTemplateArgument(const TemplateArgument &TA) { 1225 OS << " integral"; 1226 dumpTemplateArgument(TA); 1227 } 1228 1229 void TextNodeDumper::dumpTemplateName(TemplateName TN, StringRef Label) { 1230 AddChild(Label, [=] { 1231 { 1232 llvm::SmallString<128> Str; 1233 { 1234 llvm::raw_svector_ostream SS(Str); 1235 TN.print(SS, PrintPolicy); 1236 } 1237 OS << "'" << Str << "'"; 1238 1239 if (Context) { 1240 if (TemplateName CanonTN = Context->getCanonicalTemplateName(TN); 1241 CanonTN != TN) { 1242 llvm::SmallString<128> CanonStr; 1243 { 1244 llvm::raw_svector_ostream SS(CanonStr); 1245 CanonTN.print(SS, PrintPolicy); 1246 } 1247 if (CanonStr != Str) 1248 OS << ":'" << CanonStr << "'"; 1249 } 1250 } 1251 } 1252 dumpBareTemplateName(TN); 1253 }); 1254 } 1255 1256 void TextNodeDumper::dumpBareTemplateName(TemplateName TN) { 1257 switch (TN.getKind()) { 1258 case TemplateName::Template: 1259 AddChild([=] { Visit(TN.getAsTemplateDecl()); }); 1260 return; 1261 case TemplateName::UsingTemplate: { 1262 const UsingShadowDecl *USD = TN.getAsUsingShadowDecl(); 1263 AddChild([=] { Visit(USD); }); 1264 AddChild("target", [=] { Visit(USD->getTargetDecl()); }); 1265 return; 1266 } 1267 case TemplateName::QualifiedTemplate: { 1268 OS << " qualified"; 1269 const QualifiedTemplateName *QTN = TN.getAsQualifiedTemplateName(); 1270 if (QTN->hasTemplateKeyword()) 1271 OS << " keyword"; 1272 dumpNestedNameSpecifier(QTN->getQualifier()); 1273 dumpBareTemplateName(QTN->getUnderlyingTemplate()); 1274 return; 1275 } 1276 case TemplateName::DependentTemplate: { 1277 OS << " dependent"; 1278 const DependentTemplateName *DTN = TN.getAsDependentTemplateName(); 1279 dumpNestedNameSpecifier(DTN->getQualifier()); 1280 return; 1281 } 1282 case TemplateName::SubstTemplateTemplateParm: { 1283 OS << " subst"; 1284 const SubstTemplateTemplateParmStorage *STS = 1285 TN.getAsSubstTemplateTemplateParm(); 1286 OS << " index " << STS->getIndex(); 1287 if (std::optional<unsigned int> PackIndex = STS->getPackIndex()) 1288 OS << " pack_index " << *PackIndex; 1289 if (const TemplateTemplateParmDecl *P = STS->getParameter()) 1290 AddChild("parameter", [=] { Visit(P); }); 1291 dumpDeclRef(STS->getAssociatedDecl(), "associated"); 1292 dumpTemplateName(STS->getReplacement(), "replacement"); 1293 return; 1294 } 1295 case TemplateName::DeducedTemplate: { 1296 OS << " deduced"; 1297 const DeducedTemplateStorage *DTS = TN.getAsDeducedTemplateName(); 1298 dumpTemplateName(DTS->getUnderlying(), "underlying"); 1299 AddChild("defaults", [=] { 1300 auto [StartPos, Args] = DTS->getDefaultArguments(); 1301 OS << " start " << StartPos; 1302 for (const TemplateArgument &Arg : Args) 1303 AddChild([=] { Visit(Arg, SourceRange()); }); 1304 }); 1305 return; 1306 } 1307 // FIXME: Implement these. 1308 case TemplateName::OverloadedTemplate: 1309 OS << " overloaded"; 1310 return; 1311 case TemplateName::AssumedTemplate: 1312 OS << " assumed"; 1313 return; 1314 case TemplateName::SubstTemplateTemplateParmPack: 1315 OS << " subst_pack"; 1316 return; 1317 } 1318 llvm_unreachable("Unexpected TemplateName Kind"); 1319 } 1320 1321 void TextNodeDumper::VisitTemplateTemplateArgument(const TemplateArgument &TA) { 1322 OS << " template"; 1323 dumpTemplateArgument(TA); 1324 dumpBareTemplateName(TA.getAsTemplate()); 1325 } 1326 1327 void TextNodeDumper::VisitTemplateExpansionTemplateArgument( 1328 const TemplateArgument &TA) { 1329 OS << " template expansion"; 1330 dumpTemplateArgument(TA); 1331 dumpBareTemplateName(TA.getAsTemplateOrTemplatePattern()); 1332 } 1333 1334 void TextNodeDumper::VisitExpressionTemplateArgument( 1335 const TemplateArgument &TA) { 1336 OS << " expr"; 1337 dumpTemplateArgument(TA); 1338 } 1339 1340 void TextNodeDumper::VisitPackTemplateArgument(const TemplateArgument &TA) { 1341 OS << " pack"; 1342 dumpTemplateArgument(TA); 1343 } 1344 1345 static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) { 1346 if (Node->path_empty()) 1347 return; 1348 1349 OS << " ("; 1350 bool First = true; 1351 for (CastExpr::path_const_iterator I = Node->path_begin(), 1352 E = Node->path_end(); 1353 I != E; ++I) { 1354 const CXXBaseSpecifier *Base = *I; 1355 if (!First) 1356 OS << " -> "; 1357 1358 const auto *RD = 1359 cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl()); 1360 1361 if (Base->isVirtual()) 1362 OS << "virtual "; 1363 OS << RD->getName(); 1364 First = false; 1365 } 1366 1367 OS << ')'; 1368 } 1369 1370 void TextNodeDumper::VisitIfStmt(const IfStmt *Node) { 1371 if (Node->hasInitStorage()) 1372 OS << " has_init"; 1373 if (Node->hasVarStorage()) 1374 OS << " has_var"; 1375 if (Node->hasElseStorage()) 1376 OS << " has_else"; 1377 if (Node->isConstexpr()) 1378 OS << " constexpr"; 1379 if (Node->isConsteval()) { 1380 OS << " "; 1381 if (Node->isNegatedConsteval()) 1382 OS << "!"; 1383 OS << "consteval"; 1384 } 1385 } 1386 1387 void TextNodeDumper::VisitSwitchStmt(const SwitchStmt *Node) { 1388 if (Node->hasInitStorage()) 1389 OS << " has_init"; 1390 if (Node->hasVarStorage()) 1391 OS << " has_var"; 1392 } 1393 1394 void TextNodeDumper::VisitWhileStmt(const WhileStmt *Node) { 1395 if (Node->hasVarStorage()) 1396 OS << " has_var"; 1397 } 1398 1399 void TextNodeDumper::VisitLabelStmt(const LabelStmt *Node) { 1400 OS << " '" << Node->getName() << "'"; 1401 if (Node->isSideEntry()) 1402 OS << " side_entry"; 1403 } 1404 1405 void TextNodeDumper::VisitGotoStmt(const GotoStmt *Node) { 1406 OS << " '" << Node->getLabel()->getName() << "'"; 1407 dumpPointer(Node->getLabel()); 1408 } 1409 1410 void TextNodeDumper::VisitCaseStmt(const CaseStmt *Node) { 1411 if (Node->caseStmtIsGNURange()) 1412 OS << " gnu_range"; 1413 } 1414 1415 void clang::TextNodeDumper::VisitReturnStmt(const ReturnStmt *Node) { 1416 if (const VarDecl *Cand = Node->getNRVOCandidate()) { 1417 OS << " nrvo_candidate("; 1418 dumpBareDeclRef(Cand); 1419 OS << ")"; 1420 } 1421 } 1422 1423 void clang::TextNodeDumper::VisitCoawaitExpr(const CoawaitExpr *Node) { 1424 if (Node->isImplicit()) 1425 OS << " implicit"; 1426 } 1427 1428 void clang::TextNodeDumper::VisitCoreturnStmt(const CoreturnStmt *Node) { 1429 if (Node->isImplicit()) 1430 OS << " implicit"; 1431 } 1432 1433 void TextNodeDumper::VisitConstantExpr(const ConstantExpr *Node) { 1434 if (Node->hasAPValueResult()) 1435 AddChild("value", 1436 [=] { Visit(Node->getAPValueResult(), Node->getType()); }); 1437 } 1438 1439 void TextNodeDumper::VisitCallExpr(const CallExpr *Node) { 1440 if (Node->usesADL()) 1441 OS << " adl"; 1442 if (Node->hasStoredFPFeatures()) 1443 printFPOptions(Node->getFPFeatures()); 1444 } 1445 1446 void TextNodeDumper::VisitCXXOperatorCallExpr(const CXXOperatorCallExpr *Node) { 1447 const char *OperatorSpelling = clang::getOperatorSpelling(Node->getOperator()); 1448 if (OperatorSpelling) 1449 OS << " '" << OperatorSpelling << "'"; 1450 1451 VisitCallExpr(Node); 1452 } 1453 1454 void TextNodeDumper::VisitCastExpr(const CastExpr *Node) { 1455 OS << " <"; 1456 { 1457 ColorScope Color(OS, ShowColors, CastColor); 1458 OS << Node->getCastKindName(); 1459 } 1460 dumpBasePath(OS, Node); 1461 OS << ">"; 1462 if (Node->hasStoredFPFeatures()) 1463 printFPOptions(Node->getFPFeatures()); 1464 } 1465 1466 void TextNodeDumper::VisitImplicitCastExpr(const ImplicitCastExpr *Node) { 1467 VisitCastExpr(Node); 1468 if (Node->isPartOfExplicitCast()) 1469 OS << " part_of_explicit_cast"; 1470 } 1471 1472 void TextNodeDumper::VisitDeclRefExpr(const DeclRefExpr *Node) { 1473 OS << " "; 1474 dumpBareDeclRef(Node->getDecl()); 1475 dumpNestedNameSpecifier(Node->getQualifier()); 1476 if (Node->getDecl() != Node->getFoundDecl()) { 1477 OS << " ("; 1478 dumpBareDeclRef(Node->getFoundDecl()); 1479 OS << ")"; 1480 } 1481 switch (Node->isNonOdrUse()) { 1482 case NOUR_None: break; 1483 case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break; 1484 case NOUR_Constant: OS << " non_odr_use_constant"; break; 1485 case NOUR_Discarded: OS << " non_odr_use_discarded"; break; 1486 } 1487 if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter()) 1488 OS << " dependent_capture"; 1489 else if (Node->refersToEnclosingVariableOrCapture()) 1490 OS << " refers_to_enclosing_variable_or_capture"; 1491 1492 if (Node->isImmediateEscalating()) 1493 OS << " immediate-escalating"; 1494 } 1495 1496 void clang::TextNodeDumper::VisitDependentScopeDeclRefExpr( 1497 const DependentScopeDeclRefExpr *Node) { 1498 1499 dumpNestedNameSpecifier(Node->getQualifier()); 1500 } 1501 1502 void TextNodeDumper::VisitUnresolvedLookupExpr( 1503 const UnresolvedLookupExpr *Node) { 1504 OS << " ("; 1505 if (!Node->requiresADL()) 1506 OS << "no "; 1507 OS << "ADL) = '" << Node->getName() << '\''; 1508 1509 UnresolvedLookupExpr::decls_iterator I = Node->decls_begin(), 1510 E = Node->decls_end(); 1511 if (I == E) 1512 OS << " empty"; 1513 for (; I != E; ++I) 1514 dumpPointer(*I); 1515 } 1516 1517 void TextNodeDumper::VisitObjCIvarRefExpr(const ObjCIvarRefExpr *Node) { 1518 { 1519 ColorScope Color(OS, ShowColors, DeclKindNameColor); 1520 OS << " " << Node->getDecl()->getDeclKindName() << "Decl"; 1521 } 1522 OS << "='" << *Node->getDecl() << "'"; 1523 dumpPointer(Node->getDecl()); 1524 if (Node->isFreeIvar()) 1525 OS << " isFreeIvar"; 1526 } 1527 1528 void TextNodeDumper::VisitSYCLUniqueStableNameExpr( 1529 const SYCLUniqueStableNameExpr *Node) { 1530 dumpType(Node->getTypeSourceInfo()->getType()); 1531 } 1532 1533 void TextNodeDumper::VisitPredefinedExpr(const PredefinedExpr *Node) { 1534 OS << " " << PredefinedExpr::getIdentKindName(Node->getIdentKind()); 1535 } 1536 1537 void TextNodeDumper::VisitCharacterLiteral(const CharacterLiteral *Node) { 1538 ColorScope Color(OS, ShowColors, ValueColor); 1539 OS << " " << Node->getValue(); 1540 } 1541 1542 void TextNodeDumper::VisitIntegerLiteral(const IntegerLiteral *Node) { 1543 bool isSigned = Node->getType()->isSignedIntegerType(); 1544 ColorScope Color(OS, ShowColors, ValueColor); 1545 OS << " " << toString(Node->getValue(), 10, isSigned); 1546 } 1547 1548 void TextNodeDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) { 1549 ColorScope Color(OS, ShowColors, ValueColor); 1550 OS << " " << Node->getValueAsString(/*Radix=*/10); 1551 } 1552 1553 void TextNodeDumper::VisitFloatingLiteral(const FloatingLiteral *Node) { 1554 ColorScope Color(OS, ShowColors, ValueColor); 1555 OS << " " << Node->getValueAsApproximateDouble(); 1556 } 1557 1558 void TextNodeDumper::VisitStringLiteral(const StringLiteral *Str) { 1559 ColorScope Color(OS, ShowColors, ValueColor); 1560 OS << " "; 1561 Str->outputString(OS); 1562 } 1563 1564 void TextNodeDumper::VisitInitListExpr(const InitListExpr *ILE) { 1565 if (auto *Field = ILE->getInitializedFieldInUnion()) { 1566 OS << " field "; 1567 dumpBareDeclRef(Field); 1568 } 1569 } 1570 1571 void TextNodeDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) { 1572 if (E->isResultDependent()) 1573 OS << " result_dependent"; 1574 } 1575 1576 void TextNodeDumper::VisitUnaryOperator(const UnaryOperator *Node) { 1577 OS << " " << (Node->isPostfix() ? "postfix" : "prefix") << " '" 1578 << UnaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1579 if (!Node->canOverflow()) 1580 OS << " cannot overflow"; 1581 if (Node->hasStoredFPFeatures()) 1582 printFPOptions(Node->getStoredFPFeatures()); 1583 } 1584 1585 void TextNodeDumper::VisitUnaryExprOrTypeTraitExpr( 1586 const UnaryExprOrTypeTraitExpr *Node) { 1587 OS << " " << getTraitSpelling(Node->getKind()); 1588 1589 if (Node->isArgumentType()) 1590 dumpType(Node->getArgumentType()); 1591 } 1592 1593 void TextNodeDumper::VisitMemberExpr(const MemberExpr *Node) { 1594 OS << " " << (Node->isArrow() ? "->" : ".") << *Node->getMemberDecl(); 1595 dumpPointer(Node->getMemberDecl()); 1596 dumpNestedNameSpecifier(Node->getQualifier()); 1597 switch (Node->isNonOdrUse()) { 1598 case NOUR_None: break; 1599 case NOUR_Unevaluated: OS << " non_odr_use_unevaluated"; break; 1600 case NOUR_Constant: OS << " non_odr_use_constant"; break; 1601 case NOUR_Discarded: OS << " non_odr_use_discarded"; break; 1602 } 1603 } 1604 1605 void TextNodeDumper::VisitExtVectorElementExpr( 1606 const ExtVectorElementExpr *Node) { 1607 OS << " " << Node->getAccessor().getNameStart(); 1608 } 1609 1610 void TextNodeDumper::VisitBinaryOperator(const BinaryOperator *Node) { 1611 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) << "'"; 1612 if (Node->hasStoredFPFeatures()) 1613 printFPOptions(Node->getStoredFPFeatures()); 1614 } 1615 1616 void TextNodeDumper::VisitCompoundAssignOperator( 1617 const CompoundAssignOperator *Node) { 1618 OS << " '" << BinaryOperator::getOpcodeStr(Node->getOpcode()) 1619 << "' ComputeLHSTy="; 1620 dumpBareType(Node->getComputationLHSType()); 1621 OS << " ComputeResultTy="; 1622 dumpBareType(Node->getComputationResultType()); 1623 if (Node->hasStoredFPFeatures()) 1624 printFPOptions(Node->getStoredFPFeatures()); 1625 } 1626 1627 void TextNodeDumper::VisitAddrLabelExpr(const AddrLabelExpr *Node) { 1628 OS << " " << Node->getLabel()->getName(); 1629 dumpPointer(Node->getLabel()); 1630 } 1631 1632 void TextNodeDumper::VisitCXXNamedCastExpr(const CXXNamedCastExpr *Node) { 1633 OS << " " << Node->getCastName() << "<" 1634 << Node->getTypeAsWritten().getAsString() << ">" 1635 << " <" << Node->getCastKindName(); 1636 dumpBasePath(OS, Node); 1637 OS << ">"; 1638 } 1639 1640 void TextNodeDumper::VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *Node) { 1641 OS << " " << (Node->getValue() ? "true" : "false"); 1642 } 1643 1644 void TextNodeDumper::VisitCXXThisExpr(const CXXThisExpr *Node) { 1645 if (Node->isImplicit()) 1646 OS << " implicit"; 1647 if (Node->isCapturedByCopyInLambdaWithExplicitObjectParameter()) 1648 OS << " dependent_capture"; 1649 OS << " this"; 1650 } 1651 1652 void TextNodeDumper::VisitCXXFunctionalCastExpr( 1653 const CXXFunctionalCastExpr *Node) { 1654 OS << " functional cast to " << Node->getTypeAsWritten().getAsString() << " <" 1655 << Node->getCastKindName() << ">"; 1656 if (Node->hasStoredFPFeatures()) 1657 printFPOptions(Node->getFPFeatures()); 1658 } 1659 1660 void TextNodeDumper::VisitCXXStaticCastExpr(const CXXStaticCastExpr *Node) { 1661 VisitCXXNamedCastExpr(Node); 1662 if (Node->hasStoredFPFeatures()) 1663 printFPOptions(Node->getFPFeatures()); 1664 } 1665 1666 void TextNodeDumper::VisitCXXUnresolvedConstructExpr( 1667 const CXXUnresolvedConstructExpr *Node) { 1668 dumpType(Node->getTypeAsWritten()); 1669 if (Node->isListInitialization()) 1670 OS << " list"; 1671 } 1672 1673 void TextNodeDumper::VisitCXXConstructExpr(const CXXConstructExpr *Node) { 1674 CXXConstructorDecl *Ctor = Node->getConstructor(); 1675 dumpType(Ctor->getType()); 1676 if (Node->isElidable()) 1677 OS << " elidable"; 1678 if (Node->isListInitialization()) 1679 OS << " list"; 1680 if (Node->isStdInitListInitialization()) 1681 OS << " std::initializer_list"; 1682 if (Node->requiresZeroInitialization()) 1683 OS << " zeroing"; 1684 if (Node->isImmediateEscalating()) 1685 OS << " immediate-escalating"; 1686 } 1687 1688 void TextNodeDumper::VisitCXXBindTemporaryExpr( 1689 const CXXBindTemporaryExpr *Node) { 1690 OS << " (CXXTemporary"; 1691 dumpPointer(Node); 1692 OS << ")"; 1693 } 1694 1695 void TextNodeDumper::VisitCXXNewExpr(const CXXNewExpr *Node) { 1696 if (Node->isGlobalNew()) 1697 OS << " global"; 1698 if (Node->isArray()) 1699 OS << " array"; 1700 if (Node->getOperatorNew()) { 1701 OS << ' '; 1702 dumpBareDeclRef(Node->getOperatorNew()); 1703 } 1704 // We could dump the deallocation function used in case of error, but it's 1705 // usually not that interesting. 1706 } 1707 1708 void TextNodeDumper::VisitCXXDeleteExpr(const CXXDeleteExpr *Node) { 1709 if (Node->isGlobalDelete()) 1710 OS << " global"; 1711 if (Node->isArrayForm()) 1712 OS << " array"; 1713 if (Node->getOperatorDelete()) { 1714 OS << ' '; 1715 dumpBareDeclRef(Node->getOperatorDelete()); 1716 } 1717 } 1718 1719 void TextNodeDumper::VisitTypeTraitExpr(const TypeTraitExpr *Node) { 1720 OS << " " << getTraitSpelling(Node->getTrait()); 1721 } 1722 1723 void TextNodeDumper::VisitArrayTypeTraitExpr(const ArrayTypeTraitExpr *Node) { 1724 OS << " " << getTraitSpelling(Node->getTrait()); 1725 } 1726 1727 void TextNodeDumper::VisitExpressionTraitExpr(const ExpressionTraitExpr *Node) { 1728 OS << " " << getTraitSpelling(Node->getTrait()); 1729 } 1730 1731 void TextNodeDumper::VisitCXXDefaultArgExpr(const CXXDefaultArgExpr *Node) { 1732 if (Node->hasRewrittenInit()) 1733 OS << " has rewritten init"; 1734 } 1735 1736 void TextNodeDumper::VisitCXXDefaultInitExpr(const CXXDefaultInitExpr *Node) { 1737 if (Node->hasRewrittenInit()) 1738 OS << " has rewritten init"; 1739 } 1740 1741 void TextNodeDumper::VisitMaterializeTemporaryExpr( 1742 const MaterializeTemporaryExpr *Node) { 1743 if (const ValueDecl *VD = Node->getExtendingDecl()) { 1744 OS << " extended by "; 1745 dumpBareDeclRef(VD); 1746 } 1747 } 1748 1749 void TextNodeDumper::VisitExprWithCleanups(const ExprWithCleanups *Node) { 1750 for (unsigned i = 0, e = Node->getNumObjects(); i != e; ++i) 1751 dumpCleanupObject(Node->getObject(i)); 1752 } 1753 1754 void TextNodeDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) { 1755 dumpPointer(Node->getPack()); 1756 dumpName(Node->getPack()); 1757 } 1758 1759 void TextNodeDumper::VisitCXXDependentScopeMemberExpr( 1760 const CXXDependentScopeMemberExpr *Node) { 1761 OS << " " << (Node->isArrow() ? "->" : ".") << Node->getMember(); 1762 } 1763 1764 void TextNodeDumper::VisitObjCMessageExpr(const ObjCMessageExpr *Node) { 1765 OS << " selector="; 1766 Node->getSelector().print(OS); 1767 switch (Node->getReceiverKind()) { 1768 case ObjCMessageExpr::Instance: 1769 break; 1770 1771 case ObjCMessageExpr::Class: 1772 OS << " class="; 1773 dumpBareType(Node->getClassReceiver()); 1774 break; 1775 1776 case ObjCMessageExpr::SuperInstance: 1777 OS << " super (instance)"; 1778 break; 1779 1780 case ObjCMessageExpr::SuperClass: 1781 OS << " super (class)"; 1782 break; 1783 } 1784 } 1785 1786 void TextNodeDumper::VisitObjCBoxedExpr(const ObjCBoxedExpr *Node) { 1787 if (auto *BoxingMethod = Node->getBoxingMethod()) { 1788 OS << " selector="; 1789 BoxingMethod->getSelector().print(OS); 1790 } 1791 } 1792 1793 void TextNodeDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 1794 if (!Node->getCatchParamDecl()) 1795 OS << " catch all"; 1796 } 1797 1798 void TextNodeDumper::VisitObjCEncodeExpr(const ObjCEncodeExpr *Node) { 1799 dumpType(Node->getEncodedType()); 1800 } 1801 1802 void TextNodeDumper::VisitObjCSelectorExpr(const ObjCSelectorExpr *Node) { 1803 OS << " "; 1804 Node->getSelector().print(OS); 1805 } 1806 1807 void TextNodeDumper::VisitObjCProtocolExpr(const ObjCProtocolExpr *Node) { 1808 OS << ' ' << *Node->getProtocol(); 1809 } 1810 1811 void TextNodeDumper::VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *Node) { 1812 if (Node->isImplicitProperty()) { 1813 OS << " Kind=MethodRef Getter=\""; 1814 if (Node->getImplicitPropertyGetter()) 1815 Node->getImplicitPropertyGetter()->getSelector().print(OS); 1816 else 1817 OS << "(null)"; 1818 1819 OS << "\" Setter=\""; 1820 if (ObjCMethodDecl *Setter = Node->getImplicitPropertySetter()) 1821 Setter->getSelector().print(OS); 1822 else 1823 OS << "(null)"; 1824 OS << "\""; 1825 } else { 1826 OS << " Kind=PropertyRef Property=\"" << *Node->getExplicitProperty() 1827 << '"'; 1828 } 1829 1830 if (Node->isSuperReceiver()) 1831 OS << " super"; 1832 1833 OS << " Messaging="; 1834 if (Node->isMessagingGetter() && Node->isMessagingSetter()) 1835 OS << "Getter&Setter"; 1836 else if (Node->isMessagingGetter()) 1837 OS << "Getter"; 1838 else if (Node->isMessagingSetter()) 1839 OS << "Setter"; 1840 } 1841 1842 void TextNodeDumper::VisitObjCSubscriptRefExpr( 1843 const ObjCSubscriptRefExpr *Node) { 1844 if (Node->isArraySubscriptRefExpr()) 1845 OS << " Kind=ArraySubscript GetterForArray=\""; 1846 else 1847 OS << " Kind=DictionarySubscript GetterForDictionary=\""; 1848 if (Node->getAtIndexMethodDecl()) 1849 Node->getAtIndexMethodDecl()->getSelector().print(OS); 1850 else 1851 OS << "(null)"; 1852 1853 if (Node->isArraySubscriptRefExpr()) 1854 OS << "\" SetterForArray=\""; 1855 else 1856 OS << "\" SetterForDictionary=\""; 1857 if (Node->setAtIndexMethodDecl()) 1858 Node->setAtIndexMethodDecl()->getSelector().print(OS); 1859 else 1860 OS << "(null)"; 1861 } 1862 1863 void TextNodeDumper::VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *Node) { 1864 OS << " " << (Node->getValue() ? "__objc_yes" : "__objc_no"); 1865 } 1866 1867 void TextNodeDumper::VisitOMPIteratorExpr(const OMPIteratorExpr *Node) { 1868 OS << " "; 1869 for (unsigned I = 0, E = Node->numOfIterators(); I < E; ++I) { 1870 Visit(Node->getIteratorDecl(I)); 1871 OS << " = "; 1872 const OMPIteratorExpr::IteratorRange Range = Node->getIteratorRange(I); 1873 OS << " begin "; 1874 Visit(Range.Begin); 1875 OS << " end "; 1876 Visit(Range.End); 1877 if (Range.Step) { 1878 OS << " step "; 1879 Visit(Range.Step); 1880 } 1881 } 1882 } 1883 1884 void TextNodeDumper::VisitConceptSpecializationExpr( 1885 const ConceptSpecializationExpr *Node) { 1886 OS << " "; 1887 dumpBareDeclRef(Node->getFoundDecl()); 1888 } 1889 1890 void TextNodeDumper::VisitRequiresExpr( 1891 const RequiresExpr *Node) { 1892 if (!Node->isValueDependent()) 1893 OS << (Node->isSatisfied() ? " satisfied" : " unsatisfied"); 1894 } 1895 1896 void TextNodeDumper::VisitRValueReferenceType(const ReferenceType *T) { 1897 if (T->isSpelledAsLValue()) 1898 OS << " written as lvalue reference"; 1899 } 1900 1901 void TextNodeDumper::VisitArrayType(const ArrayType *T) { 1902 switch (T->getSizeModifier()) { 1903 case ArraySizeModifier::Normal: 1904 break; 1905 case ArraySizeModifier::Static: 1906 OS << " static"; 1907 break; 1908 case ArraySizeModifier::Star: 1909 OS << " *"; 1910 break; 1911 } 1912 OS << " " << T->getIndexTypeQualifiers().getAsString(); 1913 } 1914 1915 void TextNodeDumper::VisitConstantArrayType(const ConstantArrayType *T) { 1916 OS << " " << T->getSize(); 1917 VisitArrayType(T); 1918 } 1919 1920 void TextNodeDumper::VisitVariableArrayType(const VariableArrayType *T) { 1921 OS << " "; 1922 dumpSourceRange(T->getBracketsRange()); 1923 VisitArrayType(T); 1924 } 1925 1926 void TextNodeDumper::VisitDependentSizedArrayType( 1927 const DependentSizedArrayType *T) { 1928 VisitArrayType(T); 1929 OS << " "; 1930 dumpSourceRange(T->getBracketsRange()); 1931 } 1932 1933 void TextNodeDumper::VisitDependentSizedExtVectorType( 1934 const DependentSizedExtVectorType *T) { 1935 OS << " "; 1936 dumpLocation(T->getAttributeLoc()); 1937 } 1938 1939 void TextNodeDumper::VisitVectorType(const VectorType *T) { 1940 switch (T->getVectorKind()) { 1941 case VectorKind::Generic: 1942 break; 1943 case VectorKind::AltiVecVector: 1944 OS << " altivec"; 1945 break; 1946 case VectorKind::AltiVecPixel: 1947 OS << " altivec pixel"; 1948 break; 1949 case VectorKind::AltiVecBool: 1950 OS << " altivec bool"; 1951 break; 1952 case VectorKind::Neon: 1953 OS << " neon"; 1954 break; 1955 case VectorKind::NeonPoly: 1956 OS << " neon poly"; 1957 break; 1958 case VectorKind::SveFixedLengthData: 1959 OS << " fixed-length sve data vector"; 1960 break; 1961 case VectorKind::SveFixedLengthPredicate: 1962 OS << " fixed-length sve predicate vector"; 1963 break; 1964 case VectorKind::RVVFixedLengthData: 1965 OS << " fixed-length rvv data vector"; 1966 break; 1967 case VectorKind::RVVFixedLengthMask: 1968 case VectorKind::RVVFixedLengthMask_1: 1969 case VectorKind::RVVFixedLengthMask_2: 1970 case VectorKind::RVVFixedLengthMask_4: 1971 OS << " fixed-length rvv mask vector"; 1972 break; 1973 } 1974 OS << " " << T->getNumElements(); 1975 } 1976 1977 void TextNodeDumper::VisitFunctionType(const FunctionType *T) { 1978 auto EI = T->getExtInfo(); 1979 if (EI.getNoReturn()) 1980 OS << " noreturn"; 1981 if (EI.getProducesResult()) 1982 OS << " produces_result"; 1983 if (EI.getHasRegParm()) 1984 OS << " regparm " << EI.getRegParm(); 1985 OS << " " << FunctionType::getNameForCallConv(EI.getCC()); 1986 } 1987 1988 void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) { 1989 auto EPI = T->getExtProtoInfo(); 1990 if (EPI.HasTrailingReturn) 1991 OS << " trailing_return"; 1992 if (T->isConst()) 1993 OS << " const"; 1994 if (T->isVolatile()) 1995 OS << " volatile"; 1996 if (T->isRestrict()) 1997 OS << " restrict"; 1998 if (T->getExtProtoInfo().Variadic) 1999 OS << " variadic"; 2000 switch (EPI.RefQualifier) { 2001 case RQ_None: 2002 break; 2003 case RQ_LValue: 2004 OS << " &"; 2005 break; 2006 case RQ_RValue: 2007 OS << " &&"; 2008 break; 2009 } 2010 2011 switch (EPI.ExceptionSpec.Type) { 2012 case EST_None: 2013 break; 2014 case EST_DynamicNone: 2015 OS << " exceptionspec_dynamic_none"; 2016 break; 2017 case EST_Dynamic: 2018 OS << " exceptionspec_dynamic"; 2019 break; 2020 case EST_MSAny: 2021 OS << " exceptionspec_ms_any"; 2022 break; 2023 case EST_NoThrow: 2024 OS << " exceptionspec_nothrow"; 2025 break; 2026 case EST_BasicNoexcept: 2027 OS << " exceptionspec_basic_noexcept"; 2028 break; 2029 case EST_DependentNoexcept: 2030 OS << " exceptionspec_dependent_noexcept"; 2031 break; 2032 case EST_NoexceptFalse: 2033 OS << " exceptionspec_noexcept_false"; 2034 break; 2035 case EST_NoexceptTrue: 2036 OS << " exceptionspec_noexcept_true"; 2037 break; 2038 case EST_Unevaluated: 2039 OS << " exceptionspec_unevaluated"; 2040 break; 2041 case EST_Uninstantiated: 2042 OS << " exceptionspec_uninstantiated"; 2043 break; 2044 case EST_Unparsed: 2045 OS << " exceptionspec_unparsed"; 2046 break; 2047 } 2048 if (!EPI.ExceptionSpec.Exceptions.empty()) { 2049 AddChild([=] { 2050 OS << "Exceptions:"; 2051 for (unsigned I = 0, N = EPI.ExceptionSpec.Exceptions.size(); I != N; 2052 ++I) { 2053 if (I) 2054 OS << ","; 2055 dumpType(EPI.ExceptionSpec.Exceptions[I]); 2056 } 2057 }); 2058 } 2059 if (EPI.ExceptionSpec.NoexceptExpr) { 2060 AddChild([=] { 2061 OS << "NoexceptExpr: "; 2062 Visit(EPI.ExceptionSpec.NoexceptExpr); 2063 }); 2064 } 2065 dumpDeclRef(EPI.ExceptionSpec.SourceDecl, "ExceptionSourceDecl"); 2066 dumpDeclRef(EPI.ExceptionSpec.SourceTemplate, "ExceptionSourceTemplate"); 2067 2068 // FIXME: Consumed parameters. 2069 VisitFunctionType(T); 2070 } 2071 2072 void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) { 2073 dumpDeclRef(T->getDecl()); 2074 } 2075 2076 void TextNodeDumper::VisitUsingType(const UsingType *T) { 2077 dumpDeclRef(T->getFoundDecl()); 2078 if (!T->typeMatchesDecl()) 2079 OS << " divergent"; 2080 } 2081 2082 void TextNodeDumper::VisitTypedefType(const TypedefType *T) { 2083 dumpDeclRef(T->getDecl()); 2084 if (!T->typeMatchesDecl()) 2085 OS << " divergent"; 2086 } 2087 2088 void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) { 2089 switch (T->getUTTKind()) { 2090 #define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \ 2091 case UnaryTransformType::Enum: \ 2092 OS << " " #Trait; \ 2093 break; 2094 #include "clang/Basic/TransformTypeTraits.def" 2095 } 2096 } 2097 2098 void TextNodeDumper::VisitTagType(const TagType *T) { 2099 dumpDeclRef(T->getDecl()); 2100 } 2101 2102 void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) { 2103 OS << " depth " << T->getDepth() << " index " << T->getIndex(); 2104 if (T->isParameterPack()) 2105 OS << " pack"; 2106 dumpDeclRef(T->getDecl()); 2107 } 2108 2109 void TextNodeDumper::VisitSubstTemplateTypeParmType( 2110 const SubstTemplateTypeParmType *T) { 2111 dumpDeclRef(T->getAssociatedDecl()); 2112 VisitTemplateTypeParmDecl(T->getReplacedParameter()); 2113 if (auto PackIndex = T->getPackIndex()) 2114 OS << " pack_index " << *PackIndex; 2115 } 2116 2117 void TextNodeDumper::VisitSubstTemplateTypeParmPackType( 2118 const SubstTemplateTypeParmPackType *T) { 2119 dumpDeclRef(T->getAssociatedDecl()); 2120 VisitTemplateTypeParmDecl(T->getReplacedParameter()); 2121 } 2122 2123 void TextNodeDumper::VisitAutoType(const AutoType *T) { 2124 if (T->isDecltypeAuto()) 2125 OS << " decltype(auto)"; 2126 if (!T->isDeduced()) 2127 OS << " undeduced"; 2128 if (T->isConstrained()) 2129 dumpDeclRef(T->getTypeConstraintConcept()); 2130 } 2131 2132 void TextNodeDumper::VisitDeducedTemplateSpecializationType( 2133 const DeducedTemplateSpecializationType *T) { 2134 dumpTemplateName(T->getTemplateName(), "name"); 2135 } 2136 2137 void TextNodeDumper::VisitTemplateSpecializationType( 2138 const TemplateSpecializationType *T) { 2139 if (T->isTypeAlias()) 2140 OS << " alias"; 2141 dumpTemplateName(T->getTemplateName(), "name"); 2142 } 2143 2144 void TextNodeDumper::VisitInjectedClassNameType( 2145 const InjectedClassNameType *T) { 2146 dumpDeclRef(T->getDecl()); 2147 } 2148 2149 void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) { 2150 dumpDeclRef(T->getDecl()); 2151 } 2152 2153 void TextNodeDumper::VisitPackExpansionType(const PackExpansionType *T) { 2154 if (auto N = T->getNumExpansions()) 2155 OS << " expansions " << *N; 2156 } 2157 2158 void TextNodeDumper::VisitTypeLoc(TypeLoc TL) { 2159 // By default, add extra Type details with no extra loc info. 2160 TypeVisitor<TextNodeDumper>::Visit(TL.getTypePtr()); 2161 } 2162 // FIXME: override behavior for TypeLocs that have interesting location 2163 // information, such as the qualifier in ElaboratedTypeLoc. 2164 2165 void TextNodeDumper::VisitLabelDecl(const LabelDecl *D) { dumpName(D); } 2166 2167 void TextNodeDumper::VisitTypedefDecl(const TypedefDecl *D) { 2168 dumpName(D); 2169 dumpType(D->getUnderlyingType()); 2170 if (D->isModulePrivate()) 2171 OS << " __module_private__"; 2172 } 2173 2174 void TextNodeDumper::VisitEnumDecl(const EnumDecl *D) { 2175 if (D->isScoped()) { 2176 if (D->isScopedUsingClassTag()) 2177 OS << " class"; 2178 else 2179 OS << " struct"; 2180 } 2181 dumpName(D); 2182 if (D->isModulePrivate()) 2183 OS << " __module_private__"; 2184 if (D->isFixed()) 2185 dumpType(D->getIntegerType()); 2186 } 2187 2188 void TextNodeDumper::VisitRecordDecl(const RecordDecl *D) { 2189 OS << ' ' << D->getKindName(); 2190 dumpName(D); 2191 if (D->isModulePrivate()) 2192 OS << " __module_private__"; 2193 if (D->isCompleteDefinition()) 2194 OS << " definition"; 2195 } 2196 2197 void TextNodeDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { 2198 dumpName(D); 2199 dumpType(D->getType()); 2200 } 2201 2202 void TextNodeDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { 2203 dumpName(D); 2204 dumpType(D->getType()); 2205 2206 for (const auto *Child : D->chain()) 2207 dumpDeclRef(Child); 2208 } 2209 2210 void TextNodeDumper::VisitFunctionDecl(const FunctionDecl *D) { 2211 dumpName(D); 2212 dumpType(D->getType()); 2213 dumpTemplateSpecializationKind(D->getTemplateSpecializationKind()); 2214 2215 StorageClass SC = D->getStorageClass(); 2216 if (SC != SC_None) 2217 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 2218 if (D->isInlineSpecified()) 2219 OS << " inline"; 2220 if (D->isVirtualAsWritten()) 2221 OS << " virtual"; 2222 if (D->isModulePrivate()) 2223 OS << " __module_private__"; 2224 2225 if (D->isPureVirtual()) 2226 OS << " pure"; 2227 if (D->isDefaulted()) { 2228 OS << " default"; 2229 if (D->isDeleted()) 2230 OS << "_delete"; 2231 } 2232 if (D->isDeletedAsWritten()) 2233 OS << " delete"; 2234 if (D->isTrivial()) 2235 OS << " trivial"; 2236 2237 if (const StringLiteral *M = D->getDeletedMessage()) 2238 AddChild("delete message", [=] { Visit(M); }); 2239 2240 if (D->isIneligibleOrNotSelected()) 2241 OS << (isa<CXXDestructorDecl>(D) ? " not_selected" : " ineligible"); 2242 2243 if (const auto *FPT = D->getType()->getAs<FunctionProtoType>()) { 2244 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 2245 switch (EPI.ExceptionSpec.Type) { 2246 default: 2247 break; 2248 case EST_Unevaluated: 2249 OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl; 2250 break; 2251 case EST_Uninstantiated: 2252 OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate; 2253 break; 2254 } 2255 } 2256 2257 if (const auto *MD = dyn_cast<CXXMethodDecl>(D)) { 2258 if (MD->size_overridden_methods() != 0) { 2259 auto dumpOverride = [=](const CXXMethodDecl *D) { 2260 SplitQualType T_split = D->getType().split(); 2261 OS << D << " " << D->getParent()->getName() << "::" << D->getDeclName() 2262 << " '" << QualType::getAsString(T_split, PrintPolicy) << "'"; 2263 }; 2264 2265 AddChild([=] { 2266 auto Overrides = MD->overridden_methods(); 2267 OS << "Overrides: [ "; 2268 dumpOverride(*Overrides.begin()); 2269 for (const auto *Override : llvm::drop_begin(Overrides)) { 2270 OS << ", "; 2271 dumpOverride(Override); 2272 } 2273 OS << " ]"; 2274 }); 2275 } 2276 } 2277 2278 if (!D->isInlineSpecified() && D->isInlined()) { 2279 OS << " implicit-inline"; 2280 } 2281 // Since NumParams comes from the FunctionProtoType of the FunctionDecl and 2282 // the Params are set later, it is possible for a dump during debugging to 2283 // encounter a FunctionDecl that has been created but hasn't been assigned 2284 // ParmVarDecls yet. 2285 if (!D->param_empty() && !D->param_begin()) 2286 OS << " <<<NULL params x " << D->getNumParams() << ">>>"; 2287 2288 if (const auto *Instance = D->getInstantiatedFromMemberFunction()) { 2289 OS << " instantiated_from"; 2290 dumpPointer(Instance); 2291 } 2292 } 2293 2294 void TextNodeDumper::VisitCXXDeductionGuideDecl( 2295 const CXXDeductionGuideDecl *D) { 2296 VisitFunctionDecl(D); 2297 switch (D->getDeductionCandidateKind()) { 2298 case DeductionCandidate::Normal: 2299 case DeductionCandidate::Copy: 2300 return; 2301 case DeductionCandidate::Aggregate: 2302 OS << " aggregate "; 2303 break; 2304 } 2305 } 2306 2307 void TextNodeDumper::VisitLifetimeExtendedTemporaryDecl( 2308 const LifetimeExtendedTemporaryDecl *D) { 2309 OS << " extended by "; 2310 dumpBareDeclRef(D->getExtendingDecl()); 2311 OS << " mangling "; 2312 { 2313 ColorScope Color(OS, ShowColors, ValueColor); 2314 OS << D->getManglingNumber(); 2315 } 2316 } 2317 2318 void TextNodeDumper::VisitFieldDecl(const FieldDecl *D) { 2319 dumpName(D); 2320 dumpType(D->getType()); 2321 if (D->isMutable()) 2322 OS << " mutable"; 2323 if (D->isModulePrivate()) 2324 OS << " __module_private__"; 2325 } 2326 2327 void TextNodeDumper::VisitVarDecl(const VarDecl *D) { 2328 dumpNestedNameSpecifier(D->getQualifier()); 2329 dumpName(D); 2330 if (const auto *P = dyn_cast<ParmVarDecl>(D); 2331 P && P->isExplicitObjectParameter()) 2332 OS << " this"; 2333 2334 dumpType(D->getType()); 2335 dumpTemplateSpecializationKind(D->getTemplateSpecializationKind()); 2336 StorageClass SC = D->getStorageClass(); 2337 if (SC != SC_None) 2338 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 2339 switch (D->getTLSKind()) { 2340 case VarDecl::TLS_None: 2341 break; 2342 case VarDecl::TLS_Static: 2343 OS << " tls"; 2344 break; 2345 case VarDecl::TLS_Dynamic: 2346 OS << " tls_dynamic"; 2347 break; 2348 } 2349 if (D->isModulePrivate()) 2350 OS << " __module_private__"; 2351 if (D->isNRVOVariable()) 2352 OS << " nrvo"; 2353 if (D->isInline()) 2354 OS << " inline"; 2355 if (D->isConstexpr()) 2356 OS << " constexpr"; 2357 if (D->hasInit()) { 2358 switch (D->getInitStyle()) { 2359 case VarDecl::CInit: 2360 OS << " cinit"; 2361 break; 2362 case VarDecl::CallInit: 2363 OS << " callinit"; 2364 break; 2365 case VarDecl::ListInit: 2366 OS << " listinit"; 2367 break; 2368 case VarDecl::ParenListInit: 2369 OS << " parenlistinit"; 2370 } 2371 } 2372 if (D->needsDestruction(D->getASTContext())) 2373 OS << " destroyed"; 2374 if (D->isParameterPack()) 2375 OS << " pack"; 2376 2377 if (D->hasInit()) { 2378 const Expr *E = D->getInit(); 2379 // Only dump the value of constexpr VarDecls for now. 2380 if (E && !E->isValueDependent() && D->isConstexpr() && 2381 !D->getType()->isDependentType()) { 2382 const APValue *Value = D->evaluateValue(); 2383 if (Value) 2384 AddChild("value", [=] { Visit(*Value, E->getType()); }); 2385 } 2386 } 2387 } 2388 2389 void TextNodeDumper::VisitBindingDecl(const BindingDecl *D) { 2390 dumpName(D); 2391 dumpType(D->getType()); 2392 } 2393 2394 void TextNodeDumper::VisitCapturedDecl(const CapturedDecl *D) { 2395 if (D->isNothrow()) 2396 OS << " nothrow"; 2397 } 2398 2399 void TextNodeDumper::VisitImportDecl(const ImportDecl *D) { 2400 OS << ' ' << D->getImportedModule()->getFullModuleName(); 2401 2402 for (Decl *InitD : 2403 D->getASTContext().getModuleInitializers(D->getImportedModule())) 2404 dumpDeclRef(InitD, "initializer"); 2405 } 2406 2407 void TextNodeDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) { 2408 OS << ' '; 2409 switch (D->getCommentKind()) { 2410 case PCK_Unknown: 2411 llvm_unreachable("unexpected pragma comment kind"); 2412 case PCK_Compiler: 2413 OS << "compiler"; 2414 break; 2415 case PCK_ExeStr: 2416 OS << "exestr"; 2417 break; 2418 case PCK_Lib: 2419 OS << "lib"; 2420 break; 2421 case PCK_Linker: 2422 OS << "linker"; 2423 break; 2424 case PCK_User: 2425 OS << "user"; 2426 break; 2427 } 2428 StringRef Arg = D->getArg(); 2429 if (!Arg.empty()) 2430 OS << " \"" << Arg << "\""; 2431 } 2432 2433 void TextNodeDumper::VisitPragmaDetectMismatchDecl( 2434 const PragmaDetectMismatchDecl *D) { 2435 OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\""; 2436 } 2437 2438 void TextNodeDumper::VisitOMPExecutableDirective( 2439 const OMPExecutableDirective *D) { 2440 if (D->isStandaloneDirective()) 2441 OS << " openmp_standalone_directive"; 2442 } 2443 2444 void TextNodeDumper::VisitOMPDeclareReductionDecl( 2445 const OMPDeclareReductionDecl *D) { 2446 dumpName(D); 2447 dumpType(D->getType()); 2448 OS << " combiner"; 2449 dumpPointer(D->getCombiner()); 2450 if (const auto *Initializer = D->getInitializer()) { 2451 OS << " initializer"; 2452 dumpPointer(Initializer); 2453 switch (D->getInitializerKind()) { 2454 case OMPDeclareReductionInitKind::Direct: 2455 OS << " omp_priv = "; 2456 break; 2457 case OMPDeclareReductionInitKind::Copy: 2458 OS << " omp_priv ()"; 2459 break; 2460 case OMPDeclareReductionInitKind::Call: 2461 break; 2462 } 2463 } 2464 } 2465 2466 void TextNodeDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) { 2467 for (const auto *C : D->clauselists()) { 2468 AddChild([=] { 2469 if (!C) { 2470 ColorScope Color(OS, ShowColors, NullColor); 2471 OS << "<<<NULL>>> OMPClause"; 2472 return; 2473 } 2474 { 2475 ColorScope Color(OS, ShowColors, AttrColor); 2476 StringRef ClauseName( 2477 llvm::omp::getOpenMPClauseName(C->getClauseKind())); 2478 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() 2479 << ClauseName.drop_front() << "Clause"; 2480 } 2481 dumpPointer(C); 2482 dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); 2483 }); 2484 } 2485 } 2486 2487 void TextNodeDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) { 2488 dumpName(D); 2489 dumpType(D->getType()); 2490 } 2491 2492 void TextNodeDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 2493 dumpName(D); 2494 if (D->isInline()) 2495 OS << " inline"; 2496 if (D->isNested()) 2497 OS << " nested"; 2498 if (!D->isFirstDecl()) 2499 dumpDeclRef(D->getFirstDecl(), "original"); 2500 } 2501 2502 void TextNodeDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 2503 OS << ' '; 2504 dumpBareDeclRef(D->getNominatedNamespace()); 2505 } 2506 2507 void TextNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 2508 dumpName(D); 2509 dumpDeclRef(D->getAliasedNamespace()); 2510 } 2511 2512 void TextNodeDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 2513 dumpName(D); 2514 dumpType(D->getUnderlyingType()); 2515 } 2516 2517 void TextNodeDumper::VisitTypeAliasTemplateDecl( 2518 const TypeAliasTemplateDecl *D) { 2519 dumpName(D); 2520 } 2521 2522 void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 2523 VisitRecordDecl(D); 2524 if (const auto *Instance = D->getInstantiatedFromMemberClass()) { 2525 OS << " instantiated_from"; 2526 dumpPointer(Instance); 2527 } 2528 if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) 2529 dumpTemplateSpecializationKind(CTSD->getSpecializationKind()); 2530 2531 dumpNestedNameSpecifier(D->getQualifier()); 2532 2533 if (!D->isCompleteDefinition()) 2534 return; 2535 2536 AddChild([=] { 2537 { 2538 ColorScope Color(OS, ShowColors, DeclKindNameColor); 2539 OS << "DefinitionData"; 2540 } 2541 #define FLAG(fn, name) \ 2542 if (D->fn()) \ 2543 OS << " " #name; 2544 FLAG(isParsingBaseSpecifiers, parsing_base_specifiers); 2545 2546 FLAG(isGenericLambda, generic); 2547 FLAG(isLambda, lambda); 2548 2549 FLAG(isAnonymousStructOrUnion, is_anonymous); 2550 FLAG(canPassInRegisters, pass_in_registers); 2551 FLAG(isEmpty, empty); 2552 FLAG(isAggregate, aggregate); 2553 FLAG(isStandardLayout, standard_layout); 2554 FLAG(isTriviallyCopyable, trivially_copyable); 2555 FLAG(isPOD, pod); 2556 FLAG(isTrivial, trivial); 2557 FLAG(isPolymorphic, polymorphic); 2558 FLAG(isAbstract, abstract); 2559 FLAG(isLiteral, literal); 2560 2561 FLAG(hasUserDeclaredConstructor, has_user_declared_ctor); 2562 FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor); 2563 FLAG(hasMutableFields, has_mutable_fields); 2564 FLAG(hasVariantMembers, has_variant_members); 2565 FLAG(allowConstDefaultInit, can_const_default_init); 2566 2567 AddChild([=] { 2568 { 2569 ColorScope Color(OS, ShowColors, DeclKindNameColor); 2570 OS << "DefaultConstructor"; 2571 } 2572 FLAG(hasDefaultConstructor, exists); 2573 FLAG(hasTrivialDefaultConstructor, trivial); 2574 FLAG(hasNonTrivialDefaultConstructor, non_trivial); 2575 FLAG(hasUserProvidedDefaultConstructor, user_provided); 2576 FLAG(hasConstexprDefaultConstructor, constexpr); 2577 FLAG(needsImplicitDefaultConstructor, needs_implicit); 2578 FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr); 2579 }); 2580 2581 AddChild([=] { 2582 { 2583 ColorScope Color(OS, ShowColors, DeclKindNameColor); 2584 OS << "CopyConstructor"; 2585 } 2586 FLAG(hasSimpleCopyConstructor, simple); 2587 FLAG(hasTrivialCopyConstructor, trivial); 2588 FLAG(hasNonTrivialCopyConstructor, non_trivial); 2589 FLAG(hasUserDeclaredCopyConstructor, user_declared); 2590 FLAG(hasCopyConstructorWithConstParam, has_const_param); 2591 FLAG(needsImplicitCopyConstructor, needs_implicit); 2592 FLAG(needsOverloadResolutionForCopyConstructor, 2593 needs_overload_resolution); 2594 if (!D->needsOverloadResolutionForCopyConstructor()) 2595 FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted); 2596 FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param); 2597 }); 2598 2599 AddChild([=] { 2600 { 2601 ColorScope Color(OS, ShowColors, DeclKindNameColor); 2602 OS << "MoveConstructor"; 2603 } 2604 FLAG(hasMoveConstructor, exists); 2605 FLAG(hasSimpleMoveConstructor, simple); 2606 FLAG(hasTrivialMoveConstructor, trivial); 2607 FLAG(hasNonTrivialMoveConstructor, non_trivial); 2608 FLAG(hasUserDeclaredMoveConstructor, user_declared); 2609 FLAG(needsImplicitMoveConstructor, needs_implicit); 2610 FLAG(needsOverloadResolutionForMoveConstructor, 2611 needs_overload_resolution); 2612 if (!D->needsOverloadResolutionForMoveConstructor()) 2613 FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted); 2614 }); 2615 2616 AddChild([=] { 2617 { 2618 ColorScope Color(OS, ShowColors, DeclKindNameColor); 2619 OS << "CopyAssignment"; 2620 } 2621 FLAG(hasSimpleCopyAssignment, simple); 2622 FLAG(hasTrivialCopyAssignment, trivial); 2623 FLAG(hasNonTrivialCopyAssignment, non_trivial); 2624 FLAG(hasCopyAssignmentWithConstParam, has_const_param); 2625 FLAG(hasUserDeclaredCopyAssignment, user_declared); 2626 FLAG(needsImplicitCopyAssignment, needs_implicit); 2627 FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution); 2628 FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param); 2629 }); 2630 2631 AddChild([=] { 2632 { 2633 ColorScope Color(OS, ShowColors, DeclKindNameColor); 2634 OS << "MoveAssignment"; 2635 } 2636 FLAG(hasMoveAssignment, exists); 2637 FLAG(hasSimpleMoveAssignment, simple); 2638 FLAG(hasTrivialMoveAssignment, trivial); 2639 FLAG(hasNonTrivialMoveAssignment, non_trivial); 2640 FLAG(hasUserDeclaredMoveAssignment, user_declared); 2641 FLAG(needsImplicitMoveAssignment, needs_implicit); 2642 FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution); 2643 }); 2644 2645 AddChild([=] { 2646 { 2647 ColorScope Color(OS, ShowColors, DeclKindNameColor); 2648 OS << "Destructor"; 2649 } 2650 FLAG(hasSimpleDestructor, simple); 2651 FLAG(hasIrrelevantDestructor, irrelevant); 2652 FLAG(hasTrivialDestructor, trivial); 2653 FLAG(hasNonTrivialDestructor, non_trivial); 2654 FLAG(hasUserDeclaredDestructor, user_declared); 2655 FLAG(hasConstexprDestructor, constexpr); 2656 FLAG(needsImplicitDestructor, needs_implicit); 2657 FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution); 2658 if (!D->needsOverloadResolutionForDestructor()) 2659 FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted); 2660 }); 2661 }); 2662 2663 for (const auto &I : D->bases()) { 2664 AddChild([=] { 2665 if (I.isVirtual()) 2666 OS << "virtual "; 2667 dumpAccessSpecifier(I.getAccessSpecifier()); 2668 dumpType(I.getType()); 2669 if (I.isPackExpansion()) 2670 OS << "..."; 2671 }); 2672 } 2673 } 2674 2675 void TextNodeDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 2676 dumpName(D); 2677 } 2678 2679 void TextNodeDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 2680 dumpName(D); 2681 } 2682 2683 void TextNodeDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { 2684 dumpName(D); 2685 } 2686 2687 void TextNodeDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { 2688 dumpName(D); 2689 } 2690 2691 void TextNodeDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 2692 if (const auto *TC = D->getTypeConstraint()) { 2693 OS << " "; 2694 dumpBareDeclRef(TC->getNamedConcept()); 2695 if (TC->getNamedConcept() != TC->getFoundDecl()) { 2696 OS << " ("; 2697 dumpBareDeclRef(TC->getFoundDecl()); 2698 OS << ")"; 2699 } 2700 } else if (D->wasDeclaredWithTypename()) 2701 OS << " typename"; 2702 else 2703 OS << " class"; 2704 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 2705 if (D->isParameterPack()) 2706 OS << " ..."; 2707 dumpName(D); 2708 } 2709 2710 void TextNodeDumper::VisitNonTypeTemplateParmDecl( 2711 const NonTypeTemplateParmDecl *D) { 2712 dumpType(D->getType()); 2713 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 2714 if (D->isParameterPack()) 2715 OS << " ..."; 2716 dumpName(D); 2717 } 2718 2719 void TextNodeDumper::VisitTemplateTemplateParmDecl( 2720 const TemplateTemplateParmDecl *D) { 2721 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 2722 if (D->isParameterPack()) 2723 OS << " ..."; 2724 dumpName(D); 2725 } 2726 2727 void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) { 2728 OS << ' '; 2729 if (D->getQualifier()) 2730 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 2731 OS << D->getDeclName(); 2732 dumpNestedNameSpecifier(D->getQualifier()); 2733 } 2734 2735 void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) { 2736 OS << ' '; 2737 dumpBareDeclRef(D->getEnumDecl()); 2738 } 2739 2740 void TextNodeDumper::VisitUnresolvedUsingTypenameDecl( 2741 const UnresolvedUsingTypenameDecl *D) { 2742 OS << ' '; 2743 if (D->getQualifier()) 2744 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 2745 OS << D->getDeclName(); 2746 } 2747 2748 void TextNodeDumper::VisitUnresolvedUsingValueDecl( 2749 const UnresolvedUsingValueDecl *D) { 2750 OS << ' '; 2751 if (D->getQualifier()) 2752 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 2753 OS << D->getDeclName(); 2754 dumpType(D->getType()); 2755 } 2756 2757 void TextNodeDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 2758 OS << ' '; 2759 dumpBareDeclRef(D->getTargetDecl()); 2760 } 2761 2762 void TextNodeDumper::VisitConstructorUsingShadowDecl( 2763 const ConstructorUsingShadowDecl *D) { 2764 if (D->constructsVirtualBase()) 2765 OS << " virtual"; 2766 2767 AddChild([=] { 2768 OS << "target "; 2769 dumpBareDeclRef(D->getTargetDecl()); 2770 }); 2771 2772 AddChild([=] { 2773 OS << "nominated "; 2774 dumpBareDeclRef(D->getNominatedBaseClass()); 2775 OS << ' '; 2776 dumpBareDeclRef(D->getNominatedBaseClassShadowDecl()); 2777 }); 2778 2779 AddChild([=] { 2780 OS << "constructed "; 2781 dumpBareDeclRef(D->getConstructedBaseClass()); 2782 OS << ' '; 2783 dumpBareDeclRef(D->getConstructedBaseClassShadowDecl()); 2784 }); 2785 } 2786 2787 void TextNodeDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 2788 switch (D->getLanguage()) { 2789 case LinkageSpecLanguageIDs::C: 2790 OS << " C"; 2791 break; 2792 case LinkageSpecLanguageIDs::CXX: 2793 OS << " C++"; 2794 break; 2795 } 2796 } 2797 2798 void TextNodeDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 2799 OS << ' '; 2800 dumpAccessSpecifier(D->getAccess()); 2801 } 2802 2803 void TextNodeDumper::VisitFriendDecl(const FriendDecl *D) { 2804 if (TypeSourceInfo *T = D->getFriendType()) 2805 dumpType(T->getType()); 2806 if (D->isPackExpansion()) 2807 OS << "..."; 2808 } 2809 2810 void TextNodeDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 2811 dumpName(D); 2812 dumpType(D->getType()); 2813 if (D->getSynthesize()) 2814 OS << " synthesize"; 2815 2816 switch (D->getAccessControl()) { 2817 case ObjCIvarDecl::None: 2818 OS << " none"; 2819 break; 2820 case ObjCIvarDecl::Private: 2821 OS << " private"; 2822 break; 2823 case ObjCIvarDecl::Protected: 2824 OS << " protected"; 2825 break; 2826 case ObjCIvarDecl::Public: 2827 OS << " public"; 2828 break; 2829 case ObjCIvarDecl::Package: 2830 OS << " package"; 2831 break; 2832 } 2833 } 2834 2835 void TextNodeDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 2836 if (D->isInstanceMethod()) 2837 OS << " -"; 2838 else 2839 OS << " +"; 2840 dumpName(D); 2841 dumpType(D->getReturnType()); 2842 2843 if (D->isVariadic()) 2844 OS << " variadic"; 2845 } 2846 2847 void TextNodeDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) { 2848 dumpName(D); 2849 switch (D->getVariance()) { 2850 case ObjCTypeParamVariance::Invariant: 2851 break; 2852 2853 case ObjCTypeParamVariance::Covariant: 2854 OS << " covariant"; 2855 break; 2856 2857 case ObjCTypeParamVariance::Contravariant: 2858 OS << " contravariant"; 2859 break; 2860 } 2861 2862 if (D->hasExplicitBound()) 2863 OS << " bounded"; 2864 dumpType(D->getUnderlyingType()); 2865 } 2866 2867 void TextNodeDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 2868 dumpName(D); 2869 dumpDeclRef(D->getClassInterface()); 2870 dumpDeclRef(D->getImplementation()); 2871 for (const auto *P : D->protocols()) 2872 dumpDeclRef(P); 2873 } 2874 2875 void TextNodeDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 2876 dumpName(D); 2877 dumpDeclRef(D->getClassInterface()); 2878 dumpDeclRef(D->getCategoryDecl()); 2879 } 2880 2881 void TextNodeDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 2882 dumpName(D); 2883 2884 for (const auto *Child : D->protocols()) 2885 dumpDeclRef(Child); 2886 } 2887 2888 void TextNodeDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 2889 dumpName(D); 2890 dumpDeclRef(D->getSuperClass(), "super"); 2891 2892 dumpDeclRef(D->getImplementation()); 2893 for (const auto *Child : D->protocols()) 2894 dumpDeclRef(Child); 2895 } 2896 2897 void TextNodeDumper::VisitObjCImplementationDecl( 2898 const ObjCImplementationDecl *D) { 2899 dumpName(D); 2900 dumpDeclRef(D->getSuperClass(), "super"); 2901 dumpDeclRef(D->getClassInterface()); 2902 } 2903 2904 void TextNodeDumper::VisitObjCCompatibleAliasDecl( 2905 const ObjCCompatibleAliasDecl *D) { 2906 dumpName(D); 2907 dumpDeclRef(D->getClassInterface()); 2908 } 2909 2910 void TextNodeDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 2911 dumpName(D); 2912 dumpType(D->getType()); 2913 2914 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 2915 OS << " required"; 2916 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 2917 OS << " optional"; 2918 2919 ObjCPropertyAttribute::Kind Attrs = D->getPropertyAttributes(); 2920 if (Attrs != ObjCPropertyAttribute::kind_noattr) { 2921 if (Attrs & ObjCPropertyAttribute::kind_readonly) 2922 OS << " readonly"; 2923 if (Attrs & ObjCPropertyAttribute::kind_assign) 2924 OS << " assign"; 2925 if (Attrs & ObjCPropertyAttribute::kind_readwrite) 2926 OS << " readwrite"; 2927 if (Attrs & ObjCPropertyAttribute::kind_retain) 2928 OS << " retain"; 2929 if (Attrs & ObjCPropertyAttribute::kind_copy) 2930 OS << " copy"; 2931 if (Attrs & ObjCPropertyAttribute::kind_nonatomic) 2932 OS << " nonatomic"; 2933 if (Attrs & ObjCPropertyAttribute::kind_atomic) 2934 OS << " atomic"; 2935 if (Attrs & ObjCPropertyAttribute::kind_weak) 2936 OS << " weak"; 2937 if (Attrs & ObjCPropertyAttribute::kind_strong) 2938 OS << " strong"; 2939 if (Attrs & ObjCPropertyAttribute::kind_unsafe_unretained) 2940 OS << " unsafe_unretained"; 2941 if (Attrs & ObjCPropertyAttribute::kind_class) 2942 OS << " class"; 2943 if (Attrs & ObjCPropertyAttribute::kind_direct) 2944 OS << " direct"; 2945 if (Attrs & ObjCPropertyAttribute::kind_getter) 2946 dumpDeclRef(D->getGetterMethodDecl(), "getter"); 2947 if (Attrs & ObjCPropertyAttribute::kind_setter) 2948 dumpDeclRef(D->getSetterMethodDecl(), "setter"); 2949 } 2950 } 2951 2952 void TextNodeDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 2953 dumpName(D->getPropertyDecl()); 2954 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 2955 OS << " synthesize"; 2956 else 2957 OS << " dynamic"; 2958 dumpDeclRef(D->getPropertyDecl()); 2959 dumpDeclRef(D->getPropertyIvarDecl()); 2960 } 2961 2962 void TextNodeDumper::VisitBlockDecl(const BlockDecl *D) { 2963 if (D->isVariadic()) 2964 OS << " variadic"; 2965 2966 if (D->capturesCXXThis()) 2967 OS << " captures_this"; 2968 } 2969 2970 void TextNodeDumper::VisitConceptDecl(const ConceptDecl *D) { 2971 dumpName(D); 2972 } 2973 2974 void TextNodeDumper::VisitCompoundStmt(const CompoundStmt *S) { 2975 VisitStmt(S); 2976 if (S->hasStoredFPFeatures()) 2977 printFPOptions(S->getStoredFPFeatures()); 2978 } 2979 2980 void TextNodeDumper::VisitHLSLBufferDecl(const HLSLBufferDecl *D) { 2981 if (D->isCBuffer()) 2982 OS << " cbuffer"; 2983 else 2984 OS << " tbuffer"; 2985 dumpName(D); 2986 } 2987 2988 void TextNodeDumper::VisitHLSLOutArgExpr(const HLSLOutArgExpr *E) { 2989 OS << (E->isInOut() ? " inout" : " out"); 2990 } 2991 2992 void TextNodeDumper::VisitOpenACCConstructStmt(const OpenACCConstructStmt *S) { 2993 OS << " " << S->getDirectiveKind(); 2994 } 2995 void TextNodeDumper::VisitOpenACCLoopConstruct(const OpenACCLoopConstruct *S) { 2996 if (S->isOrphanedLoopConstruct()) 2997 OS << " <orphan>"; 2998 else 2999 OS << " parent: " << S->getParentComputeConstructKind(); 3000 } 3001 3002 void TextNodeDumper::VisitOpenACCCombinedConstruct( 3003 const OpenACCCombinedConstruct *S) { 3004 VisitOpenACCConstructStmt(S); 3005 } 3006 3007 void TextNodeDumper::VisitOpenACCDataConstruct(const OpenACCDataConstruct *S) { 3008 VisitOpenACCConstructStmt(S); 3009 } 3010 3011 void TextNodeDumper::VisitOpenACCEnterDataConstruct( 3012 const OpenACCEnterDataConstruct *S) { 3013 VisitOpenACCConstructStmt(S); 3014 } 3015 3016 void TextNodeDumper::VisitOpenACCExitDataConstruct( 3017 const OpenACCExitDataConstruct *S) { 3018 VisitOpenACCConstructStmt(S); 3019 } 3020 3021 void TextNodeDumper::VisitOpenACCHostDataConstruct( 3022 const OpenACCHostDataConstruct *S) { 3023 VisitOpenACCConstructStmt(S); 3024 } 3025 3026 void TextNodeDumper::VisitOpenACCWaitConstruct(const OpenACCWaitConstruct *S) { 3027 VisitOpenACCConstructStmt(S); 3028 } 3029 void TextNodeDumper::VisitOpenACCInitConstruct(const OpenACCInitConstruct *S) { 3030 VisitOpenACCConstructStmt(S); 3031 } 3032 void TextNodeDumper::VisitOpenACCShutdownConstruct( 3033 const OpenACCShutdownConstruct *S) { 3034 VisitOpenACCConstructStmt(S); 3035 } 3036 void TextNodeDumper::VisitOpenACCSetConstruct(const OpenACCSetConstruct *S) { 3037 VisitOpenACCConstructStmt(S); 3038 } 3039 void TextNodeDumper::VisitOpenACCUpdateConstruct( 3040 const OpenACCUpdateConstruct *S) { 3041 VisitOpenACCConstructStmt(S); 3042 } 3043 3044 void TextNodeDumper::VisitEmbedExpr(const EmbedExpr *S) { 3045 AddChild("begin", [=] { OS << S->getStartingElementPos(); }); 3046 AddChild("number of elements", [=] { OS << S->getDataElementCount(); }); 3047 } 3048 3049 void TextNodeDumper::VisitAtomicExpr(const AtomicExpr *AE) { 3050 OS << ' ' << AE->getOpAsString(); 3051 } 3052