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