mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-04-12 06:49:02 +02:00
Merged dmd 2.059beta
This commit is contained in:
144
dmd2/func.c
144
dmd2/func.c
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user