Mercurial > hg > CbC > CbC_llvm
view clang/lib/Frontend/ASTConsumers.cpp @ 176:de4ac79aef9d
...
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Mon, 25 May 2020 17:13:11 +0900 |
parents | 1d019706d866 |
children | 2e18cbf3894f |
line wrap: on
line source
//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception // //===----------------------------------------------------------------------===// // // AST Consumer Implementations. // //===----------------------------------------------------------------------===// #include "clang/Frontend/ASTConsumers.h" #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" #include "clang/AST/PrettyPrinter.h" #include "clang/AST/RecordLayout.h" #include "clang/AST/RecursiveASTVisitor.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" #include "llvm/Support/Path.h" #include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" using namespace clang; //===----------------------------------------------------------------------===// /// ASTPrinter - Pretty-printer and dumper of ASTs namespace { class ASTPrinter : public ASTConsumer, public RecursiveASTVisitor<ASTPrinter> { typedef RecursiveASTVisitor<ASTPrinter> base; public: enum Kind { DumpFull, Dump, Print, None }; ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K, ASTDumpOutputFormat Format, StringRef FilterString, bool DumpLookups = false) : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)), OutputKind(K), OutputFormat(Format), FilterString(FilterString), DumpLookups(DumpLookups) {} void HandleTranslationUnit(ASTContext &Context) override { TranslationUnitDecl *D = Context.getTranslationUnitDecl(); if (FilterString.empty()) return print(D); TraverseDecl(D); } bool shouldWalkTypesOfTypeLocs() const { return false; } bool TraverseDecl(Decl *D) { if (D && filterMatches(D)) { bool ShowColors = Out.has_colors(); if (ShowColors) Out.changeColor(raw_ostream::BLUE); Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D) << ":\n"; if (ShowColors) Out.resetColor(); print(D); Out << "\n"; // Don't traverse child nodes to avoid output duplication. return true; } return base::TraverseDecl(D); } private: std::string getName(Decl *D) { if (isa<NamedDecl>(D)) return cast<NamedDecl>(D)->getQualifiedNameAsString(); return ""; } bool filterMatches(Decl *D) { return getName(D).find(FilterString) != std::string::npos; } void print(Decl *D) { if (DumpLookups) { if (DeclContext *DC = dyn_cast<DeclContext>(D)) { if (DC == DC->getPrimaryContext()) DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull); else Out << "Lookup map is in primary DeclContext " << DC->getPrimaryContext() << "\n"; } else Out << "Not a DeclContext\n"; } else if (OutputKind == Print) { PrintingPolicy Policy(D->getASTContext().getLangOpts()); D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true); } else if (OutputKind != None) D->dump(Out, OutputKind == DumpFull, OutputFormat); } raw_ostream &Out; std::unique_ptr<raw_ostream> OwnedOut; /// How to output individual declarations. Kind OutputKind; /// What format should the output take? ASTDumpOutputFormat OutputFormat; /// Which declarations or DeclContexts to display. std::string FilterString; /// Whether the primary output is lookup results or declarations. Individual /// results will be output with a format determined by OutputKind. This is /// incompatible with OutputKind == Print. bool DumpLookups; }; class ASTDeclNodeLister : public ASTConsumer, public RecursiveASTVisitor<ASTDeclNodeLister> { public: ASTDeclNodeLister(raw_ostream *Out = nullptr) : Out(Out ? *Out : llvm::outs()) {} void HandleTranslationUnit(ASTContext &Context) override { TraverseDecl(Context.getTranslationUnitDecl()); } bool shouldWalkTypesOfTypeLocs() const { return false; } bool VisitNamedDecl(NamedDecl *D) { D->printQualifiedName(Out); Out << '\n'; return true; } private: raw_ostream &Out; }; } // end anonymous namespace std::unique_ptr<ASTConsumer> clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out, StringRef FilterString) { return std::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print, ADOF_Default, FilterString); } std::unique_ptr<ASTConsumer> clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out, StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups, ASTDumpOutputFormat Format) { assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump"); return std::make_unique<ASTPrinter>(std::move(Out), Deserialize ? ASTPrinter::DumpFull : DumpDecls ? ASTPrinter::Dump : ASTPrinter::None, Format, FilterString, DumpLookups); } std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() { return std::make_unique<ASTDeclNodeLister>(nullptr); } //===----------------------------------------------------------------------===// /// ASTViewer - AST Visualization namespace { class ASTViewer : public ASTConsumer { ASTContext *Context; public: void Initialize(ASTContext &Context) override { this->Context = &Context; } bool HandleTopLevelDecl(DeclGroupRef D) override { for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I) HandleTopLevelSingleDecl(*I); return true; } void HandleTopLevelSingleDecl(Decl *D); }; } void ASTViewer::HandleTopLevelSingleDecl(Decl *D) { if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) { D->print(llvm::errs()); if (Stmt *Body = D->getBody()) { llvm::errs() << '\n'; Body->viewAST(); llvm::errs() << '\n'; } } } std::unique_ptr<ASTConsumer> clang::CreateASTViewer() { return std::make_unique<ASTViewer>(); }