Merged DMD 1.045 !!!

This commit is contained in:
Tomas Lindquist Olsen 2009-05-16 22:21:31 +02:00
parent 9beb33770f
commit e8780d50e8
37 changed files with 9631 additions and 9388 deletions

View file

@ -186,9 +186,9 @@ struct BaseClass
}; };
#if DMDV2 #if DMDV2
#define CLASSINFO_SIZE (0x3C+16) // value of ClassInfo.size #define CLASSINFO_SIZE (0x3C+16+4) // value of ClassInfo.size
#else #else
#define CLASSINFO_SIZE (0x3C+12) // value of ClassInfo.size #define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
#endif #endif
struct ClassDeclaration : AggregateDeclaration struct ClassDeclaration : AggregateDeclaration

View file

@ -1511,6 +1511,9 @@ Expression *BinExp::typeCombine(Scope *sc)
{ {
Lincompatible: Lincompatible:
incompatibleTypes(); incompatibleTypes();
type = Type::terror;
e1 = new ErrorExp();
e2 = new ErrorExp();
} }
Lret: Lret:
if (!type) if (!type)

View file

@ -522,7 +522,7 @@ void ClassDeclaration::semantic(Scope *sc)
else else
assert(0); assert(0);
assert(!vthis); assert(!vthis);
vthis = new ThisDeclaration(t); vthis = new ThisDeclaration(loc, t);
members->push(vthis); members->push(vthis);
} }
} }
@ -1225,11 +1225,14 @@ int InterfaceDeclaration::isBaseOf(BaseClass *bc, int *poffset)
{ {
if (poffset) if (poffset)
{ *poffset = b->offset; { *poffset = b->offset;
if (j && bc->base->isInterfaceDeclaration())
*poffset = OFFSET_RUNTIME;
} }
return 1; return 1;
} }
if (isBaseOf(b, poffset)) if (isBaseOf(b, poffset))
{ { if (j && poffset && bc->base->isInterfaceDeclaration())
*poffset = OFFSET_RUNTIME;
return 1; return 1;
} }
} }

View file

@ -137,6 +137,7 @@ void VersionCondition::checkPredefined(Loc loc, const char *ident)
"Posix", "Posix",
#endif #endif
"OSX", "FreeBSD", "OSX", "FreeBSD",
"Solaris",
"LittleEndian", "BigEndian", "LittleEndian", "BigEndian",
"all", "all",
"none", "none",

View file

@ -19,6 +19,7 @@
#include "rmem.h" #include "rmem.h"
#include "root.h" #include "root.h"
#include "port.h"
#include "mtype.h" #include "mtype.h"
#include "expression.h" #include "expression.h"
@ -34,6 +35,10 @@ extern "C" bool real_isnan (const real_t *);
static real_t zero; // work around DMC bug for now static real_t zero; // work around DMC bug for now
#if __FreeBSD__
#define fmodl fmod // hack for now, fix later
#endif
#define LOG 0 #define LOG 0
Expression *expType(Type *type, Expression *e) Expression *expType(Type *type, Expression *e)
@ -460,7 +465,7 @@ Expression *Div(Type *type, Expression *e1, Expression *e2)
n2 = e2->toInteger(); n2 = e2->toInteger();
if (n2 == 0) if (n2 == 0)
{ e2->error("divide by 0"); { e2->error("divide by 0");
e2 = new IntegerExp(0, 1, e2->type); e2 = new IntegerExp(loc, 1, e2->type);
n2 = 1; n2 = 1;
} }
if (e1->type->isunsigned() || e2->type->isunsigned()) if (e1->type->isunsigned() || e2->type->isunsigned())
@ -531,7 +536,7 @@ Expression *Mod(Type *type, Expression *e1, Expression *e2)
n2 = e2->toInteger(); n2 = e2->toInteger();
if (n2 == 0) if (n2 == 0)
{ e2->error("divide by 0"); { e2->error("divide by 0");
e2 = new IntegerExp(0, 1, e2->type); e2 = new IntegerExp(loc, 1, e2->type);
n2 = 1; n2 = 1;
} }
if (e1->type->isunsigned() || e2->type->isunsigned()) if (e1->type->isunsigned() || e2->type->isunsigned())
@ -640,26 +645,21 @@ Expression *Ushr(Type *type, Expression *e1, Expression *e2)
} }
Expression *And(Type *type, Expression *e1, Expression *e2) Expression *And(Type *type, Expression *e1, Expression *e2)
{ Expression *e; {
Loc loc = e1->loc; Expression *e;
e = new IntegerExp(e1->loc, e1->toInteger() & e2->toInteger(), type);
e = new IntegerExp(loc, e1->toInteger() & e2->toInteger(), type);
return e; return e;
} }
Expression *Or(Type *type, Expression *e1, Expression *e2) Expression *Or(Type *type, Expression *e1, Expression *e2)
{ Expression *e; { Expression *e;
Loc loc = e1->loc; e = new IntegerExp(e1->loc, e1->toInteger() | e2->toInteger(), type);
e = new IntegerExp(loc, e1->toInteger() | e2->toInteger(), type);
return e; return e;
} }
Expression *Xor(Type *type, Expression *e1, Expression *e2) Expression *Xor(Type *type, Expression *e1, Expression *e2)
{ Expression *e; { Expression *e;
Loc loc = e1->loc; e = new IntegerExp(e1->loc, e1->toInteger() ^ e2->toInteger(), type);
e = new IntegerExp(loc, e1->toInteger() ^ e2->toInteger(), type);
return e; return e;
} }
@ -831,7 +831,7 @@ Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2)
#if __DMC__ #if __DMC__
cmp = (r1 == r2); cmp = (r1 == r2);
#else #else
if (isnan(r1) || isnan(r2)) // if unordered if (Port::isNan(r1) || Port::isNan(r2)) // if unordered
{ {
cmp = 0; cmp = 0;
} }
@ -926,11 +926,7 @@ Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2)
} }
#else #else
// Don't rely on compiler, handle NAN arguments separately // Don't rely on compiler, handle NAN arguments separately
#if IN_GCC if (Port::isNan(r1) || Port::isNan(r2)) // if unordered
if (real_isnan(&r1) || real_isnan(&r2)) // if unordered
#else
if (isnan(r1) || isnan(r2)) // if unordered
#endif
{ {
switch (op) switch (op)
{ {
@ -1313,6 +1309,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
Type *t2 = e2->type->toBasetype(); Type *t2 = e2->type->toBasetype();
//printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars()); //printf("Cat(e1 = %s, e2 = %s)\n", e1->toChars(), e2->toChars());
//printf("\tt1 = %s, t2 = %s\n", t1->toChars(), t2->toChars());
if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral)) if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral))
{ e = e2; { e = e2;
@ -1498,7 +1495,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
if (type->toBasetype()->ty == Tsarray) if (type->toBasetype()->ty == Tsarray)
{ {
e->type = new TypeSArray(e2->type, new IntegerExp(0, es1->elements->dim, Type::tindex)); e->type = new TypeSArray(e2->type, new IntegerExp(loc, es1->elements->dim, Type::tindex));
e->type = e->type->semantic(loc, NULL); e->type = e->type->semantic(loc, NULL);
} }
else else
@ -1515,7 +1512,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
if (type->toBasetype()->ty == Tsarray) if (type->toBasetype()->ty == Tsarray)
{ {
e->type = new TypeSArray(e1->type, new IntegerExp(0, es2->elements->dim, Type::tindex)); e->type = new TypeSArray(e1->type, new IntegerExp(loc, es2->elements->dim, Type::tindex));
e->type = e->type->semantic(loc, NULL); e->type = e->type->semantic(loc, NULL);
} }
else else

View file

@ -33,6 +33,7 @@ Declaration::Declaration(Identifier *id)
storage_class = STCundefined; storage_class = STCundefined;
protection = PROTundefined; protection = PROTundefined;
linkage = LINKdefault; linkage = LINKdefault;
inuse = 0;
} }
void Declaration::semantic(Scope *sc) void Declaration::semantic(Scope *sc)
@ -253,7 +254,6 @@ TypedefDeclaration::TypedefDeclaration(Loc loc, Identifier *id, Type *basetype,
this->hbasetype = NULL; this->hbasetype = NULL;
#endif #endif
this->sem = 0; this->sem = 0;
this->inuse = 0;
this->loc = loc; this->loc = loc;
#if IN_DMD #if IN_DMD
this->sinit = NULL; this->sinit = NULL;
@ -482,7 +482,9 @@ void AliasDeclaration::semantic(Scope *sc)
} }
} }
else if (t) else if (t)
{
type = t; type = t;
}
if (overnext) if (overnext)
ScopeDsymbol::multiplyDefined(0, this, overnext); ScopeDsymbol::multiplyDefined(0, this, overnext);
this->inSemantic = 0; this->inSemantic = 0;
@ -559,7 +561,7 @@ Dsymbol *AliasDeclaration::toAlias()
//static int count; if (++count == 10) *(char*)0=0; //static int count; if (++count == 10) *(char*)0=0;
if (inSemantic) if (inSemantic)
{ error("recursive alias declaration"); { error("recursive alias declaration");
// return this; aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL);
} }
Dsymbol *s = aliassym ? aliassym->toAlias() : this; Dsymbol *s = aliassym ? aliassym->toAlias() : this;
return s; return s;
@ -619,7 +621,6 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer
offset = 0; offset = 0;
noauto = 0; noauto = 0;
nestedref = 0; nestedref = 0;
inuse = 0;
ctorinit = 0; ctorinit = 0;
aliassym = NULL; aliassym = NULL;
onstack = 0; onstack = 0;
@ -1399,8 +1400,8 @@ TypeInfoTupleDeclaration::TypeInfoTupleDeclaration(Type *tinfo)
// For the "this" parameter to member functions // For the "this" parameter to member functions
ThisDeclaration::ThisDeclaration(Type *t) ThisDeclaration::ThisDeclaration(Loc loc, Type *t)
: VarDeclaration(0, t, Id::This, NULL) : VarDeclaration(loc, t, Id::This, NULL)
{ {
noauto = 1; noauto = 1;
} }

