mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-06 19:06:02 +03:00
Merged DMD 1.045 !!!
This commit is contained in:
parent
9beb33770f
commit
e8780d50e8
37 changed files with 9631 additions and 9388 deletions
|
@ -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
|
||||
|
|
|
@ -1511,6 +1511,9 @@ Expression *BinExp::typeCombine(Scope *sc)
|
|||
{
|
||||
Lincompatible:
|
||||
incompatibleTypes();
|
||||
type = Type::terror;
|
||||
e1 = new ErrorExp();
|
||||
e2 = new ErrorExp();
|
||||
}
|
||||
Lret:
|
||||
if (!type)
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -137,6 +137,7 @@ void VersionCondition::checkPredefined(Loc loc, const char *ident)
|
|||
"Posix",
|
||||
#endif
|
||||
"OSX", "FreeBSD",
|
||||
"Solaris",
|
||||
"LittleEndian", "BigEndian",
|
||||
"all",
|
||||
"none",
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
{
|
||||
|
|
27
dmd/func.c
27
dmd/func.c
|
@ -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()
|
||||
|
|
17
dmd/init.c
17
dmd/init.c
|
@ -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()
|
||||
|
|
15
dmd/inline.c
15
dmd/inline.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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";
|
||||
|
|
|
@ -51,7 +51,7 @@ enum TOK
|
|||
TOKnull, TOKassert,
|
||||
TOKtrue, TOKfalse,
|
||||
TOKarray, TOKcall,
|
||||
TOKaddress, TOKtypedot,
|
||||
TOKaddress,
|
||||
TOKtype, TOKthrow,
|
||||
TOKnew, TOKdelete,
|
||||
TOKstar, TOKsymoff,
|
||||
|
|
10
dmd/mangle.c
10
dmd/mangle.c
|
@ -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')
|
||||
|
|
11
dmd/mars.h
11
dmd/mars.h
|
@ -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
|
||||
|
|
108
dmd/mtype.c
108
dmd/mtype.c
|
@ -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;
|
||||
}
|
||||
|
|
33
dmd/mtype.h
33
dmd/mtype.h
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 *);
|
||||
|
|
|
@ -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
|
||||
|
|
173
dmd/root/root.c
173
dmd/root/root.c
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1128,6 +1128,7 @@ Statement *ForStatement::semantic(Scope *sc)
|
|||
|
||||
sc->sbreak = this;
|
||||
sc->scontinue = this;
|
||||
if (body)
|
||||
body = body->semantic(sc);
|
||||
sc->noctor--;
|
||||
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -427,7 +427,7 @@ void StructDeclaration::semantic(Scope *sc)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (!vd->type->isZeroInit())
|
||||
if (!vd->type->isZeroInit(loc))
|
||||
{
|
||||
zeroInit = 0;
|
||||
break;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -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.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue