Skip to content

Commit

Permalink
issue 5710 - POC
Browse files Browse the repository at this point in the history
  • Loading branch information
SSoulaimane committed Jan 27, 2019
1 parent 7c39734 commit 7a9c5d7
Show file tree
Hide file tree
Showing 6 changed files with 99 additions and 8 deletions.
2 changes: 1 addition & 1 deletion src/dmd/dmangle.d
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,7 @@ public:
{
Dsymbol p;
if (TemplateInstance ti = s.isTemplateInstance())
p = ti.isTemplateMixin() ? ti.parent : ti.tempdecl.parent;
p = ti.isTemplateMixin() ? ti.parent : ti.vthis ? ti.vthis : ti.tempdecl.parent;
else
p = s.parent;
if (p)
Expand Down
4 changes: 3 additions & 1 deletion src/dmd/dtemplate.d
Original file line number Diff line number Diff line change
Expand Up @@ -5934,6 +5934,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol

Dsymbol tempdecl; // referenced by foo.bar.abc
Dsymbol enclosing; // if referencing local symbols, this is the context
VarDeclaration vthis; // 'this' parameter (member function)
Dsymbol aliasdecl; // !=null if instance is an alias for its sole member
TemplateInstance inst; // refer to existing instance
ScopeDsymbol argsym; // argument symbol table
Expand Down Expand Up @@ -6228,6 +6229,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
if (!hash)
{
hash = cast(size_t)cast(void*)enclosing;
hash += cast(size_t)cast(void*)vthis;
hash += arrayObjectHash(&tdtypes);
hash += hash == 0;
}
Expand Down Expand Up @@ -7279,7 +7281,7 @@ extern (C++) class TemplateInstance : ScopeDsymbol
if ((td && td.literal) || (ti && ti.enclosing) || (d && !d.isDataseg() && !(d.storage_class & STC.manifest) && (!d.isFuncDeclaration() || d.isFuncDeclaration().isNested()) && !isTemplateMixin()))
{
// if module level template
if (isstatic)
if (1)
{
Dsymbol dparent = sa.toParent2();
if (!dparent)
Expand Down
82 changes: 76 additions & 6 deletions src/dmd/expressionsem.d
Original file line number Diff line number Diff line change
Expand Up @@ -1125,6 +1125,12 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
Dsymbol s;
Objects* tiargs;
Type tthis;
CommaExp ce1;
if (e1.op == TOK.comma)
{
ce1 = cast(CommaExp)e1;
e1 = ce1.e2;
}
if (e1.op == TOK.dot)
{
DotExp de = cast(DotExp)e1;
Expand Down Expand Up @@ -1167,7 +1173,8 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
if (fd)
{
Expression e = new CallExp(loc, e1, e2);
return e.expressionSemantic(sc);
e1 = e.expressionSemantic(sc);
goto Lret;
}
}
{
Expand All @@ -1189,7 +1196,8 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
Expression e = new CallExp(loc, e1);
if (e2)
e = new AssignExp(loc, e, e2);
return e.expressionSemantic(sc);
e1 = e.expressionSemantic(sc);
goto Lret;
}
}
if (e2)
Expand Down Expand Up @@ -1273,7 +1281,8 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
return new ErrorExp();
assert(fd.type.ty == Tfunction);
Expression e = new CallExp(loc, e1, e2);
return e.expressionSemantic(sc);
e1 = e.expressionSemantic(sc);
goto Lret;
}
}
{
Expand All @@ -1289,7 +1298,8 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
Expression e = new CallExp(loc, e1);
if (e2)
e = new AssignExp(loc, e, e2);
return e.expressionSemantic(sc);
e1 = e.expressionSemantic(sc);
goto Lret;
}
}
}
Expand All @@ -1298,7 +1308,8 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
// Keep better diagnostic message for invalid property usage of functions
assert(fd.type.ty == Tfunction);
Expression e = new CallExp(loc, e1, e2);
return e.expressionSemantic(sc);
e1 = e.expressionSemantic(sc);
goto Lret;
}
if (e2)
goto Leprop;
Expand All @@ -1323,7 +1334,8 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
if (ve.var.storage_class & STC.lazy_)
{
Expression e = new CallExp(loc, e1);
return e.expressionSemantic(sc);
e1 = e.expressionSemantic(sc);
goto Lret;
}
}
else if (e1.op == TOK.dotVariable)
Expand Down Expand Up @@ -1351,6 +1363,13 @@ private Expression resolvePropertiesX(Scope* sc, Expression e1, Expression e2 =
error(loc, "cannot resolve type for %s", e1.toChars());
e1 = new ErrorExp();
}

Lret:
if (ce1)
{
ce1.e2 = e1;
e1 = ce1;
}
return e1;

Leprop:
Expand Down Expand Up @@ -2398,6 +2417,13 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
if (s.errors)
return setError();