View file

@ -68,6 +68,7 @@ enum STC
STCtemplateparameter = 0x40000, // template parameter STCtemplateparameter = 0x40000, // template parameter
STCscope = 0x80000, // template parameter STCscope = 0x80000, // template parameter
STCinvariant = 0x100000, STCinvariant = 0x100000,
STCimmutable = 0x100000,
STCref = 0x200000, STCref = 0x200000,
STCinit = 0x400000, // has explicit initializer STCinit = 0x400000, // has explicit initializer
STCmanifest = 0x800000, // manifest constant STCmanifest = 0x800000, // manifest constant
@ -76,6 +77,10 @@ enum STC
STCpure = 0x4000000, // pure function STCpure = 0x4000000, // pure function
STCtls = 0x8000000, // thread local STCtls = 0x8000000, // thread local
STCalias = 0x10000000, // alias parameter STCalias = 0x10000000, // alias parameter
STCshared = 0x20000000, // accessible from multiple threads
STCgshared = 0x40000000, // accessible from multiple threads
// but not typed as "shared"
STC_TYPECTOR = (STCconst | STCimmutable | STCshared),
}; };
struct Match struct Match
@ -101,6 +106,7 @@ struct Declaration : Dsymbol
unsigned storage_class; unsigned storage_class;
enum PROT protection; enum PROT protection;
enum LINK linkage; enum LINK linkage;
int inuse; // used to detect cycles
Declaration(Identifier *id); Declaration(Identifier *id);
void semantic(Scope *sc); void semantic(Scope *sc);
@ -177,7 +183,6 @@ struct TypedefDeclaration : Declaration
// 1: semantic() is in progress // 1: semantic() is in progress
// 2: semantic() has been run // 2: semantic() has been run
// 3: semantic2() has been run // 3: semantic2() has been run
int inuse; // used to detect typedef cycles
TypedefDeclaration(Loc loc, Identifier *ident, Type *basetype, Initializer *init); TypedefDeclaration(Loc loc, Identifier *ident, Type *basetype, Initializer *init);
Dsymbol *syntaxCopy(Dsymbol *); Dsymbol *syntaxCopy(Dsymbol *);
@ -249,7 +254,6 @@ struct VarDeclaration : Declaration
unsigned offset; unsigned offset;
int noauto; // no auto semantics int noauto; // no auto semantics
int nestedref; // referenced by a lexically nested function int nestedref; // referenced by a lexically nested function
int inuse;
int ctorinit; // it has been initialized in a ctor int ctorinit; // it has been initialized in a ctor
int onstack; // 1: it has been allocated on the stack int onstack; // 1: it has been allocated on the stack
// 2: on stack, run destructor anyway // 2: on stack, run destructor anyway
@ -257,6 +261,7 @@ struct VarDeclaration : Declaration
Dsymbol *aliassym; // if redone as alias to another symbol Dsymbol *aliassym; // if redone as alias to another symbol
Expression *value; // when interpreting, this is the value Expression *value; // when interpreting, this is the value
// (NULL if value not determinable) // (NULL if value not determinable)
Scope *scope; // !=NULL means context to use
VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init); VarDeclaration(Loc loc, Type *t, Identifier *id, Initializer *init);
Dsymbol *syntaxCopy(Dsymbol *); Dsymbol *syntaxCopy(Dsymbol *);
@ -561,14 +566,22 @@ struct TypeInfoInvariantDeclaration : TypeInfoDeclaration
void llvmDefine(); void llvmDefine();
#endif #endif
}; };
struct TypeInfoSharedDeclaration : TypeInfoDeclaration
{
TypeInfoSharedDeclaration(Type *tinfo);
void toDt(dt_t **pdt);
};
#endif #endif
/**************************************************************/ /**************************************************************/
struct ThisDeclaration : VarDeclaration struct ThisDeclaration : VarDeclaration
{ {
ThisDeclaration(Type *t); ThisDeclaration(Loc loc, Type *t);
Dsymbol *syntaxCopy(Dsymbol *); Dsymbol *syntaxCopy(Dsymbol *);
ThisDeclaration *isThisDeclaration() { return this; }
}; };
enum ILS enum ILS
@ -624,7 +637,11 @@ struct FuncDeclaration : Declaration
ILS inlineStatus; ILS inlineStatus;
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; // 1 semantic() run
// 2 semantic2() run
// 3 semantic3() started
// 4 semantic3() done
// 5 toObjFile() run
// this function's frame ptr // 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

View file

@ -99,7 +99,6 @@ void initPrecedence()
precedence[TOKnull] = PREC_primary; precedence[TOKnull] = PREC_primary;
precedence[TOKstring] = PREC_primary; precedence[TOKstring] = PREC_primary;
precedence[TOKarrayliteral] = PREC_primary; precedence[TOKarrayliteral] = PREC_primary;
precedence[TOKtypedot] = PREC_primary;
precedence[TOKtypeid] = PREC_primary; precedence[TOKtypeid] = PREC_primary;
precedence[TOKis] = PREC_primary; precedence[TOKis] = PREC_primary;
precedence[TOKassert] = PREC_primary; precedence[TOKassert] = PREC_primary;
@ -1558,6 +1557,22 @@ void IntegerExp::toMangleBuffer(OutBuffer *buf)
buf->printf("%jd", value); buf->printf("%jd", value);
} }
/******************************** ErrorExp **************************/
/* Use this expression for error recovery.
* It should behave as a 'sink' to prevent further cascaded error messages.
*/
ErrorExp::ErrorExp()
: IntegerExp(0, 0, Type::terror)
{
}
void ErrorExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("__error");
}
/******************************** RealExp **************************/ /******************************** RealExp **************************/
RealExp::RealExp(Loc loc, real_t value, Type *type) RealExp::RealExp(Loc loc, real_t value, Type *type)
@ -1940,7 +1955,7 @@ Expression *IdentifierExp::semantic(Scope *sc)
{ Type *t = withsym->withstate->wthis->type; { Type *t = withsym->withstate->wthis->type;
if (t->ty == Tpointer) if (t->ty == Tpointer)
t = ((TypePointer *)t)->next; t = ((TypePointer *)t)->next;
e = new TypeDotIdExp(loc, t, ident); e = typeDotIdExp(loc, t, ident);
} }
} }
else else
@ -3288,38 +3303,11 @@ void StructLiteralExp::toMangleBuffer(OutBuffer *buf)
* cast(foo).size * cast(foo).size
*/ */
TypeDotIdExp::TypeDotIdExp(Loc loc, Type *type, Identifier *ident) Expression *typeDotIdExp(Loc loc, Type *type, Identifier *ident)
: Expression(loc, TOKtypedot, sizeof(TypeDotIdExp))
{ {
this->type = type; return new DotIdExp(loc, new TypeExp(loc, type), ident);
this->ident = ident;
} }
Expression *TypeDotIdExp::syntaxCopy()
{
TypeDotIdExp *te = new TypeDotIdExp(loc, type->syntaxCopy(), ident);
return te;
}
Expression *TypeDotIdExp::semantic(Scope *sc)
{ Expression *e;
#if LOGSEMANTIC
printf("TypeDotIdExp::semantic()\n");
#endif
e = new DotIdExp(loc, new TypeExp(loc, type), ident);
e = e->semantic(sc);
return e;
}
void TypeDotIdExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writeByte('(');
type->toCBuffer(buf, NULL, hgs);
buf->writeByte(')');
buf->writeByte('.');
buf->writestring(ident->toChars());
}
/************************************************************/ /************************************************************/
@ -5257,12 +5245,12 @@ Expression *DotIdExp::semantic(Scope *sc)
{ {
if (e1->op == TOKthis) if (e1->op == TOKthis)
{ {
e = new TypeDotIdExp(loc, cd->type, ident); e = typeDotIdExp(loc, cd->type, ident);
return e->semantic(sc); return e->semantic(sc);
} }
else if (cd->baseClass && e1->op == TOKsuper) else if (cd->baseClass && e1->op == TOKsuper)
{ {
e = new TypeDotIdExp(loc, cd->baseClass->type, ident); e = typeDotIdExp(loc, cd->baseClass->type, ident);
return e->semantic(sc); return e->semantic(sc);
} }
} }
@ -5273,7 +5261,7 @@ Expression *DotIdExp::semantic(Scope *sc)
{ {
if (e1->op == TOKthis) if (e1->op == TOKthis)
{ {
e = new TypeDotIdExp(loc, sd->type, ident); e = typeDotIdExp(loc, sd->type, ident);
return e->semantic(sc); return e->semantic(sc);
} }
} }
@ -5321,6 +5309,18 @@ Expression *DotIdExp::semantic(Scope *sc)
return e; return e;
} }
if (e1->op == TOKdottd)
{
error("template %s does not have property %s", e1->toChars(), ident->toChars());
return e1;
}
if (!e1->type)
{
error("expression %s does not have property %s", e1->toChars(), ident->toChars());
return e1;
}
if (eright->op == TOKimport) // also used for template alias's if (eright->op == TOKimport) // also used for template alias's
{ {
ScopeExp *ie = (ScopeExp *)eright; ScopeExp *ie = (ScopeExp *)eright;
@ -5607,7 +5607,8 @@ Expression *DotVarExp::semantic(Scope *sc)
if (!var->isFuncDeclaration()) // for functions, do checks after overload resolution if (!var->isFuncDeclaration()) // for functions, do checks after overload resolution
{ {
AggregateDeclaration *ad = var->toParent()->isAggregateDeclaration(); Dsymbol *vparent = var->toParent();
AggregateDeclaration *ad = vparent ? vparent->isAggregateDeclaration() : NULL;
e1 = getRightThis(loc, sc, ad, e1, var); e1 = getRightThis(loc, sc, ad, e1, var);
if (!sc->noaccesscheck) if (!sc->noaccesscheck)
accessCheck(loc, sc, e1, var); accessCheck(loc, sc, e1, var);
@ -5802,10 +5803,11 @@ Expression *DotTemplateInstanceExp::semantic(Scope *sc)
id = ti->name; id = ti->name;
s2 = s->search(loc, id, 0); s2 = s->search(loc, id, 0);
if (!s2) if (!s2)
{ if (s->ident) {
error("template identifier %s is not a member of %s %s", id->toChars(), s->kind(), s->ident->toChars()); if (!s->ident)
error("template identifier %s is not a member of undefined %s", id->toChars(), s->kind());
else else
error("template identifier %s is not a member of %s", id->toChars(), s->kind()); error("template identifier %s is not a member of %s %s", id->toChars(), s->kind(), s->ident->toChars());
goto Lerr; goto Lerr;
} }
s = s2; s = s2;
@ -7264,7 +7266,7 @@ Expression *SliceExp::semantic(Scope *sc)
else else
{ {
error("string slice [%ju .. %ju] is out of bounds", i1, i2); error("string slice [%ju .. %ju] is out of bounds", i1, i2);
e = e1; e = new IntegerExp(0);
} }
return e; return e;
} }
@ -9275,8 +9277,15 @@ Expression *CmpExp::semantic(Scope *sc)
e = op_overload(sc); e = op_overload(sc);
if (e) if (e)
{ {
e = new CmpExp(op, loc, e, new IntegerExp(loc, 0, Type::tint32)); if (!e->type->isscalar() && e->type->equals(e1->type))
e = e->semantic(sc); {
error("recursive opCmp expansion");
e = new ErrorExp();
}
else
{ e = new CmpExp(op, loc, e, new IntegerExp(loc, 0, Type::tint32));
e = e->semantic(sc);
}
return e; return e;
} }

View file

@ -203,6 +203,13 @@ struct IntegerExp : Expression
#endif #endif
}; };
struct ErrorExp : IntegerExp
{
ErrorExp();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};
struct RealExp : Expression struct RealExp : Expression
{ {
real_t value; real_t value;
@ -519,22 +526,13 @@ struct StructLiteralExp : Expression
#endif #endif
}; };
struct TypeDotIdExp : Expression Expression *typeDotIdExp(Loc loc, Type *type, Identifier *ident);
{
Identifier *ident;
TypeDotIdExp(Loc loc, Type *type, Identifier *ident);
Expression *syntaxCopy();
Expression *semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#if IN_DMD #if IN_DMD
elem *toElem(IRState *irs);
#endif #endif
#if IN_LLVM #if IN_LLVM
DValue* toElem(IRState* irs); DValue* toElem(IRState* irs);
#endif #endif
};
struct TypeExp : Expression struct TypeExp : Expression
{ {

6129
dmd/func.c

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,6 @@
// Compiler implementation of the D programming language // Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars // Copyright (c) 1999-2009 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
@ -568,7 +568,20 @@ Type *ExpInitializer::inferType(Scope *sc)
//printf("ExpInitializer::inferType() %s\n", toChars()); //printf("ExpInitializer::inferType() %s\n", toChars());
exp = exp->semantic(sc); exp = exp->semantic(sc);
exp = resolveProperties(sc, exp); exp = resolveProperties(sc, exp);
return exp->type;
#if DMDV2
// Give error for overloaded function addresses
if (exp->op == TOKsymoff)
{ SymOffExp *se = (SymOffExp *)exp;
if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique())
exp->error("cannot infer type from overloaded function symbol %s", exp->toChars());
}
#endif
Type *t = exp->type;
if (!t)
t = Initializer::inferType(sc);
return t;
} }
Expression *ExpInitializer::toExpression() Expression *ExpInitializer::toExpression()

