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
#define CLASSINFO_SIZE (0x3C+16) // value of ClassInfo.size
#define CLASSINFO_SIZE (0x3C+16+4) // value of ClassInfo.size
#else
#define CLASSINFO_SIZE (0x3C+12) // value of ClassInfo.size
#define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
#endif
struct ClassDeclaration : AggregateDeclaration

View file

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

View file

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

View file

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

View file

@ -19,6 +19,7 @@
#include "rmem.h"
#include "root.h"
#include "port.h"
#include "mtype.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
#if __FreeBSD__
#define fmodl fmod // hack for now, fix later
#endif
#define LOG 0
Expression *expType(Type *type, Expression *e)
@ -460,7 +465,7 @@ Expression *Div(Type *type, Expression *e1, Expression *e2)
n2 = e2->toInteger();
if (n2 == 0)
{ e2->error("divide by 0");
e2 = new IntegerExp(0, 1, e2->type);
e2 = new IntegerExp(loc, 1, e2->type);
n2 = 1;
}
if (e1->type->isunsigned() || e2->type->isunsigned())
@ -531,7 +536,7 @@ Expression *Mod(Type *type, Expression *e1, Expression *e2)
n2 = e2->toInteger();
if (n2 == 0)
{ e2->error("divide by 0");
e2 = new IntegerExp(0, 1, e2->type);
e2 = new IntegerExp(loc, 1, e2->type);
n2 = 1;
}
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 *e;
Loc loc = e1->loc;
e = new IntegerExp(loc, e1->toInteger() & e2->toInteger(), type);
{
Expression *e;
e = new IntegerExp(e1->loc, e1->toInteger() & e2->toInteger(), type);
return e;
}
Expression *Or(Type *type, Expression *e1, Expression *e2)
{ Expression *e;
Loc loc = e1->loc;
e = new IntegerExp(loc, e1->toInteger() | e2->toInteger(), type);
e = new IntegerExp(e1->loc, e1->toInteger() | e2->toInteger(), type);
return e;
}
Expression *Xor(Type *type, Expression *e1, Expression *e2)
{ Expression *e;
Loc loc = e1->loc;
e = new IntegerExp(loc, e1->toInteger() ^ e2->toInteger(), type);
e = new IntegerExp(e1->loc, e1->toInteger() ^ e2->toInteger(), type);
return e;
}
@ -831,7 +831,7 @@ Expression *Equal(enum TOK op, Type *type, Expression *e1, Expression *e2)
#if __DMC__
cmp = (r1 == r2);
#else
if (isnan(r1) || isnan(r2)) // if unordered
if (Port::isNan(r1) || Port::isNan(r2)) // if unordered
{
cmp = 0;
}
@ -926,11 +926,7 @@ Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2)
}
#else
// Don't rely on compiler, handle NAN arguments separately
#if IN_GCC
if (real_isnan(&r1) || real_isnan(&r2)) // if unordered
#else
if (isnan(r1) || isnan(r2)) // if unordered
#endif
if (Port::isNan(r1) || Port::isNan(r2)) // if unordered
{
switch (op)
{
@ -1313,6 +1309,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
Type *t2 = e2->type->toBasetype();
//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))
{ e = e2;
@ -1498,7 +1495,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
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);
}
else
@ -1515,7 +1512,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
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);
}
else

View file

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

View file

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

View file

