Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/cast.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,15 @@ Expression *implicitCastTo(Expression *e, Scope *sc, Type *t)
//printf("FuncExp::implicitCastTo type = %p %s, t = %s\n", e->type, e->type ? e->type->toChars() : NULL, t->toChars());
visit((Expression *)e->inferType(t));
}

void visit(ArrayLiteralExp *e)
{
visit((Expression *)e);

Type *tb = result->type->toBasetype();
if (tb->ty == Tarray)
semanticTypeInfo(sc, ((TypeDArray *)tb)->next);
}
};

ImplicitCastTo v(sc, t);
Expand Down
50 changes: 34 additions & 16 deletions src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -1281,8 +1281,7 @@ bool Expression::checkPostblit(Scope *sc, Type *t)
if (t->ty == Tstruct)
{
// Bugzilla 11395: Require TypeInfo generation for array concatenation
if (!t->vtinfo)
t->getTypeInfo(sc);
semanticTypeInfo(sc, t);

StructDeclaration *sd = ((TypeStruct *)t)->sym;
if (sd->postblit)
Expand Down Expand Up @@ -3980,6 +3979,8 @@ Expression *ArrayLiteralExp::semantic(Scope *sc)
return new ErrorExp();
}

semanticTypeInfo(sc, t0);

return this;
}

Expand Down Expand Up @@ -4117,6 +4118,9 @@ Expression *AssocArrayLiteralExp::semantic(Scope *sc)

type = new TypeAArray(tvalue, tkey);
type = type->semantic(loc, sc);

semanticTypeInfo(sc, type);

return this;
}

Expand Down Expand Up @@ -4996,8 +5000,9 @@ Expression *NewExp::semantic(Scope *sc)
goto Lerr;
}

//printf("NewExp: '%s'\n", toChars());
//printf("NewExp:type '%s'\n", type->toChars());
//printf("NewExp: '%s'\n", toChars());
//printf("NewExp:type '%s'\n", type->toChars());
semanticTypeInfo(sc, type);

return this;

Expand Down Expand Up @@ -5806,13 +5811,15 @@ Expression *TypeidExp::semantic(Scope *sc)
}

