brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.2 KiB · 4fe575b Raw
150 lines · cpp
1//===--- ParserActions.cpp ------------------------------------------------===//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// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/10//11//===----------------------------------------------------------------------===//12 13#include "flang/Frontend/ParserActions.h"14#include "flang/Frontend/CompilerInstance.h"15#include "flang/Lower/Bridge.h"16#include "flang/Lower/PFTBuilder.h"17#include "flang/Parser/dump-parse-tree.h"18#include "flang/Parser/parsing.h"19#include "flang/Parser/provenance.h"20#include "flang/Parser/source.h"21#include "flang/Parser/unparse.h"22#include "flang/Semantics/unparse-with-symbols.h"23#include "llvm/Support/raw_ostream.h"24 25namespace Fortran::frontend {26 27parser::AllCookedSources &getAllCooked(CompilerInstance &ci) {28  return ci.getParsing().allCooked();29}30 31void parseAndLowerTree(CompilerInstance &ci, lower::LoweringBridge &lb) {32  parser::Program &parseTree{*ci.getParsing().parseTree()};33  lb.lower(parseTree, ci.getSemanticsContext());34}35 36void dumpTree(CompilerInstance &ci) {37  auto &parseTree{ci.getParsing().parseTree()};38  llvm::outs() << "========================";39  llvm::outs() << " Flang: parse tree dump ";40  llvm::outs() << "========================\n";41  parser::DumpTree(llvm::outs(), parseTree, &ci.getInvocation().getAsFortran());42}43 44void dumpProvenance(CompilerInstance &ci) {45  ci.getParsing().DumpProvenance(llvm::outs());46}47 48void dumpPreFIRTree(CompilerInstance &ci) {49  auto &parseTree{*ci.getParsing().parseTree()};50 51  if (auto ast{lower::createPFT(parseTree, ci.getSemanticsContext())}) {52    lower::dumpPFT(llvm::outs(), *ast);53  } else {54    unsigned diagID = ci.getDiagnostics().getCustomDiagID(55        clang::DiagnosticsEngine::Error, "Pre FIR Tree is NULL.");56    ci.getDiagnostics().Report(diagID);57  }58}59 60void formatOrDumpPrescanner(std::string &buf,61                            llvm::raw_string_ostream &outForPP,62                            CompilerInstance &ci) {63  if (ci.getInvocation().getPreprocessorOpts().showMacros) {64    ci.getParsing().EmitPreprocessorMacros(outForPP);65  } else if (ci.getInvocation().getPreprocessorOpts().noReformat) {66    ci.getParsing().DumpCookedChars(outForPP);67  } else {68    ci.getParsing().EmitPreprocessedSource(69        outForPP, !ci.getInvocation().getPreprocessorOpts().noLineDirectives);70  }71 72  // Print getDiagnostics from the prescanner73  ci.getParsing().messages().Emit(llvm::errs(), ci.getAllCookedSources());74}75 76struct MeasurementVisitor {77  template <typename A>78  bool Pre(const A &) {79    return true;80  }81  template <typename A>82  void Post(const A &) {83    ++objects;84    bytes += sizeof(A);85  }86  size_t objects{0}, bytes{0};87};88 89void debugMeasureParseTree(CompilerInstance &ci, llvm::StringRef filename) {90  // Parse. In case of failure, report and return.91  ci.getParsing().Parse(llvm::outs());92 93  if ((ci.getParsing().parseTree().has_value() &&94       !ci.getParsing().consumedWholeFile()) ||95      (!ci.getParsing().messages().empty() &&96       (ci.getInvocation().getWarnAsErr() ||97        ci.getParsing().messages().AnyFatalError()))) {98    unsigned diagID = ci.getDiagnostics().getCustomDiagID(99        clang::DiagnosticsEngine::Error, "Could not parse %0");100    ci.getDiagnostics().Report(diagID) << filename;101 102    ci.getParsing().messages().Emit(llvm::errs(), ci.getAllCookedSources());103    return;104  }105 106  // Report the getDiagnostics from parsing107  ci.getParsing().messages().Emit(llvm::errs(), ci.getAllCookedSources());108 109  auto &parseTree{ci.getParsing().parseTree()};110  MeasurementVisitor visitor;111  parser::Walk(parseTree, visitor);112  llvm::outs() << "Parse tree comprises " << visitor.objects113               << " objects and occupies " << visitor.bytes114               << " total bytes.\n";115}116 117void debugUnparseNoSema(CompilerInstance &ci, llvm::raw_ostream &out) {118  auto &invoc = ci.getInvocation();119  auto &parseTree{ci.getParsing().parseTree()};120 121  // TODO: Options should come from CompilerInvocation122  Unparse(out, *parseTree, ci.getInvocation().getLangOpts(),123          /*encoding=*/parser::Encoding::UTF_8,124          /*capitalizeKeywords=*/true, /*backslashEscapes=*/false,125          /*preStatement=*/nullptr,126          invoc.getUseAnalyzedObjectsForUnparse() ? &invoc.getAsFortran()127                                                  : nullptr);128}129 130void debugUnparseWithSymbols(CompilerInstance &ci) {131  auto &parseTree{*ci.getParsing().parseTree()};132 133  semantics::UnparseWithSymbols(llvm::outs(), parseTree,134                                ci.getInvocation().getLangOpts(),135                                /*encoding=*/parser::Encoding::UTF_8);136}137 138void debugUnparseWithModules(CompilerInstance &ci) {139  auto &parseTree{*ci.getParsing().parseTree()};140  semantics::UnparseWithModules(llvm::outs(), ci.getSemantics().context(),141                                parseTree,142                                /*encoding=*/parser::Encoding::UTF_8);143}144 145void debugDumpParsingLog(CompilerInstance &ci) {146  ci.getParsing().Parse(llvm::errs());147  ci.getParsing().DumpParsingLog(llvm::outs());148}149} // namespace Fortran::frontend150