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
5 changes: 5 additions & 0 deletions src/aggregate.h
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ class StructDeclaration : public AggregateDeclaration
Type *arg1type;
Type *arg2type;

// Even if struct is defined as non-root symbol, some built-in operations
// (e.g. TypeidExp, NewExp, ArrayLiteralExp, etc) request its TypeInfo.
// For those, today TypeInfo_Struct is generated in COMDAT.
bool requestTypeInfo;

StructDeclaration(Loc loc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
Expand Down
5 changes: 4 additions & 1 deletion src/expression.c
Original file line number Diff line number Diff line change
Expand Up @@ -4161,7 +4161,7 @@ Expression *ArrayLiteralExp::semantic(Scope *sc)
return new ErrorExp();
}

semanticTypeInfo(sc, t0);
semanticTypeInfo(sc, type);

return this;
}
Expand Down Expand Up @@ -6114,6 +6114,9 @@ Expression *TypeidExp::semantic(Scope *sc)
// Handle this in the glue layer
e = new TypeidExp(loc, ta);
e->type = getTypeInfoType(ta, sc);

semanticTypeInfo(sc, ta);

if (ea)
{
e = new CommaExp(loc, ea, e); // execute ea
Expand Down
63 changes: 63 additions & 0 deletions src/inline.c
Original file line number Diff line number Diff line change
Expand Up @@ -919,6 +919,26 @@ Expression *doInline(Expression *e, InlineDoState *ids)
ne->newargs = arrayExpressiondoInline(e->newargs);
ne->arguments = arrayExpressiondoInline(e->arguments);
result = ne;

semanticTypeInfo(NULL, e->type);
}

void visit(DeleteExp *e)
{
visit((UnaExp *)e);

Type *tb = e->e1->type->toBasetype();
if (tb->ty == Tarray)
{
Type *tv = tb->nextOf()->baseElemOf();
if (tv->ty == Tstruct)
{
TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->dtor)
semanticTypeInfo(NULL, ts);
}
}
}

void visit(UnaExp *e)
Expand Down Expand Up @@ -957,6 +977,37 @@ Expression *doInline(Expression *e, InlineDoState *ids)
result = ce;
}

void visit(AssignExp *e)
{
visit((BinExp *)e);

if (e->e1->op == TOKarraylength)
{
ArrayLengthExp *ale = (ArrayLengthExp *)e->e1;
Type *tn = ale->e1->type->toBasetype()->nextOf();
semanticTypeInfo(NULL, tn);
}
}

void visit(EqualExp *e)
{
visit((BinExp *)e);

Type *t1 = e->e1->type->toBasetype();
if (t1->ty == Tarray || t1->ty == Tsarray)
{
Type *t = t1->nextOf()->toBasetype();
while (t->toBasetype()->nextOf())
t = t->nextOf()->toBasetype();
if (t->ty == Tstruct)
semanticTypeInfo(NULL, t);
}
else if (t1->ty == Taarray)
{
semanticTypeInfo(NULL, t1);
}
}

void visit(IndexExp *e)
{
IndexExp *are = (IndexExp *)e->copy();
Expand Down Expand Up @@ -1042,6 +1093,8 @@ Expression *doInline(Expression *e, InlineDoState *ids)

ce->elements = arrayExpressiondoInline(e->elements);
result = ce;

semanticTypeInfo(NULL, e->type);
}

void visit(AssocArrayLiteralExp *e)
Expand All @@ -1051,6 +1104,8 @@ Expression *doInline(Expression *e, InlineDoState *ids)
ce->keys = arrayExpressiondoInline(e->keys);
ce->values = arrayExpressiondoInline(e->values);
result = ce;

semanticTypeInfo(NULL, e->type);
}

void visit(StructLiteralExp *e)
Expand Down Expand Up @@ -1838,6 +1893,14 @@ static Expression *expandInline(FuncDeclaration *fd, FuncDeclaration *parent,
ids.parent = parent;
ids.fd = fd;

// When the function is actually expanded
if (TemplateInstance *ti = fd->isInstantiated())
{
// change ti to non-speculative instance
if (!ti->minst)
ti->minst = ti->tempdecl->getModule();
}

if (ps)
as = new Statements();

Expand Down
1 change: 1 addition & 0 deletions src/magicport.json
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,7 @@
"aggregate",
"argtypes",
"arraytypes",
"backend",
"clone",
"declaration",
"dmodule",
Expand Down
29 changes: 25 additions & 4 deletions src/struct.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "template.h"
#include "tokens.h"

Type *getTypeInfoType(Type *t, Scope *sc);
TypeTuple *toArgTypes(Type *t);

FuncDeclaration *StructDeclaration::xerreq; // object.xopEquals
Expand Down Expand Up @@ -100,12 +101,31 @@ void semanticTypeInfo(Scope *sc, Type *t)

// If the struct is in a non-root module, run semantic3 to get
// correct symbols for the member function.
// Note that, all instantiated symbols will run semantic3.
if (sd->inNonRoot())
if (TemplateInstance *ti = sd->isInstantiated())
{
//printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), sd->inNonRoot());
Module::addDeferredSemantic3(sd);
if (ti->minst && !ti->minst->isRoot())
Module::addDeferredSemantic3(sd);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense b/c non-root instances no longer run semantic3.
In the longer run the TypeInfo should only be generated where the struct is instantiated.

}
else
{
if (sd->inNonRoot())
{
//printf("deferred sem3 for TypeInfo - sd = %s, inNonRoot = %d\n", sd->toChars(), sd->inNonRoot());
Module::addDeferredSemantic3(sd);
}
}

if (!sc) // inline may request TypeInfo.
{
Scope scx;
scx.module = sd->getModule();
getTypeInfoType(t, &scx);
}
else
getTypeInfoType(t, sc);

if (!sc || sc->minst)
sd->requestTypeInfo = true;
}
void visit(TypeClass *t) { }
void visit(TypeTuple *t)
Expand Down Expand Up @@ -663,6 +683,7 @@ StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
ispod = ISPODfwd;
arg1type = NULL;
arg2type = NULL;
requestTypeInfo = false;

// For forward references
type = new TypeStruct(this);
Expand Down
Loading