xref: /freebsd/contrib/llvm-project/clang/lib/AST/ASTDumper.cpp (revision 5f757f3ff9144b609b3c433dfd370cc6bdc191ad)
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"
15*5f757f3fSDimitry Andric #include "clang/AST/ASTConcept.h"
160b57cec5SDimitry Andric #include "clang/AST/ASTContext.h"
170b57cec5SDimitry Andric #include "clang/AST/DeclLookups.h"
180b57cec5SDimitry Andric #include "clang/AST/JSONNodeDumper.h"
190b57cec5SDimitry Andric #include "clang/Basic/Builtins.h"
200b57cec5SDimitry Andric #include "clang/Basic/Module.h"
210b57cec5SDimitry Andric #include "clang/Basic/SourceManager.h"
220b57cec5SDimitry Andric #include "llvm/Support/raw_ostream.h"
23bdd1243dSDimitry Andric 
240b57cec5SDimitry Andric using namespace clang;
250b57cec5SDimitry Andric using namespace clang::comments;
260b57cec5SDimitry Andric 
27bdd1243dSDimitry Andric void ASTDumper::dumpInvalidDeclContext(const DeclContext *DC) {
28bdd1243dSDimitry Andric   NodeDumper.AddChild([=] {
29bdd1243dSDimitry Andric     if (!DC) {
30bdd1243dSDimitry Andric       ColorScope Color(OS, ShowColors, NullColor);
31bdd1243dSDimitry Andric       OS << "<<<NULL>>>";
32bdd1243dSDimitry Andric       return;
33bdd1243dSDimitry Andric     }
34bdd1243dSDimitry Andric     // An invalid DeclContext is one for which a dyn_cast() from a DeclContext
35bdd1243dSDimitry Andric     // pointer to a Decl pointer would fail an assertion or otherwise fall prey
36bdd1243dSDimitry Andric     // to undefined behavior as a result of an invalid associated DeclKind.
37bdd1243dSDimitry Andric     // Such invalidity is not supposed to happen of course, but, when it does,
38bdd1243dSDimitry Andric     // the information provided below is intended to provide some hints about
39bdd1243dSDimitry Andric     // what might have gone awry.
40bdd1243dSDimitry Andric     {
41bdd1243dSDimitry Andric       ColorScope Color(OS, ShowColors, DeclKindNameColor);
42bdd1243dSDimitry Andric       OS << "DeclContext";
43bdd1243dSDimitry Andric     }
44bdd1243dSDimitry Andric     NodeDumper.dumpPointer(DC);
45bdd1243dSDimitry Andric     OS << " <";
46bdd1243dSDimitry Andric     {
47bdd1243dSDimitry Andric       ColorScope Color(OS, ShowColors, DeclNameColor);
48bdd1243dSDimitry Andric       OS << "unrecognized Decl kind " << (unsigned)DC->getDeclKind();
49bdd1243dSDimitry Andric     }
50bdd1243dSDimitry Andric     OS << ">";
51bdd1243dSDimitry Andric   });
52bdd1243dSDimitry Andric }
53bdd1243dSDimitry Andric 
540b57cec5SDimitry Andric void ASTDumper::dumpLookups(const DeclContext *DC, bool DumpDecls) {
550b57cec5SDimitry Andric   NodeDumper.AddChild([=] {
560b57cec5SDimitry Andric     OS << "StoredDeclsMap ";
570b57cec5SDimitry Andric     NodeDumper.dumpBareDeclRef(cast<Decl>(DC));
580b57cec5SDimitry Andric 
590b57cec5SDimitry Andric     const DeclContext *Primary = DC->getPrimaryContext();
600b57cec5SDimitry Andric     if (Primary != DC) {
610b57cec5SDimitry Andric       OS << " primary";
620b57cec5SDimitry Andric       NodeDumper.dumpPointer(cast<Decl>(Primary));
630b57cec5SDimitry Andric     }
640b57cec5SDimitry Andric 
650b57cec5SDimitry Andric     bool HasUndeserializedLookups = Primary->hasExternalVisibleStorage();
660b57cec5SDimitry Andric 
670b57cec5SDimitry Andric     auto Range = getDeserialize()
680b57cec5SDimitry Andric                      ? Primary->lookups()
690b57cec5SDimitry Andric                      : Primary->noload_lookups(/*PreserveInternalState=*/true);
700b57cec5SDimitry Andric     for (auto I = Range.begin(), E = Range.end(); I != E; ++I) {
710b57cec5SDimitry Andric       DeclarationName Name = I.getLookupName();
720b57cec5SDimitry Andric       DeclContextLookupResult R = *I;
730b57cec5SDimitry Andric 
740b57cec5SDimitry Andric       NodeDumper.AddChild([=] {
750b57cec5SDimitry Andric         OS << "DeclarationName ";
760b57cec5SDimitry Andric         {
770b57cec5SDimitry Andric           ColorScope Color(OS, ShowColors, DeclNameColor);
780b57cec5SDimitry Andric           OS << '\'' << Name << '\'';
790b57cec5SDimitry Andric         }
800b57cec5SDimitry Andric 
810b57cec5SDimitry Andric         for (DeclContextLookupResult::iterator RI = R.begin(), RE = R.end();
820b57cec5SDimitry Andric              RI != RE; ++RI) {
830b57cec5SDimitry Andric           NodeDumper.AddChild([=] {
840b57cec5SDimitry Andric             NodeDumper.dumpBareDeclRef(*RI);
850b57cec5SDimitry Andric 
865ffd83dbSDimitry Andric             if (!(*RI)->isUnconditionallyVisible())
870b57cec5SDimitry Andric               OS << " hidden";
880b57cec5SDimitry Andric 
890b57cec5SDimitry Andric             // If requested, dump the redecl chain for this lookup.
900b57cec5SDimitry Andric             if (DumpDecls) {
910b57cec5SDimitry Andric               // Dump earliest decl first.
920b57cec5SDimitry Andric               std::function<void(Decl *)> DumpWithPrev = [&](Decl *D) {
930b57cec5SDimitry Andric                 if (Decl *Prev = D->getPreviousDecl())
940b57cec5SDimitry Andric                   DumpWithPrev(Prev);
950b57cec5SDimitry Andric                 Visit(D);
960b57cec5SDimitry Andric               };
970b57cec5SDimitry Andric               DumpWithPrev(*RI);
980b57cec5SDimitry Andric             }
990b57cec5SDimitry Andric           });
1000b57cec5SDimitry Andric         }
1010b57cec5SDimitry Andric       });
1020b57cec5SDimitry Andric     }
1030b57cec5SDimitry Andric 
1040b57cec5SDimitry Andric     if (HasUndeserializedLookups) {
1050b57cec5SDimitry Andric       NodeDumper.AddChild([=] {
1060b57cec5SDimitry Andric         ColorScope Color(OS, ShowColors, UndeserializedColor);
1070b57cec5SDimitry Andric         OS << "<undeserialized lookups>";
1080b57cec5SDimitry Andric       });
1090b57cec5SDimitry Andric     }
1100b57cec5SDimitry Andric   });
1110b57cec5SDimitry Andric }
1120b57cec5SDimitry Andric 
1130b57cec5SDimitry Andric template <typename SpecializationDecl>
1140b57cec5SDimitry Andric void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
1150b57cec5SDimitry Andric                                                bool DumpExplicitInst,
1160b57cec5SDimitry Andric                                                bool DumpRefOnly) {
1170b57cec5SDimitry Andric   bool DumpedAny = false;
1180b57cec5SDimitry Andric   for (const auto *RedeclWithBadType : D->redecls()) {
1190b57cec5SDimitry Andric     // FIXME: The redecls() range sometimes has elements of a less-specific
1200b57cec5SDimitry Andric     // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
1210b57cec5SDimitry Andric     // us TagDecls, and should give CXXRecordDecls).
122349cc55cSDimitry Andric     auto *Redecl = cast<SpecializationDecl>(RedeclWithBadType);
1230b57cec5SDimitry Andric     switch (Redecl->getTemplateSpecializationKind()) {
1240b57cec5SDimitry Andric     case TSK_ExplicitInstantiationDeclaration:
1250b57cec5SDimitry Andric     case TSK_ExplicitInstantiationDefinition:
1260b57cec5SDimitry Andric       if (!DumpExplicitInst)
1270b57cec5SDimitry Andric         break;
128bdd1243dSDimitry Andric       [[fallthrough]];
1290b57cec5SDimitry Andric     case TSK_Undeclared:
1300b57cec5SDimitry Andric     case TSK_ImplicitInstantiation:
1310b57cec5SDimitry Andric       if (DumpRefOnly)
1320b57cec5SDimitry Andric         NodeDumper.dumpDeclRef(Redecl);
1330b57cec5SDimitry Andric       else
1340b57cec5SDimitry Andric         Visit(Redecl);
1350b57cec5SDimitry Andric       DumpedAny = true;
1360b57cec5SDimitry Andric       break;
1370b57cec5SDimitry Andric     case TSK_ExplicitSpecialization:
1380b57cec5SDimitry Andric       break;
1390b57cec5SDimitry Andric     }
1400b57cec5SDimitry Andric   }
1410b57cec5SDimitry Andric 
1420b57cec5SDimitry Andric   // Ensure we dump at least one decl for each specialization.
1430b57cec5SDimitry Andric   if (!DumpedAny)
1440b57cec5SDimitry Andric     NodeDumper.dumpDeclRef(D);
1450b57cec5SDimitry Andric }
1460b57cec5SDimitry Andric 
1470b57cec5SDimitry Andric template <typename TemplateDecl>
1480b57cec5SDimitry Andric void ASTDumper::dumpTemplateDecl(const TemplateDecl *D, bool DumpExplicitInst) {
1490b57cec5SDimitry Andric   dumpTemplateParameters(D->getTemplateParameters());
1500b57cec5SDimitry Andric 
1510b57cec5SDimitry Andric   Visit(D->getTemplatedDecl());
1520b57cec5SDimitry Andric 
153e8d8bef9SDimitry Andric   if (GetTraversalKind() == TK_AsIs) {
1540b57cec5SDimitry Andric     for (const auto *Child : D->specializations())
1550b57cec5SDimitry Andric       dumpTemplateDeclSpecialization(Child, DumpExplicitInst,
1560b57cec5SDimitry Andric                                      !D->isCanonicalDecl());
1570b57cec5SDimitry Andric   }
158e8d8bef9SDimitry Andric }
1590b57cec5SDimitry Andric 
1600b57cec5SDimitry Andric void ASTDumper::VisitFunctionTemplateDecl(const FunctionTemplateDecl *D) {
1610b57cec5SDimitry Andric   // FIXME: We don't add a declaration of a function template specialization
1620b57cec5SDimitry Andric   // to its context when it's explicitly instantiated, so dump explicit
1630b57cec5SDimitry Andric   // instantiations when we dump the template itself.
1640b57cec5SDimitry Andric   dumpTemplateDecl(D, true);
1650b57cec5SDimitry Andric }
1660b57cec5SDimitry Andric 
1670b57cec5SDimitry Andric void ASTDumper::VisitClassTemplateDecl(const ClassTemplateDecl *D) {
1680b57cec5SDimitry Andric   dumpTemplateDecl(D, false);
1690b57cec5SDimitry Andric }
1700b57cec5SDimitry Andric 
1710b57cec5SDimitry Andric void ASTDumper::VisitVarTemplateDecl(const VarTemplateDecl *D) {
1720b57cec5SDimitry Andric   dumpTemplateDecl(D, false);
1730b57cec5SDimitry Andric }
1740b57cec5SDimitry Andric 
1750b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1760b57cec5SDimitry Andric // Type method implementations
1770b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
1780b57cec5SDimitry Andric 
1790b57cec5SDimitry Andric void QualType::dump(const char *msg) const {
1800b57cec5SDimitry Andric   if (msg)
1810b57cec5SDimitry Andric     llvm::errs() << msg << ": ";
1820b57cec5SDimitry Andric   dump();
1830b57cec5SDimitry Andric }
1840b57cec5SDimitry Andric 
1855ffd83dbSDimitry Andric LLVM_DUMP_METHOD void QualType::dump() const {
1865ffd83dbSDimitry Andric   ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
1870b57cec5SDimitry Andric   Dumper.Visit(*this);
1880b57cec5SDimitry Andric }
1890b57cec5SDimitry Andric 
1905ffd83dbSDimitry Andric LLVM_DUMP_METHOD void QualType::dump(llvm::raw_ostream &OS,
1915ffd83dbSDimitry Andric                                      const ASTContext &Context) const {
1925ffd83dbSDimitry Andric   ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
1935ffd83dbSDimitry Andric   Dumper.Visit(*this);
1945ffd83dbSDimitry Andric }
1950b57cec5SDimitry Andric 
1965ffd83dbSDimitry Andric LLVM_DUMP_METHOD void Type::dump() const { QualType(this, 0).dump(); }
1975ffd83dbSDimitry Andric 
1985ffd83dbSDimitry Andric LLVM_DUMP_METHOD void Type::dump(llvm::raw_ostream &OS,
1995ffd83dbSDimitry Andric                                  const ASTContext &Context) const {
2005ffd83dbSDimitry Andric   QualType(this, 0).dump(OS, Context);
2010b57cec5SDimitry Andric }
2020b57cec5SDimitry Andric 
2030b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2040b57cec5SDimitry Andric // Decl method implementations
2050b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2060b57cec5SDimitry Andric 
2070b57cec5SDimitry Andric LLVM_DUMP_METHOD void Decl::dump() const { dump(llvm::errs()); }
2080b57cec5SDimitry Andric 
2090b57cec5SDimitry Andric LLVM_DUMP_METHOD void Decl::dump(raw_ostream &OS, bool Deserialize,
2100b57cec5SDimitry Andric                                  ASTDumpOutputFormat Format) const {
2110b57cec5SDimitry Andric   ASTContext &Ctx = getASTContext();
2120b57cec5SDimitry Andric   const SourceManager &SM = Ctx.getSourceManager();
2130b57cec5SDimitry Andric 
2140b57cec5SDimitry Andric   if (ADOF_JSON == Format) {
2150b57cec5SDimitry Andric     JSONDumper P(OS, SM, Ctx, Ctx.getPrintingPolicy(),
2160b57cec5SDimitry Andric                  &Ctx.getCommentCommandTraits());
2170b57cec5SDimitry Andric     (void)Deserialize; // FIXME?
2180b57cec5SDimitry Andric     P.Visit(this);
2190b57cec5SDimitry Andric   } else {
2205ffd83dbSDimitry Andric     ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
2210b57cec5SDimitry Andric     P.setDeserialize(Deserialize);
2220b57cec5SDimitry Andric     P.Visit(this);
2230b57cec5SDimitry Andric   }
2240b57cec5SDimitry Andric }
2250b57cec5SDimitry Andric 
2260b57cec5SDimitry Andric LLVM_DUMP_METHOD void Decl::dumpColor() const {
2270b57cec5SDimitry Andric   const ASTContext &Ctx = getASTContext();
2285ffd83dbSDimitry Andric   ASTDumper P(llvm::errs(), Ctx, /*ShowColors=*/true);
2290b57cec5SDimitry Andric   P.Visit(this);
2300b57cec5SDimitry Andric }
2310b57cec5SDimitry Andric 
232bdd1243dSDimitry Andric LLVM_DUMP_METHOD void DeclContext::dumpAsDecl() const {
233bdd1243dSDimitry Andric   dumpAsDecl(nullptr);
234bdd1243dSDimitry Andric }
235bdd1243dSDimitry Andric 
236bdd1243dSDimitry Andric LLVM_DUMP_METHOD void DeclContext::dumpAsDecl(const ASTContext *Ctx) const {
237bdd1243dSDimitry Andric   // By design, DeclContext is required to be a base class of some class that
238bdd1243dSDimitry Andric   // derives from Decl. Thus, it should always be possible to dyn_cast() from
239bdd1243dSDimitry Andric   // a DeclContext pointer to a Decl pointer and Decl::castFromDeclContext()
240bdd1243dSDimitry Andric   // asserts that to be the case. Since this function is intended for use in a
241bdd1243dSDimitry Andric   // debugger, it performs an additional check in order to prevent a failed
242bdd1243dSDimitry Andric   // cast and assertion. If that check fails, then the (invalid) DeclContext
243bdd1243dSDimitry Andric   // is dumped with an indication of its invalidity.
244bdd1243dSDimitry Andric   if (hasValidDeclKind()) {
245bdd1243dSDimitry Andric     const auto *D = cast<Decl>(this);
246bdd1243dSDimitry Andric     D->dump();
247bdd1243dSDimitry Andric   } else {
248bdd1243dSDimitry Andric     // If an ASTContext is not available, a less capable ASTDumper is
249bdd1243dSDimitry Andric     // constructed for which color diagnostics are, regrettably, disabled.
250bdd1243dSDimitry Andric     ASTDumper P = Ctx ? ASTDumper(llvm::errs(), *Ctx,
251bdd1243dSDimitry Andric                                   Ctx->getDiagnostics().getShowColors())
252bdd1243dSDimitry Andric                       : ASTDumper(llvm::errs(), /*ShowColors*/ false);
253bdd1243dSDimitry Andric     P.dumpInvalidDeclContext(this);
254bdd1243dSDimitry Andric   }
255bdd1243dSDimitry Andric }
256bdd1243dSDimitry Andric 
2570b57cec5SDimitry Andric LLVM_DUMP_METHOD void DeclContext::dumpLookups() const {
2580b57cec5SDimitry Andric   dumpLookups(llvm::errs());
2590b57cec5SDimitry Andric }
2600b57cec5SDimitry Andric 
2610b57cec5SDimitry Andric LLVM_DUMP_METHOD void DeclContext::dumpLookups(raw_ostream &OS,
2620b57cec5SDimitry Andric                                                bool DumpDecls,
2630b57cec5SDimitry Andric                                                bool Deserialize) const {
2640b57cec5SDimitry Andric   const DeclContext *DC = this;
2650b57cec5SDimitry Andric   while (!DC->isTranslationUnit())
2660b57cec5SDimitry Andric     DC = DC->getParent();
2675ffd83dbSDimitry Andric   const ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
2685ffd83dbSDimitry Andric   ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
2690b57cec5SDimitry Andric   P.setDeserialize(Deserialize);
2700b57cec5SDimitry Andric   P.dumpLookups(this, DumpDecls);
2710b57cec5SDimitry Andric }
2720b57cec5SDimitry Andric 
2730b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2740b57cec5SDimitry Andric // Stmt method implementations
2750b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2760b57cec5SDimitry Andric 
2770b57cec5SDimitry Andric LLVM_DUMP_METHOD void Stmt::dump() const {
2785ffd83dbSDimitry Andric   ASTDumper P(llvm::errs(), /*ShowColors=*/false);
2795ffd83dbSDimitry Andric   P.Visit(this);
2805ffd83dbSDimitry Andric }
2815ffd83dbSDimitry Andric 
2825ffd83dbSDimitry Andric LLVM_DUMP_METHOD void Stmt::dump(raw_ostream &OS,
2835ffd83dbSDimitry Andric                                  const ASTContext &Context) const {
2845ffd83dbSDimitry Andric   ASTDumper P(OS, Context, Context.getDiagnostics().getShowColors());
2850b57cec5SDimitry Andric   P.Visit(this);
2860b57cec5SDimitry Andric }
2870b57cec5SDimitry Andric 
2880b57cec5SDimitry Andric LLVM_DUMP_METHOD void Stmt::dumpColor() const {
2895ffd83dbSDimitry Andric   ASTDumper P(llvm::errs(), /*ShowColors=*/true);
2900b57cec5SDimitry Andric   P.Visit(this);
2910b57cec5SDimitry Andric }
2920b57cec5SDimitry Andric 
2930b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2940b57cec5SDimitry Andric // Comment method implementations
2950b57cec5SDimitry Andric //===----------------------------------------------------------------------===//
2960b57cec5SDimitry Andric 
2970b57cec5SDimitry Andric LLVM_DUMP_METHOD void Comment::dump() const {
2985ffd83dbSDimitry Andric   const auto *FC = dyn_cast<FullComment>(this);
2990b57cec5SDimitry Andric   if (!FC)
3000b57cec5SDimitry Andric     return;
3015ffd83dbSDimitry Andric   ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
3025ffd83dbSDimitry Andric   Dumper.Visit(FC, FC);
3035ffd83dbSDimitry Andric }
3045ffd83dbSDimitry Andric 
3055ffd83dbSDimitry Andric LLVM_DUMP_METHOD void Comment::dump(raw_ostream &OS,
3065ffd83dbSDimitry Andric                                     const ASTContext &Context) const {
3075ffd83dbSDimitry Andric   const auto *FC = dyn_cast<FullComment>(this);
3085ffd83dbSDimitry Andric   if (!FC)
3095ffd83dbSDimitry Andric     return;
3105ffd83dbSDimitry Andric   ASTDumper Dumper(OS, Context, Context.getDiagnostics().getShowColors());
3115ffd83dbSDimitry Andric   Dumper.Visit(FC, FC);
3120b57cec5SDimitry Andric }
3130b57cec5SDimitry Andric 
3140b57cec5SDimitry Andric LLVM_DUMP_METHOD void Comment::dumpColor() const {
3155ffd83dbSDimitry Andric   const auto *FC = dyn_cast<FullComment>(this);
3160b57cec5SDimitry Andric   if (!FC)
3170b57cec5SDimitry Andric     return;
3185ffd83dbSDimitry Andric   ASTDumper Dumper(llvm::errs(), /*ShowColors=*/true);
3195ffd83dbSDimitry Andric   Dumper.Visit(FC, FC);
3205ffd83dbSDimitry Andric }
3215ffd83dbSDimitry Andric 
3225ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
3235ffd83dbSDimitry Andric // APValue method implementations
3245ffd83dbSDimitry Andric //===----------------------------------------------------------------------===//
3255ffd83dbSDimitry Andric 
3265ffd83dbSDimitry Andric LLVM_DUMP_METHOD void APValue::dump() const {
3275ffd83dbSDimitry Andric   ASTDumper Dumper(llvm::errs(), /*ShowColors=*/false);
3285ffd83dbSDimitry Andric   Dumper.Visit(*this, /*Ty=*/QualType());
3295ffd83dbSDimitry Andric }
3305ffd83dbSDimitry Andric 
3315ffd83dbSDimitry Andric LLVM_DUMP_METHOD void APValue::dump(raw_ostream &OS,
3325ffd83dbSDimitry Andric                                     const ASTContext &Context) const {
3335ffd83dbSDimitry Andric   ASTDumper Dumper(llvm::errs(), Context,
3345ffd83dbSDimitry Andric                    Context.getDiagnostics().getShowColors());
3355ffd83dbSDimitry Andric   Dumper.Visit(*this, /*Ty=*/Context.getPointerType(Context.CharTy));
3360b57cec5SDimitry Andric }
337*5f757f3fSDimitry Andric 
338*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
339*5f757f3fSDimitry Andric // ConceptReference method implementations
340*5f757f3fSDimitry Andric //===----------------------------------------------------------------------===//
341*5f757f3fSDimitry Andric 
342*5f757f3fSDimitry Andric LLVM_DUMP_METHOD void ConceptReference::dump() const {
343*5f757f3fSDimitry Andric   dump(llvm::errs());
344*5f757f3fSDimitry Andric }
345*5f757f3fSDimitry Andric 
346*5f757f3fSDimitry Andric LLVM_DUMP_METHOD void ConceptReference::dump(raw_ostream &OS) const {
347*5f757f3fSDimitry Andric   auto &Ctx = getNamedConcept()->getASTContext();
348*5f757f3fSDimitry Andric   ASTDumper P(OS, Ctx, Ctx.getDiagnostics().getShowColors());
349*5f757f3fSDimitry Andric   P.Visit(this);
350*5f757f3fSDimitry Andric }
351