Skip to content

Commit

Permalink
Remove implicit [WIP]
Browse files Browse the repository at this point in the history
  • Loading branch information
RazvanN7 committed Sep 21, 2018
1 parent da493b0 commit cdd8100
Show file tree
Hide file tree
Showing 13 changed files with 54 additions and 123 deletions.
3 changes: 1 addition & 2 deletions src/dmd/aggregate.h
Expand Up @@ -22,7 +22,6 @@ class TypeFunction;
class Expression;
class FuncDeclaration;
class CtorDeclaration;
class CopyCtorDeclaration;
class DtorDeclaration;
class InvariantDeclaration;
class NewDeclaration;
Expand Down Expand Up @@ -182,7 +181,7 @@ class StructDeclaration : public AggregateDeclaration
FuncDeclarations postblits; // Array of postblit functions
FuncDeclaration *postblit; // aggregate postblit

CopyCtorDeclaration *copyCtor; // copy constructor
CtorDeclaration *copyCtor; // copy constructor
void *copyCtorTypes; // hashtable of copy constructor types for this struct

FuncDeclaration *xeq; // TypeInfo_Struct.xopEquals
Expand Down
16 changes: 1 addition & 15 deletions src/dmd/astbase.d
Expand Up @@ -128,7 +128,6 @@ struct ASTBase
scopeinferred = (1L << 49), // 'scope' has been inferred and should not be part of mangling
future = (1L << 50), // introducing new base class function
local = (1L << 51), // do not forward (see dmd.dsymbol.ForwardingScopeDsymbol).
implicit = (1L << 52), // @implicit

TYPECTOR = (STC.const_ | STC.immutable_ | STC.shared_ | STC.wild),
FUNCATTR = (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.property | STC.safe | STC.trusted | STC.system),
Expand Down Expand Up @@ -816,23 +815,10 @@ struct ASTBase
}

extern (C++) class CtorDeclaration : FuncDeclaration
{
extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc, Type type, bool isCpCtor = false)
{
super(loc, endloc, isCpCtor ? Id.copyCtor : Id.ctor, stc, type);
}

override void accept(Visitor v)
{
v.visit(this);
}
}

extern (C++) final class CopyCtorDeclaration : CtorDeclaration
{
extern (D) this(const ref Loc loc, Loc endloc, StorageClass stc, Type type)
{
super(loc, endloc, stc, type, true);
super(loc, endloc, Id.ctor, stc, type);
}

override void accept(Visitor v)
Expand Down
1 change: 0 additions & 1 deletion src/dmd/declaration.d
Expand Up @@ -258,7 +258,6 @@ enum STC : long
scopeinferred = (1L << 49), // 'scope' has been inferred and should not be part of mangling
future = (1L << 50), // introducing new base class function
local = (1L << 51), // do not forward (see dmd.dsymbol.ForwardingScopeDsymbol).
implicit = (1L << 52), // @implicit

TYPECTOR = (STC.const_ | STC.immutable_ | STC.shared_ | STC.wild),
FUNCATTR = (STC.ref_ | STC.nothrow_ | STC.nogc | STC.pure_ | STC.property | STC.safe | STC.trusted | STC.system),
Expand Down
12 changes: 0 additions & 12 deletions src/dmd/declaration.h
Expand Up @@ -707,18 +707,6 @@ class CtorDeclaration : public FuncDeclaration
void accept(Visitor *v) { v->visit(this); }
};

class CopyCtorDeclaration : public CtorDeclaration
{
public:
Dsymbol *syntaxCopy(Dsymbol *);
const char *kind() const;
const char *toChars();
bool isVirtual() const;

CtorDeclaration *isCtorDeclaration() { return this; }
void accept(Visitor *v) { v->visit(this); }
};

class PostBlitDeclaration : public FuncDeclaration
{
public:
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/dstruct.d
Expand Up @@ -229,7 +229,7 @@ extern (C++) class StructDeclaration : AggregateDeclaration
FuncDeclarations postblits; // Array of postblit functions
FuncDeclaration postblit; // aggregate postblit

CopyCtorDeclaration copyCtor; // copy constructor
CtorDeclaration copyCtor; // copy constructor
bool[ModBits] copyCtorTypes; // source-destination qualifiers for the struct copy constructors

FuncDeclaration xeq; // TypeInfo_Struct.xopEquals
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/dsymbol.d
Expand Up @@ -1094,7 +1094,7 @@ extern (C++) class Dsymbol : RootObject
return null;
}