@ -99,7 +99,6 @@ void initPrecedence()
precedence[TOKnull] = PREC_primary;
precedence[TOKstring] = PREC_primary;
precedence[TOKarrayliteral] = PREC_primary;
precedence[TOKtypedot] = PREC_primary;
precedence[TOKtypeid] = PREC_primary;
precedence[TOKis] = PREC_primary;
precedence[TOKassert] = PREC_primary;
@ -1558,6 +1557,22 @@ void IntegerExp::toMangleBuffer(OutBuffer *buf)
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(Loc loc, real_t value, Type *type)
@ -1940,7 +1955,7 @@ Expression *IdentifierExp::semantic(Scope *sc)
{ Type *t = withsym->withstate->wthis->type;
if (t->ty == Tpointer)
t = ((TypePointer *)t)->next;
e = new TypeDotIdExp(loc, t, ident);
e = typeDotIdExp(loc, t, ident);
}
}
else
@ -3288,38 +3303,11 @@ void StructLiteralExp::toMangleBuffer(OutBuffer *buf)
* cast(foo).size
*/
TypeDotIdExp::TypeDotIdExp(Loc loc, Type *type, Identifier *ident)
: Expression(loc, TOKtypedot, sizeof(TypeDotIdExp))
Expression *typeDotIdExp(Loc loc, Type *type, Identifier *ident)
{
this->type = type;
this->ident = ident;
return new DotIdExp(loc, new TypeExp(loc, type), 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)
{
e = new TypeDotIdExp(loc, cd->type, ident);
e = typeDotIdExp(loc, cd->type, ident);
return e->semantic(sc);
}
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);
}
}
@ -5273,7 +5261,7 @@ Expression *DotIdExp::semantic(Scope *sc)
{
if (e1->op == TOKthis)
{
e = new TypeDotIdExp(loc, sd->type, ident);
e = typeDotIdExp(loc, sd->type, ident);
return e->semantic(sc);
}
}
@ -5321,6 +5309,18 @@ Expression *DotIdExp::semantic(Scope *sc)
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
{
ScopeExp *ie = (ScopeExp *)eright;
@ -5607,7 +5607,8 @@ Expression *DotVarExp::semantic(Scope *sc)
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);
if (!sc->noaccesscheck)
accessCheck(loc, sc, e1, var);
@ -5802,10 +5803,11 @@ Expression *DotTemplateInstanceExp::semantic(Scope *sc)
id = ti->name;
s2 = s->search(loc, id, 0);
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
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;
}
s = s2;
@ -7264,7 +7266,7 @@ Expression *SliceExp::semantic(Scope *sc)
else
{
error("string slice [%ju .. %ju] is out of bounds", i1, i2);
e = e1;
e = new IntegerExp(0);
}
return e;
}
@ -9275,8 +9277,15 @@ Expression *CmpExp::semantic(Scope *sc)
e = op_overload(sc);
if (e)
{
e = new CmpExp(op, loc, e, new IntegerExp(loc, 0, Type::tint32));
if (!e->type->isscalar() && e->type->equals(e1->type))
{
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;
}

View file

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

View file

@ -1,4 +1,3 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
@ -145,6 +144,18 @@ void FuncDeclaration::semantic(Scope *sc)
printf("type: %p, %s\n", type, type->toChars());
#endif
if (semanticRun && isFuncLiteralDeclaration())
{
/* Member functions that have return types that are
* forward references can have semantic() run more than
* once on them.
* See test\interface2.d, test20
*/
return;
}
assert(semanticRun <= 1);
semanticRun = 1;
if (type->nextOf())
type = type->semantic(loc, sc);
//type->print();
@ -659,9 +670,9 @@ void FuncDeclaration::semantic3(Scope *sc)
//printf("\tlinkage = %d\n", sc->linkage);
//printf(" sc->incontract = %d\n", sc->incontract);
if (semanticRun)
if (semanticRun >= 3)
return;
semanticRun = 1;
semanticRun = 3;
if (!type || type->ty != Tfunction)
return;
@ -723,7 +734,7 @@ void FuncDeclaration::semantic3(Scope *sc)
{
assert(!isNested()); // can't be both member and nested
assert(ad->handle);
v = new ThisDeclaration(ad->handle);
v = new ThisDeclaration(loc, ad->handle);
v->storage_class |= STCparameter | STCin;
v->semantic(sc2);
if (!sc2->insert(v))
@ -738,7 +749,7 @@ void FuncDeclaration::semantic3(Scope *sc)
* enclosing function's stack frame.
* Note that nested functions and member functions are disjoint.
*/
VarDeclaration *v = new ThisDeclaration(Type::tvoid->pointerTo());
VarDeclaration *v = new ThisDeclaration(loc, Type::tvoid->pointerTo());
v->storage_class |= STCparameter | STCin;
v->semantic(sc2);
if (!sc2->insert(v))
@ -1352,7 +1363,7 @@ void FuncDeclaration::semantic3(Scope *sc)
sc2->callSuper = 0;
sc2->pop();
}
semanticRun = 2;
semanticRun = 4;
}
void FuncDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
@ -2432,7 +2443,7 @@ int CtorDeclaration::addPreInvariant()
int CtorDeclaration::addPostInvariant()
{
return (vthis && global.params.useInvariants);
return (isThis() && vthis && global.params.useInvariants);
}
@ -2495,7 +2506,7 @@ int DtorDeclaration::overloadInsert(Dsymbol *s)
int DtorDeclaration::addPreInvariant()
{
return (vthis && global.params.useInvariants);
return (isThis() && vthis && global.params.useInvariants);
}
int DtorDeclaration::addPostInvariant()

