mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-07-29 02:20:04 +02:00
[svn r175] merged dmd 1.029
This commit is contained in:
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2006 by Digital Mars
|
// Copyright (c) 1999-2008 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -64,6 +64,8 @@ struct AggregateDeclaration : ScopeDsymbol
|
|||||||
// 2: cannot determine size; fwd referenced
|
// 2: cannot determine size; fwd referenced
|
||||||
int isdeprecated; // !=0 if deprecated
|
int isdeprecated; // !=0 if deprecated
|
||||||
Scope *scope; // !=NULL means context to use
|
Scope *scope; // !=NULL means context to use
|
||||||
|
FuncDeclarations dtors; // Array of destructors
|
||||||
|
FuncDeclaration *dtor; // aggregate destructor
|
||||||
|
|
||||||
// Special member functions
|
// Special member functions
|
||||||
InvariantDeclaration *inv; // invariant
|
InvariantDeclaration *inv; // invariant
|
||||||
@@ -83,6 +85,7 @@ struct AggregateDeclaration : ScopeDsymbol
|
|||||||
Type *getType();
|
Type *getType();
|
||||||
void addField(Scope *sc, VarDeclaration *v);
|
void addField(Scope *sc, VarDeclaration *v);
|
||||||
int isDeprecated(); // is aggregate deprecated?
|
int isDeprecated(); // is aggregate deprecated?
|
||||||
|
FuncDeclaration *buildDtor(Scope *sc);
|
||||||
|
|
||||||
void emitComment(Scope *sc);
|
void emitComment(Scope *sc);
|
||||||
void toDocBuffer(OutBuffer *buf);
|
void toDocBuffer(OutBuffer *buf);
|
||||||
@@ -123,6 +126,7 @@ struct StructDeclaration : AggregateDeclaration
|
|||||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||||
char *mangle();
|
char *mangle();
|
||||||
char *kind();
|
char *kind();
|
||||||
|
Expression *cloneMembers();
|
||||||
void toDocBuffer(OutBuffer *buf);
|
void toDocBuffer(OutBuffer *buf);
|
||||||
|
|
||||||
PROT getAccess(Dsymbol *smember); // determine access to smember
|
PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||||
@@ -164,7 +168,11 @@ struct BaseClass
|
|||||||
void copyBaseInterfaces(BaseClasses *);
|
void copyBaseInterfaces(BaseClasses *);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#if V2
|
||||||
|
#define CLASSINFO_SIZE (0x3C+16) // value of ClassInfo.size
|
||||||
|
#else
|
||||||
#define CLASSINFO_SIZE (0x3C+12) // value of ClassInfo.size
|
#define CLASSINFO_SIZE (0x3C+12) // value of ClassInfo.size
|
||||||
|
#endif
|
||||||
|
|
||||||
struct ClassDeclaration : AggregateDeclaration
|
struct ClassDeclaration : AggregateDeclaration
|
||||||
{
|
{
|
||||||
@@ -174,7 +182,6 @@ struct ClassDeclaration : AggregateDeclaration
|
|||||||
ClassDeclaration *baseClass; // NULL only if this is Object
|
ClassDeclaration *baseClass; // NULL only if this is Object
|
||||||
CtorDeclaration *ctor;
|
CtorDeclaration *ctor;
|
||||||
CtorDeclaration *defaultCtor; // default constructor
|
CtorDeclaration *defaultCtor; // default constructor
|
||||||
FuncDeclarations dtors; // Array of destructors
|
|
||||||
FuncDeclaration *staticCtor;
|
FuncDeclaration *staticCtor;
|
||||||
FuncDeclaration *staticDtor;
|
FuncDeclaration *staticDtor;
|
||||||
Array vtbl; // Array of FuncDeclaration's making up the vtbl[]
|
Array vtbl; // Array of FuncDeclaration's making up the vtbl[]
|
||||||
@@ -191,13 +198,16 @@ struct ClassDeclaration : AggregateDeclaration
|
|||||||
// their own vtbl[]
|
// their own vtbl[]
|
||||||
|
|
||||||
ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
||||||
int com; // !=0 if this is a COM class
|
int com; // !=0 if this is a COM class (meaning
|
||||||
|
// it derives from IUnknown)
|
||||||
int isauto; // !=0 if this is an auto class
|
int isauto; // !=0 if this is an auto class
|
||||||
int isabstract; // !=0 if abstract class
|
int isabstract; // !=0 if abstract class
|
||||||
|
|
||||||
int isnested; // !=0 if is nested
|
int isnested; // !=0 if is nested
|
||||||
VarDeclaration *vthis; // 'this' parameter if this class is nested
|
VarDeclaration *vthis; // 'this' parameter if this class is nested
|
||||||
|
|
||||||
|
int inuse; // to prevent recursive attempts
|
||||||
|
|
||||||
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
|
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
|
||||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||||
void semantic(Scope *sc);
|
void semantic(Scope *sc);
|
||||||
@@ -208,11 +218,17 @@ struct ClassDeclaration : AggregateDeclaration
|
|||||||
virtual int isBaseOf(ClassDeclaration *cd, int *poffset);
|
virtual int isBaseOf(ClassDeclaration *cd, int *poffset);
|
||||||
|
|
||||||
Dsymbol *search(Loc, Identifier *ident, int flags);
|
Dsymbol *search(Loc, Identifier *ident, int flags);
|
||||||
|
#if V2
|
||||||
|
int isFuncHidden(FuncDeclaration *fd);
|
||||||
|
#endif
|
||||||
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
|
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
|
||||||
void interfaceSemantic(Scope *sc);
|
void interfaceSemantic(Scope *sc);
|
||||||
int isNested();
|
int isNested();
|
||||||
int isCOMclass();
|
int isCOMclass();
|
||||||
virtual int isCOMinterface();
|
virtual int isCOMinterface();
|
||||||
|
#if V2
|
||||||
|
virtual int isCPPinterface();
|
||||||
|
#endif
|
||||||
int isAbstract();
|
int isAbstract();
|
||||||
virtual int vtblOffset();
|
virtual int vtblOffset();
|
||||||
char *kind();
|
char *kind();
|
||||||
@@ -234,6 +250,7 @@ struct ClassDeclaration : AggregateDeclaration
|
|||||||
|
|
||||||
Symbol *vtblsym;
|
Symbol *vtblsym;
|
||||||
|
|
||||||
|
// llvm
|
||||||
void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result);
|
void offsetToIndex(Type* t, unsigned os, std::vector<unsigned>& result);
|
||||||
|
|
||||||
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
|
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
|
||||||
@@ -241,6 +258,9 @@ struct ClassDeclaration : AggregateDeclaration
|
|||||||
|
|
||||||
struct InterfaceDeclaration : ClassDeclaration
|
struct InterfaceDeclaration : ClassDeclaration
|
||||||
{
|
{
|
||||||
|
#if V2
|
||||||
|
int cpp; // !=0 if this is a C++ interface
|
||||||
|
#endif
|
||||||
InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
|
InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
|
||||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||||
void semantic(Scope *sc);
|
void semantic(Scope *sc);
|
||||||
@@ -248,6 +268,9 @@ struct InterfaceDeclaration : ClassDeclaration
|
|||||||
int isBaseOf(BaseClass *bc, int *poffset);
|
int isBaseOf(BaseClass *bc, int *poffset);
|
||||||
char *kind();
|
char *kind();
|
||||||
int vtblOffset();
|
int vtblOffset();
|
||||||
|
#if V2
|
||||||
|
int isCPPinterface();
|
||||||
|
#endif
|
||||||
virtual int isCOMinterface();
|
virtual int isCOMinterface();
|
||||||
|
|
||||||
void toObjFile(); // compile to .obj file
|
void toObjFile(); // compile to .obj file
|
||||||
|
|||||||
43
dmd/attrib.c
43
dmd/attrib.c
@@ -203,15 +203,15 @@ int AttribDeclaration::cvMember(unsigned char *p)
|
|||||||
|
|
||||||
if (d)
|
if (d)
|
||||||
{
|
{
|
||||||
for (i = 0; i < d->dim; i++)
|
for (i = 0; i < d->dim; i++)
|
||||||
{ Dsymbol *s;
|
{ Dsymbol *s;
|
||||||
|
|
||||||
s = (Dsymbol *)d->data[i];
|
s = (Dsymbol *)d->data[i];
|
||||||
n = s->cvMember(p);
|
n = s->cvMember(p);
|
||||||
if (p)
|
if (p)
|
||||||
p += n;
|
p += n;
|
||||||
nwritten += n;
|
nwritten += n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nwritten;
|
return nwritten;
|
||||||
}
|
}
|
||||||
@@ -917,6 +917,33 @@ void PragmaDeclaration::semantic(Scope *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (global.params.ignoreUnsupportedPragmas)
|
||||||
|
{
|
||||||
|
if (global.params.verbose)
|
||||||
|
{
|
||||||
|
/* Print unrecognized pragmas
|
||||||
|
*/
|
||||||
|
printf("pragma %s", ident->toChars());
|
||||||
|
if (args)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < args->dim; i++)
|
||||||
|
{
|
||||||
|
Expression *e = (Expression *)args->data[i];
|
||||||
|
e = e->semantic(sc);
|
||||||
|
e = e->optimize(WANTvalue | WANTinterpret);
|
||||||
|
if (i == 0)
|
||||||
|
printf(" (");
|
||||||
|
else
|
||||||
|
printf(",");
|
||||||
|
printf("%s", e->toChars());
|
||||||
|
}
|
||||||
|
if (args->dim)
|
||||||
|
printf(")");
|
||||||
|
}
|
||||||
|
printf("\n");
|
||||||
|
}
|
||||||
|
goto Lnodecl;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
error("unrecognized pragma(%s)", ident->toChars());
|
error("unrecognized pragma(%s)", ident->toChars());
|
||||||
|
|
||||||
|
|||||||
@@ -959,7 +959,8 @@ Expression *ArrayLiteralExp::castTo(Scope *sc, Type *t)
|
|||||||
Type *tb = t->toBasetype();
|
Type *tb = t->toBasetype();
|
||||||
if ((tb->ty == Tarray || tb->ty == Tsarray) &&
|
if ((tb->ty == Tarray || tb->ty == Tsarray) &&
|
||||||
(typeb->ty == Tarray || typeb->ty == Tsarray) &&
|
(typeb->ty == Tarray || typeb->ty == Tsarray) &&
|
||||||
tb->nextOf()->toBasetype()->ty != Tvoid)
|
// Not trying to convert non-void[] to void[]
|
||||||
|
!(tb->nextOf()->toBasetype()->ty == Tvoid && typeb->nextOf()->toBasetype()->ty != Tvoid))
|
||||||
{
|
{
|
||||||
if (tb->ty == Tsarray)
|
if (tb->ty == Tsarray)
|
||||||
{ TypeSArray *tsa = (TypeSArray *)tb;
|
{ TypeSArray *tsa = (TypeSArray *)tb;
|
||||||
|
|||||||
10
dmd/class.c
10
dmd/class.c
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2007 by Digital Mars
|
// Copyright (c) 1999-2008 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -186,6 +186,7 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
|
|||||||
isabstract = 0;
|
isabstract = 0;
|
||||||
isnested = 0;
|
isnested = 0;
|
||||||
vthis = NULL;
|
vthis = NULL;
|
||||||
|
inuse = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s)
|
Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s)
|
||||||
@@ -642,6 +643,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
sizeok = 1;
|
sizeok = 1;
|
||||||
Module::dprogress++;
|
Module::dprogress++;
|
||||||
|
|
||||||
|
dtor = buildDtor(sc);
|
||||||
|
|
||||||
sc->pop();
|
sc->pop();
|
||||||
|
|
||||||
@@ -974,6 +976,8 @@ void InterfaceDeclaration::semantic(Scope *sc)
|
|||||||
{ int i;
|
{ int i;
|
||||||
|
|
||||||
//printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type);
|
//printf("InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type);
|
||||||
|
if (inuse)
|
||||||
|
return;
|
||||||
if (!scope)
|
if (!scope)
|
||||||
{ type = type->semantic(loc, sc);
|
{ type = type->semantic(loc, sc);
|
||||||
handle = handle->semantic(loc, sc);
|
handle = handle->semantic(loc, sc);
|
||||||
@@ -1058,7 +1062,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
|
|||||||
baseclasses.remove(i);
|
baseclasses.remove(i);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (!b->base->symtab || b->base->scope)
|
if (!b->base->symtab || b->base->scope || b->base->inuse)
|
||||||
{
|
{
|
||||||
//error("forward reference of base class %s", baseClass->toChars());
|
//error("forward reference of base class %s", baseClass->toChars());
|
||||||
// Forward reference of base, try again later
|
// Forward reference of base, try again later
|
||||||
@@ -1123,11 +1127,13 @@ void InterfaceDeclaration::semantic(Scope *sc)
|
|||||||
sc->structalign = 8;
|
sc->structalign = 8;
|
||||||
structalign = sc->structalign;
|
structalign = sc->structalign;
|
||||||
sc->offset = 8;
|
sc->offset = 8;
|
||||||
|
inuse++;
|
||||||
for (i = 0; i < members->dim; i++)
|
for (i = 0; i < members->dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = (Dsymbol *)members->data[i];
|
Dsymbol *s = (Dsymbol *)members->data[i];
|
||||||
s->semantic(sc);
|
s->semantic(sc);
|
||||||
}
|
}
|
||||||
|
inuse--;
|
||||||
//members->print();
|
//members->print();
|
||||||
sc->pop();
|
sc->pop();
|
||||||
//printf("-InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type);
|
//printf("-InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type);
|
||||||
|
|||||||
175
dmd/clone.c
Normal file
175
dmd/clone.c
Normal file
@@ -0,0 +1,175 @@
|
|||||||
|
|
||||||
|
// Compiler implementation of the D programming language
|
||||||
|
// Copyright (c) 1999-2008 by Digital Mars
|
||||||
|
// All Rights Reserved
|
||||||
|
// written by Walter Bright
|
||||||
|
// http://www.digitalmars.com
|
||||||
|
// License for redistribution is by either the Artistic License
|
||||||
|
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||||
|
// See the included readme.txt for details.
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <assert.h>
|
||||||
|
|
||||||
|
#include "root.h"
|
||||||
|
#include "aggregate.h"
|
||||||
|
#include "scope.h"
|
||||||
|
#include "mtype.h"
|
||||||
|
#include "declaration.h"
|
||||||
|
#include "module.h"
|
||||||
|
#include "id.h"
|
||||||
|
#include "expression.h"
|
||||||
|
#include "statement.h"
|
||||||
|
|
||||||
|
|
||||||
|
/*********************************
|
||||||
|
* Generate expression that calls opClone()
|
||||||
|
* for each member of the struct
|
||||||
|
* (can be NULL for members that don't need one)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if V2
|
||||||
|
Expression *StructDeclaration::cloneMembers()
|
||||||
|
{
|
||||||
|
Expression *e = NULL;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < fields.dim; i++)
|
||||||
|
{
|
||||||
|
Dsymbol *s = (Dsymbol *)fields.data[i];
|
||||||
|
VarDeclaration *v = s->isVarDeclaration();
|
||||||
|
assert(v && v->storage_class & STCfield);
|
||||||
|
Type *tv = v->type->toBasetype();
|
||||||
|
size_t dim = 1;
|
||||||
|
while (tv->ty == Tsarray)
|
||||||
|
{ TypeSArray *ta = (TypeSArray *)tv;
|
||||||
|
dim *= ((TypeSArray *)tv)->dim->toInteger();
|
||||||
|
tv = tv->nextOf()->toBasetype();
|
||||||
|
}
|
||||||
|
if (tv->ty == Tstruct)
|
||||||
|
{ TypeStruct *ts = (TypeStruct *)tv;
|
||||||
|
StructDeclaration *sd = ts->sym;
|
||||||
|
if (sd->opclone)
|
||||||
|
{ Expression *ex;
|
||||||
|
|
||||||
|
// this.v
|
||||||
|
ex = new ThisExp(0);
|
||||||
|
ex = new DotVarExp(0, ex, v, 0);
|
||||||
|
|
||||||
|
if (dim == 1)
|
||||||
|
{ // this.v.opClone()
|
||||||
|
ex = new DotVarExp(0, ex, sd->opclone, 0);
|
||||||
|
ex = new CallExp(0, ex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// _callOpClones(&this.v, opclone, dim)
|
||||||
|
Expressions *args = new Expressions();
|
||||||
|
args->push(new AddrExp(0, ex));
|
||||||
|
args->push(new SymOffExp(0, sd->opclone, 0));
|
||||||
|
args->push(new IntegerExp(dim));
|
||||||
|
FuncDeclaration *ec = FuncDeclaration::genCfunc(Type::tvoid, "_callOpClones");
|
||||||
|
ex = new CallExp(0, new VarExp(0, ec), args);
|
||||||
|
}
|
||||||
|
e = Expression::combine(e, ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return e;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/*****************************************
|
||||||
|
* Create inclusive destructor for struct by aggregating
|
||||||
|
* all the destructors in dtors[] with the destructors for
|
||||||
|
* all the members.
|
||||||
|
*/
|
||||||
|
|
||||||
|
FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
|
||||||
|
{
|
||||||
|
//printf("StructDeclaration::buildDtor() %s\n", toChars());
|
||||||
|
Expression *e = NULL;
|
||||||
|
|
||||||
|
#if V2
|
||||||
|
for (size_t i = 0; i < fields.dim; i++)
|
||||||
|
{
|
||||||
|
Dsymbol *s = (Dsymbol *)fields.data[i];
|
||||||
|
VarDeclaration *v = s->isVarDeclaration();
|
||||||
|
assert(v && v->storage_class & STCfield);
|
||||||
|
Type *tv = v->type->toBasetype();
|
||||||
|
size_t dim = 1;
|
||||||
|
while (tv->ty == Tsarray)
|
||||||
|
{ TypeSArray *ta = (TypeSArray *)tv;
|
||||||
|
dim *= ((TypeSArray *)tv)->dim->toInteger();
|
||||||
|
tv = tv->nextOf()->toBasetype();
|
||||||
|
}
|
||||||
|
if (tv->ty == Tstruct)
|
||||||
|
{ TypeStruct *ts = (TypeStruct *)tv;
|
||||||
|
StructDeclaration *sd = ts->sym;
|
||||||
|
if (sd->dtor)
|
||||||
|
{ Expression *ex;
|
||||||
|
|
||||||
|
// this.v
|
||||||
|
ex = new ThisExp(0);
|
||||||
|
ex = new DotVarExp(0, ex, v, 0);
|
||||||
|
|
||||||
|
if (dim == 1)
|
||||||
|
{ // this.v.dtor()
|
||||||
|
ex = new DotVarExp(0, ex, sd->dtor, 0);
|
||||||
|
ex = new CallExp(0, ex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Typeinfo.destroy(cast(void*)&this.v);
|
||||||
|
Expression *ea = new AddrExp(0, ex);
|
||||||
|
ea = new CastExp(0, ea, Type::tvoid->pointerTo());
|
||||||
|
Expressions *args = new Expressions();
|
||||||
|
args->push(ea);
|
||||||
|
|
||||||
|
Expression *et = v->type->getTypeInfo(sc);
|
||||||
|
et = new DotIdExp(0, et, Id::destroy);
|
||||||
|
|
||||||
|
ex = new CallExp(0, et, args);
|
||||||
|
}
|
||||||
|
e = Expression::combine(ex, e); // combine in reverse order
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build our own "destructor" which executes e
|
||||||
|
*/
|
||||||
|
if (e)
|
||||||
|
{ //printf("Building __fieldDtor()\n");
|
||||||
|
DtorDeclaration *dd = new DtorDeclaration(0, 0, Lexer::idPool("__fieldDtor"));
|
||||||
|
dd->fbody = new ExpStatement(0, e);
|
||||||
|
dtors.shift(dd);
|
||||||
|
members->push(dd);
|
||||||
|
dd->semantic(sc);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (dtors.dim)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return (FuncDeclaration *)dtors.data[0];
|
||||||
|
|
||||||
|
default:
|
||||||
|
e = NULL;
|
||||||
|
for (size_t i = 0; i < dtors.dim; i++)
|
||||||
|
{ FuncDeclaration *fd = (FuncDeclaration *)dtors.data[i];
|
||||||
|
Expression *ex = new ThisExp(0);
|
||||||
|
ex = new DotVarExp(0, ex, fd);
|
||||||
|
ex = new CallExp(0, ex);
|
||||||
|
e = Expression::combine(ex, e);
|
||||||
|
}
|
||||||
|
DtorDeclaration *dd = new DtorDeclaration(0, 0, Lexer::idPool("__aggrDtor"));
|
||||||
|
dd->fbody = new ExpStatement(0, e);
|
||||||
|
members->push(dd);
|
||||||
|
dd->semantic(sc);
|
||||||
|
return dd;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -667,6 +667,7 @@ void VarDeclaration::semantic(Scope *sc)
|
|||||||
size_t nelems = Argument::dim(tt->arguments);
|
size_t nelems = Argument::dim(tt->arguments);
|
||||||
Objects *exps = new Objects();
|
Objects *exps = new Objects();
|
||||||
exps->setDim(nelems);
|
exps->setDim(nelems);
|
||||||
|
Expression *ie = init ? init->toExpression() : NULL;
|
||||||
|
|
||||||
for (size_t i = 0; i < nelems; i++)
|
for (size_t i = 0; i < nelems; i++)
|
||||||
{ Argument *arg = Argument::getNth(tt->arguments, i);
|
{ Argument *arg = Argument::getNth(tt->arguments, i);
|
||||||
@@ -677,7 +678,16 @@ void VarDeclaration::semantic(Scope *sc)
|
|||||||
char *name = (char *)buf.extractData();
|
char *name = (char *)buf.extractData();
|
||||||
Identifier *id = new Identifier(name, TOKidentifier);
|
Identifier *id = new Identifier(name, TOKidentifier);
|
||||||
|
|
||||||
VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL);
|
Expression *einit = ie;
|
||||||
|
if (ie && ie->op == TOKtuple)
|
||||||
|
{ einit = (Expression *)((TupleExp *)ie)->exps->data[i];
|
||||||
|
}
|
||||||
|
Initializer *ti = init;
|
||||||
|
if (einit)
|
||||||
|
{ ti = new ExpInitializer(einit->loc, einit);
|
||||||
|
}
|
||||||
|
|
||||||
|
VarDeclaration *v = new VarDeclaration(loc, arg->type, id, ti);
|
||||||
//printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
|
//printf("declaring field %s of type %s\n", v->toChars(), v->type->toChars());
|
||||||
v->semantic(sc);
|
v->semantic(sc);
|
||||||
|
|
||||||
@@ -1109,8 +1119,8 @@ Expression *VarDeclaration::callAutoDtor()
|
|||||||
* classes to determine if there's no way the monitor
|
* classes to determine if there's no way the monitor
|
||||||
* could be set.
|
* could be set.
|
||||||
*/
|
*/
|
||||||
if (cd->isInterfaceDeclaration())
|
//if (cd->isInterfaceDeclaration())
|
||||||
error("interface %s cannot be scope", cd->toChars());
|
//error("interface %s cannot be scope", cd->toChars());
|
||||||
if (1 || onstack || cd->dtors.dim) // if any destructors
|
if (1 || onstack || cd->dtors.dim) // if any destructors
|
||||||
{
|
{
|
||||||
// delete this;
|
// delete this;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2007 by Digital Mars
|
// Copyright (c) 1999-2008 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -33,6 +33,7 @@ struct ExpInitializer;
|
|||||||
struct StructDeclaration;
|
struct StructDeclaration;
|
||||||
struct TupleType;
|
struct TupleType;
|
||||||
struct InterState;
|
struct InterState;
|
||||||
|
struct IRState;
|
||||||
|
|
||||||
enum PROT;
|
enum PROT;
|
||||||
enum LINK;
|
enum LINK;
|
||||||
@@ -64,6 +65,12 @@ enum STC
|
|||||||
STCscope = 0x80000, // template parameter
|
STCscope = 0x80000, // template parameter
|
||||||
STCinvariant = 0x100000,
|
STCinvariant = 0x100000,
|
||||||
STCref = 0x200000,
|
STCref = 0x200000,
|
||||||
|
STCinit = 0x400000, // has explicit initializer
|
||||||
|
STCmanifest = 0x800000, // manifest constant
|
||||||
|
STCnodtor = 0x1000000, // don't run destructor
|
||||||
|
STCnothrow = 0x2000000, // never throws exceptions
|
||||||
|
STCpure = 0x4000000, // pure function
|
||||||
|
STCtls = 0x8000000, // thread local
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Match
|
struct Match
|
||||||
@@ -94,6 +101,7 @@ struct Declaration : Dsymbol
|
|||||||
void semantic(Scope *sc);
|
void semantic(Scope *sc);
|
||||||
char *kind();
|
char *kind();
|
||||||
unsigned size(Loc loc);
|
unsigned size(Loc loc);
|
||||||
|
void checkModify(Loc loc, Scope *sc, Type *t);
|
||||||
|
|
||||||
void emitComment(Scope *sc);
|
void emitComment(Scope *sc);
|
||||||
void toDocBuffer(OutBuffer *buf);
|
void toDocBuffer(OutBuffer *buf);
|
||||||
@@ -125,6 +133,7 @@ struct Declaration : Dsymbol
|
|||||||
|
|
||||||
Declaration *isDeclaration() { return this; }
|
Declaration *isDeclaration() { return this; }
|
||||||
|
|
||||||
|
// llvm
|
||||||
virtual void toObjFile(); // compile to .obj file
|
virtual void toObjFile(); // compile to .obj file
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -517,13 +526,14 @@ struct FuncDeclaration : Declaration
|
|||||||
int inlineNest; // !=0 if nested inline
|
int inlineNest; // !=0 if nested inline
|
||||||
int cantInterpret; // !=0 if cannot interpret function
|
int cantInterpret; // !=0 if cannot interpret function
|
||||||
int semanticRun; // !=0 if semantic3() had been run
|
int semanticRun; // !=0 if semantic3() had been run
|
||||||
|
// this function's frame ptr
|
||||||
ForeachStatement *fes; // if foreach body, this is the foreach
|
ForeachStatement *fes; // if foreach body, this is the foreach
|
||||||
int introducing; // !=0 if 'introducing' function
|
int introducing; // !=0 if 'introducing' function
|
||||||
Type *tintro; // if !=NULL, then this is the type
|
Type *tintro; // if !=NULL, then this is the type
|
||||||
// of the 'introducing' function
|
// of the 'introducing' function
|
||||||
// this one is overriding
|
// this one is overriding
|
||||||
int inferRetType; // !=0 if return type is to be inferred
|
int inferRetType; // !=0 if return type is to be inferred
|
||||||
Scope *scope; // !=NULL means context to use
|
Scope *scope; // !=NULL means context to use
|
||||||
|
|
||||||
// Things that should really go into Scope
|
// Things that should really go into Scope
|
||||||
int hasReturnExp; // 1 if there's a return exp; statement
|
int hasReturnExp; // 1 if there's a return exp; statement
|
||||||
@@ -558,6 +568,7 @@ struct FuncDeclaration : Declaration
|
|||||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||||
void bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
void bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||||
int overrides(FuncDeclaration *fd);
|
int overrides(FuncDeclaration *fd);
|
||||||
|
int findVtblIndex(Array *vtbl, int dim);
|
||||||
int overloadInsert(Dsymbol *s);
|
int overloadInsert(Dsymbol *s);
|
||||||
FuncDeclaration *overloadExactMatch(Type *t);
|
FuncDeclaration *overloadExactMatch(Type *t);
|
||||||
FuncDeclaration *overloadResolve(Loc loc, Expressions *arguments);
|
FuncDeclaration *overloadResolve(Loc loc, Expressions *arguments);
|
||||||
@@ -648,6 +659,7 @@ struct CtorDeclaration : FuncDeclaration
|
|||||||
struct DtorDeclaration : FuncDeclaration
|
struct DtorDeclaration : FuncDeclaration
|
||||||
{
|
{
|
||||||
DtorDeclaration(Loc loc, Loc endloc);
|
DtorDeclaration(Loc loc, Loc endloc);
|
||||||
|
DtorDeclaration(Loc loc, Loc endloc, Identifier *id);
|
||||||
Dsymbol *syntaxCopy(Dsymbol *);
|
Dsymbol *syntaxCopy(Dsymbol *);
|
||||||
void semantic(Scope *sc);
|
void semantic(Scope *sc);
|
||||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||||
|
|||||||
84
dmd/doc.c
84
dmd/doc.c
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2006 by Digital Mars
|
// Copyright (c) 1999-2008 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -102,6 +102,7 @@ int isDitto(unsigned char *comment);
|
|||||||
unsigned char *skipwhitespace(unsigned char *p);
|
unsigned char *skipwhitespace(unsigned char *p);
|
||||||
unsigned skiptoident(OutBuffer *buf, unsigned i);
|
unsigned skiptoident(OutBuffer *buf, unsigned i);
|
||||||
unsigned skippastident(OutBuffer *buf, unsigned i);
|
unsigned skippastident(OutBuffer *buf, unsigned i);
|
||||||
|
unsigned skippastURL(OutBuffer *buf, unsigned i);
|
||||||
void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
|
void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
|
||||||
void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
|
void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
|
||||||
void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
|
void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset);
|
||||||
@@ -114,7 +115,7 @@ DDOC = <html><head>\n\
|
|||||||
</head><body>\n\
|
</head><body>\n\
|
||||||
<h1>$(TITLE)</h1>\n\
|
<h1>$(TITLE)</h1>\n\
|
||||||
$(BODY)\n\
|
$(BODY)\n\
|
||||||
<hr>$(SMALL Page generated by $(LINK2 http://www.digitalmars.com/d/ddoc.html, Ddoc). $(COPYRIGHT))\n\
|
<hr>$(SMALL Page generated by $(LINK2 http://www.digitalmars.com/d/1.0/ddoc.html, Ddoc). $(COPYRIGHT))\n\
|
||||||
</body></html>\n\
|
</body></html>\n\
|
||||||
\n\
|
\n\
|
||||||
B = <b>$0</b>\n\
|
B = <b>$0</b>\n\
|
||||||
@@ -371,14 +372,26 @@ void Module::gendocfile()
|
|||||||
|
|
||||||
void Dsymbol::emitDitto(Scope *sc)
|
void Dsymbol::emitDitto(Scope *sc)
|
||||||
{
|
{
|
||||||
|
//printf("Dsymbol::emitDitto() %s %s\n", kind(), toChars());
|
||||||
OutBuffer *buf = sc->docbuf;
|
OutBuffer *buf = sc->docbuf;
|
||||||
unsigned o;
|
unsigned o;
|
||||||
OutBuffer b;
|
OutBuffer b;
|
||||||
|
|
||||||
b.writestring("$(DDOC_DITTO ");
|
b.writestring("$(DDOC_DITTO ");
|
||||||
o = b.offset;
|
o = b.offset;
|
||||||
toDocBuffer(&b);
|
toDocBuffer(&b);
|
||||||
highlightCode(sc, this, &b, o);
|
//printf("b: '%.*s'\n", b.offset, b.data);
|
||||||
|
/* If 'this' is a function template, then highlightCode() was
|
||||||
|
* already run by FuncDeclaration::toDocbuffer().
|
||||||
|
*/
|
||||||
|
TemplateDeclaration *td;
|
||||||
|
if (parent &&
|
||||||
|
(td = parent->isTemplateDeclaration()) != NULL &&
|
||||||
|
td->onemember == this)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
highlightCode(sc, this, &b, o);
|
||||||
b.writeByte(')');
|
b.writeByte(')');
|
||||||
buf->spread(sc->lastoffset, b.offset);
|
buf->spread(sc->lastoffset, b.offset);
|
||||||
memcpy(buf->data + sc->lastoffset, b.data, b.offset);
|
memcpy(buf->data + sc->lastoffset, b.data, b.offset);
|
||||||
@@ -435,6 +448,7 @@ void emitProtection(OutBuffer *buf, PROT prot)
|
|||||||
|
|
||||||
void Dsymbol::emitComment(Scope *sc) { }
|
void Dsymbol::emitComment(Scope *sc) { }
|
||||||
void InvariantDeclaration::emitComment(Scope *sc) { }
|
void InvariantDeclaration::emitComment(Scope *sc) { }
|
||||||
|
//void PostBlitDeclaration::emitComment(Scope *sc) { }
|
||||||
void DtorDeclaration::emitComment(Scope *sc) { }
|
void DtorDeclaration::emitComment(Scope *sc) { }
|
||||||
void StaticCtorDeclaration::emitComment(Scope *sc) { }
|
void StaticCtorDeclaration::emitComment(Scope *sc) { }
|
||||||
void StaticDtorDeclaration::emitComment(Scope *sc) { }
|
void StaticDtorDeclaration::emitComment(Scope *sc) { }
|
||||||
@@ -635,6 +649,7 @@ void Dsymbol::toDocBuffer(OutBuffer *buf)
|
|||||||
//printf("Dsymbol::toDocbuffer() %s\n", toChars());
|
//printf("Dsymbol::toDocbuffer() %s\n", toChars());
|
||||||
HdrGenState hgs;
|
HdrGenState hgs;
|
||||||
|
|
||||||
|
hgs.ddoc = 1;
|
||||||
toCBuffer(buf, &hgs);
|
toCBuffer(buf, &hgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -738,9 +753,9 @@ void FuncDeclaration::toDocBuffer(OutBuffer *buf)
|
|||||||
buf->writeByte(' ');
|
buf->writeByte(' ');
|
||||||
buf->writestring(ident->toChars());
|
buf->writestring(ident->toChars());
|
||||||
buf->writeByte('(');
|
buf->writeByte('(');
|
||||||
for (int i = 0; i < td->parameters->dim; i++)
|
for (int i = 0; i < td->origParameters->dim; i++)
|
||||||
{
|
{
|
||||||
TemplateParameter *tp = (TemplateParameter *)td->parameters->data[i];
|
TemplateParameter *tp = (TemplateParameter *)td->origParameters->data[i];
|
||||||
if (i)
|
if (i)
|
||||||
buf->writeByte(',');
|
buf->writeByte(',');
|
||||||
tp->toCBuffer(buf, &hgs);
|
tp->toCBuffer(buf, &hgs);
|
||||||
@@ -1491,6 +1506,55 @@ unsigned skippastident(OutBuffer *buf, unsigned i)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/************************************************
|
||||||
|
* Scan forward past URL starting at i.
|
||||||
|
* We don't want to highlight parts of a URL.
|
||||||
|
* Returns:
|
||||||
|
* i if not a URL
|
||||||
|
* index just past it if it is a URL
|
||||||
|
*/
|
||||||
|
|
||||||
|
unsigned skippastURL(OutBuffer *buf, unsigned i)
|
||||||
|
{ unsigned length = buf->offset - i;
|
||||||
|
unsigned char *p = &buf->data[i];
|
||||||
|
unsigned j;
|
||||||
|
unsigned sawdot = 0;
|
||||||
|
|
||||||
|
if (length > 7 && memicmp((char *)p, "http://", 7) == 0)
|
||||||
|
{
|
||||||
|
j = 7;
|
||||||
|
}
|
||||||
|
else if (length > 8 && memicmp((char *)p, "https://", 8) == 0)
|
||||||
|
{
|
||||||
|
j = 8;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
goto Lno;
|
||||||
|
|
||||||
|
for (; j < length; j++)
|
||||||
|
{ unsigned char c = p[j];
|
||||||
|
if (isalnum(c))
|
||||||
|
continue;
|
||||||
|
if (c == '-' || c == '_' || c == '?' ||
|
||||||
|
c == '=' || c == '%' || c == '&' ||
|
||||||
|
c == '/' || c == '+' || c == '#' ||
|
||||||
|
c == '~')
|
||||||
|
continue;
|
||||||
|
if (c == '.')
|
||||||
|
{
|
||||||
|
sawdot = 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (sawdot)
|
||||||
|
return i + j;
|
||||||
|
|
||||||
|
Lno:
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/****************************************************
|
/****************************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -1735,6 +1799,12 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset)
|
|||||||
j = skippastident(buf, i);
|
j = skippastident(buf, i);
|
||||||
if (j > i)
|
if (j > i)
|
||||||
{
|
{
|
||||||
|
unsigned k = skippastURL(buf, i);
|
||||||
|
if (k > i)
|
||||||
|
{ i = k - 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
if (buf->data[i] == '_') // leading '_' means no highlight
|
if (buf->data[i] == '_') // leading '_' means no highlight
|
||||||
{
|
{
|
||||||
buf->remove(i, 1);
|
buf->remove(i, 1);
|
||||||
|
|||||||
@@ -94,6 +94,7 @@ enum PROT
|
|||||||
PROTexport,
|
PROTexport,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct Dsymbol : Object
|
struct Dsymbol : Object
|
||||||
{
|
{
|
||||||
Identifier *ident;
|
Identifier *ident;
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2007 by Digital Mars
|
// Copyright (c) 1999-2008 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -89,6 +89,7 @@ enum PREC precedence[TOKMAX];
|
|||||||
|
|
||||||
void initPrecedence()
|
void initPrecedence()
|
||||||
{
|
{
|
||||||
|
precedence[TOKdotvar] = PREC_primary;
|
||||||
precedence[TOKimport] = PREC_primary;
|
precedence[TOKimport] = PREC_primary;
|
||||||
precedence[TOKidentifier] = PREC_primary;
|
precedence[TOKidentifier] = PREC_primary;
|
||||||
precedence[TOKthis] = PREC_primary;
|
precedence[TOKthis] = PREC_primary;
|
||||||
@@ -170,6 +171,8 @@ void initPrecedence()
|
|||||||
precedence[TOKquestion] = PREC_cond;
|
precedence[TOKquestion] = PREC_cond;
|
||||||
|
|
||||||
precedence[TOKassign] = PREC_assign;
|
precedence[TOKassign] = PREC_assign;
|
||||||
|
precedence[TOKconstruct] = PREC_assign;
|
||||||
|
precedence[TOKblit] = PREC_assign;
|
||||||
precedence[TOKaddass] = PREC_assign;
|
precedence[TOKaddass] = PREC_assign;
|
||||||
precedence[TOKminass] = PREC_assign;
|
precedence[TOKminass] = PREC_assign;
|
||||||
precedence[TOKcatass] = PREC_assign;
|
precedence[TOKcatass] = PREC_assign;
|
||||||
@@ -645,7 +648,7 @@ void argExpTypesToCBuffer(OutBuffer *buf, Expressions *arguments, HdrGenState *h
|
|||||||
if (i)
|
if (i)
|
||||||
buf->writeByte(',');
|
buf->writeByte(',');
|
||||||
argbuf.reset();
|
argbuf.reset();
|
||||||
arg->type->toCBuffer2(&argbuf, NULL, hgs);
|
arg->type->toCBuffer2(&argbuf, hgs, 0);
|
||||||
buf->write(&argbuf);
|
buf->write(&argbuf);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2496,6 +2499,8 @@ Expression *ArrayLiteralExp::semantic(Scope *sc)
|
|||||||
#if LOGSEMANTIC
|
#if LOGSEMANTIC
|
||||||
printf("ArrayLiteralExp::semantic('%s')\n", toChars());
|
printf("ArrayLiteralExp::semantic('%s')\n", toChars());
|
||||||
#endif
|
#endif
|
||||||
|
if (type)
|
||||||
|
return this;
|
||||||
|
|
||||||
// Run semantic() on each element
|
// Run semantic() on each element
|
||||||
for (int i = 0; i < elements->dim; i++)
|
for (int i = 0; i < elements->dim; i++)
|
||||||
@@ -4408,6 +4413,8 @@ int BinExp::checkSideEffect(int flag)
|
|||||||
if (op == TOKplusplus ||
|
if (op == TOKplusplus ||
|
||||||
op == TOKminusminus ||
|
op == TOKminusminus ||
|
||||||
op == TOKassign ||
|
op == TOKassign ||
|
||||||
|
op == TOKconstruct ||
|
||||||
|
op == TOKblit ||
|
||||||
op == TOKaddass ||
|
op == TOKaddass ||
|
||||||
op == TOKminass ||
|
op == TOKminass ||
|
||||||
op == TOKcatass ||
|
op == TOKcatass ||
|
||||||
@@ -4995,6 +5002,7 @@ Expression *DotVarExp::semantic(Scope *sc)
|
|||||||
if (s && s->isClassDeclaration())
|
if (s && s->isClassDeclaration())
|
||||||
e1->type = s->isClassDeclaration()->type;
|
e1->type = s->isClassDeclaration()->type;
|
||||||
|
|
||||||
|
e1 = e1->semantic(sc);
|
||||||
goto L1;
|
goto L1;
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -6135,13 +6143,10 @@ Expression *DeleteExp::semantic(Scope *sc)
|
|||||||
|
|
||||||
if (f)
|
if (f)
|
||||||
{
|
{
|
||||||
Expression *e;
|
|
||||||
Expression *ec;
|
|
||||||
Type *tpv = Type::tvoid->pointerTo();
|
Type *tpv = Type::tvoid->pointerTo();
|
||||||
|
|
||||||
e = e1;
|
Expression *e = e1->castTo(sc, tpv);
|
||||||
e->type = tpv;
|
Expression *ec = new VarExp(loc, f);
|
||||||
ec = new VarExp(loc, f);
|
|
||||||
e = new CallExp(loc, ec, e);
|
e = new CallExp(loc, ec, e);
|
||||||
return e->semantic(sc);
|
return e->semantic(sc);
|
||||||
}
|
}
|
||||||
@@ -6233,7 +6238,10 @@ Expression *CastExp::semantic(Scope *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
Type *tob = to->toBasetype();
|
Type *tob = to->toBasetype();
|
||||||
if (tob->ty == Tstruct && !tob->equals(e1->type->toBasetype()))
|
if (tob->ty == Tstruct &&
|
||||||
|
!tob->equals(e1->type->toBasetype()) &&
|
||||||
|
((TypeStruct *)to)->sym->search(0, Id::call, 0)
|
||||||
|
)
|
||||||
{
|
{
|
||||||
/* Look to replace:
|
/* Look to replace:
|
||||||
* cast(S)t
|
* cast(S)t
|
||||||
@@ -7272,6 +7280,8 @@ Expression *CatAssignExp::semantic(Scope *sc)
|
|||||||
Type *tb1 = e1->type->toBasetype();
|
Type *tb1 = e1->type->toBasetype();
|
||||||
Type *tb2 = e2->type->toBasetype();
|
Type *tb2 = e2->type->toBasetype();
|
||||||
|
|
||||||
|
e2->rvalue();
|
||||||
|
|
||||||
if ((tb1->ty == Tarray) &&
|
if ((tb1->ty == Tarray) &&
|
||||||
(tb2->ty == Tarray || tb2->ty == Tsarray) &&
|
(tb2->ty == Tarray || tb2->ty == Tsarray) &&
|
||||||
e2->implicitConvTo(e1->type)
|
e2->implicitConvTo(e1->type)
|
||||||
@@ -8339,6 +8349,13 @@ Expression *CmpExp::semantic(Scope *sc)
|
|||||||
return this;
|
return this;
|
||||||
|
|
||||||
BinExp::semanticp(sc);
|
BinExp::semanticp(sc);
|
||||||
|
|
||||||
|
if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull ||
|
||||||
|
e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull)
|
||||||
|
{
|
||||||
|
error("do not use null when comparing class types");
|
||||||
|
}
|
||||||
|
|
||||||
e = op_overload(sc);
|
e = op_overload(sc);
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
@@ -8392,6 +8409,7 @@ int CmpExp::isBit()
|
|||||||
EqualExp::EqualExp(enum TOK op, Loc loc, Expression *e1, Expression *e2)
|
EqualExp::EqualExp(enum TOK op, Loc loc, Expression *e1, Expression *e2)
|
||||||
: BinExp(loc, op, sizeof(EqualExp), e1, e2)
|
: BinExp(loc, op, sizeof(EqualExp), e1, e2)
|
||||||
{
|
{
|
||||||
|
assert(op == TOKequal || op == TOKnotequal);
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression *EqualExp::semantic(Scope *sc)
|
Expression *EqualExp::semantic(Scope *sc)
|
||||||
@@ -8426,6 +8444,14 @@ Expression *EqualExp::semantic(Scope *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (e1->type->toBasetype()->ty == Tclass && e2->op == TOKnull ||
|
||||||
|
e2->type->toBasetype()->ty == Tclass && e1->op == TOKnull)
|
||||||
|
{
|
||||||
|
error("use '%s' instead of '%s' when comparing with null",
|
||||||
|
Token::toChars(op == TOKequal ? TOKidentity : TOKnotidentity),
|
||||||
|
Token::toChars(op));
|
||||||
|
}
|
||||||
|
|
||||||
//if (e2->op != TOKnull)
|
//if (e2->op != TOKnull)
|
||||||
{
|
{
|
||||||
e = op_overload(sc);
|
e = op_overload(sc);
|
||||||
|
|||||||
402
dmd/func.c
402
dmd/func.c
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2007 by Digital Mars
|
// Copyright (c) 1999-2008 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -35,6 +35,7 @@
|
|||||||
FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type)
|
FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type)
|
||||||
: Declaration(id)
|
: Declaration(id)
|
||||||
{
|
{
|
||||||
|
//printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
|
||||||
this->storage_class = storage_class;
|
this->storage_class = storage_class;
|
||||||
this->type = type;
|
this->type = type;
|
||||||
this->loc = loc;
|
this->loc = loc;
|
||||||
@@ -262,117 +263,155 @@ void FuncDeclaration::semantic(Scope *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Find index of existing function in vtbl[] to override
|
// Find index of existing function in vtbl[] to override
|
||||||
if (cd->baseClass)
|
vi = findVtblIndex(&cd->vtbl, cd->baseClass ? cd->baseClass->vtbl.dim : 0);
|
||||||
|
switch (vi)
|
||||||
{
|
{
|
||||||
for (vi = 0; vi < cd->baseClass->vtbl.dim; vi++)
|
case -1: // didn't find one
|
||||||
{
|
// This is an 'introducing' function.
|
||||||
FuncDeclaration *fdv = ((Dsymbol *)cd->vtbl.data[vi])->isFuncDeclaration();
|
|
||||||
|
|
||||||
// BUG: should give error if argument types match,
|
// Verify this doesn't override previous final function
|
||||||
// but return type does not?
|
if (cd->baseClass)
|
||||||
|
{ Dsymbol *s = cd->baseClass->search(loc, ident, 0);
|
||||||
//printf("\tvtbl[%d] = '%s'\n", vi, fdv ? fdv->ident->toChars() : "");
|
if (s)
|
||||||
if (fdv && fdv->ident == ident)
|
|
||||||
{
|
|
||||||
int cov = type->covariant(fdv->type);
|
|
||||||
//printf("\tbaseclass cov = %d\n", cov);
|
|
||||||
if (cov == 2)
|
|
||||||
{
|
{
|
||||||
//type->print();
|
FuncDeclaration *f = s->isFuncDeclaration();
|
||||||
//fdv->type->print();
|
f = f->overloadExactMatch(type);
|
||||||
//printf("%s %s\n", type->deco, fdv->type->deco);
|
if (f && f->isFinal() && f->prot() != PROTprivate)
|
||||||
error("of type %s overrides but is not covariant with %s of type %s",
|
error("cannot override final function %s", f->toPrettyChars());
|
||||||
type->toChars(), fdv->toPrettyChars(), fdv->type->toChars());
|
|
||||||
}
|
|
||||||
if (cov == 1)
|
|
||||||
{
|
|
||||||
if (fdv->isFinal())
|
|
||||||
error("cannot override final function %s", fdv->toPrettyChars());
|
|
||||||
if (fdv->toParent() == parent)
|
|
||||||
{
|
|
||||||
// If both are mixins, then error.
|
|
||||||
// If either is not, the one that is not overrides
|
|
||||||
// the other.
|
|
||||||
if (fdv->parent->isClassDeclaration())
|
|
||||||
goto L1;
|
|
||||||
if (!this->parent->isClassDeclaration()
|
|
||||||
#if !BREAKABI
|
|
||||||
&& !isDtorDeclaration()
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
error("multiple overrides of same function");
|
|
||||||
}
|
|
||||||
cd->vtbl.data[vi] = (void *)this;
|
|
||||||
vtblIndex = vi;
|
|
||||||
|
|
||||||
/* This works by whenever this function is called,
|
|
||||||
* it actually returns tintro, which gets dynamically
|
|
||||||
* cast to type. But we know that tintro is a base
|
|
||||||
* of type, so we could optimize it by not doing a
|
|
||||||
* dynamic cast, but just subtracting the isBaseOf()
|
|
||||||
* offset if the value is != null.
|
|
||||||
*/
|
|
||||||
|
|
||||||
if (fdv->tintro)
|
|
||||||
tintro = 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))
|
|
||||||
{
|
|
||||||
tintro = fdv->type;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
goto L1;
|
|
||||||
}
|
|
||||||
if (cov == 3)
|
|
||||||
{
|
|
||||||
cd->sizeok = 2; // can't finish due to forward reference
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isFinal())
|
||||||
|
{
|
||||||
|
cd->vtblFinal.push(this);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Append to end of vtbl[]
|
||||||
|
//printf("\tintroducing function\n");
|
||||||
|
introducing = 1;
|
||||||
|
vi = cd->vtbl.dim;
|
||||||
|
cd->vtbl.push(this);
|
||||||
|
vtblIndex = vi;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -2: // can't determine because of fwd refs
|
||||||
|
cd->sizeok = 2; // can't finish due to forward reference
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{ FuncDeclaration *fdv = (FuncDeclaration *)cd->vtbl.data[vi];
|
||||||
|
// This function is covariant with fdv
|
||||||
|
if (fdv->isFinal())
|
||||||
|
error("cannot override final function %s", fdv->toPrettyChars());
|
||||||
|
|
||||||
|
#if V2
|
||||||
|
if (!isOverride() && global.params.warnings)
|
||||||
|
error("overrides base class function %s, but is not marked with 'override'", fdv->toPrettyChars());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (fdv->toParent() == parent)
|
||||||
|
{
|
||||||
|
// If both are mixins, then error.
|
||||||
|
// If either is not, the one that is not overrides
|
||||||
|
// the other.
|
||||||
|
if (fdv->parent->isClassDeclaration())
|
||||||
|
break;
|
||||||
|
if (!this->parent->isClassDeclaration()
|
||||||
|
#if !BREAKABI
|
||||||
|
&& !isDtorDeclaration()
|
||||||
|
#endif
|
||||||
|
#if V2
|
||||||
|
&& !isPostBlitDeclaration()
|
||||||
|
#endif
|
||||||
|
)
|
||||||
|
error("multiple overrides of same function");
|
||||||
|
}
|
||||||
|
cd->vtbl.data[vi] = (void *)this;
|
||||||
|
vtblIndex = vi;
|
||||||
|
|
||||||
|
/* This works by whenever this function is called,
|
||||||
|
* it actually returns tintro, which gets dynamically
|
||||||
|
* cast to type. But we know that tintro is a base
|
||||||
|
* of type, so we could optimize it by not doing a
|
||||||
|
* dynamic cast, but just subtracting the isBaseOf()
|
||||||
|
* offset if the value is != null.
|
||||||
|
*/
|
||||||
|
|
||||||
|
if (fdv->tintro)
|
||||||
|
tintro = 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))
|
||||||
|
{
|
||||||
|
tintro = fdv->type;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is an 'introducing' function.
|
|
||||||
|
|
||||||
// Verify this doesn't override previous final function
|
|
||||||
if (cd->baseClass)
|
|
||||||
{ Dsymbol *s = cd->baseClass->search(loc, ident, 0);
|
|
||||||
if (s)
|
|
||||||
{
|
|
||||||
FuncDeclaration *f = s->isFuncDeclaration();
|
|
||||||
f = f->overloadExactMatch(type);
|
|
||||||
if (f && f->isFinal() && f->prot() != PROTprivate)
|
|
||||||
error("cannot override final function %s", f->toPrettyChars());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isFinal())
|
|
||||||
{
|
|
||||||
cd->vtblFinal.push(this);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// Append to end of vtbl[]
|
|
||||||
//printf("\tintroducing function\n");
|
|
||||||
introducing = 1;
|
|
||||||
vi = cd->vtbl.dim;
|
|
||||||
cd->vtbl.push(this);
|
|
||||||
vtblIndex = vi;
|
|
||||||
}
|
|
||||||
|
|
||||||
L1: ;
|
|
||||||
|
|
||||||
/* Go through all the interface bases.
|
/* Go through all the interface bases.
|
||||||
* If this function is covariant with any members of those interface
|
* If this function is covariant with any members of those interface
|
||||||
* functions, set the tintro.
|
* functions, set the tintro.
|
||||||
*/
|
*/
|
||||||
for (int i = 0; i < cd->interfaces_dim; i++)
|
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)
|
||||||
|
{
|
||||||
|
case -1:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -2:
|
||||||
|
cd->sizeok = 2; // can't finish due to forward reference
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{ FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.data[vi];
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#else
|
||||||
BaseClass *b = cd->interfaces[i];
|
BaseClass *b = cd->interfaces[i];
|
||||||
for (vi = 0; vi < b->base->vtbl.dim; vi++)
|
for (vi = 0; vi < b->base->vtbl.dim; vi++)
|
||||||
{
|
{
|
||||||
@@ -433,11 +472,12 @@ void FuncDeclaration::semantic(Scope *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (introducing && isOverride())
|
if (introducing && isOverride())
|
||||||
{
|
{
|
||||||
error("function %s does not override any", toChars());
|
error("does not override any function");
|
||||||
}
|
}
|
||||||
|
|
||||||
L2: ;
|
L2: ;
|
||||||
@@ -557,10 +597,10 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
{
|
{
|
||||||
if (global.errors)
|
if (global.errors)
|
||||||
return;
|
return;
|
||||||
printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
|
//printf("FuncDeclaration::semantic3(%s '%s', sc = %p)\n", kind(), toChars(), sc);
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
//printf("FuncDeclaration::semantic3('%s.%s', sc = %p)\n", parent->toChars(), toChars(), sc);
|
//printf("FuncDeclaration::semantic3('%s.%s', sc = %p, loc = %s)\n", parent->toChars(), toChars(), sc, loc.toChars());
|
||||||
//fflush(stdout);
|
//fflush(stdout);
|
||||||
//{ static int x; if (++x == 2) *(char*)0=0; }
|
//{ static int x; if (++x == 2) *(char*)0=0; }
|
||||||
//printf("\tlinkage = %d\n", sc->linkage);
|
//printf("\tlinkage = %d\n", sc->linkage);
|
||||||
@@ -591,15 +631,15 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
|
|
||||||
if (fbody || frequire)
|
if (fbody || frequire)
|
||||||
{
|
{
|
||||||
// Establish function scope
|
/* Symbol table into which we place parameters and nested functions,
|
||||||
ScopeDsymbol *ss;
|
* solely to diagnose name collisions.
|
||||||
Scope *sc2;
|
*/
|
||||||
|
|
||||||
localsymtab = new DsymbolTable();
|
localsymtab = new DsymbolTable();
|
||||||
|
|
||||||
ss = new ScopeDsymbol();
|
// Establish function scope
|
||||||
|
ScopeDsymbol *ss = new ScopeDsymbol();
|
||||||
ss->parent = sc->scopesym;
|
ss->parent = sc->scopesym;
|
||||||
sc2 = sc->push(ss);
|
Scope *sc2 = sc->push(ss);
|
||||||
sc2->func = this;
|
sc2->func = this;
|
||||||
sc2->parent = this;
|
sc2->parent = this;
|
||||||
sc2->callSuper = 0;
|
sc2->callSuper = 0;
|
||||||
@@ -608,7 +648,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
sc2->sw = NULL;
|
sc2->sw = NULL;
|
||||||
sc2->fes = fes;
|
sc2->fes = fes;
|
||||||
sc2->linkage = LINKd;
|
sc2->linkage = LINKd;
|
||||||
sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated);
|
sc2->stc &= ~(STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STCfinal);
|
||||||
sc2->protection = PROTpublic;
|
sc2->protection = PROTpublic;
|
||||||
sc2->explicitProtection = 0;
|
sc2->explicitProtection = 0;
|
||||||
sc2->structalign = 8;
|
sc2->structalign = 8;
|
||||||
@@ -693,7 +733,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Propagate storage class from tuple arguments to their sub-arguments.
|
// Propagate storage class from tuple parameters to their element-parameters.
|
||||||
if (f->parameters)
|
if (f->parameters)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < f->parameters->dim; i++)
|
for (size_t i = 0; i < f->parameters->dim; i++)
|
||||||
@@ -712,8 +752,9 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
|
|
||||||
// Declare all the function parameters as variables
|
// Declare all the function parameters as variables
|
||||||
if (nparams)
|
if (nparams)
|
||||||
{ // parameters[] has all the tuples removed, as the back end
|
{ /* parameters[] has all the tuples removed, as the back end
|
||||||
// doesn't know about tuples
|
* doesn't know about tuples
|
||||||
|
*/
|
||||||
parameters = new Dsymbols();
|
parameters = new Dsymbols();
|
||||||
parameters->reserve(nparams);
|
parameters->reserve(nparams);
|
||||||
for (size_t i = 0; i < nparams; i++)
|
for (size_t i = 0; i < nparams; i++)
|
||||||
@@ -722,14 +763,16 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
Identifier *id = arg->ident;
|
Identifier *id = arg->ident;
|
||||||
if (!id)
|
if (!id)
|
||||||
{
|
{
|
||||||
//error("no identifier for parameter %d of %s", i + 1, toChars());
|
/* Generate identifier for un-named parameter,
|
||||||
|
* because we need it later on.
|
||||||
|
*/
|
||||||
OutBuffer buf;
|
OutBuffer buf;
|
||||||
buf.printf("_param_%zu", i);
|
buf.printf("_param_%zu", i);
|
||||||
char *name = (char *)buf.extractData();
|
char *name = (char *)buf.extractData();
|
||||||
id = new Identifier(name, TOKidentifier);
|
id = new Identifier(name, TOKidentifier);
|
||||||
arg->ident = id;
|
arg->ident = id;
|
||||||
}
|
}
|
||||||
VarDeclaration *v = new VarDeclaration(0, arg->type, id, NULL);
|
VarDeclaration *v = new VarDeclaration(loc, arg->type, id, NULL);
|
||||||
//printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars());
|
//printf("declaring parameter %s of type %s\n", v->toChars(), v->type->toChars());
|
||||||
v->storage_class |= STCparameter;
|
v->storage_class |= STCparameter;
|
||||||
if (f->varargs == 2 && i + 1 == nparams)
|
if (f->varargs == 2 && i + 1 == nparams)
|
||||||
@@ -783,10 +826,14 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Do the semantic analysis on the [in] preconditions and
|
||||||
|
* [out] postconditions.
|
||||||
|
*/
|
||||||
sc2->incontract++;
|
sc2->incontract++;
|
||||||
|
|
||||||
if (frequire)
|
if (frequire)
|
||||||
{
|
{ /* frequire is composed of the [in] contracts
|
||||||
|
*/
|
||||||
// BUG: need to error if accessing out parameters
|
// BUG: need to error if accessing out parameters
|
||||||
// BUG: need to treat parameters as const
|
// BUG: need to treat parameters as const
|
||||||
// BUG: need to disallow returns and throws
|
// BUG: need to disallow returns and throws
|
||||||
@@ -796,10 +843,9 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (fensure || addPostInvariant())
|
if (fensure || addPostInvariant())
|
||||||
{
|
{ /* fensure is composed of the [out] contracts
|
||||||
ScopeDsymbol *sym;
|
*/
|
||||||
|
ScopeDsymbol *sym = new ScopeDsymbol();
|
||||||
sym = new ScopeDsymbol();
|
|
||||||
sym->parent = sc2->scopesym;
|
sym->parent = sc2->scopesym;
|
||||||
sc2 = sc2->push(sym);
|
sc2 = sc2->push(sym);
|
||||||
|
|
||||||
@@ -903,6 +949,8 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
if (fbody)
|
if (fbody)
|
||||||
{ ClassDeclaration *cd = isClassMember();
|
{ ClassDeclaration *cd = isClassMember();
|
||||||
|
|
||||||
|
/* If this is a class constructor
|
||||||
|
*/
|
||||||
if (isCtorDeclaration() && cd)
|
if (isCtorDeclaration() && cd)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < cd->fields.dim; i++)
|
for (int i = 0; i < cd->fields.dim; i++)
|
||||||
@@ -921,7 +969,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
{ // If no return type inferred yet, then infer a void
|
{ // If no return type inferred yet, then infer a void
|
||||||
if (!type->nextOf())
|
if (!type->nextOf())
|
||||||
{
|
{
|
||||||
type->next = Type::tvoid;
|
((TypeFunction *)type)->next = Type::tvoid;
|
||||||
type = type->semantic(loc, sc);
|
type = type->semantic(loc, sc);
|
||||||
}
|
}
|
||||||
f = (TypeFunction *)type;
|
f = (TypeFunction *)type;
|
||||||
@@ -1042,9 +1090,8 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
// Merge in initialization of 'out' parameters
|
// Merge in initialization of 'out' parameters
|
||||||
if (parameters)
|
if (parameters)
|
||||||
{ for (size_t i = 0; i < parameters->dim; i++)
|
{ for (size_t i = 0; i < parameters->dim; i++)
|
||||||
{ VarDeclaration *v;
|
{
|
||||||
|
VarDeclaration *v = (VarDeclaration *)parameters->data[i];
|
||||||
v = (VarDeclaration *)parameters->data[i];
|
|
||||||
if (v->storage_class & STCout)
|
if (v->storage_class & STCout)
|
||||||
{
|
{
|
||||||
assert(v->init);
|
assert(v->init);
|
||||||
@@ -1255,6 +1302,50 @@ int FuncDeclaration::overrides(FuncDeclaration *fd)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*************************************************
|
||||||
|
* Find index of function in vtbl[0..dim] that
|
||||||
|
* this function overrides.
|
||||||
|
* Returns:
|
||||||
|
* -1 didn't find one
|
||||||
|
* -2 can't determine because of forward references
|
||||||
|
*/
|
||||||
|
|
||||||
|
int FuncDeclaration::findVtblIndex(Array *vtbl, int dim)
|
||||||
|
{
|
||||||
|
for (int vi = 0; vi < dim; vi++)
|
||||||
|
{
|
||||||
|
FuncDeclaration *fdv = ((Dsymbol *)vtbl->data[vi])->isFuncDeclaration();
|
||||||
|
if (fdv && fdv->ident == ident)
|
||||||
|
{
|
||||||
|
int cov = type->covariant(fdv->type);
|
||||||
|
//printf("\tbaseclass cov = %d\n", cov);
|
||||||
|
switch (cov)
|
||||||
|
{
|
||||||
|
case 0: // types are distinct
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1:
|
||||||
|
return vi;
|
||||||
|
|
||||||
|
case 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());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 3:
|
||||||
|
return -2; // forward references
|
||||||
|
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************
|
/****************************************************
|
||||||
* Overload this FuncDeclaration with the new one f.
|
* Overload this FuncDeclaration with the new one f.
|
||||||
* Return !=0 if successful; i.e. no conflict.
|
* Return !=0 if successful; i.e. no conflict.
|
||||||
@@ -1684,6 +1775,11 @@ LabelDsymbol *FuncDeclaration::searchLabel(Identifier *ident)
|
|||||||
}
|
}
|
||||||
return (LabelDsymbol *)s;
|
return (LabelDsymbol *)s;
|
||||||
}
|
}
|
||||||
|
/****************************************
|
||||||
|
* If non-static member function that has a 'this' pointer,
|
||||||
|
* return the aggregate it is a member of.
|
||||||
|
* Otherwise, return NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
AggregateDeclaration *FuncDeclaration::isThis()
|
AggregateDeclaration *FuncDeclaration::isThis()
|
||||||
{ AggregateDeclaration *ad;
|
{ AggregateDeclaration *ad;
|
||||||
@@ -1937,6 +2033,55 @@ char *FuncDeclaration::kind()
|
|||||||
{
|
{
|
||||||
return "function";
|
return "function";
|
||||||
}
|
}
|
||||||
|
/*******************************
|
||||||
|
* Look at all the variables in this function that are referenced
|
||||||
|
* by nested functions, and determine if a closure needs to be
|
||||||
|
* created for them.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#if V2
|
||||||
|
int FuncDeclaration::needsClosure()
|
||||||
|
{
|
||||||
|
/* Need a closure for all the closureVars[] if any of the
|
||||||
|
* closureVars[] are accessed by a
|
||||||
|
* function that escapes the scope of this function.
|
||||||
|
* We take the conservative approach and decide that any function that:
|
||||||
|
* 1) is a virtual function
|
||||||
|
* 2) has its address taken
|
||||||
|
* 3) has a parent that escapes
|
||||||
|
* escapes.
|
||||||
|
*/
|
||||||
|
|
||||||
|
//printf("FuncDeclaration::needsClosure() %s\n", toChars());
|
||||||
|
for (int i = 0; i < closureVars.dim; i++)
|
||||||
|
{ VarDeclaration *v = (VarDeclaration *)closureVars.data[i];
|
||||||
|
assert(v->isVarDeclaration());
|
||||||
|
//printf("\tv = %s\n", v->toChars());
|
||||||
|
|
||||||
|
for (int j = 0; j < v->nestedrefs.dim; j++)
|
||||||
|
{ FuncDeclaration *f = (FuncDeclaration *)v->nestedrefs.data[j];
|
||||||
|
assert(f != this);
|
||||||
|
|
||||||
|
//printf("\t\tf = %s, %d, %d\n", f->toChars(), f->isVirtual(), f->tookAddressOf);
|
||||||
|
if (f->isVirtual() || f->tookAddressOf)
|
||||||
|
goto Lyes; // assume f escapes this function's scope
|
||||||
|
|
||||||
|
// Look to see if any parents of f that are below this escape
|
||||||
|
for (Dsymbol *s = f->parent; s != this; s = s->parent)
|
||||||
|
{
|
||||||
|
f = s->isFuncDeclaration();
|
||||||
|
if (f && (f->isVirtual() || f->tookAddressOf))
|
||||||
|
goto Lyes;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
Lyes:
|
||||||
|
//printf("\tneeds closure\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/****************************** FuncAliasDeclaration ************************/
|
/****************************** FuncAliasDeclaration ************************/
|
||||||
|
|
||||||
@@ -2049,6 +2194,8 @@ void CtorDeclaration::semantic(Scope *sc)
|
|||||||
Type *tret;
|
Type *tret;
|
||||||
|
|
||||||
//printf("CtorDeclaration::semantic()\n");
|
//printf("CtorDeclaration::semantic()\n");
|
||||||
|
if (type)
|
||||||
|
return;
|
||||||
|
|
||||||
sc = sc->push();
|
sc = sc->push();
|
||||||
sc->stc &= ~STCstatic; // not a static constructor
|
sc->stc &= ~STCstatic; // not a static constructor
|
||||||
@@ -2058,7 +2205,7 @@ void CtorDeclaration::semantic(Scope *sc)
|
|||||||
cd = parent->isClassDeclaration();
|
cd = parent->isClassDeclaration();
|
||||||
if (!cd)
|
if (!cd)
|
||||||
{
|
{
|
||||||
error("constructors only are for class definitions");
|
error("constructors are only for class definitions");
|
||||||
tret = Type::tvoid;
|
tret = Type::tvoid;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -2130,12 +2277,15 @@ DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc)
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DtorDeclaration::DtorDeclaration(Loc loc, Loc endloc, Identifier *id)
|
||||||
|
: FuncDeclaration(loc, endloc, id, STCundefined, NULL)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
Dsymbol *DtorDeclaration::syntaxCopy(Dsymbol *s)
|
Dsymbol *DtorDeclaration::syntaxCopy(Dsymbol *s)
|
||||||
{
|
{
|
||||||
DtorDeclaration *dd;
|
|
||||||
|
|
||||||
assert(!s);
|
assert(!s);
|
||||||
dd = new DtorDeclaration(loc, endloc);
|
DtorDeclaration *dd = new DtorDeclaration(loc, endloc, ident);
|
||||||
return FuncDeclaration::syntaxCopy(dd);
|
return FuncDeclaration::syntaxCopy(dd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2007 by Digital Mars
|
// Copyright (c) 1999-2008 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -109,7 +109,7 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
|
|||||||
istatex.caller = istate;
|
istatex.caller = istate;
|
||||||
istatex.fd = this;
|
istatex.fd = this;
|
||||||
|
|
||||||
Expressions vsave;
|
Expressions vsave; // place to save previous parameter values
|
||||||
size_t dim = 0;
|
size_t dim = 0;
|
||||||
if (arguments)
|
if (arguments)
|
||||||
{
|
{
|
||||||
@@ -117,9 +117,40 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
|
|||||||
assert(!dim || parameters->dim == dim);
|
assert(!dim || parameters->dim == dim);
|
||||||
vsave.setDim(dim);
|
vsave.setDim(dim);
|
||||||
|
|
||||||
|
/* Evaluate all the arguments to the function,
|
||||||
|
* store the results in eargs[]
|
||||||
|
*/
|
||||||
|
Expressions eargs;
|
||||||
|
eargs.setDim(dim);
|
||||||
|
|
||||||
for (size_t i = 0; i < dim; i++)
|
for (size_t i = 0; i < dim; i++)
|
||||||
{ Expression *earg = (Expression *)arguments->data[i];
|
{ Expression *earg = (Expression *)arguments->data[i];
|
||||||
Argument *arg = Argument::getNth(tf->parameters, i);
|
Argument *arg = Argument::getNth(tf->parameters, i);
|
||||||
|
|
||||||
|
if (arg->storageClass & (STCout | STCref))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ /* Value parameters
|
||||||
|
*/
|
||||||
|
Type *ta = arg->type->toBasetype();
|
||||||
|
if (ta->ty == Tsarray && earg->op == TOKaddress)
|
||||||
|
{
|
||||||
|
/* Static arrays are passed by a simple pointer.
|
||||||
|
* Skip past this to get at the actual arg.
|
||||||
|
*/
|
||||||
|
earg = ((AddrExp *)earg)->e1;
|
||||||
|
}
|
||||||
|
earg = earg->interpret(istate ? istate : &istatex);
|
||||||
|
if (earg == EXP_CANT_INTERPRET)
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
eargs.data[i] = earg;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (size_t i = 0; i < dim; i++)
|
||||||
|
{ Expression *earg = (Expression *)eargs.data[i];
|
||||||
|
Argument *arg = Argument::getNth(tf->parameters, i);
|
||||||
VarDeclaration *v = (VarDeclaration *)parameters->data[i];
|
VarDeclaration *v = (VarDeclaration *)parameters->data[i];
|
||||||
vsave.data[i] = v->value;
|
vsave.data[i] = v->value;
|
||||||
#if LOG
|
#if LOG
|
||||||
@@ -161,17 +192,6 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
|
|||||||
else
|
else
|
||||||
{ /* Value parameters
|
{ /* Value parameters
|
||||||
*/
|
*/
|
||||||
Type *ta = arg->type->toBasetype();
|
|
||||||
if (ta->ty == Tsarray && earg->op == TOKaddress)
|
|
||||||
{
|
|
||||||
/* Static arrays are passed by a simple pointer.
|
|
||||||
* Skip past this to get at the actual arg.
|
|
||||||
*/
|
|
||||||
earg = ((AddrExp *)earg)->e1;
|
|
||||||
}
|
|
||||||
earg = earg->interpret(istate ? istate : &istatex);
|
|
||||||
if (earg == EXP_CANT_INTERPRET)
|
|
||||||
return NULL;
|
|
||||||
v->value = earg;
|
v->value = earg;
|
||||||
}
|
}
|
||||||
#if LOG
|
#if LOG
|
||||||
@@ -584,6 +604,8 @@ Expression *ForStatement::interpret(InterState *istate)
|
|||||||
|
|
||||||
while (1)
|
while (1)
|
||||||
{
|
{
|
||||||
|
if (!condition)
|
||||||
|
goto Lhead;
|
||||||
e = condition->interpret(istate);
|
e = condition->interpret(istate);
|
||||||
if (e == EXP_CANT_INTERPRET)
|
if (e == EXP_CANT_INTERPRET)
|
||||||
break;
|
break;
|
||||||
@@ -592,7 +614,9 @@ Expression *ForStatement::interpret(InterState *istate)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (e->isBool(TRUE))
|
if (e->isBool(TRUE))
|
||||||
{ e = body ? body->interpret(istate) : NULL;
|
{
|
||||||
|
Lhead:
|
||||||
|
e = body ? body->interpret(istate) : NULL;
|
||||||
if (e == EXP_CANT_INTERPRET)
|
if (e == EXP_CANT_INTERPRET)
|
||||||
break;
|
break;
|
||||||
if (e == EXP_BREAK_INTERPRET)
|
if (e == EXP_BREAK_INTERPRET)
|
||||||
@@ -602,9 +626,12 @@ Expression *ForStatement::interpret(InterState *istate)
|
|||||||
if (e && e != EXP_CONTINUE_INTERPRET)
|
if (e && e != EXP_CONTINUE_INTERPRET)
|
||||||
break;
|
break;
|
||||||
Lcontinue:
|
Lcontinue:
|
||||||
e = increment->interpret(istate);
|
if (increment)
|
||||||
if (e == EXP_CANT_INTERPRET)
|
{
|
||||||
break;
|
e = increment->interpret(istate);
|
||||||
|
if (e == EXP_CANT_INTERPRET)
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (e->isBool(FALSE))
|
else if (e->isBool(FALSE))
|
||||||
{ e = NULL;
|
{ e = NULL;
|
||||||
|
|||||||
75
dmd/lexer.c
75
dmd/lexer.c
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2007 by Digital Mars
|
// Copyright (c) 1999-2008 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -597,8 +597,20 @@ void Lexer::scan(Token *t)
|
|||||||
do
|
do
|
||||||
{
|
{
|
||||||
p++;
|
p++;
|
||||||
c = escapeSequence();
|
switch (*p)
|
||||||
stringbuffer.writeUTF8(c);
|
{
|
||||||
|
case 'u':
|
||||||
|
case 'U':
|
||||||
|
case '&':
|
||||||
|
c = escapeSequence();
|
||||||
|
stringbuffer.writeUTF8(c);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
c = escapeSequence();
|
||||||
|
stringbuffer.writeByte(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
} while (*p == '\\');
|
} while (*p == '\\');
|
||||||
t->len = stringbuffer.offset;
|
t->len = stringbuffer.offset;
|
||||||
stringbuffer.writeByte(0);
|
stringbuffer.writeByte(0);
|
||||||
@@ -718,6 +730,15 @@ void Lexer::scan(Token *t)
|
|||||||
t->value = TOKint64v;
|
t->value = TOKint64v;
|
||||||
t->uns64value = major * 1000 + minor;
|
t->uns64value = major * 1000 + minor;
|
||||||
}
|
}
|
||||||
|
#if V2
|
||||||
|
else if (id == Id::EOFX)
|
||||||
|
{
|
||||||
|
t->value = TOKeof;
|
||||||
|
// Advance scanner to end of file
|
||||||
|
while (!(*p == 0 || *p == 0x1A))
|
||||||
|
p++;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
//printf("t->value = %d\n",t->value);
|
//printf("t->value = %d\n",t->value);
|
||||||
return;
|
return;
|
||||||
@@ -1290,7 +1311,7 @@ unsigned Lexer::escapeSequence()
|
|||||||
|
|
||||||
default:
|
default:
|
||||||
if (isoctal(c))
|
if (isoctal(c))
|
||||||
{ unsigned char v;
|
{ unsigned v;
|
||||||
|
|
||||||
n = 0;
|
n = 0;
|
||||||
v = 0;
|
v = 0;
|
||||||
@@ -1300,6 +1321,8 @@ unsigned Lexer::escapeSequence()
|
|||||||
c = *++p;
|
c = *++p;
|
||||||
} while (++n < 3 && isoctal(c));
|
} while (++n < 3 && isoctal(c));
|
||||||
c = v;
|
c = v;
|
||||||
|
if (c > 0xFF)
|
||||||
|
error("0%03o is larger than a byte", c);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
error("undefined escape sequence \\%c\n",c);
|
error("undefined escape sequence \\%c\n",c);
|
||||||
@@ -1487,7 +1510,6 @@ TOK Lexer::delimitedStringConstant(Token *t)
|
|||||||
{
|
{
|
||||||
case '\n':
|
case '\n':
|
||||||
Lnextline:
|
Lnextline:
|
||||||
printf("Lnextline\n");
|
|
||||||
loc.linnum++;
|
loc.linnum++;
|
||||||
startline = 1;
|
startline = 1;
|
||||||
if (blankrol)
|
if (blankrol)
|
||||||
@@ -1544,7 +1566,7 @@ printf("Lnextline\n");
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ hereid = t.ident;
|
{ hereid = t.ident;
|
||||||
printf("hereid = '%s'\n", hereid->toChars());
|
//printf("hereid = '%s'\n", hereid->toChars());
|
||||||
blankrol = 1;
|
blankrol = 1;
|
||||||
}
|
}
|
||||||
nest = 0;
|
nest = 0;
|
||||||
@@ -1578,11 +1600,10 @@ printf("hereid = '%s'\n", hereid->toChars());
|
|||||||
unsigned char *psave = p;
|
unsigned char *psave = p;
|
||||||
p--;
|
p--;
|
||||||
scan(&t); // read in possible heredoc identifier
|
scan(&t); // read in possible heredoc identifier
|
||||||
printf("endid = '%s'\n", t.ident->toChars());
|
//printf("endid = '%s'\n", t.ident->toChars());
|
||||||
if (t.value == TOKidentifier && t.ident->equals(hereid))
|
if (t.value == TOKidentifier && t.ident->equals(hereid))
|
||||||
{ /* should check that rest of line is blank
|
{ /* should check that rest of line is blank
|
||||||
*/
|
*/
|
||||||
printf("done\n");
|
|
||||||
goto Ldone;
|
goto Ldone;
|
||||||
}
|
}
|
||||||
p = psave;
|
p = psave;
|
||||||
@@ -2742,13 +2763,10 @@ unsigned char *Lexer::combineComments(unsigned char *c1, unsigned char *c2)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
Identifier *Lexer::idPool(const char *s)
|
Identifier *Lexer::idPool(const char *s)
|
||||||
{ unsigned len;
|
{
|
||||||
Identifier *id;
|
size_t len = strlen(s);
|
||||||
StringValue *sv;
|
StringValue *sv = stringtable.update(s, len);
|
||||||
|
Identifier *id = (Identifier *) sv->ptrvalue;
|
||||||
len = strlen(s);
|
|
||||||
sv = stringtable.update(s, len);
|
|
||||||
id = (Identifier *) sv->ptrvalue;
|
|
||||||
if (!id)
|
if (!id)
|
||||||
{
|
{
|
||||||
id = new Identifier(sv->lstring.string, TOKidentifier);
|
id = new Identifier(sv->lstring.string, TOKidentifier);
|
||||||
@@ -2757,6 +2775,25 @@ Identifier *Lexer::idPool(const char *s)
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*********************************************
|
||||||
|
* Create a unique identifier using the prefix s.
|
||||||
|
*/
|
||||||
|
|
||||||
|
Identifier *Lexer::uniqueId(const char *s, int num)
|
||||||
|
{ char buffer[32];
|
||||||
|
size_t slen = strlen(s);
|
||||||
|
|
||||||
|
assert(slen + sizeof(num) * 3 + 1 <= sizeof(buffer));
|
||||||
|
sprintf(buffer, "%s%d", s, num);
|
||||||
|
return idPool(buffer);
|
||||||
|
}
|
||||||
|
|
||||||
|
Identifier *Lexer::uniqueId(const char *s)
|
||||||
|
{
|
||||||
|
static int num;
|
||||||
|
return uniqueId(s, ++num);
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************
|
/****************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -2875,12 +2912,16 @@ static Keyword keywords[] =
|
|||||||
{ "invariant", TOKinvariant },
|
{ "invariant", TOKinvariant },
|
||||||
{ "unittest", TOKunittest },
|
{ "unittest", TOKunittest },
|
||||||
{ "version", TOKversion },
|
{ "version", TOKversion },
|
||||||
|
//{ "manifest", TOKmanifest },
|
||||||
|
|
||||||
// Added after 1.0
|
// Added after 1.0
|
||||||
{ "ref", TOKref },
|
{ "ref", TOKref },
|
||||||
{ "macro", TOKmacro },
|
{ "macro", TOKmacro },
|
||||||
#if V2
|
#if V2
|
||||||
|
{ "pure", TOKpure },
|
||||||
|
{ "nothrow", TOKnothrow },
|
||||||
{ "__traits", TOKtraits },
|
{ "__traits", TOKtraits },
|
||||||
|
{ "__overloadset", TOKoverloadset },
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -2933,6 +2974,9 @@ void Lexer::initKeywords()
|
|||||||
Token::tochars[TOKxorass] = "^=";
|
Token::tochars[TOKxorass] = "^=";
|
||||||
Token::tochars[TOKassign] = "=";
|
Token::tochars[TOKassign] = "=";
|
||||||
Token::tochars[TOKconstruct] = "=";
|
Token::tochars[TOKconstruct] = "=";
|
||||||
|
#if V2
|
||||||
|
Token::tochars[TOKblit] = "=";
|
||||||
|
#endif
|
||||||
Token::tochars[TOKlt] = "<";
|
Token::tochars[TOKlt] = "<";
|
||||||
Token::tochars[TOKgt] = ">";
|
Token::tochars[TOKgt] = ">";
|
||||||
Token::tochars[TOKle] = "<=";
|
Token::tochars[TOKle] = "<=";
|
||||||
@@ -3016,4 +3060,5 @@ void Lexer::initKeywords()
|
|||||||
Token::tochars[TOKtuple] = "tuple";
|
Token::tochars[TOKtuple] = "tuple";
|
||||||
Token::tochars[TOKdeclaration] = "declaration";
|
Token::tochars[TOKdeclaration] = "declaration";
|
||||||
Token::tochars[TOKdottd] = "dottd";
|
Token::tochars[TOKdottd] = "dottd";
|
||||||
|
Token::tochars[TOKon_scope_exit] = "scope(exit)";
|
||||||
}
|
}
|
||||||
|
|||||||
12
dmd/lexer.h
12
dmd/lexer.h
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2007 by Digital Mars
|
// Copyright (c) 1999-2008 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -92,11 +92,11 @@ enum TOK
|
|||||||
TOKand, TOKor, TOKxor,
|
TOKand, TOKor, TOKxor,
|
||||||
TOKandass, TOKorass, TOKxorass,
|
TOKandass, TOKorass, TOKxorass,
|
||||||
TOKassign, TOKnot, TOKtilde,
|
TOKassign, TOKnot, TOKtilde,
|
||||||
TOKplusplus, TOKminusminus, TOKconstruct,
|
TOKplusplus, TOKminusminus, TOKconstruct, TOKblit,
|
||||||
TOKdot, TOKarrow, TOKcomma,
|
TOKdot, TOKarrow, TOKcomma,
|
||||||
TOKquestion, TOKandand, TOKoror,
|
TOKquestion, TOKandand, TOKoror,
|
||||||
|
|
||||||
// 103
|
// 104
|
||||||
// Numeric literals
|
// Numeric literals
|
||||||
TOKint32v, TOKuns32v,
|
TOKint32v, TOKuns32v,
|
||||||
TOKint64v, TOKuns64v,
|
TOKint64v, TOKuns64v,
|
||||||
@@ -131,7 +131,7 @@ enum TOK
|
|||||||
TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
|
TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
|
||||||
TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile,
|
TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile,
|
||||||
TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
|
TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
|
||||||
TOKauto, TOKpackage,
|
TOKauto, TOKpackage, TOKmanifest,
|
||||||
|
|
||||||
// Statements
|
// Statements
|
||||||
TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,
|
TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,
|
||||||
@@ -152,6 +152,8 @@ enum TOK
|
|||||||
TOKmacro,
|
TOKmacro,
|
||||||
#if V2
|
#if V2
|
||||||
TOKtraits,
|
TOKtraits,
|
||||||
|
TOKoverloadset,
|
||||||
|
TOKpure,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TOKMAX
|
TOKMAX
|
||||||
@@ -261,6 +263,8 @@ struct Lexer
|
|||||||
|
|
||||||
static void initKeywords();
|
static void initKeywords();
|
||||||
static Identifier *idPool(const char *s);
|
static Identifier *idPool(const char *s);
|
||||||
|
static Identifier *uniqueId(const char *s);
|
||||||
|
static Identifier *uniqueId(const char *s, int num);
|
||||||
|
|
||||||
TOK nextToken();
|
TOK nextToken();
|
||||||
void scan(Token *t);
|
void scan(Token *t);
|
||||||
|
|||||||
@@ -296,7 +296,7 @@ int runLINK()
|
|||||||
runtime_path.append("libtango-base-llvmdc.a");
|
runtime_path.append("libtango-base-llvmdc.a");
|
||||||
argv.push((void*)runtime_path.c_str());
|
argv.push((void*)runtime_path.c_str());
|
||||||
|
|
||||||
if (!global.params.quiet)
|
if (!global.params.quiet || global.params.verbose)
|
||||||
{
|
{
|
||||||
// Print it
|
// Print it
|
||||||
for (i = 0; i < argv.dim; i++)
|
for (i = 0; i < argv.dim; i++)
|
||||||
|
|||||||
12
dmd/mars.c
12
dmd/mars.c
@@ -70,8 +70,8 @@ Global::Global()
|
|||||||
|
|
||||||
copyright = "Copyright (c) 1999-2008 by Digital Mars and Tomas Lindquist Olsen";
|
copyright = "Copyright (c) 1999-2008 by Digital Mars and Tomas Lindquist Olsen";
|
||||||
written = "written by Walter Bright and Tomas Lindquist Olsen";
|
written = "written by Walter Bright and Tomas Lindquist Olsen";
|
||||||
|
version = "v1.029";
|
||||||
llvmdc_version = "0.1";
|
llvmdc_version = "0.1";
|
||||||
version = "v1.026";
|
|
||||||
global.structalign = 8;
|
global.structalign = 8;
|
||||||
|
|
||||||
memset(¶ms, 0, sizeof(Param));
|
memset(¶ms, 0, sizeof(Param));
|
||||||
@@ -188,6 +188,7 @@ Usage:\n\
|
|||||||
--help print help\n\
|
--help print help\n\
|
||||||
-I<path> where to look for imports\n\
|
-I<path> where to look for imports\n\
|
||||||
-J<path> where to look for string imports\n\
|
-J<path> where to look for string imports\n\
|
||||||
|
-ignore ignore unsupported pragmas\n\
|
||||||
-inline do function inlining\n\
|
-inline do function inlining\n\
|
||||||
-Llinkerflag pass linkerflag to link\n\
|
-Llinkerflag pass linkerflag to link\n\
|
||||||
-m<arch> emit code specific to <arch>\n\
|
-m<arch> emit code specific to <arch>\n\
|
||||||
@@ -201,9 +202,9 @@ Usage:\n\
|
|||||||
-od<objdir> write object files to directory <objdir>\n\
|
-od<objdir> write object files to directory <objdir>\n\
|
||||||
-of<filename> name output file to <filename>\n\
|
-of<filename> name output file to <filename>\n\
|
||||||
-op do not strip paths from source file\n\
|
-op do not strip paths from source file\n\
|
||||||
-profile profile runtime performance of generated code\n\
|
-profile profile runtime performance of generated code\n\
|
||||||
-quiet suppress unnecessary messages\n\
|
-quiet suppress unnecessary messages\n\
|
||||||
-release compile release version\n\
|
-release compile release version\n\
|
||||||
-run srcfile args... run resulting program, passing args\n\
|
-run srcfile args... run resulting program, passing args\n\
|
||||||
-R<path> provide path to the directory containing the runtime library\n\
|
-R<path> provide path to the directory containing the runtime library\n\
|
||||||
-unittest compile in unit tests\n\
|
-unittest compile in unit tests\n\
|
||||||
@@ -268,6 +269,7 @@ int main(int argc, char *argv[])
|
|||||||
global.params.llvmInline = 0; // use this one instead to know if inline passes should be run
|
global.params.llvmInline = 0; // use this one instead to know if inline passes should be run
|
||||||
global.params.obj = 1;
|
global.params.obj = 1;
|
||||||
global.params.Dversion = 2;
|
global.params.Dversion = 2;
|
||||||
|
global.params.quiet = 1;
|
||||||
|
|
||||||
global.params.linkswitches = new Array();
|
global.params.linkswitches = new Array();
|
||||||
global.params.libfiles = new Array();
|
global.params.libfiles = new Array();
|
||||||
@@ -356,7 +358,7 @@ int main(int argc, char *argv[])
|
|||||||
global.params.symdebug = 2;
|
global.params.symdebug = 2;
|
||||||
else if (strcmp(p + 1, "gt") == 0)
|
else if (strcmp(p + 1, "gt") == 0)
|
||||||
{ error("use -profile instead of -gt\n");
|
{ error("use -profile instead of -gt\n");
|
||||||
global.params.trace = 1;
|
global.params.trace = 1;
|
||||||
}
|
}
|
||||||
else if (strcmp(p + 1, "profile") == 0)
|
else if (strcmp(p + 1, "profile") == 0)
|
||||||
global.params.trace = 1;
|
global.params.trace = 1;
|
||||||
@@ -476,6 +478,8 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
else if (strcmp(p + 1, "ignore") == 0)
|
||||||
|
global.params.ignoreUnsupportedPragmas = 1;
|
||||||
else if (strcmp(p + 1, "inline") == 0) {
|
else if (strcmp(p + 1, "inline") == 0) {
|
||||||
// TODO
|
// TODO
|
||||||
// the ast rewrites dmd does for inlining messes up the ast.
|
// the ast rewrites dmd does for inlining messes up the ast.
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ struct Param
|
|||||||
char noruntime; // code is not allowed to make implicit calls to the runtime
|
char noruntime; // code is not allowed to make implicit calls to the runtime
|
||||||
char novalidate;// no bitcode validation
|
char novalidate;// no bitcode validation
|
||||||
char Dversion; // D version number
|
char Dversion; // D version number
|
||||||
|
char ignoreUnsupportedPragmas; // rather than error on them
|
||||||
|
|
||||||
char *argv0; // program name
|
char *argv0; // program name
|
||||||
Array *imppath; // array of char*'s of where to look for import modules
|
Array *imppath; // array of char*'s of where to look for import modules
|
||||||
|
|||||||
425
dmd/mtype.c
425
dmd/mtype.c
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2007 by Digital Mars
|
// Copyright (c) 1999-2008 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -107,8 +107,13 @@ StringTable Type::stringtable;
|
|||||||
Type::Type(TY ty, Type *next)
|
Type::Type(TY ty, Type *next)
|
||||||
{
|
{
|
||||||
this->ty = ty;
|
this->ty = ty;
|
||||||
|
this->mod = 0;
|
||||||
this->next = next;
|
this->next = next;
|
||||||
this->deco = NULL;
|
this->deco = NULL;
|
||||||
|
#if V2
|
||||||
|
this->cto = NULL;
|
||||||
|
this->ito = NULL;
|
||||||
|
#endif
|
||||||
this->pto = NULL;
|
this->pto = NULL;
|
||||||
this->rto = NULL;
|
this->rto = NULL;
|
||||||
this->arrayof = NULL;
|
this->arrayof = NULL;
|
||||||
@@ -337,16 +342,6 @@ void Type::toDecoBuffer(OutBuffer *buf)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/********************************
|
|
||||||
* Name mangling.
|
|
||||||
*/
|
|
||||||
|
|
||||||
void Type::toTypeInfoBuffer(OutBuffer *buf)
|
|
||||||
{
|
|
||||||
assert(0);
|
|
||||||
buf->writeByte(mangleChar[ty]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/********************************
|
/********************************
|
||||||
* For pretty-printing a type.
|
* For pretty-printing a type.
|
||||||
*/
|
*/
|
||||||
@@ -356,27 +351,54 @@ char *Type::toChars()
|
|||||||
HdrGenState hgs;
|
HdrGenState hgs;
|
||||||
|
|
||||||
buf = new OutBuffer();
|
buf = new OutBuffer();
|
||||||
toCBuffer2(buf, NULL, &hgs);
|
toCBuffer(buf, NULL, &hgs);
|
||||||
return buf->toChars();
|
return buf->toChars();
|
||||||
}
|
}
|
||||||
|
|
||||||
void Type::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void Type::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
||||||
{
|
{
|
||||||
OutBuffer tbuf;
|
toCBuffer2(buf, hgs, 0);
|
||||||
|
|
||||||
toCBuffer2(&tbuf, ident, hgs);
|
|
||||||
buf->write(&tbuf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Type::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
|
||||||
{
|
|
||||||
buf->prependstring(toChars());
|
|
||||||
if (ident)
|
if (ident)
|
||||||
{ buf->writeByte(' ');
|
{ buf->writeByte(' ');
|
||||||
buf->writestring(ident->toChars());
|
buf->writestring(ident->toChars());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Type::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
|
{
|
||||||
|
if (mod != this->mod)
|
||||||
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
buf->writestring(toChars());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Type::toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
|
{
|
||||||
|
if (mod != this->mod)
|
||||||
|
{ char *p;
|
||||||
|
|
||||||
|
switch (this->mod)
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
toCBuffer2(buf, hgs, this->mod);
|
||||||
|
break;
|
||||||
|
case MODconst:
|
||||||
|
p = "const(";
|
||||||
|
goto L1;
|
||||||
|
case MODinvariant:
|
||||||
|
p = "invariant(";
|
||||||
|
L1: buf->writestring(p);
|
||||||
|
toCBuffer2(buf, hgs, this->mod);
|
||||||
|
buf->writeByte(')');
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/************************************
|
/************************************
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@@ -906,13 +928,14 @@ char *TypeBasic::toChars()
|
|||||||
return dstring;
|
return dstring;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeBasic::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypeBasic::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
buf->prependstring(cstring);
|
//printf("TypeBasic::toCBuffer2(mod = %d, this->mod = %d)\n", mod, this->mod);
|
||||||
if (ident)
|
if (mod != this->mod)
|
||||||
{ buf->writeByte(' ');
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
buf->writestring(ident->toChars());
|
return;
|
||||||
}
|
}
|
||||||
|
buf->writestring(dstring);
|
||||||
}
|
}
|
||||||
|
|
||||||
d_uns64 TypeBasic::size(Loc loc)
|
d_uns64 TypeBasic::size(Loc loc)
|
||||||
@@ -1589,58 +1612,6 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
|||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeArray::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
|
||||||
{
|
|
||||||
#if 1
|
|
||||||
OutBuffer buf2;
|
|
||||||
toPrettyBracket(&buf2, hgs);
|
|
||||||
buf->prependstring(buf2.toChars());
|
|
||||||
if (ident)
|
|
||||||
{
|
|
||||||
buf->writeByte(' ');
|
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
|
||||||
next->toCBuffer2(buf, NULL, hgs);
|
|
||||||
#elif 1
|
|
||||||
// The D way
|
|
||||||
Type *t;
|
|
||||||
OutBuffer buf2;
|
|
||||||
for (t = this; 1; t = t->next)
|
|
||||||
{ TypeArray *ta;
|
|
||||||
|
|
||||||
ta = dynamic_cast<TypeArray *>(t);
|
|
||||||
if (!ta)
|
|
||||||
break;
|
|
||||||
ta->toPrettyBracket(&buf2, hgs);
|
|
||||||
}
|
|
||||||
buf->prependstring(buf2.toChars());
|
|
||||||
if (ident)
|
|
||||||
{
|
|
||||||
buf2.writestring(ident->toChars());
|
|
||||||
}
|
|
||||||
t->toCBuffer2(buf, NULL, hgs);
|
|
||||||
#else
|
|
||||||
// The C way
|
|
||||||
if (buf->offset)
|
|
||||||
{ buf->bracket('(', ')');
|
|
||||||
assert(!ident);
|
|
||||||
}
|
|
||||||
else if (ident)
|
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
Type *t = this;
|
|
||||||
do
|
|
||||||
{ Expression *dim;
|
|
||||||
buf->writeByte('[');
|
|
||||||
dim = ((TypeSArray *)t)->dim;
|
|
||||||
if (dim)
|
|
||||||
buf->printf("%lld", dim->toInteger());
|
|
||||||
buf->writeByte(']');
|
|
||||||
t = t->next;
|
|
||||||
} while (t->ty == Tsarray);
|
|
||||||
t->toCBuffer2(buf, NULL, hgs);
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/***************************** TypeSArray *****************************/
|
/***************************** TypeSArray *****************************/
|
||||||
|
|
||||||
@@ -1902,15 +1873,13 @@ void TypeSArray::toDecoBuffer(OutBuffer *buf)
|
|||||||
next->toDecoBuffer(buf);
|
next->toDecoBuffer(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeSArray::toTypeInfoBuffer(OutBuffer *buf)
|
void TypeSArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
|
||||||
buf->writeByte(mangleChar[Tarray]);
|
|
||||||
if (next)
|
|
||||||
next->toTypeInfoBuffer(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TypeSArray::toPrettyBracket(OutBuffer *buf, HdrGenState *hgs)
|
|
||||||
{
|
{
|
||||||
|
if (mod != this->mod)
|
||||||
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
next->toCBuffer2(buf, hgs, this->mod);
|
||||||
buf->printf("[%s]", dim->toChars());
|
buf->printf("[%s]", dim->toChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2068,15 +2037,13 @@ void TypeDArray::toDecoBuffer(OutBuffer *buf)
|
|||||||
next->toDecoBuffer(buf);
|
next->toDecoBuffer(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeDArray::toTypeInfoBuffer(OutBuffer *buf)
|
void TypeDArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
|
||||||
buf->writeByte(mangleChar[ty]);
|
|
||||||
if (next)
|
|
||||||
next->toTypeInfoBuffer(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TypeDArray::toPrettyBracket(OutBuffer *buf, HdrGenState *hgs)
|
|
||||||
{
|
{
|
||||||
|
if (mod != this->mod)
|
||||||
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
next->toCBuffer2(buf, hgs, this->mod);
|
||||||
buf->writestring("[]");
|
buf->writestring("[]");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2343,14 +2310,15 @@ void TypeAArray::toDecoBuffer(OutBuffer *buf)
|
|||||||
next->toDecoBuffer(buf);
|
next->toDecoBuffer(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeAArray::toPrettyBracket(OutBuffer *buf, HdrGenState *hgs)
|
void TypeAArray::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
buf->writeByte('[');
|
if (mod != this->mod)
|
||||||
{ OutBuffer ibuf;
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
|
return;
|
||||||
index->toCBuffer2(&ibuf, NULL, hgs);
|
|
||||||
buf->write(&ibuf);
|
|
||||||
}
|
}
|
||||||
|
next->toCBuffer2(buf, hgs, this->mod);
|
||||||
|
buf->writeByte('[');
|
||||||
|
index->toCBuffer2(buf, hgs, 0);
|
||||||
buf->writeByte(']');
|
buf->writeByte(']');
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2415,16 +2383,16 @@ d_uns64 TypePointer::size(Loc loc)
|
|||||||
return PTRSIZE;
|
return PTRSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypePointer::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypePointer::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
//printf("TypePointer::toCBuffer2() next = %d\n", next->ty);
|
//printf("TypePointer::toCBuffer2() next = %d\n", next->ty);
|
||||||
buf->prependstring("*");
|
if (mod != this->mod)
|
||||||
if (ident)
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
{
|
return;
|
||||||
buf->writeByte(' ');
|
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
}
|
||||||
next->toCBuffer2(buf, NULL, hgs);
|
next->toCBuffer2(buf, hgs, this->mod);
|
||||||
|
if (next->ty != Tfunction)
|
||||||
|
buf->writeByte('*');
|
||||||
}
|
}
|
||||||
|
|
||||||
MATCH TypePointer::implicitConvTo(Type *to)
|
MATCH TypePointer::implicitConvTo(Type *to)
|
||||||
@@ -2509,14 +2477,14 @@ d_uns64 TypeReference::size(Loc loc)
|
|||||||
return PTRSIZE;
|
return PTRSIZE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeReference::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypeReference::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
buf->prependstring("&");
|
if (mod != this->mod)
|
||||||
if (ident)
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
{
|
return;
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
}
|
||||||
next->toCBuffer2(buf, NULL, hgs);
|
next->toCBuffer2(buf, hgs, this->mod);
|
||||||
|
buf->writeByte('&');
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
Expression *TypeReference::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||||
@@ -2687,7 +2655,7 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf)
|
|||||||
inuse--;
|
inuse--;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeFunction::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
||||||
{
|
{
|
||||||
char *p = NULL;
|
char *p = NULL;
|
||||||
|
|
||||||
@@ -2696,6 +2664,8 @@ void TypeFunction::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hg
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
inuse++;
|
inuse++;
|
||||||
|
if (next && (!ident || ident->toHChars2() == ident->toChars()))
|
||||||
|
next->toCBuffer2(buf, hgs, 0);
|
||||||
if (hgs->ddoc != 1)
|
if (hgs->ddoc != 1)
|
||||||
{
|
{
|
||||||
switch (linkage)
|
switch (linkage)
|
||||||
@@ -2710,25 +2680,45 @@ void TypeFunction::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hg
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (buf->offset)
|
if (!hgs->hdrgen && p)
|
||||||
{
|
buf->writestring(p);
|
||||||
if (!hgs->hdrgen && p)
|
if (ident)
|
||||||
buf->prependstring(p);
|
{ buf->writeByte(' ');
|
||||||
buf->bracket('(', ')');
|
buf->writestring(ident->toHChars2());
|
||||||
assert(!ident);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (!hgs->hdrgen && p)
|
|
||||||
buf->writestring(p);
|
|
||||||
if (ident)
|
|
||||||
{ buf->writeByte(' ');
|
|
||||||
buf->writestring(ident->toHChars2());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Argument::argsToCBuffer(buf, hgs, parameters, varargs);
|
Argument::argsToCBuffer(buf, hgs, parameters, varargs);
|
||||||
if (next && (!ident || ident->toHChars2() == ident->toChars()))
|
inuse--;
|
||||||
next->toCBuffer2(buf, NULL, hgs);
|
}
|
||||||
|
|
||||||
|
void TypeFunction::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
|
{
|
||||||
|
char *p = NULL;
|
||||||
|
|
||||||
|
if (inuse)
|
||||||
|
{ inuse = 2; // flag error to caller
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
inuse++;
|
||||||
|
if (next)
|
||||||
|
next->toCBuffer2(buf, hgs, 0);
|
||||||
|
if (hgs->ddoc != 1)
|
||||||
|
{
|
||||||
|
switch (linkage)
|
||||||
|
{
|
||||||
|
case LINKd: p = NULL; break;
|
||||||
|
case LINKc: p = "C "; break;
|
||||||
|
case LINKwindows: p = "Windows "; break;
|
||||||
|
case LINKpascal: p = "Pascal "; break;
|
||||||
|
case LINKcpp: p = "C++ "; break;
|
||||||
|
default:
|
||||||
|
assert(0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!hgs->hdrgen && p)
|
||||||
|
buf->writestring(p);
|
||||||
|
buf->writestring(" function");
|
||||||
|
Argument::argsToCBuffer(buf, hgs, parameters, varargs);
|
||||||
inuse--;
|
inuse--;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2999,28 +2989,17 @@ d_uns64 TypeDelegate::size(Loc loc)
|
|||||||
return PTRSIZE * 2;
|
return PTRSIZE * 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeDelegate::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypeDelegate::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
#if 1
|
if (mod != this->mod)
|
||||||
OutBuffer args;
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
|
return;
|
||||||
|
}
|
||||||
TypeFunction *tf = (TypeFunction *)next;
|
TypeFunction *tf = (TypeFunction *)next;
|
||||||
|
|
||||||
Argument::argsToCBuffer(&args, hgs, tf->parameters, tf->varargs);
|
tf->next->toCBuffer2(buf, hgs, 0);
|
||||||
buf->prependstring(args.toChars());
|
buf->writestring(" delegate");
|
||||||
buf->prependstring(" delegate");
|
Argument::argsToCBuffer(buf, hgs, tf->parameters, tf->varargs);
|
||||||
if (ident)
|
|
||||||
{
|
|
||||||
buf->writeByte(' ');
|
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
|
||||||
next->next->toCBuffer2(buf, NULL, hgs);
|
|
||||||
#else
|
|
||||||
next->toCBuffer2(buf, Id::delegate, hgs);
|
|
||||||
if (ident)
|
|
||||||
{
|
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression *TypeDelegate::defaultInit(Loc loc)
|
Expression *TypeDelegate::defaultInit(Loc loc)
|
||||||
@@ -3110,7 +3089,7 @@ void TypeQualified::addIdent(Identifier *ident)
|
|||||||
idents.push(ident);
|
idents.push(ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeQualified::toCBuffer2Helper(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypeQualified::toCBuffer2Helper(OutBuffer *buf, HdrGenState *hgs)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
@@ -3340,17 +3319,14 @@ void TypeIdentifier::toDecoBuffer(OutBuffer *buf)
|
|||||||
//buf->printf("%c%s", mangleChar[ty], name);
|
//buf->printf("%c%s", mangleChar[ty], name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeIdentifier::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypeIdentifier::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
OutBuffer tmp;
|
if (mod != this->mod)
|
||||||
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
tmp.writestring(this->ident->toChars());
|
return;
|
||||||
toCBuffer2Helper(&tmp, NULL, hgs);
|
|
||||||
buf->prependstring(tmp.toChars());
|
|
||||||
if (ident)
|
|
||||||
{ buf->writeByte(' ');
|
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
}
|
||||||
|
buf->writestring(this->ident->toChars());
|
||||||
|
toCBuffer2Helper(buf, hgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************
|
/*************************************
|
||||||
@@ -3472,17 +3448,14 @@ Type *TypeInstance::syntaxCopy()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void TypeInstance::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypeInstance::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
OutBuffer tmp;
|
if (mod != this->mod)
|
||||||
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
tempinst->toCBuffer(&tmp, hgs);
|
return;
|
||||||
toCBuffer2Helper(&tmp, NULL, hgs);
|
|
||||||
buf->prependstring(tmp.toChars());
|
|
||||||
if (ident)
|
|
||||||
{ buf->writeByte(' ');
|
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
}
|
||||||
|
tempinst->toCBuffer(buf, hgs);
|
||||||
|
toCBuffer2Helper(buf, hgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeInstance::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps)
|
void TypeInstance::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps)
|
||||||
@@ -3575,19 +3548,16 @@ Dsymbol *TypeTypeof::toDsymbol(Scope *sc)
|
|||||||
return t->toDsymbol(sc);
|
return t->toDsymbol(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeTypeof::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypeTypeof::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
OutBuffer tmp;
|
if (mod != this->mod)
|
||||||
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
tmp.writestring("typeof(");
|
return;
|
||||||
exp->toCBuffer(&tmp, hgs);
|
|
||||||
tmp.writeByte(')');
|
|
||||||
toCBuffer2Helper(&tmp, NULL, hgs);
|
|
||||||
buf->prependstring(tmp.toChars());
|
|
||||||
if (ident)
|
|
||||||
{ buf->writeByte(' ');
|
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
}
|
||||||
|
buf->writestring("typeof(");
|
||||||
|
exp->toCBuffer(buf, hgs);
|
||||||
|
buf->writeByte(')');
|
||||||
|
toCBuffer2Helper(buf, hgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
Type *TypeTypeof::semantic(Loc loc, Scope *sc)
|
Type *TypeTypeof::semantic(Loc loc, Scope *sc)
|
||||||
@@ -3764,18 +3734,13 @@ void TypeEnum::toDecoBuffer(OutBuffer *buf)
|
|||||||
buf->printf("%c%s", mangleChar[ty], name);
|
buf->printf("%c%s", mangleChar[ty], name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeEnum::toTypeInfoBuffer(OutBuffer *buf)
|
void TypeEnum::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
toBasetype()->toTypeInfoBuffer(buf);
|
if (mod != this->mod)
|
||||||
}
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
|
return;
|
||||||
void TypeEnum::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
|
||||||
{
|
|
||||||
buf->prependstring(sym->toChars());
|
|
||||||
if (ident)
|
|
||||||
{ buf->writeByte(' ');
|
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
}
|
||||||
|
buf->writestring(sym->toChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||||
@@ -3945,19 +3910,14 @@ void TypeTypedef::toDecoBuffer(OutBuffer *buf)
|
|||||||
buf->printf("%c%s", mangleChar[ty], name);
|
buf->printf("%c%s", mangleChar[ty], name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeTypedef::toTypeInfoBuffer(OutBuffer *buf)
|
void TypeTypedef::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
|
||||||
sym->basetype->toTypeInfoBuffer(buf);
|
|
||||||
}
|
|
||||||
|
|
||||||
void TypeTypedef::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
|
||||||
{
|
{
|
||||||
//printf("TypeTypedef::toCBuffer2() '%s'\n", sym->toChars());
|
//printf("TypeTypedef::toCBuffer2() '%s'\n", sym->toChars());
|
||||||
buf->prependstring(sym->toChars());
|
if (mod != this->mod)
|
||||||
if (ident)
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
{ buf->writeByte(' ');
|
return;
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
}
|
||||||
|
buf->writestring(sym->toChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression *TypeTypedef::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
Expression *TypeTypedef::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||||
@@ -4173,18 +4133,17 @@ void TypeStruct::toDecoBuffer(OutBuffer *buf)
|
|||||||
buf->printf("%c%s", mangleChar[ty], name);
|
buf->printf("%c%s", mangleChar[ty], name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeStruct::toTypeInfoBuffer(OutBuffer *buf)
|
void TypeStruct::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
toDecoBuffer(buf);
|
if (mod != this->mod)
|
||||||
}
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
|
return;
|
||||||
|
}
|
||||||
void TypeStruct::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
TemplateInstance *ti = sym->parent->isTemplateInstance();
|
||||||
{
|
if (ti && ti->toAlias() == sym)
|
||||||
buf->prependbyte(' ');
|
buf->writestring(ti->toChars());
|
||||||
buf->prependstring(toChars());
|
else
|
||||||
if (ident)
|
buf->writestring(sym->toChars());
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||||
@@ -4455,13 +4414,13 @@ void TypeClass::toDecoBuffer(OutBuffer *buf)
|
|||||||
buf->printf("%c%s", mangleChar[ty], name);
|
buf->printf("%c%s", mangleChar[ty], name);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeClass::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypeClass::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
buf->prependstring(sym->toChars());
|
if (mod != this->mod)
|
||||||
if (ident)
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
{ buf->writeByte(' ');
|
return;
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
}
|
||||||
|
buf->writestring(sym->toChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||||
@@ -4928,15 +4887,9 @@ Type *TypeTuple::reliesOnTident()
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeTuple::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypeTuple::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
OutBuffer buf2;
|
Argument::argsToCBuffer(buf, hgs, arguments, 0);
|
||||||
Argument::argsToCBuffer(&buf2, hgs, arguments, 0);
|
|
||||||
buf->prependstring(buf2.toChars());
|
|
||||||
if (ident)
|
|
||||||
{ buf->writeByte(' ');
|
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeTuple::toDecoBuffer(OutBuffer *buf)
|
void TypeTuple::toDecoBuffer(OutBuffer *buf)
|
||||||
@@ -5084,20 +5037,16 @@ void TypeSlice::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TypeSlice::toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
|
void TypeSlice::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
|
||||||
{
|
{
|
||||||
OutBuffer buf2;
|
if (mod != this->mod)
|
||||||
|
{ toCBuffer3(buf, hgs, mod);
|
||||||
buf2.printf("[%s .. ", lwr->toChars());
|
return;
|
||||||
buf2.printf("%s]", upr->toChars());
|
|
||||||
|
|
||||||
buf->prependstring(buf2.toChars());
|
|
||||||
if (ident)
|
|
||||||
{
|
|
||||||
buf->writeByte(' ');
|
|
||||||
buf->writestring(ident->toChars());
|
|
||||||
}
|
}
|
||||||
next->toCBuffer2(buf, NULL, hgs);
|
next->toCBuffer2(buf, hgs, this->mod);
|
||||||
|
|
||||||
|
buf->printf("[%s .. ", lwr->toChars());
|
||||||
|
buf->printf("%s]", upr->toChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
/***************************** Argument *****************************/
|
/***************************** Argument *****************************/
|
||||||
@@ -5155,7 +5104,7 @@ char *Argument::argsTypesToChars(Arguments *args, int varargs)
|
|||||||
buf->writeByte(',');
|
buf->writeByte(',');
|
||||||
arg = (Argument *)args->data[i];
|
arg = (Argument *)args->data[i];
|
||||||
argbuf.reset();
|
argbuf.reset();
|
||||||
arg->type->toCBuffer2(&argbuf, NULL, &hgs);
|
arg->type->toCBuffer2(&argbuf, &hgs, 0);
|
||||||
buf->write(&argbuf);
|
buf->write(&argbuf);
|
||||||
}
|
}
|
||||||
if (varargs)
|
if (varargs)
|
||||||
@@ -5191,7 +5140,7 @@ void Argument::argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Arguments *argume
|
|||||||
else if (arg->storageClass & STClazy)
|
else if (arg->storageClass & STClazy)
|
||||||
buf->writestring("lazy ");
|
buf->writestring("lazy ");
|
||||||
argbuf.reset();
|
argbuf.reset();
|
||||||
arg->type->toCBuffer2(&argbuf, arg->ident, hgs);
|
arg->type->toCBuffer(&argbuf, arg->ident, hgs);
|
||||||
if (arg->defaultArg)
|
if (arg->defaultArg)
|
||||||
{
|
{
|
||||||
argbuf.writestring(" = ");
|
argbuf.writestring(" = ");
|
||||||
|
|||||||
53
dmd/mtype.h
53
dmd/mtype.h
@@ -105,6 +105,9 @@ extern int Tptrdiff_t;
|
|||||||
struct Type : Object
|
struct Type : Object
|
||||||
{
|
{
|
||||||
TY ty;
|
TY ty;
|
||||||
|
unsigned char mod; // modifiers (MODconst, MODinvariant)
|
||||||
|
#define MODconst 1 // type is const
|
||||||
|
#define MODinvariant 2 // type is invariant
|
||||||
Type *next;
|
Type *next;
|
||||||
char *deco;
|
char *deco;
|
||||||
Type *pto; // merged pointer to this type
|
Type *pto; // merged pointer to this type
|
||||||
@@ -193,10 +196,10 @@ struct Type : Object
|
|||||||
virtual unsigned alignsize();
|
virtual unsigned alignsize();
|
||||||
virtual Type *semantic(Loc loc, Scope *sc);
|
virtual Type *semantic(Loc loc, Scope *sc);
|
||||||
virtual void toDecoBuffer(OutBuffer *buf);
|
virtual void toDecoBuffer(OutBuffer *buf);
|
||||||
virtual void toTypeInfoBuffer(OutBuffer *buf);
|
|
||||||
Type *merge();
|
Type *merge();
|
||||||
void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
virtual void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
||||||
virtual void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
virtual void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
|
void toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
virtual int isbit();
|
virtual int isbit();
|
||||||
virtual int isintegral();
|
virtual int isintegral();
|
||||||
virtual int isfloating(); // real, imaginary, or complex
|
virtual int isfloating(); // real, imaginary, or complex
|
||||||
@@ -260,7 +263,7 @@ struct TypeBasic : Type
|
|||||||
Expression *getProperty(Loc loc, Identifier *ident);
|
Expression *getProperty(Loc loc, Identifier *ident);
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
char *toChars();
|
char *toChars();
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
int isintegral();
|
int isintegral();
|
||||||
int isbit();
|
int isbit();
|
||||||
int isfloating();
|
int isfloating();
|
||||||
@@ -281,8 +284,6 @@ struct TypeBasic : Type
|
|||||||
struct TypeArray : Type
|
struct TypeArray : Type
|
||||||
{
|
{
|
||||||
TypeArray(TY ty, Type *next);
|
TypeArray(TY ty, Type *next);
|
||||||
virtual void toPrettyBracket(OutBuffer *buf, HdrGenState *hgs) = 0;
|
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -298,8 +299,7 @@ struct TypeSArray : TypeArray
|
|||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
|
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
|
||||||
void toDecoBuffer(OutBuffer *buf);
|
void toDecoBuffer(OutBuffer *buf);
|
||||||
void toTypeInfoBuffer(OutBuffer *buf);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
void toPrettyBracket(OutBuffer *buf, HdrGenState *hgs);
|
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
int isString();
|
int isString();
|
||||||
int isZeroInit();
|
int isZeroInit();
|
||||||
@@ -326,8 +326,7 @@ struct TypeDArray : TypeArray
|
|||||||
unsigned alignsize();
|
unsigned alignsize();
|
||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
void toDecoBuffer(OutBuffer *buf);
|
void toDecoBuffer(OutBuffer *buf);
|
||||||
void toTypeInfoBuffer(OutBuffer *buf);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
void toPrettyBracket(OutBuffer *buf, HdrGenState *hgs);
|
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
int isString();
|
int isString();
|
||||||
int isZeroInit();
|
int isZeroInit();
|
||||||
@@ -351,7 +350,7 @@ struct TypeAArray : TypeArray
|
|||||||
d_uns64 size(Loc loc);
|
d_uns64 size(Loc loc);
|
||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
void toDecoBuffer(OutBuffer *buf);
|
void toDecoBuffer(OutBuffer *buf);
|
||||||
void toPrettyBracket(OutBuffer *buf, HdrGenState *hgs);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
Expression *defaultInit(Loc loc);
|
Expression *defaultInit(Loc loc);
|
||||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||||
@@ -371,7 +370,7 @@ struct TypePointer : Type
|
|||||||
Type *syntaxCopy();
|
Type *syntaxCopy();
|
||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
d_uns64 size(Loc loc);
|
d_uns64 size(Loc loc);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
MATCH implicitConvTo(Type *to);
|
MATCH implicitConvTo(Type *to);
|
||||||
int isscalar();
|
int isscalar();
|
||||||
Expression *defaultInit(Loc loc);
|
Expression *defaultInit(Loc loc);
|
||||||
@@ -387,7 +386,7 @@ struct TypeReference : Type
|
|||||||
TypeReference(Type *t);
|
TypeReference(Type *t);
|
||||||
Type *syntaxCopy();
|
Type *syntaxCopy();
|
||||||
d_uns64 size(Loc loc);
|
d_uns64 size(Loc loc);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
Expression *defaultInit(Loc loc);
|
Expression *defaultInit(Loc loc);
|
||||||
int isZeroInit();
|
int isZeroInit();
|
||||||
@@ -412,7 +411,8 @@ struct TypeFunction : Type
|
|||||||
Type *syntaxCopy();
|
Type *syntaxCopy();
|
||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
void toDecoBuffer(OutBuffer *buf);
|
void toDecoBuffer(OutBuffer *buf);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
||||||
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||||
Type *reliesOnTident();
|
Type *reliesOnTident();
|
||||||
@@ -433,7 +433,7 @@ struct TypeDelegate : Type
|
|||||||
Type *syntaxCopy();
|
Type *syntaxCopy();
|
||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
d_uns64 size(Loc loc);
|
d_uns64 size(Loc loc);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
Expression *defaultInit(Loc loc);
|
Expression *defaultInit(Loc loc);
|
||||||
int isZeroInit();
|
int isZeroInit();
|
||||||
int checkBoolean();
|
int checkBoolean();
|
||||||
@@ -452,7 +452,7 @@ struct TypeQualified : Type
|
|||||||
TypeQualified(TY ty, Loc loc);
|
TypeQualified(TY ty, Loc loc);
|
||||||
void syntaxCopyHelper(TypeQualified *t);
|
void syntaxCopyHelper(TypeQualified *t);
|
||||||
void addIdent(Identifier *ident);
|
void addIdent(Identifier *ident);
|
||||||
void toCBuffer2Helper(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer2Helper(OutBuffer *buf, HdrGenState *hgs);
|
||||||
d_uns64 size(Loc loc);
|
d_uns64 size(Loc loc);
|
||||||
void resolveHelper(Loc loc, Scope *sc, Dsymbol *s, Dsymbol *scopesym,
|
void resolveHelper(Loc loc, Scope *sc, Dsymbol *s, Dsymbol *scopesym,
|
||||||
Expression **pe, Type **pt, Dsymbol **ps);
|
Expression **pe, Type **pt, Dsymbol **ps);
|
||||||
@@ -466,7 +466,7 @@ struct TypeIdentifier : TypeQualified
|
|||||||
Type *syntaxCopy();
|
Type *syntaxCopy();
|
||||||
//char *toChars();
|
//char *toChars();
|
||||||
void toDecoBuffer(OutBuffer *buf);
|
void toDecoBuffer(OutBuffer *buf);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
|
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
|
||||||
Dsymbol *toDsymbol(Scope *sc);
|
Dsymbol *toDsymbol(Scope *sc);
|
||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
@@ -485,7 +485,7 @@ struct TypeInstance : TypeQualified
|
|||||||
Type *syntaxCopy();
|
Type *syntaxCopy();
|
||||||
//char *toChars();
|
//char *toChars();
|
||||||
//void toDecoBuffer(OutBuffer *buf);
|
//void toDecoBuffer(OutBuffer *buf);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
|
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
|
||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||||
@@ -498,7 +498,7 @@ struct TypeTypeof : TypeQualified
|
|||||||
TypeTypeof(Loc loc, Expression *exp);
|
TypeTypeof(Loc loc, Expression *exp);
|
||||||
Type *syntaxCopy();
|
Type *syntaxCopy();
|
||||||
Dsymbol *toDsymbol(Scope *sc);
|
Dsymbol *toDsymbol(Scope *sc);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
d_uns64 size(Loc loc);
|
d_uns64 size(Loc loc);
|
||||||
};
|
};
|
||||||
@@ -515,8 +515,7 @@ struct TypeStruct : Type
|
|||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
Dsymbol *toDsymbol(Scope *sc);
|
Dsymbol *toDsymbol(Scope *sc);
|
||||||
void toDecoBuffer(OutBuffer *buf);
|
void toDecoBuffer(OutBuffer *buf);
|
||||||
void toTypeInfoBuffer(OutBuffer *buf);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
unsigned memalign(unsigned salign);
|
unsigned memalign(unsigned salign);
|
||||||
Expression *defaultInit(Loc loc);
|
Expression *defaultInit(Loc loc);
|
||||||
@@ -541,8 +540,7 @@ struct TypeEnum : Type
|
|||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
Dsymbol *toDsymbol(Scope *sc);
|
Dsymbol *toDsymbol(Scope *sc);
|
||||||
void toDecoBuffer(OutBuffer *buf);
|
void toDecoBuffer(OutBuffer *buf);
|
||||||
void toTypeInfoBuffer(OutBuffer *buf);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
Expression *getProperty(Loc loc, Identifier *ident);
|
Expression *getProperty(Loc loc, Identifier *ident);
|
||||||
int isintegral();
|
int isintegral();
|
||||||
@@ -572,8 +570,7 @@ struct TypeTypedef : Type
|
|||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
Dsymbol *toDsymbol(Scope *sc);
|
Dsymbol *toDsymbol(Scope *sc);
|
||||||
void toDecoBuffer(OutBuffer *buf);
|
void toDecoBuffer(OutBuffer *buf);
|
||||||
void toTypeInfoBuffer(OutBuffer *buf);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
Expression *getProperty(Loc loc, Identifier *ident);
|
Expression *getProperty(Loc loc, Identifier *ident);
|
||||||
int isbit();
|
int isbit();
|
||||||
@@ -609,7 +606,7 @@ struct TypeClass : Type
|
|||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
Dsymbol *toDsymbol(Scope *sc);
|
Dsymbol *toDsymbol(Scope *sc);
|
||||||
void toDecoBuffer(OutBuffer *buf);
|
void toDecoBuffer(OutBuffer *buf);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
ClassDeclaration *isClassHandle();
|
ClassDeclaration *isClassHandle();
|
||||||
int isBaseOf(Type *t, int *poffset);
|
int isBaseOf(Type *t, int *poffset);
|
||||||
@@ -637,7 +634,7 @@ struct TypeTuple : Type
|
|||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
int equals(Object *o);
|
int equals(Object *o);
|
||||||
Type *reliesOnTident();
|
Type *reliesOnTident();
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
void toDecoBuffer(OutBuffer *buf);
|
void toDecoBuffer(OutBuffer *buf);
|
||||||
Expression *getProperty(Loc loc, Identifier *ident);
|
Expression *getProperty(Loc loc, Identifier *ident);
|
||||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||||
@@ -652,7 +649,7 @@ struct TypeSlice : Type
|
|||||||
Type *syntaxCopy();
|
Type *syntaxCopy();
|
||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
|
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
|
||||||
void toCBuffer2(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**************************************************************/
|
/**************************************************************/
|
||||||
|
|||||||
@@ -637,6 +637,14 @@ Condition *Parser::parseVersionCondition()
|
|||||||
id = token.ident;
|
id = token.ident;
|
||||||
else if (token.value == TOKint32v)
|
else if (token.value == TOKint32v)
|
||||||
level = (unsigned)token.uns64value;
|
level = (unsigned)token.uns64value;
|
||||||
|
#if V2
|
||||||
|
/* Allow:
|
||||||
|
* version (unittest)
|
||||||
|
* even though unittest is a keyword
|
||||||
|
*/
|
||||||
|
else if (token.value == TOKunittest)
|
||||||
|
id = Lexer::idPool(Token::toChars(TOKunittest));
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
error("identifier or integer expected, not %s", token.toChars());
|
error("identifier or integer expected, not %s", token.toChars());
|
||||||
nextToken();
|
nextToken();
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ Scope::Scope()
|
|||||||
this->incontract = 0;
|
this->incontract = 0;
|
||||||
this->nofree = 0;
|
this->nofree = 0;
|
||||||
this->noctor = 0;
|
this->noctor = 0;
|
||||||
|
this->noaccesscheck = 0;
|
||||||
this->intypeof = 0;
|
this->intypeof = 0;
|
||||||
this->parameterSpecialization = 0;
|
this->parameterSpecialization = 0;
|
||||||
this->callSuper = 0;
|
this->callSuper = 0;
|
||||||
@@ -115,6 +116,7 @@ Scope::Scope(Scope *enclosing)
|
|||||||
this->incontract = enclosing->incontract;
|
this->incontract = enclosing->incontract;
|
||||||
this->nofree = 0;
|
this->nofree = 0;
|
||||||
this->noctor = enclosing->noctor;
|
this->noctor = enclosing->noctor;
|
||||||
|
this->noaccesscheck = enclosing->noaccesscheck;
|
||||||
this->intypeof = enclosing->intypeof;
|
this->intypeof = enclosing->intypeof;
|
||||||
this->parameterSpecialization = enclosing->parameterSpecialization;
|
this->parameterSpecialization = enclosing->parameterSpecialization;
|
||||||
this->callSuper = enclosing->callSuper;
|
this->callSuper = enclosing->callSuper;
|
||||||
|
|||||||
@@ -56,6 +56,7 @@ struct Scope
|
|||||||
int noctor; // set if constructor calls aren't allowed
|
int noctor; // set if constructor calls aren't allowed
|
||||||
int intypeof; // in typeof(exp)
|
int intypeof; // in typeof(exp)
|
||||||
int parameterSpecialization; // if in template parameter specialization
|
int parameterSpecialization; // if in template parameter specialization
|
||||||
|
int noaccesscheck; // don't do access checks
|
||||||
|
|
||||||
unsigned callSuper; // primitive flow analysis for constructors
|
unsigned callSuper; // primitive flow analysis for constructors
|
||||||
#define CSXthis_ctor 1 // called this()
|
#define CSXthis_ctor 1 // called this()
|
||||||
|
|||||||
@@ -522,7 +522,7 @@ int CompoundStatement::usesEH()
|
|||||||
int CompoundStatement::fallOffEnd()
|
int CompoundStatement::fallOffEnd()
|
||||||
{ int falloff = TRUE;
|
{ int falloff = TRUE;
|
||||||
|
|
||||||
//printf("CompoundStatement::fallOffEnd()\n");
|
//printf("CompoundStatement::fallOffEnd() %s\n", toChars());
|
||||||
for (int i = 0; i < statements->dim; i++)
|
for (int i = 0; i < statements->dim; i++)
|
||||||
{ Statement *s = (Statement *)statements->data[i];
|
{ Statement *s = (Statement *)statements->data[i];
|
||||||
|
|
||||||
@@ -3251,7 +3251,7 @@ int TryFinallyStatement::usesEH()
|
|||||||
int TryFinallyStatement::fallOffEnd()
|
int TryFinallyStatement::fallOffEnd()
|
||||||
{ int result;
|
{ int result;
|
||||||
|
|
||||||
result = body->fallOffEnd();
|
result = body ? body->fallOffEnd() : TRUE;
|
||||||
// if (finalbody)
|
// if (finalbody)
|
||||||
// result = finalbody->fallOffEnd();
|
// result = finalbody->fallOffEnd();
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
264
dmd/template.c
264
dmd/template.c
@@ -130,6 +130,7 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
|
|||||||
Dsymbol *s2 = isDsymbol(o2);
|
Dsymbol *s2 = isDsymbol(o2);
|
||||||
Tuple *v1 = isTuple(o1);
|
Tuple *v1 = isTuple(o1);
|
||||||
Tuple *v2 = isTuple(o2);
|
Tuple *v2 = isTuple(o2);
|
||||||
|
//printf("\t match t1 %p t2 %p, e1 %p e2 %p, s1 %p s2 %p, v1 %p v2 %p\n", t1,t2,e1,e2,s1,s2,v1,v2);
|
||||||
|
|
||||||
/* A proper implementation of the various equals() overrides
|
/* A proper implementation of the various equals() overrides
|
||||||
* should make it possible to just do o1->equals(o2), but
|
* should make it possible to just do o1->equals(o2), but
|
||||||
@@ -158,7 +159,7 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!t2 || !t1->equals(t2))
|
if (!t2 || !t1->equals(t2))
|
||||||
goto L1;
|
goto Lnomatch;
|
||||||
}
|
}
|
||||||
else if (e1)
|
else if (e1)
|
||||||
{
|
{
|
||||||
@@ -168,33 +169,39 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
|
|||||||
printf("match %d\n", e1->equals(e2));
|
printf("match %d\n", e1->equals(e2));
|
||||||
e1->print();
|
e1->print();
|
||||||
e2->print();
|
e2->print();
|
||||||
|
e1->type->print();
|
||||||
|
e2->type->print();
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (!e2 || !e1->equals(e2))
|
if (!e2)
|
||||||
goto L1;
|
goto Lnomatch;
|
||||||
|
if (!e1->equals(e2))
|
||||||
|
goto Lnomatch;
|
||||||
}
|
}
|
||||||
else if (s1)
|
else if (s1)
|
||||||
{
|
{
|
||||||
//printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars());
|
//printf("%p %s, %p %s\n", s1, s1->toChars(), s2, s2->toChars());
|
||||||
if (!s2 || !s1->equals(s2) || s1->parent != s2->parent)
|
if (!s2 || !s1->equals(s2) || s1->parent != s2->parent)
|
||||||
goto L1;
|
{
|
||||||
|
goto Lnomatch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (v1)
|
else if (v1)
|
||||||
{
|
{
|
||||||
if (!v2)
|
if (!v2)
|
||||||
goto L1;
|
goto Lnomatch;
|
||||||
if (v1->objects.dim != v2->objects.dim)
|
if (v1->objects.dim != v2->objects.dim)
|
||||||
goto L1;
|
goto Lnomatch;
|
||||||
for (size_t i = 0; i < v1->objects.dim; i++)
|
for (size_t i = 0; i < v1->objects.dim; i++)
|
||||||
{
|
{
|
||||||
if (!match((Object *)v1->objects.data[i],
|
if (!match((Object *)v1->objects.data[i],
|
||||||
(Object *)v2->objects.data[i],
|
(Object *)v2->objects.data[i],
|
||||||
tempdecl, sc))
|
tempdecl, sc))
|
||||||
goto L1;
|
goto Lnomatch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 1; // match
|
return 1; // match
|
||||||
L1:
|
Lnomatch:
|
||||||
return 0; // nomatch;
|
return 0; // nomatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -268,6 +275,7 @@ TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateParame
|
|||||||
#endif
|
#endif
|
||||||
this->loc = loc;
|
this->loc = loc;
|
||||||
this->parameters = parameters;
|
this->parameters = parameters;
|
||||||
|
this->origParameters = parameters;
|
||||||
this->members = decldefs;
|
this->members = decldefs;
|
||||||
this->overnext = NULL;
|
this->overnext = NULL;
|
||||||
this->overroot = NULL;
|
this->overroot = NULL;
|
||||||
@@ -336,6 +344,17 @@ void TemplateDeclaration::semantic(Scope *sc)
|
|||||||
Scope *paramscope = sc->push(paramsym);
|
Scope *paramscope = sc->push(paramsym);
|
||||||
paramscope->parameterSpecialization = 1;
|
paramscope->parameterSpecialization = 1;
|
||||||
|
|
||||||
|
if (global.params.doDocComments)
|
||||||
|
{
|
||||||
|
origParameters = new TemplateParameters();
|
||||||
|
origParameters->setDim(parameters->dim);
|
||||||
|
for (int i = 0; i < parameters->dim; i++)
|
||||||
|
{
|
||||||
|
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||||
|
origParameters->data[i] = (void *)tp->syntaxCopy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (int i = 0; i < parameters->dim; i++)
|
for (int i = 0; i < parameters->dim; i++)
|
||||||
{
|
{
|
||||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||||
@@ -348,6 +367,8 @@ void TemplateDeclaration::semantic(Scope *sc)
|
|||||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||||
|
|
||||||
tp->semantic(paramscope);
|
tp->semantic(paramscope);
|
||||||
|
if (i + 1 != parameters->dim && tp->isTemplateTupleParameter())
|
||||||
|
error("template tuple parameter must be last one");
|
||||||
}
|
}
|
||||||
|
|
||||||
paramscope->pop();
|
paramscope->pop();
|
||||||
@@ -437,6 +458,7 @@ int TemplateDeclaration::overloadInsert(Dsymbol *s)
|
|||||||
* those deduced types in dedtypes[].
|
* those deduced types in dedtypes[].
|
||||||
* Input:
|
* Input:
|
||||||
* flag 1: don't do semantic() because of dummy types
|
* flag 1: don't do semantic() because of dummy types
|
||||||
|
* 2: don't change types in matchArg()
|
||||||
* Output:
|
* Output:
|
||||||
* dedtypes deduced arguments
|
* dedtypes deduced arguments
|
||||||
* Return match level.
|
* Return match level.
|
||||||
@@ -447,8 +469,9 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
|||||||
{ MATCH m;
|
{ MATCH m;
|
||||||
int dedtypes_dim = dedtypes->dim;
|
int dedtypes_dim = dedtypes->dim;
|
||||||
|
|
||||||
#if LOG
|
#define LOGM 0
|
||||||
printf("+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
|
#if LOGM
|
||||||
|
printf("\n+TemplateDeclaration::matchWithInstance(this = %s, ti = %s, flag = %d)\n", toChars(), ti->toChars(), flag);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
@@ -466,7 +489,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
|||||||
// If more arguments than parameters, no match
|
// If more arguments than parameters, no match
|
||||||
if (ti->tiargs->dim > parameters_dim && !variadic)
|
if (ti->tiargs->dim > parameters_dim && !variadic)
|
||||||
{
|
{
|
||||||
#if LOG
|
#if LOGM
|
||||||
printf(" no match: more arguments than parameters\n");
|
printf(" no match: more arguments than parameters\n");
|
||||||
#endif
|
#endif
|
||||||
return MATCHnomatch;
|
return MATCHnomatch;
|
||||||
@@ -489,7 +512,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
|||||||
Declaration *sparam;
|
Declaration *sparam;
|
||||||
|
|
||||||
//printf("\targument [%d]\n", i);
|
//printf("\targument [%d]\n", i);
|
||||||
#if 0
|
#if LOGM
|
||||||
//printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null");
|
//printf("\targument [%d] is %s\n", i, oarg ? oarg->toChars() : "null");
|
||||||
TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
|
TemplateTypeParameter *ttp = tp->isTemplateTypeParameter();
|
||||||
if (ttp)
|
if (ttp)
|
||||||
@@ -528,7 +551,7 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if LOGM
|
||||||
// Print out the results
|
// Print out the results
|
||||||
printf("--------------------------\n");
|
printf("--------------------------\n");
|
||||||
printf("template %s\n", toChars());
|
printf("template %s\n", toChars());
|
||||||
@@ -553,20 +576,20 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
|
|||||||
goto Lnomatch;
|
goto Lnomatch;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if LOG
|
#if LOGM
|
||||||
printf(" match = %d\n", m);
|
printf(" match = %d\n", m);
|
||||||
#endif
|
#endif
|
||||||
goto Lret;
|
goto Lret;
|
||||||
|
|
||||||
Lnomatch:
|
Lnomatch:
|
||||||
#if LOG
|
#if LOGM
|
||||||
printf(" no match\n");
|
printf(" no match\n");
|
||||||
#endif
|
#endif
|
||||||
m = MATCHnomatch;
|
m = MATCHnomatch;
|
||||||
|
|
||||||
Lret:
|
Lret:
|
||||||
paramscope->pop();
|
paramscope->pop();
|
||||||
#if LOG
|
#if LOGM
|
||||||
printf("-TemplateDeclaration::matchWithInstance(this = %p, ti = %p) = %d\n", this, ti, m);
|
printf("-TemplateDeclaration::matchWithInstance(this = %p, ti = %p) = %d\n", this, ti, m);
|
||||||
#endif
|
#endif
|
||||||
return m;
|
return m;
|
||||||
@@ -645,6 +668,8 @@ int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
|
|||||||
* fargs arguments to function
|
* fargs arguments to function
|
||||||
* Output:
|
* Output:
|
||||||
* dedargs Expression/Type deduced template arguments
|
* dedargs Expression/Type deduced template arguments
|
||||||
|
* Returns:
|
||||||
|
* match level
|
||||||
*/
|
*/
|
||||||
|
|
||||||
MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs,
|
MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs,
|
||||||
@@ -652,12 +677,13 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
|||||||
{
|
{
|
||||||
size_t i;
|
size_t i;
|
||||||
size_t nfparams;
|
size_t nfparams;
|
||||||
size_t nfparams2;
|
|
||||||
size_t nfargs;
|
size_t nfargs;
|
||||||
size_t nargsi;
|
size_t nargsi; // array size of targsi
|
||||||
|
int fptupindex = -1;
|
||||||
|
int tuple_dim = 0;
|
||||||
MATCH match = MATCHexact;
|
MATCH match = MATCHexact;
|
||||||
FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration();
|
FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration();
|
||||||
TypeFunction *fdtype;
|
TypeFunction *fdtype; // type of fd
|
||||||
TemplateTupleParameter *tp;
|
TemplateTupleParameter *tp;
|
||||||
Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
|
Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
|
||||||
|
|
||||||
@@ -682,13 +708,19 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
|||||||
paramsym->parent = scope->parent;
|
paramsym->parent = scope->parent;
|
||||||
Scope *paramscope = scope->push(paramsym);
|
Scope *paramscope = scope->push(paramsym);
|
||||||
|
|
||||||
|
tp = isVariadic();
|
||||||
|
|
||||||
nargsi = 0;
|
nargsi = 0;
|
||||||
if (targsi)
|
if (targsi)
|
||||||
{ // Set initial template arguments
|
{ // Set initial template arguments
|
||||||
|
|
||||||
nargsi = targsi->dim;
|
nargsi = targsi->dim;
|
||||||
if (nargsi > parameters->dim)
|
if (nargsi > parameters->dim)
|
||||||
goto Lnomatch;
|
{ if (!tp)
|
||||||
|
goto Lnomatch;
|
||||||
|
dedargs->setDim(nargsi);
|
||||||
|
dedargs->zero();
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data));
|
memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data));
|
||||||
|
|
||||||
@@ -698,6 +730,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
|||||||
Declaration *sparam;
|
Declaration *sparam;
|
||||||
|
|
||||||
m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
|
m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
|
||||||
|
//printf("\tdeduceType m = %d\n", m);
|
||||||
if (m == MATCHnomatch)
|
if (m == MATCHnomatch)
|
||||||
goto Lnomatch;
|
goto Lnomatch;
|
||||||
if (m < match)
|
if (m < match)
|
||||||
@@ -713,7 +746,6 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
|||||||
fdtype = (TypeFunction *)fd->type;
|
fdtype = (TypeFunction *)fd->type;
|
||||||
|
|
||||||
nfparams = Argument::dim(fdtype->parameters); // number of function parameters
|
nfparams = Argument::dim(fdtype->parameters); // number of function parameters
|
||||||
nfparams2 = nfparams;
|
|
||||||
nfargs = fargs->dim; // number of function arguments
|
nfargs = fargs->dim; // number of function arguments
|
||||||
|
|
||||||
/* Check for match of function arguments with variadic template
|
/* Check for match of function arguments with variadic template
|
||||||
@@ -723,7 +755,7 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
|||||||
* void main() { Foo(1,2,3); }
|
* void main() { Foo(1,2,3); }
|
||||||
*/
|
*/
|
||||||
tp = isVariadic();
|
tp = isVariadic();
|
||||||
if (tp)
|
if (tp) // if variadic
|
||||||
{
|
{
|
||||||
if (nfparams == 0) // if no function parameters
|
if (nfparams == 0) // if no function parameters
|
||||||
{
|
{
|
||||||
@@ -736,33 +768,38 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressi
|
|||||||
goto L1;
|
goto L1;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* See if 'A' of the template parameter matches 'A'
|
/* Figure out which of the function parameters matches
|
||||||
* of the type of the last function parameter.
|
* the tuple template parameter. Do this by matching
|
||||||
|
* type identifiers.
|
||||||
|
* Set the index of this function parameter to fptupindex.
|
||||||
*/
|
*/
|
||||||
Argument *fparam = (Argument *)fdtype->parameters->data[nfparams - 1];
|
for (fptupindex = 0; fptupindex < nfparams; fptupindex++)
|
||||||
if (fparam->type->ty != Tident)
|
{
|
||||||
goto L1;
|
Argument *fparam = (Argument *)fdtype->parameters->data[fptupindex];
|
||||||
TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
|
if (fparam->type->ty != Tident)
|
||||||
if (!tp->ident->equals(tid->ident) || tid->idents.dim)
|
continue;
|
||||||
goto L1;
|
TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
|
||||||
|
if (!tp->ident->equals(tid->ident) || tid->idents.dim)
|
||||||
|
continue;
|
||||||
|
|
||||||
if (fdtype->varargs) // variadic function doesn't
|
if (fdtype->varargs) // variadic function doesn't
|
||||||
goto Lnomatch; // go with variadic template
|
goto Lnomatch; // go with variadic template
|
||||||
|
|
||||||
/* The types of the function arguments [nfparams - 1 .. nfargs]
|
/* The types of the function arguments
|
||||||
* now form the tuple argument.
|
* now form the tuple argument.
|
||||||
*/
|
*/
|
||||||
Tuple *t = new Tuple();
|
Tuple *t = new Tuple();
|
||||||
dedargs->data[parameters->dim - 1] = (void *)t;
|
dedargs->data[parameters->dim - 1] = (void *)t;
|
||||||
|
|
||||||
int tuple_dim = nfargs - (nfparams - 1);
|
tuple_dim = nfargs - (nfparams - 1);
|
||||||
t->objects.setDim(tuple_dim);
|
t->objects.setDim(tuple_dim);
|
||||||
for (i = 0; i < tuple_dim; i++)
|
for (i = 0; i < tuple_dim; i++)
|
||||||
{ Expression *farg = (Expression *)fargs->data[nfparams - 1 + i];
|
{ Expression *farg = (Expression *)fargs->data[fptupindex + i];
|
||||||
t->objects.data[i] = (void *)farg->type;
|
t->objects.data[i] = (void *)farg->type;
|
||||||
|
}
|
||||||
|
goto L2;
|
||||||
}
|
}
|
||||||
nfparams2--; // don't consider the last parameter for type deduction
|
fptupindex = -1;
|
||||||
goto L2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,11 +815,19 @@ L1:
|
|||||||
|
|
||||||
L2:
|
L2:
|
||||||
// Loop through the function parameters
|
// Loop through the function parameters
|
||||||
for (i = 0; i < nfparams2; i++)
|
for (i = 0; i < nfparams; i++)
|
||||||
{
|
{
|
||||||
|
/* Skip over function parameters which wound up
|
||||||
|
* as part of a template tuple parameter.
|
||||||
|
*/
|
||||||
|
if (i == fptupindex)
|
||||||
|
{ if (fptupindex == nfparams - 1)
|
||||||
|
break;
|
||||||
|
i += tuple_dim - 1;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
Argument *fparam = Argument::getNth(fdtype->parameters, i);
|
Argument *fparam = Argument::getNth(fdtype->parameters, i);
|
||||||
Expression *farg;
|
|
||||||
MATCH m;
|
|
||||||
|
|
||||||
if (i >= nfargs) // if not enough arguments
|
if (i >= nfargs) // if not enough arguments
|
||||||
{
|
{
|
||||||
@@ -794,12 +839,13 @@ L2:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ farg = (Expression *)fargs->data[i];
|
{ Expression *farg = (Expression *)fargs->data[i];
|
||||||
#if 0
|
#if 0
|
||||||
printf("\tfarg->type = %s\n", farg->type->toChars());
|
printf("\tfarg->type = %s\n", farg->type->toChars());
|
||||||
printf("\tfparam->type = %s\n", fparam->type->toChars());
|
printf("\tfparam->type = %s\n", fparam->type->toChars());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
MATCH m;
|
||||||
m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes);
|
m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes);
|
||||||
//printf("\tdeduceType m = %d\n", m);
|
//printf("\tdeduceType m = %d\n", m);
|
||||||
|
|
||||||
@@ -852,30 +898,40 @@ Lmatch:
|
|||||||
for (i = nargsi; i < dedargs->dim; i++)
|
for (i = nargsi; i < dedargs->dim; i++)
|
||||||
{
|
{
|
||||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||||
|
//printf("tp[%d] = %s\n", i, tp->ident->toChars());
|
||||||
|
/* For T:T*, the dedargs is the T*, dedtypes is the T
|
||||||
|
* But for function templates, we really need them to match
|
||||||
|
*/
|
||||||
Object *oarg = (Object *)dedargs->data[i];
|
Object *oarg = (Object *)dedargs->data[i];
|
||||||
Object *o = (Object *)dedtypes.data[i];
|
Object *oded = (Object *)dedtypes.data[i];
|
||||||
//printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, o);
|
//printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
|
||||||
if (!oarg)
|
if (!oarg)
|
||||||
{
|
{
|
||||||
if (o)
|
if (oded)
|
||||||
{
|
{
|
||||||
if (tp->specialization())
|
if (tp->specialization())
|
||||||
error("specialization not allowed for deduced parameter %s", tp->ident->toChars());
|
{ /* The specialization can work as long as afterwards
|
||||||
|
* the oded == oarg
|
||||||
|
*/
|
||||||
|
Declaration *sparam;
|
||||||
|
dedargs->data[i] = (void *)oded;
|
||||||
|
MATCH m2 = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
|
||||||
|
//printf("m2 = %d\n", m2);
|
||||||
|
if (!m2)
|
||||||
|
goto Lnomatch;
|
||||||
|
if (m2 < match)
|
||||||
|
match = m2; // pick worst match
|
||||||
|
if (dedtypes.data[i] != oded)
|
||||||
|
error("specialization not allowed for deduced parameter %s", tp->ident->toChars());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ o = tp->defaultArg(paramscope);
|
{ oded = tp->defaultArg(paramscope);
|
||||||
if (!o)
|
if (!oded)
|
||||||
goto Lnomatch;
|
goto Lnomatch;
|
||||||
#if 0
|
|
||||||
Match m;
|
|
||||||
Declaration *sparam;
|
|
||||||
m = tp->matchArg(paramscope, dedargs, i, parameters, &sparam);
|
|
||||||
if (!m)
|
|
||||||
goto Lnomatch;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
declareParameter(paramscope, tp, o);
|
declareParameter(paramscope, tp, oded);
|
||||||
dedargs->data[i] = (void *)o;
|
dedargs->data[i] = (void *)oded;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -887,7 +943,7 @@ Lmatch:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
paramscope->pop();
|
paramscope->pop();
|
||||||
//printf("\tmatch\n");
|
//printf("\tmatch %d\n", match);
|
||||||
return match;
|
return match;
|
||||||
|
|
||||||
Lnomatch:
|
Lnomatch:
|
||||||
@@ -1044,9 +1100,9 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
|
|||||||
int c2 = td_best->leastAsSpecialized(td);
|
int c2 = td_best->leastAsSpecialized(td);
|
||||||
//printf("c1 = %d, c2 = %d\n", c1, c2);
|
//printf("c1 = %d, c2 = %d\n", c1, c2);
|
||||||
|
|
||||||
if (c1 && !c2)
|
if (c1 > c2)
|
||||||
goto Ltd;
|
goto Ltd;
|
||||||
else if (!c1 && c2)
|
else if (c1 < c2)
|
||||||
goto Ltd_best;
|
goto Ltd_best;
|
||||||
else
|
else
|
||||||
goto Lambig;
|
goto Lambig;
|
||||||
@@ -1116,6 +1172,8 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
|||||||
for (int i = 0; i < parameters->dim; i++)
|
for (int i = 0; i < parameters->dim; i++)
|
||||||
{
|
{
|
||||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
||||||
|
if (hgs->ddoc)
|
||||||
|
tp = (TemplateParameter *)origParameters->data[i];
|
||||||
if (i)
|
if (i)
|
||||||
buf->writeByte(',');
|
buf->writeByte(',');
|
||||||
tp->toCBuffer(buf, hgs);
|
tp->toCBuffer(buf, hgs);
|
||||||
@@ -1516,7 +1574,19 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
|||||||
*/
|
*/
|
||||||
int i = templateIdentifierLookup(tp->tempinst->name, parameters);
|
int i = templateIdentifierLookup(tp->tempinst->name, parameters);
|
||||||
if (i == -1)
|
if (i == -1)
|
||||||
|
{ /* Didn't find it as a parameter identifier. Try looking
|
||||||
|
* it up and seeing if is an alias. See Bugzilla 1454
|
||||||
|
*/
|
||||||
|
Dsymbol *s = tempinst->tempdecl->scope->search(0, tp->tempinst->name, NULL);
|
||||||
|
if (s)
|
||||||
|
{
|
||||||
|
s = s->toAlias();
|
||||||
|
TemplateDeclaration *td = s->isTemplateDeclaration();
|
||||||
|
if (td && td == tempinst->tempdecl)
|
||||||
|
goto L2;
|
||||||
|
}
|
||||||
goto Lnomatch;
|
goto Lnomatch;
|
||||||
|
}
|
||||||
TemplateParameter *tpx = (TemplateParameter *)parameters->data[i];
|
TemplateParameter *tpx = (TemplateParameter *)parameters->data[i];
|
||||||
// This logic duplicates tpx->matchArg()
|
// This logic duplicates tpx->matchArg()
|
||||||
TemplateAliasParameter *ta = tpx->isTemplateAliasParameter();
|
TemplateAliasParameter *ta = tpx->isTemplateAliasParameter();
|
||||||
@@ -1540,12 +1610,14 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
|||||||
else if (tempinst->tempdecl != tp->tempinst->tempdecl)
|
else if (tempinst->tempdecl != tp->tempinst->tempdecl)
|
||||||
goto Lnomatch;
|
goto Lnomatch;
|
||||||
|
|
||||||
|
L2:
|
||||||
if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim)
|
if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim)
|
||||||
goto Lnomatch;
|
goto Lnomatch;
|
||||||
|
|
||||||
for (int i = 0; i < tempinst->tiargs->dim; i++)
|
for (int i = 0; i < tempinst->tiargs->dim; i++)
|
||||||
{
|
{
|
||||||
//printf("test: [%d]\n", i);
|
//printf("\ttest: tempinst->tiargs[%d]\n", i);
|
||||||
|
int j;
|
||||||
Object *o1 = (Object *)tempinst->tiargs->data[i];
|
Object *o1 = (Object *)tempinst->tiargs->data[i];
|
||||||
Object *o2 = (Object *)tp->tempinst->tiargs->data[i];
|
Object *o2 = (Object *)tp->tempinst->tiargs->data[i];
|
||||||
|
|
||||||
@@ -1570,18 +1642,29 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
|||||||
else if (e1 && e2)
|
else if (e1 && e2)
|
||||||
{
|
{
|
||||||
if (!e1->equals(e2))
|
if (!e1->equals(e2))
|
||||||
|
{ if (e2->op == TOKvar)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* (T:Number!(e2), int e2)
|
||||||
|
*/
|
||||||
|
j = templateIdentifierLookup(((VarExp *)e2)->var->ident, parameters);
|
||||||
|
goto L1;
|
||||||
|
}
|
||||||
goto Lnomatch;
|
goto Lnomatch;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (e1 && t2 && t2->ty == Tident)
|
else if (e1 && t2 && t2->ty == Tident)
|
||||||
{ int i = templateParameterLookup(t2, parameters);
|
{
|
||||||
if (i == -1)
|
j = templateParameterLookup(t2, parameters);
|
||||||
|
L1:
|
||||||
|
if (j == -1)
|
||||||
goto Lnomatch;
|
goto Lnomatch;
|
||||||
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
|
TemplateParameter *tp = (TemplateParameter *)parameters->data[j];
|
||||||
// BUG: use tp->matchArg() instead of the following
|
// BUG: use tp->matchArg() instead of the following
|
||||||
TemplateValueParameter *tv = tp->isTemplateValueParameter();
|
TemplateValueParameter *tv = tp->isTemplateValueParameter();
|
||||||
if (!tv)
|
if (!tv)
|
||||||
goto Lnomatch;
|
goto Lnomatch;
|
||||||
Expression *e = (Expression *)dedtypes->data[i];
|
Expression *e = (Expression *)dedtypes->data[j];
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
if (!e1->equals(e))
|
if (!e1->equals(e))
|
||||||
@@ -1592,7 +1675,7 @@ MATCH TypeInstance::deduceType(Scope *sc,
|
|||||||
MATCH m = (MATCH)e1->implicitConvTo(vt);
|
MATCH m = (MATCH)e1->implicitConvTo(vt);
|
||||||
if (!m)
|
if (!m)
|
||||||
goto Lnomatch;
|
goto Lnomatch;
|
||||||
dedtypes->data[i] = e1;
|
dedtypes->data[j] = e1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// BUG: Need to handle alias and tuple parameters
|
// BUG: Need to handle alias and tuple parameters
|
||||||
@@ -2351,6 +2434,7 @@ Lmatch:
|
|||||||
return m;
|
return m;
|
||||||
|
|
||||||
Lnomatch:
|
Lnomatch:
|
||||||
|
//printf("\tno match\n");
|
||||||
*psparam = NULL;
|
*psparam = NULL;
|
||||||
return MATCHnomatch;
|
return MATCHnomatch;
|
||||||
}
|
}
|
||||||
@@ -2780,7 +2864,7 @@ void TemplateInstance::semantic(Scope *sc)
|
|||||||
if (m->semanticdone >= 3)
|
if (m->semanticdone >= 3)
|
||||||
dosemantic3 = 1;
|
dosemantic3 = 1;
|
||||||
}
|
}
|
||||||
for (i = 0; 1; i++)
|
for (int i = 0; 1; i++)
|
||||||
{
|
{
|
||||||
if (i == a->dim)
|
if (i == a->dim)
|
||||||
{
|
{
|
||||||
@@ -2953,7 +3037,7 @@ void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs)
|
|||||||
Expression *ea = isExpression(o);
|
Expression *ea = isExpression(o);
|
||||||
Dsymbol *sa = isDsymbol(o);
|
Dsymbol *sa = isDsymbol(o);
|
||||||
|
|
||||||
//printf("1: tiargs->data[%d] = %p, %p, %p\n", j, o, isDsymbol(o), isTuple(o));
|
//printf("1: tiargs->data[%d] = %p, %p, %p, ea=%p, ta=%p\n", j, o, isDsymbol(o), isTuple(o), ea, ta);
|
||||||
if (ta)
|
if (ta)
|
||||||
{
|
{
|
||||||
//printf("type %s\n", ta->toChars());
|
//printf("type %s\n", ta->toChars());
|
||||||
@@ -3196,9 +3280,9 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc)
|
|||||||
int c2 = td_best->leastAsSpecialized(td);
|
int c2 = td_best->leastAsSpecialized(td);
|
||||||
//printf("c1 = %d, c2 = %d\n", c1, c2);
|
//printf("c1 = %d, c2 = %d\n", c1, c2);
|
||||||
|
|
||||||
if (c1 && !c2)
|
if (c1 > c2)
|
||||||
goto Ltd;
|
goto Ltd;
|
||||||
else if (!c1 && c2)
|
else if (c1 < c2)
|
||||||
goto Ltd_best;
|
goto Ltd_best;
|
||||||
else
|
else
|
||||||
goto Lambig;
|
goto Lambig;
|
||||||
@@ -3305,10 +3389,30 @@ int TemplateInstance::isNested(Objects *args)
|
|||||||
{
|
{
|
||||||
// if module level template
|
// if module level template
|
||||||
if (tempdecl->toParent()->isModule())
|
if (tempdecl->toParent()->isModule())
|
||||||
{
|
{ Dsymbol *dparent = d->toParent();
|
||||||
if (isnested && isnested != d->toParent())
|
if (!isnested)
|
||||||
error("inconsistent nesting levels %s and %s", isnested->toChars(), d->toParent()->toChars());
|
isnested = dparent;
|
||||||
isnested = d->toParent();
|
else if (isnested != dparent)
|
||||||
|
{
|
||||||
|
/* Select the more deeply nested of the two.
|
||||||
|
* Error if one is not nested inside the other.
|
||||||
|
*/
|
||||||
|
for (Dsymbol *p = isnested; p; p = p->parent)
|
||||||
|
{
|
||||||
|
if (p == dparent)
|
||||||
|
goto L1; // isnested is most nested
|
||||||
|
}
|
||||||
|
for (Dsymbol *p = dparent; 1; p = p->parent)
|
||||||
|
{
|
||||||
|
if (p == isnested)
|
||||||
|
{ isnested = dparent;
|
||||||
|
goto L1; // dparent is most nested
|
||||||
|
}
|
||||||
|
}
|
||||||
|
error("is nested in both %s and %s", isnested->toChars(), dparent->toChars());
|
||||||
|
}
|
||||||
|
L1:
|
||||||
|
//printf("\tnested inside %s\n", isnested->toChars());
|
||||||
nested |= 1;
|
nested |= 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -49,6 +49,9 @@ struct Tuple : Object
|
|||||||
struct TemplateDeclaration : ScopeDsymbol
|
struct TemplateDeclaration : ScopeDsymbol
|
||||||
{
|
{
|
||||||
TemplateParameters *parameters; // array of TemplateParameter's
|
TemplateParameters *parameters; // array of TemplateParameter's
|
||||||
|
|
||||||
|
TemplateParameters *origParameters; // originals for Ddoc
|
||||||
|
|
||||||
Array instances; // array of TemplateInstance's
|
Array instances; // array of TemplateInstance's
|
||||||
|
|
||||||
TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
|
TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
|
||||||
|
|||||||
Reference in New Issue
Block a user