inout(CopyCtorDeclaration) isCopyCtorDeclaration() inout
inout(CtorDeclaration) isCopyCtorDeclaration() inout
{
return null;
}
Expand Down
58 changes: 36 additions & 22 deletions src/dmd/dsymbolsem.d
Expand Up @@ -361,14 +361,15 @@ private extern (C++) FuncDeclaration buildPostBlit(StructDeclaration sd, Scope*
}

// Concatenates 2 MODs(ubyte) into one ModBits(ushort)
private ModBits createModKey(MOD mod1, MOD mod2)
/*private ModBits createModKey(MOD mod1, MOD mod2)
{
return ((mod1 << 8) | mod2);
}

*/
/* Generates a copy constructor declaration with the specified storage
class for the parameter and the function : @implicit this(ref paramSTC S p) funcStc;
*/
/*
private CopyCtorDeclaration generateCopyCtorDeclaration(StructDeclaration sd, const StorageClass paramStc, const StorageClass funcStc)
{
auto fparams = new Parameters();
Expand All @@ -381,14 +382,15 @@ private CopyCtorDeclaration generateCopyCtorDeclaration(StructDeclaration sd, co
ccd.generated = true;
return ccd;
}

*/
/* Generates a trivial copy constructor body that simply does memberwise
* initialization:
*
* this.field1 = rhs.field1;
* this.field2 = rhs.field2;
* ...
*/
/*
private Statement generateCopyCtorBody(StructDeclaration sd)
{
Loc loc;
Expand All @@ -404,17 +406,30 @@ private Statement generateCopyCtorBody(StructDeclaration sd)
Statement s1 = new ExpStatement(loc, e);
return new CompoundStatement(loc, s1);
}

*/
/* Generates copy constructors for the fields that define copy constructors.
The body of all generated copy constructors is the same and it does
memberwise initialization. If any initialization in a particular
generated copy constructor is not possible (through implicit conversion
or copy construction), the generated copy constructor is marked `@disable`.
*/
private CopyCtorDeclaration buildCopyCtor(StructDeclaration sd, Scope* sc)
private CtorDeclaration buildCopyCtor(StructDeclaration sd, Scope* sc)
{
Dsymbol s = sd.search(sd.loc, Id.copyCtor);
bool[ModBits] copyCtorTable; // hashtable used to store what copy constructors should be generated
Dsymbol s = sd.search(sd.loc, Id.ctor);
bool exists;
if (s)
{
overloadApply(s, (Dsymbol ctor)
{
auto cpCtor = ctor.isCopyCtorDeclaration();
if (cpCtor)
exists = true;
return 0;
});
}

return exists ? s.isCtorDeclaration : null;
/* bool[ModBits] copyCtorTable; // hashtable used to store what copy constructors should be generated
// see if any struct members define a copy constructor
foreach (v; sd.fields)
{
Expand Down Expand Up @@ -477,7 +492,8 @@ private CopyCtorDeclaration buildCopyCtor(StructDeclaration sd, Scope* sc)
s = ccd;
}
}
return s ? s.isCopyCtorDeclaration : null;
*/
//return s ? s.isCopyCtorDeclaration : null;
}

private uint setMangleOverride(Dsymbol s, char* sym)
Expand Down Expand Up @@ -707,12 +723,6 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (dsym.semanticRun >= PASS.semanticdone)
return;

if (dsym.storage_class & STC.implicit)
{
dsym.error("cannot be marked with `@implicit` because it is not a copy constructor");
return;
}

Scope* scx = null;
if (dsym._scope)
{
Expand Down Expand Up @@ -2995,12 +3005,6 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
return;
}

if ((funcdecl.storage_class & STC.implicit) && !funcdecl.isCtorDeclaration)
{
funcdecl.error("cannot be marked with `@implicit` because it is not a copy constructor");
return;
}

if (funcdecl.semanticRun >= PASS.semanticdone)
return;
assert(funcdecl.semanticRun <= PASS.semantic);
Expand Down Expand Up @@ -3771,7 +3775,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
{
funcDeclarationSemantic(funcdecl);
}

