mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-09-17 19:07:05 +02:00
Merge DMD r243: some harmonization with D2 dmd
--- dmd/aggregate.h | 24 ++++- dmd/attrib.c | 63 ++++++---- dmd/attrib.h | 10 +- dmd/declaration.h | 5 +- dmd/func.c | 337 ++++++++++++++++++++++------------------------------- dmd/mars.c | 2 +- dmd/mars.h | 7 + dmd/mtype.h | 13 ++- dmd/parse.c | 32 ++++- dmd/parse.h | 14 ++- dmd/scope.h | 2 +- 11 files changed, 263 insertions(+), 246 deletions(-)
This commit is contained in:
+140
-197
@@ -31,7 +31,7 @@
|
||||
|
||||
/********************************* FuncDeclaration ****************************/
|
||||
|
||||
FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type)
|
||||
FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type)
|
||||
: Declaration(id)
|
||||
{
|
||||
//printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
|
||||
@@ -124,7 +124,7 @@ Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
|
||||
if (s)
|
||||
f = (FuncDeclaration *)s;
|
||||
else
|
||||
f = new FuncDeclaration(loc, endloc, ident, (enum STC) storage_class, type->syntaxCopy());
|
||||
f = new FuncDeclaration(loc, endloc, ident, storage_class, type->syntaxCopy());
|
||||
f->outId = outId;
|
||||
f->frequire = frequire ? frequire->syntaxCopy() : NULL;
|
||||
f->fensure = fensure ? fensure->syntaxCopy() : NULL;
|
||||
@@ -446,7 +446,6 @@ void FuncDeclaration::semantic(Scope *sc)
|
||||
*/
|
||||
for (int i = 0; i < cd->interfaces_dim; i++)
|
||||
{
|
||||
#if 1
|
||||
BaseClass *b = cd->interfaces[i];
|
||||
vi = findVtblIndex(&b->base->vtbl, b->base->vtbl.dim);
|
||||
switch (vi)
|
||||
@@ -499,68 +498,6 @@ void FuncDeclaration::semantic(Scope *sc)
|
||||
goto L2;
|
||||
}
|
||||
}
|
||||
#else
|
||||
BaseClass *b = cd->interfaces[i];
|
||||
for (vi = 0; vi < b->base->vtbl.dim; vi++)
|
||||
{
|
||||
Dsymbol *s = (Dsymbol *)b->base->vtbl.data[vi];
|
||||
//printf("interface %d vtbl[%d] %p %s\n", i, vi, s, s->toChars());
|
||||
FuncDeclaration *fdv = s->isFuncDeclaration();
|
||||
if (fdv && fdv->ident == ident)
|
||||
{
|
||||
int cov = type->covariant(fdv->type);
|
||||
//printf("\tcov = %d\n", cov);
|
||||
if (cov == 2)
|
||||
{
|
||||
//type->print();
|
||||
//fdv->type->print();
|
||||
//printf("%s %s\n", type->deco, fdv->type->deco);
|
||||
error("of type %s overrides but is not covariant with %s of type %s",
|
||||
type->toChars(), fdv->toPrettyChars(), fdv->type->toChars());
|
||||
}
|
||||
if (cov == 1)
|
||||
{ Type *ti = NULL;
|
||||
|
||||
if (fdv->tintro)
|
||||
ti = fdv->tintro;
|
||||
else if (!type->equals(fdv->type))
|
||||
{
|
||||
/* Only need to have a tintro if the vptr
|
||||
* offsets differ
|
||||
*/
|
||||
int offset;
|
||||
if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
|
||||
{
|
||||
ti = fdv->type;
|
||||
#if 0
|
||||
if (offset)
|
||||
ti = fdv->type;
|
||||
else if (type->nextOf()->ty == Tclass)
|
||||
{ ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym;
|
||||
if (cdn && cdn->sizeok != 1)
|
||||
ti = fdv->type;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if (ti)
|
||||
{
|
||||
if (tintro && !tintro->equals(ti))
|
||||
{
|
||||
error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars());
|
||||
}
|
||||
tintro = ti;
|
||||
}
|
||||
goto L2;
|
||||
}
|
||||
if (cov == 3)
|
||||
{
|
||||
cd->sizeok = 2; // can't finish due to forward reference
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
if (introducing && isOverride())
|
||||
@@ -1312,13 +1249,11 @@ void FuncDeclaration::semantic3(Scope *sc)
|
||||
v_argptr = argptr;
|
||||
v_argptr->init = new VoidInitializer(loc);
|
||||
#else
|
||||
Expression *e1;
|
||||
Expression *e;
|
||||
Type *t = argptr->type;
|
||||
VarDeclaration *p;
|
||||
unsigned offset;
|
||||
|
||||
e1 = new VarExp(0, argptr);
|
||||
Expression *e1 = new VarExp(0, argptr);
|
||||
if (parameters && parameters->dim)
|
||||
p = (VarDeclaration *)parameters->data[parameters->dim - 1];
|
||||
else
|
||||
@@ -1329,7 +1264,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
||||
else
|
||||
offset = p->type->size();
|
||||
offset = (offset + 3) & ~3; // assume stack aligns on 4
|
||||
e = new SymOffExp(0, p, offset);
|
||||
Expression *e = new SymOffExp(0, p, offset);
|
||||
e = new AssignExp(0, e1, e);
|
||||
e->type = t;
|
||||
a->push(new ExpStatement(0, e));
|
||||
@@ -1918,48 +1853,6 @@ FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t, Module* from)
|
||||
return p.f;
|
||||
}
|
||||
|
||||
#if 0
|
||||
FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t)
|
||||
{
|
||||
FuncDeclaration *f;
|
||||
Declaration *d;
|
||||
Declaration *next;
|
||||
|
||||
for (d = this; d; d = next)
|
||||
{ FuncAliasDeclaration *fa = d->isFuncAliasDeclaration();
|
||||
|
||||
if (fa)
|
||||
{
|
||||
FuncDeclaration *f2 = fa->funcalias->overloadExactMatch(t);
|
||||
if (f2)
|
||||
return f2;
|
||||
next = fa->overnext;
|
||||
}
|
||||
else
|
||||
{
|
||||
AliasDeclaration *a = d->isAliasDeclaration();
|
||||
|
||||
if (a)
|
||||
{
|
||||
Dsymbol *s = a->toAlias();
|
||||
next = s->isDeclaration();
|
||||
if (next == a)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
f = d->isFuncDeclaration();
|
||||
if (!f)
|
||||
break; // BUG: should print error message?
|
||||
if (t->equals(d->type))
|
||||
return f;
|
||||
next = f->overnext;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************
|
||||
* Decide which function matches the arguments best.
|
||||
@@ -1968,6 +1861,9 @@ FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t)
|
||||
struct Param2
|
||||
{
|
||||
Match *m;
|
||||
#if DMDV2
|
||||
Expression *ethis;
|
||||
#endif
|
||||
Expressions *arguments;
|
||||
};
|
||||
|
||||
@@ -1998,6 +1894,22 @@ int fp2(void *param, FuncDeclaration *f)
|
||||
else if (f->overrides(m->lastf))
|
||||
goto LfIsBetter;
|
||||
|
||||
#if DMDV2
|
||||
/* Try to disambiguate using template-style partial ordering rules.
|
||||
* In essence, if f() and g() are ambiguous, if f() can call g(),
|
||||
* but g() cannot call f(), then pick f().
|
||||
* This is because f() is "more specialized."
|
||||
*/
|
||||
{
|
||||
MATCH c1 = f->leastAsSpecialized(m->lastf);
|
||||
MATCH c2 = m->lastf->leastAsSpecialized(f);
|
||||
//printf("c1 = %d, c2 = %d\n", c1, c2);
|
||||
if (c1 > c2)
|
||||
goto LfIsBetter;
|
||||
if (c1 < c2)
|
||||
goto LlastIsBetter;
|
||||
}
|
||||
#endif
|
||||
Lambiguous:
|
||||
m->nextf = f;
|
||||
m->count++;
|
||||
@@ -2026,87 +1938,6 @@ void overloadResolveX(Match *m, FuncDeclaration *fstart,
|
||||
overloadApply(from, fstart, &fp2, &p);
|
||||
}
|
||||
|
||||
#if 0
|
||||
// Recursive helper function
|
||||
|
||||
void overloadResolveX(Match *m, FuncDeclaration *fstart, Expressions *arguments)
|
||||
{
|
||||
MATCH match;
|
||||
Declaration *d;
|
||||
Declaration *next;
|
||||
|
||||
for (d = fstart; d; d = next)
|
||||
{
|
||||
FuncDeclaration *f;
|
||||
FuncAliasDeclaration *fa;
|
||||
AliasDeclaration *a;
|
||||
|
||||
fa = d->isFuncAliasDeclaration();
|
||||
if (fa)
|
||||
{
|
||||
overloadResolveX(m, fa->funcalias, NULL, arguments);
|
||||
next = fa->overnext;
|
||||
}
|
||||
else if ((f = d->isFuncDeclaration()) != NULL)
|
||||
{
|
||||
next = f->overnext;
|
||||
if (f == m->lastf)
|
||||
continue; // skip duplicates
|
||||
else
|
||||
{
|
||||
TypeFunction *tf;
|
||||
|
||||
m->anyf = f;
|
||||
tf = (TypeFunction *)f->type;
|
||||
match = (MATCH) tf->callMatch(arguments);
|
||||
//printf("2match = %d\n", match);
|
||||
if (match != MATCHnomatch)
|
||||
{
|
||||
if (match > m->last)
|
||||
goto LfIsBetter;
|
||||
|
||||
if (match < m->last)
|
||||
goto LlastIsBetter;
|
||||
|
||||
/* See if one of the matches overrides the other.
|
||||
*/
|
||||
if (m->lastf->overrides(f))
|
||||
goto LlastIsBetter;
|
||||
else if (f->overrides(m->lastf))
|
||||
goto LfIsBetter;
|
||||
|
||||
Lambiguous:
|
||||
m->nextf = f;
|
||||
m->count++;
|
||||
continue;
|
||||
|
||||
LfIsBetter:
|
||||
m->last = match;
|
||||
m->lastf = f;
|
||||
m->count = 1;
|
||||
continue;
|
||||
|
||||
LlastIsBetter:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((a = d->isAliasDeclaration()) != NULL)
|
||||
{
|
||||
Dsymbol *s = a->toAlias();
|
||||
next = s->isDeclaration();
|
||||
if (next == a)
|
||||
break;
|
||||
if (next == fstart)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{ d->error("is aliased to a function");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, Module *from, int flags)
|
||||
{
|
||||
@@ -2179,6 +2010,118 @@ if (arguments)
|
||||
}
|
||||
}
|
||||
|
||||
/*************************************
|
||||
* Determine partial specialization order of 'this' vs g.
|
||||
* This is very similar to TemplateDeclaration::leastAsSpecialized().
|
||||
* Returns:
|
||||
* match 'this' is at least as specialized as g
|
||||
* 0 g is more specialized than 'this'
|
||||
*/
|
||||
|
||||
#if DMDV2
|
||||
MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
|
||||
{
|
||||
#define LOG_LEASTAS 0
|
||||
|
||||
#if LOG_LEASTAS
|
||||
printf("%s.leastAsSpecialized(%s)\n", toChars(), g->toChars());
|
||||
#endif
|
||||
|
||||
/* This works by calling g() with f()'s parameters, and
|
||||
* if that is possible, then f() is at least as specialized
|
||||
* as g() is.
|
||||
*/
|
||||
|
||||
TypeFunction *tf = (TypeFunction *)type;
|
||||
TypeFunction *tg = (TypeFunction *)g->type;
|
||||
size_t nfparams = Argument::dim(tf->parameters);
|
||||
size_t ngparams = Argument::dim(tg->parameters);
|
||||
MATCH match = MATCHexact;
|
||||
|
||||
/* If both functions have a 'this' pointer, and the mods are not
|
||||
* the same and g's is not const, then this is less specialized.
|
||||
*/
|
||||
if (needThis() && g->needThis())
|
||||
{
|
||||
if (tf->mod != tg->mod)
|
||||
{
|
||||
if (tg->mod == MODconst)
|
||||
match = MATCHconst;
|
||||
else
|
||||
return MATCHnomatch;
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a dummy array of arguments out of the parameters to f()
|
||||
*/
|
||||
Expressions args;
|
||||
args.setDim(nfparams);
|
||||
for (int u = 0; u < nfparams; u++)
|
||||
{
|
||||
Argument *p = Argument::getNth(tf->parameters, u);
|
||||
Expression *e;
|
||||
if (p->storageClass & (STCref | STCout))
|
||||
{
|
||||
e = new IdentifierExp(0, p->ident);
|
||||
e->type = p->type;
|
||||
}
|
||||
else
|
||||
e = p->type->defaultInit();
|
||||
args.data[u] = e;
|
||||
}
|
||||
|
||||
MATCH m = (MATCH) tg->callMatch(NULL, &args);
|
||||
if (m)
|
||||
{
|
||||
/* A variadic parameter list is less specialized than a
|
||||
* non-variadic one.
|
||||
*/
|
||||
if (tf->varargs && !tg->varargs)
|
||||
goto L1; // less specialized
|
||||
|
||||
#if LOG_LEASTAS
|
||||
printf(" matches %d, so is least as specialized\n", m);
|
||||
#endif
|
||||
return m;
|
||||
}
|
||||
L1:
|
||||
#if LOG_LEASTAS
|
||||
printf(" doesn't match, so is not as specialized\n");
|
||||
#endif
|
||||
return MATCHnomatch;
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* Given a symbol that could be either a FuncDeclaration or
|
||||
* a function template, resolve it to a function symbol.
|
||||
* sc instantiation scope
|
||||
* loc instantiation location
|
||||
* targsi initial list of template arguments
|
||||
* ethis if !NULL, the 'this' pointer argument
|
||||
* fargs arguments to function
|
||||
* flags 1: do not issue error message on no match, just return NULL
|
||||
*/
|
||||
|
||||
FuncDeclaration *resolveFuncCall(Scope *sc, Loc loc, Dsymbol *s,
|
||||
Objects *tiargs,
|
||||
Expression *ethis,
|
||||
Expressions *arguments,
|
||||
int flags)
|
||||
{
|
||||
if (!s)
|
||||
return NULL; // no match
|
||||
FuncDeclaration *f = s->isFuncDeclaration();
|
||||
if (f)
|
||||
f = f->overloadResolve(loc, ethis, arguments);
|
||||
else
|
||||
{ TemplateDeclaration *td = s->isTemplateDeclaration();
|
||||
assert(td);
|
||||
f = td->deduceFunctionTemplate(sc, loc, tiargs, NULL, arguments, flags);
|
||||
}
|
||||
return f;
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************
|
||||
* Labels are in a separate scope, one per function.
|
||||
*/
|
||||
@@ -2298,15 +2241,14 @@ void FuncDeclaration::appendExp(Expression *e)
|
||||
}
|
||||
|
||||
void FuncDeclaration::appendState(Statement *s)
|
||||
{ CompoundStatement *cs;
|
||||
|
||||
{
|
||||
if (!fbody)
|
||||
{ Statements *a;
|
||||
|
||||
a = new Statements();
|
||||
fbody = new CompoundStatement(0, a);
|
||||
}
|
||||
cs = fbody->isCompoundStatement();
|
||||
CompoundStatement *cs = fbody->isCompoundStatement();
|
||||
cs->statements->push(s);
|
||||
}
|
||||
|
||||
@@ -2362,7 +2304,7 @@ int FuncDeclaration::isVirtual()
|
||||
{
|
||||
#if 0
|
||||
printf("FuncDeclaration::isVirtual(%s)\n", toChars());
|
||||
printf("%p %d %d %d %d\n", isMember(), isStatic(), protection == PROTprivate, isCtorDeclaration(), linkage != LINKd);
|
||||
printf("isMember:%p isStatic:%d private:%d ctor:%d !Dlinkage:%d\n", isMember(), isStatic(), protection == PROTprivate, isCtorDeclaration(), linkage != LINKd);
|
||||
printf("result is %d\n",
|
||||
isMember() &&
|
||||
!(isStatic() || protection == PROTprivate || protection == PROTpackage) &&
|
||||
@@ -2407,7 +2349,7 @@ int FuncDeclaration::isNested()
|
||||
{
|
||||
//if (!toParent())
|
||||
//printf("FuncDeclaration::isNested('%s') parent=%p\n", toChars(), parent);
|
||||
//printf("\ttoParent() = '%s'\n", toParent()->toChars());
|
||||
//printf("\ttoParent2() = '%s'\n", toParent2()->toChars());
|
||||
return ((storage_class & STCstatic) == 0) && toParent2() &&
|
||||
(toParent2()->isFuncDeclaration() != NULL);
|
||||
}
|
||||
@@ -3078,6 +3020,7 @@ void StaticDtorDeclaration::semantic(Scope *sc)
|
||||
m = sc->module;
|
||||
if (m)
|
||||
{ m->needmoduleinfo = 1;
|
||||
//printf("module2 %s needs moduleinfo\n", m->toChars());
|
||||
#ifdef IN_GCC
|
||||
m->strictlyneedmoduleinfo = 1;
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user