View file

@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@ -568,7 +568,20 @@ Type *ExpInitializer::inferType(Scope *sc)
//printf("ExpInitializer::inferType() %s\n", toChars());
exp = exp->semantic(sc);
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()

View file

@ -1,5 +1,5 @@
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@ -929,8 +929,11 @@ Statement *DefaultStatement::inlineScan(InlineScanState *iss)
Statement *ReturnStatement::inlineScan(InlineScanState *iss)
{
//printf("ReturnStatement::inlineScan()\n");
if (exp)
{
exp = exp->inlineScan(iss);
}
return this;
}
@ -1234,7 +1237,7 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan)
if (needThis() && !hasthis)
return 0;
if (inlineNest || (!semanticRun && !hdrscan))
if (inlineNest || (semanticRun < 3 && !hdrscan))
{
#if CANINLINE_LOG
printf("\t1: no, inlineNest = %d, semanticRun = %d\n", inlineNest, semanticRun);
@ -1246,13 +1249,13 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan)
{
case ILSyes:
#if CANINLINE_LOG
printf("\tyes\n");
printf("\t1: yes %s\n", toChars());
#endif
return 1;
case ILSno:
#if CANINLINE_LOG
printf("\t2: no\n");
printf("\t1: no %s\n", toChars());
#endif
return 0;
@ -1338,7 +1341,7 @@ Lyes:
if (!hdrscan) // Don't modify inlineStatus for header content scan
inlineStatus = ILSyes;
#if CANINLINE_LOG
printf("\tyes\n");
printf("\t2: yes %s\n", toChars());
#endif
return 1;
@ -1346,7 +1349,7 @@ Lno:
if (!hdrscan) // Don't modify inlineStatus for header content scan
inlineStatus = ILSno;
#if CANINLINE_LOG
printf("\tno\n");
printf("\t2: no %s\n", toChars());
#endif
return 0;
}

View file

