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-exception
6//
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 prescanner
73 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 parsing
107 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.objects
113 << " objects and occupies " << visitor.bytes
114 << " 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 CompilerInvocation
122 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::frontend
150

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of flang/lib/Frontend/ParserActions.cpp