mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-15 20:33:14 +01: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:
@@ -16,6 +16,7 @@
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
|
||||
#include "dsymbol.h"
|
||||
|
||||
#include <vector>
|
||||
@@ -49,7 +50,7 @@ namespace llvm
|
||||
struct AggregateDeclaration : ScopeDsymbol
|
||||
{
|
||||
Type *type;
|
||||
unsigned storage_class;
|
||||
StorageClass storage_class;
|
||||
enum PROT protection;
|
||||
Type *handle; // 'this' type
|
||||
unsigned structsize; // size of struct
|
||||
@@ -63,6 +64,10 @@ struct AggregateDeclaration : ScopeDsymbol
|
||||
// 2: cannot determine size; fwd referenced
|
||||
int isdeprecated; // !=0 if deprecated
|
||||
|
||||
#if DMDV2
|
||||
int isnested; // !=0 if is nested
|
||||
VarDeclaration *vthis; // 'this' parameter if this aggregate is nested
|
||||
#endif
|
||||
// Special member functions
|
||||
InvariantDeclaration *inv; // invariant
|
||||
NewDeclaration *aggNew; // allocator
|
||||
@@ -92,6 +97,7 @@ struct AggregateDeclaration : ScopeDsymbol
|
||||
void addField(Scope *sc, VarDeclaration *v);
|
||||
int isDeprecated(); // is aggregate deprecated?
|
||||
FuncDeclaration *buildDtor(Scope *sc);
|
||||
int isNested();
|
||||
|
||||
void emitComment(Scope *sc);
|
||||
void toJsonBuffer(OutBuffer *buf);
|
||||
@@ -147,7 +153,15 @@ struct StructDeclaration : AggregateDeclaration
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
char *mangle();
|
||||
const char *kind();
|
||||
#if DMDV1
|
||||
Expression *cloneMembers();
|
||||
#endif
|
||||
#if DMDV2
|
||||
int needOpAssign();
|
||||
FuncDeclaration *buildOpAssign(Scope *sc);
|
||||
FuncDeclaration *buildPostBlit(Scope *sc);
|
||||
FuncDeclaration *buildCpCtor(Scope *sc);
|
||||
#endif
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
@@ -209,8 +223,10 @@ struct ClassDeclaration : AggregateDeclaration
|
||||
static ClassDeclaration *classinfo;
|
||||
|
||||
ClassDeclaration *baseClass; // NULL only if this is Object
|
||||
#if DMDV1
|
||||
CtorDeclaration *ctor;
|
||||
CtorDeclaration *defaultCtor; // default constructor
|
||||
#endif
|
||||
FuncDeclaration *staticCtor;
|
||||
FuncDeclaration *staticDtor;
|
||||
Array vtbl; // Array of FuncDeclaration's making up the vtbl[]
|
||||
@@ -231,10 +247,10 @@ struct ClassDeclaration : AggregateDeclaration
|
||||
// it derives from IUnknown)
|
||||
int isscope; // !=0 if this is a scope class
|
||||
int isabstract; // !=0 if abstract class
|
||||
|
||||
#if DMDV1
|
||||
int isnested; // !=0 if is nested
|
||||
VarDeclaration *vthis; // 'this' parameter if this class is nested
|
||||
|
||||
#endif
|
||||
int inuse; // to prevent recursive attempts
|
||||
|
||||
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
|
||||
@@ -252,7 +268,9 @@ struct ClassDeclaration : AggregateDeclaration
|
||||
#endif
|
||||
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
|
||||
void interfaceSemantic(Scope *sc);
|
||||
#if DMDV1
|
||||
int isNested();
|
||||
#endif
|
||||
int isCOMclass();
|
||||
virtual int isCOMinterface();
|
||||
#if DMDV2
|
||||
|
||||
63
dmd/attrib.c
63
dmd/attrib.c
@@ -78,7 +78,7 @@ int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
|
||||
}
|
||||
|
||||
void AttribDeclaration::setScopeNewSc(Scope *sc,
|
||||
unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection,
|
||||
StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
|
||||
unsigned structalign)
|
||||
{
|
||||
if (decl)
|
||||
@@ -113,7 +113,7 @@ void AttribDeclaration::setScopeNewSc(Scope *sc,
|
||||
}
|
||||
|
||||
void AttribDeclaration::semanticNewSc(Scope *sc,
|
||||
unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection,
|
||||
StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
|
||||
unsigned structalign)
|
||||
{
|
||||
if (decl)
|
||||
@@ -360,7 +360,7 @@ void AttribDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
|
||||
/************************* StorageClassDeclaration ****************************/
|
||||
|
||||
StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl)
|
||||
StorageClassDeclaration::StorageClassDeclaration(StorageClass stc, Array *decl)
|
||||
: AttribDeclaration(decl)
|
||||
{
|
||||
this->stc = stc;
|
||||
@@ -379,7 +379,7 @@ void StorageClassDeclaration::setScope(Scope *sc)
|
||||
{
|
||||
if (decl)
|
||||
{
|
||||
unsigned scstc = sc->stc;
|
||||
StorageClass scstc = sc->stc;
|
||||
|
||||
/* These sets of storage classes are mutually exclusive,
|
||||
* so choose the innermost or most recent one.
|
||||
@@ -402,7 +402,7 @@ void StorageClassDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
if (decl)
|
||||
{
|
||||
unsigned scstc = sc->stc;
|
||||
StorageClass scstc = sc->stc;
|
||||
|
||||
/* These sets of storage classes are mutually exclusive,
|
||||
* so choose the innermost or most recent one.
|
||||
@@ -421,11 +421,11 @@ void StorageClassDeclaration::semantic(Scope *sc)
|
||||
}
|
||||
}
|
||||
|
||||
void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc)
|
||||
void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, StorageClass stc)
|
||||
{
|
||||
struct SCstring
|
||||
{
|
||||
int stc;
|
||||
StorageClass stc;
|
||||
enum TOK tok;
|
||||
};
|
||||
|
||||
@@ -441,6 +441,19 @@ void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc)
|
||||
{ STCsynchronized, TOKsynchronized },
|
||||
{ STCdeprecated, TOKdeprecated },
|
||||
{ STCoverride, TOKoverride },
|
||||
{ STClazy, TOKlazy },
|
||||
{ STCalias, TOKalias },
|
||||
{ STCout, TOKout },
|
||||
{ STCin, TOKin },
|
||||
#if DMDV2
|
||||
{ STCimmutable, TOKimmutable },
|
||||
{ STCshared, TOKshared },
|
||||
{ STCnothrow, TOKnothrow },
|
||||
{ STCpure, TOKpure },
|
||||
{ STCref, TOKref },
|
||||
{ STCtls, TOKtls },
|
||||
{ STCgshared, TOKgshared },
|
||||
#endif
|
||||
};
|
||||
|
||||
for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++)
|
||||
@@ -1006,25 +1019,27 @@ void PragmaDeclaration::semantic(Scope *sc)
|
||||
goto Lnodecl;
|
||||
}
|
||||
#endif
|
||||
#if DMDV2
|
||||
else if (ident == Id::startaddress)
|
||||
{
|
||||
if (!args || args->dim != 1)
|
||||
error("function name expected for start address");
|
||||
else
|
||||
{
|
||||
Expression *e = (Expression *)args->data[0];
|
||||
e = e->semantic(sc);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
args->data[0] = (void *)e;
|
||||
Dsymbol *sa = getDsymbol(e);
|
||||
if (!sa || !sa->isFuncDeclaration())
|
||||
error("function name expected for start address, not '%s'", e->toChars());
|
||||
}
|
||||
goto Lnodecl;
|
||||
}
|
||||
#endif
|
||||
#if TARGET_NET
|
||||
else if (ident == Lexer::idPool("assembly"))
|
||||
{
|
||||
if (!args || args->dim != 1)
|
||||
error("pragma has invalid number of arguments");
|
||||
else
|
||||
{
|
||||
Expression *e = (Expression *)args->data[0];
|
||||
e = e->semantic(sc);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
args->data[0] = (void *)e;
|
||||
if (e->op != TOKstring)
|
||||
{
|
||||
error("string expected, not '%s'", e->toChars());
|
||||
}
|
||||
PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e));
|
||||
decl = new Array;
|
||||
decl->push(pragma);
|
||||
}
|
||||
}
|
||||
#endif // TARGET_NET
|
||||
|
||||
@@ -1385,7 +1400,7 @@ void PragmaDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
e->toCBuffer(buf, hgs);
|
||||
}
|
||||
}
|
||||
buf->writestring(")");
|
||||
buf->writeByte(')');
|
||||
AttribDeclaration::toCBuffer(buf, hgs);
|
||||
}
|
||||
|
||||
|
||||
10
dmd/attrib.h
10
dmd/attrib.h
@@ -37,10 +37,10 @@ struct AttribDeclaration : Dsymbol
|
||||
virtual Array *include(Scope *sc, ScopeDsymbol *s);
|
||||
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||
void setScopeNewSc(Scope *sc,
|
||||
unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
||||
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
||||
unsigned structalign);
|
||||
void semanticNewSc(Scope *sc,
|
||||
unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
||||
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
||||
unsigned structalign);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
@@ -69,15 +69,15 @@ struct AttribDeclaration : Dsymbol
|
||||
|
||||
struct StorageClassDeclaration: AttribDeclaration
|
||||
{
|
||||
unsigned stc;
|
||||
StorageClass stc;
|
||||
|
||||
StorageClassDeclaration(unsigned stc, Array *decl);
|
||||
StorageClassDeclaration(StorageClass stc, Array *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void setScope(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
static void stcToCBuffer(OutBuffer *buf, int stc);
|
||||
static void stcToCBuffer(OutBuffer *buf, StorageClass stc);
|
||||
};
|
||||
|
||||
struct LinkDeclaration : AttribDeclaration
|
||||
|
||||
@@ -104,7 +104,7 @@ struct Declaration : Dsymbol
|
||||
{
|
||||
Type *type;
|
||||
Type *originalType; // before semantic analysis
|
||||
unsigned storage_class;
|
||||
StorageClass storage_class;
|
||||
enum PROT protection;
|
||||
enum LINK linkage;
|
||||
int inuse; // used to detect cycles
|
||||
@@ -260,6 +260,7 @@ struct VarDeclaration : Declaration
|
||||
int noscope; // no scope semantics
|
||||
#if DMDV2
|
||||
FuncDeclarations nestedrefs; // referenced by these lexically nested functions
|
||||
bool isargptr; // if parameter that _argptr points to
|
||||
#else
|
||||
int nestedref; // referenced by a lexically nested function
|
||||
#endif
|
||||
@@ -712,7 +713,7 @@ struct FuncDeclaration : Declaration
|
||||
int nestedFrameRef; // !=0 if nested variables referenced
|
||||
#endif
|
||||
|
||||
FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type);
|
||||
FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type);
|
||||
Dsymbol *syntaxCopy(Dsymbol *);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
|
||||
337
dmd/func.c
337
dmd/func.c
@@ -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
|
||||
|
||||
@@ -58,7 +58,7 @@ Global::Global()
|
||||
|
||||
copyright = "Copyright (c) 1999-2009 by Digital Mars and Tomas Lindquist Olsen";
|
||||
written = "written by Walter Bright and Tomas Lindquist Olsen";
|
||||
version = "v1.051";
|
||||
version = "v1.052";
|
||||
ldc_version = LDC_REV;
|
||||
llvm_version = LLVM_REV_STR;
|
||||
global.structalign = 8;
|
||||
|
||||
@@ -93,6 +93,10 @@ the target object file format:
|
||||
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
|
||||
#define STRUCTTHISREF DMDV2 // if 'this' for struct is a reference, not a pointer
|
||||
#define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN
|
||||
#define SARRAYVALUE DMDV2 // static arrays are value types
|
||||
|
||||
// Set if C++ mangling is done by the front end
|
||||
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS))
|
||||
|
||||
/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and
|
||||
* TARGET_SOLARIS, which are
|
||||
@@ -413,6 +417,9 @@ enum MATCH
|
||||
MATCHexact // exact match
|
||||
};
|
||||
|
||||
typedef unsigned StorageClass;
|
||||
|
||||
|
||||
void warning(Loc loc, const char *format, ...) IS_PRINTF(2);
|
||||
void vwarning(Loc loc, const char *format, va_list);
|
||||
void error(Loc loc, const char *format, ...) IS_PRINTF(2);
|
||||
|
||||
13
dmd/mtype.h
13
dmd/mtype.h
@@ -590,6 +590,9 @@ struct TypeStruct : Type
|
||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
int hasPointers();
|
||||
#if CPP_MANGLE
|
||||
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
|
||||
#endif
|
||||
|
||||
#if IN_DMD
|
||||
type *toCtype();
|
||||
@@ -701,7 +704,7 @@ struct TypeClass : Type
|
||||
#if DMDV2
|
||||
Type *toHeadMutable();
|
||||
MATCH constConv(Type *to);
|
||||
#if TARGET_LINUX || TARGET_OSX
|
||||
#if CPP_MANGLE
|
||||
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
|
||||
#endif
|
||||
#endif
|
||||
@@ -748,19 +751,21 @@ struct TypeSlice : Type
|
||||
struct Argument : Object
|
||||
{
|
||||
//enum InOut inout;
|
||||
unsigned storageClass;
|
||||
StorageClass storageClass;
|
||||
Type *type;
|
||||
Identifier *ident;
|
||||
Expression *defaultArg;
|
||||
|
||||
Argument(unsigned storageClass, Type *type, Identifier *ident, Expression *defaultArg);
|
||||
Argument(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
|
||||
Argument *syntaxCopy();
|
||||
Type *isLazyArray();
|
||||
void toDecoBuffer(OutBuffer *buf, bool mangle);
|
||||
static Arguments *arraySyntaxCopy(Arguments *args);
|
||||
static char *argsTypesToChars(Arguments *args, int varargs);
|
||||
static void argsCppMangle(OutBuffer *buf, CppMangleState *cms, Arguments *arguments, int varargs);
|
||||
static void argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Arguments *arguments, int varargs);
|
||||
static void argsToDecoBuffer(OutBuffer *buf, Arguments *arguments, bool mangle);
|
||||
static int isTPL(Arguments *arguments);
|
||||
static size_t dim(Arguments *arguments);
|
||||
static Argument *getNth(Arguments *arguments, size_t nth, size_t *pn = NULL);
|
||||
};
|
||||
@@ -771,4 +776,6 @@ extern int REALPAD;
|
||||
extern int Tsize_t;
|
||||
extern int Tptrdiff_t;
|
||||
|
||||
int arrayTypeCompatible(Loc loc, Type *t1, Type *t2);
|
||||
|
||||
#endif /* DMD_MTYPE_H */
|
||||
|
||||
32
dmd/parse.c
32
dmd/parse.c
@@ -149,7 +149,7 @@ Array *Parser::parseDeclDefs(int once)
|
||||
Array *a;
|
||||
Array *aelse;
|
||||
enum PROT prot;
|
||||
unsigned stc;
|
||||
StorageClass stc;
|
||||
Condition *condition;
|
||||
unsigned char *comment;
|
||||
|
||||
@@ -286,6 +286,7 @@ Array *Parser::parseDeclDefs(int once)
|
||||
case TOKpure: stc = STCpure; goto Lstc;
|
||||
case TOKref: stc = STCref; goto Lstc;
|
||||
case TOKtls: stc = STCtls; goto Lstc;
|
||||
case TOKgshared: stc = STCgshared; goto Lstc;
|
||||
//case TOKmanifest: stc = STCmanifest; goto Lstc;
|
||||
#endif
|
||||
|
||||
@@ -514,6 +515,23 @@ Array *Parser::parseDeclDefs(int once)
|
||||
return decldefs;
|
||||
}
|
||||
|
||||
/*********************************************
|
||||
* Give error on conflicting storage classes.
|
||||
*/
|
||||
|
||||
#if DMDV2
|
||||
void Parser::composeStorageClass(StorageClass stc)
|
||||
{
|
||||
StorageClass u = stc;
|
||||
u &= STCconst | STCimmutable | STCmanifest;
|
||||
if (u & (u - 1))
|
||||
error("conflicting storage class %s", Token::toChars(token.value));
|
||||
u = stc;
|
||||
u &= STCgshared | STCshared | STCtls;
|
||||
if (u & (u - 1))
|
||||
error("conflicting storage class %s", Token::toChars(token.value));
|
||||
}
|
||||
#endif
|
||||
|
||||
/********************************************
|
||||
* Parse declarations after an align, protection, or extern decl.
|
||||
@@ -767,7 +785,7 @@ Condition *Parser::parseStaticIfCondition()
|
||||
* Current token is 'this'.
|
||||
*/
|
||||
|
||||
CtorDeclaration *Parser::parseCtor()
|
||||
Dsymbol *Parser::parseCtor()
|
||||
{
|
||||
CtorDeclaration *f;
|
||||
Arguments *arguments;
|
||||
@@ -945,7 +963,7 @@ Arguments *Parser::parseParameters(int *pvarargs)
|
||||
Identifier *ai = NULL;
|
||||
Type *at;
|
||||
Argument *a;
|
||||
unsigned storageClass;
|
||||
StorageClass storageClass = 0;
|
||||
Expression *ae;
|
||||
|
||||
storageClass = STCin; // parameter is "in" by default
|
||||
@@ -1323,7 +1341,7 @@ Lerr:
|
||||
* Parse template parameter list.
|
||||
*/
|
||||
|
||||
TemplateParameters *Parser::parseTemplateParameterList()
|
||||
TemplateParameters *Parser::parseTemplateParameterList(int flag)
|
||||
{
|
||||
TemplateParameters *tpl = new TemplateParameters();
|
||||
|
||||
@@ -2082,8 +2100,8 @@ Type *Parser::parseDeclarator(Type *t, Identifier **pident, TemplateParameters *
|
||||
|
||||
Array *Parser::parseDeclarations()
|
||||
{
|
||||
enum STC storage_class;
|
||||
enum STC stc;
|
||||
StorageClass storage_class;
|
||||
StorageClass stc;
|
||||
Type *ts;
|
||||
Type *t;
|
||||
Type *tfirst;
|
||||
@@ -2338,7 +2356,7 @@ Array *Parser::parseDeclarations()
|
||||
*/
|
||||
|
||||
#if DMDV2
|
||||
Array *Parser::parseAutoDeclarations(unsigned storageClass, unsigned char *comment)
|
||||
Array *Parser::parseAutoDeclarations(StorageClass storageClass, unsigned char *comment)
|
||||
{
|
||||
Array *a = new Array;
|
||||
|
||||
|
||||
14
dmd/parse.h
14
dmd/parse.h
@@ -68,18 +68,24 @@ struct Parser : Lexer
|
||||
|
||||
Array *parseModule();
|
||||
Array *parseDeclDefs(int once);
|
||||
Array *parseAutoDeclarations(StorageClass storageClass, unsigned char *comment);
|
||||
Array *parseBlock();
|
||||
void composeStorageClass(unsigned stc);
|
||||
void composeStorageClass(StorageClass stc);
|
||||
Expression *parseConstraint();
|
||||
TemplateDeclaration *parseTemplateDeclaration();
|
||||
TemplateParameters *parseTemplateParameterList();
|
||||
TemplateParameters *parseTemplateParameterList(int flag = 0);
|
||||
Dsymbol *parseMixin();
|
||||
Objects *parseTemplateArgumentList();
|
||||
Objects *parseTemplateArgumentList2();
|
||||
Objects *parseTemplateArgument();
|
||||
StaticAssert *parseStaticAssert();
|
||||
TypeQualified *parseTypeof();
|
||||
enum LINK parseLinkage();
|
||||
Condition *parseDebugCondition();
|
||||
Condition *parseVersionCondition();
|
||||
Condition *parseStaticIfCondition();
|
||||
CtorDeclaration *parseCtor();
|
||||
Dsymbol *parseCtor();
|
||||
PostBlitDeclaration *parsePostBlit();
|
||||
DtorDeclaration *parseDtor();
|
||||
StaticCtorDeclaration *parseStaticCtor();
|
||||
StaticDtorDeclaration *parseStaticDtor();
|
||||
@@ -92,6 +98,7 @@ struct Parser : Lexer
|
||||
Dsymbol *parseAggregate();
|
||||
BaseClasses *parseBaseClasses();
|
||||
Import *parseImport(Array *decldefs, int isstatic);
|
||||
Type *parseType(Identifier **pident = NULL, TemplateParameters **tpl = NULL);
|
||||
Type *parseBasicType();
|
||||
Type *parseBasicType2(Type *t);
|
||||
Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL);
|
||||
@@ -99,6 +106,7 @@ struct Parser : Lexer
|
||||
void parseContracts(FuncDeclaration *f);
|
||||
Statement *parseStatement(int flags);
|
||||
Initializer *parseInitializer();
|
||||
Expression *parseDefaultInitExp();
|
||||
void check(Loc loc, enum TOK value);
|
||||
void check(enum TOK value);
|
||||
void check(enum TOK value, const char *string);
|
||||
|
||||
@@ -88,7 +88,7 @@ struct Scope
|
||||
enum PROT protection; // protection for class members
|
||||
int explicitProtection; // set if in an explicit protection attribute
|
||||
|
||||
unsigned stc; // storage class
|
||||
StorageClass stc; // storage class
|
||||
|
||||
unsigned flags;
|
||||
#define SCOPEctor 1 // constructor type
|
||||
|
||||
Reference in New Issue
Block a user