/** * Functions for raising errors. * * Copyright: Copyright (C) 1999-2023 by The D Language Foundation, All Rights Reserved * Authors: $(LINK2 https://www.digitalmars.com, Walter Bright) * License: $(LINK2 https://www.boost.org/LICENSE_1_0.txt, Boost License 1.0) * Source: $(LINK2 https://github.com/dlang/dmd/blob/master/src/dmd/errors.d, _errors.d) * Documentation: https://dlang.org/phobos/dmd_errors.html * Coverage: https://codecov.io/gh/dlang/dmd/src/master/src/dmd/errors.d */ module dmd.errors; import core.stdc.stdarg; import dmd.errorsink; import dmd.globals; import dmd.location; nothrow: /*************************** * Error message sink for D compiler. */ class ErrorSinkCompiler : ErrorSink { nothrow: extern (C++): override: void error(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); verror(loc, format, ap); va_end(ap); } void errorSupplemental(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); verrorSupplemental(loc, format, ap); va_end(ap); } void warning(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vwarning(loc, format, ap); va_end(ap); } void deprecation(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vdeprecation(loc, format, ap); va_end(ap); } void deprecationSupplemental(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vdeprecationSupplemental(loc, format, ap); va_end(ap); } } /** * Color highlighting to classify messages */ enum Classification : Color { error = Color.brightRed, /// for errors gagged = Color.brightBlue, /// for gagged errors warning = Color.brightYellow, /// for warnings deprecation = Color.brightCyan, /// for deprecations tip = Color.brightGreen, /// for tip messages } enum Color : int { black = 0, red = 1, green = 2, blue = 4, yellow = red | green, magenta = red | blue, cyan = green | blue, lightGray = red | green | blue, bright = 8, darkGray = bright | black, brightRed = bright | red, brightGreen = bright | green, brightBlue = bright | blue, brightYellow = bright | yellow, brightMagenta = bright | magenta, brightCyan = bright | cyan, white = bright | lightGray, } static if (__VERSION__ < 2092) private extern (C++) void noop(const ref Loc loc, const(char)* format, ...) {} else pragma(printf) private extern (C++) void noop(const ref Loc loc, const(char)* format, ...) {} package auto previewErrorFunc(bool isDeprecated, FeatureState featureState) @safe @nogc pure nothrow { if (featureState == FeatureState.enabled) return &error; else if (featureState == FeatureState.disabled || isDeprecated) return &noop; else return &deprecation; } package auto previewSupplementalFunc(bool isDeprecated, FeatureState featureState) @safe @nogc pure nothrow { if (featureState == FeatureState.enabled) return &errorSupplemental; else if (featureState == FeatureState.disabled || isDeprecated) return &noop; else return &deprecationSupplemental; } /** * Print an error message, increasing the global error count. * Params: * loc = location of error * format = printf-style format specification * ... = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void error(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); verror(loc, format, ap); va_end(ap); } else pragma(printf) extern (C++) void error(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); verror(loc, format, ap); va_end(ap); } /** * Same as above, but takes a filename and line information arguments as separate parameters. * Params: * filename = source file of error * linnum = line in the source file * charnum = column number on the line * format = printf-style format specification * ... = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void error(const(char)* filename, uint linnum, uint charnum, const(char)* format, ...) { const loc = Loc(filename, linnum, charnum); va_list ap; va_start(ap, format); verror(loc, format, ap); va_end(ap); } else pragma(printf) extern (C++) void error(const(char)* filename, uint linnum, uint charnum, const(char)* format, ...) { const loc = Loc(filename, linnum, charnum); va_list ap; va_start(ap, format); verror(loc, format, ap); va_end(ap); } /** * Print additional details about an error message. * Doesn't increase the error count or print an additional error prefix. * Params: * loc = location of error * format = printf-style format specification * ... = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void errorSupplemental(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); verrorSupplemental(loc, format, ap); va_end(ap); } else pragma(printf) extern (C++) void errorSupplemental(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); verrorSupplemental(loc, format, ap); va_end(ap); } /** * Print a warning message, increasing the global warning count. * Params: * loc = location of warning * format = printf-style format specification * ... = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void warning(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vwarning(loc, format, ap); va_end(ap); } else pragma(printf) extern (C++) void warning(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vwarning(loc, format, ap); va_end(ap); } /** * Print additional details about a warning message. * Doesn't increase the warning count or print an additional warning prefix. * Params: * loc = location of warning * format = printf-style format specification * ... = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void warningSupplemental(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vwarningSupplemental(loc, format, ap); va_end(ap); } else pragma(printf) extern (C++) void warningSupplemental(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vwarningSupplemental(loc, format, ap); va_end(ap); } /** * Print a deprecation message, may increase the global warning or error count * depending on whether deprecations are ignored. * Params: * loc = location of deprecation * format = printf-style format specification * ... = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void deprecation(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vdeprecation(loc, format, ap); va_end(ap); } else pragma(printf) extern (C++) void deprecation(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vdeprecation(loc, format, ap); va_end(ap); } /** * Print additional details about a deprecation message. * Doesn't increase the error count, or print an additional deprecation prefix. * Params: * loc = location of deprecation * format = printf-style format specification * ... = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void deprecationSupplemental(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vdeprecationSupplemental(loc, format, ap); va_end(ap); } else pragma(printf) extern (C++) void deprecationSupplemental(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vdeprecationSupplemental(loc, format, ap); va_end(ap); } /** * Print a verbose message. * Doesn't prefix or highlight messages. * Params: * loc = location of message * format = printf-style format specification * ... = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void message(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vmessage(loc, format, ap); va_end(ap); } else pragma(printf) extern (C++) void message(const ref Loc loc, const(char)* format, ...) { va_list ap; va_start(ap, format); vmessage(loc, format, ap); va_end(ap); } /** * Same as above, but doesn't take a location argument. * Params: * format = printf-style format specification * ... = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void message(const(char)* format, ...) { va_list ap; va_start(ap, format); vmessage(Loc.initial, format, ap); va_end(ap); } else pragma(printf) extern (C++) void message(const(char)* format, ...) { va_list ap; va_start(ap, format); vmessage(Loc.initial, format, ap); va_end(ap); } /** * The type of the diagnostic handler * see verrorPrint for arguments * Returns: true if error handling is done, false to continue printing to stderr */ alias DiagnosticHandler = bool delegate(const ref Loc location, Color headerColor, const(char)* header, const(char)* messageFormat, va_list args, const(char)* prefix1, const(char)* prefix2); /** * The diagnostic handler. * If non-null it will be called for every diagnostic message issued by the compiler. * If it returns false, the message will be printed to stderr as usual. */ __gshared DiagnosticHandler diagnosticHandler; /** * Print a tip message with the prefix and highlighting. * Params: * format = printf-style format specification * ... = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void tip(const(char)* format, ...) { va_list ap; va_start(ap, format); vtip(format, ap); va_end(ap); } else pragma(printf) extern (C++) void tip(const(char)* format, ...) { va_list ap; va_start(ap, format); vtip(format, ap); va_end(ap); } /** * Same as $(D error), but takes a va_list parameter, and optionally additional message prefixes. * Params: * loc = location of error * format = printf-style format specification * ap = printf-style variadic arguments * p1 = additional message prefix * p2 = additional message prefix * header = title of error message */ extern (C++) void verror(const ref Loc loc, const(char)* format, va_list ap, const(char)* p1 = null, const(char)* p2 = null, const(char)* header = "Error: "); /** * Same as $(D errorSupplemental), but takes a va_list parameter. * Params: * loc = location of error * format = printf-style format specification * ap = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void verrorSupplemental(const ref Loc loc, const(char)* format, va_list ap); else pragma(printf) extern (C++) void verrorSupplemental(const ref Loc loc, const(char)* format, va_list ap); /** * Same as $(D warning), but takes a va_list parameter. * Params: * loc = location of warning * format = printf-style format specification * ap = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void vwarning(const ref Loc loc, const(char)* format, va_list ap); else pragma(printf) extern (C++) void vwarning(const ref Loc loc, const(char)* format, va_list ap); /** * Same as $(D warningSupplemental), but takes a va_list parameter. * Params: * loc = location of warning * format = printf-style format specification * ap = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void vwarningSupplemental(const ref Loc loc, const(char)* format, va_list ap); else pragma(printf) extern (C++) void vwarningSupplemental(const ref Loc loc, const(char)* format, va_list ap); /** * Same as $(D deprecation), but takes a va_list parameter, and optionally additional message prefixes. * Params: * loc = location of deprecation * format = printf-style format specification * ap = printf-style variadic arguments * p1 = additional message prefix * p2 = additional message prefix */ extern (C++) void vdeprecation(const ref Loc loc, const(char)* format, va_list ap, const(char)* p1 = null, const(char)* p2 = null); /** * Same as $(D message), but takes a va_list parameter. * Params: * loc = location of message * format = printf-style format specification * ap = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void vmessage(const ref Loc loc, const(char)* format, va_list ap); else pragma(printf) extern (C++) void vmessage(const ref Loc loc, const(char)* format, va_list ap); /** * Same as $(D tip), but takes a va_list parameter. * Params: * format = printf-style format specification * ap = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void vtip(const(char)* format, va_list ap); else pragma(printf) extern (C++) void vtip(const(char)* format, va_list ap); /** * Same as $(D deprecationSupplemental), but takes a va_list parameter. * Params: * loc = location of deprecation * format = printf-style format specification * ap = printf-style variadic arguments */ static if (__VERSION__ < 2092) extern (C++) void vdeprecationSupplemental(const ref Loc loc, const(char)* format, va_list ap); else pragma(printf) extern (C++) void vdeprecationSupplemental(const ref Loc loc, const(char)* format, va_list ap); /** * 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(); /** * Try to stop forgetting to remove the breakpoints from * release builds. */ extern (C++) void halt();