Skip to content

Commit 408c468

Browse files
authored
Merge pull request #8122 from WalterBright/merge-super
refactor: merge redundant super() and this() code
2 parents 190e2e0 + 5e6a3d8 commit 408c468

File tree

1 file changed

+25
-48
lines changed

1 file changed

+25
-48
lines changed

src/dmd/expressionsem.d

Lines changed: 25 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -3249,81 +3249,58 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
32493249
}
32503250
t1 = exp.e1.type;
32513251
}
3252-
else if (exp.e1.op == TOK.super_)
3252+
else if (exp.e1.op == TOK.super_ || exp.e1.op == TOK.this_)
32533253
{
3254-
// Base class constructor call
32553254
auto ad = sc.func ? sc.func.isThis() : null;
32563255
auto cd = ad ? ad.isClassDeclaration() : null;
3257-
if (!cd || !cd.baseClass || !sc.func.isCtorDeclaration())
3258-
{
3259-
exp.error("super class constructor call must be in a constructor");
3260-
return setError();
3261-
}
3262-
if (!cd.baseClass.ctor)
3263-
{
3264-
exp.error("no super class constructor for `%s`", cd.baseClass.toChars());
3265-
return setError();
3266-
}
32673256

3268-
if (!sc.intypeof)
3257+
const bool isSuper = exp.e1.op == TOK.super_;
3258+
if (isSuper)
32693259
{
3270-
if (sc.noctor || sc.ctorflow.callSuper & CSX.label)
3271-
exp.error("constructor calls not allowed in loops or after labels");
3272-
if (sc.ctorflow.callSuper & (CSX.super_ctor | CSX.this_ctor))
3273-
exp.error("multiple constructor calls");
3274-
if ((sc.ctorflow.callSuper & CSX.return_) && !(sc.ctorflow.callSuper & CSX.any_ctor))
3275-
exp.error("an earlier `return` statement skips constructor");
3276-
sc.ctorflow.callSuper |= CSX.any_ctor | CSX.super_ctor;
3260+
// Base class constructor call
3261+
if (!cd || !cd.baseClass || !sc.func.isCtorDeclaration())
3262+
{
3263+
exp.error("super class constructor call must be in a constructor");
3264+
return setError();
3265+
}
3266+
if (!cd.baseClass.ctor)
3267+
{
3268+
exp.error("no super class constructor for `%s`", cd.baseClass.toChars());
3269+
return setError();
3270+
}
32773271
}
3278-
3279-
tthis = cd.type.addMod(sc.func.type.mod);
3280-
if (auto os = cd.baseClass.ctor.isOverloadSet())
3281-
exp.f = resolveOverloadSet(exp.loc, sc, os, null, tthis, exp.arguments);
32823272
else
3283-
exp.f = resolveFuncCall(exp.loc, sc, cd.baseClass.ctor, null, tthis, exp.arguments, 0);
3284-
3285-
if (!exp.f || exp.f.errors)
3286-
return setError();
3287-
3288-
checkFunctionAttributes(exp, sc, exp.f);
3289-
checkAccess(exp.loc, sc, null, exp.f);
3290-
3291-
exp.e1 = new DotVarExp(exp.e1.loc, exp.e1, exp.f, false);
3292-
exp.e1 = exp.e1.expressionSemantic(sc);
3293-
t1 = exp.e1.type;
3294-
}
3295-
else if (exp.e1.op == TOK.this_)
3296-
{
3297-
// same class constructor call
3298-
auto ad = sc.func ? sc.func.isThis() : null;
3299-
if (!ad || !sc.func.isCtorDeclaration())
33003273
{
3301-
exp.error("constructor call must be in a constructor");
3302-
return setError();
3274+
if (!ad || !sc.func.isCtorDeclaration())
3275+
{
3276+
exp.error("constructor call must be in a constructor");
3277+
return setError();
3278+
}
33033279
}
33043280

3305-
if (!sc.intypeof)
3281+
if (!sc.intypeof /*&& !(sc.ctorflow.callSuper & CSX.halt)*/)
33063282
{
33073283
if (sc.noctor || sc.ctorflow.callSuper & CSX.label)
33083284
exp.error("constructor calls not allowed in loops or after labels");
33093285
if (sc.ctorflow.callSuper & (CSX.super_ctor | CSX.this_ctor))
33103286
exp.error("multiple constructor calls");
33113287
if ((sc.ctorflow.callSuper & CSX.return_) && !(sc.ctorflow.callSuper & CSX.any_ctor))
33123288
exp.error("an earlier `return` statement skips constructor");
3313-
sc.ctorflow.callSuper |= CSX.any_ctor | CSX.this_ctor;
3289+
sc.ctorflow.callSuper |= CSX.any_ctor | (isSuper ? CSX.super_ctor : CSX.this_ctor);
33143290
}
33153291

33163292
tthis = ad.type.addMod(sc.func.type.mod);
3317-
if (auto os = ad.ctor.isOverloadSet())
3293+
auto ctor = isSuper ? cd.baseClass.ctor : ad.ctor;
3294+
if (auto os = ctor.isOverloadSet())
33183295
exp.f = resolveOverloadSet(exp.loc, sc, os, null, tthis, exp.arguments);
33193296
else
3320-
exp.f = resolveFuncCall(exp.loc, sc, ad.ctor, null, tthis, exp.arguments, 0);
3297+
exp.f = resolveFuncCall(exp.loc, sc, ctor, null, tthis, exp.arguments, 0);
33213298

33223299
if (!exp.f || exp.f.errors)
33233300
return setError();
33243301

33253302
checkFunctionAttributes(exp, sc, exp.f);
3326-
//checkAccess(loc, sc, NULL, f); // necessary?
3303+
checkAccess(exp.loc, sc, null, exp.f);
33273304

33283305
exp.e1 = new DotVarExp(exp.e1.loc, exp.e1, exp.f, false);
33293306
exp.e1 = exp.e1.expressionSemantic(sc);

0 commit comments

Comments
 (0)