aboutsummaryrefslogtreecommitdiff
path: root/gcc/d/dmd
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2025-03-14 01:36:45 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2025-03-16 20:49:55 +0100
commit26c4ea2ebcdcd0aa26350d04dc4cd38348148bd9 (patch)
treeabe80e8d65acfee1b474c17cdbbb6c04894cac96 /gcc/d/dmd
parent427972b2f1335c7430785ad4afd15386a17156ec (diff)
downloadgcc-26c4ea2ebcdcd0aa26350d04dc4cd38348148bd9.zip
gcc-26c4ea2ebcdcd0aa26350d04dc4cd38348148bd9.tar.gz
gcc-26c4ea2ebcdcd0aa26350d04dc4cd38348148bd9.tar.bz2
d: Merge upstream dmd, druntime 53a1cc8d13
D front-end changes: - Typesafe variadic class parameters have been deprecated. D runtime changes: - Added `entry' field to TypeInfo_AssociativeArray. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream dmd 53a1cc8d13. * d-tree.h (create_typeinfo): Change second parameter to Scope *. (speculative_type_p): Remove prototype. * d-frontend.cc (getTypeInfoType): Adjust. * decl.cc: Include dmd/typinf.h. (DeclVisitor::visit (TypeInfoDeclaration *)): Update for new front-end interface. * typeinfo.cc (create_typeinfo): Likewise. (class SpeculativeTypeVisitor): Remove class. (speculative_type_p): Remove function. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream druntime 53a1cc8d13. gcc/testsuite/ChangeLog: * gdc.dg/pr100967.d: Adjust error message.
Diffstat (limited to 'gcc/d/dmd')
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/attrib.d7
-rw-r--r--gcc/d/dmd/attrib.h1
-rw-r--r--gcc/d/dmd/common/charactertables.d3
-rw-r--r--gcc/d/dmd/cparse.d11
-rw-r--r--gcc/d/dmd/cxxfrontend.d13
-rw-r--r--gcc/d/dmd/dcast.d3
-rw-r--r--gcc/d/dmd/declaration.d39
-rw-r--r--gcc/d/dmd/declaration.h8
-rw-r--r--gcc/d/dmd/dinterpret.d6
-rw-r--r--gcc/d/dmd/doc.d4
-rw-r--r--gcc/d/dmd/dsymbol.d4
-rw-r--r--gcc/d/dmd/dsymbol.h1
-rw-r--r--gcc/d/dmd/dsymbolsem.d41
-rw-r--r--gcc/d/dmd/dtemplate.d14
-rw-r--r--gcc/d/dmd/dtoh.d3
-rw-r--r--gcc/d/dmd/expression.d3
-rw-r--r--gcc/d/dmd/expressionsem.d259
-rw-r--r--gcc/d/dmd/file_manager.d31
-rw-r--r--gcc/d/dmd/func.d8
-rw-r--r--gcc/d/dmd/hdrgen.d97
-rw-r--r--gcc/d/dmd/id.d1
-rw-r--r--gcc/d/dmd/identifier.d7
-rw-r--r--gcc/d/dmd/initsem.d2
-rw-r--r--gcc/d/dmd/json.d7
-rw-r--r--gcc/d/dmd/lambdacomp.d3
-rw-r--r--gcc/d/dmd/lexer.d9
-rw-r--r--gcc/d/dmd/location.d55
-rw-r--r--gcc/d/dmd/mtype.d20
-rw-r--r--gcc/d/dmd/mtype.h4
-rw-r--r--gcc/d/dmd/parse.d52
-rw-r--r--gcc/d/dmd/root/string.d4
-rw-r--r--gcc/d/dmd/semantic2.d2
-rw-r--r--gcc/d/dmd/semantic3.d40
-rw-r--r--gcc/d/dmd/sideeffect.d10
-rw-r--r--gcc/d/dmd/statementsem.d4
-rw-r--r--gcc/d/dmd/tokens.d17
-rw-r--r--gcc/d/dmd/typesem.d107
-rw-r--r--gcc/d/dmd/typinf.d74
-rw-r--r--gcc/d/dmd/typinf.h4
40 files changed, 643 insertions, 337 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 59d5a18..66cfdd6 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-ffbad272b649b7ae3e88cfdc85688bfef3168994
+53a1cc8d13e8db2cb1642219320a8dfc1b0cc6c5
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/attrib.d b/gcc/d/dmd/attrib.d
index f5618f1..df04ed1 100644
--- a/gcc/d/dmd/attrib.d
+++ b/gcc/d/dmd/attrib.d
@@ -32,7 +32,7 @@ import dmd.declaration;
import dmd.dmodule;
import dmd.dscope;
import dmd.dsymbol;
-import dmd.dsymbolsem : setScope, addMember, include;
+import dmd.dsymbolsem : include;
import dmd.expression;
import dmd.func;
import dmd.globals;
@@ -125,11 +125,6 @@ extern (C++) abstract class AttribDeclaration : Dsymbol
return this.include(null).foreachDsymbol( (s) { return s.hasStaticCtorOrDtor(); } ) != 0;
}
- override final void checkCtorConstInit()
- {
- this.include(null).foreachDsymbol( s => s.checkCtorConstInit() );
- }
-
/****************************************
*/
override final void addObjcSymbols(ClassDeclarations* classes, ClassDeclarations* categories)
diff --git a/gcc/d/dmd/attrib.h b/gcc/d/dmd/attrib.h
index 79b0cb0..ab5f219 100644
--- a/gcc/d/dmd/attrib.h
+++ b/gcc/d/dmd/attrib.h
@@ -32,7 +32,6 @@ public:
bool oneMember(Dsymbol *&ps, Identifier *ident) override;
bool hasPointers() override final;
bool hasStaticCtorOrDtor() override final;
- void checkCtorConstInit() override final;
AttribDeclaration *isAttribDeclaration() override { return this; }
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/common/charactertables.d b/gcc/d/dmd/common/charactertables.d
index ac89807..6a3b302 100644
--- a/gcc/d/dmd/common/charactertables.d
+++ b/gcc/d/dmd/common/charactertables.d
@@ -42,7 +42,8 @@ struct IdentifierCharLookup
// Awful solution to require these lambdas.
// However without them the extern(C++) ABI issues crop up for isInRange,
// and then it can't access the tables.
- final switch(table) {
+ final switch(table)
+ {
case IdentifierTable.UAX31:
return IdentifierCharLookup(
(c) => isInRange!UAX31_Start(c),
diff --git a/gcc/d/dmd/cparse.d b/gcc/d/dmd/cparse.d
index 548bee9..9f1eab7 100644
--- a/gcc/d/dmd/cparse.d
+++ b/gcc/d/dmd/cparse.d
@@ -2006,7 +2006,7 @@ final class CParser(AST) : Parser!AST
//printf("AliasDeclaration %s %s\n", id.toChars(), dt.toChars());
auto ad = new AST.AliasDeclaration(token.loc, id, dt);
if (id == idt)
- ad.adFlags |= ad.hidden; // do not print when generating .di files
+ ad.hidden = true; // do not print when generating .di files
s = ad;
}
@@ -2088,8 +2088,7 @@ final class CParser(AST) : Parser!AST
{
auto str = asmName.peekString();
p.mangleOverride = str;
-// p.adFlags |= AST.VarDeclaration.nounderscore;
- p.adFlags |= 4; // cannot get above line to compile on Ubuntu
+ p.noUnderscore = true;
}
}
s = applySpecifier(s, specifier);
@@ -5527,6 +5526,12 @@ final class CParser(AST) : Parser!AST
if (pt && *pt)
t = *pt;
}
+ if (t.mcache && t.mcache.typedefIdent)
+ {
+ t = t.copy();
+ t.mcache = null;
+ }
+ t.getMcache().typedefIdent = id;
auto tab = cast(void*[void*])(typedefTab[$ - 1]);
tab[cast(void*)id] = cast(void*)t;
typedefTab[$ - 1] = cast(void*)tab;
diff --git a/gcc/d/dmd/cxxfrontend.d b/gcc/d/dmd/cxxfrontend.d
index dfc76ff..3cd4ced 100644
--- a/gcc/d/dmd/cxxfrontend.d
+++ b/gcc/d/dmd/cxxfrontend.d
@@ -15,6 +15,7 @@ import dmd.arraytypes;
import dmd.astenums;
import dmd.attrib;
import dmd.common.outbuffer : OutBuffer;
+import dmd.declaration : TypeInfoDeclaration;
import dmd.denum : EnumDeclaration;
import dmd.dmodule /*: Module*/;
import dmd.dscope : Scope;
@@ -702,6 +703,18 @@ bool builtinTypeInfo(Type t)
return dmd.typinf.builtinTypeInfo(t);
}
+Type makeNakedAssociativeArray(TypeAArray t)
+{
+ import dmd.typinf;
+ return dmd.typinf.makeNakedAssociativeArray(t);
+}
+
+TypeInfoDeclaration getTypeInfoAssocArrayDeclaration(TypeAArray t, Scope* sc)
+{
+ import dmd.typinf;
+ return dmd.typinf.getTypeInfoAssocArrayDeclaration(t, sc);
+}
+
version (IN_LLVM)
{
/***********************************************************
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index f42a061..172c827 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -150,7 +150,7 @@ Expression implicitCastTo(Expression e, Scope* sc, Type t)
//printf("type %s t %s\n", type.deco, t.deco);
auto ts = toAutoQualChars(e.type, t);
error(e.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
- e.toChars(), ts[0], ts[1]);
+ e.toErrMsg(), ts[0], ts[1]);
}
}
return ErrorExp.get();
@@ -2832,6 +2832,7 @@ Expression castTo(Expression e, Scope* sc, Type t, Type att = null)
(*ae.keys)[i] = ex;
}
ae.type = t;
+ semanticTypeInfo(sc, ae.type);
return ae;
}
return visit(e);
diff --git a/gcc/d/dmd/declaration.d b/gcc/d/dmd/declaration.d
index 26887f8..30f017d 100644
--- a/gcc/d/dmd/declaration.d
+++ b/gcc/d/dmd/declaration.d
@@ -54,6 +54,7 @@ else version = MARS;
*/
void ObjectNotFound(Loc loc, Identifier id)
{
+ global.gag = 0; // never gag the fatal error
error(loc, "`%s` not found. object.d may be incorrectly installed or corrupt.", id.toChars());
version (IN_LLVM)
{
@@ -87,19 +88,23 @@ extern (C++) abstract class Declaration : Dsymbol
Type type;
Type originalType; // before semantic analysis
StorageClass storage_class = STC.undefined_;
+ // overridden symbol with pragma(mangle, "...")
+ const(char)[] mangleOverride;
Visibility visibility;
- LINK _linkage = LINK.default_; // may be `LINK.system`; use `resolvedLinkage()` to resolve it
short inuse; // used to detect cycles
- ubyte adFlags; // control re-assignment of AliasDeclaration (put here for packing reasons)
- enum wasRead = 1; // set if AliasDeclaration was read
- enum ignoreRead = 2; // ignore any reads of AliasDeclaration
- enum nounderscore = 4; // don't prepend _ to mangled name
- enum hidden = 8; // don't print this in .di files
- enum nrvo = 0x10; /// forward to fd.nrvo_var when generating code
+ private extern (D) static struct BitFields
+ {
+ LINK _linkage = LINK.default_; // may be `LINK.system`; use `resolvedLinkage()` to resolve it
+ bool wasRead; // set if AliasDeclaration was read
+ bool ignoreRead; // ignore any reads of AliasDeclaration
+ bool noUnderscore; // don't prepend _ to mangled name
+ bool hidden; // don't print this in .di files
+ bool nrvo; /// forward to fd.nrvo_var when generating code
+ }
- // overridden symbol with pragma(mangle, "...")
- const(char)[] mangleOverride;
+ import dmd.common.bitfields;
+ mixin(generateBitFields!(BitFields, ubyte));
final extern (D) this(Identifier ident) @safe
{
@@ -628,8 +633,8 @@ extern (C++) final class AliasDeclaration : Declaration
return aliassym;
}
// Reading the AliasDeclaration
- if (!(adFlags & ignoreRead))
- adFlags |= wasRead; // can never assign to this AliasDeclaration again
+ if (!this.ignoreRead)
+ this.wasRead = true; // can never assign to this AliasDeclaration again
if (inuse == 1 && type && _scope)
{
@@ -1124,16 +1129,6 @@ extern (C++) class VarDeclaration : Declaration
return e;
}
- override final void checkCtorConstInit()
- {
- version (none)
- {
- /* doesn't work if more than one static ctor */
- if (ctorinit == 0 && isCtorinit() && !isField())
- error("missing initializer in static constructor for const variable");
- }
- }
-
/************************************
* Check to see if this variable is actually in an enclosing function
* rather than the current one.
@@ -1544,6 +1539,8 @@ extern (C++) final class TypeInfoStaticArrayDeclaration : TypeInfoDeclaration
*/
extern (C++) final class TypeInfoAssociativeArrayDeclaration : TypeInfoDeclaration
{
+ Type entry; // type of TypeInfo_AssociativeArray.Entry!(t.index, t.next)
+
extern (D) this(Type tinfo)
{
super(tinfo);
diff --git a/gcc/d/dmd/declaration.h b/gcc/d/dmd/declaration.h
index 4fd35ee..6fef6a5 100644
--- a/gcc/d/dmd/declaration.h
+++ b/gcc/d/dmd/declaration.h
@@ -121,11 +121,10 @@ public:
Type *type;
Type *originalType; // before semantic analysis
StorageClass storage_class;
+ DString mangleOverride; // overridden symbol with pragma(mangle, "...")
Visibility visibility;
- LINK _linkage; // may be `LINK::system`; use `resolvedLinkage()` to resolve it
short inuse; // used to detect cycles
- uint8_t adFlags;
- DString mangleOverride; // overridden symbol with pragma(mangle, "...")
+ uint8_t bitFields;
const char *kind() const override;
uinteger_t size(Loc loc) override final;
@@ -299,7 +298,6 @@ public:
bool hasPointers() override final;
bool canTakeAddressOf();
bool needsScopeDtor();
- void checkCtorConstInit() override final;
Dsymbol *toAlias() override final;
// Eliminate need for dynamic_cast
VarDeclaration *isVarDeclaration() override final { return (VarDeclaration *)this; }
@@ -398,6 +396,8 @@ public:
class TypeInfoAssociativeArrayDeclaration final : public TypeInfoDeclaration
{
public:
+ Type* entry;
+
static TypeInfoAssociativeArrayDeclaration *create(Type *tinfo);
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/dinterpret.d b/gcc/d/dmd/dinterpret.d
index 5dbab09..3a08c10 100644
--- a/gcc/d/dmd/dinterpret.d
+++ b/gcc/d/dmd/dinterpret.d
@@ -1989,13 +1989,15 @@ public:
Declaration decl = ve.var;
// We cannot take the address of an imported symbol at compile time
- if (decl.isImportedSymbol()) {
+ if (decl.isImportedSymbol())
+ {
error(e.loc, "cannot take address of imported symbol `%s` at compile time", decl.toChars());
result = CTFEExp.cantexp;
return;
}
- if (decl.isDataseg()) {
+ if (decl.isDataseg())
+ {
// Normally this is already done by optimize()
// Do it here in case optimize(WANTvalue) wasn't run before CTFE
emplaceExp!(SymOffExp)(pue, e.loc, e.e1.isVarExp().var, 0);
diff --git a/gcc/d/dmd/doc.d b/gcc/d/dmd/doc.d
index 0e77cdf..261fa38 100644
--- a/gcc/d/dmd/doc.d
+++ b/gcc/d/dmd/doc.d
@@ -2061,9 +2061,9 @@ string toLowercase(string s) pure @safe
// TODO: maybe unicode lowercase, somehow
if (c >= 'A' && c <= 'Z')
{
- if (!lower.length) {
+ if (!lower.length)
lower.reserve(s.length);
- }
+
lower ~= s[lower.length..i];
c += 'a' - 'A';
lower ~= c;
diff --git a/gcc/d/dmd/dsymbol.d b/gcc/d/dmd/dsymbol.d
index bad9ca2..64cf6be 100644
--- a/gcc/d/dmd/dsymbol.d
+++ b/gcc/d/dmd/dsymbol.d
@@ -916,10 +916,6 @@ extern (C++) class Dsymbol : ASTNode
{
}
- void checkCtorConstInit()
- {
- }
-
/****************************************
* Add documentation comment to Dsymbol.
* Ignore NULL comments.
diff --git a/gcc/d/dmd/dsymbol.h b/gcc/d/dmd/dsymbol.h
index 6d223bf..8209dea 100644
--- a/gcc/d/dmd/dsymbol.h
+++ b/gcc/d/dmd/dsymbol.h
@@ -241,7 +241,6 @@ public:
virtual bool hasPointers();
virtual bool hasStaticCtorOrDtor();
virtual void addObjcSymbols(ClassDeclarations *, ClassDeclarations *) { }
- virtual void checkCtorConstInit() { }
virtual void addComment(const utf8_t *comment);
const utf8_t *comment(); // current value of comment
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 3e7f9b9..b017366 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -1896,8 +1896,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
const sident = se.toStringz();
if (!sident.length || !Identifier.isValidIdentifier(sident))
{
- error(ns.exp.loc, "expected valid identifier for C++ namespace but got `%.*s`",
- cast(int)sident.length, sident.ptr);
+ error(ns.exp.loc, "expected valid identifier for C++ namespace but got `%s`", se.toErrMsg());
return null;
}
else
@@ -5343,7 +5342,8 @@ void aliasSemantic(AliasDeclaration ds, Scope* sc)
{
s = tident.toDsymbol(sc);
// don't error for `var1.static_symbol`
- if (s && s.needThis()) {
+ if (s && s.needThis())
+ {
error(ds.loc, "cannot alias %s member `%s` of variable `%s`",
s.kind(), s.toChars(), mt.ident.toChars());
errorSupplemental(ds.loc, "Use `typeof(%s)` instead to preserve behaviour",
@@ -5500,7 +5500,7 @@ private void aliasAssignSemantic(AliasAssign ds, Scope* sc)
if (!aliassym)
return errorRet();
- if (aliassym.adFlags & Declaration.wasRead)
+ if (aliassym.wasRead)
{
if (!aliassym.errors)
error(ds.loc, "%s was read, so cannot reassign", aliassym.toChars());
@@ -5508,7 +5508,7 @@ private void aliasAssignSemantic(AliasAssign ds, Scope* sc)
return errorRet();
}
- aliassym.adFlags |= Declaration.ignoreRead; // temporarilly allow reads of aliassym
+ aliassym.ignoreRead = true; // temporarilly allow reads of aliassym
const storage_class = sc.stc & (STC.deprecated_ | STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.shared_ | STC.disable);
@@ -5632,8 +5632,7 @@ private void aliasAssignSemantic(AliasAssign ds, Scope* sc)
aliassym.aliassym = null;
}
-
- aliassym.adFlags &= ~Declaration.ignoreRead;
+ aliassym.ignoreRead = false;
if (aliassym.type && aliassym.type.ty == Terror ||
global.gag && errors != global.errors)
@@ -7940,3 +7939,31 @@ extern (C++) class AddCommentVisitor: Visitor
}
override void visit(StaticForeachDeclaration sfd) {}
}
+
+void checkCtorConstInit(Dsymbol d)
+{
+ scope v = new CheckCtorConstInitVisitor();
+ d.accept(v);
+}
+
+private extern(C++) class CheckCtorConstInitVisitor : Visitor
+{
+ alias visit = Visitor.visit;
+
+ override void visit(AttribDeclaration ad)
+ {
+ ad.include(null).foreachDsymbol( s => s.checkCtorConstInit() );
+ }
+
+ override void visit(VarDeclaration vd)
+ {
+ version (none)
+ {
+ /* doesn't work if more than one static ctor */
+ if (vd.ctorinit == 0 && vd.isCtorinit() && !vd.isField())
+ error("missing initializer in static constructor for const variable");
+ }
+ }
+
+ override void visit(Dsymbol d){}
+}
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index 1aab94d..c19d4b9 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -136,6 +136,13 @@ inout(Parameter) isParameter(inout RootObject o)
return cast(inout(Parameter))o;
}
+inout(Identifier) isIdentifier(inout RootObject o)
+{
+ if (!o || o.dyncast() != DYNCAST.identifier)
+ return null;
+ return cast(inout(Identifier))o;
+}
+
inout(TemplateParameter) isTemplateParameter(inout RootObject o)
{
if (!o || o.dyncast() != DYNCAST.templateparameter)
@@ -3884,7 +3891,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
if (n_instantiations <= max_shown)
{
for (TemplateInstance cur = this; cur; cur = cur.tinst)
- printFn(cur.loc, format, cur.toChars());
+ printFn(cur.loc, format, cur.toErrMsg());
}
else if (n_instantiations - n_totalrecursions <= max_shown)
{
@@ -6265,6 +6272,9 @@ void write(ref OutBuffer buf, RootObject obj)
{
if (obj)
{
- buf.writestring(obj.toChars());
+ if (auto e = isExpression(obj))
+ buf.writestring(e.toErrMsg());
+ else
+ buf.writestring(obj.toChars());
}
}
diff --git a/gcc/d/dmd/dtoh.d b/gcc/d/dmd/dtoh.d
index efd0a2f..a586f87 100644
--- a/gcc/d/dmd/dtoh.d
+++ b/gcc/d/dmd/dtoh.d
@@ -976,7 +976,8 @@ public:
{
EnumKind kind = getEnumKind(type);
- if (vd.visibility.kind == AST.Visibility.Kind.none || vd.visibility.kind == AST.Visibility.Kind.private_) {
+ if (vd.visibility.kind == AST.Visibility.Kind.none || vd.visibility.kind == AST.Visibility.Kind.private_)
+ {
ignored("enum `%s` because it is `%s`.", vd.toPrettyChars(), AST.visibilityToChars(vd.visibility.kind));
return;
}
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 6827612..388023f 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -383,8 +383,7 @@ extern (C++) abstract class Expression : ASTNode
final override const(char)* toChars() const
{
- // FIXME: Test suite relies on lambda's being printed as __lambdaXXX in errors and .stringof
- // Printing a (truncated) lambda body is more user friendly
+ // FIXME: mangling (see runnable/mangle.d) relies on toChars outputting __lambdaXXX here
if (auto fe = isFuncExp())
return fe.fd.toChars();
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index 7a35328..22fbfc2 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -362,11 +362,11 @@ private Expression incompatibleTypes(UnaExp e)
if (e.e1.op == EXP.type)
{
- error(e.loc, "incompatible type for `%s(%s)`: cannot use `%s` with types", EXPtoString(e.op).ptr, e.e1.toChars(), EXPtoString(e.op).ptr);
+ error(e.loc, "incompatible type for `%s(%s)`: cannot use `%s` with types", EXPtoString(e.op).ptr, e.e1.toErrMsg(), EXPtoString(e.op).ptr);
}
else
{
- error(e.loc, "incompatible type for `%s(%s)`: `%s`", EXPtoString(e.op).ptr, e.e1.toChars(), e.e1.type.toChars());
+ error(e.loc, "incompatible type for `%s(%s)`: `%s`", EXPtoString(e.op).ptr, e.e1.toErrMsg(), e.e1.type.toChars());
}
return ErrorExp.get();
}
@@ -393,18 +393,18 @@ extern (D) Expression incompatibleTypes(BinExp e, Scope* sc = null)
if (e.e1.op == EXP.type || e.e2.op == EXP.type)
{
error(e.loc, "incompatible types for `(%s) %s (%s)`: cannot use `%s` with types",
- e.e1.toChars(), thisOp, e.e2.toChars(), EXPtoString(e.op).ptr);
+ e.e1.toErrMsg(), thisOp, e.e2.toErrMsg(), EXPtoString(e.op).ptr);
}
else if (e.e1.type.equals(e.e2.type))
{
error(e.loc, "incompatible types for `(%s) %s (%s)`: both operands are of type `%s`",
- e.e1.toChars(), thisOp, e.e2.toChars(), e.e1.type.toChars());
+ e.e1.toErrMsg(), thisOp, e.e2.toErrMsg(), e.e1.type.toChars());
}
else
{
auto ts = toAutoQualChars(e.e1.type, e.e2.type);
error(e.loc, "incompatible types for `(%s) %s (%s)`: `%s` and `%s`",
- e.e1.toChars(), thisOp, e.e2.toChars(), ts[0], ts[1]);
+ e.e1.toErrMsg(), thisOp, e.e2.toErrMsg(), ts[0], ts[1]);
}
return ErrorExp.get();
}
@@ -731,7 +731,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, out Expression pe0)
if (!e.type)
{
- error(ae.loc, "`%s` has no value", e.toChars());
+ error(ae.loc, "`%s` has no value", e.toErrMsg());
e = ErrorExp.get();
}
if (e.op == EXP.error)
@@ -768,7 +768,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, IntervalExp ie, ref Expressio
e = resolveProperties(sc, e);
if (!e.type)
{
- error(ae.loc, "`%s` has no value", e.toChars());
+ error(ae.loc, "`%s` has no value", e.toErrMsg());
errors = true;
}
return e;
@@ -853,7 +853,7 @@ extern (D) Expression doCopyOrMove(Scope* sc, Expression e, Type t, bool nrvo, b
*/
VarDeclaration vd = new VarDeclaration(e.loc, e.type, Identifier.generateId("__copyrvalue"), null);
if (nrvo)
- vd.adFlags |= Declaration.nrvo;
+ vd.nrvo = true;
vd.storage_class |= STC.nodtor;
vd.dsymbolSemantic(sc);
Expression de = new DeclarationExp(e.loc, vd);
@@ -903,7 +903,7 @@ private Expression callCpCtor(Scope* sc, Expression e, Type destinationType, boo
*/
VarDeclaration tmp = copyToTemp(STC.rvalue, "__copytmp", e);
if (nrvo)
- tmp.adFlags |= Declaration.nrvo;
+ tmp.nrvo = true;
if (sd.hasCopyCtor && destinationType)
{
// https://issues.dlang.org/show_bug.cgi?id=22619
@@ -2109,7 +2109,7 @@ public void errorSupplementalInferredAttr(FuncDeclaration fd, int maxDepth, bool
{
if (maxDepth > 0)
{
- errorFunc(s.loc, "which calls `%s`", s.fd.toPrettyChars());
+ errorFunc(s.loc, "which calls `%s`", s.fd.toErrMsg());
errorSupplementalInferredAttr(s.fd, maxDepth - 1, deprecation, stc, eSink);
}
}
@@ -2477,7 +2477,7 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
auto tf = fd.type.isTypeFunction();
if (!tf.isRef && e2)
{
- error(loc, "%s is not an lvalue", e1.toChars());
+ error(loc, "%s is not an lvalue", e1.toErrMsg());
return ErrorExp.get();
}
}
@@ -2645,13 +2645,13 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
if (!e1.type)
{
- error(loc, "cannot resolve type for %s", e1.toChars());
+ error(loc, "cannot resolve type for %s", e1.toErrMsg());
e1 = ErrorExp.get();
}
return e1;
Leprop:
- error(loc, "not a property %s", e1.toChars());
+ error(loc, "not a property %s", e1.toErrMsg());
return ErrorExp.get();
}
@@ -2715,7 +2715,7 @@ private Type arrayExpressionToCommonType(Scope* sc, ref Expressions exps)
e = resolveProperties(sc, e);
if (!e.type)
{
- error(e.loc, "`%s` has no value", e.toChars());
+ error(e.loc, "`%s` has no value", e.toErrMsg());
t0 = Type.terror;
continue;
}
@@ -2912,7 +2912,7 @@ private bool preFunctionParameters(Scope* sc, ArgumentList argumentList, ErrorSi
{
if (eSink)
{
- eSink.error(arg.loc, "cannot pass type `%s` as a function argument", arg.toChars());
+ eSink.error(arg.loc, "cannot pass type `%s` as a function argument", arg.toErrMsg());
arg = ErrorExp.get();
}
err = true;
@@ -2922,7 +2922,7 @@ private bool preFunctionParameters(Scope* sc, ArgumentList argumentList, ErrorSi
{
if (eSink)
{
- eSink.error(arg.loc, "cannot pass function `%s` as a function argument", arg.toChars());
+ eSink.error(arg.loc, "cannot pass function `%s` as a function argument", arg.toErrMsg());
arg = ErrorExp.get();
}
err = true;
@@ -3515,7 +3515,7 @@ private bool functionParameters(Loc loc, Scope* sc,
{
if (se.hasOverloads && !se.var.isFuncDeclaration().isUnique())
{
- error(arg.loc, "function `%s` is overloaded", arg.toChars());
+ error(arg.loc, "function `%s` is overloaded", arg.toErrMsg());
err = true;
}
}
@@ -4159,7 +4159,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
if (!s)
{
- error(e.loc, "`%s` is not in a class or struct scope", e.toChars());
+ error(e.loc, "`%s` is not in a class or struct scope", e.toErrMsg());
return setError();
}
ClassDeclaration cd = s.isClassDeclaration();
@@ -4225,7 +4225,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
if (!s)
{
- error(e.loc, "`%s` is not in a class scope", e.toChars());
+ error(e.loc, "`%s` is not in a class scope", e.toErrMsg());
return setError();
}
cd = s.isClassDeclaration();
@@ -4489,7 +4489,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
e = e.expressionSemantic(sc);
if (!e.type)
{
- error(exp.loc, "`%s` has no value", e.toChars());
+ error(exp.loc, "`%s` has no value", e.toErrMsg());
err = true;
}
else if (e.op == EXP.error)
@@ -4540,7 +4540,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
*/
if (e.elements.length > 0 && t0.ty == Tvoid)
{
- error(e.loc, "`%s` of type `%s` has no value", e.toChars(), e.type.toChars());
+ error(e.loc, "`%s` of type `%s` has no value", e.toErrMsg(), e.type.toChars());
return setError();
}
@@ -4864,14 +4864,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
id = new DotTemplateInstanceExp(ne.loc, id, hook, tiargs);
auto arguments = new Expressions();
- if (global.params.tracegc)
- {
- auto funcname = (sc.callsc && sc.callsc.func) ?
- sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
- arguments.push(new StringExp(ne.loc, ne.loc.filename.toDString()));
- arguments.push(new IntegerExp(ne.loc, ne.loc.linnum, Type.tint32));
- arguments.push(new StringExp(ne.loc, funcname.toDString()));
- }
id = new CallExp(ne.loc, id, arguments);
ne.lowering = id.expressionSemantic(sc);
@@ -5210,14 +5202,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
tiargs.push(t);
id = new DotTemplateInstanceExp(exp.loc, id, hook, tiargs);
auto arguments = new Expressions();
- if (global.params.tracegc)
- {
- auto funcname = (sc.callsc && sc.callsc.func) ?
- sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
- arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString()));
- arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32));
- arguments.push(new StringExp(exp.loc, funcname.toDString()));
- }
id = new CallExp(exp.loc, id, arguments);
exp.lowering = id.expressionSemantic(sc);
@@ -5359,9 +5343,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!global.params.useGC && sc.needsCodegen())
{
version(IN_GCC)
- error(exp.loc, "expression `%s` allocates with the GC and cannot be used with switch `-fno-rtti`", exp.toChars());
+ error(exp.loc, "expression `%s` allocates with the GC and cannot be used with switch `-fno-rtti`", exp.toErrMsg());
else
- error(exp.loc, "expression `%s` allocates with the GC and cannot be used with switch `-betterC`", exp.toChars());
+ error(exp.loc, "expression `%s` allocates with the GC and cannot be used with switch `-betterC`", exp.toErrMsg());
return setError();
}
@@ -5402,14 +5386,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
lowering = new DotTemplateInstanceExp(exp.loc, lowering, hook, tiargs);
auto arguments = new Expressions();
- if (global.params.tracegc)
- {
- auto funcname = (sc.callsc && sc.callsc.func) ?
- sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
- arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString()));
- arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32));
- arguments.push(new StringExp(exp.loc, funcname.toDString()));
- }
arguments.push((*exp.arguments)[0]);
arguments.push(new IntegerExp(exp.loc, isShared, Type.tbool));
@@ -5441,14 +5417,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
lowering = new DotTemplateInstanceExp(exp.loc, lowering, hook, tiargs);
auto arguments = new Expressions();
- if (global.params.tracegc)
- {
- auto funcname = (sc.callsc && sc.callsc.func) ?
- sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
- arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString()));
- arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32));
- arguments.push(new StringExp(exp.loc, funcname.toDString()));
- }
arguments.push(new ArrayLiteralExp(exp.loc, Type.tsize_t.sarrayOf(nargs), exp.arguments));
arguments.push(new IntegerExp(exp.loc, tbn.isShared(), Type.tbool));
@@ -5832,8 +5800,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
OutBuffer buf;
foreach (idx, ref arg; *arguments)
buf.printf("%s%s", (idx ? ", ".ptr : "".ptr), arg.type.toChars());
- error(exp.loc, "function literal `%s%s` is not callable using argument types `(%s)`",
- exp.fd.toChars(), parametersTypeToChars(tfl.parameterList),
+ error(exp.loc, "`%s` is not callable using argument types `(%s)`",
+ exp.fd.toErrMsg(), // parametersTypeToChars(tfl.parameterList),
buf.peekChars());
errorSupplemental(exp.loc, "too %s arguments, expected %d, got %d",
arguments.length < dim ? "few".ptr : "many".ptr,
@@ -6038,7 +6006,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
__gshared int nest;
if (++nest > global.recursionLimit)
{
- error(exp.loc, "recursive evaluation of `%s`", exp.toChars());
+ error(exp.loc, "recursive evaluation of `%s`", exp.toErrMsg());
--nest;
return setError();
}
@@ -6331,7 +6299,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return null;
if (f)
return f;
- .error(loc, "no overload matches for `%s`", exp.toChars());
+ .error(loc, "no overload matches for `%s`", exp.toErrMsg());
errorSupplemental(loc, "Candidates are:");
foreach (s; os.a)
{
@@ -6591,7 +6559,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else if (!t1)
{
- error(exp.loc, "function expected before `()`, not `%s`", exp.e1.toChars());
+ error(exp.loc, "function expected before `()`, not `%s`", exp.e1.toErrMsg());
return setError();
}
else if (t1.ty == Terror)
@@ -6674,7 +6642,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else
{
- error(exp.loc, "function expected before `()`, not `%s` of type `%s`", exp.e1.toChars(), exp.e1.type.toChars());
+ error(exp.loc, "function expected before `()`, not `%s` of type `%s`", exp.e1.toErrMsg(), exp.e1.type.toChars());
return setError();
}
@@ -6688,8 +6656,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
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`",
- p, exp.e1.toChars(), parametersTypeToChars(tf.parameterList), buf.peekChars());
+ .error(exp.loc, "%s `%s` is not callable using argument types `%s`",
+ p, exp.e1.toErrMsg(), buf.peekChars());
if (failMessage)
errorSupplemental(exp.loc, "%s", failMessage);
}
@@ -6712,20 +6680,20 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!tf.purity && sc.func.setImpure(exp.loc, "calling impure `%s`", exp.e1))
{
error(exp.loc, "`pure` %s `%s` cannot call impure %s `%s`",
- sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
+ sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toErrMsg());
err = true;
}
if (!tf.isNogc && sc.func.setGC(exp.loc, "calling non-@nogc `%s`", exp.e1))
{
error(exp.loc, "`@nogc` %s `%s` cannot call non-@nogc %s `%s`",
- sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
+ sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toErrMsg());
err = true;
}
if (tf.trust <= TRUST.system && sc.setUnsafe(true, exp.loc,
"calling `@system` `%s`", exp.e1))
{
error(exp.loc, "`@safe` %s `%s` cannot call `@system` %s `%s`",
- sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toChars());
+ sc.func.kind(), sc.func.toPrettyChars(), p, exp.e1.toErrMsg());
err = true;
}
if (err)
@@ -6770,7 +6738,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
.error(exp.loc, "%s `%s` is not callable using argument types `%s`",
- exp.f.kind(), exp.f.toChars(), buf.peekChars());
+ exp.f.kind(), exp.f.toErrMsg(), buf.peekChars());
if (failMessage)
errorSupplemental(exp.loc, "%s", failMessage);
.errorSupplemental(exp.f.loc, "`%s%s` declared here", exp.f.toPrettyChars(), parametersTypeToChars(tf.parameterList));
@@ -6846,7 +6814,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
exp.e1 = e1org; // https://issues.dlang.org/show_bug.cgi?id=10922
// avoid recursive expression printing
- error(exp.loc, "forward reference to inferred return type of function call `%s`", exp.toChars());
+ error(exp.loc, "forward reference to inferred return type of function call `%s`", exp.toErrMsg());
return setError();
}
@@ -7126,7 +7094,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!ta)
{
//printf("ta %p ea %p sa %p\n", ta, ea, sa);
- error(exp.loc, "no type for `typeid(%s)`", ea ? ea.toChars() : (sa ? sa.toChars() : ""));
+ error(exp.loc, "no type for `typeid(%s)`", ea ? ea.toErrMsg() : (sa ? sa.toChars() : ""));
return setError();
}
@@ -7798,7 +7766,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// deprecated in 2.107
deprecation(e.loc, "assert condition cannot be a string literal");
deprecationSupplemental(e.loc, "If intentional, use `%s !is null` instead to preserve behaviour",
- e.toChars());
+ e.toErrMsg());
}
const generateMsg = !exp.msg &&
@@ -8430,7 +8398,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
MODMatchToBuffer(&thisBuf, e.e1.type.mod, tf.mod);
MODMatchToBuffer(&funcBuf, tf.mod, e.e1.type.mod);
error(e.loc, "%smethod `%s` is not callable using a %s`%s`",
- funcBuf.peekChars(), f.toPrettyChars(), thisBuf.peekChars(), e.e1.toChars());
+ funcBuf.peekChars(), f.toPrettyChars(), thisBuf.peekChars(), e.e1.toErrMsg());
return setError();
}
}
@@ -8614,7 +8582,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!exp.e1.type)
{
- error(exp.loc, "cannot take address of `%s`", exp.e1.toChars());
+ error(exp.loc, "cannot take address of `%s`", exp.e1.toErrMsg());
return setError();
}
if (!checkAddressable(exp, sc))
@@ -8638,7 +8606,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
error(exp.loc, "forward reference to %s `%s`", d.kind(), d.toChars());
}
else
- error(exp.loc, "forward reference to type `%s` of expression `%s`", exp.e1.type.toChars(), exp.e1.toChars());
+ error(exp.loc, "forward reference to type `%s` of expression `%s`", exp.e1.type.toChars(), exp.e1.toErrMsg());
return setError();
}
}
@@ -8801,7 +8769,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
case Tarray:
if (isNonAssignmentArrayOp(exp.e1))
goto default;
- error(exp.loc, "using `*` on an array is no longer supported; use `*(%s).ptr` instead", exp.e1.toChars());
+ error(exp.loc, "using `*` on an array is no longer supported; use `*(%s).ptr` instead", exp.e1.toErrMsg());
exp.type = (cast(TypeArray)tb).next;
exp.e1 = exp.e1.castTo(sc, exp.type.pointerTo());
break;
@@ -9111,7 +9079,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!exp.e1.type)
{
- error(exp.loc, "cannot cast `%s`", exp.e1.toChars());
+ error(exp.loc, "cannot cast `%s`", exp.e1.toErrMsg());
return setError();
}
@@ -9149,7 +9117,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.to.ty == Ttuple)
{
- error(exp.loc, "cannot cast `%s` of type `%s` to type sequence `%s`", exp.e1.toChars(), exp.e1.type.toChars(), exp.to.toChars());
+ error(exp.loc, "cannot cast `%s` of type `%s` to type sequence `%s`", exp.e1.toErrMsg(), exp.e1.type.toChars(), exp.to.toChars());
return setError();
}
@@ -9333,7 +9301,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (elem.isConst() == 1)
return false;
- error(exp.loc, "constant expression expected, not `%s`", elem.toChars());
+ error(exp.loc, "constant expression expected, not `%s`", elem.toErrMsg());
return true;
}
@@ -9393,7 +9361,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
if (exp.lwr || exp.upr)
{
- error(exp.loc, "cannot slice type `%s`", exp.e1.toChars());
+ error(exp.loc, "cannot slice type `%s`", exp.e1.toErrMsg());
return setError();
}
Expression e = new TypeExp(exp.loc, exp.e1.type.arrayOf());
@@ -9445,7 +9413,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
if (t1b.isPtrToFunction())
{
- error(exp.loc, "cannot slice function pointer `%s`", exp.e1.toChars());
+ error(exp.loc, "cannot slice function pointer `%s`", exp.e1.toErrMsg());
return setError();
}
if (!exp.lwr || !exp.upr)
@@ -9462,9 +9430,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
errorSupplemental(exp.loc,
"pointer `%s` points to an aggregate that defines an `%s`, perhaps you meant `(*%s)[]`",
- exp.e1.toChars(),
+ exp.e1.toErrMsg(),
s.ident.toChars(),
- exp.e1.toChars()
+ exp.e1.toErrMsg()
);
}
@@ -9505,7 +9473,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else
{
- error(exp.loc, "`%s` cannot be sliced with `[]`", t1b.ty == Tvoid ? exp.e1.toChars() : t1b.toChars());
+ error(exp.loc, "`%s` cannot be sliced with `[]`", t1b.ty == Tvoid ? exp.e1.toErrMsg() : t1b.toChars());
return setError();
}
@@ -9981,7 +9949,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
case Tpointer:
if (t1b.isPtrToFunction())
{
- error(exp.loc, "cannot index function pointer `%s`", exp.e1.toChars());
+ error(exp.loc, "cannot index function pointer `%s`", exp.e1.toErrMsg());
return setError();
}
exp.e2 = exp.e2.implicitCastTo(sc, Type.tsize_t);
@@ -10078,7 +10046,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}
default:
- error(exp.loc, "`%s` must be an array or pointer type, not `%s`", exp.e1.toChars(), exp.e1.type.toChars());
+ error(exp.loc, "`%s` must be an array or pointer type, not `%s`", exp.e1.toErrMsg(), exp.e1.type.toChars());
return setError();
}
@@ -10156,7 +10124,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.e1.op == EXP.slice)
{
const(char)* s = exp.op == EXP.plusPlus ? "increment" : "decrement";
- error(exp.loc, "cannot post-%s array slice `%s`, use pre-%s instead", s, exp.e1.toChars(), s);
+ error(exp.loc, "cannot post-%s array slice `%s`, use pre-%s instead", s, exp.e1.toErrMsg(), s);
return setError();
}
@@ -10909,7 +10877,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (newExp.newtype && newExp.newtype == t1)
{
error(exp.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
- newExp.toChars(), newExp.type.toChars(), t1.toChars());
+ newExp.toErrMsg(), newExp.type.toChars(), t1.toChars());
errorSupplemental(exp.loc, "Perhaps remove the `new` keyword?");
return setError();
}
@@ -11200,6 +11168,11 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.e2 = e2x;
t1 = e1x.type.toBasetype();
}
+ else if (t1.ty == Taarray)
+ {
+ // when assigning a constant, the need for TypeInfo might change
+ semanticTypeInfo(sc, t1);
+ }
/* Check the mutability of e1.
*/
if (auto ale = exp.e1.isArrayLengthExp())
@@ -11248,14 +11221,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
id = id.expressionSemantic(sc);
auto arguments = new Expressions();
- arguments.reserve(5);
- if (global.params.tracegc)
- {
- auto funcname = (sc.callsc && sc.callsc.func) ? sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
- arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString()));
- arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32));
- arguments.push(new StringExp(exp.loc, funcname.toDString()));
- }
arguments.push(ale.e1);
arguments.push(exp.e2);
@@ -11282,7 +11247,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.op == EXP.assign && !tn.baseElemOf().isAssignable())
{
error(exp.loc, "slice `%s` is not mutable, struct `%s` has immutable members",
- exp.e1.toChars(), tn.baseElemOf().toChars());
+ exp.e1.toErrMsg(), tn.baseElemOf().toChars());
result = ErrorExp.get();
return;
}
@@ -11305,7 +11270,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (tn && !tn.baseElemOf().isAssignable())
{
error(exp.loc, "array `%s` is not mutable, struct `%s` has immutable members",
- exp.e1.toChars(), tn.baseElemOf().toChars());
+ exp.e1.toErrMsg(), tn.baseElemOf().toChars());
result = ErrorExp.get();
return;
}
@@ -11375,7 +11340,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
uinteger_t dim2 = tsa2.dim.toInteger();
if (dim1 != dim2)
{
- error(exp.loc, "mismatched array lengths %d and %d for assignment `%s`", cast(int)dim1, cast(int)dim2, exp.toChars());
+ error(exp.loc, "mismatched array lengths %d and %d for assignment `%s`", cast(int)dim1, cast(int)dim2, exp.toErrMsg());
return setError();
}
}
@@ -11451,7 +11416,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// offer more information about the cause of the problem
errorSupplemental(exp.loc,
"`%s` is the first assignment of `%s` therefore it represents its initialization",
- exp.toChars(), exp.e1.toChars());
+ exp.toErrMsg(), exp.e1.toErrMsg());
errorSupplemental(exp.loc,
"`opAssign` methods are not used for initialization, but for subsequent assignments");
}
@@ -11973,15 +11938,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
id = new DotIdExp(exp.loc, id, hook);
auto arguments = new Expressions();
- arguments.reserve(5);
- if (global.params.tracegc)
- {
- auto funcname = (sc.callsc && sc.callsc.func) ? sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
- arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString()));
- arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32));
- arguments.push(new StringExp(exp.loc, funcname.toDString()));
- }
-
arguments.push(exp.e1);
arguments.push(exp.e2);
Expression ce = new CallExp(exp.loc, id, arguments);
@@ -12016,15 +11972,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
id = new DotIdExp(exp.loc, id, hook);
auto arguments = new Expressions();
- arguments.reserve(5);
- if (global.params.tracegc)
- {
- auto funcname = (sc.callsc && sc.callsc.func) ? sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
- arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString()));
- arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32));
- arguments.push(new StringExp(exp.loc, funcname.toDString()));
- }
-
Expression eValue1;
Expression value1 = extractSideEffect(sc, "__appendtmp", eValue1, exp.e1);
@@ -12368,7 +12315,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (hook == Id._d_arraycatnTX)
arguments.pushSlice((*callExp.arguments)[]);
else
- arguments.pushSlice((*callExp.arguments)[3 .. $]);
+ arguments.pushSlice((*callExp.arguments)[0 .. $ - 3]);
}
}
else
@@ -12376,15 +12323,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
auto arguments = new Expressions();
- if (useTraceGCHook)
- {
- auto funcname = (sc.callsc && sc.callsc.func) ?
- sc.callsc.func.toPrettyChars() : sc.func.toPrettyChars();
- arguments.push(new StringExp(exp.loc, exp.loc.filename.toDString()));
- arguments.push(new IntegerExp(exp.loc, exp.loc.linnum, Type.tint32));
- arguments.push(new StringExp(exp.loc, funcname.toDString()));
- }
-
handleCatArgument(arguments, exp.e1, exp.type.toBasetype(), false);
handleCatArgument(arguments, exp.e2, exp.type.toBasetype(), true);
@@ -12796,7 +12734,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
Module mmath = Module.loadStdMath();
if (!mmath)
{
- error(e.loc, "`%s` requires `std.math` for `^^` operators", e.toChars());
+ error(e.loc, "`%s` requires `std.math` for `^^` operators", e.toErrMsg());
return setError();
}
e = new ScopeExp(exp.loc, mmath);
@@ -12970,7 +12908,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (e2x.op == EXP.type || e2x.op == EXP.scope_)
{
- error(exp.loc, "`%s` is not an expression", exp.e2.toChars());
+ error(exp.loc, "`%s` is not an expression", exp.e2.toErrMsg());
return setError();
}
if (e1x.op == EXP.error || e1x.type.ty == Tnoreturn)
@@ -13137,7 +13075,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.e1 = exp.e1.implicitCastTo(sc, ta.index);
}
- semanticTypeInfo(sc, ta.index);
+ // even though the glue layer only needs the type info of the index,
+ // this might be the first time an AA literal is accessed, so check
+ // the full type info
+ semanticTypeInfo(sc, ta);
// Return type is pointer to value
exp.type = ta.nextOf().pointerTo();
@@ -13152,7 +13093,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
errorSupplemental(exp.loc, "`in` is only allowed on associative arrays");
const(char)* slice = (t2b.ty == Tsarray) ? "[]" : "";
errorSupplemental(exp.loc, "perhaps use `std.algorithm.find(%s, %s%s)` instead",
- exp.e1.toChars(), exp.e2.toChars(), slice);
+ exp.e1.toErrMsg(), exp.e2.toErrMsg(), slice);
return;
default:
@@ -13374,8 +13315,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
if (exp.e1.type.toBasetype().ty == Taarray)
+ {
semanticTypeInfo(sc, exp.e1.type.toBasetype());
-
+ }
if (!target.isVectorOpSupported(t1, exp.op, t2))
{
@@ -13998,12 +13940,12 @@ private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)
// Template has no built-in properties except for 'stringof'.
if ((exp.e1.isDotTemplateExp() || exp.e1.isTemplateExp()) && exp.ident != Id.stringof)
{
- error(exp.loc, "template `%s` does not have property `%s`", exp.e1.toChars(), exp.ident.toChars());
+ error(exp.loc, "template `%s` does not have property `%s`", exp.e1.toErrMsg(), exp.ident.toChars());
return ErrorExp.get();
}
if (!exp.e1.type)
{
- error(exp.loc, "expression `%s` does not have property `%s`", exp.e1.toChars(), exp.ident.toChars());
+ error(exp.loc, "expression `%s` does not have property `%s`", exp.e1.toErrMsg(), exp.ident.toChars());
return ErrorExp.get();
}
@@ -14405,7 +14347,7 @@ Expression dotTemplateSemanticProp(DotTemplateInstanceExp exp, Scope* sc, bool g
Expression notTemplate()
{
- error(exp.loc, "`%s` isn't a template", e.toChars());
+ error(exp.loc, "`%s` isn't a template", e.toErrMsg());
return errorExp();
}
@@ -14720,7 +14662,7 @@ MATCH matchType(FuncExp funcExp, Type to, Scope* sc, FuncExp* presult, ErrorSink
{
auto ts = toAutoQualChars(tx, to);
eSink.error(loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`",
- funcExp.toChars(), ts[0], ts[1]);
+ funcExp.toErrMsg(), ts[0], ts[1]);
}
return m;
}
@@ -14733,7 +14675,7 @@ private bool checkScalar(Expression e)
return true;
if (!e.type.isScalar())
{
- error(e.loc, "`%s` is not a scalar, it is a `%s`", e.toChars(), e.type.toChars());
+ error(e.loc, "`%s` is not a scalar, it is a `%s`", e.toErrMsg(), e.type.toChars());
return true;
}
return e.checkValue();
@@ -14747,7 +14689,7 @@ private bool checkNoBool(Expression e)
return true;
if (e.type.toBasetype().ty == Tbool)
{
- error(e.loc, "operation not allowed on `bool` `%s`", e.toChars());
+ error(e.loc, "operation not allowed on `bool` `%s`", e.toErrMsg());
return true;
}
return false;
@@ -14761,7 +14703,7 @@ private bool checkIntegral(Expression e)
return true;
if (!e.type.isIntegral())
{
- error(e.loc, "`%s` is not of integral type, it is a `%s`", e.toChars(), e.type.toChars());
+ error(e.loc, "`%s` is not of integral type, it is a `%s`", e.toErrMsg(), e.type.toChars());
return true;
}
return e.checkValue();
@@ -14779,7 +14721,7 @@ private bool checkArithmetic(Expression e, EXP op)
const char* msg = e.type.isAggregate() ?
"operator `%s` is not defined for `%s` of type `%s`" :
"illegal operator `%s` for `%s` of type `%s`";
- error(e.loc, msg, EXPtoString(op).ptr, e.toChars(), e.type.toChars());
+ error(e.loc, msg, EXPtoString(op).ptr, e.toErrMsg(), e.type.toChars());
return true;
}
@@ -14862,7 +14804,7 @@ bool checkValue(Expression e)
{
if (auto te = e.isTypeExp())
{
- error(e.loc, "type `%s` has no value", e.toChars());
+ error(e.loc, "type `%s` has no value", e.toErrMsg());
if (!e.type.isOpaqueType)
errorSupplemental(e.loc, "perhaps use `%s.init`", e.toChars());
return true;
@@ -14874,7 +14816,7 @@ bool checkValue(Expression e)
dtie.ti.semantictiargsdone &&
dtie.ti.semanticRun == PASS.initial)
- error(e.loc, "partial %s `%s` has no value", dtie.ti.kind(), e.toChars());
+ error(e.loc, "partial %s `%s` has no value", dtie.ti.kind(), e.toErrMsg());
else
error(e.loc, "%s `%s` has no value", dtie.ti.kind(), dtie.ti.toChars());
return true;
@@ -14904,13 +14846,13 @@ bool checkValue(Expression e)
if (auto dte = e.isDotTemplateExp())
{
- error(e.loc, "%s `%s` has no value", dte.td.kind(), e.toChars());
+ error(e.loc, "%s `%s` has no value", dte.td.kind(), e.toErrMsg());
return true;
}
if (e.type && e.type.toBasetype().ty == Tvoid)
{
- error(e.loc, "expression `%s` is `void` and has no value", e.toChars());
+ error(e.loc, "expression `%s` is `void` and has no value", e.toErrMsg());
//print(); assert(0);
if (!global.gag)
e.type = Type.terror;
@@ -14970,7 +14912,7 @@ bool checkSharedAccess(Expression e, Scope* sc, bool returnRef = false)
bool sharedError(Expression e)
{
// https://dlang.org/phobos/core_atomic.html
- error(e.loc, "direct access to shared `%s` is not allowed, see `core.atomic`", e.toChars());
+ error(e.loc, "direct access to shared `%s` is not allowed, see `core.atomic`", e.toErrMsg());
return true;
}
@@ -15494,9 +15436,9 @@ private Expression toLvalueImpl(Expression _this, Scope* sc, const(char)* action
if (e.op == EXP.type)
error(_this.loc, "cannot %s type `%s`", action, e.type.toChars());
else if (e.op == EXP.template_)
- error(_this.loc, "cannot %s template `%s`, perhaps instantiate it first", action, e.toChars());
+ error(_this.loc, "cannot %s template `%s`, perhaps instantiate it first", action, e.toErrMsg());
else
- error(_this.loc, "cannot %s expression `%s` because it is not an lvalue", action, e.toChars());
+ error(_this.loc, "cannot %s expression `%s` because it is not an lvalue", action, e.toErrMsg());
return ErrorExp.get();
}
@@ -15505,7 +15447,7 @@ private Expression toLvalueImpl(Expression _this, Scope* sc, const(char)* action
{
if (!_this.loc.isValid())
_this.loc = e.loc;
- error(e.loc, "cannot %s constant `%s`", action, e.toChars());
+ error(e.loc, "cannot %s constant `%s`", action, e.toErrMsg());
return ErrorExp.get();
}
@@ -15930,12 +15872,12 @@ private Expression modifiableLvalueImpl(Expression _this, Scope* sc, Expression
break;
if (!ff.type.isMutable)
{
- error(exp.loc, "cannot modify `%s` in `%s` function", exp.toChars(), MODtoChars(type.mod));
+ error(exp.loc, "cannot modify `%s` in `%s` function", exp.toErrMsg(), MODtoChars(type.mod));
return ErrorExp.get();
}
}
}
- error(exp.loc, "cannot modify `%s` expression `%s`", MODtoChars(type.mod), exp.toChars());
+ error(exp.loc, "cannot modify `%s` expression `%s`", MODtoChars(type.mod), exp.toErrMsg());
return ErrorExp.get();
}
else if (!type.isAssignable())
@@ -15950,7 +15892,7 @@ private Expression modifiableLvalueImpl(Expression _this, Scope* sc, Expression
Expression visitString(StringExp exp)
{
- error(exp.loc, "cannot modify string literal `%s`", exp.toChars());
+ error(exp.loc, "cannot modify string literal `%s`", exp.toErrMsg());
return ErrorExp.get();
}
@@ -15959,7 +15901,7 @@ private Expression modifiableLvalueImpl(Expression _this, Scope* sc, Expression
//printf("VarExp::modifiableLvalue('%s')\n", exp.var.toChars());
if (exp.var.storage_class & STC.manifest)
{
- error(exp.loc, "cannot modify manifest constant `%s`", exp.toChars());
+ error(exp.loc, "cannot modify manifest constant `%s`", exp.toErrMsg());
return ErrorExp.get();
}
// See if this expression is a modifiable lvalue (i.e. not const)
@@ -15988,7 +15930,7 @@ private Expression modifiableLvalueImpl(Expression _this, Scope* sc, Expression
Expression visitSlice(SliceExp exp)
{
- error(exp.loc, "slice expression `%s` is not a modifiable lvalue", exp.toChars());
+ error(exp.loc, "slice expression `%s` is not a modifiable lvalue", exp.toErrMsg());
return exp;
}
@@ -16030,7 +15972,7 @@ private Expression modifiableLvalueImpl(Expression _this, Scope* sc, Expression
{
if (!exp.e1.isLvalue() && !exp.e2.isLvalue())
{
- error(exp.loc, "conditional expression `%s` is not a modifiable lvalue", exp.toChars());
+ error(exp.loc, "conditional expression `%s` is not a modifiable lvalue", exp.toErrMsg());
return ErrorExp.get();
}
exp.e1 = exp.e1.modifiableLvalue(sc);
@@ -16071,7 +16013,7 @@ private bool checkAddressVar(Scope* sc, Expression exp, VarDeclaration v)
if (!v.canTakeAddressOf())
{
- error(exp.loc, "cannot take address of `%s`", exp.toChars());
+ error(exp.loc, "cannot take address of `%s`", exp.toErrMsg());
return false;
}
if (sc.func && !sc.intypeof && !v.isDataseg())
@@ -16133,9 +16075,9 @@ bool checkAddressable(Expression e, Scope* sc)
if (ex.isVarExp().var.storage_class & STC.register)
{
if (e.isIndexExp())
- error(e.loc, "cannot index through register variable `%s`", ex.toChars());
+ error(e.loc, "cannot index through register variable `%s`", ex.toErrMsg());
else
- error(e.loc, "cannot take address of register variable `%s`", ex.toChars());
+ error(e.loc, "cannot take address of register variable `%s`", ex.toErrMsg());
return false;
}
}
@@ -16629,7 +16571,7 @@ bool evalStaticCondition(Scope* sc, Expression original, Expression e, out bool
if (opt.isEmpty())
{
if (!e.type.isTypeError())
- error(e.loc, "expression `%s` is not constant", e.toChars());
+ error(e.loc, "expression `%s` is not constant", e.toErrMsg());
errors = true;
return false;
}
@@ -16916,6 +16858,9 @@ void semanticTypeInfo(Scope* sc, Type t)
{
semanticTypeInfo(sc, t.index);
semanticTypeInfo(sc, t.next);
+
+ if (global.params.useTypeInfo)
+ getTypeInfoType(t.loc, t, sc);
}
void visitStruct(TypeStruct t)
diff --git a/gcc/d/dmd/file_manager.d b/gcc/d/dmd/file_manager.d
index 7f39ec91..f2116e5 100644
--- a/gcc/d/dmd/file_manager.d
+++ b/gcc/d/dmd/file_manager.d
@@ -101,8 +101,10 @@ private struct PathCache
*/
bool exists = true;
auto st = PathStack(filespec);
- while (st.up) {
- if (auto cached = pathStatus.lookup(st.cur)) {
+ while (st.up)
+ {
+ if (auto cached = pathStatus.lookup(st.cur))
+ {
exists = cached.value;
break;
}
@@ -112,7 +114,8 @@ private struct PathCache
* Once a directory is found to not exist, all the directories
* to the right of it do not exist
*/
- while (st.down) {
+ while (st.down)
+ {
if (!exists)
pathStatus.insert(st.cur, false);
else
@@ -218,17 +221,19 @@ nothrow:
const(char)[] n = FileName.combine(p, sdi);
- if (!pathCache.pathExists(n)) {
+ if (!pathCache.pathExists(n))
+ {
FileName.free(n.ptr);
continue; // no need to check for anything else.
}
- if (FileName.exists(n) == 1) {
+ if (FileName.exists(n) == 1)
return n;
- }
+
FileName.free(n.ptr);
n = FileName.combine(p, sd);
- if (FileName.exists(n) == 1) {
+ if (FileName.exists(n) == 1)
+ {
whichPathFoundThis = pathIndex;
return n;
}
@@ -241,14 +246,16 @@ nothrow:
if (pathCache.isExistingPath(n))
{
const n2i = FileName.combine(n, package_di);
- if (FileName.exists(n2i) == 1) {
+ if (FileName.exists(n2i) == 1)
+ {
whichPathFoundThis = pathIndex;
return n2i;
}
FileName.free(n2i.ptr);
const n2 = FileName.combine(n, package_d);
- if (FileName.exists(n2) == 1) {
+ if (FileName.exists(n2) == 1)
+ {
whichPathFoundThis = pathIndex;
return n2;
}
@@ -272,14 +279,16 @@ nothrow:
const p = entry.path.toDString();
const(char)[] n = FileName.combine(p, si);
- if (FileName.exists(n) == 1) {
+ if (FileName.exists(n) == 1)
+ {
whichPathFoundThis = pathIndex;
return n;
}
FileName.free(n.ptr);
n = FileName.combine(p, sc);
- if (FileName.exists(n) == 1) {
+ if (FileName.exists(n) == 1)
+ {
whichPathFoundThis = pathIndex;
return n;
}
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 80312f2..e5b72e2 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -1883,10 +1883,10 @@ struct AttributeViolation
assert(args.length <= 4); // expand if necessary
OutBuffer buf;
buf.printf(fmt,
- args.length > 0 && args[0] ? args[0].toChars() : "",
- args.length > 1 && args[1] ? args[1].toChars() : "",
- args.length > 2 && args[2] ? args[2].toChars() : "",
- args.length > 3 && args[3] ? args[3].toChars() : "",
+ args.length > 0 && args[0] ? args[0].toErrMsg() : "",
+ args.length > 1 && args[1] ? args[1].toErrMsg() : "",
+ args.length > 2 && args[2] ? args[2].toErrMsg() : "",
+ args.length > 3 && args[3] ? args[3].toErrMsg() : "",
);
this.action = buf.extractSlice();
}
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index c0fcf64..0ef955a 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -59,10 +59,12 @@ struct HdrGenState
bool ddoc; /// true if generating Ddoc file
bool fullDump; /// true if generating a full AST dump file
bool importcHdr; /// true if generating a .di file from an ImportC file
+ bool inCAlias; /// Set to prevent ImportC translating typedefs as `alias X = X`
bool doFuncBodies; /// include function bodies in output
bool vcg_ast; /// write out codegen-ast
bool skipConstraints; // skip constraints when doing templates
bool showOneMember = true;
+ bool errorMsg; /// true if formatting for inside an error message
bool fullQual; /// fully qualify types when printing
int tpltMember;
@@ -96,6 +98,87 @@ void genhdrfile(Module m, bool doFuncBodies, ref OutBuffer buf)
toCBuffer(m, buf, hgs);
}
+/**
+ * Convert `o` to a string for error messages.
+ * Params:
+ * e = object to convert
+ * Returns: string representation of `e`
+ */
+const(char)* toErrMsg(const RootObject o)
+{
+ if (auto e = o.isExpression())
+ return toErrMsg(e);
+ if (auto d = o.isDsymbol())
+ return toErrMsg(d);
+ if (auto t = o.isType())
+ return t.toChars();
+ if (auto id = o.isIdentifier())
+ return id.toChars();
+ assert(0);
+}
+
+/// ditto
+const(char)* toErrMsg(const Expression e)
+{
+ HdrGenState hgs;
+ hgs.errorMsg = true;
+ OutBuffer buf;
+ toCBuffer(e, buf, hgs);
+ truncateForError(buf, 60);
+
+ return buf.extractChars();
+}
+
+/// ditto
+const(char)* toErrMsg(const Dsymbol d)
+{
+ if (d.isFuncDeclaration() || d.isTemplateInstance())
+ {
+ if (d.ident && d.ident.toString.startsWith("__") && !d.isCtorDeclaration())
+ {
+ HdrGenState hgs;
+ hgs.errorMsg = true;
+ OutBuffer buf;
+ toCBuffer(cast() d, buf, hgs);
+ truncateForError(buf, 80);
+ return buf.extractChars();
+ }
+ }
+
+ return d.toChars();
+}
+
+/**
+ * Make the content of `buf` fit inline for an error message.
+ * Params:
+ * buf = buffer with text to modify
+ * maxLength = truncate text when it exceeds this length
+ */
+private void truncateForError(ref OutBuffer buf, size_t maxLength)
+{
+ // Remove newlines, escape backticks ` by doubling them
+ for (size_t i = 0; i < buf.length; i++)
+ {
+ if (buf[i] == '\r')
+ buf.remove(i, 1);
+ if (buf[i] == '\n')
+ buf.peekSlice[i] = ' ';
+ if (buf[i] == '`')
+ i = buf.insert(i, "`");
+ }
+
+ // Strip trailing whitespace
+ while (buf.length && buf[$-1] == ' ')
+ buf.setsize(buf.length - 1);
+
+ // Truncate
+ if (buf.length > maxLength)
+ {
+ buf.setsize(maxLength - 3);
+ buf.writestring("...");
+ }
+}
+
/***************************************
* Turn a Statement into a string suitable for printf.
* Leaks memory.
@@ -1658,7 +1741,7 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
{
if (d.storage_class & STC.local)
return;
- if (d.adFlags & d.hidden)
+ if (d.hidden)
return;
buf.writestring("alias ");
if (d.aliassym)
@@ -1695,7 +1778,9 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
buf.writestring(" = ");
if (stcToBuffer(buf, d.storage_class))
buf.writeByte(' ');
+ hgs.inCAlias = hgs.importcHdr;
typeToBuffer(d.type, null, buf, hgs);
+ hgs.inCAlias = false;
hgs.declstring = false;
}
buf.writeByte(';');
@@ -1772,7 +1857,7 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
buf.writestring("__error");
return;
}
- if (f.tok != TOK.reserved)
+ if (f.tok != TOK.reserved && !hgs.errorMsg)
{
buf.writestring(f.kind());
buf.writeByte(' ');
@@ -1789,8 +1874,9 @@ void toCBuffer(Dsymbol s, ref OutBuffer buf, ref HdrGenState hgs)
buf.writeByte(' ');
buf.writestring(str);
}
- tf.attributesApply(&printAttribute);
+ if (!hgs.errorMsg)
+ tf.attributesApply(&printAttribute);
CompoundStatement cs = f.fbody.isCompoundStatement();
Statement s1;
@@ -4366,6 +4452,11 @@ private void typeToBufferx(Type t, ref OutBuffer buf, ref HdrGenState hgs)
buf.writestring("noreturn");
}
+ if (hgs.importcHdr && !hgs.inCAlias && t.mcache && t.mcache.typedefIdent)
+ {
+ buf.writestring(t.mcache.typedefIdent.toString());
+ return;
+ }
switch (t.ty)
{
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index 9833e198..fa7fe1d 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -166,6 +166,7 @@ immutable Msgtable[] msgtable =
{ "xopCmp", "__xopCmp" },
{ "xtoHash", "__xtoHash" },
{ "__tmpfordtor" },
+ { "Entry" },
{ "LINE", "__LINE__" },
{ "FILE", "__FILE__" },
diff --git a/gcc/d/dmd/identifier.d b/gcc/d/dmd/identifier.d
index 231aa58..9ef8285 100644
--- a/gcc/d/dmd/identifier.d
+++ b/gcc/d/dmd/identifier.d
@@ -248,13 +248,14 @@ nothrow:
* directly, but that would unnecessary lengthen symbols names. See issue:
* https://issues.dlang.org/show_bug.cgi?id=23722
*/
- static struct Key { uint fileOffset; string prefix; string parent; }
+ static struct Key { string locKey; string prefix; string parent; }
__gshared uint[Key] counters;
+ string locKey = cast(string) (sl.filename ~ idBuf[]);
static if (__traits(compiles, counters.update(Key.init, () => 0u, (ref uint a) => 0u)))
{
// 2.082+
- counters.update(Key(loc.fileOffset, prefix, parent),
+ counters.update(Key(locKey, prefix, parent),
() => 1u, // insertion
(ref uint counter) // update
{
@@ -266,7 +267,7 @@ nothrow:
}
else
{
- const key = Key(loc.fileOffset, prefix, parent);
+ const key = Key(locKey, prefix, parent);
if (auto pCounter = key in counters)
{
idBuf.writestring("_");
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index 467b796..cda4088 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -585,7 +585,7 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
const errors = global.startGagging();
i.exp = i.exp.implicitCastTo(sc, t);
if (global.endGagging(errors))
- error(currExp.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`", currExp.toChars(), et.toChars(), t.toChars());
+ error(currExp.loc, "cannot implicitly convert expression `%s` of type `%s` to `%s`", currExp.toErrMsg(), et.toChars(), t.toChars());
}
}
L1:
diff --git a/gcc/d/dmd/json.d b/gcc/d/dmd/json.d
index 05924f7..4900320 100644
--- a/gcc/d/dmd/json.d
+++ b/gcc/d/dmd/json.d
@@ -41,10 +41,13 @@ import dmd.root.string;
import dmd.target;
import dmd.visitor;
-version(Windows) {
+version(Windows)
+{
extern (C) char* _getcwd(char* buffer, size_t maxlen);
alias getcwd = _getcwd;
-} else {
+}
+else
+{
import core.sys.posix.unistd : getcwd;
}
diff --git a/gcc/d/dmd/lambdacomp.d b/gcc/d/dmd/lambdacomp.d
index 90c794e..96a1780 100644
--- a/gcc/d/dmd/lambdacomp.d
+++ b/gcc/d/dmd/lambdacomp.d
@@ -445,7 +445,8 @@ public:
visitType(p.type);
}
- override void visit(StructLiteralExp e) {
+ override void visit(StructLiteralExp e)
+ {
static if (LOG)
printf("StructLiteralExp: %s\n", e.toChars);
diff --git a/gcc/d/dmd/lexer.d b/gcc/d/dmd/lexer.d
index 61b4f41..51e597c 100644
--- a/gcc/d/dmd/lexer.d
+++ b/gcc/d/dmd/lexer.d
@@ -867,7 +867,7 @@ class Lexer
case 0:
case 0x1A:
error(t.loc, "unterminated /* */ comment");
- p = end;
+ //p = end;
t.loc = loc();
t.value = TOK.endOfFile;
return;
@@ -927,7 +927,7 @@ class Lexer
getDocComment(t, lastLine == startLoc.linnum, startLoc.linnum - lastDocLine > 1);
lastDocLine = linnum;
}
- p = end;
+ //p = end;
t.loc = loc();
t.value = TOK.endOfFile;
return;
@@ -1003,7 +1003,7 @@ class Lexer
case 0:
case 0x1A:
error(t.loc, "unterminated /+ +/ comment");
- p = end;
+ //p = end;
t.loc = loc();
t.value = TOK.endOfFile;
return;
@@ -3441,9 +3441,8 @@ class Lexer
int linestart = 0;
if (ct == '/')
{
- if (q < qend && *q == ' ') {
+ if (q < qend && *q == ' ')
++q;
- }
}
else if (q < qend)
{
diff --git a/gcc/d/dmd/location.d b/gcc/d/dmd/location.d
index 8a27541..ef5430f 100644
--- a/gcc/d/dmd/location.d
+++ b/gcc/d/dmd/location.d
@@ -64,7 +64,7 @@ nothrow:
extern (C++) static Loc singleFilename(const char* filename)
{
Loc result;
- locFileTable ~= BaseLoc(filename.toDString, locIndex, 0, [0]);
+ locFileTable ~= new BaseLoc(filename.toDString, locIndex, 0, [0]);
result.index = locIndex++;
return result;
}
@@ -95,7 +95,19 @@ nothrow:
*/
extern (C++) const(char)* filename() const @nogc
{
- return SourceLoc(this).filename.ptr; // _filename;
+ if (this.index == 0)
+ return null;
+
+ const i = fileTableIndex(this.index);
+ if (locFileTable[i].substitutions.length > 0)
+ {
+ const si = locFileTable[i].getSubstitutionIndex(this.index - locFileTable[i].startIndex);
+ const fname = locFileTable[i].substitutions[si].filename;
+ if (fname.length > 0)
+ return fname.ptr;
+ }
+
+ return locFileTable[i].filename.ptr;
}
extern (C++) const(char)* toChars(
@@ -293,11 +305,11 @@ private size_t fileTableIndex(uint index) nothrow @nogc
*/
BaseLoc* newBaseLoc(const(char)* filename, size_t size) nothrow
{
- locFileTable ~= BaseLoc(filename.toDString, locIndex, 1, [0]);
+ locFileTable ~= new BaseLoc(filename.toDString, locIndex, 1, [0]);
// Careful: the endloc of a FuncDeclaration can
// point to 1 past the very last byte in the file, so account for that
locIndex += size + 1;
- return &locFileTable[$ - 1];
+ return locFileTable[$ - 1];
}
/**
@@ -385,7 +397,23 @@ struct BaseLoc
if (substitutions.length == 0)
return loc;
- const offset = loc.fileOffset;
+ const i = getSubstitutionIndex(loc.fileOffset);
+ if (substitutions[i].filename.length > 0)
+ loc.filename = substitutions[i].filename;
+ loc.linnum += substitutions[i].startLine;
+ return loc;
+ }
+
+ /// Resolve an offset into this file to a filename + line + column
+ private SourceLoc getSourceLoc(uint offset) @nogc
+ {
+ const i = getLineIndex(offset);
+ const sl = SourceLoc(filename, cast(int) (i + startLine), cast(int) (1 + offset - lines[i]), offset);
+ return substitute(sl);
+ }
+
+ private size_t getSubstitutionIndex(uint offset) @nogc
+ {
size_t lo = 0;
size_t hi = substitutions.length + -1;
size_t mid = 0;
@@ -395,12 +423,7 @@ struct BaseLoc
if (substitutions[mid].startIndex <= offset)
{
if (mid == substitutions.length - 1 || substitutions[mid + 1].startIndex > offset)
- {
- if (substitutions[mid].filename.length > 0)
- loc.filename = substitutions[mid].filename;
- loc.linnum += substitutions[mid].startLine;
- return loc;
- }
+ return mid;
lo = mid + 1;
}
@@ -412,14 +435,6 @@ struct BaseLoc
assert(0);
}
- /// Resolve an offset into this file to a filename + line + column
- private SourceLoc getSourceLoc(uint offset) @nogc
- {
- const i = getLineIndex(offset);
- const sl = SourceLoc(filename, cast(int) (i + startLine), cast(int) (1 + offset - lines[i]), offset);
- return substitute(sl);
- }
-
/// Binary search the index in `this.lines` corresponding to `offset`
private size_t getLineIndex(uint offset) @nogc
{
@@ -449,4 +464,4 @@ struct BaseLoc
private __gshared uint locIndex = 1;
// Global mapping of Loc indices to source file offset/line/column, see `BaseLoc`
-private __gshared BaseLoc[] locFileTable;
+private __gshared BaseLoc*[] locFileTable;
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index 1cebcc8..84899d0 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -299,13 +299,16 @@ extern (C++) abstract class Type : ASTNode
Type wcto; // MODFlags.wildconst
Type swto; // MODFlags.shared_ | MODFlags.wild
Type swcto; // MODFlags.shared_ | MODFlags.wildconst
+ Type pto; // merged pointer to this type
+ Type rto; // reference to this type
+ Type arrayof; // array of this type
+
+ // ImportC: store the name of the typedef resolving to this type
+ // So `uint8_t x;` will be printed as `uint8_t x;` and not as the resolved `ubyte x;`
+ Identifier typedefIdent;
}
Mcache* mcache;
- Type pto; // merged pointer to this type
- Type rto; // reference to this type
- Type arrayof; // array of this type
-
TypeInfoDeclaration vtinfo; // TypeInfo object for this Type
void* ctype; // for back end
@@ -762,9 +765,6 @@ extern (C++) abstract class Type : ASTNode
memcpy(cast(void*)t, cast(void*)this, sz);
// t.mod = NULL; // leave mod unchanged
t.deco = null;
- t.arrayof = null;
- t.pto = null;
- t.rto = null;
t.vtinfo = null;
t.ctype = null;
t.mcache = null;
@@ -2959,9 +2959,6 @@ extern (C++) final class TypeIdentifier : TypeQualified
{
Identifier ident;
- // The symbol representing this identifier, before alias resolution
- Dsymbol originalSymbol;
-
extern (D) this(Loc loc, Identifier ident)
{
super(Tident, loc);
@@ -3870,7 +3867,8 @@ extern (C++) struct ParameterList
foreach (_, p1; cast() this)
{
auto p2 = other[idx++];
- if (!p2 || p1 != p2) {
+ if (!p2 || p1 != p2)
+ {
diff = true;
break;
}
diff --git a/gcc/d/dmd/mtype.h b/gcc/d/dmd/mtype.h
index 0cf08e7..990f8d4 100644
--- a/gcc/d/dmd/mtype.h
+++ b/gcc/d/dmd/mtype.h
@@ -146,9 +146,6 @@ public:
MOD mod; // modifiers MODxxxx
char *deco;
void* mcache;
- Type *pto; // merged pointer to this type
- Type *rto; // reference to this type
- Type *arrayof; // array of this type
TypeInfoDeclaration *vtinfo; // TypeInfo object for this Type
type *ctype; // for back end
@@ -630,7 +627,6 @@ class TypeIdentifier final : public TypeQualified
{
public:
Identifier *ident;
- Dsymbol *originalSymbol; // The symbol representing this identifier, before alias resolution
static TypeIdentifier *create(Loc loc, Identifier *ident);
const char *kind() override;
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index 121f990..33e0e5a 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -1041,6 +1041,30 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
nextToken();
continue;
+ // The following are all errors, the cases are just for better error messages than the default case
+ case TOK.return_:
+ case TOK.goto_:
+ case TOK.break_:
+ case TOK.continue_:
+ error("`%s` statement must be inside function scope", token.toChars());
+ goto Lerror;
+ case TOK.asm_:
+ case TOK.do_:
+ case TOK.for_:
+ case TOK.foreach_:
+ case TOK.foreach_reverse_:
+ case TOK.if_:
+ case TOK.switch_:
+ case TOK.try_:
+ case TOK.while_:
+ error("`%s` statement must be inside function scope", token.toChars());
+ if (peekNext() == TOK.leftParenthesis || peekNext() == TOK.leftCurly)
+ {
+ parseStatement(0);
+ s = null;
+ continue;
+ }
+ goto Lerror;
default:
error("declaration expected, not `%s`", token.toChars());
Lerror:
@@ -1504,28 +1528,26 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (token.value != TOK.identifier)
{
error("identifier expected following `template`");
- goto Lerr;
+ return null;
}
id = token.ident;
nextToken();
tpl = parseTemplateParameterList();
if (!tpl)
- goto Lerr;
+ return null;
constraint = parseConstraint();
if (token.value != TOK.leftCurly)
{
error("`{` expected after template parameter list, not `%s`", token.toChars()); /* } */
- goto Lerr;
+ nextToken();
+ return null;
}
decldefs = parseBlock(null);
tempdecl = new AST.TemplateDeclaration(loc, id, tpl, constraint, decldefs, ismixin);
return tempdecl;
-
- Lerr:
- return null;
}
/******************************************
@@ -4509,7 +4531,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
if (ident)
checkCstyleTypeSyntax(loc, t, alt, ident);
else if (!isThis && (t != AST.Type.terror))
- noIdentifierForDeclarator(t);
+ noIdentifierForDeclarator(t, token);
if (isAliasDeclaration)
{
@@ -4571,6 +4593,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
default:
error("semicolon expected to close `alias` declaration, not `%s`", token.toChars());
+ nextToken();
break;
}
}
@@ -4734,11 +4757,12 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
return a;
}
- /// Report an error that a declaration of type `t` is missing an identifier
+ /// Report an error that a declaration of type `t` is missing an identifier and got `tok` instead
/// The parser is expected to sit on the next token after the type.
- private void noIdentifierForDeclarator(AST.Type t)
+ private void noIdentifierForDeclarator(AST.Type t, Token tok)
{
- error("no identifier for declarator `%s`", t.toChars());
+ error("variable name expected after type `%s`, not `%s`", t.toChars(), tok.toChars);
+
// A common mistake is to use a reserved keyword as an identifier, e.g. `in` or `out`
if (token.isKeyword)
{
@@ -5016,6 +5040,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
default:
error("semicolon expected to close `alias` declaration, not `%s`", token.toChars());
+ nextToken();
break;
}
break;
@@ -5356,9 +5381,14 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
error("template constraint must follow parameter lists and attributes");
else
error("cannot use function constraints for non-template functions. Use `static if` instead");
+
+ parseConstraint();
}
else
+ {
error("semicolon expected following function declaration, not `%s`", token.toChars());
+ nextToken();
+ }
}
break;
}
@@ -5542,7 +5572,7 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
}
at = parseType(&ai);
if (!ai)
- noIdentifierForDeclarator(at);
+ noIdentifierForDeclarator(at, token);
Larg:
auto p = new AST.Parameter(aloc, storageClass, at, ai, null, null);
parameters.push(p);
diff --git a/gcc/d/dmd/root/string.d b/gcc/d/dmd/root/string.d
index 847af0e..be606c4 100644
--- a/gcc/d/dmd/root/string.d
+++ b/gcc/d/dmd/root/string.d
@@ -377,9 +377,9 @@ auto splitLines(const char[] text)
public const(char)[] front()
{
advance();
- if (index > eolIndex || index >= text.length) {
+ if (index > eolIndex || index >= text.length)
return "";
- }
+
return text[index .. eolIndex];
}
diff --git a/gcc/d/dmd/semantic2.d b/gcc/d/dmd/semantic2.d
index 31fc418..893dc1b 100644
--- a/gcc/d/dmd/semantic2.d
+++ b/gcc/d/dmd/semantic2.d
@@ -852,6 +852,8 @@ private extern(C++) final class StaticAAVisitor : SemanticTimeTransitiveVisitor
loweredExp = loweredExp.ctfeInterpret();
aaExp.lowering = loweredExp;
+
+ semanticTypeInfo(sc, loweredExp.type);
}
// https://issues.dlang.org/show_bug.cgi?id=24602
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index 5d7f8bc..f7a7ce1 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -380,7 +380,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
if (!sc.intypeof)
{
if (fld.tok == TOK.delegate_)
- .error(funcdecl.loc, "%s `%s` cannot be %s members", funcdecl.kind, funcdecl.toPrettyChars, ad.kind());
+ .error(funcdecl.loc, "%s `%s` cannot be %s members", funcdecl.kind, funcdecl.toErrMsg, ad.kind());
else
fld.tok = TOK.function_;
}
@@ -933,7 +933,37 @@ private extern(C++) final class Semantic3Visitor : Visitor
// if a copy constructor is present, the return type conversion will be handled by it
const hasCopyCtor = exp.type.ty == Tstruct && (cast(TypeStruct)exp.type).sym.hasCopyCtor;
if (!hasCopyCtor || !exp.isLvalue())
- exp = exp.implicitCastTo(sc2, tret);
+ {
+ const errors = global.startGagging();
+ auto implicitlyCastedExp = exp.implicitCastTo(sc2, tret);
+ global.endGagging(errors);
+
+ // <https://github.com/dlang/dmd/issues/20888>
+ if (implicitlyCastedExp.isErrorExp())
+ {
+ auto types = toAutoQualChars(exp.type, tret);
+ error(
+ exp.loc,
+ "return value `%s` of type `%s` does not match return type `%s`"
+ ~ ", and cannot be implicitly converted",
+ exp.toErrMsg(),
+ types[0],
+ types[1],
+ );
+
+ if (const func = exp.type.isFunction_Delegate_PtrToFunction())
+ if (func.next.equals(tret))
+ errorSupplemental(
+ exp.loc,
+ "Did you intend to call the %s?",
+ (exp.type.isPtrToFunction())
+ ? "function pointer"
+ : exp.type.kind
+ );
+ }
+
+ exp = implicitlyCastedExp;
+ }
exp = exp.optimize(WANTvalue);
@@ -1375,7 +1405,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
}
if (isCppNonMappableType(f.next.toBasetype()))
{
- .error(funcdecl.loc, "%s `%s` cannot return type `%s` because its linkage is `extern(C++)`", funcdecl.kind, funcdecl.toPrettyChars, f.next.toChars());
+ .error(funcdecl.loc, "%s `%s` cannot return type `%s` because its linkage is `extern(C++)`", funcdecl.kind, funcdecl.toErrMsg(), f.next.toChars());
if (f.next.isTypeDArray())
errorSupplemental(funcdecl.loc, "slices are specific to D and do not have a counterpart representation in C++", f.next.toChars());
funcdecl.errors = true;
@@ -1384,7 +1414,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
{
if (isCppNonMappableType(param.type.toBasetype(), param))
{
- .error(funcdecl.loc, "%s `%s` cannot have parameter of type `%s` because its linkage is `extern(C++)`", funcdecl.kind, funcdecl.toPrettyChars, param.type.toChars());
+ .error(funcdecl.loc, "%s `%s` cannot have parameter of type `%s` because its linkage is `extern(C++)`", funcdecl.kind, funcdecl.toErrMsg(), param.type.toChars());
if (param.type.toBasetype().isTypeSArray())
errorSupplemental(funcdecl.loc, "perhaps use a `%s*` type instead",
param.type.nextOf().mutableOf().unSharedOf().toChars());
@@ -1741,7 +1771,7 @@ extern (D) bool checkClosure(FuncDeclaration fd)
}
a.push(f);
.errorSupplemental(f.loc, "%s `%s` closes over variable `%s`",
- f.kind, f.toPrettyChars(), v.toChars());
+ f.kind, f.toErrMsg(), v.toChars());
if (v.ident != Id.This)
.errorSupplemental(v.loc, "`%s` declared here", v.toChars());
diff --git a/gcc/d/dmd/sideeffect.d b/gcc/d/dmd/sideeffect.d
index 84b9e4e..659b0f4 100644
--- a/gcc/d/dmd/sideeffect.d
+++ b/gcc/d/dmd/sideeffect.d
@@ -20,6 +20,7 @@ import dmd.expressionsem;
import dmd.func;
import dmd.funcsem;
import dmd.globals;
+import dmd.hdrgen;
import dmd.id;
import dmd.identifier;
import dmd.init;
@@ -346,12 +347,13 @@ bool discardValue(Expression e)
BinExp tmp = e.isBinExp();
assert(tmp);
- error(e.loc, "the result of the equality expression `%s` is discarded", e.toChars());
+ error(e.loc, "the result of the equality expression `%s` is discarded", e.toErrMsg());
bool seenSideEffect = false;
foreach(expr; [tmp.e1, tmp.e2])
{
- if (hasSideEffect(expr)) {
- errorSupplemental(expr.loc, "note that `%s` may have a side effect", expr.toChars());
+ if (hasSideEffect(expr))
+ {
+ errorSupplemental(expr.loc, "note that `%s` may have a side effect", expr.toErrMsg());
seenSideEffect |= true;
}
}
@@ -359,7 +361,7 @@ bool discardValue(Expression e)
default:
break;
}
- error(e.loc, "`%s` has no effect", e.toChars());
+ error(e.loc, "`%s` has no effect", e.toErrMsg());
return true;
}
diff --git a/gcc/d/dmd/statementsem.d b/gcc/d/dmd/statementsem.d
index 6a3bc38..4029fda 100644
--- a/gcc/d/dmd/statementsem.d
+++ b/gcc/d/dmd/statementsem.d
@@ -664,7 +664,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
const olderrors = global.startGagging();
discardValue(fs.increment);
if (global.endGagging(olderrors))
- deprecation(fs.increment.loc, "`%s` has no effect", fs.increment.toChars());
+ deprecation(fs.increment.loc, "`%s` has no effect", fs.increment.toErrMsg());
if (checkNonAssignmentArrayOp(fs.increment))
fs.increment = ErrorExp.get();
fs.increment = fs.increment.optimize(WANTvalue);
@@ -2604,7 +2604,7 @@ Statement statementSemanticVisit(Statement s, Scope* sc)
//errors = true;
}
if (global.endGagging(olderrors))
- deprecation(rs.exp.loc, "`%s` has no effect", rs.exp.toChars());
+ deprecation(rs.exp.loc, "`%s` has no effect", rs.exp.toErrMsg());
/* Replace:
* return exp;
diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d
index e82a582..aad88d6 100644
--- a/gcc/d/dmd/tokens.d
+++ b/gcc/d/dmd/tokens.d
@@ -436,8 +436,10 @@ enum FirstCKeyword = TOK.inline;
// Assert that all token enum members have consecutive values and
// that none of them overlap
static assert(() {
- foreach (idx, enumName; __traits(allMembers, TOK)) {
- static if (idx != __traits(getMember, TOK, enumName)) {
+ foreach (idx, enumName; __traits(allMembers, TOK))
+ {
+ static if (idx != __traits(getMember, TOK, enumName))
+ {
pragma(msg, "Error: Expected TOK.", enumName, " to be ", idx, " but is ", __traits(getMember, TOK, enumName));
static assert(0);
}
@@ -925,13 +927,18 @@ nothrow:
return 0;
}
- extern(D) void appendInterpolatedPart(const ref OutBuffer buf) {
+ extern(D) void appendInterpolatedPart(const ref OutBuffer buf)
+ {
appendInterpolatedPart(cast(const(char)*)buf[].ptr, buf.length);
}
- extern(D) void appendInterpolatedPart(const(char)[] str) {
+
+ extern(D) void appendInterpolatedPart(const(char)[] str)
+ {
appendInterpolatedPart(str.ptr, str.length);
}
- extern(D) void appendInterpolatedPart(const(char)* ptr, size_t length) {
+
+ extern(D) void appendInterpolatedPart(const(char)* ptr, size_t length)
+ {
assert(value == TOK.interpolated);
if (interpolatedSet is null)
interpolatedSet = new InterpolatedSet;
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index ae52de5..7f87ac4 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -1187,7 +1187,7 @@ private const(char)* getParamError(TypeFunction tf, Expression arg, Parameter pa
// only mention rvalue if it's relevant
const rv = !arg.isLvalue() && par.isReference();
buf.printf("cannot pass %sargument `%s` of type `%s` to parameter `%s`",
- rv ? "rvalue ".ptr : "".ptr, arg.toChars(), at,
+ rv ? "rvalue ".ptr : "".ptr, arg.toErrMsg(), at,
parameterToChars(par, tf, qual));
return buf.extractChars();
}
@@ -2329,7 +2329,7 @@ Type typeSemantic(Type type, Loc loc, Scope* sc)
{
const(char)* errTxt = fparam.storageClass & STC.ref_ ? "ref" : "out";
.error(e.loc, "expression `%s` of type `%s` is not implicitly convertible to type `%s %s` of parameter `%s`",
- e.toChars(), e.type.toChars(), errTxt, fparam.type.toChars(), fparam.toChars());
+ e.toErrMsg(), e.type.toChars(), errTxt, fparam.type.toChars(), fparam.toChars());
}
e = e.implicitCastTo(sc, fparam.type);
@@ -2493,10 +2493,17 @@ Type typeSemantic(Type type, Loc loc, Scope* sc)
errors = true;
}
- const bool isTypesafeVariadic = i + 1 == dim &&
- tf.parameterList.varargs == VarArg.typesafe &&
- (t.isTypeDArray() || t.isTypeClass());
- if (isTypesafeVariadic)
+ const bool isTypesafeVariadic = i + 1 == dim && tf.parameterList.varargs == VarArg.typesafe;
+ const bool isStackAllocatedVariadic = isTypesafeVariadic && (t.isTypeDArray() || t.isTypeClass());
+
+ if (isTypesafeVariadic && t.isTypeClass())
+ {
+ // Deprecated in 2.111, kept as a legacy feature for compatibility (currently no plan to turn it into an error)
+ .deprecation(loc, "typesafe variadic parameters with a `class` type (`%s %s...`) are deprecated",
+ t.isTypeClass().sym.ident.toChars(), fparam.toChars());
+ }
+
+ if (isStackAllocatedVariadic)
{
/* typesafe variadic arguments are constructed on the stack, so must be `scope`
*/
@@ -2518,7 +2525,7 @@ Type typeSemantic(Type type, Loc loc, Scope* sc)
}
}
- if (isTypesafeVariadic)
+ if (isStackAllocatedVariadic)
{
/* This is because they can be constructed on the stack
* https://dlang.org/spec/function.html#typesafe_variadic_functions
@@ -3454,10 +3461,26 @@ Expression getProperty(Type t, Scope* scope_, Loc loc, Identifier ident, int fla
{
if (auto sym = dsym.isAggregateDeclaration())
{
- if (auto fd = search_function(sym, Id.opDispatch))
- errorSupplemental(loc, "potentially malformed `opDispatch`. Use an explicit instantiation to get a better error message");
- else if (!sym.members)
+ if (!sym.members)
+ {
errorSupplemental(sym.loc, "`%s %s` is opaque and has no members.", sym.kind, mt.toPrettyChars(true));
+ return ErrorExp.get();
+ }
+
+ if (auto fd = search_function(sym, Id.opDispatch))
+ {
+ if (auto td = fd.isTemplateDeclaration())
+ {
+ e = mt.defaultInitLiteral(loc);
+ auto se = new StringExp(e.loc, ident.toString());
+ auto tiargs = new Objects();
+ tiargs.push(se);
+ auto dti = new DotTemplateInstanceExp(e.loc, e, Id.opDispatch, tiargs);
+ dti.ti.tempdecl = td;
+ dti.dotTemplateSemanticProp(scope_, DotExpFlag.none);
+ return ErrorExp.get();
+ }
+ }
}
errorSupplemental(dsym.loc, "%s `%s` defined here",
dsym.kind, dsym.toChars());
@@ -4731,7 +4754,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
{
if (e.op == EXP.type)
{
- error(e.loc, "`%s` is not an expression", e.toChars());
+ error(e.loc, "`%s` is not an expression", e.toErrMsg());
return ErrorExp.get();
}
else if (mt.dim.toUInteger() < 1 && checkUnsafeDotExp(sc, e, ident, flag))
@@ -4780,7 +4803,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
}
if (e.op == EXP.type && (ident == Id.length || ident == Id.ptr))
{
- error(e.loc, "`%s` is not an expression", e.toChars());
+ error(e.loc, "`%s` is not an expression", e.toErrMsg());
return ErrorExp.get();
}
if (ident == Id.length)
@@ -5207,7 +5230,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
Declaration d = s.isDeclaration();
if (!d)
{
- error(e.loc, "`%s.%s` is not a declaration", e.toChars(), ident.toChars());
+ error(e.loc, "`%s.%s` is not a declaration", e.toErrMsg(), ident.toChars());
return ErrorExp.get();
}
@@ -5640,7 +5663,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
Declaration d = s.isDeclaration();
if (!d)
{
- error(e.loc, "`%s.%s` is not a declaration", e.toChars(), ident.toChars());
+ error(e.loc, "`%s.%s` is not a declaration", e.toErrMsg(), ident.toChars());
return ErrorExp.get();
}
@@ -6715,30 +6738,32 @@ Type pointerTo(Type type)
{
if (type.ty == Terror)
return type;
- if (!type.pto)
+ auto mcache = type.getMcache();
+ if (!mcache.pto)
{
Type t = new TypePointer(type);
if (type.ty == Tfunction)
{
t.deco = t.merge().deco;
- type.pto = t;
+ mcache.pto = t;
}
else
- type.pto = t.merge();
+ mcache.pto = t.merge();
}
- return type.pto;
+ return mcache.pto;
}
Type referenceTo(Type type)
{
if (type.ty == Terror)
return type;
- if (!type.rto)
+ auto mcache = type.getMcache();
+ if (!mcache.rto)
{
Type t = new TypeReference(type);
- type.rto = t.merge();
+ mcache.rto = t.merge();
}
- return type.rto;
+ return mcache.rto;
}
// Make corresponding static array type without semantic
@@ -6756,12 +6781,13 @@ Type arrayOf(Type type)
{
if (type.ty == Terror)
return type;
- if (!type.arrayof)
+ auto mcache = type.getMcache();
+ if (!mcache.arrayof)
{
Type t = new TypeDArray(type);
- type.arrayof = t.merge();
+ mcache.arrayof = t.merge();
}
- return type.arrayof;
+ return mcache.arrayof;
}
/********************************
@@ -7013,6 +7039,39 @@ Type sharedWildConstOf(Type type)
return t;
}
+Type nakedOf(Type type)
+{
+ //printf("Type::nakedOf() %p, %s\n", type, type.toChars());
+ if (type.mod == 0)
+ return type;
+ if (type.mcache) with(type.mcache)
+ {
+ // the cache has the naked type at the "identity" position, try to find it
+ if (cto && cto.mod == 0)
+ return cto;
+ if (ito && ito.mod == 0)
+ return ito;
+ if (sto && sto.mod == 0)
+ return sto;
+ if (scto && scto.mod == 0)
+ return scto;
+ if (wto && wto.mod == 0)
+ return wto;
+ if (wcto && wcto.mod == 0)
+ return wcto;
+ if (swto && swto.mod == 0)
+ return swto;
+ if (swcto && swcto.mod == 0)
+ return swcto;
+ }
+ Type t = type.nullAttributes();
+ t.mod = 0;
+ t = t.merge();
+ t.fixTo(type);
+ //printf("\t%p %s\n", t, t.toChars());
+ return t;
+}
+
Type unqualify(Type type, uint m)
{
Type t = type.mutableOf().unSharedOf();
diff --git a/gcc/d/dmd/typinf.d b/gcc/d/dmd/typinf.d
index 58102cd..1a96823 100644
--- a/gcc/d/dmd/typinf.d
+++ b/gcc/d/dmd/typinf.d
@@ -22,6 +22,7 @@ import dmd.expression;
import dmd.globals;
import dmd.location;
import dmd.mtype;
+import dmd.typesem;
import core.stdc.stdio;
/****************************************************
@@ -67,6 +68,9 @@ bool genTypeInfo(Expression e, Loc loc, Type torig, Scope* sc)
import dmd.typesem : merge2;
Type t = torig.merge2(); // do this since not all Type's are merge'd
+ if (t.ty == Taarray)
+ t = makeNakedAssociativeArray(cast(TypeAArray)t);
+
bool needsCodegen = false;
if (!t.vtinfo)
{
@@ -79,7 +83,7 @@ bool genTypeInfo(Expression e, Loc loc, Type torig, Scope* sc)
else if (t.isWild())
t.vtinfo = TypeInfoWildDeclaration.create(t);
else
- t.vtinfo = getTypeInfoDeclaration(t);
+ t.vtinfo = getTypeInfoDeclaration(t, sc);
assert(t.vtinfo);
// ClassInfos are generated as part of ClassDeclaration codegen
@@ -105,7 +109,7 @@ bool genTypeInfo(Expression e, Loc loc, Type torig, Scope* sc)
*/
extern (C++) Type getTypeInfoType(Loc loc, Type t, Scope* sc);
-private TypeInfoDeclaration getTypeInfoDeclaration(Type t)
+private TypeInfoDeclaration getTypeInfoDeclaration(Type t, Scope* sc)
{
//printf("Type::getTypeInfoDeclaration() %s\n", t.toChars());
switch (t.ty)
@@ -117,7 +121,7 @@ private TypeInfoDeclaration getTypeInfoDeclaration(Type t)
case Tsarray:
return TypeInfoStaticArrayDeclaration.create(t);
case Taarray:
- return TypeInfoAssociativeArrayDeclaration.create(t);
+ return getTypeInfoAssocArrayDeclaration(cast(TypeAArray)t, sc);
case Tstruct:
return TypeInfoStructDeclaration.create(t);
case Tvector:
@@ -141,6 +145,70 @@ private TypeInfoDeclaration getTypeInfoDeclaration(Type t)
}
}
+/******************************************
+ * Instantiate TypeInfoAssociativeArrayDeclaration and fill
+ * the entry with TypeInfo_AssociativeArray.Entry!(t.index, t.next)
+ *
+ * Params:
+ * t = TypeAArray to generate TypeInfo_AssociativeArray for
+ * sc = context
+ * Returns:
+ * a TypeInfoAssociativeArrayDeclaration with field entry initialized
+ */
+TypeInfoDeclaration getTypeInfoAssocArrayDeclaration(TypeAArray t, Scope* sc)
+{
+ import dmd.arraytypes;
+ import dmd.expressionsem;
+ import dmd.id;
+
+ assert(sc); // must not be called in the code generation phase
+
+ auto ti = TypeInfoAssociativeArrayDeclaration.create(t);
+ t.vtinfo = ti; // assign it early to avoid recursion in expressionSemantic
+ Loc loc = t.loc;
+ auto tiargs = new Objects();
+ tiargs.push(t.index); // always called with naked types
+ tiargs.push(t.next);
+
+ Expression id = new IdentifierExp(loc, Id.empty);
+ id = new DotIdExp(loc, id, Id.object);
+ id = new DotIdExp(loc, id, Id.TypeInfo_AssociativeArray);
+ auto tempinst = new DotTemplateInstanceExp(loc, id, Id.Entry, tiargs);
+ auto e = expressionSemantic(tempinst, sc);
+ assert(e.type);
+ ti.entry = e.type;
+ if (auto ts = ti.entry.isTypeStruct())
+ {
+ ts.sym.requestTypeInfo = true;
+ if (auto tmpl = ts.sym.isInstantiated())
+ tmpl.minst = sc._module.importedFrom; // ensure it get's emitted
+ }
+ getTypeInfoType(loc, ti.entry, sc);
+ assert(ti.entry.vtinfo);
+
+ return ti;
+}
+
+/******************************************
+ * Find or create a TypeAArray with index and next without
+ * any head modifiers, tail `inout` is replaced with `const`
+ *
+ * Params:
+ * t = TypeAArray to convert
+ * Returns:
+ * t = found type
+ */
+Type makeNakedAssociativeArray(TypeAArray t)
+{
+ Type tindex = t.index.toBasetype().nakedOf().substWildTo(MODFlags.const_);
+ Type tnext = t.next.toBasetype().nakedOf().substWildTo(MODFlags.const_);
+ if (tindex == t.index && tnext == t.next)
+ return t;
+
+ t = new TypeAArray(tnext, tindex);
+ return t.merge();
+}
+
/**************************************************
* Returns:
* true if any part of type t is speculative.
diff --git a/gcc/d/dmd/typinf.h b/gcc/d/dmd/typinf.h
index 4a8c942..e416191 100644
--- a/gcc/d/dmd/typinf.h
+++ b/gcc/d/dmd/typinf.h
@@ -14,6 +14,8 @@
class Expression;
class Type;
+class TypeAArray;
+class TypeInfoDeclaration;
struct Scope;
namespace dmd
@@ -21,5 +23,7 @@ namespace dmd
bool genTypeInfo(Expression *e, Loc loc, Type *torig, Scope *sc);
bool isSpeculativeType(Type *t);
bool builtinTypeInfo(Type *t);
+ Type *makeNakedAssociativeArray(TypeAArray *t);
+ TypeInfoDeclaration *getTypeInfoAssocArrayDeclaration(TypeAArray *t, Scope *sc);
}
Type *getTypeInfoType(Loc loc, Type *t, Scope *sc);