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