View file

@ -1,5 +1,5 @@
// 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
@ -929,8 +929,11 @@ Statement *DefaultStatement::inlineScan(InlineScanState *iss)
Statement *ReturnStatement::inlineScan(InlineScanState *iss) Statement *ReturnStatement::inlineScan(InlineScanState *iss)
{ {
//printf("ReturnStatement::inlineScan()\n");
if (exp) if (exp)
{
exp = exp->inlineScan(iss); exp = exp->inlineScan(iss);
}
return this; return this;
} }
@ -1234,7 +1237,7 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan)
if (needThis() && !hasthis) if (needThis() && !hasthis)
return 0; return 0;
if (inlineNest || (!semanticRun && !hdrscan)) if (inlineNest || (semanticRun < 3 && !hdrscan))
{ {
#if CANINLINE_LOG #if CANINLINE_LOG
printf("\t1: no, inlineNest = %d, semanticRun = %d\n", inlineNest, semanticRun); printf("\t1: no, inlineNest = %d, semanticRun = %d\n", inlineNest, semanticRun);
@ -1246,13 +1249,13 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan)
{ {
case ILSyes: case ILSyes:
#if CANINLINE_LOG #if CANINLINE_LOG
printf("\tyes\n"); printf("\t1: yes %s\n", toChars());
#endif #endif
return 1; return 1;
case ILSno: case ILSno:
#if CANINLINE_LOG #if CANINLINE_LOG
printf("\t2: no\n"); printf("\t1: no %s\n", toChars());
#endif #endif
return 0; return 0;
@ -1338,7 +1341,7 @@ Lyes:
if (!hdrscan) // Don't modify inlineStatus for header content scan if (!hdrscan) // Don't modify inlineStatus for header content scan
inlineStatus = ILSyes; inlineStatus = ILSyes;
#if CANINLINE_LOG #if CANINLINE_LOG
printf("\tyes\n"); printf("\t2: yes %s\n", toChars());
#endif #endif
return 1; return 1;
@ -1346,7 +1349,7 @@ Lno:
if (!hdrscan) // Don't modify inlineStatus for header content scan if (!hdrscan) // Don't modify inlineStatus for header content scan
inlineStatus = ILSno; inlineStatus = ILSno;
#if CANINLINE_LOG #if CANINLINE_LOG
printf("\tno\n"); printf("\t2: no %s\n", toChars());
#endif #endif
return 0; return 0;
} }

View file

@ -69,7 +69,7 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
else if (ident == Id::aaValues) else if (ident == Id::aaValues)
return interpret_aaValues(istate, arguments); return interpret_aaValues(istate, arguments);
if (cantInterpret || semanticRun == 1) if (cantInterpret || semanticRun == 3)
return NULL; return NULL;
if (needThis() || isNested() || !fbody) if (needThis() || isNested() || !fbody)
@ -77,13 +77,13 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
return NULL; return NULL;
} }
if (semanticRun == 0 && scope) if (semanticRun < 3 && scope)
{ {
semantic3(scope); semantic3(scope);
if (global.errors) // if errors compiling this function if (global.errors) // if errors compiling this function
return NULL; return NULL;
} }
if (semanticRun < 2) if (semanticRun < 4)
return NULL; return NULL;
Type *tb = type->toBasetype(); Type *tb = type->toBasetype();
@ -1525,6 +1525,15 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
{ error("variable %s is used before initialization", v->toChars()); { error("variable %s is used before initialization", v->toChars());
return e; return e;
} }
if (v->value == NULL && v->init->isVoidInitializer())
{ /* Since a void initializer initializes to undefined
* values, it is valid here to use the default initializer.
* No attempt is made to determine if someone actually relies
* on the void value - to do that we'd need a VoidExp.
* That's probably a good enhancement idea.
*/
v->value = v->type->defaultInit();
}
Expression *vie = v->value; Expression *vie = v->value;
if (vie->op == TOKvar) if (vie->op == TOKvar)
{ {

View file

@ -3072,7 +3072,6 @@ void Lexer::initKeywords()
Token::tochars[TOKdotvar] = "dotvar"; Token::tochars[TOKdotvar] = "dotvar";
Token::tochars[TOKdottype] = "dottype"; Token::tochars[TOKdottype] = "dottype";
Token::tochars[TOKsymoff] = "symoff"; Token::tochars[TOKsymoff] = "symoff";
Token::tochars[TOKtypedot] = "typedot";
Token::tochars[TOKarraylength] = "arraylength"; Token::tochars[TOKarraylength] = "arraylength";
Token::tochars[TOKarrayliteral] = "arrayliteral"; Token::tochars[TOKarrayliteral] = "arrayliteral";
Token::tochars[TOKassocarrayliteral] = "assocarrayliteral"; Token::tochars[TOKassocarrayliteral] = "assocarrayliteral";

View file

@ -51,7 +51,7 @@ enum TOK
TOKnull, TOKassert, TOKnull, TOKassert,
TOKtrue, TOKfalse, TOKtrue, TOKfalse,
TOKarray, TOKcall, TOKarray, TOKcall,
TOKaddress, TOKtypedot, TOKaddress,
TOKtype, TOKthrow, TOKtype, TOKthrow,
TOKnew, TOKdelete, TOKnew, TOKdelete,
TOKstar, TOKsymoff, TOKstar, TOKsymoff,

View file

@ -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-2009 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
@ -24,7 +24,7 @@
#include "id.h" #include "id.h"
#include "module.h" #include "module.h"
#if TARGET_LINUX || TARGET_OSX #if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
char *cpp_mangle(Dsymbol *s); char *cpp_mangle(Dsymbol *s);
#endif #endif
@ -117,7 +117,7 @@ char *Declaration::mangle()
return ident->toChars(); return ident->toChars();
case LINKcpp: case LINKcpp:
#if DMDV2 && (TARGET_LINUX || TARGET_OSX) #if DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS)
return cpp_mangle(this); return cpp_mangle(this);
#else #else
// Windows C++ mangling is done by C++ back end // Windows C++ mangling is done by C++ back end
@ -220,7 +220,9 @@ char *TemplateInstance::mangle()
printf("\n"); printf("\n");
#endif #endif
id = ident ? ident->toChars() : toChars(); id = ident ? ident->toChars() : toChars();
if (tempdecl->parent) if (!tempdecl)
error("is not defined");
else if (tempdecl->parent)
{ {
char *p = tempdecl->parent->mangle(); char *p = tempdecl->parent->mangle();
if (p[0] == '_' && p[1] == 'D') if (p[0] == '_' && p[1] == 'D')

View file

@ -36,6 +36,8 @@ Macros defined by the compiler, not the code:
_WIN64 Windows for AMD64 _WIN64 Windows for AMD64
linux Linux linux Linux
__APPLE__ Mac OSX __APPLE__ Mac OSX
__FreeBSD__ FreeBSD
__sun&&__SVR4 Solaris, OpenSolaris (yes, both macros are necessary)
For the target systems, there are the target operating system and For the target systems, there are the target operating system and
the target object file format: the target object file format:
@ -44,13 +46,15 @@ the target object file format:
TARGET_WINDOS Covers 32 bit windows and 64 bit windows TARGET_WINDOS Covers 32 bit windows and 64 bit windows
TARGET_LINUX Covers 32 and 64 bit linux TARGET_LINUX Covers 32 and 64 bit linux
TARGET_OSX Covers 32 and 64 bit Mac OSX TARGET_OSX Covers 32 and 64 bit Mac OSX
TARGET_FREEBSD Covers 32 and 64 bit FreeBSD
TARGET_SOLARIS Covers 32 and 64 bit Solaris
It is expected that the compiler for each platform will be able It is expected that the compiler for each platform will be able
to generate 32 and 64 bit code from the same compiler binary. to generate 32 and 64 bit code from the same compiler binary.
Target object module format: Target object module format:
OMFOBJ Intel Object Module Format, used on Windows OMFOBJ Intel Object Module Format, used on Windows
ELFOBJ Elf Object Module Format, used on linux ELFOBJ Elf Object Module Format, used on linux, FreeBSD and Solaris
MACHOBJ Mach-O Object Module Format, used on Mac OSX MACHOBJ Mach-O Object Module Format, used on Mac OSX
There are currently no macros for byte endianness order. There are currently no macros for byte endianness order.
@ -81,7 +85,8 @@ the target object file format:
#define STRUCTTHISREF DMDV2 // if 'this' for struct is a reference, not a pointer #define STRUCTTHISREF DMDV2 // if 'this' for struct is a reference, not a pointer
#define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN #define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN
/* Other targets are TARGET_LINUX and TARGET_OSX, which are /* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and
* TARGET_SOLARIS, which are
* set on the command line via the compiler makefile. * set on the command line via the compiler makefile.
*/ */
@ -90,7 +95,7 @@ the target object file format:
#define OMFOBJ 1 #define OMFOBJ 1
#endif #endif
#if TARGET_LINUX #if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
#ifndef ELFOBJ #ifndef ELFOBJ
#define ELFOBJ 1 #define ELFOBJ 1
#endif #endif

View file

@ -72,11 +72,16 @@ FuncDeclaration *hasThis(Scope *sc);
*/ */
int PTRSIZE = 4; int PTRSIZE = 4;
/* REALSIZE = size a real consumes in memory
* REALPAD = 'padding' added to the CPU real size to bring it up to REALSIZE
* REALALIGNSIZE = alignment for reals
*/
#if TARGET_OSX #if TARGET_OSX
int REALSIZE = 16; int REALSIZE = 16;
int REALPAD = 6; int REALPAD = 6;
int REALALIGNSIZE = 16; int REALALIGNSIZE = 16;
#elif TARGET_LINUX || TARGET_FREEBSD #elif TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
int REALSIZE = 12; int REALSIZE = 12;
int REALPAD = 2; int REALPAD = 2;
int REALALIGNSIZE = 4; int REALALIGNSIZE = 4;
@ -85,6 +90,7 @@ int REALSIZE = 10;
int REALPAD = 0; int REALPAD = 0;
int REALALIGNSIZE = 2; int REALALIGNSIZE = 2;
#endif #endif
int Tsize_t = Tuns32; int Tsize_t = Tuns32;
int Tptrdiff_t = Tint32; int Tptrdiff_t = Tint32;
@ -405,7 +411,7 @@ void Type::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
void Type::toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod) void Type::toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod)
{ {
if (mod != this->mod) if (mod != this->mod)
{ char *p; { const char *p;
switch (this->mod) switch (this->mod)
{ {
@ -432,20 +438,18 @@ void Type::toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod)
*/ */
Type *Type::merge() Type *Type::merge()
{ Type *t; {
//printf("merge(%s)\n", toChars()); //printf("merge(%s)\n", toChars());
t = this; Type *t = this;
assert(t); assert(t);
if (!deco) if (!deco)
{ {
OutBuffer buf;
StringValue *sv;
if (next) if (next)
next = next->merge(); next = next->merge();
OutBuffer buf;
toDecoBuffer(&buf, false); toDecoBuffer(&buf, false);
sv = stringtable.update((char *)buf.data, buf.offset); StringValue *sv = stringtable.update((char *)buf.data, buf.offset);
if (sv->ptrvalue) if (sv->ptrvalue)
{ t = (Type *) sv->ptrvalue; { t = (Type *) sv->ptrvalue;
assert(t->deco); assert(t->deco);
@ -477,6 +481,28 @@ Type *Type::merge()
return t; return t;
} }
/*************************************
* This version does a merge even if the deco is already computed.
* Necessary for types that have a deco, but are not merged.
*/
Type *Type::merge2()
{
//printf("merge2(%s)\n", toChars());
Type *t = this;
assert(t);
if (!t->deco)
return t->merge();
StringValue *sv = deco_stringtable.lookup((char *)t->deco, strlen(t->deco));
if (sv && sv->ptrvalue)
{ t = (Type *) sv->ptrvalue;
assert(t->deco);
}
else
assert(0);
return t;
}
int Type::isbit() int Type::isbit()
{ {
return FALSE; return FALSE;
@ -563,7 +589,7 @@ Expression *Type::defaultInit(Loc loc)
return NULL; return NULL;
} }
int Type::isZeroInit() int Type::isZeroInit(Loc loc)
{ {
return 0; // assume not return 0; // assume not
} }
@ -625,9 +651,14 @@ Expression *Type::getProperty(Loc loc, Identifier *ident)
e = defaultInit(loc); e = defaultInit(loc);
} }
else if (ident == Id::mangleof) else if (ident == Id::mangleof)
{ { const char *s;
assert(deco); if (!deco)
e = new StringExp(loc, deco, strlen(deco), 'c'); { s = toChars();
error(loc, "forward reference of type %s.mangleof", s);
}
else
s = deco;
e = new StringExp(loc, (char *)s, strlen(s), 'c');
Scope sc; Scope sc;
e = e->semantic(&sc); e = e->semantic(&sc);
} }
@ -1049,6 +1080,17 @@ unsigned TypeBasic::alignsize()
if (ty == Tvoid) if (ty == Tvoid)
return 1; return 1;
return GetTypeAlignment(sir, this); return GetTypeAlignment(sir, this);
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
case Tint64:
case Tuns64:
case Tfloat64:
case Timaginary64:
case Tcomplex32:
case Tcomplex64:
sz = 4;
break;
#endif
} }
@ -1089,7 +1131,7 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident)
case Tfloat64: fvalue = DBL_MAX; goto Lfvalue; case Tfloat64: fvalue = DBL_MAX; goto Lfvalue;
case Tcomplex80: case Tcomplex80:
case Timaginary80: case Timaginary80:
case Tfloat80: fvalue = LDBL_MAX; goto Lfvalue; case Tfloat80: fvalue = Port::ldbl_max; goto Lfvalue;
} }
} }
else if (ident == Id::min) else if (ident == Id::min)
@ -1402,7 +1444,7 @@ Expression *TypeBasic::defaultInit(Loc loc)
return new IntegerExp(loc, value, this); return new IntegerExp(loc, value, this);
} }
int TypeBasic::isZeroInit() int TypeBasic::isZeroInit(Loc loc)
{ {
switch (ty) switch (ty)
{ {
@ -2050,9 +2092,9 @@ Expression *TypeSArray::defaultInit(Loc loc)
return next->defaultInit(loc); return next->defaultInit(loc);
} }
int TypeSArray::isZeroInit() int TypeSArray::isZeroInit(Loc loc)
{ {
return next->isZeroInit(); return next->isZeroInit(loc);
} }
@ -2209,7 +2251,7 @@ Expression *TypeDArray::defaultInit(Loc loc)
return e; return e;
} }
int TypeDArray::isZeroInit() int TypeDArray::isZeroInit(Loc loc)
{ {
return 1; return 1;
} }
@ -2481,7 +2523,7 @@ Expression *TypeAArray::defaultInit(Loc loc)
return e; return e;
} }
int TypeAArray::isZeroInit() int TypeAArray::isZeroInit(Loc loc)
{ {
return TRUE; return TRUE;
} }
@ -2594,7 +2636,7 @@ Expression *TypePointer::defaultInit(Loc loc)
return e; return e;
} }
int TypePointer::isZeroInit() int TypePointer::isZeroInit(Loc loc)
{ {
return 1; return 1;
} }
@ -2660,7 +2702,7 @@ Expression *TypeReference::defaultInit(Loc loc)
return e; return e;
} }
int TypeReference::isZeroInit() int TypeReference::isZeroInit(Loc loc)
{ {
return 1; return 1;
} }
@ -2841,7 +2883,7 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, bool mangle)
void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs) void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
{ {
char *p = NULL; const char *p = NULL;
if (inuse) if (inuse)
{ inuse = 2; // flag error to caller { inuse = 2; // flag error to caller
@ -2880,7 +2922,7 @@ void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs
void TypeFunction::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod) void TypeFunction::toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod)
{ {
char *p = NULL; const char *p = NULL;
if (inuse) if (inuse)
{ inuse = 2; // flag error to caller { inuse = 2; // flag error to caller
@ -3223,7 +3265,7 @@ Expression *TypeDelegate::defaultInit(Loc loc)
return e; return e;
} }
int TypeDelegate::isZeroInit() int TypeDelegate::isZeroInit(Loc loc)
{ {
return 1; return 1;
} }
@ -3865,6 +3907,8 @@ Type *TypeTypeof::semantic(Loc loc, Scope *sc)
error(loc, "expression (%s) has no type", exp->toChars()); error(loc, "expression (%s) has no type", exp->toChars());
goto Lerr; goto Lerr;
} }
if (t->ty == Ttypeof)
error(loc, "forward reference to %s", toChars());
} }
if (idents.dim) if (idents.dim)
@ -3966,7 +4010,7 @@ Type *TypeEnum::toBasetype()
printf("2: "); printf("2: ");
#endif #endif
error(sym->loc, "enum %s is forward referenced", sym->toChars()); error(sym->loc, "enum %s is forward referenced", sym->toChars());
return tint32; return terror;
} }
return sym->memtype->toBasetype(); return sym->memtype->toBasetype();
} }
@ -4020,8 +4064,8 @@ Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident)
return em; return em;
Lfwd: Lfwd:
error(e->loc, "forward reference of %s.%s", toChars(), ident->toChars()); error(e->loc, "forward reference of enum %s.%s", toChars(), ident->toChars());
return new IntegerExp(0, 0, this); return new IntegerExp(0, 0, Type::terror);
} }
Expression *TypeEnum::getProperty(Loc loc, Identifier *ident) Expression *TypeEnum::getProperty(Loc loc, Identifier *ident)
@ -4109,7 +4153,7 @@ Expression *TypeEnum::defaultInit(Loc loc)
return e; return e;
} }
int TypeEnum::isZeroInit() int TypeEnum::isZeroInit(Loc loc)
{ {
return (sym->defaultval == 0); return (sym->defaultval == 0);
} }
@ -4300,7 +4344,7 @@ Expression *TypeTypedef::defaultInit(Loc loc)
return e; return e;
} }
int TypeTypedef::isZeroInit() int TypeTypedef::isZeroInit(Loc loc)
{ {
if (sym->init) if (sym->init)
{ {
@ -4317,7 +4361,7 @@ int TypeTypedef::isZeroInit()
sym->basetype = Type::terror; sym->basetype = Type::terror;
} }
sym->inuse = 1; sym->inuse = 1;
int result = sym->basetype->isZeroInit(); int result = sym->basetype->isZeroInit(loc);
sym->inuse = 0; sym->inuse = 0;
return result; return result;
} }
@ -4613,7 +4657,7 @@ Expression *TypeStruct::defaultInit(Loc loc)
return new VarExp(sym->loc, d); return new VarExp(sym->loc, d);
} }
int TypeStruct::isZeroInit() int TypeStruct::isZeroInit(Loc loc)
{ {
return sym->zeroInit; return sym->zeroInit;
} }
@ -5074,7 +5118,7 @@ Expression *TypeClass::defaultInit(Loc loc)
return e; return e;
} }
int TypeClass::isZeroInit() int TypeClass::isZeroInit(Loc loc)
{ {
return 1; return 1;
} }

