brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.0 KiB · 67c8761 Raw
238 lines · cpp
1//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8//9// AST Consumer Implementations.10//11//===----------------------------------------------------------------------===//12 13#include "clang/Frontend/ASTConsumers.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 "llvm/Support/Timer.h"21#include "llvm/Support/raw_ostream.h"22using namespace clang;23 24//===----------------------------------------------------------------------===//25/// ASTPrinter - Pretty-printer and dumper of ASTs26 27namespace {28  class ASTPrinter : public ASTConsumer,29                     public RecursiveASTVisitor<ASTPrinter> {30    typedef RecursiveASTVisitor<ASTPrinter> base;31 32  public:33    enum Kind { DumpFull, Dump, Print, None };34    ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K,35               ASTDumpOutputFormat Format, StringRef FilterString,36               bool DumpLookups = false, bool DumpDeclTypes = false)37        : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),38          OutputKind(K), OutputFormat(Format), FilterString(FilterString),39          DumpLookups(DumpLookups), DumpDeclTypes(DumpDeclTypes) {}40 41    ASTPrinter(raw_ostream &Out, Kind K, ASTDumpOutputFormat Format,42               StringRef FilterString, bool DumpLookups = false,43               bool DumpDeclTypes = false)44        : Out(Out), OwnedOut(nullptr), OutputKind(K), OutputFormat(Format),45          FilterString(FilterString), DumpLookups(DumpLookups),46          DumpDeclTypes(DumpDeclTypes) {}47 48    void HandleTranslationUnit(ASTContext &Context) override {49      TranslationUnitDecl *D = Context.getTranslationUnitDecl();50 51      if (FilterString.empty())52        return print(D);53 54      TraverseDecl(D);55    }56 57    bool shouldWalkTypesOfTypeLocs() const { return false; }58 59    bool TraverseDecl(Decl *D) {60      if (D && filterMatches(D)) {61        bool ShowColors = Out.has_colors();62        if (ShowColors)63          Out.changeColor(raw_ostream::BLUE);64 65        if (OutputFormat == ADOF_Default)66          Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)67              << ":\n";68 69        if (ShowColors)70          Out.resetColor();71        print(D);72        Out << "\n";73        // Don't traverse child nodes to avoid output duplication.74        return true;75      }76      return base::TraverseDecl(D);77    }78 79  private:80    std::string getName(Decl *D) {81      if (isa<NamedDecl>(D))82        return cast<NamedDecl>(D)->getQualifiedNameAsString();83      return "";84    }85    bool filterMatches(Decl *D) {86      return getName(D).find(FilterString) != std::string::npos;87    }88    void print(Decl *D) {89      if (DumpLookups) {90        if (DeclContext *DC = dyn_cast<DeclContext>(D)) {91          if (DC == DC->getPrimaryContext())92            DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);93          else94            Out << "Lookup map is in primary DeclContext "95                << DC->getPrimaryContext() << "\n";96        } else97          Out << "Not a DeclContext\n";98      } else if (OutputKind == Print) {99        PrintingPolicy Policy(D->getASTContext().getLangOpts());100        Policy.IncludeTagDefinition = true;101        D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);102      } else if (OutputKind != None) {103        D->dump(Out, OutputKind == DumpFull, OutputFormat);104      }105 106      if (DumpDeclTypes) {107        Decl *InnerD = D;108        if (auto *TD = dyn_cast<TemplateDecl>(D))109          if (Decl *TempD = TD->getTemplatedDecl())110            InnerD = TempD;111 112        // FIXME: Support OutputFormat in type dumping.113        // FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups.114        if (auto *VD = dyn_cast<ValueDecl>(InnerD))115          VD->getType().dump(Out, VD->getASTContext());116        if (auto *TD = dyn_cast<TypeDecl>(InnerD)) {117          const ASTContext &Ctx = TD->getASTContext();118          Ctx.getTypeDeclType(TD)->dump(Out, Ctx);119        }120      }121    }122 123    raw_ostream &Out;124    std::unique_ptr<raw_ostream> OwnedOut;125 126    /// How to output individual declarations.127    Kind OutputKind;128 129    /// What format should the output take?130    ASTDumpOutputFormat OutputFormat;131 132    /// Which declarations or DeclContexts to display.133    std::string FilterString;134 135    /// Whether the primary output is lookup results or declarations. Individual136    /// results will be output with a format determined by OutputKind. This is137    /// incompatible with OutputKind == Print.138    bool DumpLookups;139 140    /// Whether to dump the type for each declaration dumped.141    bool DumpDeclTypes;142  };143 144  class ASTDeclNodeLister : public ASTConsumer,145                     public RecursiveASTVisitor<ASTDeclNodeLister> {146  public:147    ASTDeclNodeLister(raw_ostream *Out = nullptr)148        : Out(Out ? *Out : llvm::outs()) {}149 150    void HandleTranslationUnit(ASTContext &Context) override {151      TraverseDecl(Context.getTranslationUnitDecl());152    }153 154    bool shouldWalkTypesOfTypeLocs() const { return false; }155 156    bool VisitNamedDecl(NamedDecl *D) {157      D->printQualifiedName(Out);158      Out << '\n';159      return true;160    }161 162  private:163    raw_ostream &Out;164  };165} // end anonymous namespace166 167std::unique_ptr<ASTConsumer>168clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,169                        StringRef FilterString) {170  return std::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,171                                       ADOF_Default, FilterString);172}173 174std::unique_ptr<ASTConsumer>175clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out, StringRef FilterString,176                       bool DumpDecls, bool Deserialize, bool DumpLookups,177                       bool DumpDeclTypes, ASTDumpOutputFormat Format) {178  assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");179  return std::make_unique<ASTPrinter>(180      std::move(Out),181      Deserialize ? ASTPrinter::DumpFull182                  : DumpDecls ? ASTPrinter::Dump : ASTPrinter::None,183      Format, FilterString, DumpLookups, DumpDeclTypes);184}185 186std::unique_ptr<ASTConsumer>187clang::CreateASTDumper(raw_ostream &Out, StringRef FilterString, bool DumpDecls,188                       bool Deserialize, bool DumpLookups, bool DumpDeclTypes,189                       ASTDumpOutputFormat Format) {190  assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");191  return std::make_unique<ASTPrinter>(Out,192                                      Deserialize ? ASTPrinter::DumpFull193                                      : DumpDecls ? ASTPrinter::Dump194                                                  : ASTPrinter::None,195                                      Format, FilterString, DumpLookups,196                                      DumpDeclTypes);197}198 199std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {200  return std::make_unique<ASTDeclNodeLister>(nullptr);201}202 203//===----------------------------------------------------------------------===//204/// ASTViewer - AST Visualization205 206namespace {207class ASTViewer : public ASTConsumer {208  ASTContext *Context = nullptr;209 210public:211  void Initialize(ASTContext &Context) override { this->Context = &Context; }212 213  bool HandleTopLevelDecl(DeclGroupRef D) override {214    for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)215      HandleTopLevelSingleDecl(*I);216    return true;217  }218 219  void HandleTopLevelSingleDecl(Decl *D);220};221}222 223void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {224  if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {225    D->print(llvm::errs());226 227    if (Stmt *Body = D->getBody()) {228      llvm::errs() << '\n';229      Body->viewAST();230      llvm::errs() << '\n';231    }232  }233}234 235std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {236  return std::make_unique<ASTViewer>();237}238