forked from OSchip/llvm-project
[flang] Runtime starting and stopping
Define ImageTerminator as a mixin-able class Turn start.cc into main.cc Original-commit: flang-compiler/f18@cbc6225213 Reviewed-on: https://github.com/flang-compiler/f18/pull/914
This commit is contained in:
parent
9744328fed
commit
aeb07fbea6
|
@ -14,7 +14,7 @@
|
|||
#include <cstring>
|
||||
|
||||
// Define a FormatValidator class template to validate a format expression
|
||||
// of a given CHAR kind. To enable use in runtime library code as well as
|
||||
// of a given CHAR type. To enable use in runtime library code as well as
|
||||
// compiler code, the implementation does its own parsing without recourse
|
||||
// to compiler parser machinery, and avoids features that require C++ runtime
|
||||
// library support. A format expression is a pointer to a fixed size
|
||||
|
@ -57,6 +57,7 @@ public:
|
|||
}
|
||||
|
||||
bool Check();
|
||||
int maxNesting() const { return maxNesting_; }
|
||||
|
||||
private:
|
||||
common::EnumSet<TokenKind, TokenKind_enumSize> itemsWithLeadingInts_{
|
||||
|
@ -145,6 +146,7 @@ private:
|
|||
bool unterminatedFormatError_{false};
|
||||
bool suppressMessageCascade_{false};
|
||||
bool reporterExit_{false};
|
||||
int maxNesting_{0}; // max level of nested parentheses
|
||||
};
|
||||
|
||||
template<typename CHAR> CHAR FormatValidator<CHAR>::NextChar() {
|
||||
|
@ -682,7 +684,9 @@ template<typename CHAR> bool FormatValidator<CHAR>::Check() {
|
|||
if (knrValue_ == 0) {
|
||||
ReportError("List repeat specifier must be positive", knrToken_);
|
||||
}
|
||||
++nestLevel;
|
||||
if (++nestLevel > maxNesting_) {
|
||||
maxNesting_ = nestLevel;
|
||||
}
|
||||
break;
|
||||
case TokenKind::RParen:
|
||||
if (knrValue_ >= 0) {
|
||||
|
|
|
@ -10,6 +10,9 @@ add_library(FortranRuntime
|
|||
ISO_Fortran_binding.cc
|
||||
derived-type.cc
|
||||
descriptor.cc
|
||||
main.cc
|
||||
stop.cc
|
||||
terminator.cc
|
||||
transformational.cc
|
||||
type-code.cc
|
||||
)
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
//===-- runtime/c-or-cpp.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
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#ifndef FORTRAN_RUNTIME_C_OR_CPP_H_
|
||||
#define FORTRAN_RUNTIME_C_OR_CPP_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define IF_CPLUSPLUS(x) x
|
||||
#define IF_NOT_CPLUSPLUS(x)
|
||||
#define DEFAULT_VALUE(x) = (x)
|
||||
#else
|
||||
#include <stdbool.h>
|
||||
#define IF_CPLUSPLUS(x)
|
||||
#define IF_NOT_CPLUSPLUS(x) x
|
||||
#define DEFAULT_VALUE(x)
|
||||
#endif
|
||||
|
||||
#define EXTERN_C_BEGIN IF_CPLUSPLUS(extern "C" {)
|
||||
#define EXTERN_C_END IF_CPLUSPLUS( \
|
||||
})
|
||||
#define NORETURN IF_CPLUSPLUS([[noreturn]])
|
||||
#define NO_ARGUMENTS IF_NOT_CPLUSPLUS(void)
|
||||
|
||||
#endif // FORTRAN_RUNTIME_C_OR_CPP_H_
|
|
@ -0,0 +1,35 @@
|
|||
//===-- runtime/main.cc -----------------------------------------*- 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
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include "main.h"
|
||||
#include "terminator.h"
|
||||
#include <cfenv>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace Fortran::runtime {
|
||||
int argc;
|
||||
const char **argv;
|
||||
const char **envp;
|
||||
}
|
||||
|
||||
extern "C" {
|
||||
|
||||
void __FortranProgram(); // PROGRAM statement
|
||||
|
||||
int main(int argc, const char *argv[], const char *envp[]) {
|
||||
Fortran::runtime::argc = argc;
|
||||
Fortran::runtime::argv = argv;
|
||||
Fortran::runtime::envp = envp;
|
||||
std::feclearexcept(FE_ALL_EXCEPT);
|
||||
std::fesetround(FE_TONEAREST);
|
||||
std::atexit(Fortran::runtime::NotifyOtherImagesOfNormalEnd);
|
||||
// TODO: Runtime configuration settings from environment
|
||||
__FortranProgram();
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,18 @@
|
|||
//===-- runtime/main.cc -----------------------------------------*- 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
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#ifndef FORTRAN_RUNTIME_MAIN_H_
|
||||
#define FORTRAN_RUNTIME_MAIN_H_
|
||||
|
||||
namespace Fortran::runtime {
|
||||
extern int argc;
|
||||
extern const char **argv;
|
||||
extern const char **envp;
|
||||
}
|
||||
|
||||
#endif // FORTRAN_RUNTIME_MAIN_H_
|
|
@ -0,0 +1,64 @@
|
|||
//===-- runtime/stop.cc -----------------------------------------*- 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
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include "stop.h"
|
||||
#include "terminator.h"
|
||||
#include <cfenv>
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
extern "C" {
|
||||
|
||||
static void DescribeIEEESignaledExceptions() {
|
||||
if (auto excepts{std::fetestexcept(FE_ALL_EXCEPT)}) {
|
||||
std::fputs("IEEE arithmetic exceptions signaled:", stderr);
|
||||
if (excepts & FE_DIVBYZERO) {
|
||||
std::fputs(" DIVBYZERO", stderr);
|
||||
}
|
||||
if (excepts & FE_INEXACT) {
|
||||
std::fputs(" INEXACT", stderr);
|
||||
}
|
||||
if (excepts & FE_INVALID) {
|
||||
std::fputs(" INVALID", stderr);
|
||||
}
|
||||
if (excepts & FE_OVERFLOW) {
|
||||
std::fputs(" OVERFLOW", stderr);
|
||||
}
|
||||
if (excepts & FE_UNDERFLOW) {
|
||||
std::fputs(" UNDERFLOW", stderr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[[noreturn]] void RTNAME(StopStatement)(
|
||||
int code, bool isErrorStop, bool quiet) {
|
||||
if (!quiet) {
|
||||
if (code != EXIT_SUCCESS) {
|
||||
std::fprintf(stderr, "Fortran %s: code %d\n",
|
||||
isErrorStop ? "ERROR STOP" : "STOP", code);
|
||||
}
|
||||
DescribeIEEESignaledExceptions();
|
||||
}
|
||||
std::exit(code);
|
||||
}
|
||||
|
||||
[[noreturn]] void RTNAME(StopStatementText)(
|
||||
const char *code, bool isErrorStop, bool quiet) {
|
||||
if (!quiet) {
|
||||
std::fprintf(stderr, "Fortran %s: %s\n",
|
||||
isErrorStop ? "ERROR STOP" : "STOP", code);
|
||||
DescribeIEEESignaledExceptions();
|
||||
}
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
[[noreturn]] void RTNAME(FailImageStatement)() {
|
||||
Fortran::runtime::NotifyOtherImagesOfFailImageStatement();
|
||||
std::exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
//===-- runtime/stop.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
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#ifndef FORTRAN_RUNTIME_STOP_H_
|
||||
#define FORTRAN_RUNTIME_STOP_H_
|
||||
|
||||
#include "c-or-cpp.h"
|
||||
#include "entry-names.h"
|
||||
#include <stdlib.h>
|
||||
|
||||
EXTERN_C_BEGIN
|
||||
|
||||
// Program-initiated image stop
|
||||
NORETURN void RTNAME(StopStatement)(int code DEFAULT_VALUE(EXIT_SUCCESS),
|
||||
bool isErrorStop DEFAULT_VALUE(false), bool quiet DEFAULT_VALUE(false));
|
||||
NORETURN void RTNAME(StopStatementText)(const char *,
|
||||
bool isErrorStop DEFAULT_VALUE(false), bool quiet DEFAULT_VALUE(false));
|
||||
NORETURN void RTNAME(FailImageStatement)(NO_ARGUMENTS);
|
||||
|
||||
EXTERN_C_END
|
||||
|
||||
#endif // FORTRAN_RUNTIME_STOP_H_
|
|
@ -0,0 +1,47 @@
|
|||
//===-- runtime/terminate.cc ------------------------------------*- 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
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
#include "terminator.h"
|
||||
#include <cstdio>
|
||||
#include <cstdlib>
|
||||
|
||||
namespace Fortran::runtime {
|
||||
|
||||
[[noreturn]] void Terminator::Crash(const char *message, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, message);
|
||||
CrashArgs(message, ap);
|
||||
}
|
||||
|
||||
[[noreturn]] void Terminator::CrashArgs(const char *message, va_list &ap) {
|
||||
std::fputs("\nfatal Fortran runtime error", stderr);
|
||||
if (sourceFileName_) {
|
||||
std::fprintf(stderr, "(%s", sourceFileName_);
|
||||
if (sourceLine_) {
|
||||
std::fprintf(stderr, ":%d", sourceLine_);
|
||||
}
|
||||
fputc(')', stderr);
|
||||
}
|
||||
std::fputs(": ", stderr);
|
||||
std::vfprintf(stderr, message, ap);
|
||||
fputc('\n', stderr);
|
||||
va_end(ap);
|
||||
NotifyOtherImagesOfErrorTermination();
|
||||
std::abort();
|
||||
}
|
||||
|
||||
void NotifyOtherImagesOfNormalEnd() {
|
||||
// TODO
|
||||
}
|
||||
void NotifyOtherImagesOfFailImageStatement() {
|
||||
// TODO
|
||||
}
|
||||
void NotifyOtherImagesOfErrorTermination() {
|
||||
// TODO
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
//===-- runtime/terminator.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
|
||||
//
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
// Termination of the image
|
||||
|
||||
#ifndef FORTRAN_RUNTIME_TERMINATOR_H_
|
||||
#define FORTRAN_RUNTIME_TERMINATOR_H_
|
||||
|
||||
#include "entry-names.h"
|
||||
#include <cstdarg>
|
||||
|
||||
namespace Fortran::runtime {
|
||||
|
||||
// A mixin class for statement-specific image error termination
|
||||
// for errors detected in the runtime library
|
||||
class Terminator {
|
||||
public:
|
||||
Terminator() {}
|
||||
explicit Terminator(const char *sourceFileName, int sourceLine = 0)
|
||||
: sourceFileName_{sourceFileName}, sourceLine_{sourceLine} {}
|
||||
void SetLocation(const char *sourceFileName = nullptr, int sourceLine = 0) {
|
||||
sourceFileName_ = sourceFileName;
|
||||
sourceLine_ = sourceLine;
|
||||
}
|
||||
[[noreturn]] void Crash(const char *message, ...);
|
||||
[[noreturn]] void CrashArgs(const char *message, va_list &);
|
||||
|
||||
private:
|
||||
const char *sourceFileName_{nullptr};
|
||||
int sourceLine_{0};
|
||||
};
|
||||
|
||||
void NotifyOtherImagesOfNormalEnd();
|
||||
void NotifyOtherImagesOfFailImageStatement();
|
||||
void NotifyOtherImagesOfErrorTermination();
|
||||
}
|
||||
#endif // FORTRAN_RUNTIME_TERMINATOR_H_
|
Loading…
Reference in New Issue