View file

@ -222,6 +222,7 @@ struct Type : Object
// append the mangleof or a string uniquely identifying this type to buf // append the mangleof or a string uniquely identifying this type to buf
virtual void toDecoBuffer(OutBuffer *buf, bool mangle); virtual void toDecoBuffer(OutBuffer *buf, bool mangle);
Type *merge(); Type *merge();
Type *merge2();
virtual void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs); virtual void toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs);
virtual void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); virtual void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod); void toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod);
@ -249,7 +250,7 @@ struct Type : Object
virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
virtual unsigned memalign(unsigned salign); virtual unsigned memalign(unsigned salign);
virtual Expression *defaultInit(Loc loc = 0); virtual Expression *defaultInit(Loc loc = 0);
virtual int isZeroInit(); // if initializer is 0 virtual int isZeroInit(Loc loc = 0); // if initializer is 0
#if IN_DMD #if IN_DMD
virtual dt_t **toDt(dt_t **pdt); virtual dt_t **toDt(dt_t **pdt);
#endif #endif
@ -310,7 +311,7 @@ struct TypeBasic : Type
int isunsigned(); int isunsigned();
MATCH implicitConvTo(Type *to); MATCH implicitConvTo(Type *to);
Expression *defaultInit(Loc loc); Expression *defaultInit(Loc loc);
int isZeroInit(); int isZeroInit(Loc loc);
int builtinTypeInfo(); int builtinTypeInfo();
// For eliminating dynamic_cast // For eliminating dynamic_cast
@ -338,7 +339,7 @@ struct TypeSArray : TypeArray
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
int isString(); int isString();
int isZeroInit(); int isZeroInit(Loc loc);
unsigned memalign(unsigned salign); unsigned memalign(unsigned salign);
MATCH implicitConvTo(Type *to); MATCH implicitConvTo(Type *to);
Expression *defaultInit(Loc loc); Expression *defaultInit(Loc loc);
@ -369,7 +370,7 @@ struct TypeDArray : TypeArray
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
int isString(); int isString();
int isZeroInit(); int isZeroInit(Loc loc);
int checkBoolean(); int checkBoolean();
MATCH implicitConvTo(Type *to); MATCH implicitConvTo(Type *to);
Expression *defaultInit(Loc loc); Expression *defaultInit(Loc loc);
@ -397,7 +398,7 @@ struct TypeAArray : TypeArray
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);
int isZeroInit(); int isZeroInit(Loc loc);
int checkBoolean(); int checkBoolean();
TypeInfoDeclaration *getTypeInfoDeclaration(); TypeInfoDeclaration *getTypeInfoDeclaration();
int hasPointers(); int hasPointers();
@ -422,7 +423,7 @@ struct TypePointer : Type
// LDC: pointers are unsigned // LDC: pointers are unsigned
int isunsigned() { return TRUE; }; int isunsigned() { return TRUE; };
Expression *defaultInit(Loc loc); Expression *defaultInit(Loc loc);
int isZeroInit(); int isZeroInit(Loc loc);
TypeInfoDeclaration *getTypeInfoDeclaration(); TypeInfoDeclaration *getTypeInfoDeclaration();
int hasPointers(); int hasPointers();
@ -439,7 +440,7 @@ struct TypeReference : Type
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); 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(Loc loc);
}; };
enum RET enum RET
@ -493,7 +494,7 @@ struct TypeDelegate : Type
unsigned alignsize(); // added in LDC unsigned alignsize(); // added in LDC
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod); void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
Expression *defaultInit(Loc loc); Expression *defaultInit(Loc loc);
int isZeroInit(); int isZeroInit(Loc loc);
int checkBoolean(); int checkBoolean();
TypeInfoDeclaration *getTypeInfoDeclaration(); TypeInfoDeclaration *getTypeInfoDeclaration();
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident); Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
@ -580,7 +581,7 @@ struct TypeStruct : Type
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);
int isZeroInit(); int isZeroInit(Loc loc);
int checkBoolean(); int checkBoolean();
#if IN_DMD #if IN_DMD
dt_t **toDt(dt_t **pdt); dt_t **toDt(dt_t **pdt);
@ -621,7 +622,7 @@ struct TypeEnum : Type
MATCH implicitConvTo(Type *to); MATCH implicitConvTo(Type *to);
Type *toBasetype(); Type *toBasetype();
Expression *defaultInit(Loc loc); Expression *defaultInit(Loc loc);
int isZeroInit(); int isZeroInit(Loc loc);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
TypeInfoDeclaration *getTypeInfoDeclaration(); TypeInfoDeclaration *getTypeInfoDeclaration();
int hasPointers(); int hasPointers();
@ -658,7 +659,7 @@ struct TypeTypedef : Type
Type *toBasetype(); Type *toBasetype();
MATCH implicitConvTo(Type *to); MATCH implicitConvTo(Type *to);
Expression *defaultInit(Loc loc); Expression *defaultInit(Loc loc);
int isZeroInit(); int isZeroInit(Loc loc);
#if IN_DMD #if IN_DMD
dt_t **toDt(dt_t **pdt); dt_t **toDt(dt_t **pdt);
#endif #endif
@ -689,12 +690,20 @@ struct TypeClass : Type
int isBaseOf(Type *t, int *poffset); int isBaseOf(Type *t, int *poffset);
MATCH implicitConvTo(Type *to); MATCH implicitConvTo(Type *to);
Expression *defaultInit(Loc loc); Expression *defaultInit(Loc loc);
int isZeroInit(); int isZeroInit(Loc loc);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes); MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
int isauto(); int isauto();
int checkBoolean(); int checkBoolean();
TypeInfoDeclaration *getTypeInfoDeclaration(); TypeInfoDeclaration *getTypeInfoDeclaration();
int hasPointers(); int hasPointers();
int builtinTypeInfo();
#if DMDV2
Type *toHeadMutable();
MATCH constConv(Type *to);
#if TARGET_LINUX || TARGET_OSX
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif
#endif
#if IN_DMD #if IN_DMD
type *toCtype(); type *toCtype();

