Skip to content

Commit f3b35bd

Browse files
committed
Address PR comments, add a unit test
Most of the changes are NFCs that address the PR comments. I've also added a unit test in flang/unittests/Frontend/FrontendActionTest.cpp. For that I had to extend the `CompilerInstance` class.
1 parent 88e1769 commit f3b35bd

File tree

6 files changed

+52
-10
lines changed

6 files changed

+52
-10
lines changed

clang/lib/Driver/Driver.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@
4343
#include "ToolChains/PS4CPU.h"
4444
#include "ToolChains/RISCVToolchain.h"
4545
#include "ToolChains/Solaris.h"
46-
4746
#include "ToolChains/TCE.h"
4847
#include "ToolChains/VEToolchain.h"
4948
#include "ToolChains/WebAssembly.h"

flang/include/flang/Frontend/CompilerInstance.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -250,6 +250,13 @@ class CompilerInstance {
250250
void WriteOutputStream(const std::string &message) {
251251
*outputStream_ << message;
252252
}
253+
254+
/// Get the user specified output stream.
255+
llvm::raw_pwrite_stream &GetOutputStream() {
256+
assert(outputStream_ &&
257+
"Compiler instance has no user-specified output stream!");
258+
return *outputStream_;
259+
}
253260
};
254261

255262
} // end namespace Fortran::frontend

flang/lib/Frontend/FrontendActions.cpp

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,6 @@ void GetSymbolsSourcesAction::ExecuteAction() {
367367

368368
// Translate front-end KINDs for use in the IR and code gen. Extracted from
369369
// bbc.cpp.
370-
// TODO: How to share this with bbc.cpp?
371370
static std::vector<fir::KindTy>
372371
fromDefaultKinds(const Fortran::common::IntrinsicTypeDefaultKinds &defKinds) {
373372
return {static_cast<fir::KindTy>(defKinds.GetDefaultKind(
@@ -400,7 +399,7 @@ void EmitFirAction::ExecuteAction() {
400399
ci.invocation().semanticsContext().intrinsics(), ci.parsing().allCooked(),
401400
"", kindMap);
402401

403-
// Create PFT and lower it to FIR
402+
// Create a parse tree and lower it to FIR
404403
auto &parseTree{*ci.parsing().parseTree()};
405404
lb.lower(parseTree, ci.invocation().semanticsContext());
406405

@@ -410,19 +409,32 @@ void EmitFirAction::ExecuteAction() {
410409
pm.addPass(std::make_unique<Fortran::lower::VerifierPass>());
411410
mlir::ModuleOp mlirModule = lb.getModule();
412411
if (mlir::failed(pm.run(mlirModule))) {
413-
// TODO: Replace with a diagnostic
414-
llvm::errs() << "FATAL: verification of lowering to FIR failed";
412+
unsigned diagID =
413+
ci.diagnostics().getCustomDiagID(clang::DiagnosticsEngine::Error,
414+
"verification of lowering to FIR failed");
415+
ci.diagnostics().Report(diagID);
416+
return;
415417
}
416418

417-
// Print the output
419+
// Print the output. If a pre-defined output stream exists, dump the MLIR
420+
// content there.
421+
if (!ci.IsOutputStreamNull()) {
422+
mlirModule.print(ci.GetOutputStream());
423+
return;
424+
}
425+
426+
// ... otherwise, print to a file.
418427
auto os{ci.CreateDefaultOutputFile(
419-
/*Binary=*/true, /*InFile=*/GetCurrentFileOrBufferName(), "mlir")};
428+
/*Binary=*/true, /*InFile=*/GetCurrentFileOrBufferName(), "mlir")};
420429
if (!os) {
430+
unsigned diagID = ci.diagnostics().getCustomDiagID(
431+
clang::DiagnosticsEngine::Error, "failed to create the output file");
432+
ci.diagnostics().Report(diagID);
421433
return;
422434
}
423435

424436
mlirModule.print(*os);
425-
}
437+
}
426438

427439
void EmitObjAction::ExecuteAction() {
428440
CompilerInstance &ci = this->instance();

flang/lib/FrontendTool/ExecuteCompilerInvocation.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,8 @@ static std::unique_ptr<FrontendAction> CreateFrontendBaseAction(
3232
return std::make_unique<PrintPreprocessedAction>();
3333
case ParseSyntaxOnly:
3434
return std::make_unique<ParseSyntaxOnlyAction>();
35-
break;
3635
case EmitFir:
3736
return std::make_unique<EmitFirAction>();
38-
break;
3937
case EmitObj:
4038
return std::make_unique<EmitObjAction>();
4139
case DebugUnparse:
File renamed without changes.

flang/unittests/Frontend/FrontendActionTest.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,4 +161,30 @@ TEST_F(FrontendActionTest, ParseSyntaxOnly) {
161161
.contains(
162162
":1:14: error: IF statement is not allowed in IF statement\n"));
163163
}
164+
165+
TEST_F(FrontendActionTest, EmitFir) {
166+
// Populate the input file with the pre-defined input and flush it.
167+
*(inputFileOs_) << "end program";
168+
inputFileOs_.reset();
169+
170+
// Set-up the action kind.
171+
compInst_.invocation().frontendOpts().programAction = EmitFir;
172+
compInst_.invocation().preprocessorOpts().noReformat = true;
173+
174+
// Set-up the output stream. We are using output buffer wrapped as an output
175+
// stream, as opposed to an actual file (or a file descriptor).
176+
llvm::SmallVector<char, 256> outputFileBuffer;
177+
std::unique_ptr<llvm::raw_pwrite_stream> outputFileStream(
178+
new llvm::raw_svector_ostream(outputFileBuffer));
179+
compInst_.set_outputStream(std::move(outputFileStream));
180+
181+
// Execute the action.
182+
bool success = ExecuteCompilerInvocation(&compInst_);
183+
184+
// Validate the expected output.
185+
EXPECT_TRUE(success);
186+
EXPECT_TRUE(!outputFileBuffer.empty());
187+
EXPECT_TRUE(
188+
llvm::StringRef(outputFileBuffer.data()).contains("func @_QQmain"));
189+
}
164190
} // namespace

0 commit comments

Comments
 (0)