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