if (s.isDeclaration() && sc.func && sc.func.vthis2 && isNeedThisScope(sc, s.isDeclaration()))
{
auto exp2 = new DotIdExp(exp.loc, new VarExp(sc.func.vthis2.loc, sc.func.vthis2), exp.ident);
visit(exp2);
return;
}

Expression e;

/* See if the symbol was a member of an enclosing 'with'
Expand Down Expand Up @@ -3938,6 +3964,18 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}

if (exp.e1.op == TOK.comma)
{
/* Rewrite (a,b)(args) as (a,(b(args)))
*/
auto ce = cast(CommaExp)exp.e1;
exp.e1 = ce.e2;
ce.e2 = exp;
ce.type = null;
result = ce.expressionSemantic(sc);
return;
}

/* This recognizes:
* foo!(tiargs)(funcargs)
*/
Expand Down Expand Up @@ -5971,6 +6009,18 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
return;
}

if (exp.e1.op == TOK.comma)
{
/* Rewrite &(a,b) as (a,&b)
*/
auto ce = cast(CommaExp)exp.e1;
exp.e1 = ce.e2;
ce.e2 = exp;
ce.type = null;
result = ce.expressionSemantic(sc);
return;
}

int wasCond = exp.e1.op == TOK.question;

if (exp.e1.op == TOK.dotTemplateInstance)
Expand Down Expand Up @@ -11225,8 +11275,28 @@ Expression semanticY(DotTemplateInstanceExp exp, Scope* sc, int flag)
exp.e1 = dte.e1; // pull semantic() result

exp.ti.tempdecl = dte.td;

if (!exp.ti.semanticTiargs(sc))
return errorExp();

auto td = exp.ti.tempdecl.isTemplateDeclaration();
if (!td.isstatic && td.isMember2() && exp.ti.hasNestedArgs(exp.ti.tiargs, td.isstatic))
{
if (exp.e1.isVarExp())
exp.ti.vthis = exp.e1.isVarExp().var.isVarDeclaration();
else
{
VarDeclaration tmp = copyToTemp(0, "__this", exp.e1);
tmp.dsymbolSemantic(sc);
Expression de = new DeclarationExp(exp.e1.loc, tmp);
Expression ve = new VarExp(exp.e1.loc, tmp);
Expression ce = Expression.combine(de, ve);
ce = ce.expressionSemantic(sc);
exp.e1 = ce;
exp.ti.vthis = tmp;
}
}

if (exp.ti.needsTypeInference(sc))
return exp;
exp.ti.dsymbolSemantic(sc);
Expand Down
1 change: 1 addition & 0 deletions src/dmd/func.d
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ extern (C++) class FuncDeclaration : Declaration
// scopes from having the same name
DsymbolTable localsymtab;
VarDeclaration vthis; /// 'this' parameter (member and nested)
VarDeclaration vthis2; /// 'this' parameter member when nested
VarDeclaration v_arguments; /// '_arguments' parameter
ObjcSelector* selector; /// Objective-C method selector (member function only)
VarDeclaration selectorParameter; /// Objective-C implicit selector parameter
Expand Down
5 changes: 5 additions & 0 deletions src/dmd/hdrgen.d
Original file line number Diff line number Diff line change
Expand Up @@ -1567,6 +1567,11 @@ public:

override void visit(TemplateInstance ti)
{
if (ti.vthis)
{
buf.writestring(ti.vthis.toChars());
buf.writeByte('.');
}
buf.writestring(ti.name.toChars());
tiargsToBuffer(ti);

Expand Down
13 changes: 13 additions & 0 deletions src/dmd/semantic3.d
Original file line number Diff line number Diff line change
Expand Up @@ -126,14 +126,24 @@ private extern(C++) final class Semantic3Visitor : Visitor
if (needGagging)
oldGaggedErrors = global.startGagging();

bool needVthis;
for (size_t i = 0; i < tempinst.members.dim; i++)
{
Dsymbol s = (*tempinst.members)[i];
auto fd = s.isFuncDeclaration();
if (fd && tempinst.vthis)
{
fd.vthis2 = tempinst.vthis;
needVthis = true;
}
s.semantic3(sc);
if (tempinst.gagged && global.errors != olderrors)
break;
}

if (!needVthis)
tempinst.vthis = null;

if (global.errors != olderrors)
{
if (!tempinst.errors)
Expand Down Expand Up @@ -371,6 +381,9 @@ private extern(C++) final class Semantic3Visitor : Visitor
//printf("[%s] ad = %p vthis = %p\n", loc.toChars(), ad, vthis);
//if (vthis) printf("\tvthis.type = %s\n", vthis.type.toChars());

if (!funcdecl.vthis2 && funcdecl.isNested())
funcdecl.vthis2 = funcdecl.toParent2().isFuncDeclaration().vthis2;

// Declare hidden variable _arguments[] and _argptr
if (f.parameterList.varargs == VarArg.variadic)
{
Expand Down

0 comments on commit 7a9c5d7

Please sign in to comment.