errors: add FatalErrorHandler to handle when an abnormal error occurs on DMDLIB

This patch introduces a FatalErrorHandler for error handling on DMD to make DMD
as a library usable with the semantic analysis.

Signed-off-by: Luís Ferreira <contact@lsferreira.net>
This commit is contained in:
Luís Ferreira 2022-03-26 16:40:22 +00:00 committed by The Dlang Bot
parent 7195063f4c
commit e672df26e1
3 changed files with 26 additions and 11 deletions

View file

@ -649,15 +649,26 @@ private void _vdeprecationSupplemental(const ref Loc loc, const(char)* format, v
}
/**
* Call this after printing out fatal error messages to clean up and exit
* the compiler.
* The type of the fatal error handler
* Returns: true if error handling is done, false to do exit(EXIT_FAILURE)
*/
alias FatalErrorHandler = bool delegate();
/**
* The fatal error handler.
* If non-null it will be called for every fatal() call issued by the compiler.
*/
__gshared FatalErrorHandler fatalErrorHandler;
/**
* Call this after printing out fatal error messages to clean up and exit the
* compiler. You can also set a fatalErrorHandler to override this behaviour.
*/
extern (C++) void fatal()
{
version (none)
{
halt();
}
if (fatalErrorHandler && fatalErrorHandler())
return;
exit(EXIT_FAILURE);
}

View file

@ -13,7 +13,7 @@ module dmd.frontend;
import dmd.astcodegen : ASTCodegen;
import dmd.dmodule : Module;
import dmd.globals : CHECKENABLE, Loc, DiagnosticReporting;
import dmd.errors : DiagnosticHandler, diagnosticHandler, Classification;
import dmd.errors;
import std.range.primitives : isInputRange, ElementType;
import std.traits : isNarrowString;
@ -96,12 +96,14 @@ Initializes the global variables of the DMD compiler.
This needs to be done $(I before) calling any function.
Params:
handler = a delegate to configure what to do with diagnostics (other than printing to console or stderr).
diagnosticHandler = a delegate to configure what to do with diagnostics (other than printing to console or stderr).
fatalErrorHandler = a delegate to configure what to do with fatal errors (default is to call exit(EXIT_FAILURE)).
contractChecks = indicates which contracts should be enabled or not
versionIdentifiers = a list of version identifiers that should be enabled
*/
void initDMD(
DiagnosticHandler handler = null,
DiagnosticHandler diagnosticHandler = null,
FatalErrorHandler fatalErrorHandler = null,
const string[] versionIdentifiers = [],
ContractChecks contractChecks = ContractChecks()
)
@ -124,7 +126,8 @@ void initDMD(
import dmd.objc : Objc;
import dmd.target : target, defaultTargetOS;
diagnosticHandler = handler;
.diagnosticHandler = diagnosticHandler;
.fatalErrorHandler = fatalErrorHandler;
global._init();
@ -175,6 +178,7 @@ void deinitializeDMD()
import dmd.target : target;
diagnosticHandler = null;
fatalErrorHandler = null;
global.deinitialize();

View file

@ -216,7 +216,7 @@ unittest
import dmd.frontend;
import dmd.globals : global;
initDMD(null, ["Foo"]);
initDMD(null, null, ["Foo"]);
defaultImportPaths.each!addImport;
auto t = parseModule("test.d", q{