aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIain Buclaw <ibuclaw@gdcproject.org>2025-03-12 17:19:49 +0100
committerIain Buclaw <ibuclaw@gdcproject.org>2025-03-15 16:33:00 +0100
commite8c9f4ab8f0c8ad8da5f7fb0f1a4956507fe64f5 (patch)
tree46099e73f24300a919394d9f1972fdf5941f672d
parent254549d2bb9bb3c2719dec597427919c59514fc3 (diff)
downloadgcc-e8c9f4ab8f0c8ad8da5f7fb0f1a4956507fe64f5.zip
gcc-e8c9f4ab8f0c8ad8da5f7fb0f1a4956507fe64f5.tar.gz
gcc-e8c9f4ab8f0c8ad8da5f7fb0f1a4956507fe64f5.tar.bz2
d: Merge upstream dmd, druntime b7e3b3b617
D front-end changes: - `delete' is no longer a keyword. - Initializing a field with itself has been deprecated. D runtime changes: - Add Windows BCrypt bindings under `core.sys.windows.bcrypt'. gcc/d/ChangeLog: * dmd/MERGE: Merge upstream b7e3b3b617. libphobos/ChangeLog: * libdruntime/MERGE: Merge upstream b7e3b3b617. * libdruntime/Makefile.am (DRUNTIME_DSOURCES_WINDOWS): Add core/sys/windows/bcrypt.d. * libdruntime/Makefile.in: Regenerate. * libdruntime/gcc/sections/elf.d (sizeofTLS): Give function the same mangling as gcc.sections.sizeofTLS. * libdruntime/gcc/sections/package.d: Import core.internal.traits. (pinLoadedLibraries): Mangle as function from rt.sections_elf_shared. (unpinLoadedLibraries): Likewise. (inheritLoadedLibraries): Likewise. (cleanupLoadedLibraries): Likewise. (sizeOfTLS): Add forward declaration.
-rw-r--r--gcc/d/dmd/MERGE2
-rw-r--r--gcc/d/dmd/clone.d18
-rw-r--r--gcc/d/dmd/ctfeexpr.d8
-rw-r--r--gcc/d/dmd/dcast.d14
-rw-r--r--gcc/d/dmd/dsymbolsem.d2
-rw-r--r--gcc/d/dmd/dtemplate.d23
-rw-r--r--gcc/d/dmd/expression.d108
-rw-r--r--gcc/d/dmd/expression.h3
-rw-r--r--gcc/d/dmd/expressionsem.d617
-rw-r--r--gcc/d/dmd/func.d3
-rw-r--r--gcc/d/dmd/hdrgen.d2
-rw-r--r--gcc/d/dmd/id.d66
-rw-r--r--gcc/d/dmd/initsem.d4
-rw-r--r--gcc/d/dmd/mangle/cpp.d43
-rw-r--r--gcc/d/dmd/mtype.d12
-rw-r--r--gcc/d/dmd/mustuse.d23
-rw-r--r--gcc/d/dmd/objc.d11
-rw-r--r--gcc/d/dmd/opover.d1757
-rw-r--r--gcc/d/dmd/parse.d44
-rw-r--r--gcc/d/dmd/semantic3.d2
-rw-r--r--gcc/d/dmd/tokens.d3
-rw-r--r--gcc/d/dmd/tokens.h1
-rw-r--r--gcc/d/dmd/typesem.d27
-rw-r--r--gcc/testsuite/gdc.test/compilable/interpret3.d4
-rw-r--r--gcc/testsuite/gdc.test/compilable/nogc.d3
-rw-r--r--gcc/testsuite/gdc.test/compilable/test22510.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ctor_self_assignment.d23
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/dep_d1_ops.d325
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/deprecateopdot.d30
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/diag_class_alloc.d19
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail10534.d28
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail11445.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail13902.d4
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail14343.d25
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail14486.d79
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail17906.d13
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail2361.d15
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail297.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail3.d2
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d8
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/faildeleteaa.d13
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/hexstring.d36
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/ice11968.d9
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/nogc1.d20
-rw-r--r--gcc/testsuite/gdc.test/fail_compilation/test16195.d15
-rw-r--r--gcc/testsuite/gdc.test/runnable/funclit.d11
-rw-r--r--gcc/testsuite/gdc.test/runnable/newdel.d19
-rw-r--r--gcc/testsuite/gdc.test/runnable/opover.d40
-rw-r--r--gcc/testsuite/gdc.test/runnable/xtest46.d16
-rw-r--r--libphobos/libdruntime/MERGE2
-rw-r--r--libphobos/libdruntime/Makefile.am15
-rw-r--r--libphobos/libdruntime/Makefile.in180
-rw-r--r--libphobos/libdruntime/core/internal/abort.d2
-rw-r--r--libphobos/libdruntime/core/internal/array/casting.d2
-rw-r--r--libphobos/libdruntime/core/internal/array/construction.d3
-rw-r--r--libphobos/libdruntime/core/internal/array/duplication.d2
-rw-r--r--libphobos/libdruntime/core/internal/array/utils.d2
-rw-r--r--libphobos/libdruntime/core/internal/gc/bits.d4
-rw-r--r--libphobos/libdruntime/core/internal/gc/blkcache.d5
-rw-r--r--libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d12
-rw-r--r--libphobos/libdruntime/core/internal/gc/os.d10
-rw-r--r--libphobos/libdruntime/core/internal/gc/pooltable.d2
-rw-r--r--libphobos/libdruntime/core/internal/parseoptions.d8
-rw-r--r--libphobos/libdruntime/core/internal/qsort.d5
-rw-r--r--libphobos/libdruntime/core/internal/util/array.d2
-rw-r--r--libphobos/libdruntime/core/runtime.d216
-rw-r--r--libphobos/libdruntime/core/stdc/config.d3
-rw-r--r--libphobos/libdruntime/core/sys/windows/bcrypt.d900
-rw-r--r--libphobos/libdruntime/core/sys/windows/dll.d40
-rw-r--r--libphobos/libdruntime/core/sys/windows/sdkddkver.d50
-rw-r--r--libphobos/libdruntime/core/sys/windows/threadaux.d50
-rw-r--r--libphobos/libdruntime/core/sys/windows/w32api.d93
-rw-r--r--libphobos/libdruntime/core/sys/windows/winbase.d4
-rw-r--r--libphobos/libdruntime/core/thread/osthread.d59
-rw-r--r--libphobos/libdruntime/gcc/sections/elf.d6
-rw-r--r--libphobos/libdruntime/gcc/sections/package.d31
-rw-r--r--libphobos/libdruntime/rt/adi.d7
-rw-r--r--libphobos/libdruntime/rt/arraycat.d12
-rw-r--r--libphobos/libdruntime/rt/deh.d4
-rw-r--r--libphobos/libdruntime/rt/dmain2.d39
-rw-r--r--libphobos/libdruntime/rt/ehalloc.d5
-rw-r--r--libphobos/libdruntime/rt/lifetime.d41
-rw-r--r--libphobos/libdruntime/rt/minfo.d12
-rw-r--r--libphobos/libdruntime/rt/monitor_.d37
-rw-r--r--libphobos/libdruntime/rt/profilegc.d7
-rw-r--r--libphobos/libdruntime/rt/sections.d3
-rw-r--r--libphobos/libdruntime/rt/tlsgc.d9
87 files changed, 2878 insertions, 2562 deletions
diff --git a/gcc/d/dmd/MERGE b/gcc/d/dmd/MERGE
index 4172630..a91f40b 100644
--- a/gcc/d/dmd/MERGE
+++ b/gcc/d/dmd/MERGE
@@ -1,4 +1,4 @@
-d1157134103a209d36d6ee9c1df1d61d5929ec6d
+b7e3b3b61711bf6c6cad27c7b5b73df0e570c215
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/clone.d b/gcc/d/dmd/clone.d
index d7658c6..93b6dc3 100644
--- a/gcc/d/dmd/clone.d
+++ b/gcc/d/dmd/clone.d
@@ -101,7 +101,7 @@ StorageClass mergeFuncAttrs(StorageClass s1, const FuncDeclaration f) pure @safe
*/
FuncDeclaration hasIdentityOpAssign(AggregateDeclaration ad, Scope* sc)
{
- Dsymbol assign = search_function(ad, Id.assign);
+ Dsymbol assign = search_function(ad, Id.opAssign);
if (!assign)
return null;
@@ -303,7 +303,7 @@ FuncDeclaration buildOpAssign(StructDeclaration sd, Scope* sc)
auto fparams = new Parameters();
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);
+ auto fop = new FuncDeclaration(declLoc, Loc.initial, Id.opAssign, stc, tf);
fop.storage_class |= STC.inference;
fop.isGenerated = true;
Expression e;
@@ -482,7 +482,7 @@ bool needOpEquals(StructDeclaration sd)
private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc)
{
FuncDeclaration f;
- Dsymbol eq = search_function(ad, Id.eq);
+ Dsymbol eq = search_function(ad, Id.opEquals);
if (!eq)
return null;
@@ -537,7 +537,7 @@ private FuncDeclaration hasIdentityOpEquals(AggregateDeclaration ad, Scope* sc)
* opEquals is changed to be never implicitly generated.
* Now, struct objects comparison s1 == s2 is translated to:
* s1.tupleof == s2.tupleof
- * to calculate structural equality. See EqualExp.op_overload.
+ * to calculate structural equality. See `opOverloadEquals`.
*/
FuncDeclaration buildOpEquals(StructDeclaration sd, Scope* sc)
{
@@ -564,7 +564,7 @@ FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc)
return null; // bitwise comparison would work
//printf("StructDeclaration::buildXopEquals() %s\n", sd.toChars());
- if (Dsymbol eq = search_function(sd, Id.eq))
+ if (Dsymbol eq = search_function(sd, Id.opEquals))
{
if (FuncDeclaration fd = eq.isFuncDeclaration())
{
@@ -639,7 +639,7 @@ FuncDeclaration buildXopEquals(StructDeclaration sd, Scope* sc)
FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc)
{
//printf("StructDeclaration::buildXopCmp() %s\n", toChars());
- if (Dsymbol cmp = search_function(sd, Id.cmp))
+ if (Dsymbol cmp = search_function(sd, Id.opCmp))
{
if (FuncDeclaration fd = cmp.isFuncDeclaration())
{
@@ -667,7 +667,7 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc)
* Consider 'alias this', but except opDispatch.
*/
Expression e = new DsymbolExp(sd.loc, sd);
- e = new DotIdExp(sd.loc, e, Id.cmp);
+ e = new DotIdExp(sd.loc, e, Id.opCmp);
Scope* sc2 = sc.push();
e = e.trySemantic(sc2);
sc2.pop();
@@ -688,7 +688,7 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc)
default:
break;
}
- if (!s || s.ident != Id.cmp)
+ if (!s || s.ident != Id.opCmp)
e = null; // there's no valid member 'opCmp'
}
if (!e)
@@ -736,7 +736,7 @@ FuncDeclaration buildXopCmp(StructDeclaration sd, Scope* sc)
fop.parent = sd;
Expression e1 = new IdentifierExp(loc, Id.This);
Expression e2 = new IdentifierExp(loc, Id.p);
- Expression e = new CallExp(loc, new DotIdExp(loc, e1, Id.cmp), e2);
+ Expression e = new CallExp(loc, new DotIdExp(loc, e1, Id.opCmp), e2);
fop.fbody = new ReturnStatement(loc, e);
const errors = global.startGagging(); // Do not report errors
Scope* sc2 = sc.push();
diff --git a/gcc/d/dmd/ctfeexpr.d b/gcc/d/dmd/ctfeexpr.d
index a6cfe6e..6d2a954 100644
--- a/gcc/d/dmd/ctfeexpr.d
+++ b/gcc/d/dmd/ctfeexpr.d
@@ -1529,11 +1529,9 @@ Expression ctfeCast(UnionExp* pue, const ref Loc loc, Type type, Type to, Expres
: tclass.implicitConvTo(to.mutableOf());
if (match)
return paint();
- else
- {
- emplaceExp!(NullExp)(pue, loc, to);
- return pue.exp();
- }
+
+ emplaceExp!(NullExp)(pue, loc, to);
+ return pue.exp();
}
// Allow TypeInfo type painting
diff --git a/gcc/d/dmd/dcast.d b/gcc/d/dmd/dcast.d
index 2f33301..0d95ad4 100644
--- a/gcc/d/dmd/dcast.d
+++ b/gcc/d/dmd/dcast.d
@@ -4144,20 +4144,6 @@ Expression typeCombine(BinExp be, Scope* sc)
return ErrorExp.get();
}
- Type t1 = be.e1.type.toBasetype();
- Type t2 = be.e2.type.toBasetype();
-
- if (be.op == EXP.min || be.op == EXP.add)
- {
- // struct+struct, and class+class are errors
- if (t1.ty == Tstruct && t2.ty == Tstruct)
- return errorReturn();
- if (t1.ty == Tclass && t2.ty == Tclass)
- return errorReturn();
- if (t1.ty == Taarray && t2.ty == Taarray)
- return errorReturn();
- }
-
if (auto result = typeMerge(sc, be.op, be.e1, be.e2))
{
if (be.type is null)
diff --git a/gcc/d/dmd/dsymbolsem.d b/gcc/d/dmd/dsymbolsem.d
index 0d87f6e..c7fb26a 100644
--- a/gcc/d/dmd/dsymbolsem.d
+++ b/gcc/d/dmd/dsymbolsem.d
@@ -3061,7 +3061,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (sd.ctor)
{
- Dsymbol scall = sd.search(Loc.initial, Id.call);
+ Dsymbol scall = sd.search(Loc.initial, Id.opCall);
if (scall)
{
const xerrors = global.startGagging();
diff --git a/gcc/d/dmd/dtemplate.d b/gcc/d/dmd/dtemplate.d
index 7f7437c..dd9f3da 100644
--- a/gcc/d/dmd/dtemplate.d
+++ b/gcc/d/dmd/dtemplate.d
@@ -217,17 +217,12 @@ Dsymbol getDsymbol(RootObject oarg)
return te.td;
if (auto te = ea.isScopeExp())
return te.sds;
- else
- return null;
- }
- else
- {
- // Try to convert Type to symbol
- if (auto ta = isType(oarg))
- return ta.toDsymbol(null);
- else
- return isDsymbol(oarg); // if already a symbol
+ return null;
}
+ // Try to convert Type to symbol
+ if (auto ta = isType(oarg))
+ return ta.toDsymbol(null);
+ return isDsymbol(oarg); // if already a symbol
}
@@ -5752,8 +5747,8 @@ MATCH matchArg(TemplateParameter tp, Loc instLoc, Scope* sc, Objects* tiargs, si
if (auto ttp = tp.isTemplateTupleParameter())
return matchArgTuple(ttp);
- else
- return matchArgParameter();
+
+ return matchArgParameter();
}
MATCH matchArg(TemplateParameter tp, Scope* sc, RootObject oarg, size_t i, TemplateParameters* parameters, ref Objects dedtypes, Declaration* psparam)
@@ -6221,8 +6216,8 @@ void printTemplateStats(bool listInstances, ErrorSink eSink)
auto diff = b.ts.uniqueInstantiations - a.ts.uniqueInstantiations;
if (diff)
return diff;
- else
- return b.ts.numInstantiations - a.ts.numInstantiations;
+
+ return b.ts.numInstantiations - a.ts.numInstantiations;
}
}
diff --git a/gcc/d/dmd/expression.d b/gcc/d/dmd/expression.d
index 75d6468..5b8e010 100644
--- a/gcc/d/dmd/expression.d
+++ b/gcc/d/dmd/expression.d
@@ -535,98 +535,6 @@ extern (C++) abstract class Expression : ASTNode
return false;
}
- extern (D) final bool checkScalar()
- {
- if (op == EXP.error)
- return true;
- if (type.toBasetype().ty == Terror)
- return true;
- if (!type.isScalar())
- {
- error(loc, "`%s` is not a scalar, it is a `%s`", toChars(), type.toChars());
- return true;
- }
- return checkValue();
- }
-
- extern (D) final bool checkNoBool()
- {
- if (op == EXP.error)
- return true;
- if (type.toBasetype().ty == Terror)
- return true;
- if (type.toBasetype().ty == Tbool)
- {
- error(loc, "operation not allowed on `bool` `%s`", toChars());
- return true;
- }
- return false;
- }
-
- extern (D) final bool checkIntegral()
- {
- if (op == EXP.error)
- return true;
- if (type.toBasetype().ty == Terror)
- return true;
- if (!type.isIntegral())
- {
- error(loc, "`%s` is not of integral type, it is a `%s`", toChars(), type.toChars());
- return true;
- }
- return checkValue();
- }
-
- extern (D) final bool checkArithmetic(EXP op)
- {
- if (op == EXP.error)
- return true;
- if (type.toBasetype().ty == Terror)
- return true;
- if (!type.isIntegral() && !type.isFloating())
- {
- // 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(loc, msg, EXPtoString(op).ptr, toChars(), type.toChars());
- return true;
- }
- return checkValue();
- }
-
- /*******************************
- * Check whether the expression allows RMW operations, error with rmw operator diagnostic if not.
- * ex is the RHS expression, or NULL if ++/-- is used (for diagnostics)
- * Returns true if error occurs.
- */
- extern (D) final bool checkReadModifyWrite(EXP rmwOp, Expression ex = null)
- {
- //printf("Expression::checkReadModifyWrite() %s %s", toChars(), ex ? ex.toChars() : "");
- if (!type || !type.isShared() || type.isTypeStruct() || type.isTypeClass())
- return false;
-
- // atomicOp uses opAssign (+=/-=) rather than opOp (++/--) for the CT string literal.
- switch (rmwOp)
- {
- case EXP.plusPlus:
- case EXP.prePlusPlus:
- rmwOp = EXP.addAssign;
- break;
- case EXP.minusMinus:
- case EXP.preMinusMinus:
- rmwOp = EXP.minAssign;
- break;
- default:
- break;
- }
-
- error(loc, "read-modify-write operations are not allowed for `shared` variables");
- errorSupplemental(loc, "Use `core.atomic.atomicOp!\"%s\"(%s, %s)` instead",
- EXPtoString(rmwOp).ptr, toChars(), ex ? ex.toChars() : "1");
- return true;
- }
-
/******************************
* Take address of expression.
*/
@@ -3039,8 +2947,6 @@ extern (C++) abstract class BinExp : Expression
{
Expression e1;
Expression e2;
- Type att1; // Save alias this type to detect recursion
- Type att2; // Save alias this type to detect recursion
extern (D) this(const ref Loc loc, EXP op, Expression e1, Expression e2) scope @safe
{
@@ -3058,20 +2964,6 @@ extern (C++) abstract class BinExp : Expression
return e;
}
- extern (D) final bool checkIntegralBin()
- {
- bool r1 = e1.checkIntegral();
- bool r2 = e2.checkIntegral();
- return (r1 || r2);
- }
-
- extern (D) final bool checkArithmeticBin()
- {
- bool r1 = e1.checkArithmetic(this.op);
- bool r2 = e2.checkArithmetic(this.op);
- return (r1 || r2);
- }
-
/*********************
* Mark the operands as will never be dereferenced,
* which is useful info for @safe checks.
diff --git a/gcc/d/dmd/expression.h b/gcc/d/dmd/expression.h
index d62aea8..07b163f1 100644
--- a/gcc/d/dmd/expression.h
+++ b/gcc/d/dmd/expression.h
@@ -679,9 +679,6 @@ public:
Expression *e1;
Expression *e2;
- Type *att1; // Save alias this type to detect recursion
- Type *att2; // Save alias this type to detect recursion
-
BinExp *syntaxCopy() override;
void accept(Visitor *v) override { v->visit(this); }
diff --git a/gcc/d/dmd/expressionsem.d b/gcc/d/dmd/expressionsem.d
index eb4a5f8..fcb47a5 100644
--- a/gcc/d/dmd/expressionsem.d
+++ b/gcc/d/dmd/expressionsem.d
@@ -663,7 +663,7 @@ Expression resolveOpDollar(Scope* sc, ArrayExp ae, Expression* pe0)
assert(!ae.lengthVar);
*pe0 = null;
AggregateDeclaration ad = isAggregate(ae.e1.type);
- Dsymbol slice = search_function(ad, Id.slice);
+ Dsymbol slice = search_function(ad, Id.opSlice);
//printf("slice = %s %s\n", slice.kind(), slice.toChars());
Expression fallback()
{
@@ -2403,7 +2403,7 @@ private bool checkPostblit(Type t, ref Loc loc, Scope* sc)
/***************************************
* Pull out any properties.
*/
-private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = null, BinExp saveAtts = null)
+private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 = null, Type[2]* aliasThisStop = null)
{
//printf("resolvePropertiesX, e1 = %s %s, e2 = %s\n", EXPtoString(e1.op).ptr, e1.toChars(), e2 ? e2.toChars() : null);
Loc loc = e1.loc;
@@ -2478,11 +2478,9 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
if (e2)
{
e = new AssignExp(loc, e, e2);
- if (saveAtts)
- {
- (cast(BinExp)e).att1 = saveAtts.att1;
- (cast(BinExp)e).att2 = saveAtts.att2;
- }
+ if (aliasThisStop)
+ return e.expressionSemantic(sc, *aliasThisStop);
+ return e.expressionSemantic(sc);
}
return e.expressionSemantic(sc);
}
@@ -2584,11 +2582,8 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
if (e2)
{
e = new AssignExp(loc, e, e2);
- if (saveAtts)
- {
- (cast(BinExp)e).att1 = saveAtts.att1;
- (cast(BinExp)e).att2 = saveAtts.att2;
- }
+ if (aliasThisStop)
+ return e.expressionSemantic(sc, *aliasThisStop);
}
return e.expressionSemantic(sc);
}
@@ -3816,6 +3811,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
Scope* sc;
Expression result;
+ // For binary expressions, stores recursive 'alias this' types of lhs and rhs to prevent endless loops.
+ // See tryAliasThisSemantic
+ Type[2] aliasThisStop;
+
this(Scope* sc) scope @safe
{
this.sc = sc;
@@ -6206,7 +6205,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}
// No constructor, look for overload of opCall
- if (search_function(sd, Id.call))
+ if (search_function(sd, Id.opCall))
goto L1;
// overload of opCall, therefore it's a call
if (exp.e1.op != EXP.type)
@@ -6247,7 +6246,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
L1:
// Rewrite as e1.call(arguments)
- Expression e = new DotIdExp(exp.loc, exp.e1, Id.call);
+ Expression e = new DotIdExp(exp.loc, exp.e1, Id.opCall);
e = new CallExp(exp.loc, e, exp.arguments, exp.names);
e = e.expressionSemantic(sc);
result = e;
@@ -7536,13 +7535,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
override void visit(BinAssignExp exp)
{
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadBinaryAssign(sc, aliasThisStop))
{
result = e;
return;
}
+ Expression e;
if (exp.e1.op == EXP.arrayLength)
{
// arr.length op= e2;
@@ -7933,7 +7932,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
const callExpIdent = callExpFunc.ident;
isEqualsCallExpression = callExpIdent == Id.__equals ||
- callExpIdent == Id.eq;
+ callExpIdent == Id.opEquals;
}
}
if (op == EXP.equal || op == EXP.notEqual ||
@@ -8777,8 +8776,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
printf("PtrExp::semantic('%s')\n", exp.toChars());
}
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadUnary(sc))
{
result = e;
return;
@@ -8835,8 +8833,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
printf("NegExp::semantic('%s')\n", exp.toChars());
}
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadUnary(sc))
{
result = e;
return;
@@ -8876,8 +8873,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
printf("UAddExp::semantic('%s')\n", exp.toChars());
}
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadUnary(sc))
{
result = e;
return;
@@ -8902,8 +8898,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
override void visit(ComExp exp)
{
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadUnary(sc))
{
result = e;
return;
@@ -8975,17 +8970,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
override void visit(DeleteExp exp)
{
- // @@@DEPRECATED_2.109@@@
- // 1. Deprecated since 2.079
- // 2. Error since 2.099
- // 3. Removal of keyword, "delete" can be used for other identities
- if (!exp.isRAII)
- {
- error(exp.loc, "the `delete` keyword is obsolete");
- errorSupplemental(exp.loc, "use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead");
- return setError();
- }
-
Expression e = exp;
if (Expression ex = unaSemantic(exp, sc))
@@ -9176,7 +9160,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!exp.to.equals(exp.e1.type) && exp.mod == cast(ubyte)~0)
{
- if (Expression e = exp.op_overload(sc))
+ if (Expression e = exp.opOverloadCast(sc))
{
result = e.implicitCastTo(sc, exp.to);
return;
@@ -9466,8 +9450,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
error(exp.loc, "upper and lower bounds are needed to slice a pointer");
if (auto ad = isAggregate(tp.next.toBasetype()))
{
- auto s = search_function(ad, Id.index);
- if (!s) s = search_function(ad, Id.slice);
+ auto s = search_function(ad, Id.opIndex);
+ if (!s) s = search_function(ad, Id.opSlice);
if (s)
{
auto fd = s.isFuncDeclaration();
@@ -9710,8 +9694,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (result)
return;
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadArray(sc))
{
result = e;
return;
@@ -10133,13 +10116,6 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
exp.e1 = e1x;
- Expression e = exp.op_overload(sc);
- if (e)
- {
- result = e;
- return;
- }
-
if (exp.e1.checkReadModifyWrite(exp.op))
return setError();
@@ -10182,7 +10158,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// Combine de,ea,eb,ec
if (de)
ea = new CommaExp(exp.loc, de, ea);
- e = new CommaExp(exp.loc, ea, eb);
+ Expression e = new CommaExp(exp.loc, ea, eb);
e = new CommaExp(exp.loc, e, ec);
e = e.expressionSemantic(sc);
result = e;
@@ -10192,7 +10168,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.e1 = exp.e1.modifiableLvalue(sc);
exp.e1 = exp.e1.optimize(WANTvalue, /*keepLvalue*/ true);
- e = exp;
+ Expression e = exp;
if (exp.e1.checkScalar() ||
exp.e1.checkSharedAccess(sc))
return setError();
@@ -10209,15 +10185,15 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
override void visit(PreExp exp)
{
- Expression e = exp.op_overload(sc);
// printf("PreExp::semantic('%s')\n", toChars());
- if (e)
+ if (Expression e = exp.opOverloadUnary(sc))
{
result = e;
return;
}
// Rewrite as e1+=1 or e1-=1
+ Expression e;
if (exp.op == EXP.prePlusPlus)
e = new AddAssignExp(exp.loc, exp.e1, IntegerExp.literal!1);
else
@@ -10328,7 +10304,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
AggregateDeclaration ad = isAggregate(t1b);
if (!ad)
break;
- if (search_function(ad, Id.indexass))
+ if (search_function(ad, Id.opIndexAssign))
{
// Deal with $
res = resolveOpDollar(sc, ae, &e0);
@@ -10347,7 +10323,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
*/
Expressions* a = ae.arguments.copy();
a.insert(0, exp.e2);
- res = new DotIdExp(exp.loc, ae.e1, Id.indexass);
+ res = new DotIdExp(exp.loc, ae.e1, Id.opIndexAssign);
res = new CallExp(exp.loc, res, a);
if (maybeSlice) // a[] = e2 might be: a.opSliceAssign(e2)
res = res.trySemantic(sc);
@@ -10358,7 +10334,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
Lfallback:
- if (maybeSlice && search_function(ad, Id.sliceass))
+ if (maybeSlice && search_function(ad, Id.opSliceAssign))
{
// Deal with $
res = resolveOpDollar(sc, ae, ie, &e0);
@@ -10381,7 +10357,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
a.push(ie.lwr);
a.push(ie.upr);
}
- res = new DotIdExp(exp.loc, ae.e1, Id.sliceass);
+ res = new DotIdExp(exp.loc, ae.e1, Id.opSliceAssign);
res = new CallExp(exp.loc, res, a);
res = res.expressionSemantic(sc);
return setResult(Expression.combine(e0, res));
@@ -10471,7 +10447,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
* or:
* f() = value
*/
- if (Expression e = resolvePropertiesX(sc, e1x, exp.e2, exp))
+ if (Expression e = resolvePropertiesX(sc, e1x, exp.e2, &aliasThisStop))
return setResult(e);
if (e1x.checkRightThis(sc))
@@ -10604,6 +10580,35 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (exp.op == EXP.assign
&& exp.e1.checkModifiable(sc) == Modifiable.initialization)
{
+ // Check common mistake of misspelled parameters in constructors,
+ // e.g. `this(int feild) { this.field = field; }`
+ if (auto dve1 = exp.e1.isDotVarExp)
+ if (auto dve2 = exp.e2.isDotVarExp)
+ if (sc.func && sc.func.parameters && dve1.e1.isThisExp && dve2.e1.isThisExp()
+ && dve1.var.ident.equals(dve2.var.ident))
+ {
+ // @@@DEPRECATED_2.121@@@
+ // Deprecated in 2.111, make it an error in 2.121
+ deprecation(exp.e1.loc, "cannot initialize field `%s` with itself", dve1.var.toChars());
+ auto findParameter(const(char)[] s, ref int cost)
+ {
+ foreach (p; *sc.func.parameters)
+ {
+ if (p.ident.toString == s)
+ {
+ cost = 1;
+ return p.ident.toString;
+ }
+ }
+ return null;
+ }
+ import dmd.root.speller : speller;
+ if (auto s = speller!findParameter(dve1.var.ident.toString))
+ {
+ deprecationSupplemental(sc.func.loc, "did you mean to use parameter `%.*s`?\n", s.fTuple.expand);
+ }
+ }
+
//printf("[%s] change to init - %s\n", exp.loc.toChars(), exp.toChars());
auto t = exp.type;
exp = new ConstructExp(exp.loc, exp.e1, exp.e2);
@@ -10826,13 +10831,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!e2x.implicitConvTo(t1))
{
AggregateDeclaration ad2 = isAggregate(e2x.type);
- if (ad2 && ad2.aliasthis && !isRecursiveAliasThis(exp.att2, exp.e2.type))
+ if (ad2 && ad2.aliasthis && !isRecursiveAliasThis(aliasThisStop[1], exp.e2.type))
{
/* Rewrite (e1 op e2) as:
* (e1 op e2.aliasthis)
*/
exp.e2 = new DotIdExp(exp.e2.loc, exp.e2, ad2.aliasthis.ident);
- result = exp.expressionSemantic(sc);
+ result = exp.expressionSemantic(sc, aliasThisStop);
return;
}
}
@@ -10887,14 +10892,14 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
result = e;
return;
}
- if (search_function(sd, Id.call))
+ if (search_function(sd, Id.opCall))
{
/* Look for static opCall
* https://issues.dlang.org/show_bug.cgi?id=2702
* Rewrite as:
* e1 = typeof(e1).opCall(arguments)
*/
- e2x = typeDotIdExp(e2x.loc, e1x.type, Id.call);
+ e2x = typeDotIdExp(e2x.loc, e1x.type, Id.opCall);
e2x = new CallExp(exp.loc, e2x, exp.e2);
e2x = e2x.expressionSemantic(sc);
@@ -10911,13 +10916,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
else // https://issues.dlang.org/show_bug.cgi?id=11355
{
AggregateDeclaration ad2 = isAggregate(e2x.type);
- if (ad2 && ad2.aliasthis && !isRecursiveAliasThis(exp.att2, exp.e2.type))
+ if (ad2 && ad2.aliasthis && !isRecursiveAliasThis(aliasThisStop[1], exp.e2.type))
{
/* Rewrite (e1 op e2) as:
* (e1 op e2.aliasthis)
*/
exp.e2 = new DotIdExp(exp.e2.loc, exp.e2, ad2.aliasthis.ident);
- result = exp.expressionSemantic(sc);
+ result = exp.expressionSemantic(sc, aliasThisStop);
return;
}
}
@@ -10958,8 +10963,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
ae.e1 = ae.e1.expressionSemantic(sc);
ae.e1 = ae.e1.optimize(WANTvalue);
ae.e2 = ev;
- Expression e = ae.op_overload(sc);
- if (e)
+ if (Expression e = ae.opOverloadAssign(sc, aliasThisStop))
{
Expression ey = null;
if (t2.ty == Tstruct && sd == t2.toDsymbol(sc))
@@ -11009,14 +11013,10 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}
}
- else
+ else if (Expression e = exp.isAssignExp().opOverloadAssign(sc, aliasThisStop))
{
- Expression e = exp.op_overload(sc);
- if (e)
- {
- result = e;
- return;
- }
+ result = e;
+ return;
}
}
else
@@ -11033,8 +11033,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// Disallow assignment operator overloads for same type
if (exp.op == EXP.assign && !exp.e2.implicitConvTo(exp.e1.type))
{
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.isAssignExp().opOverloadAssign(sc, aliasThisStop))
{
result = e;
return;
@@ -11410,7 +11409,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (e2x.op == EXP.error && exp.op == EXP.construct && t1.ty == Tstruct)
{
scope sd = (cast(TypeStruct)t1).sym;
- Dsymbol opAssign = search_function(sd, Id.assign);
+ Dsymbol opAssign = search_function(sd, Id.opAssign);
// and the struct defines an opAssign
if (opAssign)
@@ -11705,9 +11704,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
override void visit(PowAssignExp exp)
{
-
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadBinaryAssign(sc, aliasThisStop))
{
result = e;
return;
@@ -11754,7 +11751,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if ((exp.e1.type.isIntegral() || exp.e1.type.isFloating()) && (exp.e2.type.isIntegral() || exp.e2.type.isFloating()))
{
Expression e0 = null;
- e = exp.reorderSettingAAElem(sc);
+ Expression e = exp.reorderSettingAAElem(sc);
e = Expression.extractLast(e, e0);
assert(e == exp);
@@ -11786,8 +11783,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
//printf("CatAssignExp::semantic() %s\n", exp.toChars());
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadBinaryAssign(sc, aliasThisStop))
{
result = e;
return;
@@ -11881,49 +11877,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
else
{
- // Try alias this on first operand
- static Expression tryAliasThisForLhs(BinAssignExp exp, Scope* sc)
- {
- AggregateDeclaration ad1 = isAggregate(exp.e1.type);
- if (!ad1 || !ad1.aliasthis)
- return null;
-
- /* Rewrite (e1 op e2) as:
- * (e1.aliasthis op e2)
- */
- if (isRecursiveAliasThis(exp.att1, exp.e1.type))
- return null;
- //printf("att %s e1 = %s\n", Token.toChars(e.op), e.e1.type.toChars());
- Expression e1 = new DotIdExp(exp.loc, exp.e1, ad1.aliasthis.ident);
- BinExp be = cast(BinExp)exp.copy();
- be.e1 = e1;
- return be.trySemantic(sc);
- }
-
- // Try alias this on second operand
- static Expression tryAliasThisForRhs(BinAssignExp exp, Scope* sc)
- {
- AggregateDeclaration ad2 = isAggregate(exp.e2.type);
- if (!ad2 || !ad2.aliasthis)
- return null;
- /* Rewrite (e1 op e2) as:
- * (e1 op e2.aliasthis)
- */
- if (isRecursiveAliasThis(exp.att2, exp.e2.type))
- return null;
- //printf("att %s e2 = %s\n", Token.toChars(e.op), e.e2.type.toChars());
- Expression e2 = new DotIdExp(exp.loc, exp.e2, ad2.aliasthis.ident);
- BinExp be = cast(BinExp)exp.copy();
- be.e2 = e2;
- return be.trySemantic(sc);
- }
-
Laliasthis:
- result = tryAliasThisForLhs(exp, sc);
+ result = checkAliasThisForLhs(isAggregate(exp.e1.type), sc, exp, aliasThisStop);
if (result)
return;
- result = tryAliasThisForRhs(exp, sc);
+ result = checkAliasThisForRhs(isAggregate(exp.e2.type), sc, exp, aliasThisStop);
if (result)
return;
@@ -12076,13 +12035,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
printf("AddExp::semantic('%s')\n", exp.toChars());
}
- if (Expression ex = binSemanticProp(exp, sc))
- {
- result = ex;
- return;
- }
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadBinary(sc, aliasThisStop))
{
result = e;
return;
@@ -12139,6 +12092,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}
+ if (exp.checkArithmeticBin())
+ return setError();
+
tb1 = exp.e1.type.toBasetype();
if (!target.isVectorOpSupported(tb1, exp.op, tb2))
{
@@ -12178,13 +12134,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
printf("MinExp::semantic('%s')\n", exp.toChars());
}
- if (Expression ex = binSemanticProp(exp, sc))
- {
- result = ex;
- return;
- }
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadBinary(sc, aliasThisStop))
{
result = e;
return;
@@ -12217,6 +12167,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (t1.ty == Tpointer)
{
+ Expression e;
if (t2.ty == Tpointer)
{
// https://dlang.org/spec/expression.html#add_expressions
@@ -12294,6 +12245,9 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}
+ if (exp.checkArithmeticBin())
+ return setError();
+
t1 = exp.e1.type.toBasetype();
t2 = exp.e2.type.toBasetype();
if (!target.isVectorOpSupported(t1, exp.op, t2))
@@ -12422,14 +12376,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
// https://dlang.org/spec/expression.html#cat_expressions
//printf("CatExp.semantic() %s\n", toChars());
-
- if (Expression ex = binSemanticProp(exp, sc))
- {
- result = ex;
- return;
- }
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadBinary(sc, aliasThisStop))
{
result = e;
return;
@@ -12581,6 +12528,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
}
Type t1 = exp.e1.type.toBasetype();
Type t2 = exp.e2.type.toBasetype();
+ Expression e;
if ((t1.ty == Tarray || t1.ty == Tsarray) &&
(t2.ty == Tarray || t2.ty == Tsarray))
{
@@ -12598,30 +12546,25 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
trySetCatExpLowering(result);
}
- override void visit(MulExp exp)
+ bool commonBinOpSemantic(BinExp exp)
{
- version (none)
- {
- printf("MulExp::semantic() %s\n", exp.toChars());
- }
-
- if (Expression ex = binSemanticProp(exp, sc))
- {
- result = ex;
- return;
- }
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadBinary(sc, aliasThisStop))
{
result = e;
- return;
+ return true;
}
if (Expression ex = typeCombine(exp, sc))
{
result = ex;
- return;
+ return true;
}
+ return false;
+ }
+ bool commonArithBinOpSemantic(BinExp exp)
+ {
+ if (commonBinOpSemantic(exp))
+ return true;
Type tb = exp.type.toBasetype();
if (tb.ty == Tarray || tb.ty == Tsarray)
@@ -12629,15 +12572,28 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (!isArrayOpValid(exp))
{
result = arrayOpInvalidError(exp);
- return;
+ return true;
}
result = exp;
- return;
+ return true;
}
if (exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
- return setError();
+ {
+ setError();
+ return true;
+ }
+ return false;
+ }
+ override void visit(MulExp exp)
+ {
+ version (none)
+ {
+ printf("MulExp::semantic() %s\n", exp.toChars());
+ }
+ if (commonArithBinOpSemantic(exp))
+ return;
if (exp.type.isFloating())
{
Type t1 = exp.e1.type;
@@ -12676,7 +12632,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
// iy * iv = -yv
exp.e1.type = exp.type;
exp.e2.type = exp.type;
- e = new NegExp(exp.loc, exp);
+ Expression e = new NegExp(exp.loc, exp);
e = e.expressionSemantic(sc);
result = e;
return;
@@ -12689,7 +12645,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.type = t1; // t1 is complex
}
}
- else if (!target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))
+ else if (!target.isVectorOpSupported(exp.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))
{
result = exp.incompatibleTypes();
return;
@@ -12699,39 +12655,8 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
override void visit(DivExp exp)
{
-
- if (Expression ex = binSemanticProp(exp, sc))
- {
- result = ex;
- return;
- }
- Expression e = exp.op_overload(sc);
- if (e)
- {
- result = e;
- return;
- }
-
- if (Expression ex = typeCombine(exp, sc))
- {
- result = ex;
- return;
- }
-
- Type tb = exp.type.toBasetype();
- if (tb.ty == Tarray || tb.ty == Tsarray)
- {
- if (!isArrayOpValid(exp))
- {
- result = arrayOpInvalidError(exp);
- return;
- }
- result = exp;
+ if (commonArithBinOpSemantic(exp))
return;
- }
-
- if (exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
- return setError();
if (exp.type.isFloating())
{
@@ -12745,7 +12670,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
{
// x/iv = i(-x/v)
exp.e2.type = t1;
- e = new NegExp(exp.loc, exp);
+ Expression e = new NegExp(exp.loc, exp);
e = e.expressionSemantic(sc);
result = e;
return;
@@ -12785,7 +12710,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
exp.type = t1; // t1 is complex
}
}
- else if (!target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))
+ else if (!target.isVectorOpSupported(exp.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))
{
result = exp.incompatibleTypes();
return;
@@ -12795,45 +12720,15 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
override void visit(ModExp exp)
{
-
- if (Expression ex = binSemanticProp(exp, sc))
- {
- result = ex;
- return;
- }
- Expression e = exp.op_overload(sc);
- if (e)
- {
- result = e;
+ if (commonArithBinOpSemantic(exp))
return;
- }
- if (Expression ex = typeCombine(exp, sc))
- {
- result = ex;
- return;
- }
-
- Type tb = exp.type.toBasetype();
- if (tb.ty == Tarray || tb.ty == Tsarray)
- {
- if (!isArrayOpValid(exp))
- {
- result = arrayOpInvalidError(exp);
- return;
- }
- result = exp;
- return;
- }
- if (!target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))
+ if (!target.isVectorOpSupported(exp.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))
{
result = exp.incompatibleTypes();
return;
}
- if (exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
- return setError();
-
if (exp.type.isFloating())
{
exp.type = exp.e1.type;
@@ -12848,49 +12743,17 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
override void visit(PowExp exp)
{
-
- //printf("PowExp::semantic() %s\n", toChars());
- if (Expression ex = binSemanticProp(exp, sc))
- {
- result = ex;
- return;
- }
- Expression e = exp.op_overload(sc);
- if (e)
- {
- result = e;
+ if (commonArithBinOpSemantic(exp))
return;
- }
-
- if (Expression ex = typeCombine(exp, sc))
- {
- result = ex;
- return;
- }
-
- Type tb = exp.type.toBasetype();
- if (tb.ty == Tarray || tb.ty == Tsarray)
- {
- if (!isArrayOpValid(exp))
- {
- result = arrayOpInvalidError(exp);
- return;
- }
- result = exp;
- return;
- }
-
- if (exp.checkArithmeticBin() || exp.checkSharedAccessBin(sc))
- return setError();
- if (!target.isVectorOpSupported(tb, exp.op, exp.e2.type.toBasetype()))
+ if (!target.isVectorOpSupported(exp.type.toBasetype(), exp.op, exp.e2.type.toBasetype()))
{
result = exp.incompatibleTypes();
return;
}
// First, attempt to fold the expression.
- e = exp.optimize(WANTvalue);
+ Expression e = exp.optimize(WANTvalue);
if (e.op != EXP.pow)
{
e = e.expressionSemantic(sc);
@@ -12923,14 +12786,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
private void visitShift(BinExp exp)
{
-
- if (Expression ex = binSemanticProp(exp, sc))
- {
- result = ex;
- return;
- }
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadBinary(sc, aliasThisStop))
{
result = e;
return;
@@ -12971,14 +12827,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
private void visitBinaryBitOp(BinExp exp)
{
-
- if (Expression ex = binSemanticProp(exp, sc))
- {
- result = ex;
- return;
- }
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadBinary(sc, aliasThisStop))
{
result = e;
return;
@@ -13136,57 +12985,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return setError();
}
-
- EXP cmpop = exp.op;
- if (auto e = exp.op_overload(sc, &cmpop))
+ if (auto e = exp.opOverloadCmp(sc, aliasThisStop))
{
- if (!e.type.isScalar() && e.type.equals(exp.e1.type))
- {
- error(exp.loc, "recursive `opCmp` expansion");
- return setError();
- }
- if (e.op == EXP.call)
- {
-
- if (t1.ty == Tclass && t2.ty == Tclass)
- {
- // Lower to object.__cmp(e1, e2)
- Expression cl = new IdentifierExp(exp.loc, Id.empty);
- cl = new DotIdExp(exp.loc, cl, Id.object);
- cl = new DotIdExp(exp.loc, cl, Id.__cmp);
- cl = cl.expressionSemantic(sc);
-
- auto arguments = new Expressions();
- // Check if op_overload found a better match by calling e2.opCmp(e1)
- // If the operands were swapped, then the result must be reversed
- // e1.opCmp(e2) == -e2.opCmp(e1)
- // cmpop takes care of this
- if (exp.op == cmpop)
- {
- arguments.push(exp.e1);
- arguments.push(exp.e2);
- }
- else
- {
- // Use better match found by op_overload
- arguments.push(exp.e2);
- arguments.push(exp.e1);
- }
-
- cl = new CallExp(exp.loc, cl, arguments);
- cl = new CmpExp(cmpop, exp.loc, cl, new IntegerExp(0));
- result = cl.expressionSemantic(sc);
- return;
- }
-
- e = new CmpExp(cmpop, exp.loc, e, IntegerExp.literal!0);
- e = e.expressionSemantic(sc);
- }
result = e;
return;
}
-
if (Expression ex = typeCombine(exp, sc))
{
result = ex;
@@ -13284,14 +13088,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
override void visit(InExp exp)
{
-
- if (Expression ex = binSemanticProp(exp, sc))
- {
- result = ex;
- return;
- }
- Expression e = exp.op_overload(sc);
- if (e)
+ if (Expression e = exp.opOverloadBinary(sc, aliasThisStop))
{
result = e;
return;
@@ -13455,13 +13252,12 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return false;
}
- if (auto e = exp.op_overload(sc))
+ if (auto e = exp.opOverloadEqual(sc, aliasThisStop))
{
result = e;
return;
}
-
const isArrayComparison = (t1.ty == Tarray || t1.ty == Tsarray) &&
(t2.ty == Tarray || t2.ty == Tsarray);
const needsArrayLowering = isArrayComparison && needsDirectEq(t1, t2, sc);
@@ -13931,6 +13727,32 @@ Expression trySemantic(Expression exp, Scope* sc)
return e;
}
+/**********************************
+ * Try expression semantic on `exp`, gagging semantic errors,
+ * but don't resolve alias this on a BinExp when the lhs or rhs
+ * has the corresponding type in `aliasThisStop` (See `isRecursiveAliasThis`).
+ *
+ * Params:
+ * exp = expression to try semantic on
+ * sc = scope
+ * aliasThisStop = pair of recursive alias this types to stop endless recursion
+ * Returns:
+ * exp after expression semantic, or `null` on error
+ */
+Expression trySemanticAliasThis(Expression exp, Scope* sc, Type[2] aliasThisStop)
+{
+ if (exp.expressionSemanticDone)
+ return exp;
+
+ const errors = global.startGagging();
+ Expression e = expressionSemantic(exp, sc, aliasThisStop);
+
+ if (global.endGagging(errors))
+ return null;
+
+ return e;
+}
+
/**************************
* Helper function for easy error propagation.
* If error occurs, returns ErrorExp. Otherwise returns NULL.
@@ -14015,6 +13837,18 @@ Expression expressionSemantic(Expression e, Scope* sc)
return v.result;
}
+// ditto, but passes alias this stop types, see trySemanticAliasThis
+private Expression expressionSemantic(Expression e, Scope* sc, Type[2] aliasThisStop)
+{
+ if (e.expressionSemanticDone)
+ return e;
+
+ scope v = new ExpressionSemanticVisitor(sc);
+ v.aliasThisStop = aliasThisStop;
+ e.accept(v);
+ return v.result;
+}
+
private Expression dotIdSemanticPropX(DotIdExp exp, Scope* sc)
{
//printf("dotIdSemanticPropX() %s\n", toChars(exp));
@@ -14849,6 +14683,105 @@ MATCH matchType(FuncExp funcExp, Type to, Scope* sc, FuncExp* presult, ErrorSink
return m;
}
+private bool checkScalar(Expression e)
+{
+ if (e.op == EXP.error)
+ return true;
+ if (e.type.toBasetype().ty == Terror)
+ return true;
+ if (!e.type.isScalar())
+ {
+ error(e.loc, "`%s` is not a scalar, it is a `%s`", e.toChars(), e.type.toChars());
+ return true;
+ }
+ return e.checkValue();
+}
+
+private bool checkNoBool(Expression e)
+{
+ if (e.op == EXP.error)
+ return true;
+ if (e.type.toBasetype().ty == Terror)
+ return true;
+ if (e.type.toBasetype().ty == Tbool)
+ {
+ error(e.loc, "operation not allowed on `bool` `%s`", e.toChars());
+ return true;
+ }
+ return false;
+}
+
+private bool checkIntegral(Expression e)
+{
+ if (e.op == EXP.error)
+ return true;
+ if (e.type.toBasetype().ty == Terror)
+ return true;
+ if (!e.type.isIntegral())
+ {
+ error(e.loc, "`%s` is not of integral type, it is a `%s`", e.toChars(), e.type.toChars());
+ return true;
+ }
+ return e.checkValue();
+}
+
+private bool checkArithmetic(Expression e, EXP op)
+{
+ if (op == EXP.error)
+ return true;
+ if (e.type.toBasetype().ty == Terror)
+ return true;
+ if (!e.type.isIntegral() && !e.type.isFloating())
+ {
+ // unary aggregate ops error here
+ 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());
+ return true;
+ }
+
+ // FIXME: Existing code relies on adding / subtracting types in typeof() expressions:
+ // alias I = ulong; alias U = typeof(I + 1u);
+ // https://github.com/dlang/dmd/issues/20763
+ if (op == EXP.add || op == EXP.min)
+ return false;
+
+ return e.checkValue();
+}
+
+/*******************************
+ * Check whether the expression allows RMW operations, error with rmw operator diagnostic if not.
+ * ex is the RHS expression, or NULL if ++/-- is used (for diagnostics)
+ * Returns true if error occurs.
+ */
+private bool checkReadModifyWrite(Expression e, EXP rmwOp, Expression ex = null)
+{
+ //printf("Expression::checkReadModifyWrite() %s %s", toChars(), ex ? ex.toChars() : "");
+ if (!e.type || !e.type.isShared() || e.type.isTypeStruct() || e.type.isTypeClass())
+ return false;
+
+ // atomicOp uses opAssign (+=/-=) rather than opOp (++/--) for the CT string literal.
+ switch (rmwOp)
+ {
+ case EXP.plusPlus:
+ case EXP.prePlusPlus:
+ rmwOp = EXP.addAssign;
+ break;
+ case EXP.minusMinus:
+ case EXP.preMinusMinus:
+ rmwOp = EXP.minAssign;
+ break;
+ default:
+ break;
+ }
+
+ error(e.loc, "read-modify-write operations are not allowed for `shared` variables");
+ errorSupplemental(e.loc, "Use `core.atomic.atomicOp!\"%s\"(%s, %s)` instead",
+ EXPtoString(rmwOp).ptr, e.toChars(), ex ? ex.toChars() : "1");
+ return true;
+}
+
private bool checkSharedAccessBin(BinExp binExp, Scope* sc)
{
const r1 = binExp.e1.checkSharedAccess(sc);
@@ -14856,6 +14789,18 @@ private bool checkSharedAccessBin(BinExp binExp, Scope* sc)
return (r1 || r2);
}
+private bool checkIntegralBin(BinExp e)
+{
+ bool r1 = e.e1.checkIntegral();
+ bool r2 = e.e2.checkIntegral();
+ return (r1 || r2);
+}
+
+private bool checkArithmeticBin(BinExp e)
+{
+ return (e.e1.checkArithmetic(e.op) || e.e2.checkArithmetic(e.op));
+}
+
/***************************************
* If expression is shared, check that we can access it.
* Give error message if not.
@@ -16451,7 +16396,7 @@ Expression toBoolean(Expression exp, Scope* sc)
/* Don't really need to check for opCast first, but by doing so we
* get better error messages if it isn't there.
*/
- if (Dsymbol fd = search_function(ad, Id._cast))
+ if (Dsymbol fd = search_function(ad, Id.opCast))
{
e = new CastExp(exp.loc, e, Type.tbool);
e = e.expressionSemantic(sc);
diff --git a/gcc/d/dmd/func.d b/gcc/d/dmd/func.d
index 993bce8..70f4c83 100644
--- a/gcc/d/dmd/func.d
+++ b/gcc/d/dmd/func.d
@@ -581,8 +581,7 @@ extern (C++) class FuncDeclaration : Declaration
{
if (isMain())
return "D main";
- else
- return Dsymbol.toPrettyChars(QualifyTypes);
+ return Dsymbol.toPrettyChars(QualifyTypes);
}
/** for diagnostics, e.g. 'int foo(int x, int y) pure' */
diff --git a/gcc/d/dmd/hdrgen.d b/gcc/d/dmd/hdrgen.d
index d391bdb..961a0d2 100644
--- a/gcc/d/dmd/hdrgen.d
+++ b/gcc/d/dmd/hdrgen.d
@@ -2435,7 +2435,7 @@ private void expressionPrettyPrint(Expression e, ref OutBuffer buf, ref HdrGenSt
void visitSymOff(SymOffExp e)
{
if (e.offset)
- buf.printf("(& %s%+lld)", e.var.toChars(), e.offset);
+ buf.printf("(& %s + %llu)", e.var.toChars(), e.offset);
else if (e.var.isTypeInfoDeclaration())
buf.writestring(e.var.toChars());
else
diff --git a/gcc/d/dmd/id.d b/gcc/d/dmd/id.d
index ee4214a..9833e198 100644
--- a/gcc/d/dmd/id.d
+++ b/gcc/d/dmd/id.d
@@ -223,60 +223,15 @@ immutable Msgtable[] msgtable =
{ "__LOCAL_SIZE" },
// For operator overloads
- { "uadd", "opPos" },
- { "neg", "opNeg" },
- { "com", "opCom" },
- { "add", "opAdd" },
- { "add_r", "opAdd_r" },
- { "sub", "opSub" },
- { "sub_r", "opSub_r" },
- { "mul", "opMul" },
- { "mul_r", "opMul_r" },
- { "div", "opDiv" },
- { "div_r", "opDiv_r" },
- { "mod", "opMod" },
- { "mod_r", "opMod_r" },
- { "eq", "opEquals" },
- { "cmp", "opCmp" },
- { "iand", "opAnd" },
- { "iand_r", "opAnd_r" },
- { "ior", "opOr" },
- { "ior_r", "opOr_r" },
- { "ixor", "opXor" },
- { "ixor_r", "opXor_r" },
- { "shl", "opShl" },
- { "shl_r", "opShl_r" },
- { "shr", "opShr" },
- { "shr_r", "opShr_r" },
- { "ushr", "opUShr" },
- { "ushr_r", "opUShr_r" },
- { "cat", "opCat" },
- { "cat_r", "opCat_r" },
- { "assign", "opAssign" },
- { "addass", "opAddAssign" },
- { "subass", "opSubAssign" },
- { "mulass", "opMulAssign" },
- { "divass", "opDivAssign" },
- { "modass", "opModAssign" },
- { "andass", "opAndAssign" },
- { "orass", "opOrAssign" },
- { "xorass", "opXorAssign" },
- { "shlass", "opShlAssign" },
- { "shrass", "opShrAssign" },
- { "ushrass", "opUShrAssign" },
- { "catass", "opCatAssign" },
- { "postinc", "opPostInc" },
- { "postdec", "opPostDec" },
- { "index", "opIndex" },
- { "indexass", "opIndexAssign" },
- { "slice", "opSlice" },
- { "sliceass", "opSliceAssign" },
- { "call", "opCall" },
- { "_cast", "opCast" },
- { "opIn" },
- { "opIn_r" },
- { "opStar" },
- { "opDot" },
+ { "opEquals" },
+ { "opCmp" },
+ { "opAssign" },
+ { "opIndex" },
+ { "opIndexAssign" },
+ { "opSlice" },
+ { "opSliceAssign" },
+ { "opCall" },
+ { "opCast" },
{ "opDispatch" },
{ "opDollar" },
{ "opUnary" },
@@ -287,9 +242,6 @@ immutable Msgtable[] msgtable =
{ "opOpAssign" },
{ "opIndexOpAssign" },
{ "opSliceOpAssign" },
- { "pow", "opPow" },
- { "pow_r", "opPow_r" },
- { "powass", "opPowAssign" },
{ "classNew", "new" },
{ "classDelete", "delete" },
diff --git a/gcc/d/dmd/initsem.d b/gcc/d/dmd/initsem.d
index aec6807..c181d53 100644
--- a/gcc/d/dmd/initsem.d
+++ b/gcc/d/dmd/initsem.d
@@ -489,7 +489,7 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
else
i.exp = e.optimize(WANTvalue);
}
- else if (search_function(sd, Id.call))
+ else if (search_function(sd, Id.opCall))
{
/* https://issues.dlang.org/show_bug.cgi?id=1547
*
@@ -499,7 +499,7 @@ Initializer initializerSemantic(Initializer init, Scope* sc, ref Type tx, NeedIn
* i.exp = typeof(sd).opCall(arguments)
*/
- Expression e = typeDotIdExp(i.loc, sd.type, Id.call);
+ Expression e = typeDotIdExp(i.loc, sd.type, Id.opCall);
e = new CallExp(i.loc, e, i.exp);
e = e.expressionSemantic(sc);
e = resolveProperties(sc, e);
diff --git a/gcc/d/dmd/mangle/cpp.d b/gcc/d/dmd/mangle/cpp.d
index 67c9b53..4932b01 100644
--- a/gcc/d/dmd/mangle/cpp.d
+++ b/gcc/d/dmd/mangle/cpp.d
@@ -60,11 +60,11 @@ package CppOperator isCppOperator(const scope Identifier id)
{
with (Id) with (CppOperator)
{
- return (id == _cast) ? Cast :
- (id == assign) ? Assign :
- (id == eq) ? Eq :
- (id == index) ? Index :
- (id == call) ? Call :
+ return (id == opCast) ? Cast :
+ (id == opAssign) ? Assign :
+ (id == opEquals) ? Eq :
+ (id == opIndex) ? Index :
+ (id == opCall) ? Call :
(id == opUnary) ? Unary :
(id == opBinary) ? Binary :
(id == opOpAssign) ? OpAssign :
@@ -435,10 +435,10 @@ private final class CppMangleVisitor : Visitor
// 4. null pointer: std::nullptr_t (since C++11)
if (t.ty == Tvoid || t.ty == Tbool)
return true;
- else if (t.ty == Tnull && global.params.cplusplus >= CppStdRevision.cpp11)
+ if (t.ty == Tnull && global.params.cplusplus >= CppStdRevision.cpp11)
return true;
- else
- return t.isTypeBasic() && (t.isIntegral() || t.isReal());
+
+ return t.isTypeBasic() && (t.isIntegral() || t.isReal());
}
/******************************
@@ -1102,13 +1102,13 @@ private final class CppMangleVisitor : Visitor
buf.writestring(ctor.isCpCtor ? "C2" : "C1");
else if (d.isAggregateDtor())
buf.writestring("D1");
- else if (d.ident && d.ident == Id.assign)
+ else if (d.ident && d.ident == Id.opAssign)
buf.writestring("aS");
- else if (d.ident && d.ident == Id.eq)
+ else if (d.ident && d.ident == Id.opEquals)
buf.writestring("eq");
- else if (d.ident && d.ident == Id.index)
+ else if (d.ident && d.ident == Id.opIndex)
buf.writestring("ix");
- else if (d.ident && d.ident == Id.call)
+ else if (d.ident && d.ident == Id.opCall)
buf.writestring("cl");
else
source_name(d, true);
@@ -1939,21 +1939,21 @@ extern(C++):
//printf("enum id = '%s'\n", id.toChars());
if (id == Id.__c_long)
return writeBasicType(t, 0, 'l');
- else if (id == Id.__c_ulong)
+ if (id == Id.__c_ulong)
return writeBasicType(t, 0, 'm');
- else if (id == Id.__c_char)
+ if (id == Id.__c_char)
return writeBasicType(t, 0, 'c');
- else if (id == Id.__c_wchar_t)
+ if (id == Id.__c_wchar_t)
return writeBasicType(t, 0, 'w');
- else if (id == Id.__c_longlong)
+ if (id == Id.__c_longlong)
return writeBasicType(t, 0, 'x');
- else if (id == Id.__c_ulonglong)
+ if (id == Id.__c_ulonglong)
return writeBasicType(t, 0, 'y');
- else if (id == Id.__c_complex_float)
+ if (id == Id.__c_complex_float)
return Type.tcomplex32.accept(this);
- else if (id == Id.__c_complex_double)
+ if (id == Id.__c_complex_double)
return Type.tcomplex64.accept(this);
- else if (id == Id.__c_complex_real)
+ if (id == Id.__c_complex_real)
return Type.tcomplex80.accept(this);
doSymbol(t);
@@ -2362,8 +2362,7 @@ private bool isNamespaceEqual (CPPNamespaceDeclaration a, Nspace b, size_t idx =
// We need to see if there's more ident enclosing
if (auto pb = b.toParent().isNspace())
return isNamespaceEqual(a.cppnamespace, pb);
- else
- return a.cppnamespace is null;
+ return a.cppnamespace is null;
}
/// Returns:
diff --git a/gcc/d/dmd/mtype.d b/gcc/d/dmd/mtype.d
index f91687b..b270943 100644
--- a/gcc/d/dmd/mtype.d
+++ b/gcc/d/dmd/mtype.d
@@ -1295,17 +1295,15 @@ extern (C++) abstract class Type : ASTNode
{
if (t.isWildConst())
return MODFlags.wild;
- else
- return MODFlags.wildconst;
+ return MODFlags.wildconst;
}
- else if (isWild())
+ if (isWild())
return MODFlags.wild;
- else if (isConst())
+ if (isConst())
return MODFlags.const_;
- else if (isMutable())
+ if (isMutable())
return MODFlags.mutable;
- else
- assert(0);
+ assert(0);
}
return 0;
}
diff --git a/gcc/d/dmd/mustuse.d b/gcc/d/dmd/mustuse.d
index fc7618b..4fc117e 100644
--- a/gcc/d/dmd/mustuse.d
+++ b/gcc/d/dmd/mustuse.d
@@ -111,26 +111,13 @@ private bool isAssignmentOpId(Identifier id)
{
import dmd.id : Id;
- return id == Id.assign
- || id == Id.addass
- || id == Id.subass
- || id == Id.mulass
- || id == Id.divass
- || id == Id.modass
- || id == Id.andass
- || id == Id.orass
- || id == Id.xorass
- || id == Id.shlass
- || id == Id.shrass
- || id == Id.ushrass
- || id == Id.catass
- || id == Id.indexass
- || id == Id.slice
- || id == Id.sliceass
+ return id == Id.opAssign
+ || id == Id.opIndexAssign
+ || id == Id.opSlice
+ || id == Id.opSliceAssign
|| id == Id.opOpAssign
|| id == Id.opIndexOpAssign
- || id == Id.opSliceOpAssign
- || id == Id.powass;
+ || id == Id.opSliceOpAssign;
}
/**
diff --git a/gcc/d/dmd/objc.d b/gcc/d/dmd/objc.d
index c5ee77a..b671986 100644
--- a/gcc/d/dmd/objc.d
+++ b/gcc/d/dmd/objc.d
@@ -714,8 +714,8 @@ extern(C++) private final class Supported : Objc
{
if (cd.classKind == ClassKind.objc && fd.isStatic && !cd.objc.isMeta)
return cd.objc.metaclass;
- else
- return cd;
+
+ return cd;
}
override void addToClassMethodList(FuncDeclaration fd, ClassDeclaration cd) const
@@ -805,11 +805,10 @@ extern(C++) private final class Supported : Objc
{
if (classDeclaration.baseClass)
return getRuntimeMetaclass(classDeclaration.baseClass);
- else
- return classDeclaration;
+
+ return classDeclaration;
}
- else
- return classDeclaration.objc.metaclass;
+ return classDeclaration.objc.metaclass;
}
override void addSymbols(AttribDeclaration attribDeclaration,
diff --git a/gcc/d/dmd/opover.d b/gcc/d/dmd/opover.d
index 56b3601..92f3bb2 100644
--- a/gcc/d/dmd/opover.d
+++ b/gcc/d/dmd/opover.d
@@ -71,84 +71,6 @@ bool isCommutative(EXP op) @safe
return false;
}
-/***********************************
- * Get Identifier for operator overload.
- */
-private Identifier opId(Expression e)
-{
- switch (e.op)
- {
- case EXP.uadd: return Id.uadd;
- case EXP.negate: return Id.neg;
- case EXP.tilde: return Id.com;
- case EXP.cast_: return Id._cast;
- case EXP.in_: return Id.opIn;
- case EXP.plusPlus: return Id.postinc;
- case EXP.minusMinus: return Id.postdec;
- case EXP.add: return Id.add;
- case EXP.min: return Id.sub;
- case EXP.mul: return Id.mul;
- case EXP.div: return Id.div;
- case EXP.mod: return Id.mod;
- case EXP.pow: return Id.pow;
- case EXP.leftShift: return Id.shl;
- case EXP.rightShift: return Id.shr;
- case EXP.unsignedRightShift: return Id.ushr;
- case EXP.and: return Id.iand;
- case EXP.or: return Id.ior;
- case EXP.xor: return Id.ixor;
- case EXP.concatenate: return Id.cat;
- case EXP.assign: return Id.assign;
- case EXP.addAssign: return Id.addass;
- case EXP.minAssign: return Id.subass;
- case EXP.mulAssign: return Id.mulass;
- case EXP.divAssign: return Id.divass;
- case EXP.modAssign: return Id.modass;
- case EXP.powAssign: return Id.powass;
- case EXP.leftShiftAssign: return Id.shlass;
- case EXP.rightShiftAssign: return Id.shrass;
- case EXP.unsignedRightShiftAssign: return Id.ushrass;
- case EXP.andAssign: return Id.andass;
- case EXP.orAssign: return Id.orass;
- case EXP.xorAssign: return Id.xorass;
- case EXP.concatenateAssign: return Id.catass;
- case EXP.equal: return Id.eq;
- case EXP.lessThan:
- case EXP.lessOrEqual:
- case EXP.greaterThan:
- case EXP.greaterOrEqual: return Id.cmp;
- case EXP.array: return Id.index;
- case EXP.star: return Id.opStar;
- default: assert(0);
- }
-}
-
-/***********************************
- * Get Identifier for reverse operator overload,
- * `null` if not supported for this operator.
- */
-private Identifier opId_r(Expression e)
-{
- switch (e.op)
- {
- case EXP.in_: return Id.opIn_r;
- case EXP.add: return Id.add_r;
- case EXP.min: return Id.sub_r;
- case EXP.mul: return Id.mul_r;
- case EXP.div: return Id.div_r;
- case EXP.mod: return Id.mod_r;
- case EXP.pow: return Id.pow_r;
- case EXP.leftShift: return Id.shl_r;
- case EXP.rightShift: return Id.shr_r;
- case EXP.unsignedRightShift:return Id.ushr_r;
- case EXP.and: return Id.iand_r;
- case EXP.or: return Id.ior_r;
- case EXP.xor: return Id.ixor_r;
- case EXP.concatenate: return Id.cat_r;
- default: return null;
- }
-}
-
/*******************************************
* Helper function to turn operator into template argument list
*/
@@ -208,7 +130,7 @@ Objects* opToArg(Scope* sc, EXP op)
}
// Try alias this on first operand
-private Expression checkAliasThisForLhs(AggregateDeclaration ad, Scope* sc, BinExp e)
+Expression checkAliasThisForLhs(AggregateDeclaration ad, Scope* sc, BinExp e, Type[2] aliasThisStop)
{
if (!ad || !ad.aliasthis)
return null;
@@ -216,7 +138,7 @@ private Expression checkAliasThisForLhs(AggregateDeclaration ad, Scope* sc, BinE
/* Rewrite (e1 op e2) as:
* (e1.aliasthis op e2)
*/
- if (isRecursiveAliasThis(e.att1, e.e1.type))
+ if (isRecursiveAliasThis(aliasThisStop[0], e.e1.type))
return null;
//printf("att %s e1 = %s\n", Token.toChars(e.op), e.e1.type.toChars());
BinExp be = cast(BinExp)e.copy();
@@ -227,24 +149,18 @@ private Expression checkAliasThisForLhs(AggregateDeclaration ad, Scope* sc, BinE
if (!be.e1)
return null;
- Expression result;
- if (be.op == EXP.concatenateAssign)
- result = be.op_overload(sc);
- else
- result = be.trySemantic(sc);
-
- return result;
+ return be.trySemanticAliasThis(sc, aliasThisStop);
}
// Try alias this on second operand
-private Expression checkAliasThisForRhs(AggregateDeclaration ad, Scope* sc, BinExp e)
+Expression checkAliasThisForRhs(AggregateDeclaration ad, Scope* sc, BinExp e, Type[2] aliasThisStop)
{
if (!ad || !ad.aliasthis)
return null;
/* Rewrite (e1 op e2) as:
* (e1 op e2.aliasthis)
*/
- if (isRecursiveAliasThis(e.att2, e.e2.type))
+ if (isRecursiveAliasThis(aliasThisStop[1], e.e2.type))
return null;
//printf("att %s e2 = %s\n", Token.toChars(e.op), e.e2.type.toChars());
BinExp be = cast(BinExp)e.copy();
@@ -252,189 +168,14 @@ private Expression checkAliasThisForRhs(AggregateDeclaration ad, Scope* sc, BinE
if (!be.e2)
return null;
- Expression result;
- if (be.op == EXP.concatenateAssign)
- result = be.op_overload(sc);
- else
- result = be.trySemantic(sc);
-
- return result;
+ return be.trySemanticAliasThis(sc, aliasThisStop);
}
-/************************************
- * Operator overload.
- * Check for operator overload, if so, replace
- * with function call.
- * Params:
- * e = expression with operator
- * sc = context
- * pop = if not null, is set to the operator that was actually overloaded,
- * which may not be `e.op`. Happens when operands are reversed to
- * match an overload
- * Returns:
- * `null` if not an operator overload,
- * otherwise the lowered expression
- */
-Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
+Expression opOverloadUnary(UnaExp e, Scope* sc)
{
- Expression visit(Expression e)
- {
- assert(0);
- }
-
- Expression visitUna(UnaExp e)
- {
- //printf("UnaExp::op_overload() (%s)\n", e.toChars());
- Expression result;
- if (auto ae = e.e1.isArrayExp())
- {
- ae.e1 = ae.e1.expressionSemantic(sc);
- ae.e1 = resolveProperties(sc, ae.e1);
- Expression ae1old = ae.e1;
- const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
- IntervalExp ie = null;
- if (maybeSlice && ae.arguments.length)
- {
- ie = (*ae.arguments)[0].isIntervalExp();
- }
- Type att = null; // first cyclic `alias this` type
- while (true)
- {
- if (ae.e1.op == EXP.error)
- {
- return ae.e1;
- }
- Expression e0 = null;
- Expression ae1save = ae.e1;
- ae.lengthVar = null;
- Type t1b = ae.e1.type.toBasetype();
- AggregateDeclaration ad = isAggregate(t1b);
- if (!ad)
- break;
- if (search_function(ad, Id.opIndexUnary))
- {
- // Deal with $
- result = resolveOpDollar(sc, ae, &e0);
- if (!result) // op(a[i..j]) might be: a.opSliceUnary!(op)(i, j)
- goto Lfallback;
- if (result.op == EXP.error)
- return result;
- /* Rewrite op(a[arguments]) as:
- * a.opIndexUnary!(op)(arguments)
- */
- Expressions* a = ae.arguments.copy();
- Objects* tiargs = opToArg(sc, e.op);
- result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opIndexUnary, tiargs);
- result = new CallExp(e.loc, result, a);
- if (maybeSlice) // op(a[]) might be: a.opSliceUnary!(op)()
- result = result.trySemantic(sc);
- else
- result = result.expressionSemantic(sc);
- if (result)
- {
- return Expression.combine(e0, result);
- }
- }
- Lfallback:
- if (maybeSlice && search_function(ad, Id.opSliceUnary))
- {
- // Deal with $
- result = resolveOpDollar(sc, ae, ie, &e0);
- if (result.op == EXP.error)
- return result;
- /* Rewrite op(a[i..j]) as:
- * a.opSliceUnary!(op)(i, j)
- */
- auto a = new Expressions();
- if (ie)
- {
- a.push(ie.lwr);
- a.push(ie.upr);
- }
- Objects* tiargs = opToArg(sc, e.op);
- result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opSliceUnary, tiargs);
- result = new CallExp(e.loc, result, a);
- result = result.expressionSemantic(sc);
- result = Expression.combine(e0, result);
- return result;
- }
- // Didn't find it. Forward to aliasthis
- if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type))
- {
- /* Rewrite op(a[arguments]) as:
- * op(a.aliasthis[arguments])
- */
- ae.e1 = resolveAliasThis(sc, ae1save, true);
- if (ae.e1)
- continue;
- }
- break;
- }
- ae.e1 = ae1old; // recovery
- ae.lengthVar = null;
- }
- e.e1 = e.e1.expressionSemantic(sc);
- e.e1 = resolveProperties(sc, e.e1);
- Type att = null; // first cyclic `alias this` type
- while (1)
- {
- if (e.e1.op == EXP.error)
- {
- return e.e1;
- }
-
- AggregateDeclaration ad = isAggregate(e.e1.type);
- if (!ad)
- break;
-
- Dsymbol fd = null;
- /* Rewrite as:
- * e1.opUnary!(op)()
- */
- fd = search_function(ad, Id.opUnary);
- if (fd)
- {
- Objects* tiargs = opToArg(sc, e.op);
- result = new DotTemplateInstanceExp(e.loc, e.e1, fd.ident, tiargs);
- result = new CallExp(e.loc, result);
- result = result.expressionSemantic(sc);
- return result;
- }
- // D1-style operator overloads, deprecated
- if (e.op != EXP.prePlusPlus && e.op != EXP.preMinusMinus)
- {
- auto id = opId(e);
- fd = search_function(ad, id);
- if (fd)
- {
- // @@@DEPRECATED_2.110@@@.
- // Deprecated in 2.088, made an error in 2.100
- error(e.loc, "`%s` is obsolete. Use `opUnary(string op)() if (op == \"%s\")` instead.", id.toChars(), EXPtoString(e.op).ptr);
- return ErrorExp.get();
- }
- }
- // Didn't find it. Forward to aliasthis
- if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type))
- {
- /* Rewrite op(e1) as:
- * op(e1.aliasthis)
- */
- //printf("att una %s e1 = %s\n", EXPtoString(op).ptr, this.e1.type.toChars());
- if (auto e1 = resolveAliasThis(sc, e.e1, true))
- {
- e.e1 = e1;
- continue;
- }
- break;
- }
- break;
- }
- return result;
- }
-
- Expression visitArray(ArrayExp ae)
+ Expression result;
+ if (auto ae = e.e1.isArrayExp())
{
- //printf("ArrayExp::op_overload() (%s)\n", ae.toChars());
ae.e1 = ae.e1.expressionSemantic(sc);
ae.e1 = resolveProperties(sc, ae.e1);
Expression ae1old = ae.e1;
@@ -444,7 +185,6 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
{
ie = (*ae.arguments)[0].isIntervalExp();
}
- Expression result;
Type att = null; // first cyclic `alias this` type
while (true)
{
@@ -458,43 +198,23 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
Type t1b = ae.e1.type.toBasetype();
AggregateDeclaration ad = isAggregate(t1b);
if (!ad)
- {
- // If the non-aggregate expression ae.e1 is indexable or sliceable,
- // convert it to the corresponding concrete expression.
- if (isIndexableNonAggregate(t1b) || ae.e1.op == EXP.type)
- {
- // Convert to SliceExp
- if (maybeSlice)
- {
- result = new SliceExp(ae.loc, ae.e1, ie);
- result = result.expressionSemantic(sc);
- return result;
- }
- // Convert to IndexExp
- if (ae.arguments.length == 1)
- {
- result = new IndexExp(ae.loc, ae.e1, (*ae.arguments)[0]);
- result = result.expressionSemantic(sc);
- return result;
- }
- }
break;
- }
- if (search_function(ad, Id.index))
+ if (search_function(ad, Id.opIndexUnary))
{
// Deal with $
result = resolveOpDollar(sc, ae, &e0);
- if (!result) // a[i..j] might be: a.opSlice(i, j)
+ if (!result) // op(a[i..j]) might be: a.opSliceUnary!(op)(i, j)
goto Lfallback;
if (result.op == EXP.error)
return result;
- /* Rewrite e1[arguments] as:
- * e1.opIndex(arguments)
- */
+ /* Rewrite op(a[arguments]) as:
+ * a.opIndexUnary!(op)(arguments)
+ */
Expressions* a = ae.arguments.copy();
- result = new DotIdExp(ae.loc, ae.e1, Id.index);
- result = new CallExp(ae.loc, result, a);
- if (maybeSlice) // a[] might be: a.opSlice()
+ Objects* tiargs = opToArg(sc, e.op);
+ result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opIndexUnary, tiargs);
+ result = new CallExp(e.loc, result, a);
+ if (maybeSlice) // op(a[]) might be: a.opSliceUnary!(op)()
result = result.trySemantic(sc);
else
result = result.expressionSemantic(sc);
@@ -504,36 +224,24 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
}
}
Lfallback:
- if (maybeSlice && ae.e1.op == EXP.type)
- {
- result = new SliceExp(ae.loc, ae.e1, ie);
- result = result.expressionSemantic(sc);
- result = Expression.combine(e0, result);
- return result;
- }
- if (maybeSlice && search_function(ad, Id.slice))
+ if (maybeSlice && search_function(ad, Id.opSliceUnary))
{
// Deal with $
result = resolveOpDollar(sc, ae, ie, &e0);
-
if (result.op == EXP.error)
- {
- if (!e0 && !search_function(ad, Id.dollar)) {
- ae.loc.errorSupplemental("Aggregate declaration '%s' does not define 'opDollar'", ae.e1.toChars());
- }
return result;
- }
- /* Rewrite a[i..j] as:
- * a.opSlice(i, j)
- */
+ /* Rewrite op(a[i..j]) as:
+ * a.opSliceUnary!(op)(i, j)
+ */
auto a = new Expressions();
if (ie)
{
a.push(ie.lwr);
a.push(ie.upr);
}
- result = new DotIdExp(ae.loc, ae.e1, Id.slice);
- result = new CallExp(ae.loc, result, a);
+ Objects* tiargs = opToArg(sc, e.op);
+ result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opSliceUnary, tiargs);
+ result = new CallExp(e.loc, result, a);
result = result.expressionSemantic(sc);
result = Expression.combine(e0, result);
return result;
@@ -541,10 +249,9 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
// Didn't find it. Forward to aliasthis
if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type))
{
- //printf("att arr e1 = %s\n", this.e1.type.toChars());
/* Rewrite op(a[arguments]) as:
- * op(a.aliasthis[arguments])
- */
+ * op(a.aliasthis[arguments])
+ */
ae.e1 = resolveAliasThis(sc, ae1save, true);
if (ae.e1)
continue;
@@ -553,846 +260,810 @@ Expression op_overload(Expression e, Scope* sc, EXP* pop = null)
}
ae.e1 = ae1old; // recovery
ae.lengthVar = null;
- return result;
}
-
- /***********************************************
- * This is mostly the same as UnaryExp::op_overload(), but has
- * a different rewrite.
- */
- Expression visitCast(CastExp e, Type att = null)
+ e.e1 = e.e1.expressionSemantic(sc);
+ e.e1 = resolveProperties(sc, e.e1);
+ Type att = null; // first cyclic `alias this` type
+ while (1)
{
- //printf("CastExp::op_overload() (%s)\n", e.toChars());
- Expression result;
- if (AggregateDeclaration ad = isAggregate(e.e1.type))
+ if (e.e1.op == EXP.error)
{
- Dsymbol fd = null;
- /* Rewrite as:
- * e1.opCast!(T)()
+ return e.e1;
+ }
+
+ AggregateDeclaration ad = isAggregate(e.e1.type);
+ if (!ad)
+ break;
+
+ Dsymbol fd = null;
+ /* Rewrite as:
+ * e1.opUnary!(op)()
+ */
+ fd = search_function(ad, Id.opUnary);
+ if (fd)
+ {
+ Objects* tiargs = opToArg(sc, e.op);
+ result = new DotTemplateInstanceExp(e.loc, e.e1, fd.ident, tiargs);
+ result = new CallExp(e.loc, result);
+ result = result.expressionSemantic(sc);
+ return result;
+ }
+
+ // Didn't find it. Forward to aliasthis
+ if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type))
+ {
+ /* Rewrite op(e1) as:
+ * op(e1.aliasthis)
*/
- fd = search_function(ad, Id._cast);
- if (fd)
- {
- version (all)
- {
- // Backwards compatibility with D1 if opCast is a function, not a template
- if (fd.isFuncDeclaration())
- {
- // Rewrite as: e1.opCast()
- return build_overload(e.loc, sc, e.e1, null, fd);
- }
- }
- auto tiargs = new Objects();
- tiargs.push(e.to);
- result = new DotTemplateInstanceExp(e.loc, e.e1, fd.ident, tiargs);
- result = new CallExp(e.loc, result);
- result = result.expressionSemantic(sc);
- return result;
- }
- // Didn't find it. Forward to aliasthis
- if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type))
+ //printf("att una %s e1 = %s\n", EXPtoString(op).ptr, this.e1.type.toChars());
+ if (auto e1 = resolveAliasThis(sc, e.e1, true))
{
- /* Rewrite op(e1) as:
- * op(e1.aliasthis)
- */
- if (auto e1 = resolveAliasThis(sc, e.e1, true))
- {
- result = e.copy();
- (cast(UnaExp)result).e1 = e1;
- result = visitCast(result.isCastExp(), att);
- return result;
- }
+ e.e1 = e1;
+ continue;
}
+ break;
}
- return result;
+ break;
}
+ return result;
+}
- Expression visitBin(BinExp e)
+Expression opOverloadArray(ArrayExp ae, Scope* sc)
+{
+ ae.e1 = ae.e1.expressionSemantic(sc);
+ ae.e1 = resolveProperties(sc, ae.e1);
+ Expression ae1old = ae.e1;
+ const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
+ IntervalExp ie = null;
+ if (maybeSlice && ae.arguments.length)
{
- //printf("BinExp::op_overload() (%s)\n", e.toChars());
- Identifier id = opId(e);
- Identifier id_r = opId_r(e);
- int argsset = 0;
- AggregateDeclaration ad1 = isAggregate(e.e1.type);
- AggregateDeclaration ad2 = isAggregate(e.e2.type);
- if (e.op == EXP.assign && ad1 == ad2)
- {
- StructDeclaration sd = ad1.isStructDeclaration();
- if (sd &&
- (!sd.hasIdentityAssign ||
- /* Do a blit if we can and the rvalue is something like .init,
- * where a postblit is not necessary.
- */
- (sd.hasBlitAssign && !e.e2.isLvalue())))
- {
- /* This is bitwise struct assignment. */
- return null;
- }
- }
- Dsymbol s = null;
- Dsymbol s_r = null;
- Objects* tiargs = null;
- if (e.op == EXP.plusPlus || e.op == EXP.minusMinus)
+ ie = (*ae.arguments)[0].isIntervalExp();
+ }
+ Expression result;
+ Type att = null; // first cyclic `alias this` type
+ while (true)
+ {
+ if (ae.e1.op == EXP.error)
{
- // Bug4099 fix
- if (ad1 && search_function(ad1, Id.opUnary))
- return null;
+ return ae.e1;
}
- if (e.op != EXP.equal && e.op != EXP.notEqual && e.op != EXP.assign && e.op != EXP.plusPlus && e.op != EXP.minusMinus)
+ Expression e0 = null;
+ Expression ae1save = ae.e1;
+ ae.lengthVar = null;
+ Type t1b = ae.e1.type.toBasetype();
+ AggregateDeclaration ad = isAggregate(t1b);
+ if (!ad)
{
- /* Try opBinary and opBinaryRight
- */
- if (ad1)
+ // If the non-aggregate expression ae.e1 is indexable or sliceable,
+ // convert it to the corresponding concrete expression.
+ if (isIndexableNonAggregate(t1b) || ae.e1.op == EXP.type)
{
- s = search_function(ad1, Id.opBinary);
- if (s && !s.isTemplateDeclaration())
+ // Convert to SliceExp
+ if (maybeSlice)
{
- error(e.e1.loc, "`%s.opBinary` isn't a template", e.e1.toChars());
- return ErrorExp.get();
+ result = new SliceExp(ae.loc, ae.e1, ie);
+ result = result.expressionSemantic(sc);
+ return result;
}
- }
- if (ad2)
- {
- s_r = search_function(ad2, Id.opBinaryRight);
- if (s_r && !s_r.isTemplateDeclaration())
+ // Convert to IndexExp
+ if (ae.arguments.length == 1)
{
- error(e.e2.loc, "`%s.opBinaryRight` isn't a template", e.e2.toChars());
- return ErrorExp.get();
+ result = new IndexExp(ae.loc, ae.e1, (*ae.arguments)[0]);
+ result = result.expressionSemantic(sc);
+ return result;
}
- if (s_r && s_r == s) // https://issues.dlang.org/show_bug.cgi?id=12778
- s_r = null;
}
- // Set tiargs, the template argument list, which will be the operator string
- if (s || s_r)
+ break;
+ }
+ if (search_function(ad, Id.opIndex))
+ {
+ // Deal with $
+ result = resolveOpDollar(sc, ae, &e0);
+ if (!result) // a[i..j] might be: a.opSlice(i, j)
+ goto Lfallback;
+ if (result.op == EXP.error)
+ return result;
+ /* Rewrite e1[arguments] as:
+ * e1.opIndex(arguments)
+ */
+ Expressions* a = ae.arguments.copy();
+ result = new DotIdExp(ae.loc, ae.e1, Id.opIndex);
+ result = new CallExp(ae.loc, result, a);
+ if (maybeSlice) // a[] might be: a.opSlice()
+ result = result.trySemantic(sc);
+ else
+ result = result.expressionSemantic(sc);
+ if (result)
{
- id = Id.opBinary;
- id_r = Id.opBinaryRight;
- tiargs = opToArg(sc, e.op);
+ return Expression.combine(e0, result);
}
}
- if (!s && !s_r)
+ Lfallback:
+ if (maybeSlice && ae.e1.op == EXP.type)
+ {
+ result = new SliceExp(ae.loc, ae.e1, ie);
+ result = result.expressionSemantic(sc);
+ result = Expression.combine(e0, result);
+ return result;
+ }
+ if (maybeSlice && search_function(ad, Id.opSlice))
{
- // Try the D1-style operators, deprecated
- if (ad1 && id)
+ // Deal with $
+ result = resolveOpDollar(sc, ae, ie, &e0);
+
+ if (result.op == EXP.error)
{
- s = search_function(ad1, id);
- if (s && id != Id.assign)
- {
- // @@@DEPRECATED_2.110@@@.
- // Deprecated in 2.088, made an error in 2.100
- if (id == Id.postinc || id == Id.postdec)
- error(e.loc, "`%s` is obsolete. Use `opUnary(string op)() if (op == \"%s\")` instead.", id.toChars(), EXPtoString(e.op).ptr);
- else
- error(e.loc, "`%s` is obsolete. Use `opBinary(string op)(...) if (op == \"%s\")` instead.", id.toChars(), EXPtoString(e.op).ptr);
- return ErrorExp.get();
+ if (!e0 && !search_function(ad, Id.dollar)) {
+ ae.loc.errorSupplemental("Aggregate declaration '%s' does not define 'opDollar'", ae.e1.toChars());
}
+ return result;
}
- if (ad2 && id_r)
+ /* Rewrite a[i..j] as:
+ * a.opSlice(i, j)
+ */
+ auto a = new Expressions();
+ if (ie)
{
- s_r = search_function(ad2, id_r);
- // https://issues.dlang.org/show_bug.cgi?id=12778
- // If both x.opBinary(y) and y.opBinaryRight(x) found,
- // and they are exactly same symbol, x.opBinary(y) should be preferred.
- if (s_r && s_r == s)
- s_r = null;
- if (s_r)
- {
- // @@@DEPRECATED_2.110@@@.
- // Deprecated in 2.088, made an error in 2.100
- error(e.loc, "`%s` is obsolete. Use `opBinaryRight(string op)(...) if (op == \"%s\")` instead.", id_r.toChars(), EXPtoString(e.op).ptr);
- return ErrorExp.get();
- }
+ a.push(ie.lwr);
+ a.push(ie.upr);
}
+ result = new DotIdExp(ae.loc, ae.e1, Id.opSlice);
+ result = new CallExp(ae.loc, result, a);
+ result = result.expressionSemantic(sc);
+ result = Expression.combine(e0, result);
+ return result;
}
- Expressions* args1 = new Expressions();
- Expressions* args2 = new Expressions();
- if (s || s_r)
+ // Didn't find it. Forward to aliasthis
+ if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type))
{
- /* Try:
- * a.opfunc(b)
- * b.opfunc_r(a)
- * and see which is better.
+ //printf("att arr e1 = %s\n", this.e1.type.toChars());
+ /* Rewrite op(a[arguments]) as:
+ * op(a.aliasthis[arguments])
*/
- args1.setDim(1);
- (*args1)[0] = e.e1;
- expandTuples(args1);
- args2.setDim(1);
- (*args2)[0] = e.e2;
- expandTuples(args2);
- argsset = 1;
- MatchAccumulator m;
- if (s)
- {
- functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
- if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
- {
- return ErrorExp.get();
- }
- }
- FuncDeclaration lastf = m.lastf;
- if (s_r)
+ ae.e1 = resolveAliasThis(sc, ae1save, true);
+ if (ae.e1)
+ continue;
+ }
+ break;
+ }
+ ae.e1 = ae1old; // recovery
+ ae.lengthVar = null;
+ return result;
+}
+
+/***********************************************
+ * This is mostly the same as opOverloadUnary but has
+ * a different rewrite.
+ */
+Expression opOverloadCast(CastExp e, Scope* sc, Type att = null)
+{
+ Expression result;
+ if (AggregateDeclaration ad = isAggregate(e.e1.type))
+ {
+ Dsymbol fd = null;
+ /* Rewrite as:
+ * e1.opCast!(T)()
+ */
+ fd = search_function(ad, Id.opCast);
+ if (fd)
+ {
+ version (all)
{
- functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
- if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
+ // Backwards compatibility with D1 if opCast is a function, not a template
+ if (fd.isFuncDeclaration())
{
- return ErrorExp.get();
+ // Rewrite as: e1.opCast()
+ return build_overload(e.loc, sc, e.e1, null, fd);
}
}
- if (m.count > 1)
- {
- // Error, ambiguous
- error(e.loc, "overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars());
- }
- else if (m.last == MATCH.nomatch)
- {
- if (tiargs)
- goto L1;
- m.lastf = null;
- }
- if (e.op == EXP.plusPlus || e.op == EXP.minusMinus)
- {
- // Kludge because operator overloading regards e++ and e--
- // as unary, but it's implemented as a binary.
- // Rewrite (e1 ++ e2) as e1.postinc()
- // Rewrite (e1 -- e2) as e1.postdec()
- return build_overload(e.loc, sc, e.e1, null, m.lastf ? m.lastf : s);
- }
- else if (lastf && m.lastf == lastf || !s_r && m.last == MATCH.nomatch)
- {
- // Rewrite (e1 op e2) as e1.opfunc(e2)
- return build_overload(e.loc, sc, e.e1, e.e2, m.lastf ? m.lastf : s);
- }
- else
- {
- // Rewrite (e1 op e2) as e2.opfunc_r(e1)
- return build_overload(e.loc, sc, e.e2, e.e1, m.lastf ? m.lastf : s_r);
- }
+ auto tiargs = new Objects();
+ tiargs.push(e.to);
+ result = new DotTemplateInstanceExp(e.loc, e.e1, fd.ident, tiargs);
+ result = new CallExp(e.loc, result);
+ result = result.expressionSemantic(sc);
+ return result;
}
- L1:
- version (all)
+ // Didn't find it. Forward to aliasthis
+ if (ad.aliasthis && !isRecursiveAliasThis(att, e.e1.type))
{
- // Retained for D1 compatibility
- if (isCommutative(e.op) && !tiargs)
+ /* Rewrite op(e1) as:
+ * op(e1.aliasthis)
+ */
+ if (auto e1 = resolveAliasThis(sc, e.e1, true))
{
- s = null;
- s_r = null;
- if (ad1 && id_r)
- {
- s_r = search_function(ad1, id_r);
- }
- if (ad2 && id)
- {
- s = search_function(ad2, id);
- if (s && s == s_r) // https://issues.dlang.org/show_bug.cgi?id=12778
- s = null;
- }
- if (s || s_r)
- {
- /* Try:
- * a.opfunc_r(b)
- * b.opfunc(a)
- * and see which is better.
- */
- if (!argsset)
- {
- args1.setDim(1);
- (*args1)[0] = e.e1;
- expandTuples(args1);
- args2.setDim(1);
- (*args2)[0] = e.e2;
- expandTuples(args2);
- }
- MatchAccumulator m;
- if (s_r)
- {
- functionResolve(m, s_r, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
- if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
- {
- return ErrorExp.get();
- }
- }
- FuncDeclaration lastf = m.lastf;
- if (s)
- {
- functionResolve(m, s, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
- if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
- {
- return ErrorExp.get();
- }
- }
- if (m.count > 1)
- {
- // Error, ambiguous
- error(e.loc, "overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars());
- }
- else if (m.last == MATCH.nomatch)
- {
- m.lastf = null;
- }
-
- if (lastf && m.lastf == lastf || !s && m.last == MATCH.nomatch)
- {
- // Rewrite (e1 op e2) as e1.opfunc_r(e2)
- return build_overload(e.loc, sc, e.e1, e.e2, m.lastf ? m.lastf : s_r);
- }
- else
- {
- // Rewrite (e1 op e2) as e2.opfunc(e1)
- Expression result = build_overload(e.loc, sc, e.e2, e.e1, m.lastf ? m.lastf : s);
- // When reversing operands of comparison operators,
- // need to reverse the sense of the op
- if (pop)
- *pop = reverseRelation(e.op);
- return result;
- }
- }
+ result = e.copy();
+ (cast(UnaExp)result).e1 = e1;
+ result = opOverloadCast(result.isCastExp(), sc, att);
+ return result;
}
}
+ }
+ return result;
+}
- Expression rewrittenLhs;
- if (!(e.op == EXP.assign && ad2 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
+// When no operator overload functions are found for `e`, recursively try with `alias this`
+// Returns: `null` when still no overload found, otherwise resolved lowering
+Expression binAliasThis(BinExp e, Scope* sc, Type[2] aliasThisStop)
+{
+ AggregateDeclaration ad1 = isAggregate(e.e1.type);
+ AggregateDeclaration ad2 = isAggregate(e.e2.type);
+ Expression rewrittenLhs;
+ if (!(e.op == EXP.assign && ad2 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
+ {
+ if (Expression result = checkAliasThisForLhs(ad1, sc, e, aliasThisStop))
{
- if (Expression result = checkAliasThisForLhs(ad1, sc, e))
- {
- /* https://issues.dlang.org/show_bug.cgi?id=19441
- *
- * alias this may not be used for partial assignment.
- * If a struct has a single member which is aliased this
- * directly or aliased to a ref getter function that returns
- * the mentioned member, then alias this may be
- * used since the object will be fully initialised.
- * If the struct is nested, the context pointer is considered
- * one of the members, hence the `ad1.fields.length == 2 && ad1.vthis`
- * condition.
- */
- if (result.op != EXP.assign)
- return result; // i.e: Rewrote `e1 = e2` -> `e1(e2)`
+ /* https://issues.dlang.org/show_bug.cgi?id=19441
+ *
+ * alias this may not be used for partial assignment.
+ * If a struct has a single member which is aliased this
+ * directly or aliased to a ref getter function that returns
+ * the mentioned member, then alias this may be
+ * used since the object will be fully initialised.
+ * If the struct is nested, the context pointer is considered
+ * one of the members, hence the `ad1.fields.length == 2 && ad1.vthis`
+ * condition.
+ */
+ if (result.op != EXP.assign)
+ return result; // i.e: Rewrote `e1 = e2` -> `e1(e2)`
- auto ae = result.isAssignExp();
- if (ae.e1.op != EXP.dotVariable)
- return result; // i.e: Rewrote `e1 = e2` -> `e1() = e2`
+ auto ae = result.isAssignExp();
+ if (ae.e1.op != EXP.dotVariable)
+ return result; // i.e: Rewrote `e1 = e2` -> `e1() = e2`
- auto dve = ae.e1.isDotVarExp();
- if (auto ad = dve.var.isMember2())
+ auto dve = ae.e1.isDotVarExp();
+ if (auto ad = dve.var.isMember2())
+ {
+ // i.e: Rewrote `e1 = e2` -> `e1.some.var = e2`
+ // Ensure that `var` is the only field member in `ad`
+ if (ad.fields.length == 1 || (ad.fields.length == 2 && ad.vthis))
{
- // i.e: Rewrote `e1 = e2` -> `e1.some.var = e2`
- // Ensure that `var` is the only field member in `ad`
- if (ad.fields.length == 1 || (ad.fields.length == 2 && ad.vthis))
- {
- if (dve.var == ad.aliasthis.sym)
- return result;
- }
+ if (dve.var == ad.aliasthis.sym)
+ return result;
}
- rewrittenLhs = ae.e1;
}
+ rewrittenLhs = ae.e1;
}
- if (!(e.op == EXP.assign && ad1 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
- {
- if (Expression result = checkAliasThisForRhs(ad2, sc, e))
- return result;
- }
- if (rewrittenLhs)
- {
- error(e.loc, "cannot use `alias this` to partially initialize variable `%s` of type `%s`. Use `%s`",
- e.e1.toChars(), ad1.toChars(), rewrittenLhs.toChars());
- return ErrorExp.get();
- }
- return null;
}
-
- Expression visitEqual(EqualExp e)
+ if (!(e.op == EXP.assign && ad1 && ad1 == ad2)) // https://issues.dlang.org/show_bug.cgi?id=2943
{
- //printf("EqualExp::op_overload() (%s)\n", e.toChars());
- Type t1 = e.e1.type.toBasetype();
- Type t2 = e.e2.type.toBasetype();
+ if (Expression result = checkAliasThisForRhs(ad2, sc, e, aliasThisStop))
+ return result;
+ }
+ if (rewrittenLhs)
+ {
+ error(e.loc, "cannot use `alias this` to partially initialize variable `%s` of type `%s`. Use `%s`",
+ e.e1.toChars(), ad1.toChars(), rewrittenLhs.toChars());
+ return ErrorExp.get();
+ }
+ return null;
+}
- /* Array equality is handled by expressionSemantic() potentially
- * lowering to object.__equals(), which takes care of overloaded
- * operators for the element types.
- */
- if ((t1.ty == Tarray || t1.ty == Tsarray) &&
- (t2.ty == Tarray || t2.ty == Tsarray))
+Expression opOverloadAssign(AssignExp e, Scope* sc, Type[2] aliasThisStop)
+{
+ AggregateDeclaration ad1 = isAggregate(e.e1.type);
+ AggregateDeclaration ad2 = isAggregate(e.e2.type);
+ if (ad1 == ad2)
+ {
+ StructDeclaration sd = ad1.isStructDeclaration();
+ if (sd &&
+ (!sd.hasIdentityAssign ||
+ /* Do a blit if we can and the rvalue is something like .init,
+ * where a postblit is not necessary.
+ */
+ (sd.hasBlitAssign && !e.e2.isLvalue())))
{
+ /* This is bitwise struct assignment. */
return null;
}
+ }
+ Dsymbol s = search_function(ad1, Id.opAssign);
- /* Check for class equality with null literal or typeof(null).
- */
- if (t1.ty == Tclass && e.e2.op == EXP.null_ ||
- t2.ty == Tclass && e.e1.op == EXP.null_)
- {
- error(e.loc, "use `%s` instead of `%s` when comparing with `null`",
- EXPtoString(e.op == EXP.equal ? EXP.identity : EXP.notIdentity).ptr,
- EXPtoString(e.op).ptr);
- return ErrorExp.get();
- }
- if (t1.ty == Tclass && t2.ty == Tnull ||
- t1.ty == Tnull && t2.ty == Tclass)
- {
- // Comparing a class with typeof(null) should not call opEquals
- return null;
- }
+ bool choseReverse;
+ if (auto result = pickBestBinaryOverload(sc, null, s, null, e, choseReverse))
+ return result;
- /* Check for class equality.
- */
- if (t1.ty == Tclass && t2.ty == Tclass)
- {
- ClassDeclaration cd1 = t1.isClassHandle();
- ClassDeclaration cd2 = t2.isClassHandle();
- if (!(cd1.classKind == ClassKind.cpp || cd2.classKind == ClassKind.cpp))
- {
- /* Rewrite as:
- * .object.opEquals(e1, e2)
- */
- if (!ClassDeclaration.object)
- {
- error(e.loc, "cannot compare classes for equality because `object.Object` was not declared");
- return null;
- }
+ return binAliasThis(e, sc, aliasThisStop);
+}
- Expression e1x = e.e1;
- Expression e2x = e.e2;
+Expression opOverloadBinary(BinExp e, Scope* sc, Type[2] aliasThisStop)
+{
+ if (Expression err = binSemanticProp(e, sc))
+ return err;
- /* The explicit cast is necessary for interfaces
- * https://issues.dlang.org/show_bug.cgi?id=4088
- */
- Type to = ClassDeclaration.object.getType();
- if (cd1.isInterfaceDeclaration())
- e1x = new CastExp(e.loc, e.e1, t1.isMutable() ? to : to.constOf());
- if (cd2.isInterfaceDeclaration())
- e2x = new CastExp(e.loc, e.e2, t2.isMutable() ? to : to.constOf());
-
- Expression result = new IdentifierExp(e.loc, Id.empty);
- result = new DotIdExp(e.loc, result, Id.object);
- result = new DotIdExp(e.loc, result, Id.eq);
- result = new CallExp(e.loc, result, e1x, e2x);
- if (e.op == EXP.notEqual)
- result = new NotExp(e.loc, result);
- result = result.expressionSemantic(sc);
- return result;
- }
- }
+ AggregateDeclaration ad1 = isAggregate(e.e1.type);
+ AggregateDeclaration ad2 = isAggregate(e.e2.type);
+
+ // Try opBinary and opBinaryRight
+ Dsymbol s = search_function(ad1, Id.opBinary);
+ if (s && !s.isTemplateDeclaration())
+ {
+ error(e.e1.loc, "`%s.opBinary` isn't a template", e.e1.toChars());
+ return ErrorExp.get();
+ }
+
+ Dsymbol s_r = search_function(ad2, Id.opBinaryRight);
+ if (s_r && !s_r.isTemplateDeclaration())
+ {
+ error(e.e2.loc, "`%s.opBinaryRight` isn't a template", e.e2.toChars());
+ return ErrorExp.get();
+ }
+ if (s_r && s_r == s) // https://issues.dlang.org/show_bug.cgi?id=12778
+ s_r = null;
+
+ bool choseReverse;
+ if (auto res = pickBestBinaryOverload(sc, opToArg(sc, e.op), s, s_r, e, choseReverse))
+ return res;
+
+ return binAliasThis(e, sc, aliasThisStop);
+}
+
+Expression opOverloadEqual(EqualExp e, Scope* sc, Type[2] aliasThisStop)
+{
+ Type t1 = e.e1.type.toBasetype();
+ Type t2 = e.e2.type.toBasetype();
+
+ /* Array equality is handled by expressionSemantic() potentially
+ * lowering to object.__equals(), which takes care of overloaded
+ * operators for the element types.
+ */
+ if ((t1.ty == Tarray || t1.ty == Tsarray) &&
+ (t2.ty == Tarray || t2.ty == Tsarray))
+ {
+ return null;
+ }
+
+ /* Check for class equality with null literal or typeof(null).
+ */
+ if (t1.ty == Tclass && e.e2.op == EXP.null_ ||
+ t2.ty == Tclass && e.e1.op == EXP.null_)
+ {
+ error(e.loc, "use `%s` instead of `%s` when comparing with `null`",
+ EXPtoString(e.op == EXP.equal ? EXP.identity : EXP.notIdentity).ptr,
+ EXPtoString(e.op).ptr);
+ return ErrorExp.get();
+ }
+ if (t1.ty == Tclass && t2.ty == Tnull ||
+ t1.ty == Tnull && t2.ty == Tclass)
+ {
+ // Comparing a class with typeof(null) should not call opEquals
+ return null;
+ }
- if (Expression result = compare_overload(e, sc, Id.eq, null))
+ /* Check for class equality.
+ */
+ if (t1.ty == Tclass && t2.ty == Tclass)
+ {
+ ClassDeclaration cd1 = t1.isClassHandle();
+ ClassDeclaration cd2 = t2.isClassHandle();
+ if (!(cd1.classKind == ClassKind.cpp || cd2.classKind == ClassKind.cpp))
{
- if (lastComma(result).op == EXP.call && e.op == EXP.notEqual)
+ /* Rewrite as:
+ * .object.opEquals(e1, e2)
+ */
+ if (!ClassDeclaration.object)
{
- result = new NotExp(result.loc, result);
- result = result.expressionSemantic(sc);
+ error(e.loc, "cannot compare classes for equality because `object.Object` was not declared");
+ return null;
}
+
+ Expression e1x = e.e1;
+ Expression e2x = e.e2;
+
+ /* The explicit cast is necessary for interfaces
+ * https://issues.dlang.org/show_bug.cgi?id=4088
+ */
+ Type to = ClassDeclaration.object.getType();
+ if (cd1.isInterfaceDeclaration())
+ e1x = new CastExp(e.loc, e.e1, t1.isMutable() ? to : to.constOf());
+ if (cd2.isInterfaceDeclaration())
+ e2x = new CastExp(e.loc, e.e2, t2.isMutable() ? to : to.constOf());
+
+ Expression result = new IdentifierExp(e.loc, Id.empty);
+ result = new DotIdExp(e.loc, result, Id.object);
+ result = new DotIdExp(e.loc, result, Id.opEquals);
+ result = new CallExp(e.loc, result, e1x, e2x);
+ if (e.op == EXP.notEqual)
+ result = new NotExp(e.loc, result);
+ result = result.expressionSemantic(sc);
return result;
}
+ }
+
+ EXP cmpOp;
+ if (Expression result = compare_overload(e, sc, Id.opEquals, cmpOp, aliasThisStop))
+ {
+ if (lastComma(result).op == EXP.call && e.op == EXP.notEqual)
+ {
+ result = new NotExp(result.loc, result);
+ result = result.expressionSemantic(sc);
+ }
+ return result;
+ }
- /* Check for pointer equality.
+ /* Check for pointer equality.
+ */
+ if (t1.ty == Tpointer || t2.ty == Tpointer)
+ {
+ /* Rewrite:
+ * ptr1 == ptr2
+ * as:
+ * ptr1 is ptr2
+ *
+ * This is just a rewriting for deterministic AST representation
+ * as the backend input.
*/
- if (t1.ty == Tpointer || t2.ty == Tpointer)
+ auto op2 = e.op == EXP.equal ? EXP.identity : EXP.notIdentity;
+ Expression r = new IdentityExp(op2, e.loc, e.e1, e.e2);
+ return r.expressionSemantic(sc);
+ }
+
+ /* Check for struct equality without opEquals.
+ */
+ if (t1.ty == Tstruct && t2.ty == Tstruct)
+ {
+ auto sd = t1.isTypeStruct().sym;
+ if (sd != t2.isTypeStruct().sym)
+ return null;
+
+ import dmd.clone : needOpEquals;
+ if (!sc.previews.fieldwise && !needOpEquals(sd))
{
- /* Rewrite:
- * ptr1 == ptr2
- * as:
- * ptr1 is ptr2
- *
- * This is just a rewriting for deterministic AST representation
- * as the backend input.
- */
+ // Use bitwise equality.
auto op2 = e.op == EXP.equal ? EXP.identity : EXP.notIdentity;
Expression r = new IdentityExp(op2, e.loc, e.e1, e.e2);
return r.expressionSemantic(sc);
}
- /* Check for struct equality without opEquals.
+ /* Do memberwise equality.
+ * https://dlang.org/spec/expression.html#equality_expressions
+ * Rewrite:
+ * e1 == e2
+ * as:
+ * e1.tupleof == e2.tupleof
+ *
+ * If sd is a nested struct, and if it's nested in a class, it will
+ * also compare the parent class's equality. Otherwise, compares
+ * the identity of parent context through void*.
*/
- if (t1.ty == Tstruct && t2.ty == Tstruct)
- {
- auto sd = t1.isTypeStruct().sym;
- if (sd != t2.isTypeStruct().sym)
- return null;
-
- import dmd.clone : needOpEquals;
- if (!sc.previews.fieldwise && !needOpEquals(sd))
- {
- // Use bitwise equality.
- auto op2 = e.op == EXP.equal ? EXP.identity : EXP.notIdentity;
- Expression r = new IdentityExp(op2, e.loc, e.e1, e.e2);
- return r.expressionSemantic(sc);
- }
+ e = e.copy().isEqualExp();
+ e.e1 = new DotIdExp(e.loc, e.e1, Id._tupleof);
+ e.e2 = new DotIdExp(e.loc, e.e2, Id._tupleof);
+
+ auto sc2 = sc.push();
+ sc2.noAccessCheck = true;
+ Expression r = e.expressionSemantic(sc2);
+ sc2.pop();
+ return r;
+ }
- /* Do memberwise equality.
- * https://dlang.org/spec/expression.html#equality_expressions
- * Rewrite:
- * e1 == e2
- * as:
- * e1.tupleof == e2.tupleof
- *
- * If sd is a nested struct, and if it's nested in a class, it will
- * also compare the parent class's equality. Otherwise, compares
- * the identity of parent context through void*.
- */
- e = e.copy().isEqualExp();
- e.e1 = new DotIdExp(e.loc, e.e1, Id._tupleof);
- e.e2 = new DotIdExp(e.loc, e.e2, Id._tupleof);
-
- auto sc2 = sc.push();
- sc2.noAccessCheck = true;
- Expression r = e.expressionSemantic(sc2);
- sc2.pop();
- return r;
+ /* Check for tuple equality.
+ */
+ if (e.e1.op == EXP.tuple && e.e2.op == EXP.tuple)
+ {
+ auto tup1 = e.e1.isTupleExp();
+ auto tup2 = e.e2.isTupleExp();
+ size_t dim = tup1.exps.length;
+ if (dim != tup2.exps.length)
+ {
+ error(e.loc, "mismatched sequence lengths, `%d` and `%d`",
+ cast(int)dim, cast(int)tup2.exps.length);
+ return ErrorExp.get();
}
- /* Check for tuple equality.
- */
- if (e.e1.op == EXP.tuple && e.e2.op == EXP.tuple)
+ Expression result;
+ if (dim == 0)
+ {
+ // zero-length tuple comparison should always return true or false.
+ result = IntegerExp.createBool(e.op == EXP.equal);
+ }
+ else
{
- auto tup1 = e.e1.isTupleExp();
- auto tup2 = e.e2.isTupleExp();
- size_t dim = tup1.exps.length;
- if (dim != tup2.exps.length)
+ for (size_t i = 0; i < dim; i++)
{
- error(e.loc, "mismatched sequence lengths, `%d` and `%d`",
- cast(int)dim, cast(int)tup2.exps.length);
- return ErrorExp.get();
+ auto ex1 = (*tup1.exps)[i];
+ auto ex2 = (*tup2.exps)[i];
+ auto eeq = new EqualExp(e.op, e.loc, ex1, ex2);
+
+ if (!result)
+ result = eeq;
+ else if (e.op == EXP.equal)
+ result = new LogicalExp(e.loc, EXP.andAnd, result, eeq);
+ else
+ result = new LogicalExp(e.loc, EXP.orOr, result, eeq);
}
+ assert(result);
+ }
+ result = Expression.combine(tup1.e0, tup2.e0, result);
+ result = result.expressionSemantic(sc);
- Expression result;
- if (dim == 0)
- {
- // zero-length tuple comparison should always return true or false.
- result = IntegerExp.createBool(e.op == EXP.equal);
- }
- else
- {
- for (size_t i = 0; i < dim; i++)
- {
- auto ex1 = (*tup1.exps)[i];
- auto ex2 = (*tup2.exps)[i];
- auto eeq = new EqualExp(e.op, e.loc, ex1, ex2);
-
- if (!result)
- result = eeq;
- else if (e.op == EXP.equal)
- result = new LogicalExp(e.loc, EXP.andAnd, result, eeq);
- else
- result = new LogicalExp(e.loc, EXP.orOr, result, eeq);
- }
- assert(result);
- }
- result = Expression.combine(tup1.e0, tup2.e0, result);
- result = result.expressionSemantic(sc);
+ return result;
+ }
+ return null;
+}
- return result;
- }
+Expression opOverloadCmp(CmpExp exp, Scope* sc, Type[2] aliasThisStop)
+{
+ //printf("CmpExp:: () (%s)\n", e.toChars());
+ EXP cmpOp = exp.op;
+ auto e = compare_overload(exp, sc, Id.opCmp, cmpOp, aliasThisStop);
+ if (!e)
return null;
+
+ if (!e.type.isScalar() && e.type.equals(exp.e1.type))
+ {
+ error(e.loc, "recursive `opCmp` expansion");
+ return ErrorExp.get();
}
+ if (e.op != EXP.call)
+ return e;
- Expression visitCmp(CmpExp e)
+ Type t1 = exp.e1.type.toBasetype();
+ Type t2 = exp.e2.type.toBasetype();
+ if (t1.ty != Tclass || t2.ty != Tclass)
{
- //printf("CmpExp:: () (%s)\n", e.toChars());
- return compare_overload(e, sc, Id.cmp, pop);
+ return new CmpExp(cmpOp, exp.loc, e, IntegerExp.literal!0).expressionSemantic(sc);
}
- /*********************************
- * Operator overloading for op=
- */
- Expression visitBinAssign(BinAssignExp e)
+ // Lower to object.__cmp(e1, e2)
+ Expression cl = new IdentifierExp(exp.loc, Id.empty);
+ cl = new DotIdExp(exp.loc, cl, Id.object);
+ cl = new DotIdExp(exp.loc, cl, Id.__cmp);
+ cl = cl.expressionSemantic(sc);
+
+ auto arguments = new Expressions();
+ // Check if op_overload found a better match by calling e2.opCmp(e1)
+ // If the operands were swapped, then the result must be reversed
+ // e1.opCmp(e2) == -e2.opCmp(e1)
+ // cmpop takes care of this
+ if (exp.op == cmpOp)
+ {
+ arguments.push(exp.e1);
+ arguments.push(exp.e2);
+ }
+ else
+ {
+ // Use better match found by op_overload
+ arguments.push(exp.e2);
+ arguments.push(exp.e1);
+ }
+
+ cl = new CallExp(e.loc, cl, arguments);
+ cl = new CmpExp(cmpOp, exp.loc, cl, new IntegerExp(0));
+ return cl.expressionSemantic(sc);
+}
+
+/*********************************
+ * Operator overloading for op=
+ */
+Expression opOverloadBinaryAssign(BinAssignExp e, Scope* sc, Type[2] aliasThisStop)
+{
+ if (auto ae = e.e1.isArrayExp())
{
- //printf("BinAssignExp::op_overload() (%s)\n", e.toChars());
- if (auto ae = e.e1.isArrayExp())
+ ae.e1 = ae.e1.expressionSemantic(sc);
+ ae.e1 = resolveProperties(sc, ae.e1);
+ Expression ae1old = ae.e1;
+ const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
+ IntervalExp ie = null;
+ if (maybeSlice && ae.arguments.length)
{
- ae.e1 = ae.e1.expressionSemantic(sc);
- ae.e1 = resolveProperties(sc, ae.e1);
- Expression ae1old = ae.e1;
- const(bool) maybeSlice = (ae.arguments.length == 0 || ae.arguments.length == 1 && (*ae.arguments)[0].op == EXP.interval);
- IntervalExp ie = null;
- if (maybeSlice && ae.arguments.length)
+ ie = (*ae.arguments)[0].isIntervalExp();
+ }
+ Type att = null; // first cyclic `alias this` type
+ while (true)
+ {
+ if (ae.e1.op == EXP.error)
{
- ie = (*ae.arguments)[0].isIntervalExp();
+ return ae.e1;
}
- Type att = null; // first cyclic `alias this` type
- while (true)
+ Expression e0 = null;
+ Expression ae1save = ae.e1;
+ ae.lengthVar = null;
+ Type t1b = ae.e1.type.toBasetype();
+ AggregateDeclaration ad = isAggregate(t1b);
+ if (!ad)
+ break;
+ if (search_function(ad, Id.opIndexOpAssign))
{
- if (ae.e1.op == EXP.error)
- {
- return ae.e1;
- }
- Expression e0 = null;
- Expression ae1save = ae.e1;
- ae.lengthVar = null;
- Type t1b = ae.e1.type.toBasetype();
- AggregateDeclaration ad = isAggregate(t1b);
- if (!ad)
- break;
- if (search_function(ad, Id.opIndexOpAssign))
- {
- // Deal with $
- Expression result = resolveOpDollar(sc, ae, &e0);
- if (!result) // (a[i..j] op= e2) might be: a.opSliceOpAssign!(op)(e2, i, j)
- goto Lfallback;
- if (result.op == EXP.error)
- return result;
- result = e.e2.expressionSemantic(sc);
- if (result.op == EXP.error)
- return result;
- e.e2 = result;
- /* Rewrite a[arguments] op= e2 as:
- * a.opIndexOpAssign!(op)(e2, arguments)
- */
- Expressions* a = ae.arguments.copy();
- a.insert(0, e.e2);
- Objects* tiargs = opToArg(sc, e.op);
- result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opIndexOpAssign, tiargs);
- result = new CallExp(e.loc, result, a);
- if (maybeSlice) // (a[] op= e2) might be: a.opSliceOpAssign!(op)(e2)
- result = result.trySemantic(sc);
- else
- result = result.expressionSemantic(sc);
- if (result)
- {
- return Expression.combine(e0, result);
- }
- }
- Lfallback:
- if (maybeSlice && search_function(ad, Id.opSliceOpAssign))
- {
- // Deal with $
- Expression result = resolveOpDollar(sc, ae, ie, &e0);
- if (result.op == EXP.error)
- return result;
- result = e.e2.expressionSemantic(sc);
- if (result.op == EXP.error)
- return result;
- e.e2 = result;
- /* Rewrite (a[i..j] op= e2) as:
- * a.opSliceOpAssign!(op)(e2, i, j)
- */
- auto a = new Expressions();
- a.push(e.e2);
- if (ie)
- {
- a.push(ie.lwr);
- a.push(ie.upr);
- }
- Objects* tiargs = opToArg(sc, e.op);
- result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opSliceOpAssign, tiargs);
- result = new CallExp(e.loc, result, a);
- result = result.expressionSemantic(sc);
- result = Expression.combine(e0, result);
+ // Deal with $
+ Expression result = resolveOpDollar(sc, ae, &e0);
+ if (!result) // (a[i..j] op= e2) might be: a.opSliceOpAssign!(op)(e2, i, j)
+ goto Lfallback;
+ if (result.op == EXP.error)
return result;
- }
- // Didn't find it. Forward to aliasthis
- if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type))
+ result = e.e2.expressionSemantic(sc);
+ if (result.op == EXP.error)
+ return result;
+ e.e2 = result;
+ /* Rewrite a[arguments] op= e2 as:
+ * a.opIndexOpAssign!(op)(e2, arguments)
+ */
+ Expressions* a = ae.arguments.copy();
+ a.insert(0, e.e2);
+ Objects* tiargs = opToArg(sc, e.op);
+ result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opIndexOpAssign, tiargs);
+ result = new CallExp(e.loc, result, a);
+ if (maybeSlice) // (a[] op= e2) might be: a.opSliceOpAssign!(op)(e2)
+ result = result.trySemantic(sc);
+ else
+ result = result.expressionSemantic(sc);
+ if (result)
{
- /* Rewrite (a[arguments] op= e2) as:
- * a.aliasthis[arguments] op= e2
- */
- ae.e1 = resolveAliasThis(sc, ae1save, true);
- if (ae.e1)
- continue;
+ return Expression.combine(e0, result);
}
- break;
}
- ae.e1 = ae1old; // recovery
- ae.lengthVar = null;
- }
- Expression result = e.binSemanticProp(sc);
- if (result)
- return result;
- // Don't attempt 'alias this' if an error occurred
- if (e.e1.type.ty == Terror || e.e2.type.ty == Terror)
- {
- return ErrorExp.get();
- }
- Identifier id = opId(e);
- Expressions* args2 = new Expressions();
- AggregateDeclaration ad1 = isAggregate(e.e1.type);
- Dsymbol s = null;
- Objects* tiargs = null;
- /* Try opOpAssign
- */
- if (ad1)
- {
- s = search_function(ad1, Id.opOpAssign);
- if (s && !s.isTemplateDeclaration())
+ Lfallback:
+ if (maybeSlice && search_function(ad, Id.opSliceOpAssign))
{
- error(e.loc, "`%s.opOpAssign` isn't a template", e.e1.toChars());
- return ErrorExp.get();
+ // Deal with $
+ Expression result = resolveOpDollar(sc, ae, ie, &e0);
+ if (result.op == EXP.error)
+ return result;
+ result = e.e2.expressionSemantic(sc);
+ if (result.op == EXP.error)
+ return result;
+ e.e2 = result;
+ /* Rewrite (a[i..j] op= e2) as:
+ * a.opSliceOpAssign!(op)(e2, i, j)
+ */
+ auto a = new Expressions();
+ a.push(e.e2);
+ if (ie)
+ {
+ a.push(ie.lwr);
+ a.push(ie.upr);
+ }
+ Objects* tiargs = opToArg(sc, e.op);
+ result = new DotTemplateInstanceExp(e.loc, ae.e1, Id.opSliceOpAssign, tiargs);
+ result = new CallExp(e.loc, result, a);
+ result = result.expressionSemantic(sc);
+ result = Expression.combine(e0, result);
+ return result;
}
- }
- // Set tiargs, the template argument list, which will be the operator string
- if (s)
- {
- id = Id.opOpAssign;
- tiargs = opToArg(sc, e.op);
- }
-
- // Try D1-style operator overload, deprecated
- if (!s && ad1 && id)
- {
- s = search_function(ad1, id);
- if (s)
+ // Didn't find it. Forward to aliasthis
+ if (ad.aliasthis && !isRecursiveAliasThis(att, ae.e1.type))
{
- // @@@DEPRECATED_2.110@@@.
- // Deprecated in 2.088, made an error in 2.100
- scope char[] op = EXPtoString(e.op).dup;
- op[$-1] = '\0'; // remove trailing `=`
- error(e.loc, "`%s` is obsolete. Use `opOpAssign(string op)(...) if (op == \"%s\")` instead.", id.toChars(), op.ptr);
- return ErrorExp.get();
+ /* Rewrite (a[arguments] op= e2) as:
+ * a.aliasthis[arguments] op= e2
+ */
+ ae.e1 = resolveAliasThis(sc, ae1save, true);
+ if (ae.e1)
+ continue;
}
+ break;
}
+ ae.e1 = ae1old; // recovery
+ ae.lengthVar = null;
+ }
+ Expression result = e.binSemanticProp(sc);
+ if (result)
+ return result;
+ // Don't attempt 'alias this' if an error occurred
+ if (e.e1.type.ty == Terror || e.e2.type.ty == Terror)
+ {
+ return ErrorExp.get();
+ }
+ AggregateDeclaration ad1 = isAggregate(e.e1.type);
+ Dsymbol s = search_function(ad1, Id.opOpAssign);
+ if (s && !s.isTemplateDeclaration())
+ {
+ error(e.loc, "`%s.opOpAssign` isn't a template", e.e1.toChars());
+ return ErrorExp.get();
+ }
- if (s)
- {
- /* Try:
- * a.opOpAssign(b)
- */
- args2.setDim(1);
- (*args2)[0] = e.e2;
- expandTuples(args2);
- MatchAccumulator m;
- functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
- if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
- {
- return ErrorExp.get();
- }
- if (m.count > 1)
- {
- // Error, ambiguous
- error(e.loc, "overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars());
- }
- else if (m.last == MATCH.nomatch)
- {
- if (tiargs)
- goto L1;
- m.lastf = null;
- }
- // Rewrite (e1 op e2) as e1.opOpAssign(e2)
- return build_overload(e.loc, sc, e.e1, e.e2, m.lastf ? m.lastf : s);
- }
- L1:
- result = checkAliasThisForLhs(ad1, sc, e);
- if (result || !s) // no point in trying Rhs alias-this if there's no overload of any kind in lhs
- return result;
+ bool choseReverse;
+ if (auto res = pickBestBinaryOverload(sc, opToArg(sc, e.op), s, null, e, choseReverse))
+ return res;
- return checkAliasThisForRhs(isAggregate(e.e2.type), sc, e);
- }
+ result = checkAliasThisForLhs(ad1, sc, e, aliasThisStop);
+ if (result || !s) // no point in trying Rhs alias-this if there's no overload of any kind in lhs
+ return result;
- if (pop)
- *pop = e.op;
+ return checkAliasThisForRhs(isAggregate(e.e2.type), sc, e, aliasThisStop);
+}
- switch (e.op)
- {
- case EXP.cast_ : return visitCast(e.isCastExp());
- case EXP.array : return visitArray(e.isArrayExp());
+/**
+Given symbols `s` and `s_r`, try to instantiate `e.e1.s!tiargs(e.e2)` and `e.e2.s_r!tiargs(e.e1)`,
+and return the one with the best match level.
+
+Params:
+ sc = scope
+ tiargs = (optional) template arguments to instantiate symbols with
+ s = (optional) symbol of straightforward template (e.g. opBinary)
+ s_r = (optional) symbol of reversed template (e.g. opBinaryRight)
+ e = binary expression being overloaded, supplying arguments to the function calls
+ choseReverse = set to true when `s_r` was chosen instead of `s`
+Returns:
+ Resulting operator overload function call, or `null` if neither symbol worked
+*/
+private Expression pickBestBinaryOverload(Scope* sc, Objects* tiargs, Dsymbol s, Dsymbol s_r, BinExp e, out bool choseReverse)
+{
+ if (!s && !s_r)
+ return null;
- case EXP.notEqual :
- case EXP.equal : return visitEqual(e.isEqualExp());
+ Expressions* args1 = new Expressions(1);
+ (*args1)[0] = e.e1;
+ expandTuples(args1);
+ Expressions* args2 = new Expressions(1);
+ (*args2)[0] = e.e2;
+ expandTuples(args2);
+ MatchAccumulator m;
- case EXP.lessOrEqual :
- case EXP.greaterThan :
- case EXP.greaterOrEqual:
- case EXP.lessThan : return visitCmp(cast(CmpExp)e);
+ if (s)
+ {
+ functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
+ if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
+ return ErrorExp.get();
+ }
+ FuncDeclaration lastf = m.lastf;
+ int count = m.count;
+ if (s_r)
+ {
+ functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
+ if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
+ return ErrorExp.get();
+ }
+ if (m.count > 1)
+ {
+ /* The following if says "not ambiguous" if there's one match
+ * from s and one from s_r, in which case we pick s.
+ * This doesn't follow the spec, but is a workaround for the case
+ * where opEquals was generated from templates and we cannot figure
+ * out if both s and s_r came from the same declaration or not.
+ * The test case is:
+ * import std.typecons;
+ * void main() {
+ * assert(tuple("has a", 2u) == tuple("has a", 1));
+ * }
+ */
+ if (!(m.lastf == lastf && m.count == 2 && count == 1))
+ {
+ // Error, ambiguous
+ error(e.loc, "overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars());
+ }
+ }
+ else if (m.last == MATCH.nomatch)
+ {
+ if (tiargs)
+ return null;
+ m.lastf = null;
+ }
- default:
- if (auto ex = e.isBinAssignExp()) return visitBinAssign(ex);
- if (auto ex = e.isBinExp()) return visitBin(ex);
- if (auto ex = e.isUnaExp()) return visitUna(ex);
- return visit(e);
+ if (lastf && m.lastf == lastf || !s_r && m.last == MATCH.nomatch)
+ {
+ choseReverse = false;
+ // Rewrite (e1 op e2) as e1.opfunc(e2)
+ return build_overload(e.loc, sc, e.e1, e.e2, m.lastf ? m.lastf : s);
+ }
+ else
+ {
+ choseReverse = true;
+ // Rewrite (e1 op e2) as e2.opfunc_r(e1)
+ return build_overload(e.loc, sc, e.e2, e.e1, m.lastf ? m.lastf : s_r);
}
}
/******************************************
* Common code for overloading of EqualExp and CmpExp
*/
-private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop)
+private Expression compare_overload(BinExp e, Scope* sc, Identifier id, ref EXP cmpOp, Type[2] aliasThisStop)
{
//printf("BinExp::compare_overload(id = %s) %s\n", id.toChars(), e.toChars());
AggregateDeclaration ad1 = isAggregate(e.e1.type);
AggregateDeclaration ad2 = isAggregate(e.e2.type);
- Dsymbol s = null;
- Dsymbol s_r = null;
- if (ad1)
- {
- s = search_function(ad1, id);
- }
- if (ad2)
+ Dsymbol s = search_function(ad1, id);
+ Dsymbol s_r = search_function(ad2, id);
+
+ if (s == s_r)
+ s_r = null;
+
+ bool choseReverse;
+ if (auto res = pickBestBinaryOverload(sc, null, s, s_r, e, choseReverse))
{
- s_r = search_function(ad2, id);
- if (s == s_r)
- s_r = null;
- }
- Objects* tiargs = null;
- if (s || s_r)
- {
- /* Try:
- * a.opEquals(b)
- * b.opEquals(a)
- * and see which is better.
- */
- Expressions* args1 = new Expressions(1);
- (*args1)[0] = e.e1;
- expandTuples(args1);
- Expressions* args2 = new Expressions(1);
- (*args2)[0] = e.e2;
- expandTuples(args2);
- MatchAccumulator m;
- if (0 && s && s_r)
- {
- printf("s : %s\n", s.toPrettyChars());
- printf("s_r: %s\n", s_r.toPrettyChars());
- }
- if (s)
- {
- functionResolve(m, s, e.loc, sc, tiargs, e.e1.type, ArgumentList(args2));
- if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
- return ErrorExp.get();
- }
- FuncDeclaration lastf = m.lastf;
- int count = m.count;
- if (s_r)
- {
- functionResolve(m, s_r, e.loc, sc, tiargs, e.e2.type, ArgumentList(args1));
- if (m.lastf && (m.lastf.errors || m.lastf.hasSemantic3Errors()))
- return ErrorExp.get();
- }
- if (m.count > 1)
- {
- /* The following if says "not ambiguous" if there's one match
- * from s and one from s_r, in which case we pick s.
- * This doesn't follow the spec, but is a workaround for the case
- * where opEquals was generated from templates and we cannot figure
- * out if both s and s_r came from the same declaration or not.
- * The test case is:
- * import std.typecons;
- * void main() {
- * assert(tuple("has a", 2u) == tuple("has a", 1));
- * }
- */
- if (!(m.lastf == lastf && m.count == 2 && count == 1))
- {
- // Error, ambiguous
- error(e.loc, "overloads `%s` and `%s` both match argument list for `%s`", m.lastf.type.toChars(), m.nextf.type.toChars(), m.lastf.toChars());
- }
- }
- else if (m.last == MATCH.nomatch)
- {
- m.lastf = null;
- }
- Expression result;
- if (lastf && m.lastf == lastf || !s_r && m.last == MATCH.nomatch)
- {
- // Rewrite (e1 op e2) as e1.opfunc(e2)
- result = build_overload(e.loc, sc, e.e1, e.e2, m.lastf ? m.lastf : s);
- }
- else
- {
- // Rewrite (e1 op e2) as e2.opfunc_r(e1)
- result = build_overload(e.loc, sc, e.e2, e.e1, m.lastf ? m.lastf : s_r);
- // When reversing operands of comparison operators,
- // need to reverse the sense of the op
- if (pop)
- *pop = reverseRelation(e.op);
- }
- return result;
+ if (choseReverse)
+ cmpOp = reverseRelation(e.op);
+ return res;
}
+
/*
* https://issues.dlang.org/show_bug.cgi?id=16657
* at this point, no matching opEquals was found for structs,
@@ -1400,8 +1071,8 @@ private Expression compare_overload(BinExp e, Scope* sc, Identifier id, EXP* pop
*/
if ((e.op == EXP.equal || e.op == EXP.notEqual) && ad1 == ad2)
return null;
- Expression result = checkAliasThisForLhs(ad1, sc, e);
- return result ? result : checkAliasThisForRhs(isAggregate(e.e2.type), sc, e);
+ Expression result = checkAliasThisForLhs(ad1, sc, e, aliasThisStop);
+ return result ? result : checkAliasThisForRhs(isAggregate(e.e2.type), sc, e, aliasThisStop);
}
/***********************************
@@ -1425,6 +1096,8 @@ Expression build_overload(const ref Loc loc, Scope* sc, Expression ethis, Expres
*/
Dsymbol search_function(ScopeDsymbol ad, Identifier funcid)
{
+ if (!ad)
+ return null;
if (Dsymbol s = ad.search(Loc.initial, funcid))
{
//printf("search_function: s = '%s'\n", s.kind());
diff --git a/gcc/d/dmd/parse.d b/gcc/d/dmd/parse.d
index b851b9a..2e29762 100644
--- a/gcc/d/dmd/parse.d
+++ b/gcc/d/dmd/parse.d
@@ -2759,35 +2759,10 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
error("`new` allocator must be annotated with `@disabled`");
}
nextToken();
-
- /* @@@DEPRECATED_2.108@@@
- * After deprecation period (2.108), remove all code in the version(all) block.
- */
- version (all)
- {
- auto parameterList = parseParameterList(null); // parameterList ignored
- if (parameterList.parameters.length > 0 || parameterList.varargs != VarArg.none)
- deprecation("`new` allocator with non-empty parameter list is deprecated");
- auto f = new AST.NewDeclaration(loc, stc);
- if (token.value != TOK.semicolon)
- {
- deprecation("`new` allocator with function definition is deprecated");
- parseContracts(f); // body ignored
- f.fbody = null;
- f.fensures = null;
- f.frequires = null;
- }
- else
- nextToken();
- return f;
- }
- else
- {
- check(TOK.leftParenthesis);
- check(TOK.rightParenthesis);
- check(TOK.semicolon);
- return new AST.NewDeclaration(loc, stc);
- }
+ check(TOK.leftParenthesis);
+ check(TOK.rightParenthesis);
+ check(TOK.semicolon);
+ return new AST.NewDeclaration(loc, stc);
}
/**********************************************
@@ -5844,7 +5819,6 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
case TOK.plusPlus:
case TOK.minusMinus:
case TOK.new_:
- case TOK.delete_:
case TOK.delegate_:
case TOK.function_:
case TOK.typeid_:
@@ -8713,15 +8687,6 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
e = new AST.ComExp(loc, e);
break;
- case TOK.delete_:
- // @@@DEPRECATED_2.109@@@
- // Use of `delete` keyword has been an error since 2.099.
- // Remove from the parser after 2.109.
- nextToken();
- e = parseUnaryExp();
- e = new AST.DeleteExp(loc, e, false);
- break;
-
case TOK.cast_: // cast(type) expression
{
nextToken();
@@ -8839,7 +8804,6 @@ class Parser(AST, Lexer = dmd.lexer.Lexer) : Lexer
case TOK.dot:
case TOK.plusPlus:
case TOK.minusMinus:
- case TOK.delete_:
case TOK.new_:
case TOK.leftParenthesis:
case TOK.identifier:
diff --git a/gcc/d/dmd/semantic3.d b/gcc/d/dmd/semantic3.d
index def7d46..89f612c 100644
--- a/gcc/d/dmd/semantic3.d
+++ b/gcc/d/dmd/semantic3.d
@@ -270,7 +270,7 @@ private extern(C++) final class Semantic3Visitor : Visitor
//{ static int x; if (++x == 2) *(char*)0=0; }
//printf("\tlinkage = %d\n", sc.linkage);
- if (funcdecl.ident == Id.assign && !funcdecl.inuse)
+ if (funcdecl.ident == Id.opAssign && !funcdecl.inuse)
{
if (funcdecl.storage_class & STC.inference)
{
diff --git a/gcc/d/dmd/tokens.d b/gcc/d/dmd/tokens.d
index b499c00..e82a582 100644
--- a/gcc/d/dmd/tokens.d
+++ b/gcc/d/dmd/tokens.d
@@ -48,7 +48,6 @@ enum TOK : ubyte
false_,
throw_,
new_,
- delete_,
variable,
slice,
version_,
@@ -459,7 +458,6 @@ private immutable TOK[] keywords =
TOK.false_,
TOK.cast_,
TOK.new_,
- TOK.delete_,
TOK.throw_,
TOK.module_,
TOK.pragma_,
@@ -680,7 +678,6 @@ extern (C++) struct Token
TOK.false_: "false",
TOK.cast_: "cast",
TOK.new_: "new",
- TOK.delete_: "delete",
TOK.throw_: "throw",
TOK.module_: "module",
TOK.pragma_: "pragma",
diff --git a/gcc/d/dmd/tokens.h b/gcc/d/dmd/tokens.h
index 2a984b4..c12a00b 100644
--- a/gcc/d/dmd/tokens.h
+++ b/gcc/d/dmd/tokens.h
@@ -54,7 +54,6 @@ enum class TOK : unsigned char
false_,
throw_,
new_,
- delete_,
variable,
slice,
version_,
diff --git a/gcc/d/dmd/typesem.d b/gcc/d/dmd/typesem.d
index ca10db1..65d267f 100644
--- a/gcc/d/dmd/typesem.d
+++ b/gcc/d/dmd/typesem.d
@@ -2025,7 +2025,7 @@ Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
}
else if (sd.xeq == sd.xerreq)
{
- if (search_function(sd, Id.eq))
+ if (search_function(sd, Id.opEquals))
{
.error(loc, "%sAA key type `%s` does not have `bool opEquals(ref const %s) const`", s, sd.toChars(), sd.toChars());
}
@@ -2037,7 +2037,7 @@ Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
}
else if (!sd.xhash)
{
- if (search_function(sd, Id.eq))
+ if (search_function(sd, Id.opEquals))
{
.error(loc, "%sAA key type `%s` should have `extern (D) size_t toHash() const nothrow @safe` if `opEquals` defined", s, sd.toChars());
}
@@ -2075,9 +2075,9 @@ Type typeSemantic(Type type, const ref Loc loc, Scope* sc)
__gshared FuncDeclaration fcmp = null;
__gshared FuncDeclaration fhash = null;
if (!feq)
- feq = search_function(ClassDeclaration.object, Id.eq).isFuncDeclaration();
+ feq = search_function(ClassDeclaration.object, Id.opEquals).isFuncDeclaration();
if (!fcmp)
- fcmp = search_function(ClassDeclaration.object, Id.cmp).isFuncDeclaration();
+ fcmp = search_function(ClassDeclaration.object, Id.opCmp).isFuncDeclaration();
if (!fhash)
fhash = search_function(ClassDeclaration.object, Id.tohash).isFuncDeclaration();
assert(fcmp && feq && fhash);
@@ -3417,7 +3417,7 @@ Expression getProperty(Type t, Scope* scope_, const ref Loc loc, Identifier iden
if (s)
error(loc, "no property `%s` for type `%s`, did you mean `%s`?", ident.toChars(), mt.toChars(), s.toPrettyChars());
- else if (ident == Id.call && mt.ty == Tclass)
+ else if (ident == Id.opCall && mt.ty == Tclass)
error(loc, "no property `%s` for type `%s`, did you mean `new %s`?", ident.toChars(), mt.toChars(), mt.toPrettyChars());
else if (const n = importHint(ident.toString()))
@@ -4883,7 +4883,7 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
/***************************************
* `ident` was not found as a member of `mt`.
- * Attempt to use overloaded opDot(), overloaded opDispatch(), or `alias this`.
+ * Attempt to use overloaded opDispatch() or `alias this`.
* If that fails, forward to visitType().
* Params:
* mt = class or struct
@@ -4939,21 +4939,6 @@ Expression dotExp(Type mt, Scope* sc, Expression e, Identifier ident, DotExpFlag
ident != Id.postblit &&
ident != Id.__xpostblit)
{
- /* Look for overloaded opDot() to see if we should forward request
- * to it.
- */
- if (auto fd = search_function(sym, Id.opDot))
- {
- /* Rewrite e.ident as:
- * e.opDot().ident
- */
- e = build_overload(e.loc, sc, e, null, fd);
- // @@@DEPRECATED_2.110@@@.
- // Deprecated in 2.082, made an error in 2.100.
- error(e.loc, "`opDot` is obsolete. Use `alias this`");
- return ErrorExp.get();
- }
-
/* Look for overloaded opDispatch to see if we should forward request
* to it.
*/
diff --git a/gcc/testsuite/gdc.test/compilable/interpret3.d b/gcc/testsuite/gdc.test/compilable/interpret3.d
index aa88458..f62147a 100644
--- a/gcc/testsuite/gdc.test/compilable/interpret3.d
+++ b/gcc/testsuite/gdc.test/compilable/interpret3.d
@@ -6240,9 +6240,9 @@ struct Coord13831
struct Chunk13831
{
- this(Coord13831)
+ this(Coord13831 coord)
{
- coord = coord;
+ this.coord = coord;
}
Coord13831 coord;
diff --git a/gcc/testsuite/gdc.test/compilable/nogc.d b/gcc/testsuite/gdc.test/compilable/nogc.d
index 959adc4..5f14339 100644
--- a/gcc/testsuite/gdc.test/compilable/nogc.d
+++ b/gcc/testsuite/gdc.test/compilable/nogc.d
@@ -36,9 +36,6 @@ void foo_compiles() {}
static assert(!__traits(compiles, new Struct()));
static assert(!__traits(compiles, new Object()));
- int* p;
- static assert(!__traits(compiles, delete p));
-
int[int] aa;
static assert( __traits(compiles, aa[0]));
static assert(!__traits(compiles, (aa[0] = 10)));
diff --git a/gcc/testsuite/gdc.test/compilable/test22510.d b/gcc/testsuite/gdc.test/compilable/test22510.d
index af5d0a4..1207bf0 100644
--- a/gcc/testsuite/gdc.test/compilable/test22510.d
+++ b/gcc/testsuite/gdc.test/compilable/test22510.d
@@ -7,7 +7,7 @@ struct S
@disable this(this);
this (scope ref inout S) inout
{
- this.b = b;
+ this.b = 0;
}
}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ctor_self_assignment.d b/gcc/testsuite/gdc.test/fail_compilation/ctor_self_assignment.d
new file mode 100644
index 0000000..9d424b1
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/ctor_self_assignment.d
@@ -0,0 +1,23 @@
+/**
+REQUIRED_ARGS: -de
+TEST_OUTPUT:
+---
+fail_compilation/ctor_self_assignment.d(17): Deprecation: cannot initialize field `location` with itself
+fail_compilation/ctor_self_assignment.d(15): did you mean to use parameter `locaction`?
+---
+*/
+// https://forum.dlang.org/post/teghfhpmvkdcfwfeovua@forum.dlang.org
+
+alias Location = int;
+
+struct Node
+{
+ this(Location locaction, uint f)
+ {
+ this.location = location;
+ this.f = f;
+ }
+
+ Location location;
+ uint f;
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/dep_d1_ops.d b/gcc/testsuite/gdc.test/fail_compilation/dep_d1_ops.d
index 19c6475..f8ebc37 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/dep_d1_ops.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/dep_d1_ops.d
@@ -1,52 +1,93 @@
/*
-REQUIRED_ARGS: -de
+REQUIRED_ARGS:
TEST_OUTPUT:
---
-fail_compilation/dep_d1_ops.d(105): Error: `opAdd` is obsolete. Use `opBinary(string op)(...) if (op == "+")` instead.
-fail_compilation/dep_d1_ops.d(106): Error: `opAdd_r` is obsolete. Use `opBinaryRight(string op)(...) if (op == "+")` instead.
-fail_compilation/dep_d1_ops.d(107): Error: `opSub` is obsolete. Use `opBinary(string op)(...) if (op == "-")` instead.
-fail_compilation/dep_d1_ops.d(108): Error: `opSub_r` is obsolete. Use `opBinaryRight(string op)(...) if (op == "-")` instead.
-fail_compilation/dep_d1_ops.d(109): Error: `opMul` is obsolete. Use `opBinary(string op)(...) if (op == "*")` instead.
-fail_compilation/dep_d1_ops.d(110): Error: `opMul_r` is obsolete. Use `opBinaryRight(string op)(...) if (op == "*")` instead.
-fail_compilation/dep_d1_ops.d(111): Error: `opDiv` is obsolete. Use `opBinary(string op)(...) if (op == "/")` instead.
-fail_compilation/dep_d1_ops.d(112): Error: `opDiv_r` is obsolete. Use `opBinaryRight(string op)(...) if (op == "/")` instead.
-fail_compilation/dep_d1_ops.d(113): Error: `opMod` is obsolete. Use `opBinary(string op)(...) if (op == "%")` instead.
-fail_compilation/dep_d1_ops.d(114): Error: `opMod_r` is obsolete. Use `opBinaryRight(string op)(...) if (op == "%")` instead.
-fail_compilation/dep_d1_ops.d(116): Error: `opAnd` is obsolete. Use `opBinary(string op)(...) if (op == "&")` instead.
-fail_compilation/dep_d1_ops.d(117): Error: `opOr` is obsolete. Use `opBinary(string op)(...) if (op == "|")` instead.
-fail_compilation/dep_d1_ops.d(118): Error: `opXor` is obsolete. Use `opBinary(string op)(...) if (op == "^")` instead.
-fail_compilation/dep_d1_ops.d(120): Error: `opShl` is obsolete. Use `opBinary(string op)(...) if (op == "<<")` instead.
-fail_compilation/dep_d1_ops.d(121): Error: `opShl_r` is obsolete. Use `opBinaryRight(string op)(...) if (op == "<<")` instead.
-fail_compilation/dep_d1_ops.d(122): Error: `opShr` is obsolete. Use `opBinary(string op)(...) if (op == ">>")` instead.
-fail_compilation/dep_d1_ops.d(123): Error: `opShr_r` is obsolete. Use `opBinaryRight(string op)(...) if (op == ">>")` instead.
-fail_compilation/dep_d1_ops.d(124): Error: `opUShr` is obsolete. Use `opBinary(string op)(...) if (op == ">>>")` instead.
-fail_compilation/dep_d1_ops.d(125): Error: `opUShr_r` is obsolete. Use `opBinaryRight(string op)(...) if (op == ">>>")` instead.
-fail_compilation/dep_d1_ops.d(127): Error: `opCat` is obsolete. Use `opBinary(string op)(...) if (op == "~")` instead.
-fail_compilation/dep_d1_ops.d(128): Error: `opCat_r` is obsolete. Use `opBinaryRight(string op)(...) if (op == "~")` instead.
-fail_compilation/dep_d1_ops.d(130): Error: `opNeg` is obsolete. Use `opUnary(string op)() if (op == "-")` instead.
-fail_compilation/dep_d1_ops.d(131): Error: `opCom` is obsolete. Use `opUnary(string op)() if (op == "~")` instead.
-fail_compilation/dep_d1_ops.d(132): Error: `opPostInc` is obsolete. Use `opUnary(string op)() if (op == "++")` instead.
-fail_compilation/dep_d1_ops.d(133): Error: `opPostDec` is obsolete. Use `opUnary(string op)() if (op == "--")` instead.
-fail_compilation/dep_d1_ops.d(134): Error: `opStar` is obsolete. Use `opUnary(string op)() if (op == "*")` instead.
-fail_compilation/dep_d1_ops.d(136): Error: `opIn` is obsolete. Use `opBinary(string op)(...) if (op == "in")` instead.
-fail_compilation/dep_d1_ops.d(137): Error: `opIn_r` is obsolete. Use `opBinaryRight(string op)(...) if (op == "in")` instead.
-fail_compilation/dep_d1_ops.d(139): Error: `opAddAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == "+")` instead.
-fail_compilation/dep_d1_ops.d(140): Error: `opSubAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == "-")` instead.
-fail_compilation/dep_d1_ops.d(141): Error: `opMulAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == "*")` instead.
-fail_compilation/dep_d1_ops.d(142): Error: `opDivAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == "/")` instead.
-fail_compilation/dep_d1_ops.d(143): Error: `opModAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == "%")` instead.
-fail_compilation/dep_d1_ops.d(144): Error: `opAndAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == "&")` instead.
-fail_compilation/dep_d1_ops.d(145): Error: `opOrAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == "|")` instead.
-fail_compilation/dep_d1_ops.d(146): Error: `opXorAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == "^")` instead.
-fail_compilation/dep_d1_ops.d(147): Error: `opShlAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == "<<")` instead.
-fail_compilation/dep_d1_ops.d(148): Error: `opShrAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == ">>")` instead.
-fail_compilation/dep_d1_ops.d(149): Error: `opUShrAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == ">>>")` instead.
-fail_compilation/dep_d1_ops.d(150): Error: `opCatAssign` is obsolete. Use `opOpAssign(string op)(...) if (op == "~")` instead.
-fail_compilation/dep_d1_ops.d(158): Error: `opCom` is obsolete. Use `opUnary(string op)() if (op == "~")` instead.
+fail_compilation/dep_d1_ops.d(198): Error: incompatible types for `(s) + (1)`: `S` and `int`
+fail_compilation/dep_d1_ops.d(199): Error: incompatible types for `(1) + (s)`: `int` and `S`
+fail_compilation/dep_d1_ops.d(200): Error: incompatible types for `(s) - (1)`: `S` and `int`
+fail_compilation/dep_d1_ops.d(201): Error: incompatible types for `(1) - (s)`: `int` and `S`
+fail_compilation/dep_d1_ops.d(202): Error: incompatible types for `(s) * (1)`: `S` and `int`
+fail_compilation/dep_d1_ops.d(203): Error: incompatible types for `(1) * (s)`: `int` and `S`
+fail_compilation/dep_d1_ops.d(204): Error: incompatible types for `(s) / (1)`: `S` and `int`
+fail_compilation/dep_d1_ops.d(205): Error: incompatible types for `(1) / (s)`: `int` and `S`
+fail_compilation/dep_d1_ops.d(206): Error: incompatible types for `(s) % (1)`: `S` and `int`
+fail_compilation/dep_d1_ops.d(207): Error: incompatible types for `(1) % (s)`: `int` and `S`
+fail_compilation/dep_d1_ops.d(209): Error: incompatible types for `(s) & (1)`: `S` and `int`
+fail_compilation/dep_d1_ops.d(210): Error: incompatible types for `(s) | (1)`: `S` and `int`
+fail_compilation/dep_d1_ops.d(211): Error: incompatible types for `(s) ^ (1)`: `S` and `int`
+fail_compilation/dep_d1_ops.d(213): Error: `s` is not of integral type, it is a `S`
+fail_compilation/dep_d1_ops.d(214): Error: `s` is not of integral type, it is a `S`
+fail_compilation/dep_d1_ops.d(215): Error: `s` is not of integral type, it is a `S`
+fail_compilation/dep_d1_ops.d(216): Error: `s` is not of integral type, it is a `S`
+fail_compilation/dep_d1_ops.d(217): Error: `s` is not of integral type, it is a `S`
+fail_compilation/dep_d1_ops.d(218): Error: `s` is not of integral type, it is a `S`
+fail_compilation/dep_d1_ops.d(220): Error: incompatible types for `(s) ~ (1)`: `S` and `int`
+fail_compilation/dep_d1_ops.d(221): Error: incompatible types for `(1) ~ (s)`: `int` and `S`
+fail_compilation/dep_d1_ops.d(223): Error: operator `+` is not defined for `s` of type `S`
+fail_compilation/dep_d1_ops.d(224): Error: operator `-` is not defined for `s` of type `S`
+fail_compilation/dep_d1_ops.d(225): Error: `s` is not of integral type, it is a `S`
+fail_compilation/dep_d1_ops.d(226): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(227): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(228): Error: can only `*` a pointer, not a `S`
+fail_compilation/dep_d1_ops.d(230): Error: incompatible types for `(s) in (1)`: `S` and `int`
+fail_compilation/dep_d1_ops.d(231): Error: incompatible types for `(1) in (s)`: `int` and `S`
+fail_compilation/dep_d1_ops.d(233): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(234): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(235): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(236): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(237): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(238): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(239): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(240): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(241): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(242): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(243): Error: `s` is not a scalar, it is a `S`
+fail_compilation/dep_d1_ops.d(244): Error: cannot append type `int` to type `S`
+fail_compilation/dep_d1_ops.d(248): Error: incompatible types for `(c) + (1)`: `dep_d1_ops.C` and `int`
+fail_compilation/dep_d1_ops.d(249): Error: incompatible types for `(1) + (c)`: `int` and `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(250): Error: incompatible types for `(c) - (1)`: `dep_d1_ops.C` and `int`
+fail_compilation/dep_d1_ops.d(251): Error: incompatible types for `(1) - (c)`: `int` and `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(252): Error: incompatible types for `(c) * (1)`: `dep_d1_ops.C` and `int`
+fail_compilation/dep_d1_ops.d(253): Error: incompatible types for `(1) * (c)`: `int` and `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(254): Error: incompatible types for `(c) / (1)`: `dep_d1_ops.C` and `int`
+fail_compilation/dep_d1_ops.d(255): Error: incompatible types for `(1) / (c)`: `int` and `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(256): Error: incompatible types for `(c) % (1)`: `dep_d1_ops.C` and `int`
+fail_compilation/dep_d1_ops.d(257): Error: incompatible types for `(1) % (c)`: `int` and `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(259): Error: incompatible types for `(c) & (1)`: `dep_d1_ops.C` and `int`
+fail_compilation/dep_d1_ops.d(260): Error: incompatible types for `(c) | (1)`: `dep_d1_ops.C` and `int`
+fail_compilation/dep_d1_ops.d(261): Error: incompatible types for `(c) ^ (1)`: `dep_d1_ops.C` and `int`
+fail_compilation/dep_d1_ops.d(263): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(264): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(265): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(266): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(267): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(268): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(270): Error: incompatible types for `(c) ~ (1)`: `dep_d1_ops.C` and `int`
+fail_compilation/dep_d1_ops.d(271): Error: incompatible types for `(1) ~ (c)`: `int` and `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(273): Error: operator `+` is not defined for `c` of type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(274): Error: operator `-` is not defined for `c` of type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(275): Error: `c` is not of integral type, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(276): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(277): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(278): Error: can only `*` a pointer, not a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(280): Error: incompatible types for `(c) in (1)`: `dep_d1_ops.C` and `int`
+fail_compilation/dep_d1_ops.d(281): Error: incompatible types for `(1) in (c)`: `int` and `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(283): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(284): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(285): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(286): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(287): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(288): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(289): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(290): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(291): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(292): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(293): Error: `c` is not a scalar, it is a `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(294): Error: cannot append type `int` to type `dep_d1_ops.C`
+fail_compilation/dep_d1_ops.d(303): Error: `nd` is not of integral type, it is a `dep_d1_ops.NoDeprecation`
---
*/
-#line 50
struct S
{
int opAdd(int i) { return 0; }
@@ -74,6 +115,58 @@ struct S
int opCat(int i) { return 0; }
int opCat_r(int i) { return 0; }
+ int opPos() { return 0; }
+ int opNeg() { return 0; }
+ int opCom() { return 0; }
+ int opPostInc() { return 0; }
+ int opPostDec() { return 0; }
+ int opStar() { return 0; }
+
+ int opIn(int i) { return 0; }
+ int opIn_r(int i) { return 0; }
+
+ int opAddAssign(int i) { return 0; }
+ int opSubAssign(int i) { return 0; }
+ int opMulAssign(int i) { return 0; }
+ int opDivAssign(int i) { return 0; }
+ int opModAssign(int i) { return 0; }
+ int opAndAssign(int i) { return 0; }
+ int opOrAssign(int i) { return 0; }
+ int opXorAssign(int i) { return 0; }
+ int opShlAssign(int i) { return 0; }
+ int opShrAssign(int i) { return 0; }
+ int opUShrAssign(int i) { return 0; }
+ int opCatAssign(int i) { return 0; }
+}
+
+class C
+{
+ int opAdd(int i) { return 0; }
+ int opAdd_r(int i) { return 0; }
+ int opSub(int i) { return 0; }
+ int opSub_r(int i) { return 0; }
+ int opMul(int i) { return 0; }
+ int opMul_r(int i) { return 0; }
+ int opDiv(int i) { return 0; }
+ int opDiv_r(int i) { return 0; }
+ int opMod(int i) { return 0; }
+ int opMod_r(int i) { return 0; }
+
+ int opAnd(int i) { return 0; }
+ int opOr(int i) { return 0; }
+ int opXor(int i) { return 0; }
+
+ int opShl(int i) { return 0; }
+ int opShl_r(int i) { return 0; }
+ int opShr(int i) { return 0; }
+ int opShr_r(int i) { return 0; }
+ int opUShr(int i) { return 0; }
+ int opUShr_r(int i) { return 0; }
+
+ int opCat(int i) { return 0; }
+ int opCat_r(int i) { return 0; }
+
+ int opPos() { return 0; }
int opNeg() { return 0; }
int opCom() { return 0; }
int opPostInc() { return 0; }
@@ -99,55 +192,107 @@ struct S
void main()
{
- S s;
int i;
+ {
+ S s;
+ i = s + 1;
+ i = 1 + s;
+ i = s - 1;
+ i = 1 - s;
+ i = s * 1;
+ i = 1 * s;
+ i = s / 1;
+ i = 1 / s;
+ i = s % 1;
+ i = 1 % s;
+
+ i = s & 1;
+ i = s | 1;
+ i = s ^ 1;
+
+ i = s << 1;
+ i = 1 << s;
+ i = s >> 1;
+ i = 1 >> s;
+ i = s >>> 1;
+ i = 1 >>> s;
+
+ i = s ~ 1;
+ i = 1 ~ s;
+
+ i = +s;
+ i = -s;
+ i = ~s;
+ s++;
+ s--;
+ i = *s;
+
+ i = s in 1;
+ i = 1 in s;
+
+ s += 1;
+ s -= 1;
+ s *= 1;
+ s /= 1;
+ s %= 1;
+ s &= 1;
+ s |= 1;
+ s ^= 1;
+ s <<= 1;
+ s >>= 1;
+ s >>>= 1;
+ s ~= 1;
+ }
+ {
+ C c;
+ i = c + 1;
+ i = 1 + c;
+ i = c - 1;
+ i = 1 - c;
+ i = c * 1;
+ i = 1 * c;
+ i = c / 1;
+ i = 1 / c;
+ i = c % 1;
+ i = 1 % c;
+
+ i = c & 1;
+ i = c | 1;
+ i = c ^ 1;
+
+ i = c << 1;
+ i = 1 << c;
+ i = c >> 1;
+ i = 1 >> c;
+ i = c >>> 1;
+ i = 1 >>> c;
- i = s + 1;
- i = 1 + s;
- i = s - 1;
- i = 1 - s;
- i = s * 1;
- i = 1 * s;
- i = s / 1;
- i = 1 / s;
- i = s % 1;
- i = 1 % s;
-
- i = s & 1;
- i = s | 1;
- i = s ^ 1;
-
- i = s << 1;
- i = 1 << s;
- i = s >> 1;
- i = 1 >> s;
- i = s >>> 1;
- i = 1 >>> s;
-
- i = s ~ 1;
- i = 1 ~ s;
-
- i = -s;
- i = ~s;
- s++;
- s--;
- i = *s;
-
- i = s in 1;
- i = 1 in s;
-
- s += 1;
- s -= 1;
- s *= 1;
- s /= 1;
- s %= 1;
- s &= 1;
- s |= 1;
- s ^= 1;
- s <<= 1;
- s >>= 1;
- s >>>= 1;
- s ~= 1;
+ i = c ~ 1;
+ i = 1 ~ c;
+
+ i = +c;
+ i = -c;
+ i = ~c;
+ c++;
+ c--;
+ i = *c;
+
+ i = c in 1;
+ i = 1 in c;
+
+ c += 1;
+ c -= 1;
+ c *= 1;
+ c /= 1;
+ c %= 1;
+ c &= 1;
+ c |= 1;
+ c ^= 1;
+ c <<= 1;
+ c >>= 1;
+ c >>>= 1;
+ c ~= 1;
+ }
scope nd = new NoDeprecation;
assert((42 in nd) == 0);
diff --git a/gcc/testsuite/gdc.test/fail_compilation/deprecateopdot.d b/gcc/testsuite/gdc.test/fail_compilation/deprecateopdot.d
deleted file mode 100644
index 46c9493..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/deprecateopdot.d
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-REQUIRED_ARGS: -de
-TEST_OUTPUT:
----
-fail_compilation/deprecateopdot.d(27): Error: `opDot` is obsolete. Use `alias this`
-fail_compilation/deprecateopdot.d(28): Error: `opDot` is obsolete. Use `alias this`
-fail_compilation/deprecateopdot.d(29): Error: `opDot` is obsolete. Use `alias this`
----
-*/
-struct S6
-{
- int a, b;
-}
-struct T6
-{
- S6 s;
-
- S6* opDot() return
- {
- return &s;
- }
-}
-
-void test6()
-{
- T6 t;
- t.a = 4;
- assert(t.a == 4);
- t.b = 5;
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/diag_class_alloc.d b/gcc/testsuite/gdc.test/fail_compilation/diag_class_alloc.d
deleted file mode 100644
index 326d82e..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/diag_class_alloc.d
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
-TEST_OUTPUT:
----
-fail_compilation/diag_class_alloc.d(15): Error: `new` allocator must be annotated with `@disabled`
-fail_compilation/diag_class_alloc.d(16): Deprecation: `new` allocator with non-empty parameter list is deprecated
-fail_compilation/diag_class_alloc.d(16): Deprecation: `new` allocator with function definition is deprecated
----
-*/
-
-// This test exists to ensure class allocators and deallocators emit an appropriate error message.
-// This test can be deleted when class allocators and deallocators are removed from the language.
-
-class C
-{
- new(size_t size) // error message
- {
- return malloc(size);
- }
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail10534.d b/gcc/testsuite/gdc.test/fail_compilation/fail10534.d
index b5bb67c..f0e0b85 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail10534.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail10534.d
@@ -1,22 +1,18 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail10534.d(28): Error: illegal operator `+` for `a` of type `int delegate()`
-fail_compilation/fail10534.d(28): Error: illegal operator `+` for `b` of type `int delegate()`
-fail_compilation/fail10534.d(29): Error: illegal operator `-` for `a` of type `int delegate()`
-fail_compilation/fail10534.d(29): Error: illegal operator `-` for `b` of type `int delegate()`
-fail_compilation/fail10534.d(30): Error: illegal operator `/` for `a` of type `int delegate()`
-fail_compilation/fail10534.d(30): Error: illegal operator `/` for `b` of type `int delegate()`
-fail_compilation/fail10534.d(31): Error: illegal operator `*` for `a` of type `int delegate()`
-fail_compilation/fail10534.d(31): Error: illegal operator `*` for `b` of type `int delegate()`
-fail_compilation/fail10534.d(36): Error: illegal operator `+` for `a` of type `int function()`
-fail_compilation/fail10534.d(36): Error: illegal operator `+` for `b` of type `int function()`
-fail_compilation/fail10534.d(37): Error: illegal operator `-` for `a` of type `int function()`
-fail_compilation/fail10534.d(37): Error: illegal operator `-` for `b` of type `int function()`
-fail_compilation/fail10534.d(38): Error: illegal operator `/` for `a` of type `int function()`
-fail_compilation/fail10534.d(38): Error: illegal operator `/` for `b` of type `int function()`
-fail_compilation/fail10534.d(39): Error: illegal operator `*` for `a` of type `int function()`
-fail_compilation/fail10534.d(39): Error: illegal operator `*` for `b` of type `int function()`
+fail_compilation/fail10534.d(24): Error: illegal operator `+` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(24): Error: illegal operator `+` for `b` of type `int delegate()`
+fail_compilation/fail10534.d(25): Error: illegal operator `-` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(25): Error: illegal operator `-` for `b` of type `int delegate()`
+fail_compilation/fail10534.d(26): Error: illegal operator `/` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(27): Error: illegal operator `*` for `a` of type `int delegate()`
+fail_compilation/fail10534.d(32): Error: illegal operator `+` for `a` of type `int function()`
+fail_compilation/fail10534.d(32): Error: illegal operator `+` for `b` of type `int function()`
+fail_compilation/fail10534.d(33): Error: illegal operator `-` for `a` of type `int function()`
+fail_compilation/fail10534.d(33): Error: illegal operator `-` for `b` of type `int function()`
+fail_compilation/fail10534.d(34): Error: illegal operator `/` for `a` of type `int function()`
+fail_compilation/fail10534.d(35): Error: illegal operator `*` for `a` of type `int function()`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail11445.d b/gcc/testsuite/gdc.test/fail_compilation/fail11445.d
index 3295b24..e4105b8 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail11445.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail11445.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail11445.d(11): Error: incompatible types for `(a) + (b)`: both operands are of type `double[string]`
+fail_compilation/fail11445.d(11): Error: illegal operator `+` for `a` of type `double[string]`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail13902.d b/gcc/testsuite/gdc.test/fail_compilation/fail13902.d
index 9c82b2c..a1c1bab 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail13902.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail13902.d
@@ -14,7 +14,7 @@ fail_compilation/fail13902.d(33): Error: returning `&s1.v` escapes a reference t
fail_compilation/fail13902.d(38): Error: returning `& sa1` escapes a reference to local variable `sa1`
fail_compilation/fail13902.d(39): Error: returning `& sa2` escapes a reference to local variable `sa2`
fail_compilation/fail13902.d(40): Error: returning `& x` escapes a reference to local variable `x`
-fail_compilation/fail13902.d(41): Error: returning `(& x+4)` escapes a reference to local variable `x`
+fail_compilation/fail13902.d(41): Error: returning `(& x + 4)` escapes a reference to local variable `x`
fail_compilation/fail13902.d(42): Error: returning `& x + cast(long)x * 4L` escapes a reference to local variable `x`
fail_compilation/fail13902.d(45): Error: returning `& y` escapes a reference to local variable `y`
---
@@ -59,7 +59,7 @@ fail_compilation/fail13902.d(76): Error: returning `&s1.v` escapes a reference t
fail_compilation/fail13902.d(81): Error: returning `& sa1` escapes a reference to parameter `sa1`
fail_compilation/fail13902.d(82): Error: returning `& sa2` escapes a reference to parameter `sa2`
fail_compilation/fail13902.d(83): Error: returning `& x` escapes a reference to parameter `x`
-fail_compilation/fail13902.d(84): Error: returning `(& x+4)` escapes a reference to parameter `x`
+fail_compilation/fail13902.d(84): Error: returning `(& x + 4)` escapes a reference to parameter `x`
fail_compilation/fail13902.d(85): Error: returning `& x + cast(long)x * 4L` escapes a reference to parameter `x`
fail_compilation/fail13902.d(88): Error: returning `& y` escapes a reference to parameter `y`
---
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail14343.d b/gcc/testsuite/gdc.test/fail_compilation/fail14343.d
new file mode 100644
index 0000000..d644ec9
--- /dev/null
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail14343.d
@@ -0,0 +1,25 @@
+// https://issues.dlang.org/show_bug.cgi?id=14343
+/* TEST_OUTPUT:
+---
+fail_compilation/fail14343.d(21): Error: cannot modify struct instance `s` of type `S14343b` because it contains `const` or `immutable` members
+fail_compilation/fail14343.d(23): Error: cannot modify struct instance `s` of type `S14343b` because it contains `const` or `immutable` members
+---
+*/
+
+struct S14343b
+{
+ int i;
+ immutable(Object) o;
+
+ void opAddAssign(int j) { i += j; }
+ void opAssign(S14343b other) {}
+}
+
+void test14343()
+{
+ S14343b s;
+ ++s;
+ assert(s.i == 1);
+ s++;
+ assert(s.i == 2);
+}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail14486.d b/gcc/testsuite/gdc.test/fail_compilation/fail14486.d
deleted file mode 100644
index 35312454..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail14486.d
+++ /dev/null
@@ -1,79 +0,0 @@
-// REQUIRED_ARGS: -o-
-
-/*
-TEST_OUTPUT:
----
-fail_compilation/fail14486.d(47): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(47): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/fail14486.d(48): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(48): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/fail14486.d(53): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(53): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/fail14486.d(54): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(54): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/fail14486.d(59): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(59): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/fail14486.d(60): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(60): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/fail14486.d(65): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(65): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/fail14486.d(66): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(66): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/fail14486.d(71): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(71): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/fail14486.d(72): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(72): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/fail14486.d(77): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(77): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/fail14486.d(78): Error: the `delete` keyword is obsolete
-fail_compilation/fail14486.d(78): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
----
-*/
-
-class C0a { }
-class C1a { ~this() {} }
-
-class C0b { }
-class C1b { ~this() {} }
-
-struct S0a { }
-struct S1a { ~this() {} }
-
-struct S0b { }
-struct S1b { ~this() {} }
-
-void test1a() @nogc pure @safe
-{
- C0a c0; delete c0; // error
- C1a c1; delete c1; // error
-}
-
-void test1b() nothrow
-{
- C0b c0; delete c0; // no error
- C1b c1; delete c1; // error
-}
-
-void test2a() @nogc pure @safe
-{
- S0a* s0; delete s0; // error
- S1a* s1; delete s1; // error
-}
-
-void test2b() nothrow
-{
- S0b* s0; delete s0; // no error
- S1b* s1; delete s1; // error
-}
-
-void test3a() @nogc pure @safe
-{
- S0a[] a0; delete a0; // error
- S1a[] a1; delete a1; // error
-}
-
-void test3b() nothrow
-{
- S0b[] a0; delete a0; // no error
- S1b[] a1; delete a1; // error
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail17906.d b/gcc/testsuite/gdc.test/fail_compilation/fail17906.d
deleted file mode 100644
index 41f7465..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail17906.d
+++ /dev/null
@@ -1,13 +0,0 @@
-// REQUIRED_ARGS: -de
-/* TEST_OUTPUT:
----
-fail_compilation/fail17906.d(12): Error: the `delete` keyword is obsolete
-fail_compilation/fail17906.d(12): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
----
-*/
-// https://issues.dlang.org/show_bug.cgi?id=18647
-deprecated void main ()
-{
- Object o = new Object;
- delete o;
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail2361.d b/gcc/testsuite/gdc.test/fail_compilation/fail2361.d
deleted file mode 100644
index ffc12f1..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/fail2361.d
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
-TEST_OUTPUT:
----
-fail_compilation/fail2361.d(14): Error: the `delete` keyword is obsolete
-fail_compilation/fail2361.d(14): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
----
-*/
-
-class C {}
-
-void main()
-{
- immutable c = new immutable(C);
- delete c;
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail297.d b/gcc/testsuite/gdc.test/fail_compilation/fail297.d
index 5fc3bbf..3bb25dd 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail297.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail297.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail297.d(30): Error: incompatible types for `(Bar()) + (baz())`: `Bar` and `const(Bar)`
+fail_compilation/fail297.d(30): Error: operator `+` is not defined for `Bar()` of type `Bar`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail3.d b/gcc/testsuite/gdc.test/fail_compilation/fail3.d
index 5c1ea91..1c40c4f 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail3.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail3.d
@@ -1,7 +1,7 @@
/*
TEST_OUTPUT:
---
-fail_compilation/fail3.d(41): Error: incompatible types for `(a) + (b)`: both operands are of type `vec2`
+fail_compilation/fail3.d(41): Error: operator `+` is not defined for `a` of type `vec2`
---
*/
diff --git a/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d b/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
index 0db6a45..a8b53f1 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/fail_arrayop2.d
@@ -209,8 +209,6 @@ fail_compilation/fail_arrayop2.d(269): Error: array operation `"abc"[] + '\x01'`
fail_compilation/fail_arrayop2.d(272): Error: array operation `[1] * 6` without destination memory not allowed
fail_compilation/fail_arrayop2.d(275): Error: cannot take address of expression `([1] * 6)[0..2]` because it is not an lvalue
fail_compilation/fail_arrayop2.d(278): Error: can only `*` a pointer, not a `int[]`
-fail_compilation/fail_arrayop2.d(281): Error: the `delete` keyword is obsolete
-fail_compilation/fail_arrayop2.d(281): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
fail_compilation/fail_arrayop2.d(284): Error: array operation `da[] * 6` without destination memory not allowed
fail_compilation/fail_arrayop2.d(287): Error: array operation `da[] * 6` without destination memory not allowed
fail_compilation/fail_arrayop2.d(290): Error: cannot modify expression `[1] * 6` because it is not an lvalue
@@ -235,6 +233,8 @@ fail_compilation/fail_arrayop2.d(321): Error: array operation `[1] * 6` without
fail_compilation/fail_arrayop2.d(321): Error: array operation `[1] * 6` without destination memory not allowed
---
*/
+
+
// Test all expressions, which can take arrays as their operands but cannot be a part of array operation.
void test15407exp()
{
@@ -277,8 +277,8 @@ void test15407exp()
// PtrExp, *([1] * 6).ptr is also invalid -> show better diagnostic
{ auto r = *([1] * 6); }
- // DeleteExp - e1
- delete ([1] * 6);
+
+
// TypeDArray.dotExp, cannot check in ArrayLengthExp.semantic()
{ auto r = (6 * da[]).length; }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/faildeleteaa.d b/gcc/testsuite/gdc.test/fail_compilation/faildeleteaa.d
deleted file mode 100644
index ed640fb..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/faildeleteaa.d
+++ /dev/null
@@ -1,13 +0,0 @@
-/*
-TEST_OUTPUT:
----
-fail_compilation/faildeleteaa.d(12): Error: the `delete` keyword is obsolete
-fail_compilation/faildeleteaa.d(12): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
----
-*/
-
-void main()
-{
- int[int] aa = [1 : 2];
- delete aa[1];
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/hexstring.d b/gcc/testsuite/gdc.test/fail_compilation/hexstring.d
index edbb4e6..2c6191e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/hexstring.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/hexstring.d
@@ -1,21 +1,24 @@
/**
TEST_OUTPUT:
---
-fail_compilation/hexstring.d(29): Error: cannot implicitly convert expression `"123F"` of type `string` to `immutable(ubyte[])`
-fail_compilation/hexstring.d(33): Error: hex string length 1 must be a multiple of 2 to cast to `immutable(ushort[])`
-fail_compilation/hexstring.d(34): Error: hex string length 3 must be a multiple of 4 to cast to `immutable(uint[])`
-fail_compilation/hexstring.d(35): Error: hex string length 5 must be a multiple of 8 to cast to `immutable(ulong[])`
-fail_compilation/hexstring.d(36): Error: array cast from `wstring` to `immutable(ulong[])` is not supported at compile time
-fail_compilation/hexstring.d(36): perhaps remove postfix `w` from hex string
-fail_compilation/hexstring.d(37): Error: array cast from `string` to `immutable(uint[])` is not supported at compile time
-fail_compilation/hexstring.d(38): Error: array cast from `string` to `immutable(ushort[])` is not supported at compile time
-fail_compilation/hexstring.d(39): Error: array cast from `string` to `immutable(uint[])` is not supported at compile time
-fail_compilation/hexstring.d(39): perhaps remove postfix `c` from hex string
-fail_compilation/hexstring.d(40): Error: hex string with `dstring` type needs to be multiple of 4 bytes, not 5
-fail_compilation/hexstring.d(41): Error: cannot implicitly convert expression `x"11223344"d` of type `dstring` to `immutable(float[])`
-fail_compilation/hexstring.d(42): Error: cannot implicitly convert expression `x"1122"w` of type `wstring` to `immutable(ubyte[])`
-fail_compilation/hexstring.d(50): Error: array cast from `string` to `S[]` is not supported at compile time
-fail_compilation/hexstring.d(28): Error: cannot implicitly convert expression `x"123F"` of type `string` to `ubyte[]`
+fail_compilation/hexstring.d(30): Error: array cast from `string` to `ubyte[3][1]` is not supported at compile time
+fail_compilation/hexstring.d(33): Error: cannot implicitly convert expression `"123F"` of type `string` to `immutable(ubyte[])`
+fail_compilation/hexstring.d(37): Error: hex string length 1 must be a multiple of 2 to cast to `immutable(ushort[])`
+fail_compilation/hexstring.d(38): Error: hex string length 3 must be a multiple of 4 to cast to `immutable(uint[])`
+fail_compilation/hexstring.d(39): Error: hex string length 5 must be a multiple of 8 to cast to `immutable(ulong[])`
+fail_compilation/hexstring.d(40): Error: array cast from `wstring` to `immutable(ulong[])` is not supported at compile time
+fail_compilation/hexstring.d(40): perhaps remove postfix `w` from hex string
+fail_compilation/hexstring.d(41): Error: array cast from `string` to `immutable(uint[])` is not supported at compile time
+fail_compilation/hexstring.d(42): Error: array cast from `string` to `immutable(ushort[])` is not supported at compile time
+fail_compilation/hexstring.d(43): Error: array cast from `string` to `immutable(uint[])` is not supported at compile time
+fail_compilation/hexstring.d(43): perhaps remove postfix `c` from hex string
+fail_compilation/hexstring.d(44): Error: hex string with `dstring` type needs to be multiple of 4 bytes, not 5
+fail_compilation/hexstring.d(45): Error: cannot implicitly convert expression `x"11223344"d` of type `dstring` to `immutable(float[])`
+fail_compilation/hexstring.d(46): Error: cannot implicitly convert expression `x"1122"w` of type `wstring` to `immutable(ubyte[])`
+fail_compilation/hexstring.d(47): Error: array cast from `string` to `ubyte[3][1]` is not supported at compile time
+fail_compilation/hexstring.d(48): Error: array cast from `string` to `ubyte[3][1][1]` is not supported at compile time
+fail_compilation/hexstring.d(56): Error: array cast from `string` to `S[]` is not supported at compile time
+fail_compilation/hexstring.d(32): Error: cannot implicitly convert expression `x"123F"` of type `string` to `ubyte[]`
---
*/
immutable ubyte[] s0 = x"123F";
@@ -24,6 +27,7 @@ static assert(s0[1] == 0x3F);
immutable byte[] s1 = x"123F";
enum E(X) = cast(X[]) x"AABBCCDD";
static assert(E!int[0] == 0xAABBCCDD);
+immutable ubyte[3] s2 = cast(ubyte[3][1])x"FFAAFF";
ubyte[] f1 = x"123F";
immutable ubyte[] f2 = "123F";
@@ -40,6 +44,8 @@ immutable uint[] f11 = cast(immutable uint[]) x"AABBCCDD"c;
immutable uint[] f12 = x"1122334455"d;
immutable float[] f13 = x"11223344"d;
immutable ubyte[] f14 = x"1122"w;
+immutable ubyte[3][1] f16 = cast(ubyte[3][1])x"FFBBFF";
+immutable ubyte[3][1][1] f17 = cast(ubyte[3][1][1])x"FFCCFF";
// https://issues.dlang.org/show_bug.cgi?id=24832
struct S
diff --git a/gcc/testsuite/gdc.test/fail_compilation/ice11968.d b/gcc/testsuite/gdc.test/fail_compilation/ice11968.d
deleted file mode 100644
index 1d50b66..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/ice11968.d
+++ /dev/null
@@ -1,9 +0,0 @@
-/*
-TEST_OUTPUT:
-----
-fail_compilation/ice11968.d(9): Error: the `delete` keyword is obsolete
-fail_compilation/ice11968.d(9): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-----
-*/
-
-void main() { delete __FILE__ ; }
diff --git a/gcc/testsuite/gdc.test/fail_compilation/nogc1.d b/gcc/testsuite/gdc.test/fail_compilation/nogc1.d
index b2bea5b..ba6956e 100644
--- a/gcc/testsuite/gdc.test/fail_compilation/nogc1.d
+++ b/gcc/testsuite/gdc.test/fail_compilation/nogc1.d
@@ -57,23 +57,3 @@ fail_compilation/nogc1.d(55): Error: allocating with `new` causes a GC allocatio
scope Object o1 = new Object(); // no error
scope o2 = new Object(); // no error
}
-
-/***************** DeleteExp *******************/
-
-/*
-TEST_OUTPUT:
----
-fail_compilation/nogc1.d(76): Error: the `delete` keyword is obsolete
-fail_compilation/nogc1.d(76): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/nogc1.d(77): Error: the `delete` keyword is obsolete
-fail_compilation/nogc1.d(77): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
-fail_compilation/nogc1.d(78): Error: the `delete` keyword is obsolete
-fail_compilation/nogc1.d(78): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
----
-*/
-@nogc void testDelete(int* p, Object o, S1* s)
-{
- delete p;
- delete o;
- delete s;
-}
diff --git a/gcc/testsuite/gdc.test/fail_compilation/test16195.d b/gcc/testsuite/gdc.test/fail_compilation/test16195.d
deleted file mode 100644
index 018ab0d..0000000
--- a/gcc/testsuite/gdc.test/fail_compilation/test16195.d
+++ /dev/null
@@ -1,15 +0,0 @@
-/*
- * TEST_OUTPUT:
----
-fail_compilation/test16195.d(14): Error: the `delete` keyword is obsolete
-fail_compilation/test16195.d(14): use `object.destroy()` (and `core.memory.GC.free()` if applicable) instead
----
- */
-
-
-// https://issues.dlang.org/show_bug.cgi?id=16195
-
-@safe pure nothrow @nogc void test(int* p)
-{
- delete p;
-}
diff --git a/gcc/testsuite/gdc.test/runnable/funclit.d b/gcc/testsuite/gdc.test/runnable/funclit.d
index 253df8f..bce4e9a 100644
--- a/gcc/testsuite/gdc.test/runnable/funclit.d
+++ b/gcc/testsuite/gdc.test/runnable/funclit.d
@@ -384,16 +384,6 @@ void test6714()
}
/***************************************************/
-// https://issues.dlang.org/show_bug.cgi?id=7193
-
-void test7193()
-{
- static assert(!__traits(compiles, {
- delete a => a;
- }));
-}
-
-/***************************************************/
// https://issues.dlang.org/show_bug.cgi?id=7207
// on CastExp
@@ -1331,7 +1321,6 @@ int main()
test11();
test3235();
test6714();
- test7193();
test7202();
test7288();
test7499();
diff --git a/gcc/testsuite/gdc.test/runnable/newdel.d b/gcc/testsuite/gdc.test/runnable/newdel.d
index 8ba7a0c..8888c75 100644
--- a/gcc/testsuite/gdc.test/runnable/newdel.d
+++ b/gcc/testsuite/gdc.test/runnable/newdel.d
@@ -42,10 +42,29 @@ void test1()
}
/*********************************************/
+// delete is no longer a keyword and can be used as an identifier
+
+enum E
+{
+ add, delete
+}
+
+E delete()
+{
+ return E.delete;
+}
+
+void test2()
+{
+ assert(delete() == E.delete);
+}
+
+/*********************************************/
int main()
{
test1();
+ test2();
printf("Success\n");
return 0;
diff --git a/gcc/testsuite/gdc.test/runnable/opover.d b/gcc/testsuite/gdc.test/runnable/opover.d
index 253a7a5..4e34e52 100644
--- a/gcc/testsuite/gdc.test/runnable/opover.d
+++ b/gcc/testsuite/gdc.test/runnable/opover.d
@@ -2,29 +2,13 @@
RUN_OUTPUT:
---
i = 1
-Writer.opShl(char[])
-BinaryWriter.opShl(int)
-a + 1 = 2
-1 + a = 2
-a + b = 3
-b + a = 3
i = 64
12
534
-A::opShl(int 4)
-4A::opShl(char[])
- A::opShl(int 12)
-12A::opShl(char[])
-
-B::opShl_r(A)
Success
---
*/
-// Test operator overloading
-// Ignore deprecation warnings for D1 style operator overloading
-// TRANSFORM_OUTPUT: remove_lines("Deprecation: `op")
-
import core.stdc.stdio;
/**************************************/
@@ -996,20 +980,11 @@ struct S14343b
void test14343()
{
- {
- S14343a s, t;
+ S14343a s, t;
- t = s; // OK
- ++s; // OK
- s++; // OK <- Error: cannot modify struct s S with immutable members
- }
- {
- S14343b s;
- ++s;
- assert(s.i == 1);
- s++;
- assert(s.i == 2);
- }
+ t = s; // OK
+ ++s; // OK
+ s++; // OK <- Error: cannot modify struct s S with immutable members
}
/**************************************/
@@ -1081,20 +1056,13 @@ void test20475()
/**************************************/
int main()
{
- test1();
- test2();
- test3();
test4();
test5();
test6();
test7();
- test8();
test9();
- test10();
test11();
test12();
- test13();
- test14();
test15();
test1547();
test4953a();
diff --git a/gcc/testsuite/gdc.test/runnable/xtest46.d b/gcc/testsuite/gdc.test/runnable/xtest46.d
index cbcbd1a..5893560 100644
--- a/gcc/testsuite/gdc.test/runnable/xtest46.d
+++ b/gcc/testsuite/gdc.test/runnable/xtest46.d
@@ -4091,30 +4091,30 @@ void test4258() {
struct Foo4258 {
// binary ++/--
- int opPostInc()() if (false) { return 0; }
+ int opUnary(string op)() if (false) { return 0; }
// binary 1st
- int opAdd(R)(R rhs) if (false) { return 0; }
- int opAdd_r(R)(R rhs) if (false) { return 0; }
+ int opBinary(string op, R)(R rhs) if (false) { return 0; }
+ int opBinaryRight(string op, R)(R rhs) if (false) { return 0; }
// compare
- int opCmp(R)(R rhs) if (false) { return 0; }
+ int opCmp(R)(const(R) rhs) const if (false) { return 0; }
// binary-op assign
- int opAddAssign(R)(R rhs) if (false) { return 0; }
+ int opOpAssign(string op, R)(R rhs) if (false) { return 0; }
}
struct Bar4258 {
// binary commutive 1
- int opAdd_r(R)(R rhs) if (false) { return 0; }
+ int opBinary(string op, R)(R rhs) if (false) { return 0; }
// binary-op assign
int opOpAssign(string op, R)(R rhs) if (false) { return 0; }
}
struct Baz4258 {
// binary commutive 2
- int opAdd(R)(R rhs) if (false) { return 0; }
+ int opBinaryRight(string op, R)(R rhs) if (false) { return 0; }
}
-static assert(!is(typeof(Foo4258.init++)));
+static assert(!is(typeof(++Foo4258.init)));
static assert(!is(typeof(Foo4258.init + 1)));
static assert(!is(typeof(1 + Foo4258.init)));
static assert(!is(typeof(Foo4258.init < Foo4258.init)));
diff --git a/libphobos/libdruntime/MERGE b/libphobos/libdruntime/MERGE
index 4172630..a91f40b 100644
--- a/libphobos/libdruntime/MERGE
+++ b/libphobos/libdruntime/MERGE
@@ -1,4 +1,4 @@
-d1157134103a209d36d6ee9c1df1d61d5929ec6d
+b7e3b3b61711bf6c6cad27c7b5b73df0e570c215
The first line of this file holds the git revision number of the last
merge done from the dlang/dmd repository.
diff --git a/libphobos/libdruntime/Makefile.am b/libphobos/libdruntime/Makefile.am
index efdae4c..595e3f9 100644
--- a/libphobos/libdruntime/Makefile.am
+++ b/libphobos/libdruntime/Makefile.am
@@ -361,13 +361,14 @@ DRUNTIME_DSOURCES_SOLARIS = core/sys/solaris/dlfcn.d \
DRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \
core/sys/windows/aclapi.d core/sys/windows/aclui.d \
core/sys/windows/basetsd.d core/sys/windows/basetyps.d \
- core/sys/windows/cderr.d core/sys/windows/cguid.d \
- core/sys/windows/com.d core/sys/windows/comcat.d \
- core/sys/windows/commctrl.d core/sys/windows/commdlg.d \
- core/sys/windows/core.d core/sys/windows/cpl.d \
- core/sys/windows/cplext.d core/sys/windows/custcntl.d \
- core/sys/windows/dbghelp.d core/sys/windows/dbghelp_types.d \
- core/sys/windows/dbt.d core/sys/windows/dde.d core/sys/windows/ddeml.d \
+ core/sys/windows/bcrypt.d core/sys/windows/cderr.d \
+ core/sys/windows/cguid.d core/sys/windows/com.d \
+ core/sys/windows/comcat.d core/sys/windows/commctrl.d \
+ core/sys/windows/commdlg.d core/sys/windows/core.d \
+ core/sys/windows/cpl.d core/sys/windows/cplext.d \
+ core/sys/windows/custcntl.d core/sys/windows/dbghelp.d \
+ core/sys/windows/dbghelp_types.d core/sys/windows/dbt.d \
+ core/sys/windows/dde.d core/sys/windows/ddeml.d \
core/sys/windows/dhcpcsdk.d core/sys/windows/dlgs.d \
core/sys/windows/dll.d core/sys/windows/docobj.d \
core/sys/windows/errorrep.d core/sys/windows/exdisp.d \
diff --git a/libphobos/libdruntime/Makefile.in b/libphobos/libdruntime/Makefile.in
index 1227c59..4832fd1 100644
--- a/libphobos/libdruntime/Makefile.in
+++ b/libphobos/libdruntime/Makefile.in
@@ -392,88 +392,88 @@ am__objects_19 = core/sys/linux/config.lo core/sys/linux/dlfcn.lo \
am__objects_21 = core/sys/windows/accctrl.lo \
core/sys/windows/aclapi.lo core/sys/windows/aclui.lo \
core/sys/windows/basetsd.lo core/sys/windows/basetyps.lo \
- core/sys/windows/cderr.lo core/sys/windows/cguid.lo \
- core/sys/windows/com.lo core/sys/windows/comcat.lo \
- core/sys/windows/commctrl.lo core/sys/windows/commdlg.lo \
- core/sys/windows/core.lo core/sys/windows/cpl.lo \
- core/sys/windows/cplext.lo core/sys/windows/custcntl.lo \
- core/sys/windows/dbghelp.lo core/sys/windows/dbghelp_types.lo \
- core/sys/windows/dbt.lo core/sys/windows/dde.lo \
- core/sys/windows/ddeml.lo core/sys/windows/dhcpcsdk.lo \
- core/sys/windows/dlgs.lo core/sys/windows/dll.lo \
- core/sys/windows/docobj.lo core/sys/windows/errorrep.lo \
- core/sys/windows/exdisp.lo core/sys/windows/exdispid.lo \
- core/sys/windows/httpext.lo core/sys/windows/idispids.lo \
- core/sys/windows/imagehlp.lo core/sys/windows/imm.lo \
- core/sys/windows/intshcut.lo core/sys/windows/ipexport.lo \
- core/sys/windows/iphlpapi.lo core/sys/windows/ipifcons.lo \
- core/sys/windows/iprtrmib.lo core/sys/windows/iptypes.lo \
- core/sys/windows/isguids.lo core/sys/windows/lm.lo \
- core/sys/windows/lmaccess.lo core/sys/windows/lmalert.lo \
- core/sys/windows/lmapibuf.lo core/sys/windows/lmat.lo \
- core/sys/windows/lmaudit.lo core/sys/windows/lmbrowsr.lo \
- core/sys/windows/lmchdev.lo core/sys/windows/lmconfig.lo \
- core/sys/windows/lmcons.lo core/sys/windows/lmerr.lo \
- core/sys/windows/lmerrlog.lo core/sys/windows/lmmsg.lo \
- core/sys/windows/lmremutl.lo core/sys/windows/lmrepl.lo \
- core/sys/windows/lmserver.lo core/sys/windows/lmshare.lo \
- core/sys/windows/lmsname.lo core/sys/windows/lmstats.lo \
- core/sys/windows/lmsvc.lo core/sys/windows/lmuse.lo \
- core/sys/windows/lmuseflg.lo core/sys/windows/lmwksta.lo \
- core/sys/windows/lzexpand.lo core/sys/windows/mapi.lo \
- core/sys/windows/mciavi.lo core/sys/windows/mcx.lo \
- core/sys/windows/mgmtapi.lo core/sys/windows/mmsystem.lo \
- core/sys/windows/msacm.lo core/sys/windows/mshtml.lo \
- core/sys/windows/mswsock.lo core/sys/windows/nb30.lo \
- core/sys/windows/nddeapi.lo core/sys/windows/nspapi.lo \
- core/sys/windows/ntdef.lo core/sys/windows/ntdll.lo \
- core/sys/windows/ntldap.lo core/sys/windows/ntsecapi.lo \
- core/sys/windows/ntsecpkg.lo core/sys/windows/oaidl.lo \
- core/sys/windows/objbase.lo core/sys/windows/objfwd.lo \
- core/sys/windows/objidl.lo core/sys/windows/objsafe.lo \
- core/sys/windows/ocidl.lo core/sys/windows/odbcinst.lo \
- core/sys/windows/ole.lo core/sys/windows/ole2.lo \
- core/sys/windows/ole2ver.lo core/sys/windows/oleacc.lo \
- core/sys/windows/oleauto.lo core/sys/windows/olectl.lo \
- core/sys/windows/olectlid.lo core/sys/windows/oledlg.lo \
- core/sys/windows/oleidl.lo core/sys/windows/pbt.lo \
- core/sys/windows/powrprof.lo core/sys/windows/prsht.lo \
- core/sys/windows/psapi.lo core/sys/windows/rapi.lo \
- core/sys/windows/ras.lo core/sys/windows/rasdlg.lo \
- core/sys/windows/raserror.lo core/sys/windows/rassapi.lo \
- core/sys/windows/reason.lo core/sys/windows/regstr.lo \
- core/sys/windows/richedit.lo core/sys/windows/richole.lo \
- core/sys/windows/rpc.lo core/sys/windows/rpcdce.lo \
- core/sys/windows/rpcdce2.lo core/sys/windows/rpcdcep.lo \
- core/sys/windows/rpcndr.lo core/sys/windows/rpcnsi.lo \
- core/sys/windows/rpcnsip.lo core/sys/windows/rpcnterr.lo \
- core/sys/windows/schannel.lo core/sys/windows/sdkddkver.lo \
- core/sys/windows/secext.lo core/sys/windows/security.lo \
- core/sys/windows/servprov.lo core/sys/windows/setupapi.lo \
- core/sys/windows/shellapi.lo core/sys/windows/shldisp.lo \
- core/sys/windows/shlguid.lo core/sys/windows/shlobj.lo \
- core/sys/windows/shlwapi.lo core/sys/windows/snmp.lo \
- core/sys/windows/sql.lo core/sys/windows/sqlext.lo \
- core/sys/windows/sqltypes.lo core/sys/windows/sqlucode.lo \
- core/sys/windows/sspi.lo core/sys/windows/stacktrace.lo \
- core/sys/windows/stat.lo core/sys/windows/stdc/malloc.lo \
- core/sys/windows/stdc/time.lo core/sys/windows/subauth.lo \
- core/sys/windows/threadaux.lo core/sys/windows/tlhelp32.lo \
- core/sys/windows/tmschema.lo core/sys/windows/unknwn.lo \
- core/sys/windows/uuid.lo core/sys/windows/vfw.lo \
- core/sys/windows/w32api.lo core/sys/windows/winbase.lo \
- core/sys/windows/winber.lo core/sys/windows/wincon.lo \
- core/sys/windows/wincrypt.lo core/sys/windows/windef.lo \
- core/sys/windows/windows.lo core/sys/windows/winerror.lo \
- core/sys/windows/wingdi.lo core/sys/windows/winhttp.lo \
- core/sys/windows/wininet.lo core/sys/windows/winioctl.lo \
- core/sys/windows/winldap.lo core/sys/windows/winnetwk.lo \
- core/sys/windows/winnls.lo core/sys/windows/winnt.lo \
- core/sys/windows/winperf.lo core/sys/windows/winreg.lo \
- core/sys/windows/winsock2.lo core/sys/windows/winspool.lo \
- core/sys/windows/winsvc.lo core/sys/windows/winuser.lo \
- core/sys/windows/winver.lo core/sys/windows/wtsapi32.lo \
- core/sys/windows/wtypes.lo
+ core/sys/windows/bcrypt.lo core/sys/windows/cderr.lo \
+ core/sys/windows/cguid.lo core/sys/windows/com.lo \
+ core/sys/windows/comcat.lo core/sys/windows/commctrl.lo \
+ core/sys/windows/commdlg.lo core/sys/windows/core.lo \
+ core/sys/windows/cpl.lo core/sys/windows/cplext.lo \
+ core/sys/windows/custcntl.lo core/sys/windows/dbghelp.lo \
+ core/sys/windows/dbghelp_types.lo core/sys/windows/dbt.lo \
+ core/sys/windows/dde.lo core/sys/windows/ddeml.lo \
+ core/sys/windows/dhcpcsdk.lo core/sys/windows/dlgs.lo \
+ core/sys/windows/dll.lo core/sys/windows/docobj.lo \
+ core/sys/windows/errorrep.lo core/sys/windows/exdisp.lo \
+ core/sys/windows/exdispid.lo core/sys/windows/httpext.lo \
+ core/sys/windows/idispids.lo core/sys/windows/imagehlp.lo \
+ core/sys/windows/imm.lo core/sys/windows/intshcut.lo \
+ core/sys/windows/ipexport.lo core/sys/windows/iphlpapi.lo \
+ core/sys/windows/ipifcons.lo core/sys/windows/iprtrmib.lo \
+ core/sys/windows/iptypes.lo core/sys/windows/isguids.lo \
+ core/sys/windows/lm.lo core/sys/windows/lmaccess.lo \
+ core/sys/windows/lmalert.lo core/sys/windows/lmapibuf.lo \
+ core/sys/windows/lmat.lo core/sys/windows/lmaudit.lo \
+ core/sys/windows/lmbrowsr.lo core/sys/windows/lmchdev.lo \
+ core/sys/windows/lmconfig.lo core/sys/windows/lmcons.lo \
+ core/sys/windows/lmerr.lo core/sys/windows/lmerrlog.lo \
+ core/sys/windows/lmmsg.lo core/sys/windows/lmremutl.lo \
+ core/sys/windows/lmrepl.lo core/sys/windows/lmserver.lo \
+ core/sys/windows/lmshare.lo core/sys/windows/lmsname.lo \
+ core/sys/windows/lmstats.lo core/sys/windows/lmsvc.lo \
+ core/sys/windows/lmuse.lo core/sys/windows/lmuseflg.lo \
+ core/sys/windows/lmwksta.lo core/sys/windows/lzexpand.lo \
+ core/sys/windows/mapi.lo core/sys/windows/mciavi.lo \
+ core/sys/windows/mcx.lo core/sys/windows/mgmtapi.lo \
+ core/sys/windows/mmsystem.lo core/sys/windows/msacm.lo \
+ core/sys/windows/mshtml.lo core/sys/windows/mswsock.lo \
+ core/sys/windows/nb30.lo core/sys/windows/nddeapi.lo \
+ core/sys/windows/nspapi.lo core/sys/windows/ntdef.lo \
+ core/sys/windows/ntdll.lo core/sys/windows/ntldap.lo \
+ core/sys/windows/ntsecapi.lo core/sys/windows/ntsecpkg.lo \
+ core/sys/windows/oaidl.lo core/sys/windows/objbase.lo \
+ core/sys/windows/objfwd.lo core/sys/windows/objidl.lo \
+ core/sys/windows/objsafe.lo core/sys/windows/ocidl.lo \
+ core/sys/windows/odbcinst.lo core/sys/windows/ole.lo \
+ core/sys/windows/ole2.lo core/sys/windows/ole2ver.lo \
+ core/sys/windows/oleacc.lo core/sys/windows/oleauto.lo \
+ core/sys/windows/olectl.lo core/sys/windows/olectlid.lo \
+ core/sys/windows/oledlg.lo core/sys/windows/oleidl.lo \
+ core/sys/windows/pbt.lo core/sys/windows/powrprof.lo \
+ core/sys/windows/prsht.lo core/sys/windows/psapi.lo \
+ core/sys/windows/rapi.lo core/sys/windows/ras.lo \
+ core/sys/windows/rasdlg.lo core/sys/windows/raserror.lo \
+ core/sys/windows/rassapi.lo core/sys/windows/reason.lo \
+ core/sys/windows/regstr.lo core/sys/windows/richedit.lo \
+ core/sys/windows/richole.lo core/sys/windows/rpc.lo \
+ core/sys/windows/rpcdce.lo core/sys/windows/rpcdce2.lo \
+ core/sys/windows/rpcdcep.lo core/sys/windows/rpcndr.lo \
+ core/sys/windows/rpcnsi.lo core/sys/windows/rpcnsip.lo \
+ core/sys/windows/rpcnterr.lo core/sys/windows/schannel.lo \
+ core/sys/windows/sdkddkver.lo core/sys/windows/secext.lo \
+ core/sys/windows/security.lo core/sys/windows/servprov.lo \
+ core/sys/windows/setupapi.lo core/sys/windows/shellapi.lo \
+ core/sys/windows/shldisp.lo core/sys/windows/shlguid.lo \
+ core/sys/windows/shlobj.lo core/sys/windows/shlwapi.lo \
+ core/sys/windows/snmp.lo core/sys/windows/sql.lo \
+ core/sys/windows/sqlext.lo core/sys/windows/sqltypes.lo \
+ core/sys/windows/sqlucode.lo core/sys/windows/sspi.lo \
+ core/sys/windows/stacktrace.lo core/sys/windows/stat.lo \
+ core/sys/windows/stdc/malloc.lo core/sys/windows/stdc/time.lo \
+ core/sys/windows/subauth.lo core/sys/windows/threadaux.lo \
+ core/sys/windows/tlhelp32.lo core/sys/windows/tmschema.lo \
+ core/sys/windows/unknwn.lo core/sys/windows/uuid.lo \
+ core/sys/windows/vfw.lo core/sys/windows/w32api.lo \
+ core/sys/windows/winbase.lo core/sys/windows/winber.lo \
+ core/sys/windows/wincon.lo core/sys/windows/wincrypt.lo \
+ core/sys/windows/windef.lo core/sys/windows/windows.lo \
+ core/sys/windows/winerror.lo core/sys/windows/wingdi.lo \
+ core/sys/windows/winhttp.lo core/sys/windows/wininet.lo \
+ core/sys/windows/winioctl.lo core/sys/windows/winldap.lo \
+ core/sys/windows/winnetwk.lo core/sys/windows/winnls.lo \
+ core/sys/windows/winnt.lo core/sys/windows/winperf.lo \
+ core/sys/windows/winreg.lo core/sys/windows/winsock2.lo \
+ core/sys/windows/winspool.lo core/sys/windows/winsvc.lo \
+ core/sys/windows/winuser.lo core/sys/windows/winver.lo \
+ core/sys/windows/wtsapi32.lo core/sys/windows/wtypes.lo
@DRUNTIME_OS_MINGW_TRUE@am__objects_22 = $(am__objects_21) \
@DRUNTIME_OS_MINGW_TRUE@ config/mingw/libgdruntime_la-msvc.lo
am__objects_23 = core/sys/solaris/dlfcn.lo core/sys/solaris/elf.lo \
@@ -1041,13 +1041,14 @@ DRUNTIME_DSOURCES_SOLARIS = core/sys/solaris/dlfcn.d \
DRUNTIME_DSOURCES_WINDOWS = core/sys/windows/accctrl.d \
core/sys/windows/aclapi.d core/sys/windows/aclui.d \
core/sys/windows/basetsd.d core/sys/windows/basetyps.d \
- core/sys/windows/cderr.d core/sys/windows/cguid.d \
- core/sys/windows/com.d core/sys/windows/comcat.d \
- core/sys/windows/commctrl.d core/sys/windows/commdlg.d \
- core/sys/windows/core.d core/sys/windows/cpl.d \
- core/sys/windows/cplext.d core/sys/windows/custcntl.d \
- core/sys/windows/dbghelp.d core/sys/windows/dbghelp_types.d \
- core/sys/windows/dbt.d core/sys/windows/dde.d core/sys/windows/ddeml.d \
+ core/sys/windows/bcrypt.d core/sys/windows/cderr.d \
+ core/sys/windows/cguid.d core/sys/windows/com.d \
+ core/sys/windows/comcat.d core/sys/windows/commctrl.d \
+ core/sys/windows/commdlg.d core/sys/windows/core.d \
+ core/sys/windows/cpl.d core/sys/windows/cplext.d \
+ core/sys/windows/custcntl.d core/sys/windows/dbghelp.d \
+ core/sys/windows/dbghelp_types.d core/sys/windows/dbt.d \
+ core/sys/windows/dde.d core/sys/windows/ddeml.d \
core/sys/windows/dhcpcsdk.d core/sys/windows/dlgs.d \
core/sys/windows/dll.d core/sys/windows/docobj.d \
core/sys/windows/errorrep.d core/sys/windows/exdisp.d \
@@ -1767,6 +1768,7 @@ core/sys/windows/aclapi.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/aclui.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/basetsd.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/basetyps.lo: core/sys/windows/$(am__dirstamp)
+core/sys/windows/bcrypt.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/cderr.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/cguid.lo: core/sys/windows/$(am__dirstamp)
core/sys/windows/com.lo: core/sys/windows/$(am__dirstamp)
diff --git a/libphobos/libdruntime/core/internal/abort.d b/libphobos/libdruntime/core/internal/abort.d
index 6942f7e..c0adde9 100644
--- a/libphobos/libdruntime/core/internal/abort.d
+++ b/libphobos/libdruntime/core/internal/abort.d
@@ -6,7 +6,7 @@ module core.internal.abort;
*/
void abort(scope string msg, scope string filename = __FILE__, size_t line = __LINE__) @nogc nothrow @safe
{
- import core.stdc.stdlib: c_abort = abort;
+ import core.stdc.stdlib : c_abort = abort;
// use available OS system calls to print the message to stderr
version (Posix)
{
diff --git a/libphobos/libdruntime/core/internal/array/casting.d b/libphobos/libdruntime/core/internal/array/casting.d
index 4366da8..54e7463 100644
--- a/libphobos/libdruntime/core/internal/array/casting.d
+++ b/libphobos/libdruntime/core/internal/array/casting.d
@@ -136,7 +136,7 @@ TTo[] __ArrayCast(TFrom, TTo)(return scope TFrom[] from) @nogc pure @trusted
if (msg != expected)
{
- import core.stdc.stdio;
+ import core.stdc.stdio : printf;
printf("Expected: |%.*s|\n", cast(int) expected.length, expected.ptr);
printf("Actual : |%.*s|\n", cast(int) msg.length, msg.ptr);
assert(false);
diff --git a/libphobos/libdruntime/core/internal/array/construction.d b/libphobos/libdruntime/core/internal/array/construction.d
index c5d8c79..45a1ce5 100644
--- a/libphobos/libdruntime/core/internal/array/construction.d
+++ b/libphobos/libdruntime/core/internal/array/construction.d
@@ -13,7 +13,7 @@ import core.internal.traits : Unqual;
debug(PRINTF)
{
- import core.stdc.stdio;
+ import core.stdc.stdio : printf;
}
/**
@@ -46,7 +46,6 @@ Tarr _d_arrayctor(Tarr : T[], T)(return scope Tarr to, scope Tarr from, char* ma
import core.lifetime : copyEmplace;
import core.stdc.string : memcpy;
import core.stdc.stdint : uintptr_t;
- debug(PRINTF) import core.stdc.stdio : printf;
debug(PRINTF) printf("_d_arrayctor(from = %p,%zd) size = %zd\n", from.ptr, from.length, T.sizeof);
diff --git a/libphobos/libdruntime/core/internal/array/duplication.d b/libphobos/libdruntime/core/internal/array/duplication.d
index 9df8489..b5222b3 100644
--- a/libphobos/libdruntime/core/internal/array/duplication.d
+++ b/libphobos/libdruntime/core/internal/array/duplication.d
@@ -327,7 +327,7 @@ U[] _dup(T, U)(T[] a) if (!__traits(isPOD, T))
{
if (l != 0xDEADBEEF)
{
- import core.stdc.stdio;
+ import core.stdc.stdio : fflush, printf, stdout;
printf("Unexpected value: %lld\n", l);
fflush(stdout);
assert(false);
diff --git a/libphobos/libdruntime/core/internal/array/utils.d b/libphobos/libdruntime/core/internal/array/utils.d
index 03d4144..e7a661a 100644
--- a/libphobos/libdruntime/core/internal/array/utils.d
+++ b/libphobos/libdruntime/core/internal/array/utils.d
@@ -55,7 +55,7 @@ version (D_ProfileGC)
// FIXME: use rt.tracegc.accumulator when it is accessable in the future.
version (tracegc)
} ~ "{\n" ~ q{
- import core.stdc.stdio;
+ import core.stdc.stdio : printf;
printf("%sTrace file = '%.*s' line = %d function = '%.*s' type = %.*s\n",
} ~ "\"" ~ Hook ~ "\".ptr," ~ q{
diff --git a/libphobos/libdruntime/core/internal/gc/bits.d b/libphobos/libdruntime/core/internal/gc/bits.d
index a060e65..7aeb2e2 100644
--- a/libphobos/libdruntime/core/internal/gc/bits.d
+++ b/libphobos/libdruntime/core/internal/gc/bits.d
@@ -10,9 +10,9 @@ module core.internal.gc.bits;
import core.internal.gc.os : os_mem_map, os_mem_unmap, HaveFork;
import core.bitop;
-import core.stdc.string;
-import core.stdc.stdlib;
import core.exception : onOutOfMemoryError;
+import core.stdc.stdlib : calloc, free;
+import core.stdc.string : memcpy, memset;
// use version gcbitsSingleBitOperation to disable optimizations that use
// word operands on bulk operation copyRange, setRange, clrRange, etc.
diff --git a/libphobos/libdruntime/core/internal/gc/blkcache.d b/libphobos/libdruntime/core/internal/gc/blkcache.d
index b141a69..07027f5 100644
--- a/libphobos/libdruntime/core/internal/gc/blkcache.d
+++ b/libphobos/libdruntime/core/internal/gc/blkcache.d
@@ -44,8 +44,7 @@ else
{
if (!__blkcache_storage)
{
- import core.stdc.stdlib;
- import core.stdc.string;
+ import core.stdc.stdlib : calloc;
import core.thread.threadbase;
auto tBase = ThreadBase.getThis();
if (tBase is null)
@@ -68,7 +67,7 @@ else
{
if (__blkcache_storage)
{
- import core.stdc.stdlib;
+ import core.stdc.stdlib : free;
import core.thread.threadbase;
auto tBase = ThreadBase.getThis();
if (tBase !is null)
diff --git a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
index b5d9802..4cb7b57 100644
--- a/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
+++ b/libphobos/libdruntime/core/internal/gc/impl/conservative/gc.d
@@ -15,7 +15,7 @@ module core.internal.gc.impl.conservative.gc;
//debug = PARALLEL_PRINTF; // turn on printf's
//debug = COLLECT_PRINTF; // turn on printf's
//debug = MARK_PRINTF; // turn on printf's
-//debug = PRINTF_TO_FILE; // redirect printf's ouptut to file "gcx.log"
+//debug = PRINTF_TO_FILE; // redirect printf's output to file "gcx.log"
//debug = LOGGING; // log allocations / frees
//debug = MEMSTOMP; // stomp on memory
//debug = SENTINEL; // add underrun/overrrun protection
@@ -43,7 +43,7 @@ import core.internal.spinlock;
import core.internal.gc.pooltable;
import core.internal.gc.blkcache;
-import cstdlib = core.stdc.stdlib : calloc, free, malloc, realloc;
+import cstdlib = core.stdc.stdlib;
import core.stdc.string : memcpy, memset, memmove;
import core.bitop;
import core.thread;
@@ -4800,7 +4800,7 @@ debug(PRINTF_TO_FILE)
}
len += fprintf(gcx_fh, fmt, args);
fflush(gcx_fh);
- import core.stdc.string;
+ import core.stdc.string : strlen;
hadNewline = fmt && fmt[0] && fmt[strlen(fmt) - 1] == '\n';
return len;
}
@@ -5266,8 +5266,8 @@ version (D_LP64) unittest
catch (OutOfMemoryError)
{
// ignore if the system still doesn't have enough virtual memory
- import core.stdc.stdio;
- printf("%s(%d): out-of-memory execption ignored, phys_mem = %zd",
+ import core.stdc.stdio : printf;
+ printf("%s(%d): out-of-memory exception ignored, phys_mem = %zd",
__FILE__.ptr, __LINE__, phys_mem);
}
}
@@ -5321,7 +5321,7 @@ unittest
unittest
{
import core.memory;
- import core.stdc.stdio;
+ import core.stdc.stdio : printf;
// allocate from large pool
auto o = GC.malloc(10);
diff --git a/libphobos/libdruntime/core/internal/gc/os.d b/libphobos/libdruntime/core/internal/gc/os.d
index 9142708..d5431d4 100644
--- a/libphobos/libdruntime/core/internal/gc/os.d
+++ b/libphobos/libdruntime/core/internal/gc/os.d
@@ -33,8 +33,10 @@ else version (Posix)
else version (WatchOS)
version = Darwin;
- import core.stdc.stdlib;
+ public import core.sys.posix.unistd : fork, pid_t;
+ import core.stdc.errno : ECHILD, EINTR, errno;
import core.sys.posix.sys.mman : MAP_ANON, MAP_FAILED, MAP_PRIVATE, MAP_SHARED, mmap, munmap, PROT_READ, PROT_WRITE;
+ import core.sys.posix.sys.wait : waitpid, WNOHANG;
/// Possible results for the wait_pid() function.
@@ -74,15 +76,11 @@ else version (Posix)
return ChildStatus.done;
}
- public import core.sys.posix.unistd : fork, pid_t;
- import core.stdc.errno : ECHILD, EINTR, errno;
- import core.sys.posix.sys.wait : waitpid, WNOHANG;
-
//version = GC_Use_Alloc_MMap;
}
else
{
- import core.stdc.stdlib;
+ import core.stdc.stdlib : free, malloc;
//version = GC_Use_Alloc_Malloc;
}
diff --git a/libphobos/libdruntime/core/internal/gc/pooltable.d b/libphobos/libdruntime/core/internal/gc/pooltable.d
index f9ec3d2..412ade4 100644
--- a/libphobos/libdruntime/core/internal/gc/pooltable.d
+++ b/libphobos/libdruntime/core/internal/gc/pooltable.d
@@ -7,7 +7,7 @@
*/
module core.internal.gc.pooltable;
-static import cstdlib=core.stdc.stdlib;
+static import cstdlib = core.stdc.stdlib;
struct PoolTable(Pool)
{
diff --git a/libphobos/libdruntime/core/internal/parseoptions.d b/libphobos/libdruntime/core/internal/parseoptions.d
index 2dd3ec8..bc47555 100644
--- a/libphobos/libdruntime/core/internal/parseoptions.d
+++ b/libphobos/libdruntime/core/internal/parseoptions.d
@@ -9,12 +9,10 @@
module core.internal.parseoptions;
-import core.stdc.stdlib;
-import core.stdc.stdio;
-import core.stdc.ctype;
-import core.stdc.string;
-import core.vararg;
import core.internal.traits : externDFunc, hasUDA;
+import core.stdc.ctype : isdigit, isspace;
+import core.stdc.stdio : fprintf, snprintf, sscanf, stderr;
+import core.vararg;
@nogc nothrow:
diff --git a/libphobos/libdruntime/core/internal/qsort.d b/libphobos/libdruntime/core/internal/qsort.d
index fce1067..8938a44 100644
--- a/libphobos/libdruntime/core/internal/qsort.d
+++ b/libphobos/libdruntime/core/internal/qsort.d
@@ -10,8 +10,6 @@ module core.internal.qsort;
//debug=qsort;
-import core.stdc.stdlib;
-
debug (qsort) import core.stdc.stdio : printf;
version (OSX)
@@ -150,6 +148,8 @@ else version (CRuntime_UClibc)
}
else
{
+ import core.stdc.stdlib : qsort;
+
private TypeInfo tiglobal;
extern (C) void[] _adSort(return scope void[] a, TypeInfo ti)
@@ -166,7 +166,6 @@ else
unittest
{
- debug(qsort) import core.stdc.stdio;
debug(qsort) printf("array.sort.unittest()\n");
int[] a = new int[10];
diff --git a/libphobos/libdruntime/core/internal/util/array.d b/libphobos/libdruntime/core/internal/util/array.d
index 066ee7e..1a5c41b 100644
--- a/libphobos/libdruntime/core/internal/util/array.d
+++ b/libphobos/libdruntime/core/internal/util/array.d
@@ -10,7 +10,7 @@ module core.internal.util.array;
import core.internal.string;
-import core.stdc.stdint;
+import core.stdc.stdint : uintptr_t;
// TLS storage shared for all error messages.
diff --git a/libphobos/libdruntime/core/runtime.d b/libphobos/libdruntime/core/runtime.d
index ff1df7f..d76e14a 100644
--- a/libphobos/libdruntime/core/runtime.d
+++ b/libphobos/libdruntime/core/runtime.d
@@ -29,10 +29,12 @@ version (GNU)
// It does however prevent the unittest SEGV handler to be installed,
// which is desireable as it uses backtrace directly.
private enum hasExecinfo = false;
+ version = LibBacktrace_TraceHandler;
}
else version (DRuntime_Use_Libunwind)
{
- import core.internal.backtrace.libunwind;
+ version = DefineBacktrace_using_UnwindBacktrace;
+
// This shouldn't be necessary but ensure that code doesn't get mixed
// It does however prevent the unittest SEGV handler to be installed,
// which is desireable as it uses backtrace directly.
@@ -611,7 +613,9 @@ extern (C) UnitTestResult runModuleUnitTests()
}
else static if (hasExecinfo)
{
- import core.sys.posix.signal; // segv handler
+ // segv handler
+ import core.sys.posix.signal : SA_RESETHAND, SA_SIGINFO, sigaction, sigaction_t, SIGBUS, sigfillset, siginfo_t,
+ SIGSEGV;
static extern (C) void unittestSegvHandler( int signum, siginfo_t* info, void* ptr ) nothrow
{
@@ -717,6 +721,44 @@ extern (C) UnitTestResult runModuleUnitTests()
return results;
}
+version (DefineBacktrace_using_UnwindBacktrace)
+{
+ import core.internal.backtrace.unwind;
+
+ private int backtrace(void** buffer, int maxSize) nothrow
+ {
+ if (maxSize < 0) return 0;
+
+ struct State
+ {
+ void** buffer;
+ int maxSize;
+ int entriesWritten = 0;
+ }
+
+ static extern(C) int handler(_Unwind_Context* context, void* statePtr)
+ {
+ auto state = cast(State*)statePtr;
+ if (state.entriesWritten >= state.maxSize) return _URC_END_OF_STACK;
+
+ auto instructionPtr = _Unwind_GetIP(context);
+ if (!instructionPtr) return _URC_END_OF_STACK;
+
+ state.buffer[state.entriesWritten] = cast(void*)instructionPtr;
+ ++state.entriesWritten;
+
+ return _URC_NO_REASON;
+ }
+
+ State state;
+ state.buffer = buffer;
+ state.maxSize = maxSize;
+ _Unwind_Backtrace(&handler, &state);
+
+ return state.entriesWritten;
+ }
+}
+
/**
* Get the default `Throwable.TraceInfo` implementation for the platform
*
@@ -833,14 +875,11 @@ void defaultTraceDeallocator(Throwable.TraceInfo info) nothrow
free(cast(void *)obj);
}
-version (DRuntime_Use_Libunwind)
+version (LibBacktrace_TraceHandler)
{
- import core.internal.backtrace.handler;
-
- alias DefaultTraceInfo = LibunwindHandler;
}
/// Default implementation for most POSIX systems
-else static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInfo
+else version (Posix) private class DefaultTraceInfo : Throwable.TraceInfo
{
import core.demangle;
import core.stdc.stdlib : free;
@@ -907,30 +946,100 @@ else static if (hasExecinfo) private class DefaultTraceInfo : Throwable.TraceInf
else version (Darwin) enum enableDwarf = true;
else enum enableDwarf = false;
- const framelist = backtrace_symbols( callstack.ptr, numframes );
- scope(exit) free(cast(void*) framelist);
-
- static if (enableDwarf)
+ static if (hasExecinfo)
{
- import core.internal.backtrace.dwarf;
- return traceHandlerOpApplyImpl(numframes,
- i => callstack[i],
- (i) { auto str = framelist[i][0 .. strlen(framelist[i])]; return getMangledSymbolName(str); },
- dg);
+ const framelist = backtrace_symbols( callstack.ptr, numframes );
+ scope(exit) free(cast(void*) framelist);
+
+ static if (enableDwarf)
+ {
+ import core.internal.backtrace.dwarf;
+ return traceHandlerOpApplyImpl(numframes,
+ i => callstack[i],
+ (i) { auto str = framelist[i][0 .. strlen(framelist[i])]; return getMangledSymbolName(str); },
+ dg);
+ }
+ else
+ {
+ int ret = 0;
+ for (size_t pos = 0; pos < numframes; ++pos)
+ {
+ char[4096] fixbuf = void;
+ auto buf = framelist[pos][0 .. strlen(framelist[pos])];
+ buf = fixline( buf, fixbuf );
+ ret = dg( pos, buf );
+ if ( ret )
+ break;
+ }
+ return ret;
+ }
}
else
{
- int ret = 0;
- for (size_t pos = 0; pos < numframes; ++pos)
+ // https://code.woboq.org/userspace/glibc/debug/backtracesyms.c.html
+ // The logic that glibc's backtrace use is to check for for `dli_fname`,
+ // the file name, and error if not present, then check for `dli_sname`.
+ // In case `dli_fname` is present but not `dli_sname`, the address is
+ // printed related to the file. We just print the file.
+ static const(char)[] getFrameName (const(void)* ptr)
+ {
+ import core.sys.posix.dlfcn;
+ Dl_info info = void;
+ // Note: See the module documentation about `-L--export-dynamic`
+ if (dladdr(ptr, &info))
+ {
+ // Return symbol name if possible
+ if (info.dli_sname !is null && info.dli_sname[0] != '\0')
+ return info.dli_sname[0 .. strlen(info.dli_sname)];
+
+ // Fall back to file name
+ if (info.dli_fname !is null && info.dli_fname[0] != '\0')
+ return info.dli_fname[0 .. strlen(info.dli_fname)];
+ }
+
+ // `dladdr` failed
+ return "<ERROR: Unable to retrieve function name>";
+ }
+
+ static if (enableDwarf)
{
- char[4096] fixbuf = void;
- auto buf = framelist[pos][0 .. strlen(framelist[pos])];
- buf = fixline( buf, fixbuf );
- ret = dg( pos, buf );
- if ( ret )
- break;
+ import core.internal.backtrace.dwarf;
+ return traceHandlerOpApplyImpl(numframes,
+ i => callstack[i],
+ i => getFrameName(callstack[i]),
+ dg);
+ }
+ else
+ {
+ // Poor man solution. Does not show line numbers, but does (potentially) show a backtrace of function names.
+ import core.internal.container.array;
+ Array!(const(char)[]) frameNames;
+ frameNames.length = numframes;
+ size_t startIdx;
+ foreach (idx; 0 .. numframes)
+ {
+ frameNames[idx] = getFrameName(callstack[idx]);
+
+ // NOTE: The first few frames with the current implementation are
+ // inside core.runtime and the object code, so eliminate
+ // these for readability.
+ // They also might depend on build parameters, which would make
+ // using a fixed number of frames otherwise brittle.
+ version (LDC) enum BaseExceptionFunctionName = "_d_throw_exception";
+ else enum BaseExceptionFunctionName = "_d_throwdwarf";
+ if (!startIdx && frameNames[idx] == BaseExceptionFunctionName)
+ startIdx = idx + 1;
+ }
+
+ int ret = 0;
+ foreach (idx; startIdx .. numframes)
+ {
+ ret = dg( idx, frameNames[idx] );
+ if ( ret )
+ break;
+ }
+ return ret;
}
- return ret;
}
}
@@ -948,40 +1057,43 @@ private:
void*[MAXFRAMES] callstack = void;
private:
- const(char)[] fixline( const(char)[] buf, return ref char[4096] fixbuf ) const
+ static if (hasExecinfo)
{
- size_t symBeg, symEnd;
-
- getMangledSymbolName(buf, symBeg, symEnd);
-
- enum min = (size_t a, size_t b) => a <= b ? a : b;
- if (symBeg == symEnd || symBeg >= fixbuf.length)
- {
- immutable len = min(buf.length, fixbuf.length);
- fixbuf[0 .. len] = buf[0 .. len];
- return fixbuf[0 .. len];
- }
- else
+ const(char)[] fixline( const(char)[] buf, return ref char[4096] fixbuf ) const
{
- fixbuf[0 .. symBeg] = buf[0 .. symBeg];
+ size_t symBeg, symEnd;
- auto sym = demangle(buf[symBeg .. symEnd], fixbuf[symBeg .. $], getCXXDemangler());
+ getMangledSymbolName(buf, symBeg, symEnd);
- if (sym.ptr !is fixbuf.ptr + symBeg)
+ enum min = (size_t a, size_t b) => a <= b ? a : b;
+ if (symBeg == symEnd || symBeg >= fixbuf.length)
{
- // demangle reallocated the buffer, copy the symbol to fixbuf
- immutable len = min(fixbuf.length - symBeg, sym.length);
- memmove(fixbuf.ptr + symBeg, sym.ptr, len);
- if (symBeg + len == fixbuf.length)
- return fixbuf[];
+ immutable len = min(buf.length, fixbuf.length);
+ fixbuf[0 .. len] = buf[0 .. len];
+ return fixbuf[0 .. len];
}
+ else
+ {
+ fixbuf[0 .. symBeg] = buf[0 .. symBeg];
+
+ auto sym = demangle(buf[symBeg .. symEnd], fixbuf[symBeg .. $], getCXXDemangler());
+
+ if (sym.ptr !is fixbuf.ptr + symBeg)
+ {
+ // demangle reallocated the buffer, copy the symbol to fixbuf
+ immutable len = min(fixbuf.length - symBeg, sym.length);
+ memmove(fixbuf.ptr + symBeg, sym.ptr, len);
+ if (symBeg + len == fixbuf.length)
+ return fixbuf[];
+ }
- immutable pos = symBeg + sym.length;
- assert(pos < fixbuf.length);
- immutable tail = buf.length - symEnd;
- immutable len = min(fixbuf.length - pos, tail);
- fixbuf[pos .. pos + len] = buf[symEnd .. symEnd + len];
- return fixbuf[0 .. pos + len];
+ immutable pos = symBeg + sym.length;
+ assert(pos < fixbuf.length);
+ immutable tail = buf.length - symEnd;
+ immutable len = min(fixbuf.length - pos, tail);
+ fixbuf[pos .. pos + len] = buf[symEnd .. symEnd + len];
+ return fixbuf[0 .. pos + len];
+ }
}
}
}
diff --git a/libphobos/libdruntime/core/stdc/config.d b/libphobos/libdruntime/core/stdc/config.d
index ca833ea..c95fe65 100644
--- a/libphobos/libdruntime/core/stdc/config.d
+++ b/libphobos/libdruntime/core/stdc/config.d
@@ -11,9 +11,6 @@
* Standards: ISO/IEC 9899:1999 (E)
*/
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
module core.stdc.config;
version (StdDdoc)
diff --git a/libphobos/libdruntime/core/sys/windows/bcrypt.d b/libphobos/libdruntime/core/sys/windows/bcrypt.d
new file mode 100644
index 0000000..6edf0df
--- /dev/null
+++ b/libphobos/libdruntime/core/sys/windows/bcrypt.d
@@ -0,0 +1,900 @@
+/**
+ * Cryptographic primitives
+ *
+ * Translated from MinGW-w64 Windows headers
+ *
+ * License: $(LINK2 http://www.boost.org/LICENSE_1_0.txt, Boost License 1.0)
+ * Authors: Aya Partridge
+ * Source: $(DRUNTIMESRC core/sys/windows/_bcrypt.d)
+ */
+module core.sys.windows.bcrypt;
+version (Windows):
+
+pragma(lib, "bcrypt");
+
+import core.sys.windows.ntdef, core.sys.windows.sdkddkver, core.sys.windows.winbase, core.sys.windows.windef, core.sys.windows.winnt;
+
+pragma(inline, true)
+bool BCRYPT_SUCCESS(NTSTATUS Status) @nogc nothrow pure @safe => Status >= 0;
+
+enum BCRYPT_OBJECT_ALIGNMENT = 16;
+
+enum {
+ BCRYPT_KDF_HASH = "HASH"w,
+ BCRYPT_KDF_HMAC = "HMAC"w,
+ BCRYPT_KDF_TLS_PRF = "TLS_PRF"w,
+ BCRYPT_KDF_SP80056A_CONCAT = "SP800_56A_CONCAT"w,
+}
+static if (NTDDI_VERSION >= NTDDI_WINBLUE)
+enum {
+ BCRYPT_KDF_RAW_SECRET = "TRUNCATE"w,
+}
+static if (NTDDI_VERSION >= NTDDI_WIN10_RS4)
+enum {
+ BCRYPT_KDF_HKDF = "HKDF"w,
+}
+
+enum {
+ KDF_HASH_ALGORITHM = 0x0,
+ KDF_SECRET_PREPEND = 0x1,
+ KDF_SECRET_APPEND = 0x2,
+ KDF_HMAC_KEY = 0x3,
+ KDF_TLS_PRF_LABEL = 0x4,
+ KDF_TLS_PRF_SEED = 0x5,
+ KDF_SECRET_HANDLE = 0x6,
+}
+static if (NTDDI_VERSION >= NTDDI_WIN7)
+enum {
+ KDF_TLS_PRF_PROTOCOL = 0x7,
+ KDF_ALGORITHMID = 0x8,
+ KDF_PARTYUINFO = 0x9,
+ KDF_PARTYVINFO = 0xA,
+ KDF_SUPPPUBINFO = 0xB,
+ KDF_SUPPPRIVINFO = 0xC,
+}
+static if (NTDDI_VERSION >= NTDDI_WIN8)
+enum {
+ KDF_LABEL = 0xD,
+ KDF_CONTEXT = 0xE,
+ KDF_SALT = 0xF,
+ KDF_ITERATION_COUNT = 0x10,
+ KDF_GENERIC_PARAMETER = 0x11,
+ KDF_KEYBITLENGTH = 0x12,
+}
+static if (NTDDI_VERSION >= NTDDI_WIN10_RS4)
+enum {
+ KDF_HKDF_SALT = 0x13,
+ KDF_HKDF_INFO = 0x14,
+}
+
+enum KDF_USE_SECRET_AS_HMAC_KEY_FLAG = 1;
+
+enum BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION = 1;
+
+enum {
+ BCRYPT_AUTH_MODE_CHAIN_CALLS_FLAG = 0x00000001,
+ BCRYPT_AUTH_MODE_IN_PROGRESS_FLAG = 0x00000002,
+}
+
+pragma(inline, true)
+void BCRYPT_INIT_AUTH_MODE_INFO(ref BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO _AUTH_INFO_STRUCT_) @nogc nothrow pure @safe {
+ (() @trusted => RtlZeroMemory(&_AUTH_INFO_STRUCT_, _AUTH_INFO_STRUCT_.sizeof))();
+ _AUTH_INFO_STRUCT_.cbSize = _AUTH_INFO_STRUCT_.sizeof;
+ _AUTH_INFO_STRUCT_.dwInfoVersion = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO_VERSION;
+}
+
+enum {
+ BCRYPT_OPAQUE_KEY_BLOB = "OpaqueKeyBlob"w,
+ BCRYPT_KEY_DATA_BLOB = "KeyDataBlob"w,
+}
+static if (NTDDI_VERSION >= NTDDI_WIN7)
+enum {
+ BCRYPT_AES_WRAP_KEY_BLOB = "Rfc3565KeyWrapBlob"w,
+}
+
+enum {
+ BCRYPT_ALGORITHM_NAME = "AlgorithmName"w,
+ BCRYPT_AUTH_TAG_LENGTH = "AuthTagLength"w,
+ BCRYPT_BLOCK_LENGTH = "BlockLength"w,
+ BCRYPT_BLOCK_SIZE_LIST = "BlockSizeList"w,
+ BCRYPT_CHAINING_MODE = "ChainingMode"w,
+ BCRYPT_CHAIN_MODE_CBC = "ChainingModeCBC"w,
+ BCRYPT_CHAIN_MODE_CCM = "ChainingModeCCM"w,
+ BCRYPT_CHAIN_MODE_CFB = "ChainingModeCFB"w,
+ BCRYPT_CHAIN_MODE_ECB = "ChainingModeECB"w,
+ BCRYPT_CHAIN_MODE_GCM = "ChainingModeGCM"w,
+ BCRYPT_CHAIN_MODE_NA = "ChainingModeN/A"w,
+ BCRYPT_EFFECTIVE_KEY_LENGTH = "EffectiveKeyLength"w,
+ BCRYPT_HASH_BLOCK_LENGTH = "HashBlockLength"w,
+ BCRYPT_HASH_LENGTH = "HashDigestLength"w,
+ BCRYPT_HASH_OID_LIST = "HashOIDList"w,
+ BCRYPT_INITIALIZATION_VECTOR = "IV"w,
+ BCRYPT_IS_KEYED_HASH = "IsKeyedHash"w,
+ BCRYPT_IS_REUSABLE_HASH = "IsReusableHash"w,
+ BCRYPT_KEY_LENGTH = "KeyLength"w,
+ BCRYPT_KEY_LENGTHS = "KeyLengths"w,
+ BCRYPT_KEY_OBJECT_LENGTH = "KeyObjectLength"w,
+ BCRYPT_KEY_STRENGTH = "KeyStrength"w,
+ BCRYPT_MESSAGE_BLOCK_LENGTH = "MessageBlockLength"w,
+ BCRYPT_OBJECT_LENGTH = "ObjectLength"w,
+ BCRYPT_PADDING_SCHEMES = "PaddingSchemes"w,
+ BCRYPT_PCP_PLATFORM_TYPE_PROPERTY = "PCP_PLATFORM_TYPE"w,
+ BCRYPT_PCP_PROVIDER_VERSION_PROPERTY = "PCP_PROVIDER_VERSION"w,
+ BCRYPT_PRIMITIVE_TYPE = "PrimitiveType"w,
+ BCRYPT_PROVIDER_HANDLE = "ProviderHandle"w,
+ BCRYPT_PUBLIC_KEY_LENGTH = "PublicKeyLength"w,
+ BCRYPT_SIGNATURE_LENGTH = "SignatureLength"w,
+}
+static if (NTDDI_VERSION >= NTDDI_WINBLUE)
+enum {
+ BCRYPT_MULTI_OBJECT_LENGTH = "MultiObjectLength"w,
+}
+static if (NTDDI_VERSION >= NTDDI_WIN10_RS4)
+enum {
+ BCRYPT_IS_IFX_TPM_WEAK_KEY = "IsIfxTpmWeakKey"w,
+ BCRYPT_HKDF_HASH_ALGORITHM = "HkdfHashAlgorithm"w,
+ BCRYPT_HKDF_SALT_AND_FINALIZE = "HkdfSaltAndFinalize"w,
+ BCRYPT_HKDF_PRK_AND_FINALIZE = "HkdfPrkAndFinalize"w,
+}
+static if (NTDDI_VERSION >= NTDDI_WIN11_ZN)
+enum {
+ BCRYPT_FUNCTION_NAME_STRING = "FunctionNameString"w,
+ BCRYPT_CUSTOMIZATION_STRING = "CustomizationString"w,
+}
+static if (NTDDI_VERSION >= NTDDI_WIN11_GA)
+enum {
+ BCRYPT_CHAIN_MODE_KWP = "ChainingModeKWP"w,
+}
+
+enum {
+ BCRYPT_SUPPORTED_PAD_ROUTER = 0x00000001,
+ BCRYPT_SUPPORTED_PAD_PKCS1_ENC = 0x00000002,
+ BCRYPT_SUPPORTED_PAD_PKCS1_SIG = 0x00000004,
+ BCRYPT_SUPPORTED_PAD_OAEP = 0x00000008,
+ BCRYPT_SUPPORTED_PAD_PSS = 0x00000010,
+}
+
+enum BCRYPT_PROV_DISPATCH = 0x00000001;
+
+enum BCRYPT_BLOCK_PADDING = 0x00000001;
+
+static if (NTDDI_VERSION >= NTDDI_WIN10_CO)
+enum BCRYPT_GENERATE_IV = 0x00000020;
+
+enum {
+ BCRYPT_PAD_NONE = 0x00000001,
+ BCRYPT_PAD_PKCS1 = 0x00000002,
+ BCRYPT_PAD_OAEP = 0x00000004,
+ BCRYPT_PAD_PSS = 0x00000008,
+}
+static if (NTDDI_VERSION >= NTDDI_WINBLUE)
+enum {
+ BCRYPT_PAD_PKCS1_OPTIONAL_HASH_OID = 0x00000010,
+}
+
+enum BCRYPTBUFFER_VERSION = 0;
+
+struct BCRYPT_KEY_LENGTHS_STRUCT {
+ ULONG dwMinLength;
+ ULONG dwMaxLength;
+ ULONG dwIncrement;
+}
+
+alias BCRYPT_AUTH_TAG_LENGTHS_STRUCT = BCRYPT_KEY_LENGTHS_STRUCT;
+
+struct BCRYPT_OID {
+ ULONG cbOID;
+ PUCHAR pbOID;
+}
+
+struct BCRYPT_OID_LIST {
+ ULONG dwOIDCount;
+ BCRYPT_OID* pOIDs;
+}
+
+struct BCRYPT_PKCS1_PADDING_INFO {
+ LPCWSTR pszAlgId;
+}
+
+struct BCRYPT_PSS_PADDING_INFO {
+ LPCWSTR pszAlgId;
+ ULONG cbSalt;
+}
+
+struct BCRYPT_OAEP_PADDING_INFO {
+ LPCWSTR pszAlgId;
+ PUCHAR pbLabel;
+ ULONG cbLabel;
+}
+
+struct BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO {
+ ULONG cbSize;
+ ULONG dwInfoVersion;
+ PUCHAR pbNonce;
+ ULONG cbNonce;
+ PUCHAR pbAuthData;
+ ULONG cbAuthData;
+ PUCHAR pbTag;
+ ULONG cbTag;
+ PUCHAR pbMacContext;
+ ULONG cbMacContext;
+ ULONG cbAAD;
+ ULONGLONG cbData;
+ ULONG dwFlags;
+}
+alias PBCRYPT_AUTHENTICATED_CIPHER_MODE_INFO = BCRYPT_AUTHENTICATED_CIPHER_MODE_INFO*;
+
+struct BCryptBuffer {
+ ULONG cbBuffer;
+ ULONG BufferType;
+ PVOID pvBuffer;
+}
+alias PBCryptBuffer = BCryptBuffer*;
+
+struct BCryptBufferDesc {
+ ULONG ulVersion;
+ ULONG cBuffers;
+ PBCryptBuffer pBuffers;
+}
+alias PBCryptBufferDesc = BCryptBufferDesc*;
+
+enum {
+ BCRYPT_PUBLIC_KEY_BLOB = "PUBLICBLOB"w,
+ BCRYPT_PRIVATE_KEY_BLOB = "PRIVATEBLOB"w,
+}
+
+enum {
+ BCRYPT_RSAPUBLIC_BLOB = "RSAPUBLICBLOB"w,
+ BCRYPT_RSAPRIVATE_BLOB = "RSAPRIVATEBLOB"w,
+ LEGACY_RSAPUBLIC_BLOB = "CAPIPUBLICBLOB"w,
+ LEGACY_RSAPRIVATE_BLOB = "CAPIPRIVATEBLOB"w,
+}
+
+enum {
+ BCRYPT_RSAPUBLIC_MAGIC = 0x31415352,
+ BCRYPT_RSAPRIVATE_MAGIC = 0x32415352,
+}
+
+enum BCRYPT_RSAFULLPRIVATE_BLOB = "RSAFULLPRIVATEBLOB"w;
+
+enum BCRYPT_RSAFULLPRIVATE_MAGIC = 0x33415352;
+
+static if (NTDDI_VERSION >= NTDDI_WIN8) {
+ enum BCRYPT_GLOBAL_PARAMETERS = "SecretAgreementParam"w;
+ enum BCRYPT_PRIVATE_KEY = "PrivKeyVal"w;
+}
+
+enum {
+ BCRYPT_ECCPUBLIC_BLOB = "ECCPUBLICBLOB"w,
+ BCRYPT_ECCPRIVATE_BLOB = "ECCPRIVATEBLOB"w,
+}
+static if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
+enum {
+ BCRYPT_ECCFULLPUBLIC_BLOB = "ECCFULLPUBLICBLOB"w,
+ BCRYPT_ECCFULLPRIVATE_BLOB = "ECCFULLPRIVATEBLOB"w,
+}
+
+static if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
+enum SSL_ECCPUBLIC_BLOB = "SSLECCPUBLICBLOB"w;
+
+enum TLS_13_PRE_SHARED_KEY = "TLS13PRESHAREDKEY"w;
+
+enum {
+ BCRYPT_ECDH_PUBLIC_P256_MAGIC = 0x314B4345,
+ BCRYPT_ECDH_PRIVATE_P256_MAGIC = 0x324B4345,
+ BCRYPT_ECDH_PUBLIC_P384_MAGIC = 0x334B4345,
+ BCRYPT_ECDH_PRIVATE_P384_MAGIC = 0x344B4345,
+ BCRYPT_ECDH_PUBLIC_P521_MAGIC = 0x354B4345,
+ BCRYPT_ECDH_PRIVATE_P521_MAGIC = 0x364B4345,
+}
+static if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
+enum {
+ BCRYPT_ECDH_PUBLIC_GENERIC_MAGIC = 0x504B4345,
+ BCRYPT_ECDH_PRIVATE_GENERIC_MAGIC = 0x564B4345,
+}
+
+enum {
+ BCRYPT_ECDSA_PUBLIC_P256_MAGIC = 0x31534345,
+ BCRYPT_ECDSA_PRIVATE_P256_MAGIC = 0x32534345,
+ BCRYPT_ECDSA_PUBLIC_P384_MAGIC = 0x33534345,
+ BCRYPT_ECDSA_PRIVATE_P384_MAGIC = 0x34534345,
+ BCRYPT_ECDSA_PUBLIC_P521_MAGIC = 0x35534345,
+ BCRYPT_ECDSA_PRIVATE_P521_MAGIC = 0x36534345,
+}
+static if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
+enum {
+ BCRYPT_ECDSA_PUBLIC_GENERIC_MAGIC = 0x50444345,
+ BCRYPT_ECDSA_PRIVATE_GENERIC_MAGIC = 0x56444345,
+}
+
+enum {
+ BCRYPT_DH_PUBLIC_BLOB = "DHPUBLICBLOB"w,
+ BCRYPT_DH_PRIVATE_BLOB = "DHPRIVATEBLOB"w,
+ LEGACY_DH_PUBLIC_BLOB = "CAPIDHPUBLICBLOB"w,
+ LEGACY_DH_PRIVATE_BLOB = "CAPIDHPRIVATEBLOB"w,
+}
+
+enum {
+ BCRYPT_DH_PUBLIC_MAGIC = 0x42504844,
+ BCRYPT_DH_PRIVATE_MAGIC = 0x56504844,
+}
+
+enum {
+ BCRYPT_DH_PARAMETERS = "DHParameters"w,
+ BCRYPT_DH_PARAMETERS_MAGIC = 0x4D504844,
+}
+
+enum {
+ BCRYPT_DSA_PUBLIC_BLOB = "DSAPUBLICBLOB"w,
+ BCRYPT_DSA_PRIVATE_BLOB = "DSAPRIVATEBLOB"w,
+ LEGACY_DSA_PUBLIC_BLOB = "CAPIDSAPUBLICBLOB"w,
+ LEGACY_DSA_PRIVATE_BLOB = "CAPIDSAPRIVATEBLOB"w,
+ LEGACY_DSA_V2_PUBLIC_BLOB = "V2CAPIDSAPUBLICBLOB"w,
+ LEGACY_DSA_V2_PRIVATE_BLOB = "V2CAPIDSAPRIVATEBLOB"w,
+}
+
+enum {
+ BCRYPT_DSA_PUBLIC_MAGIC = 0x42505344,
+ BCRYPT_DSA_PRIVATE_MAGIC = 0x56505344,
+ BCRYPT_DSA_PUBLIC_MAGIC_V2 = 0x32425044,
+ BCRYPT_DSA_PRIVATE_MAGIC_V2 = 0x32565044,
+}
+
+enum {
+ BCRYPT_KEY_DATA_BLOB_MAGIC = 0x4D42444B,
+ BCRYPT_KEY_DATA_BLOB_VERSION1 = 0x1,
+}
+
+enum {
+ BCRYPT_DSA_PARAMETERS = "DSAParameters"w,
+ BCRYPT_DSA_PARAMETERS_MAGIC = 0x4D505344,
+ BCRYPT_DSA_PARAMETERS_MAGIC_V2 = 0x324D5044,
+}
+
+enum {
+ MS_PRIMITIVE_PROVIDER = "Microsoft Primitive Provider"w,
+ MS_PLATFORM_CRYPTO_PROVIDER = "Microsoft Platform Crypto Provider"w,
+}
+
+enum {
+ BCRYPT_RSA_ALGORITHM = "RSA"w,
+ BCRYPT_RSA_SIGN_ALGORITHM = "RSA_SIGN"w,
+ BCRYPT_DH_ALGORITHM = "DH"w,
+ BCRYPT_DSA_ALGORITHM = "DSA"w,
+ BCRYPT_RC2_ALGORITHM = "RC2"w,
+ BCRYPT_RC4_ALGORITHM = "RC4"w,
+ BCRYPT_AES_ALGORITHM = "AES"w,
+ BCRYPT_DES_ALGORITHM = "DES"w,
+ BCRYPT_DESX_ALGORITHM = "DESX"w,
+ BCRYPT_3DES_ALGORITHM = "3DES"w,
+ BCRYPT_3DES_112_ALGORITHM = "3DES_112"w,
+ BCRYPT_MD2_ALGORITHM = "MD2"w,
+ BCRYPT_MD4_ALGORITHM = "MD4"w,
+ BCRYPT_MD5_ALGORITHM = "MD5"w,
+ BCRYPT_SHA1_ALGORITHM = "SHA1"w,
+ BCRYPT_SHA256_ALGORITHM = "SHA256"w,
+ BCRYPT_SHA384_ALGORITHM = "SHA384"w,
+ BCRYPT_SHA512_ALGORITHM = "SHA512"w,
+ BCRYPT_AES_GMAC_ALGORITHM = "AES-GMAC"w,
+ BCRYPT_AES_CMAC_ALGORITHM = "AES-CMAC"w,
+ BCRYPT_ECDSA_P256_ALGORITHM = "ECDSA_P256"w,
+ BCRYPT_ECDSA_P384_ALGORITHM = "ECDSA_P384"w,
+ BCRYPT_ECDSA_P521_ALGORITHM = "ECDSA_P521"w,
+ BCRYPT_ECDH_P256_ALGORITHM = "ECDH_P256"w,
+ BCRYPT_ECDH_P384_ALGORITHM = "ECDH_P384"w,
+ BCRYPT_ECDH_P521_ALGORITHM = "ECDH_P521"w,
+ BCRYPT_RNG_ALGORITHM = "RNG"w,
+ BCRYPT_RNG_FIPS186_DSA_ALGORITHM = "FIPS186DSARNG"w,
+ BCRYPT_RNG_DUAL_EC_ALGORITHM = "DUALECRNG"w,
+ BCRYPT_SP800108_CTR_HMAC_ALGORITHM = "SP800_108_CTR_HMAC"w,
+ BCRYPT_SP80056A_CONCAT_ALGORITHM = "SP800_56A_CONCAT"w,
+ BCRYPT_PBKDF2_ALGORITHM = "PBKDF2"w,
+ BCRYPT_CAPI_KDF_ALGORITHM = "CAPI_KDF"w,
+}
+
+enum {
+ BCRYPT_CIPHER_INTERFACE = 0x00000001,
+ BCRYPT_HASH_INTERFACE = 0x00000002,
+ BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE = 0x00000003,
+ BCRYPT_SECRET_AGREEMENT_INTERFACE = 0x00000004,
+ BCRYPT_SIGNATURE_INTERFACE = 0x00000005,
+ BCRYPT_RNG_INTERFACE = 0x00000006,
+ BCRYPT_KEY_DERIVATION_INTERFACE = 0x00000007,
+}
+
+static if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD)
+enum : BCRYPT_ALG_HANDLE {
+ BCRYPT_MD2_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000001,
+ BCRYPT_MD4_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000011,
+ BCRYPT_MD5_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000021,
+ BCRYPT_SHA1_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000031,
+ BCRYPT_SHA256_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000041,
+ BCRYPT_SHA384_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000051,
+ BCRYPT_SHA512_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000061,
+ BCRYPT_RC4_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000071,
+ BCRYPT_RNG_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000081,
+ BCRYPT_HMAC_MD5_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000091,
+ BCRYPT_HMAC_SHA1_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000000A1,
+ BCRYPT_HMAC_SHA256_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000000B1,
+ BCRYPT_HMAC_SHA384_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000000C1,
+ BCRYPT_HMAC_SHA512_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000000D1,
+ BCRYPT_RSA_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000000E1,
+ BCRYPT_ECDSA_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000000F1,
+
+ BCRYPT_AES_CMAC_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000101,
+ BCRYPT_AES_GMAC_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000111,
+ BCRYPT_HMAC_MD2_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000121,
+ BCRYPT_HMAC_MD4_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000131,
+
+ BCRYPT_3DES_CBC_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000141,
+ BCRYPT_3DES_ECB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000151,
+ BCRYPT_3DES_CFB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000161,
+ BCRYPT_3DES_112_CBC_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000171,
+ BCRYPT_3DES_112_ECB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000181,
+ BCRYPT_3DES_112_CFB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000191,
+ BCRYPT_AES_CBC_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000001A1,
+ BCRYPT_AES_ECB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000001B1,
+ BCRYPT_AES_CFB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000001C1,
+ BCRYPT_AES_CCM_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000001D1,
+ BCRYPT_AES_GCM_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000001E1,
+ BCRYPT_DES_CBC_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000001F1,
+ BCRYPT_DES_ECB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000201,
+ BCRYPT_DES_CFB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000211,
+ BCRYPT_DESX_CBC_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000221,
+ BCRYPT_DESX_ECB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000231,
+ BCRYPT_DESX_CFB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000241,
+ BCRYPT_RC2_CBC_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000251,
+ BCRYPT_RC2_ECB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000261,
+ BCRYPT_RC2_CFB_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000271,
+
+ BCRYPT_DH_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000281,
+ BCRYPT_ECDH_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000291,
+ BCRYPT_ECDH_P256_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000002A1,
+ BCRYPT_ECDH_P384_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000002B1,
+ BCRYPT_ECDH_P521_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000002C1,
+ BCRYPT_DSA_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000002D1,
+ BCRYPT_ECDSA_P256_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000002E1,
+ BCRYPT_ECDSA_P384_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000002F1,
+ BCRYPT_ECDSA_P521_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000301,
+ BCRYPT_RSA_SIGN_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000311,
+
+ BCRYPT_CAPI_KDF_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000321,
+ BCRYPT_PBKDF2_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000331,
+
+ BCRYPT_SP800108_CTR_HMAC_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000341,
+ BCRYPT_SP80056A_CONCAT_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000351,
+
+ BCRYPT_TLS1_1_KDF_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000361,
+ BCRYPT_TLS1_2_KDF_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000371,
+
+ BCRYPT_XTS_AES_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000381,
+
+ BCRYPT_HKDF_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000391,
+}
+static if (NTDDI_VERSION >= NTDDI_WIN10_FE)
+enum {
+ BCRYPT_CHACHA20_POLY1305_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000003A1,
+}
+static if (NTDDI_VERSION >= NTDDI_WIN11_ZN)
+enum {
+ BCRYPT_SHA3_256_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000003B1,
+ BCRYPT_SHA3_384_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000003C1,
+ BCRYPT_SHA3_512_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000003D1,
+ BCRYPT_HMAC_SHA3_256_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000003E1,
+ BCRYPT_HMAC_SHA3_384_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x000003F1,
+ BCRYPT_HMAC_SHA3_512_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000401,
+ BCRYPT_CSHAKE128_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000411,
+ BCRYPT_CSHAKE256_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000421,
+ BCRYPT_KMAC128_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000431,
+ BCRYPT_KMAC256_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000441,
+}
+static if (NTDDI_VERSION >= NTDDI_WIN11_GA)
+enum {
+ BCRYPT_AES_KWP_ALG_HANDLE = cast(BCRYPT_ALG_HANDLE) 0x00000451,
+}
+
+enum {
+ BCRYPT_ALG_HANDLE_HMAC_FLAG = 0x00000008,
+ BCRYPT_CAPI_AES_FLAG = 0x00000010,
+ BCRYPT_HASH_REUSABLE_FLAG = 0x00000020,
+
+ BCRYPT_BUFFERS_LOCKED_FLAG = 0x00000040,
+}
+
+enum {
+ BCRYPT_CIPHER_OPERATION = 0x00000001,
+ BCRYPT_HASH_OPERATION = 0x00000002,
+ BCRYPT_ASYMMETRIC_ENCRYPTION_OPERATION = 0x00000004,
+ BCRYPT_SECRET_AGREEMENT_OPERATION = 0x00000008,
+ BCRYPT_SIGNATURE_OPERATION = 0x00000010,
+ BCRYPT_RNG_OPERATION = 0x00000020,
+ BCRYPT_KEY_DERIVATION_OPERATION = 0x00000040,
+}
+
+enum {
+ BCRYPT_PUBLIC_KEY_FLAG = 0x00000001,
+ BCRYPT_PRIVATE_KEY_FLAG = 0x00000002,
+}
+
+enum BCRYPT_NO_KEY_VALIDATION = 0x00000008;
+
+enum {
+ BCRYPT_RNG_USE_ENTROPY_IN_BUFFER = 0x00000001,
+ BCRYPT_USE_SYSTEM_PREFERRED_RNG = 0x00000002,
+}
+
+pragma(inline, true) @nogc nothrow pure @safe {
+ BCRYPT_INTERFACE_VERSION BCRYPT_MAKE_INTERFACE_VERSION(int major, int minor) =>
+ BCRYPT_INTERFACE_VERSION(MajorVersion: cast(USHORT)major, MinorVersion: cast(USHORT)minor);
+ bool BCRYPT_IS_INTERFACE_VERSION_COMPATIBLE(BCRYPT_INTERFACE_VERSION loader, BCRYPT_INTERFACE_VERSION provider) =>
+ loader.MajorVersion <= provider.MajorVersion;
+}
+
+enum {
+ BCRYPT_CIPHER_INTERFACE_VERSION_1 = BCRYPT_MAKE_INTERFACE_VERSION(1, 0),
+ BCRYPT_HASH_INTERFACE_VERSION_1 = BCRYPT_MAKE_INTERFACE_VERSION(1, 0),
+ BCRYPT_ASYMMETRIC_ENCRYPTION_INTERFACE_VERSION_1 = BCRYPT_MAKE_INTERFACE_VERSION(1, 0),
+ BCRYPT_SECRET_AGREEMENT_INTERFACE_VERSION_1 = BCRYPT_MAKE_INTERFACE_VERSION(1, 0),
+ BCRYPT_SIGNATURE_INTERFACE_VERSION_1 = BCRYPT_MAKE_INTERFACE_VERSION(1, 0),
+ BCRYPT_RNG_INTERFACE_VERSION_1 = BCRYPT_MAKE_INTERFACE_VERSION(1, 0),
+}
+
+enum {
+ CRYPT_MIN_DEPENDENCIES = 0x00000001,
+ CRYPT_PROCESS_ISOLATE = 0x00010000,
+}
+
+enum {
+ CRYPT_UM = 0x00000001,
+ CRYPT_KM = 0x00000002,
+ CRYPT_MM = 0x00000003,
+ CRYPT_ANY = 0x00000004,
+}
+
+enum CRYPT_OVERWRITE = 0x00000001;
+
+enum {
+ CRYPT_LOCAL = 0x00000001,
+ CRYPT_DOMAIN = 0x00000002,
+}
+
+enum {
+ CRYPT_EXCLUSIVE = 0x00000001,
+ CRYPT_OVERRIDE = 0x00010000,
+}
+
+enum {
+ CRYPT_ALL_FUNCTIONS = 0x00000001,
+ CRYPT_ALL_PROVIDERS = 0x00000002,
+}
+
+enum {
+ CRYPT_PRIORITY_TOP = 0x00000000,
+ CRYPT_PRIORITY_BOTTOM = 0xFFFFFFFF,
+}
+
+enum CRYPT_DEFAULT_CONTEXT = "Default"w;
+
+alias BCRYPT_HANDLE = PVOID;
+alias BCRYPT_ALG_HANDLE = PVOID;
+alias BCRYPT_KEY_HANDLE = PVOID;
+alias BCRYPT_HASH_HANDLE = PVOID;
+alias BCRYPT_SECRET_HANDLE = PVOID;
+
+struct BCRYPT_KEY_BLOB {
+ ULONG Magic;
+}
+
+struct BCRYPT_RSAKEY_BLOB {
+ ULONG Magic;
+ ULONG BitLength;
+ ULONG cbPublicExp;
+ ULONG cbModulus;
+ ULONG cbPrime1;
+ ULONG cbPrime2;
+}
+
+struct BCRYPT_ECCKEY_BLOB {
+ ULONG dwMagic;
+ ULONG cbKey;
+}
+alias PBCRYPT_ECCKEY_BLOB = BCRYPT_ECCKEY_BLOB*;
+
+static if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) {
+ struct SSL_ECCKEY_BLOB {
+ ULONG dwCurveType;
+ ULONG cbKey;
+ }
+ alias PSSL_ECCKEY_BLOB = SSL_ECCKEY_BLOB*;
+
+ enum BCRYPT_ECC_FULLKEY_BLOB_V1 = 0x1;
+
+ alias ECC_CURVE_TYPE_ENUM = int;
+ enum : ECC_CURVE_TYPE_ENUM {
+ BCRYPT_ECC_PRIME_SHORT_WEIERSTRASS_CURVE = 0x1,
+ BCRYPT_ECC_PRIME_TWISTED_EDWARDS_CURVE = 0x2,
+ BCRYPT_ECC_PRIME_MONTGOMERY_CURVE = 0x3
+ }
+
+ alias ECC_CURVE_ALG_ID_ENUM = int;
+ enum : ECC_CURVE_ALG_ID_ENUM {
+ BCRYPT_NO_CURVE_GENERATION_ALG_ID = 0x0,
+ }
+
+ struct BCRYPT_ECCFULLKEY_BLOB {
+ ULONG dwMagic;
+ ULONG dwVersion;
+ ECC_CURVE_TYPE_ENUM dwCurveType;
+ ECC_CURVE_ALG_ID_ENUM dwCurveGenerationAlgId;
+ ULONG cbFieldLength;
+ ULONG cbSubgroupOrder;
+ ULONG cbCofactor;
+ ULONG cbSeed;
+ }
+ alias PBCRYPT_ECCFULLKEY_BLOB = BCRYPT_ECCFULLKEY_BLOB*;
+}
+
+struct BCRYPT_DH_KEY_BLOB {
+ ULONG dwMagic;
+ ULONG cbKey;
+}
+alias PBCRYPT_DH_KEY_BLOB = BCRYPT_DH_KEY_BLOB*;
+
+struct BCRYPT_DH_PARAMETER_HEADER {
+ ULONG cbLength;
+ ULONG dwMagic;
+ ULONG cbKeyLength;
+}
+
+struct BCRYPT_DSA_KEY_BLOB {
+ ULONG dwMagic;
+ ULONG cbKey;
+ UCHAR[4] Count;
+ UCHAR[20] Seed;
+ UCHAR[20] q;
+}
+alias PBCRYPT_DSA_KEY_BLOB = BCRYPT_DSA_KEY_BLOB*;
+
+alias HASHALGORITHM_ENUM = int;
+enum : HASHALGORITHM_ENUM {
+ DSA_HASH_ALGORITHM_SHA1,
+ DSA_HASH_ALGORITHM_SHA256,
+ DSA_HASH_ALGORITHM_SHA512,
+}
+
+alias DSAFIPSVERSION_ENUM = int;
+enum : DSAFIPSVERSION_ENUM {
+ DSA_FIPS186_2,
+ DSA_FIPS186_3,
+}
+
+struct BCRYPT_DSA_KEY_BLOB_V2 {
+ ULONG dwMagic;
+ ULONG cbKey;
+ HASHALGORITHM_ENUM hashAlgorithm;
+ DSAFIPSVERSION_ENUM standardVersion;
+ ULONG cbSeedLength;
+ ULONG cbGroupSize;
+ UCHAR[4] Count;
+}
+alias PBCRYPT_DSA_KEY_BLOB_V2 = BCRYPT_DSA_KEY_BLOB_V2*;
+
+struct BCRYPT_KEY_DATA_BLOB_HEADER {
+ ULONG dwMagic;
+ ULONG dwVersion;
+ ULONG cbKeyData;
+}
+alias PBCRYPT_KEY_DATA_BLOB_HEADER = BCRYPT_KEY_DATA_BLOB_HEADER*;
+
+struct BCRYPT_DSA_PARAMETER_HEADER {
+ ULONG cbLength;
+ ULONG dwMagic;
+ ULONG cbKeyLength;
+ UCHAR[4] Count;
+ UCHAR[20] Seed;
+ UCHAR[20] q;
+}
+
+struct BCRYPT_DSA_PARAMETER_HEADER_V2 {
+ ULONG cbLength;
+ ULONG dwMagic;
+ ULONG cbKeyLength;
+ HASHALGORITHM_ENUM hashAlgorithm;
+ DSAFIPSVERSION_ENUM standardVersion;
+ ULONG cbSeedLength;
+ ULONG cbGroupSize;
+ UCHAR[4] Count;
+}
+
+struct BCRYPT_ECC_CURVE_NAMES {
+ ULONG dwEccCurveNames;
+ LPWSTR* pEccCurveNames;
+}
+
+alias BCRYPT_HASH_OPERATION_TYPE = int;
+enum : BCRYPT_HASH_OPERATION_TYPE {
+ BCRYPT_HASH_OPERATION_HASH_DATA = 1,
+ BCRYPT_HASH_OPERATION_FINISH_HASH = 2,
+}
+
+struct BCRYPT_MULTI_HASH_OPERATION {
+ ULONG iHash;
+ BCRYPT_HASH_OPERATION_TYPE hashOperation;
+ PUCHAR pbBuffer;
+ ULONG cbBuffer;
+}
+
+alias BCRYPT_MULTI_OPERATION_TYPE = int;
+enum : BCRYPT_MULTI_OPERATION_TYPE {
+ BCRYPT_OPERATION_TYPE_HASH = 1,
+}
+
+struct BCRYPT_MULTI_OBJECT_LENGTH_STRUCT {
+ ULONG cbPerObject;
+ ULONG cbPerElement;
+}
+
+struct BCRYPT_ALGORITHM_IDENTIFIER {
+ LPWSTR pszName;
+ ULONG dwClass;
+ ULONG dwFlags;
+}
+
+struct BCRYPT_PROVIDER_NAME {
+ LPWSTR pszProviderName;
+}
+
+struct BCRYPT_INTERFACE_VERSION {
+ USHORT MajorVersion;
+ USHORT MinorVersion;
+}
+alias PBCRYPT_INTERFACE_VERSION = BCRYPT_INTERFACE_VERSION*;
+
+struct CRYPT_INTERFACE_REG {
+ ULONG dwInterface;
+ ULONG dwFlags;
+ ULONG cFunctions;
+ PWSTR* rgpszFunctions;
+}
+alias PCRYPT_INTERFACE_REG = CRYPT_INTERFACE_REG*;
+
+struct CRYPT_IMAGE_REG {
+ PWSTR pszImage;
+ ULONG cInterfaces;
+ PCRYPT_INTERFACE_REG* rgpInterfaces;
+}
+alias PCRYPT_IMAGE_REG = CRYPT_IMAGE_REG*;
+
+struct CRYPT_PROVIDER_REG {
+ ULONG cAliases;
+ PWSTR* rgpszAliases;
+ PCRYPT_IMAGE_REG pUM;
+ PCRYPT_IMAGE_REG pKM;
+}
+alias PCRYPT_PROVIDER_REG = CRYPT_PROVIDER_REG*;
+
+struct CRYPT_PROVIDERS {
+ ULONG cProviders;
+ PWSTR* rgpszProviders;
+}
+alias PCRYPT_PROVIDERS = CRYPT_PROVIDERS*;
+
+struct CRYPT_CONTEXT_CONFIG {
+ ULONG dwFlags;
+ ULONG dwReserved;
+}
+alias PCRYPT_CONTEXT_CONFIG = CRYPT_CONTEXT_CONFIG*;
+
+struct CRYPT_CONTEXT_FUNCTION_CONFIG {
+ ULONG dwFlags;
+ ULONG dwReserved;
+}
+alias PCRYPT_CONTEXT_FUNCTION_CONFIG = CRYPT_CONTEXT_FUNCTION_CONFIG*;
+
+struct CRYPT_CONTEXTS {
+ ULONG cContexts;
+ PWSTR* rgpszContexts;
+}
+alias PCRYPT_CONTEXTS = CRYPT_CONTEXTS*;
+
+struct CRYPT_CONTEXT_FUNCTIONS {
+ ULONG cFunctions;
+ PWSTR* rgpszFunctions;
+}
+alias PCRYPT_CONTEXT_FUNCTIONS = CRYPT_CONTEXT_FUNCTIONS*;
+
+struct CRYPT_CONTEXT_FUNCTION_PROVIDERS {
+ ULONG cProviders;
+ PWSTR* rgpszProviders;
+}
+alias PCRYPT_CONTEXT_FUNCTION_PROVIDERS = CRYPT_CONTEXT_FUNCTION_PROVIDERS*;
+
+struct CRYPT_PROPERTY_REF {
+ PWSTR pszProperty;
+ ULONG cbValue;
+ PUCHAR pbValue;
+}
+alias PCRYPT_PROPERTY_REF = CRYPT_PROPERTY_REF*;
+
+struct CRYPT_IMAGE_REF {
+ PWSTR pszImage;
+ ULONG dwFlags;
+}
+alias PCRYPT_IMAGE_REF = CRYPT_IMAGE_REF*;
+
+struct CRYPT_PROVIDER_REF {
+ ULONG dwInterface;
+ PWSTR pszFunction;
+ PWSTR pszProvider;
+ ULONG cProperties;
+ PCRYPT_PROPERTY_REF* rgpProperties;
+ PCRYPT_IMAGE_REF pUM;
+ PCRYPT_IMAGE_REF pKM;
+}
+alias PCRYPT_PROVIDER_REF = CRYPT_PROVIDER_REF*;
+
+struct CRYPT_PROVIDER_REFS {
+ ULONG cProviders;
+ PCRYPT_PROVIDER_REF* rgpProviders;
+}
+alias PCRYPT_PROVIDER_REFS = CRYPT_PROVIDER_REFS*;
+
+extern(Windows) @nogc nothrow {
+ NTSTATUS BCryptOpenAlgorithmProvider(scope BCRYPT_ALG_HANDLE* phAlgorithm, scope LPCWSTR pszAlgId, scope LPCWSTR pszImplementation, ULONG dwFlags);
+ NTSTATUS BCryptEnumAlgorithms(ULONG dwAlgOperations, scope ULONG* pAlgCount, scope BCRYPT_ALGORITHM_IDENTIFIER** ppAlgList, ULONG dwFlags);
+ NTSTATUS BCryptEnumProviders(scope LPCWSTR pszAlgId, scope ULONG* pImplCount, scope BCRYPT_PROVIDER_NAME** ppImplList, ULONG dwFlags);
+ NTSTATUS BCryptGetProperty(BCRYPT_HANDLE hObject, scope LPCWSTR pszProperty, scope PUCHAR pbOutput, ULONG cbOutput, scope ULONG* pcbResult, ULONG dwFlags);
+ NTSTATUS BCryptSetProperty(BCRYPT_HANDLE hObject, scope LPCWSTR pszProperty, scope PUCHAR pbInput, ULONG cbInput, ULONG dwFlags);
+ NTSTATUS BCryptCloseAlgorithmProvider(BCRYPT_ALG_HANDLE hAlgorithm, ULONG dwFlags);
+ VOID BCryptFreeBuffer(PVOID pvBuffer);
+ NTSTATUS BCryptGenerateSymmetricKey(BCRYPT_ALG_HANDLE hAlgorithm, scope BCRYPT_KEY_HANDLE* phKey, scope PUCHAR pbKeyObject, ULONG cbKeyObject, scope PUCHAR pbSecret, ULONG cbSecret, ULONG dwFlags);
+ NTSTATUS BCryptGenerateKeyPair(BCRYPT_ALG_HANDLE hAlgorithm, scope BCRYPT_KEY_HANDLE* phKey, ULONG dwLength, ULONG dwFlags);
+ NTSTATUS BCryptEncrypt(BCRYPT_KEY_HANDLE hKey, scope PUCHAR pbInput, ULONG cbInput, scope VOID* pPaddingInfo, scope PUCHAR pbIV, ULONG cbIV, scope PUCHAR pbOutput, ULONG cbOutput, scope ULONG* pcbResult, ULONG dwFlags);
+ NTSTATUS BCryptDecrypt(BCRYPT_KEY_HANDLE hKey, scope PUCHAR pbInput, ULONG cbInput, scope VOID* pPaddingInfo, scope PUCHAR pbIV, ULONG cbIV, scope PUCHAR pbOutput, ULONG cbOutput, scope ULONG* pcbResult, ULONG dwFlags);
+ NTSTATUS BCryptExportKey(BCRYPT_KEY_HANDLE hKey, BCRYPT_KEY_HANDLE hExportKey, scope LPCWSTR pszBlobType, scope PUCHAR pbOutput, ULONG cbOutput, scope ULONG* pcbResult, ULONG dwFlags);
+ NTSTATUS BCryptImportKey(BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE hImportKey, scope LPCWSTR pszBlobType, scope BCRYPT_KEY_HANDLE* phKey, scope PUCHAR pbKeyObject, ULONG cbKeyObject, scope PUCHAR pbInput, ULONG cbInput, ULONG dwFlags);
+ NTSTATUS BCryptImportKeyPair(BCRYPT_ALG_HANDLE hAlgorithm, BCRYPT_KEY_HANDLE hImportKey, scope LPCWSTR pszBlobType, scope BCRYPT_KEY_HANDLE* phKey, scope PUCHAR pbInput, ULONG cbInput, ULONG dwFlags);
+ NTSTATUS BCryptDuplicateKey(BCRYPT_KEY_HANDLE hKey, scope BCRYPT_KEY_HANDLE* phNewKey, scope PUCHAR pbKeyObject, ULONG cbKeyObject, ULONG dwFlags);
+ NTSTATUS BCryptFinalizeKeyPair(BCRYPT_KEY_HANDLE hKey, ULONG dwFlags);
+ NTSTATUS BCryptDestroyKey(BCRYPT_KEY_HANDLE hKey);
+ NTSTATUS BCryptDestroySecret(BCRYPT_SECRET_HANDLE hSecret);
+ NTSTATUS BCryptSignHash(BCRYPT_KEY_HANDLE hKey, scope VOID* pPaddingInfo, scope PUCHAR pbInput, ULONG cbInput, scope PUCHAR pbOutput, ULONG cbOutput, scope ULONG* pcbResult, ULONG dwFlags);
+ NTSTATUS BCryptVerifySignature(BCRYPT_KEY_HANDLE hKey, scope VOID* pPaddingInfo, scope PUCHAR pbHash, ULONG cbHash, scope PUCHAR pbSignature, ULONG cbSignature, ULONG dwFlags);
+ NTSTATUS BCryptSecretAgreement(BCRYPT_KEY_HANDLE hPrivKey, BCRYPT_KEY_HANDLE hPubKey, scope BCRYPT_SECRET_HANDLE* phAgreedSecret, ULONG dwFlags);
+ NTSTATUS BCryptDeriveKey(BCRYPT_SECRET_HANDLE hSharedSecret, LPCWSTR pwszKDF, scope BCryptBufferDesc* pParameterList, scope PUCHAR pbDerivedKey, ULONG cbDerivedKey, scope ULONG* pcbResult, ULONG dwFlags);
+ NTSTATUS BCryptKeyDerivation(BCRYPT_KEY_HANDLE hKey, scope BCryptBufferDesc* pParameterList, scope PUCHAR pbDerivedKey, ULONG cbDerivedKey, scope ULONG* pcbResult, ULONG dwFlags);
+ NTSTATUS BCryptCreateHash(BCRYPT_ALG_HANDLE hAlgorithm, scope BCRYPT_HASH_HANDLE* phHash, scope PUCHAR pbHashObject, ULONG cbHashObject, scope PUCHAR pbSecret, ULONG cbSecret, ULONG dwFlags);
+ NTSTATUS BCryptHashData(BCRYPT_HASH_HANDLE hHash, scope PUCHAR pbInput, ULONG cbInput, ULONG dwFlags);
+ NTSTATUS BCryptFinishHash(BCRYPT_HASH_HANDLE hHash, scope PUCHAR pbOutput, ULONG cbOutput, ULONG dwFlags);
+ static if (NTDDI_VERSION >= NTDDI_WINBLUE) {
+ NTSTATUS BCryptCreateMultiHash(BCRYPT_ALG_HANDLE hAlgorithm, scope BCRYPT_HASH_HANDLE* phHash, ULONG nHashes, scope PUCHAR pbHashObject, ULONG cbHashObject, scope PUCHAR pbSecret, ULONG cbSecret, ULONG dwFlags);
+ NTSTATUS BCryptProcessMultiOperations(BCRYPT_HANDLE hObject, BCRYPT_MULTI_OPERATION_TYPE operationType, scope PVOID pOperations, ULONG cbOperations, ULONG dwFlags);
+ }
+ NTSTATUS BCryptDuplicateHash(BCRYPT_HASH_HANDLE hHash, scope BCRYPT_HASH_HANDLE* phNewHash, scope PUCHAR pbHashObject, ULONG cbHashObject, ULONG dwFlags);
+ NTSTATUS BCryptDestroyHash(BCRYPT_HASH_HANDLE hHash);
+ static if (NTDDI_VERSION >= NTDDI_WINTHRESHOLD) {
+ NTSTATUS BCryptHash(BCRYPT_ALG_HANDLE hAlgorithm, scope PUCHAR pbSecret, ULONG cbSecret, scope PUCHAR pbInput, ULONG cbInput, scope PUCHAR pbOutput, ULONG cbOutput);
+ }
+ NTSTATUS BCryptGenRandom(BCRYPT_ALG_HANDLE hAlgorithm, scope PUCHAR pbBuffer, ULONG cbBuffer, ULONG dwFlags);
+ NTSTATUS BCryptDeriveKeyCapi(BCRYPT_HASH_HANDLE hHash, BCRYPT_ALG_HANDLE hTargetAlg, scope PUCHAR pbDerivedKey, ULONG cbDerivedKey, ULONG dwFlags);
+ NTSTATUS BCryptDeriveKeyPBKDF2(BCRYPT_ALG_HANDLE hPrf, scope PUCHAR pbPassword, ULONG cbPassword, scope PUCHAR pbSalt, ULONG cbSalt, ULONGLONG cIterations, scope PUCHAR pbDerivedKey, ULONG cbDerivedKey, ULONG dwFlags);
+ NTSTATUS BCryptResolveProviders(scope LPCWSTR pszContext, ULONG dwInterface, scope LPCWSTR pszFunction, scope LPCWSTR pszProvider, ULONG dwMode, ULONG dwFlags, scope ULONG* pcbBuffer, scope PCRYPT_PROVIDER_REFS* ppBuffer);
+ NTSTATUS BCryptGetFipsAlgorithmMode(scope BOOLEAN* pfEnabled);
+ NTSTATUS BCryptQueryProviderRegistration(scope LPCWSTR pszProvider, ULONG dwMode, ULONG dwInterface, scope ULONG* pcbBuffer, scope PCRYPT_PROVIDER_REG* ppBuffer);
+ NTSTATUS BCryptEnumRegisteredProviders(scope ULONG* pcbBuffer, scope PCRYPT_PROVIDERS* ppBuffer);
+ NTSTATUS BCryptCreateContext(ULONG dwTable, scope LPCWSTR pszContext, PCRYPT_CONTEXT_CONFIG pConfig);
+ NTSTATUS BCryptDeleteContext(ULONG dwTable, scope LPCWSTR pszContext);
+ NTSTATUS BCryptEnumContexts(ULONG dwTable, scope ULONG* pcbBuffer, scope PCRYPT_CONTEXTS* ppBuffer);
+ NTSTATUS BCryptConfigureContext(ULONG dwTable, scope LPCWSTR pszContext, PCRYPT_CONTEXT_CONFIG pConfig);
+ NTSTATUS BCryptQueryContextConfiguration(ULONG dwTable, scope LPCWSTR pszContext, scope ULONG* pcbBuffer, scope PCRYPT_CONTEXT_CONFIG* ppBuffer);
+ NTSTATUS BCryptAddContextFunction(ULONG dwTable, scope LPCWSTR pszContext, ULONG dwInterface, scope LPCWSTR pszFunction, ULONG dwPosition);
+ NTSTATUS BCryptRemoveContextFunction(ULONG dwTable, scope LPCWSTR pszContext, ULONG dwInterface, scope LPCWSTR pszFunction);
+ NTSTATUS BCryptEnumContextFunctions(ULONG dwTable, scope LPCWSTR pszContext, ULONG dwInterface, scope ULONG* pcbBuffer, scope PCRYPT_CONTEXT_FUNCTIONS* ppBuffer);
+ NTSTATUS BCryptConfigureContextFunction(ULONG dwTable, scope LPCWSTR pszContext, ULONG dwInterface, scope LPCWSTR pszFunction, PCRYPT_CONTEXT_FUNCTION_CONFIG pConfig);
+ NTSTATUS BCryptQueryContextFunctionConfiguration(ULONG dwTable, scope LPCWSTR pszContext, ULONG dwInterface, scope LPCWSTR pszFunction, scope ULONG* pcbBuffer, scope PCRYPT_CONTEXT_FUNCTION_CONFIG* ppBuffer);
+ NTSTATUS BCryptEnumContextFunctionProviders(ULONG dwTable, scope LPCWSTR pszContext, ULONG dwInterface, scope LPCWSTR pszFunction, scope ULONG* pcbBuffer, scope PCRYPT_CONTEXT_FUNCTION_PROVIDERS* ppBuffer);
+ NTSTATUS BCryptSetContextFunctionProperty(ULONG dwTable, scope LPCWSTR pszContext, ULONG dwInterface, scope LPCWSTR pszFunction, LPCWSTR pszProperty, ULONG cbValue, scope PUCHAR pbValue);
+ NTSTATUS BCryptQueryContextFunctionProperty(ULONG dwTable, scope LPCWSTR pszContext, ULONG dwInterface, scope LPCWSTR pszFunction, LPCWSTR pszProperty, ULONG* pcbValue, scope PUCHAR* ppbValue);
+ deprecated NTSTATUS BCryptRegisterConfigChangeNotify(scope HANDLE* phEvent);
+ NTSTATUS BCryptUnregisterConfigChangeNotify(HANDLE hEvent);
+}
diff --git a/libphobos/libdruntime/core/sys/windows/dll.d b/libphobos/libdruntime/core/sys/windows/dll.d
index 7c601bb..06f01f3 100644
--- a/libphobos/libdruntime/core/sys/windows/dll.d
+++ b/libphobos/libdruntime/core/sys/windows/dll.d
@@ -9,9 +9,6 @@
* Source: $(DRUNTIMESRC core/sys/windows/_dll.d)
*/
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
module core.sys.windows.dll;
version (Windows):
@@ -405,36 +402,29 @@ private bool isWindows8OrLater() nothrow @nogc
int dll_getRefCount( HINSTANCE hInstance ) nothrow @nogc
{
void** peb;
- version (Win64)
+ version (D_InlineAsm_X86_64)
{
- version (GNU_InlineAsm)
+ asm pure nothrow @nogc
{
- asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" (peb); }
+ mov RAX, 0x60;
+ mov RAX,GS:[RAX];
+ mov peb, RAX;
}
- else
+ }
+ else version (D_InlineAsm_X86)
+ {
+ asm pure nothrow @nogc
{
- asm pure nothrow @nogc
- {
- mov RAX, 0x60;
- mov RAX,GS:[RAX];
- mov peb, RAX;
- }
+ mov EAX,FS:[0x30];
+ mov peb, EAX;
}
}
- else version (Win32)
+ else version (GNU_InlineAsm)
{
- version (GNU_InlineAsm)
- {
+ version (X86_64)
+ asm pure nothrow @nogc { "movq %%gs:0x60, %0;" : "=r" (peb); }
+ else version (X86)
asm pure nothrow @nogc { "movl %%fs:0x30, %0;" : "=r" (peb); }
- }
- else
- {
- asm pure nothrow @nogc
- {
- mov EAX,FS:[0x30];
- mov peb, EAX;
- }
- }
}
dll_aux.LDR_MODULE *ldrMod = dll_aux.findLdrModule( hInstance, peb );
if ( !ldrMod )
diff --git a/libphobos/libdruntime/core/sys/windows/sdkddkver.d b/libphobos/libdruntime/core/sys/windows/sdkddkver.d
index 3f5c01b..bdaaa81 100644
--- a/libphobos/libdruntime/core/sys/windows/sdkddkver.d
+++ b/libphobos/libdruntime/core/sys/windows/sdkddkver.d
@@ -7,9 +7,10 @@
* Source: $(DRUNTIMESRC core/sys/windows/sdkddkver.d)
*/
module core.sys.windows.sdkddkver;
-
version (Windows):
+import core.sys.windows.w32api;
+
enum _WIN32_WINNT_NT4 = 0x0400;
enum _WIN32_WINNT_WIN2K = 0x0500;
enum _WIN32_WINNT_WINXP = 0x0501;
@@ -21,6 +22,7 @@ enum _WIN32_WINNT_LONGHORN = 0x0600;
enum _WIN32_WINNT_WIN7 = 0x0601;
enum _WIN32_WINNT_WIN8 = 0x0602;
enum _WIN32_WINNT_WINBLUE = 0x0603;
+enum _WIN32_WINNT_WINTHRESHOLD = 0x0A00;
enum _WIN32_WINNT_WIN10 = 0x0A00;
enum _WIN32_IE_IE20 = 0x0200;
@@ -38,6 +40,7 @@ enum _WIN32_IE_IE70 = 0x0700;
enum _WIN32_IE_IE80 = 0x0800;
enum _WIN32_IE_IE90 = 0x0900;
enum _WIN32_IE_IE100 = 0x0A00;
+enum _WIN32_IE_IE110 = 0x0A00;
enum _WIN32_IE_NT4 = _WIN32_IE_IE20;
enum _WIN32_IE_NT4SP1 = _WIN32_IE_IE20;
@@ -64,6 +67,8 @@ enum _WIN32_IE_LONGHORN = _WIN32_IE_IE70;
enum _WIN32_IE_WIN7 = _WIN32_IE_IE80;
enum _WIN32_IE_WIN8 = _WIN32_IE_IE100;
enum _WIN32_IE_WINBLUE = _WIN32_IE_IE100;
+enum _WIN32_IE_WINTHRESHOLD = _WIN32_IE_IE110;
+enum _WIN32_IE_WIN10 = _WIN32_IE_IE110;
enum NTDDI_WIN2K = 0x05000000;
@@ -106,12 +111,45 @@ enum NTDDI_WS08SP4 = NTDDI_WIN6SP4;
enum NTDDI_WIN7 = 0x06010000;
enum NTDDI_WIN8 = 0x06020000;
enum NTDDI_WINBLUE = 0x06030000;
-
-enum OSVERSION_MASK = 0xFFFF0000;
+enum NTDDI_WINTHRESHOLD = 0x0A000000;
+enum NTDDI_WIN10 = 0x0A000000;
+enum NTDDI_WIN10_TH2 = 0x0A000001;
+enum NTDDI_WIN10_RS1 = 0x0A000002;
+enum NTDDI_WIN10_RS2 = 0x0A000003;
+enum NTDDI_WIN10_RS3 = 0x0A000004;
+enum NTDDI_WIN10_RS4 = 0x0A000005;
+enum NTDDI_WIN10_RS5 = 0x0A000006;
+enum NTDDI_WIN10_19H1 = 0x0A000007;
+enum NTDDI_WIN10_VB = 0x0A000008;
+enum NTDDI_WIN10_MN = 0x0A000009;
+enum NTDDI_WIN10_FE = 0x0A00000A;
+enum NTDDI_WIN10_CO = 0x0A00000B;
+enum NTDDI_WIN10_NI = 0x0A00000C;
+enum NTDDI_WIN10_CU = 0x0A00000D;
+enum NTDDI_WIN11_ZN = 0x0A00000E;
+enum NTDDI_WIN11_GA = 0x0A00000F;
+enum NTDDI_WIN11_GE = 0x0A000010;
+
+enum WDK_NTDDI_VERSION = NTDDI_WIN11_GE;
+
+enum OSVERSION_MASK = 0xFFFF0000U;
enum SPVERSION_MASK = 0x0000FF00;
enum SUBVERSION_MASK = 0x000000FF;
-enum _WIN32_WINNT = 0x0603;
+pragma(inline, true) @nogc nothrow pure @safe {
+ uint OSVER(uint Version) => Version & OSVERSION_MASK;
+ uint SPVER(uint Version) => (Version & SPVERSION_MASK) >> 8;
+ uint SUBVER(uint Version) => Version & SUBVERSION_MASK;
+
+ uint NTDDI_VERSION_FROM_WIN32_WINNT2(uint Version) => Version * 0x10000;
+ alias NTDDI_VERSION_FROM_WIN32_WINNT = NTDDI_VERSION_FROM_WIN32_WINNT2;
+}
+
+
+static if (_WIN32_WINNT < _WIN32_WINNT_WIN10) {
+ enum NTDDI_VERSION = NTDDI_VERSION_FROM_WIN32_WINNT(_WIN32_WINNT);
+} else {
+ enum NTDDI_VERSION = WDK_NTDDI_VERSION;
+}
-enum NTDDI_VERSION = 0x06030000;
-enum WINVER = _WIN32_WINNT;
+enum WINVER = _WIN32_WINNT;
diff --git a/libphobos/libdruntime/core/sys/windows/threadaux.d b/libphobos/libdruntime/core/sys/windows/threadaux.d
index 92bd1c6..dae8896 100644
--- a/libphobos/libdruntime/core/sys/windows/threadaux.d
+++ b/libphobos/libdruntime/core/sys/windows/threadaux.d
@@ -9,9 +9,6 @@
* Authors: Rainer Schuetze
*/
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
module core.sys.windows.threadaux;
version (Windows):
@@ -166,42 +163,35 @@ struct thread_aux
// get linear address of TEB of current thread
static void** getTEB() nothrow @nogc
{
- version (Win32)
+ version (D_InlineAsm_X86)
{
- version (GNU_InlineAsm)
+ asm pure nothrow @nogc
{
- void** teb;
- asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" (teb); }
- return teb;
+ naked;
+ mov EAX,FS:[0x18];
+ ret;
}
- else
+ }
+ else version (D_InlineAsm_X86_64)
+ {
+ asm pure nothrow @nogc
{
- asm pure nothrow @nogc
- {
- naked;
- mov EAX,FS:[0x18];
- ret;
- }
+ naked;
+ mov RAX,0x30;
+ mov RAX,GS:[RAX]; // immediate value causes fixup
+ ret;
}
}
- else version (Win64)
+ else version (GNU_InlineAsm)
{
- version (GNU_InlineAsm)
- {
- void** teb;
+ void** teb;
+ version (X86)
+ asm pure nothrow @nogc { "movl %%fs:0x18, %0;" : "=r" (teb); }
+ else version (X86_64)
asm pure nothrow @nogc { "movq %%gs:0x30, %0;" : "=r" (teb); }
- return teb;
- }
else
- {
- asm pure nothrow @nogc
- {
- naked;
- mov RAX,0x30;
- mov RAX,GS:[RAX]; // immediate value causes fixup
- ret;
- }
- }
+ static assert(false);
+ return teb;
}
else
{
diff --git a/libphobos/libdruntime/core/sys/windows/w32api.d b/libphobos/libdruntime/core/sys/windows/w32api.d
index a5aa975..bf84195 100644
--- a/libphobos/libdruntime/core/sys/windows/w32api.d
+++ b/libphobos/libdruntime/core/sys/windows/w32api.d
@@ -10,12 +10,45 @@
module core.sys.windows.w32api;
version (Windows):
+import core.sys.windows.sdkddkver;
+
version (ANSI) {} else version = Unicode;
enum __W32API_VERSION = 3.17;
enum __W32API_MAJOR_VERSION = 3;
enum __W32API_MINOR_VERSION = 17;
+enum Windows95 = 0x0400;
+enum Windows98 = 0x0410;
+enum WindowsME = 0x0500;
+
+enum WindowsNT4 = 0x0400;
+enum Windows2000 = 0x0500;
+enum WindowsXP = 0x0501;
+enum Windows2003 = 0x0502;
+enum WindowsVista = 0x0600;
+enum Windows7 = 0x0601;
+enum Windows8 = 0x0602;
+
+enum IE3 = 0x0300;
+enum IE301 = 0x0300;
+enum IE302 = 0x0300;
+enum IE4 = 0x0400;
+enum IE401 = 0x0401;
+enum IE5 = 0x0500;
+enum IE5a = 0x0500;
+enum IE5b = 0x0500;
+enum IE501 = 0x0501;
+enum IE55 = 0x0501;
+enum IE56 = 0x0560;
+enum IE6 = 0x0600;
+enum IE601 = 0x0601;
+enum IE602 = 0x0603;
+enum IE7 = 0x0700;
+enum IE8 = 0x0800;
+enum IE9 = 0x0900;
+enum IE10 = 0x0A00;
+
/* These version identifiers are used to specify the minimum version of Windows that an
* application will support.
*
@@ -23,62 +56,64 @@ enum __W32API_MINOR_VERSION = 17;
* Windows 9x is no longer supported, either by Microsoft or by DMD, this distinction has been
* removed in order to simplify the bindings.
*/
- version (Windows10) {
- enum uint _WIN32_WINNT = 0xA00;
+version (Windows11) {
+ enum uint _WIN32_WINNT = _WIN32_WINNT_WIN10;
+} else version (Windows10) {
+ enum uint _WIN32_WINNT = _WIN32_WINNT_WIN10;
} else version (Windows8_1) { // also Windows2012R2
- enum uint _WIN32_WINNT = 0x603;
+ enum uint _WIN32_WINNT = _WIN32_WINNT_WINBLUE;
} else version (Windows8) { // also Windows2012
- enum uint _WIN32_WINNT = 0x602;
+ enum uint _WIN32_WINNT = _WIN32_WINNT_WIN8;
} else version (Windows7) { // also Windows2008R2
- enum uint _WIN32_WINNT = 0x601;
+ enum uint _WIN32_WINNT = _WIN32_WINNT_WIN7;
} else version (WindowsVista) { // also Windows2008
- enum uint _WIN32_WINNT = 0x600;
+ enum uint _WIN32_WINNT = _WIN32_WINNT_VISTA;
} else version (Windows2003) { // also WindowsHomeServer, WindowsXP64
- enum uint _WIN32_WINNT = 0x502;
+ enum uint _WIN32_WINNT = _WIN32_WINNT_WS03;
} else version (WindowsXP) {
- enum uint _WIN32_WINNT = 0x501;
+ enum uint _WIN32_WINNT = _WIN32_WINNT_WINXP;
} else version (Windows2000) {
// Current DMD doesn't support any version of Windows older than XP,
// but third-party compilers could use this
- enum uint _WIN32_WINNT = 0x500;
+ enum uint _WIN32_WINNT = _WIN32_WINNT_WIN2K;
} else {
- enum uint _WIN32_WINNT = 0x601;
+ enum uint _WIN32_WINNT = _WIN32_WINNT_WIN7;
}
version (IE11) {
- enum uint _WIN32_IE = 0xA00;
+ enum uint _WIN32_IE = _WIN32_IE_IE110;
} else version (IE10) {
- enum uint _WIN32_IE = 0xA00;
+ enum uint _WIN32_IE = _WIN32_IE_IE100;
} else version (IE9) {
- enum uint _WIN32_IE = 0x900;
+ enum uint _WIN32_IE = _WIN32_IE_IE90;
} else version (IE8) {
- enum uint _WIN32_IE = 0x800;
+ enum uint _WIN32_IE = _WIN32_IE_IE80;
} else version (IE7) {
- enum uint _WIN32_IE = 0x700;
+ enum uint _WIN32_IE = _WIN32_IE_IE70;
} else version (IE602) {
- enum uint _WIN32_IE = 0x603;
+ enum uint _WIN32_IE = _WIN32_IE_IE60SP2;
} else version (IE601) {
- enum uint _WIN32_IE = 0x601;
+ enum uint _WIN32_IE = _WIN32_IE_IE60SP1;
} else version (IE6) {
- enum uint _WIN32_IE = 0x600;
+ enum uint _WIN32_IE = _WIN32_IE_IE60;
} else version (IE56) {
- enum uint _WIN32_IE = 0x560;
+ enum uint _WIN32_IE = _WIN32_IE_IE60;
} else version (IE55) {
- enum uint _WIN32_IE = 0x550;
+ enum uint _WIN32_IE = _WIN32_IE_IE55;
} else version (IE501) {
- enum uint _WIN32_IE = 0x501;
+ enum uint _WIN32_IE = _WIN32_IE_IE501;
} else version (IE5) {
- enum uint _WIN32_IE = 0x500;
+ enum uint _WIN32_IE = _WIN32_IE_IE50;
} else version (IE401) {
- enum uint _WIN32_IE = 0x401;
+ enum uint _WIN32_IE = _WIN32_IE_IE401;
} else version (IE4) {
- enum uint _WIN32_IE = 0x400;
+ enum uint _WIN32_IE = _WIN32_IE_IE40;
} else version (IE3) {
- enum uint _WIN32_IE = 0x300;
-} else static if (_WIN32_WINNT >= 0x500) {
- enum uint _WIN32_IE = 0x600;
-} else static if (_WIN32_WINNT >= 0x410) {
- enum uint _WIN32_IE = 0x400;
+ enum uint _WIN32_IE = _WIN32_IE_IE30;
+} else static if (_WIN32_WINNT >= _WIN32_WINNT_WIN2K) {
+ enum uint _WIN32_IE = _WIN32_IE_IE60;
+} else static if (_WIN32_WINNT >= Windows98) { //NOTE: _WIN32_WINNT will never be set this low
+ enum uint _WIN32_IE = _WIN32_IE_IE40;
} else {
enum uint _WIN32_IE = 0;
}
diff --git a/libphobos/libdruntime/core/sys/windows/winbase.d b/libphobos/libdruntime/core/sys/windows/winbase.d
index a30035c..935c7c4 100644
--- a/libphobos/libdruntime/core/sys/windows/winbase.d
+++ b/libphobos/libdruntime/core/sys/windows/winbase.d
@@ -1789,8 +1789,8 @@ extern (Windows) nothrow @nogc {
alias RtlMoveMemory = memmove;
alias RtlCopyMemory = memcpy;
- pragma(inline, true) void RtlFillMemory(PVOID Destination, SIZE_T Length, BYTE Fill) { memset(Destination, Fill, Length); }
- pragma(inline, true) void RtlZeroMemory(PVOID Destination, SIZE_T Length) { memset(Destination, 0, Length); }
+ pragma(inline, true) void RtlFillMemory(PVOID Destination, SIZE_T Length, BYTE Fill) pure { memset(Destination, Fill, Length); }
+ pragma(inline, true) void RtlZeroMemory(PVOID Destination, SIZE_T Length) pure { memset(Destination, 0, Length); }
alias MoveMemory = RtlMoveMemory;
alias CopyMemory = RtlCopyMemory;
alias FillMemory = RtlFillMemory;
diff --git a/libphobos/libdruntime/core/thread/osthread.d b/libphobos/libdruntime/core/thread/osthread.d
index e08e4a1..c1cd42b 100644
--- a/libphobos/libdruntime/core/thread/osthread.d
+++ b/libphobos/libdruntime/core/thread/osthread.d
@@ -10,9 +10,6 @@
* Source: $(DRUNTIMESRC core/thread/osthread.d)
*/
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
module core.thread.osthread;
import core.atomic;
@@ -37,10 +34,6 @@ else version (TVOS)
else version (WatchOS)
version = Darwin;
-version (Shared)
- version (GNU)
- version = GNUShared;
-
version (D_InlineAsm_X86)
{
version (Windows)
@@ -482,16 +475,8 @@ class Thread : ThreadBase
version (Shared)
{
- version (GNU)
- {
- auto libs = externDFunc!("gcc.sections.pinLoadedLibraries",
- void* function() @nogc nothrow)();
- }
- else
- {
- auto libs = externDFunc!("rt.sections_elf_shared.pinLoadedLibraries",
- void* function() @nogc nothrow)();
- }
+ auto libs = externDFunc!("rt.sections_elf_shared.pinLoadedLibraries",
+ void* function() @nogc nothrow)();
auto ps = cast(void**).malloc(2 * size_t.sizeof);
if (ps is null) onOutOfMemoryError();
@@ -499,16 +484,8 @@ class Thread : ThreadBase
ps[1] = cast(void*)libs;
if ( pthread_create( &m_addr, &attr, &thread_entryPoint, ps ) != 0 )
{
- version (GNU)
- {
- externDFunc!("gcc.sections.unpinLoadedLibraries",
- void function(void*) @nogc nothrow)(libs);
- }
- else
- {
- externDFunc!("rt.sections_elf_shared.unpinLoadedLibraries",
- void function(void*) @nogc nothrow)(libs);
- }
+ externDFunc!("rt.sections_elf_shared.unpinLoadedLibraries",
+ void function(void*) @nogc nothrow)(libs);
.free(ps);
onThreadError( "Error creating thread" );
}
@@ -1562,7 +1539,7 @@ private extern(D) void* getStackBottom() nothrow @nogc
else version (X86_64)
asm pure nothrow @nogc { "movq %%gs:8, %0;" : "=r" (bottom); }
else
- static assert(false, "Platform not supported.");
+ static assert(false, "Architecture not supported.");
return bottom;
}
@@ -2232,12 +2209,7 @@ else version (Posix)
// loadedLibraries need to be inherited from parent thread
// before initilizing GC for TLS (rt_tlsgc_init)
- version (GNUShared)
- {
- externDFunc!("gcc.sections.inheritLoadedLibraries",
- void function(void*) @nogc nothrow)(loadedLibraries);
- }
- else version (Shared)
+ version (Shared)
{
externDFunc!("rt.sections_elf_shared.inheritLoadedLibraries",
void function(void*) @nogc nothrow)(loadedLibraries);
@@ -2319,12 +2291,7 @@ else version (Posix)
append( t );
}
rt_moduleTlsDtor();
- version (GNUShared)
- {
- externDFunc!("gcc.sections.cleanupLoadedLibraries",
- void function() @nogc nothrow)();
- }
- else version (Shared)
+ version (Shared)
{
externDFunc!("rt.sections_elf_shared.cleanupLoadedLibraries",
void function() @nogc nothrow)();
@@ -2801,16 +2768,8 @@ private size_t adjustStackSize(size_t sz) nothrow @nogc
version (CRuntime_Glibc)
{
// On glibc, TLS uses the top of the stack, so add its size to the requested size
- version (GNU)
- {
- sz += externDFunc!("gcc.sections.elf.sizeOfTLS",
- size_t function() @nogc nothrow)();
- }
- else
- {
- sz += externDFunc!("rt.sections_elf_shared.sizeOfTLS",
- size_t function() @nogc nothrow)();
- }
+ sz += externDFunc!("rt.sections_elf_shared.sizeOfTLS",
+ size_t function() @nogc nothrow)();
}
// stack size must be a multiple of pageSize
diff --git a/libphobos/libdruntime/gcc/sections/elf.d b/libphobos/libdruntime/gcc/sections/elf.d
index bbebedf..6d8b843 100644
--- a/libphobos/libdruntime/gcc/sections/elf.d
+++ b/libphobos/libdruntime/gcc/sections/elf.d
@@ -181,7 +181,7 @@ alias ScanDG = void delegate(void* pbeg, void* pend) nothrow;
version (Shared)
{
import gcc.sections : pinLoadedLibraries, unpinLoadedLibraries,
- inheritLoadedLibraries, cleanupLoadedLibraries;
+ inheritLoadedLibraries, cleanupLoadedLibraries, sizeOfTLS;
/***
* Called once per thread; returns array of thread local storage ranges
@@ -213,6 +213,7 @@ version (Shared)
}
}
+ pragma(mangle, gcc.sections.sizeOfTLS.mangleof)
size_t sizeOfTLS() nothrow @nogc
{
auto tdsos = initTLSRanges();
@@ -295,6 +296,8 @@ version (Shared)
}
else
{
+ import gcc.sections : sizeOfTLS;
+
/***
* Called once per thread; returns array of thread local storage ranges
*/
@@ -328,6 +331,7 @@ else
}
}
+ pragma(mangle, gcc.sections.sizeOfTLS.mangleof)
size_t sizeOfTLS() nothrow @nogc
{
auto rngs = initTLSRanges();
diff --git a/libphobos/libdruntime/gcc/sections/package.d b/libphobos/libdruntime/gcc/sections/package.d
index b003c31..b41cb28 100644
--- a/libphobos/libdruntime/gcc/sections/package.d
+++ b/libphobos/libdruntime/gcc/sections/package.d
@@ -42,11 +42,32 @@ else version (SectionsPeCoff)
else
static assert(0, "unimplemented");
+import core.internal.traits : externDFunc;
+
version (Shared)
{
- // interface for core.thread to inherit loaded libraries
- void* pinLoadedLibraries() nothrow @nogc;
- void unpinLoadedLibraries(void* p) nothrow @nogc;
- void inheritLoadedLibraries(void* p) nothrow @nogc;
- void cleanupLoadedLibraries() nothrow @nogc;
+ // interface for core.thread.osthread to inherit loaded libraries
+ pragma(mangle, externDFunc!("rt.sections_elf_shared.pinLoadedLibraries",
+ void* function() @nogc nothrow).mangleof)
+ void* pinLoadedLibraries() @nogc nothrow;
+
+ pragma(mangle, externDFunc!("rt.sections_elf_shared.unpinLoadedLibraries",
+ void function(void*) @nogc nothrow).mangleof)
+ void unpinLoadedLibraries(void* p) @nogc nothrow;
+
+ pragma(mangle, externDFunc!("rt.sections_elf_shared.inheritLoadedLibraries",
+ void function(void*) @nogc nothrow).mangleof)
+ void inheritLoadedLibraries(void* p) @nogc nothrow;
+
+ pragma(mangle, externDFunc!("rt.sections_elf_shared.cleanupLoadedLibraries",
+ void function() @nogc nothrow).mangleof)
+ void cleanupLoadedLibraries() @nogc nothrow;
+}
+
+version (SectionsElf)
+{
+ // interface for core.thread.osthread to adjust stack size
+ pragma(mangle, externDFunc!("rt.sections_elf_shared.sizeOfTLS",
+ size_t function() @nogc nothrow).mangleof)
+ size_t sizeOfTLS() @nogc nothrow;
}
diff --git a/libphobos/libdruntime/rt/adi.d b/libphobos/libdruntime/rt/adi.d
index ece0f4b..02e4d77 100644
--- a/libphobos/libdruntime/rt/adi.d
+++ b/libphobos/libdruntime/rt/adi.d
@@ -11,12 +11,9 @@
module rt.adi;
-//debug=adi; // uncomment to turn on debugging printf's
+// debug = adi; // uncomment to turn on debugging printf's
-private
-{
- debug(adi) import core.stdc.stdio;
-}
+debug (adi) import core.stdc.stdio : printf;
/***************************************
* Support for array equality test.
diff --git a/libphobos/libdruntime/rt/arraycat.d b/libphobos/libdruntime/rt/arraycat.d
index 0ab785b..a443c9b 100644
--- a/libphobos/libdruntime/rt/arraycat.d
+++ b/libphobos/libdruntime/rt/arraycat.d
@@ -10,12 +10,12 @@
module rt.arraycat;
-private
-{
- import core.stdc.string;
- import core.internal.util.array;
- debug(PRINTF) import core.stdc.stdio;
-}
+// debug = PRINTF;
+
+import core.internal.util.array;
+import core.stdc.string : memcpy;
+
+debug(PRINTF) import core.stdc.stdio : printf;
extern (C) @trusted nothrow:
diff --git a/libphobos/libdruntime/rt/deh.d b/libphobos/libdruntime/rt/deh.d
index 0a44be3..cb80c76 100644
--- a/libphobos/libdruntime/rt/deh.d
+++ b/libphobos/libdruntime/rt/deh.d
@@ -33,10 +33,6 @@
* Authors: Walter Bright
* Source: $(DRUNTIMESRC rt/deh.d)
*/
-
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
module rt.deh;
extern (C)
diff --git a/libphobos/libdruntime/rt/dmain2.d b/libphobos/libdruntime/rt/dmain2.d
index a1ddba5..f1e9491 100644
--- a/libphobos/libdruntime/rt/dmain2.d
+++ b/libphobos/libdruntime/rt/dmain2.d
@@ -9,27 +9,26 @@
* Source: $(DRUNTIMESRC rt/_dmain2.d)
*/
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
module rt.dmain2;
-import rt.memory;
-import rt.sections;
import core.atomic;
-import core.stdc.stddef;
-import core.stdc.stdlib;
-import core.stdc.string;
-import core.stdc.stdio; // for printf()
+import core.internal.parseoptions : rt_parseOption;
import core.stdc.errno : errno;
+import core.stdc.stdio : fflush, fprintf, fwrite, stderr, stdout;
+import core.stdc.stdlib : alloca, EXIT_FAILURE, EXIT_SUCCESS, free, malloc, realloc;
+import core.stdc.string : strerror;
+import rt.config : rt_cmdline_enabled, rt_configOption;
+import rt.memory;
+import rt.sections;
version (Windows)
{
- import core.stdc.wchar_;
+ import core.stdc.stdio : fileno;
+ import core.stdc.wchar_ : wcslen;
import core.sys.windows.basetsd : HANDLE;
import core.sys.windows.shellapi : CommandLineToArgvW;
- import core.sys.windows.winbase : FreeLibrary, GetCommandLineW, GetProcAddress,
- IsDebuggerPresent, LoadLibraryW, LocalFree, WriteFile;
+ import core.sys.windows.winbase : FreeLibrary, GetCommandLineW, GetProcAddress, IsDebuggerPresent, LoadLibraryW,
+ LocalFree, WriteFile;
import core.sys.windows.wincon : CONSOLE_SCREEN_BUFFER_INFO, GetConsoleOutputCP,
GetConsoleScreenBufferInfo;
import core.sys.windows.winnls : CP_UTF8, MultiByteToWideChar, WideCharToMultiByte;
@@ -37,19 +36,12 @@ version (Windows)
import core.sys.windows.winuser : MB_ICONERROR, MessageBoxW;
pragma(lib, "shell32.lib"); // needed for CommandLineToArgvW
-}
-version (FreeBSD)
-{
- import core.stdc.fenv;
-}
-version (NetBSD)
-{
- import core.stdc.fenv;
+ import core.stdc.stdio : _get_osfhandle;
}
-version (DragonFlyBSD)
+else version (Posix)
{
- import core.stdc.fenv;
+ import core.stdc.string : strlen;
}
// not sure why we can't define this in one place, but this is to keep this
@@ -447,7 +439,6 @@ private extern (C) int _d_run_main2(char[][] args, size_t totalArgsLength, MainF
char[][] argsCopy = buff[0 .. args.length];
auto argBuff = cast(char*) (buff + args.length);
size_t j = 0;
- import rt.config : rt_cmdline_enabled;
bool parseOpts = rt_cmdline_enabled!();
foreach (arg; args)
{
@@ -590,8 +581,6 @@ private void formatThrowable(Throwable t, scope void delegate(in char[] s) nothr
private auto parseExceptionOptions()
{
- import rt.config : rt_configOption;
- import core.internal.parseoptions : rt_parseOption;
const optName = "trapExceptions";
auto option = rt_configOption(optName);
auto trap = rt_trapExceptions;
diff --git a/libphobos/libdruntime/rt/ehalloc.d b/libphobos/libdruntime/rt/ehalloc.d
index 65f92e3..7c3f06c 100644
--- a/libphobos/libdruntime/rt/ehalloc.d
+++ b/libphobos/libdruntime/rt/ehalloc.d
@@ -13,10 +13,7 @@ module rt.ehalloc;
//debug = PRINTF;
-debug(PRINTF)
-{
- import core.stdc.stdio;
-}
+debug (PRINTF) import core.stdc.stdio : printf;
/********************************************
diff --git a/libphobos/libdruntime/rt/lifetime.d b/libphobos/libdruntime/rt/lifetime.d
index 71ed51b..3558674 100644
--- a/libphobos/libdruntime/rt/lifetime.d
+++ b/libphobos/libdruntime/rt/lifetime.d
@@ -13,11 +13,17 @@
module rt.lifetime;
import core.attribute : weak;
-import core.memory;
+import core.checkedint : mulu;
+import core.exception : onFinalizeError, onOutOfMemoryError, onUnicodeError;
import core.internal.gc.blockmeta : PAGESIZE;
-debug(PRINTF) import core.stdc.stdio;
+import core.memory;
+import core.stdc.stdlib : malloc;
+import core.stdc.string : memcpy, memset;
static import rt.tlsgc;
+debug (PRINTF) import core.stdc.stdio : printf;
+debug (VALGRIND) import etc.valgrind.valgrind;
+
alias BlkInfo = GC.BlkInfo;
alias BlkAttr = GC.BlkAttr;
@@ -81,8 +87,6 @@ Returns: newly created object
*/
extern (C) Object _d_newclass(const ClassInfo ci) @weak
{
- import core.stdc.stdlib;
- import core.exception : onOutOfMemoryError;
void* p;
auto init = ci.initializer;
@@ -268,7 +272,6 @@ extern(C) void _d_arrayshrinkfit(const TypeInfo ti, void[] arr) nothrow
}
catch (Exception e)
{
- import core.exception : onFinalizeError;
onFinalizeError(sti, e);
}
}
@@ -336,9 +339,6 @@ in
}
do
{
- import core.stdc.string;
- import core.exception : onOutOfMemoryError;
-
auto isshared = typeid(ti) is typeid(TypeInfo_Shared);
auto tinext = unqualify(ti.next);
auto size = tinext.tsize;
@@ -368,8 +368,6 @@ do
}
else
{
- import core.checkedint : mulu;
-
bool overflow = false;
size_t reqsize = mulu(size, newcapacity, overflow);
if (!overflow)
@@ -444,8 +442,6 @@ Returns: newly allocated array
*/
extern (C) void[] _d_newarrayU(const scope TypeInfo ti, size_t length) pure nothrow @weak
{
- import core.exception : onOutOfMemoryError;
-
auto tinext = unqualify(ti.next);
auto size = tinext.tsize;
@@ -475,8 +471,6 @@ extern (C) void[] _d_newarrayU(const scope TypeInfo ti, size_t length) pure noth
}
else
{
- import core.checkedint : mulu;
-
bool overflow = false;
size = mulu(size, length, overflow);
if (!overflow)
@@ -497,8 +491,6 @@ Lcontinue:
/// ditto
extern (C) void[] _d_newarrayT(const TypeInfo ti, size_t length) pure nothrow @weak
{
- import core.stdc.string;
-
void[] result = _d_newarrayU(ti, length);
auto tinext = unqualify(ti.next);
auto size = tinext.tsize;
@@ -533,7 +525,6 @@ extern (C) void[] _d_newarrayiT(const TypeInfo ti, size_t length) pure nothrow @
default:
{
- import core.stdc.string;
immutable sz = init.length;
for (size_t u = 0; u < size * length; u += sz)
memcpy(result.ptr + u, init.ptr, sz);
@@ -650,8 +641,6 @@ extern (C) int rt_hasFinalizerInSegment(void* p, size_t size, uint attr, scope c
return false;
}
-debug (VALGRIND) import etc.valgrind.valgrind;
-
void finalize_array(void* p, size_t size, const TypeInfo_Struct si)
{
// Due to the fact that the delete operator calls destructors
@@ -676,7 +665,6 @@ void finalize_struct(void* p, TypeInfo_Struct ti) nothrow
}
catch (Exception e)
{
- import core.exception : onFinalizeError;
onFinalizeError(ti, e);
}
}
@@ -717,7 +705,6 @@ extern (C) void rt_finalize2(void* p, bool det = true, bool resetMemory = true)
}
catch (Exception e)
{
- import core.exception : onFinalizeError;
onFinalizeError(*pc, e);
}
finally
@@ -760,7 +747,6 @@ extern (C) void rt_finalizeFromGC(void* p, size_t size, uint attr) nothrow
}
catch (Exception e)
{
- import core.exception : onFinalizeError;
onFinalizeError(si, e);
}
}
@@ -801,9 +787,6 @@ in
}
do
{
- import core.stdc.string;
- import core.exception : onOutOfMemoryError;
-
debug(PRINTF)
{
//printf("_d_arraysetlengthT(p = %p, sizeelem = %d, newlength = %d)\n", p, sizeelem, newlength);
@@ -848,7 +831,6 @@ do
}
else
{
- import core.checkedint : mulu;
const size_t newsize = mulu(sizeelem, newlength, overflow);
}
if (overflow)
@@ -911,9 +893,6 @@ in
}
do
{
- import core.stdc.string;
- import core.exception : onOutOfMemoryError;
-
debug(PRINTF)
{
//printf("_d_arraysetlengthT(p = %p, sizeelem = %d, newlength = %d)\n", p, sizeelem, newlength);
@@ -958,7 +937,6 @@ do
}
else
{
- import core.checkedint : mulu;
const size_t newsize = mulu(sizeelem, newlength, overflow);
}
if (overflow)
@@ -1111,8 +1089,6 @@ Returns: `px` after being appended to
extern (C)
byte[] _d_arrayappendcTX(const TypeInfo ti, return scope ref byte[] px, size_t n) @weak
{
- import core.stdc.string;
- import core.exception : onOutOfMemoryError;
// This is a cut&paste job from _d_arrayappendT(). Should be refactored.
// Short circuit if no data is being appended.
@@ -1218,7 +1194,6 @@ extern (C) void[] _d_arrayappendcd(ref byte[] x, dchar c) @weak
}
else
{
- import core.exception : onUnicodeError;
onUnicodeError("Invalid UTF-8 sequence", 0); // invalid utf character
}
diff --git a/libphobos/libdruntime/rt/minfo.d b/libphobos/libdruntime/rt/minfo.d
index 9bc1055..6e9cd1c8 100644
--- a/libphobos/libdruntime/rt/minfo.d
+++ b/libphobos/libdruntime/rt/minfo.d
@@ -12,10 +12,13 @@
module rt.minfo;
-import core.stdc.stdlib; // alloca
-import core.stdc.string; // memcpy
+import core.stdc.stdio : fprintf, stderr;
+import core.stdc.stdlib : free, malloc, realloc;
+import core.stdc.string : memcpy, memset;
import rt.sections;
+debug (printModuleDependencies) import core.stdc.stdio : printf;
+
enum
{
MIctorstart = 0x1, // we've started constructing it
@@ -179,7 +182,6 @@ struct ModuleGroup
switch (cycleHandling) with(OnCycle)
{
case "deprecate":
- import core.stdc.stdio : fprintf, stderr;
// Option deprecated in 2.101, remove in 2.111
fprintf(stderr, "`--DRT-oncycle=deprecate` is no longer supported, using `abort` instead\n");
break;
@@ -202,8 +204,6 @@ struct ModuleGroup
debug (printModuleDependencies)
{
- import core.stdc.stdio : printf;
-
foreach (_m; _modules)
{
printf("%s%s%s:", _m.name.ptr, (_m.flags & MIstandalone)
@@ -375,7 +375,6 @@ struct ModuleGroup
case print:
// print the message
buildCycleMessage(idx, midx, (string x) {
- import core.stdc.stdio : fprintf, stderr;
fprintf(stderr, "%.*s", cast(int) x.length, x.ptr);
});
// continue on as if this is correct.
@@ -518,7 +517,6 @@ struct ModuleGroup
!doSort(MItlsctor | MItlsdtor, _tlsctors))
{
// print a warning
- import core.stdc.stdio : fprintf, stderr;
fprintf(stderr, "Deprecation 16211 warning:\n"
~ "A cycle has been detected in your program that was undetected prior to DMD\n"
~ "2.072. This program will continue, but will not operate when using DMD 2.074\n"
diff --git a/libphobos/libdruntime/rt/monitor_.d b/libphobos/libdruntime/rt/monitor_.d
index 5d6c2f8..1d4ed2e 100644
--- a/libphobos/libdruntime/rt/monitor_.d
+++ b/libphobos/libdruntime/rt/monitor_.d
@@ -8,7 +8,26 @@
*/
module rt.monitor_;
-import core.atomic, core.stdc.stdlib, core.stdc.string;
+import core.atomic;
+import core.stdc.stdlib : calloc, free, realloc;
+import core.stdc.string : memmove;
+
+version (Windows)
+{
+ import core.sys.windows.winbase /+: CRITICAL_SECTION, DeleteCriticalSection,
+ EnterCriticalSection, InitializeCriticalSection, LeaveCriticalSection+/;
+}
+else version (Posix)
+{
+ import core.sys.posix.pthread : pthread_mutex_destroy, pthread_mutex_init, pthread_mutex_lock,
+ PTHREAD_MUTEX_RECURSIVE, pthread_mutex_unlock, pthread_mutexattr_destroy, pthread_mutexattr_init,
+ pthread_mutexattr_settype;
+ import core.sys.posix.sys.types : pthread_mutex_t, pthread_mutexattr_t;
+}
+else
+{
+ static assert(0, "Unsupported platform");
+}
// NOTE: The dtor callback feature is only supported for monitors that are not
// supplied by the user. The assumption is that any object with a user-
@@ -173,9 +192,6 @@ alias DEvent = void delegate(Object);
version (Windows)
{
- import core.sys.windows.winbase /+: CRITICAL_SECTION, DeleteCriticalSection,
- EnterCriticalSection, InitializeCriticalSection, LeaveCriticalSection+/;
-
alias Mutex = CRITICAL_SECTION;
alias initMutex = InitializeCriticalSection;
@@ -185,11 +201,6 @@ version (Windows)
}
else version (Posix)
{
- import core.sys.posix.pthread : pthread_mutex_destroy, pthread_mutex_init, pthread_mutex_lock,
- PTHREAD_MUTEX_RECURSIVE, pthread_mutex_unlock, pthread_mutexattr_destroy, pthread_mutexattr_init,
- pthread_mutexattr_settype;
- import core.sys.posix.sys.types : pthread_mutex_t, pthread_mutexattr_t;
-
@nogc:
alias Mutex = pthread_mutex_t;
__gshared pthread_mutexattr_t gattr;
@@ -214,10 +225,6 @@ else version (Posix)
pthread_mutex_unlock(mtx) && assert(0);
}
}
-else
-{
- static assert(0, "Unsupported platform");
-}
struct Monitor
{
@@ -229,6 +236,8 @@ struct Monitor
private:
+__gshared Mutex gmtx;
+
@property ref shared(Monitor*) monitor(return scope Object h) pure nothrow @nogc
{
return *cast(shared Monitor**)&h.__monitor;
@@ -244,8 +253,6 @@ void setMonitor(Object h, shared(Monitor)* m) pure @nogc
atomicStore!(MemoryOrder.rel)(h.monitor, m);
}
-__gshared Mutex gmtx;
-
shared(Monitor)* ensureMonitor(Object h)
{
if (auto m = getMonitor(h))
diff --git a/libphobos/libdruntime/rt/profilegc.d b/libphobos/libdruntime/rt/profilegc.d
index b97a5c5..e7d4f03 100644
--- a/libphobos/libdruntime/rt/profilegc.d
+++ b/libphobos/libdruntime/rt/profilegc.d
@@ -15,10 +15,9 @@ module rt.profilegc;
private:
-import core.stdc.errno;
-import core.stdc.stdio;
-import core.stdc.stdlib;
-import core.stdc.string;
+import core.stdc.errno : errno;
+import core.stdc.stdio : fclose, FILE, fopen, fprintf, snprintf, stderr, stdout;
+import core.stdc.stdlib : free, malloc, qsort, realloc;
import core.exception : onOutOfMemoryError;
import core.internal.container.hashtab;
diff --git a/libphobos/libdruntime/rt/sections.d b/libphobos/libdruntime/rt/sections.d
index a7b75d4ba..ce5a668 100644
--- a/libphobos/libdruntime/rt/sections.d
+++ b/libphobos/libdruntime/rt/sections.d
@@ -8,9 +8,6 @@
* Source: $(DRUNTIMESRC rt/_sections.d)
*/
-/* NOTE: This file has been patched from the original DMD distribution to
- * work with the GDC compiler.
- */
module rt.sections;
version (OSX)
diff --git a/libphobos/libdruntime/rt/tlsgc.d b/libphobos/libdruntime/rt/tlsgc.d
index f1dcc59..2b21d1e 100644
--- a/libphobos/libdruntime/rt/tlsgc.d
+++ b/libphobos/libdruntime/rt/tlsgc.d
@@ -13,9 +13,9 @@
*/
module rt.tlsgc;
-import core.stdc.stdlib;
-
-static import rt.lifetime, rt.sections;
+import core.exception : onOutOfMemoryError;
+import core.stdc.stdlib : free, malloc;
+static import rt.sections;
/**
* Per thread record to store thread associated data for garbage collection.
@@ -32,8 +32,7 @@ struct Data
void* init() nothrow @nogc
{
auto data = cast(Data*).malloc(Data.sizeof);
- import core.exception;
- if ( data is null ) core.exception.onOutOfMemoryError();
+ if ( data is null ) onOutOfMemoryError();
*data = Data.init;
// do module specific initialization