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