View file

@ -292,7 +292,7 @@ Expression *DotVarExp::optimize(int result)
if (vf) if (vf)
{ {
e = sle->getField(type, vf->offset); e = sle->getField(type, vf->offset);
if (e != EXP_CANT_INTERPRET) if (e && e != EXP_CANT_INTERPRET)
return e; return e;
} }
} }
@ -305,7 +305,7 @@ Expression *DotVarExp::optimize(int result)
if (vf) if (vf)
{ {
Expression *e = sle->getField(type, vf->offset); Expression *e = sle->getField(type, vf->offset);
if (e != EXP_CANT_INTERPRET) if (e && e != EXP_CANT_INTERPRET)
return e; return e;
} }
} }

10672
dmd/parse.c

File diff suppressed because it is too large Load diff

View file

@ -69,6 +69,7 @@ struct Parser : Lexer
Array *parseModule(); Array *parseModule();
Array *parseDeclDefs(int once); Array *parseDeclDefs(int once);
Array *parseBlock(); Array *parseBlock();
void composeStorageClass(unsigned stc);
TemplateDeclaration *parseTemplateDeclaration(); TemplateDeclaration *parseTemplateDeclaration();
TemplateParameters *parseTemplateParameterList(); TemplateParameters *parseTemplateParameterList();
Dsymbol *parseMixin(); Dsymbol *parseMixin();

