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>
|
#include <cstring>
|
||||||
|
|
||||||
// Define a FormatValidator class template to validate a format expression
|
// 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
|
// compiler code, the implementation does its own parsing without recourse
|
||||||
// to compiler parser machinery, and avoids features that require C++ runtime
|
// to compiler parser machinery, and avoids features that require C++ runtime
|
||||||
// library support. A format expression is a pointer to a fixed size
|
// library support. A format expression is a pointer to a fixed size
|
||||||
|
@ -57,6 +57,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Check();
|
bool Check();
|
||||||
|
int maxNesting() const { return maxNesting_; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
common::EnumSet<TokenKind, TokenKind_enumSize> itemsWithLeadingInts_{
|
common::EnumSet<TokenKind, TokenKind_enumSize> itemsWithLeadingInts_{
|
||||||
|
@ -145,6 +146,7 @@ private:
|
||||||
bool unterminatedFormatError_{false};
|
bool unterminatedFormatError_{false};
|
||||||
bool suppressMessageCascade_{false};
|
bool suppressMessageCascade_{false};
|
||||||
bool reporterExit_{false};
|
bool reporterExit_{false};
|
||||||
|
int maxNesting_{0}; // max level of nested parentheses
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename CHAR> CHAR FormatValidator<CHAR>::NextChar() {
|
template<typename CHAR> CHAR FormatValidator<CHAR>::NextChar() {
|
||||||
|
@ -682,7 +684,9 @@ template<typename CHAR> bool FormatValidator<CHAR>::Check() {
|
||||||
if (knrValue_ == 0) {
|
if (knrValue_ == 0) {
|
||||||
ReportError("List repeat specifier must be positive", knrToken_);
|
ReportError("List repeat specifier must be positive", knrToken_);
|
||||||
}
|
}
|
||||||
++nestLevel;
|
if (++nestLevel > maxNesting_) {
|
||||||
|
maxNesting_ = nestLevel;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case TokenKind::RParen:
|
case TokenKind::RParen:
|
||||||
if (knrValue_ >= 0) {
|
if (knrValue_ >= 0) {
|
||||||
|
|
|
@ -10,6 +10,9 @@ add_library(FortranRuntime
|
||||||
ISO_Fortran_binding.cc
|
ISO_Fortran_binding.cc
|
||||||
derived-type.cc
|
derived-type.cc
|
||||||
descriptor.cc
|
descriptor.cc
|
||||||
|
main.cc
|
||||||
|
stop.cc
|
||||||
|
terminator.cc
|
||||||
transformational.cc
|
transformational.cc
|
||||||
type-code.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