diff --git a/flang/include/flang/Lower/Todo.h b/flang/include/flang/Lower/Todo.h --- a/flang/include/flang/Lower/Todo.h +++ b/flang/include/flang/Lower/Todo.h @@ -13,6 +13,7 @@ #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 @@ -21,29 +22,55 @@ // 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 diff --git a/flang/include/flang/Optimizer/Support/FatalError.h b/flang/include/flang/Optimizer/Support/FatalError.h new file mode 100644 --- /dev/null +++ b/flang/include/flang/Optimizer/Support/FatalError.h @@ -0,0 +1,37 @@ +//===-- 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 diff --git a/flang/lib/Lower/OpenACC.cpp b/flang/lib/Lower/OpenACC.cpp --- a/flang/lib/Lower/OpenACC.cpp +++ b/flang/lib/Lower/OpenACC.cpp @@ -910,7 +910,7 @@ } else if (standaloneDirective.v == llvm::acc::Directive::ACCD_shutdown) { genACCInitShutdownOp(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); } @@ -1003,7 +1003,8 @@ }, [&](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); @@ -1014,16 +1015,19 @@ }, [&](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); diff --git a/flang/lib/Lower/OpenMP.cpp b/flang/lib/Lower/OpenMP.cpp --- a/flang/lib/Lower/OpenMP.cpp +++ b/flang/lib/Lower/OpenMP.cpp @@ -83,13 +83,13 @@ 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"); } } @@ -112,15 +112,18 @@ if (std::get>>( flushConstruct.t)) - TODO("Handle OmpMemoryOrderClause"); + TODO(converter.getCurrentLocation(), + "Handle OmpMemoryOrderClause"); converter.getFirOpBuilder().create( 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); } @@ -256,28 +259,37 @@ 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"); }