#ifndef FORTRAN_LOWER_TODO_H
#define FORTRAN_LOWER_TODO_H
+#include "flang/Optimizer/Support/FatalError.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include <cstdlib>
// developed.
#undef TODO
+// Use TODO_NOLOC if no mlir location is available to indicate the line in
+// Fortran source file that requires an unimplemented feature.
+#undef TODO_NOLOC
+
+#undef TODOQUOTE
+#define TODOQUOTE(X) #X
#ifdef NDEBUG
// In a release build, just give a message and exit.
-#define TODO(ToDoMsg) \
+#define TODO_NOLOC(ToDoMsg) \
do { \
llvm::errs() << __FILE__ << ':' << __LINE__ << ": not yet implemented " \
<< ToDoMsg << '\n'; \
std::exit(1); \
} while (false)
-#else
+#undef TODO_DEFN
+#define TODO_DEFN(MlirLoc, ToDoMsg, ToDoFile, ToDoLine) \
+ do { \
+ mlir::emitError(MlirLoc, ToDoFile \
+ ":" TODOQUOTE(ToDoLine) ": not yet implemented " ToDoMsg); \
+ std::exit(1); \
+ } while (false)
-#undef TODOQUOTE
-#define TODOQUOTE(X) #X
+#define TODO(MlirLoc, ToDoMsg) TODO_DEFN(MlirLoc, ToDoMsg, __FILE__, __LINE__)
+
+#else
// In a developer build, print a message and give a backtrace.
-#define TODO(ToDoMsg) \
+#undef TODO_NOLOCDEFN
+#define TODO_NOLOCDEFN(ToDoMsg, ToDoFile, ToDoLine) \
do { \
llvm::report_fatal_error( \
__FILE__ ":" TODOQUOTE(__LINE__) ": not yet implemented " ToDoMsg); \
} while (false)
+#define TODO_NOLOC(ToDoMsg) TODO_NOLOCDEFN(ToDoMsg, __FILE__, __LINE__)
+
+#undef TODO_DEFN
+#define TODO_DEFN(MlirLoc, ToDoMsg, ToDoFile, ToDoLine) \
+ do { \
+ fir::emitFatalError( \
+ MlirLoc, \
+ ToDoFile ":" TODOQUOTE(ToDoLine) ": not yet implemented " ToDoMsg); \
+ } while (false)
+
+#define TODO(MlirLoc, ToDoMsg) TODO_DEFN(MlirLoc, ToDoMsg, __FILE__, __LINE__)
+
#endif
#endif // FORTRAN_LOWER_TODO_H
--- /dev/null
+//===-- Optimizer/Support/FatalError.h --------------------------*- C++ -*-===//
+//
+// 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
+//
+//===----------------------------------------------------------------------===//
+//
+// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef FORTRAN_OPTIMIZER_SUPPORT_FATALERROR_H
+#define FORTRAN_OPTIMIZER_SUPPORT_FATALERROR_H
+
+#include "mlir/IR/Diagnostics.h"
+#include "llvm/Support/ErrorHandling.h"
+
+namespace fir {
+
+/// Fatal error reporting helper. Report a fatal error with a source location
+/// and immediately abort flang.
+LLVM_ATTRIBUTE_NORETURN inline void emitFatalError(mlir::Location loc,
+ const llvm::Twine &message) {
+ mlir::emitError(loc, message);
+ llvm::report_fatal_error("aborting");
+}
+
+/// Fatal error reporting helper. Report a fatal error without a source location
+/// and immediately abort flang.
+LLVM_ATTRIBUTE_NORETURN inline void emitFatalError(const llvm::Twine &message) {
+ llvm::report_fatal_error(message);
+}
+
+} // namespace fir
+
+#endif // FORTRAN_OPTIMIZER_SUPPORT_FATALERROR_H
} else if (standaloneDirective.v == llvm::acc::Directive::ACCD_shutdown) {
genACCInitShutdownOp<mlir::acc::ShutdownOp>(converter, accClauseList);
} else if (standaloneDirective.v == llvm::acc::Directive::ACCD_set) {
- TODO("OpenACC set directive not lowered yet!");
+ TODO(converter.genLocation(), "OpenACC set directive not lowered yet!");
} else if (standaloneDirective.v == llvm::acc::Directive::ACCD_update) {
genACCUpdateOp(converter, accClauseList);
}
},
[&](const Fortran::parser::OpenACCCombinedConstruct
&combinedConstruct) {
- TODO("OpenACC Combined construct not lowered yet!");
+ TODO(converter.genLocation(),
+ "OpenACC Combined construct not lowered yet!");
},
[&](const Fortran::parser::OpenACCLoopConstruct &loopConstruct) {
genACC(converter, eval, loopConstruct);
},
[&](const Fortran::parser::OpenACCRoutineConstruct
&routineConstruct) {
- TODO("OpenACC Routine construct not lowered yet!");
+ TODO(converter.genLocation(),
+ "OpenACC Routine construct not lowered yet!");
},
[&](const Fortran::parser::OpenACCCacheConstruct &cacheConstruct) {
- TODO("OpenACC Cache construct not lowered yet!");
+ TODO(converter.genLocation(),
+ "OpenACC Cache construct not lowered yet!");
},
[&](const Fortran::parser::OpenACCWaitConstruct &waitConstruct) {
genACC(converter, eval, waitConstruct);
},
[&](const Fortran::parser::OpenACCAtomicConstruct &atomicConstruct) {
- TODO("OpenACC Atomic construct not lowered yet!");
+ TODO(converter.genLocation(),
+ "OpenACC Atomic construct not lowered yet!");
},
},
accConstruct.u);
converter.getCurrentLocation());
break;
case llvm::omp::Directive::OMPD_target_enter_data:
- TODO("");
+ TODO(converter.getCurrentLocation(), "OMPD_target_enter_data");
case llvm::omp::Directive::OMPD_target_exit_data:
- TODO("");
+ TODO(converter.getCurrentLocation(), "OMPD_target_exit_data");
case llvm::omp::Directive::OMPD_target_update:
- TODO("");
+ TODO(converter.getCurrentLocation(), "OMPD_target_update");
case llvm::omp::Directive::OMPD_ordered:
- TODO("");
+ TODO(converter.getCurrentLocation(), "OMPD_ordered");
}
}
if (std::get<std::optional<
std::list<Fortran::parser::OmpMemoryOrderClause>>>(
flushConstruct.t))
- TODO("Handle OmpMemoryOrderClause");
+ TODO(converter.getCurrentLocation(),
+ "Handle OmpMemoryOrderClause");
converter.getFirOpBuilder().create<mlir::omp::FlushOp>(
converter.getCurrentLocation(), operandRange);
},
[&](const Fortran::parser::OpenMPCancelConstruct &cancelConstruct) {
- TODO("");
+ TODO(converter.getCurrentLocation(), "OpenMPCancelConstruct");
},
[&](const Fortran::parser::OpenMPCancellationPointConstruct
- &cancellationPointConstruct) { TODO(""); },
+ &cancellationPointConstruct) {
+ TODO(converter.getCurrentLocation(), "OpenMPCancelConstruct");
+ },
},
standaloneConstruct.u);
}
genOMP(converter, eval, standaloneConstruct);
},
[&](const Fortran::parser::OpenMPSectionsConstruct
- §ionsConstruct) { TODO(""); },
+ §ionsConstruct) {
+ TODO(converter.getCurrentLocation(), "OpenMPSectionsConstruct");
+ },
[&](const Fortran::parser::OpenMPLoopConstruct &loopConstruct) {
- TODO("");
+ TODO(converter.getCurrentLocation(), "OpenMPLoopConstruct");
},
[&](const Fortran::parser::OpenMPDeclarativeAllocate
- &execAllocConstruct) { TODO(""); },
+ &execAllocConstruct) {
+ TODO(converter.getCurrentLocation(), "OpenMPDeclarativeAllocate");
+ },
[&](const Fortran::parser::OpenMPExecutableAllocate
- &execAllocConstruct) { TODO(""); },
+ &execAllocConstruct) {
+ TODO(converter.getCurrentLocation(), "OpenMPExecutableAllocate");
+ },
[&](const Fortran::parser::OpenMPBlockConstruct &blockConstruct) {
genOMP(converter, eval, blockConstruct);
},
[&](const Fortran::parser::OpenMPAtomicConstruct &atomicConstruct) {
- TODO("");
+ TODO(converter.getCurrentLocation(), "OpenMPAtomicConstruct");
},
[&](const Fortran::parser::OpenMPCriticalConstruct
- &criticalConstruct) { TODO(""); },
+ &criticalConstruct) {
+ TODO(converter.getCurrentLocation(), "OpenMPCriticalConstruct");
+ },
},
ompConstruct.u);
}
void Fortran::lower::genOpenMPEndLoop(
- Fortran::lower::AbstractConverter &, Fortran::lower::pft::Evaluation &,
+ Fortran::lower::AbstractConverter &converter,
+ Fortran::lower::pft::Evaluation &,
const Fortran::parser::OmpEndLoopDirective &) {
- TODO("");
+ TODO(converter.getCurrentLocation(), "OmpEndLoopDirective");
}