Merged dmd 2.059beta

This commit is contained in:
Alexey Prokhin
2012-04-05 11:47:00 +04:00
77 changed files with 6909 additions and 2243 deletions

View File

@@ -1,5 +1,5 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -341,13 +341,6 @@ void FuncDeclaration::semantic(Scope *sc)
}
#endif
#ifdef IN_GCC
{
AggregateDeclaration *ad = parent->isAggregateDeclaration();
if (ad)
ad->methods.push(this);
}
#endif
sd = parent->isStructDeclaration();
if (sd)
{
@@ -468,6 +461,9 @@ void FuncDeclaration::semantic(Scope *sc)
//printf("\tnot virtual\n");
goto Ldone;
}
// Suppress further errors if the return type is an error
if (type->nextOf() == Type::terror)
goto Ldone;
/* Find index of existing function in base class's vtbl[] to override
* (the index will be the same as in cd's current vtbl[])
@@ -479,6 +475,7 @@ void FuncDeclaration::semantic(Scope *sc)
switch (vi)
{
case -1:
Lintro:
/* Didn't find one, so
* This is an 'introducing' function which gets a new
* slot in the vtbl[].
@@ -515,7 +512,7 @@ void FuncDeclaration::semantic(Scope *sc)
break;
case -2: // can't determine because of fwd refs
cd->sizeok = 2; // can't finish due to forward reference
cd->sizeok = SIZEOKfwd; // can't finish due to forward reference
Module::dprogress = dprogress_save;
return;
@@ -534,9 +531,12 @@ void FuncDeclaration::semantic(Scope *sc)
FuncDeclaration *fdc = ((Dsymbol *)cd->vtbl.data[vi])->isFuncDeclaration();
if (fdc->toParent() == parent)
{
// fdc overrides fdv exactly, then this introduces new function.
if (fdc->type->mod == fdv->type->mod && this->type->mod != fdv->type->mod)
goto Lintro;
// If both are mixins, then error.
// If either is not, the one that is not overrides the other.
if (this->parent->isClassDeclaration() && fdc->parent->isClassDeclaration())
error("multiple overrides of same function");
@@ -600,7 +600,7 @@ void FuncDeclaration::semantic(Scope *sc)
break;
case -2:
cd->sizeok = 2; // can't finish due to forward reference
cd->sizeok = SIZEOKfwd; // can't finish due to forward reference
Module::dprogress = dprogress_save;
return;
@@ -636,7 +636,7 @@ void FuncDeclaration::semantic(Scope *sc)
{
// any error in isBaseOf() is a forward reference error, so we bail out
global.errors = errors;
cd->sizeok = 2; // can't finish due to forward reference
cd->sizeok = SIZEOKfwd; // can't finish due to forward reference
Module::dprogress = dprogress_save;
return;
}
@@ -647,9 +647,14 @@ void FuncDeclaration::semantic(Scope *sc)
}
if (ti)
{
if (tintro && !tintro->equals(ti))
if (tintro)
{
error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars());
if (!tintro->nextOf()->equals(ti->nextOf()) &&
!tintro->nextOf()->isBaseOf(ti->nextOf(), NULL) &&
!ti->nextOf()->isBaseOf(tintro->nextOf(), NULL))
{
error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars());
}
}
tintro = ti;
}
@@ -660,7 +665,11 @@ void FuncDeclaration::semantic(Scope *sc)
if (!doesoverride && isOverride())
{
error("does not override any function");
Dsymbol *s = cd->search_correct(ident);
if (s)
error("does not override any function, did you mean '%s'", s->toPrettyChars());
else
error("does not override any function");
}
L2: ;
@@ -879,7 +888,7 @@ void FuncDeclaration::semantic3(Scope *sc)
//printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
assert(0);
}
//printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars());
//printf("FuncDeclaration::semantic3('%s.%s', %p, sc = %p, loc = %s)\n", parent->toChars(), toChars(), this, sc, loc.toChars());
//fflush(stdout);
//printf("storage class = x%x %x\n", sc->stc, storage_class);
//{ static int x; if (++x == 2) *(char*)0=0; }
@@ -978,6 +987,9 @@ void FuncDeclaration::semantic3(Scope *sc)
}
else
assert(!isNested() || sc->intypeof); // can't be both member and nested
#if IN_GCC
ad->methods.push(this);
#endif
}
vthis = declareThis(sc2, ad);
@@ -989,7 +1001,7 @@ void FuncDeclaration::semantic3(Scope *sc)
#else
Type *t;
#if !IN_LLVM
#if !IN_GCC && !IN_LLVM
if (global.params.is64bit)
{ // Declare save area for varargs registers
Type *t = new TypeIdentifier(loc, Id::va_argsave_t);
@@ -1327,7 +1339,7 @@ void FuncDeclaration::semantic3(Scope *sc)
}
}
if (inferRetType || f->retStyle() != RETstack)
if (!inferRetType && f->retStyle() != RETstack)
nrvo_can = 0;
fbody = fbody->semantic(sc2);
@@ -1915,11 +1927,13 @@ int FuncDeclaration::equals(Object *o)
Dsymbol *s = isDsymbol(o);
if (s)
{
FuncDeclaration *fd = s->isFuncDeclaration();
if (fd)
FuncDeclaration *fd1 = this->toAliasFunc();
FuncDeclaration *fd2 = s->isFuncDeclaration();
if (fd2)
{
return toParent()->equals(fd->toParent()) &&
ident->equals(fd->ident) && type->equals(fd->type);
fd2 = fd2->toAliasFunc();
return fd1->toParent()->equals(fd2->toParent()) &&
fd1->ident->equals(fd2->ident) && fd1->type->equals(fd2->type);
}
}
return FALSE;
@@ -2137,6 +2151,8 @@ int FuncDeclaration::overrides(FuncDeclaration *fd)
int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim)
{
FuncDeclaration *mismatch = NULL;
StorageClass mismatchstc = 0;
int mismatchvi = -1;
int bestvi = -1;
for (int vi = 0; vi < dim; vi++)
{
@@ -2146,7 +2162,8 @@ int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim)
if (type->equals(fdv->type)) // if exact match
return vi; // no need to look further
int cov = type->covariant(fdv->type);
StorageClass stc = 0;
int cov = type->covariant(fdv->type, &stc);
//printf("\tbaseclass cov = %d\n", cov);
switch (cov)
{
@@ -2158,6 +2175,8 @@ int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim)
break; // keep looking for an exact match
case 2:
mismatchvi = vi;
mismatchstc = stc;
mismatch = fdv; // overrides, but is not covariant
break; // keep looking for an exact match
@@ -2174,8 +2193,15 @@ int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim)
//type->print();
//mismatch->type->print();
//printf("%s %s\n", type->deco, mismatch->type->deco);
error("of type %s overrides but is not covariant with %s of type %s",
type->toChars(), mismatch->toPrettyChars(), mismatch->type->toChars());
//printf("stc = %llx\n", mismatchstc);
if (mismatchstc)
{ // Fix it by modifying the type to add the storage classes
type = type->addStorageClass(mismatchstc);
bestvi = mismatchvi;
}
else
error("of type %s overrides but is not covariant with %s of type %s",
type->toChars(), mismatch->toPrettyChars(), mismatch->type->toChars());
}
return bestvi;
}
@@ -2262,8 +2288,21 @@ int overloadApply(FuncDeclaration *fstart,
if (fa)
{
if (overloadApply(fa->funcalias, fp, param))
return 1;
if (fa->hasOverloads)
{
if (overloadApply(fa->funcalias, fp, param))
return 1;
}
else
{
f = fa->toAliasFunc();
if (!f)
{ d->error("is aliased to a function");
break;
}
if ((*fp)(param, f))
return 1;
}
next = fa->overnext;
}
else
@@ -2611,7 +2650,7 @@ MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
e->type = p->type;
}
else
e = p->type->defaultInit();
e = p->type->defaultInitLiteral(0);
args.tdata()[u] = e;
}
@@ -2925,6 +2964,11 @@ int FuncDeclaration::isOverloadable()
return 1; // functions can be overloaded
}
int FuncDeclaration::hasOverloads()
{
return overnext != NULL;
}
enum PURE FuncDeclaration::isPure()
{
//printf("FuncDeclaration::isPure() '%s'\n", toChars());
@@ -2982,6 +3026,14 @@ int FuncDeclaration::isSafe()
return ((TypeFunction *)type)->trust == TRUSTsafe;
}
bool FuncDeclaration::isSafeBypassingInference()
{
if (flags & FUNCFLAGsafetyInprocess)
return false;
else
return isSafe();
}
int FuncDeclaration::isTrusted()
{
assert(type->ty == Tfunction);
@@ -3012,21 +3064,16 @@ bool FuncDeclaration::setUnsafe()
int FuncDeclaration::isNested()
{
//if (!toParent())
//printf("FuncDeclaration::isNested('%s') parent=%p\n", toChars(), parent);
//printf("\ttoParent2() = '%s'\n", toParent2()->toChars());
return ((storage_class & STCstatic) == 0) && toParent2() &&
(toParent2()->isFuncDeclaration() != NULL);
FuncDeclaration *f = toAliasFunc();
//printf("\ttoParent2() = '%s'\n", f->toParent2()->toChars());
return ((f->storage_class & STCstatic) == 0) &&
(f->toParent2()->isFuncDeclaration() != NULL);
}
int FuncDeclaration::needThis()
{
//printf("FuncDeclaration::needThis() '%s'\n", toChars());
int i = isThis() != NULL;
//printf("\t%d\n", i);
if (!i && isFuncAliasDeclaration())
i = ((FuncAliasDeclaration *)this)->funcalias->needThis();
return i;
return toAliasFunc()->isThis() != NULL;
}
int FuncDeclaration::addPreInvariant()
@@ -3272,7 +3319,7 @@ Parameters *FuncDeclaration::getParameters(int *pvarargs)
// Used as a way to import a set of functions from another scope into this one.
FuncAliasDeclaration::FuncAliasDeclaration(FuncDeclaration *funcalias)
FuncAliasDeclaration::FuncAliasDeclaration(FuncDeclaration *funcalias, int hasOverloads)
: FuncDeclaration(funcalias->loc, funcalias->endloc, funcalias->ident,
funcalias->storage_class, funcalias->type)
{
@@ -3281,6 +3328,18 @@ FuncAliasDeclaration::FuncAliasDeclaration(FuncDeclaration *funcalias)
#if IN_LLVM
importprot = PROTundefined;
#endif
this->hasOverloads = hasOverloads;
if (hasOverloads)
{
if (FuncAliasDeclaration *fad = funcalias->isFuncAliasDeclaration())
this->hasOverloads = fad->hasOverloads;
}
else
{ // for internal use
assert(!funcalias->isFuncAliasDeclaration());
this->hasOverloads = 0;
}
}
const char *FuncAliasDeclaration::kind()
@@ -3288,6 +3347,11 @@ const char *FuncAliasDeclaration::kind()
return "function alias";
}
FuncDeclaration *FuncAliasDeclaration::toAliasFunc()
{
return funcalias->toAliasFunc();
}
/****************************** FuncLiteralDeclaration ************************/
@@ -3737,7 +3801,7 @@ int StaticCtorDeclaration::addPostInvariant()
void StaticCtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (hgs->hdrgen)
if (hgs->hdrgen && !hgs->tpltMember)
{ buf->writestring("static this();");
buf->writenl();
return;