aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2023-10-15 12:05:10 +0200
committerIain Buclaw <ibuclaw@gdcproject.org>2023-10-15 12:12:49 +0200
commitac908237bd551fb55f2f82736cb37038e9b91459 (patch)
tree1d9efb93ef9af63ec88bf85130e16116249bb192 /gcc/d/dmd
parent648d30716d0cdb5dec96b2da9ed23328bad7cb9f (diff)
downloadgcc-ac908237bd551fb55f2f82736cb37038e9b91459.zip
gcc-ac908237bd551fb55f2f82736cb37038e9b91459.tar.gz
gcc-ac908237bd551fb55f2f82736cb37038e9b91459.tar.bz2
d: Merge upstream dmd, druntime f9efc98fd7, phobos a3f22129d.
D front-end changes: - Import dmd v2.105.2. - A function with enum storage class is now deprecated. - Global variables can now be initialized with Associative Arrays. - Improvements for the C++ header generation of static variables used in a default argument context. D runtime changes: - Import druntime v2.105.2. - The `core.memory.GC' functions `GC.enable', `GC.disable', `GC.collect', and `GC.minimize' `have been marked `@safe'. Phobos changes: - Import phobos v2.105.2. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd f9efc98fd7. * dmd/VERSION: Bump version to v2.105.2. * d-builtins.cc (build_frontend_type): Update for new front-end interface. * d-diagnostic.cc (verrorReport): Don't emit tips when error gagging is turned on. * d-lang.cc (d_handle_option): Remove obsolete parameter. (d_post_options): Likewise. (d_read_ddoc_files): New function. (d_generate_ddoc_file): New function. (d_parse_file): Update for new front-end interface. * expr.cc (ExprVisitor::visit (AssocArrayLiteralExp *)): Check for new front-end lowering of static associative arrays. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime f9efc98fd7. * libdruntime/Makefile.am (DRUNTIME_DSOURCES): Add core/internal/newaa.d. * libdruntime/Makefile.in: Regenerate. * src/MERGE: Merge upstream phobos a3f22129d. * testsuite/libphobos.hash/test_hash.d: Update test. * testsuite/libphobos.phobos/phobos.exp: Add compiler flags -Wno-deprecated. * testsuite/libphobos.phobos_shared/phobos_shared.exp: Likewise. gcc/testsuite/ChangeLog: * lib/gdc-utils.exp (gdc-convert-args): Handle new compiler options.
Diffstat (limited to 'gcc/d/dmd')
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/VERSION2
-rw-r--r--gcc/d/dmd/attrib.d2
-rw-r--r--gcc/d/dmd/blockexit.d107
-rw-r--r--gcc/d/dmd/canthrow.d2
-rw-r--r--gcc/d/dmd/chkformat.d32
-rw-r--r--gcc/d/dmd/clone.d20
-rw-r--r--gcc/d/dmd/cond.d2
-rw-r--r--gcc/d/dmd/cparse.d11
-rw-r--r--gcc/d/dmd/cppmangle.d2
-rw-r--r--gcc/d/dmd/ctfeexpr.d6
-rw-r--r--gcc/d/dmd/dcast.d13
-rw-r--r--gcc/d/dmd/dclass.d6
-rw-r--r--gcc/d/dmd/declaration.d7
-rw-r--r--gcc/d/dmd/delegatize.d1
-rw-r--r--gcc/d/dmd/denum.d2
-rw-r--r--gcc/d/dmd/dinterpret.d14
-rw-r--r--gcc/d/dmd/dmacro.d56
-rw-r--r--gcc/d/dmd/dmodule.d4
-rw-r--r--gcc/d/dmd/doc.d353
-rw-r--r--gcc/d/dmd/doc.h3
-rw-r--r--gcc/d/dmd/dscope.d1
-rw-r--r--gcc/d/dmd/dstruct.d1
-rw-r--r--gcc/d/dmd/dsymbol.d1
-rw-r--r--gcc/d/dmd/dsymbolsem.d58
-rw-r--r--gcc/d/dmd/dtemplate.d24
-rw-r--r--gcc/d/dmd/dtoh.d10
-rw-r--r--gcc/d/dmd/errors.h3
-rw-r--r--gcc/d/dmd/errorsink.d1
-rw-r--r--gcc/d/dmd/escape.d40
-rw-r--r--gcc/d/dmd/expression.d47
-rw-r--r--gcc/d/dmd/expression.h3
-rw-r--r--gcc/d/dmd/expressionsem.d109
-rw-r--r--gcc/d/dmd/func.d21
-rw-r--r--gcc/d/dmd/globals.d33
-rw-r--r--gcc/d/dmd/globals.h35
-rw-r--r--gcc/d/dmd/hdrgen.d375
-rw-r--r--gcc/d/dmd/hdrgen.h4
-rw-r--r--gcc/d/dmd/iasmgcc.d2
-rw-r--r--gcc/d/dmd/id.d2
-rw-r--r--gcc/d/dmd/init.d2
-rw-r--r--gcc/d/dmd/initsem.d31
-rw-r--r--gcc/d/dmd/json.d23
-rw-r--r--gcc/d/dmd/json.h2
-rw-r--r--gcc/d/dmd/lexer.d88
-rw-r--r--gcc/d/dmd/location.d20
-rw-r--r--gcc/d/dmd/module.h2
-rw-r--r--gcc/d/dmd/mtype.d55
-rw-r--r--gcc/d/dmd/mtype.h5
-rw-r--r--gcc/d/dmd/opover.d8
-rw-r--r--gcc/d/dmd/optimize.d28
-rw-r--r--gcc/d/dmd/parse.d110
-rw-r--r--gcc/d/dmd/printast.d2
-rw-r--r--gcc/d/dmd/safe.d23
-rw-r--r--gcc/d/dmd/semantic2.d53
-rw-r--r--gcc/d/dmd/semantic3.d14
-rw-r--r--gcc/d/dmd/statement.d117
-rw-r--r--gcc/d/dmd/statement.h3
-rw-r--r--gcc/d/dmd/statementsem.d293
-rw-r--r--gcc/d/dmd/tokens.d22
-rw-r--r--gcc/d/dmd/tokens.h1
-rw-r--r--gcc/d/dmd/traits.d2
-rw-r--r--gcc/d/dmd/typesem.d19
-rw-r--r--gcc/d/dmd/utils.d24
64 files changed, 1361 insertions, 1003 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index dc26778..d5dfe0d 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-4574d1728d1f7e52ff40e6733b8c39889d128349
+f9efc98fd7954741333f72c6a50af273f3863a1a
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/gcc/d/dmd/VERSION b/gcc/d/dmd/VERSION
index 8012337..fd05dcf 100644
--- a/gcc/d/dmd/VERSION
+++ b/gcc/d/dmd/VERSION
@@ -1 +1 @@
-v2.105.0
+v2.105.2
diff --git a/gcc/d/dmd/attrib.d b/gcc/d/dmd/attrib.d
index baabe93..5a91bc7 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -679,7 +679,7 @@ extern (C++) final class VisibilityDeclaration : AttribDeclaration
{
assert(visibility.kind > Visibility.Kind.undefined);
OutBuffer buf;
- visibilityToBuffer(&buf, visibility);
+ visibilityToBuffer(buf, visibility);
return buf.extractChars();
}
diff --git a/gcc/d/dmd/blockexit.d b/gcc/d/dmd/blockexit.d
index bdc81f2..a0da77a 100644
--- a/gcc/d/dmd/blockexit.d
+++ b/gcc/d/dmd/blockexit.d
@@ -18,6 +18,7 @@ import dmd.astenums;
import dmd.canthrow;
import dmd.dclass;
import dmd.declaration;
+import dmd.errorsink;
import dmd.expression;
import dmd.func;
import dmd.globals;
@@ -56,11 +57,11 @@ enum BE : int
* 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;
@@ -97,7 +98,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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);
}
}
@@ -143,23 +144,23 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
// 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;
}
@@ -173,7 +174,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
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;
@@ -184,7 +185,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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)
@@ -197,7 +198,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
if (s._body)
{
- result = blockExit(s._body, func, mustNotThrow);
+ result = blockExit(s._body, func, eSink);
if (result == BE.break_)
{
result = BE.fallthru;
@@ -210,7 +211,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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;
@@ -223,13 +224,13 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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))
@@ -241,22 +242,22 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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)
@@ -269,30 +270,30 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
//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)
@@ -308,11 +309,11 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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;
@@ -325,12 +326,12 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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)
@@ -353,7 +354,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
result = BE.return_;
if (s.exp)
- result |= canThrow(s.exp, func, mustNotThrow);
+ result |= canThrow(s.exp, func, eSink !is null);
}
void visitBreak(BreakStatement s)
@@ -369,20 +370,20 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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)
@@ -390,7 +391,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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
*/
@@ -411,10 +412,10 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
}
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;
}
@@ -423,12 +424,12 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
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)
@@ -436,13 +437,13 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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)
@@ -452,7 +453,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
// 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");
}
}
@@ -472,12 +473,12 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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)
@@ -489,7 +490,7 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
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;
}
@@ -502,8 +503,8 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
{
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_;
}
@@ -528,15 +529,13 @@ int blockExit(Statement s, FuncDeclaration func, bool mustNotThrow)
+ 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);
@@ -545,8 +544,8 @@ BE checkThrow(ref const Loc loc, Expression exp, const bool mustNotThrow, FuncDe
{
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);
diff --git a/gcc/d/dmd/canthrow.d b/gcc/d/dmd/canthrow.d
index ba13eb0..4cead30 100644
--- a/gcc/d/dmd/canthrow.d
+++ b/gcc/d/dmd/canthrow.d
@@ -202,7 +202,7 @@ extern (C++) /* CT */ BE canThrow(Expression e, FuncDeclaration func, bool mustN
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;
}
diff --git a/gcc/d/dmd/chkformat.d b/gcc/d/dmd/chkformat.d
index feaa3c7..8cfad59 100644
--- a/gcc/d/dmd/chkformat.d
+++ b/gcc/d/dmd/chkformat.d
@@ -15,7 +15,7 @@ import core.stdc.ctype : isdigit;
import dmd.astenums;
import dmd.cond;
-import dmd.errors;
+import dmd.errorsink;
import dmd.expression;
import dmd.globals;
import dmd.identifier;
@@ -53,6 +53,7 @@ import dmd.target;
* 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
@@ -60,7 +61,8 @@ import dmd.target;
* 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
@@ -87,7 +89,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
{
// 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;
}
@@ -96,7 +98,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
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;
@@ -106,7 +108,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
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());
}
@@ -178,7 +180,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
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;
@@ -226,7 +228,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
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;
@@ -286,7 +288,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
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:
@@ -327,6 +329,7 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
* 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
@@ -334,7 +337,8 @@ bool checkPrintfFormat(ref const Loc loc, scope const char[] format, scope Expre
* 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;)
@@ -357,7 +361,7 @@ bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expres
{
// 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;
}
@@ -366,7 +370,7 @@ bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expres
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++];
@@ -374,7 +378,7 @@ bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expres
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());
}
@@ -512,7 +516,7 @@ bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expres
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:
@@ -523,6 +527,8 @@ bool checkScanfFormat(ref const Loc loc, scope const char[] format, scope Expres
return false;
}
+/*****************************************************************************************************/
+
private:
/**************************************
diff --git a/gcc/d/dmd/clone.d b/gcc/d/dmd/clone.d
index 4cff1ec..181268e 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -297,7 +297,7 @@ FuncDeclaration buildOpAssign(StructDeclaration sd, Scope* sc)
}
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;
@@ -546,10 +546,11 @@ FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc)
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);
@@ -577,7 +578,7 @@ FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc)
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;
@@ -620,10 +621,11 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc)
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);
@@ -701,7 +703,7 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc)
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;
@@ -820,7 +822,7 @@ FuncDeclaration buildXtoHash(StructDeclaration sd, Scope* sc)
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);
@@ -1074,7 +1076,7 @@ private DtorDeclaration buildWindowsCppDtor(AggregateDeclaration ad, DtorDeclara
// // 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
@@ -1126,7 +1128,7 @@ private DtorDeclaration buildExternDDtor(AggregateDeclaration ad, Scope* sc)
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
@@ -1514,7 +1516,7 @@ private CtorDeclaration generateCopyCtorDeclaration(StructDeclaration sd, const
{
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);
diff --git a/gcc/d/dmd/cond.d b/gcc/d/dmd/cond.d
index 360acf5..76cef77 100644
--- a/gcc/d/dmd/cond.d
+++ b/gcc/d/dmd/cond.d
@@ -322,7 +322,7 @@ extern (C++) final class StaticForeach : RootObject
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;
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index 03383d1..b05d81d 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -626,7 +626,7 @@ final class CParser(AST) : Parser!AST
default:
// ImportC extensions: parse as a D asm block.
- s = parseAsm();
+ s = parseAsm(compileEnv.masm);
break;
}
break;
@@ -3114,12 +3114,13 @@ final class CParser(AST) : Parser!AST
}
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)
@@ -3297,8 +3298,10 @@ final class CParser(AST) : Parser!AST
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;
}
}
}
diff --git a/gcc/d/dmd/cppmangle.d b/gcc/d/dmd/cppmangle.d
index 5d74ec4..0c32fad 100644
--- a/gcc/d/dmd/cppmangle.d
+++ b/gcc/d/dmd/cppmangle.d
@@ -23,7 +23,6 @@
module dmd.cppmangle;
-import core.stdc.string;
import core.stdc.stdio;
import dmd.arraytypes;
@@ -46,7 +45,6 @@ import dmd.common.outbuffer;
import dmd.root.rootobject;
import dmd.root.string;
import dmd.target;
-import dmd.tokens;
import dmd.typesem;
import dmd.visitor;
diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d
index d355538..c0a2ca6 100644
--- a/gcc/d/dmd/ctfeexpr.d
+++ b/gcc/d/dmd/ctfeexpr.d
@@ -12,7 +12,6 @@
module dmd.ctfeexpr;
import core.stdc.stdio;
-import core.stdc.stdlib;
import core.stdc.string;
import dmd.arraytypes;
import dmd.astenums;
@@ -306,9 +305,10 @@ UnionExp copyLiteral(Expression e)
}
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;
}
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index b2aa643..d7cb2b1 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -23,7 +23,6 @@ import dmd.declaration;
import dmd.dscope;
import dmd.dstruct;
import dmd.dsymbol;
-import dmd.errors;
import dmd.escape;
import dmd.expression;
import dmd.expressionsem;
@@ -32,7 +31,6 @@ import dmd.globals;
import dmd.hdrgen;
import dmd.location;
import dmd.impcnvtab;
-import dmd.id;
import dmd.importc;
import dmd.init;
import dmd.intrange;
@@ -44,7 +42,6 @@ import dmd.root.rmem;
import dmd.root.utf;
import dmd.tokens;
import dmd.typesem;
-import dmd.visitor;
enum LOG = false;
@@ -73,7 +70,7 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
{
// 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);
}
@@ -174,7 +171,7 @@ Expression implicitCastTo(Expression e, Scope* sc, Type 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;
}
@@ -1075,7 +1072,7 @@ MATCH implicitConvTo(Expression e, Type t)
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;
@@ -1537,7 +1534,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
{
return e;
}
- if (e.type.isTypeNoreturn())
+ if (e.type.isTypeNoreturn() && e.op != EXP.type)
{
return specialNoreturnCast(e, t);
}
@@ -2489,7 +2486,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
{
//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;
}
diff --git a/gcc/d/dmd/dclass.d b/gcc/d/dmd/dclass.d
index 20cb82e..b446e77 100644
--- a/gcc/d/dmd/dclass.d
+++ b/gcc/d/dmd/dclass.d
@@ -19,14 +19,12 @@ import core.stdc.string;
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;
@@ -879,6 +877,10 @@ extern (C++) class ClassDeclaration : AggregateDeclaration
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];
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index 8a91a80..b21678c 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -16,7 +16,6 @@ import core.stdc.stdio;
import dmd.aggregate;
import dmd.arraytypes;
import dmd.astenums;
-import dmd.attrib;
import dmd.ctorflow;
import dmd.dclass;
import dmd.delegatize;
@@ -647,11 +646,11 @@ extern (C++) final class TupleDeclaration : Declaration
{
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)
@@ -1602,6 +1601,8 @@ extern (C++) class VarDeclaration : Declaration
{
inuse++;
_init = _init.initializerSemantic(_scope, type, INITinterpret);
+ import dmd.semantic2 : lowerStaticAAs;
+ lowerStaticAAs(this, _scope);
_scope = null;
inuse--;
}
diff --git a/gcc/d/dmd/delegatize.d b/gcc/d/dmd/delegatize.d
index 559f103..490ef56 100644
--- a/gcc/d/dmd/delegatize.d
+++ b/gcc/d/dmd/delegatize.d
@@ -21,7 +21,6 @@ import dmd.dsymbol;
import dmd.expression;
import dmd.expressionsem;
import dmd.func;
-import dmd.globals;
import dmd.init;
import dmd.initsem;
import dmd.location;
diff --git a/gcc/d/dmd/denum.d b/gcc/d/dmd/denum.d
index 87b40b8..955a17d 100644
--- a/gcc/d/dmd/denum.d
+++ b/gcc/d/dmd/denum.d
@@ -24,13 +24,11 @@ import dmd.dscope;
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;
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index 5948351..7cdafda 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -40,7 +40,6 @@ import dmd.init;
import dmd.initsem;
import dmd.location;
import dmd.mtype;
-import dmd.printast;
import dmd.root.rmem;
import dmd.root.array;
import dmd.root.ctfloat;
@@ -635,8 +634,6 @@ private Expression interpretFunction(UnionExp* pue, FuncDeclaration fd, InterSta
{
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;
@@ -790,7 +787,7 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate)
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;
}
@@ -976,7 +973,7 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate)
{
// 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;
}
@@ -1259,7 +1256,7 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate)
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;
}
@@ -1599,7 +1596,7 @@ Expression interpretStatement(UnionExp* pue, Statement s, InterState* istate)
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;
}
@@ -6105,7 +6102,8 @@ public:
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());
diff --git a/gcc/d/dmd/dmacro.d b/gcc/d/dmd/dmacro.d
index 6fc23e9..6e6c4b1 100644
--- a/gcc/d/dmd/dmacro.d
+++ b/gcc/d/dmd/dmacro.d
@@ -13,11 +13,12 @@ module dmd.dmacro;
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.
@@ -26,7 +27,7 @@ extern (C++) struct MacroTable
* 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)
@@ -37,13 +38,16 @@ extern (C++) struct MacroTable
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)
{
@@ -101,7 +105,7 @@ extern (C++) struct MacroTable
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);
@@ -119,7 +123,7 @@ extern (C++) struct MacroTable
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);
@@ -149,7 +153,7 @@ extern (C++) struct MacroTable
/* 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))
{
@@ -228,7 +232,7 @@ extern (C++) struct MacroTable
// 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);
@@ -260,7 +264,7 @@ extern (C++) struct MacroTable
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)
@@ -299,7 +303,7 @@ struct Macro
* 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];
@@ -424,3 +428,35 @@ Largstart:
//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);
+}
diff --git a/gcc/d/dmd/dmodule.d b/gcc/d/dmd/dmodule.d
index 4a2e15c..eb68b31 100644
--- a/gcc/d/dmd/dmodule.d
+++ b/gcc/d/dmd/dmodule.d
@@ -780,7 +780,9 @@ extern (C++) final class Module : Package
{
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();
@@ -1253,7 +1255,7 @@ extern (C++) final class Module : Package
// 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
diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d
index 887fd6c..5488d5a 100644
--- a/gcc/d/dmd/doc.d
+++ b/gcc/d/dmd/doc.d
@@ -52,9 +52,11 @@ import dmd.root.rmem;
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;
@@ -94,7 +96,7 @@ struct Escape
/***********************************************************
*/
-private class Section
+class Section
{
const(char)[] name;
const(char)[] body_;
@@ -105,7 +107,7 @@ private class Section
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)
@@ -151,16 +153,16 @@ private class Section
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
@@ -241,7 +243,7 @@ private final class ParamSection : Section
}
else if (fparam && fparam.type && fparam.ident)
{
- .toCBuffer(fparam.type, buf, fparam.ident, &hgs);
+ toCBuffer(fparam.type, buf, fparam.ident, hgs);
}
else
{
@@ -257,7 +259,7 @@ private final class ParamSection : Section
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 ");
@@ -265,7 +267,7 @@ private final class ParamSection : Section
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(")");
}
@@ -317,19 +319,19 @@ private final class ParamSection : Section
/***********************************************************
*/
-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)
{
@@ -340,7 +342,7 @@ private bool isCVariadicParameter(Dsymbols* a, const(char)[] p) @safe
return false;
}
-private Dsymbol getEponymousMember(TemplateDeclaration td) @safe
+Dsymbol getEponymousMember(TemplateDeclaration td) @safe
{
if (!td.onemember)
return null;
@@ -355,7 +357,7 @@ private Dsymbol getEponymousMember(TemplateDeclaration td) @safe
return null;
}
-private TemplateDeclaration getEponymousParent(Dsymbol s) @safe
+TemplateDeclaration getEponymousParent(Dsymbol s) @safe
{
if (!s.parent)
return null;
@@ -363,40 +365,46 @@ private TemplateDeclaration getEponymousParent(Dsymbol s) @safe
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;
@@ -409,14 +417,9 @@ extern(C++) void gendocfile(Module m, ErrorSink eSink)
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();
@@ -426,6 +429,8 @@ extern(C++) void gendocfile(Module m, ErrorSink eSink)
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;
@@ -433,14 +438,14 @@ extern(C++) void gendocfile(Module m, ErrorSink eSink)
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);
@@ -449,73 +454,47 @@ extern(C++) void gendocfile(Module m, ErrorSink eSink)
{
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);
}
}
@@ -526,11 +505,12 @@ extern(C++) void gendocfile(Module m, ErrorSink eSink)
* 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 '$':
@@ -568,14 +548,14 @@ void escapeDdocString(OutBuffer* buf, size_t start)
* 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 '(':
@@ -619,7 +599,7 @@ private void escapeStrayParenthesis(Loc loc, OutBuffer* buf, size_t start, bool
// 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))
@@ -635,14 +615,14 @@ private void escapeStrayParenthesis(Loc loc, OutBuffer* buf, size_t start, bool
// 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;
@@ -657,7 +637,7 @@ private void escapeStrayParenthesis(Loc loc, OutBuffer* buf, size_t start, bool
for (size_t u = buf.length; u > start;)
{
u--;
- char c = (*buf)[u];
+ char c = buf[u];
switch (c)
{
case ')':
@@ -683,14 +663,14 @@ private void escapeStrayParenthesis(Loc loc, OutBuffer* buf, size_t start, bool
// 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;
@@ -721,7 +701,7 @@ private bool emitAnchorName(ref OutBuffer buf, Dsymbol s, Scope* sc, bool includ
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;
{
@@ -846,7 +826,7 @@ private void emitAnchor(ref OutBuffer buf, Dsymbol s, Scope* sc, bool forHeader
/******************************* 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
@@ -860,7 +840,7 @@ private size_t getCodeIndent(const(char)* src)
}
/** 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);
@@ -879,7 +859,7 @@ private void expandTemplateMixinComments(TemplateMixin tm, ref OutBuffer buf, Sc
}
}
-private void emitMemberComments(ScopeDsymbol sds, ref OutBuffer buf, Scope* sc)
+void emitMemberComments(ScopeDsymbol sds, ref OutBuffer buf, Scope* sc)
{
if (!sds.members)
return;
@@ -920,14 +900,14 @@ private void emitMemberComments(ScopeDsymbol sds, ref OutBuffer buf, Scope* sc)
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_)
@@ -936,13 +916,13 @@ private void emitVisibility(ref OutBuffer buf, Declaration d)
}
}
-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
{
@@ -1037,7 +1017,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* sc)
// 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);
}
@@ -1226,7 +1206,7 @@ private void emitComment(Dsymbol s, ref OutBuffer buf, Scope* 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
{
@@ -1246,7 +1226,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
//printf("Dsymbol::toDocbuffer() %s\n", s.toChars());
HdrGenState hgs;
hgs.ddoc = true;
- .toCBuffer(s, buf, &hgs);
+ toCBuffer(s, *buf, hgs);
}
void prefix(Dsymbol s)
@@ -1296,7 +1276,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
HdrGenState hgs;
hgs.ddoc = true;
emitVisibility(*buf, i);
- .toCBuffer(i, buf, &hgs);
+ toCBuffer(i, *buf, hgs);
}
override void visit(Declaration d)
@@ -1315,10 +1295,10 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
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());
@@ -1331,7 +1311,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
{
if (i)
buf.writestring(", ");
- toCBuffer((*td.origParameters)[i], buf, &hgs);
+ toCBuffer((*td.origParameters)[i], *buf, hgs);
}
}
buf.writeByte(')');
@@ -1345,7 +1325,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
buf.writestring("$(DDOC_CONSTRAINT ");
}
- .toCBuffer(td.constraint, buf, &hgs);
+ toCBuffer(td.constraint, *buf, hgs);
if (noFuncDecl)
{
@@ -1505,7 +1485,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
else
{
HdrGenState hgs;
- .toCBuffer(bc.type, buf, null, &hgs);
+ toCBuffer(bc.type, *buf, null, hgs);
}
}
buf.writestring(";\n");
@@ -1520,7 +1500,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
{
buf.writestring(": $(DDOC_ENUM_BASETYPE ");
HdrGenState hgs;
- .toCBuffer(ed.memtype, buf, null, &hgs);
+ toCBuffer(ed.memtype, *buf, null, hgs);
buf.writestring(")");
}
buf.writestring(";\n");
@@ -1540,6 +1520,7 @@ private void toDocBuffer(Dsymbol s, ref OutBuffer buf, Scope* sc)
/***********************************************************
*/
+public
struct DocComment
{
Sections sections; // Section*[]
@@ -1872,7 +1853,7 @@ struct DocComment
}
}
- void writeSections(Scope* sc, Dsymbols* a, OutBuffer* buf)
+ void writeSections(Scope* sc, Dsymbols* a, ref OutBuffer buf)
{
assert(a.length);
//printf("DocComment::writeSections()\n");
@@ -1897,7 +1878,7 @@ struct DocComment
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
@@ -1928,7 +1909,7 @@ struct DocComment
buf.writestring("----\n");
buf.writestring(codedoc);
buf.writestring("----\n");
- highlightText(sc, a, loc, *buf, o);
+ highlightText(sc, a, loc, buf, o);
}
buf.writestring(")");
}
@@ -1948,7 +1929,7 @@ struct DocComment
/*****************************************
* Return true if comment consists entirely of "ditto".
*/
-private bool isDitto(const(char)* comment)
+bool isDitto(const(char)* comment)
{
if (comment)
{
@@ -1962,13 +1943,13 @@ private bool isDitto(const(char)* 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)
{
@@ -1993,7 +1974,7 @@ private const(char)[] skipwhitespace(const(char)[] p) @safe
* 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..$])
@@ -2028,7 +2009,7 @@ unittest {
* 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)
@@ -2070,7 +2051,7 @@ unittest
* 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)
@@ -2112,7 +2093,7 @@ unittest
* 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)
@@ -2158,7 +2139,7 @@ size_t skiptoident(ref OutBuffer buf, size_t i) @safe
/************************************************
* 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)
@@ -2188,7 +2169,7 @@ private size_t skippastident(ref OutBuffer buf, size_t i) @safe
* 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;
@@ -2250,7 +2231,7 @@ private size_t skipPastIdentWithDots(ref OutBuffer buf, size_t i) @safe
* 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;
@@ -2295,7 +2276,7 @@ Lno:
* 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;
@@ -2320,7 +2301,7 @@ private void removeBlankLineMacro(ref OutBuffer buf, ref size_t iAt, ref size_t
* 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[];
@@ -2356,7 +2337,7 @@ private bool replaceMarkdownThematicBreak(ref OutBuffer buf, ref size_t i, size_
* 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, "#");
@@ -2380,7 +2361,7 @@ private int detectAtxHeadingLevel(ref OutBuffer buf, const size_t i) @safe
* 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;
@@ -2425,7 +2406,7 @@ private void removeAnyAtxHeadingSuffix(ref OutBuffer buf, size_t i)
* 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);
@@ -2446,7 +2427,7 @@ private void endMarkdownHeading(ref OutBuffer buf, size_t iStart, ref size_t iEn
* 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)
@@ -2468,7 +2449,7 @@ private size_t endAllMarkdownQuotes(ref OutBuffer buf, size_t i, ref int quoteLe
* `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;
@@ -2487,7 +2468,7 @@ private size_t endAllListsAndQuotes(ref OutBuffer buf, ref size_t i, ref Markdow
* 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)
{
@@ -2566,7 +2547,7 @@ private size_t replaceMarkdownEmphasis(ref OutBuffer buf, const ref Loc loc, ref
/****************************************************
*/
-private bool isIdentifier(Dsymbols* a, const(char)[] s) @safe
+bool isIdentifier(Dsymbols* a, const(char)[] s) @safe
{
foreach (member; *a)
{
@@ -2608,7 +2589,7 @@ private bool isIdentifier(Dsymbols* a, const(char)[] s) @safe
/****************************************************
*/
-private bool isKeyword(const(char)[] str) @safe
+bool isKeyword(const(char)[] str) @safe
{
immutable string[3] table = ["true", "false", "null"];
foreach (s; table)
@@ -2621,7 +2602,7 @@ private bool isKeyword(const(char)[] str) @safe
/****************************************************
*/
-private TypeFunction isTypeFunction(Dsymbol s) @safe
+TypeFunction isTypeFunction(Dsymbol s) @safe
{
FuncDeclaration f = s.isFuncDeclaration();
/* f.type may be NULL for template members.
@@ -2637,7 +2618,7 @@ private TypeFunction isTypeFunction(Dsymbol s) @safe
/****************************************************
*/
-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)
@@ -2655,7 +2636,7 @@ private Parameter isFunctionParameter(Dsymbol s, const(char)[] str) @safe
/****************************************************
*/
-private Parameter isFunctionParameter(Dsymbols* a, const(char)[] p) @safe
+Parameter isFunctionParameter(Dsymbols* a, const(char)[] p) @safe
{
foreach (Dsymbol sym; *a)
{
@@ -2670,7 +2651,7 @@ private Parameter isFunctionParameter(Dsymbols* a, const(char)[] p) @safe
/****************************************************
*/
-private Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @safe
+Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @safe
{
foreach (Dsymbol dsym; *a)
{
@@ -2718,7 +2699,7 @@ private Parameter isEponymousFunctionParameter(Dsymbols *a, const(char)[] p) @sa
/****************************************************
*/
-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++)
{
@@ -2744,7 +2725,7 @@ private TemplateParameter isTemplateParameter(Dsymbols* a, const(char)* p, size_
* 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 =
[
@@ -2791,7 +2772,7 @@ private bool isReservedName(const(char)[] str) @safe
/****************************************************
* 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
@@ -2811,7 +2792,7 @@ private struct MarkdownDelimiter
/****************************************************
* 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
@@ -3028,7 +3009,7 @@ private struct MarkdownList
/****************************************************
* A Markdown link.
*/
-private struct MarkdownLink
+struct MarkdownLink
{
string href; /// the link destination
string title; /// an optional title for the link
@@ -3607,7 +3588,7 @@ private struct MarkdownLink
/**************************************************
* 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
@@ -3872,7 +3853,7 @@ private struct MarkdownLinkReferences
}
}
-private enum TableColumnAlignment
+enum TableColumnAlignment
{
none,
left,
@@ -3893,7 +3874,7 @@ private enum TableColumnAlignment
* 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')
@@ -3945,7 +3926,7 @@ private size_t parseTableDelimiterRow(ref OutBuffer buf, const size_t iStart, bo
* 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)
@@ -3981,7 +3962,7 @@ private size_t startTable(ref OutBuffer buf, size_t iStart, size_t iEnd, const r
* 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;
@@ -4108,7 +4089,7 @@ private bool replaceTableRow(ref OutBuffer buf, size_t iStart, size_t iEnd, cons
* 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;
@@ -4130,7 +4111,7 @@ private size_t endTable(ref OutBuffer buf, size_t i, ref TableColumnAlignment[]
* 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);
@@ -4148,7 +4129,7 @@ private size_t endRowAndTable(ref OutBuffer buf, size_t iStart, size_t iEnd, con
* 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;
@@ -4417,7 +4398,7 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s
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);
@@ -4626,7 +4607,7 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s
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");
@@ -5002,7 +4983,7 @@ private void highlightText(Scope* sc, Dsymbols* a, Loc loc, ref OutBuffer buf, s
/**************************************************
* 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)
@@ -5037,7 +5018,7 @@ private void highlightCode(Scope* sc, Dsymbol s, ref OutBuffer buf, size_t offse
/****************************************************
*/
-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;
@@ -5119,7 +5100,7 @@ private void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t off
size_t lastOffset = parametersBuf.length;
- .toCBuffer(tp, &parametersBuf, &hgs);
+ toCBuffer(tp, parametersBuf, hgs);
paramLens[parami] = parametersBuf.length - lastOffset;
}
@@ -5163,7 +5144,7 @@ private void highlightCode(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t off
/****************************************
*/
-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++)
{
@@ -5178,7 +5159,7 @@ private void highlightCode3(Scope* sc, ref OutBuffer buf, const(char)* p, const(
/**************************************************
* 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();
@@ -5236,7 +5217,7 @@ private void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t of
* 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
@@ -5252,7 +5233,7 @@ private void highlightCode2(Scope* sc, Dsymbols* a, ref OutBuffer buf, size_t of
/****************************************
* 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] == "...";
}
@@ -5260,6 +5241,7 @@ private bool isCVariadicArg(const(char)[] p) @nogc nothrow pure @safe
/****************************************
* Determine if p points to the start of an identifier.
*/
+@trusted
bool isIdStart(const(char)* p) @nogc nothrow pure
{
dchar c = *p;
@@ -5279,6 +5261,7 @@ bool isIdStart(const(char)* p) @nogc nothrow pure
/****************************************
* Determine if p points to the rest of an identifier.
*/
+@trusted
bool isIdTail(const(char)* p) @nogc nothrow pure
{
dchar c = *p;
@@ -5298,7 +5281,7 @@ bool isIdTail(const(char)* p) @nogc nothrow pure
/****************************************
* 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');
}
@@ -5316,7 +5299,7 @@ int utfStride(const(char)* p) @nogc nothrow pure
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++;
diff --git a/gcc/d/dmd/doc.h b/gcc/d/dmd/doc.h
index 669e308..562427f 100644
--- a/gcc/d/dmd/doc.h
+++ b/gcc/d/dmd/doc.h
@@ -13,4 +13,5 @@
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);
diff --git a/gcc/d/dmd/dscope.d b/gcc/d/dmd/dscope.d
index c2c0628..981e093 100644
--- a/gcc/d/dmd/dscope.d
+++ b/gcc/d/dmd/dscope.d
@@ -169,6 +169,7 @@ extern (C++) struct Scope
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)
diff --git a/gcc/d/dmd/dstruct.d b/gcc/d/dmd/dstruct.d
index 49b9841..a131a8a 100644
--- a/gcc/d/dmd/dstruct.d
+++ b/gcc/d/dmd/dstruct.d
@@ -105,6 +105,7 @@ extern (C++) void semanticTypeInfo(Scope* sc, Type t)
if (!sc) // inline may request TypeInfo.
{
Scope scx;
+ scx.eSink = global.errorSink;
scx._module = sd.getModule();
getTypeInfoType(sd.loc, t, &scx);
sd.requestTypeInfo = true;
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index 0fa4dbc..c9a2c92 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -1801,6 +1801,7 @@ public:
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);
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 378d3e6..ebdd3a8 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -83,7 +83,7 @@ else version = MARS;
enum LOG = false;
-private uint setMangleOverride(Dsymbol s, const(char)[] sym)
+package uint setMangleOverride(Dsymbol s, const(char)[] sym)
{
if (s.isFuncDeclaration() || s.isVarDeclaration())
{
@@ -766,7 +766,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
else
{
OutBuffer buf;
- stcToBuffer(&buf, stc);
+ stcToBuffer(buf, stc);
dsym.error("cannot be `%s`", buf.peekChars());
}
dsym.storage_class &= ~stc; // strip off
@@ -783,7 +783,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (stc)
{
OutBuffer buf;
- stcToBuffer(&buf, stc);
+ stcToBuffer(buf, stc);
dsym.error("cannot be `scope` and `%s`", buf.peekChars());
}
else if (dsym.isMember())
@@ -1121,11 +1121,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
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;
@@ -1512,11 +1510,11 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
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(": ");
@@ -2528,9 +2526,14 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
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;
@@ -2564,7 +2567,9 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
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
@@ -2578,12 +2583,23 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
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;
@@ -2593,13 +2609,21 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
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
{
@@ -3351,7 +3375,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
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
}
@@ -3889,7 +3913,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
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();
@@ -3912,7 +3936,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
}
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`?",
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index e492c7e..67ca2ef 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -750,7 +750,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
{
if (i)
buf.writestring(", ");
- .toCBuffer(tp, &buf, &hgs);
+ toCBuffer(tp, buf, hgs);
}
buf.writeByte(')');
@@ -768,7 +768,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
constraint)
{
buf.writestring(" if (");
- .toCBuffer(constraint, &buf, &hgs);
+ toCBuffer(constraint, buf, hgs);
buf.writeByte(')');
}
@@ -865,7 +865,7 @@ extern (C++) final class TemplateDeclaration : ScopeDsymbol
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);
@@ -6024,14 +6024,14 @@ extern (C++) class TemplateInstance : ScopeDsymbol
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();
}
@@ -6058,11 +6058,9 @@ extern (C++) class TemplateInstance : ScopeDsymbol
{
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);
}
}();
@@ -7056,10 +7054,10 @@ extern (C++) class TemplateInstance : ScopeDsymbol
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)
@@ -7825,7 +7823,7 @@ extern (C++) final class TemplateMixin : TemplateInstance
override const(char)* toChars() const
{
OutBuffer buf;
- toCBufferInstance(this, &buf);
+ toCBufferInstance(this, buf);
return buf.extractChars();
}
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index 6a7442a..d5f658a 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -199,7 +199,8 @@ struct _d_dynamicArray final
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();
}
}
@@ -2327,7 +2328,12 @@ public:
{
//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;
}
}
@@ -2636,7 +2642,7 @@ public:
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);
}
}
diff --git a/gcc/d/dmd/errors.h b/gcc/d/dmd/errors.h
index c6b5975..759ad27 100644
--- a/gcc/d/dmd/errors.h
+++ b/gcc/d/dmd/errors.h
@@ -14,6 +14,7 @@
struct Loc;
+// Constants used to discriminate kinds of error messages.
enum class ErrorKind
{
warning = 0,
@@ -43,7 +44,7 @@ D_ATTRIBUTE_FORMAT(1, 2) void message(const char *format, ...);
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__)
diff --git a/gcc/d/dmd/errorsink.d b/gcc/d/dmd/errorsink.d
index e14829e..ce23517 100644
--- a/gcc/d/dmd/errorsink.d
+++ b/gcc/d/dmd/errorsink.d
@@ -62,6 +62,7 @@ class ErrorSinkNull : ErrorSink
/*****************************************
* Simplest implementation, just sends messages to stderr.
+ * See also: ErrorSinkCompiler.
*/
class ErrorSinkStderr : ErrorSink
{
diff --git a/gcc/d/dmd/escape.d b/gcc/d/dmd/escape.d
index f817a4e..8562e2e 100644
--- a/gcc/d/dmd/escape.d
+++ b/gcc/d/dmd/escape.d
@@ -37,6 +37,8 @@ import dmd.tokens;
import dmd.visitor;
import dmd.arraytypes;
+private:
+
/// Groups global state for escape checking together
package(dmd) struct EscapeState
{
@@ -69,6 +71,7 @@ package(dmd) struct EscapeState
* Returns:
* `true` if error
*/
+public
bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
Expression ethis, Expressions* arguments, bool gag)
{
@@ -179,7 +182,7 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
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");
@@ -226,6 +229,7 @@ bool checkMutableArguments(Scope* sc, FuncDeclaration fd, TypeFunction tf,
* Returns:
* `true` if any elements escaped
*/
+public
bool checkArrayLiteralEscape(Scope *sc, ArrayLiteralExp ae, bool gag)
{
bool errors;
@@ -249,6 +253,7 @@ bool checkArrayLiteralEscape(Scope *sc, ArrayLiteralExp ae, bool gag)
* Returns:
* `true` if any elements escaped
*/
+public
bool checkAssocArrayLiteralEscape(Scope *sc, AssocArrayLiteralExp ae, bool gag)
{
bool errors;
@@ -274,6 +279,7 @@ bool checkAssocArrayLiteralEscape(Scope *sc, AssocArrayLiteralExp ae, bool gag)
* v = parameter that was not inferred
* recursionLimit = recursion limit for printing the reason
*/
+private
void printScopeFailure(E)(E printFunc, VarDeclaration v, int recursionLimit)
{
recursionLimit--;
@@ -316,12 +322,13 @@ void printScopeFailure(E)(E printFunc, VarDeclaration v, int 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())
@@ -334,7 +341,7 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId,
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);
@@ -467,6 +474,7 @@ bool checkParamArgumentEscape(Scope* sc, FuncDeclaration fdc, Identifier parId,
* 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;
@@ -502,6 +510,7 @@ bool checkParamArgumentReturn(Scope* sc, Expression firstArg, Expression arg, Pa
* Returns:
* `true` if construction would cause an escaping reference error
*/
+public
bool checkConstructorEscape(Scope* sc, CallExp ce, bool gag)
{
enum log = false;
@@ -543,6 +552,7 @@ bool checkConstructorEscape(Scope* sc, CallExp ce, bool gag)
}
/// How a `return` parameter escapes its pointer value
+public
enum ReturnParamDest
{
returnVal, /// through return statement: `return x`
@@ -564,6 +574,7 @@ enum ReturnParamDest
* 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);
@@ -596,6 +607,7 @@ ReturnParamDest returnParamDest(TypeFunction tf, Type tthis)
* 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;
@@ -912,7 +924,7 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef)
!(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;
@@ -959,6 +971,7 @@ bool checkAssignEscape(Scope* sc, Expression e, bool gag, bool byRef)
* 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());
@@ -1002,6 +1015,7 @@ bool checkThrowEscape(Scope* sc, Expression e, bool gag)
* Returns:
* `true` if pointers to the stack can escape
*/
+public
bool checkNewEscape(Scope* sc, Expression e, bool gag)
{
import dmd.globals: FeatureState;
@@ -1124,7 +1138,7 @@ bool checkNewEscape(Scope* sc, Expression e, bool gag)
{
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;
}
@@ -1144,6 +1158,7 @@ bool checkNewEscape(Scope* sc, Expression e, bool gag)
* 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());
@@ -1161,6 +1176,7 @@ bool checkReturnEscape(Scope* sc, Expression e, bool gag)
* Returns:
* `true` if references to the stack can escape
*/
+public
bool checkReturnEscapeRef(Scope* sc, Expression e, bool gag)
{
version (none)
@@ -1266,7 +1282,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
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
@@ -1420,7 +1436,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
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;
}
}
@@ -1434,6 +1450,7 @@ private bool checkReturnEscapeImpl(Scope* sc, Expression e, bool refs, bool gag)
* va = variable to infer scope for
* Returns: `true` if succesful or already `scope`
*/
+private
bool inferScope(VarDeclaration va)
{
if (!va)
@@ -1526,6 +1543,7 @@ private bool inferReturn(FuncDeclaration fd, VarDeclaration v, bool returnScope)
* 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());
@@ -1924,6 +1942,7 @@ void escapeByValue(Expression e, EscapeByResults* er, bool live = false, bool re
* 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);
@@ -2158,6 +2177,7 @@ void escapeByRef(Expression e, EscapeByResults* er, bool live = false, bool retR
/************************************
* Aggregate the data collected by the escapeBy??() functions.
*/
+public
struct EscapeByResults
{
VarDeclarations byref; // array into which variables being returned by ref are inserted
@@ -2295,6 +2315,7 @@ private void doNotInferScope(VarDeclaration v, RootObject o)
* 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)
{
@@ -2427,6 +2448,7 @@ private void eliminateMaybeScopes(VarDeclaration[] array)
* Returns:
* true if it's a pointer (or reference) to mutable data
*/
+private
bool isReferenceToMutable(Type t)
{
t = t.baseElemOf();
@@ -2486,6 +2508,7 @@ bool isReferenceToMutable(Type t)
* Returns:
* true if it's a pointer (or reference) to mutable data
*/
+private
bool isReferenceToMutable(Parameter p, Type t)
{
if (p.isReference())
@@ -2561,6 +2584,7 @@ private void addMaybe(VarDeclaration va, VarDeclaration v)
}
// `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)
{
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 07cc8d4..99f6587 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -40,6 +40,7 @@ import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
+import dmd.errorsink;
import dmd.escape;
import dmd.expressionsem;
import dmd.func;
@@ -813,7 +814,7 @@ extern (C++) abstract class Expression : ASTNode
{
OutBuffer buf;
HdrGenState hgs;
- toCBuffer(this, &buf, &hgs);
+ toCBuffer(this, buf, hgs);
return buf.extractChars();
}
@@ -1186,7 +1187,7 @@ extern (C++) abstract class Expression : ASTNode
return checkValue();
}
- extern (D) final bool checkArithmetic()
+ extern (D) final bool checkArithmetic(EXP op)
{
if (op == EXP.error)
return true;
@@ -1194,7 +1195,11 @@ extern (C++) abstract class Expression : ASTNode
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();
@@ -3250,6 +3255,8 @@ extern (C++) final class AssocArrayLiteralExp : Expression
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
{
@@ -4036,13 +4043,11 @@ extern (C++) final class FuncExp : Expression
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;
}
@@ -4055,8 +4060,7 @@ extern (C++) final class FuncExp : Expression
{
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();
@@ -4065,8 +4069,7 @@ extern (C++) final class FuncExp : Expression
{
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;
}
}
@@ -4075,7 +4078,7 @@ extern (C++) final class FuncExp : Expression
{
if (!tof)
{
- return cannotInfer(this, to, flag);
+ return cannotInfer();
}
// Parameter types inference from 'tof'
@@ -4086,7 +4089,7 @@ extern (C++) final class FuncExp : Expression
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);
@@ -4106,7 +4109,7 @@ extern (C++) final class FuncExp : Expression
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);
}
@@ -4124,9 +4127,9 @@ extern (C++) final class FuncExp : Expression
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)
@@ -4198,10 +4201,10 @@ extern (C++) final class FuncExp : Expression
(*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;
@@ -4674,8 +4677,8 @@ extern (C++) abstract class BinExp : Expression
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);
}
@@ -7217,7 +7220,7 @@ extern (C++) final class PrettyFuncInitExp : DefaultInitExp
{
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
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index 1f04c6c..2189757 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -94,7 +94,7 @@ public:
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();
@@ -446,6 +446,7 @@ public:
OwnedBy ownedByCtfe;
Expressions *keys;
Expressions *values;
+ Expression* lowering;
bool equals(const RootObject * const o) const override;
AssocArrayLiteralExp *syntaxCopy() override;
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 69999cb..30382bb 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -1197,6 +1197,11 @@ private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc)
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();
@@ -1206,11 +1211,6 @@ private bool haveSameThis(FuncDeclaration outerFunc, FuncDeclaration calledFunc)
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;
}
@@ -2319,6 +2319,7 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
}
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;
@@ -2331,14 +2332,14 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
{
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
@@ -2528,7 +2529,8 @@ private bool functionParameters(const ref Loc loc, Scope* sc,
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);
@@ -3889,10 +3891,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
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--;
}
}
@@ -4312,7 +4316,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
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();
@@ -5275,10 +5279,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
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`",
@@ -5348,7 +5352,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
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);
@@ -5947,7 +5951,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
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);
}
@@ -5993,7 +5997,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
*/
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;
@@ -7278,7 +7282,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
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())
@@ -7527,7 +7531,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
if (exp.e1.checkNoBool())
return setError();
- if (exp.e1.checkArithmetic() ||
+ if (exp.e1.checkArithmetic(exp.op) ||
exp.e1.checkSharedAccess(sc))
return setError();
@@ -7557,7 +7561,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
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();
@@ -10024,19 +10028,22 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
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();
@@ -10085,17 +10092,20 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
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);
@@ -10785,11 +10795,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
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();
@@ -10891,11 +10901,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
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();
@@ -11032,7 +11042,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
(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();
@@ -11061,7 +11073,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
auto arguments = new Expressions();
- if (global.params.tracegc)
+ if (useTraceGCHook)
{
auto funcname = (sc.callsc && sc.callsc.func) ?
sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
@@ -11088,7 +11100,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
/* `_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())
@@ -12087,8 +12099,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
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"))
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 73f1ba7..bf7ad7e 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -173,7 +173,7 @@ public:
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;
@@ -1311,7 +1311,7 @@ extern (C++) class FuncDeclaration : Declaration
final const(char)* toFullSignature()
{
OutBuffer buf;
- functionToBufferWithIdent(type.toTypeFunction(), &buf, toChars(), isStatic);
+ functionToBufferWithIdent(type.toTypeFunction(), buf, toChars(), isStatic);
return buf.extractChars();
}
@@ -2279,8 +2279,11 @@ extern (C++) class FuncDeclaration : Declaration
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;
}
}
@@ -2657,7 +2660,7 @@ extern (C++) class FuncDeclaration : Declaration
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);
@@ -3340,14 +3343,14 @@ FuncDeclaration resolveFuncCall(const ref Loc loc, Scope* sc, Dsymbol s,
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)
@@ -4623,7 +4626,7 @@ bool setUnsafePreview(Scope* sc, FeatureState fs, bool gag, Loc loc, const(char)
{
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() : "");
}
}
diff --git a/gcc/d/dmd/globals.d b/gcc/d/dmd/globals.d
index af711a0..840074e 100644
--- a/gcc/d/dmd/globals.d
+++ b/gcc/d/dmd/globals.d
@@ -101,6 +101,23 @@ extern(C++) struct Output
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
{
@@ -124,7 +141,6 @@ 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
@@ -143,16 +159,7 @@ extern (C++) struct Param
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=`
@@ -258,6 +265,7 @@ extern (C++) struct Global
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
@@ -281,6 +289,7 @@ extern (C++) struct Global
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;
@@ -337,6 +346,7 @@ extern (C++) struct Global
extern (C++) void _init()
{
errorSink = new ErrorSinkCompiler;
+ errorSinkNull = new ErrorSinkNull;
this.fileManager = new FileManager();
version (MARS)
@@ -369,6 +379,7 @@ extern (C++) struct Global
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;
diff --git a/gcc/d/dmd/globals.h b/gcc/d/dmd/globals.h
index 0ef9eed..e24042a 100644
--- a/gcc/d/dmd/globals.h
+++ b/gcc/d/dmd/globals.h
@@ -96,6 +96,22 @@ struct Output
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
{
@@ -119,7 +135,6 @@ 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
@@ -136,16 +151,7 @@ struct Param
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=`
@@ -265,7 +271,6 @@ struct CompileEnv
bool previewIn;
bool ddocOutput;
bool shortenedMethods;
- bool obsolete;
};
struct Global
@@ -277,6 +282,7 @@ 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;
@@ -296,6 +302,7 @@ struct Global
FileManager* fileManager;
ErrorSink* errorSink; // where the error messages go
+ ErrorSink* errorSinkNull; // where the error messages disappear
FileName (*preprocess)(FileName, const Loc&, bool&, OutBuffer&);
@@ -358,8 +365,8 @@ struct Loc
{
private:
unsigned _linnum;
- unsigned short _charnum;
- unsigned short fileIndex;
+ unsigned _charnum;
+ unsigned fileIndex;
public:
static void set(bool showColumns, MessageStyle messageStyle);
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index 33cbc19..b4c8e8b 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -51,7 +51,6 @@ import dmd.statement;
import dmd.staticassert;
import dmd.target;
import dmd.tokens;
-import dmd.utils;
import dmd.visitor;
struct HdrGenState
@@ -73,16 +72,20 @@ 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);
}
/**
@@ -91,14 +94,14 @@ extern (C++) void genhdrfile(Module m)
* 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)
{
@@ -132,7 +135,7 @@ void moduleToBuffer2(Module m, OutBuffer* buf, HdrGenState* hgs)
}
}
-private void statementToBuffer(Statement s, OutBuffer* buf, HdrGenState* hgs)
+private void statementToBuffer(Statement s, ref OutBuffer buf, HdrGenState* hgs)
{
void visitDefaultCase(Statement s)
{
@@ -201,8 +204,7 @@ private void statementToBuffer(Statement s, OutBuffer* buf, HdrGenState* hgs)
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);
@@ -792,9 +794,9 @@ private void statementToBuffer(Statement s, OutBuffer* buf, HdrGenState* 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);
}
@@ -822,13 +824,13 @@ public:
{
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(");");
@@ -860,13 +862,13 @@ public:
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);
}
}
@@ -916,7 +918,7 @@ public:
bool hasSTC;
if (auto stcd = d.isStorageClassDeclaration)
{
- hasSTC = stcToBuffer(buf, stcd.stc);
+ hasSTC = stcToBuffer(*buf, stcd.stc);
}
if (!d.decl)
@@ -959,7 +961,7 @@ public:
override void visit(DeprecatedDeclaration d)
{
buf.writestring("deprecated(");
- d.msg.expressionToBuffer(buf, hgs);
+ d.msg.expressionToBuffer(*buf, hgs);
buf.writestring(") ");
visit(cast(AttribDeclaration)d);
}
@@ -994,7 +996,7 @@ public:
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(' ');
@@ -1047,7 +1049,7 @@ public:
if (d.args && d.args.length)
{
buf.writestring(", ");
- argsToBuffer(d.args, buf, hgs);
+ argsToBuffer(d.args, *buf, hgs);
}
buf.writeByte(')');
@@ -1065,7 +1067,7 @@ public:
override void visit(ConditionalDeclaration d)
{
- d.condition.conditionToBuffer(buf, hgs);
+ d.condition.conditionToBuffer(*buf, hgs);
if (d.decl || d.elsedecl)
{
buf.writenl();
@@ -1108,15 +1110,15 @@ public:
{
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();
}
@@ -1128,13 +1130,13 @@ public:
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();
}
@@ -1162,7 +1164,7 @@ public:
override void visit(MixinDeclaration d)
{
buf.writestring("mixin(");
- argsToBuffer(d.exps, buf, hgs, null);
+ argsToBuffer(d.exps, *buf, hgs, null);
buf.writestring(");");
buf.writenl();
}
@@ -1170,7 +1172,7 @@ public:
override void visit(UserAttributeDeclaration d)
{
buf.writestring("@(");
- argsToBuffer(d.atts, buf, hgs);
+ argsToBuffer(d.atts, *buf, hgs);
buf.writeByte(')');
visit(cast(AttribDeclaration)d);
}
@@ -1221,9 +1223,9 @@ public:
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);
@@ -1262,10 +1264,10 @@ public:
{
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('(');
@@ -1276,9 +1278,9 @@ public:
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();
@@ -1295,7 +1297,7 @@ public:
{
if (i)
buf.writestring(", ");
- p.templateParameterToBuffer(buf, hgs);
+ p.templateParameterToBuffer(*buf, hgs);
}
}
@@ -1304,27 +1306,27 @@ public:
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(' ');
@@ -1333,7 +1335,7 @@ public:
buf.writeByte(';');
buf.writenl();
if (hgs.fullDump)
- dumpTemplateInstance(tm, buf, hgs);
+ dumpTemplateInstance(tm, *buf, hgs);
}
override void visit(EnumDeclaration d)
@@ -1349,7 +1351,7 @@ public:
if (d.memtype)
{
buf.writestring(" : ");
- typeToBuffer(d.memtype, null, buf, hgs);
+ typeToBuffer(d.memtype, null, *buf, hgs);
}
if (!d.members)
{
@@ -1452,7 +1454,7 @@ public:
{
if (i)
buf.writestring(", ");
- typeToBuffer(b.type, null, buf, hgs);
+ typeToBuffer(b.type, null, *buf, hgs);
}
}
@@ -1465,7 +1467,7 @@ public:
{
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
@@ -1484,18 +1486,18 @@ public:
}
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(';');
@@ -1509,7 +1511,7 @@ public:
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();
}
@@ -1518,69 +1520,18 @@ public:
{
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)
{
@@ -1627,7 +1578,7 @@ public:
{
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;
@@ -1635,7 +1586,7 @@ public:
else
{
buf.writenl();
- frequire.statementToBuffer(buf, hgs);
+ frequire.statementToBuffer(*buf, hgs);
requireDo = true;
}
}
@@ -1655,7 +1606,7 @@ public:
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;
@@ -1669,7 +1620,7 @@ public:
buf.writeByte(')');
}
buf.writenl();
- fensure.ensure.statementToBuffer(buf, hgs);
+ fensure.ensure.statementToBuffer(*buf, hgs);
requireDo = true;
}
}
@@ -1717,7 +1668,7 @@ public:
buf.writeByte('{');
buf.writenl();
buf.level++;
- f.fbody.statementToBuffer(buf, hgs);
+ f.fbody.statementToBuffer(*buf, hgs);
buf.level--;
buf.writeByte('}');
buf.writenl();
@@ -1740,8 +1691,8 @@ public:
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)
@@ -1764,7 +1715,7 @@ public:
if (rs && rs.exp)
{
buf.writestring(" => ");
- rs.exp.expressionToBuffer(buf, hgs);
+ rs.exp.expressionToBuffer(*buf, hgs);
}
else
{
@@ -1776,7 +1727,7 @@ public:
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);
@@ -1784,7 +1735,7 @@ public:
override void visit(DtorDeclaration d)
{
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
buf.writestring("~this()");
bodyToBuffer(d);
@@ -1792,7 +1743,7 @@ public:
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 ");
@@ -1808,7 +1759,7 @@ public:
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 ");
@@ -1826,14 +1777,14 @@ public:
{
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();
}
@@ -1847,7 +1798,7 @@ public:
{
if (hgs.hdrgen)
return;
- if (stcToBuffer(buf, d.storage_class))
+ if (stcToBuffer(*buf, d.storage_class))
buf.writeByte(' ');
buf.writestring("unittest");
bodyToBuffer(d);
@@ -1855,33 +1806,88 @@ public:
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)
{
@@ -1922,7 +1928,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
case Tdchar:
{
const o = buf.length;
- writeSingleCharLiteral(*buf, cast(dchar) v);
+ writeSingleCharLiteral(buf, cast(dchar) v);
if (hgs.ddoc)
escapeDdocString(buf, o);
break;
@@ -2064,7 +2070,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
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);
@@ -2251,8 +2257,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
// 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(')');
@@ -2308,7 +2313,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
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(')');
@@ -2717,7 +2722,7 @@ private void expressionPrettyPrint(Expression e, OutBuffer* buf, HdrGenState* hg
* 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".
@@ -2762,9 +2767,9 @@ void floatToBuffer(Type type, const real_t value, OutBuffer* buf, const bool all
}
}
-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);
}
@@ -2787,12 +2792,12 @@ public:
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);
}
}
@@ -2806,33 +2811,33 @@ public:
{
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);
}
}
@@ -2843,9 +2848,9 @@ public:
}
}
-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);
}
@@ -2885,42 +2890,42 @@ public:
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;
@@ -3039,7 +3044,7 @@ string stcToString(ref StorageClass stc) @safe
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)
@@ -3077,7 +3082,7 @@ string linkageToString(LINK linkage) pure nothrow @safe
}
}
-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)
@@ -3121,28 +3126,28 @@ extern (D) string visibilityToString(Visibility.Kind kind) nothrow pure @safe
}
// 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;
@@ -3155,13 +3160,13 @@ void argExpTypesToCBuffer(OutBuffer* buf, Expressions* arguments)
}
}
-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;
@@ -3184,7 +3189,7 @@ extern (C++) const(char)* parametersTypeToChars(ParameterList pl)
{
OutBuffer buf;
HdrGenState hgs;
- parametersToBuffer(pl, &buf, &hgs);
+ parametersToBuffer(pl, buf, &hgs);
return buf.extractChars();
}
@@ -3202,7 +3207,7 @@ const(char)* parameterToChars(Parameter parameter, TypeFunction tf, bool fullQua
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])
{
@@ -3220,7 +3225,7 @@ const(char)* parameterToChars(Parameter parameter, TypeFunction tf, bool fullQua
* 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)
@@ -3258,7 +3263,7 @@ private void parametersToBuffer(ParameterList pl, OutBuffer* buf, HdrGenState* h
* 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)
{
@@ -3330,7 +3335,7 @@ private void parameterToBuffer(Parameter p, OutBuffer* buf, HdrGenState* hgs)
* 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;
@@ -3381,7 +3386,7 @@ private void argsToBuffer(Expressions* expressions, OutBuffer* buf, HdrGenState*
}
}
-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)
{
@@ -3409,7 +3414,7 @@ private void sizeToBuffer(Expression e, OutBuffer* buf, HdrGenState* hgs)
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);
}
@@ -3418,7 +3423,7 @@ private void expressionToBuffer(Expression e, OutBuffer* buf, HdrGenState* 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
{
@@ -3452,7 +3457,7 @@ private void expToBuffer(Expression e, PREC pr, OutBuffer* buf, HdrGenState* hgs
/**************************************************
* 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())
@@ -3468,7 +3473,7 @@ private void typeToBuffer(Type t, const Identifier ident, OutBuffer* buf, HdrGen
}
}
-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)
@@ -3504,7 +3509,7 @@ private void visitWithMask(Type t, ubyte modMask, OutBuffer* buf, HdrGenState* h
}
-private void dumpTemplateInstance(TemplateInstance ti, OutBuffer* buf, HdrGenState* hgs)
+private void dumpTemplateInstance(TemplateInstance ti, ref OutBuffer buf, HdrGenState* hgs)
{
buf.writeByte('{');
buf.writenl();
@@ -3527,7 +3532,7 @@ private void dumpTemplateInstance(TemplateInstance ti, OutBuffer* buf, HdrGenSta
}
-private void tiargsToBuffer(TemplateInstance ti, OutBuffer* buf, HdrGenState* hgs)
+private void tiargsToBuffer(TemplateInstance ti, ref OutBuffer buf, HdrGenState* hgs)
{
buf.writeByte('!');
if (ti.nest)
@@ -3576,7 +3581,7 @@ private void tiargsToBuffer(TemplateInstance ti, OutBuffer* buf, HdrGenState* hg
* 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()
@@ -3629,7 +3634,7 @@ private void objectToBuffer(RootObject oarg, OutBuffer* buf, HdrGenState* hgs)
}
-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)
{
@@ -3674,7 +3679,7 @@ private void visitFuncIdentWithPostfix(TypeFunction t, const char[] ident, OutBu
}
private void visitFuncIdentWithPrefix(TypeFunction t, const Identifier ident, TemplateDeclaration td,
- OutBuffer* buf, HdrGenState* hgs)
+ ref OutBuffer buf, HdrGenState* hgs)
{
if (t.inuse)
{
@@ -3743,7 +3748,7 @@ private void visitFuncIdentWithPrefix(TypeFunction t, const Identifier ident, Te
}
-private void initializerToBuffer(Initializer inx, OutBuffer* buf, HdrGenState* hgs)
+private void initializerToBuffer(Initializer inx, ref OutBuffer buf, HdrGenState* hgs)
{
void visitError(ErrorInitializer iz)
{
@@ -3811,7 +3816,7 @@ private void initializerToBuffer(Initializer inx, OutBuffer* buf, HdrGenState* h
if (d.exp)
{
buf.writeByte('[');
- toCBuffer(d.exp, buf, hgs);
+ toCBuffer(d.exp, buf, *hgs);
buf.writeByte(']');
}
else
@@ -3832,7 +3837,7 @@ private void initializerToBuffer(Initializer inx, OutBuffer* buf, HdrGenState* h
}
-private void typeToBufferx(Type t, OutBuffer* buf, HdrGenState* hgs)
+private void typeToBufferx(Type t, ref OutBuffer buf, HdrGenState* hgs)
{
void visitType(Type t)
{
@@ -4020,7 +4025,7 @@ private void typeToBufferx(Type t, OutBuffer* buf, HdrGenState* hgs)
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);
diff --git a/gcc/d/dmd/hdrgen.h b/gcc/d/dmd/hdrgen.h
index 43fea34..e43a355 100644
--- a/gcc/d/dmd/hdrgen.h
+++ b/gcc/d/dmd/hdrgen.h
@@ -15,7 +15,7 @@
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);
diff --git a/gcc/d/dmd/iasmgcc.d b/gcc/d/dmd/iasmgcc.d
index 1d4dea4..5494fec 100644
--- a/gcc/d/dmd/iasmgcc.d
+++ b/gcc/d/dmd/iasmgcc.d
@@ -330,7 +330,7 @@ extern (C++) public Statement gccAsmSemantic(GccAsmStatement s, Scope *sc)
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)
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index 43b2e5f..62fb51f 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -114,6 +114,7 @@ immutable Msgtable[] msgtable =
{ "returnLabel", "__returnLabel" },
{ "line" },
{ "empty", "" },
+ { "dotdotdot", "..." }, // use for error messages
{ "p" },
{ "__vptr" },
{ "__monitor" },
@@ -305,6 +306,7 @@ immutable Msgtable[] msgtable =
{ "aaKeys", "_aaKeys" },
{ "aaValues", "_aaValues" },
{ "aaRehash", "_aaRehash" },
+ { "_aaAsStruct" },
{ "monitorenter", "_d_monitorenter" },
{ "monitorexit", "_d_monitorexit" },
{ "criticalenter", "_d_criticalenter2" },
diff --git a/gcc/d/dmd/init.d b/gcc/d/dmd/init.d
index e7cf905..4501185 100644
--- a/gcc/d/dmd/init.d
+++ b/gcc/d/dmd/init.d
@@ -61,7 +61,7 @@ extern (C++) class Initializer : ASTNode
{
OutBuffer buf;
HdrGenState hgs;
- .toCBuffer(this, &buf, &hgs);
+ toCBuffer(this, buf, hgs);
return buf.extractChars();
}
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index c60b431..45f09af8 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -53,31 +53,38 @@ import dmd.typesem;
*/
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();
}
/******************************************
diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d
index 9689986..c803bf8 100644
--- a/gcc/d/dmd/json.d
+++ b/gcc/d/dmd/json.d
@@ -810,17 +810,14 @@ public:
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();
}
@@ -981,9 +978,15 @@ public:
}
}
-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');
diff --git a/gcc/d/dmd/json.h b/gcc/d/dmd/json.h
index 7a23897..09fdecd 100644
--- a/gcc/d/dmd/json.h
+++ b/gcc/d/dmd/json.h
@@ -15,5 +15,5 @@
struct OutBuffer;
-void json_generate(OutBuffer *, Modules *);
+void json_generate(Modules &, OutBuffer &);
JsonFieldFlags tryParseJsonField(const char *fieldName);
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index c28fe5c..28ffbf8 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -51,7 +51,7 @@ struct CompileEnv
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
}
/***********************************************************
@@ -484,6 +484,12 @@ class Lexer
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;
@@ -526,7 +532,7 @@ class Lexer
//case 'u':
case 'v':
case 'w':
- case 'x':
+ /*case 'x':*/
case 'y':
case 'z':
case 'A':
@@ -1476,6 +1482,84 @@ class Lexer
}
}
+ /**************************************
+ * 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:
---
diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d
index 0f3b9a7..ef2bd0a 100644
--- a/gcc/d/dmd/location.d
+++ b/gcc/d/dmd/location.d
@@ -38,8 +38,8 @@ debug info etc.
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
@@ -67,7 +67,7 @@ nothrow:
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;
}
@@ -80,7 +80,7 @@ nothrow:
/// ditto
extern (C++) uint charnum(uint num) @nogc @safe
{
- return _charnum = cast(ushort) num;
+ return _charnum = num;
}
/// line number, starting from 1
@@ -114,8 +114,16 @@ nothrow:
{
//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;
diff --git a/gcc/d/dmd/module.h b/gcc/d/dmd/module.h
index 8b48110..ce51266 100644
--- a/gcc/d/dmd/module.h
+++ b/gcc/d/dmd/module.h
@@ -142,7 +142,7 @@ public:
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
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index 9d83db1..63e20ed 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -157,7 +157,7 @@ MOD MODmerge(MOD mod1, MOD mod2) pure nothrow @nogc @safe
/*********************************
* 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));
}
@@ -787,7 +787,7 @@ extern (C++) abstract class Type : ASTNode
HdrGenState hgs;
hgs.fullQual = (ty == Tclass && !mod);
- .toCBuffer(this, &buf, null, &hgs);
+ toCBuffer(this, buf, null, hgs);
return buf.extractChars();
}
@@ -799,7 +799,7 @@ extern (C++) abstract class Type : ASTNode
HdrGenState hgs;
hgs.fullQual = QualifyTypes;
- .toCBuffer(this, &buf, null, &hgs);
+ toCBuffer(this, buf, null, hgs);
return buf.extractChars();
}
@@ -973,7 +973,7 @@ extern (C++) abstract class Type : ASTNode
/*********************************
* 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)
{
@@ -989,7 +989,7 @@ extern (C++) abstract class Type : ASTNode
{
OutBuffer buf;
buf.reserve(16);
- modToBuffer(&buf);
+ modToBuffer(buf);
return buf.extractChars();
}
@@ -4563,7 +4563,7 @@ extern (C++) final class TypeFunction : TypeNext
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;
@@ -6218,7 +6218,7 @@ extern (C++) final class TypeTuple : Type
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;
}
}
@@ -6244,15 +6244,15 @@ extern (C++) final class TypeTuple : Type
{
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
@@ -6661,14 +6661,16 @@ extern (C++) final class Parameter : ASTNode
{
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;
@@ -6676,14 +6678,14 @@ extern (C++) final class Parameter : ASTNode
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);
}
/****************************************************
@@ -7688,3 +7690,28 @@ pure string visitTYCase(string handler) @safe
}
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;
+}
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 457b91f..aeeee8c 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -237,7 +237,7 @@ public:
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();
@@ -563,13 +563,14 @@ enum class PURE : unsigned char
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();
diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d
index 457e8b6..f9de1ee 100644
--- a/gcc/d/dmd/opover.d
+++ b/gcc/d/dmd/opover.d
@@ -1767,10 +1767,10 @@ private FuncDeclaration findBestOpApplyMatch(Expression ethis, FuncDeclaration f
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;
}
diff --git a/gcc/d/dmd/optimize.d b/gcc/d/dmd/optimize.d
index f98e7c7..3756382 100644
--- a/gcc/d/dmd/optimize.d
+++ b/gcc/d/dmd/optimize.d
@@ -1280,19 +1280,25 @@ Expression Expression_optimize(Expression e, int result, bool keepLvalue)
//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())
{
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 13bba4f..2a96415 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -1204,7 +1204,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (orig & added)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, added);
+ AST.stcToBuffer(buf, added);
error("redundant attribute `%s`", buf.peekChars());
return orig | added;
}
@@ -2007,6 +2007,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
case TOK.wcharLiteral:
case TOK.dcharLiteral:
case TOK.string_:
+ case TOK.hexadecimalString:
case TOK.file:
case TOK.fileFullPath:
case TOK.line:
@@ -2545,7 +2546,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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);
@@ -2580,7 +2581,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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);
@@ -2619,7 +2620,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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);
@@ -2653,7 +2654,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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);
@@ -2837,7 +2838,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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;
}
@@ -2935,11 +2936,12 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
//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();
@@ -2951,7 +2953,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
else
{
- at = parseType(&ai);
+ at = parseType(&ai, null, &loc);
}
ae = null;
if (token.value == TOK.assign) // = defaultArg
@@ -2959,7 +2961,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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();
@@ -3083,7 +3085,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
else
{
OutBuffer buf;
- AST.stcToBuffer(&buf, _stc);
+ AST.stcToBuffer(buf, _stc);
error(attributeErrorMessage, buf.peekChars());
}
nextToken();
@@ -3284,8 +3286,14 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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();
}
@@ -3481,8 +3489,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
* 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:
@@ -3539,6 +3548,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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);
@@ -4575,8 +4586,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
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);
@@ -4953,7 +4966,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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());
@@ -5108,7 +5121,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (save == TOK.function_)
{
OutBuffer buf;
- AST.stcToBuffer(&buf, modStc);
+ AST.stcToBuffer(buf, modStc);
error("function literal cannot be `%s`", buf.peekChars());
}
else
@@ -5126,7 +5139,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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);
@@ -5443,6 +5456,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
{
Identifier ai = null;
AST.Type at;
+ Loc aloc;
StorageClass storageClass = 0;
StorageClass stc = 0;
@@ -5524,6 +5538,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
lastai = token.ident;
ai = token.ident;
at = null; // infer argument type
+ aloc = token.loc;
nextToken();
goto Larg;
}
@@ -5532,7 +5547,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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)
{
@@ -5684,16 +5699,18 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
{
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());
@@ -5789,6 +5806,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
case TOK.true_:
case TOK.false_:
case TOK.string_:
+ case TOK.hexadecimalString:
case TOK.leftParenthesis:
case TOK.cast_:
case TOK.mul:
@@ -5816,7 +5834,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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)
@@ -5841,11 +5859,14 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
* 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();
}
}
@@ -6580,7 +6601,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
case TOK.asm_:
- s = parseAsm();
+ s = parseAsm(false);
break;
case TOK.import_:
@@ -6951,10 +6972,12 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
* 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.
@@ -6977,6 +7000,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
size_t nestlevel = 0;
while (1)
{
+ if (endOfLine)
+ nextDefineLine();
switch (token.value)
{
case TOK.identifier:
@@ -7011,6 +7036,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
break;
+ case TOK.endOfLine:
+ nextDefineLine();
+ goto case;
+
case TOK.semicolon:
if (nestlevel != 0)
error("mismatched number of curly brackets");
@@ -7018,7 +7047,9 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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)
@@ -7062,6 +7093,8 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
break;
}
nextToken();
+ if (token.value == TOK.endOfLine)
+ nextToken();
auto s = new AST.CompoundAsmStatement(loc, statements, stc);
return s;
}
@@ -7291,6 +7324,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
case TOK.wcharLiteral:
case TOK.dcharLiteral:
case TOK.string_:
+ case TOK.hexadecimalString:
case TOK.file:
case TOK.fileFullPath:
case TOK.line:
@@ -7562,7 +7596,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
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:
@@ -7581,6 +7615,23 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
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)
{
@@ -8148,6 +8199,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
break;
case TOK.string_:
+ case TOK.hexadecimalString:
{
// cat adjacent strings
auto s = token.ustring;
@@ -8157,7 +8209,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
{
const prev = token;
nextToken();
- if (token.value == TOK.string_)
+ if (token.value == TOK.string_ || token.value == TOK.hexadecimalString)
{
if (token.postfix)
{
@@ -9549,7 +9601,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
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.");
}
diff --git a/gcc/d/dmd/printast.d b/gcc/d/dmd/printast.d
index e43ffad..e1deb2c 100644
--- a/gcc/d/dmd/printast.d
+++ b/gcc/d/dmd/printast.d
@@ -64,7 +64,7 @@ extern (C++) final class PrintASTVisitor : Visitor
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() : "");
}
diff --git a/gcc/d/dmd/safe.d b/gcc/d/dmd/safe.d
index c3fa90d..bd531c0 100644
--- a/gcc/d/dmd/safe.d
+++ b/gcc/d/dmd/safe.d
@@ -51,7 +51,7 @@ bool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg)
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)
@@ -65,6 +65,11 @@ bool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg)
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);
@@ -74,9 +79,23 @@ bool checkUnsafeAccess(Scope* sc, Expression e, bool readonly, bool printmsg)
{
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);
+ }
}
}
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index 53c8714..e2d2e04 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -275,6 +275,7 @@ private extern(C++) final class Semantic2Visitor : Visitor
// 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)
@@ -819,3 +820,55 @@ private void doGNUABITagSemantic(ref Expression e, ref Expression* lastTag)
}
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;
+ }
+}
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index bff89f8..04f57a4 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -471,7 +471,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
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)
@@ -749,7 +749,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
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());
@@ -993,7 +993,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
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)
@@ -1040,7 +1040,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
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)
@@ -1177,7 +1177,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
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;
@@ -1187,7 +1187,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
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);
@@ -1453,7 +1453,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
{
// 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)
diff --git a/gcc/d/dmd/statement.d b/gcc/d/dmd/statement.d
index 607dd51..58550fe 100644
--- a/gcc/d/dmd/statement.d
+++ b/gcc/d/dmd/statement.d
@@ -16,20 +16,14 @@ module dmd.statement;
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;
@@ -37,40 +31,14 @@ import dmd.hdrgen;
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
*/
@@ -118,64 +86,11 @@ extern (C++) abstract class Statement : ASTNode
{
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;
@@ -1252,9 +1167,10 @@ extern (C++) final class SwitchStatement : Statement
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;
@@ -1813,22 +1729,22 @@ extern (C++) final class GotoStatement : Statement
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;
}
@@ -1837,7 +1753,7 @@ extern (C++) final class GotoStatement : Statement
{
if (!stb)
{
- error("cannot `goto` into `try` block");
+ error(loc, "cannot `goto` into `try` block");
return true;
}
if (auto stf = stb.isTryFinallyStatement())
@@ -1863,17 +1779,15 @@ extern (C++) final class GotoStatement : Statement
{
// 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;
}
@@ -1959,6 +1873,7 @@ extern (C++) final class LabelDsymbol : Dsymbol
extern (C++) class AsmStatement : Statement
{
Token* tokens;
+ bool caseSensitive; // for register names
extern (D) this(const ref Loc loc, Token* tokens) @safe
{
diff --git a/gcc/d/dmd/statement.h b/gcc/d/dmd/statement.h
index eb4849d..dd8b9f2 100644
--- a/gcc/d/dmd/statement.h
+++ b/gcc/d/dmd/statement.h
@@ -116,7 +116,7 @@ public:
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;
@@ -712,6 +712,7 @@ class AsmStatement : public Statement
{
public:
Token *tokens;
+ bool caseSensitive; // for register names
AsmStatement *syntaxCopy() override;
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index 178cef5..304cb86 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -38,6 +38,7 @@ import dmd.dsymbol;
import dmd.dsymbolsem;
import dmd.dtemplate;
import dmd.errors;
+import dmd.errorsink;
import dmd.escape;
import dmd.expression;
import dmd.expressionsem;
@@ -349,7 +350,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
@@ -704,7 +705,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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;
}
@@ -753,7 +754,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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))
@@ -815,11 +816,11 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
@@ -845,11 +846,11 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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");
}
}
@@ -861,7 +862,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
void rangeError()
{
- fs.error("cannot infer argument types");
+ error(fs.loc, "cannot infer argument types");
return retError();
}
@@ -959,7 +960,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
@@ -978,7 +979,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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:
@@ -990,7 +991,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
(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());
}
}
@@ -1007,7 +1008,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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)
@@ -1015,7 +1016,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
}
@@ -1036,7 +1037,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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();
}
@@ -1048,7 +1049,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
@@ -1071,7 +1072,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
@@ -1197,13 +1198,13 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
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());
@@ -1308,7 +1309,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
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();
}
@@ -1348,7 +1349,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
@@ -1371,7 +1372,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
@@ -1399,12 +1400,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
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();
}
}
@@ -1421,7 +1422,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
@@ -1430,7 +1431,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
@@ -1584,7 +1585,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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();
}
}
@@ -1762,14 +1763,14 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
/* 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
@@ -1789,7 +1790,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
/* 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)
@@ -1805,13 +1806,32 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
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();
}
@@ -1819,7 +1839,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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);
@@ -1885,7 +1905,7 @@ Statement statementSemanticVisit(Statement s, Scope* 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;
@@ -1924,7 +1944,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (!gcs.exp)
{
- gcs.error("no `case` statement following `goto case;`");
+ error(gcs.loc, "no `case` statement following `goto case;`");
sc.pop();
return setError();
}
@@ -1942,7 +1962,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
}
}
- gcs.error("`case %s` not found", gcs.exp.toChars());
+ error(gcs.loc, "`case %s` not found", gcs.exp.toChars());
sc.pop();
return setError();
}
@@ -1975,7 +1995,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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());
@@ -2000,7 +2020,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
@@ -2051,7 +2071,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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);
@@ -2193,12 +2213,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
*/
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;
}
@@ -2213,7 +2233,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
@@ -2229,7 +2249,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
@@ -2242,7 +2262,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
@@ -2265,18 +2285,18 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
@@ -2299,7 +2319,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
@@ -2307,7 +2327,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
@@ -2336,14 +2356,14 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
@@ -2385,30 +2405,30 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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;
}
@@ -2429,12 +2449,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
@@ -2447,7 +2467,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
if (!sc.sw)
{
- gcs.error("`goto case` not in `switch` statement");
+ error(gcs.loc, "`goto case` not in `switch` statement");
return setError();
}
@@ -2512,7 +2532,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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)
@@ -2521,18 +2541,18 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
// 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;
}
@@ -2540,7 +2560,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
if (rs.exp)
{
- rs.error("cannot return expression from constructor");
+ error(rs.loc, "cannot return expression from constructor");
errors = true;
}
@@ -2595,7 +2615,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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);
@@ -2655,7 +2675,7 @@ Statement statementSemanticVisit(Statement s, Scope* 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,
@@ -2697,7 +2717,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
/* 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(
@@ -2736,7 +2761,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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;
@@ -2755,15 +2780,15 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
@@ -2777,7 +2802,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
// 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;
}
@@ -2790,7 +2815,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
}
@@ -2904,9 +2929,9 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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;
@@ -2916,14 +2941,14 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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)
{
@@ -2932,12 +2957,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
@@ -2992,9 +3017,9 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
{
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;
@@ -3003,14 +3028,14 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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)
{
@@ -3019,12 +3044,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
@@ -3050,7 +3075,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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())
@@ -3060,7 +3085,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
*/
if (!ClassDeclaration.object)
{
- ss.error("missing or corrupt object.d");
+ error(ss.loc, "missing or corrupt object.d");
fatal();
}
@@ -3085,7 +3110,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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));
@@ -3127,7 +3152,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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);
@@ -3137,7 +3162,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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);
@@ -3177,7 +3202,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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);
@@ -3252,7 +3277,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
}
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();
}
}
@@ -3281,13 +3306,13 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
@@ -3320,7 +3345,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
}
@@ -3331,7 +3356,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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;
}
}
@@ -3353,7 +3378,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
/* 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)
{
@@ -3403,7 +3428,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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))
@@ -3429,7 +3454,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
// 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();
}
@@ -3439,12 +3464,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
}
}
@@ -3556,12 +3581,12 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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();
@@ -3620,14 +3645,14 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
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");
@@ -3696,7 +3721,7 @@ public bool throwSemantic(const ref Loc loc, ref Expression exp, Scope* sc)
{
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;
}
@@ -3767,7 +3792,7 @@ private extern(D) Expression applyOpApply(ForeachStatement fs, Expression flde,
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;
@@ -3792,7 +3817,7 @@ private extern(D) Expression applyDelegate(ForeachStatement fs, Expression flde,
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;
@@ -3841,13 +3866,13 @@ private extern(D) Expression applyArray(ForeachStatement fs, Expression flde,
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())
@@ -3879,7 +3904,7 @@ private extern(D) Expression applyAssocArray(ForeachStatement fs, Expression fld
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;
}
@@ -3890,7 +3915,7 @@ private extern(D) Expression applyAssocArray(ForeachStatement fs, Expression fld
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;
}
@@ -3908,14 +3933,14 @@ private extern(D) Expression applyAssocArray(ForeachStatement fs, Expression fld
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);
}
@@ -4000,7 +4025,7 @@ private FuncExp foreachBodyToFunction(Scope* sc, ForeachStatement fs, TypeFuncti
{
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;
@@ -4026,7 +4051,7 @@ private FuncExp foreachBodyToFunction(Scope* sc, ForeachStatement fs, TypeFuncti
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.
@@ -4328,7 +4353,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
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();
}
@@ -4390,7 +4415,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
// 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();
}
@@ -4405,7 +4430,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
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();
}
@@ -4416,7 +4441,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
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();
}
@@ -4450,7 +4475,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
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;
@@ -4478,7 +4503,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
}
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;
}
@@ -4487,12 +4512,12 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
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;
}
}
@@ -4501,7 +4526,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
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;
}
}
@@ -4522,17 +4547,17 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
{
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;
@@ -4548,7 +4573,7 @@ public auto makeTupleForeach(Scope* sc, bool isStatic, bool isDecl, ForeachState
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;
}
}
diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d
index 950c830..c76d549 100644
--- a/gcc/d/dmd/tokens.d
+++ b/gcc/d/dmd/tokens.d
@@ -124,6 +124,7 @@ enum TOK : ubyte
// Leaf operators
identifier,
string_,
+ hexadecimalString,
this_,
super_,
error,
@@ -855,6 +856,7 @@ extern (C++) struct Token
TOK.wcharLiteral: "wcharv",
TOK.dcharLiteral: "dcharv",
TOK.wchar_tLiteral: "wchar_tv",
+ TOK.hexadecimalString: "xstring",
TOK.endOfLine: "\\n",
TOK.whitespace: "whitespace",
@@ -898,7 +900,7 @@ extern (C++) struct Token
nothrow:
- int isKeyword() const @safe
+ int isKeyword() pure const @safe @nogc
{
foreach (kw; keywords)
{
@@ -1014,6 +1016,24 @@ nothrow:
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_:
diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h
index 6c1b979..b1f633f 100644
--- a/gcc/d/dmd/tokens.h
+++ b/gcc/d/dmd/tokens.h
@@ -133,6 +133,7 @@ enum class TOK : unsigned char
// Leaf operators
identifier,
string_,
+ hexadecimalString,
this_,
super_,
error,
diff --git a/gcc/d/dmd/traits.d b/gcc/d/dmd/traits.d
index 0d9c95f..2bde9f2 100644
--- a/gcc/d/dmd/traits.d
+++ b/gcc/d/dmd/traits.d
@@ -1920,7 +1920,7 @@ Expression semanticTraits(TraitsExp e, Scope* sc)
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);
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index a80aa80..1422689 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -1170,8 +1170,8 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* 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());
@@ -1179,7 +1179,7 @@ extern(C++) Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
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);
@@ -2089,6 +2089,7 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
{
e = new StringExp(loc, mt.deco.toDString());
Scope sc;
+ sc.eSink = global.errorSink;
e = e.expressionSemantic(&sc);
}
}
@@ -2097,6 +2098,7 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
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)
@@ -2127,7 +2129,9 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
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))
@@ -2135,6 +2139,9 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
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();
@@ -3482,7 +3489,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
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_;
@@ -3938,6 +3945,8 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
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;
@@ -4791,7 +4800,7 @@ Type stripDefaultArgs(Type t)
{
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;
}
diff --git a/gcc/d/dmd/utils.d b/gcc/d/dmd/utils.d
index dfb4cb5..bb389b6 100644
--- a/gcc/d/dmd/utils.d
+++ b/gcc/d/dmd/utils.d
@@ -53,12 +53,6 @@ const(char)* toWinPath(const(char)* src)
* 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);
@@ -78,15 +72,19 @@ Buffer readFile(Loc loc, const(char)[] 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;
}
@@ -97,8 +95,10 @@ extern (D) void writeFile(Loc loc, const(char)[] filename, const void[] data)
* 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)
@@ -106,10 +106,12 @@ void ensurePathToNameExists(Loc loc, const(char)[] name)
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;
}