First merge of 2.064 beta.

This corresponds to DMD commit a913ce4bc59a94a022a27e390fc841f4aededffb.

Doesn't build Phobos yet.
This commit is contained in:
David Nadlinger
2013-10-19 23:21:53 +02:00
committed by Kai Nacke
parent c400d180d2
commit cb341586e3
130 changed files with 13566 additions and 9190 deletions

View File

@@ -21,6 +21,7 @@
#include "dsymbol.h"
#include "scope.h"
#include "declaration.h"
#include "statement.h"
#include "aggregate.h"
#include "module.h"
#include "id.h"
@@ -50,6 +51,7 @@ Scope::Scope()
//printf("Scope::Scope() %p\n", this);
this->module = NULL;
this->instantiatingModule = NULL;
this->scopesym = NULL;
this->sd = NULL;
this->enclosing = NULL;
@@ -74,12 +76,11 @@ Scope::Scope()
this->inunion = 0;
this->nofree = 0;
this->noctor = 0;
this->noaccesscheck = 0;
this->needctfe = 0;
this->intypeof = 0;
this->speculative = 0;
this->parameterSpecialization = 0;
this->callSuper = 0;
this->fieldinit = NULL;
this->fieldinit_dim = 0;
this->flags = 0;
this->lastdc = NULL;
this->lastoffset = 0;
@@ -92,6 +93,7 @@ Scope::Scope(Scope *enclosing)
//printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
assert(!(enclosing->flags & SCOPEfree));
this->module = enclosing->module;
this->instantiatingModule = enclosing->instantiatingModule;
this->func = enclosing->func;
this->parent = enclosing->parent;
this->scopesym = NULL;
@@ -125,13 +127,12 @@ Scope::Scope(Scope *enclosing)
this->inunion = enclosing->inunion;
this->nofree = 0;
this->noctor = enclosing->noctor;
this->noaccesscheck = enclosing->noaccesscheck;
this->needctfe = enclosing->needctfe;
this->intypeof = enclosing->intypeof;
this->speculative = enclosing->speculative;
this->parameterSpecialization = enclosing->parameterSpecialization;
this->callSuper = enclosing->callSuper;
this->flags = (enclosing->flags & (SCOPEcontract | SCOPEdebug));
this->fieldinit = enclosing->saveFieldInit();
this->fieldinit_dim = enclosing->fieldinit_dim;
this->flags = (enclosing->flags & (SCOPEcontract | SCOPEdebug | SCOPEctfe));
this->lastdc = NULL;
this->lastoffset = 0;
this->docbuf = enclosing->docbuf;
@@ -183,7 +184,17 @@ Scope *Scope::pop()
Scope *enc = enclosing;
if (enclosing)
{
enclosing->callSuper |= callSuper;
if (enclosing->fieldinit && fieldinit)
{
size_t dim = fieldinit_dim;
for (size_t i = 0; i < dim; i++)
enclosing->fieldinit[i] |= fieldinit[i];
delete[] fieldinit;
fieldinit = NULL;
}
}
if (!nofree)
{ enclosing = freelist;
@@ -194,6 +205,19 @@ Scope *Scope::pop()
return enc;
}
Scope *Scope::startCTFE()
{
Scope *sc = this->push();
sc->flags = this->flags | SCOPEctfe;
return sc;
}
Scope *Scope::endCTFE()
{
assert(flags & SCOPEctfe);
return pop();
}
void Scope::mergeCallSuper(Loc loc, unsigned cs)
{
// This does a primitive flow analysis to support the restrictions
@@ -247,6 +271,131 @@ void Scope::mergeCallSuper(Loc loc, unsigned cs)
}
}
unsigned *Scope::saveFieldInit()
{
unsigned *fi = NULL;
if (fieldinit) // copy
{
size_t dim = fieldinit_dim;
fi = new unsigned[dim];
fi[0] = dim;
for (size_t i = 0; i < dim; i++)
fi[i] = fieldinit[i];
}
return fi;
}
bool mergeFieldInit(Loc loc, unsigned &fieldInit, unsigned fi, bool mustInit)
{
if (fi != fieldInit)
{
// Have any branches returned?
bool aRet = (fi & CSXreturn) != 0;
bool bRet = (fieldInit & CSXreturn) != 0;
bool ok;
if (aRet)
{
ok = !mustInit || (fi & CSXthis_ctor);
fieldInit = fieldInit;
}
else if (bRet)
{
ok = !mustInit || (fieldInit & CSXthis_ctor);
fieldInit = fi;
}
else
{
ok = !mustInit || !((fieldInit ^ fi) & CSXthis_ctor);
fieldInit |= fi;
}
return ok;
}
#if 0
// This does a primitive flow analysis to support the restrictions
// regarding when and how constructors can appear.
// It merges the results of two paths.
// The two paths are fieldInit and fi; the result is merged into fieldInit.
if (fi != fieldInit)
{ // Have ALL branches called a constructor?
int aAll = (fi & CSXthis_ctor) != 0;
int bAll = (fieldInit & CSXthis_ctor) != 0;
// Have ANY branches called a constructor?
bool aAny = (fi & CSXany_ctor) != 0;
bool bAny = (fieldInit & CSXany_ctor) != 0;
// Have any branches returned?
bool aRet = (fi & CSXreturn) != 0;
bool bRet = (fieldInit & CSXreturn) != 0;
bool ok = true;
printf("L%d fieldInit = x%x, fi = x%x\n", __LINE__, fieldInit, fi);
// If one has returned without a constructor call, there must be never
// have been ctor calls in the other.
if ( (aRet && !aAny && bAny) ||
(bRet && !bAny && aAny))
{ ok = false;
printf("L%d\n", __LINE__);
}
// If one branch has called a ctor and then exited, anything the
// other branch has done is OK (except returning without a
// ctor call, but we already checked that).
else if (aRet && aAll)
{
//fieldInit |= fi & (CSXany_ctor | CSXlabel);
printf("L%d -> fieldInit = x%x\n", __LINE__, fieldInit);
}
else if (bRet && bAll)
{
fieldInit = fi;// | (fieldInit & (CSXany_ctor | CSXlabel));
printf("L%d -> fieldInit = x%x\n", __LINE__, fieldInit);
}
else
{ // Both branches must have called ctors, or both not.
ok = (aAll == bAll);
// If one returned without a ctor, we must remember that
// (Don't bother if we've already found an error)
if (ok && aRet && !aAny)
fieldInit |= CSXreturn;
fieldInit |= fi & (CSXany_ctor | CSXlabel);
printf("L%d ok = %d, fieldInit = x%x, fi = x%x\n", __LINE__, ok, fieldInit, fi);
}
return ok;
}
#endif
return true;
}
void Scope::mergeFieldInit(Loc loc, unsigned *fies)
{
if (fieldinit && fies)
{
FuncDeclaration *f = func;
if (fes) f = fes->func;
AggregateDeclaration *ad = f->isAggregateMember2();
assert(ad);
for (size_t i = 0; i < ad->fields.dim; i++)
{
VarDeclaration *v = ad->fields[i];
bool mustInit = (v->storage_class & STCnodefaultctor ||
v->type->needsNested());
if (!::mergeFieldInit(loc, fieldinit[i], fies[i], mustInit))
{
::error(loc, "one path skips field %s", ad->fields[i]->toChars());
}
}
}
}
Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
{ Dsymbol *s;
Scope *sc;
@@ -282,8 +431,7 @@ Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
s = sc->scopesym->search(loc, ident, 0);
if (s)
{
if (global.params.Dversion > 1 &&
ident == Id::length &&
if (ident == Id::length &&
sc->scopesym->isArrayScopeSymbol() &&
sc->enclosing &&
sc->enclosing->search(loc, ident, NULL))
@@ -414,9 +562,8 @@ void *scope_search_fp(void *arg, const char *seed)
assert(id);
Scope *sc = (Scope *)arg;
Module::clearCache();
Dsymbol *s = sc->search(Loc(), id, NULL);
return s;
return (void*)s;
}
Dsymbol *Scope::search_correct(Identifier *ident)