if (ea && ta->toBasetype()->ty == Tclass)
{ /* Get the dynamic type, which is .classinfo
{
/* Get the dynamic type, which is .classinfo
*/
e = new DotIdExp(ea->loc, ea, Id::classinfo);
e = e->semantic(sc);
}
else
{ /* Get the static type
{
/* Get the static type
*/
e = ta->getTypeInfo(sc);
if (e->loc.linnum == 0)
Expand Down Expand Up @@ -8989,16 +8996,14 @@ DeleteExp::DeleteExp(Loc loc, Expression *e)

Expression *DeleteExp::semantic(Scope *sc)
{
Type *tb;

UnaExp::semantic(sc);
e1 = resolveProperties(sc, e1);
e1 = e1->modifiableLvalue(sc, NULL);
if (e1->op == TOKerror)
return e1;
type = Type::tvoid;

tb = e1->type->toBasetype();
Type *tb = e1->type->toBasetype();
switch (tb->ty)
{ case Tclass:
{ TypeClass *tc = (TypeClass *)tb;
Expand Down Expand Up @@ -9065,10 +9070,17 @@ Expression *DeleteExp::semantic(Scope *sc)
break;

case Tarray:
/* BUG: look for deleting arrays of structs with dtors.
*/
{
Type *tv = tb->nextOf()->baseElemOf();
if (tv->ty == Tstruct)
{
TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->dtor)
semanticTypeInfo(sc, ts);
}
break;

}
default:
if (e1->op == TOKindex)
{
Expand Down Expand Up @@ -10924,7 +10936,9 @@ Expression *AssignExp::semantic(Scope *sc)
if (ale->e1->op == TOKerror)
return ale->e1;

checkDefCtor(ale->loc, ale->e1->type->toBasetype()->nextOf());
Type *tn = ale->e1->type->toBasetype()->nextOf();
checkDefCtor(ale->loc, tn);
semanticTypeInfo(sc, tn);
}
else if (e1->op == TOKslice)
{
Expand Down Expand Up @@ -12605,7 +12619,7 @@ EqualExp::EqualExp(TOK op, Loc loc, Expression *e1, Expression *e2)
assert(op == TOKequal || op == TOKnotequal);
}

int needDirectEq(Type *t1, Type *t2)
int needDirectEq(Scope *sc, Type *t1, Type *t2)
{
assert(t1->ty == Tarray || t1->ty == Tsarray);
assert(t2->ty == Tarray || t2->ty == Tsarray);
Expand All @@ -12629,6 +12643,7 @@ int needDirectEq(Type *t1, Type *t2)
if (t->ty != Tstruct)
return false;

semanticTypeInfo(sc, t);
return ((TypeStruct *)t)->sym->hasIdentityEquals;
}

Expand Down Expand Up @@ -12680,8 +12695,9 @@ Expression *EqualExp::semantic(Scope *sc)
if ((t1->ty == Tarray || t1->ty == Tsarray) &&
(t2->ty == Tarray || t2->ty == Tsarray))
{
if (needDirectEq(t1, t2))
{ /* Rewrite as:
if (needDirectEq(sc, t1, t2))
{
/* Rewrite as:
* _ArrayEq(e1, e2)
*/
Expression *eq = new IdentifierExp(loc, Id::_ArrayEq);
Expand Down Expand Up @@ -12796,6 +12812,8 @@ Expression *EqualExp::semantic(Scope *sc)
e2 = e2->castTo(sc, Type::tcomplex80);
}
}
if (e1->type->toBasetype()->ty == Taarray)
semanticTypeInfo(sc, e1->type->toBasetype());

if (e1->type->toBasetype()->ty == Tvector)
return incompatibleTypes();
Expand Down
3 changes: 3 additions & 0 deletions src/mtype.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,8 @@ typedef struct TYPE type;
struct Symbol;
class TypeTuple;

void semanticTypeInfo(Scope *sc, Type *t);

enum ENUMTY
{
Tarray, // slice array, aka T[]
Expand Down Expand Up @@ -326,6 +328,7 @@ class Type : public RootObject
virtual void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps, bool intypeid = false);
Expression *getInternalTypeInfo(Scope *sc);
Expression *getTypeInfo(Scope *sc);
void genTypeInfo(Scope *sc);
virtual TypeInfoDeclaration *getTypeInfoDeclaration();
virtual int builtinTypeInfo();
virtual Type *reliesOnTident(TemplateParameters *tparams = NULL);
Expand Down
75 changes: 74 additions & 1 deletion src/struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,79 @@ FuncDeclaration *search_toString(StructDeclaration *sd)
return fd;
}

/***************************************
* Request additonal semantic analysis for TypeInfo generation.
*/
void semanticTypeInfo(Scope *sc, Type *t)
{
class FullTypeInfoVisitor : public Visitor
{
public:
Scope *sc;

void visit(Type *t)
{
Type *tb = t->toBasetype();
if (tb != t)
tb->accept(this);
}
void visit(TypeNext *t)
{
if (t->next)
t->next->accept(this);
}
void visit(TypeBasic *t) { }
void visit(TypeVector *t)
{
t->basetype->accept(this);
}
void visit(TypeAArray *t)
{
t->index->accept(this);
visit((TypeNext *)t);
}
void visit(TypeFunction *t)
{
visit((TypeNext *)t);
// Currently TypeInfo_Function doesn't store parameter types.
}
void visit(TypeStruct *t)
{
Dsymbol *s;
StructDeclaration *sd = t->sym;
if (sd->members &&
(sd->xeq && sd->xeq != sd->xerreq ||
sd->xcmp && sd->xcmp != sd->xerrcmp ||
(sd->postblit && !(sd->postblit->storage_class & STCdisable)) ||
sd->dtor ||
search_toHash(sd) ||
search_toString(sd)
) &&
sd->inNonRoot())
{
//printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), sd->inNonRoot());
Module::addDeferredSemantic3(sd);
}
}
void visit(TypeClass *t) { }
void visit(TypeTuple *t)
{
if (t->arguments)
{
for (size_t i = 0; i < t->arguments->dim; i++)
{
Type *tprm = (*t->arguments)[i]->type;
if (tprm)
tprm->accept(this);
}
}
}
};
FullTypeInfoVisitor v;
v.sc = sc;
t->accept(&v);
}

/********************************* AggregateDeclaration ****************************/

AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
Expand Down Expand Up @@ -741,7 +814,7 @@ void StructDeclaration::semantic(Scope *sc)
//if ((xeq && xeq != xerreq || xcmp && xcmp != xerrcmp) && isImportedSym(this))
// Module::addDeferredSemantic3(this);
/* Defer requesting semantic3 until TypeInfo generation is actually invoked.
* See Type::getTypeInfo().
* See semanticTypeInfo().
*/
inv = buildInv(sc2);

Expand Down
10 changes: 5 additions & 5 deletions src/toobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ void ClassDeclaration::toObjFile(int multiobj)
//////////////////////////////////////////////

// Put out the TypeInfo
type->getTypeInfo(NULL);
type->genTypeInfo(NULL);
//type->vtinfo->toObjFile(multiobj);

//////////////////////////////////////////////
Expand Down Expand Up @@ -661,7 +661,7 @@ void InterfaceDeclaration::toObjFile(int multiobj)
//////////////////////////////////////////////

// Put out the TypeInfo
type->getTypeInfo(NULL);
type->genTypeInfo(NULL);
type->vtinfo->toObjFile(multiobj);

//////////////////////////////////////////////
Expand Down Expand Up @@ -821,7 +821,7 @@ void StructDeclaration::toObjFile(int multiobj)
if (global.params.symdebug)
toDebug();

type->getTypeInfo(NULL); // generate TypeInfo
type->genTypeInfo(NULL);

if (1)
{
Expand Down Expand Up @@ -990,7 +990,7 @@ void TypedefDeclaration::toObjFile(int multiobj)
if (global.params.symdebug)
toDebug();

type->getTypeInfo(NULL); // generate TypeInfo
type->genTypeInfo(NULL);

TypeTypedef *tc = (TypeTypedef *)type;
if (type->isZeroInit() || !tc->sym->init)
Expand Down Expand Up @@ -1030,7 +1030,7 @@ void EnumDeclaration::toObjFile(int multiobj)
if (global.params.symdebug)
toDebug();

type->getTypeInfo(NULL); // generate TypeInfo
type->genTypeInfo(NULL);

TypeEnum *tc = (TypeEnum *)type;
if (!tc->sym->members || type->isZeroInit())
Expand Down
Loading