View file

@ -26,7 +26,7 @@ void browse(const char *url)
#endif #endif
#if linux #if linux || __FreeBSD__ || __sun&&__SVR4
#include <sys/types.h> #include <sys/types.h>
#include <sys/wait.h> #include <sys/wait.h>
@ -98,5 +98,3 @@ void browse(const char *url)
#endif #endif
#if __FreeBSD__
#endif

File diff suppressed because it is too large Load diff

View file

@ -18,6 +18,11 @@
#if _MSC_VER #if _MSC_VER
typedef __int64 longlong; typedef __int64 longlong;
typedef unsigned __int64 ulonglong; typedef unsigned __int64 ulonglong;
// According to VC 8.0 docs, long double is the same as double
#define strtold strtod
#define strtof strtod
#else #else
typedef long long longlong; typedef long long longlong;
typedef unsigned long long ulonglong; typedef unsigned long long ulonglong;
@ -33,6 +38,7 @@ struct Port
static double infinity; static double infinity;
static double dbl_max; static double dbl_max;
static double dbl_min; static double dbl_min;
static long double ldbl_max;
#if __GNUC__ #if __GNUC__
// These conflict with macros in math.h, should rename them // These conflict with macros in math.h, should rename them

View file

@ -7,6 +7,8 @@
// in artistic.txt, or the GNU General Public License in gnu.txt. // in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details. // See the included readme.txt for details.
#define POSIX (linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4)
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
#include <stdarg.h> #include <stdarg.h>
@ -329,17 +331,21 @@ char *FileName::combine(const char *path, const char *name)
namelen = strlen(name); namelen = strlen(name);
f = (char *)mem.malloc(pathlen + 1 + namelen + 1); f = (char *)mem.malloc(pathlen + 1 + namelen + 1);
memcpy(f, path, pathlen); memcpy(f, path, pathlen);
#if POSIX
if ( if (path[pathlen - 1] != '/')
path[pathlen - 1] != '/'
#if _WIN32
&& path[pathlen - 1] != '\\' && path[pathlen - 1] != ':'
#endif
)
{ f[pathlen] = '/'; { f[pathlen] = '/';
pathlen++; pathlen++;
} }
#elif _WIN32
if (path[pathlen - 1] != '\\' &&
path[pathlen - 1] != '/' &&
path[pathlen - 1] != ':')
{ f[pathlen] = '\\';
pathlen++;
}
#else
assert(0);
#endif
memcpy(f + pathlen, name, namelen + 1); memcpy(f + pathlen, name, namelen + 1);
return f; return f;
} }
@ -474,21 +480,27 @@ hash_t FileName::hashCode()
} }
int FileName::compare(Object *obj) int FileName::compare(Object *obj)
{
return compare(str, ((FileName *)obj)->str);
}
int FileName::compare(const char *name1, const char *name2)
{ {
#if _WIN32 #if _WIN32
return stricmp(str,((FileName *)obj)->str); return stricmp(name1, name2);
#else #else
return String::compare(obj); return strcmp(name1, name2);
#endif #endif
} }
int FileName::equals(Object *obj) int FileName::equals(Object *obj)
{ {
#if _WIN32 return compare(obj) == 0;
return stricmp(str,((FileName *)obj)->str) == 0; }
#else
return String::equals(obj); int FileName::equals(const char *name1, const char *name2)
#endif {
return compare(name1, name2) == 0;
} }
/************************************ /************************************
@ -497,13 +509,15 @@ int FileName::equals(Object *obj)
int FileName::absolute(const char *name) int FileName::absolute(const char *name)
{ {
return
#if _WIN32 #if _WIN32
(*name == '\\') || return (*name == '\\') ||
(*name == '/') || (*name == '/') ||
(*name && name[1] == ':') || (*name && name[1] == ':');
#elif POSIX
return (*name == '/');
#else
assert(0);
#endif #endif
(*name == '/');
} }
/******************************** /********************************
@ -523,13 +537,14 @@ char *FileName::ext(const char *str)
switch (*e) switch (*e)
{ case '.': { case '.':
return e + 1; return e + 1;
#if POSIX
case '/': case '/':
break; break;
#endif
#if _WIN32 #if _WIN32
case '\\': case '\\':
case ':': case ':':
case '/':
break; break;
#endif #endif
default: default:
@ -578,7 +593,10 @@ char *FileName::name(const char *str)
{ {
switch (*e) switch (*e)
{ {
#if POSIX
case '/':
return e + 1;
#endif
#if _WIN32 #if _WIN32
case '/': case '/':
case '\\': case '\\':
@ -591,9 +609,6 @@ char *FileName::name(const char *str)
*/ */
if (e == str + 1 || e == str + len - 1) if (e == str + 1 || e == str + len - 1)
return e + 1; return e + 1;
#else
case '/':
return e + 1;
#endif #endif
default: default:
if (e == str) if (e == str)
@ -623,13 +638,14 @@ char *FileName::path(const char *str)
if (n > str) if (n > str)
{ {
#if POSIX
if (n[-1] == '/') if (n[-1] == '/')
n--; n--;
#elif _WIN32
#if _WIN32
if (n[-1] == '\\' || n[-1] == '/') if (n[-1] == '\\' || n[-1] == '/')
n--; n--;
#else
assert(0);
#endif #endif
} }
pathlen = n - str; pathlen = n - str;
@ -643,7 +659,7 @@ char *FileName::path(const char *str)
* Replace filename portion of path. * Replace filename portion of path.
*/ */
char *FileName::replaceName(char *path, char *name) const char *FileName::replaceName(const char *path, const char *name)
{ char *f; { char *f;
char *n; char *n;
size_t pathlen; size_t pathlen;
@ -659,17 +675,21 @@ char *FileName::replaceName(char *path, char *name)
namelen = strlen(name); namelen = strlen(name);
f = (char *)mem.malloc(pathlen + 1 + namelen + 1); f = (char *)mem.malloc(pathlen + 1 + namelen + 1);
memcpy(f, path, pathlen); memcpy(f, path, pathlen);
#if POSIX
if ( if (path[pathlen - 1] != '/')
path[pathlen - 1] != '/'
#if _WIN32
&& path[pathlen - 1] != '\\' && path[pathlen - 1] != ':'
#endif
)
{ f[pathlen] = '/'; { f[pathlen] = '/';
pathlen++; pathlen++;
} }
#elif _WIN32
if (path[pathlen - 1] != '\\' &&
path[pathlen - 1] != '/' &&
path[pathlen - 1] != ':')
{ f[pathlen] = '\\';
pathlen++;
}
#else
assert(0);
#endif
memcpy(f + pathlen, name, namelen + 1); memcpy(f + pathlen, name, namelen + 1);
return f; return f;
} }
@ -736,9 +756,10 @@ int FileName::equalsExt(const char *ext)
return 0; return 0;
#if POSIX #if POSIX
return strcmp(e,ext) == 0; return strcmp(e,ext) == 0;
#endif #elif _WIN32
#if _WIN32
return stricmp(e,ext) == 0; return stricmp(e,ext) == 0;
#else
assert(0);
#endif #endif
} }
@ -752,9 +773,10 @@ void FileName::CopyTo(FileName *to)
#if _WIN32 #if _WIN32
file.touchtime = mem.malloc(sizeof(WIN32_FIND_DATAA)); // keep same file time file.touchtime = mem.malloc(sizeof(WIN32_FIND_DATAA)); // keep same file time
#endif #elif POSIX
#if POSIX
file.touchtime = mem.malloc(sizeof(struct stat)); // keep same file time file.touchtime = mem.malloc(sizeof(struct stat)); // keep same file time
#else
assert(0);
#endif #endif
file.readv(); file.readv();
file.name = to; file.name = to;
@ -803,8 +825,7 @@ int FileName::exists(const char *name)
if (S_ISDIR(st.st_mode)) if (S_ISDIR(st.st_mode))
return 2; return 2;
return 1; return 1;
#endif #elif _WIN32
#if _WIN32
DWORD dw; DWORD dw;
int result; int result;
@ -816,6 +837,8 @@ int FileName::exists(const char *name)
else else
result = 1; result = 1;
return result; return result;
#else
assert(0);
#endif #endif
} }
@ -974,8 +997,7 @@ err:
err1: err1:
result = 1; result = 1;
return result; return result;
#endif #elif _WIN32
#if _WIN32
DWORD size; DWORD size;
DWORD numread; DWORD numread;
HANDLE h; HANDLE h;
@ -1029,6 +1051,8 @@ err:
err1: err1:
result = 1; result = 1;
return result; return result;
#else
assert(0);
#endif #endif
} }
@ -1040,8 +1064,7 @@ int File::mmread()
{ {
#if POSIX #if POSIX
return read(); return read();
#endif #elif _WIN32
#if _WIN32
HANDLE hFile; HANDLE hFile;
HANDLE hFileMap; HANDLE hFileMap;
DWORD size; DWORD size;
@ -1081,6 +1104,8 @@ int File::mmread()
Lerr: Lerr:
return GetLastError(); // failure return GetLastError(); // failure
#else
assert(0);
#endif #endif
} }
@ -1124,8 +1149,7 @@ err2:
::remove(name); ::remove(name);
err: err:
return 1; return 1;
#endif #elif _WIN32
#if _WIN32
HANDLE h; HANDLE h;
DWORD numwritten; DWORD numwritten;
char *name; char *name;
@ -1154,6 +1178,8 @@ err2:
DeleteFileA(name); DeleteFileA(name);
err: err:
return 1; return 1;
#else
assert(0);
#endif #endif
} }
@ -1167,8 +1193,7 @@ int File::append()
{ {
#if POSIX #if POSIX
return 1; return 1;
#endif #elif _WIN32
#if _WIN32
HANDLE h; HANDLE h;
DWORD numwritten; DWORD numwritten;
char *name; char *name;
@ -1203,6 +1228,8 @@ err2:
CloseHandle(h); CloseHandle(h);
err: err:
return 1; return 1;
#else
assert(0);
#endif #endif
} }
@ -1247,8 +1274,7 @@ int File::exists()
{ {
#if POSIX #if POSIX
return 0; return 0;
#endif #elif _WIN32
#if _WIN32
DWORD dw; DWORD dw;
int result; int result;
char *name; char *name;
@ -1265,6 +1291,8 @@ int File::exists()
else else
result = 1; result = 1;
return result; return result;
#else
assert(0);
#endif #endif
} }
@ -1272,9 +1300,10 @@ void File::remove()
{ {
#if POSIX #if POSIX
::remove(this->name->toChars()); ::remove(this->name->toChars());
#endif #elif _WIN32
#if _WIN32
DeleteFileA(this->name->toChars()); DeleteFileA(this->name->toChars());
#else
assert(0);
#endif #endif
} }
@ -1287,8 +1316,7 @@ Array *File::match(FileName *n)
{ {
#if POSIX #if POSIX
return NULL; return NULL;
#endif #elif _WIN32
#if _WIN32
HANDLE h; HANDLE h;
WIN32_FIND_DATAA fileinfo; WIN32_FIND_DATAA fileinfo;
Array *a; Array *a;
@ -1318,6 +1346,8 @@ Array *File::match(FileName *n)
FindClose(h); FindClose(h);
} }
return a; return a;
#else
assert(0);
#endif #endif
} }
@ -1325,13 +1355,14 @@ int File::compareTime(File *f)
{ {
#if POSIX #if POSIX
return 0; return 0;
#endif #elif _WIN32
#if _WIN32
if (!touchtime) if (!touchtime)
stat(); stat();
if (!f->touchtime) if (!f->touchtime)
f->stat(); f->stat();
return CompareFileTime(&((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime, &((WIN32_FIND_DATAA *)f->touchtime)->ftLastWriteTime); return CompareFileTime(&((WIN32_FIND_DATAA *)touchtime)->ftLastWriteTime, &((WIN32_FIND_DATAA *)f->touchtime)->ftLastWriteTime);
#else
assert(0);
#endif #endif
} }
@ -1342,8 +1373,7 @@ void File::stat()
{ {
touchtime = mem.calloc(1, sizeof(struct stat)); touchtime = mem.calloc(1, sizeof(struct stat));
} }
#endif #elif _WIN32
#if _WIN32
HANDLE h; HANDLE h;
if (!touchtime) if (!touchtime)
@ -1355,6 +1385,8 @@ void File::stat()
{ {
FindClose(h); FindClose(h);
} }
#else
assert(0);
#endif #endif
} }
@ -1672,7 +1704,12 @@ void OutBuffer::vprintf(const char *format, va_list args)
psize = sizeof(buffer); psize = sizeof(buffer);
for (;;) for (;;)
{ {
#if POSIX || IN_LLVM #if _WIN32
count = _vsnprintf(p,psize,format,args);
if (count != -1)
break;
psize *= 2;
#elif POSIX
va_list va; va_list va;
va_copy(va, args); va_copy(va, args);
/* /*
@ -1692,11 +1729,8 @@ void OutBuffer::vprintf(const char *format, va_list args)
psize = count + 1; psize = count + 1;
else else
break; break;
#elif _WIN32 #else
count = _vsnprintf(p,psize,format,args); assert(0);
if (count != -1)
break;
psize *= 2;
#endif #endif
p = (char *) alloca(psize); // buffer too small, try again with larger size p = (char *) alloca(psize); // buffer too small, try again with larger size
} }
@ -1722,8 +1756,7 @@ void OutBuffer::vprintf(const wchar_t *format, va_list args)
if (count != -1) if (count != -1)
break; break;
psize *= 2; psize *= 2;
#endif #elif POSIX
#if POSIX
va_list va; va_list va;
va_copy(va, args); va_copy(va, args);
count = vsnwprintf(p,psize,format,va); count = vsnwprintf(p,psize,format,va);
@ -1735,6 +1768,8 @@ void OutBuffer::vprintf(const wchar_t *format, va_list args)
psize = count + 1; psize = count + 1;
else else
break; break;
#else
assert(0);
#endif #endif
p = (dchar *) alloca(psize * 2); // buffer too small, try again with larger size p = (dchar *) alloca(psize * 2); // buffer too small, try again with larger size
} }

View file

@ -128,7 +128,9 @@ struct FileName : String
FileName(char *path, char *name); FileName(char *path, char *name);
hash_t hashCode(); hash_t hashCode();
int equals(Object *obj); int equals(Object *obj);
static int equals(const char *name1, const char *name2);
int compare(Object *obj); int compare(Object *obj);
static int compare(const char *name1, const char *name2);
static int absolute(const char *name); static int absolute(const char *name);
static char *ext(const char *); static char *ext(const char *);
char *ext(); char *ext();
@ -136,7 +138,7 @@ struct FileName : String
static char *name(const char *); static char *name(const char *);
char *name(); char *name();
static char *path(const char *); static char *path(const char *);
static char *replaceName(char *path, char *name); static const char *replaceName(const char *path, const char *name);
static char *combine(const char *path, const char *name); static char *combine(const char *path, const char *name);
static Array *splitPath(const char *path); static Array *splitPath(const char *path);

View file

@ -12,7 +12,7 @@
#ifdef __DMC__ #ifdef __DMC__
#pragma once #pragma once
#endif /* __DMC__ */ #endif
struct Dsymbol; struct Dsymbol;
struct ScopeDsymbol; struct ScopeDsymbol;
@ -29,10 +29,15 @@ struct AggregateDeclaration;
struct AnonymousAggregateDeclaration; struct AnonymousAggregateDeclaration;
struct FuncDeclaration; struct FuncDeclaration;
struct DocComment; struct DocComment;
struct TemplateInstance;
#if IN_LLVM
struct EnclosingHandler; struct EnclosingHandler;
struct AnonDeclaration; struct AnonDeclaration;
#endif
#if __GNUC__ #if __GNUC__
// Requires a full definition for PROT and LINK
#include "dsymbol.h" // PROT #include "dsymbol.h" // PROT
#include "mars.h" // LINK #include "mars.h" // LINK
#else #else
@ -53,8 +58,8 @@ struct Scope
LabelStatement *slabel; // enclosing labelled statement LabelStatement *slabel; // enclosing labelled statement
SwitchStatement *sw; // enclosing switch statement SwitchStatement *sw; // enclosing switch statement
TryFinallyStatement *enclosingFinally; // enclosing try finally statement; set inside its finally block TryFinallyStatement *enclosingFinally; // enclosing try finally statement; set inside its finally block
TemplateInstance *tinst; // enclosing template instance
Statement *enclosingScopeExit; // enclosing statement that wants to do something on scope exit Statement *enclosingScopeExit; // enclosing statement that wants to do something on scope exit
TemplateInstance *tinst; // enclosing template instance
Statement *sbreak; // enclosing statement that supports "break" Statement *sbreak; // enclosing statement that supports "break"
Statement *scontinue; // enclosing statement that supports "continue" Statement *scontinue; // enclosing statement that supports "continue"
ForeachStatement *fes; // if nested function for ForeachStatement, this is it ForeachStatement *fes; // if nested function for ForeachStatement, this is it

View file

@ -1128,7 +1128,8 @@ Statement *ForStatement::semantic(Scope *sc)
sc->sbreak = this; sc->sbreak = this;
sc->scontinue = this; sc->scontinue = this;
body = body->semantic(sc); if (body)
body = body->semantic(sc);
sc->noctor--; sc->noctor--;
sc->pop(); sc->pop();

View file

@ -19,6 +19,7 @@
#include "scope.h" #include "scope.h"
#include "template.h" #include "template.h"
/********************************* AttribDeclaration ****************************/ /********************************* AttribDeclaration ****************************/
StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg) StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg)
@ -47,6 +48,10 @@ void StaticAssert::semantic(Scope *sc)
{ {
} }
#include "scope.h"
#include "template.h"
#include "declaration.h"
void StaticAssert::semantic2(Scope *sc) void StaticAssert::semantic2(Scope *sc)
{ {
Expression *e; Expression *e;
@ -67,11 +72,12 @@ void StaticAssert::semantic2(Scope *sc)
error("%s", buf.toChars()); error("%s", buf.toChars());
} }
else else
error("is false"); error("(%s) is false", exp->toChars());
if(sc->tinst) if(sc->tinst)
sc->tinst->printInstantiationTrace(); sc->tinst->printInstantiationTrace();
if (!global.gag) if (!global.gag) {
fatal(); fatal();
}
} }
else if (!e->isBool(TRUE)) else if (!e->isBool(TRUE))
{ {

View file

@ -427,7 +427,7 @@ void StructDeclaration::semantic(Scope *sc)
} }
else else
{ {
if (!vd->type->isZeroInit()) if (!vd->type->isZeroInit(loc))
{ {
zeroInit = 0; zeroInit = 0;
break; break;

View file

@ -1750,7 +1750,7 @@ MATCH TypeFunction::deduceType(Scope *sc, Type *tparam, TemplateParameters *para
/* See if 'A' of the template parameter matches 'A' /* See if 'A' of the template parameter matches 'A'
* of the type of the last function parameter. * of the type of the last function parameter.
*/ */
Argument *fparam = (Argument *)tp->parameters->data[nfparams - 1]; Argument *fparam = Argument::getNth(tp->parameters, nfparams - 1);
if (fparam->type->ty != Tident) if (fparam->type->ty != Tident)
goto L1; goto L1;
TypeIdentifier *tid = (TypeIdentifier *)fparam->type; TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
@ -3059,6 +3059,7 @@ TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
this->tiargs = NULL; this->tiargs = NULL;
this->tempdecl = NULL; this->tempdecl = NULL;
this->inst = NULL; this->inst = NULL;
this->tinst = NULL;
this->argsym = NULL; this->argsym = NULL;
this->aliasdecl = NULL; this->aliasdecl = NULL;
this->semanticdone = 0; this->semanticdone = 0;
@ -3072,7 +3073,6 @@ TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
#if IN_LLVM #if IN_LLVM
// LDC // LDC
this->emittedInModule = NULL; this->emittedInModule = NULL;
this->tinst = NULL;
this->tmodule = NULL; this->tmodule = NULL;
#endif #endif
} }
@ -3093,6 +3093,7 @@ TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *ti
this->tiargs = tiargs; this->tiargs = tiargs;
this->tempdecl = td; this->tempdecl = td;
this->inst = NULL; this->inst = NULL;
this->tinst = NULL;
this->argsym = NULL; this->argsym = NULL;
this->aliasdecl = NULL; this->aliasdecl = NULL;
this->semanticdone = 0; this->semanticdone = 0;
@ -3175,6 +3176,9 @@ void TemplateInstance::semantic(Scope *sc)
return; return;
} }
// get the enclosing template instance from the scope tinst
tinst = sc->tinst;
if (semanticdone != 0) if (semanticdone != 0)
{ {
error(loc, "recursive template expansion"); error(loc, "recursive template expansion");
@ -3420,6 +3424,14 @@ void TemplateInstance::semantic(Scope *sc)
__try __try
{ {
#endif #endif
static int nest;
//printf("%d\n", nest);
if (++nest > 500)
{
global.gag = 0; // ensure error message gets printed
error("recursive expansion");
fatal();
}
for (int i = 0; i < members->dim; i++) for (int i = 0; i < members->dim; i++)
{ {
Dsymbol *s = (Dsymbol *)members->data[i]; Dsymbol *s = (Dsymbol *)members->data[i];
@ -3432,6 +3444,7 @@ void TemplateInstance::semantic(Scope *sc)
//printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars()); //printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars());
sc2->module->runDeferredSemantic(); sc2->module->runDeferredSemantic();
} }
--nest;
#if WINDOWS_SEH #if WINDOWS_SEH
} }
__except (__ehfilter(GetExceptionInformation())) __except (__ehfilter(GetExceptionInformation()))
@ -3479,8 +3492,10 @@ void TemplateInstance::semantic(Scope *sc)
if (global.errors != errorsave) if (global.errors != errorsave)
{ {
error("error instantiating"); error("error instantiating");
if(tinst) if (tinst && !global.gag)
tinst->printInstantiationTrace(); { tinst->printInstantiationTrace();
fatal();
}
errors = 1; errors = 1;
if (global.gag) if (global.gag)
tempdecl->instances.remove(tempdecl_instance_idx); tempdecl->instances.remove(tempdecl_instance_idx);
@ -3985,7 +4000,7 @@ Identifier *TemplateInstance::genIdent()
Lsa: Lsa:
buf.writeByte('S'); buf.writeByte('S');
Declaration *d = sa->isDeclaration(); Declaration *d = sa->isDeclaration();
if (d && !d->type->deco) if (d && (!d->type || !d->type->deco))
error("forward reference of %s", d->toChars()); error("forward reference of %s", d->toChars());
else else
{ {
@ -4089,6 +4104,12 @@ void TemplateInstance::semantic3(Scope *sc)
#if IN_DMD #if IN_DMD
void TemplateInstance::printInstantiationTrace()
{
if (global.gag)
return;
}
void TemplateInstance::toObjFile(int multiobj) void TemplateInstance::toObjFile(int multiobj)
{ {
#if LOG #if LOG
@ -4201,6 +4222,8 @@ char *TemplateInstance::toChars()
return s; return s;
} }
#if IN_LLVM
void TemplateInstance::printInstantiationTrace() void TemplateInstance::printInstantiationTrace()
{ {
if(global.gag) if(global.gag)
@ -4238,6 +4261,8 @@ void TemplateInstance::printInstantiationTrace()
} }
} }
#endif
/* ======================== TemplateMixin ================================ */ /* ======================== TemplateMixin ================================ */
TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual, TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual,
@ -4508,11 +4533,24 @@ void TemplateMixin::semantic(Scope *sc)
Scope *sc2; Scope *sc2;
sc2 = scope->push(this); sc2 = scope->push(this);
sc2->offset = sc->offset; sc2->offset = sc->offset;
static int nest;
//printf("%d\n", nest);
if (++nest > 500)
{
global.gag = 0; // ensure error message gets printed
error("recursive expansion");
fatal();
}
for (int i = 0; i < members->dim; i++) for (int i = 0; i < members->dim; i++)
{ {
Dsymbol *s = (Dsymbol *)members->data[i]; Dsymbol *s = (Dsymbol *)members->data[i];
s->semantic(sc2); s->semantic(sc2);
} }
nest--;
sc->offset = sc2->offset; sc->offset = sc2->offset;
/* The problem is when to parse the initializer for a variable. /* The problem is when to parse the initializer for a variable.

View file

@ -277,6 +277,7 @@ struct TemplateInstance : ScopeDsymbol
TemplateDeclaration *tempdecl; // referenced by foo.bar.abc TemplateDeclaration *tempdecl; // referenced by foo.bar.abc
TemplateInstance *inst; // refer to existing instance TemplateInstance *inst; // refer to existing instance
TemplateInstance *tinst; // enclosing template instance
ScopeDsymbol *argsym; // argument symbol table ScopeDsymbol *argsym; // argument symbol table
AliasDeclaration *aliasdecl; // !=NULL if instance is an alias for its AliasDeclaration *aliasdecl; // !=NULL if instance is an alias for its
// sole member // sole member
@ -308,6 +309,7 @@ struct TemplateInstance : ScopeDsymbol
int oneMember(Dsymbol **ps); int oneMember(Dsymbol **ps);
char *toChars(); char *toChars();
char *mangle(); char *mangle();
void printInstantiationTrace();
#if IN_DMD #if IN_DMD
void toObjFile(int multiobj); // compile to .obj file void toObjFile(int multiobj); // compile to .obj file
@ -327,10 +329,8 @@ struct TemplateInstance : ScopeDsymbol
#if IN_LLVM #if IN_LLVM
// LDC // LDC
TemplateInstance *tinst; // enclosing template instance
Module* tmodule; // module from outermost enclosing template instantiation Module* tmodule; // module from outermost enclosing template instantiation
Module* emittedInModule; // which module this template instance has been emitted in Module* emittedInModule; // which module this template instance has been emitted in
void printInstantiationTrace();
void codegen(Ir*); void codegen(Ir*);
#endif #endif

View file

@ -806,6 +806,9 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
c = LLConstant::getNullValue(voidPtr); c = LLConstant::getNullValue(voidPtr);
inits.push_back(c); inits.push_back(c);
// typeinfo - since 1.045
inits.push_back(DtoTypeInfoOf(cd->type, true));
#if DMDV2 #if DMDV2
// xgetMembers // xgetMembers

View file

@ -1632,7 +1632,7 @@ DValue* NewExp::toElem(IRState* p)
LLValue* mem = DtoNew(newtype); LLValue* mem = DtoNew(newtype);
// init // init
TypeStruct* ts = (TypeStruct*)ntype; TypeStruct* ts = (TypeStruct*)ntype;
if (ts->isZeroInit()) { if (ts->isZeroInit(ts->sym->loc)) {
DtoAggrZeroInit(mem); DtoAggrZeroInit(mem);
} }
else { else {
@ -2662,7 +2662,6 @@ DValue* TypeExp::toElem(IRState *p)
#define STUB(x) DValue *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; } #define STUB(x) DValue *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; }
STUB(Expression); STUB(Expression);
STUB(TypeDotIdExp);
STUB(ScopeExp); STUB(ScopeExp);
STUB(TupleExp); STUB(TupleExp);

View file

@ -253,6 +253,20 @@ int TypeDArray::builtinTypeInfo()
#endif #endif
} }
int TypeClass::builtinTypeInfo()
{
/* This is statically put out with the ClassInfo, so
* claim it is built in so it isn't regenerated by each module.
*/
#if IN_DMD
return 1;
#elif IN_LLVM
// FIXME if I enable this, the way LDC does typeinfo will cause a bunch
// of linker errors to missing class typeinfo definitions.
return 0;
#endif
}
/* ========================================================================= */ /* ========================================================================= */
////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////

View file

@ -159,9 +159,11 @@ class ClassInfo : Object
// 2: // has no possible pointers into GC memory // 2: // has no possible pointers into GC memory
// 4: // has offTi[] member // 4: // has offTi[] member
// 8: // has constructors // 8: // has constructors
// 32: // has typeinfo
void* deallocator; void* deallocator;
OffsetTypeInfo[] offTi; OffsetTypeInfo[] offTi;
void* defaultConstructor; // default Constructor void* defaultConstructor; // default Constructor
TypeInfo typeinfo;
/** /**
* Search all modules for ClassInfo corresponding to classname. * Search all modules for ClassInfo corresponding to classname.