@ -69,7 +69,7 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
else if (ident == Id::aaValues)
return interpret_aaValues(istate, arguments);
if (cantInterpret || semanticRun == 1)
if (cantInterpret || semanticRun == 3)
return NULL;
if (needThis() || isNested() || !fbody)
@ -77,13 +77,13 @@ Expression *FuncDeclaration::interpret(InterState *istate, Expressions *argument
return NULL;
}
if (semanticRun == 0 && scope)
if (semanticRun < 3 && scope)
{
semantic3(scope);
if (global.errors) // if errors compiling this function
return NULL;
}
if (semanticRun < 2)
if (semanticRun < 4)
return NULL;
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());
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;
if (vie->op == TOKvar)
{

View file

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

View file

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

View file

@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@ -24,7 +24,7 @@
#include "id.h"
#include "module.h"
#if TARGET_LINUX || TARGET_OSX
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
char *cpp_mangle(Dsymbol *s);
#endif
@ -117,7 +117,7 @@ char *Declaration::mangle()
return ident->toChars();
case LINKcpp:
#if DMDV2 && (TARGET_LINUX || TARGET_OSX)
#if DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS)
return cpp_mangle(this);
#else
// Windows C++ mangling is done by C++ back end
@ -220,7 +220,9 @@ char *TemplateInstance::mangle()
printf("\n");
#endif
id = ident ? ident->toChars() : toChars();
if (tempdecl->parent)
if (!tempdecl)
error("is not defined");
else if (tempdecl->parent)
{
char *p = tempdecl->parent->mangle();
if (p[0] == '_' && p[1] == 'D')

View file

@ -36,6 +36,8 @@ Macros defined by the compiler, not the code:
_WIN64 Windows for AMD64
linux Linux
__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
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_LINUX Covers 32 and 64 bit linux
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
to generate 32 and 64 bit code from the same compiler binary.
Target object module format:
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
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 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.
*/
@ -90,7 +95,7 @@ the target object file format:
#define OMFOBJ 1
#endif
#if TARGET_LINUX
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
#ifndef ELFOBJ
#define ELFOBJ 1
#endif

View file

@ -72,11 +72,16 @@ FuncDeclaration *hasThis(Scope *sc);
*/
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
int REALSIZE = 16;
int REALPAD = 6;
int REALALIGNSIZE = 16;
#elif TARGET_LINUX || TARGET_FREEBSD
#elif TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
int REALSIZE = 12;
int REALPAD = 2;
int REALALIGNSIZE = 4;
@ -85,6 +90,7 @@ int REALSIZE = 10;
int REALPAD = 0;
int REALALIGNSIZE = 2;
#endif
int Tsize_t = Tuns32;
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)
{
if (mod != this->mod)
{ char *p;
{ const char *p;
switch (this->mod)
{
@ -432,20 +438,18 @@ void Type::toCBuffer3(OutBuffer *buf, HdrGenState *hgs, int mod)
*/
Type *Type::merge()
{ Type *t;
{
//printf("merge(%s)\n", toChars());
t = this;
Type *t = this;
assert(t);
if (!deco)
{
OutBuffer buf;
StringValue *sv;
if (next)
next = next->merge();
OutBuffer buf;
toDecoBuffer(&buf, false);
sv = stringtable.update((char *)buf.data, buf.offset);
StringValue *sv = stringtable.update((char *)buf.data, buf.offset);
if (sv->ptrvalue)
{ t = (Type *) sv->ptrvalue;
assert(t->deco);
@ -477,6 +481,28 @@ Type *Type::merge()
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()
{
return FALSE;
@ -563,7 +589,7 @@ Expression *Type::defaultInit(Loc loc)
return NULL;
}
int Type::isZeroInit()
int Type::isZeroInit(Loc loc)
{
return 0; // assume not
}
@ -625,9 +651,14 @@ Expression *Type::getProperty(Loc loc, Identifier *ident)
e = defaultInit(loc);
}
else if (ident == Id::mangleof)
{
assert(deco);
e = new StringExp(loc, deco, strlen(deco), 'c');
{ const char *s;
if (!deco)
{ 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;
e = e->semantic(&sc);
}
@ -1049,6 +1080,17 @@ unsigned TypeBasic::alignsize()
if (ty == Tvoid)
return 1;
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 Tcomplex80:
case Timaginary80:
case Tfloat80: fvalue = LDBL_MAX; goto Lfvalue;
case Tfloat80: fvalue = Port::ldbl_max; goto Lfvalue;
}
}
else if (ident == Id::min)
@ -1402,7 +1444,7 @@ Expression *TypeBasic::defaultInit(Loc loc)
return new IntegerExp(loc, value, this);
}
int TypeBasic::isZeroInit()
int TypeBasic::isZeroInit(Loc loc)
{
switch (ty)
{
@ -2050,9 +2092,9 @@ Expression *TypeSArray::defaultInit(Loc 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;
}
int TypeDArray::isZeroInit()
int TypeDArray::isZeroInit(Loc loc)
{
return 1;
}
@ -2481,7 +2523,7 @@ Expression *TypeAArray::defaultInit(Loc loc)
return e;
}
int TypeAArray::isZeroInit()
int TypeAArray::isZeroInit(Loc loc)
{
return TRUE;
}
@ -2594,7 +2636,7 @@ Expression *TypePointer::defaultInit(Loc loc)
return e;
}
int TypePointer::isZeroInit()
int TypePointer::isZeroInit(Loc loc)
{
return 1;
}
@ -2660,7 +2702,7 @@ Expression *TypeReference::defaultInit(Loc loc)
return e;
}
int TypeReference::isZeroInit()
int TypeReference::isZeroInit(Loc loc)
{
return 1;
}
@ -2841,7 +2883,7 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, bool mangle)
void TypeFunction::toCBuffer(OutBuffer *buf, Identifier *ident, HdrGenState *hgs)
{
char *p = NULL;
const char *p = NULL;
if (inuse)
{ 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)
{
char *p = NULL;
const char *p = NULL;
if (inuse)
{ inuse = 2; // flag error to caller
@ -3223,7 +3265,7 @@ Expression *TypeDelegate::defaultInit(Loc loc)
return e;
}
int TypeDelegate::isZeroInit()
int TypeDelegate::isZeroInit(Loc loc)
{
return 1;
}
@ -3865,6 +3907,8 @@ Type *TypeTypeof::semantic(Loc loc, Scope *sc)
error(loc, "expression (%s) has no type", exp->toChars());
goto Lerr;
}
if (t->ty == Ttypeof)
error(loc, "forward reference to %s", toChars());
}
if (idents.dim)
@ -3966,7 +4010,7 @@ Type *TypeEnum::toBasetype()
printf("2: ");
#endif
error(sym->loc, "enum %s is forward referenced", sym->toChars());
return tint32;
return terror;
}
return sym->memtype->toBasetype();
}
@ -4020,8 +4064,8 @@ Expression *TypeEnum::dotExp(Scope *sc, Expression *e, Identifier *ident)
return em;
Lfwd:
error(e->loc, "forward reference of %s.%s", toChars(), ident->toChars());
return new IntegerExp(0, 0, this);
error(e->loc, "forward reference of enum %s.%s", toChars(), ident->toChars());
return new IntegerExp(0, 0, Type::terror);
}
Expression *TypeEnum::getProperty(Loc loc, Identifier *ident)
@ -4109,7 +4153,7 @@ Expression *TypeEnum::defaultInit(Loc loc)
return e;
}
int TypeEnum::isZeroInit()
int TypeEnum::isZeroInit(Loc loc)
{
return (sym->defaultval == 0);
}
@ -4300,7 +4344,7 @@ Expression *TypeTypedef::defaultInit(Loc loc)
return e;
}
int TypeTypedef::isZeroInit()
int TypeTypedef::isZeroInit(Loc loc)
{
if (sym->init)
{
@ -4317,7 +4361,7 @@ int TypeTypedef::isZeroInit()
sym->basetype = Type::terror;
}
sym->inuse = 1;
int result = sym->basetype->isZeroInit();
int result = sym->basetype->isZeroInit(loc);
sym->inuse = 0;
return result;
}
@ -4613,7 +4657,7 @@ Expression *TypeStruct::defaultInit(Loc loc)
return new VarExp(sym->loc, d);
}
int TypeStruct::isZeroInit()
int TypeStruct::isZeroInit(Loc loc)
{
return sym->zeroInit;
}
@ -5074,7 +5118,7 @@ Expression *TypeClass::defaultInit(Loc loc)
return e;
}
int TypeClass::isZeroInit()
int TypeClass::isZeroInit(Loc loc)
{
return 1;
}

