return NULL;
}
- args->push (Parameter::create (sc, targ, NULL, NULL, NULL));
+ args->push (Parameter::create (Loc (), sc, targ,
+ NULL, NULL, NULL));
}
/* GCC generic and placeholder built-ins are marked as variadic, yet
void D_ATTRIBUTE_FORMAT(2,0) ATTRIBUTE_GCC_DIAG(2,0)
verrorReport (const Loc& loc, const char *format, va_list ap, ErrorKind kind,
- const char *prefix1 = NULL, const char *prefix2 = NULL)
+ const char *prefix1, const char *prefix2)
{
diagnostic_t diag_kind = DK_UNSPECIFIED;
int opt = 0;
}
else if (kind == ErrorKind::tip)
{
+ if (global.gag)
+ return;
+
diag_kind = DK_DEBUG;
verbatim = true;
}
case OPT_Wall:
if (value)
global.params.warnings = DIAGNOSTICinform;
- global.params.obsolete = value;
break;
case OPT_Wdeprecated:
global.compileEnv.previewIn = global.params.previewIn;
global.compileEnv.ddocOutput = global.params.ddoc.doOutput;
global.compileEnv.shortenedMethods = global.params.shortenedMethods;
- global.compileEnv.obsolete = global.params.obsolete;
/* Add in versions given on the command line. */
if (global.params.versionids)
error ("writing output file %s: %m", filename);
}
+/* Read ddoc macro files named by the DDOCFILES, then write the concatenated
+ the contents into DDOCBUF. */
+
+static void
+d_read_ddoc_files (Strings &ddocfiles, OutBuffer &ddocbuf)
+{
+ if (ddocbuf.length ())
+ return;
+
+ for (size_t i = 0; i < ddocfiles.length; i++)
+ {
+ int fd = open (ddocfiles[i], O_RDONLY);
+ bool ok = false;
+ struct stat buf;
+
+ if (fd == -1 || fstat (fd, &buf))
+ {
+ error ("unable to open %s for reading: %m", ddocfiles[i]);
+ continue;
+ }
+
+ /* Check we've not been given a directory, or a file bigger than 4GB. */
+ if (S_ISDIR (buf.st_mode))
+ errno = ENOENT;
+ else if (buf.st_size != unsigned (buf.st_size))
+ errno = EMFILE;
+ else
+ {
+ unsigned size = unsigned (buf.st_size);
+ char *buffer = (char *) xmalloc (size);
+
+ if (read (fd, buffer, size) == ssize_t (size))
+ {
+ ddocbuf.write (buffer, size);
+ ok = true;
+ }
+
+ free (buffer);
+ }
+
+ close (fd);
+ if (!ok)
+ fatal_error (input_location, "reading ddoc file %s: %m", ddocfiles[i]);
+ }
+}
+
+static void
+d_generate_ddoc_file (Module *m, OutBuffer &ddocbuf)
+{
+ input_location = make_location_t (m->loc);
+
+ d_read_ddoc_files (global.params.ddoc.files, ddocbuf);
+
+ OutBuffer ddocbuf_out;
+ gendocfile (m, ddocbuf.peekChars (), ddocbuf.length (), global.datetime,
+ global.errorSink, ddocbuf_out);
+
+ d_write_file (m->docfile.toChars (), ddocbuf_out.peekChars ());
+}
+
/* Implements the lang_hooks.parse_file routine for language D. */
static void
Modules modules;
modules.reserve (num_in_fnames);
+ /* Buffer for contents of .ddoc files. */
+ OutBuffer ddocbuf;
+
/* In this mode, the first file name is supposed to be a duplicate
of one of the input files. */
if (d_option.fonly && strcmp (d_option.fonly, main_input_filename) != 0)
if (m->filetype == FileType::ddoc)
{
- gendocfile (m, global.errorSink);
+ d_generate_ddoc_file (m, ddocbuf);
+
/* Remove M from list of modules. */
modules.remove (i);
i--;
if (global.params.verbose)
message ("import %s", m->toChars ());
- genhdrfile (m);
+ OutBuffer buf;
+ genhdrfile (m, buf);
+ d_write_file (m->hdrfile.toChars (), buf.peekChars ());
}
dump_headers = true;
if (global.params.json.doOutput)
{
OutBuffer buf;
- json_generate (&buf, &modules);
+ json_generate (modules, buf);
d_write_file (global.params.json.name.ptr, buf.peekChars ());
}
for (size_t i = 0; i < modules.length; i++)
{
Module *m = modules[i];
- gendocfile (m, global.errorSink);
+ d_generate_ddoc_file (m, ddocbuf);
}
}
OutBuffer buf;
buf.doindent = 1;
- moduleToBuffer (&buf, m);
+ moduleToBuffer (buf, m);
message ("%s", buf.peekChars ());
}
}
-4574d1728d1f7e52ff40e6733b8c39889d128349
+f9efc98fd7954741333f72c6a50af273f3863a1a
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
{
assert(visibility.kind > Visibility.Kind.undefined);
OutBuffer buf;
- visibilityToBuffer(&buf, visibility);
+ visibilityToBuffer(buf, visibility);
return buf.extractChars();
}
import dmd.canthrow;
import dmd.dclass;
import dmd.declaration;
+import dmd.errorsink;
import dmd.expression;
import dmd.func;
import dmd.globals;
* Params:
* s = statement to check for block exit status
* func = function that statement s is in
- * mustNotThrow = generate an error if it throws
+ * eSink = generate an error if it throws
* Returns:
* BE.xxxx
*/
-int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
+int blockExit(Statement s, FuncDeclaration func, ErrorSink eSink)
{
int result = BE.none;
if (s.exp.type && s.exp.type.toBasetype().isTypeNoreturn())
result = BE.halt;
- result |= canThrow(s.exp, func, mustNotThrow);
+ result |= canThrow(s.exp, func, eSink !is null);
}
}
// Deprecated in 2.100
// Make an error in 2.110
if (sl && sl.isCaseStatement())
- s.deprecation("switch case fallthrough - use 'goto %s;' if intended", gototype);
+ global.errorSink.deprecation(s.loc, "switch case fallthrough - use 'goto %s;' if intended", gototype);
else
- s.error("switch case fallthrough - use 'goto %s;' if intended", gototype);
+ global.errorSink.error(s.loc, "switch case fallthrough - use 'goto %s;' if intended", gototype);
}
}
}
if (!(result & BE.fallthru) && !s.comeFrom())
{
- if (blockExit(s, func, mustNotThrow) != BE.halt && s.hasCode() &&
+ if (blockExit(s, func, eSink) != BE.halt && s.hasCode() &&
s.loc != Loc.initial) // don't emit warning for generated code
- s.warning("statement is not reachable");
+ global.errorSink.warning(s.loc, "statement is not reachable");
}
else
{
result &= ~BE.fallthru;
- result |= blockExit(s, func, mustNotThrow);
+ result |= blockExit(s, func, eSink);
}
slast = s;
}
{
if (s)
{
- int r = blockExit(s, func, mustNotThrow);
+ int r = blockExit(s, func, eSink);
result |= r & ~(BE.break_ | BE.continue_ | BE.fallthru);
if ((r & (BE.fallthru | BE.continue_ | BE.break_)) == 0)
result &= ~BE.fallthru;
void visitScope(ScopeStatement s)
{
//printf("ScopeStatement::blockExit(%p)\n", s.statement);
- result = blockExit(s.statement, func, mustNotThrow);
+ result = blockExit(s.statement, func, eSink);
}
void visitWhile(WhileStatement s)
{
if (s._body)
{
- result = blockExit(s._body, func, mustNotThrow);
+ result = blockExit(s._body, func, eSink);
if (result == BE.break_)
{
result = BE.fallthru;
result = BE.fallthru;
if (result & BE.fallthru)
{
- result |= canThrow(s.condition, func, mustNotThrow);
+ result |= canThrow(s.condition, func, eSink !is null);
if (!(result & BE.break_) && s.condition.toBool().hasValue(true))
result &= ~BE.fallthru;
result = BE.fallthru;
if (s._init)
{
- result = blockExit(s._init, func, mustNotThrow);
+ result = blockExit(s._init, func, eSink);
if (!(result & BE.fallthru))
return;
}
if (s.condition)
{
- result |= canThrow(s.condition, func, mustNotThrow);
+ result |= canThrow(s.condition, func, eSink !is null);
const opt = s.condition.toBool();
if (opt.hasValue(true))
result &= ~BE.fallthru; // the body must do the exiting
if (s._body)
{
- int r = blockExit(s._body, func, mustNotThrow);
+ int r = blockExit(s._body, func, eSink);
if (r & (BE.break_ | BE.goto_))
result |= BE.fallthru;
result |= r & ~(BE.fallthru | BE.break_ | BE.continue_);
}
if (s.increment)
- result |= canThrow(s.increment, func, mustNotThrow);
+ result |= canThrow(s.increment, func, eSink !is null);
}
void visitForeach(ForeachStatement s)
{
result = BE.fallthru;
- result |= canThrow(s.aggr, func, mustNotThrow);
+ result |= canThrow(s.aggr, func, eSink !is null);
if (s._body)
- result |= blockExit(s._body, func, mustNotThrow) & ~(BE.break_ | BE.continue_);
+ result |= blockExit(s._body, func, eSink) & ~(BE.break_ | BE.continue_);
}
void visitForeachRange(ForeachRangeStatement s)
{
//printf("IfStatement::blockExit(%p)\n", s);
result = BE.none;
- result |= canThrow(s.condition, func, mustNotThrow);
+ result |= canThrow(s.condition, func, eSink !is null);
const opt = s.condition.toBool();
if (opt.hasValue(true))
{
- result |= blockExit(s.ifbody, func, mustNotThrow);
+ result |= blockExit(s.ifbody, func, eSink);
}
else if (opt.hasValue(false))
{
- result |= blockExit(s.elsebody, func, mustNotThrow);
+ result |= blockExit(s.elsebody, func, eSink);
}
else
{
- result |= blockExit(s.ifbody, func, mustNotThrow);
- result |= blockExit(s.elsebody, func, mustNotThrow);
+ result |= blockExit(s.ifbody, func, eSink);
+ result |= blockExit(s.elsebody, func, eSink);
}
//printf("IfStatement::blockExit(%p) = x%x\n", s, result);
}
void visitConditional(ConditionalStatement s)
{
- result = blockExit(s.ifbody, func, mustNotThrow);
+ result = blockExit(s.ifbody, func, eSink);
if (s.elsebody)
- result |= blockExit(s.elsebody, func, mustNotThrow);
+ result |= blockExit(s.elsebody, func, eSink);
}
void visitPragma(PragmaStatement s)
void visitSwitch(SwitchStatement s)
{
result = BE.none;
- result |= canThrow(s.condition, func, mustNotThrow);
+ result |= canThrow(s.condition, func, eSink !is null);
if (s._body)
{
- result |= blockExit(s._body, func, mustNotThrow);
+ result |= blockExit(s._body, func, eSink);
if (result & BE.break_)
{
result |= BE.fallthru;
void visitCase(CaseStatement s)
{
- result = blockExit(s.statement, func, mustNotThrow);
+ result = blockExit(s.statement, func, eSink);
}
void visitDefault(DefaultStatement s)
{
- result = blockExit(s.statement, func, mustNotThrow);
+ result = blockExit(s.statement, func, eSink);
}
void visitGotoDefault(GotoDefaultStatement s)
{
result = BE.return_;
if (s.exp)
- result |= canThrow(s.exp, func, mustNotThrow);
+ result |= canThrow(s.exp, func, eSink !is null);
}
void visitBreak(BreakStatement s)
void visitSynchronized(SynchronizedStatement s)
{
- result = blockExit(s._body, func, mustNotThrow);
+ result = blockExit(s._body, func, eSink);
}
void visitWith(WithStatement s)
{
result = BE.none;
- result |= canThrow(s.exp, func, mustNotThrow);
- result |= blockExit(s._body, func, mustNotThrow);
+ result |= canThrow(s.exp, func, eSink !is null);
+ result |= blockExit(s._body, func, eSink);
}
void visitTryCatch(TryCatchStatement s)
{
assert(s._body);
- result = blockExit(s._body, func, false);
+ result = blockExit(s._body, func, null);
int catchresult = 0;
foreach (c; *s.catches)
if (c.type == Type.terror)
continue;
- int cresult = blockExit(c.handler, func, mustNotThrow);
+ int cresult = blockExit(c.handler, func, eSink);
/* If we're catching Object, then there is no throwing
*/
}
catchresult |= cresult;
}
- if (mustNotThrow && (result & BE.throw_))
+ if (eSink && (result & BE.throw_))
{
// now explain why this is nothrow
- blockExit(s._body, func, mustNotThrow);
+ blockExit(s._body, func, eSink);
}
result |= catchresult;
}
{
result = BE.fallthru;
if (s._body)
- result = blockExit(s._body, func, false);
+ result = blockExit(s._body, func, null);
// check finally body as well, it may throw (bug #4082)
int finalresult = BE.fallthru;
if (s.finalbody)
- finalresult = blockExit(s.finalbody, func, false);
+ finalresult = blockExit(s.finalbody, func, null);
// If either body or finalbody halts
if (result == BE.halt)
if (finalresult == BE.halt)
result = BE.none;
- if (mustNotThrow)
+ if (eSink)
{
// now explain why this is nothrow
if (s._body && (result & BE.throw_))
- blockExit(s._body, func, mustNotThrow);
+ blockExit(s._body, func, eSink);
if (s.finalbody && (finalresult & BE.throw_))
- blockExit(s.finalbody, func, mustNotThrow);
+ blockExit(s.finalbody, func, eSink);
}
version (none)
// destructor call, exit of synchronized statement, etc.
if (result == BE.halt && finalresult != BE.halt && s.finalbody && s.finalbody.hasCode())
{
- s.finalbody.warning("statement is not reachable");
+ eSink.warning(s.finalbody.loc, "statement is not reachable");
}
}
if (s.internalThrow)
{
// https://issues.dlang.org/show_bug.cgi?id=8675
- // Allow throwing 'Throwable' object even if mustNotThrow.
+ // Allow throwing 'Throwable' object even if eSink.
result = BE.fallthru;
return;
}
- result = checkThrow(s.loc, s.exp, mustNotThrow, func);
+ result = checkThrow(s.loc, s.exp, func, eSink);
}
void visitGoto(GotoStatement s)
void visitLabel(LabelStatement s)
{
//printf("LabelStatement::blockExit(%p)\n", s);
- result = blockExit(s.statement, func, mustNotThrow);
+ result = blockExit(s.statement, func, eSink);
if (s.breaks)
result |= BE.fallthru;
}
{
if(func)
func.setThrow(s.loc, "`asm` statement is assumed to throw - mark it with `nothrow` if it does not");
- if (mustNotThrow)
- s.error("`asm` statement is assumed to throw - mark it with `nothrow` if it does not"); // TODO
+ if (eSink)
+ eSink.error(s.loc, "`asm` statement is assumed to throw - mark it with `nothrow` if it does not"); // TODO
else
result |= BE.throw_;
}
+ Params:
+ loc = location of the `throw`
+ exp = expression yielding the throwable
- + mustNotThrow = inside of a `nothrow` scope?
+ + eSink = if !null then inside of a `nothrow` scope
+ func = function containing the `throw`
+
+ Returns: `BE.[err]throw` depending on the type of `exp`
+/
-BE checkThrow(ref const Loc loc, Expression exp, const bool mustNotThrow, FuncDeclaration func)
+BE checkThrow(ref const Loc loc, Expression exp, FuncDeclaration func, ErrorSink eSink)
{
- import dmd.errors : error;
-
Type t = exp.type.toBasetype();
ClassDeclaration cd = t.isClassHandle();
assert(cd);
{
return BE.errthrow;
}
- if (mustNotThrow)
- loc.error("`%s` is thrown but not caught", exp.type.toChars());
+ if (eSink)
+ eSink.error(loc, "`%s` is thrown but not caught", exp.type.toChars());
else if (func)
func.setThrow(loc, "`%s` is thrown but not caught", exp.type);
override void visit(ThrowExp te)
{
- const res = checkThrow(te.loc, te.e1, mustNotThrow, func);
+ const res = checkThrow(te.loc, te.e1, func, mustNotThrow ? global.errorSink : null);
assert((res & ~(CT.exception | CT.error)) == 0);
result |= res;
}
import dmd.astenums;
import dmd.cond;
-import dmd.errors;
+import dmd.errorsink;
import dmd.expression;
import dmd.globals;
import dmd.identifier;
* format = format string
* args = arguments to match with format string
* isVa_list = if a "v" function (format check only)
+ * eSink = where the error messages go
*
* Returns:
* `true` if errors occurred
* C99 7.19.6.1
* https://www.cplusplus.com/reference/cstdio/printf/
*/
-bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expression[] args, bool isVa_list)
+public
+bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expression[] args, bool isVa_list, ErrorSink eSink)
{
//printf("checkPrintFormat('%.*s')\n", cast(int)format.length, format.ptr);
size_t n; // index in args
{
// format check only
if (fmt == Format.error)
- deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
+ eSink.deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
continue;
}
if (n == args.length)
{
if (args.length < (n + 1))
- deprecation(loc, "more format specifiers than %d arguments", cast(int)n);
+ eSink.deprecation(loc, "more format specifiers than %d arguments", cast(int)n);
else
skip = true;
return null;
void errorMsg(const char* prefix, Expression arg, const char* texpect, Type tactual)
{
- deprecation(arg.loc, "%sargument `%s` for format specification `\"%.*s\"` must be `%s`, not `%s`",
+ eSink.deprecation(arg.loc, "%sargument `%s` for format specification `\"%.*s\"` must be `%s`, not `%s`",
prefix ? prefix : "", arg.toChars(), cast(int)slice.length, slice.ptr, texpect, tactual.toChars());
}
else
errorMsg(null, e, (c_longsize == 4 ? "int" : "long"), t);
if (t.isintegral() && t.size() != c_longsize)
- errorSupplemental(e.loc, "C `long` is %d bytes on your system", c_longsize);
+ eSink.errorSupplemental(e.loc, "C `long` is %d bytes on your system", c_longsize);
}
break;
break;
case Format.n: // pointer to int
- if (!(t.ty == Tpointer && tnext.ty == Tint32))
+ if (!(t.ty == Tpointer && tnext.ty == Tint32 && tnext.isMutable()))
errorMsg(null, e, "int*", t);
break;
break;
case Format.error:
- deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
+ eSink.deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
break;
case Format.GNU_m:
* format = format string
* args = arguments to match with format string
* isVa_list = if a "v" function (format check only)
+ * eSink = where the error messages go
*
* Returns:
* `true` if errors occurred
* C99 7.19.6.2
* https://www.cplusplus.com/reference/cstdio/scanf/
*/
-bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expression[] args, bool isVa_list)
+public
+bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expression[] args, bool isVa_list, ErrorSink eSink)
{
size_t n = 0;
for (size_t i = 0; i < format.length;)
{
// format check only
if (fmt == Format.error)
- deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
+ eSink.deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
continue;
}
if (n == args.length)
{
if (!asterisk)
- deprecation(loc, "more format specifiers than %d arguments", cast(int)n);
+ eSink.deprecation(loc, "more format specifiers than %d arguments", cast(int)n);
return null;
}
return args[n++];
void errorMsg(const char* prefix, Expression arg, const char* texpect, Type tactual)
{
- deprecation(arg.loc, "%sargument `%s` for format specification `\"%.*s\"` must be `%s`, not `%s`",
+ eSink.deprecation(arg.loc, "%sargument `%s` for format specification `\"%.*s\"` must be `%s`, not `%s`",
prefix ? prefix : "", arg.toChars(), cast(int)slice.length, slice.ptr, texpect, tactual.toChars());
}
break;
case Format.error:
- deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
+ eSink.deprecation(loc, "format specifier `\"%.*s\"` is invalid", cast(int)slice.length, slice.ptr);
break;
case Format.GNU_m:
return false;
}
+/*****************************************************************************************************/
+
private:
/**************************************
}
auto fparams = new Parameters();
- fparams.push(new Parameter(STC.nodtor, sd.type, Id.p, null, null));
+ fparams.push(new Parameter(loc, STC.nodtor, sd.type, Id.p, null, null));
auto tf = new TypeFunction(ParameterList(fparams), sd.handleType(), LINK.d, stc | STC.ref_);
auto fop = new FuncDeclaration(declLoc, Loc.initial, Id.assign, stc, tf);
fop.storage_class |= STC.inference;
TypeFunction tfeqptr;
{
Scope scx;
+ scx.eSink = sc.eSink;
/* const bool opEquals(ref const S s);
*/
auto parameters = new Parameters();
- parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, null, null, null));
+ parameters.push(new Parameter(Loc.initial, STC.ref_ | STC.const_, sd.type, null, null, null));
tfeqptr = new TypeFunction(ParameterList(parameters), Type.tbool, LINK.d);
tfeqptr.mod = MODFlags.const_;
tfeqptr = cast(TypeFunction)tfeqptr.typeSemantic(Loc.initial, &scx);
Loc declLoc; // loc is unnecessary so __xopEquals is never called directly
Loc loc; // loc is unnecessary so errors are gagged
auto parameters = new Parameters();
- parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));
+ parameters.push(new Parameter(loc, STC.ref_ | STC.const_, sd.type, Id.p, null, null));
auto tf = new TypeFunction(ParameterList(parameters), Type.tbool, LINK.d, STC.const_);
tf = tf.addSTC(STC.const_).toTypeFunction();
Identifier id = Id.xopEquals;
TypeFunction tfcmpptr;
{
Scope scx;
+ scx.eSink = sc.eSink;
/* const int opCmp(ref const S s);
*/
auto parameters = new Parameters();
- parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, null, null, null));
+ parameters.push(new Parameter(Loc.initial, STC.ref_ | STC.const_, sd.type, null, null, null));
tfcmpptr = new TypeFunction(ParameterList(parameters), Type.tint32, LINK.d);
tfcmpptr.mod = MODFlags.const_;
tfcmpptr = cast(TypeFunction)tfcmpptr.typeSemantic(Loc.initial, &scx);
Loc declLoc; // loc is unnecessary so __xopCmp is never called directly
Loc loc; // loc is unnecessary so errors are gagged
auto parameters = new Parameters();
- parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));
+ parameters.push(new Parameter(loc, STC.ref_ | STC.const_, sd.type, Id.p, null, null));
auto tf = new TypeFunction(ParameterList(parameters), Type.tint32, LINK.d, STC.const_);
tf = tf.addSTC(STC.const_).toTypeFunction();
Identifier id = Id.xopCmp;
Loc declLoc; // loc is unnecessary so __xtoHash is never called directly
Loc loc; // internal code should have no loc to prevent coverage
auto parameters = new Parameters();
- parameters.push(new Parameter(STC.ref_ | STC.const_, sd.type, Id.p, null, null));
+ parameters.push(new Parameter(loc, STC.ref_ | STC.const_, sd.type, Id.p, null, null));
auto tf = new TypeFunction(ParameterList(parameters), Type.thash_t, LINK.d, STC.nothrow_ | STC.trusted);
Identifier id = Id.xtoHash;
auto fop = new FuncDeclaration(declLoc, Loc.initial, id, STC.static_, tf);
// // TODO: if (del) delete (char*)this;
// return (void*) this;
// }
- Parameter delparam = new Parameter(STC.undefined_, Type.tuns32, Identifier.idPool("del"), new IntegerExp(dtor.loc, 0, Type.tuns32), null);
+ Parameter delparam = new Parameter(Loc.initial, STC.undefined_, Type.tuns32, Identifier.idPool("del"), new IntegerExp(dtor.loc, 0, Type.tuns32), null);
Parameters* params = new Parameters;
params.push(delparam);
const stc = dtor.storage_class & ~STC.scope_; // because we add the `return this;` later
return null;
// Generate shim only when ABI incompatible on target platform
- if (ad.classKind != ClassKind.cpp || !target.cpp.wrapDtorInExternD)
+ if (dtor._linkage != LINK.cpp || !target.cpp.wrapDtorInExternD)
return dtor;
// generate member function that adjusts calling convention
{
auto fparams = new Parameters();
auto structType = sd.type;
- fparams.push(new Parameter(paramStc | STC.ref_ | STC.return_ | STC.scope_, structType, Id.p, null, null));
+ fparams.push(new Parameter(Loc.initial, paramStc | STC.ref_ | STC.return_ | STC.scope_, structType, Id.p, null, null));
ParameterList pList = ParameterList(fparams);
auto tf = new TypeFunction(pList, structType, LINK.d, STC.ref_);
auto ccd = new CtorDeclaration(sd.loc, Loc.initial, STC.ref_, tf, true);
foreach (params; pparams)
{
auto p = aggrfe ? (*aggrfe.parameters)[i] : rangefe.prm;
- params.push(new Parameter(p.storageClass, p.type, p.ident, null, null));
+ params.push(new Parameter(aloc, p.storageClass, p.type, p.ident, null, null));
}
}
Expression[2] res;
default:
// ImportC extensions: parse as a D asm block.
- s = parseAsm();
+ s = parseAsm(compileEnv.masm);
break;
}
break;
}
Identifier id;
+ const paramLoc = token.loc;
auto t = cparseDeclarator(DTR.xparameter, tspec, id, specifier);
if (token.value == TOK.__attribute__)
cparseGnuAttributes(specifier);
if (specifier.mod & MOD.xconst)
t = toConst(t);
- auto param = new AST.Parameter(specifiersToSTC(LVL.parameter, specifier),
+ auto param = new AST.Parameter(paramLoc, specifiersToSTC(LVL.parameter, specifier),
t, id, null, null);
parameters.push(param);
if (token.value == TOK.rightParenthesis || token.value == TOK.endOfFile)
nextToken();
else
{
- error("extended-decl-modifier expected");
- break;
+ error("extended-decl-modifier expected after `__declspec(`, saw `%s` instead", token.toChars());
+ nextToken();
+ if (token.value != TOK.rightParenthesis)
+ break;
}
}
}
module dmd.cppmangle;
-import core.stdc.string;
import core.stdc.stdio;
import dmd.arraytypes;
import dmd.root.rootobject;
import dmd.root.string;
import dmd.target;
-import dmd.tokens;
import dmd.typesem;
import dmd.visitor;
module dmd.ctfeexpr;
import core.stdc.stdio;
-import core.stdc.stdlib;
import core.stdc.string;
import dmd.arraytypes;
import dmd.astenums;
}
if (auto aae = e.isAssocArrayLiteralExp())
{
- emplaceExp!(AssocArrayLiteralExp)(&ue, e.loc, copyLiteralArray(aae.keys), copyLiteralArray(aae.values));
+ emplaceExp!(AssocArrayLiteralExp)(&ue, aae.loc, copyLiteralArray(aae.keys), copyLiteralArray(aae.values));
AssocArrayLiteralExp r = ue.exp().isAssocArrayLiteralExp();
- r.type = e.type;
+ r.type = aae.type;
+ r.lowering = aae.lowering;
r.ownedByCtfe = OwnedBy.ctfe;
return ue;
}
import dmd.dscope;
import dmd.dstruct;
import dmd.dsymbol;
-import dmd.errors;
import dmd.escape;
import dmd.expression;
import dmd.expressionsem;
import dmd.hdrgen;
import dmd.location;
import dmd.impcnvtab;
-import dmd.id;
import dmd.importc;
import dmd.init;
import dmd.intrange;
import dmd.root.utf;
import dmd.tokens;
import dmd.typesem;
-import dmd.visitor;
enum LOG = false;
{
// no need for an extra cast when matching is exact
- if (match == MATCH.convert && e.type.isTypeNoreturn())
+ if (match == MATCH.convert && e.type.isTypeNoreturn() && e.op != EXP.type)
{
return specialNoreturnCast(e, t);
}
{
//printf("FuncExp::implicitCastTo type = %p %s, t = %s\n", e.type, e.type ? e.type.toChars() : NULL, t.toChars());
FuncExp fe;
- if (e.matchType(t, sc, &fe) > MATCH.nomatch)
+ if (e.matchType(t, sc, &fe, global.errorSink) > MATCH.nomatch)
{
return fe;
}
MATCH visitFunc(FuncExp e)
{
//printf("FuncExp::implicitConvTo type = %p %s, t = %s\n", e.type, e.type ? e.type.toChars() : NULL, t.toChars());
- MATCH m = e.matchType(t, null, null, 1);
+ MATCH m = e.matchType(t, null, null, global.errorSinkNull);
if (m > MATCH.nomatch)
{
return m;
{
return e;
}
- if (e.type.isTypeNoreturn())
+ if (e.type.isTypeNoreturn() && e.op != EXP.type)
{
return specialNoreturnCast(e, t);
}
{
//printf("FuncExp::castTo type = %s, t = %s\n", e.type.toChars(), t.toChars());
FuncExp fe;
- if (e.matchType(t, sc, &fe, 1) > MATCH.nomatch)
+ if (e.matchType(t, sc, &fe, global.errorSinkNull) > MATCH.nomatch)
{
return fe;
}
import dmd.aggregate;
import dmd.arraytypes;
import dmd.astenums;
-import dmd.attrib;
import dmd.gluelayer;
import dmd.declaration;
import dmd.dscope;
import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.func;
-import dmd.globals;
import dmd.id;
import dmd.identifier;
import dmd.location;
return 0;
}
+ // opaque class is not abstract if it is not declared abstract
+ if (!members)
+ return no();
+
for (size_t i = 0; i < members.length; i++)
{
auto s = (*members)[i];
import dmd.aggregate;
import dmd.arraytypes;
import dmd.astenums;
-import dmd.attrib;
import dmd.ctorflow;
import dmd.dclass;
import dmd.delegatize;
{
buf.printf("_%s_%d", ident.toChars(), i);
auto id = Identifier.idPool(buf.extractSlice());
- auto arg = new Parameter(STC.in_, t, id, null);
+ auto arg = new Parameter(Loc.initial, STC.in_, t, id, null);
}
else
{
- auto arg = new Parameter(0, t, null, null, null);
+ auto arg = new Parameter(Loc.initial, 0, t, null, null, null);
}
(*args)[i] = arg;
if (!t.deco)
{
inuse++;
_init = _init.initializerSemantic(_scope, type, INITinterpret);
+ import dmd.semantic2 : lowerStaticAAs;
+ lowerStaticAAs(this, _scope);
_scope = null;
inuse--;
}
import dmd.expression;
import dmd.expressionsem;
import dmd.func;
-import dmd.globals;
import dmd.init;
import dmd.initsem;
import dmd.location;
import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.expression;
-import dmd.globals;
import dmd.id;
import dmd.identifier;
import dmd.init;
import dmd.location;
import dmd.mtype;
-import dmd.tokens;
import dmd.typesem;
import dmd.visitor;
import dmd.initsem;
import dmd.location;
import dmd.mtype;
-import dmd.printast;
import dmd.root.rmem;
import dmd.root.array;
import dmd.root.ctfloat;
{
if (ctfeGlobals.callDepth > CTFE_RECURSION_LIMIT)
{
- // This is a compiler error. It must not be suppressed.
- global.gag = 0;
fd.error("CTFE recursion limit exceeded");
e = CTFEExp.cantexp;
break;
istate.start = null;
}
- s.error("statement `%s` cannot be interpreted at compile time", s.toChars());
+ error(s.loc, "statement `%s` cannot be interpreted at compile time", s.toChars());
result = CTFEExp.cantexp;
}
{
// To support this, we need to copy all the closure vars
// into the delegate literal.
- s.error("closures are not yet supported in CTFE");
+ error(s.loc, "closures are not yet supported in CTFE");
result = CTFEExp.cantexp;
return;
}
if (!scase)
{
if (s.hasNoDefault)
- s.error("no `default` or `case` for `%s` in `switch` statement", econdition.toChars());
+ error(s.loc, "no `default` or `case` for `%s` in `switch` statement", econdition.toChars());
scase = s.sdefault;
}
return;
istate.start = null;
}
- s.error("`asm` statements cannot be interpreted at compile time");
+ error(s.loc, "`asm` statements cannot be interpreted at compile time");
result = CTFEExp.cantexp;
}
result = interpret(&ue, e.msg, istate);
if (exceptionOrCant(result))
return;
- if (StringExp se = result.isStringExp())
+ result = scrubReturnValue(e.loc, result);
+ if (StringExp se = result.toStringExp())
e.error("%s", se.toStringz().ptr);
else
e.error("%s", result.toChars());
import core.stdc.ctype;
import core.stdc.string;
-import dmd.doc;
import dmd.common.outbuffer;
import dmd.root.rmem;
-extern (C++) struct MacroTable
+@trusted:
+
+struct MacroTable
{
/**********************************
* Define name=text macro.
* name = name of macro
* text = text of macro
*/
- extern (D) void define(const(char)[] name, const(char)[] text) nothrow pure @safe
+ void define(const(char)[] name, const(char)[] text) nothrow pure @safe
{
//printf("MacroTable::define('%.*s' = '%.*s')\n", cast(int)name.length, name.ptr, text.length, text.ptr);
if (auto table = name in mactab)
mactab[name] = new Macro(name, text);
}
+ alias fp_t = bool function(const(char)* p) @nogc nothrow pure;
+
/*****************************************************
* Look for macros in buf and expand them in place.
* Only look at the text in buf from start to pend.
*
* Returns: `true` on success, `false` when the recursion limit was reached
*/
- extern (D) bool expand(ref OutBuffer buf, size_t start, ref size_t pend, const(char)[] arg, int recursionLimit) nothrow pure
+ bool expand(ref OutBuffer buf, size_t start, ref size_t pend, const(char)[] arg, int recursionLimit,
+ fp_t isIdStart, fp_t isIdTail) nothrow pure
{
version (none)
{
end += marg.length - 2;
// Scan replaced text for further expansion
size_t mend = u + marg.length;
- const success = expand(buf, u, mend, null, recursionLimit);
+ const success = expand(buf, u, mend, null, recursionLimit, isIdStart, isIdTail);
if (!success)
return false;
end += mend - (u + marg.length);
end += -2 + 2 + marg.length + 2;
// Scan replaced text for further expansion
size_t mend = u + 2 + marg.length;
- const success = expand(buf, u + 2, mend, null, recursionLimit);
+ const success = expand(buf, u + 2, mend, null, recursionLimit, isIdStart, isIdTail);
if (!success)
return false;
end += mend - (u + 2 + marg.length);
/* Scan forward to find end of macro name and
* beginning of macro argument (marg).
*/
- for (v = u + 2; v < end; v += utfStride(p + v))
+ for (v = u + 2; v < end; v += utfStride(p[v]))
{
if (!isIdTail(p + v))
{
// Scan replaced text for further expansion
m.inuse++;
size_t mend = v + 1 + 2 + m.text.length + 2;
- const success = expand(buf, v + 1, mend, marg, recursionLimit);
+ const success = expand(buf, v + 1, mend, marg, recursionLimit, isIdStart, isIdTail);
if (!success)
return false;
end += mend - (v + 1 + 2 + m.text.length + 2);
private:
- extern (D) Macro* search(const(char)[] name) @nogc nothrow pure @safe
+ Macro* search(const(char)[] name) @nogc nothrow pure @safe
{
//printf("Macro::search(%.*s)\n", cast(int)name.length, name.ptr);
if (auto table = name in mactab)
* copy allocated with mem.xmalloc()
*/
-char[] memdup(const(char)[] p) nothrow pure @trusted
+char[] memdup(const(char)[] p) nothrow pure
{
size_t len = p.length;
return (cast(char*)memcpy(mem.xmalloc(len), p.ptr, len))[0 .. len];
//printf("extractArg%d('%.*s') = '%.*s'\n", n, cast(int)end, p, cast(int)marg.length, marg.ptr);
return v;
}
+
+/*****************************************
+ * Get number of UTF-8 code units in code point that starts with `c`
+ * Params:
+ * c = starting code unit
+ * Returns: number of UTF-8 code units (i.e. bytes), else 1 on invalid UTF start
+ */
+@safe
+int utfStride(char c) @nogc nothrow pure
+{
+ return
+ c < 0x80 ? 1 :
+ c < 0xC0 ? 1 : // invalid UTF start
+ c < 0xE0 ? 2 :
+ c < 0xF0 ? 3 :
+ c < 0xF8 ? 4 :
+ c < 0xFC ? 5 :
+ c < 0xFE ? 6 :
+ 1; // invalid UTF start
+}
+
+unittest
+{
+ assert(utfStride(0) == 1);
+ assert(utfStride(0x80) == 1);
+ assert(utfStride(0xC0) == 2);
+ assert(utfStride(0xE0) == 3);
+ assert(utfStride(0xF0) == 4);
+ assert(utfStride(0xF8) == 5);
+ assert(utfStride(0xFC) == 6);
+ assert(utfStride(0xFE) == 1);
+}
{
filetype = FileType.c;
+ global.compileEnv.masm = target.os == Target.OS.Windows && !target.omfobj; // Microsoft inline assembler format
scope p = new CParser!AST(this, buf, cast(bool) docfile, global.errorSink, target.c, &defines, &global.compileEnv);
+ global.compileEnv.masm = false;
p.nextToken();
checkCompiledImport();
members = p.parseModule();
// Back end
int doppelganger; // sub-module
Symbol* cov; // private uint[] __coverage;
- uint* covb; // bit array of valid code line numbers
+ uint[] covb; // bit array of valid code line numbers
Symbol* sictor; // module order independent constructor
Symbol* sctor; // module constructor
Symbol* sdtor; // module destructor
import dmd.root.string;
import dmd.root.utf;
import dmd.tokens;
-import dmd.utils;
import dmd.visitor;
+private:
+
+public
struct Escape
{
const(char)[][char.max] strings;
/***********************************************************
*/
-private class Section
+class Section
{
const(char)[] name;
const(char)[] body_;
assert(0);
}
- void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)
+ void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, ref OutBuffer buf)
{
assert(a.length);
if (name.length)
size_t o = buf.length;
buf.write(body_);
escapeStrayParenthesis(loc, buf, o, true, sc.eSink);
- highlightText(sc, a, loc, *buf, o);
+ highlightText(sc, a, loc, buf, o);
buf.writestring(")");
}
}
/***********************************************************
*/
-private final class ParamSection : Section
+final class ParamSection : Section
{
- override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)
+ override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, ref OutBuffer buf)
{
assert(a.length);
Dsymbol s = (*a)[0]; // test
}
else if (fparam && fparam.type && fparam.ident)
{
- .toCBuffer(fparam.type, buf, fparam.ident, &hgs);
+ toCBuffer(fparam.type, buf, fparam.ident, hgs);
}
else
{
buf.write(namestart[0 .. namelen]);
}
escapeStrayParenthesis(loc, buf, o, true, sc.eSink);
- highlightCode(sc, a, *buf, o);
+ highlightCode(sc, a, buf, o);
}
buf.writestring(")");
buf.writestring("$(DDOC_PARAM_DESC ");
size_t o = buf.length;
buf.write(textstart[0 .. textlen]);
escapeStrayParenthesis(loc, buf, o, true, sc.eSink);
- highlightText(sc, a, loc, *buf, o);
+ highlightText(sc, a, loc, buf, o);
}
buf.writestring(")");
}
/***********************************************************
*/
-private final class MacroSection : Section
+final class MacroSection : Section
{
- override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, OutBuffer* buf)
+ override void write(Loc loc, DocComment* dc, Scope* sc, Dsymbols* a, ref OutBuffer buf)
{
//printf("MacroSection::write()\n");
DocComment.parseMacros(dc.escapetable, *dc.pmacrotable, body_);
}
}
-private alias Sections = Array!(Section);
+alias Sections = Array!(Section);
// Workaround for missing Parameter instance for variadic params. (it's unnecessary to instantiate one).
-private bool isCVariadicParameter(Dsymbols* a, const(char)[] p) @safe
+bool isCVariadicParameter(Dsymbols* a, const(char)[] p) @safe
{
foreach (member; *a)
{
return false;
}
-private Dsymbol getEponymousMember(TemplateDeclaration td) @safe
+Dsymbol getEponymousMember(TemplateDeclaration td) @safe
{
if (!td.onemember)
return null;
return null;
}
-private TemplateDeclaration getEponymousParent(Dsymbol s) @safe
+TemplateDeclaration getEponymousParent(Dsymbol s) @safe
{
if (!s.parent)
return null;
return (td && getEponymousMember(td)) ? td : null;
}
-private immutable ddoc_default = import("default_ddoc_theme." ~ ddoc_ext);
-private immutable ddoc_decl_s = "$(DDOC_DECL ";
-private immutable ddoc_decl_e = ")\n";
-private immutable ddoc_decl_dd_s = "$(DDOC_DECL_DD ";
-private immutable ddoc_decl_dd_e = ")\n";
+immutable ddoc_default = import("default_ddoc_theme." ~ ddoc_ext);
+immutable ddoc_decl_s = "$(DDOC_DECL ";
+immutable ddoc_decl_e = ")\n";
+immutable ddoc_decl_dd_s = "$(DDOC_DECL_DD ";
+immutable ddoc_decl_dd_e = ")\n";
/****************************************************
+ * Generate Ddoc file for Module m.
+ * Params:
+ * m = Module
+ * ddoctext_ptr = combined text of .ddoc files for macro definitions
+ * ddoctext_length = extant of ddoctext_ptr
+ * datetime = charz returned by ctime()
+ * eSink = send error messages to eSink
+ * outbuf = append the Ddoc text to this
*/
-extern(C++) void gendocfile(Module m, ErrorSink eSink)
+public
+extern(C++) void gendocfile(Module m, const char* ddoctext_ptr, size_t ddoctext_length, const char* datetime, ErrorSink eSink, ref OutBuffer outbuf)
{
- __gshared OutBuffer mbuf;
- __gshared int mbuf_done;
- OutBuffer buf;
- //printf("Module::gendocfile()\n");
- if (!mbuf_done) // if not already read the ddoc files
- {
- mbuf_done = 1;
- // Use our internal default
- mbuf.writestring(ddoc_default);
- // Override with DDOCFILE specified in the sc.ini file
- char* p = getenv("DDOCFILE");
- if (p)
- global.params.ddoc.files.shift(p);
- // Override with the ddoc macro files from the command line
- for (size_t i = 0; i < global.params.ddoc.files.length; i++)
- {
- auto buffer = readFile(m.loc, global.params.ddoc.files[i]);
- // BUG: convert file contents to UTF-8 before use
- const data = buffer.data;
- //printf("file: '%.*s'\n", cast(int)data.length, data.ptr);
- mbuf.write(data);
- }
- }
- DocComment.parseMacros(m.escapetable, m.macrotable, mbuf[]);
+ gendocfile(m, ddoctext_ptr[0 .. ddoctext_length], datetime, eSink, outbuf);
+}
+
+/****************************************************
+ * Generate Ddoc text for Module `m` and append it to `outbuf`.
+ * Params:
+ * m = Module
+ * ddoctext = combined text of .ddoc files for macro definitions
+ * datetime = charz returned by ctime()
+ * eSink = send error messages to eSink
+ * outbuf = append the Ddoc text to this
+ */
+public
+void gendocfile(Module m, const char[] ddoctext, const char* datetime, ErrorSink eSink, ref OutBuffer outbuf)
+{
+ // Load internal default macros first
+ DocComment.parseMacros(m.escapetable, m.macrotable, ddoc_default[]);
+
+ // Ddoc files override default macros
+ DocComment.parseMacros(m.escapetable, m.macrotable, ddoctext);
+
Scope* sc = Scope.createGlobal(m, eSink); // create root scope
DocComment* dc = DocComment.parse(m, m.comment);
dc.pmacrotable = &m.macrotable;
m.macrotable.define("TITLE", p);
}
// Set time macros
- {
- time_t t;
- time(&t);
- char* p = ctime(&t);
- p = mem.xstrdup(p);
- m.macrotable.define("DATETIME", p.toDString());
- m.macrotable.define("YEAR", p[20 .. 20 + 4]);
- }
+ m.macrotable.define("DATETIME", datetime[0 .. 26]);
+ m.macrotable.define("YEAR", datetime[20 .. 20 + 4]);
+
const srcfilename = m.srcfile.toString();
m.macrotable.define("SRCFILENAME", srcfilename);
const docfilename = m.docfile.toString();
dc.copyright.nooutput = 1;
m.macrotable.define("COPYRIGHT", dc.copyright.body_);
}
+
+ OutBuffer buf;
if (m.filetype == FileType.ddoc)
{
const ploc = m.md ? &m.md.loc : &m.loc;
if (!loc.filename)
loc.filename = srcfilename.ptr;
- size_t commentlen = strlen(cast(char*)m.comment);
+ size_t commentlen = m.comment ? strlen(cast(char*)m.comment) : 0;
Dsymbols a;
// https://issues.dlang.org/show_bug.cgi?id=9764
// Don't push m in a, to prevent emphasize ddoc file name.
if (dc.macros)
{
commentlen = dc.macros.name.ptr - m.comment;
- dc.macros.write(loc, dc, sc, &a, &buf);
+ dc.macros.write(loc, dc, sc, &a, buf);
}
buf.write(m.comment[0 .. commentlen]);
highlightText(sc, &a, loc, buf, 0);
{
Dsymbols a;
a.push(m);
- dc.writeSections(sc, &a, &buf);
+ dc.writeSections(sc, &a, buf);
emitMemberComments(m, buf, sc);
}
//printf("BODY= '%.*s'\n", cast(int)buf.length, buf.data);
m.macrotable.define("BODY", buf[]);
+
OutBuffer buf2;
buf2.writestring("$(DDOC)");
size_t end = buf2.length;
- const success = m.macrotable.expand(buf2, 0, end, null, global.recursionLimit);
+ // Expand buf in place with macro expansions
+ const success = m.macrotable.expand(buf2, 0, end, null, global.recursionLimit, &isIdStart, &isIdTail);
if (!success)
eSink.error(Loc.initial, "DDoc macro expansion limit exceeded; more than %d expansions.", global.recursionLimit);
- version (all)
+ /* Remove all the escape sequences from buf,
+ * and make CR-LF the newline.
+ */
+ const slice = buf2[];
+ outbuf.reserve(slice.length);
+ auto p = slice.ptr;
+ for (size_t j = 0; j < slice.length; j++)
{
- /* Remove all the escape sequences from buf2,
- * and make CR-LF the newline.
- */
+ char c = p[j];
+ if (c == 0xFF && j + 1 < slice.length)
{
- const slice = buf2[];
- buf.setsize(0);
- buf.reserve(slice.length);
- auto p = slice.ptr;
- for (size_t j = 0; j < slice.length; j++)
- {
- char c = p[j];
- if (c == 0xFF && j + 1 < slice.length)
- {
- j++;
- continue;
- }
- if (c == '\n')
- buf.writeByte('\r');
- else if (c == '\r')
- {
- buf.writestring("\r\n");
- if (j + 1 < slice.length && p[j + 1] == '\n')
- {
- j++;
- }
- continue;
- }
- buf.writeByte(c);
- }
+ j++;
+ continue;
}
- writeFile(m.loc, m.docfile.toString(), buf[]);
- }
- else
- {
- /* Remove all the escape sequences from buf2
- */
+ if (c == '\n')
+ outbuf.writeByte('\r');
+ else if (c == '\r')
{
- size_t i = 0;
- char* p = buf2.data;
- for (size_t j = 0; j < buf2.length; j++)
+ outbuf.writestring("\r\n");
+ if (j + 1 < slice.length && p[j + 1] == '\n')
{
- if (p[j] == 0xFF && j + 1 < buf2.length)
- {
- j++;
- continue;
- }
- p[i] = p[j];
- i++;
+ j++;
}
- buf2.setsize(i);
+ continue;
}
- writeFile(m.loc, m.docfile.toString(), buf2[]);
+ outbuf.writeByte(c);
}
}
* to preserve text literally. This also means macros in the
* text won't be expanded.
*/
-void escapeDdocString(OutBuffer* buf, size_t start)
+public
+void escapeDdocString(ref OutBuffer buf, size_t start)
{
for (size_t u = start; u < buf.length; u++)
{
- char c = (*buf)[u];
+ char c = buf[u];
switch (c)
{
case '$':
* directly preceeded by a backslash with $(LPAREN) or $(RPAREN) instead of
* counting them as stray parentheses
*/
-private void escapeStrayParenthesis(Loc loc, OutBuffer* buf, size_t start, bool respectBackslashEscapes, ErrorSink eSink)
+private void escapeStrayParenthesis(Loc loc, ref OutBuffer buf, size_t start, bool respectBackslashEscapes, ErrorSink eSink)
{
uint par_open = 0;
char inCode = 0;
bool atLineStart = true;
for (size_t u = start; u < buf.length; u++)
{
- char c = (*buf)[u];
+ char c = buf[u];
switch (c)
{
case '(':
// Issue 15465: don't try to escape unbalanced parens inside code
// blocks.
int numdash = 1;
- for (++u; u < buf.length && (*buf)[u] == c; ++u)
+ for (++u; u < buf.length && buf[u] == c; ++u)
++numdash;
--u;
if (c == '`' || (atLineStart && numdash >= 3))
// replace backslash-escaped parens with their macros
if (!inCode && respectBackslashEscapes && u+1 < buf.length)
{
- if ((*buf)[u+1] == '(' || (*buf)[u+1] == ')')
+ if (buf[u+1] == '(' || buf[u+1] == ')')
{
- const paren = (*buf)[u+1] == '(' ? "$(LPAREN)" : "$(RPAREN)";
+ const paren = buf[u+1] == '(' ? "$(LPAREN)" : "$(RPAREN)";
buf.remove(u, 2); //remove the \)
buf.insert(u, paren); //insert this instead
u += 8; //skip over newly inserted macro
}
- else if ((*buf)[u+1] == '\\')
+ else if (buf[u+1] == '\\')
++u;
}
break;
for (size_t u = buf.length; u > start;)
{
u--;
- char c = (*buf)[u];
+ char c = buf[u];
switch (c)
{
case ')':
// Basically, this is to skip over things like private{} blocks in a struct or
// class definition that don't add any components to the qualified name.
-private Scope* skipNonQualScopes(Scope* sc) @safe
+Scope* skipNonQualScopes(Scope* sc) @safe
{
while (sc && !sc.scopesym)
sc = sc.enclosing;
return sc;
}
-private bool emitAnchorName(ref OutBuffer buf, Dsymbol s, Scope* sc, bool includeParent)
+bool emitAnchorName(ref OutBuffer buf, Dsymbol s, Scope* sc, bool includeParent)
{
if (!s || s.isPackage() || s.isModule())
return false;
return true;
}
-private void emitAnchor(ref OutBuffer buf, Dsymbol s, Scope* sc, bool forHeader = false)
+void emitAnchor(ref OutBuffer buf, Dsymbol s, Scope* sc, bool forHeader = false)
{
Identifier ident;
{
/******************************* emitComment **********************************/
/** Get leading indentation from 'src' which represents lines of code. */
-private size_t getCodeIndent(const(char)* src)
+size_t getCodeIndent(const(char)* src)
{
while (src && (*src == '\r' || *src == '\n'))
++src; // skip until we find the first non-empty line
}
/** Recursively expand template mixin member docs into the scope. */
-private void expandTemplateMixinComments(TemplateMixin tm, ref OutBuffer buf, Scope* sc)
+void expandTemplateMixinComments(TemplateMixin tm, ref OutBuffer buf, Scope* sc)
{
if (!tm.semanticRun)
tm.dsymbolSemantic(sc);
}
}
-private void emitMemberComments(ScopeDsymbol sds, ref OutBuffer buf, Scope* sc)
+void emitMemberComments(ScopeDsymbol sds, ref OutBuffer buf, Scope* sc)
{
if (!sds.members)
return;
buf.writestring(")");
}
-private void emitVisibility(ref OutBuffer buf, Import i)
+void emitVisibility(ref OutBuffer buf, Import i)
{
// imports are private by default, which is different from other declarations
// so they should explicitly show their visibility
emitVisibility(buf, i.visibility);
}
-private void emitVisibility(ref OutBuffer buf, Declaration d)
+void emitVisibility(ref OutBuffer buf, Declaration d)
{
auto vis = d.visibility;
if (vis.kind != Visibility.Kind.undefined && vis.kind != Visibility.Kind.public_)
}
}
-private void emitVisibility(ref OutBuffer buf, Visibility vis)
+void emitVisibility(ref OutBuffer buf, Visibility vis)
{
- visibilityToBuffer(&buf, vis);
+ visibilityToBuffer(buf, vis);
buf.writeByte(' ');
}
-private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
+void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
{
extern (C++) final class EmitComment : Visitor
{
// Put the ddoc comment as the document 'description'
buf.writestring(ddoc_decl_dd_s);
{
- dc.writeSections(sc, &dc.a, buf);
+ dc.writeSections(sc, &dc.a, *buf);
if (ScopeDsymbol sds = dc.a[0].isScopeDsymbol())
emitMemberComments(sds, *buf, sc);
}
s.accept(v);
}
-private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
+void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
{
extern (C++) final class ToDocBuffer : Visitor
{
//printf("Dsymbol::toDocbuffer() %s\n", s.toChars());
HdrGenState hgs;
hgs.ddoc = true;
- .toCBuffer(s, buf, &hgs);
+ toCBuffer(s, *buf, hgs);
}
void prefix(Dsymbol s)
HdrGenState hgs;
hgs.ddoc = true;
emitVisibility(*buf, i);
- .toCBuffer(i, buf, &hgs);
+ toCBuffer(i, *buf, hgs);
}
override void visit(Declaration d)
Type origType = d.originalType ? d.originalType : d.type;
if (origType.ty == Tfunction)
{
- functionToBufferFull(cast(TypeFunction)origType, buf, d.ident, &hgs, td);
+ functionToBufferFull(cast(TypeFunction)origType, *buf, d.ident, &hgs, td);
}
else
- .toCBuffer(origType, buf, d.ident, &hgs);
+ toCBuffer(origType, *buf, d.ident, hgs);
}
else
buf.writestring(d.ident.toString());
{
if (i)
buf.writestring(", ");
- toCBuffer((*td.origParameters)[i], buf, &hgs);
+ toCBuffer((*td.origParameters)[i], *buf, hgs);
}
}
buf.writeByte(')');
buf.writestring("$(DDOC_CONSTRAINT ");
}
- .toCBuffer(td.constraint, buf, &hgs);
+ toCBuffer(td.constraint, *buf, hgs);
if (noFuncDecl)
{
else
{
HdrGenState hgs;
- .toCBuffer(bc.type, buf, null, &hgs);
+ toCBuffer(bc.type, *buf, null, hgs);
}
}
buf.writestring(";\n");
{
buf.writestring(": $(DDOC_ENUM_BASETYPE ");
HdrGenState hgs;
- .toCBuffer(ed.memtype, buf, null, &hgs);
+ toCBuffer(ed.memtype, *buf, null, hgs);
buf.writestring(")");
}
buf.writestring(";\n");
/***********************************************************
*/
+public
struct DocComment
{
Sections sections; // Section*[]
}
}
- void writeSections(Scope* sc, Dsymbols* a, OutBuffer* buf)
+ void writeSections(Scope* sc, Dsymbols* a, ref OutBuffer buf)
{
assert(a.length);
//printf("DocComment::writeSections()\n");
size_t o = buf.length;
buf.write(sec.body_);
escapeStrayParenthesis(loc, buf, o, true, sc.eSink);
- highlightText(sc, a, loc, *buf, o);
+ highlightText(sc, a, loc, buf, o);
buf.writestring(")");
}
else
buf.writestring("----\n");
buf.writestring(codedoc);
buf.writestring("----\n");
- highlightText(sc, a, loc, *buf, o);
+ highlightText(sc, a, loc, buf, o);
}
buf.writestring(")");
}
/*****************************************
* Return true if comment consists entirely of "ditto".
*/
-private bool isDitto(const(char)* comment)
+bool isDitto(const(char)* comment)
{
if (comment)
{
/**********************************************
* Skip white space.
*/
-private const(char)* skipwhitespace(const(char)* p)
+const(char)* skipwhitespace(const(char)* p)
{
return skipwhitespace(p.toDString).ptr;
}
/// Ditto
-private const(char)[] skipwhitespace(const(char)[] p) @safe
+const(char)[] skipwhitespace(const(char)[] p) @safe
{
foreach (idx, char c; p)
{
* chars = the characters to skip; order is unimportant
* Returns: the index after skipping characters.
*/
-private size_t skipChars(ref OutBuffer buf, size_t i, string chars) @safe
+size_t skipChars(ref OutBuffer buf, size_t i, string chars) @safe
{
Outer:
foreach (j, c; buf[][i..$])
* r = the string to replace `c` with
* Returns: `s` with `c` replaced with `r`
*/
-private inout(char)[] replaceChar(inout(char)[] s, char c, string r) pure @safe
+inout(char)[] replaceChar(inout(char)[] s, char c, string r) pure @safe
{
int count = 0;
foreach (char sc; s)
* s = the string to lowercase
* Returns: the lowercase version of the string or the original if already lowercase
*/
-private string toLowercase(string s) pure @safe
+string toLowercase(string s) pure @safe
{
string lower;
foreach (size_t i; 0..s.length)
* to = the index within `buf` to stop counting at, exclusive
* Returns: the indent
*/
-private int getMarkdownIndent(ref OutBuffer buf, size_t from, size_t to) @safe
+int getMarkdownIndent(ref OutBuffer buf, size_t from, size_t to) @safe
{
const slice = buf[];
if (to > slice.length)
/************************************************
* Scan forward past end of identifier.
*/
-private size_t skippastident(ref OutBuffer buf, size_t i) @safe
+size_t skippastident(ref OutBuffer buf, size_t i) @safe
{
const slice = buf[];
while (i < slice.length)
* Scan forward past end of an identifier that might
* contain dots (e.g. `abc.def`)
*/
-private size_t skipPastIdentWithDots(ref OutBuffer buf, size_t i) @safe
+size_t skipPastIdentWithDots(ref OutBuffer buf, size_t i) @safe
{
const slice = buf[];
bool lastCharWasDot;
* i if not a URL
* index just past it if it is a URL
*/
-private size_t skippastURL(ref OutBuffer buf, size_t i)
+size_t skippastURL(ref OutBuffer buf, size_t i)
{
const slice = buf[][i .. $];
size_t j;
* i = an index within `buf`. If `i` is after `iAt` then it gets
* reduced by the length of the removed macro.
*/
-private void removeBlankLineMacro(ref OutBuffer buf, ref size_t iAt, ref size_t i)
+void removeBlankLineMacro(ref OutBuffer buf, ref size_t iAt, ref size_t i)
{
if (!iAt)
return;
* loc = the current location within the file
* Returns: whether a thematic break was replaced
*/
-private bool replaceMarkdownThematicBreak(ref OutBuffer buf, ref size_t i, size_t iLineStart, const ref Loc loc)
+bool replaceMarkdownThematicBreak(ref OutBuffer buf, ref size_t i, size_t iLineStart, const ref Loc loc)
{
const slice = buf[];
* the detected heading level from 1 to 6, or
* 0 if not at an ATX heading
*/
-private int detectAtxHeadingLevel(ref OutBuffer buf, const size_t i) @safe
+int detectAtxHeadingLevel(ref OutBuffer buf, const size_t i) @safe
{
const iHeadingStart = i;
const iAfterHashes = skipChars(buf, i, "#");
* buf = an OutBuffer containing the DDoc
* i = the index within `buf` to start looking for a suffix at
*/
-private void removeAnyAtxHeadingSuffix(ref OutBuffer buf, size_t i)
+void removeAnyAtxHeadingSuffix(ref OutBuffer buf, size_t i)
{
size_t j = i;
size_t iSuffixStart = 0;
* headingLevel = the level (1-6) of heading to end. Is set to `0` when this
* function ends.
*/
-private void endMarkdownHeading(ref OutBuffer buf, size_t iStart, ref size_t iEnd, const ref Loc loc, ref int headingLevel)
+void endMarkdownHeading(ref OutBuffer buf, size_t iStart, ref size_t iEnd, const ref Loc loc, ref int headingLevel)
{
char[5] heading = "$(H0 ";
heading[3] = cast(char) ('0' + headingLevel);
* quoteLevel = the current quote level. Is set to `0` when this function ends.
* Returns: the amount that `i` was moved
*/
-private size_t endAllMarkdownQuotes(ref OutBuffer buf, size_t i, ref int quoteLevel)
+size_t endAllMarkdownQuotes(ref OutBuffer buf, size_t i, ref int quoteLevel)
{
const length = quoteLevel;
for (; quoteLevel > 0; --quoteLevel)
* `0` when this function ends.
* Returns: the amount that `i` was moved
*/
-private size_t endAllListsAndQuotes(ref OutBuffer buf, ref size_t i, ref MarkdownList[] nestedLists, ref int quoteLevel, out int quoteMacroLevel)
+size_t endAllListsAndQuotes(ref OutBuffer buf, ref size_t i, ref MarkdownList[] nestedLists, ref int quoteLevel, out int quoteMacroLevel)
{
quoteMacroLevel = 0;
const i0 = i;
* downToLevel = the length within `inlineDelimiters`` to reduce emphasis to
* Returns: the number of characters added to the buffer by the replacements
*/
-private size_t replaceMarkdownEmphasis(ref OutBuffer buf, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, int downToLevel = 0)
+size_t replaceMarkdownEmphasis(ref OutBuffer buf, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, int downToLevel = 0)
{
size_t replaceEmphasisPair(ref MarkdownDelimiter start, ref MarkdownDelimiter end)
{
/****************************************************
*/
-private bool isIdentifier(Dsymbols* a, const(char)[] s) @safe
+bool isIdentifier(Dsymbols* a, const(char)[] s) @safe
{
foreach (member; *a)
{
/****************************************************
*/
-private bool isKeyword(const(char)[] str) @safe
+bool isKeyword(const(char)[] str) @safe
{
immutable string[3] table = ["true", "false", "null"];
foreach (s; table)
/****************************************************
*/
-private TypeFunction isTypeFunction(Dsymbol s) @safe
+TypeFunction isTypeFunction(Dsymbol s) @safe
{
FuncDeclaration f = s.isFuncDeclaration();
/* f.type may be NULL for template members.
/****************************************************
*/
-private Parameter isFunctionParameter(Dsymbol s, const(char)[] str) @safe
+Parameter isFunctionParameter(Dsymbol s, const(char)[] str) @safe
{
TypeFunction tf = isTypeFunction(s);
if (tf && tf.parameterList.parameters)
/****************************************************
*/
-private Parameter isFunctionParameter(Dsymbols* a, const(char)[] p) @safe
+Parameter isFunctionParameter(Dsymbols* a, const(char)[] p) @safe
{
foreach (Dsymbol sym; *a)
{
/****************************************************
*/
-private Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @safe
+Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @safe
{
foreach (Dsymbol dsym; *a)
{
/****************************************************
*/
-private TemplateParameter isTemplateParameter(Dsymbols* a, const(char)* p, size_t len)
+TemplateParameter isTemplateParameter(Dsymbols* a, const(char)* p, size_t len)
{
for (size_t i = 0; i < a.length; i++)
{
* Return true if str is a reserved symbol name
* that starts with a double underscore.
*/
-private bool isReservedName(const(char)[] str) @safe
+bool isReservedName(const(char)[] str) @safe
{
immutable string[] table =
[
/****************************************************
* A delimiter for Markdown inline content like emphasis and links.
*/
-private struct MarkdownDelimiter
+struct MarkdownDelimiter
{
size_t iStart; /// the index where this delimiter starts
int count; /// the length of this delimeter's start sequence
/****************************************************
* Info about a Markdown list.
*/
-private struct MarkdownList
+struct MarkdownList
{
string orderedStart; /// an optional start number--if present then the list starts at this number
size_t iStart; /// the index where the list item starts
/****************************************************
* A Markdown link.
*/
-private struct MarkdownLink
+struct MarkdownLink
{
string href; /// the link destination
string title; /// an optional title for the link
/**************************************************
* A set of Markdown link references.
*/
-private struct MarkdownLinkReferences
+struct MarkdownLinkReferences
{
MarkdownLink[string] references; // link references keyed by normalized label
MarkdownLink[string] symbols; // link symbols keyed by name
}
}
-private enum TableColumnAlignment
+enum TableColumnAlignment
{
none,
left,
* columnAlignments = alignments to populate for each column
* Returns: the index of the end of the parsed delimiter, or `0` if not found
*/
-private size_t parseTableDelimiterRow(ref OutBuffer buf, const size_t iStart, bool inQuote, ref TableColumnAlignment[] columnAlignments) @safe
+size_t parseTableDelimiterRow(ref OutBuffer buf, const size_t iStart, bool inQuote, ref TableColumnAlignment[] columnAlignments) @safe
{
size_t i = skipChars(buf, iStart, inQuote ? ">| \t" : "| \t");
while (i < buf.length && buf[i] != '\r' && buf[i] != '\n')
* columnAlignments = the parsed alignments for each column
* Returns: the number of characters added by starting the table, or `0` if unchanged
*/
-private size_t startTable(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, bool inQuote, ref MarkdownDelimiter[] inlineDelimiters, out TableColumnAlignment[] columnAlignments)
+size_t startTable(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, bool inQuote, ref MarkdownDelimiter[] inlineDelimiters, out TableColumnAlignment[] columnAlignments)
{
const iDelimiterRowEnd = parseTableDelimiterRow(buf, iEnd + 1, inQuote, columnAlignments);
if (iDelimiterRowEnd)
* delta = the number of characters added by replacing the row, or `0` if unchanged
* Returns: `true` if a table row was found and replaced
*/
-private bool replaceTableRow(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, TableColumnAlignment[] columnAlignments, bool headerRow, out size_t delta)
+bool replaceTableRow(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, TableColumnAlignment[] columnAlignments, bool headerRow, out size_t delta)
{
delta = 0;
* columnAlignments = alignments for each column; upon return is set to length `0`
* Returns: the number of characters added by ending the table, or `0` if unchanged
*/
-private size_t endTable(ref OutBuffer buf, size_t i, ref TableColumnAlignment[] columnAlignments)
+size_t endTable(ref OutBuffer buf, size_t i, ref TableColumnAlignment[] columnAlignments)
{
if (!columnAlignments.length)
return 0;
* columnAlignments = alignments for each column; upon return is set to length `0`
* Returns: the number of characters added by replacing the row, or `0` if unchanged
*/
-private size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, ref TableColumnAlignment[] columnAlignments)
+size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, const ref Loc loc, ref MarkdownDelimiter[] inlineDelimiters, ref TableColumnAlignment[] columnAlignments)
{
size_t delta;
replaceTableRow(buf, iStart, iEnd, loc, inlineDelimiters, columnAlignments, false, delta);
* buf = an OutBuffer containing the DDoc
* offset = the index within buf to start highlighting
*/
-private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t offset)
+void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, size_t offset)
{
const incrementLoc = loc.linnum == 0 ? 1 : 0;
loc.linnum = loc.linnum + incrementLoc;
codebuf.write(buf[iCodeStart + count .. i]);
// escape the contents, but do not perform highlighting except for DDOC_PSYMBOL
highlightCode(sc, a, codebuf, 0);
- escapeStrayParenthesis(loc, &codebuf, 0, false, sc.eSink);
+ escapeStrayParenthesis(loc, codebuf, 0, false, sc.eSink);
buf.remove(iCodeStart, i - iCodeStart + count); // also trimming off the current `
immutable pre = "$(DDOC_BACKQUOTED ";
i = buf.insert(iCodeStart, pre);
highlightCode2(sc, a, codebuf, 0);
else
codebuf.remove(codebuf.length-1, 1); // remove the trailing 0 byte
- escapeStrayParenthesis(loc, &codebuf, 0, false, sc.eSink);
+ escapeStrayParenthesis(loc, codebuf, 0, false, sc.eSink);
buf.remove(iCodeStart, i - iCodeStart);
i = buf.insert(iCodeStart, codebuf[]);
i = buf.insert(i, ")\n");
/**************************************************
* Highlight code for DDOC section.
*/
-private void highlightCode(Scope* sc, Dsymbol s, ref OutBuffer buf, size_t offset)
+void highlightCode(Scope* sc, Dsymbol s, ref OutBuffer buf, size_t offset)
{
auto imp = s.isImport();
if (imp && imp.aliases.length > 0)
/****************************************************
*/
-private void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset)
+void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset)
{
//printf("highlightCode(a = '%s')\n", a.toChars());
bool resolvedTemplateParameters = false;
size_t lastOffset = parametersBuf.length;
- .toCBuffer(tp, ¶metersBuf, &hgs);
+ toCBuffer(tp, parametersBuf, hgs);
paramLens[parami] = parametersBuf.length - lastOffset;
}
/****************************************
*/
-private void highlightCode3(Scope* sc, ref OutBuffer buf, const(char)* p, const(char)* pend)
+void highlightCode3(Scope* sc, ref OutBuffer buf, const(char)* p, const(char)* pend)
{
for (; p < pend; p++)
{
/**************************************************
* Highlight code for CODE section.
*/
-private void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset)
+void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t offset)
{
scope eSinkNull = new ErrorSinkNull();
* https://issues.dlang.org/show_bug.cgi?id=7715
* https://issues.dlang.org/show_bug.cgi?id=10519
*/
- escapeDdocString(&res, o);
+ escapeDdocString(res, o);
res.writeByte(')');
}
else
/****************************************
* Determine if p points to the start of a "..." parameter identifier.
*/
-private bool isCVariadicArg(const(char)[] p) @nogc nothrow pure @safe
+bool isCVariadicArg(const(char)[] p) @nogc nothrow pure @safe
{
return p.length >= 3 && p[0 .. 3] == "...";
}
/****************************************
* Determine if p points to the start of an identifier.
*/
+@trusted
bool isIdStart(const(char)* p) @nogc nothrow pure
{
dchar c = *p;
/****************************************
* Determine if p points to the rest of an identifier.
*/
+@trusted
bool isIdTail(const(char)* p) @nogc nothrow pure
{
dchar c = *p;
/****************************************
* Determine if p points to the indentation space.
*/
-private bool isIndentWS(const(char)* p) @nogc nothrow pure @safe
+bool isIndentWS(const(char)* p) @nogc nothrow pure @safe
{
return (*p == ' ') || (*p == '\t');
}
return cast(int)i;
}
-private inout(char)* stripLeadingNewlines(inout(char)* s) @nogc nothrow pure
+inout(char)* stripLeadingNewlines(inout(char)* s) @nogc nothrow pure
{
while (s && *s == '\n' || *s == '\r')
s++;
class Module;
class ErrorSink;
-void gendocfile(Module *m, ErrorSink *eSink);
+void gendocfile(Module *m, const char *ddoctext_ptr, size_t ddoctext_length,
+ const char *datetime, ErrorSink *eSink, OutBuffer &outbuf);
sc.scopesym = new ScopeDsymbol();
sc.scopesym.symtab = new DsymbolTable();
sc.eSink = eSink;
+ assert(eSink);
// Add top level package as member of this global scope
Dsymbol m = _module;
while (m.parent)
if (!sc) // inline may request TypeInfo.
{
Scope scx;
+ scx.eSink = global.errorSink;
scx._module = sd.getModule();
getTypeInfoType(sd.loc, t, &scx);
sd.requestTypeInfo = true;
if (!tfgetmembers)
{
Scope sc;
+ sc.eSink = global.errorSink;
auto parameters = new Parameters();
Parameters* p = new Parameter(STC.in_, Type.tchar.constOf().arrayOf(), null, null);
parameters.push(p);
enum LOG = false;
-private uint setMangleOverride(Dsymbol s, const(char)[] sym)
+package uint setMangleOverride(Dsymbol s, const(char)[] sym)
{
if (s.isFuncDeclaration() || s.isVarDeclaration())
{
else
{
OutBuffer buf;
- stcToBuffer(&buf, stc);
+ stcToBuffer(buf, stc);
dsym.error("cannot be `%s`", buf.peekChars());
}
dsym.storage_class &= ~stc; // strip off
if (stc)
{
OutBuffer buf;
- stcToBuffer(&buf, stc);
+ stcToBuffer(buf, stc);
dsym.error("cannot be `scope` and `%s`", buf.peekChars());
}
else if (dsym.isMember())
if (ne.member && !(ne.member.storage_class & STC.scope_))
{
import dmd.escape : setUnsafeDIP1000;
- const inSafeFunc = sc.func && sc.func.isSafeBypassingInference();
+ const inSafeFunc = sc.func && sc.func.isSafeBypassingInference(); // isSafeBypassingInference may call setUnsafe().
if (sc.setUnsafeDIP1000(false, dsym.loc, "`scope` allocation of `%s` requires that constructor be annotated with `scope`", dsym))
errorSupplemental(ne.member.loc, "is the location of the constructor");
- else if (global.params.obsolete && inSafeFunc)
- warningSupplemental(ne.member.loc, "is the location of the constructor");
}
ne.onstack = 1;
dsym.onstack = true;
ob.writestring(") : ");
// use visibility instead of sc.visibility because it couldn't be
// resolved yet, see the comment above
- visibilityToBuffer(ob, imp.visibility);
+ visibilityToBuffer(*ob, imp.visibility);
ob.writeByte(' ');
if (imp.isstatic)
{
- stcToBuffer(ob, STC.static_);
+ stcToBuffer(*ob, STC.static_);
ob.writeByte(' ');
}
ob.writestring(": ");
if (!em.ed.isAnonymous())
em.ed.memtype = t;
}
+ const errors = global.startGagging();
Expression e = new IntegerExp(em.loc, 0, t);
e = e.ctfeInterpret();
-
+ if (global.endGagging(errors))
+ {
+ error(em.loc, "cannot generate 0 value of type `%s` for `%s`",
+ t.toChars(), em.toChars());
+ }
// save origValue for better json output
em.origValue = e;
if (emprev.errors)
return errorReturn();
+ auto errors = global.startGagging();
Expression eprev = emprev.value;
+ assert(eprev);
// .toHeadMutable() due to https://issues.dlang.org/show_bug.cgi?id=18645
Type tprev = eprev.type.toHeadMutable().equals(em.ed.type.toHeadMutable())
? em.ed.memtype
emax = emax.expressionSemantic(sc);
emax = emax.ctfeInterpret();
- // Set value to (eprev + 1).
- // But first check that (eprev != emax)
- assert(eprev);
+ // check that (eprev != emax)
Expression e = new EqualExp(EXP.equal, em.loc, eprev, emax);
e = e.expressionSemantic(sc);
e = e.ctfeInterpret();
+ if (global.endGagging(errors))
+ {
+ // display an introductory error before showing what actually failed
+ error(em.loc, "cannot check `%s` value for overflow", em.toPrettyChars());
+ // rerun to show errors
+ Expression e2 = DotIdExp.create(em.ed.loc, new TypeExp(em.ed.loc, tprev), Id.max);
+ e2 = e2.expressionSemantic(sc);
+ e2 = e2.ctfeInterpret();
+ e2 = new EqualExp(EXP.equal, em.loc, eprev, e2);
+ e2 = e2.expressionSemantic(sc);
+ e2 = e2.ctfeInterpret();
+ }
+ // now any errors are for generating a value
if (e.toInteger())
{
auto mt = em.ed.memtype;
emprev.ed.toChars(), emprev.toChars(), mt.toChars());
return errorReturn();
}
-
+ errors = global.startGagging();
// Now set e to (eprev + 1)
e = new AddExp(em.loc, eprev, IntegerExp.literal!1);
e = e.expressionSemantic(sc);
e = e.castTo(sc, eprev.type);
e = e.ctfeInterpret();
-
+ if (global.endGagging(errors))
+ {
+ error(em.loc, "cannot generate value for `%s`", em.toPrettyChars());
+ // rerun to show errors
+ Expression e2 = new AddExp(em.loc, eprev, IntegerExp.literal!1);
+ e2 = e2.expressionSemantic(sc);
+ e2 = e2.castTo(sc, eprev.type);
+ e2 = e2.ctfeInterpret();
+ }
// save origValue (without cast) for better json output
if (e.op != EXP.error) // avoid duplicate diagnostics
{
if (!tf.isNaked() && !(funcdecl.isThis() || funcdecl.isNested()))
{
OutBuffer buf;
- MODtoBuffer(&buf, tf.mod);
+ MODtoBuffer(buf, tf.mod);
funcdecl.error("without `this` cannot be `%s`", buf.peekChars());
tf.mod = 0; // remove qualifiers
}
OutBuffer buf;
auto fd = s.isFuncDeclaration();
- functionToBufferFull(cast(TypeFunction)(funcdecl.type), &buf,
+ functionToBufferFull(cast(TypeFunction)(funcdecl.type), buf,
new Identifier(funcdecl.toPrettyChars()), &hgs, null);
const(char)* funcdeclToChars = buf.peekChars();
}
else
{
- functionToBufferFull(cast(TypeFunction)(fd.type), &buf1,
+ functionToBufferFull(cast(TypeFunction)(fd.type), buf1,
new Identifier(fd.toPrettyChars()), &hgs, null);
error(funcdecl.loc, "function `%s` does not override any function, did you mean to override `%s`?",
{
if (i)
buf.writestring(", ");
- .toCBuffer(tp, &buf, &hgs);
+ toCBuffer(tp, buf, hgs);
}
buf.writeByte(')');
constraint)
{
buf.writestring(" if (");
- .toCBuffer(constraint, &buf, &hgs);
+ toCBuffer(constraint, buf, hgs);
buf.writeByte(')');
}
if (!fparam.ident)
continue;
// don't add it, if it has no name
- auto v = new VarDeclaration(loc, fparam.type, fparam.ident, null);
+ auto v = new VarDeclaration(fparam.loc, fparam.type, fparam.ident, null);
fparam.storageClass |= STC.parameter;
v.storage_class = fparam.storageClass;
v.dsymbolSemantic(scx);
override const(char)* toChars() const
{
OutBuffer buf;
- toCBufferInstance(this, &buf);
+ toCBufferInstance(this, buf);
return buf.extractChars();
}
override final const(char)* toPrettyCharsHelper()
{
OutBuffer buf;
- toCBufferInstance(this, &buf, true);
+ toCBufferInstance(this, buf, true);
return buf.extractChars();
}
{
case Classification.error:
return &errorSupplemental;
- case Classification.warning:
- return &warningSupplemental;
case Classification.deprecation:
return &deprecationSupplemental;
- case Classification.gagged, Classification.tip:
+ case Classification.gagged, Classification.tip, Classification.warning:
assert(0);
}
}();
if (td_ambig)
{
- .error(loc, "%s `%s.%s` matches more than one template declaration:\n%s: `%s`\nand\n%s: `%s`",
- td_best.kind(), td_best.parent.toPrettyChars(), td_best.ident.toChars(),
- td_best.loc.toChars(), td_best.toChars(),
- td_ambig.loc.toChars(), td_ambig.toChars());
+ .error(loc, "%s `%s.%s` matches more than one template declaration:",
+ td_best.kind(), td_best.parent.toPrettyChars(), td_best.ident.toChars());
+ .errorSupplemental(td_best.loc, "`%s`\nand:", td_best.toChars());
+ .errorSupplemental(td_ambig.loc, "`%s`", td_ambig.toChars());
return false;
}
if (td_best)
override const(char)* toChars() const
{
OutBuffer buf;
- toCBufferInstance(this, &buf);
+ toCBufferInstance(this, buf);
return buf.extractChars();
}
else
{
const(char)[] name = FileName.combine(global.params.cxxhdr.dir, global.params.cxxhdr.name);
- writeFile(Loc.initial, name, buf[]);
+ if (!writeFile(Loc.initial, name, buf[]))
+ return fatal();
}
}
{
//printf("%s %d\n", p.defaultArg.toChars, p.defaultArg.op);
buf.writestring(" = ");
+ // Always emit the FDN of a symbol for the default argument,
+ // to avoid generating an ambiguous assignment.
+ auto save = adparent;
+ adparent = null;
printExpressionFor(p.type, p.defaultArg);
+ adparent = save;
}
}
import dmd.hdrgen;
// Hex floating point literals were introduced in C++ 17
const allowHex = global.params.cplusplus >= CppStdRevision.cpp17;
- floatToBuffer(e.type, e.value, buf, allowHex);
+ floatToBuffer(e.type, e.value, *buf, allowHex);
}
}
struct Loc;
+// Constants used to discriminate kinds of error messages.
enum class ErrorKind
{
warning = 0,
D_ATTRIBUTE_FORMAT(2, 3) void message(const Loc& loc, const char *format, ...);
D_ATTRIBUTE_FORMAT(1, 2) void tip(const char *format, ...);
-D_ATTRIBUTE_FORMAT(2, 0) void verrorReport(const Loc& loc, const char *format, va_list ap, const char *p1 = NULL, const char *p2 = NULL);
+D_ATTRIBUTE_FORMAT(2, 0) void verrorReport(const Loc& loc, const char *format, va_list ap, ErrorKind kind, const char *p1 = NULL, const char *p2 = NULL);
D_ATTRIBUTE_FORMAT(2, 0) void verrorReportSupplemental(const Loc& loc, const char* format, va_list ap, ErrorKind kind);
#if defined(__GNUC__) || defined(__clang__)
/*****************************************
* Simplest implementation, just sends messages to stderr.
+ * See also: ErrorSinkCompiler.
*/
class ErrorSinkStderr : ErrorSink
{
import dmd.visitor;
import dmd.arraytypes;
+private:
+
/// Groups global state for escape checking together
package(dmd) struct EscapeState
{
* Returns:
* `true` if error
*/
+public
bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
Expression ethis, Expressions* arguments, bool gag)
{
const(char)* msg = eb.isMutable && eb2.isMutable
? "more than one mutable reference %s `%s` in arguments to `%s()`"
: "mutable and const references %s `%s` in arguments to `%s()`";
- error((*arguments)[i].loc, msg,
+ sc.eSink.error((*arguments)[i].loc, msg,
referenceVerb,
v.toChars(),
fd ? fd.toPrettyChars() : "indirectly");
* Returns:
* `true` if any elements escaped
*/
+public
bool checkArrayLiteralEscape(Scope *sc, ArrayLiteralExp ae, bool gag)
{
bool errors;
* Returns:
* `true` if any elements escaped
*/
+public
bool checkAssocArrayLiteralEscape(Scope *sc, AssocArrayLiteralExp ae, bool gag)
{
bool errors;
* v = parameter that was not inferred
* recursionLimit = recursion limit for printing the reason
*/
+private
void printScopeFailure(E)(E printFunc, VarDeclaration v, int recursionLimit)
{
recursionLimit--;
* Returns:
* `true` if pointers to the stack can escape via assignment
*/
+public
bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId, VarDeclaration vPar, STC parStc, Expression arg, bool assertmsg, bool gag)
{
enum log = false;
- if (log) printf("checkParamArgumentEscape(arg: %s par: %s)\n",
+ if (log) printf("checkParamArgumentEscape(arg: %s par: %s parSTC: %llx)\n",
arg ? arg.toChars() : "null",
- parId ? parId.toChars() : "null");
+ parId ? parId.toChars() : "null", parStc);
//printf("type = %s, %d\n", arg.type.toChars(), arg.type.hasPointers());
if (!arg.type.hasPointers())
if (parStc & STC.scope_)
{
// These errors only apply to non-scope parameters
- // When the paraneter is `scope`, only `checkScopeVarAddr` on `er.byref` is needed
+ // When the parameter is `scope`, only `checkScopeVarAddr` on `er.byref` is needed
er.byfunc.setDim(0);
er.byvalue.setDim(0);
er.byexp.setDim(0);
* Returns:
* `true` if assignment to `firstArg` would cause an error
*/
+public
bool checkParamArgumentReturn(Scope* sc, Expression firstArg, Expression arg, Parameter param, bool gag)
{
enum log = false;
* Returns:
* `true` if construction would cause an escaping reference error
*/
+public
bool checkConstructorEscape(Scope* sc, CallExp ce, bool gag)
{
enum log = false;
}
/// How a `return` parameter escapes its pointer value
+public
enum ReturnParamDest
{
returnVal, /// through return statement: `return x`
* tthis = type of `this` parameter, or `null` if none
* Returns: What a `return` parameter should transfer the lifetime of the argument to
*/
+public
ReturnParamDest returnParamDest(TypeFunction tf, Type tthis)
{
assert(tf);
* Returns:
* `true` if pointers to the stack can escape via assignment
*/
+public
bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef)
{
enum log = false;
!(va && va.storage_class & STC.temp))
{
if (!gag)
- deprecation(ee.loc, "slice of static array temporary returned by `%s` assigned to longer lived variable `%s`",
+ sc.eSink.deprecation(ee.loc, "slice of static array temporary returned by `%s` assigned to longer lived variable `%s`",
ee.toChars(), e1.toChars());
//result = true;
continue;
* Returns:
* `true` if pointers to the stack can escape
*/
+public
bool checkThrowEscape(Scope* sc, Expression e, bool gag)
{
//printf("[%s] checkThrowEscape, e = %s\n", e.loc.toChars(), e.toChars());
* Returns:
* `true` if pointers to the stack can escape
*/
+public
bool checkNewEscape(Scope* sc, Expression e, bool gag)
{
import dmd.globals: FeatureState;
{
if (log) printf("byexp %s\n", ee.toChars());
if (!gag)
- error(ee.loc, "storing reference to stack allocated value returned by `%s` into allocated memory causes it to escape",
+ sc.eSink.error(ee.loc, "storing reference to stack allocated value returned by `%s` into allocated memory causes it to escape",
ee.toChars());
result = true;
}
* Returns:
* `true` if pointers to the stack can escape
*/
+public
bool checkReturnEscape(Scope* sc, Expression e, bool gag)
{
//printf("[%s] checkReturnEscape, e: %s\n", e.loc.toChars(), e.toChars());
* Returns:
* `true` if references to the stack can escape
*/
+public
bool checkReturnEscapeRef(Scope* sc, Expression e, bool gag)
{
version (none)
else if (v.isTypesafeVariadicArray && p == sc.func)
{
if (!gag)
- error(e.loc, "returning `%s` escapes a reference to variadic parameter `%s`", e.toChars(), v.toChars());
+ sc.eSink.error(e.loc, "returning `%s` escapes a reference to variadic parameter `%s`", e.toChars(), v.toChars());
result = false;
}
else
else
{
if (!gag)
- error(ee.loc, "escaping reference to stack allocated value returned by `%s`", ee.toChars());
+ sc.eSink.error(ee.loc, "escaping reference to stack allocated value returned by `%s`", ee.toChars());
result = true;
}
}
* va = variable to infer scope for
* Returns: `true` if succesful or already `scope`
*/
+private
bool inferScope(VarDeclaration va)
{
if (!va)
* live = if @live semantics apply, i.e. expressions `p`, `*p`, `**p`, etc., all return `p`.
* retRefTransition = if `e` is returned through a `return ref scope` function call
*/
+public
void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool retRefTransition = false)
{
//printf("[%s] escapeByValue, e: %s\n", e.loc.toChars(), e.toChars());
* live = if @live semantics apply, i.e. expressions `p`, `*p`, `**p`, etc., all return `p`.
* retRefTransition = if `e` is returned through a `return ref scope` function call
*/
+private
void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retRefTransition = false)
{
//printf("[%s] escapeByRef, e: %s, retRefTransition: %d\n", e.loc.toChars(), e.toChars(), retRefTransition);
/************************************
* Aggregate the data collected by the escapeBy??() functions.
*/
+public
struct EscapeByResults
{
VarDeclarations byref; // array into which variables being returned by ref are inserted
* f = final function type. `funcdecl.type` started as the 'premature type' before attribute
* inference, then its inferred attributes are copied over to final type `f`
*/
+public
void finishScopeParamInference(FuncDeclaration funcdecl, ref TypeFunction f)
{
* Returns:
* true if it's a pointer (or reference) to mutable data
*/
+private
bool isReferenceToMutable(Type t)
{
t = t.baseElemOf();
* Returns:
* true if it's a pointer (or reference) to mutable data
*/
+private
bool isReferenceToMutable(Parameter p, Type t)
{
if (p.isReference())
}
// `setUnsafePreview` partially evaluated for dip1000
+public
bool setUnsafeDIP1000(Scope* sc, bool gag, Loc loc, const(char)* msg,
RootObject arg0 = null, RootObject arg1 = null, RootObject arg2 = null)
{
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
+import dmd.errorsink;
import dmd.escape;
import dmd.expressionsem;
import dmd.func;
{
OutBuffer buf;
HdrGenState hgs;
- toCBuffer(this, &buf, &hgs);
+ toCBuffer(this, buf, hgs);
return buf.extractChars();
}
return checkValue();
}
- extern (D) final bool checkArithmetic()
+ extern (D) final bool checkArithmetic(EXP op)
{
if (op == EXP.error)
return true;
return true;
if (!type.isintegral() && !type.isfloating())
{
- error("`%s` is not of arithmetic type, it is a `%s`", toChars(), type.toChars());
+ // unary aggregate ops error here
+ const char* msg = type.isAggregate() ?
+ "operator `%s` is not defined for `%s` of type `%s`" :
+ "illegal operator `%s` for `%s` of type `%s`";
+ error(msg, EXPtoString(op).ptr, toChars(), type.toChars());
return true;
}
return checkValue();
Expressions* keys;
Expressions* values;
+ /// Lower to core.internal.newaa for static initializaton
+ Expression lowering;
extern (D) this(const ref Loc loc, Expressions* keys, Expressions* values) @safe
{
return new FuncExp(loc, fd);
}
- extern (D) MATCH matchType(Type to, Scope* sc, FuncExp* presult, int flag = 0)
+ extern (D) MATCH matchType(Type to, Scope* sc, FuncExp* presult, ErrorSink eSink)
{
-
- static MATCH cannotInfer(Expression e, Type to, int flag)
+ MATCH cannotInfer()
{
- if (!flag)
- e.error("cannot infer parameter types from `%s`", to.toChars());
+ eSink.error(loc, "cannot infer parameter types from `%s`", to.toChars());
return MATCH.nomatch;
}
{
if (tok == TOK.function_)
{
- if (!flag)
- error("cannot match function literal to delegate type `%s`", to.toChars());
+ eSink.error(loc, "cannot match function literal to delegate type `%s`", to.toChars());
return MATCH.nomatch;
}
tof = cast(TypeFunction)to.nextOf();
{
if (tok == TOK.delegate_)
{
- if (!flag)
- error("cannot match delegate literal to function pointer type `%s`", to.toChars());
+ eSink.error(loc, "cannot match delegate literal to function pointer type `%s`", to.toChars());
return MATCH.nomatch;
}
}
{
if (!tof)
{
- return cannotInfer(this, to, flag);
+ return cannotInfer();
}
// Parameter types inference from 'tof'
const dim = tf.parameterList.length;
if (tof.parameterList.length != dim || tof.parameterList.varargs != tf.parameterList.varargs)
- return cannotInfer(this, to, flag);
+ return cannotInfer();
auto tiargs = new Objects();
tiargs.reserve(td.parameters.length);
Parameter pto = tof.parameterList[u];
Type t = pto.type;
if (t.ty == Terror)
- return cannotInfer(this, to, flag);
+ return cannotInfer();
tf.parameterList[u].storageClass = tof.parameterList[u].storageClass;
tiargs.push(t);
}
if (ex.op == EXP.error)
return MATCH.nomatch;
if (auto ef = ex.isFuncExp())
- return ef.matchType(to, sc, presult, flag);
+ return ef.matchType(to, sc, presult, eSink);
else
- return cannotInfer(this, to, flag);
+ return cannotInfer();
}
if (!tof || !tof.next)
(*presult).fd.modifyReturns(sc, tof.next);
}
}
- else if (!flag)
+ else if (!cast(ErrorSinkNull)eSink)
{
auto ts = toAutoQualChars(tx, to);
- error("cannot implicitly convert expression `%s` of type `%s` to `%s`",
+ eSink.error(loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
toChars(), ts[0], ts[1]);
}
return m;
extern (D) final bool checkArithmeticBin()
{
- bool r1 = e1.checkArithmetic();
- bool r2 = e2.checkArithmetic();
+ bool r1 = e1.checkArithmetic(this.op);
+ bool r2 = e2.checkArithmetic(this.op);
return (r1 || r2);
}
{
const funcStr = fd.Dsymbol.toPrettyChars();
OutBuffer buf;
- functionToBufferWithIdent(fd.type.isTypeFunction(), &buf, funcStr, fd.isStatic);
+ functionToBufferWithIdent(fd.type.isTypeFunction(), buf, funcStr, fd.isStatic);
s = buf.extractChars();
}
else
const char *toChars() const override;
void error(const char *format, ...) const;
- void warning(const char *format, ...) const;
+ void warning(unsigned flag, const char *format, ...) const;
void deprecation(const char *format, ...) const;
virtual dinteger_t toInteger();
OwnedBy ownedByCtfe;
Expressions *keys;
Expressions *values;
+ Expression* lowering;
bool equals(const RootObject * const o) const override;
AssocArrayLiteralExp *syntaxCopy() override;
if (thisAd == requiredAd)
return true;
+ // if outerfunc is the member of a nested aggregate, then let
+ // getRightThis take care of this.
+ if (thisAd.isNested())
+ return true;
+
// outerfunc is the member of a base class that contains calledFunc,
// then we consider that they have the same this.
auto cd = requiredAd.isClassDeclaration();
if (cd.isBaseOf2(thisAd.isClassDeclaration()))
return true;
- // if outerfunc is the member of a nested aggregate, then let
- // getRightThis take care of this.
- if (thisAd.isNested())
- return true;
-
return false;
}
}
err |= arg.checkValue();
err |= arg.checkSharedAccess(sc);
+ err |= checkParamArgumentEscape(sc, fd, Id.dotdotdot, null, cast(STC) tf.parameterList.stc, arg, false, false);
arg = arg.optimize(WANTvalue);
}
(*arguments)[i] = arg;
{
if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp())
{
- checkPrintfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list);
+ checkPrintfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list, sc.eSink);
}
}
else if (fd && fd.scanf)
{
if (auto se = (*arguments)[nparams - 1 - isVa_list].isStringExp())
{
- checkScanfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list);
+ checkScanfFormat(se.loc, se.peekString(), (*arguments)[nparams .. nargs], isVa_list, sc.eSink);
}
}
else
auto args = new Parameters(arguments.length - nparams);
for (size_t i = 0; i < arguments.length - nparams; i++)
{
- auto arg = new Parameter(STC.in_, (*arguments)[nparams + i].type, null, null, null);
+ Expression earg = (*arguments)[nparams + i];
+ auto arg = new Parameter(earg.loc, STC.in_, earg.type, null, null, null);
(*args)[i] = arg;
}
auto tup = new TypeTuple(args);
foreach (v; c.fields)
{
if (v.inuse || v._scope is null || v._init is null ||
- v._init.isVoidInitializer())
+ v._init.isVoidInitializer() || v.semanticRun >= PASS.semantic2done)
continue;
v.inuse++;
v._init = v._init.initializerSemantic(v._scope, v.type, INITinterpret);
+ import dmd.semantic2 : lowerStaticAAs;
+ lowerStaticAAs(v, sc);
v.inuse--;
}
}
if (exp.fd.treq) // defer type determination
{
FuncExp fe;
- if (exp.matchType(exp.fd.treq, sc, &fe) > MATCH.nomatch)
+ if (exp.matchType(exp.fd.treq, sc, &fe, sc.eSink) > MATCH.nomatch)
e = fe;
else
e = ErrorExp.get();
{
OutBuffer buf;
buf.writeByte('(');
- argExpTypesToCBuffer(&buf, exp.arguments);
+ argExpTypesToCBuffer(buf, exp.arguments);
buf.writeByte(')');
if (tthis)
- tthis.modToBuffer(&buf);
+ tthis.modToBuffer(buf);
//printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco);
.error(exp.loc, "%s `%s%s` is not callable using argument types `%s`",
{
OutBuffer buf;
buf.writeByte('(');
- argExpTypesToCBuffer(&buf, exp.arguments);
+ argExpTypesToCBuffer(buf, exp.arguments);
buf.writeByte(')');
//printf("tf = %s, args = %s\n", tf.deco, (*arguments)[0].type.deco);
for (size_t i = 0; i < cd.baseclasses.length; i++)
{
BaseClass* b = (*cd.baseclasses)[i];
- args.push(new Parameter(STC.in_, b.type, null, null, null));
+ args.push(new Parameter(Loc.initial, STC.in_, b.type, null, null, null));
}
tded = new TypeTuple(args);
}
*/
if (e.tok2 == TOK.parameters && arg.defaultArg && arg.defaultArg.op == EXP.error)
return setError();
- args.push(new Parameter(arg.storageClass, arg.type, (e.tok2 == TOK.parameters) ? arg.ident : null, (e.tok2 == TOK.parameters) ? arg.defaultArg : null, arg.userAttribDecl));
+ args.push(new Parameter(arg.loc, arg.storageClass, arg.type, (e.tok2 == TOK.parameters) ? arg.ident : null, (e.tok2 == TOK.parameters) ? arg.defaultArg : null, arg.userAttribDecl));
}
tded = new TypeTuple(args);
break;
else if (!exp.e1.type.deco)
{
// try to resolve the type
- exp.e1.type = exp.e1.type.typeSemantic(exp.e1.loc, null);
+ exp.e1.type = exp.e1.type.typeSemantic(exp.e1.loc, sc);
if (!exp.e1.type.deco) // still couldn't resolve it
{
if (auto ve = exp.e1.isVarExp())
}
if (exp.e1.checkNoBool())
return setError();
- if (exp.e1.checkArithmetic() ||
+ if (exp.e1.checkArithmetic(exp.op) ||
exp.e1.checkSharedAccess(sc))
return setError();
}
if (exp.e1.checkNoBool())
return setError();
- if (exp.e1.checkArithmetic())
+ if (exp.e1.checkArithmetic(exp.op))
return setError();
if (exp.e1.checkSharedAccess(sc))
return setError();
return setError();
}
- if (0 && global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
- e2x.op != EXP.slice && e2x.op != EXP.assign &&
- e2x.op != EXP.arrayLiteral && e2x.op != EXP.string_ &&
- !(e2x.op == EXP.add || e2x.op == EXP.min ||
- e2x.op == EXP.mul || e2x.op == EXP.div ||
- e2x.op == EXP.mod || e2x.op == EXP.xor ||
- e2x.op == EXP.and || e2x.op == EXP.or ||
- e2x.op == EXP.pow ||
- e2x.op == EXP.tilde || e2x.op == EXP.negate))
+ version (none)
{
- const(char)* e1str = exp.e1.toChars();
- const(char)* e2str = e2x.toChars();
- exp.warning("explicit element-wise assignment `%s = (%s)[]` is better than `%s = %s`", e1str, e2str, e1str, e2str);
+ if (global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
+ e2x.op != EXP.slice && e2x.op != EXP.assign &&
+ e2x.op != EXP.arrayLiteral && e2x.op != EXP.string_ &&
+ !(e2x.op == EXP.add || e2x.op == EXP.min ||
+ e2x.op == EXP.mul || e2x.op == EXP.div ||
+ e2x.op == EXP.mod || e2x.op == EXP.xor ||
+ e2x.op == EXP.and || e2x.op == EXP.or ||
+ e2x.op == EXP.pow ||
+ e2x.op == EXP.tilde || e2x.op == EXP.negate))
+ {
+ const(char)* e1str = exp.e1.toChars();
+ const(char)* e2str = e2x.toChars();
+ exp.warning("explicit element-wise assignment `%s = (%s)[]` is better than `%s = %s`", e1str, e2str, e1str, e2str);
+ }
}
Type t2n = t2.nextOf();
}
else
{
- if (0 && global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
- t1.ty == Tarray && t2.ty == Tsarray &&
- e2x.op != EXP.slice &&
- t2.implicitConvTo(t1))
+ version (none)
{
- // Disallow ar[] = sa (Converted to ar[] = sa[])
- // Disallow da = sa (Converted to da = sa[])
- const(char)* e1str = exp.e1.toChars();
- const(char)* e2str = e2x.toChars();
- const(char)* atypestr = exp.e1.op == EXP.slice ? "element-wise" : "slice";
- exp.warning("explicit %s assignment `%s = (%s)[]` is better than `%s = %s`", atypestr, e1str, e2str, e1str, e2str);
+ if (global.params.warnings != DiagnosticReporting.off && !global.gag && exp.op == EXP.assign &&
+ t1.ty == Tarray && t2.ty == Tsarray &&
+ e2x.op != EXP.slice &&
+ t2.implicitConvTo(t1))
+ {
+ // Disallow ar[] = sa (Converted to ar[] = sa[])
+ // Disallow da = sa (Converted to da = sa[])
+ const(char)* e1str = exp.e1.toChars();
+ const(char)* e2str = e2x.toChars();
+ const(char)* atypestr = exp.e1.op == EXP.slice ? "element-wise" : "slice";
+ exp.warning("explicit %s assignment `%s = (%s)[]` is better than `%s = %s`", atypestr, e1str, e2str, e1str, e2str);
+ }
}
if (exp.op == EXP.blit)
e2x = e2x.castTo(sc, exp.e1.type);
bool err = false;
if (tb1.ty == Tdelegate || tb1.isPtrToFunction())
{
- err |= exp.e1.checkArithmetic() || exp.e1.checkSharedAccess(sc);
+ err |= exp.e1.checkArithmetic(exp.op) || exp.e1.checkSharedAccess(sc);
}
if (tb2.ty == Tdelegate || tb2.isPtrToFunction())
{
- err |= exp.e2.checkArithmetic() || exp.e2.checkSharedAccess(sc);
+ err |= exp.e2.checkArithmetic(exp.op) || exp.e2.checkSharedAccess(sc);
}
if (err)
return setError();
bool err = false;
if (t1.ty == Tdelegate || t1.isPtrToFunction())
{
- err |= exp.e1.checkArithmetic() || exp.e1.checkSharedAccess(sc);
+ err |= exp.e1.checkArithmetic(exp.op) || exp.e1.checkSharedAccess(sc);
}
if (t2.ty == Tdelegate || t2.isPtrToFunction())
{
- err |= exp.e2.checkArithmetic() || exp.e2.checkSharedAccess(sc);
+ err |= exp.e2.checkArithmetic(exp.op) || exp.e2.checkSharedAccess(sc);
}
if (err)
return setError();
(exp.e2.isStringExp() && (exp.e1.isIntegerExp() || exp.e1.isStringExp())))
return exp;
- Identifier hook = global.params.tracegc ? Id._d_arraycatnTXTrace : Id._d_arraycatnTX;
+ bool useTraceGCHook = global.params.tracegc && sc.needsCodegen();
+
+ Identifier hook = useTraceGCHook ? Id._d_arraycatnTXTrace : Id._d_arraycatnTX;
if (!verifyHookExist(exp.loc, *sc, hook, "concatenating arrays"))
{
setError();
}
auto arguments = new Expressions();
- if (global.params.tracegc)
+ if (useTraceGCHook)
{
auto funcname = (sc.callsc && sc.callsc.func) ?
sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
/* `_d_arraycatnTX` canot be used with `-betterC`, but `CatExp`s may be
* used with `-betterC`, but only during CTFE.
*/
- if (!global.params.useGC || !sc.needsCodegen())
+ if (!global.params.useGC)
return;
if (auto ce = exp.isCatExp())
return setError();
}
- if (sc.needsCodegen() &&
- (t1.ty == Tarray || t1.ty == Tsarray) &&
+ if ((t1.ty == Tarray || t1.ty == Tsarray) &&
(t2.ty == Tarray || t2.ty == Tsarray))
{
if (!verifyHookExist(exp.loc, *sc, Id.__cmp, "comparing arrays"))
Identifier id = Identifier.generateId("__o");
Statement handler = new PeelStatement(sexception);
- if (sexception.blockExit(fd, false) & BE.fallthru)
+ if (sexception.blockExit(fd, null) & BE.fallthru)
{
auto ts = new ThrowStatement(Loc.initial, new IdentifierExp(Loc.initial, id));
ts.internalThrow = true;
final const(char)* toFullSignature()
{
OutBuffer buf;
- functionToBufferWithIdent(type.toTypeFunction(), &buf, toChars(), isStatic);
+ functionToBufferWithIdent(type.toTypeFunction(), buf, toChars(), isStatic);
return buf.extractChars();
}
break LcheckAncestorsOfANestedRef;
}
a.push(f);
- .errorSupplemental(f.loc, "`%s` closes over variable `%s` at %s",
- f.toPrettyChars(), v.toChars(), v.loc.toChars());
+ .errorSupplemental(f.loc, "%s `%s` closes over variable `%s`",
+ f.kind, f.toPrettyChars(), v.toChars());
+ if (v.ident != Id.This)
+ .errorSupplemental(v.loc, "`%s` declared here", v.toChars());
+
break LcheckAncestorsOfANestedRef;
}
}
auto fparams = new Parameters();
if (canBuildResultVar())
{
- Parameter p = new Parameter(STC.ref_ | STC.const_, f.nextOf(), Id.result, null, null);
+ Parameter p = new Parameter(loc, STC.ref_ | STC.const_, f.nextOf(), Id.result, null, null);
fparams.push(p);
}
auto fo = cast(TypeFunction)(originalType ? originalType : f);
s = fd = td.funcroot;
OutBuffer tiargsBuf;
- arrayObjectsToBuffer(&tiargsBuf, tiargs);
+ arrayObjectsToBuffer(tiargsBuf, tiargs);
OutBuffer fargsBuf;
fargsBuf.writeByte('(');
- argExpTypesToCBuffer(&fargsBuf, fargs);
+ argExpTypesToCBuffer(fargsBuf, fargs);
fargsBuf.writeByte(')');
if (tthis)
- tthis.modToBuffer(&fargsBuf);
+ tthis.modToBuffer(fargsBuf);
// The call is ambiguous
if (m.lastf && m.nextf)
{
if (!gag)
{
- if (!sc.isDeprecated() && global.params.obsolete)
+ version (none) // disable obsolete warning
warning(loc, msg, arg0 ? arg0.toChars() : "", arg1 ? arg1.toChars() : "", arg2 ? arg2.toChars() : "");
}
}
OutBuffer* buffer; // if this output is buffered, this is the buffer
int bufferLines; // number of lines written to the buffer
}
+
+/// Command line state related to printing usage about other switches
+extern(C++) struct Help
+{
+ bool manual; // open browser on compiler manual
+ bool usage; // print usage and exit
+ // print help of switch:
+ bool mcpu; // -mcpu
+ bool transition; // -transition
+ bool check; // -check
+ bool checkAction; // -checkaction
+ bool revert; // -revert
+ bool preview; // -preview
+ bool externStd; // -extern-std
+ bool hc; // -HC
+}
+
/// Put command line switches in here
extern (C++) struct Param
{
bool release; // build release version
bool preservePaths; // true means don't strip path from source file
DiagnosticReporting warnings = DiagnosticReporting.off; // how compiler warnings are handled
- bool obsolete; // enable warnings about use of obsolete messages
bool color; // use ANSI colors in console output
bool cov; // generate code coverage data
ubyte covPercent; // 0..100 code coverage percentage required
bool showGaggedErrors; // print gagged errors anyway
bool printErrorContext; // print errors with the error context (the error line in the source file)
- bool manual; // open browser on compiler manual
- bool usage; // print usage and exit
- bool mcpuUsage; // print help on -mcpu switch
- bool transitionUsage; // print help on -transition switch
- bool checkUsage; // print help on -check switch
- bool checkActionUsage; // print help on -checkaction switch
- bool revertUsage; // print help on -revert switch
- bool previewUsage; // print help on -preview switch
- bool externStdUsage; // print help on -extern-std switch
- bool hcUsage; // print help on -HC switch
+ Help help;
bool logo; // print compiler logo
// Options for `-preview=/-revert=`
Array!(const(char)*)* filePath; /// Array of char*'s which form the file import lookup path
private enum string _version = import("VERSION");
+ char[26] datetime; /// string returned by ctime()
CompileEnv compileEnv;
Param params; /// command line parameters
enum recursionLimit = 500; /// number of recursive template expansions before abort
ErrorSink errorSink; /// where the error messages go
+ ErrorSink errorSinkNull; /// where the error messages are ignored
extern (C++) FileName function(FileName, ref const Loc, out bool, OutBuffer*) preprocess;
extern (C++) void _init()
{
errorSink = new ErrorSinkCompiler;
+ errorSinkNull = new ErrorSinkNull;
this.fileManager = new FileManager();
version (MARS)
core.stdc.time.time(&ct);
const p = ctime(&ct);
assert(p);
+ datetime[] = p[0 .. 26];
__gshared char[11 + 1] date = 0; // put in BSS segment
__gshared char[8 + 1] time = 0;
int bufferLines; // number of lines written to the buffer
};
+/// Command line state related to printing uasage about other switches
+struct Help
+{
+ d_bool manual; // open browser on compiler manual
+ d_bool usage; // print usage and exit
+ // print help of switch:
+ d_bool mcpu; // -mcpu
+ d_bool transition; // -transition
+ d_bool check; // -check
+ d_bool checkAction; // -checkaction
+ d_bool revert; // -revert
+ d_bool preview; // -preview
+ d_bool externStd; // -extern-std
+ d_bool hc; // -HC
+};
+
// Put command line switches in here
struct Param
{
d_bool release; // build release version
d_bool preservePaths; // true means don't strip path from source file
Diagnostic warnings;
- d_bool obsolete; // warn about use of obsolete features
d_bool color; // use ANSI colors in console output
d_bool cov; // generate code coverage data
unsigned char covPercent; // 0..100 code coverage percentage required
CppStdRevision cplusplus; // version of C++ name mangling to support
d_bool showGaggedErrors; // print gagged errors anyway
d_bool printErrorContext; // print errors with the error context (the error line in the source file)
- d_bool manual; // open browser on compiler manual
- d_bool usage; // print usage and exit
- d_bool mcpuUsage; // print help on -mcpu switch
- d_bool transitionUsage; // print help on -transition switch
- d_bool checkUsage; // print help on -check switch
- d_bool checkActionUsage; // print help on -checkaction switch
- d_bool revertUsage; // print help on -revert switch
- d_bool previewUsage; // print help on -preview switch
- d_bool externStdUsage; // print help on -extern-std switch
- d_bool hcUsage; // print help on -HC switch
+ Help help;
d_bool logo; // print logo;
// Options for `-preview=/-revert=`
bool previewIn;
bool ddocOutput;
bool shortenedMethods;
- bool obsolete;
};
struct Global
Array<const char *> *path; // Array of char*'s which form the import lookup path
Array<const char *> *filePath; // Array of char*'s which form the file import lookup path
+ char datetime[26]; /// string returned by ctime()
CompileEnv compileEnv;
Param params;
FileManager* fileManager;
ErrorSink* errorSink; // where the error messages go
+ ErrorSink* errorSinkNull; // where the error messages disappear
FileName (*preprocess)(FileName, const Loc&, bool&, OutBuffer&);
{
private:
unsigned _linnum;
- unsigned short _charnum;
- unsigned short fileIndex;
+ unsigned _charnum;
+ unsigned fileIndex;
public:
static void set(bool showColumns, MessageStyle messageStyle);
import dmd.staticassert;
import dmd.target;
import dmd.tokens;
-import dmd.utils;
import dmd.visitor;
struct HdrGenState
enum TEST_EMIT_ALL = 0;
-extern (C++) void genhdrfile(Module m)
+/****************************************
+ * Generate a header (.di) file for Module m.
+ * Params:
+ * m = Module to generate header for
+ * buf = buffer to write the data to
+ */
+extern (C++) void genhdrfile(Module m, ref OutBuffer buf)
{
- OutBuffer buf;
buf.doindent = 1;
buf.printf("// D import file generated from '%s'", m.srcfile.toChars());
buf.writenl();
HdrGenState hgs;
hgs.hdrgen = true;
- toCBuffer(m, &buf, &hgs);
- writeFile(m.loc, m.hdrfile.toString(), buf[]);
+ toCBuffer(m, buf, hgs);
}
/**
* buf = buffer to write to.
* m = module to visit all members of.
*/
-extern (C++) void moduleToBuffer(OutBuffer* buf, Module m)
+extern (C++) void moduleToBuffer(ref OutBuffer buf, Module m)
{
HdrGenState hgs;
hgs.fullDump = true;
- toCBuffer(m, buf, &hgs);
+ toCBuffer(m, buf, hgs);
}
-void moduleToBuffer2(Module m, OutBuffer* buf, HdrGenState* hgs)
+void moduleToBuffer2(Module m, ref OutBuffer buf, HdrGenState* hgs)
{
if (m.md)
{
}
}
-private void statementToBuffer(Statement s, OutBuffer* buf, HdrGenState* hgs)
+private void statementToBuffer(Statement s, ref OutBuffer buf, HdrGenState* hgs)
{
void visitDefaultCase(Statement s)
{
auto d = ds.exp.isDeclarationExp().declaration;
if (auto v = d.isVarDeclaration())
{
- scope ppv = new DsymbolPrettyPrintVisitor(buf, hgs);
- ppv.visitVarDecl(v, anywritten);
+ visitVarDecl(v, anywritten, buf, *hgs);
}
else
d.dsymbolToBuffer(buf, hgs);
visit.VisitStatement(s);
}
-private void dsymbolToBuffer(Dsymbol s, OutBuffer* buf, HdrGenState* hgs)
+private void dsymbolToBuffer(Dsymbol s, ref OutBuffer buf, HdrGenState* hgs)
{
- scope v = new DsymbolPrettyPrintVisitor(buf, hgs);
+ scope v = new DsymbolPrettyPrintVisitor(&buf, hgs);
s.accept(v);
}
{
buf.writestring(s.kind());
buf.writeByte('(');
- s.exp.expressionToBuffer(buf, hgs);
+ s.exp.expressionToBuffer(*buf, hgs);
if (s.msgs)
{
foreach (m; (*s.msgs)[])
{
buf.writestring(", ");
- m.expressionToBuffer(buf, hgs);
+ m.expressionToBuffer(*buf, hgs);
}
}
buf.writestring(");");
override void visit(EnumMember em)
{
if (em.type)
- typeToBuffer(em.type, em.ident, buf, hgs);
+ typeToBuffer(em.type, em.ident, *buf, hgs);
else
buf.writestring(em.ident.toString());
if (em.value)
{
buf.writestring(" = ");
- em.value.expressionToBuffer(buf, hgs);
+ em.value.expressionToBuffer(*buf, hgs);
}
}
bool hasSTC;
if (auto stcd = d.isStorageClassDeclaration)
{
- hasSTC = stcToBuffer(buf, stcd.stc);
+ hasSTC = stcToBuffer(*buf, stcd.stc);
}
if (!d.decl)
override void visit(DeprecatedDeclaration d)
{
buf.writestring("deprecated(");
- d.msg.expressionToBuffer(buf, hgs);
+ d.msg.expressionToBuffer(*buf, hgs);
buf.writestring(") ");
visit(cast(AttribDeclaration)d);
}
override void visit(VisibilityDeclaration d)
{
- visibilityToBuffer(buf, d.visibility);
+ visibilityToBuffer(*buf, d.visibility);
AttribDeclaration ad = cast(AttribDeclaration)d;
if (ad.decl.length <= 1)
buf.writeByte(' ');
if (d.args && d.args.length)
{
buf.writestring(", ");
- argsToBuffer(d.args, buf, hgs);
+ argsToBuffer(d.args, *buf, hgs);
}
buf.writeByte(')');
override void visit(ConditionalDeclaration d)
{
- d.condition.conditionToBuffer(buf, hgs);
+ d.condition.conditionToBuffer(*buf, hgs);
if (d.decl || d.elsedecl)
{
buf.writenl();
{
if (i)
buf.writestring(", ");
- if (stcToBuffer(buf, p.storageClass))
+ if (stcToBuffer(*buf, p.storageClass))
buf.writeByte(' ');
if (p.type)
- typeToBuffer(p.type, p.ident, buf, hgs);
+ typeToBuffer(p.type, p.ident, *buf, hgs);
else
buf.writestring(p.ident.toString());
}
buf.writestring("; ");
- s.aggr.expressionToBuffer(buf, hgs);
+ s.aggr.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
buf.writenl();
}
buf.writestring(Token.toString(s.op));
buf.writestring(" (");
if (s.prm.type)
- typeToBuffer(s.prm.type, s.prm.ident, buf, hgs);
+ typeToBuffer(s.prm.type, s.prm.ident, *buf, hgs);
else
buf.writestring(s.prm.ident.toString());
buf.writestring("; ");
- s.lwr.expressionToBuffer(buf, hgs);
+ s.lwr.expressionToBuffer(*buf, hgs);
buf.writestring(" .. ");
- s.upr.expressionToBuffer(buf, hgs);
+ s.upr.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
buf.writenl();
}
override void visit(MixinDeclaration d)
{
buf.writestring("mixin(");
- argsToBuffer(d.exps, buf, hgs, null);
+ argsToBuffer(d.exps, *buf, hgs, null);
buf.writestring(");");
buf.writenl();
}
override void visit(UserAttributeDeclaration d)
{
buf.writestring("@(");
- argsToBuffer(d.atts, buf, hgs);
+ argsToBuffer(d.atts, *buf, hgs);
buf.writeByte(')');
visit(cast(AttribDeclaration)d);
}
if (FuncDeclaration fd = onemember.isFuncDeclaration())
{
assert(fd.type);
- if (stcToBuffer(buf, fd.storage_class))
+ if (stcToBuffer(*buf, fd.storage_class))
buf.writeByte(' ');
- functionToBufferFull(cast(TypeFunction)fd.type, buf, d.ident, hgs, d);
+ functionToBufferFull(cast(TypeFunction)fd.type, *buf, d.ident, hgs, d);
visitTemplateConstraint(d.constraint);
hgs.tpltMember++;
bodyToBuffer(fd);
{
if (d.constraint)
return false;
- if (stcToBuffer(buf, vd.storage_class))
+ if (stcToBuffer(*buf, vd.storage_class))
buf.writeByte(' ');
if (vd.type)
- typeToBuffer(vd.type, vd.ident, buf, hgs);
+ typeToBuffer(vd.type, vd.ident, *buf, hgs);
else
buf.writestring(vd.ident.toString());
buf.writeByte('(');
buf.writestring(" = ");
ExpInitializer ie = vd._init.isExpInitializer();
if (ie && (ie.exp.op == EXP.construct || ie.exp.op == EXP.blit))
- (cast(AssignExp)ie.exp).e2.expressionToBuffer(buf, hgs);
+ (cast(AssignExp)ie.exp).e2.expressionToBuffer(*buf, hgs);
else
- vd._init.initializerToBuffer(buf, hgs);
+ vd._init.initializerToBuffer(*buf, hgs);
}
buf.writeByte(';');
buf.writenl();
{
if (i)
buf.writestring(", ");
- p.templateParameterToBuffer(buf, hgs);
+ p.templateParameterToBuffer(*buf, hgs);
}
}
if (!constraint)
return;
buf.writestring(" if (");
- constraint.expressionToBuffer(buf, hgs);
+ constraint.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
}
override void visit(TemplateInstance ti)
{
buf.writestring(ti.name.toChars());
- tiargsToBuffer(ti, buf, hgs);
+ tiargsToBuffer(ti, *buf, hgs);
if (hgs.fullDump)
{
buf.writenl();
- dumpTemplateInstance(ti, buf, hgs);
+ dumpTemplateInstance(ti, *buf, hgs);
}
}
override void visit(TemplateMixin tm)
{
buf.writestring("mixin ");
- typeToBuffer(tm.tqual, null, buf, hgs);
- tiargsToBuffer(tm, buf, hgs);
+ typeToBuffer(tm.tqual, null, *buf, hgs);
+ tiargsToBuffer(tm, *buf, hgs);
if (tm.ident && memcmp(tm.ident.toChars(), cast(const(char)*)"__mixin", 7) != 0)
{
buf.writeByte(' ');
buf.writeByte(';');
buf.writenl();
if (hgs.fullDump)
- dumpTemplateInstance(tm, buf, hgs);
+ dumpTemplateInstance(tm, *buf, hgs);
}
override void visit(EnumDeclaration d)
if (d.memtype)
{
buf.writestring(" : ");
- typeToBuffer(d.memtype, null, buf, hgs);
+ typeToBuffer(d.memtype, null, *buf, hgs);
}
if (!d.members)
{
{
if (i)
buf.writestring(", ");
- typeToBuffer(b.type, null, buf, hgs);
+ typeToBuffer(b.type, null, *buf, hgs);
}
}
{
buf.writestring(d.ident.toString());
buf.writestring(" = ");
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
/*
https://issues.dlang.org/show_bug.cgi?id=23223
}
else if (d.type.ty == Tfunction)
{
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
- typeToBuffer(d.type, d.ident, buf, hgs);
+ typeToBuffer(d.type, d.ident, *buf, hgs);
}
else if (d.ident)
{
hgs.declstring = (d.ident == Id.string || d.ident == Id.wstring || d.ident == Id.dstring);
buf.writestring(d.ident.toString());
buf.writestring(" = ");
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
- typeToBuffer(d.type, null, buf, hgs);
+ typeToBuffer(d.type, null, *buf, hgs);
hgs.declstring = false;
}
buf.writeByte(';');
if (d.aliassym)
d.aliassym.accept(this);
else // d.type
- typeToBuffer(d.type, null, buf, hgs);
+ typeToBuffer(d.type, null, *buf, hgs);
buf.writeByte(';');
buf.writenl();
}
{
if (d.storage_class & STC.local)
return;
- visitVarDecl(d, false);
+ visitVarDecl(d, false, *buf, *hgs);
buf.writeByte(';');
buf.writenl();
}
- void visitVarDecl(VarDeclaration v, bool anywritten)
- {
- const bool isextern = hgs.hdrgen &&
- !hgs.insideFuncBody &&
- !hgs.tpltMember &&
- !hgs.insideAggregate &&
- !(v.storage_class & STC.manifest);
-
- void vinit(VarDeclaration v)
- {
- auto ie = v._init.isExpInitializer();
- if (ie && (ie.exp.op == EXP.construct || ie.exp.op == EXP.blit))
- (cast(AssignExp)ie.exp).e2.expressionToBuffer(buf, hgs);
- else
- v._init.initializerToBuffer(buf, hgs);
- }
-
- if (anywritten)
- {
- buf.writestring(", ");
- buf.writestring(v.ident.toString());
- }
- else
- {
- const bool useTypeof = isextern && v._init && !v.type;
- auto stc = v.storage_class;
- if (isextern)
- stc |= STC.extern_;
- if (useTypeof)
- stc &= ~STC.auto_;
- if (stcToBuffer(buf, stc))
- buf.writeByte(' ');
- if (v.type)
- typeToBuffer(v.type, v.ident, buf, hgs);
- else if (useTypeof)
- {
- buf.writestring("typeof(");
- vinit(v);
- buf.writestring(") ");
- buf.writestring(v.ident.toString());
- }
- else
- buf.writestring(v.ident.toString());
- }
- if (v._init && !isextern)
- {
- buf.writestring(" = ");
- vinit(v);
- }
- }
-
override void visit(FuncDeclaration f)
{
//printf("FuncDeclaration::toCBuffer() '%s'\n", f.toChars());
- if (stcToBuffer(buf, f.storage_class))
+ if (stcToBuffer(*buf, f.storage_class))
buf.writeByte(' ');
auto tf = cast(TypeFunction)f.type;
- typeToBuffer(tf, f.ident, buf, hgs);
+ typeToBuffer(tf, f.ident, *buf, hgs);
if (hgs.hdrgen)
{
{
assert(es.exp && es.exp.op == EXP.assert_);
buf.writestring(" (");
- (cast(AssertExp)es.exp).e1.expressionToBuffer(buf, hgs);
+ (cast(AssertExp)es.exp).e1.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
buf.writenl();
requireDo = false;
else
{
buf.writenl();
- frequire.statementToBuffer(buf, hgs);
+ frequire.statementToBuffer(*buf, hgs);
requireDo = true;
}
}
buf.writestring(fensure.id.toString());
}
buf.writestring("; ");
- (cast(AssertExp)es.exp).e1.expressionToBuffer(buf, hgs);
+ (cast(AssertExp)es.exp).e1.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
buf.writenl();
requireDo = false;
buf.writeByte(')');
}
buf.writenl();
- fensure.ensure.statementToBuffer(buf, hgs);
+ fensure.ensure.statementToBuffer(*buf, hgs);
requireDo = true;
}
}
buf.writeByte('{');
buf.writenl();
buf.level++;
- f.fbody.statementToBuffer(buf, hgs);
+ f.fbody.statementToBuffer(*buf, hgs);
buf.level--;
buf.writeByte('}');
buf.writenl();
TypeFunction tf = cast(TypeFunction)f.type;
if (!f.inferRetType && tf.next)
- typeToBuffer(tf.next, null, buf, hgs);
- parametersToBuffer(tf.parameterList, buf, hgs);
+ typeToBuffer(tf.next, null, *buf, hgs);
+ parametersToBuffer(tf.parameterList, *buf, hgs);
// https://issues.dlang.org/show_bug.cgi?id=20074
void printAttribute(string str)
if (rs && rs.exp)
{
buf.writestring(" => ");
- rs.exp.expressionToBuffer(buf, hgs);
+ rs.exp.expressionToBuffer(*buf, hgs);
}
else
{
override void visit(PostBlitDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
buf.writestring("this(this)");
bodyToBuffer(d);
override void visit(DtorDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
buf.writestring("~this()");
bodyToBuffer(d);
override void visit(StaticCtorDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class & ~STC.static_))
+ if (stcToBuffer(*buf, d.storage_class & ~STC.static_))
buf.writeByte(' ');
if (d.isSharedStaticCtorDeclaration())
buf.writestring("shared ");
override void visit(StaticDtorDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class & ~STC.static_))
+ if (stcToBuffer(*buf, d.storage_class & ~STC.static_))
buf.writeByte(' ');
if (d.isSharedStaticDtorDeclaration())
buf.writestring("shared ");
{
if (hgs.hdrgen)
return;
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
buf.writestring("invariant");
if(auto es = d.fbody.isExpStatement())
{
assert(es.exp && es.exp.op == EXP.assert_);
buf.writestring(" (");
- (cast(AssertExp)es.exp).e1.expressionToBuffer(buf, hgs);
+ (cast(AssertExp)es.exp).e1.expressionToBuffer(*buf, hgs);
buf.writestring(");");
buf.writenl();
}
{
if (hgs.hdrgen)
return;
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
buf.writestring("unittest");
bodyToBuffer(d);
override void visit(BitFieldDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
Identifier id = d.isAnonymous() ? null : d.ident;
- typeToBuffer(d.type, id, buf, hgs);
+ typeToBuffer(d.type, id, *buf, hgs);
buf.writestring(" : ");
- d.width.expressionToBuffer(buf, hgs);
+ d.width.expressionToBuffer(*buf, hgs);
buf.writeByte(';');
buf.writenl();
}
override void visit(NewDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class & ~STC.static_))
+ if (stcToBuffer(*buf, d.storage_class & ~STC.static_))
buf.writeByte(' ');
buf.writestring("new();");
}
override void visit(Module m)
{
- moduleToBuffer2(m, buf, hgs);
+ moduleToBuffer2(m, *buf, hgs);
+ }
+}
+
+/*******************************************
+ * Pretty-print a VarDeclaration to buf.
+ */
+private void visitVarDecl(VarDeclaration v, bool anywritten, ref OutBuffer buf, ref HdrGenState hgs)
+{
+ const bool isextern = hgs.hdrgen &&
+ !hgs.insideFuncBody &&
+ !hgs.tpltMember &&
+ !hgs.insideAggregate &&
+ !(v.storage_class & STC.manifest);
+
+ void vinit(VarDeclaration v)
+ {
+ auto ie = v._init.isExpInitializer();
+ if (ie && (ie.exp.op == EXP.construct || ie.exp.op == EXP.blit))
+ (cast(AssignExp)ie.exp).e2.expressionToBuffer(buf, &hgs);
+ else
+ v._init.initializerToBuffer(buf, &hgs);
+ }
+
+ if (anywritten)
+ {
+ buf.writestring(", ");
+ buf.writestring(v.ident.toString());
+ }
+ else
+ {
+ const bool useTypeof = isextern && v._init && !v.type;
+ auto stc = v.storage_class;
+ if (isextern)
+ stc |= STC.extern_;
+ if (useTypeof)
+ stc &= ~STC.auto_;
+ if (stcToBuffer(buf, stc))
+ buf.writeByte(' ');
+ if (v.type)
+ typeToBuffer(v.type, v.ident, buf, &hgs);
+ else if (useTypeof)
+ {
+ buf.writestring("typeof(");
+ vinit(v);
+ buf.writestring(") ");
+ buf.writestring(v.ident.toString());
+ }
+ else
+ buf.writestring(v.ident.toString());
+ }
+ if (v._init && !isextern)
+ {
+ buf.writestring(" = ");
+ vinit(v);
}
}
+
/*********************************************
* Print expression to buffer.
*/
-private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hgs)
+private void expressionPrettyPrint(Expression e, ref OutBuffer buf, HdrGenState* hgs)
{
void visit(Expression e)
{
case Tdchar:
{
const o = buf.length;
- writeSingleCharLiteral(*buf, cast(dchar) v);
+ writeSingleCharLiteral(buf, cast(dchar) v);
if (hgs.ddoc)
escapeDdocString(buf, o);
break;
const o = buf.length;
foreach (i; 0 .. e.len)
{
- writeCharLiteral(*buf, e.getCodeUnit(i));
+ writeCharLiteral(buf, e.getCodeUnit(i));
}
if (hgs.ddoc)
escapeDdocString(buf, o);
// which isn't correct as regular D code.
buf.writeByte('(');
- scope v = new DsymbolPrettyPrintVisitor(buf, hgs);
- v.visitVarDecl(var, false);
+ visitVarDecl(var, false, buf, *hgs);
buf.writeByte(';');
buf.writeByte(')');
if (e.parameters && e.parameters.length)
{
buf.writestring(", ");
- scope v = new DsymbolPrettyPrintVisitor(buf, hgs);
+ scope v = new DsymbolPrettyPrintVisitor(&buf, hgs);
v.visitTemplateParameters(e.parameters);
}
buf.writeByte(')');
* allowHex = whether hex floating point literals may be used
* for greater accuracy
*/
-void floatToBuffer(Type type, const real_t value, OutBuffer* buf, const bool allowHex)
+void floatToBuffer(Type type, const real_t value, ref OutBuffer buf, const bool allowHex)
{
/** sizeof(value)*3 is because each byte of mantissa is max
of 256 (3 characters). The string will be "-M.MMMMe-4932".
}
}
-private void templateParameterToBuffer(TemplateParameter tp, OutBuffer* buf, HdrGenState* hgs)
+private void templateParameterToBuffer(TemplateParameter tp, ref OutBuffer buf, HdrGenState* hgs)
{
- scope v = new TemplateParameterPrettyPrintVisitor(buf, hgs);
+ scope v = new TemplateParameterPrettyPrintVisitor(&buf, hgs);
tp.accept(v);
}
if (tp.specType)
{
buf.writestring(" : ");
- typeToBuffer(tp.specType, null, buf, hgs);
+ typeToBuffer(tp.specType, null, *buf, hgs);
}
if (tp.defaultType)
{
buf.writestring(" = ");
- typeToBuffer(tp.defaultType, null, buf, hgs);
+ typeToBuffer(tp.defaultType, null, *buf, hgs);
}
}
{
buf.writestring("alias ");
if (tp.specType)
- typeToBuffer(tp.specType, tp.ident, buf, hgs);
+ typeToBuffer(tp.specType, tp.ident, *buf, hgs);
else
buf.writestring(tp.ident.toString());
if (tp.specAlias)
{
buf.writestring(" : ");
- objectToBuffer(tp.specAlias, buf, hgs);
+ objectToBuffer(tp.specAlias, *buf, hgs);
}
if (tp.defaultAlias)
{
buf.writestring(" = ");
- objectToBuffer(tp.defaultAlias, buf, hgs);
+ objectToBuffer(tp.defaultAlias, *buf, hgs);
}
}
override void visit(TemplateValueParameter tp)
{
- typeToBuffer(tp.valType, tp.ident, buf, hgs);
+ typeToBuffer(tp.valType, tp.ident, *buf, hgs);
if (tp.specValue)
{
buf.writestring(" : ");
- tp.specValue.expressionToBuffer(buf, hgs);
+ tp.specValue.expressionToBuffer(*buf, hgs);
}
if (tp.defaultValue)
{
buf.writestring(" = ");
- tp.defaultValue.expressionToBuffer(buf, hgs);
+ tp.defaultValue.expressionToBuffer(*buf, hgs);
}
}
}
}
-private void conditionToBuffer(Condition c, OutBuffer* buf, HdrGenState* hgs)
+private void conditionToBuffer(Condition c, ref OutBuffer buf, HdrGenState* hgs)
{
- scope v = new ConditionPrettyPrintVisitor(buf, hgs);
+ scope v = new ConditionPrettyPrintVisitor(&buf, hgs);
c.accept(v);
}
override void visit(StaticIfCondition c)
{
buf.writestring("static if (");
- c.exp.expressionToBuffer(buf, hgs);
+ c.exp.expressionToBuffer(*buf, hgs);
buf.writeByte(')');
}
}
-void toCBuffer(const Statement s, OutBuffer* buf, HdrGenState* hgs)
+void toCBuffer(const Statement s, ref OutBuffer buf, ref HdrGenState hgs)
{
- (cast()s).statementToBuffer(buf, hgs);
+ (cast()s).statementToBuffer(buf, &hgs);
}
-void toCBuffer(const Type t, OutBuffer* buf, const Identifier ident, HdrGenState* hgs)
+void toCBuffer(const Type t, ref OutBuffer buf, const Identifier ident, ref HdrGenState hgs)
{
- typeToBuffer(cast() t, ident, buf, hgs);
+ typeToBuffer(cast() t, ident, buf, &hgs);
}
-void toCBuffer(Dsymbol s, OutBuffer* buf, HdrGenState* hgs)
+void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
{
- scope v = new DsymbolPrettyPrintVisitor(buf, hgs);
+ scope v = new DsymbolPrettyPrintVisitor(&buf, &hgs);
s.accept(v);
}
// used from TemplateInstance::toChars() and TemplateMixin::toChars()
-void toCBufferInstance(const TemplateInstance ti, OutBuffer* buf, bool qualifyTypes = false)
+void toCBufferInstance(const TemplateInstance ti, ref OutBuffer buf, bool qualifyTypes = false)
{
HdrGenState hgs;
hgs.fullQual = qualifyTypes;
- scope v = new DsymbolPrettyPrintVisitor(buf, &hgs);
+ scope v = new DsymbolPrettyPrintVisitor(&buf, &hgs);
v.visit(cast() ti);
}
-void toCBuffer(const Initializer iz, OutBuffer* buf, HdrGenState* hgs)
+void toCBuffer(const Initializer iz, ref OutBuffer buf, ref HdrGenState hgs)
{
- initializerToBuffer(cast() iz, buf, hgs);
+ initializerToBuffer(cast() iz, buf, &hgs);
}
-bool stcToBuffer(OutBuffer* buf, StorageClass stc) @safe
+bool stcToBuffer(ref OutBuffer buf, StorageClass stc) @safe
{
//printf("stc: %llx\n", stc);
bool result = false;
return null;
}
-private void linkageToBuffer(OutBuffer* buf, LINK linkage) @safe
+private void linkageToBuffer(ref OutBuffer buf, LINK linkage) @safe
{
const s = linkageToString(linkage);
if (s.length)
}
}
-void visibilityToBuffer(OutBuffer* buf, Visibility vis)
+void visibilityToBuffer(ref OutBuffer buf, Visibility vis)
{
buf.writestring(visibilityToString(vis.kind));
if (vis.kind == Visibility.Kind.package_ && vis.pkg)
}
// Print the full function signature with correct ident, attributes and template args
-void functionToBufferFull(TypeFunction tf, OutBuffer* buf, const Identifier ident, HdrGenState* hgs, TemplateDeclaration td)
+void functionToBufferFull(TypeFunction tf, ref OutBuffer buf, const Identifier ident, HdrGenState* hgs, TemplateDeclaration td)
{
//printf("TypeFunction::toCBuffer() this = %p\n", this);
visitFuncIdentWithPrefix(tf, ident, td, buf, hgs);
}
// ident is inserted before the argument list and will be "function" or "delegate" for a type
-void functionToBufferWithIdent(TypeFunction tf, OutBuffer* buf, const(char)* ident, bool isStatic)
+void functionToBufferWithIdent(TypeFunction tf, ref OutBuffer buf, const(char)* ident, bool isStatic)
{
HdrGenState hgs;
visitFuncIdentWithPostfix(tf, ident.toDString(), buf, &hgs, isStatic);
}
-void toCBuffer(const Expression e, OutBuffer* buf, HdrGenState* hgs)
+void toCBuffer(const Expression e, ref OutBuffer buf, ref HdrGenState hgs)
{
- expressionPrettyPrint(cast()e, buf, hgs);
+ expressionPrettyPrint(cast()e, buf, &hgs);
}
/**************************************************
* Write out argument types to buf.
*/
-void argExpTypesToCBuffer(OutBuffer* buf, Expressions* arguments)
+void argExpTypesToCBuffer(ref OutBuffer buf, Expressions* arguments)
{
if (!arguments || !arguments.length)
return;
}
}
-void toCBuffer(const TemplateParameter tp, OutBuffer* buf, HdrGenState* hgs)
+void toCBuffer(const TemplateParameter tp, ref OutBuffer buf, ref HdrGenState hgs)
{
- scope v = new TemplateParameterPrettyPrintVisitor(buf, hgs);
+ scope v = new TemplateParameterPrettyPrintVisitor(&buf, &hgs);
(cast() tp).accept(v);
}
-void arrayObjectsToBuffer(OutBuffer* buf, Objects* objects)
+void arrayObjectsToBuffer(ref OutBuffer buf, Objects* objects)
{
if (!objects || !objects.length)
return;
{
OutBuffer buf;
HdrGenState hgs;
- parametersToBuffer(pl, &buf, &hgs);
+ parametersToBuffer(pl, buf, &hgs);
return buf.extractChars();
}
HdrGenState hgs;
hgs.fullQual = fullQual;
- parameterToBuffer(parameter, &buf, &hgs);
+ parameterToBuffer(parameter, buf, &hgs);
if (tf.parameterList.varargs == VarArg.typesafe && parameter == tf.parameterList[tf.parameterList.parameters.length - 1])
{
* hgs = context
*/
-private void parametersToBuffer(ParameterList pl, OutBuffer* buf, HdrGenState* hgs)
+private void parametersToBuffer(ParameterList pl, ref OutBuffer buf, HdrGenState* hgs)
{
buf.writeByte('(');
foreach (i; 0 .. pl.length)
* buf = buffer to write it to
* hgs = context
*/
-private void parameterToBuffer(Parameter p, OutBuffer* buf, HdrGenState* hgs)
+private void parameterToBuffer(Parameter p, ref OutBuffer buf, HdrGenState* hgs)
{
if (p.userAttribDecl)
{
* basis = replace `null`s in argument list with this expression (for sparse array literals)
* names = if non-null, use these as the names for the arguments
*/
-private void argsToBuffer(Expressions* expressions, OutBuffer* buf, HdrGenState* hgs, Expression basis = null, Identifiers* names = null)
+private void argsToBuffer(Expressions* expressions, ref OutBuffer buf, HdrGenState* hgs, Expression basis = null, Identifiers* names = null)
{
if (!expressions || !expressions.length)
return;
}
}
-private void sizeToBuffer(Expression e, OutBuffer* buf, HdrGenState* hgs)
+private void sizeToBuffer(Expression e, ref OutBuffer buf, HdrGenState* hgs)
{
if (e.type == Type.tsize_t)
{
expToBuffer(e, PREC.assign, buf, hgs);
}
-private void expressionToBuffer(Expression e, OutBuffer* buf, HdrGenState* hgs)
+private void expressionToBuffer(Expression e, ref OutBuffer buf, HdrGenState* hgs)
{
expressionPrettyPrint(e, buf, hgs);
}
* Write expression out to buf, but wrap it
* in ( ) if its precedence is less than pr.
*/
-private void expToBuffer(Expression e, PREC pr, OutBuffer* buf, HdrGenState* hgs)
+private void expToBuffer(Expression e, PREC pr, ref OutBuffer buf, HdrGenState* hgs)
{
debug
{
/**************************************************
* An entry point to pretty-print type.
*/
-private void typeToBuffer(Type t, const Identifier ident, OutBuffer* buf, HdrGenState* hgs,
+private void typeToBuffer(Type t, const Identifier ident, ref OutBuffer buf, HdrGenState* hgs,
ubyte modMask = 0)
{
if (auto tf = t.isTypeFunction())
}
}
-private void visitWithMask(Type t, ubyte modMask, OutBuffer* buf, HdrGenState* hgs)
+private void visitWithMask(Type t, ubyte modMask, ref OutBuffer buf, HdrGenState* hgs)
{
// Tuples and functions don't use the type constructor syntax
if (modMask == t.mod || t.ty == Tfunction || t.ty == Ttuple)
}
-private void dumpTemplateInstance(TemplateInstance ti, OutBuffer* buf, HdrGenState* hgs)
+private void dumpTemplateInstance(TemplateInstance ti, ref OutBuffer buf, HdrGenState* hgs)
{
buf.writeByte('{');
buf.writenl();
}
-private void tiargsToBuffer(TemplateInstance ti, OutBuffer* buf, HdrGenState* hgs)
+private void tiargsToBuffer(TemplateInstance ti, ref OutBuffer buf, HdrGenState* hgs)
{
buf.writeByte('!');
if (ti.nest)
* This makes a 'pretty' version of the template arguments.
* It's analogous to genIdent() which makes a mangled version.
*/
-private void objectToBuffer(RootObject oarg, OutBuffer* buf, HdrGenState* hgs)
+private void objectToBuffer(RootObject oarg, ref OutBuffer buf, HdrGenState* hgs)
{
//printf("objectToBuffer()\n");
/* The logic of this should match what genIdent() does. The _dynamic_cast()
}
-private void visitFuncIdentWithPostfix(TypeFunction t, const char[] ident, OutBuffer* buf, HdrGenState* hgs, bool isStatic)
+private void visitFuncIdentWithPostfix(TypeFunction t, const char[] ident, ref OutBuffer buf, HdrGenState* hgs, bool isStatic)
{
if (t.inuse)
{
}
private void visitFuncIdentWithPrefix(TypeFunction t, const Identifier ident, TemplateDeclaration td,
- OutBuffer* buf, HdrGenState* hgs)
+ ref OutBuffer buf, HdrGenState* hgs)
{
if (t.inuse)
{
}
-private void initializerToBuffer(Initializer inx, OutBuffer* buf, HdrGenState* hgs)
+private void initializerToBuffer(Initializer inx, ref OutBuffer buf, HdrGenState* hgs)
{
void visitError(ErrorInitializer iz)
{
if (d.exp)
{
buf.writeByte('[');
- toCBuffer(d.exp, buf, hgs);
+ toCBuffer(d.exp, buf, *hgs);
buf.writeByte(']');
}
else
}
-private void typeToBufferx(Type t, OutBuffer* buf, HdrGenState* hgs)
+private void typeToBufferx(Type t, ref OutBuffer buf, HdrGenState* hgs)
{
void visitType(Type t)
{
buf.writeByte(' ');
if (t.id)
buf.writestring(t.id.toChars());
- if (t.tok == TOK.enum_ && t.base.ty != TY.Tint32)
+ if (t.tok == TOK.enum_ && t.base && t.base.ty != TY.Tint32)
{
buf.writestring(" : ");
visitWithMask(t.base, t.mod, buf, hgs);
class Module;
-void genhdrfile(Module *m);
+void genhdrfile(Module *m, OutBuffer &buf);
void genCppHdrFiles(Modules &ms);
-void moduleToBuffer(OutBuffer *buf, Module *m);
+void moduleToBuffer(OutBuffer& buf, Module *m);
const char *parametersTypeToChars(ParameterList pl);
s.insn = semanticString(sc, s.insn, "asm instruction template");
if (s.labels && s.outputargs)
- s.error("extended asm statements with labels cannot have output constraints");
+ error(s.loc, "extended asm statements with labels cannot have output constraints");
// Analyse all input and output operands.
if (s.args)
{ "returnLabel", "__returnLabel" },
{ "line" },
{ "empty", "" },
+ { "dotdotdot", "..." }, // use for error messages
{ "p" },
{ "__vptr" },
{ "__monitor" },
{ "aaKeys", "_aaKeys" },
{ "aaValues", "_aaValues" },
{ "aaRehash", "_aaRehash" },
+ { "_aaAsStruct" },
{ "monitorenter", "_d_monitorenter" },
{ "monitorexit", "_d_monitorexit" },
{ "criticalenter", "_d_criticalenter2" },
{
OutBuffer buf;
HdrGenState hgs;
- .toCBuffer(this, &buf, &hgs);
+ toCBuffer(this, buf, hgs);
return buf.extractChars();
}
*/
Expression toAssocArrayLiteral(ArrayInitializer ai)
{
- Expression e;
- //printf("ArrayInitializer::toAssocArrayInitializer()\n");
+ //printf("ArrayInitializer::toAssocArrayInitializer(%s)\n", ai.toChars());
//static int i; if (++i == 2) assert(0);
const dim = ai.value.length;
+ if (!dim)
+ {
+ error(ai.loc, "invalid associative array initializer `%s`, use `null` instead",
+ ai.toChars());
+ return ErrorExp.get();
+ }
+ auto no(const char* format, Initializer i)
+ {
+ error(i.loc, format, i.toChars());
+ return ErrorExp.get();
+ }
+ Expression e;
auto keys = new Expressions(dim);
auto values = new Expressions(dim);
for (size_t i = 0; i < dim; i++)
{
- e = ai.index[i];
- if (!e)
- goto Lno;
- (*keys)[i] = e;
Initializer iz = ai.value[i];
- if (!iz)
- goto Lno;
+ assert(iz);
e = iz.initializerToExpression();
if (!e)
- goto Lno;
+ return no("invalid value `%s` in initializer", iz);
(*values)[i] = e;
+ e = ai.index[i];
+ if (!e)
+ return no("missing key for value `%s` in initializer", iz);
+ (*keys)[i] = e;
}
e = new AssocArrayLiteralExp(ai.loc, keys, values);
return e;
-Lno:
- error(ai.loc, "not an associative array initializer");
- return ErrorExp.get();
}
/******************************************
Params:
modules = array of the "root modules"
*/
- private void generateModules(Modules* modules)
+ private void generateModules(ref Modules modules)
{
arrayStart();
- if (modules)
+ foreach (m; modules)
{
- foreach (m; *modules)
- {
- if (global.params.verbose)
- message("json gen %s", m.toChars());
- m.accept(this);
- }
+ if (global.params.verbose)
+ message("json gen %s", m.toChars());
+ m.accept(this);
}
arrayEnd();
}
}
}
-extern (C++) void json_generate(OutBuffer* buf, Modules* modules)
+/***********************************
+ * Generate json for the modules.
+ * Params:
+ * modules = array of Modules
+ * buf = write json output to buf
+ */
+extern (C++) void json_generate(ref Modules modules, ref OutBuffer buf)
{
- scope ToJsonVisitor json = new ToJsonVisitor(buf);
+ scope ToJsonVisitor json = new ToJsonVisitor(&buf);
// write trailing newline
scope(exit) buf.writeByte('\n');
struct OutBuffer;
-void json_generate(OutBuffer *, Modules *);
+void json_generate(Modules &, OutBuffer &);
JsonFieldFlags tryParseJsonField(const char *fieldName);
bool previewIn; /// `in` means `[ref] scope const`, accepts rvalues
bool ddocOutput; /// collect embedded documentation comments
bool shortenedMethods = true; /// allow => in normal function declarations
- bool obsolete; /// warn on use of legacy code
+ bool masm; /// use MASM inline asm syntax
}
/***********************************************************
goto default;
wysiwygStringConstant(t);
return;
+ case 'x':
+ if (p[1] != '"')
+ goto case_ident;
+ p++;
+ t.value = hexStringConstant(t);
+ return;
case 'q':
if (Ccompile)
goto case_ident;
//case 'u':
case 'v':
case 'w':
- case 'x':
+ /*case 'x':*/
case 'y':
case 'z':
case 'A':
}
}
+ /**************************************
+ * Lex hex strings:
+ * x"0A ae 34FE BD"
+ */
+ final TOK hexStringConstant(Token* t)
+ {
+ Loc start = loc();
+ uint n = 0;
+ uint v = ~0; // dead assignment, needed to suppress warning
+ p++;
+ stringbuffer.setsize(0);
+ while (1)
+ {
+ dchar c = *p++;
+ switch (c)
+ {
+ case ' ':
+ case '\t':
+ case '\v':
+ case '\f':
+ continue; // skip white space
+ case '\r':
+ if (*p == '\n')
+ continue; // ignore '\r' if followed by '\n'
+ // Treat isolated '\r' as if it were a '\n'
+ goto case '\n';
+ case '\n':
+ endOfLine();
+ continue;
+ case 0:
+ case 0x1A:
+ error("unterminated string constant starting at %s", start.toChars());
+ t.setString();
+ // decrement `p`, because it needs to point to the next token (the 0 or 0x1A character is the TOK.endOfFile token).
+ p--;
+ return TOK.hexadecimalString;
+ case '"':
+ if (n & 1)
+ {
+ error("odd number (%d) of hex characters in hex string", n);
+ stringbuffer.writeByte(v);
+ }
+ t.setString(stringbuffer);
+ stringPostfix(t);
+ return TOK.hexadecimalString;
+ default:
+ if (c >= '0' && c <= '9')
+ c -= '0';
+ else if (c >= 'a' && c <= 'f')
+ c -= 'a' - 10;
+ else if (c >= 'A' && c <= 'F')
+ c -= 'A' - 10;
+ else if (c & 0x80)
+ {
+ p--;
+ const u = decodeUTF();
+ p++;
+ if (u == PS || u == LS)
+ endOfLine();
+ else
+ error("non-hex character \\u%04x in hex string", u);
+ }
+ else
+ error("non-hex character '%c' in hex string", c);
+ if (n & 1)
+ {
+ v = (v << 4) | c;
+ stringbuffer.writeByte(v);
+ }
+ else
+ v = c;
+ n++;
+ break;
+ }
+ }
+ assert(0); // see bug 15731
+ }
+
/**
Lex a delimited string. Some examples of delimited strings are:
---
struct Loc
{
private uint _linnum;
- private ushort _charnum;
- private ushort fileIndex; // index into filenames[], starting from 1 (0 means no filename)
+ private uint _charnum;
+ private uint fileIndex; // index into filenames[], starting from 1 (0 means no filename)
version (LocOffset)
uint fileOffset; /// utf8 code unit index relative to start of file, starting from 0
extern (D) this(const(char)* filename, uint linnum, uint charnum) @safe
{
this._linnum = linnum;
- this._charnum = cast(ushort) charnum;
+ this._charnum = charnum;
this.filename = filename;
}
/// ditto
extern (C++) uint charnum(uint num) @nogc @safe
{
- return _charnum = cast(ushort) num;
+ return _charnum = num;
}
/// line number, starting from 1
{
//printf("setting %s\n", name);
filenames.push(name);
- fileIndex = cast(ushort)filenames.length;
- assert(fileIndex); // no overflow
+ fileIndex = cast(uint)filenames.length;
+ if (!fileIndex)
+ {
+ import dmd.globals : global;
+ import dmd.errors : error, fatal;
+
+ global.gag = 0; // ensure error message gets printed
+ error(Loc.initial, "internal compiler error: file name index overflow!");
+ fatal();
+ }
}
else
fileIndex = 0;
int doppelganger; // sub-module
Symbol *cov; // private uint[] __coverage;
- unsigned *covb; // bit array of valid code line numbers
+ DArray<unsigned> covb; // bit array of valid code line numbers
Symbol *sictor; // module order independent constructor
Symbol *sctor; // module constructor
/*********************************
* Store modifier name into buf.
*/
-void MODtoBuffer(OutBuffer* buf, MOD mod) nothrow @safe
+void MODtoBuffer(ref OutBuffer buf, MOD mod) nothrow @safe
{
buf.writestring(MODtoString(mod));
}
HdrGenState hgs;
hgs.fullQual = (ty == Tclass && !mod);
- .toCBuffer(this, &buf, null, &hgs);
+ toCBuffer(this, buf, null, hgs);
return buf.extractChars();
}
HdrGenState hgs;
hgs.fullQual = QualifyTypes;
- .toCBuffer(this, &buf, null, &hgs);
+ toCBuffer(this, buf, null, hgs);
return buf.extractChars();
}
/*********************************
* Store this type's modifier name into buf.
*/
- final void modToBuffer(OutBuffer* buf) nothrow const
+ final void modToBuffer(ref OutBuffer buf) nothrow const
{
if (mod)
{
{
OutBuffer buf;
buf.reserve(16);
- modToBuffer(&buf);
+ modToBuffer(buf);
return buf.extractChars();
}
continue;
if (params == parameterList.parameters)
params = parameterList.parameters.copy();
- (*params)[i] = new Parameter(p.storageClass, t, null, null, null);
+ (*params)[i] = new Parameter(p.loc, p.storageClass, t, null, null, null);
}
if (next == tret && params == parameterList.parameters)
return this;
Expression e = (*exps)[i];
if (e.type.ty == Ttuple)
e.error("cannot form sequence of sequences");
- auto arg = new Parameter(STC.undefined_, e.type, null, null, null);
+ auto arg = new Parameter(e.loc, STC.undefined_, e.type, null, null, null);
(*arguments)[i] = arg;
}
}
{
super(Ttuple);
arguments = new Parameters();
- arguments.push(new Parameter(0, t1, null, null, null));
+ arguments.push(new Parameter(Loc.initial, 0, t1, null, null, null));
}
extern (D) this(Type t1, Type t2)
{
super(Ttuple);
arguments = new Parameters();
- arguments.push(new Parameter(0, t1, null, null, null));
- arguments.push(new Parameter(0, t2, null, null, null));
+ arguments.push(new Parameter(Loc.initial, 0, t1, null, null, null));
+ arguments.push(new Parameter(Loc.initial, 0, t2, null, null, null));
}
static TypeTuple create() @safe
{
import dmd.attrib : UserAttributeDeclaration;
+ Loc loc;
StorageClass storageClass;
Type type;
Identifier ident;
Expression defaultArg;
UserAttributeDeclaration userAttribDecl; // user defined attributes
- extern (D) this(StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) @safe
+ extern (D) this(const ref Loc loc, StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) @safe
{
+ this.loc = loc;
this.type = type;
this.ident = ident;
this.storageClass = storageClass;
this.userAttribDecl = userAttribDecl;
}
- static Parameter create(StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) @safe
+ static Parameter create(const ref Loc loc, StorageClass storageClass, Type type, Identifier ident, Expression defaultArg, UserAttributeDeclaration userAttribDecl) @safe
{
- return new Parameter(storageClass, type, ident, defaultArg, userAttribDecl);
+ return new Parameter(loc, storageClass, type, ident, defaultArg, userAttribDecl);
}
Parameter syntaxCopy()
{
- return new Parameter(storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null, userAttribDecl ? userAttribDecl.syntaxCopy(null) : null);
+ return new Parameter(loc, storageClass, type ? type.syntaxCopy() : null, ident, defaultArg ? defaultArg.syntaxCopy() : null, userAttribDecl ? userAttribDecl.syntaxCopy(null) : null);
}
/****************************************************
}
assert(0);
}
+
+
+/**
+ * Returns:
+ * `TypeIdentifier` corresponding to `object.Throwable`
+ */
+TypeIdentifier getThrowable()
+{
+ auto tid = new TypeIdentifier(Loc.initial, Id.empty);
+ tid.addIdent(Id.object);
+ tid.addIdent(Id.Throwable);
+ return tid;
+}
+
+/**
+ * Returns:
+ * TypeIdentifier corresponding to `object.Exception`
+ */
+TypeIdentifier getException()
+{
+ auto tid = new TypeIdentifier(Loc.initial, Id.empty);
+ tid.addIdent(Id.object);
+ tid.addIdent(Id.Exception);
+ return tid;
+}
virtual unsigned alignsize();
Type *trySemantic(const Loc &loc, Scope *sc);
Type *merge2();
- void modToBuffer(OutBuffer *buf) const;
+ void modToBuffer(OutBuffer& buf) const;
char *modToChars() const;
virtual bool isintegral();
class Parameter final : public ASTNode
{
public:
+ Loc loc;
StorageClass storageClass;
Type *type;
Identifier *ident;
Expression *defaultArg;
UserAttributeDeclaration *userAttribDecl; // user defined attributes
- static Parameter *create(StorageClass storageClass, Type *type, Identifier *ident,
+ static Parameter *create(const Loc &loc, StorageClass storageClass, Type *type, Identifier *ident,
Expression *defaultArg, UserAttributeDeclaration *userAttribDecl);
Parameter *syntaxCopy();
Type *isLazyArray();
if (fd_ambig)
{
- .error(ethis.loc, "`%s.%s` matches more than one declaration:\n`%s`: `%s`\nand:\n`%s`: `%s`",
- ethis.toChars(), fstart.ident.toChars(),
- fd_best.loc.toChars(), fd_best.type.toChars(),
- fd_ambig.loc.toChars(), fd_ambig.type.toChars());
+ .error(ethis.loc, "`%s.%s` matches more than one declaration:",
+ ethis.toChars(), fstart.ident.toChars());
+ .errorSupplemental(fd_best.loc, "`%s`\nand:", fd_best.type.toChars());
+ .errorSupplemental(fd_ambig.loc, "`%s`", fd_ambig.type.toChars());
return null;
}
//printf("CatExp::optimize(%d) %s\n", result, e.toChars());
if (binOptimize(e, result))
return;
- if (auto ce1 = e.e1.isCatExp())
- {
- // https://issues.dlang.org/show_bug.cgi?id=12798
- // optimize ((expr ~ str1) ~ str2)
- scope CatExp cex = new CatExp(e.loc, ce1.e2, e.e2);
- cex.type = e.type;
- Expression ex = Expression_optimize(cex, result, false);
- if (ex != cex)
+
+ if (e.type == Type.tstring)
+ if (auto ce1 = e.e1.isCatExp())
{
- e.e1 = ce1.e1;
- e.e2 = ex;
+ // https://issues.dlang.org/show_bug.cgi?id=12798
+ // optimize ((expr ~ str1) ~ str2)
+ // https://issues.dlang.org/show_bug.cgi?id=24078
+ // This optimization is only valid if `expr` is a string.
+ // Otherwise it leads to:
+ // `["c"] ~ "a" ~ "b"` becoming `["c"] ~ "ab"`
+ scope CatExp cex = new CatExp(e.loc, ce1.e2, e.e2);
+ cex.type = e.type;
+ Expression ex = Expression_optimize(cex, result, false);
+ if (ex != cex)
+ {
+ e.e1 = ce1.e1;
+ e.e2 = ex;
+ }
}
- }
// optimize "str"[] -> "str"
if (auto se1 = e.e1.isSliceExp())
{
if (orig & added)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, added);
+ AST.stcToBuffer(buf, added);
error("redundant attribute `%s`", buf.peekChars());
return orig | added;
}
case TOK.wcharLiteral:
case TOK.dcharLiteral:
case TOK.string_:
+ case TOK.hexadecimalString:
case TOK.file:
case TOK.fileFullPath:
case TOK.line:
else if (StorageClass modStc = stc & STC.TYPECTOR)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, modStc);
+ AST.stcToBuffer(buf, modStc);
error(loc, "static constructor cannot be `%s`", buf.peekChars());
}
stc &= ~(STC.static_ | STC.TYPECTOR);
else if (StorageClass modStc = stc & STC.TYPECTOR)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, modStc);
+ AST.stcToBuffer(buf, modStc);
error(loc, "static destructor cannot be `%s`", buf.peekChars());
}
stc &= ~(STC.static_ | STC.TYPECTOR);
else if (StorageClass modStc = stc & STC.TYPECTOR)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, modStc);
+ AST.stcToBuffer(buf, modStc);
error(loc, "shared static constructor cannot be `%s`", buf.peekChars());
}
stc &= ~(STC.static_ | STC.TYPECTOR);
else if (StorageClass modStc = stc & STC.TYPECTOR)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, modStc);
+ AST.stcToBuffer(buf, modStc);
error(loc, "shared static destructor cannot be `%s`", buf.peekChars());
}
stc &= ~(STC.static_ | STC.TYPECTOR);
if (varargsStc & ~VarArgsStc)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, varargsStc & ~VarArgsStc);
+ AST.stcToBuffer(buf, varargsStc & ~VarArgsStc);
error("variadic parameter cannot have attributes `%s`", buf.peekChars());
varargsStc &= VarArgsStc;
}
//error("scope cannot be ref or out");
const tv = peekNext();
+ Loc loc;
if (tpl && token.value == TOK.identifier &&
(tv == TOK.comma || tv == TOK.rightParenthesis || tv == TOK.dotDotDot))
{
Identifier id = Identifier.generateId("__T");
- const loc = token.loc;
+ loc = token.loc;
at = new AST.TypeIdentifier(loc, id);
if (!*tpl)
*tpl = new AST.TemplateParameters();
}
else
{
- at = parseType(&ai);
+ at = parseType(&ai, null, &loc);
}
ae = null;
if (token.value == TOK.assign) // = defaultArg
nextToken();
ae = parseDefaultInitExp();
}
- auto param = new AST.Parameter(storageClass | STC.parameter, at, ai, ae, null);
+ auto param = new AST.Parameter(loc, storageClass | STC.parameter, at, ai, ae, null);
if (udas)
{
auto a = new AST.Dsymbols();
else
{
OutBuffer buf;
- AST.stcToBuffer(&buf, _stc);
+ AST.stcToBuffer(buf, _stc);
error(attributeErrorMessage, buf.peekChars());
}
nextToken();
if (token.value != TOK.rightCurly)
{
/* { */
- error(token.loc, "`}` expected following members in `%s` declaration at %s",
- Token.toChars(tok), loc.toChars());
+ error(token.loc, "`}` expected following members in `%s` declaration",
+ Token.toChars(tok));
+ if (id)
+ eSink.errorSupplemental(loc, "%s `%s` starts here",
+ Token.toChars(tok), id.toChars());
+ else
+ eSink.errorSupplemental(loc, "%s starts here",
+ Token.toChars(tok));
}
nextToken();
}
* Params:
* pident = set to Identifier if there is one, null if not
* ptpl = if !null, then set to TemplateParameterList
+ * pdeclLoc = if !null, then set to location of the declarator
*/
- AST.Type parseType(Identifier* pident = null, AST.TemplateParameters** ptpl = null)
+ AST.Type parseType(Identifier* pident = null, AST.TemplateParameters** ptpl = null, Loc* pdeclLoc = null)
{
/* Take care of the storage class prefixes that
* serve as type attributes:
AST.Type t;
t = parseBasicType();
+ if (pdeclLoc)
+ *pdeclLoc = token.loc;
int alt = 0;
t = parseDeclarator(t, alt, pident, ptpl);
checkCstyleTypeSyntax(typeLoc, t, alt, pident ? *pident : null);
}
else if (t.ty == Tfunction)
{
+ /* @@@DEPRECATED_2.115@@@
+ * change to error, deprecated in 2.105.1 */
if (storage_class & STC.manifest)
- error("function cannot have enum storage class");
+ deprecation("function cannot have enum storage class");
AST.Expression constraint = null;
//printf("%s funcdecl t = %s, storage_class = x%lx\n", loc.toChars(), t.toChars(), storage_class);
if (remStc)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, remStc);
+ AST.stcToBuffer(buf, remStc);
// @@@DEPRECATED_2.103@@@
// Deprecated in 2020-07, can be made an error in 2.103
eSink.deprecation(token.loc, "storage class `%s` has no effect in type aliases", buf.peekChars());
if (save == TOK.function_)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, modStc);
+ AST.stcToBuffer(buf, modStc);
error("function literal cannot be `%s`", buf.peekChars());
}
else
parameterList.parameters = new AST.Parameters();
Identifier id = Identifier.generateId("__T");
AST.Type t = new AST.TypeIdentifier(loc, id);
- parameterList.parameters.push(new AST.Parameter(STC.parameter, t, token.ident, null, null));
+ parameterList.parameters.push(new AST.Parameter(loc, STC.parameter, t, token.ident, null, null));
tpl = new AST.TemplateParameters();
AST.TemplateParameter tp = new AST.TemplateTypeParameter(loc, id, null, null);
{
Identifier ai = null;
AST.Type at;
+ Loc aloc;
StorageClass storageClass = 0;
StorageClass stc = 0;
lastai = token.ident;
ai = token.ident;
at = null; // infer argument type
+ aloc = token.loc;
nextToken();
goto Larg;
}
if (!ai)
noIdentifierForDeclarator(at);
Larg:
- auto p = new AST.Parameter(storageClass, at, ai, null, null);
+ auto p = new AST.Parameter(aloc, storageClass, at, ai, null, null);
parameters.push(p);
if (token.value == TOK.comma)
{
{
Identifier ai = token.ident;
AST.Type at = null; // infer parameter type
+ const aloc = token.loc;
nextToken();
check(TOK.assign);
- param = new AST.Parameter(storageClass, at, ai, null, null);
+ param = new AST.Parameter(aloc, storageClass, at, ai, null, null);
}
else if (isDeclaration(&token, NeedDeclaratorId.must, TOK.assign, null))
{
Identifier ai;
+ const aloc = token.loc;
AST.Type at = parseType(&ai);
check(TOK.assign);
- param = new AST.Parameter(storageClass, at, ai, null, null);
+ param = new AST.Parameter(aloc, storageClass, at, ai, null, null);
}
else if (storageClass != 0)
error("found `%s` while expecting `=` or identifier", n.toChars());
case TOK.true_:
case TOK.false_:
case TOK.string_:
+ case TOK.hexadecimalString:
case TOK.leftParenthesis:
case TOK.cast_:
case TOK.mul:
AST.Expression exp = parseExpression();
/* https://issues.dlang.org/show_bug.cgi?id=15103
* Improve declaration / initialization syntax error message
- * Error: found 'foo' when expecting ';' following statement
+ * Error: found 'foo' when expecting ';' following expression
* becomes Error: found `(` when expecting `;` or `=`, did you mean `Foo foo = 42`?
*/
if (token.value == TOK.identifier && exp.op == EXP.identifier)
* otherwise we fall back on the old path (advancing the token).
*/
if (token.value != TOK.semicolon && peek(&token).value == TOK.semicolon)
- error("found `%s` when expecting `;` following statement", token.toChars());
+ error("found `%s` when expecting `;` following expression", token.toChars());
else
{
if (token.value != TOK.semicolon)
- error("found `%s` when expecting `;` following statement `%s` on line %s", token.toChars(), exp.toChars(), exp.loc.toChars());
+ {
+ error("found `%s` when expecting `;` following expression", token.toChars());
+ eSink.errorSupplemental(exp.loc, "expression: `%s`", exp.toChars());
+ }
nextToken();
}
}
}
case TOK.asm_:
- s = parseAsm();
+ s = parseAsm(false);
break;
case TOK.import_:
* AsmInstruction ;
* AsmInstruction ; AsmInstruction
*
+ * Params:
+ * endOfLine = true if EOL means end of asm statement
* Returns:
* inline assembler block as a Statement
*/
- AST.Statement parseAsm()
+ AST.Statement parseAsm(bool endOfLine)
{
// Parse the asm block into a sequence of AsmStatements,
// each AsmStatement is one instruction.
size_t nestlevel = 0;
while (1)
{
+ if (endOfLine)
+ nextDefineLine();
switch (token.value)
{
case TOK.identifier:
}
break;
+ case TOK.endOfLine:
+ nextDefineLine();
+ goto case;
+
case TOK.semicolon:
if (nestlevel != 0)
error("mismatched number of curly brackets");
if (toklist || label)
{
// Create AsmStatement from list of tokens we've saved
- AST.Statement s = new AST.AsmStatement(token.loc, toklist);
+ AST.AsmStatement as = new AST.AsmStatement(token.loc, toklist);
+ as.caseSensitive = !endOfLine;
+ AST.Statement s = as;
toklist = null;
ptoklist = &toklist;
if (label)
break;
}
nextToken();
+ if (token.value == TOK.endOfLine)
+ nextToken();
auto s = new AST.CompoundAsmStatement(loc, statements, stc);
return s;
}
case TOK.wcharLiteral:
case TOK.dcharLiteral:
case TOK.string_:
+ case TOK.hexadecimalString:
case TOK.file:
case TOK.fileFullPath:
case TOK.line:
}
continue;
- // Valid tokens that follow a declaration
+ // Valid tokens that follow the start of a declaration
case TOK.rightParenthesis:
case TOK.rightBracket:
case TOK.assign:
}
return false;
+ // To recognize the shortened function declaration syntax
+ case TOK.goesTo:
+ /*
+ 1. https://issues.dlang.org/show_bug.cgi?id=24088
+
+ 2. We need to make sure the would-be
+ declarator has an identifier otherwise function literals
+ are handled incorrectly. Some special treatment is required
+ here, it turns out that a lot of code in the compiler relies
+ on this mess (in the parser), i.e. having isDeclarator be more
+ precise the parsing of other things go kaboom, so we do it in a
+ separate case.
+ */
+ if (*haveId)
+ goto case TOK.do_;
+ goto default;
+
case TOK.identifier:
if (t.ident == Id._body)
{
break;
case TOK.string_:
+ case TOK.hexadecimalString:
{
// cat adjacent strings
auto s = token.ustring;
{
const prev = token;
nextToken();
- if (token.value == TOK.string_)
+ if (token.value == TOK.string_ || token.value == TOK.hexadecimalString)
{
if (token.postfix)
{
void usageOfBodyKeyword()
{
- if (compileEnv.obsolete)
+ version (none) // disable obsolete warning
{
eSink.warning(token.loc, "usage of identifer `body` as a keyword is obsolete. Use `do` instead.");
}
import dmd.hdrgen : floatToBuffer;
import dmd.common.outbuffer : OutBuffer;
OutBuffer buf;
- floatToBuffer(e.type, e.value, &buf, false);
+ floatToBuffer(e.type, e.value, buf, false);
printf("Real %s %s\n", buf.peekChars(), e.type ? e.type.toChars() : "");
}
DotVarExp dve = cast(DotVarExp)e;
if (VarDeclaration v = dve.var.isVarDeclaration())
{
- if (sc.intypeof || !sc.func || !sc.func.isSafeBypassingInference())
+ if (!sc.func)
return false;
auto ad = v.isMember2();
if (!ad)
return true;
}
+ // This branch shouldn't be here, but unfortunately calling `ad.determineSize`
+ // breaks code with circular reference errors. Specifically, test23589.d fails
+ if (ad.sizeok != Sizeok.done && !sc.func.isSafeBypassingInference())
+ return false;
+
// needed to set v.overlapped and v.overlapUnsafe
if (ad.sizeok != Sizeok.done)
ad.determineSize(ad.loc);
{
if (v.overlapped)
{
- if (sc.setUnsafe(!printmsg, e.loc,
+ if (sc.func.isSafeBypassingInference() && sc.setUnsafe(!printmsg, e.loc,
"field `%s.%s` cannot access pointers in `@safe` code that overlap other fields", ad, v))
+ {
return true;
+ }
+ else
+ {
+ import dmd.globals : FeatureState;
+ // @@@DEPRECATED_2.116@@@
+ // https://issues.dlang.org/show_bug.cgi?id=20655
+ // Inferring `@system` because of union access breaks code,
+ // so make it a deprecation safety violation as of 2.106
+ // To turn into an error, remove `isSafeBypassingInference` check in the
+ // above if statement and remove the else branch
+ sc.setUnsafePreview(FeatureState.default_, !printmsg, e.loc,
+ "field `%s.%s` cannot access pointers in `@safe` code that overlap other fields", ad, v);
+ }
}
}
// https://issues.dlang.org/show_bug.cgi?id=20417
// Don't run CTFE for the temporary variables inside typeof or __traits(compiles)
vd._init = vd._init.initializerSemantic(sc, vd.type, sc.intypeof == 1 || sc.flags & SCOPE.compile ? INITnointerpret : INITinterpret);
+ lowerStaticAAs(vd, sc);
vd.inuse--;
}
if (vd._init && vd.storage_class & STC.manifest)
}
ale.elements.sort!predicate;
}
+
+/**
+ * Try lower a variable's static Associative Array to a newaa struct.
+ * Params:
+ * vd = Variable to lower
+ * sc = Scope
+ */
+void lowerStaticAAs(VarDeclaration vd, Scope* sc)
+{
+ if (vd.storage_class & STC.manifest)
+ return;
+ if (auto ei = vd._init.isExpInitializer())
+ {
+ scope v = new StaticAAVisitor(sc);
+ v.vd = vd;
+ ei.exp.accept(v);
+ }
+}
+
+/// Visit Associative Array literals and lower them to structs for static initialization
+private extern(C++) final class StaticAAVisitor : SemanticTimeTransitiveVisitor
+{
+ alias visit = SemanticTimeTransitiveVisitor.visit;
+ Scope* sc;
+ VarDeclaration vd;
+
+ this(Scope* sc) scope @safe
+ {
+ this.sc = sc;
+ }
+
+ override void visit(AssocArrayLiteralExp aaExp)
+ {
+ if (!verifyHookExist(aaExp.loc, *sc, Id._aaAsStruct, "initializing static associative arrays", Id.object))
+ return;
+
+ Expression hookFunc = new IdentifierExp(aaExp.loc, Id.empty);
+ hookFunc = new DotIdExp(aaExp.loc, hookFunc, Id.object);
+ hookFunc = new DotIdExp(aaExp.loc, hookFunc, Id._aaAsStruct);
+ auto arguments = new Expressions();
+ arguments.push(aaExp.syntaxCopy());
+ Expression loweredExp = new CallExp(aaExp.loc, hookFunc, arguments);
+
+ sc = sc.startCTFE();
+ loweredExp = loweredExp.expressionSemantic(sc);
+ loweredExp = resolveProperties(sc, loweredExp);
+ sc = sc.endCTFE();
+ loweredExp = loweredExp.ctfeInterpret();
+
+ aaExp.lowering = loweredExp;
+ }
+}
stc |= STC.temp;
}
Type vtype = fparam.type;
- auto v = new VarDeclaration(funcdecl.loc, vtype, id, null);
+ auto v = new VarDeclaration(fparam.loc, vtype, id, null);
//printf("declaring parameter %s of type %s\n", v.toChars(), v.type.toChars());
stc |= STC.parameter;
if (f.parameterList.varargs == VarArg.typesafe && i + 1 == nparams)
funcdecl.buildEnsureRequire();
// Check for errors related to 'nothrow'.
- const blockexit = funcdecl.fbody.blockExit(funcdecl, f.isnothrow);
+ const blockexit = funcdecl.fbody.blockExit(funcdecl, f.isnothrow ? global.errorSink : null);
if (f.isnothrow && blockexit & BE.throw_)
error(funcdecl.loc, "%s `%s` may throw but is marked as `nothrow`", funcdecl.kind(), funcdecl.toPrettyChars());
freq = freq.statementSemantic(sc2);
// @@@DEPRECATED_2.111@@@ - pass `isnothrow` instead of `false` to print a more detailed error msg`
- const blockExit = freq.blockExit(funcdecl, false);
+ const blockExit = freq.blockExit(funcdecl, null);
if (blockExit & BE.throw_)
{
if (isnothrow)
fens = fens.statementSemantic(sc2);
// @@@DEPRECATED_2.111@@@ - pass `isnothrow` instead of `false` to print a more detailed error msg`
- const blockExit = fens.blockExit(funcdecl, false);
+ const blockExit = fens.blockExit(funcdecl, null);
if (blockExit & BE.throw_)
{
if (isnothrow)
s = s.statementSemantic(sc2);
- const blockexit = s.blockExit(funcdecl, isnothrow);
+ const blockexit = s.blockExit(funcdecl, isnothrow ? global.errorSink : null);
if (blockexit & BE.throw_)
{
funcdecl.hasNoEH = false;
f.isnothrow = false;
}
- if (sbody.blockExit(funcdecl, f.isnothrow) == BE.fallthru)
+ if (sbody.blockExit(funcdecl, f.isnothrow ? global.errorSink : null) == BE.fallthru)
sbody = new CompoundStatement(Loc.initial, sbody, s);
else
sbody = new TryFinallyStatement(Loc.initial, sbody, s);
{
// storage_class is apparently not set for dtor & ctor
OutBuffer ob;
- stcToBuffer(&ob,
+ stcToBuffer(ob,
(ngErr ? STC.nogc : 0) |
(puErr ? STC.pure_ : 0) |
(saErr ? STC.system : 0)
import core.stdc.stdarg;
import core.stdc.stdio;
-import dmd.aggregate;
import dmd.arraytypes;
import dmd.astenums;
import dmd.ast_node;
+import dmd.errors;
import dmd.gluelayer;
import dmd.cond;
-import dmd.dclass;
import dmd.declaration;
-import dmd.denum;
-import dmd.dimport;
-import dmd.dscope;
import dmd.dsymbol;
-import dmd.dtemplate;
-import dmd.errors;
import dmd.expression;
import dmd.func;
import dmd.globals;
import dmd.id;
import dmd.identifier;
import dmd.location;
-import dmd.dinterpret;
import dmd.mtype;
import dmd.common.outbuffer;
import dmd.root.rootobject;
import dmd.sapply;
-import dmd.sideeffect;
import dmd.staticassert;
import dmd.tokens;
import dmd.visitor;
-/**
- * Returns:
- * `TypeIdentifier` corresponding to `object.Throwable`
- */
-TypeIdentifier getThrowable()
-{
- auto tid = new TypeIdentifier(Loc.initial, Id.empty);
- tid.addIdent(Id.object);
- tid.addIdent(Id.Throwable);
- return tid;
-}
-
-/**
- * Returns:
- * TypeIdentifier corresponding to `object.Exception`
- */
-TypeIdentifier getException()
-{
- auto tid = new TypeIdentifier(Loc.initial, Id.empty);
- tid.addIdent(Id.object);
- tid.addIdent(Id.Exception);
- return tid;
-}
-
/***********************************************************
* Specification: https://dlang.org/spec/statement.html
*/
{
HdrGenState hgs;
OutBuffer buf;
- .toCBuffer(this, &buf, &hgs);
+ toCBuffer(this, buf, hgs);
buf.writeByte(0);
return buf.extractSlice().ptr;
}
- static if (__VERSION__ < 2092)
- {
- final void error(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.error);
- va_end(ap);
- }
-
- final void warning(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.warning);
- va_end(ap);
- }
-
- final void deprecation(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.deprecation);
- va_end(ap);
- }
- }
- else
- {
- pragma(printf) final void error(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.error);
- va_end(ap);
- }
-
- pragma(printf) final void warning(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.warning);
- va_end(ap);
- }
-
- pragma(printf) final void deprecation(const(char)* format, ...)
- {
- va_list ap;
- va_start(ap, format);
- .verrorReport(loc, format, ap, ErrorKind.deprecation);
- va_end(ap);
- }
- }
-
Statement getRelatedLabeled()
{
return this;
if (v.isDataseg() || (v.storage_class & (STC.manifest | STC.temp) && vd.ident != Id.withSym) || v._init.isVoidInitializer())
continue;
if (vd.ident == Id.withSym)
- error("`switch` skips declaration of `with` temporary at %s", v.loc.toChars());
+ error(loc, "`switch` skips declaration of `with` temporary");
else
- error("`switch` skips declaration of variable `%s` at %s", v.toPrettyChars(), v.loc.toChars());
+ error(loc, "`switch` skips declaration of variable `%s`", v.toPrettyChars());
+ errorSupplemental(v.loc, "declared here");
return true;
}
return false;
else
{
if (label.statement.os)
- error("cannot `goto` in to `%s` block", Token.toChars(label.statement.os.tok));
+ error(loc, "cannot `goto` in to `%s` block", Token.toChars(label.statement.os.tok));
else
- error("cannot `goto` out of `%s` block", Token.toChars(os.tok));
+ error(loc, "cannot `goto` out of `%s` block", Token.toChars(os.tok));
return true;
}
}
if (label.statement.tf != tf)
{
- error("cannot `goto` in or out of `finally` block");
+ error(loc, "cannot `goto` in or out of `finally` block");
return true;
}
if (label.statement.inCtfeBlock && !inCtfeBlock)
{
- error("cannot `goto` into `if (__ctfe)` block");
+ error(loc, "cannot `goto` into `if (__ctfe)` block");
return true;
}
{
if (!stb)
{
- error("cannot `goto` into `try` block");
+ error(loc, "cannot `goto` into `try` block");
return true;
}
if (auto stf = stb.isTryFinallyStatement())
{
// Lifetime ends at end of expression, so no issue with skipping the statement
}
- else if (vd.ident == Id.withSym)
- {
- error("`goto` skips declaration of `with` temporary at %s", vd.loc.toChars());
- return true;
- }
else
{
- error("`goto` skips declaration of variable `%s` at %s", vd.toPrettyChars(), vd.loc.toChars());
+ if (vd.ident == Id.withSym)
+ error(loc, "`goto` skips declaration of `with` temporary");
+ else
+ error(loc, "`goto` skips declaration of variable `%s`", vd.toPrettyChars());
+ errorSupplemental(vd.loc, "declared here");
return true;
}
-
return false;
}
extern (C++) class AsmStatement : Statement
{
Token* tokens;
+ bool caseSensitive; // for register names
extern (D) this(const ref Loc loc, Token* tokens) @safe
{
const char *toChars() const override final;
void error(const char *format, ...);
- void warning(const char *format, ...);
+ void warning(unsigned flag, const char *format, ...);
void deprecation(const char *format, ...);
virtual Statement *getRelatedLabeled() { return this; }
virtual bool hasBreak() const;
{
public:
Token *tokens;
+ bool caseSensitive; // for register names
AsmStatement *syntaxCopy() override;
void accept(Visitor *v) override { v->visit(this); }
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
+import dmd.errorsink;
import dmd.escape;
import dmd.expression;
import dmd.expressionsem;
Identifier id = Identifier.generateId("__o");
Statement handler = new PeelStatement(sexception);
- if (sexception.blockExit(sc.func, false) & BE.fallthru)
+ if (sexception.blockExit(sc.func, null) & BE.fallthru)
{
auto ts = new ThrowStatement(Loc.initial, new IdentifierExp(Loc.initial, id));
ts.internalThrow = true;
{
if (!p.type)
{
- fs.error("cannot infer type for `foreach` variable `%s`, perhaps set it explicitly", p.ident.toChars());
+ error(fs.loc, "cannot infer type for `foreach` variable `%s`, perhaps set it explicitly", p.ident.toChars());
p.type = Type.terror;
result = true;
}
{
assert(oaggr.type);
- fs.error("invalid `%s` aggregate `%s` of type `%s`",
+ error(fs.loc, "invalid `%s` aggregate `%s` of type `%s`",
Token.toChars(fs.op), oaggr.toChars(), oaggr.type.toPrettyChars());
if (auto ad = isAggregate(fs.aggr.type))
if (foundMismatch && dim != foreachParamCount)
{
const(char)* plural = foreachParamCount > 1 ? "s" : "";
- fs.error("cannot infer argument types, expected %llu argument%s, not %llu",
+ error(fs.loc, "cannot infer argument types, expected %llu argument%s, not %llu",
cast(ulong) foreachParamCount, plural, cast(ulong) dim);
}
else
- fs.error("cannot uniquely infer `foreach` argument types");
+ error(fs.loc, "cannot uniquely infer `foreach` argument types");
return setError();
}
{
if (p.storageClass & STC.manifest)
{
- fs.error("cannot declare `enum` loop variables for non-unrolled foreach");
+ error(fs.loc, "cannot declare `enum` loop variables for non-unrolled foreach");
}
if (p.storageClass & STC.alias_)
{
- fs.error("cannot declare `alias` loop variables for non-unrolled foreach");
+ error(fs.loc, "cannot declare `alias` loop variables for non-unrolled foreach");
}
}
void rangeError()
{
- fs.error("cannot infer argument types");
+ error(fs.loc, "cannot infer argument types");
return retError();
}
if (dim < 1 || dim > 2)
{
- fs.error("only one or two arguments for array `foreach`");
+ error(fs.loc, "only one or two arguments for array `foreach`");
return retError();
}
Type tindex = (*fs.parameters)[0].type;
if (!tindex.isintegral())
{
- fs.error("foreach: key cannot be of non-integral type `%s`", tindex.toChars());
+ error(fs.loc, "foreach: key cannot be of non-integral type `%s`", tindex.toChars());
return retError();
}
/* What cases to deprecate implicit conversions for:
(tn.ty != tv.ty && tn.ty.isSomeChar && tv.ty.isSomeChar)) &&
!Type.tsize_t.implicitConvTo(tindex))
{
- fs.deprecation("foreach: loop index implicitly converted from `size_t` to `%s`",
+ deprecation(fs.loc, "foreach: loop index implicitly converted from `size_t` to `%s`",
tindex.toChars());
}
}
{
if (p.storageClass & STC.ref_)
{
- fs.error("`foreach`: value of UTF conversion cannot be `ref`");
+ error(fs.loc, "`foreach`: value of UTF conversion cannot be `ref`");
return retError();
}
if (dim == 2)
p = (*fs.parameters)[0];
if (p.storageClass & STC.ref_)
{
- fs.error("`foreach`: key cannot be `ref`");
+ error(fs.loc, "`foreach`: key cannot be `ref`");
return retError();
}
}
{
if (fs.key.type.constConv(p.type) == MATCH.nomatch)
{
- fs.error("key type mismatch, `%s` to `ref %s`",
+ error(fs.loc, "key type mismatch, `%s` to `ref %s`",
fs.key.type.toChars(), p.type.toChars());
return retError();
}
dimrange.imax = SignExtendedNumber(dimrange.imax.value-1);
if (!IntRange.fromType(fs.key.type).contains(dimrange))
{
- fs.error("index type `%s` cannot cover index range 0..%llu",
+ error(fs.loc, "index type `%s` cannot cover index range 0..%llu",
p.type.toChars(), ta.dim.toInteger());
return retError();
}
Type t = tab.nextOf();
if (t.constConv(p.type) == MATCH.nomatch)
{
- fs.error("argument type mismatch, `%s` to `ref %s`",
+ error(fs.loc, "argument type mismatch, `%s` to `ref %s`",
t.toChars(), p.type.toChars());
return retError();
}
}
case Taarray:
if (fs.op == TOK.foreach_reverse_)
- fs.warning("cannot use `foreach_reverse` with an associative array");
+ warning(fs.loc, "cannot use `foreach_reverse` with an associative array");
if (checkForArgTypes(fs))
return retError();
if (dim < 1 || dim > 2)
{
- fs.error("only one or two arguments for associative array `foreach`");
+ error(fs.loc, "only one or two arguments for associative array `foreach`");
return retError();
}
return retStmt(apply());
}
if (tfront.ty == Tvoid)
{
- fs.error("`%s.front` is `void` and has no value", oaggr.toChars());
+ error(fs.loc, "`%s.front` is `void` and has no value", oaggr.toChars());
return retError();
}
if (exps.length != dim)
{
const(char)* plural = exps.length > 1 ? "s" : "";
- fs.error("cannot infer argument types, expected %llu argument%s, not %llu",
+ error(fs.loc, "cannot infer argument types, expected %llu argument%s, not %llu",
cast(ulong) exps.length, plural, cast(ulong) dim);
return retError();
}
p.type = p.type.addStorageClass(sc).typeSemantic(loc, sc2);
if (!exp.implicitConvTo(p.type))
{
- fs.error("cannot implicilty convert range element of type `%s` to variable `%s` of type `%s`",
+ error(fs.loc, "cannot implicilty convert range element of type `%s` to variable `%s` of type `%s`",
exp.type.toChars(), p.toChars(), p.type.toChars());
return retError();
}
}
case Tdelegate:
if (fs.op == TOK.foreach_reverse_)
- fs.deprecation("cannot use `foreach_reverse` with a delegate");
+ deprecation(fs.loc, "cannot use `foreach_reverse` with a delegate");
return retStmt(apply());
case Terror:
return retError();
default:
- fs.error("`foreach`: `%s` is not an aggregate type", fs.aggr.type.toChars());
+ error(fs.loc, "`foreach`: `%s` is not an aggregate type", fs.aggr.type.toChars());
return retError();
}
}
fs.lwr = fs.lwr.optimize(WANTvalue);
if (!fs.lwr.type)
{
- fs.error("invalid range lower bound `%s`", fs.lwr.toChars());
+ error(fs.loc, "invalid range lower bound `%s`", fs.lwr.toChars());
return setError();
}
fs.upr = fs.upr.optimize(WANTvalue);
if (!fs.upr.type)
{
- fs.error("invalid range upper bound `%s`", fs.upr.toChars());
+ error(fs.loc, "invalid range upper bound `%s`", fs.upr.toChars());
return setError();
}
{
if (fs.key.type.constConv(fs.prm.type) == MATCH.nomatch)
{
- fs.error("argument type mismatch, `%s` to `ref %s`", fs.key.type.toChars(), fs.prm.type.toChars());
+ error(fs.loc, "argument type mismatch, `%s` to `ref %s`", fs.key.type.toChars(), fs.prm.type.toChars());
return setError();
}
}
{
/* Should this be allowed?
*/
- ps.error("`pragma(lib)` not allowed as statement");
+ error(ps.loc, "`pragma(lib)` not allowed as statement");
return setError();
}
else
{
if (!ps.args || ps.args.length != 1)
{
- ps.error("`string` expected for library name");
+ error(ps.loc, "`string` expected for library name");
return setError();
}
else
{
/* Should this be allowed?
*/
- ps.error("`pragma(linkerDirective)` not allowed as statement");
+ error(ps.loc, "`pragma(linkerDirective)` not allowed as statement");
return setError();
}
else if (ps.ident == Id.startaddress)
}
else
{
- ps.error("`pragma(inline)` is not inside a function");
+ error(ps.loc, "`pragma(inline)` is not inside a function");
return setError();
}
}
+ else if (ps.ident == Id.mangle)
+ {
+ auto es = ps._body ? ps._body.isExpStatement() : null;
+ auto de = es ? es.exp.isDeclarationExp() : null;
+ if (!de)
+ {
+ error(ps.loc, "`pragma(mangle)` must be attached to a declaration");
+ return setError();
+ }
+ const se = ps.args && (*ps.args).length == 1 ? semanticString(sc, (*ps.args)[0], "pragma mangle argument") : null;
+ if (!se)
+ {
+ error(ps.loc, "`pragma(mangle)` takes a single argument that must be a string literal");
+ return setError();
+ }
+ const cnt = setMangleOverride(de.declaration, cast(const(char)[])se.peekData());
+ if (cnt != 1)
+ assert(0);
+ }
else if (!global.params.ignoreUnsupportedPragmas)
{
- ps.error("unrecognized `pragma(%s)`", ps.ident.toChars());
+ error(ps.loc, "unrecognized `pragma(%s)`", ps.ident.toChars());
return setError();
}
{
if (ps.ident == Id.msg || ps.ident == Id.startaddress)
{
- ps.error("`pragma(%s)` is missing a terminating `;`", ps.ident.toChars());
+ error(ps.loc, "`pragma(%s)` is missing a terminating `;`", ps.ident.toChars());
return setError();
}
ps._body = ps._body.statementSemantic(sc);
if (!ss.condition.isErrorExp())
{
- ss.error("`%s` must be of integral or string type, it is a `%s`",
+ error(ss.loc, "`%s` must be of integral or string type, it is a `%s`",
ss.condition.toChars(), ss.condition.type.toChars());
conditionError = true;
break;
{
if (!gcs.exp)
{
- gcs.error("no `case` statement following `goto case;`");
+ error(gcs.loc, "no `case` statement following `goto case;`");
sc.pop();
return setError();
}
}
}
}
- gcs.error("`case %s` not found", gcs.exp.toChars());
+ error(gcs.loc, "`case %s` not found", gcs.exp.toChars());
sc.pop();
return setError();
}
continue Lmembers;
}
if (missingMembers == 0)
- ss.error("missing cases for `enum` members in `final switch`:");
+ error(ss.loc, "missing cases for `enum` members in `final switch`:");
if (missingMembers < maxShown)
errorSupplemental(ss.loc, "`%s`", em.toChars());
ss.hasNoDefault = 1;
if (!ss.isFinal && (!ss._body || !ss._body.isErrorStatement()) && !(sc.flags & SCOPE.Cfile))
- ss.error("`switch` statement without a `default`; use `final switch` or add `default: assert(0);` or add `default: break;`");
+ error(ss.loc, "`switch` statement without a `default`; use `final switch` or add `default: assert(0);` or add `default: break;`");
// Generate runtime error if the default is hit
auto a = new Statements();
a.reserve(2);
sc.sw.sdefault = new DefaultStatement(ss.loc, s);
a.push(ss._body);
- if (ss._body.blockExit(sc.func, false) & BE.fallthru)
+ if (ss._body.blockExit(sc.func, null) & BE.fallthru)
a.push(new BreakStatement(Loc.initial, null));
a.push(sc.sw.sdefault);
cs = new CompoundStatement(ss.loc, a);
*/
if (!v.isConst() && !v.isImmutable())
{
- cs.error("`case` variables have to be `const` or `immutable`");
+ error(cs.loc, "`case` variables have to be `const` or `immutable`");
}
if (sw.isFinal)
{
- cs.error("`case` variables not allowed in `final switch` statements");
+ error(cs.loc, "`case` variables not allowed in `final switch` statements");
errors = true;
}
if (!scx.search(cs.exp.loc, v.ident, null))
{
- cs.error("`case` variable `%s` declared at %s cannot be declared in `switch` body",
+ error(cs.loc, "`case` variable `%s` declared at %s cannot be declared in `switch` body",
v.toChars(), v.loc.toChars());
errors = true;
}
cs.exp = se;
else if (!cs.exp.isIntegerExp() && !cs.exp.isErrorExp())
{
- cs.error("`case` expression must be a compile-time `string` or an integral constant, not `%s`", cs.exp.toChars());
+ error(cs.loc, "`case` expression must be a compile-time `string` or an integral constant, not `%s`", cs.exp.toChars());
errors = true;
}
if (cs2.exp.equals(cs.exp))
{
// https://issues.dlang.org/show_bug.cgi?id=15909
- cs.error("duplicate `case %s` in `switch` statement", initialExp.toChars());
+ error(cs.loc, "duplicate `case %s` in `switch` statement", initialExp.toChars());
errors = true;
break;
}
if (sc.sw.tf != sc.tf)
{
- cs.error("`switch` and `case` are in different `finally` blocks");
+ error(cs.loc, "`switch` and `case` are in different `finally` blocks");
errors = true;
}
if (sc.sw.tryBody != sc.tryBody)
{
- cs.error("case cannot be in different `try` block level from `switch`");
+ error(cs.loc, "case cannot be in different `try` block level from `switch`");
errors = true;
}
}
else
{
- cs.error("`case` not in `switch` statement");
+ error(cs.loc, "`case` not in `switch` statement");
errors = true;
}
SwitchStatement sw = sc.sw;
if (sw is null)
{
- crs.error("case range not in `switch` statement");
+ error(crs.loc, "case range not in `switch` statement");
return setError();
}
bool errors = false;
if (sw.isFinal)
{
- crs.error("case ranges not allowed in `final switch`");
+ error(crs.loc, "case ranges not allowed in `final switch`");
errors = true;
}
uinteger_t lval = crs.last.toInteger();
if ((crs.first.type.isunsigned() && fval > lval) || (!crs.first.type.isunsigned() && cast(sinteger_t)fval > cast(sinteger_t)lval))
{
- crs.error("first `case %s` is greater than last `case %s`", crs.first.toChars(), crs.last.toChars());
+ error(crs.loc, "first `case %s` is greater than last `case %s`", crs.first.toChars(), crs.last.toChars());
errors = true;
lval = fval;
}
if (lval - fval > 256)
{
- crs.error("had %llu cases which is more than 257 cases in case range", 1 + lval - fval);
+ error(crs.loc, "had %llu cases which is more than 257 cases in case range", 1 + lval - fval);
errors = true;
lval = fval + 256;
}
{
if (sc.sw.sdefault)
{
- ds.error("`switch` statement already has a default");
+ error(ds.loc, "`switch` statement already has a default");
errors = true;
}
sc.sw.sdefault = ds;
if (sc.sw.tf != sc.tf)
{
- ds.error("`switch` and `default` are in different `finally` blocks");
+ error(ds.loc, "`switch` and `default` are in different `finally` blocks");
errors = true;
}
if (sc.sw.tryBody != sc.tryBody)
{
- ds.error("default cannot be in different `try` block level from `switch`");
+ error(ds.loc, "default cannot be in different `try` block level from `switch`");
errors = true;
}
if (sc.sw.isFinal)
{
- ds.error("`default` statement not allowed in `final switch` statement");
+ error(ds.loc, "`default` statement not allowed in `final switch` statement");
errors = true;
}
}
else
{
- ds.error("`default` not in `switch` statement");
+ error(ds.loc, "`default` not in `switch` statement");
errors = true;
}
gds.sw = sc.sw;
if (!gds.sw)
{
- gds.error("`goto default` not in `switch` statement");
+ error(gds.loc, "`goto default` not in `switch` statement");
return setError();
}
if (gds.sw.isFinal)
{
- gds.error("`goto default` not allowed in `final switch` statement");
+ error(gds.loc, "`goto default` not allowed in `final switch` statement");
return setError();
}
result = gds;
if (!sc.sw)
{
- gcs.error("`goto case` not in `switch` statement");
+ error(gcs.loc, "`goto case` not in `switch` statement");
return setError();
}
bool errors = false;
if (sc.flags & SCOPE.contract)
{
- rs.error("`return` statements cannot be in contracts");
+ error(rs.loc, "`return` statements cannot be in contracts");
errors = true;
}
if (sc.os)
// Deprecated in 2.100, transform into an error in 2.112
if (sc.os.tok == TOK.onScopeFailure)
{
- rs.deprecation("`return` statements cannot be in `scope(failure)` bodies.");
+ deprecation(rs.loc, "`return` statements cannot be in `scope(failure)` bodies.");
deprecationSupplemental(rs.loc, "Use try-catch blocks for this purpose");
}
else
{
- rs.error("`return` statements cannot be in `%s` bodies", Token.toChars(sc.os.tok));
+ error(rs.loc, "`return` statements cannot be in `%s` bodies", Token.toChars(sc.os.tok));
errors = true;
}
}
if (sc.tf)
{
- rs.error("`return` statements cannot be in `finally` bodies");
+ error(rs.loc, "`return` statements cannot be in `finally` bodies");
errors = true;
}
{
if (rs.exp)
{
- rs.error("cannot return expression from constructor");
+ error(rs.loc, "cannot return expression from constructor");
errors = true;
}
{
if (!convToVoid)
{
- rs.error("cannot return non-void from `void` function");
+ error(rs.loc, "cannot return non-void from `void` function");
errors = true;
rs.exp = new CastExp(rs.loc, rs.exp, Type.tvoid);
rs.exp = rs.exp.expressionSemantic(sc);
}
else if (!rs.exp.isErrorExp())
{
- rs.error("expected return type of `%s`, not `%s`:",
+ error(rs.loc, "expected return type of `%s`, not `%s`:",
tret.toChars(),
rs.exp.type.toChars());
errorSupplemental((fd.returns) ? (*fd.returns)[0].loc : fd.loc,
{
/* May return by ref
*/
- if (checkReturnEscapeRef(sc, rs.exp, true))
+ Scope* sc2 = sc.push();
+ sc2.eSink = global.errorSinkNull;
+ bool err = checkReturnEscapeRef(sc2, rs.exp, true);
+ sc2.pop();
+
+ if (err)
turnOffRef(() { checkReturnEscapeRef(sc, rs.exp, false); });
else if (!rs.exp.type.constConv(tf.next))
turnOffRef(
{
if (tf.next.ty != Terror)
{
- rs.error("mismatched function return type inference of `void` and `%s`", tf.next.toChars());
+ error(rs.loc, "mismatched function return type inference of `void` and `%s`", tf.next.toChars());
}
errors = true;
tf.next = Type.terror;
if (tbret.ty != Terror)
{
if (e0)
- rs.error("expected return type of `%s`, not `%s`", tret.toChars(), resType.toChars());
+ error(rs.loc, "expected return type of `%s`, not `%s`", tret.toChars(), resType.toChars());
else if (tbret.isTypeNoreturn())
{
- rs.error("cannot return from `noreturn` function");
+ error(rs.loc, "cannot return from `noreturn` function");
.errorSupplemental(rs.loc,
"Consider adding an endless loop, `assert(0)`, or another `noreturn` expression");
}
else
- rs.error("`return` expression expected");
+ error(rs.loc, "`return` expression expected");
}
errors = true;
}
// If any branches have called a ctor, but this branch hasn't, it's an error
if (sc.ctorflow.callSuper & CSX.any_ctor && !(sc.ctorflow.callSuper & (CSX.this_ctor | CSX.super_ctor)))
{
- rs.error("`return` without calling constructor");
+ error(rs.loc, "`return` without calling constructor");
errors = true;
}
bool mustInit = (v.storage_class & STC.nodefaultctor || v.type.needsNested());
if (mustInit && !(sc.ctorflow.fieldinit[i].csx & CSX.this_ctor))
{
- rs.error("an earlier `return` statement skips field `%s` initialization", v.toChars());
+ error(rs.loc, "an earlier `return` statement skips field `%s` initialization", v.toChars());
errors = true;
}
}
{
Statement s = ls.statement;
if (!s || !s.hasBreak())
- bs.error("label `%s` has no `break`", bs.ident.toChars());
+ error(bs.loc, "label `%s` has no `break`", bs.ident.toChars());
else if (ls.tf != sc.tf)
- bs.error("cannot break out of `finally` block");
+ error(bs.loc, "cannot break out of `finally` block");
else
{
ls.breaks = true;
return setError();
}
}
- bs.error("enclosing label `%s` for `break` not found", bs.ident.toChars());
+ error(bs.loc, "enclosing label `%s` for `break` not found", bs.ident.toChars());
return setError();
}
else if (!sc.sbreak)
{
if (sc.os && sc.os.tok != TOK.onScopeFailure)
{
- bs.error("`break` is not allowed inside `%s` bodies", Token.toChars(sc.os.tok));
+ error(bs.loc, "`break` is not allowed inside `%s` bodies", Token.toChars(sc.os.tok));
}
else if (sc.fes)
{
return;
}
else
- bs.error("`break` is not inside a loop or `switch`");
+ error(bs.loc, "`break` is not inside a loop or `switch`");
return setError();
}
else if (sc.sbreak.isForwardingStatement())
{
- bs.error("must use labeled `break` within `static foreach`");
+ error(bs.loc, "must use labeled `break` within `static foreach`");
}
result = bs;
}
{
Statement s = ls.statement;
if (!s || !s.hasContinue())
- cs.error("label `%s` has no `continue`", cs.ident.toChars());
+ error(cs.loc, "label `%s` has no `continue`", cs.ident.toChars());
else if (ls.tf != sc.tf)
- cs.error("cannot continue out of `finally` block");
+ error(cs.loc, "cannot continue out of `finally` block");
else
{
result = cs;
return setError();
}
}
- cs.error("enclosing label `%s` for `continue` not found", cs.ident.toChars());
+ error(cs.loc, "enclosing label `%s` for `continue` not found", cs.ident.toChars());
return setError();
}
else if (!sc.scontinue)
{
if (sc.os && sc.os.tok != TOK.onScopeFailure)
{
- cs.error("`continue` is not allowed inside `%s` bodies", Token.toChars(sc.os.tok));
+ error(cs.loc, "`continue` is not allowed inside `%s` bodies", Token.toChars(sc.os.tok));
}
else if (sc.fes)
{
return;
}
else
- cs.error("`continue` is not inside a loop");
+ error(cs.loc, "`continue` is not inside a loop");
return setError();
}
else if (sc.scontinue.isForwardingStatement())
{
- cs.error("must use labeled `continue` within `static foreach`");
+ error(cs.loc, "must use labeled `continue` within `static foreach`");
}
result = cs;
}
ClassDeclaration cd = ss.exp.type.isClassHandle();
if (!cd)
{
- ss.error("can only `synchronize` on class objects, not `%s`", ss.exp.type.toChars());
+ error(ss.loc, "can only `synchronize` on class objects, not `%s`", ss.exp.type.toChars());
return setError();
}
else if (cd.isInterfaceDeclaration())
*/
if (!ClassDeclaration.object)
{
- ss.error("missing or corrupt object.d");
+ error(ss.loc, "missing or corrupt object.d");
fatal();
}
cs.push(new ExpStatement(ss.loc, tmp));
auto args = new Parameters();
- args.push(new Parameter(0, ClassDeclaration.object.type, null, null, null));
+ args.push(new Parameter(Loc.initial, 0, ClassDeclaration.object.type, null, null, null));
FuncDeclaration fdenter = FuncDeclaration.genCfunc(args, Type.tvoid, Id.monitorenter);
Expression e = new CallExp(ss.loc, fdenter, new VarExp(ss.loc, tmp));
cs.push(new ExpStatement(ss.loc, v));
auto enterArgs = new Parameters();
- enterArgs.push(new Parameter(0, t.pointerTo(), null, null, null));
+ enterArgs.push(new Parameter(Loc.initial, 0, t.pointerTo(), null, null, null));
FuncDeclaration fdenter = FuncDeclaration.genCfunc(enterArgs, Type.tvoid, Id.criticalenter, STC.nothrow_);
Expression e = new AddrExp(ss.loc, tmpExp);
cs.push(new ExpStatement(ss.loc, e));
auto exitArgs = new Parameters();
- exitArgs.push(new Parameter(0, t, null, null, null));
+ exitArgs.push(new Parameter(Loc.initial, 0, t, null, null, null));
FuncDeclaration fdexit = FuncDeclaration.genCfunc(exitArgs, Type.tvoid, Id.criticalexit, STC.nothrow_);
e = new CallExp(ss.loc, fdexit, tmpExp);
Dsymbol s = (cast(TypeExp)ws.exp).type.toDsymbol(sc);
if (!s || !s.isScopeDsymbol())
{
- ws.error("`with` type `%s` has no members", ws.exp.toChars());
+ error(ws.loc, "`with` type `%s` has no members", ws.exp.toChars());
return setError();
}
sym = new WithScopeSymbol(ws);
}
else
{
- ws.error("`with` expression types must be enums or aggregates or pointers to them, not `%s`", olde.type.toChars());
+ error(ws.loc, "`with` expression types must be enums or aggregates or pointers to them, not `%s`", olde.type.toChars());
return setError();
}
}
if (!global.params.useExceptions)
{
- tcs.error("cannot use try-catch statements with -betterC");
+ error(tcs.loc, "cannot use try-catch statements with %s", global.params.betterC ? "-betterC".ptr : "-nothrow".ptr);
return setError();
}
if (!ClassDeclaration.throwable)
{
- tcs.error("cannot use try-catch statements because `object.Throwable` was not declared");
+ error(tcs.loc, "cannot use try-catch statements because `object.Throwable` was not declared");
return setError();
}
const sj = cj.loc.toChars();
if (c.type.toBasetype().implicitConvTo(cj.type.toBasetype()))
{
- tcs.error("`catch` at %s hides `catch` at %s", sj, si);
+ error(tcs.loc, "`catch` at %s hides `catch` at %s", sj, si);
catchErrors = true;
}
}
sc.func.hasCatches = true;
if (flags == (FLAGcpp | FLAGd))
{
- tcs.error("cannot mix catching D and C++ exceptions in the same try-catch");
+ error(tcs.loc, "cannot mix catching D and C++ exceptions in the same try-catch");
catchErrors = true;
}
}
/* If the try body never throws, we can eliminate any catches
* of recoverable exceptions.
*/
- if (!(tcs._body.blockExit(sc.func, false) & BE.throw_) && ClassDeclaration.exception)
+ if (!(tcs._body.blockExit(sc.func, null) & BE.throw_) && ClassDeclaration.exception)
{
foreach_reverse (i; 0 .. tcs.catches.length)
{
return;
}
- auto blockexit = tfs._body.blockExit(sc.func, false);
+ auto blockexit = tfs._body.blockExit(sc.func, null);
// if not worrying about exceptions
if (!(global.params.useExceptions && ClassDeclaration.throwable))
// https://issues.dlang.org/show_bug.cgi?id=23159
if (!global.params.useExceptions)
{
- oss.error("`%s` cannot be used with -betterC", Token.toChars(oss.tok));
+ error(oss.loc, "`%s` cannot be used with -betterC", Token.toChars(oss.tok));
return setError();
}
if (sc.os && sc.os.tok != TOK.onScopeFailure)
{
// If enclosing is scope(success) or scope(exit), this will be placed in finally block.
- oss.error("cannot put `%s` statement inside `%s`", Token.toChars(oss.tok), Token.toChars(sc.os.tok));
+ error(oss.loc, "cannot put `%s` statement inside `%s`", Token.toChars(oss.tok), Token.toChars(sc.os.tok));
return setError();
}
if (sc.tf)
{
- oss.error("cannot put `%s` statement inside `finally` block", Token.toChars(oss.tok));
+ error(oss.loc, "cannot put `%s` statement inside `finally` block", Token.toChars(oss.tok));
return setError();
}
}
if (ls.loc == ls2.loc)
{
ls2.duplicated = true;
- ls.error("label `%s` is duplicated", ls2.toChars());
+ error(ls.loc, "label `%s` is duplicated", ls2.toChars());
.errorSupplemental(ls2.loc, "labels cannot be used in a static foreach with more than 1 iteration");
}
else
{
- ls.error("label `%s` is already defined", ls2.toChars());
+ error(ls.loc, "label `%s` is already defined", ls2.toChars());
.errorSupplemental(ls2.loc, "first definition is here");
}
return setError();
assert(sc.func);
if (!(cas.stc & STC.pure_) && sc.func.setImpure(cas.loc, "`asm` statement is assumed to be impure - mark it with `pure` if it is not"))
- cas.error("`asm` statement is assumed to be impure - mark it with `pure` if it is not");
+ error(cas.loc, "`asm` statement is assumed to be impure - mark it with `pure` if it is not");
if (!(cas.stc & STC.nogc) && sc.func.setGC(cas.loc, "`asm` statement in %s `%s` is assumed to use the GC - mark it with `@nogc` if it does not"))
- cas.error("`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not");
+ error(cas.loc, "`asm` statement is assumed to use the GC - mark it with `@nogc` if it does not");
// @@@DEPRECATED_2.114@@@
// change deprecation() to error(), add `else` and remove `| STC.safe`
// to turn deprecation into an error when deprecation cycle is over
if (cas.stc & STC.safe)
- cas.deprecation("`asm` statement cannot be marked `@safe`, use `@system` or `@trusted` instead");
+ deprecation(cas.loc, "`asm` statement cannot be marked `@safe`, use `@system` or `@trusted` instead");
if (!(cas.stc & (STC.trusted | STC.safe)))
{
sc.setUnsafe(false, cas.loc, "`asm` statement is assumed to be `@system` - mark it with `@trusted` if it is not");
{
if (!global.params.useExceptions)
{
- loc.error("cannot use `throw` statements with -betterC");
+ loc.error("cannot use `throw` statements with %s", global.params.betterC ? "-betterC".ptr : "-nothrow".ptr);
return false;
}
return null;
if (ec.type != Type.tint32)
{
- fs.error("`opApply()` function for `%s` must return an `int`", tab.toChars());
+ error(fs.loc, "`opApply()` function for `%s` must return an `int`", tab.toChars());
return null;
}
return ec;
return null;
if (ec.type != Type.tint32)
{
- fs.error("`opApply()` function for `%s` must return an `int`", tab.toChars());
+ error(fs.loc, "`opApply()` function for `%s` must return an `int`", tab.toChars());
return null;
}
return ec;
FuncDeclaration fdapply;
TypeDelegate dgty;
auto params = new Parameters();
- params.push(new Parameter(STC.in_, tn.arrayOf(), null, null, null));
+ params.push(new Parameter(Loc.initial, STC.in_, tn.arrayOf(), null, null, null));
auto dgparams = new Parameters();
- dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));
+ dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null));
if (dim == 2)
- dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));
+ dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null));
dgty = new TypeDelegate(new TypeFunction(ParameterList(dgparams), Type.tint32, LINK.d));
- params.push(new Parameter(0, dgty, null, null, null));
+ params.push(new Parameter(Loc.initial, 0, dgty, null, null, null));
fdapply = FuncDeclaration.genCfunc(params, Type.tint32, fdname.ptr);
if (tab.isTypeSArray())
Type ti = (isRef ? taa.index.addMod(MODFlags.const_) : taa.index);
if (isRef ? !ti.constConv(ta) : !ti.implicitConvTo(ta))
{
- fs.error("`foreach`: index must be type `%s`, not `%s`",
+ error(fs.loc, "`foreach`: index must be type `%s`, not `%s`",
ti.toChars(), ta.toChars());
return null;
}
Type taav = taa.nextOf();
if (isRef ? !taav.constConv(ta) : !taav.implicitConvTo(ta))
{
- fs.error("`foreach`: value must be type `%s`, not `%s`",
+ error(fs.loc, "`foreach`: value must be type `%s`, not `%s`",
taav.toChars(), ta.toChars());
return null;
}
if (!fdapply[i])
{
auto params = new Parameters();
- params.push(new Parameter(0, Type.tvoid.pointerTo(), null, null, null));
- params.push(new Parameter(STC.const_, Type.tsize_t, null, null, null));
+ params.push(new Parameter(Loc.initial, 0, Type.tvoid.pointerTo(), null, null, null));
+ params.push(new Parameter(Loc.initial, STC.const_, Type.tsize_t, null, null, null));
auto dgparams = new Parameters();
- dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));
+ dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null));
if (dim == 2)
- dgparams.push(new Parameter(0, Type.tvoidptr, null, null, null));
+ dgparams.push(new Parameter(Loc.initial, 0, Type.tvoidptr, null, null, null));
fldeTy[i] = new TypeDelegate(new TypeFunction(ParameterList(dgparams), Type.tint32, LINK.d));
- params.push(new Parameter(0, fldeTy[i], null, null, null));
+ params.push(new Parameter(Loc.initial, 0, fldeTy[i], null, null, null));
fdapply[i] = FuncDeclaration.genCfunc(params, Type.tint32, i ? Id._aaApply2 : Id._aaApply);
}
{
if (!(prm.storageClass & STC.ref_))
{
- fs.error("`foreach`: cannot make `%s` `ref`", p.ident.toChars());
+ error(fs.loc, "`foreach`: cannot make `%s` `ref`", p.ident.toChars());
return null;
}
goto LcopyArg;
Statement s = new ExpStatement(fs.loc, v);
fs._body = new CompoundStatement(fs.loc, s, fs._body);
}
- params.push(new Parameter(stc, p.type, id, null, null));
+ params.push(new Parameter(fs.loc, stc, p.type, id, null, null));
}
// https://issues.dlang.org/show_bug.cgi?id=13840
// Throwable nested function inside nothrow function is acceptable.
const bool skipCheck = isStatic && needExpansion;
if (!skipCheck && (dim < 1 || dim > 2))
{
- fs.error("only one (value) or two (key,value) arguments allowed for sequence `foreach`");
+ error(fs.loc, "only one (value) or two (key,value) arguments allowed for sequence `foreach`");
return returnEarly();
}
// Declare key
if (p.isReference() || p.isLazy())
{
- fs.error("no storage class for key `%s`", p.ident.toChars());
+ error(fs.loc, "no storage class for key `%s`", p.ident.toChars());
return returnEarly();
}
if (!p.type.isintegral())
{
- fs.error("foreach: key cannot be of non-integral type `%s`",
+ error(fs.loc, "foreach: key cannot be of non-integral type `%s`",
p.type.toChars());
return returnEarly();
}
dimrange.imax = SignExtendedNumber(dimrange.imax.value-1);
if (!IntRange.fromType(p.type).contains(dimrange))
{
- fs.error("index type `%s` cannot cover index range 0..%llu",
+ error(fs.loc, "index type `%s` cannot cover index range 0..%llu",
p.type.toChars(), cast(ulong)length);
return returnEarly();
}
if (storageClass & (STC.out_ | STC.lazy_) ||
storageClass & STC.ref_ && !te)
{
- fs.error("no storage class for value `%s`", ident.toChars());
+ error(fs.loc, "no storage class for value `%s`", ident.toChars());
return false;
}
Declaration var;
}
else if (storageClass & STC.alias_)
{
- fs.error("`foreach` loop variable cannot be both `enum` and `alias`");
+ error(fs.loc, "`foreach` loop variable cannot be both `enum` and `alias`");
return false;
}
var = new AliasDeclaration(loc, ident, ds);
if (storageClass & STC.ref_)
{
- fs.error("symbol `%s` cannot be `ref`", ds.toChars());
+ error(fs.loc, "symbol `%s` cannot be `ref`", ds.toChars());
return false;
}
if (paramtype)
{
- fs.error("cannot specify element type for symbol `%s`", ds.toChars());
+ error(fs.loc, "cannot specify element type for symbol `%s`", ds.toChars());
return false;
}
}
var = new AliasDeclaration(loc, ident, e.type);
if (paramtype)
{
- fs.error("cannot specify element type for type `%s`", e.type.toChars());
+ error(fs.loc, "cannot specify element type for type `%s`", e.type.toChars());
return false;
}
}
{
if (!isStatic)
{
- fs.error("constant value `%s` cannot be `ref`", ie.toChars());
+ error(fs.loc, "constant value `%s` cannot be `ref`", ie.toChars());
}
else
{
if (!needExpansion)
{
- fs.error("constant value `%s` cannot be `ref`", ie.toChars());
+ error(fs.loc, "constant value `%s` cannot be `ref`", ie.toChars());
}
else
{
- fs.error("constant value `%s` cannot be `ref`", ident.toChars());
+ error(fs.loc, "constant value `%s` cannot be `ref`", ident.toChars());
}
}
return false;
var = new AliasDeclaration(loc, ident, t);
if (paramtype)
{
- fs.error("cannot specify element type for symbol `%s`", fs.toChars());
+ error(fs.loc, "cannot specify element type for symbol `%s`", fs.toChars());
return false;
}
}
// Leaf operators
identifier,
string_,
+ hexadecimalString,
this_,
super_,
error,
TOK.wcharLiteral: "wcharv",
TOK.dcharLiteral: "dcharv",
TOK.wchar_tLiteral: "wchar_tv",
+ TOK.hexadecimalString: "xstring",
TOK.endOfLine: "\\n",
TOK.whitespace: "whitespace",
nothrow:
- int isKeyword() const @safe
+ int isKeyword() pure const @safe @nogc
{
foreach (kw; keywords)
{
p = buf.extractChars();
}
break;
+ case TOK.hexadecimalString:
+ {
+ OutBuffer buf;
+ buf.writeByte('x');
+ buf.writeByte('"');
+ foreach (size_t i; 0 .. len)
+ {
+ if (i)
+ buf.writeByte(' ');
+ buf.printf("%02x", ustring[i]);
+ }
+ buf.writeByte('"');
+ if (postfix)
+ buf.writeByte(postfix);
+ buf.writeByte(0);
+ p = buf.extractData();
+ break;
+ }
case TOK.identifier:
case TOK.enum_:
case TOK.struct_:
// Leaf operators
identifier,
string_,
+ hexadecimalString,
this_,
super_,
error,
StringExp se = ex ? ex.ctfeInterpret().toStringExp() : null;
if (!ex || !se || se.len == 0)
{
- e.error("string expected as argument of __traits `%s` instead of `%s`", e.ident.toChars(), ex.toChars());
+ e.error("string expected as argument of __traits `%s` instead of `%s`", e.ident.toChars(), (*e.args)[0].toChars());
return ErrorExp.get();
}
se = se.toUTF8(sc);
StorageClass stc2 = narg.storageClass & (STC.ref_ | STC.out_ | STC.lazy_);
if (stc1 && stc2 && stc1 != stc2)
{
- OutBuffer buf1; stcToBuffer(&buf1, stc1 | ((stc1 & STC.ref_) ? (fparam.storageClass & STC.auto_) : 0));
- OutBuffer buf2; stcToBuffer(&buf2, stc2);
+ OutBuffer buf1; stcToBuffer(buf1, stc1 | ((stc1 & STC.ref_) ? (fparam.storageClass & STC.auto_) : 0));
+ OutBuffer buf2; stcToBuffer(buf2, stc2);
.error(loc, "incompatible parameter storage classes `%s` and `%s`",
buf1.peekChars(), buf2.peekChars());
stc = stc1 | (stc & ~(STC.ref_ | STC.out_ | STC.lazy_));
}
(*newparams)[j] = new Parameter(
- stc, narg.type, narg.ident, narg.defaultArg, narg.userAttribDecl);
+ loc, stc, narg.type, narg.ident, narg.defaultArg, narg.userAttribDecl);
}
fparam.type = new TypeTuple(newparams);
fparam.type = fparam.type.typeSemantic(loc, argsc);
{
e = new StringExp(loc, mt.deco.toDString());
Scope sc;
+ sc.eSink = global.errorSink;
e = e.expressionSemantic(&sc);
}
}
const s = mt.toChars();
e = new StringExp(loc, s.toDString());
Scope sc;
+ sc.eSink = global.errorSink;
e = e.expressionSemantic(&sc);
}
else if (flag && mt != Type.terror)
error(loc, "no property `%s` for `%s` of type `%s`", ident.toChars(), src.toChars(), mt.toPrettyChars(true));
else
error(loc, "no property `%s` for type `%s`", ident.toChars(), mt.toPrettyChars(true));
+
if (auto dsym = mt.toDsymbol(scope_))
+ {
if (auto sym = dsym.isAggregateDeclaration())
{
if (auto fd = search_function(sym, Id.opDispatch))
else if (!sym.members)
errorSupplemental(sym.loc, "`%s %s` is opaque and has no members.", sym.kind, mt.toPrettyChars(true));
}
+ errorSupplemental(dsym.loc, "%s `%s` defined here",
+ dsym.kind, dsym.toChars());
+ }
}
}
e = ErrorExp.get();
if (fd_aaLen is null)
{
auto fparams = new Parameters();
- fparams.push(new Parameter(STC.const_ | STC.scope_, mt, null, null, null));
+ fparams.push(new Parameter(Loc.initial, STC.const_ | STC.scope_, mt, null, null, null));
fd_aaLen = FuncDeclaration.genCfunc(fparams, Type.tsize_t, Id.aaLen);
TypeFunction tf = fd_aaLen.type.toTypeFunction();
tf.purity = PURE.const_;
e.error("no property `%s` for type `%s`", ident.toChars(),
mt.toChars());
+ errorSupplemental(mt.sym.loc, "%s `%s` defined here",
+ mt.sym.kind, mt.toChars());
return ErrorExp.get();
}
return res;
{
Type t = stripDefaultArgs(p.type);
return (t != p.type || p.defaultArg || p.ident || p.userAttribDecl)
- ? new Parameter(p.storageClass, t, null, null, null)
+ ? new Parameter(p.loc, p.storageClass, t, null, null, null)
: null;
}
* loc = The line number information from where the call originates
* filename = Path to file
*/
-Buffer readFile(Loc loc, const(char)* filename)
-{
- return readFile(loc, filename.toDString());
-}
-
-/// Ditto
Buffer readFile(Loc loc, const(char)[] filename)
{
auto result = File.read(filename);
* loc = The line number information from where the call originates
* filename = Path to file
* data = Full content of the file to be written
+ * Returns:
+ * false on error
*/
-extern (D) void writeFile(Loc loc, const(char)[] filename, const void[] data)
+extern (D) bool writeFile(Loc loc, const(char)[] filename, const void[] data)
{
- ensurePathToNameExists(Loc.initial, filename);
+ if (!ensurePathToNameExists(Loc.initial, filename))
+ return false;
if (!File.update(filename, data))
{
error(loc, "error writing file '%.*s'", cast(int) filename.length, filename.ptr);
- fatal();
+ return false;
}
+ return true;
}
* Params:
* loc = The line number information from where the call originates
* name = a path to check (the name is stripped)
+ * Returns:
+ * false on error
*/
-void ensurePathToNameExists(Loc loc, const(char)[] name)
+bool ensurePathToNameExists(Loc loc, const(char)[] name)
{
const char[] pt = FileName.path(name);
if (pt.length)
if (!FileName.ensurePathExists(pt))
{
error(loc, "cannot create directory %*.s", cast(int) pt.length, pt.ptr);
- fatal();
+ FileName.free(pt.ptr);
+ return false;
}
}
FileName.free(pt.ptr);
+ return true;
}
void visit (AssocArrayLiteralExp *e) final override
{
+ if (e->lowering != NULL)
+ {
+ /* When an associative array literal gets lowered, it's converted into a
+ struct literal suitable for static initialization. */
+ gcc_assert (this->constp_);
+ this->result_ = build_expr (e->lowering, this->constp_, true);
+ return ;
+ }
+
/* Want the mutable type for typeinfo reference. */
Type *tb = e->type->toBasetype ()->mutableOf ();
ddocfiles(ddocfiles)
{}
};
+
+struct Loc final
+{
+ static int32_t showColumns;
+ void toChars(int32_t showColumns = Loc::showColumns);
+ Loc()
+ {
+ }
+};
---
*/
bool obj = true;
Array ddocfiles;
}
+
+extern (C++) struct Loc
+{
+ __gshared int showColumns;
+ void toChars(int showColumns = Loc.showColumns) {}
+}
int32_t get(int32_t , int32_t );
static int32_t get();
static const int32_t staticVar;
- void useVars(int32_t pi = i, int32_t psv = staticVar);
+ void useVars(int32_t pi = i, int32_t psv = S::staticVar);
struct Nested final
{
- void useStaticVar(int32_t i = staticVar);
+ void useStaticVar(int32_t i = S::staticVar);
Nested()
{
}
--- /dev/null
+module issue22682;
+
+void main()
+{
+ pragma(mangle, "put" ~ "s")
+ extern(C) static int libcPuts(const char*);
+ libcPuts("issue 22682");
+}
--- /dev/null
+/* REQUIRED_ARGS: -w
+*/
+
+void test()
+in { } body { }
static assert(test() == "hello"); // works normally
static assert(is(typeof(&test) == string function())); // same normal type
+struct S(T) {}
+
void func() {
int a;
int nested() => a; // and at nested scopes too
+
+ // Issue 24088 - https://issues.dlang.org/show_bug.cgi?id=24088
+ S!int f() => S!int();
}
-/* REQUIRED_ARGS: -wo -wi
-TEST_OUTPUT:
----
-compilable/test23145.d(117): Warning: `scope` allocation of `c` requires that constructor be annotated with `scope`
-compilable/test23145.d(111): is the location of the constructor
-compilable/test23145.d(124): Warning: `scope` allocation of `c` requires that constructor be annotated with `scope`
-compilable/test23145.d(111): is the location of the constructor
----
+/* REQUIRED_ARGS: -wi
*/
// https://issues.dlang.org/show_bug.cgi?id=23145
C foo(D d) @nogc @safe
{
scope e = new C(1); // ok
- scope c = new C(d); // deprecation
+ scope c = new C(d); // obsolete
return c.d.c;
}
C bax(D d) @safe
{
scope e = new C(1); // ok
- scope c = new C(d); // deprecation
+ scope c = new C(d); // obsolete
return c.d.c;
}
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=24066
+
+/*
+TEST_OUTPUT:
+---
+false
+---
+*/
+
+class C;
+pragma(msg, __traits(isAbstractClass, C));
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=24107
+
+/*
+TEST_OUTPUT:
+---
+This should not output an error message: false
+---
+*/
+
+bool recurse ()
+{
+ return recurse();
+}
+
+pragma(msg,
+ "This should not output an error message: ",
+ __traits(compiles, {enum bool r = recurse();}));
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=24109
+
+struct Outer
+{
+ void method1() {}
+
+ void method2()
+ {
+ class Inner
+ {
+ void innerMethod()
+ {
+ method1();
+ }
+ }
+ }
+}
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=24118
+
+void map(alias fun, T)(T[] arr)
+{
+ fun(arr);
+}
+
+
+void foo()
+{
+ if( __ctfe )
+ {
+ ["a", "b", "c"].map!( a => " " ~ a[0] );
+ }
+}
--- /dev/null
+/*
+REQUIRED_ARGS: -vcolumns
+TEST_OUTPUT:
+---
+fail_compilation/aa_init.d(13,18): Error: invalid associative array initializer `[]`, use `null` instead
+fail_compilation/aa_init.d(14,24): Error: missing key for value `4` in initializer
+fail_compilation/aa_init.d(15,9): Error: cannot implicitly convert expression `[]` of type `void[]` to `int[int]`
+---
+*/
+
+void main()
+{
+ int[int] a = [];
+ int[int] b = [2:3, 4];
+ a = [];
+}
+++ /dev/null
-/* REQUIRED_ARGS: -wo -w
-TEST_OUTPUT:
----
-fail_compilation/body.d(11): Warning: usage of identifer `body` as a keyword is obsolete. Use `do` instead.
-Error: warnings are treated as errors
- Use -wi if you wish to treat warnings only as informational.
----
-*/
-
-void test()
-in { } body { }
fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system|32=
fail_compilation/chkformat.d(122): Deprecation: argument `0LU` for format specification `"%lu"` must be `uint`, not `ulong`
fail_compilation/chkformat.d(122): C `long` is 4 bytes on your system$
+fail_compilation/chkformat.d(123): Deprecation: argument `p` for format specification `"%n"` must be `int*`, not `const(int)*`
fail_compilation/chkformat.d(201): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
fail_compilation/chkformat.d(202): Deprecation: more format specifiers than 1 arguments
fail_compilation/chkformat.d(203): Deprecation: argument `0L` for format specification `"%d"` must be `int*`, not `long`
//void test20() { int u; char[] s; sprintf(&s[0], "%d\n", &u); }
//void test21() { int u; fprintf(null, "%d\n", &u); }
void test20() { printf("%lu", ulong.init); }
+void test22() { int i; const(int)* p = &i; printf("%n", p); }
#line 200
+++ /dev/null
-// REQUIRED_ARGS: -de
-/*
-TEST_OUTPUT:
----
-fail_compilation/dephexstrings.d(9): Error: semicolon expected following auto declaration, not `"60"`
-fail_compilation/dephexstrings.d(9): Error: declaration expected, not `"60"`
----
-*/
-enum xstr = x"60";
EXTRA_FILES: imports/a10169.d
TEST_OUTPUT:
---
-fail_compilation/diag10169.d(12): Error: no property `x` for `B(0)` of type `imports.a10169.B`
+fail_compilation/diag10169.d(13): Error: no property `x` for `B(0)` of type `imports.a10169.B`
+fail_compilation/imports/a10169.d(3): struct `B` defined here
---
*/
import imports.a10169;
/*
TEST_OUTPUT:
---
-fail_compilation/diag10783.d(14): Error: no property `type` for `event` of type `diag10783.Event`
-fail_compilation/diag10783.d(14): Error: undefined identifier `En`
+fail_compilation/diag10783.d(15): Error: no property `type` for `event` of type `diag10783.Event`
+fail_compilation/diag10783.d(10): struct `Event` defined here
+fail_compilation/diag10783.d(15): Error: undefined identifier `En`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/diag12063.d(11): Error: no property `max` for type `Foo`, perhaps `import std.algorithm;` is needed?
-fail_compilation/diag12063.d(14): Error: incompatible types for `(Foo()) + (1)`: `Bar` and `int`
+fail_compilation/diag12063.d(19): Error: cannot check `diag12063.Bar.b` value for overflow
+fail_compilation/diag12063.d(16): Error: no property `max` for type `Foo`, perhaps `import std.algorithm;` is needed?
+fail_compilation/diag12063.d(19): Error: cannot generate value for `diag12063.Bar.b`
+fail_compilation/diag12063.d(19): Error: incompatible types for `(Foo()) + (1)`: `Bar` and `int`
+fail_compilation/diag12063.d(29): Error: cannot check `diag12063.b` value for overflow
+fail_compilation/diag12063.d(29): Error: incompatible types for `(S()) == (1)`: `S` and `int`
+fail_compilation/diag12063.d(38): Error: enum member `diag12063.d` initialization with `__anonymous.c+1` causes overflow for type `Q`
---
*/
enum Bar : Foo
{
a = Foo(),
- b
+ b // no max, can't +1
+}
+
+struct S {
+ S opBinary(string s: "+")(int) => this;
+ enum max = 1; // wrong type
+}
+
+enum {
+ a = S(),
+ b // can't do S() == 1
+}
+
+struct Q {
+ enum max = Q();
+}
+
+enum {
+ c = Q(),
+ d // overflow detected
+}
+
+struct R {
+ int i;
+ R opBinary(string s: "+")(int) => this;
+ enum max = R(1);
+}
+
+enum ER
+{
+ e = R(),
+ f // OK
}
/*
TEST_OUTPUT:
---
-fail_compilation/diag12829.d(12): Error: function `diag12829.test1` is `@nogc` yet allocates closure for `test1()` with the GC
-fail_compilation/diag12829.d(15): `diag12829.test1.__lambda2` closes over variable `x` at fail_compilation/diag12829.d(14)
-fail_compilation/diag12829.d(19): `diag12829.test1.bar` closes over variable `x` at fail_compilation/diag12829.d(14)
-fail_compilation/diag12829.d(26): Error: function `diag12829.test2` is `@nogc` yet allocates closure for `test2()` with the GC
-fail_compilation/diag12829.d(31): `diag12829.test2.S.foo` closes over variable `x` at fail_compilation/diag12829.d(28)
+fail_compilation/diag12829.d(15): Error: function `diag12829.test1` is `@nogc` yet allocates closure for `test1()` with the GC
+fail_compilation/diag12829.d(18): delegate `diag12829.test1.__lambda2` closes over variable `x`
+fail_compilation/diag12829.d(17): `x` declared here
+fail_compilation/diag12829.d(22): function `diag12829.test1.bar` closes over variable `x`
+fail_compilation/diag12829.d(17): `x` declared here
+fail_compilation/diag12829.d(29): Error: function `diag12829.test2` is `@nogc` yet allocates closure for `test2()` with the GC
+fail_compilation/diag12829.d(34): function `diag12829.test2.S.foo` closes over variable `x`
+fail_compilation/diag12829.d(31): `x` declared here
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/diag13609a.d(11): Error: `}` expected following members in `class` declaration at fail_compilation/diag13609a.d(8)
+fail_compilation/diag13609a.d(16): Error: `}` expected following members in `struct` declaration
+fail_compilation/diag13609a.d(15): struct starts here
+fail_compilation/diag13609a.d(16): Error: `}` expected following members in `class` declaration
+fail_compilation/diag13609a.d(11): class `C` starts here
---
*/
class C
{
void foo() {}
+
+ struct {
/*
TEST_OUTPUT:
---
-fail_compilation/diag14145.d(15): Error: no property `i` for `_` of type `diag14145.main.Capture!(i)`
-fail_compilation/diag14145.d(15): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
-fail_compilation/diag14145.d(34): Error: expression `*this.ptr` of type `shared(int)` is not implicitly convertible to return type `ref int`
-fail_compilation/diag14145.d(16): Error: template instance `diag14145.main.Capture!(i).Capture.opDispatch!"i"` error instantiating
+fail_compilation/diag14145.d(16): Error: no property `i` for `_` of type `diag14145.main.Capture!(i)`
+fail_compilation/diag14145.d(16): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/diag14145.d(26): struct `Capture` defined here
+fail_compilation/diag14145.d(35): Error: expression `*this.ptr` of type `shared(int)` is not implicitly convertible to return type `ref int`
+fail_compilation/diag14145.d(17): Error: template instance `diag14145.main.Capture!(i).Capture.opDispatch!"i"` error instantiating
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/diag15713.d(19): Error: no property `widthSign` for `this` of type `diag15713.WrData.Data`
-fail_compilation/diag15713.d(39): Error: template instance `diag15713.conwritefImpl!("parse-int", "width", "\n", Data(null))` error instantiating
-fail_compilation/diag15713.d(44): instantiated from here: `conwritefImpl!("main", "\n", Data(null))`
-fail_compilation/diag15713.d(49): instantiated from here: `fdwritef!()`
+fail_compilation/diag15713.d(20): Error: no property `widthSign` for `this` of type `diag15713.WrData.Data`
+fail_compilation/diag15713.d(16): struct `Data` defined here
+fail_compilation/diag15713.d(40): Error: template instance `diag15713.conwritefImpl!("parse-int", "width", "\n", Data(null))` error instantiating
+fail_compilation/diag15713.d(45): instantiated from here: `conwritefImpl!("main", "\n", Data(null))`
+fail_compilation/diag15713.d(50): instantiated from here: `fdwritef!()`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/diag3913.d(12): Error: no property `foobardoo` for type `Foo`
-fail_compilation/diag3913.d(13): Error: no property `secon` for type `Foo`. Did you mean `Foo.second` ?
+fail_compilation/diag3913.d(14): Error: no property `foobardoo` for type `Foo`
+fail_compilation/diag3913.d(13): enum `Foo` defined here
+fail_compilation/diag3913.d(15): Error: no property `secon` for type `Foo`. Did you mean `Foo.second` ?
+fail_compilation/diag3913.d(13): enum `Foo` defined here
---
*/
EXTRA_FILES: imports/fail5385.d
TEST_OUTPUT:
---
-fail_compilation/diag5385.d(20): Error: no property `privX` for type `imports.fail5385.C`
-fail_compilation/diag5385.d(21): Error: no property `packX` for type `imports.fail5385.C`
-fail_compilation/diag5385.d(22): Error: no property `privX2` for type `imports.fail5385.C`
-fail_compilation/diag5385.d(23): Error: no property `packX2` for type `imports.fail5385.C`
-fail_compilation/diag5385.d(24): Error: no property `privX` for type `imports.fail5385.S`
-fail_compilation/diag5385.d(25): Error: no property `packX` for type `imports.fail5385.S`
-fail_compilation/diag5385.d(26): Error: no property `privX2` for type `imports.fail5385.S`
-fail_compilation/diag5385.d(27): Error: no property `packX2` for type `imports.fail5385.S`
+fail_compilation/diag5385.d(28): Error: no property `privX` for type `imports.fail5385.C`
+fail_compilation/imports/fail5385.d(3): class `C` defined here
+fail_compilation/diag5385.d(29): Error: no property `packX` for type `imports.fail5385.C`
+fail_compilation/imports/fail5385.d(3): class `C` defined here
+fail_compilation/diag5385.d(30): Error: no property `privX2` for type `imports.fail5385.C`
+fail_compilation/imports/fail5385.d(3): class `C` defined here
+fail_compilation/diag5385.d(31): Error: no property `packX2` for type `imports.fail5385.C`
+fail_compilation/imports/fail5385.d(3): class `C` defined here
+fail_compilation/diag5385.d(32): Error: no property `privX` for type `imports.fail5385.S`
+fail_compilation/imports/fail5385.d(11): struct `S` defined here
+fail_compilation/diag5385.d(33): Error: no property `packX` for type `imports.fail5385.S`
+fail_compilation/imports/fail5385.d(11): struct `S` defined here
+fail_compilation/diag5385.d(34): Error: no property `privX2` for type `imports.fail5385.S`
+fail_compilation/imports/fail5385.d(11): struct `S` defined here
+fail_compilation/diag5385.d(35): Error: no property `packX2` for type `imports.fail5385.S`
+fail_compilation/imports/fail5385.d(11): struct `S` defined here
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/diag7477.d(13): Error: integral constant must be scalar type, not `Foo`
-fail_compilation/diag7477.d(20): Error: integral constant must be scalar type, not `string`
+fail_compilation/diag7477.d(13): Error: cannot generate 0 value of type `Foo` for `a`
+fail_compilation/diag7477.d(20): Error: cannot generate 0 value of type `string` for `a`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/diag8697.d(10): Error: no property `Invalid` for type `diag8697.Base`
+fail_compilation/diag8697.d(11): Error: no property `Invalid` for type `diag8697.Base`
+fail_compilation/diag8697.d(9): class `Base` defined here
---
*/
interface InterBase : InterRoot { }
/*
TEST_OUTPUT:
---
-fail_compilation/diag8894.d(16): Error: no property `x` for `f` of type `diag8894.Foo`
-fail_compilation/diag8894.d(17): Error: no property `y` for `f` of type `diag8894.Foo`
-fail_compilation/diag8894.d(18): Error: no property `x` for `f` of type `diag8894.Foo`
-fail_compilation/diag8894.d(19): Error: no property `x` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(20): Error: no property `x` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(15): struct `Foo` defined here
+fail_compilation/diag8894.d(21): Error: no property `y` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(15): struct `Foo` defined here
+fail_compilation/diag8894.d(22): Error: no property `x` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(15): struct `Foo` defined here
+fail_compilation/diag8894.d(23): Error: no property `x` for `f` of type `diag8894.Foo`
+fail_compilation/diag8894.d(15): struct `Foo` defined here
---
*/
/*
-REQUIRED_ARGS: -de -wo
+REQUIRED_ARGS: -de
TEST_OUTPUT:
---
-fail_compilation/dip1000_deprecation.d(20): Deprecation: `@safe` function `main` calling `inferred`
-fail_compilation/dip1000_deprecation.d(28): which wouldn't be `@safe` because of:
-fail_compilation/dip1000_deprecation.d(28): scope variable `x0` may not be returned
-fail_compilation/dip1000_deprecation.d(22): Deprecation: `@safe` function `main` calling `inferredC`
-fail_compilation/dip1000_deprecation.d(39): which calls `dip1000_deprecation.inferred`
-fail_compilation/dip1000_deprecation.d(28): which wouldn't be `@safe` because of:
-fail_compilation/dip1000_deprecation.d(28): scope variable `x0` may not be returned
-fail_compilation/dip1000_deprecation.d(54): Warning: escaping reference to stack allocated value returned by `S(null)`
-fail_compilation/dip1000_deprecation.d(55): Warning: escaping reference to stack allocated value returned by `createS()`
-fail_compilation/dip1000_deprecation.d(58): Warning: returning `s.incorrectReturnRef()` escapes a reference to local variable `s`
+fail_compilation/dip1000_deprecation.d(17): Deprecation: `@safe` function `main` calling `inferred`
+fail_compilation/dip1000_deprecation.d(25): which wouldn't be `@safe` because of:
+fail_compilation/dip1000_deprecation.d(25): scope variable `x0` may not be returned
+fail_compilation/dip1000_deprecation.d(19): Deprecation: `@safe` function `main` calling `inferredC`
+fail_compilation/dip1000_deprecation.d(36): which calls `dip1000_deprecation.inferred`
+fail_compilation/dip1000_deprecation.d(25): which wouldn't be `@safe` because of:
+fail_compilation/dip1000_deprecation.d(25): scope variable `x0` may not be returned
---
*/
EXTRA_FILES: imports/dip22a.d
TEST_OUTPUT:
---
-fail_compilation/dip22a.d(16): Error: no property `bar` for `new Klass` of type `imports.dip22a.Klass`
-fail_compilation/dip22a.d(17): Error: no property `bar` for `Struct()` of type `imports.dip22a.Struct`
-fail_compilation/dip22a.d(18): Error: undefined identifier `bar` in module `imports.dip22a`
-fail_compilation/dip22a.d(19): Error: no property `bar` for `Template!int` of type `void`
-fail_compilation/dip22a.d(20): Error: no property `bar` for `12` of type `int`
+fail_compilation/dip22a.d(18): Error: no property `bar` for `new Klass` of type `imports.dip22a.Klass`
+fail_compilation/imports/dip22a.d(3): class `Klass` defined here
+fail_compilation/dip22a.d(19): Error: no property `bar` for `Struct()` of type `imports.dip22a.Struct`
+fail_compilation/imports/dip22a.d(8): struct `Struct` defined here
+fail_compilation/dip22a.d(20): Error: undefined identifier `bar` in module `imports.dip22a`
+fail_compilation/dip22a.d(21): Error: no property `bar` for `Template!int` of type `void`
+fail_compilation/dip22a.d(22): Error: no property `bar` for `12` of type `int`
---
*/
import imports.dip22a;
/*
+REQUIRED_ARGS: -de
TEST_OUTPUT:
---
-fail_compilation/enum_function.d(10): Error: function cannot have enum storage class
-fail_compilation/enum_function.d(11): Error: function cannot have enum storage class
-fail_compilation/enum_function.d(12): Error: function cannot have enum storage class
-fail_compilation/enum_function.d(13): Error: function cannot have enum storage class
+fail_compilation/enum_function.d(11): Deprecation: function cannot have enum storage class
+fail_compilation/enum_function.d(12): Deprecation: function cannot have enum storage class
+fail_compilation/enum_function.d(13): Deprecation: function cannot have enum storage class
+fail_compilation/enum_function.d(14): Deprecation: function cannot have enum storage class
---
*/
enum void f1() { return; }
EXTRA_FILES: imports/a10528.d
TEST_OUTPUT:
---
-fail_compilation/fail10528.d(20): Error: undefined identifier `a`
-fail_compilation/fail10528.d(21): Error: undefined identifier `a` in module `a10528`
-fail_compilation/fail10528.d(23): Error: undefined identifier `b`
-fail_compilation/fail10528.d(24): Error: undefined identifier `b` in module `a10528`
-fail_compilation/fail10528.d(26): Error: no property `c` for type `a10528.S`
-fail_compilation/fail10528.d(27): Error: no property `c` for type `a10528.S`
-fail_compilation/fail10528.d(29): Error: no property `d` for type `a10528.C`
-fail_compilation/fail10528.d(30): Error: no property `d` for type `a10528.C`
+fail_compilation/fail10528.d(24): Error: undefined identifier `a`
+fail_compilation/fail10528.d(25): Error: undefined identifier `a` in module `a10528`
+fail_compilation/fail10528.d(27): Error: undefined identifier `b`
+fail_compilation/fail10528.d(28): Error: undefined identifier `b` in module `a10528`
+fail_compilation/fail10528.d(30): Error: no property `c` for type `a10528.S`
+fail_compilation/imports/a10528.d(4): struct `S` defined here
+fail_compilation/fail10528.d(31): Error: no property `c` for type `a10528.S`
+fail_compilation/imports/a10528.d(4): struct `S` defined here
+fail_compilation/fail10528.d(33): Error: no property `d` for type `a10528.C`
+fail_compilation/imports/a10528.d(5): class `C` defined here
+fail_compilation/fail10528.d(34): Error: no property `d` for type `a10528.C`
+fail_compilation/imports/a10528.d(5): class `C` defined here
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail10534.d(28): Error: `a` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(28): Error: `b` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(29): Error: `a` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(29): Error: `b` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(30): Error: `a` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(30): Error: `b` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(31): Error: `a` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(31): Error: `b` is not of arithmetic type, it is a `int delegate()`
-fail_compilation/fail10534.d(36): Error: `a` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(36): Error: `b` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(37): Error: `a` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(37): Error: `b` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(38): Error: `a` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(38): Error: `b` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(39): Error: `a` is not of arithmetic type, it is a `int function()`
-fail_compilation/fail10534.d(39): Error: `b` is not of arithmetic type, it is a `int function()`
+fail_compilation/fail10534.d(28): Error: illegal operator `+` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(28): Error: illegal operator `+` for `b` of type `int delegate()`
+fail_compilation/fail10534.d(29): Error: illegal operator `-` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(29): Error: illegal operator `-` for `b` of type `int delegate()`
+fail_compilation/fail10534.d(30): Error: illegal operator `/` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(30): Error: illegal operator `/` for `b` of type `int delegate()`
+fail_compilation/fail10534.d(31): Error: illegal operator `*` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(31): Error: illegal operator `*` for `b` of type `int delegate()`
+fail_compilation/fail10534.d(36): Error: illegal operator `+` for `a` of type `int function()`
+fail_compilation/fail10534.d(36): Error: illegal operator `+` for `b` of type `int function()`
+fail_compilation/fail10534.d(37): Error: illegal operator `-` for `a` of type `int function()`
+fail_compilation/fail10534.d(37): Error: illegal operator `-` for `b` of type `int function()`
+fail_compilation/fail10534.d(38): Error: illegal operator `/` for `a` of type `int function()`
+fail_compilation/fail10534.d(38): Error: illegal operator `/` for `b` of type `int function()`
+fail_compilation/fail10534.d(39): Error: illegal operator `*` for `a` of type `int function()`
+fail_compilation/fail10534.d(39): Error: illegal operator `*` for `b` of type `int function()`
---
*/
/* https://issues.dlang.org/show_bug.cgi?id=14950
TEST_OUTPUT:
---
+fail_compilation/fail109.d(50): Error: cannot check `fail109.B.end` value for overflow
fail_compilation/fail109.d(50): Error: comparison between different enumeration types `B` and `C`; If this behavior is intended consider using `std.conv.asOriginalType`
fail_compilation/fail109.d(50): Error: enum member `fail109.B.end` initialization with `B.start+1` causes overflow for type `C`
---
start,
end
}
-
enum B
{
start = C.end,
/*
TEST_OUTPUT:
---
-fail_compilation/fail121.d(23): Error: no property `typeinfo` for `list[1]` of type `fail121.myobject`
-fail_compilation/fail121.d(23): Error: no property `typeinfo` for `i` of type `int`
+fail_compilation/fail121.d(24): Error: no property `typeinfo` for `list[1]` of type `fail121.myobject`
+fail_compilation/fail121.d(12): struct `myobject` defined here
+fail_compilation/fail121.d(24): Error: no property `typeinfo` for `i` of type `int`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail136.d(10): Error: found `"EF BB BF"` when expecting `;` following statement
+fail_compilation\fail136.d(10): Error: `"\xef\xbb\xbf"` has no effect
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail17570.d(11): Error: cannot use function constraints for non-template functions. Use `static if` instead
-fail_compilation/fail17570.d(11): Error: declaration expected, not `if`
-fail_compilation/fail17570.d(14): Error: `}` expected following members in `struct` declaration at fail_compilation/fail17570.d(10)
+fail_compilation/fail17570.d(12): Error: cannot use function constraints for non-template functions. Use `static if` instead
+fail_compilation/fail17570.d(12): Error: declaration expected, not `if`
+fail_compilation/fail17570.d(15): Error: `}` expected following members in `struct` declaration
+fail_compilation/fail17570.d(11): struct `S` starts here
---
*/
/* TEST_OUTPUT:
---
-fail_compilation/fail17969.d(9): Error: no property `sum` for type `fail17969.__lambda6!(int[]).__lambda6.MapResult2!((b) => b)`
+fail_compilation/fail17969.d(10): Error: no property `sum` for type `fail17969.__lambda6!(int[]).__lambda6.MapResult2!((b) => b)`
+fail_compilation/fail17969.d(16): struct `MapResult2` defined here
---
* https://issues.dlang.org/show_bug.cgi?id=17969
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail18219.d(16): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
-fail_compilation/fail18219.d(17): Error: no property `Bar` for type `a18219.AST`
-fail_compilation/fail18219.d(18): Error: no property `fun` for type `AST`, did you mean `b18219.fun`?
-fail_compilation/fail18219.d(19): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
+fail_compilation/fail18219.d(17): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
+fail_compilation/fail18219.d(18): Error: no property `Bar` for type `a18219.AST`
+fail_compilation/imports/a18219.d(3): struct `AST` defined here
+fail_compilation/fail18219.d(19): Error: no property `fun` for type `AST`, did you mean `b18219.fun`?
+fail_compilation/fail18219.d(20): Error: no property `Foobar` for type `AST`, did you mean `b18219.Foobar`?
---
*/
import imports.a18219;
/*
TEST_OUTPUT:
---
-fail_compilation/fail18892.d(20): Error: no property `foo` for `a` of type `fail18892.MT`
-fail_compilation/fail18892.d(21): Error: no property `foo` for `MT` of type `fail18892.MT`
+fail_compilation/fail18892.d(22): Error: no property `foo` for `a` of type `fail18892.MT`
+fail_compilation/fail18892.d(13): struct `MT` defined here
+fail_compilation/fail18892.d(23): Error: no property `foo` for `MT` of type `fail18892.MT`
+fail_compilation/fail18892.d(13): struct `MT` defined here
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail18970.d(24): Error: no property `y` for `S()` of type `fail18970.S`
-fail_compilation/fail18970.d(24): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
-fail_compilation/fail18970.d(31): Error: no property `yyy` for `this` of type `fail18970.S2`
-fail_compilation/fail18970.d(31): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/fail18970.d(26): Error: no property `y` for `S()` of type `fail18970.S`
+fail_compilation/fail18970.d(26): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/fail18970.d(15): struct `S` defined here
+fail_compilation/fail18970.d(33): Error: no property `yyy` for `this` of type `fail18970.S2`
+fail_compilation/fail18970.d(33): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/fail18970.d(29): struct `S2` defined here
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail18979.d(13): Error: no property `__ctor` for `Foo()` of type `imports.imp18979.Foo`
+fail_compilation/fail18979.d(14): Error: no property `__ctor` for `Foo()` of type `imports.imp18979.Foo`
+fail_compilation/imports/imp18979.d(3): struct `Foo` defined here
----
*/
TEST_OUTPUT:
---
fail_compilation/fail1900.d(27): Error: template `fail1900.Mix1a!().Foo` matches more than one template declaration:
-fail_compilation/fail1900.d(14): `Foo(ubyte x)`
-and
-fail_compilation/fail1900.d(15): `Foo(byte x)`
+fail_compilation/fail1900.d(14): `Foo(ubyte x)`
+and:
+fail_compilation/fail1900.d(15): `Foo(byte x)`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail19076.d(11): Error: no property `V` for type `fail19076.I`
-fail_compilation/fail19076.d(11): Error: `(I).V` cannot be resolved
+fail_compilation/fail19076.d(12): Error: no property `V` for type `fail19076.I`
+fail_compilation/fail19076.d(11): interface `I` defined here
+fail_compilation/fail19076.d(12): Error: `(I).V` cannot be resolved
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail19103.d(12): Error: no property `puts` for `new C` of type `fail19103.C`
-fail_compilation/fail19103.d(14): Error: no property `puts` for `s1` of type `fail19103.S1`
-fail_compilation/fail19103.d(16): Error: no property `puts` for type `S2`, did you mean `core.stdc.stdio.puts`?
+fail_compilation/fail19103.d(14): Error: no property `puts` for `new C` of type `fail19103.C`
+fail_compilation/fail19103.d(26): class `C` defined here
+fail_compilation/fail19103.d(16): Error: no property `puts` for `s1` of type `fail19103.S1`
+fail_compilation/fail19103.d(30): struct `S1` defined here
+fail_compilation/fail19103.d(18): Error: no property `puts` for type `S2`, did you mean `core.stdc.stdio.puts`?
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail196.d(29): Error: delimited string must end in `)"`
-fail_compilation/fail196.d(29): Error: implicit string concatenation is error-prone and disallowed in D
-fail_compilation/fail196.d(29): Use the explicit syntax instead (concatenating literals is `@nogc`): "foo(xxx)" ~ ";\n assert(s == "
-fail_compilation/fail196.d(30): Error: semicolon needed to end declaration of `s`, instead of `foo`
-fail_compilation/fail196.d(29): `s` declared here
-fail_compilation/fail196.d(30): Error: found `");\n\n s = q"` when expecting `;` following statement `foo(xxx)` on line fail_compilation/fail196.d(30)
-fail_compilation/fail196.d(32): Error: found `";\n assert(s == "` when expecting `;` following statement `[foo[xxx]]` on line fail_compilation/fail196.d(32)
-fail_compilation/fail196.d(33): Error: found `");\n\n s = q"` when expecting `;` following statement `foo[xxx]` on line fail_compilation/fail196.d(33)
-fail_compilation/fail196.d(35): Error: found `{` when expecting `;` following statement `foo` on line fail_compilation/fail196.d(35)
-fail_compilation/fail196.d(35): Error: found `}` when expecting `;` following statement `xxx` on line fail_compilation/fail196.d(35)
-fail_compilation/fail196.d(36): Error: found `foo` when expecting `;` following statement `";\n assert(s == "` on line fail_compilation/fail196.d(35)
-fail_compilation/fail196.d(36): Error: found `}` when expecting `;` following statement `xxx` on line fail_compilation/fail196.d(36)
-fail_compilation/fail196.d(38): Error: found `<` when expecting `;` following statement `");\n\n s = q" < foo` on line fail_compilation/fail196.d(36)
-fail_compilation/fail196.d(39): Error: found `foo` when expecting `;` following statement `xxx >> ";\n assert(s == "` on line fail_compilation/fail196.d(38)
-fail_compilation/fail196.d(39): Error: found `<` instead of statement
-fail_compilation/fail196.d(45): Error: unterminated string constant starting at fail_compilation/fail196.d(45)
-fail_compilation/fail196.d(47): Error: matching `}` expected following compound statement, not `End of File`
-fail_compilation/fail196.d(36): unmatched `{`
-fail_compilation/fail196.d(47): Error: matching `}` expected following compound statement, not `End of File`
-fail_compilation/fail196.d(28): unmatched `{`
+fail_compilation/fail196.d(38): Error: delimited string must end in `)"`
+fail_compilation/fail196.d(38): Error: implicit string concatenation is error-prone and disallowed in D
+fail_compilation/fail196.d(38): Use the explicit syntax instead (concatenating literals is `@nogc`): "foo(xxx)" ~ ";\n assert(s == "
+fail_compilation/fail196.d(39): Error: semicolon needed to end declaration of `s`, instead of `foo`
+fail_compilation/fail196.d(38): `s` declared here
+fail_compilation/fail196.d(39): Error: found `");\n\n s = q"` when expecting `;` following expression
+fail_compilation/fail196.d(39): expression: `foo(xxx)`
+fail_compilation/fail196.d(41): Error: found `";\n assert(s == "` when expecting `;` following expression
+fail_compilation/fail196.d(41): expression: `[foo[xxx]]`
+fail_compilation/fail196.d(42): Error: found `");\n\n s = q"` when expecting `;` following expression
+fail_compilation/fail196.d(42): expression: `foo[xxx]`
+fail_compilation/fail196.d(44): Error: found `{` when expecting `;` following expression
+fail_compilation/fail196.d(44): expression: `foo`
+fail_compilation/fail196.d(44): Error: found `}` when expecting `;` following expression
+fail_compilation/fail196.d(44): expression: `xxx`
+fail_compilation/fail196.d(45): Error: found `foo` when expecting `;` following expression
+fail_compilation/fail196.d(44): expression: `";\n assert(s == "`
+fail_compilation/fail196.d(45): Error: found `}` when expecting `;` following expression
+fail_compilation/fail196.d(45): expression: `xxx`
+fail_compilation/fail196.d(47): Error: found `<` when expecting `;` following expression
+fail_compilation/fail196.d(45): expression: `");\n\n s = q" < foo`
+fail_compilation/fail196.d(48): Error: found `foo` when expecting `;` following expression
+fail_compilation/fail196.d(47): expression: `xxx >> ";\n assert(s == "`
+fail_compilation/fail196.d(48): Error: found `<` instead of statement
+fail_compilation/fail196.d(54): Error: unterminated string constant starting at fail_compilation/fail196.d(54)
+fail_compilation/fail196.d(56): Error: matching `}` expected following compound statement, not `End of File`
+fail_compilation/fail196.d(45): unmatched `{`
+fail_compilation/fail196.d(56): Error: matching `}` expected following compound statement, not `End of File`
+fail_compilation/fail196.d(37): unmatched `{`
---
*/
EXTRA_FILES: imports/fail20637b.d
TEST_OUTPUT:
---
-fail_compilation/fail20637.d(12): Error: no property `foo` for type `imports.fail20637b.A`
+fail_compilation/fail20637.d(13): Error: no property `foo` for type `imports.fail20637b.A`
+fail_compilation/imports/fail20637b.d(3): class `A` defined here
---
*/
module fail20637;
/*
TEST_OUTPUT:
---
-fail_compilation/fail22054.d(21): Error: no property `what` for type `fail22054.exception`
-fail_compilation/fail22054.d(16): `class fail22054.exception` is opaque and has no members.
-fail_compilation/fail22054.d(22): Error: no property `what` for type `fail22054.exception2`
-fail_compilation/fail22054.d(17): `struct fail22054.exception2` is opaque and has no members.
+fail_compilation/fail22054.d(23): Error: no property `what` for type `fail22054.exception`
+fail_compilation/fail22054.d(18): `class fail22054.exception` is opaque and has no members.
+fail_compilation/fail22054.d(18): class `exception` defined here
+fail_compilation/fail22054.d(24): Error: no property `what` for type `fail22054.exception2`
+fail_compilation/fail22054.d(19): `struct fail22054.exception2` is opaque and has no members.
+fail_compilation/fail22054.d(19): struct `exception2` defined here
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail22529.d(13): Error: found `return` when expecting `;` following statement
+fail_compilation/fail22529.d(13): Error: found `return` when expecting `;` following expression
---
*/
TEST_OUTPUT:
---
Error: no property `getHash` for `typeid(const(Ensure[]))` of type `object.TypeInfo_Const`
+fail_compilation/extra-files/test23109/object.d(7): class `TypeInfo_Const` defined here
Error: no property `getHash` for `typeid(const(Ensure[1]))` of type `object.TypeInfo_Const`
+fail_compilation/extra-files/test23109/object.d(7): class `TypeInfo_Const` defined here
fail_compilation/imports/test23109a.d(10): Error: template instance `imports.test23109a.Array!(Ensure)` error instantiating
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail61.d(22): Error: no property `B` for type `fail61.A.B`
-fail_compilation/fail61.d(23): Error: no property `B` for type `fail61.A.B`
-fail_compilation/fail61.d(32): Error: no property `A2` for type `fail61.B2`
-fail_compilation/fail61.d(41): Error: calling non-static function `foo` requires an instance of type `B3`
+fail_compilation/fail61.d(25): Error: no property `B` for type `fail61.A.B`
+fail_compilation/fail61.d(16): class `B` defined here
+fail_compilation/fail61.d(26): Error: no property `B` for type `fail61.A.B`
+fail_compilation/fail61.d(16): class `B` defined here
+fail_compilation/fail61.d(35): Error: no property `A2` for type `fail61.B2`
+fail_compilation/fail61.d(30): class `B2` defined here
+fail_compilation/fail61.d(44): Error: calling non-static function `foo` requires an instance of type `B3`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fail7861.d(17): Error: no property `nonexistent` for type `test.B`
+fail_compilation/fail7861.d(18): Error: no property `nonexistent` for type `test.B`
+fail_compilation/fail7861.d(14): struct `B` defined here
---
*/
module test;
/*
TEST_OUTPUT:
---
-fail_compilation/fail9.d(23): Error: no property `Vector` for type `fail9.Vector!int`
+fail_compilation/fail9.d(24): Error: no property `Vector` for type `fail9.Vector!int`
+fail_compilation/fail9.d(13): class `Vector` defined here
---
*/
/*
-REQUIRED_ARGS: -wo
TEST_OUTPUT:
---
-fail_compilation/fail_scope.d(30): Deprecation: scope parameter `da` may not be returned
-fail_compilation/fail_scope.d(32): Deprecation: scope parameter `o` may not be returned
-fail_compilation/fail_scope.d(33): Deprecation: scope parameter `dg` may not be returned
-fail_compilation/fail_scope.d(40): Deprecation: scope parameter `p` may not be returned
-fail_compilation/fail_scope.d(45): Error: returning `cast(char[])string` escapes a reference to local variable `string`
-fail_compilation/fail_scope.d(63): Error: returning `s.bar()` escapes a reference to local variable `s`
-fail_compilation/fail_scope.d(74): Error: `fail_scope.foo8` called with argument types `(int)` matches both:
-fail_compilation/fail_scope.d(68): `fail_scope.foo8(ref int x)`
+fail_compilation/fail_scope.d(28): Deprecation: scope parameter `da` may not be returned
+fail_compilation/fail_scope.d(30): Deprecation: scope parameter `o` may not be returned
+fail_compilation/fail_scope.d(31): Deprecation: scope parameter `dg` may not be returned
+fail_compilation/fail_scope.d(38): Deprecation: scope parameter `p` may not be returned
+fail_compilation/fail_scope.d(43): Error: returning `cast(char[])string` escapes a reference to local variable `string`
+fail_compilation/fail_scope.d(61): Error: returning `s.bar()` escapes a reference to local variable `s`
+fail_compilation/fail_scope.d(72): Error: `fail_scope.foo8` called with argument types `(int)` matches both:
+fail_compilation/fail_scope.d(66): `fail_scope.foo8(ref int x)`
and:
-fail_compilation/fail_scope.d(69): `fail_scope.foo8(return ref int x)`
-fail_compilation/fail_scope.d(82): Error: returning `& string` escapes a reference to local variable `string`
-fail_compilation/fail_scope.d(92): Error: returning `cast(int[])a` escapes a reference to local variable `a`
-fail_compilation/fail_scope.d(100): Error: returning `cast(int[])a` escapes a reference to local variable `a`
-fail_compilation/fail_scope.d(108): Error: escaping reference to outer local variable `x`
-fail_compilation/fail_scope.d(127): Warning: returning `s.bar()` escapes a reference to local variable `s`
-fail_compilation/fail_scope.d(137): Error: returning `foo16226(i)` escapes a reference to local variable `i`
+fail_compilation/fail_scope.d(67): `fail_scope.foo8(return ref int x)`
+fail_compilation/fail_scope.d(80): Error: returning `& string` escapes a reference to local variable `string`
+fail_compilation/fail_scope.d(90): Error: returning `cast(int[])a` escapes a reference to local variable `a`
+fail_compilation/fail_scope.d(98): Error: returning `cast(int[])a` escapes a reference to local variable `a`
+fail_compilation/fail_scope.d(106): Error: escaping reference to outer local variable `x`
+fail_compilation/fail_scope.d(135): Error: returning `foo16226(i)` escapes a reference to local variable `i`
---
//fail_compilation/fail_scope.d(35): Error: scope variable `da` may not be returned
//fail_compilation/fail_scope.d(37): Error: scope variable `o` may not be returned
/*
TEST_OUTPUT:
---
-fail_compilation/faildottypeinfo.d(11): Error: no property `typeinfo` for `0` of type `int`
-fail_compilation/faildottypeinfo.d(12): Error: no property `typeinfo` for type `object.Object`
+fail_compilation/faildottypeinfo.d(12): Error: no property `typeinfo` for `0` of type `int`
+fail_compilation/faildottypeinfo.d(13): Error: no property `typeinfo` for type `object.Object`
+$p:druntime/import/object.d$($n$): class `Object` defined here
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/fnconstraint.d(13): Error: template constraint must follow parameter lists and attributes
-fail_compilation/fnconstraint.d(13): Error: declaration expected, not `if`
-fail_compilation/fnconstraint.d(22): Error: template constraint must follow parameter lists and attributes
-fail_compilation/fnconstraint.d(22): Error: declaration expected, not `if`
-fail_compilation/fnconstraint.d(26): Error: `}` expected following members in `struct` declaration at fail_compilation/fnconstraint.d(18)
+fail_compilation/fnconstraint.d(14): Error: template constraint must follow parameter lists and attributes
+fail_compilation/fnconstraint.d(14): Error: declaration expected, not `if`
+fail_compilation/fnconstraint.d(23): Error: template constraint must follow parameter lists and attributes
+fail_compilation/fnconstraint.d(23): Error: declaration expected, not `if`
+fail_compilation/fnconstraint.d(27): Error: `}` expected following members in `struct` declaration
+fail_compilation/fnconstraint.d(19): struct `S` starts here
---
*/
void foo()()
--- /dev/null
+/*
+REQUIRED_ARGS: -verrors=context
+TEST_OUTPUT:
+---
+fail_compilation/goto_skip.d(28): Error: `goto` skips declaration of variable `goto_skip.skip.ch`
+ goto Lskip;
+ ^
+fail_compilation/goto_skip.d(29): declared here
+ char ch = '!';
+ ^
+fail_compilation/goto_skip.d(36): Error: `goto` skips declaration of `with` temporary
+ goto L1;
+ ^
+fail_compilation/goto_skip.d(38): declared here
+ with (S()) {
+ ^
+fail_compilation/goto_skip.d(46): Error: `goto` skips declaration of variable `goto_skip.test8.e`
+ goto L2;
+ ^
+fail_compilation/goto_skip.d(51): declared here
+ catch (Exception e) {
+ ^
+---
+*/
+char skip(bool b)
+{
+ if (b)
+ goto Lskip;
+ char ch = '!';
+Lskip:
+ return ch;
+}
+
+int f()
+{
+ goto L1;
+ struct S { int e = 5; }
+ with (S()) {
+L1:
+ return e;
+ }
+}
+
+void test8(int a)
+{
+ goto L2;
+
+ try {
+ a += 2;
+ }
+ catch (Exception e) {
+ a += 3;
+L2: ;
+ a += 100;
+ }
+ assert(a == 100);
+}
/*
TEST_OUTPUT:
---
-fail_compilation/ice10713.d(10): Error: no property `nonExistingField` for type `ice10713.S`
+fail_compilation/ice10713.d(11): Error: no property `nonExistingField` for type `ice10713.S`
+fail_compilation/ice10713.d(9): struct `S` defined here
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/ice10938.d(13): Error: no property `opts` for `this` of type `ice10938.C`
-fail_compilation/ice10938.d(13): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/ice10938.d(14): Error: no property `opts` for `this` of type `ice10938.C`
+fail_compilation/ice10938.d(14): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/ice10938.d(10): class `C` defined here
---
*/
TEST_OUTPUT:
---
fail_compilation/ice11518.d(17): Error: class `ice11518.B` matches more than one template declaration:
-fail_compilation/ice11518.d(12): `B(T : A!T)`
-and
-fail_compilation/ice11518.d(13): `B(T : A!T)`
+fail_compilation/ice11518.d(12): `B(T : A!T)`
+and:
+fail_compilation/ice11518.d(13): `B(T : A!T)`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/ice11982.d(20): Error: basic type expected, not `scope`
-fail_compilation/ice11982.d(20): Error: found `scope` when expecting `;` following statement `new _error_` on line fail_compilation/ice11982.d(20)
-fail_compilation/ice11982.d(20): Error: basic type expected, not `}`
-fail_compilation/ice11982.d(20): Error: missing `{ ... }` for function literal
-fail_compilation/ice11982.d(20): Error: C style cast illegal, use `cast(funk)function _error_()
+fail_compilation/ice11982.d(22): Error: basic type expected, not `scope`
+fail_compilation/ice11982.d(22): Error: found `scope` when expecting `;` following expression
+fail_compilation/ice11982.d(22): expression: `new _error_`
+fail_compilation/ice11982.d(22): Error: basic type expected, not `}`
+fail_compilation/ice11982.d(22): Error: missing `{ ... }` for function literal
+fail_compilation/ice11982.d(22): Error: C style cast illegal, use `cast(funk)function _error_()
{
}
`
-fail_compilation/ice11982.d(20): Error: found `}` when expecting `;` following statement `cast(funk)function _error_()
+fail_compilation/ice11982.d(22): Error: found `}` when expecting `;` following expression
+fail_compilation/ice11982.d(22): expression: `cast(funk)function _error_()
{
}
-` on line fail_compilation/ice11982.d(20)
-fail_compilation/ice11982.d(21): Error: matching `}` expected following compound statement, not `End of File`
-fail_compilation/ice11982.d(20): unmatched `{`
+`
+fail_compilation/ice11982.d(23): Error: matching `}` expected following compound statement, not `End of File`
+fail_compilation/ice11982.d(22): unmatched `{`
---
*/
void main() { new scope ( funk ) function }
/*
TEST_OUTPUT:
---
-fail_compilation/ice8100.d(10): Error: no property `Q` for type `ice8100.Bar!bool`
-fail_compilation/ice8100.d(11): Error: template instance `ice8100.Foo!(Bar!bool)` error instantiating
-fail_compilation/ice8100.d(12): instantiated from here: `Bar!bool`
+fail_compilation/ice8100.d(11): Error: no property `Q` for type `ice8100.Bar!bool`
+fail_compilation/ice8100.d(12): class `Bar` defined here
+fail_compilation/ice8100.d(12): Error: template instance `ice8100.Foo!(Bar!bool)` error instantiating
+fail_compilation/ice8100.d(13): instantiated from here: `Bar!bool`
---
*/
+++ /dev/null
-/*
-TEST_OUTPUT:
-----
-fail_compilation/issue12652.d(18): Error: static initializations of associative arrays is not allowed.
-fail_compilation/issue12652.d(18): associative arrays must be initialized at runtime: https://dlang.org/spec/hash-map.html#runtime_initialization
----
-*/
-
-enum A
-{
- x,
- y,
- z
-}
-
-struct S
-{
- string[A] t = [A.x : "aaa", A.y : "bbb"];
-}
-
-void main ()
-{
- S s;
-}
--- /dev/null
+/* TEST_OUTPUT:
+---
+fail_compilation/issue22682.d(14): Error: `pragma(mangle)` must be attached to a declaration
+fail_compilation/issue22682.d(15): Error: `pragma(mangle)` takes a single argument that must be a string literal
+fail_compilation/issue22682.d(16): Error: `string` expected for pragma mangle argument, not `(0)` of type `int`
+fail_compilation/issue22682.d(16): Error: `pragma(mangle)` takes a single argument that must be a string literal
+fail_compilation/issue22682.d(17): Error: `pragma(mangle)` must be attached to a declaration
+---
+ */
+module issue22682;
+
+void main()
+{
+ pragma(mangle) {}
+ pragma(mangle) static int i0;
+ pragma(mangle, 0) static int i1;
+ pragma(mangle);
+}
/*
TEST_OUTPUT:
---
-fail_compilation/lexer1.d(30): Error: no identifier for declarator `x`
-fail_compilation/lexer1.d(30): Error: declaration expected, not `"01 02 03"w`
+fail_compilation/lexer1.d(30): Error: declaration expected, not `x"01 02 03"w`
fail_compilation/lexer1.d(31): Error: declaration expected, not `2147483649U`
fail_compilation/lexer1.d(32): Error: declaration expected, not `0.1`
fail_compilation/lexer1.d(33): Error: declaration expected, not `0.1f`
fail_compilation/lexer1.d(53): Error: html entity requires 2 code units, use a string instead of a character
---
*/
+
// https://dlang.dawg.eu/coverage/src/lexer.c.gcov.html
x"01 02 03"w;
0x80000001;
/*
TEST_OUTPUT:
---
-fail_compilation/lexer2.d(16): Error: semicolon expected following auto declaration, not `"123"`
-fail_compilation/lexer2.d(16): Error: declaration expected, not `"123"`
-fail_compilation/lexer2.d(17): Error: semicolon expected following auto declaration, not `"123G"`
-fail_compilation/lexer2.d(17): Error: declaration expected, not `"123G"`
+fail_compilation/lexer2.d(16): Error: odd number (3) of hex characters in hex string
+fail_compilation/lexer2.d(17): Error: non-hex character 'G' in hex string
fail_compilation/lexer2.d(18): Error: heredoc rest of line should be blank
fail_compilation/lexer2.d(20): Error: unterminated delimited string constant starting at fail_compilation/lexer2.d(20)
fail_compilation/lexer2.d(22): Error: semicolon expected following auto declaration, not `End of File`
---
*/
+
+
// https://dlang.dawg.eu/coverage/src/lexer.c.gcov.html
static s1 = x"123";
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+fail_compilation/main.d(9): Error: only one entry point `main`$?:windows=, `WinMain` or `DllMain`$ is allowed
+fail_compilation/main.d(8): previously found `void main()` here
+---
+*/
+void main() {}
+void main(string[] args) {}
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+fail_compilation/match_func_ptr.d(13): Error: cannot match delegate literal to function pointer type `void function()`
+fail_compilation/match_func_ptr.d(14): Error: cannot match function literal to delegate type `void delegate()`
+fail_compilation/match_func_ptr.d(15): Error: cannot infer parameter types from `int function()`
+fail_compilation/match_func_ptr.d(16): Error: cannot infer parameter types from `int delegate(int, int)`
+---
+*/
+
+void main()
+{
+ void function() f = delegate {};
+ void delegate() d = function {};
+ int function() f2 = i => 2;
+ int delegate(int, int) d2 = i => 2;
+}
fail_compilation/misc_parser_err_cov1.d(40): Error: identifier or `new` expected following `.`, not `+`
fail_compilation/misc_parser_err_cov1.d(41): Error: identifier or new keyword expected following `(...)`.
fail_compilation/misc_parser_err_cov1.d(41): Error: expression expected, not `;`
-fail_compilation/misc_parser_err_cov1.d(42): Error: found `}` when expecting `;` following statement `(__error) + 0` on line fail_compilation/misc_parser_err_cov1.d(41)
+fail_compilation/misc_parser_err_cov1.d(42): Error: found `}` when expecting `;` following expression
+fail_compilation/misc_parser_err_cov1.d(41): expression: `(__error) + 0`
fail_compilation/misc_parser_err_cov1.d(43): Error: matching `}` expected following compound statement, not `End of File`
fail_compilation/misc_parser_err_cov1.d(33): unmatched `{`
---
/*
TEST_OUTPUT:
---
-fail_compilation/nogc3.d(52): Error: function `nogc3.testClosure1` is `@nogc` yet allocates closure for `testClosure1()` with the GC
-fail_compilation/nogc3.d(55): `nogc3.testClosure1.bar` closes over variable `x` at fail_compilation/nogc3.d(54)
-fail_compilation/nogc3.d(64): Error: function `nogc3.testClosure3` is `@nogc` yet allocates closure for `testClosure3()` with the GC
-fail_compilation/nogc3.d(67): `nogc3.testClosure3.bar` closes over variable `x` at fail_compilation/nogc3.d(66)
+fail_compilation/nogc3.d(54): Error: function `nogc3.testClosure1` is `@nogc` yet allocates closure for `testClosure1()` with the GC
+fail_compilation/nogc3.d(57): function `nogc3.testClosure1.bar` closes over variable `x`
+fail_compilation/nogc3.d(56): `x` declared here
+fail_compilation/nogc3.d(66): Error: function `nogc3.testClosure3` is `@nogc` yet allocates closure for `testClosure3()` with the GC
+fail_compilation/nogc3.d(69): function `nogc3.testClosure3.bar` closes over variable `x`
+fail_compilation/nogc3.d(68): `x` declared here
---
*/
@nogc auto testClosure1()
/*
TEST_OUTPUT:
---
-fail_compilation/nogc3.d(85): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation
-fail_compilation/nogc3.d(86): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation
-fail_compilation/nogc3.d(92): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation
-fail_compilation/nogc3.d(91): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation
+fail_compilation/nogc3.d(87): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation
+fail_compilation/nogc3.d(88): Error: array literal in `@nogc` function `nogc3.foo13702` may cause a GC allocation
+fail_compilation/nogc3.d(94): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation
+fail_compilation/nogc3.d(93): Error: array literal in `@nogc` function `nogc3.bar13702` may cause a GC allocation
---
*/
int[] foo13702(bool b) @nogc
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+fail_compilation/noreturn_expr.d(10): Error: type `noreturn` is not an expression
+---
+*/
+
+int v(e)()
+{
+ return e + 0;
+}
+
+int main()
+{
+ return v!(noreturn)();
+}
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+fail_compilation/noreturn_expr2.d(8): Error: cannot cast `noreturn` to `int` at compile time
+---
+*/
+
+enum E {e1 = 1, e2 = 2, illegal = noreturn}
+
+void main()
+{
+ E e;
+ e = E.illegal;
+}
--- /dev/null
+/*
+TEST_OUTPUT:
+---
+fail_compilation/operator_undefined.d(19): Error: operator `-` is not defined for `toJson(2)` of type `Json`
+---
+*/
+
+import std.stdio;
+
+struct Json
+{
+ //int opUnary(string op : "-")();
+}
+
+Json toJson(int);
+
+void main()
+{
+ auto x = -2.toJson;
+}
---
fail_compilation/parseStc.d(12): Error: missing closing `)` after `if (x`
fail_compilation/parseStc.d(12): Error: use `{ }` for an empty statement, not `;`
-fail_compilation/parseStc.d(12): Error: found `)` when expecting `;` following statement `1` on line fail_compilation/parseStc.d(12)
+fail_compilation/parseStc.d(12): Error: found `)` when expecting `;` following expression
+fail_compilation/parseStc.d(12): expression: `1`
fail_compilation/parseStc.d(13): Error: redundant attribute `const`
---
*/
-void test1()
-{
+void test1() {
if (x; 1) {}
if (const const auto x = 1) {}
}
TEST_OUTPUT:
---
fail_compilation/retscope.d(75): Error: function `retscope.HTTP.Impl.onReceive` is `@nogc` yet allocates closure for `onReceive()` with the GC
-fail_compilation/retscope.d(77): `retscope.HTTP.Impl.onReceive.__lambda1` closes over variable `this` at fail_compilation/retscope.d(75)
+fail_compilation/retscope.d(77): delegate `retscope.HTTP.Impl.onReceive.__lambda1` closes over variable `this`
---
*/
* REQUIRED_ARGS: -de
* TEST_OUTPUT:
---
-fail_compilation/skip.d(21): Error: `switch` skips declaration of `with` temporary at fail_compilation/skip.d(26)
-fail_compilation/skip.d(43): Error: `switch` skips declaration of variable `skip.test14532.n` at fail_compilation/skip.d(45)
+fail_compilation/skip.d(23): Error: `switch` skips declaration of `with` temporary
+fail_compilation/skip.d(28): declared here
+fail_compilation/skip.d(45): Error: `switch` skips declaration of variable `skip.test14532.n`
+fail_compilation/skip.d(47): declared here
---
*/
// https://issues.dlang.org/show_bug.cgi?id=10524
--- /dev/null
+/*
+REQUIRED_ARGS: -verrors=context
+TEST_OUTPUT:
+---
+fail_compilation/switch_skip.d(22): Error: `switch` skips declaration of variable `switch_skip.test3.j`
+ switch (i)
+ ^
+fail_compilation/switch_skip.d(26): declared here
+ int j;
+ ^
+fail_compilation/switch_skip.d(39): Error: `switch` skips declaration of variable `switch_skip.test.z`
+ final switch(n)
+ ^
+fail_compilation/switch_skip.d(41): declared here
+ int z = 5;
+ ^
+---
+*/
+
+void test3(int i)
+{
+ switch (i)
+ {
+ case 1:
+ {
+ int j;
+ case 2:
+ ++j;
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+// https://issues.dlang.org/show_bug.cgi?id=18858
+int test(int n)
+{
+ final switch(n)
+ {
+ int z = 5;
+ enum e = 6;
+
+ case 1:
+ int y = 2;
+ return y;
+ }
+}
-/************************************************************/
-
/*
TEST_OUTPUT:
---
-fail_compilation/switches.d(105): Error: `case 2` not found
+fail_compilation/switches.d(14): Error: `case 2` not found
+fail_compilation/switches.d(25): Error: no `case` statement following `goto case;`
---
*/
-#line 100
void test1(int i)
{
switch (i)
}
}
-/************************************************************/
-
-/*
-TEST_OUTPUT:
----
-fail_compilation/switches.d(205): Error: no `case` statement following `goto case;`
----
-*/
-
-#line 200
void test2(int i)
{
switch (i)
break;
}
}
-
-/************************************************************/
-
-/*
-TEST_OUTPUT:
----
-fail_compilation/switches.d(302): Error: `switch` skips declaration of variable `switches.test3.j` at fail_compilation/switches.d(306)
----
-*/
-
-#line 300
-void test3(int i)
-{
- switch (i)
- {
- case 1:
- {
- int j;
- case 2:
- ++j;
- break;
- }
- default:
- break;
- }
-}
-
-
-/************************************************************/
-
-/*
-TEST_OUTPUT:
----
-fail_compilation/switches.d(404): Error: `switch` skips declaration of variable `switches.test.z` at fail_compilation/switches.d(406)
----
-*/
-
-#line 400
-// https://issues.dlang.org/show_bug.cgi?id=18858
-
-int test(int n)
-{
- final switch(n)
- {
- int z = 5;
- enum e = 6;
-
- case 1:
- int y = 2;
- return y;
- }
-}
-/* REQUIRED_ARGS: -wo
+/*
TEST_OUTPUT:
---
-fail_compilation/test13536.d(23): Error: field `U.sysDg` cannot access pointers in `@safe` code that overlap other fields
-fail_compilation/test13536.d(23): Warning: address of variable `s` assigned to `u` with longer lifetime
-fail_compilation/test13536.d(24): Error: field `U.safeDg` cannot access pointers in `@safe` code that overlap other fields
+fail_compilation/test13536.d(22): Error: field `U.sysDg` cannot access pointers in `@safe` code that overlap other fields
+fail_compilation/test13536.d(23): Error: field `U.safeDg` cannot access pointers in `@safe` code that overlap other fields
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/test15785.d(16): Error: no property `foo` for `super` of type `imports.test15785.Base`
-fail_compilation/test15785.d(17): Error: undefined identifier `bar`
+fail_compilation/test15785.d(17): Error: no property `foo` for `super` of type `imports.test15785.Base`
+fail_compilation/imports/test15785.d(3): class `Base` defined here
+fail_compilation/test15785.d(18): Error: undefined identifier `bar`
---
*/
/*
TEST_OUTPUT:
---
-fail_compilation/test15897.d(19): Error: no property `create` for `cat` of type `imports.test15897.Cat`
+fail_compilation/test15897.d(20): Error: no property `create` for `cat` of type `imports.test15897.Cat`
+fail_compilation/imports/test15897.d(4): class `Cat` defined here
---
*/
module test15897;
---
fail_compilation/test16188.d(101): Error: no property `name` for `Where()` of type `test16188.Where`
fail_compilation/test16188.d(101): potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message
+fail_compilation/test16188.d(103): struct `Where` defined here
---
*/
REQUIRED_ARGS: -preview=dip1000
TEST_OUTPUT:
---
-fail_compilation/test16193.d(38): Error: function `test16193.abc` is `@nogc` yet allocates closure for `abc()` with the GC
-fail_compilation/test16193.d(40): `test16193.abc.__foreachbody2` closes over variable `x` at fail_compilation/test16193.d(39)
+fail_compilation/test16193.d(39): Error: function `test16193.abc` is `@nogc` yet allocates closure for `abc()` with the GC
+fail_compilation/test16193.d(41): delegate `test16193.abc.__foreachbody2` closes over variable `x`
+fail_compilation/test16193.d(40): `x` declared here
---
*/
//fail_compilation/test16193.d(22): To enforce `@safe`, the compiler allocates a closure unless `opApply()` uses `scope`
-/* REQUIRED_ARGS: -wo
+/*
TEST_OUTPUT:
---
-fail_compilation/test16365.d(21): Error: `this` reference necessary to take address of member `f1` in `@safe` function `main`
-fail_compilation/test16365.d(23): Error: cannot implicitly convert expression `&f2` of type `void delegate() pure nothrow @nogc @safe` to `void function() @safe`
-fail_compilation/test16365.d(27): Warning: address of variable `s` assigned to `dg` with longer lifetime
-fail_compilation/test16365.d(28): Error: `dg.funcptr` cannot be used in `@safe` code
+fail_compilation/test16365.d(20): Error: `this` reference necessary to take address of member `f1` in `@safe` function `main`
+fail_compilation/test16365.d(22): Error: cannot implicitly convert expression `&f2` of type `void delegate() pure nothrow @nogc @safe` to `void function() @safe`
+fail_compilation/test16365.d(27): Error: `dg.funcptr` cannot be used in `@safe` code
---
*/
/* REQUIRED_ARGS: -verrors=spec
TEST_OUTPUT:
---
-(spec:1) fail_compilation/test17380spec.d(14): Error: cannot resolve identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
-(spec:1) fail_compilation/test17380spec.d(14): Error: no property `ThisTypeDoesNotExistAndCrashesTheCompiler` for `this.opCast()` of type `test17380spec.Uint128`
-fail_compilation/test17380spec.d(14): Error: undefined identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
+(spec:1) fail_compilation/test17380spec.d(15): Error: cannot resolve identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
+(spec:1) fail_compilation/test17380spec.d(15): Error: no property `ThisTypeDoesNotExistAndCrashesTheCompiler` for `this.opCast()` of type `test17380spec.Uint128`
+(spec:1) fail_compilation/test17380spec.d(20): struct `Uint128` defined here
+fail_compilation/test17380spec.d(15): Error: undefined identifier `ThisTypeDoesNotExistAndCrashesTheCompiler`
---
*/
--- /dev/null
+/*
+REQUIRED_ARGS: -de
+TEST_OUTPUT:
+---
+fail_compilation/test20655.d(29): Deprecation: `@safe` function `g` calling `f1`
+fail_compilation/test20655.d(24): which wouldn't be `@safe` because of:
+fail_compilation/test20655.d(24): field `U.s` cannot access pointers in `@safe` code that overlap other fields
+fail_compilation/test20655.d(30): Deprecation: `@safe` function `g` calling `f2`
+fail_compilation/test20655.d(25): which wouldn't be `@safe` because of:
+fail_compilation/test20655.d(25): field `U.s` cannot access pointers in `@safe` code that overlap other fields
+fail_compilation/test20655.d(31): Deprecation: `@safe` function `g` calling `f3`
+fail_compilation/test20655.d(28): which wouldn't be `@safe` because of:
+fail_compilation/test20655.d(28): field `U.s` cannot access pointers in `@safe` code that overlap other fields
+---
+*/
+
+union U
+{
+ string s;
+ int x;
+}
+U u;
+
+auto f1() { auto s = u.s; } /* Should be inferred as @system. */
+void f2()() { auto s = u.s; } /* ditto */
+void g() @safe
+{
+ void f3() { auto s = u.s; } /* ditto */
+ f1(); /* Should be rejected with error "cannot call @system function". */
+ f2(); /* ditto */
+ f3(); /* ditto */
+}
EXTRA_FILES: imports/imp21353.d
TEST_OUTPUT:
---
-fail_compilation/test21353.d(19): Error: no property `A` for type `imports.imp21353.B`
-fail_compilation/test21353.d(20): Error: no property `A` for type `imports.imp21353.B`
-fail_compilation/test21353.d(21): Error: no property `A` for type `imports.imp21353.B`
-fail_compilation/test21353.d(23): Error: undefined identifier `P` in module `imports.imp21353`
-fail_compilation/test21353.d(24): Error: undefined identifier `P` in module `imports.imp21353`
+fail_compilation/test21353.d(22): Error: no property `A` for type `imports.imp21353.B`
+fail_compilation/imports/imp21353.d(5): struct `B` defined here
+fail_compilation/test21353.d(23): Error: no property `A` for type `imports.imp21353.B`
+fail_compilation/imports/imp21353.d(5): struct `B` defined here
+fail_compilation/test21353.d(24): Error: no property `A` for type `imports.imp21353.B`
+fail_compilation/imports/imp21353.d(5): struct `B` defined here
+fail_compilation/test21353.d(26): Error: undefined identifier `P` in module `imports.imp21353`
+fail_compilation/test21353.d(27): Error: undefined identifier `P` in module `imports.imp21353`
---
*/
PERMUTE_ARGS: -preview=dip1000
TEST_OUTPUT:
---
-fail_compilation/test21912.d(24): Error: function `test21912.escapeParam` is `@nogc` yet allocates closure for `escapeParam()` with the GC
-fail_compilation/test21912.d(26): `test21912.escapeParam.__lambda2` closes over variable `i` at fail_compilation/test21912.d(24)
-fail_compilation/test21912.d(29): Error: function `test21912.escapeAssign` is `@nogc` yet allocates closure for `escapeAssign()` with the GC
-fail_compilation/test21912.d(31): `test21912.escapeAssign.__lambda3` closes over variable `i` at fail_compilation/test21912.d(29)
-fail_compilation/test21912.d(40): Error: function `test21912.escapeAssignRef` is `@nogc` yet allocates closure for `escapeAssignRef()` with the GC
-fail_compilation/test21912.d(42): `test21912.escapeAssignRef.__lambda3` closes over variable `i` at fail_compilation/test21912.d(40)
-fail_compilation/test21912.d(51): Error: function `test21912.escapeParamInferred` is `@nogc` yet allocates closure for `escapeParamInferred()` with the GC
-fail_compilation/test21912.d(53): `test21912.escapeParamInferred.__lambda2` closes over variable `i` at fail_compilation/test21912.d(51)
+fail_compilation/test21912.d(28): Error: function `test21912.escapeParam` is `@nogc` yet allocates closure for `escapeParam()` with the GC
+fail_compilation/test21912.d(30): delegate `test21912.escapeParam.__lambda2` closes over variable `i`
+fail_compilation/test21912.d(28): `i` declared here
+fail_compilation/test21912.d(33): Error: function `test21912.escapeAssign` is `@nogc` yet allocates closure for `escapeAssign()` with the GC
+fail_compilation/test21912.d(35): delegate `test21912.escapeAssign.__lambda3` closes over variable `i`
+fail_compilation/test21912.d(33): `i` declared here
+fail_compilation/test21912.d(44): Error: function `test21912.escapeAssignRef` is `@nogc` yet allocates closure for `escapeAssignRef()` with the GC
+fail_compilation/test21912.d(46): delegate `test21912.escapeAssignRef.__lambda3` closes over variable `i`
+fail_compilation/test21912.d(44): `i` declared here
+fail_compilation/test21912.d(55): Error: function `test21912.escapeParamInferred` is `@nogc` yet allocates closure for `escapeParamInferred()` with the GC
+fail_compilation/test21912.d(57): delegate `test21912.escapeParamInferred.__lambda2` closes over variable `i`
+fail_compilation/test21912.d(55): `i` declared here
---
*/
@nogc:
TEST_OUTPUT:
---
fail_compilation/imports/imp22329.d(3): Error: no property `values` for type `test22329.Foo`
+fail_compilation/test22329.d(13): struct `Foo` defined here
fail_compilation/imports/imp22329.d(3): Error: incompatible types for `(arg) + (1)`: `Foo` and `int`
-fail_compilation/test22329.d(20): Error: template instance `imp22329.func!(Foo)` error instantiating
+fail_compilation/test22329.d(21): Error: template instance `imp22329.func!(Foo)` error instantiating
---
*/
TEST_OUTPUT:
---
fail_compilation/test23112.d(106): Error: function `test23112.bar` is `@nogc` yet allocates closure for `bar()` with the GC
-fail_compilation/test23112.d(108): `test23112.bar.f` closes over variable `a` at fail_compilation/test23112.d(106)
+fail_compilation/test23112.d(108): function `test23112.bar.f` closes over variable `a`
+fail_compilation/test23112.d(106): `a` declared here
---
*/
--- /dev/null
+/* REQUIRED_ARGS: -preview=dip1000
+ * TEST_OUTPUT:
+---
+fail_compilation/test24015.d(19): Error: scope variable `v` assigned to non-scope parameter `...` calling `jer`
+---
+*/
+
+// https://issues.dlang.org/show_bug.cgi?id=24105
+
+@safe:
+
+extern (C) void ben(int i, scope ...);
+
+extern (C) void jer(int i, ...);
+
+void bar(scope const char* v)
+{
+ ben(3, v);
+ jer(3, v);
+}
--- /dev/null
+/*
+https://issues.dlang.org/show_bug.cgi?id=24036
+Issue 24036 - assert message in CTFE becomes `['m', 'e', 's', 's', 'a', 'g', 'e'][0..7]` if produced using std.format.format
+
+TEST_OUTPUT:
+---
+fail_compilation/test24036.d(19): Error: message
+fail_compilation/test24036.d(21): called from here: `(*function () pure nothrow @safe => 42)()`
+---
+*/
+
+auto format()
+{
+ return ['m', 'e', 's', 's', 'a', 'g', 'e'][0 .. 7];
+}
+
+immutable ctfeThing = ()
+{
+ assert(0, format());
+ return 42;
+}();
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=24065
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test24065.d(12): Error: string expected as argument of __traits `getTargetInfo` instead of `int`
+fail_compilation/test24065.d(15): Error: string expected as argument of __traits `getTargetInfo` instead of `foo`
+fail_compilation/test24065.d(18): Error: string expected as argument of __traits `getTargetInfo` instead of `e`
+---
+*/
+
+auto s1 = __traits(getTargetInfo, int);
+
+void foo() {}
+auto s2 = __traits(getTargetInfo, foo);
+
+enum e;
+auto s3 = __traits(getTargetInfo, e);
--- /dev/null
+/* REQUIRED_ARGS: -nothrow
+ * TEST_OUTPUT:
+---
+fail_compilation/test24084.d(110): Error: cannot use `throw` statements with -nothrow
+fail_compilation/test24084.d(112): Error: cannot use try-catch statements with -nothrow
+---
+ */
+
+// https://issues.dlang.org/show_bug.cgi?id=24084
+
+#line 100
+
+struct S
+{
+ int x;
+ ~this() { }
+}
+
+void xyzzy()
+{
+ S s;
+ throw new Exception("xx");
+
+ try
+ {
+ int y;
+ } catch (Exception) { }
+}
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=24110
+
+/*
+TEST_OUTPUT:
+---
+fail_compilation/test24110.d(12): Error: static assert: `__traits(compiles, __error)` is false
+---
+*/
+
+struct S { int x; }
+alias T = shared S;
+static assert(__traits(compiles, (T[] a, T[] b) => a < b));
TEST_OUTPUT:
---
fail_compilation/testOpApply.d(217): Error: `sa.opApply` matches more than one declaration:
-`fail_compilation/testOpApply.d(203)`: `int(int delegate(int) dg)`
+fail_compilation/testOpApply.d(203): `int(int delegate(int) dg)`
and:
-`fail_compilation/testOpApply.d(208)`: `int(int delegate(string) dg)`
+fail_compilation/testOpApply.d(208): `int(int delegate(string) dg)`
fail_compilation/testOpApply.d(217): Error: cannot uniquely infer `foreach` argument types
---
+/
TEST_OUTPUT:
---
fail_compilation/testOpApply.d(317): Error: `sa.opApply` matches more than one declaration:
-`fail_compilation/testOpApply.d(303)`: `int(int delegate(int) dg)`
+fail_compilation/testOpApply.d(303): `int(int delegate(int) dg)`
and:
-`fail_compilation/testOpApply.d(308)`: `int(int delegate(long) dg)`
+fail_compilation/testOpApply.d(308): `int(int delegate(long) dg)`
fail_compilation/testOpApply.d(317): Error: cannot uniquely infer `foreach` argument types
---
+/
TEST_OUTPUT:
---
fail_compilation/testOpApply.d(420): Error: `sa.opApply` matches more than one declaration:
-`fail_compilation/testOpApply.d(404)`: `int(int delegate(int) dg)`
+fail_compilation/testOpApply.d(404): `int(int delegate(int) dg)`
and:
-`fail_compilation/testOpApply.d(410)`: `int(int delegate(ref int) dg)`
+fail_compilation/testOpApply.d(410): `int(int delegate(ref int) dg)`
fail_compilation/testOpApply.d(420): Error: cannot uniquely infer `foreach` argument types
---
+/
TEST_OUTPUT:
---
fail_compilation/testOpApply.d(504): Error: `sa.opApply` matches more than one declaration:
-`fail_compilation/testOpApply.d(404)`: `int(int delegate(int) dg)`
+fail_compilation/testOpApply.d(404): `int(int delegate(int) dg)`
and:
-`fail_compilation/testOpApply.d(410)`: `int(int delegate(ref int) dg)`
+fail_compilation/testOpApply.d(410): `int(int delegate(ref int) dg)`
fail_compilation/testOpApply.d(504): Error: cannot uniquely infer `foreach` argument types
---
+/
fail_compilation/testsemi.d(117): Error: no identifier for declarator `x`
fail_compilation/testsemi.d(123): Error: found `int` when expecting `;` following mixin
fail_compilation/testsemi.d(129): Error: found `int` when expecting `;` following `import` Expression
-fail_compilation/testsemi.d(131): Error: `}` expected following members in `class` declaration at fail_compilation/testsemi.d(112)
+fail_compilation/testsemi.d(131): Error: `}` expected following members in `class` declaration
+fail_compilation/testsemi.d(112): class `C` starts here
---
*/
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=23103
+// Issue 23103 - static initialization of associative arrays is not implemented
+
+nothrow @safe:
+
+/////////////////////////////////////////////
+
+int[int] globalAA = [1: 10, 2: 20];
+
+void testSimple()
+{
+ assert(globalAA[1] == 10);
+ assert(globalAA[2] == 20);
+ assert(!(30 in globalAA));
+
+ foreach (i; 0 .. 1000)
+ {
+ globalAA[i] = i * 10;
+ assert(globalAA[i] == i * 10);
+ }
+}
+
+/////////////////////////////////////////////
+
+struct Composit
+{
+ string[string][] aa;
+}
+
+auto getAA() { return ["a": "A"]; }
+
+immutable Composit compositAA = Composit([getAA(), ["b": "B"]]);
+
+void testComposit() pure
+{
+ assert(compositAA.aa[0]["a"] == "A");
+ assert(compositAA.aa[1]["b"] == "B");
+}
+
+/////////////////////////////////////////////
+
+struct Destructing
+{
+ int v;
+ static int destructorsCalled = 0;
+
+ ~this() nothrow
+ {
+ // FIXME: the lowering to newaa calls the destructor at CTFE, so we can't modify globals in it
+ if (!__ctfe)
+ destructorsCalled++;
+ }
+}
+
+struct Key
+{
+ int v;
+ bool opEquals(ref const Key o) const { return v == o.v; }
+ size_t toHash() const { return v; }
+}
+
+Destructing[Key] dAa = [Key(1): Destructing(10), Key(2): Destructing(20)];
+
+void testDestructor()
+{
+ assert(dAa[Key(1)].v == 10);
+ assert(dAa[Key(2)].v == 20);
+ assert(Destructing.destructorsCalled == 0);
+ dAa[Key(1)] = Destructing(100);
+ assert(dAa[Key(1)].v == 100);
+ assert(Destructing.destructorsCalled == 1);
+}
+
+/////////////////////////////////////////////
+
+enum A
+{
+ x, y, z
+}
+
+struct S
+{
+ string[A] t = [A.x : "A.x", A.y : "A.y"];
+}
+
+void testStructInit()
+{
+ S s;
+ assert(s.t[A.x] == "A.x");
+ assert(s.t[A.y] == "A.y");
+}
+
+/////////////////////////////////////////////
+
+class C
+{
+ string[int] t = [0 : "zero"];
+}
+
+void testClassInit()
+{
+ C c = new C();
+ assert(c.t[0] == "zero");
+}
+
+/////////////////////////////////////////////
+
+immutable(string)[immutable(int)] immutableAA = [1: "one", 2: "two"];
+
+void testImmutable()
+{
+ assert(immutableAA[1] == "one");
+ assert(immutableAA[2] == "two");
+}
+
+/////////////////////////////////////////////
+
+void main()
+{
+ testSimple();
+ testComposit();
+ testDestructor();
+ testStructInit();
+ testClassInit();
+ testImmutable();
+}
--- /dev/null
+//https://issues.dlang.org/show_bug.cgi?id=24078
+
+void main()
+{
+ assert(["c"] ~ "a" ~ "b" == ["c", "a", "b"]);
+}
--- /dev/null
+// https://issues.dlang.org/show_bug.cgi?id=24139
+
+struct S1
+{
+ int x;
+ extern(C++) ~this() { assert(&this == s1); }
+}
+
+extern(C++) struct S2
+{
+ int x;
+ ~this() { assert(&this == s2); }
+}
+
+S1* s1;
+S2* s2;
+
+void main()
+{
+ s1 = new S1;
+ s2 = new S2;
+
+ typeid(S1).destroy(s1);
+ typeid(S2).destroy(s2);
+}
upvar 2 compilable_do_what compilable_do_what
set compilable_do_what "compile"
+ } elseif [string match "-nothrow" $arg] {
+ lappend out "-fno-exceptions"
+
} elseif [string match "-vgc" $arg] {
lappend out "-ftransition=nogc"
-4574d1728d1f7e52ff40e6733b8c39889d128349
+f9efc98fd7954741333f72c6a50af273f3863a1a
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
core/internal/gc/impl/manual/gc.d core/internal/gc/impl/proto/gc.d \
core/internal/gc/os.d core/internal/gc/pooltable.d \
core/internal/gc/proxy.d core/internal/hash.d core/internal/lifetime.d \
- core/internal/moving.d core/internal/parseoptions.d \
- core/internal/postblit.d core/internal/qsort.d \
- core/internal/spinlock.d core/internal/string.d \
+ core/internal/moving.d core/internal/newaa.d \
+ core/internal/parseoptions.d core/internal/postblit.d \
+ core/internal/qsort.d core/internal/spinlock.d core/internal/string.d \
core/internal/switch_.d core/internal/traits.d core/internal/utf.d \
core/internal/util/array.d core/internal/util/math.d core/lifetime.d \
core/math.d core/memory.d core/runtime.d core/simd.d \
core/internal/gc/impl/proto/gc.lo core/internal/gc/os.lo \
core/internal/gc/pooltable.lo core/internal/gc/proxy.lo \
core/internal/hash.lo core/internal/lifetime.lo \
- core/internal/moving.lo core/internal/parseoptions.lo \
- core/internal/postblit.lo core/internal/qsort.lo \
- core/internal/spinlock.lo core/internal/string.lo \
- core/internal/switch_.lo core/internal/traits.lo \
- core/internal/utf.lo core/internal/util/array.lo \
- core/internal/util/math.lo core/lifetime.lo core/math.lo \
- core/memory.lo core/runtime.lo core/simd.lo \
- core/stdc/assert_.lo core/stdc/complex.lo core/stdc/config.lo \
- core/stdc/ctype.lo core/stdc/errno.lo core/stdc/fenv.lo \
- core/stdc/float_.lo core/stdc/inttypes.lo core/stdc/limits.lo \
- core/stdc/locale.lo core/stdc/math.lo core/stdc/signal.lo \
- core/stdc/stdarg.lo core/stdc/stddef.lo core/stdc/stdint.lo \
- core/stdc/stdio.lo core/stdc/stdlib.lo core/stdc/string.lo \
- core/stdc/tgmath.lo core/stdc/time.lo core/stdc/wchar_.lo \
- core/stdc/wctype.lo core/sync/barrier.lo \
+ core/internal/moving.lo core/internal/newaa.lo \
+ core/internal/parseoptions.lo core/internal/postblit.lo \
+ core/internal/qsort.lo core/internal/spinlock.lo \
+ core/internal/string.lo core/internal/switch_.lo \
+ core/internal/traits.lo core/internal/utf.lo \
+ core/internal/util/array.lo core/internal/util/math.lo \
+ core/lifetime.lo core/math.lo core/memory.lo core/runtime.lo \
+ core/simd.lo core/stdc/assert_.lo core/stdc/complex.lo \
+ core/stdc/config.lo core/stdc/ctype.lo core/stdc/errno.lo \
+ core/stdc/fenv.lo core/stdc/float_.lo core/stdc/inttypes.lo \
+ core/stdc/limits.lo core/stdc/locale.lo core/stdc/math.lo \
+ core/stdc/signal.lo core/stdc/stdarg.lo core/stdc/stddef.lo \
+ core/stdc/stdint.lo core/stdc/stdio.lo core/stdc/stdlib.lo \
+ core/stdc/string.lo core/stdc/tgmath.lo core/stdc/time.lo \
+ core/stdc/wchar_.lo core/stdc/wctype.lo core/sync/barrier.lo \
core/sync/condition.lo core/sync/config.lo core/sync/event.lo \
core/sync/exception.lo core/sync/mutex.lo core/sync/package.lo \
core/sync/rwmutex.lo core/sync/semaphore.lo \
core/internal/gc/impl/manual/gc.d core/internal/gc/impl/proto/gc.d \
core/internal/gc/os.d core/internal/gc/pooltable.d \
core/internal/gc/proxy.d core/internal/hash.d core/internal/lifetime.d \
- core/internal/moving.d core/internal/parseoptions.d \
- core/internal/postblit.d core/internal/qsort.d \
- core/internal/spinlock.d core/internal/string.d \
+ core/internal/moving.d core/internal/newaa.d \
+ core/internal/parseoptions.d core/internal/postblit.d \
+ core/internal/qsort.d core/internal/spinlock.d core/internal/string.d \
core/internal/switch_.d core/internal/traits.d core/internal/utf.d \
core/internal/util/array.d core/internal/util/math.d core/lifetime.d \
core/math.d core/memory.d core/runtime.d core/simd.d \
core/internal/hash.lo: core/internal/$(am__dirstamp)
core/internal/lifetime.lo: core/internal/$(am__dirstamp)
core/internal/moving.lo: core/internal/$(am__dirstamp)
+core/internal/newaa.lo: core/internal/$(am__dirstamp)
core/internal/parseoptions.lo: core/internal/$(am__dirstamp)
core/internal/postblit.lo: core/internal/$(am__dirstamp)
core/internal/qsort.lo: core/internal/$(am__dirstamp)
--- /dev/null
+/**
+ Turn an Associative Array into a binary compatible struct for static initialization.
+
+ This does not implement all the pieces of
+ the associative array type in druntime, just enough to create an AA from an
+ existing range of key/value pairs.
+
+ Copyright: Copyright Digital Mars 2000 - 2015, Steven Schveighoffer 2022.
+ License: $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
+ Authors: Martin Nowak, Steven Schveighoffer
+*/
+module core.internal.newaa;
+
+import core.memory;
+
+// grow threshold
+private enum GROW_NUM = 4;
+private enum GROW_DEN = 5;
+// shrink threshold
+private enum SHRINK_NUM = 1;
+private enum SHRINK_DEN = 8;
+// grow factor
+private enum GROW_FAC = 4;
+// growing the AA doubles it's size, so the shrink threshold must be
+// smaller than half the grow threshold to have a hysteresis
+static assert(GROW_FAC * SHRINK_NUM * GROW_DEN < GROW_NUM * SHRINK_DEN);
+// initial load factor (for literals), mean of both thresholds
+private enum INIT_NUM = (GROW_DEN * SHRINK_NUM + GROW_NUM * SHRINK_DEN) / 2;
+private enum INIT_DEN = SHRINK_DEN * GROW_DEN;
+
+private enum INIT_NUM_BUCKETS = 8;
+// magic hash constants to distinguish empty, deleted, and filled buckets
+private enum HASH_EMPTY = 0;
+private enum HASH_FILLED_MARK = size_t(1) << 8 * size_t.sizeof - 1;
+
+private struct Bucket
+{
+ size_t hash;
+ void *entry;
+}
+
+struct Impl
+{
+ Bucket[] buckets;
+ uint used;
+ uint deleted;
+ TypeInfo_Struct entryTI;
+ uint firstUsed;
+ immutable uint keysz;
+ immutable uint valsz;
+ immutable uint valoff;
+ Flags flags;
+
+ enum Flags : ubyte
+ {
+ none = 0x0,
+ keyHasPostblit = 0x1,
+ hasPointers = 0x2,
+ }
+}
+
+private struct AAShell
+{
+ Impl *impl;
+}
+
+private size_t mix(size_t h) @safe pure nothrow @nogc
+{
+ // final mix function of MurmurHash2
+ enum m = 0x5bd1e995;
+ h ^= h >> 13;
+ h *= m;
+ h ^= h >> 15;
+ return h;
+}
+
+struct Entry(K, V)
+{
+ /*const*/ K key; // this really should be const, but legacy issues.
+ V value;
+}
+
+
+// create a binary-compatible AA structure that can be used directly as an
+// associative array.
+AAShell makeAA(K, V)(V[K] src)
+{
+ immutable srclen = src.length;
+ assert(srclen <= uint.max);
+ alias E = Entry!(K, V);
+ if (srclen == 0)
+ return AAShell.init;
+ // first, determine the size that would be used if we grew the bucket list
+ // one element at a time using the standard AA algorithm.
+ size_t dim = INIT_NUM_BUCKETS;
+ while (srclen * GROW_DEN > dim * GROW_NUM)
+ dim = dim * GROW_FAC;
+
+ Bucket[] buckets;
+ // Allocate and fill the buckets
+ if (__ctfe)
+ buckets = new Bucket[dim];
+ else
+ assert(0);
+
+ assert(buckets.length >= dim);
+
+ immutable mask = dim - 1;
+ assert((dim & mask) == 0); // must be a power of 2
+
+ Bucket* findSlotInsert(immutable size_t hash)
+ {
+ for (size_t i = hash & mask, j = 1;; ++j)
+ {
+ if (buckets[i].hash == HASH_EMPTY)
+ return &buckets[i];
+ i = (i + j) & mask;
+ }
+ }
+
+ uint firstUsed = cast(uint) buckets.length;
+ foreach (k, v; src)
+ {
+ immutable h = hashOf(k).mix | HASH_FILLED_MARK;
+ auto location = findSlotInsert(h);
+ immutable nfu = cast(uint) (location - &buckets[0]);
+ if (nfu < firstUsed)
+ firstUsed = nfu;
+ *location = Bucket(h, new E(k, v));
+ }
+
+ enum flags = () {
+ import core.internal.traits;
+ Impl.Flags flags;
+ static if (__traits(hasPostblit, K))
+ flags |= flags.keyHasPostblit;
+ static if (hasIndirections!E)
+ flags |= flags.hasPointers;
+ return flags;
+ } ();
+ // return the new implementation
+ return AAShell(new Impl(buckets, cast(uint)srclen, 0, typeid(E), firstUsed,
+ K.sizeof, V.sizeof, E.value.offsetof, flags));
+}
///
pure float modff(float value, float* iptr);
///
- extern(D) pure real modfl(real value, real *iptr) { return modf(cast(double) value, cast(double*) iptr); }
+ extern(D) pure real modfl(real value, real *iptr)
+ {
+ static if (double.sizeof == real.sizeof)
+ return modf(cast(double) value, cast(double*) iptr);
+ else
+ {
+ double i;
+ double r = modf(cast(double) value, &i);
+ *iptr = i;
+ return r;
+ }
+ }
///
double scalbn(double x, int n);
///
alias opDollar = length;
///
- bool empty() const nothrow @safe { return size() == 0; }
+ bool empty() const nothrow @trusted { return size() == 0; }
///
size_t[2] opSlice(size_t dim : 0)(size_t start, size_t end) const pure nothrow @safe @nogc { return [start, end]; }
///
size_type capacity() const nothrow { return (__is_long() ? __get_long_cap() : __min_cap) - 1; }
///
- inout(T)* data() inout @safe { return __get_pointer(); }
+ inout(T)* data() inout @trusted { return __get_pointer(); }
///
inout(T)[] as_array() scope return inout nothrow @trusted { return __get_pointer()[0 .. size()]; }
///
}
}
void __set_long_size(size_type __s) nothrow { __r_.first().__l.__size_ = __s; }
- size_type __get_long_size() const nothrow { return __r_.first().__l.__size_; }
+ size_type __get_long_size() const nothrow @trusted { return __r_.first().__l.__size_; }
void __set_size(size_type __s) nothrow { if (__is_long()) __set_long_size(__s); else __set_short_size(__s); }
void __set_long_cap(size_type __s) nothrow { __r_.first().__l.__cap_ = __long_mask | __s; }
enum F_SETLK = 6;
enum F_SETLKW = 7;
}
+ else version (MIPS_N64)
+ {
+ enum F_GETLK = 14;
+ enum F_SETLK = 6;
+ enum F_SETLKW = 7;
+ }
+ else version (MIPS_Any)
+ {
+ static if ( __USE_FILE_OFFSET64 )
+ {
+ enum F_GETLK = 33;
+ enum F_SETLK = 34;
+ enum F_SETLKW = 35;
+ }
+ else
+ {
+ enum F_GETLK = 14;
+ enum F_SETLK = 6;
+ enum F_SETLKW = 7;
+ }
+ }
else
static if ( __USE_FILE_OFFSET64 )
{
//ucontext_t (defined in core.sys.posix.ucontext)
//mcontext_t (defined in core.sys.posix.ucontext)
- struct stack_t
+ version (MIPS_Any)
{
- void* ss_sp;
- int ss_flags;
- size_t ss_size;
+ struct stack_t
+ {
+ void* ss_sp;
+ size_t ss_size;
+ int ss_flags;
+ }
+ }
+ else
+ {
+ struct stack_t
+ {
+ void* ss_sp;
+ int ss_flags;
+ size_t ss_size;
+ }
}
struct sigstack
enum MINSIGSTKSZ = 2048;
enum SIGSTKSZ = 8192;
- version (MIPS32)
+ version (MIPS_Any)
{
struct stack_t
{
else version (WatchOS)
version = Darwin;
+version (MIPS32) version = MIPS_Any;
+version (MIPS64) version = MIPS_Any;
+
nothrow @nogc extern(C):
//
c_long[16] __reserved;
}
- enum
+ version (MIPS_Any)
{
- RLIMIT_CORE = 4,
- RLIMIT_CPU = 0,
- RLIMIT_DATA = 2,
- RLIMIT_FSIZE = 1,
- RLIMIT_NOFILE = 7,
- RLIMIT_STACK = 3,
- RLIMIT_AS = 9,
+ enum
+ {
+ RLIMIT_CORE = 4,
+ RLIMIT_CPU = 0,
+ RLIMIT_DATA = 2,
+ RLIMIT_FSIZE = 1,
+ RLIMIT_NOFILE = 5,
+ RLIMIT_STACK = 3,
+ RLIMIT_AS = 6,
+ }
+ }
+ else
+ {
+ enum
+ {
+ RLIMIT_CORE = 4,
+ RLIMIT_CPU = 0,
+ RLIMIT_DATA = 2,
+ RLIMIT_FSIZE = 1,
+ RLIMIT_NOFILE = 7,
+ RLIMIT_STACK = 3,
+ RLIMIT_AS = 9,
+ }
}
}
else version (Darwin)
/**
+$(RED Warning:
+ This binding is out-of-date and does not allow use on non-Windows platforms. Use `etc.c.odbc.sql` instead.)
+
* Windows API header module
*
* Translated from MinGW Windows headers
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(DRUNTIMESRC core/sys/windows/_sql.d)
*/
+
module core.sys.windows.sql;
version (Windows):
/**
+$(RED Warning:
+ This binding is out-of-date and does not allow use on non-Windows platforms. Use `etc.c.odbc.sqlext` instead.)
+
* Windows API header module
*
* Translated from MinGW Windows headers
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(DRUNTIMESRC core/sys/windows/_sqlext.d)
*/
+
module core.sys.windows.sqlext;
version (Windows):
/**
+$(RED Warning:
+ This binding is out-of-date and does not allow use on non-Windows platforms. Use `etc.c.odbc.sqltypes` instead.)
+
* Windows API header module
*
* Translated from MinGW Windows headers
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(DRUNTIMESRC core/sys/windows/_sqltypes.d)
*/
+
module core.sys.windows.sqltypes;
version (Windows):
/**
+$(RED Warning:
+ This binding is out-of-date and does not allow use on non-Windows platforms. Use `etc.c.odbc.sqlucode` instead.)
+
* Windows API header module
*
* Translated from MinGW Windows headers
* License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
* Source: $(DRUNTIMESRC core/sys/windows/_sqlucode.d)
*/
+
module core.sys.windows.sqlucode;
version (Windows):
PIMAGE_SECTION_HEADER IMAGE_FIRST_SECTION(PIMAGE_NT_HEADERS h) {
return cast(PIMAGE_SECTION_HEADER)
- (&h.OptionalHeader + h.FileHeader.SizeOfOptionalHeader);
+ (cast(ubyte*) &h.OptionalHeader + h.FileHeader.SizeOfOptionalHeader);
}
// ImageDirectoryEntryToDataEx()
return _d_assocarrayliteralTX(typeid(Value[Key]), *cast(void[]*)&keys, *cast(void[]*)&values);
}
+// Lower an Associative Array to a newaa struct for static initialization.
+auto _aaAsStruct(K, V)(V[K] aa) @safe
+{
+ import core.internal.newaa : makeAA;
+ assert(__ctfe);
+ return makeAA!(K, V)(aa);
+}
+
alias AssociativeArray(Key, Value) = Value[Key];
/***********************************
GC.runFinalizers((cast(char*)(&entryDtor))[0 .. 1]);
assert(T.dtor == 6 && T.postblit == 2);
}
+
+// Ensure the newaa struct layout (used for static initialization) is in sync
+unittest
+{
+ import newaa = core.internal.newaa;
+ static assert(newaa.Impl.sizeof == Impl.sizeof);
+ // ensure compatible types and offsets
+ static foreach (i; 0 .. Impl.tupleof.length)
+ {
+ // for bucket array and Flags, we "compatible" types, not exactly the same types.
+ static if (__traits(identifier, Impl.tupleof[i]) == "buckets"
+ || __traits(identifier, Impl.tupleof[i]) == "flags")
+ static assert(Impl.tupleof[i].sizeof == newaa.Impl.tupleof[i].sizeof);
+ else
+ static assert(is(typeof(Impl.tupleof[i]) == typeof(newaa.Impl.tupleof[i])));
+
+ static assert(Impl.tupleof[i].offsetof == newaa.Impl.tupleof[i].offsetof);
+ }
+}
edge[nEdges++] = *impidx;
}
}
- // trim space to what is needed.
- edges[i] = nEdges > 0
- ? (cast(int*)realloc(edge, int.sizeof * nEdges))[0 .. nEdges]
- : null;
+ if (nEdges > 0)
+ {
+ // trim space to what is needed
+ edges[i] = (cast(int*)realloc(edge, int.sizeof * nEdges))[0 .. nEdges];
+ }
+ else
+ {
+ edges[i] = null;
+ .free(edge);
+ }
}
}
-d7e79f024606f18e989ae8b5fe298f9d07c7dced
+a3f22129dd2a134338ca02b79ff0de242d7f016e
The first line of this file holds the git revision number of the last
merge done from the dlang/phobos repository.
/** Support casting to a bool
* Params: T = bool
- * Returns: boolean result
+ * Returns: true if value is not zero
*/
bool opCast(T : bool)() const
{
}
} // @safe pure nothrow @nogc
+ /** Support casting to an integral type
+ * Params: T = integral type
+ * Returns: low bits of value reinterpreted as T
+ */
+ T opCast(T : long)() const
+ if (is(byte : T))
+ {
+ return cast(T) this.data.lo;
+ }
+
+ ///
+ @safe unittest
+ {
+ const Int128 a = Int128(0xffff_ffff_ffff_ffffL, 0x0123_4567_89ab_cdefL);
+ assert(cast(long) a == 0x0123_4567_89ab_cdefL);
+ assert(cast(int) a == 0x89ab_cdef);
+ assert(cast(byte) a == cast(byte) 0xef);
+ }
+
+ /** Support casting to floating point type
+ * Params: T = floating point type
+ * Returns: value cast to floating point with environment-dependent
+ * rounding if the value is not exactly representable
+ */
+ T opCast(T : real)() const
+ {
+ import core.math : ldexp;
+ if (cast(long) this.data.hi >= 0)
+ return ldexp(cast(T) this.data.hi, 64) + this.data.lo;
+ else
+ {
+ const absData = neg(this.data);
+ return -ldexp(cast(T) absData.hi, 64) - absData.lo;
+ }
+ }
+
+ ///
+ @safe unittest
+ {
+ const Int128 a = Int128(-1L << 60);
+ assert(cast(double) a == -(2.0 ^^ 60));
+ assert(cast(double) (a * a) == 2.0 ^^ 120);
+ }
+
/** Support binary arithmetic operators + - * / % & | ^ << >> >>>
* Params:
* op = one of the arithmetic binary operators
assert(chomp(" hello world \n\n" ~ [lineSep]) == " hello world \n\n");
assert(chomp(" hello world \n\n" ~ [paraSep]) == " hello world \n\n");
assert(chomp(" hello world \n\n" ~ [ nelSep]) == " hello world \n\n");
+ assert(chomp(" hello world ") == " hello world ");
assert(chomp(" hello world") == " hello world");
assert(chomp("") == "");
extern(C++) static class C0
{
int foo() { return 0; } // Need at least one function in vtable.
- S0 a; alias a this; // { dg-warning "is deprecated" }
+ S0 a; alias a this;
}
extern(C++) static class C1
{
S1 a;
inout(S1)* b() inout nothrow { return &a; }
- alias b this; // { dg-warning "is deprecated" }
+ alias b this;
}
cast(void) hashOf(S0.init);
foreach test $tests {
set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../src $test]"
dg-runtest $test "-static-libphobos" \
- "-fmain -fbuilding-libphobos-tests $version_flags"
+ "-Wno-deprecated -fmain -fbuilding-libphobos-tests $version_flags"
set libphobos_test_name ""
}
foreach test $tests {
set libphobos_test_name "$subdir/[dg-trim-dirname $srcdir/../src $test]"
dg-runtest $test "-shared-libphobos" \
- "-fmain -fbuilding-libphobos-tests -fno-moduleinfo $version_flags"
+ "-Wno-deprecated -fmain -fbuilding-libphobos-tests -fno-moduleinfo $version_flags"
set libphobos_test_name ""
}