/*
override void visit(CopyCtorDeclaration cctd)
{
//printf("CopyCtorDeclaration::semantic() %s\n", toChars());
Expand Down Expand Up @@ -3820,7 +3824,7 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
if (unqualParamType != unqualStructType)
error(cctd.loc, "the copy constructor parameter base type needs to be `%s`, not `%s`", unqualStructType.toChars(), unqualParamType.toChars());
}

*/
override void visit(CtorDeclaration ctd)
{
//printf("CtorDeclaration::semantic() %s\n", toChars());
Expand Down Expand Up @@ -3904,6 +3908,16 @@ private extern(C++) final class DsymbolSemanticVisitor : Visitor
ctd.deprecation("all parameters have default arguments, "~
"but structs cannot have default constructors.");
}
else if (dim == 1)
{
printf("tf: %s\n", tf.toChars());
auto param = Parameter.getNth(tf.parameters, 0);
if (param.storageClass & STC.ref_ && param.type.mutableOf().unSharedOf() == sd.type.mutableOf().unSharedOf())
{
printf("copy constructor\n");
ctd.isCopyCtor = true;
}
}
}
else if (dim == 0 && tf.varargs == 0)
{
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/expressionsem.d
Expand Up @@ -7745,7 +7745,7 @@ private extern (C++) final class ExpressionSemanticVisitor : Visitor
einit.type = e1x.type;

Expression e;
e = new DotIdExp(exp.loc, e1x, Id.copyCtor);
e = new DotIdExp(exp.loc, e1x, Id.ctor);
e = new CallExp(exp.loc, e, e2x);
e = new CommaExp(exp.loc, einit, e);

Expand Down
40 changes: 5 additions & 35 deletions src/dmd/func.d
Expand Up @@ -3253,9 +3253,10 @@ extern (C++) final class FuncLiteralDeclaration : FuncDeclaration
*/
extern (C++) class CtorDeclaration : FuncDeclaration
{
extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Type type, bool isCpCtor = false)
bool isCopyCtor;
extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Type type)
{
super(loc, endloc, isCpCtor ? Id.copyCtor : Id.ctor, stc, type);
super(loc, endloc, Id.ctor, stc, type);
//printf("CtorDeclaration(loc = %s) %s\n", loc.toChars(), toChars());
}

Expand Down Expand Up @@ -3296,42 +3297,11 @@ extern (C++) class CtorDeclaration : FuncDeclaration
return this;
}

override void accept(Visitor v)
{
v.visit(this);
}
}

