Path: blob/main/contrib/llvm-project/clang/lib/Frontend/ASTConsumers.cpp
35234 views
//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//1//2// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.3// See https://llvm.org/LICENSE.txt for license information.4// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception5//6//===----------------------------------------------------------------------===//7//8// AST Consumer Implementations.9//10//===----------------------------------------------------------------------===//1112#include "clang/Frontend/ASTConsumers.h"13#include "clang/AST/AST.h"14#include "clang/AST/ASTConsumer.h"15#include "clang/AST/ASTContext.h"16#include "clang/AST/PrettyPrinter.h"17#include "clang/AST/RecordLayout.h"18#include "clang/AST/RecursiveASTVisitor.h"19#include "clang/Basic/Diagnostic.h"20#include "clang/Basic/SourceManager.h"21#include "llvm/Support/Path.h"22#include "llvm/Support/Timer.h"23#include "llvm/Support/raw_ostream.h"24using namespace clang;2526//===----------------------------------------------------------------------===//27/// ASTPrinter - Pretty-printer and dumper of ASTs2829namespace {30class ASTPrinter : public ASTConsumer,31public RecursiveASTVisitor<ASTPrinter> {32typedef RecursiveASTVisitor<ASTPrinter> base;3334public:35enum Kind { DumpFull, Dump, Print, None };36ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K,37ASTDumpOutputFormat Format, StringRef FilterString,38bool DumpLookups = false, bool DumpDeclTypes = false)39: Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),40OutputKind(K), OutputFormat(Format), FilterString(FilterString),41DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {}4243void HandleTranslationUnit(ASTContext &Context) override {44TranslationUnitDecl *D = Context.getTranslationUnitDecl();4546if (FilterString.empty())47return print(D);4849TraverseDecl(D);50}5152bool shouldWalkTypesOfTypeLocs() const { return false; }5354bool TraverseDecl(Decl *D) {55if (D && filterMatches(D)) {56bool ShowColors = Out.has_colors();57if (ShowColors)58Out.changeColor(raw_ostream::BLUE);5960if (OutputFormat == ADOF_Default)61Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)62<< ":\n";6364if (ShowColors)65Out.resetColor();66print(D);67Out << "\n";68// Don't traverse child nodes to avoid output duplication.69return true;70}71return base::TraverseDecl(D);72}7374private:75std::string getName(Decl *D) {76if (isa<NamedDecl>(D))77return cast<NamedDecl>(D)->getQualifiedNameAsString();78return "";79}80bool filterMatches(Decl *D) {81return getName(D).find(FilterString) != std::string::npos;82}83void print(Decl *D) {84if (DumpLookups) {85if (DeclContext *DC = dyn_cast<DeclContext>(D)) {86if (DC == DC->getPrimaryContext())87DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);88else89Out << "Lookup map is in primary DeclContext "90<< DC->getPrimaryContext() << "\n";91} else92Out << "Not a DeclContext\n";93} else if (OutputKind == Print) {94PrintingPolicy Policy(D->getASTContext().getLangOpts());95D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);96} else if (OutputKind != None) {97D->dump(Out, OutputKind == DumpFull, OutputFormat);98}99100if (DumpDeclTypes) {101Decl *InnerD = D;102if (auto *TD = dyn_cast<TemplateDecl>(D))103InnerD = TD->getTemplatedDecl();104105// FIXME: Support OutputFormat in type dumping.106// FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups.107if (auto *VD = dyn_cast<ValueDecl>(InnerD))108VD->getType().dump(Out, VD->getASTContext());109if (auto *TD = dyn_cast<TypeDecl>(InnerD))110TD->getTypeForDecl()->dump(Out, TD->getASTContext());111}112}113114raw_ostream &Out;115std::unique_ptr<raw_ostream> OwnedOut;116117/// How to output individual declarations.118Kind OutputKind;119120/// What format should the output take?121ASTDumpOutputFormat OutputFormat;122123/// Which declarations or DeclContexts to display.124std::string FilterString;125126/// Whether the primary output is lookup results or declarations. Individual127/// results will be output with a format determined by OutputKind. This is128/// incompatible with OutputKind == Print.129bool DumpLookups;130131/// Whether to dump the type for each declaration dumped.132bool DumpDeclTypes;133};134135class ASTDeclNodeLister : public ASTConsumer,136public RecursiveASTVisitor<ASTDeclNodeLister> {137public:138ASTDeclNodeLister(raw_ostream *Out = nullptr)139: Out(Out ? *Out : llvm::outs()) {}140141void HandleTranslationUnit(ASTContext &Context) override {142TraverseDecl(Context.getTranslationUnitDecl());143}144145bool shouldWalkTypesOfTypeLocs() const { return false; }146147bool VisitNamedDecl(NamedDecl *D) {148D->printQualifiedName(Out);149Out << '\n';150return true;151}152153private:154raw_ostream &Out;155};156} // end anonymous namespace157158std::unique_ptr<ASTConsumer>159clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,160StringRef FilterString) {161return std::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,162ADOF_Default, FilterString);163}164165std::unique_ptr<ASTConsumer>166clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out, StringRef FilterString,167bool DumpDecls, bool Deserialize, bool DumpLookups,168bool DumpDeclTypes, ASTDumpOutputFormat Format) {169assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");170return std::make_unique<ASTPrinter>(171std::move(Out),172Deserialize ? ASTPrinter::DumpFull173: DumpDecls ? ASTPrinter::Dump : ASTPrinter::None,174Format, FilterString, DumpLookups, DumpDeclTypes);175}176177std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {178return std::make_unique<ASTDeclNodeLister>(nullptr);179}180181//===----------------------------------------------------------------------===//182/// ASTViewer - AST Visualization183184namespace {185class ASTViewer : public ASTConsumer {186ASTContext *Context = nullptr;187188public:189void Initialize(ASTContext &Context) override { this->Context = &Context; }190191bool HandleTopLevelDecl(DeclGroupRef D) override {192for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)193HandleTopLevelSingleDecl(*I);194return true;195}196197void HandleTopLevelSingleDecl(Decl *D);198};199}200201void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {202if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {203D->print(llvm::errs());204205if (Stmt *Body = D->getBody()) {206llvm::errs() << '\n';207Body->viewAST();208llvm::errs() << '\n';209}210}211}212213std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {214return std::make_unique<ASTViewer>();215}216217218