fixes #432 :: apply DMDFE 1.063; thanks SiegeLord

This commit is contained in:
Moritz Warning
2010-09-27 00:07:03 +02:00
parent c4e255206a
commit f654235139
21 changed files with 463 additions and 168 deletions
+5
View File
@@ -620,6 +620,8 @@ Dsymbol *AliasDeclaration::toAlias()
{ error("recursive alias declaration");
aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL);
}
else if (!aliassym && scope)
semantic(scope);
Dsymbol *s = aliassym ? aliassym->toAlias() : this;
return s;
}
@@ -1356,6 +1358,9 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
#endif
#endif
//printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
// __dollar creates problems because it isn't a real variable Bugzilla 3326
if (ident == Id::dollar)
::error(loc, "cannnot use $ inside a function literal");
}
}
}
+39 -1
View File
@@ -106,6 +106,14 @@ int overloadApply(Module* from, FuncDeclaration *fstart,
int (*fp)(void *, FuncDeclaration *),
void *param);
enum Semantic
{
SemanticStart, // semantic has not been run
SemanticIn, // semantic() is in progress
SemanticDone, // semantic() has been run
Semantic2Done, // semantic2() has been run
};
/**************************************************************/
struct Declaration : Dsymbol
@@ -612,6 +620,13 @@ struct TypeInfoSharedDeclaration : TypeInfoDeclaration
void toDt(dt_t **pdt);
};
struct TypeInfoWildDeclaration : TypeInfoDeclaration
{
TypeInfoWildDeclaration(Type *tinfo);
void toDt(dt_t **pdt);
};
#endif
/**************************************************************/
@@ -756,6 +771,8 @@ struct FuncDeclaration : Declaration
int isCodeseg();
int isOverloadable();
int isPure();
int isSafe();
int isTrusted();
virtual int isNested();
int needThis();
virtual int isVirtual();
@@ -930,6 +947,17 @@ struct StaticCtorDeclaration : FuncDeclaration
StaticCtorDeclaration *isStaticCtorDeclaration() { return this; }
};
#if DMDV2
struct SharedStaticCtorDeclaration : StaticCtorDeclaration
{
SharedStaticCtorDeclaration(Loc loc, Loc endloc);
Dsymbol *syntaxCopy(Dsymbol *);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return this; }
};
#endif
struct StaticDtorDeclaration : FuncDeclaration
{ VarDeclaration *vgate; // 'gate' variable
@@ -948,6 +976,17 @@ struct StaticDtorDeclaration : FuncDeclaration
StaticDtorDeclaration *isStaticDtorDeclaration() { return this; }
};
#if DMDV2
struct SharedStaticDtorDeclaration : StaticDtorDeclaration
{
SharedStaticDtorDeclaration(Loc loc, Loc endloc);
Dsymbol *syntaxCopy(Dsymbol *);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return this; }
};
#endif
struct InvariantDeclaration : FuncDeclaration
{
InvariantDeclaration(Loc loc, Loc endloc);
@@ -963,7 +1002,6 @@ struct InvariantDeclaration : FuncDeclaration
InvariantDeclaration *isInvariantDeclaration() { return this; }
};
struct UnitTestDeclaration : FuncDeclaration
{
UnitTestDeclaration(Loc loc, Loc endloc);
+4
View File
@@ -301,6 +301,10 @@ void Dsymbol::importAll(Scope *sc)
* Does semantic analysis on the public face of declarations.
*/
void Dsymbol::semantic0(Scope *sc)
{
}
void Dsymbol::semantic(Scope *sc)
{
error("%p has no semantic routine", this);
+1
View File
@@ -163,6 +163,7 @@ struct Dsymbol : Object
virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
virtual void setScope(Scope *sc);
virtual void importAll(Scope *sc);
virtual void semantic0(Scope *sc);
virtual void semantic(Scope *sc);
virtual void semantic2(Scope *sc);
virtual void semantic3(Scope *sc);
+28
View File
@@ -51,6 +51,34 @@ Dsymbol *EnumDeclaration::syntaxCopy(Dsymbol *s)
return ed;
}
void EnumDeclaration::semantic0(Scope *sc)
{
/* This function is a hack to get around a significant problem.
* The members of anonymous enums, like:
* enum { A, B, C }
* don't get installed into the symbol table until after they are
* semantically analyzed, yet they're supposed to go into the enclosing
* scope's table. Hence, when forward referenced, they come out as
* 'undefined'. The real fix is to add them in at addSymbol() time.
* But to get code to compile, we'll just do this quick hack at the moment
* to compile it if it doesn't depend on anything else.
*/
if (isdone || !scope)
return;
if (!isAnonymous() || memtype)
return;
for (int i = 0; i < members->dim; i++)
{
EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
if (em && em->value)
return;
}
// Can do it
semantic(sc);
}
void EnumDeclaration::semantic(Scope *sc)
{ int i;
uinteger_t number;
+1
View File
@@ -47,6 +47,7 @@ struct EnumDeclaration : ScopeDsymbol
EnumDeclaration(Loc loc, Identifier *id, Type *memtype);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic0(Scope *sc);
void semantic(Scope *sc);
int oneMember(Dsymbol **ps);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+5 -142
View File
@@ -60,148 +60,6 @@ Expression *expandVar(int result, VarDeclaration *v);
#define LOGSEMANTIC 0
/**********************************
* Set operator precedence for each operator.
*/
// Operator precedence - greater values are higher precedence
enum PREC
{
PREC_zero,
PREC_expr,
PREC_assign,
PREC_cond,
PREC_oror,
PREC_andand,
PREC_or,
PREC_xor,
PREC_and,
PREC_equal,
PREC_rel,
PREC_shift,
PREC_add,
PREC_mul,
PREC_unary,
PREC_primary,
};
enum PREC precedence[TOKMAX];
void initPrecedence()
{
precedence[TOKdotvar] = PREC_primary;
precedence[TOKimport] = PREC_primary;
precedence[TOKidentifier] = PREC_primary;
precedence[TOKthis] = PREC_primary;
precedence[TOKsuper] = PREC_primary;
precedence[TOKint64] = PREC_primary;
precedence[TOKfloat64] = PREC_primary;
precedence[TOKnull] = PREC_primary;
precedence[TOKstring] = PREC_primary;
precedence[TOKarrayliteral] = PREC_primary;
precedence[TOKtypeid] = PREC_primary;
precedence[TOKis] = PREC_primary;
precedence[TOKassert] = PREC_primary;
precedence[TOKfunction] = PREC_primary;
precedence[TOKvar] = PREC_primary;
#if DMDV2
precedence[TOKdefault] = PREC_primary;
#endif
// post
precedence[TOKdotti] = PREC_primary;
precedence[TOKdot] = PREC_primary;
// precedence[TOKarrow] = PREC_primary;
precedence[TOKplusplus] = PREC_primary;
precedence[TOKminusminus] = PREC_primary;
precedence[TOKcall] = PREC_primary;
precedence[TOKslice] = PREC_primary;
precedence[TOKarray] = PREC_primary;
precedence[TOKaddress] = PREC_unary;
precedence[TOKstar] = PREC_unary;
precedence[TOKneg] = PREC_unary;
precedence[TOKuadd] = PREC_unary;
precedence[TOKnot] = PREC_unary;
precedence[TOKtobool] = PREC_add;
precedence[TOKtilde] = PREC_unary;
precedence[TOKdelete] = PREC_unary;
precedence[TOKnew] = PREC_unary;
precedence[TOKcast] = PREC_unary;
precedence[TOKmul] = PREC_mul;
precedence[TOKdiv] = PREC_mul;
precedence[TOKmod] = PREC_mul;
precedence[TOKadd] = PREC_add;
precedence[TOKmin] = PREC_add;
precedence[TOKcat] = PREC_add;
precedence[TOKshl] = PREC_shift;
precedence[TOKshr] = PREC_shift;
precedence[TOKushr] = PREC_shift;
precedence[TOKlt] = PREC_rel;
precedence[TOKle] = PREC_rel;
precedence[TOKgt] = PREC_rel;
precedence[TOKge] = PREC_rel;
precedence[TOKunord] = PREC_rel;
precedence[TOKlg] = PREC_rel;
precedence[TOKleg] = PREC_rel;
precedence[TOKule] = PREC_rel;
precedence[TOKul] = PREC_rel;
precedence[TOKuge] = PREC_rel;
precedence[TOKug] = PREC_rel;
precedence[TOKue] = PREC_rel;
precedence[TOKin] = PREC_rel;
#if 0
precedence[TOKequal] = PREC_equal;
precedence[TOKnotequal] = PREC_equal;
precedence[TOKidentity] = PREC_equal;
precedence[TOKnotidentity] = PREC_equal;
#else
/* Note that we changed precedence, so that < and != have the same
* precedence. This change is in the parser, too.
*/
precedence[TOKequal] = PREC_rel;
precedence[TOKnotequal] = PREC_rel;
precedence[TOKidentity] = PREC_rel;
precedence[TOKnotidentity] = PREC_rel;
#endif
precedence[TOKand] = PREC_and;
precedence[TOKxor] = PREC_xor;
precedence[TOKor] = PREC_or;
precedence[TOKandand] = PREC_andand;
precedence[TOKoror] = PREC_oror;
precedence[TOKquestion] = PREC_cond;
precedence[TOKassign] = PREC_assign;
precedence[TOKconstruct] = PREC_assign;
precedence[TOKblit] = PREC_assign;
precedence[TOKaddass] = PREC_assign;
precedence[TOKminass] = PREC_assign;
precedence[TOKcatass] = PREC_assign;
precedence[TOKmulass] = PREC_assign;
precedence[TOKdivass] = PREC_assign;
precedence[TOKmodass] = PREC_assign;
precedence[TOKshlass] = PREC_assign;
precedence[TOKshrass] = PREC_assign;
precedence[TOKushrass] = PREC_assign;
precedence[TOKandass] = PREC_assign;
precedence[TOKorass] = PREC_assign;
precedence[TOKxorass] = PREC_assign;
precedence[TOKcomma] = PREC_expr;
}
/*************************************************************
* Given var, we need to get the
* right 'this' pointer if var is in an outer class, but our
@@ -6225,6 +6083,11 @@ Expression *DelegateExp::semantic(Scope *sc)
AggregateDeclaration *ad = func->toParent()->isAggregateDeclaration();
if (func->needThis())
e1 = getRightThis(loc, sc, ad, e1, func);
if (ad && ad->isClassDeclaration() && ad->type != e1->type)
{ // A downcast is required for interfaces, see Bugzilla 3706
e1 = new CastExp(loc, e1, ad->type);
e1 = e1->semantic(sc);
}
}
return this;
}
+24 -6
View File
@@ -1101,7 +1101,6 @@ void FuncDeclaration::semantic3(Scope *sc)
if (fensure)
{ returnLabel = new LabelDsymbol(Id::returnLabel);
LabelStatement *ls = new LabelStatement(0, Id::returnLabel, fensure);
ls->isReturnLabel = 1;
returnLabel->statement = ls;
}
sc2 = sc2->pop();
@@ -1283,19 +1282,38 @@ void FuncDeclaration::semantic3(Scope *sc)
#else
Type *t = argptr->type;
VarDeclaration *p;
unsigned offset;
unsigned offset = 0;
Expression *e1 = new VarExp(0, argptr);
// Find the last non-ref parameter
if (parameters && parameters->dim)
p = (VarDeclaration *)parameters->data[parameters->dim - 1];
{
int lastNonref = parameters->dim -1;
p = (VarDeclaration *)parameters->data[lastNonref];
/* The trouble with out and ref parameters is that taking
* the address of it doesn't work, because later processing
* adds in an extra level of indirection. So we skip over them.
*/
while (p->storage_class & (STCout | STCref))
{
--lastNonref;
offset += PTRSIZE;
if (lastNonref < 0)
{
p = v_arguments;
break;
}
p = (VarDeclaration *)parameters->data[lastNonref];
}
}
else
p = v_arguments; // last parameter is _arguments[]
if (p->storage_class & STClazy)
// If the last parameter is lazy, it's the size of a delegate
offset = PTRSIZE * 2;
offset += PTRSIZE * 2;
else
offset = p->type->size();
offset = (offset + 3) & ~3; // assume stack aligns on 4
offset += p->type->size();
offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1); // assume stack aligns on pointer size
Expression *e = new SymOffExp(0, p, offset);
e->type = Type::tvoidptr;
//e = e->semantic(sc);
+1 -1
View File
@@ -341,7 +341,7 @@ void ArrayInitializer::addInit(Expression *index, Initializer *value)
Initializer *ArrayInitializer::semantic(Scope *sc, Type *t)
{ unsigned i;
unsigned length;
const unsigned long amax = 0x80000000;
const unsigned amax = 0x80000000;
//printf("ArrayInitializer::semantic(%s)\n", t->toChars());
if (sem) // if semantic() already run
+7 -1
View File
@@ -1112,8 +1112,9 @@ Expression *Expression::interpret(InterState *istate)
Expression *ThisExp::interpret(InterState *istate)
{
if (istate->localThis)
if (istate && istate->localThis)
return istate->localThis->interpret(istate);
error("value of 'this' is not known at compile time");
return EXP_CANT_INTERPRET;
}
@@ -2106,6 +2107,11 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, fp_t fp, int post)
#endif
Expression *e = EXP_CANT_INTERPRET;
Expression *e1 = this->e1;
if (!istate)
{
error("value of %s is not known at compile time", e1->toChars());
return e;
}
if (fp)
{
+1 -1
View File
@@ -63,7 +63,7 @@ Global::Global()
copyright = "Copyright (c) 1999-2010 by Digital Mars and Tomas Lindquist Olsen";
written = "written by Walter Bright and Tomas Lindquist Olsen";
version = "v1.062";
version = "v1.063";
ldc_version = LDC_REV;
llvm_version = LLVM_REV_STR;
global.structalign = 8;
+20 -6
View File
@@ -99,6 +99,7 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
vmoduleinfo = NULL;
#if IN_DMD
massert = NULL;
munittest = NULL;
marray = NULL;
sictor = NULL;
sctor = NULL;
@@ -387,15 +388,20 @@ void Module::read(Loc loc)
{
//printf("Module::read('%s') file '%s'\n", toChars(), srcfile->toChars());
if (srcfile->read())
{ error(loc, "cannot read file '%s'", srcfile->toChars());
if (!global.gag)
{ error(loc, "is in file '%s' which cannot be read", srcfile->toChars());
if (!global.gag)
{ /* Print path
*/
for (size_t i = 0; i < global.path->dim; i++)
*/
if (global.path)
{
for (int i = 0; i < global.path->dim; i++)
{
char *p = (char *)global.path->data[i];
fprintf(stdmsg, "import path[%d] = %s\n", i, p);
char *p = (char *)global.path->data[i];
fprintf(stdmsg, "import path[%d] = %s\n", i, p);
}
}
else
fprintf(stdmsg, "Specify path to file '%s' with -I switch\n", srcfile->toChars());
}
fatal();
}
@@ -791,6 +797,14 @@ void Module::semantic(Scope *unused_sc)
}
#endif
// Do semantic() on members that don't depend on others
for (int i = 0; i < members->dim; i++)
{ Dsymbol *s = (Dsymbol *)members->data[i];
//printf("\tModule('%s'): '%s'.semantic0()\n", toChars(), s->toChars());
s->semantic0(sc);
}
// Pass 1 semantic routines: do public side of the definition
for (int i = 0; i < members->dim; i++)
{ Dsymbol *s = (Dsymbol *)members->data[i];
+3
View File
@@ -173,6 +173,9 @@ struct Module : Package
Symbol *massert; // module assert function
Symbol *toModuleAssert(); // get module assert function
Symbol *munittest; // module unittest failure function
Symbol *toModuleUnittest(); // get module unittest failure function
Symbol *marray; // module array bounds function
Symbol *toModuleArray(); // get module array bounds function
+3
View File
@@ -4939,6 +4939,9 @@ Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident)
exps->reserve(sym->fields.dim);
for (size_t i = 0; i < sym->fields.dim; i++)
{ VarDeclaration *v = (VarDeclaration *)sym->fields.data[i];
// Don't include hidden 'this' pointer
if (v->isThisDeclaration())
continue;
Expression *fe = new DotVarExp(e->loc, e, v);
exps->push(fe);
}
+120 -1
View File
@@ -5461,6 +5461,125 @@ void Parser::addComment(Dsymbol *s, unsigned char *blockComment)
token.lineComment = NULL;
}
/**********************************
* Set operator precedence for each operator.
*/
enum PREC precedence[TOKMAX];
void initPrecedence()
{
precedence[TOKdotvar] = PREC_primary;
precedence[TOKimport] = PREC_primary;
precedence[TOKidentifier] = PREC_primary;
precedence[TOKthis] = PREC_primary;
precedence[TOKsuper] = PREC_primary;
precedence[TOKint64] = PREC_primary;
precedence[TOKfloat64] = PREC_primary;
precedence[TOKnull] = PREC_primary;
precedence[TOKstring] = PREC_primary;
precedence[TOKarrayliteral] = PREC_primary;
precedence[TOKtypeid] = PREC_primary;
precedence[TOKis] = PREC_primary;
precedence[TOKassert] = PREC_primary;
precedence[TOKfunction] = PREC_primary;
precedence[TOKvar] = PREC_primary;
#if DMDV2
precedence[TOKdefault] = PREC_primary;
#endif
// post
precedence[TOKdotti] = PREC_primary;
precedence[TOKdot] = PREC_primary;
// precedence[TOKarrow] = PREC_primary;
precedence[TOKplusplus] = PREC_primary;
precedence[TOKminusminus] = PREC_primary;
precedence[TOKcall] = PREC_primary;
precedence[TOKslice] = PREC_primary;
precedence[TOKarray] = PREC_primary;
precedence[TOKaddress] = PREC_unary;
precedence[TOKstar] = PREC_unary;
precedence[TOKneg] = PREC_unary;
precedence[TOKuadd] = PREC_unary;
precedence[TOKnot] = PREC_unary;
precedence[TOKtobool] = PREC_add;
precedence[TOKtilde] = PREC_unary;
precedence[TOKdelete] = PREC_unary;
precedence[TOKnew] = PREC_unary;
precedence[TOKcast] = PREC_unary;
precedence[TOKmul] = PREC_mul;
precedence[TOKdiv] = PREC_mul;
precedence[TOKmod] = PREC_mul;
precedence[TOKadd] = PREC_add;
precedence[TOKmin] = PREC_add;
precedence[TOKcat] = PREC_add;
precedence[TOKshl] = PREC_shift;
precedence[TOKshr] = PREC_shift;
precedence[TOKushr] = PREC_shift;
precedence[TOKlt] = PREC_rel;
precedence[TOKle] = PREC_rel;
precedence[TOKgt] = PREC_rel;
precedence[TOKge] = PREC_rel;
precedence[TOKunord] = PREC_rel;
precedence[TOKlg] = PREC_rel;
precedence[TOKleg] = PREC_rel;
precedence[TOKule] = PREC_rel;
precedence[TOKul] = PREC_rel;
precedence[TOKuge] = PREC_rel;
precedence[TOKug] = PREC_rel;
precedence[TOKue] = PREC_rel;
precedence[TOKin] = PREC_rel;
#if 0
precedence[TOKequal] = PREC_equal;
precedence[TOKnotequal] = PREC_equal;
precedence[TOKidentity] = PREC_equal;
precedence[TOKnotidentity] = PREC_equal;
#else
/* Note that we changed precedence, so that < and != have the same
* precedence. This change is in the parser, too.
*/
precedence[TOKequal] = PREC_rel;
precedence[TOKnotequal] = PREC_rel;
precedence[TOKidentity] = PREC_rel;
precedence[TOKnotidentity] = PREC_rel;
#endif
precedence[TOKand] = PREC_and;
precedence[TOKxor] = PREC_xor;
precedence[TOKor] = PREC_or;
precedence[TOKandand] = PREC_andand;
precedence[TOKoror] = PREC_oror;
precedence[TOKquestion] = PREC_cond;
precedence[TOKassign] = PREC_assign;
precedence[TOKconstruct] = PREC_assign;
precedence[TOKblit] = PREC_assign;
precedence[TOKaddass] = PREC_assign;
precedence[TOKminass] = PREC_assign;
precedence[TOKcatass] = PREC_assign;
precedence[TOKmulass] = PREC_assign;
precedence[TOKdivass] = PREC_assign;
precedence[TOKmodass] = PREC_assign;
precedence[TOKshlass] = PREC_assign;
precedence[TOKshrass] = PREC_assign;
precedence[TOKushrass] = PREC_assign;
precedence[TOKandass] = PREC_assign;
precedence[TOKorass] = PREC_assign;
precedence[TOKxorass] = PREC_assign;
precedence[TOKcomma] = PREC_expr;
}
/********************************* ***************************/
+26
View File
@@ -143,4 +143,30 @@ struct Parser : Lexer
void addComment(Dsymbol *s, unsigned char *blockComment);
};
// Operator precedence - greater values are higher precedence
enum PREC
{
PREC_zero,
PREC_expr,
PREC_assign,
PREC_cond,
PREC_oror,
PREC_andand,
PREC_or,
PREC_xor,
PREC_and,
PREC_equal,
PREC_rel,
PREC_shift,
PREC_add,
PREC_mul,
PREC_unary,
PREC_primary,
};
extern enum PREC precedence[TOKMAX];
void initPrecedence();
#endif /* DMD_PARSE_H */
+147 -1
View File
@@ -8,7 +8,6 @@
#if _WIN32
#include <windows.h>
#include <stdio.h>
#include <errno.h>
#include <process.h>
@@ -113,6 +112,153 @@ unsigned __stdcall startthread(void *p)
return EXIT_SUCCESS; // if skidding
}
#elif linux // Posix
#include <errno.h>
#include <pthread.h>
#include <time.h>
#include "root.h"
#include "rmem.h"
void *startthread(void *arg);
void err_abort(int status, const char *msg)
{
fprintf(stderr, "fatal error = %d, %s\n", status, msg);
exit(EXIT_FAILURE);
}
struct FileData
{
File *file;
int result;
pthread_mutex_t mutex;
pthread_cond_t cond;
int value;
};
struct AsyncRead
{
static AsyncRead *create(size_t nfiles);
void addFile(File *file);
void start();
int read(size_t i);
static void dispose(AsyncRead *);
size_t filesdim;
size_t filesmax;
FileData files[1];
};
AsyncRead *AsyncRead::create(size_t nfiles)
{
AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
(nfiles - 1) * sizeof(FileData));
aw->filesmax = nfiles;
return aw;
}
void AsyncRead::addFile(File *file)
{
//printf("addFile(file = %p)\n", file);
//printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax);
assert(filesdim < filesmax);
FileData *f = &files[filesdim];
f->file = file;
int status = pthread_mutex_init(&f->mutex, NULL);
if (status != 0)
err_abort(status, "init mutex");
status = pthread_cond_init(&f->cond, NULL);
if (status != 0)
err_abort(status, "init cond");
filesdim++;
}
void AsyncRead::start()
{
//printf("aw->filesdim = %p %d\n", this, filesdim);
if (filesdim)
{
pthread_t thread_id;
int status = pthread_create(&thread_id,
NULL,
&startthread,
this);
if (status != 0)
err_abort(status, "create thread");
}
}
int AsyncRead::read(size_t i)
{
FileData *f = &files[i];
// Wait for the event
int status = pthread_mutex_lock(&f->mutex);
if (status != 0)
err_abort(status, "lock mutex");
while (f->value == 0)
{
status = pthread_cond_wait(&f->cond, &f->mutex);
if (status != 0)
err_abort(status, "wait on condition");
}
status = pthread_mutex_unlock(&f->mutex);
if (status != 0)
err_abort(status, "unlock mutex");
return f->result;
}
void AsyncRead::dispose(AsyncRead *aw)
{
//printf("AsyncRead::dispose()\n");
for (int i = 0; i < aw->filesdim; i++)
{
FileData *f = &aw->files[i];
int status = pthread_cond_destroy(&f->cond);
if (status != 0)
err_abort(status, "cond destroy");
status = pthread_mutex_destroy(&f->mutex);
if (status != 0)
err_abort(status, "mutex destroy");
}
delete aw;
}
void *startthread(void *p)
{
AsyncRead *aw = (AsyncRead *)p;
//printf("startthread: aw->filesdim = %p %d\n", aw, aw->filesdim);
size_t dim = aw->filesdim;
for (size_t i = 0; i < dim; i++)
{ FileData *f = &aw->files[i];
f->result = f->file->read();
// Set event
int status = pthread_mutex_lock(&f->mutex);
if (status != 0)
err_abort(status, "lock mutex");
f->value = 1;
status = pthread_cond_signal(&f->cond);
if (status != 0)
err_abort(status, "signal condition");
status = pthread_mutex_unlock(&f->mutex);
if (status != 0)
err_abort(status, "unlock mutex");
}
return NULL; // end thread
}
#else
#include <stdio.h>
+6 -1
View File
@@ -322,6 +322,9 @@ char *Port::strupr(char *s)
#include <bits/nan.h>
#include <bits/mathdef.h>
#endif
#if __FreeBSD__ && __i386__
#include <ieeefp.h>
#endif
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
@@ -355,11 +358,13 @@ PortInitializer::PortInitializer()
foo = -foo; // turn off sign bit
Port::nan = foo;
#if __FreeBSD__
#if __FreeBSD__ && __i386__
// 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];
// FreeBSD defaults to double precision. Switch to extended precision.
fpsetprec(FP_PE);
#endif
}
+8 -1
View File
@@ -31,6 +31,7 @@
#if _WIN32
#include <windows.h>
#include <direct.h>
#include <errno.h>
#endif
#if POSIX
@@ -966,7 +967,13 @@ void FileName::ensurePathExists(const char *path)
#if POSIX
if (mkdir(path, 0777))
#endif
error("cannot create directory %s", path);
{
/* Don't error out if another instance of dmd just created
* this directory
*/
if (errno != EEXIST)
error("cannot create directory %s", path);
}
}
}
}
+12 -5
View File
@@ -1896,7 +1896,12 @@ Statement *ForeachStatement::semantic(Scope *sc)
*/
Expressions *exps = new Expressions();
exps->push(flde);
e = new CallExp(loc, aggr, exps);
if (aggr->op == TOKdelegate &&
((DelegateExp *)aggr)->func->isNested())
// See Bugzilla 3560
e = new CallExp(loc, ((DelegateExp *)aggr)->e1, exps);
else
e = new CallExp(loc, aggr, exps);
e = e->semantic(sc);
if (e->type != Type::tint32)
error("opApply() function for %s must return an int", tab->toChars());
@@ -3888,10 +3893,12 @@ Statement *WithStatement::semantic(Scope *sc)
else if (exp->op == TOKtype)
{ TypeExp *es = (TypeExp *)exp;
sym = es->type->toDsymbol(sc)->isScopeDsymbol();
Dsymbol *s = es->type->toDsymbol(sc);
sym = s ? s->isScopeDsymbol() : NULL;
if (!sym)
{ error("%s has no members", es->toChars());
body = body->semantic(sc);
{ error("with type %s has no members", es->toChars());
if (body)
body = body->semantic(sc);
return this;
}
}
@@ -4454,8 +4461,8 @@ LabelStatement::LabelStatement(Loc loc, Identifier *ident, Statement *statement)
this->enclosingFinally = NULL;
this->enclosingScopeExit = NULL;
this->lblock = NULL;
this->isReturnLabel = 0;
this->asmLabel = false;
this->fwdrefs = NULL;
}
Statement *LabelStatement::syntaxCopy()
+2 -1
View File
@@ -853,7 +853,8 @@ struct LabelStatement : Statement
TryFinallyStatement *enclosingFinally;
Statement* enclosingScopeExit;
block *lblock; // back end
int isReturnLabel;
Array *fwdrefs; // forward references to this LabelStatement
LabelStatement(Loc loc, Identifier *ident, Statement *statement);
Statement *syntaxCopy();