/***********************************************************
*/
extern (C++) class CopyCtorDeclaration : CtorDeclaration
{
extern (D) this(const ref Loc loc, const ref Loc endloc, StorageClass stc, Type type)
{
super(loc, endloc, stc, type, true);
}

override Dsymbol syntaxCopy(Dsymbol s)
{
assert(!s);
auto f = new CopyCtorDeclaration(loc, endloc, storage_class, type.syntaxCopy());
return FuncDeclaration.syntaxCopy(f);
}

override const(char)* kind() const
override inout(CtorDeclaration) isCopyCtorDeclaration() inout
{
return "copy constructor";
return isCopyCtor ? this : null;
}

override const(char)* toChars() const
{
return "@implicit this";
}

override inout(CopyCtorDeclaration) isCopyCtorDeclaration() inout
{
return this;
}

override void accept(Visitor v)
{
Expand Down
2 changes: 1 addition & 1 deletion src/dmd/mtype.d
Expand Up @@ -4821,7 +4821,7 @@ extern (C++) final class TypeFunction : TypeNext
auto tmp = new VarDeclaration(arg.loc, tprm, Identifier.generateId("__copytmp"), null);
tmp.dsymbolSemantic(sc);
Expression ve = new VarExp(arg.loc, tmp);
Expression e = new DotIdExp(arg.loc, ve, Id.copyCtor);
Expression e = new DotIdExp(arg.loc, ve, Id.ctor);
e = new CallExp(arg.loc, e, arg);
if (.trySemantic(e, sc))
m = MATCH.convert; // implicit conversion using copy constructor
Expand Down
37 changes: 7 additions & 30 deletions src/dmd/parse.d
Expand Up @@ -309,8 +309,7 @@ final class Parser(AST) : Lexer
const stc = parseAttribute(&exps);
if (stc == AST.STC.property || stc == AST.STC.nogc
|| stc == AST.STC.disable || stc == AST.STC.safe
|| stc == AST.STC.trusted || stc == AST.STC.system
|| stc == AST.STC.implicit)
|| stc == AST.STC.trusted || stc == AST.STC.system)
{
error("`@%s` attribute for module declaration is not supported", token.toChars());
}
Expand Down Expand Up @@ -1331,8 +1330,6 @@ final class Parser(AST) : Lexer
stc = AST.STC.trusted;
else if (token.ident == Id.system)
stc = AST.STC.system;
else if (token.ident == Id.implicit)
stc = AST.STC.implicit;
else if (token.ident == Id.disable)
stc = AST.STC.disable;
else if (token.ident == Id.future)
Expand Down Expand Up @@ -2400,43 +2397,25 @@ final class Parser(AST) : Lexer
int varargs;
AST.Parameters* parameters = parseParameters(&varargs);
stc = parsePostfix(stc, &udas);
size_t paramDim = AST.Parameter.dim(parameters);
if (varargs != 0 || paramDim != 0)
if (varargs != 0 || AST.Parameter.dim(parameters) != 0)
{
if (stc & AST.STC.static_)
error(loc, "constructors and copy constructors cannot be static");
error(loc, "constructors cannot be static");
}
else if (StorageClass ss = stc & (AST.STC.shared_ | AST.STC.static_)) // this()
{
if (stc & AST.STC.implicit)
{}
else if (ss == AST.STC.static_)
if (ss == AST.STC.static_)
error(loc, "use `static this()` to declare a static constructor");
else if (ss == (AST.STC.shared_ | AST.STC.static_))
error(loc, "use `shared static this()` to declare a shared static constructor");
}

// copy constructor
if (stc & AST.STC.implicit)
{
if (tpl)
error(loc, "the copy constructor cannot be templated");
if (paramDim != 1 || varargs)
error(loc, "the copy constructor receives exactly one argument");
else if (!(AST.Parameter.getNth(parameters, 0).storageClass & AST.STC.ref_))
error(loc, "the parameter to the copy constructor must by passed by reference. Add `ref` to the parameter type");
}

AST.Expression constraint = tpl ? parseConstraint() : null;

AST.Type tf = new AST.TypeFunction(parameters, null, varargs, linkage, stc); // RetrunType -> auto
tf = tf.addSTC(stc);

AST.FuncDeclaration f;
if (stc & AST.STC.implicit)
f = new AST.CopyCtorDeclaration(loc, Loc.initial, stc, tf);
else
f = new AST.CtorDeclaration(loc, Loc.initial, stc, tf);
auto f = new AST.CtorDeclaration(loc, Loc.initial, stc, tf);
AST.Dsymbol s = parseContracts(f);
if (udas)
{
Expand Down Expand Up @@ -2829,8 +2808,7 @@ final class Parser(AST) : Lexer
StorageClass stc2 = parseAttribute(&exps);
if (stc2 == AST.STC.property || stc2 == AST.STC.nogc ||
stc2 == AST.STC.disable || stc2 == AST.STC.safe ||
stc2 == AST.STC.trusted || stc2 == AST.STC.system ||
stc2 == AST.STC.implicit)
stc2 == AST.STC.trusted || stc2 == AST.STC.system)
{
error("`@%s` attribute for function parameter is not supported", token.toChars());
}
Expand Down Expand Up @@ -2974,8 +2952,7 @@ final class Parser(AST) : Lexer
StorageClass stc2 = parseAttribute(&exps);
if (stc2 == AST.STC.property || stc2 == AST.STC.nogc ||
stc2 == AST.STC.disable || stc2 == AST.STC.safe ||
stc2 == AST.STC.trusted || stc2 == AST.STC.system ||
stc2 == AST.STC.implicit)
stc2 == AST.STC.trusted || stc2 == AST.STC.system)
{
error("`@%s` attribute for function parameter is not supported", token.toChars());
}
Expand Down

0 comments on commit cdd8100

Please sign in to comment.