1 //===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===// 2 // 3 // The LLVM Compiler Infrastructure 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file implements the AST dump methods, which dump out the 11 // AST in a form that exposes type details and other fields. 12 // 13 //===----------------------------------------------------------------------===// 14 15 #include "clang/AST/ASTContext.h" 16 #include "clang/AST/ASTDumperUtils.h" 17 #include "clang/AST/Attr.h" 18 #include "clang/AST/AttrVisitor.h" 19 #include "clang/AST/CommentVisitor.h" 20 #include "clang/AST/DeclCXX.h" 21 #include "clang/AST/DeclLookups.h" 22 #include "clang/AST/DeclObjC.h" 23 #include "clang/AST/DeclOpenMP.h" 24 #include "clang/AST/DeclVisitor.h" 25 #include "clang/AST/LocInfoType.h" 26 #include "clang/AST/StmtVisitor.h" 27 #include "clang/AST/TemplateArgumentVisitor.h" 28 #include "clang/AST/TextNodeDumper.h" 29 #include "clang/AST/TypeVisitor.h" 30 #include "clang/Basic/Builtins.h" 31 #include "clang/Basic/Module.h" 32 #include "clang/Basic/SourceManager.h" 33 #include "llvm/Support/raw_ostream.h" 34 using namespace clang; 35 using namespace clang::comments; 36 37 //===----------------------------------------------------------------------===// 38 // ASTDumper Visitor 39 //===----------------------------------------------------------------------===// 40 41 namespace { 42 43 class ASTDumper 44 : public ConstDeclVisitor<ASTDumper>, 45 public ConstStmtVisitor<ASTDumper>, 46 public ConstCommentVisitor<ASTDumper, void, const FullComment *>, 47 public TypeVisitor<ASTDumper>, 48 public ConstAttrVisitor<ASTDumper>, 49 public ConstTemplateArgumentVisitor<ASTDumper> { 50 51 TextNodeDumper NodeDumper; 52 53 raw_ostream &OS; 54 55 /// The policy to use for printing; can be defaulted. 56 PrintingPolicy PrintPolicy; 57 58 /// Indicates whether we should trigger deserialization of nodes that had 59 /// not already been loaded. 60 bool Deserialize = false; 61 62 const bool ShowColors; 63 64 /// Dump a child of the current node. 65 template<typename Fn> void dumpChild(Fn DoDumpChild) { 66 NodeDumper.AddChild(DoDumpChild); 67 } 68 template <typename Fn> void dumpChild(StringRef Label, Fn DoDumpChild) { 69 NodeDumper.AddChild(Label, DoDumpChild); 70 } 71 72 public: 73 ASTDumper(raw_ostream &OS, const CommandTraits *Traits, 74 const SourceManager *SM) 75 : ASTDumper(OS, Traits, SM, 76 SM && SM->getDiagnostics().getShowColors()) {} 77 78 ASTDumper(raw_ostream &OS, const CommandTraits *Traits, 79 const SourceManager *SM, bool ShowColors) 80 : ASTDumper(OS, Traits, SM, ShowColors, LangOptions()) {} 81 ASTDumper(raw_ostream &OS, const CommandTraits *Traits, 82 const SourceManager *SM, bool ShowColors, 83 const PrintingPolicy &PrintPolicy) 84 : NodeDumper(OS, ShowColors, SM, PrintPolicy, Traits), OS(OS), 85 PrintPolicy(PrintPolicy), ShowColors(ShowColors) {} 86 87 void setDeserialize(bool D) { Deserialize = D; } 88 89 void dumpDecl(const Decl *D); 90 void dumpStmt(const Stmt *S, StringRef Label = {}); 91 92 // Utilities 93 void dumpTypeAsChild(QualType T); 94 void dumpTypeAsChild(const Type *T); 95 void dumpDeclContext(const DeclContext *DC); 96 void dumpLookups(const DeclContext *DC, bool DumpDecls); 97 void dumpAttr(const Attr *A); 98 99 // C++ Utilities 100 void dumpCXXCtorInitializer(const CXXCtorInitializer *Init); 101 void dumpTemplateParameters(const TemplateParameterList *TPL); 102 void dumpTemplateArgumentListInfo(const TemplateArgumentListInfo &TALI); 103 void dumpTemplateArgumentLoc(const TemplateArgumentLoc &A, 104 const Decl *From = nullptr, 105 const char *Label = nullptr); 106 void dumpTemplateArgumentList(const TemplateArgumentList &TAL); 107 void dumpTemplateArgument(const TemplateArgument &A, 108 SourceRange R = SourceRange(), 109 const Decl *From = nullptr, 110 const char *Label = nullptr); 111 template <typename SpecializationDecl> 112 void dumpTemplateDeclSpecialization(const SpecializationDecl *D, 113 bool DumpExplicitInst, 114 bool DumpRefOnly); 115 template <typename TemplateDecl> 116 void dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst); 117 118 // Objective-C utilities. 119 void dumpObjCTypeParamList(const ObjCTypeParamList *typeParams); 120 121 // Types 122 void VisitComplexType(const ComplexType *T) { 123 dumpTypeAsChild(T->getElementType()); 124 } 125 void VisitLocInfoType(const LocInfoType *T) { 126 dumpTypeAsChild(T->getTypeSourceInfo()->getType()); 127 } 128 void VisitPointerType(const PointerType *T) { 129 dumpTypeAsChild(T->getPointeeType()); 130 } 131 void VisitBlockPointerType(const BlockPointerType *T) { 132 dumpTypeAsChild(T->getPointeeType()); 133 } 134 void VisitReferenceType(const ReferenceType *T) { 135 dumpTypeAsChild(T->getPointeeType()); 136 } 137 void VisitMemberPointerType(const MemberPointerType *T) { 138 dumpTypeAsChild(T->getClass()); 139 dumpTypeAsChild(T->getPointeeType()); 140 } 141 void VisitArrayType(const ArrayType *T) { 142 dumpTypeAsChild(T->getElementType()); 143 } 144 void VisitVariableArrayType(const VariableArrayType *T) { 145 VisitArrayType(T); 146 dumpStmt(T->getSizeExpr()); 147 } 148 void VisitDependentSizedArrayType(const DependentSizedArrayType *T) { 149 dumpTypeAsChild(T->getElementType()); 150 dumpStmt(T->getSizeExpr()); 151 } 152 void VisitDependentSizedExtVectorType( 153 const DependentSizedExtVectorType *T) { 154 dumpTypeAsChild(T->getElementType()); 155 dumpStmt(T->getSizeExpr()); 156 } 157 void VisitVectorType(const VectorType *T) { 158 dumpTypeAsChild(T->getElementType()); 159 } 160 void VisitFunctionType(const FunctionType *T) { 161 dumpTypeAsChild(T->getReturnType()); 162 } 163 void VisitFunctionProtoType(const FunctionProtoType *T) { 164 VisitFunctionType(T); 165 for (QualType PT : T->getParamTypes()) 166 dumpTypeAsChild(PT); 167 if (T->getExtProtoInfo().Variadic) 168 dumpChild([=] { OS << "..."; }); 169 } 170 void VisitTypeOfExprType(const TypeOfExprType *T) { 171 dumpStmt(T->getUnderlyingExpr()); 172 } 173 void VisitDecltypeType(const DecltypeType *T) { 174 dumpStmt(T->getUnderlyingExpr()); 175 } 176 void VisitUnaryTransformType(const UnaryTransformType *T) { 177 dumpTypeAsChild(T->getBaseType()); 178 } 179 void VisitAttributedType(const AttributedType *T) { 180 // FIXME: AttrKind 181 dumpTypeAsChild(T->getModifiedType()); 182 } 183 void VisitSubstTemplateTypeParmType(const SubstTemplateTypeParmType *T) { 184 dumpTypeAsChild(T->getReplacedParameter()); 185 } 186 void VisitSubstTemplateTypeParmPackType( 187 const SubstTemplateTypeParmPackType *T) { 188 dumpTypeAsChild(T->getReplacedParameter()); 189 dumpTemplateArgument(T->getArgumentPack()); 190 } 191 void VisitTemplateSpecializationType(const TemplateSpecializationType *T) { 192 for (auto &Arg : *T) 193 dumpTemplateArgument(Arg); 194 if (T->isTypeAlias()) 195 dumpTypeAsChild(T->getAliasedType()); 196 } 197 void VisitObjCObjectPointerType(const ObjCObjectPointerType *T) { 198 dumpTypeAsChild(T->getPointeeType()); 199 } 200 void VisitAtomicType(const AtomicType *T) { 201 dumpTypeAsChild(T->getValueType()); 202 } 203 void VisitPipeType(const PipeType *T) { 204 dumpTypeAsChild(T->getElementType()); 205 } 206 void VisitAdjustedType(const AdjustedType *T) { 207 dumpTypeAsChild(T->getOriginalType()); 208 } 209 void VisitPackExpansionType(const PackExpansionType *T) { 210 if (!T->isSugared()) 211 dumpTypeAsChild(T->getPattern()); 212 } 213 // FIXME: ElaboratedType, DependentNameType, 214 // DependentTemplateSpecializationType, ObjCObjectType 215 216 // Decls 217 void VisitLabelDecl(const LabelDecl *D); 218 void VisitTypedefDecl(const TypedefDecl *D); 219 void VisitEnumDecl(const EnumDecl *D); 220 void VisitRecordDecl(const RecordDecl *D); 221 void VisitEnumConstantDecl(const EnumConstantDecl *D); 222 void VisitIndirectFieldDecl(const IndirectFieldDecl *D); 223 void VisitFunctionDecl(const FunctionDecl *D); 224 void VisitFieldDecl(const FieldDecl *D); 225 void VisitVarDecl(const VarDecl *D); 226 void VisitDecompositionDecl(const DecompositionDecl *D); 227 void VisitBindingDecl(const BindingDecl *D); 228 void VisitFileScopeAsmDecl(const FileScopeAsmDecl *D); 229 void VisitImportDecl(const ImportDecl *D); 230 void VisitPragmaCommentDecl(const PragmaCommentDecl *D); 231 void VisitPragmaDetectMismatchDecl(const PragmaDetectMismatchDecl *D); 232 void VisitCapturedDecl(const CapturedDecl *D); 233 234 // OpenMP decls 235 void VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D); 236 void VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D); 237 void VisitOMPRequiresDecl(const OMPRequiresDecl *D); 238 void VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D); 239 240 // C++ Decls 241 void VisitNamespaceDecl(const NamespaceDecl *D); 242 void VisitUsingDirectiveDecl(const UsingDirectiveDecl *D); 243 void VisitNamespaceAliasDecl(const NamespaceAliasDecl *D); 244 void VisitTypeAliasDecl(const TypeAliasDecl *D); 245 void VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D); 246 void VisitCXXRecordDecl(const CXXRecordDecl *D); 247 void VisitStaticAssertDecl(const StaticAssertDecl *D); 248 void VisitFunctionTemplateDecl(const FunctionTemplateDecl *D); 249 void VisitClassTemplateDecl(const ClassTemplateDecl *D); 250 void VisitClassTemplateSpecializationDecl( 251 const ClassTemplateSpecializationDecl *D); 252 void VisitClassTemplatePartialSpecializationDecl( 253 const ClassTemplatePartialSpecializationDecl *D); 254 void VisitClassScopeFunctionSpecializationDecl( 255 const ClassScopeFunctionSpecializationDecl *D); 256 void VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D); 257 void VisitVarTemplateDecl(const VarTemplateDecl *D); 258 void VisitVarTemplateSpecializationDecl( 259 const VarTemplateSpecializationDecl *D); 260 void VisitVarTemplatePartialSpecializationDecl( 261 const VarTemplatePartialSpecializationDecl *D); 262 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D); 263 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D); 264 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D); 265 void VisitUsingDecl(const UsingDecl *D); 266 void VisitUnresolvedUsingTypenameDecl(const UnresolvedUsingTypenameDecl *D); 267 void VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D); 268 void VisitUsingShadowDecl(const UsingShadowDecl *D); 269 void VisitConstructorUsingShadowDecl(const ConstructorUsingShadowDecl *D); 270 void VisitLinkageSpecDecl(const LinkageSpecDecl *D); 271 void VisitAccessSpecDecl(const AccessSpecDecl *D); 272 void VisitFriendDecl(const FriendDecl *D); 273 274 // ObjC Decls 275 void VisitObjCIvarDecl(const ObjCIvarDecl *D); 276 void VisitObjCMethodDecl(const ObjCMethodDecl *D); 277 void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D); 278 void VisitObjCCategoryDecl(const ObjCCategoryDecl *D); 279 void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D); 280 void VisitObjCProtocolDecl(const ObjCProtocolDecl *D); 281 void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D); 282 void VisitObjCImplementationDecl(const ObjCImplementationDecl *D); 283 void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D); 284 void VisitObjCPropertyDecl(const ObjCPropertyDecl *D); 285 void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D); 286 void VisitBlockDecl(const BlockDecl *D); 287 288 // Stmts. 289 void VisitDeclStmt(const DeclStmt *Node); 290 void VisitAttributedStmt(const AttributedStmt *Node); 291 void VisitCXXCatchStmt(const CXXCatchStmt *Node); 292 void VisitCapturedStmt(const CapturedStmt *Node); 293 294 // OpenMP 295 void VisitOMPExecutableDirective(const OMPExecutableDirective *Node); 296 297 // Exprs 298 void VisitInitListExpr(const InitListExpr *ILE); 299 void VisitBlockExpr(const BlockExpr *Node); 300 void VisitOpaqueValueExpr(const OpaqueValueExpr *Node); 301 void VisitGenericSelectionExpr(const GenericSelectionExpr *E); 302 303 // C++ 304 void VisitLambdaExpr(const LambdaExpr *Node) { 305 dumpDecl(Node->getLambdaClass()); 306 } 307 void VisitSizeOfPackExpr(const SizeOfPackExpr *Node); 308 309 // ObjC 310 void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node); 311 312 // Comments. 313 void dumpComment(const Comment *C, const FullComment *FC); 314 315 void VisitExpressionTemplateArgument(const TemplateArgument &TA) { 316 dumpStmt(TA.getAsExpr()); 317 } 318 void VisitPackTemplateArgument(const TemplateArgument &TA) { 319 for (const auto &TArg : TA.pack_elements()) 320 dumpTemplateArgument(TArg); 321 } 322 323 // Implements Visit methods for Attrs. 324 #include "clang/AST/AttrNodeTraverse.inc" 325 }; 326 } 327 328 //===----------------------------------------------------------------------===// 329 // Utilities 330 //===----------------------------------------------------------------------===// 331 332 void ASTDumper::dumpTypeAsChild(QualType T) { 333 SplitQualType SQT = T.split(); 334 if (!SQT.Quals.hasQualifiers()) 335 return dumpTypeAsChild(SQT.Ty); 336 337 dumpChild([=] { 338 NodeDumper.Visit(T); 339 dumpTypeAsChild(T.split().Ty); 340 }); 341 } 342 343 void ASTDumper::dumpTypeAsChild(const Type *T) { 344 dumpChild([=] { 345 NodeDumper.Visit(T); 346 if (!T) 347 return; 348 TypeVisitor<ASTDumper>::Visit(T); 349 350 QualType SingleStepDesugar = 351 T->getLocallyUnqualifiedSingleStepDesugaredType(); 352 if (SingleStepDesugar != QualType(T, 0)) 353 dumpTypeAsChild(SingleStepDesugar); 354 }); 355 } 356 357 void ASTDumper::dumpDeclContext(const DeclContext *DC) { 358 if (!DC) 359 return; 360 361 for (auto *D : (Deserialize ? DC->decls() : DC->noload_decls())) 362 dumpDecl(D); 363 364 if (DC->hasExternalLexicalStorage()) { 365 dumpChild([=] { 366 ColorScope Color(OS, ShowColors, UndeserializedColor); 367 OS << "<undeserialized declarations>"; 368 }); 369 } 370 } 371 372 void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) { 373 dumpChild([=] { 374 OS << "StoredDeclsMap "; 375 NodeDumper.dumpBareDeclRef(cast<Decl>(DC)); 376 377 const DeclContext *Primary = DC->getPrimaryContext(); 378 if (Primary != DC) { 379 OS << " primary"; 380 NodeDumper.dumpPointer(cast<Decl>(Primary)); 381 } 382 383 bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage(); 384 385 auto Range = Deserialize 386 ? Primary->lookups() 387 : Primary->noload_lookups(/*PreserveInternalState=*/true); 388 for (auto I = Range.begin(), E = Range.end(); I != E; ++I) { 389 DeclarationName Name = I.getLookupName(); 390 DeclContextLookupResult R = *I; 391 392 dumpChild([=] { 393 OS << "DeclarationName "; 394 { 395 ColorScope Color(OS, ShowColors, DeclNameColor); 396 OS << '\'' << Name << '\''; 397 } 398 399 for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end(); 400 RI != RE; ++RI) { 401 dumpChild([=] { 402 NodeDumper.dumpBareDeclRef(*RI); 403 404 if ((*RI)->isHidden()) 405 OS << " hidden"; 406 407 // If requested, dump the redecl chain for this lookup. 408 if (DumpDecls) { 409 // Dump earliest decl first. 410 std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) { 411 if (Decl *Prev = D->getPreviousDecl()) 412 DumpWithPrev(Prev); 413 dumpDecl(D); 414 }; 415 DumpWithPrev(*RI); 416 } 417 }); 418 } 419 }); 420 } 421 422 if (HasUndeserializedLookups) { 423 dumpChild([=] { 424 ColorScope Color(OS, ShowColors, UndeserializedColor); 425 OS << "<undeserialized lookups>"; 426 }); 427 } 428 }); 429 } 430 431 void ASTDumper::dumpAttr(const Attr *A) { 432 dumpChild([=] { 433 NodeDumper.Visit(A); 434 ConstAttrVisitor<ASTDumper>::Visit(A); 435 }); 436 } 437 438 //===----------------------------------------------------------------------===// 439 // C++ Utilities 440 //===----------------------------------------------------------------------===// 441 442 void ASTDumper::dumpCXXCtorInitializer(const CXXCtorInitializer *Init) { 443 dumpChild([=] { 444 OS << "CXXCtorInitializer"; 445 if (Init->isAnyMemberInitializer()) { 446 OS << ' '; 447 NodeDumper.dumpBareDeclRef(Init->getAnyMember()); 448 } else if (Init->isBaseInitializer()) { 449 NodeDumper.dumpType(QualType(Init->getBaseClass(), 0)); 450 } else if (Init->isDelegatingInitializer()) { 451 NodeDumper.dumpType(Init->getTypeSourceInfo()->getType()); 452 } else { 453 llvm_unreachable("Unknown initializer type"); 454 } 455 dumpStmt(Init->getInit()); 456 }); 457 } 458 459 void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) { 460 if (!TPL) 461 return; 462 463 for (TemplateParameterList::const_iterator I = TPL->begin(), E = TPL->end(); 464 I != E; ++I) 465 dumpDecl(*I); 466 } 467 468 void ASTDumper::dumpTemplateArgumentListInfo( 469 const TemplateArgumentListInfo &TALI) { 470 for (unsigned i = 0, e = TALI.size(); i < e; ++i) 471 dumpTemplateArgumentLoc(TALI[i]); 472 } 473 474 void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A, 475 const Decl *From, const char *Label) { 476 dumpTemplateArgument(A.getArgument(), A.getSourceRange(), From, Label); 477 } 478 479 void ASTDumper::dumpTemplateArgumentList(const TemplateArgumentList &TAL) { 480 for (unsigned i = 0, e = TAL.size(); i < e; ++i) 481 dumpTemplateArgument(TAL[i]); 482 } 483 484 void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R, 485 const Decl *From, const char *Label) { 486 dumpChild([=] { 487 NodeDumper.Visit(A, R, From, Label); 488 ConstTemplateArgumentVisitor<ASTDumper>::Visit(A); 489 }); 490 } 491 492 //===----------------------------------------------------------------------===// 493 // Objective-C Utilities 494 //===----------------------------------------------------------------------===// 495 void ASTDumper::dumpObjCTypeParamList(const ObjCTypeParamList *typeParams) { 496 if (!typeParams) 497 return; 498 499 for (auto typeParam : *typeParams) { 500 dumpDecl(typeParam); 501 } 502 } 503 504 //===----------------------------------------------------------------------===// 505 // Decl dumping methods. 506 //===----------------------------------------------------------------------===// 507 508 void ASTDumper::dumpDecl(const Decl *D) { 509 dumpChild([=] { 510 NodeDumper.Visit(D); 511 if (!D) 512 return; 513 514 ConstDeclVisitor<ASTDumper>::Visit(D); 515 516 for (Decl::attr_iterator I = D->attr_begin(), E = D->attr_end(); I != E; 517 ++I) 518 dumpAttr(*I); 519 520 if (const FullComment *Comment = 521 D->getASTContext().getLocalCommentForDeclUncached(D)) 522 dumpComment(Comment, Comment); 523 524 // Decls within functions are visited by the body. 525 if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D)) { 526 auto DC = dyn_cast<DeclContext>(D); 527 if (DC && 528 (DC->hasExternalLexicalStorage() || 529 (Deserialize ? DC->decls_begin() != DC->decls_end() 530 : DC->noload_decls_begin() != DC->noload_decls_end()))) 531 dumpDeclContext(DC); 532 } 533 }); 534 } 535 536 void ASTDumper::VisitLabelDecl(const LabelDecl *D) { NodeDumper.dumpName(D); } 537 538 void ASTDumper::VisitTypedefDecl(const TypedefDecl *D) { 539 NodeDumper.dumpName(D); 540 NodeDumper.dumpType(D->getUnderlyingType()); 541 if (D->isModulePrivate()) 542 OS << " __module_private__"; 543 dumpTypeAsChild(D->getUnderlyingType()); 544 } 545 546 void ASTDumper::VisitEnumDecl(const EnumDecl *D) { 547 if (D->isScoped()) { 548 if (D->isScopedUsingClassTag()) 549 OS << " class"; 550 else 551 OS << " struct"; 552 } 553 NodeDumper.dumpName(D); 554 if (D->isModulePrivate()) 555 OS << " __module_private__"; 556 if (D->isFixed()) 557 NodeDumper.dumpType(D->getIntegerType()); 558 } 559 560 void ASTDumper::VisitRecordDecl(const RecordDecl *D) { 561 OS << ' ' << D->getKindName(); 562 NodeDumper.dumpName(D); 563 if (D->isModulePrivate()) 564 OS << " __module_private__"; 565 if (D->isCompleteDefinition()) 566 OS << " definition"; 567 } 568 569 void ASTDumper::VisitEnumConstantDecl(const EnumConstantDecl *D) { 570 NodeDumper.dumpName(D); 571 NodeDumper.dumpType(D->getType()); 572 if (const Expr *Init = D->getInitExpr()) 573 dumpStmt(Init); 574 } 575 576 void ASTDumper::VisitIndirectFieldDecl(const IndirectFieldDecl *D) { 577 NodeDumper.dumpName(D); 578 NodeDumper.dumpType(D->getType()); 579 580 for (auto *Child : D->chain()) 581 NodeDumper.dumpDeclRef(Child); 582 } 583 584 void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) { 585 NodeDumper.dumpName(D); 586 NodeDumper.dumpType(D->getType()); 587 588 StorageClass SC = D->getStorageClass(); 589 if (SC != SC_None) 590 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 591 if (D->isInlineSpecified()) 592 OS << " inline"; 593 if (D->isVirtualAsWritten()) 594 OS << " virtual"; 595 if (D->isModulePrivate()) 596 OS << " __module_private__"; 597 598 if (D->isPure()) 599 OS << " pure"; 600 if (D->isDefaulted()) { 601 OS << " default"; 602 if (D->isDeleted()) 603 OS << "_delete"; 604 } 605 if (D->isDeletedAsWritten()) 606 OS << " delete"; 607 if (D->isTrivial()) 608 OS << " trivial"; 609 610 if (const FunctionProtoType *FPT = D->getType()->getAs<FunctionProtoType>()) { 611 FunctionProtoType::ExtProtoInfo EPI = FPT->getExtProtoInfo(); 612 switch (EPI.ExceptionSpec.Type) { 613 default: break; 614 case EST_Unevaluated: 615 OS << " noexcept-unevaluated " << EPI.ExceptionSpec.SourceDecl; 616 break; 617 case EST_Uninstantiated: 618 OS << " noexcept-uninstantiated " << EPI.ExceptionSpec.SourceTemplate; 619 break; 620 } 621 } 622 623 if (const FunctionTemplateSpecializationInfo *FTSI = 624 D->getTemplateSpecializationInfo()) 625 dumpTemplateArgumentList(*FTSI->TemplateArguments); 626 627 if (!D->param_begin() && D->getNumParams()) 628 dumpChild([=] { OS << "<<NULL params x " << D->getNumParams() << ">>"; }); 629 else 630 for (const ParmVarDecl *Parameter : D->parameters()) 631 dumpDecl(Parameter); 632 633 if (const CXXConstructorDecl *C = dyn_cast<CXXConstructorDecl>(D)) 634 for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), 635 E = C->init_end(); 636 I != E; ++I) 637 dumpCXXCtorInitializer(*I); 638 639 if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(D)) { 640 if (MD->size_overridden_methods() != 0) { 641 auto dumpOverride = [=](const CXXMethodDecl *D) { 642 SplitQualType T_split = D->getType().split(); 643 OS << D << " " << D->getParent()->getName() 644 << "::" << D->getNameAsString() << " '" 645 << QualType::getAsString(T_split, PrintPolicy) << "'"; 646 }; 647 648 dumpChild([=] { 649 auto Overrides = MD->overridden_methods(); 650 OS << "Overrides: [ "; 651 dumpOverride(*Overrides.begin()); 652 for (const auto *Override : 653 llvm::make_range(Overrides.begin() + 1, Overrides.end())) { 654 OS << ", "; 655 dumpOverride(Override); 656 } 657 OS << " ]"; 658 }); 659 } 660 } 661 662 if (D->doesThisDeclarationHaveABody()) 663 dumpStmt(D->getBody()); 664 } 665 666 void ASTDumper::VisitFieldDecl(const FieldDecl *D) { 667 NodeDumper.dumpName(D); 668 NodeDumper.dumpType(D->getType()); 669 if (D->isMutable()) 670 OS << " mutable"; 671 if (D->isModulePrivate()) 672 OS << " __module_private__"; 673 674 if (D->isBitField()) 675 dumpStmt(D->getBitWidth()); 676 if (Expr *Init = D->getInClassInitializer()) 677 dumpStmt(Init); 678 } 679 680 void ASTDumper::VisitVarDecl(const VarDecl *D) { 681 NodeDumper.dumpName(D); 682 NodeDumper.dumpType(D->getType()); 683 StorageClass SC = D->getStorageClass(); 684 if (SC != SC_None) 685 OS << ' ' << VarDecl::getStorageClassSpecifierString(SC); 686 switch (D->getTLSKind()) { 687 case VarDecl::TLS_None: break; 688 case VarDecl::TLS_Static: OS << " tls"; break; 689 case VarDecl::TLS_Dynamic: OS << " tls_dynamic"; break; 690 } 691 if (D->isModulePrivate()) 692 OS << " __module_private__"; 693 if (D->isNRVOVariable()) 694 OS << " nrvo"; 695 if (D->isInline()) 696 OS << " inline"; 697 if (D->isConstexpr()) 698 OS << " constexpr"; 699 if (D->hasInit()) { 700 switch (D->getInitStyle()) { 701 case VarDecl::CInit: OS << " cinit"; break; 702 case VarDecl::CallInit: OS << " callinit"; break; 703 case VarDecl::ListInit: OS << " listinit"; break; 704 } 705 dumpStmt(D->getInit()); 706 } 707 } 708 709 void ASTDumper::VisitDecompositionDecl(const DecompositionDecl *D) { 710 VisitVarDecl(D); 711 for (auto *B : D->bindings()) 712 dumpDecl(B); 713 } 714 715 void ASTDumper::VisitBindingDecl(const BindingDecl *D) { 716 NodeDumper.dumpName(D); 717 NodeDumper.dumpType(D->getType()); 718 if (auto *E = D->getBinding()) 719 dumpStmt(E); 720 } 721 722 void ASTDumper::VisitFileScopeAsmDecl(const FileScopeAsmDecl *D) { 723 dumpStmt(D->getAsmString()); 724 } 725 726 void ASTDumper::VisitImportDecl(const ImportDecl *D) { 727 OS << ' ' << D->getImportedModule()->getFullModuleName(); 728 } 729 730 void ASTDumper::VisitPragmaCommentDecl(const PragmaCommentDecl *D) { 731 OS << ' '; 732 switch (D->getCommentKind()) { 733 case PCK_Unknown: llvm_unreachable("unexpected pragma comment kind"); 734 case PCK_Compiler: OS << "compiler"; break; 735 case PCK_ExeStr: OS << "exestr"; break; 736 case PCK_Lib: OS << "lib"; break; 737 case PCK_Linker: OS << "linker"; break; 738 case PCK_User: OS << "user"; break; 739 } 740 StringRef Arg = D->getArg(); 741 if (!Arg.empty()) 742 OS << " \"" << Arg << "\""; 743 } 744 745 void ASTDumper::VisitPragmaDetectMismatchDecl( 746 const PragmaDetectMismatchDecl *D) { 747 OS << " \"" << D->getName() << "\" \"" << D->getValue() << "\""; 748 } 749 750 void ASTDumper::VisitCapturedDecl(const CapturedDecl *D) { 751 dumpStmt(D->getBody()); 752 } 753 754 //===----------------------------------------------------------------------===// 755 // OpenMP Declarations 756 //===----------------------------------------------------------------------===// 757 758 void ASTDumper::VisitOMPThreadPrivateDecl(const OMPThreadPrivateDecl *D) { 759 for (auto *E : D->varlists()) 760 dumpStmt(E); 761 } 762 763 void ASTDumper::VisitOMPDeclareReductionDecl(const OMPDeclareReductionDecl *D) { 764 NodeDumper.dumpName(D); 765 NodeDumper.dumpType(D->getType()); 766 OS << " combiner"; 767 NodeDumper.dumpPointer(D->getCombiner()); 768 if (const auto *Initializer = D->getInitializer()) { 769 OS << " initializer"; 770 NodeDumper.dumpPointer(Initializer); 771 switch (D->getInitializerKind()) { 772 case OMPDeclareReductionDecl::DirectInit: 773 OS << " omp_priv = "; 774 break; 775 case OMPDeclareReductionDecl::CopyInit: 776 OS << " omp_priv ()"; 777 break; 778 case OMPDeclareReductionDecl::CallInit: 779 break; 780 } 781 } 782 783 dumpStmt(D->getCombiner()); 784 if (const auto *Initializer = D->getInitializer()) 785 dumpStmt(Initializer); 786 } 787 788 void ASTDumper::VisitOMPRequiresDecl(const OMPRequiresDecl *D) { 789 for (auto *C : D->clauselists()) { 790 dumpChild([=] { 791 if (!C) { 792 ColorScope Color(OS, ShowColors, NullColor); 793 OS << "<<<NULL>>> OMPClause"; 794 return; 795 } 796 { 797 ColorScope Color(OS, ShowColors, AttrColor); 798 StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); 799 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() 800 << ClauseName.drop_front() << "Clause"; 801 } 802 NodeDumper.dumpPointer(C); 803 NodeDumper.dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); 804 }); 805 } 806 } 807 808 void ASTDumper::VisitOMPCapturedExprDecl(const OMPCapturedExprDecl *D) { 809 NodeDumper.dumpName(D); 810 NodeDumper.dumpType(D->getType()); 811 dumpStmt(D->getInit()); 812 } 813 814 //===----------------------------------------------------------------------===// 815 // C++ Declarations 816 //===----------------------------------------------------------------------===// 817 818 void ASTDumper::VisitNamespaceDecl(const NamespaceDecl *D) { 819 NodeDumper.dumpName(D); 820 if (D->isInline()) 821 OS << " inline"; 822 if (!D->isOriginalNamespace()) 823 NodeDumper.dumpDeclRef(D->getOriginalNamespace(), "original"); 824 } 825 826 void ASTDumper::VisitUsingDirectiveDecl(const UsingDirectiveDecl *D) { 827 OS << ' '; 828 NodeDumper.dumpBareDeclRef(D->getNominatedNamespace()); 829 } 830 831 void ASTDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) { 832 NodeDumper.dumpName(D); 833 NodeDumper.dumpDeclRef(D->getAliasedNamespace()); 834 } 835 836 void ASTDumper::VisitTypeAliasDecl(const TypeAliasDecl *D) { 837 NodeDumper.dumpName(D); 838 NodeDumper.dumpType(D->getUnderlyingType()); 839 dumpTypeAsChild(D->getUnderlyingType()); 840 } 841 842 void ASTDumper::VisitTypeAliasTemplateDecl(const TypeAliasTemplateDecl *D) { 843 NodeDumper.dumpName(D); 844 dumpTemplateParameters(D->getTemplateParameters()); 845 dumpDecl(D->getTemplatedDecl()); 846 } 847 848 void ASTDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) { 849 VisitRecordDecl(D); 850 if (!D->isCompleteDefinition()) 851 return; 852 853 dumpChild([=] { 854 { 855 ColorScope Color(OS, ShowColors, DeclKindNameColor); 856 OS << "DefinitionData"; 857 } 858 #define FLAG(fn, name) if (D->fn()) OS << " " #name; 859 FLAG(isParsingBaseSpecifiers, parsing_base_specifiers); 860 861 FLAG(isGenericLambda, generic); 862 FLAG(isLambda, lambda); 863 864 FLAG(canPassInRegisters, pass_in_registers); 865 FLAG(isEmpty, empty); 866 FLAG(isAggregate, aggregate); 867 FLAG(isStandardLayout, standard_layout); 868 FLAG(isTriviallyCopyable, trivially_copyable); 869 FLAG(isPOD, pod); 870 FLAG(isTrivial, trivial); 871 FLAG(isPolymorphic, polymorphic); 872 FLAG(isAbstract, abstract); 873 FLAG(isLiteral, literal); 874 875 FLAG(hasUserDeclaredConstructor, has_user_declared_ctor); 876 FLAG(hasConstexprNonCopyMoveConstructor, has_constexpr_non_copy_move_ctor); 877 FLAG(hasMutableFields, has_mutable_fields); 878 FLAG(hasVariantMembers, has_variant_members); 879 FLAG(allowConstDefaultInit, can_const_default_init); 880 881 dumpChild([=] { 882 { 883 ColorScope Color(OS, ShowColors, DeclKindNameColor); 884 OS << "DefaultConstructor"; 885 } 886 FLAG(hasDefaultConstructor, exists); 887 FLAG(hasTrivialDefaultConstructor, trivial); 888 FLAG(hasNonTrivialDefaultConstructor, non_trivial); 889 FLAG(hasUserProvidedDefaultConstructor, user_provided); 890 FLAG(hasConstexprDefaultConstructor, constexpr); 891 FLAG(needsImplicitDefaultConstructor, needs_implicit); 892 FLAG(defaultedDefaultConstructorIsConstexpr, defaulted_is_constexpr); 893 }); 894 895 dumpChild([=] { 896 { 897 ColorScope Color(OS, ShowColors, DeclKindNameColor); 898 OS << "CopyConstructor"; 899 } 900 FLAG(hasSimpleCopyConstructor, simple); 901 FLAG(hasTrivialCopyConstructor, trivial); 902 FLAG(hasNonTrivialCopyConstructor, non_trivial); 903 FLAG(hasUserDeclaredCopyConstructor, user_declared); 904 FLAG(hasCopyConstructorWithConstParam, has_const_param); 905 FLAG(needsImplicitCopyConstructor, needs_implicit); 906 FLAG(needsOverloadResolutionForCopyConstructor, 907 needs_overload_resolution); 908 if (!D->needsOverloadResolutionForCopyConstructor()) 909 FLAG(defaultedCopyConstructorIsDeleted, defaulted_is_deleted); 910 FLAG(implicitCopyConstructorHasConstParam, implicit_has_const_param); 911 }); 912 913 dumpChild([=] { 914 { 915 ColorScope Color(OS, ShowColors, DeclKindNameColor); 916 OS << "MoveConstructor"; 917 } 918 FLAG(hasMoveConstructor, exists); 919 FLAG(hasSimpleMoveConstructor, simple); 920 FLAG(hasTrivialMoveConstructor, trivial); 921 FLAG(hasNonTrivialMoveConstructor, non_trivial); 922 FLAG(hasUserDeclaredMoveConstructor, user_declared); 923 FLAG(needsImplicitMoveConstructor, needs_implicit); 924 FLAG(needsOverloadResolutionForMoveConstructor, 925 needs_overload_resolution); 926 if (!D->needsOverloadResolutionForMoveConstructor()) 927 FLAG(defaultedMoveConstructorIsDeleted, defaulted_is_deleted); 928 }); 929 930 dumpChild([=] { 931 { 932 ColorScope Color(OS, ShowColors, DeclKindNameColor); 933 OS << "CopyAssignment"; 934 } 935 FLAG(hasTrivialCopyAssignment, trivial); 936 FLAG(hasNonTrivialCopyAssignment, non_trivial); 937 FLAG(hasCopyAssignmentWithConstParam, has_const_param); 938 FLAG(hasUserDeclaredCopyAssignment, user_declared); 939 FLAG(needsImplicitCopyAssignment, needs_implicit); 940 FLAG(needsOverloadResolutionForCopyAssignment, needs_overload_resolution); 941 FLAG(implicitCopyAssignmentHasConstParam, implicit_has_const_param); 942 }); 943 944 dumpChild([=] { 945 { 946 ColorScope Color(OS, ShowColors, DeclKindNameColor); 947 OS << "MoveAssignment"; 948 } 949 FLAG(hasMoveAssignment, exists); 950 FLAG(hasSimpleMoveAssignment, simple); 951 FLAG(hasTrivialMoveAssignment, trivial); 952 FLAG(hasNonTrivialMoveAssignment, non_trivial); 953 FLAG(hasUserDeclaredMoveAssignment, user_declared); 954 FLAG(needsImplicitMoveAssignment, needs_implicit); 955 FLAG(needsOverloadResolutionForMoveAssignment, needs_overload_resolution); 956 }); 957 958 dumpChild([=] { 959 { 960 ColorScope Color(OS, ShowColors, DeclKindNameColor); 961 OS << "Destructor"; 962 } 963 FLAG(hasSimpleDestructor, simple); 964 FLAG(hasIrrelevantDestructor, irrelevant); 965 FLAG(hasTrivialDestructor, trivial); 966 FLAG(hasNonTrivialDestructor, non_trivial); 967 FLAG(hasUserDeclaredDestructor, user_declared); 968 FLAG(needsImplicitDestructor, needs_implicit); 969 FLAG(needsOverloadResolutionForDestructor, needs_overload_resolution); 970 if (!D->needsOverloadResolutionForDestructor()) 971 FLAG(defaultedDestructorIsDeleted, defaulted_is_deleted); 972 }); 973 }); 974 975 for (const auto &I : D->bases()) { 976 dumpChild([=] { 977 if (I.isVirtual()) 978 OS << "virtual "; 979 NodeDumper.dumpAccessSpecifier(I.getAccessSpecifier()); 980 NodeDumper.dumpType(I.getType()); 981 if (I.isPackExpansion()) 982 OS << "..."; 983 }); 984 } 985 } 986 987 void ASTDumper::VisitStaticAssertDecl(const StaticAssertDecl *D) { 988 dumpStmt(D->getAssertExpr()); 989 dumpStmt(D->getMessage()); 990 } 991 992 template <typename SpecializationDecl> 993 void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D, 994 bool DumpExplicitInst, 995 bool DumpRefOnly) { 996 bool DumpedAny = false; 997 for (auto *RedeclWithBadType : D->redecls()) { 998 // FIXME: The redecls() range sometimes has elements of a less-specific 999 // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives 1000 // us TagDecls, and should give CXXRecordDecls). 1001 auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType); 1002 if (!Redecl) { 1003 // Found the injected-class-name for a class template. This will be dumped 1004 // as part of its surrounding class so we don't need to dump it here. 1005 assert(isa<CXXRecordDecl>(RedeclWithBadType) && 1006 "expected an injected-class-name"); 1007 continue; 1008 } 1009 1010 switch (Redecl->getTemplateSpecializationKind()) { 1011 case TSK_ExplicitInstantiationDeclaration: 1012 case TSK_ExplicitInstantiationDefinition: 1013 if (!DumpExplicitInst) 1014 break; 1015 LLVM_FALLTHROUGH; 1016 case TSK_Undeclared: 1017 case TSK_ImplicitInstantiation: 1018 if (DumpRefOnly) 1019 NodeDumper.dumpDeclRef(Redecl); 1020 else 1021 dumpDecl(Redecl); 1022 DumpedAny = true; 1023 break; 1024 case TSK_ExplicitSpecialization: 1025 break; 1026 } 1027 } 1028 1029 // Ensure we dump at least one decl for each specialization. 1030 if (!DumpedAny) 1031 NodeDumper.dumpDeclRef(D); 1032 } 1033 1034 template <typename TemplateDecl> 1035 void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) { 1036 NodeDumper.dumpName(D); 1037 dumpTemplateParameters(D->getTemplateParameters()); 1038 1039 dumpDecl(D->getTemplatedDecl()); 1040 1041 for (auto *Child : D->specializations()) 1042 dumpTemplateDeclSpecialization(Child, DumpExplicitInst, 1043 !D->isCanonicalDecl()); 1044 } 1045 1046 void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) { 1047 // FIXME: We don't add a declaration of a function template specialization 1048 // to its context when it's explicitly instantiated, so dump explicit 1049 // instantiations when we dump the template itself. 1050 dumpTemplateDecl(D, true); 1051 } 1052 1053 void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) { 1054 dumpTemplateDecl(D, false); 1055 } 1056 1057 void ASTDumper::VisitClassTemplateSpecializationDecl( 1058 const ClassTemplateSpecializationDecl *D) { 1059 VisitCXXRecordDecl(D); 1060 dumpTemplateArgumentList(D->getTemplateArgs()); 1061 } 1062 1063 void ASTDumper::VisitClassTemplatePartialSpecializationDecl( 1064 const ClassTemplatePartialSpecializationDecl *D) { 1065 VisitClassTemplateSpecializationDecl(D); 1066 dumpTemplateParameters(D->getTemplateParameters()); 1067 } 1068 1069 void ASTDumper::VisitClassScopeFunctionSpecializationDecl( 1070 const ClassScopeFunctionSpecializationDecl *D) { 1071 dumpDecl(D->getSpecialization()); 1072 if (D->hasExplicitTemplateArgs()) 1073 dumpTemplateArgumentListInfo(D->templateArgs()); 1074 } 1075 1076 void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) { 1077 dumpTemplateDecl(D, false); 1078 } 1079 1080 void ASTDumper::VisitBuiltinTemplateDecl(const BuiltinTemplateDecl *D) { 1081 NodeDumper.dumpName(D); 1082 dumpTemplateParameters(D->getTemplateParameters()); 1083 } 1084 1085 void ASTDumper::VisitVarTemplateSpecializationDecl( 1086 const VarTemplateSpecializationDecl *D) { 1087 dumpTemplateArgumentList(D->getTemplateArgs()); 1088 VisitVarDecl(D); 1089 } 1090 1091 void ASTDumper::VisitVarTemplatePartialSpecializationDecl( 1092 const VarTemplatePartialSpecializationDecl *D) { 1093 dumpTemplateParameters(D->getTemplateParameters()); 1094 VisitVarTemplateSpecializationDecl(D); 1095 } 1096 1097 void ASTDumper::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D) { 1098 if (D->wasDeclaredWithTypename()) 1099 OS << " typename"; 1100 else 1101 OS << " class"; 1102 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 1103 if (D->isParameterPack()) 1104 OS << " ..."; 1105 NodeDumper.dumpName(D); 1106 if (D->hasDefaultArgument()) 1107 dumpTemplateArgument(D->getDefaultArgument(), SourceRange(), 1108 D->getDefaultArgStorage().getInheritedFrom(), 1109 D->defaultArgumentWasInherited() ? "inherited from" 1110 : "previous"); 1111 } 1112 1113 void ASTDumper::VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D) { 1114 NodeDumper.dumpType(D->getType()); 1115 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 1116 if (D->isParameterPack()) 1117 OS << " ..."; 1118 NodeDumper.dumpName(D); 1119 if (D->hasDefaultArgument()) 1120 dumpTemplateArgument(D->getDefaultArgument(), SourceRange(), 1121 D->getDefaultArgStorage().getInheritedFrom(), 1122 D->defaultArgumentWasInherited() ? "inherited from" 1123 : "previous"); 1124 } 1125 1126 void ASTDumper::VisitTemplateTemplateParmDecl( 1127 const TemplateTemplateParmDecl *D) { 1128 OS << " depth " << D->getDepth() << " index " << D->getIndex(); 1129 if (D->isParameterPack()) 1130 OS << " ..."; 1131 NodeDumper.dumpName(D); 1132 dumpTemplateParameters(D->getTemplateParameters()); 1133 if (D->hasDefaultArgument()) 1134 dumpTemplateArgumentLoc( 1135 D->getDefaultArgument(), D->getDefaultArgStorage().getInheritedFrom(), 1136 D->defaultArgumentWasInherited() ? "inherited from" : "previous"); 1137 } 1138 1139 void ASTDumper::VisitUsingDecl(const UsingDecl *D) { 1140 OS << ' '; 1141 if (D->getQualifier()) 1142 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1143 OS << D->getNameAsString(); 1144 } 1145 1146 void ASTDumper::VisitUnresolvedUsingTypenameDecl( 1147 const UnresolvedUsingTypenameDecl *D) { 1148 OS << ' '; 1149 if (D->getQualifier()) 1150 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1151 OS << D->getNameAsString(); 1152 } 1153 1154 void ASTDumper::VisitUnresolvedUsingValueDecl(const UnresolvedUsingValueDecl *D) { 1155 OS << ' '; 1156 if (D->getQualifier()) 1157 D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy()); 1158 OS << D->getNameAsString(); 1159 NodeDumper.dumpType(D->getType()); 1160 } 1161 1162 void ASTDumper::VisitUsingShadowDecl(const UsingShadowDecl *D) { 1163 OS << ' '; 1164 NodeDumper.dumpBareDeclRef(D->getTargetDecl()); 1165 if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl())) 1166 dumpTypeAsChild(TD->getTypeForDecl()); 1167 } 1168 1169 void ASTDumper::VisitConstructorUsingShadowDecl( 1170 const ConstructorUsingShadowDecl *D) { 1171 if (D->constructsVirtualBase()) 1172 OS << " virtual"; 1173 1174 dumpChild([=] { 1175 OS << "target "; 1176 NodeDumper.dumpBareDeclRef(D->getTargetDecl()); 1177 }); 1178 1179 dumpChild([=] { 1180 OS << "nominated "; 1181 NodeDumper.dumpBareDeclRef(D->getNominatedBaseClass()); 1182 OS << ' '; 1183 NodeDumper.dumpBareDeclRef(D->getNominatedBaseClassShadowDecl()); 1184 }); 1185 1186 dumpChild([=] { 1187 OS << "constructed "; 1188 NodeDumper.dumpBareDeclRef(D->getConstructedBaseClass()); 1189 OS << ' '; 1190 NodeDumper.dumpBareDeclRef(D->getConstructedBaseClassShadowDecl()); 1191 }); 1192 } 1193 1194 void ASTDumper::VisitLinkageSpecDecl(const LinkageSpecDecl *D) { 1195 switch (D->getLanguage()) { 1196 case LinkageSpecDecl::lang_c: OS << " C"; break; 1197 case LinkageSpecDecl::lang_cxx: OS << " C++"; break; 1198 } 1199 } 1200 1201 void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) { 1202 OS << ' '; 1203 NodeDumper.dumpAccessSpecifier(D->getAccess()); 1204 } 1205 1206 void ASTDumper::VisitFriendDecl(const FriendDecl *D) { 1207 if (TypeSourceInfo *T = D->getFriendType()) 1208 NodeDumper.dumpType(T->getType()); 1209 else 1210 dumpDecl(D->getFriendDecl()); 1211 } 1212 1213 //===----------------------------------------------------------------------===// 1214 // Obj-C Declarations 1215 //===----------------------------------------------------------------------===// 1216 1217 void ASTDumper::VisitObjCIvarDecl(const ObjCIvarDecl *D) { 1218 NodeDumper.dumpName(D); 1219 NodeDumper.dumpType(D->getType()); 1220 if (D->getSynthesize()) 1221 OS << " synthesize"; 1222 1223 switch (D->getAccessControl()) { 1224 case ObjCIvarDecl::None: 1225 OS << " none"; 1226 break; 1227 case ObjCIvarDecl::Private: 1228 OS << " private"; 1229 break; 1230 case ObjCIvarDecl::Protected: 1231 OS << " protected"; 1232 break; 1233 case ObjCIvarDecl::Public: 1234 OS << " public"; 1235 break; 1236 case ObjCIvarDecl::Package: 1237 OS << " package"; 1238 break; 1239 } 1240 } 1241 1242 void ASTDumper::VisitObjCMethodDecl(const ObjCMethodDecl *D) { 1243 if (D->isInstanceMethod()) 1244 OS << " -"; 1245 else 1246 OS << " +"; 1247 NodeDumper.dumpName(D); 1248 NodeDumper.dumpType(D->getReturnType()); 1249 1250 if (D->isThisDeclarationADefinition()) { 1251 dumpDeclContext(D); 1252 } else { 1253 for (const ParmVarDecl *Parameter : D->parameters()) 1254 dumpDecl(Parameter); 1255 } 1256 1257 if (D->isVariadic()) 1258 dumpChild([=] { OS << "..."; }); 1259 1260 if (D->hasBody()) 1261 dumpStmt(D->getBody()); 1262 } 1263 1264 void ASTDumper::VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D) { 1265 NodeDumper.dumpName(D); 1266 switch (D->getVariance()) { 1267 case ObjCTypeParamVariance::Invariant: 1268 break; 1269 1270 case ObjCTypeParamVariance::Covariant: 1271 OS << " covariant"; 1272 break; 1273 1274 case ObjCTypeParamVariance::Contravariant: 1275 OS << " contravariant"; 1276 break; 1277 } 1278 1279 if (D->hasExplicitBound()) 1280 OS << " bounded"; 1281 NodeDumper.dumpType(D->getUnderlyingType()); 1282 } 1283 1284 void ASTDumper::VisitObjCCategoryDecl(const ObjCCategoryDecl *D) { 1285 NodeDumper.dumpName(D); 1286 NodeDumper.dumpDeclRef(D->getClassInterface()); 1287 dumpObjCTypeParamList(D->getTypeParamList()); 1288 NodeDumper.dumpDeclRef(D->getImplementation()); 1289 for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), 1290 E = D->protocol_end(); 1291 I != E; ++I) 1292 NodeDumper.dumpDeclRef(*I); 1293 } 1294 1295 void ASTDumper::VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D) { 1296 NodeDumper.dumpName(D); 1297 NodeDumper.dumpDeclRef(D->getClassInterface()); 1298 NodeDumper.dumpDeclRef(D->getCategoryDecl()); 1299 } 1300 1301 void ASTDumper::VisitObjCProtocolDecl(const ObjCProtocolDecl *D) { 1302 NodeDumper.dumpName(D); 1303 1304 for (auto *Child : D->protocols()) 1305 NodeDumper.dumpDeclRef(Child); 1306 } 1307 1308 void ASTDumper::VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D) { 1309 NodeDumper.dumpName(D); 1310 dumpObjCTypeParamList(D->getTypeParamListAsWritten()); 1311 NodeDumper.dumpDeclRef(D->getSuperClass(), "super"); 1312 1313 NodeDumper.dumpDeclRef(D->getImplementation()); 1314 for (auto *Child : D->protocols()) 1315 NodeDumper.dumpDeclRef(Child); 1316 } 1317 1318 void ASTDumper::VisitObjCImplementationDecl(const ObjCImplementationDecl *D) { 1319 NodeDumper.dumpName(D); 1320 NodeDumper.dumpDeclRef(D->getSuperClass(), "super"); 1321 NodeDumper.dumpDeclRef(D->getClassInterface()); 1322 for (ObjCImplementationDecl::init_const_iterator I = D->init_begin(), 1323 E = D->init_end(); 1324 I != E; ++I) 1325 dumpCXXCtorInitializer(*I); 1326 } 1327 1328 void ASTDumper::VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D) { 1329 NodeDumper.dumpName(D); 1330 NodeDumper.dumpDeclRef(D->getClassInterface()); 1331 } 1332 1333 void ASTDumper::VisitObjCPropertyDecl(const ObjCPropertyDecl *D) { 1334 NodeDumper.dumpName(D); 1335 NodeDumper.dumpType(D->getType()); 1336 1337 if (D->getPropertyImplementation() == ObjCPropertyDecl::Required) 1338 OS << " required"; 1339 else if (D->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1340 OS << " optional"; 1341 1342 ObjCPropertyDecl::PropertyAttributeKind Attrs = D->getPropertyAttributes(); 1343 if (Attrs != ObjCPropertyDecl::OBJC_PR_noattr) { 1344 if (Attrs & ObjCPropertyDecl::OBJC_PR_readonly) 1345 OS << " readonly"; 1346 if (Attrs & ObjCPropertyDecl::OBJC_PR_assign) 1347 OS << " assign"; 1348 if (Attrs & ObjCPropertyDecl::OBJC_PR_readwrite) 1349 OS << " readwrite"; 1350 if (Attrs & ObjCPropertyDecl::OBJC_PR_retain) 1351 OS << " retain"; 1352 if (Attrs & ObjCPropertyDecl::OBJC_PR_copy) 1353 OS << " copy"; 1354 if (Attrs & ObjCPropertyDecl::OBJC_PR_nonatomic) 1355 OS << " nonatomic"; 1356 if (Attrs & ObjCPropertyDecl::OBJC_PR_atomic) 1357 OS << " atomic"; 1358 if (Attrs & ObjCPropertyDecl::OBJC_PR_weak) 1359 OS << " weak"; 1360 if (Attrs & ObjCPropertyDecl::OBJC_PR_strong) 1361 OS << " strong"; 1362 if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) 1363 OS << " unsafe_unretained"; 1364 if (Attrs & ObjCPropertyDecl::OBJC_PR_class) 1365 OS << " class"; 1366 if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) 1367 NodeDumper.dumpDeclRef(D->getGetterMethodDecl(), "getter"); 1368 if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) 1369 NodeDumper.dumpDeclRef(D->getSetterMethodDecl(), "setter"); 1370 } 1371 } 1372 1373 void ASTDumper::VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D) { 1374 NodeDumper.dumpName(D->getPropertyDecl()); 1375 if (D->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1376 OS << " synthesize"; 1377 else 1378 OS << " dynamic"; 1379 NodeDumper.dumpDeclRef(D->getPropertyDecl()); 1380 NodeDumper.dumpDeclRef(D->getPropertyIvarDecl()); 1381 } 1382 1383 void ASTDumper::VisitBlockDecl(const BlockDecl *D) { 1384 for (auto I : D->parameters()) 1385 dumpDecl(I); 1386 1387 if (D->isVariadic()) 1388 dumpChild([=]{ OS << "..."; }); 1389 1390 if (D->capturesCXXThis()) 1391 dumpChild([=]{ OS << "capture this"; }); 1392 1393 for (const auto &I : D->captures()) { 1394 dumpChild([=] { 1395 OS << "capture"; 1396 if (I.isByRef()) 1397 OS << " byref"; 1398 if (I.isNested()) 1399 OS << " nested"; 1400 if (I.getVariable()) { 1401 OS << ' '; 1402 NodeDumper.dumpBareDeclRef(I.getVariable()); 1403 } 1404 if (I.hasCopyExpr()) 1405 dumpStmt(I.getCopyExpr()); 1406 }); 1407 } 1408 dumpStmt(D->getBody()); 1409 } 1410 1411 //===----------------------------------------------------------------------===// 1412 // Stmt dumping methods. 1413 //===----------------------------------------------------------------------===// 1414 1415 void ASTDumper::dumpStmt(const Stmt *S, StringRef Label) { 1416 dumpChild(Label, [=] { 1417 NodeDumper.Visit(S); 1418 1419 if (!S) { 1420 return; 1421 } 1422 1423 ConstStmtVisitor<ASTDumper>::Visit(S); 1424 1425 // Some statements have custom mechanisms for dumping their children. 1426 if (isa<DeclStmt>(S) || isa<GenericSelectionExpr>(S)) { 1427 return; 1428 } 1429 1430 for (const Stmt *SubStmt : S->children()) 1431 dumpStmt(SubStmt); 1432 }); 1433 } 1434 1435 void ASTDumper::VisitDeclStmt(const DeclStmt *Node) { 1436 for (DeclStmt::const_decl_iterator I = Node->decl_begin(), 1437 E = Node->decl_end(); 1438 I != E; ++I) 1439 dumpDecl(*I); 1440 } 1441 1442 void ASTDumper::VisitAttributedStmt(const AttributedStmt *Node) { 1443 for (ArrayRef<const Attr *>::iterator I = Node->getAttrs().begin(), 1444 E = Node->getAttrs().end(); 1445 I != E; ++I) 1446 dumpAttr(*I); 1447 } 1448 1449 void ASTDumper::VisitCXXCatchStmt(const CXXCatchStmt *Node) { 1450 dumpDecl(Node->getExceptionDecl()); 1451 } 1452 1453 void ASTDumper::VisitCapturedStmt(const CapturedStmt *Node) { 1454 dumpDecl(Node->getCapturedDecl()); 1455 } 1456 1457 //===----------------------------------------------------------------------===// 1458 // OpenMP dumping methods. 1459 //===----------------------------------------------------------------------===// 1460 1461 void ASTDumper::VisitOMPExecutableDirective( 1462 const OMPExecutableDirective *Node) { 1463 for (auto *C : Node->clauses()) { 1464 dumpChild([=] { 1465 if (!C) { 1466 ColorScope Color(OS, ShowColors, NullColor); 1467 OS << "<<<NULL>>> OMPClause"; 1468 return; 1469 } 1470 { 1471 ColorScope Color(OS, ShowColors, AttrColor); 1472 StringRef ClauseName(getOpenMPClauseName(C->getClauseKind())); 1473 OS << "OMP" << ClauseName.substr(/*Start=*/0, /*N=*/1).upper() 1474 << ClauseName.drop_front() << "Clause"; 1475 } 1476 NodeDumper.dumpPointer(C); 1477 NodeDumper.dumpSourceRange(SourceRange(C->getBeginLoc(), C->getEndLoc())); 1478 if (C->isImplicit()) 1479 OS << " <implicit>"; 1480 for (auto *S : C->children()) 1481 dumpStmt(S); 1482 }); 1483 } 1484 } 1485 1486 //===----------------------------------------------------------------------===// 1487 // Expr dumping methods. 1488 //===----------------------------------------------------------------------===// 1489 1490 1491 void ASTDumper::VisitInitListExpr(const InitListExpr *ILE) { 1492 if (auto *Filler = ILE->getArrayFiller()) { 1493 dumpStmt(Filler, "array_filler"); 1494 } 1495 } 1496 1497 void ASTDumper::VisitBlockExpr(const BlockExpr *Node) { 1498 dumpDecl(Node->getBlockDecl()); 1499 } 1500 1501 void ASTDumper::VisitOpaqueValueExpr(const OpaqueValueExpr *Node) { 1502 if (Expr *Source = Node->getSourceExpr()) 1503 dumpStmt(Source); 1504 } 1505 1506 void ASTDumper::VisitGenericSelectionExpr(const GenericSelectionExpr *E) { 1507 if (E->isResultDependent()) 1508 OS << " result_dependent"; 1509 dumpStmt(E->getControllingExpr()); 1510 dumpTypeAsChild(E->getControllingExpr()->getType()); // FIXME: remove 1511 1512 for (unsigned I = 0, N = E->getNumAssocs(); I != N; ++I) { 1513 dumpChild([=] { 1514 if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) { 1515 OS << "case "; 1516 NodeDumper.dumpType(TSI->getType()); 1517 } else { 1518 OS << "default"; 1519 } 1520 1521 if (!E->isResultDependent() && E->getResultIndex() == I) 1522 OS << " selected"; 1523 1524 if (const TypeSourceInfo *TSI = E->getAssocTypeSourceInfo(I)) 1525 dumpTypeAsChild(TSI->getType()); 1526 dumpStmt(E->getAssocExpr(I)); 1527 }); 1528 } 1529 } 1530 1531 //===----------------------------------------------------------------------===// 1532 // C++ Expressions 1533 //===----------------------------------------------------------------------===// 1534 1535 void ASTDumper::VisitSizeOfPackExpr(const SizeOfPackExpr *Node) { 1536 if (Node->isPartiallySubstituted()) 1537 for (const auto &A : Node->getPartialArguments()) 1538 dumpTemplateArgument(A); 1539 } 1540 1541 //===----------------------------------------------------------------------===// 1542 // Obj-C Expressions 1543 //===----------------------------------------------------------------------===// 1544 1545 void ASTDumper::VisitObjCAtCatchStmt(const ObjCAtCatchStmt *Node) { 1546 if (const VarDecl *CatchParam = Node->getCatchParamDecl()) 1547 dumpDecl(CatchParam); 1548 } 1549 1550 //===----------------------------------------------------------------------===// 1551 // Comments 1552 //===----------------------------------------------------------------------===// 1553 1554 void ASTDumper::dumpComment(const Comment *C, const FullComment *FC) { 1555 dumpChild([=] { 1556 NodeDumper.Visit(C, FC); 1557 if (!C) { 1558 return; 1559 } 1560 ConstCommentVisitor<ASTDumper, void, const FullComment *>::visit(C, FC); 1561 for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); 1562 I != E; ++I) 1563 dumpComment(*I, FC); 1564 }); 1565 } 1566 1567 //===----------------------------------------------------------------------===// 1568 // Type method implementations 1569 //===----------------------------------------------------------------------===// 1570 1571 void QualType::dump(const char *msg) const { 1572 if (msg) 1573 llvm::errs() << msg << ": "; 1574 dump(); 1575 } 1576 1577 LLVM_DUMP_METHOD void QualType::dump() const { dump(llvm::errs()); } 1578 1579 LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS) const { 1580 ASTDumper Dumper(OS, nullptr, nullptr); 1581 Dumper.dumpTypeAsChild(*this); 1582 } 1583 1584 LLVM_DUMP_METHOD void Type::dump() const { dump(llvm::errs()); } 1585 1586 LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS) const { 1587 QualType(this, 0).dump(OS); 1588 } 1589 1590 //===----------------------------------------------------------------------===// 1591 // Decl method implementations 1592 //===----------------------------------------------------------------------===// 1593 1594 LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); } 1595 1596 LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize) const { 1597 const ASTContext &Ctx = getASTContext(); 1598 const SourceManager &SM = Ctx.getSourceManager(); 1599 ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &SM, 1600 SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy()); 1601 P.setDeserialize(Deserialize); 1602 P.dumpDecl(this); 1603 } 1604 1605 LLVM_DUMP_METHOD void Decl::dumpColor() const { 1606 const ASTContext &Ctx = getASTContext(); 1607 ASTDumper P(llvm::errs(), &Ctx.getCommentCommandTraits(), 1608 &Ctx.getSourceManager(), /*ShowColors*/ true, 1609 Ctx.getPrintingPolicy()); 1610 P.dumpDecl(this); 1611 } 1612 1613 LLVM_DUMP_METHOD void DeclContext::dumpLookups() const { 1614 dumpLookups(llvm::errs()); 1615 } 1616 1617 LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS, 1618 bool DumpDecls, 1619 bool Deserialize) const { 1620 const DeclContext *DC = this; 1621 while (!DC->isTranslationUnit()) 1622 DC = DC->getParent(); 1623 ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); 1624 const SourceManager &SM = Ctx.getSourceManager(); 1625 ASTDumper P(OS, &Ctx.getCommentCommandTraits(), &Ctx.getSourceManager(), 1626 SM.getDiagnostics().getShowColors(), Ctx.getPrintingPolicy()); 1627 P.setDeserialize(Deserialize); 1628 P.dumpLookups(this, DumpDecls); 1629 } 1630 1631 //===----------------------------------------------------------------------===// 1632 // Stmt method implementations 1633 //===----------------------------------------------------------------------===// 1634 1635 LLVM_DUMP_METHOD void Stmt::dump(SourceManager &SM) const { 1636 dump(llvm::errs(), SM); 1637 } 1638 1639 LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS, SourceManager &SM) const { 1640 ASTDumper P(OS, nullptr, &SM); 1641 P.dumpStmt(this); 1642 } 1643 1644 LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS) const { 1645 ASTDumper P(OS, nullptr, nullptr); 1646 P.dumpStmt(this); 1647 } 1648 1649 LLVM_DUMP_METHOD void Stmt::dump() const { 1650 ASTDumper P(llvm::errs(), nullptr, nullptr); 1651 P.dumpStmt(this); 1652 } 1653 1654 LLVM_DUMP_METHOD void Stmt::dumpColor() const { 1655 ASTDumper P(llvm::errs(), nullptr, nullptr, /*ShowColors*/true); 1656 P.dumpStmt(this); 1657 } 1658 1659 //===----------------------------------------------------------------------===// 1660 // Comment method implementations 1661 //===----------------------------------------------------------------------===// 1662 1663 LLVM_DUMP_METHOD void Comment::dump() const { 1664 dump(llvm::errs(), nullptr, nullptr); 1665 } 1666 1667 LLVM_DUMP_METHOD void Comment::dump(const ASTContext &Context) const { 1668 dump(llvm::errs(), &Context.getCommentCommandTraits(), 1669 &Context.getSourceManager()); 1670 } 1671 1672 void Comment::dump(raw_ostream &OS, const CommandTraits *Traits, 1673 const SourceManager *SM) const { 1674 const FullComment *FC = dyn_cast<FullComment>(this); 1675 if (!FC) 1676 return; 1677 ASTDumper D(OS, Traits, SM); 1678 D.dumpComment(FC, FC); 1679 } 1680 1681 LLVM_DUMP_METHOD void Comment::dumpColor() const { 1682 const FullComment *FC = dyn_cast<FullComment>(this); 1683 if (!FC) 1684 return; 1685 ASTDumper D(llvm::errs(), nullptr, nullptr, /*ShowColors*/true); 1686 D.dumpComment(FC, FC); 1687 } 1688