View file

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

View file

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

View file

@ -532,6 +532,10 @@ Array *Parser::parseBlock()
nextToken();
break;
case TOKeof:
error("declaration expected following attribute, not EOF");
break;
case TOKlcurly:
nextToken();
a = parseDeclDefs(0);
@ -4255,7 +4259,7 @@ Expression *Parser::parsePrimaryExp()
{ error("found '%s' when expecting identifier following '%s.'", token.toChars(), t->toChars());
goto Lerr;
}
e = new TypeDotIdExp(loc, t, token.ident);
e = typeDotIdExp(loc, t, token.ident);
nextToken();
break;
@ -4760,7 +4764,7 @@ Expression *Parser::parseUnaryExp()
{ error("Identifier expected following (type).");
return NULL;
}
e = new TypeDotIdExp(loc, t, token.ident);
e = typeDotIdExp(loc, t, token.ident);
nextToken();
e = parsePostExp(e);
}

View file

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

View file

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

View file

@ -5,7 +5,6 @@
// http://www.digitalmars.com
#include "port.h"
#if __DMC__
#include <math.h>
#include <float.h>
@ -18,6 +17,7 @@ double Port::nan = NAN;
double Port::infinity = INFINITY;
double Port::dbl_max = DBL_MAX;
double Port::dbl_min = DBL_MIN;
long double Port::ldbl_max = LDBL_MAX;
int Port::isNan(double r)
{
@ -123,6 +123,7 @@ char *Port::strupr(char *s)
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
#include <limits> // for std::numeric_limits
static unsigned long nanarray[2]= { 0xFFFFFFFF, 0x7FFFFFFF };
//static unsigned long nanarray[2] = {0,0x7FF80000 };
@ -134,6 +135,7 @@ double Port::infinity = 1 / zero;
double Port::dbl_max = DBL_MAX;
double Port::dbl_min = DBL_MIN;
long double Port::ldbl_max = LDBL_MAX;
struct PortInitializer
{
@ -326,12 +328,14 @@ char *Port::strupr(char *s)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <float.h>
static double zero = 0;
double Port::nan = NAN;
double Port::infinity = 1 / zero;
double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
long double Port::ldbl_max = LDBL_MAX;
struct PortInitializer
{
@ -350,6 +354,13 @@ PortInitializer::PortInitializer()
if (signbit(foo)) // signbit sometimes, not always, set
foo = -foo; // turn off sign bit
Port::nan = foo;
#if __FreeBSD__
// LDBL_MAX comes out as infinity. Fix.
static unsigned char x[sizeof(long double)] =
{ 0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFF,0xFE,0x7F };
Port::ldbl_max = *(long double *)&x[0];
#endif
}
#undef isnan
@ -466,7 +477,7 @@ char *Port::strupr(char *s)
#endif
#if defined (__SVR4) && defined (__sun)
#if __sun&&__SVR4
#define __C99FEATURES__ 1 // Needed on Solaris for NaN and more
#include <math.h>
@ -476,12 +487,15 @@ char *Port::strupr(char *s)
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <float.h>
#include <ieeefp.h>
static double zero = 0;
double Port::nan = NAN;
double Port::infinity = 1 / zero;
double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
long double Port::ldbl_max = LDBL_MAX;
struct PortInitializer
{
@ -502,23 +516,14 @@ PortInitializer::PortInitializer()
Port::nan = foo;
}
#undef isnan
int Port::isNan(double r)
{
#if __APPLE__
return __inline_isnan(r);
#else
return ::isnan(r);
#endif
return isnan(r);
}
int Port::isNan(long double r)
{
#if __APPLE__
return __inline_isnan(r);
#else
return ::isnan(r);
#endif
return isnan(r);
}
int Port::isSignallingNan(double r)
@ -540,13 +545,12 @@ int Port::isSignallingNan(long double r)
#undef isfinite
int Port::isFinite(double r)
{
return ::finite(r);
return finite(r);
}
#undef isinf
int Port::isInfinity(double r)
{
return ::isinf(r);
return isinf(r);
}
#undef signbit
@ -629,6 +633,7 @@ double Port::nan = NAN;
double Port::infinity = 1 / zero;
double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
long double Port::ldbl_max = LDBL_MAX;
#include "d-gcc-real.h"
extern "C" bool real_isnan (const real_t *);

View file

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

View file

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

View file

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

View file

@ -19,6 +19,7 @@
#include "scope.h"
#include "template.h"
/********************************* AttribDeclaration ****************************/
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)
{
Expression *e;
@ -67,12 +72,13 @@ void StaticAssert::semantic2(Scope *sc)
error("%s", buf.toChars());
}
else
error("is false");
error("(%s) is false", exp->toChars());
if(sc->tinst)
sc->tinst->printInstantiationTrace();
if (!global.gag)
if (!global.gag) {
fatal();
}
}
else if (!e->isBool(TRUE))
{
error("(%s) is not evaluatable at compile time", exp->toChars());

View file

@ -427,7 +427,7 @@ void StructDeclaration::semantic(Scope *sc)
}
else
{
if (!vd->type->isZeroInit())
if (!vd->type->isZeroInit(loc))
{
zeroInit = 0;
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'
* 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)
goto L1;
TypeIdentifier *tid = (TypeIdentifier *)fparam->type;
@ -3059,6 +3059,7 @@ TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
this->tiargs = NULL;
this->tempdecl = NULL;
this->inst = NULL;
this->tinst = NULL;
this->argsym = NULL;
this->aliasdecl = NULL;
this->semanticdone = 0;
@ -3072,7 +3073,6 @@ TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
#if IN_LLVM
// LDC
this->emittedInModule = NULL;
this->tinst = NULL;
this->tmodule = NULL;
#endif
}
@ -3093,6 +3093,7 @@ TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *ti
this->tiargs = tiargs;
this->tempdecl = td;
this->inst = NULL;
this->tinst = NULL;
this->argsym = NULL;
this->aliasdecl = NULL;
this->semanticdone = 0;
@ -3175,6 +3176,9 @@ void TemplateInstance::semantic(Scope *sc)
return;
}
// get the enclosing template instance from the scope tinst
tinst = sc->tinst;
if (semanticdone != 0)
{
error(loc, "recursive template expansion");
@ -3420,6 +3424,14 @@ void TemplateInstance::semantic(Scope *sc)
__try
{
#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++)
{
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());
sc2->module->runDeferredSemantic();
}
--nest;
#if WINDOWS_SEH
}
__except (__ehfilter(GetExceptionInformation()))
@ -3479,8 +3492,10 @@ void TemplateInstance::semantic(Scope *sc)
if (global.errors != errorsave)
{
error("error instantiating");
if(tinst)
tinst->printInstantiationTrace();
if (tinst && !global.gag)
{ tinst->printInstantiationTrace();
fatal();
}
errors = 1;
if (global.gag)
tempdecl->instances.remove(tempdecl_instance_idx);
@ -3985,7 +4000,7 @@ Identifier *TemplateInstance::genIdent()
Lsa:
buf.writeByte('S');
Declaration *d = sa->isDeclaration();
if (d && !d->type->deco)
if (d && (!d->type || !d->type->deco))
error("forward reference of %s", d->toChars());
else
{
@ -4089,6 +4104,12 @@ void TemplateInstance::semantic3(Scope *sc)
#if IN_DMD
void TemplateInstance::printInstantiationTrace()
{
if (global.gag)
return;
}
void TemplateInstance::toObjFile(int multiobj)
{
#if LOG
@ -4201,6 +4222,8 @@ char *TemplateInstance::toChars()
return s;
}
#if IN_LLVM
void TemplateInstance::printInstantiationTrace()
{
if(global.gag)
@ -4238,6 +4261,8 @@ void TemplateInstance::printInstantiationTrace()
}
}
#endif
/* ======================== TemplateMixin ================================ */
TemplateMixin::TemplateMixin(Loc loc, Identifier *ident, Type *tqual,
@ -4508,11 +4533,24 @@ void TemplateMixin::semantic(Scope *sc)
Scope *sc2;
sc2 = scope->push(this);
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++)
{
Dsymbol *s = (Dsymbol *)members->data[i];
s->semantic(sc2);
}
nest--;
sc->offset = sc2->offset;
/* 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
TemplateInstance *inst; // refer to existing instance
TemplateInstance *tinst; // enclosing template instance
ScopeDsymbol *argsym; // argument symbol table
AliasDeclaration *aliasdecl; // !=NULL if instance is an alias for its
// sole member
@ -308,6 +309,7 @@ struct TemplateInstance : ScopeDsymbol
int oneMember(Dsymbol **ps);
char *toChars();
char *mangle();
void printInstantiationTrace();
#if IN_DMD
void toObjFile(int multiobj); // compile to .obj file
@ -327,10 +329,8 @@ struct TemplateInstance : ScopeDsymbol
#if IN_LLVM
// LDC
TemplateInstance *tinst; // enclosing template instance
Module* tmodule; // module from outermost enclosing template instantiation
Module* emittedInModule; // which module this template instance has been emitted in
void printInstantiationTrace();
void codegen(Ir*);
#endif

View file

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

View file

@ -1632,7 +1632,7 @@ DValue* NewExp::toElem(IRState* p)
LLValue* mem = DtoNew(newtype);
// init
TypeStruct* ts = (TypeStruct*)ntype;
if (ts->isZeroInit()) {
if (ts->isZeroInit(ts->sym->loc)) {
DtoAggrZeroInit(mem);
}
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; }
STUB(Expression);
STUB(TypeDotIdExp);
STUB(ScopeExp);
STUB(TupleExp);

View file

@ -253,6 +253,20 @@ int TypeDArray::builtinTypeInfo()
#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
// 4: // has offTi[] member
// 8: // has constructors
// 32: // has typeinfo
void* deallocator;
OffsetTypeInfo[] offTi;
void* defaultConstructor; // default Constructor
TypeInfo typeinfo;
/**
* Search all modules for ClassInfo corresponding to classname.