xref: /freebsd/contrib/llvm-project/clang/lib/AST/ASTDumper.cpp (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
10b57cec5SDimitry Andric //===--- ASTDumper.cpp - Dumping implementation for ASTs ------------------===//
20b57cec5SDimitry Andric //
30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric //
70b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
80b57cec5SDimitry Andric //
90b57cec5SDimitry Andric // This file implements the AST dump methods, which dump out the
100b57cec5SDimitry Andric // AST in a form that exposes type details and other fields.
110b57cec5SDimitry Andric //
120b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
130b57cec5SDimitry Andric 
140b57cec5SDimitry Andric #include "clang/AST/ASTDumper.h"
150b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
160b57cec5SDimitry Andric #include "clang/AST/DeclLookups.h"
170b57cec5SDimitry Andric #include "clang/AST/JSONNodeDumper.h"
180b57cec5SDimitry Andric #include "clang/Basic/Builtins.h"
190b57cec5SDimitry Andric #include "clang/Basic/Module.h"
200b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
210b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
220b57cec5SDimitry Andric using namespace clang;
230b57cec5SDimitry Andric using namespace clang::comments;
240b57cec5SDimitry Andric 
250b57cec5SDimitry Andric void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
260b57cec5SDimitry Andric   NodeDumper.AddChild([=] {
270b57cec5SDimitry Andric     OS << "StoredDeclsMap ";
280b57cec5SDimitry Andric     NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
290b57cec5SDimitry Andric 
300b57cec5SDimitry Andric     const DeclContext *Primary = DC->getPrimaryContext();
310b57cec5SDimitry Andric     if (Primary != DC) {
320b57cec5SDimitry Andric       OS << " primary";
330b57cec5SDimitry Andric       NodeDumper.dumpPointer(cast<Decl>(Primary));
340b57cec5SDimitry Andric     }
350b57cec5SDimitry Andric 
360b57cec5SDimitry Andric     bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
370b57cec5SDimitry Andric 
380b57cec5SDimitry Andric     auto Range = getDeserialize()
390b57cec5SDimitry Andric                      ? Primary->lookups()
400b57cec5SDimitry Andric                      : Primary->noload_lookups(/*PreserveInternalState=*/true);
410b57cec5SDimitry Andric     for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
420b57cec5SDimitry Andric       DeclarationName Name = I.getLookupName();
430b57cec5SDimitry Andric       DeclContextLookupResult R = *I;
440b57cec5SDimitry Andric 
450b57cec5SDimitry Andric       NodeDumper.AddChild([=] {
460b57cec5SDimitry Andric         OS << "DeclarationName ";
470b57cec5SDimitry Andric         {
480b57cec5SDimitry Andric           ColorScope Color(OS, ShowColors, DeclNameColor);
490b57cec5SDimitry Andric           OS << '\'' << Name << '\'';
500b57cec5SDimitry Andric         }
510b57cec5SDimitry Andric 
520b57cec5SDimitry Andric         for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
530b57cec5SDimitry Andric              RI != RE; ++RI) {
540b57cec5SDimitry Andric           NodeDumper.AddChild([=] {
550b57cec5SDimitry Andric             NodeDumper.dumpBareDeclRef(*RI);
560b57cec5SDimitry Andric 
575ffd83dbSDimitry Andric             if (!(*RI)->isUnconditionallyVisible())
580b57cec5SDimitry Andric               OS << " hidden";
590b57cec5SDimitry Andric 
600b57cec5SDimitry Andric             // If requested, dump the redecl chain for this lookup.
610b57cec5SDimitry Andric             if (DumpDecls) {
620b57cec5SDimitry Andric               // Dump earliest decl first.
630b57cec5SDimitry Andric               std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
640b57cec5SDimitry Andric                 if (Decl *Prev = D->getPreviousDecl())
650b57cec5SDimitry Andric                   DumpWithPrev(Prev);
660b57cec5SDimitry Andric                 Visit(D);
670b57cec5SDimitry Andric               };
680b57cec5SDimitry Andric               DumpWithPrev(*RI);
690b57cec5SDimitry Andric             }
700b57cec5SDimitry Andric           });
710b57cec5SDimitry Andric         }
720b57cec5SDimitry Andric       });
730b57cec5SDimitry Andric     }
740b57cec5SDimitry Andric 
750b57cec5SDimitry Andric     if (HasUndeserializedLookups) {
760b57cec5SDimitry Andric       NodeDumper.AddChild([=] {
770b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, UndeserializedColor);
780b57cec5SDimitry Andric         OS << "<undeserialized lookups>";
790b57cec5SDimitry Andric       });
800b57cec5SDimitry Andric     }
810b57cec5SDimitry Andric   });
820b57cec5SDimitry Andric }
830b57cec5SDimitry Andric 
840b57cec5SDimitry Andric template <typename SpecializationDecl>
850b57cec5SDimitry Andric void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
860b57cec5SDimitry Andric                                                bool DumpExplicitInst,
870b57cec5SDimitry Andric                                                bool DumpRefOnly) {
880b57cec5SDimitry Andric   bool DumpedAny = false;
890b57cec5SDimitry Andric   for (const auto *RedeclWithBadType : D->redecls()) {
900b57cec5SDimitry Andric     // FIXME: The redecls() range sometimes has elements of a less-specific
910b57cec5SDimitry Andric     // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
920b57cec5SDimitry Andric     // us TagDecls, and should give CXXRecordDecls).
93*349cc55cSDimitry Andric     auto *Redecl = cast<SpecializationDecl>(RedeclWithBadType);
940b57cec5SDimitry Andric     switch (Redecl->getTemplateSpecializationKind()) {
950b57cec5SDimitry Andric     case TSK_ExplicitInstantiationDeclaration:
960b57cec5SDimitry Andric     case TSK_ExplicitInstantiationDefinition:
970b57cec5SDimitry Andric       if (!DumpExplicitInst)
980b57cec5SDimitry Andric         break;
990b57cec5SDimitry Andric       LLVM_FALLTHROUGH;
1000b57cec5SDimitry Andric     case TSK_Undeclared:
1010b57cec5SDimitry Andric     case TSK_ImplicitInstantiation:
1020b57cec5SDimitry Andric       if (DumpRefOnly)
1030b57cec5SDimitry Andric         NodeDumper.dumpDeclRef(Redecl);
1040b57cec5SDimitry Andric       else
1050b57cec5SDimitry Andric         Visit(Redecl);
1060b57cec5SDimitry Andric       DumpedAny = true;
1070b57cec5SDimitry Andric       break;
1080b57cec5SDimitry Andric     case TSK_ExplicitSpecialization:
1090b57cec5SDimitry Andric       break;
1100b57cec5SDimitry Andric     }
1110b57cec5SDimitry Andric   }
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric   // Ensure we dump at least one decl for each specialization.
1140b57cec5SDimitry Andric   if (!DumpedAny)
1150b57cec5SDimitry Andric     NodeDumper.dumpDeclRef(D);
1160b57cec5SDimitry Andric }
1170b57cec5SDimitry Andric 
1180b57cec5SDimitry Andric template <typename TemplateDecl>
1190b57cec5SDimitry Andric void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
1200b57cec5SDimitry Andric   dumpTemplateParameters(D->getTemplateParameters());
1210b57cec5SDimitry Andric 
1220b57cec5SDimitry Andric   Visit(D->getTemplatedDecl());
1230b57cec5SDimitry Andric 
124e8d8bef9SDimitry Andric   if (GetTraversalKind() == TK_AsIs) {
1250b57cec5SDimitry Andric     for (const auto *Child : D->specializations())
1260b57cec5SDimitry Andric       dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
1270b57cec5SDimitry Andric                                      !D->isCanonicalDecl());
1280b57cec5SDimitry Andric   }
129e8d8bef9SDimitry Andric }
1300b57cec5SDimitry Andric 
1310b57cec5SDimitry Andric void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
1320b57cec5SDimitry Andric   // FIXME: We don't add a declaration of a function template specialization
1330b57cec5SDimitry Andric   // to its context when it's explicitly instantiated, so dump explicit
1340b57cec5SDimitry Andric   // instantiations when we dump the template itself.
1350b57cec5SDimitry Andric   dumpTemplateDecl(D, true);
1360b57cec5SDimitry Andric }
1370b57cec5SDimitry Andric 
1380b57cec5SDimitry Andric void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
1390b57cec5SDimitry Andric   dumpTemplateDecl(D, false);
1400b57cec5SDimitry Andric }
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
1430b57cec5SDimitry Andric   dumpTemplateDecl(D, false);
1440b57cec5SDimitry Andric }
1450b57cec5SDimitry Andric 
1460b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1470b57cec5SDimitry Andric // Type method implementations
1480b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1490b57cec5SDimitry Andric 
1500b57cec5SDimitry Andric void QualType::dump(const char *msg) const {
1510b57cec5SDimitry Andric   if (msg)
1520b57cec5SDimitry Andric     llvm::errs() << msg << ": ";
1530b57cec5SDimitry Andric   dump();
1540b57cec5SDimitry Andric }
1550b57cec5SDimitry Andric 
1565ffd83dbSDimitry Andric LLVM_DUMP_METHOD void QualType::dump() const {
1575ffd83dbSDimitry Andric   ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
1580b57cec5SDimitry Andric   Dumper.Visit(*this);
1590b57cec5SDimitry Andric }
1600b57cec5SDimitry Andric 
1615ffd83dbSDimitry Andric LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS,
1625ffd83dbSDimitry Andric                                      const ASTContext &Context) const {
1635ffd83dbSDimitry Andric   ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
1645ffd83dbSDimitry Andric   Dumper.Visit(*this);
1655ffd83dbSDimitry Andric }
1660b57cec5SDimitry Andric 
1675ffd83dbSDimitry Andric LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
1685ffd83dbSDimitry Andric 
1695ffd83dbSDimitry Andric LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS,
1705ffd83dbSDimitry Andric                                  const ASTContext &Context) const {
1715ffd83dbSDimitry Andric   QualType(this, 0).dump(OS, Context);
1720b57cec5SDimitry Andric }
1730b57cec5SDimitry Andric 
1740b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1750b57cec5SDimitry Andric // Decl method implementations
1760b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1770b57cec5SDimitry Andric 
1780b57cec5SDimitry Andric LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
1790b57cec5SDimitry Andric 
1800b57cec5SDimitry Andric LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
1810b57cec5SDimitry Andric                                  ASTDumpOutputFormat Format) const {
1820b57cec5SDimitry Andric   ASTContext &Ctx = getASTContext();
1830b57cec5SDimitry Andric   const SourceManager &SM = Ctx.getSourceManager();
1840b57cec5SDimitry Andric 
1850b57cec5SDimitry Andric   if (ADOF_JSON == Format) {
1860b57cec5SDimitry Andric     JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
1870b57cec5SDimitry Andric                  &Ctx.getCommentCommandTraits());
1880b57cec5SDimitry Andric     (void)Deserialize; // FIXME?
1890b57cec5SDimitry Andric     P.Visit(this);
1900b57cec5SDimitry Andric   } else {
1915ffd83dbSDimitry Andric     ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
1920b57cec5SDimitry Andric     P.setDeserialize(Deserialize);
1930b57cec5SDimitry Andric     P.Visit(this);
1940b57cec5SDimitry Andric   }
1950b57cec5SDimitry Andric }
1960b57cec5SDimitry Andric 
1970b57cec5SDimitry Andric LLVM_DUMP_METHOD void Decl::dumpColor() const {
1980b57cec5SDimitry Andric   const ASTContext &Ctx = getASTContext();
1995ffd83dbSDimitry Andric   ASTDumper P(llvm::errs(), Ctx, /*ShowColors=*/true);
2000b57cec5SDimitry Andric   P.Visit(this);
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
2040b57cec5SDimitry Andric   dumpLookups(llvm::errs());
2050b57cec5SDimitry Andric }
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
2080b57cec5SDimitry Andric                                                bool DumpDecls,
2090b57cec5SDimitry Andric                                                bool Deserialize) const {
2100b57cec5SDimitry Andric   const DeclContext *DC = this;
2110b57cec5SDimitry Andric   while (!DC->isTranslationUnit())
2120b57cec5SDimitry Andric     DC = DC->getParent();
2135ffd83dbSDimitry Andric   const ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
2145ffd83dbSDimitry Andric   ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
2150b57cec5SDimitry Andric   P.setDeserialize(Deserialize);
2160b57cec5SDimitry Andric   P.dumpLookups(this, DumpDecls);
2170b57cec5SDimitry Andric }
2180b57cec5SDimitry Andric 
2190b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2200b57cec5SDimitry Andric // Stmt method implementations
2210b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2220b57cec5SDimitry Andric 
2230b57cec5SDimitry Andric LLVM_DUMP_METHOD void Stmt::dump() const {
2245ffd83dbSDimitry Andric   ASTDumper P(llvm::errs(), /*ShowColors=*/false);
2255ffd83dbSDimitry Andric   P.Visit(this);
2265ffd83dbSDimitry Andric }
2275ffd83dbSDimitry Andric 
2285ffd83dbSDimitry Andric LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS,
2295ffd83dbSDimitry Andric                                  const ASTContext &Context) const {
2305ffd83dbSDimitry Andric   ASTDumper P(OS, Context, Context.getDiagnostics().getShowColors());
2310b57cec5SDimitry Andric   P.Visit(this);
2320b57cec5SDimitry Andric }
2330b57cec5SDimitry Andric 
2340b57cec5SDimitry Andric LLVM_DUMP_METHOD void Stmt::dumpColor() const {
2355ffd83dbSDimitry Andric   ASTDumper P(llvm::errs(), /*ShowColors=*/true);
2360b57cec5SDimitry Andric   P.Visit(this);
2370b57cec5SDimitry Andric }
2380b57cec5SDimitry Andric 
2390b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2400b57cec5SDimitry Andric // Comment method implementations
2410b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2420b57cec5SDimitry Andric 
2430b57cec5SDimitry Andric LLVM_DUMP_METHOD void Comment::dump() const {
2445ffd83dbSDimitry Andric   const auto *FC = dyn_cast<FullComment>(this);
2450b57cec5SDimitry Andric   if (!FC)
2460b57cec5SDimitry Andric     return;
2475ffd83dbSDimitry Andric   ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
2485ffd83dbSDimitry Andric   Dumper.Visit(FC, FC);
2495ffd83dbSDimitry Andric }
2505ffd83dbSDimitry Andric 
2515ffd83dbSDimitry Andric LLVM_DUMP_METHOD void Comment::dump(raw_ostream &OS,
2525ffd83dbSDimitry Andric                                     const ASTContext &Context) const {
2535ffd83dbSDimitry Andric   const auto *FC = dyn_cast<FullComment>(this);
2545ffd83dbSDimitry Andric   if (!FC)
2555ffd83dbSDimitry Andric     return;
2565ffd83dbSDimitry Andric   ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
2575ffd83dbSDimitry Andric   Dumper.Visit(FC, FC);
2580b57cec5SDimitry Andric }
2590b57cec5SDimitry Andric 
2600b57cec5SDimitry Andric LLVM_DUMP_METHOD void Comment::dumpColor() const {
2615ffd83dbSDimitry Andric   const auto *FC = dyn_cast<FullComment>(this);
2620b57cec5SDimitry Andric   if (!FC)
2630b57cec5SDimitry Andric     return;
2645ffd83dbSDimitry Andric   ASTDumper Dumper(llvm::errs(), /*ShowColors=*/true);
2655ffd83dbSDimitry Andric   Dumper.Visit(FC, FC);
2665ffd83dbSDimitry Andric }
2675ffd83dbSDimitry Andric 
2685ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
2695ffd83dbSDimitry Andric // APValue method implementations
2705ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
2715ffd83dbSDimitry Andric 
2725ffd83dbSDimitry Andric LLVM_DUMP_METHOD void APValue::dump() const {
2735ffd83dbSDimitry Andric   ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
2745ffd83dbSDimitry Andric   Dumper.Visit(*this, /*Ty=*/QualType());
2755ffd83dbSDimitry Andric }
2765ffd83dbSDimitry Andric 
2775ffd83dbSDimitry Andric LLVM_DUMP_METHOD void APValue::dump(raw_ostream &OS,
2785ffd83dbSDimitry Andric                                     const ASTContext &Context) const {
2795ffd83dbSDimitry Andric   ASTDumper Dumper(llvm::errs(), Context,
2805ffd83dbSDimitry Andric                    Context.getDiagnostics().getShowColors());
2815ffd83dbSDimitry Andric   Dumper.Visit(*this, /*Ty=*/Context.getPointerType(Context.CharTy));
2820b57cec5SDimitry Andric }
283