diff -uNr gdc-0.8/d/d-builtins2.cc gdc-0.9/d/d-builtins2.cc --- gdc-0.8/d/d-builtins2.cc 2004-10-14 02:28:08.000000000 +0200 +++ gdc-0.9/d/d-builtins2.cc 2004-12-02 02:12:02.000000000 +0100 @@ -231,14 +231,21 @@ { Array * members = m->members; Identifier * id = Lexer::idPool("va_arg"); + Identifier * id_start = Lexer::idPool("va_start"); for (unsigned i = 0; i < members->dim; i++) { TemplateDeclaration * td = ((Dsymbol *) members->data[i])->isTemplateDeclaration(); - if (td && td->ident == id) { - if (is_c_std_arg) - IRState::setCStdArg(td); - else - IRState::setStdArg(td); + if (td) { + if (td->ident == id) { + if (is_c_std_arg) + IRState::setCStdArgArg(td); + else + IRState::setStdArg(td); + } else if (td->ident == id_start && is_c_std_arg) { + IRState::setCStdArgStart(td); + } else + continue; + if ( TREE_CODE( TREE_TYPE( va_list_type_node )) == ARRAY_TYPE ) { /* For GCC, a va_list can be an array. D static arrays are automatically passed by reference, but the 'inout' @@ -261,22 +268,11 @@ fd->isFuncDeclaration(); } } - // ? -- version(GNU_PtrVaList)/version(GNU_AryVaList) -- less total LOC } - break; } } } -/* -static void -d_gcc_magic_c_stdarg_module(Module *m) -{ - //Dsymbol * d = m->symtab->lookup("va_arg"); - Array * members = m->members; -} -*/ - static void d_gcc_magic_builtins_module(Module *m) { @@ -307,14 +303,18 @@ ! strcmp( md->id->string, "builtins" )) { d_gcc_magic_builtins_module(m); } else if (md->packages->dim >= 1 && - ! strcmp( ((Identifier *) md->packages->data[0])->string, "std" ) && - ! strcmp( md->id->string, "stdarg" )) { + ! strcmp( ((Identifier *) md->packages->data[0])->string, "std" )) { - if (md->packages->dim == 1) { - d_gcc_magic_stdarg_module(m, false); - } else if (md->packages->dim == 2 && - ! strcmp( ((Identifier *) md->packages->data[1])->string, "c" )) { - d_gcc_magic_stdarg_module(m, true); + if (! strcmp( md->id->string, "stdarg" )) { + if (md->packages->dim == 1) { + d_gcc_magic_stdarg_module(m, false); + } else if (md->packages->dim == 2 && + ! strcmp( ((Identifier *) md->packages->data[1])->string, "c" )) { + d_gcc_magic_stdarg_module(m, true); + } + } else if (! strcmp( md->id->string, "intrinsic") && + md->packages->dim == 1) { + IRState::setIntrinsicModule(m); } } } diff -uNr gdc-0.8/d/d-codegen.cc gdc-0.9/d/d-codegen.cc --- gdc-0.8/d/d-codegen.cc 2004-10-23 22:44:51.000000000 +0200 +++ gdc-0.9/d/d-codegen.cc 2004-12-19 17:25:21.000000000 +0100 @@ -162,7 +162,13 @@ // DMD seems to ignore private in this case... TREE_PUBLIC( decl_tree ) = 1; } else { - TREE_PUBLIC( decl_tree ) = 0; + // From DMD: + /* private statics should still get a global symbol, in case + * another module inlines a function that references it. + */ + + // TREE_PUBLIC( decl_tree ) = 0; + TREE_PUBLIC( decl_tree ) = 1; } } } @@ -612,13 +618,22 @@ return libCall(LIBCALL_ARRAYCAST_FROMBIT, 2, args, target_type->toCtype()); } } else { - // %% VIEW_CONVERT_EXPR or NOP_EXPR ? + // %% VIEW_CONVERT_EXPR or NOP_EXPR ? (and the two cases below) // Convert to/from void[] or elements are the same size -- don't change length return build1(NOP_EXPR, target_type->toCtype(), exp); } - } else { - abort(); + } else if (target_type->ty == Taarray) { + // DMD allows this. + return build1(NOP_EXPR, target_type->toCtype(), exp); + } + // else, default conversion, which should produce an error + break; + case Taarray: + if (target_type->ty == Taarray || target_type->ty == Tarray) { + // DMD allows this. + return build1(NOP_EXPR, target_type->toCtype(), exp); } + // else, default conversion, which should product an error break; default: if (exp_type->isreal() && target_type->isimaginary() || @@ -657,6 +672,22 @@ break; } result = convertTo(result, part_type, target_type); + } else if (target_type->iscomplex()) { + tree c1, c2, t; + c1 = convert(TREE_TYPE(target_type->toCtype()), exp); + c2 = build_real_from_int_cst( TREE_TYPE(target_type->toCtype()), integer_zero_node); + + if (exp_type->isreal()) { + // nothing + } else if (exp_type->isimaginary()) { + t = c1; + c1 = c2; + c2 = t; + } else { + // default conversion + break; + } + result = build(COMPLEX_EXPR, target_type->toCtype(), c1, c2); } else { assert( TREE_CODE( exp ) != STRING_CST ); // default conversion @@ -1134,11 +1165,8 @@ } } else /* METHOD_TYPE */ { if ( ! object ) { - FuncDeclaration * cur_func = getCurrentFunction(); - if (cur_func->isMember() && ! cur_func->isThis() && - // Front-end apparently doesn't check this. - - TREE_CODE(callable) == FUNCTION_DECL ) { // not an exact check of the condition + // Front-end apparently doesn't check this. + if (TREE_CODE(callable) == FUNCTION_DECL ) { error("need 'this' to access member %s", IDENTIFIER_POINTER( DECL_NAME( callable ))); return error_mark_node; } else { @@ -1246,7 +1274,7 @@ "_d_monitorenter", "_d_monitorexit", "_d_criticalenter", "_d_criticalexit", "_d_throw", - "_d_switch_string", "_d_switch_ustring"/*, + "_d_switch_string", "_d_switch_ustring", "_d_switch_dstring"/*, "_d_gnu_bitarrayslice", "_d_gnu_bitarrayslicep", "_d_gnu_copytobitarrayslice"*/ }; @@ -1288,7 +1316,9 @@ { FuncDeclaration * decl = libcall_decls[lib_call]; Array arg_types; - bool varargs = false; // cheap way to not declare arguments + Type * t = NULL; + bool varargs = false; + if (! decl) { Type * return_type = Type::tvoid; @@ -1385,92 +1415,74 @@ varargs = true; switch (lib_call) { - case LIBCALL_AAIN: return_type = Type::tint32; break; + case LIBCALL_AAIN: return_type = Type::tvoid->pointerTo(); break; case LIBCALL_AAGET: return_type = Type::tvoid->pointerTo(); break; case LIBCALL_AADEL: return_type = Type::tvoid; break; default: - abort(); + assert(0); } } break; case LIBCALL_ARRAYCAST: - { - Type * t = Type::tvoid->arrayOf(); - arg_types.push(Type::tuns32); - arg_types.push(Type::tuns32); - arg_types.push(t); - return_type = t; - } + t = Type::tvoid->arrayOf(); + arg_types.push(Type::tuns32); + arg_types.push(Type::tuns32); + arg_types.push(t); + return_type = t; break; case LIBCALL_ARRAYCAST_FROMBIT: - { - Type * t = Type::tvoid->arrayOf(); - arg_types.push(Type::tuns32); - arg_types.push(t); - return_type = t; - } + t = Type::tvoid->arrayOf(); + arg_types.push(Type::tuns32); + arg_types.push(t); + return_type = t; break; case LIBCALL_ARRAYCOPY: - { - Type * t = Type::tvoid->arrayOf(); - arg_types.push(Type::tuns32); - arg_types.push(t); - arg_types.push(t); - return_type = t; - } + t = Type::tvoid->arrayOf(); + arg_types.push(Type::tuns32); + arg_types.push(t); + arg_types.push(t); + return_type = t; break; case LIBCALL_ARRAYCOPYBIT: - { - Type * t = Type::tbit->arrayOf(); - arg_types.push(t); - arg_types.push(t); - return_type = t; - } + t = Type::tbit->arrayOf(); + arg_types.push(t); + arg_types.push(t); + return_type = t; break; case LIBCALL_ARRAYCAT: - { - Type * t = Type::tvoid->arrayOf(); - arg_types.push(t); - arg_types.push(t); - arg_types.push(Type::tuns32); - return_type = t; - } + t = Type::tvoid->arrayOf(); + arg_types.push(t); + arg_types.push(t); + arg_types.push(Type::tuns32); + return_type = t; break; case LIBCALL_ARRAYCATN: - { - arg_types.push(Type::tuns32); - arg_types.push(Type::tuns32); - varargs = true; - return_type = Type::tvoid->arrayOf(); - } + arg_types.push(Type::tuns32); + arg_types.push(Type::tuns32); + varargs = true; + return_type = Type::tvoid->arrayOf(); break; case LIBCALL_ARRAYAPPEND: - { - Type * t = Type::tuns8->arrayOf(); - arg_types.push(t->pointerTo()); - arg_types.push(t); - arg_types.push(Type::tuns32); - return_type = Type::tvoid->arrayOf(); - } + t = Type::tuns8->arrayOf(); + arg_types.push(t->pointerTo()); + arg_types.push(t); + arg_types.push(Type::tuns32); + return_type = Type::tvoid->arrayOf(); break; case LIBCALL_ARRAYAPPENDC: - { - Type * t = Type::tuns8->arrayOf()->pointerTo(); - arg_types.push(t->pointerTo()); - arg_types.push(Type::tuns32); - varargs = true; - return_type = Type::tvoid->arrayOf(); - } + t = Type::tuns8->arrayOf()->pointerTo(); + arg_types.push(t->pointerTo()); + arg_types.push(Type::tuns32); + varargs = true; + return_type = Type::tvoid->arrayOf(); break; case LIBCALL_ARRAYSETBIT: - { - Type * t = Type::tbit->arrayOf(); - arg_types.push(t); - arg_types.push(Type::tuns32); - arg_types.push(Type::tuns32); - arg_types.push(Type::tbit); - return_type = t; - } + t = Type::tbit->arrayOf(); + arg_types.push(t); + arg_types.push(Type::tuns32); + arg_types.push(Type::tuns32); + arg_types.push(Type::tbit); + return_type = t; break; case LIBCALL_MONITORENTER: case LIBCALL_MONITOREXIT: @@ -1482,15 +1494,19 @@ case LIBCALL_CRITICALEXIT: arg_types.push(Type::tvoid->pointerTo()); break; - case LIBCALL_SWITCH_STRING: case LIBCALL_SWITCH_USTRING: - { - Type * t = lib_call == LIBCALL_SWITCH_STRING ? - Type::tchar->arrayOf() : Type::twchar->arrayOf(); - arg_types.push(t->arrayOf()); - arg_types.push(t); - return_type = Type::tint32; - } + t = Type::twchar; + goto do_switch_string; + case LIBCALL_SWITCH_DSTRING: + t = Type::tdchar; + goto do_switch_string; + case LIBCALL_SWITCH_STRING: + t = Type::tchar; + do_switch_string: + t = t->arrayOf(); + arg_types.push(t->arrayOf()); + arg_types.push(t); + return_type = Type::tint32; break; default: abort(); @@ -1575,6 +1591,31 @@ t = build1(INDIRECT_REF, TREE_TYPE(TREE_TYPE(t)), t); } return build1(VA_ARG_EXPR, TREE_TYPE(TREE_TYPE(callee)), t); + case INTRINSIC_C_VA_START: + /* + t = TREE_VALUE(); + // signature is (inout va_list), but VA_ARG_EXPR expects the + // list itself... + if ( TREE_CODE( t ) == ADDR_EXPR ) { + t = TREE_OPERAND(t, 0); + } else { + // this probably doesn't happen... passing an inout va_list argument, + // but again, it's probably { & ( * inout_arg ) } + t = build1(INDIRECT_REF, TREE_TYPE(TREE_TYPE(t)), t); + } + */ + // The va_list argument should already have its + // address taken. The second argument, however, is + // inout and that needs to be fixed to prevent a warning. + t = TREE_VALUE(TREE_CHAIN(TREE_OPERAND(call_exp, 1))); + if ( TREE_CODE( t ) == ADDR_EXPR ) { + t = TREE_OPERAND(t, 0); + } + + return buildCall(void_type_node, // assuming nobody tries to change the return type + addressOf( built_in_decls[BUILT_IN_VA_START] ), + tree_cons(NULL_TREE, TREE_VALUE(TREE_OPERAND(call_exp, 1)), + tree_cons( NULL_TREE, t, NULL_TREE))); default: abort(); break; @@ -1592,12 +1633,13 @@ case INTRINSIC_BSR: // %% types should be correct, but should still check.. // %% 64-bit.. + return call_exp; #if D_GCC_VER >= 34 return build(CALL_EXPR, TREE_TYPE(call_exp), built_in_decls[intrinsic == INTRINSIC_BSF ? BUILT_IN_CTZ : BUILT_IN_CLZ], TREE_OPERAND(call_exp, 1)); #else - + return call_exp; #endif case INTRINSIC_BT: case INTRINSIC_BTC: @@ -1605,8 +1647,9 @@ case INTRINSIC_BTS: break; case INTRINSIC_BSWAP: - { - } +#if defined(TARGET_386) + +#endif break; case INTRINSIC_INP: case INTRINSIC_INPW: @@ -1616,7 +1659,7 @@ case INTRINSIC_OUTPL: #ifdef TARGET_386 #else - ::error("Port I/O intrinsic '%s' is only available on ix86 target", + ::error("Port I/O intrinsic '%s' is only available on ix86 targets", IDENTIFIER_POINTER(DECL_NAME(callee))); #endif break; @@ -1742,6 +1785,8 @@ DECL_STATIC_CONSTRUCTOR( func_decl ) = 1; // apparently, the back end doesn't do anything with this TREE_USED( func_decl ) = 1; // only needed for GCC 3.3? } + TREE_PUBLIC( func_decl ) = 0; // these are always private (see IRState::setupSymbolStorage, default case) + // %% maybe remove the identifier func->fbody = new ExpStatement(mod->loc, @@ -2374,7 +2419,8 @@ Module * IRState::builtinsModule = 0; Module * IRState::intrinsicModule = 0; TemplateDeclaration * IRState::stdargTemplateDecl = 0; -TemplateDeclaration * IRState::cstdargTemplateDecl = 0; +TemplateDeclaration * IRState::cstdargStartTemplateDecl = 0; +TemplateDeclaration * IRState::cstdargArgTemplateDecl = 0; static inline const char * strip_builtin(const char * x) { if (! strncmp(x, "__builtin_", strlen("__builtin_"))) @@ -2390,7 +2436,52 @@ TemplateInstance * ti; dsym = decl->toParent(); - if (dsym) { + if (dsym->getModule() == intrinsicModule) { + // Matches order of Intrinsic enum + static const char * intrinsic_names[] = { + "bsf", "bsr", + "bt", "btc", "btr", "bts", + "bswap", + "inp", "inpw", "inpl", + "outp", "outw", "outl", NULL + }; + for (int i = 0; intrinsic_names[i]; i++) { + if ( ! strcmp( decl->ident->string, intrinsic_names[i] ) ) { + bool have_intrinsic = false; + tree t = decl->toSymbol()->Stree; + + switch ( (Intrinsic) i ) { + case INTRINSIC_BSF: + case INTRINSIC_BSR: + case INTRINSIC_BT: + case INTRINSIC_BTC: + case INTRINSIC_BTR: + case INTRINSIC_BTS: + break; + case INTRINSIC_BSWAP: +#if defined(TARGET_386) + //have_intrinsic = true; +#endif + break; + case INTRINSIC_OUTP: + case INTRINSIC_OUTPW: + case INTRINSIC_OUTPL: + // Only on ix86, but need to given error message on others + have_intrinsic = true; + break; + default: + abort(); + } + + if (have_intrinsic) { + DECL_BUILT_IN_CLASS( t ) = BUILT_IN_FRONTEND; + DECL_FUNCTION_CODE( t ) = (built_in_function) i; + return true; + } else + return false; + } + } + } else if (dsym) { ti = dsym->isTemplateInstance(); if (ti) { tree t = decl->toSymbol()->Stree; @@ -2398,43 +2489,17 @@ DECL_BUILT_IN_CLASS(t) = BUILT_IN_FRONTEND; DECL_FUNCTION_CODE(t) = (built_in_function) INTRINSIC_STD_VA_ARG; return true; - } else if (ti->tempdecl == cstdargTemplateDecl) { + } else if (ti->tempdecl == cstdargArgTemplateDecl) { DECL_BUILT_IN_CLASS(t) = BUILT_IN_FRONTEND; DECL_FUNCTION_CODE(t) = (built_in_function) INTRINSIC_C_VA_ARG; return true; - } - } - } -#if 0 - else if (mod == intrinsicModule) { - // Matches order of Intrinsic enum - static const char * intrinsic_names[] = { - "bsf", "bsr", - "bt", "btc", "btr", "bts", - "bswap", - "inp", "inpw", "inpl", - "outp", "outw", "outl" - }; - for (int i = 0; i < (int) INTRINSIC_count; i++) { - if ( ! strcmp( decl->ident->string, intrinsic_names[i] ) ) { - tree type = decl->type->toCtype(); - tree fn_decl = build_decl(FUNCTION_DECL, - get_identifier(intrinsic_names[i]), type); - DECL_BUILT_IN_CLASS( fn_decl ) = BUILT_IN_FRONTEND; - DECL_FUNCTION_CODE( fn_decl ) = i; - - decl->csym = new Symbol(); - decl->csym->Stree = fn_decl; - - // %% hack (do I need this?) - TYPE_LANG_SPECIFIC( TREE_TYPE( fn_decl )) = - build_d_type_lang_specific( decl->type ); - + } else if (ti->tempdecl == cstdargStartTemplateDecl) { + DECL_BUILT_IN_CLASS(t) = BUILT_IN_FRONTEND; + DECL_FUNCTION_CODE(t) = (built_in_function) INTRINSIC_C_VA_START; return true; } } } -#endif return false; } diff -uNr gdc-0.8/d/d-codegen.h gdc-0.9/d/d-codegen.h --- gdc-0.8/d/d-codegen.h 2004-10-23 22:44:51.000000000 +0200 +++ gdc-0.9/d/d-codegen.h 2004-12-19 17:25:21.000000000 +0100 @@ -73,6 +73,7 @@ LIBCALL_THROW, LIBCALL_SWITCH_STRING, LIBCALL_SWITCH_USTRING, + LIBCALL_SWITCH_DSTRING, LIBCALL_count } LibCall; @@ -108,6 +109,7 @@ INTRINSIC_OUTP, INTRINSIC_OUTPW, INTRINSIC_OUTPL, INTRINSIC_STD_VA_ARG, INTRINSIC_C_VA_ARG, + INTRINSIC_C_VA_START, INTRINSIC_count, } Intrinsic; @@ -413,11 +415,13 @@ static Module * builtinsModule; static Module * intrinsicModule; static TemplateDeclaration * stdargTemplateDecl; - static TemplateDeclaration * cstdargTemplateDecl; + static TemplateDeclaration * cstdargStartTemplateDecl; + static TemplateDeclaration * cstdargArgTemplateDecl; static void setBuiltinsModule(Module * mod) { builtinsModule = mod; } static void setIntrinsicModule(Module * mod) { intrinsicModule = mod; } static void setStdArg(TemplateDeclaration * td) { stdargTemplateDecl = td; } - static void setCStdArg(TemplateDeclaration * td) { cstdargTemplateDecl = td; } + static void setCStdArgStart(TemplateDeclaration * td) { cstdargStartTemplateDecl = td; } + static void setCStdArgArg(TemplateDeclaration * td) { cstdargArgTemplateDecl = td; } static bool maybeSetUpBuiltin(Declaration * decl); static tree functionPointer(FuncDeclaration * func_decl); diff -uNr gdc-0.8/d/d-decls.cc gdc-0.9/d/d-decls.cc --- gdc-0.8/d/d-decls.cc 2004-10-23 22:44:51.000000000 +0200 +++ gdc-0.9/d/d-decls.cc 2004-12-02 02:49:03.000000000 +0100 @@ -122,6 +122,55 @@ return 0; } + +// Workaround for: If there is a declaration in a function, another +// other declarations with the same identifier in overloads of the +// functions will have the same mangled name. DMD gets away with this +// because it produces its own object files and the declarations are +// essentially private. Assemblers won't accept this, so unique names +// must be generated. + +// Unresolved issues: +// * What if these are referenced from another module when inlining? +// * Okay to always SET_DECL_ASSEMBLER_NAME? +// +// Use set_decl_assembler_name hook instead? +// +// Assumes 'd' is static storage. + +static StringTable * uniqueNames = 0; +static /*char **/void uniqueName(Dsymbol * d, tree t, const char * asm_name) { + // First, check if the symbol is declared in a function + Dsymbol * p = d->parent; + const char * out_name = asm_name; + char * alloc_name = 0; + + while (p) { + if (p->isFuncDeclaration()) { + StringValue * sv; + + // Assumes one assembler output file + if (! uniqueNames) + uniqueNames = new StringTable; + sv = uniqueNames->update(asm_name, strlen(asm_name)); + if (sv->intvalue) { + out_name = alloc_name = d_asm_format_private_name(asm_name, sv->intvalue ); + } + sv->intvalue++; + + //return out_name; + } + p = p->parent; + } + // return asm_name; + + SET_DECL_ASSEMBLER_NAME(t, get_identifier(out_name)); + + if (alloc_name) + free(alloc_name); +} + + /************************************* */ @@ -140,14 +189,23 @@ return csym; } + /* tree ident_to_use; if (isDataseg()) ident_to_use = get_identifier( mangle() ); else ident_to_use = get_identifier( ident->string ); + */ + const char * ident_to_use; + if (isDataseg()) + ident_to_use = mangle(); + else + ident_to_use = ident->string; var_decl = build_decl(storage_class & STCparameter ? PARM_DECL : VAR_DECL, - ident_to_use, gen.trueDeclarationType( this )); + get_identifier(ident_to_use), gen.trueDeclarationType( this )); + if (isDataseg()) + uniqueName(this, var_decl, ident_to_use); dkeep(var_decl); gen.setDeclLoc(var_decl, this); if ( TREE_CODE( var_decl ) == VAR_DECL ) { @@ -295,7 +353,8 @@ dkeep(fn_decl); if (ident) { mangled_ident_str = mangle(); - SET_DECL_ASSEMBLER_NAME (fn_decl, get_identifier( mangled_ident_str )); + uniqueName(this, fn_decl, mangled_ident_str); + // old : SET_DECL_ASSEMBLER_NAME (fn_decl, get_identifier( mangled_ident_str )); } // %% What about DECL_SECTION_NAME ? //DECL_ARGUMENTS(fn_decl) = NULL_TREE; // Probably don't need to do this until toObjFile diff -uNr gdc-0.8/d/d-glue.cc gdc-0.9/d/d-glue.cc --- gdc-0.8/d/d-glue.cc 2004-10-23 22:44:51.000000000 +0200 +++ gdc-0.9/d/d-glue.cc 2004-12-19 17:25:21.000000000 +0100 @@ -449,7 +449,7 @@ bool is_unsigned = e1_type->isunsigned() || e2_type->isunsigned() || op == TOKushr; if (exp_type->isintegral() && - exp_type->isunsigned() != is_unsigned) { + ( exp_type->isunsigned() != 0 ) != is_unsigned) { tree e_new_type_1 = is_unsigned ? d_unsigned_type(exp_type->toCtype()) : d_signed_type(exp_type->toCtype()); @@ -1168,7 +1168,8 @@ elem * DelegateExp::toElem(IRState* irs) { - if (e1->type->toBasetype()->ty == Tclass) { + Type * t = e1->type->toBasetype(); + if (t->ty == Tclass || t->ty == Tstruct) { return irs->objectInstanceMethod(e1, func, type); } else { assert(func->isNested()); // %% check @@ -1295,15 +1296,20 @@ elem * VarExp::toElem(IRState* irs) { + if (var->storage_class & STCfield) { + error("Need 'this' to access member %s", var->ident->string); + return error_mark_node; + } + // For variables that are references (currently only out/inout arguments; // objects don't count), evaluating the variable means we want what it refers to. tree e = var->toSymbol()->Stree; + if ( irs->isDeclarationReferenceType(var) ) { e = build1(INDIRECT_REF, var->type->toCtype(), e); if (irs->inVolatile()) { TREE_THIS_VOLATILE(e) = 1; } - return e; } else { if (irs->inVolatile()) { e = irs->addressOf(e); @@ -1311,8 +1317,8 @@ e = build1(INDIRECT_REF, TREE_TYPE(TREE_TYPE(e)), e); TREE_THIS_VOLATILE(e) = 1; } - return e; } + return e; } elem * @@ -2021,6 +2027,11 @@ return toCtype(); } +void +TypedefDeclaration::toDebug() +{ +} + type * TypeEnum::toCtype() @@ -2033,40 +2044,30 @@ TYPE_MIN_VALUE( ctype ) = gen.integerConstant(sym->minval, enum_mem_type_node); TYPE_MAX_VALUE( ctype ) = gen.integerConstant(sym->maxval, enum_mem_type_node); TYPE_PRECISION( ctype ) = size() * 8; - TREE_UNSIGNED( ctype ) = isunsigned(); TYPE_SIZE( ctype ) = 0; // as in c-decl.c if (sym->ident) TYPE_NAME( ctype ) = get_identifier(sym->ident->string); layout_type( ctype ); + TREE_UNSIGNED( ctype ) = isunsigned() != 0; // layout_type can change this + // Move this to toDebug() ? ListMaker enum_values; if (sym->members) { for (unsigned i = 0; i < sym->members->dim; i++) { EnumMember * member = (EnumMember *) sym->members->data[i]; - Expression * exp = member->value; + char * ident; - // %% assumes folded constant, integer, etc. - tree an_enum_val = gen.integerConstant(exp->toInteger(), ctype); + if (sym->ident) + ident = concat(sym->ident->string, ".", + member->ident->string, NULL); + else + ident = (char *) member->ident->string; - enum_values.cons( get_identifier(member->ident->string), - an_enum_val ); + enum_values.cons( get_identifier(ident), + gen.integerConstant(member->value->toInteger(), ctype) ); - // For named enums, it doesn't seem like we need to make CONST_DECLs - // For unamed enums, this function isn't called.. so we need to - // do something with toObjFile.. - /* - if ( ! sym->ident ) { - printf("enum sym %s\n", member->ident->string); - // %% What's t DECL_CONTEXT for this? Does it matter? - // if needed, have to get it after declareType -- or - // split declareType into , getDeclContext,declareType - tree decl = build_decl(CONST_DECL, get_identifier(member->ident->string), - ctype); - tree val = an_enum_val; // gen.integerConstant(e_mem->value->toInteger(), enum_type); - DECL_INITIAL( decl ) = val; - rest_of_decl_compilation(decl, NULL, 0, 0); - } - */ + if (sym->ident) + free(ident); } } TYPE_VALUES( ctype ) = enum_values.head; @@ -2099,6 +2100,11 @@ return ctype; } +void +StructDeclaration::toDebug() +{ +} + Symbol * TypeClass::toSymbol() { return sym->toSymbol(); } unsigned TypeFunction::totym() { return 0; } // Unused @@ -2319,7 +2325,6 @@ the type during this call. */ rec_type = make_node( RECORD_TYPE ); ctype = build_reference_type( rec_type ); - // TYPE_STUB_DECL(rec_type) = build_decl(TYPE_DECL, NULL_TREE, ctype);// EXPER -- DOES NOT KILL REI but does not stop second impact either obj_rec_type = TREE_TYPE( gen.getObjectType()->toCtype() ); @@ -2364,31 +2369,40 @@ } else { ClassDeclaration * p = sym; while (p->baseclasses.dim) { - p = ((BaseClass *) sym->baseclasses.data[0])->base; + p = ((BaseClass *) p->baseclasses.data[0])->base; } DECL_FCONTEXT( vfield ) = TREE_TYPE( p->type->toCtype() ); } agg_layout.finish(); - if (write_symbols != NO_DEBUG) { - gen.addAggMethods(rec_type, sym); - - if ( ! sym->isInterfaceDeclaration() ) - TYPE_BINFO( rec_type ) = binfo_for(NULL_TREE, sym); - else { - unsigned offset = 0; - BaseClass bc; - bc.base = sym; - TYPE_BINFO( rec_type ) = intfc_binfo_for(NULL_TREE, sym, offset); - } + // Create BINFO even if debugging is off. This is needed to keep + // references to inherited types. There could be a more effecient way, + // however. + // if (write_symbols != NO_DEBUG) { + + gen.addAggMethods(rec_type, sym); + + if ( ! sym->isInterfaceDeclaration() ) + TYPE_BINFO( rec_type ) = binfo_for(NULL_TREE, sym); + else { + unsigned offset = 0; + BaseClass bc; + bc.base = sym; + TYPE_BINFO( rec_type ) = intfc_binfo_for(NULL_TREE, sym, offset); } + // } + gen.declareType(rec_type, sym); } return ctype; } +void +ClassDeclaration::toDebug() +{ +} void LabelStatement::toIR(IRState* irs) @@ -2611,7 +2625,7 @@ if (ident) expand_exit_loop( irs->getLoopForLabel( ident ) ); else - expand_exit_something(); // could be a switch statement .. no loopcookie avail for that.. + expand_exit_something(); } void @@ -2682,9 +2696,13 @@ Type * cond_type = condition->type->toBasetype(); if (cond_type->ty == Tarray) { Type * elem_type = cond_type->next->toBasetype(); - if (elem_type->ty != Tchar && elem_type->ty != Twchar) { - // but allow signed 8 and 16 bit string? - ::error("cannot handle switch condition on string of character type %s", elem_type->toChars()); + LibCall lib_call; + switch (elem_type->ty) { + case Tchar: lib_call = LIBCALL_SWITCH_STRING; break; + case Twchar: lib_call = LIBCALL_SWITCH_USTRING; break; + case Tdchar: lib_call = LIBCALL_SWITCH_DSTRING; break; + default: + ::error("switch statement value must be an array of some character type, not %s", elem_type->toChars()); abort(); } @@ -2713,8 +2731,7 @@ irs->addressOf(table)), cond_tree }; - cond_tree = irs->libCall(elem_type->ty == Tchar ? LIBCALL_SWITCH_STRING : LIBCALL_SWITCH_USTRING, - 2, args); + cond_tree = irs->libCall(lib_call, 2, args); } else if (! cond_type->isscalar()) { ::error("cannot handle switch condition of type %s", cond_type->toChars()); abort(); @@ -3035,51 +3052,35 @@ } void -EnumDeclaration::toObjFile() +EnumDeclaration::toDebug() { - return; - - tree enum_type = type->toCtype(); - bool top_level = cur_irs->isToplevelDeclContext(); - if (ident) { - tree enum_decl = build_decl(TYPE_DECL, get_identifier(ident->string), enum_type); - - DECL_CONTEXT( enum_decl ) = cur_irs->getDeclContext(); - - //TYPE_STUB_DECL( enum_type ) = enum_decl; // why bother with the below? - TYPE_STUB_DECL (enum_type) = pushdecl (build_decl (TYPE_DECL, NULL_TREE, enum_type)); - rest_of_decl_compilation( enum_decl, NULL, top_level, 0 ); - rest_of_type_compilation( enum_type, top_level ); // %% toplevel - pushdecl( enum_decl ); - } else { - // nothing - } +} - if (members) { - for (unsigned i = 0; i < members->dim; i++) { - EnumMember * e_mem = ((Dsymbol *) members->data[i])->isEnumMember(); - if (e_mem) { - // the type is not the enum type, just the integer type - tree decl = build_decl(CONST_DECL, get_identifier(e_mem->ident->string), - enum_type); - // const check fold optimize, etc? %% - tree val = gen.integerConstant(e_mem->value->toInteger(), enum_type); - DECL_INITIAL( decl ) = val; - // %% is all this necc.? from pascal? -- C doesn't do this.. - /* - DECL_SIZE( an_enum_sym ) = TYPE_SIZE( ctype ); - DECL_SIZE_UNIT( an_enum_sym ) = TYPE_SIZE_UNIT( ctype ); - DECL_ALIGN( an_enum_sym ) = TYPE_ALIGN( ctype ); - DECL_USER_ALIGN( an_enum_sym ) = TYPE_USER_ALIGN( ctype ); - DECL_MODE( an_enum_sym ) = TYPE_MODE( ctype ); - */ - // in enum context? .. especially since it's really EnumName.X, unless anonymous - // not rest_of_decl_compilation for CONST_DECLs - pushdecl(decl); - } - } - } +int +Dsymbol::cvMember(unsigned char*) +{ + return 0; +} +int +EnumDeclaration::cvMember(unsigned char*) +{ + return 0; +} +int +FuncDeclaration::cvMember(unsigned char*) +{ + return 0; +} +int +VarDeclaration::cvMember(unsigned char*) +{ + return 0; +} +int +TypedefDeclaration::cvMember(unsigned char*) +{ + return 0; } rtx @@ -3257,9 +3258,11 @@ } switch ( PTRSIZE ) { case 4: + assert(POINTER_SIZE == 32); Tptrdiff_t = Tint32; break; case 8: + assert(POINTER_SIZE == 64); Tptrdiff_t = Tint64; break; default: diff -uNr gdc-0.8/d/d-lang.cc gdc-0.9/d/d-lang.cc --- gdc-0.8/d/d-lang.cc 2004-10-23 22:44:51.000000000 +0200 +++ gdc-0.9/d/d-lang.cc 2004-12-19 17:25:21.000000000 +0100 @@ -174,40 +174,42 @@ gcc_d_backend_init(); real_t::init(); - VersionCondition::addGlobalIdent("GNU"); + VersionCondition::addPredefinedGlobalIdent("GNU"); #ifdef D_CPU_VERSYM - VersionCondition::addGlobalIdent(D_CPU_VERSYM); + VersionCondition::addPredefinedGlobalIdent(D_CPU_VERSYM); #endif #ifdef D_OS_VERSYM - VersionCondition::addGlobalIdent(D_OS_VERSYM); + VersionCondition::addPredefinedGlobalIdent(D_OS_VERSYM); #endif #ifdef D_OS_VERSYM2 - VersionCondition::addGlobalIdent(D_OS_VERSYM2); + VersionCondition::addPredefinedGlobalIdent(D_OS_VERSYM2); #endif #if BYTES_BIG_ENDIAN - VersionCondition::addGlobalIdent("BigEndian"); + VersionCondition::addPredefinedGlobalIdent("BigEndian"); #else - VersionCondition::addGlobalIdent("LittleEndian"); + VersionCondition::addPredefinedGlobalIdent("LittleEndian"); #endif // Need these for phobos/gcc/unwind.d #if UNITS_PER_WORD == 4 - VersionCondition::addGlobalIdent("BitsPerWord32"); + VersionCondition::addPredefinedGlobalIdent("GNU_BitsPerWord32"); #elif UNITS_PER_WORD == 8 - VersionCondition::addGlobalIdent("BitsPerWord64"); + VersionCondition::addPredefinedGlobalIdent("GNU_BitsPerWord64"); #endif #if POINTER_SIZE == 32 - VersionCondition::addGlobalIdent("BitsPerPointer32"); + VersionCondition::addPredefinedGlobalIdent("GNU_BitsPerPointer32"); #elif POINTER_SIZE == 64 - VersionCondition::addGlobalIdent("BitsPerPointer64"); + VersionCondition::addPredefinedGlobalIdent("GNU_BitsPerPointer64"); #endif if (d_using_sjlj_exceptions()) { - VersionCondition::addGlobalIdent("GNU_SjLj_Exceptions"); + VersionCondition::addPredefinedGlobalIdent("GNU_SjLj_Exceptions"); } #if 0 - VersionCondition::addGlobalIdent("D_InlineAsm"); + VersionCondition::addPredefinedGlobalIdent("D_InlineAsm"); #endif + VersionCondition::addPredefinedGlobalIdent("all"); + // %%TODO: front or back? if (std_inc) { @@ -292,11 +294,24 @@ #endif +static bool +parse_int (const char * arg, int * value_ret) +{ + long v; + char * err; + v = strtol(arg, & err, 10); + if (*err || errno || v > INT_MAX) + return false; + * value_ret = v; + return true; +} + // gcc 3.4, but also called by gcc3 static int d_handle_option (size_t scode, const char *arg, int value) { enum opt_code code = (enum opt_code) scode; + int level; switch (code) { @@ -321,23 +336,31 @@ global.params.useUnitTests = value; break; case OPT_fversion_: - if (ISDIGIT(arg[0])) - VersionCondition::setGlobalLevel(atoi(arg)); - else if (ISALPHA(arg[0])) // %%TODO: check whole string + if (ISDIGIT(arg[0])) { + if (! parse_int(arg, & level)) + goto Lerror_v; + VersionCondition::setGlobalLevel(level); + } else if (ISALPHA(arg[0]) || arg[0] == '_') // %%TODO: check whole string VersionCondition::addGlobalIdent(xstrdup(arg)); - else + else { + Lerror_v: error("bad argument for -fversion"); + } break; case OPT_fdebug: global.params.debuglevel = value ? 1 : 0; break; case OPT_fdebug_: - if (ISDIGIT(arg[0])) - DebugCondition::setGlobalLevel(atoi(arg)); - else if (ISALPHA(arg[0])) + if (ISDIGIT(arg[0])) { + if (! parse_int(arg, & level)) + goto Lerror_d; + DebugCondition::setGlobalLevel(level); + } else if (ISALPHA(arg[0]) || arg[0] == '_') DebugCondition::addGlobalIdent(xstrdup(arg)); - else + else { + Lerror_d: error("bad argument for -fdebug"); + } break; case OPT_femit_templates: gen.emitTemplates = value ? TEfull : TEnone; @@ -522,6 +545,7 @@ if (gen.emitTemplates == TEauto) { gen.emitTemplates = (SUPPORTS_ONE_ONLY) ? TEfull : TEprivate; } + global.params.symdebug = write_symbols != NO_DEBUG; #if D_GCC_VER == 33 (*debug_hooks->start_source_file) (lineno, input_filename); @@ -596,8 +620,21 @@ name = (char *) xmalloc((e - p) + 1); memcpy(name, p, e - p); name[e - p] = 0; - } else - name = p; + + if (name[0] == 0 || + strcmp(name, "..") == 0 || + strcmp(name, ".") == 0) + { + Linvalid: + ::error("invalid file name '%s'", the_fname); + goto had_errors; + } + } + else + { name = p; + if (!*name) + goto Linvalid; + } id = new Identifier(name, 0); Module * m = new Module(the_fname, id); @@ -1272,7 +1309,9 @@ } tree d_keep_list = NULL_TREE; -void dkeep(tree t) + +void +dkeep(tree t) { d_keep_list = tree_cons(NULL_TREE, t, d_keep_list); } diff -uNr gdc-0.8/d/d-lang.h gdc-0.9/d/d-lang.h --- gdc-0.8/d/d-lang.h 2004-10-14 02:28:08.000000000 +0200 +++ gdc-0.9/d/d-lang.h 2004-12-02 03:38:49.000000000 +0100 @@ -167,6 +167,7 @@ /* In d-misc.c */ extern int d_using_sjlj_exceptions PARAMS ((void)); +extern char * d_asm_format_private_name PARAMS ((const char *,int)); /* In d-builtins2.cc */ extern void d_bi_init(int nt, int nb); diff -uNr gdc-0.8/d/dmd/access.c gdc-0.9/d/dmd/access.c --- gdc-0.8/d/dmd/access.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/dmd/access.c 2004-11-23 01:03:10.000000000 +0100 @@ -314,6 +314,13 @@ } // If both are members of the same module, grant access + while (1) + { Dsymbol *sp = smember->toParent(); + if (sp->isFuncDeclaration() && smember->isFuncDeclaration()) + smember = sp; + else + break; + } if (!cd && toParent() == smember->toParent()) { #if LOG diff -uNr gdc-0.8/d/dmd/aggregate.h gdc-0.9/d/dmd/aggregate.h --- gdc-0.8/d/dmd/aggregate.h 2004-10-15 01:21:22.000000000 +0200 +++ gdc-0.9/d/dmd/aggregate.h 2004-12-18 21:22:55.000000000 +0100 @@ -35,6 +35,7 @@ struct DeleteDeclaration; struct InterfaceDeclaration; struct ClassInfoDeclaration; +struct VarDeclaration; struct dt_t; @@ -65,6 +66,7 @@ unsigned size(); static void alignmember(unsigned salign, unsigned size, unsigned *poffset); Type *getType(); + void addField(Scope *sc, VarDeclaration *v); // Back end Symbol *stag; // tag symbol for debug data @@ -74,6 +76,16 @@ AggregateDeclaration *isAggregateDeclaration() { return this; } }; +struct AnonymousAggregateDeclaration : AggregateDeclaration +{ + AnonymousAggregateDeclaration() + : AggregateDeclaration(0, NULL) + { + } + + AnonymousAggregateDeclaration *isAnonymousAggregateDeclaration() { return this; } +}; + struct StructDeclaration : AggregateDeclaration { int zeroInit; // !=0 if initialize with 0 fill @@ -87,6 +99,7 @@ void toObjFile(); // compile to .obj file void toDt(dt_t **pdt); + void toDebug(); // to symbolic debug info StructDeclaration *isStructDeclaration() { return this; } }; @@ -171,9 +184,11 @@ void accessCheck(Loc loc, Scope *sc, Dsymbol *smember); int isFriendOf(ClassDeclaration *cd); int hasPackageAccess(Scope *sc); + void addLocalClass(Array *); // Back end void toObjFile(); // compile to .obj file + void toDebug(); unsigned baseVtblOffset(BaseClass *bc); Symbol *toSymbol(); Symbol *toVtblSymbol(); diff -uNr gdc-0.8/d/dmd/attrib.c gdc-0.9/d/dmd/attrib.c --- gdc-0.8/d/dmd/attrib.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/dmd/attrib.c 2004-12-18 21:22:55.000000000 +0100 @@ -29,36 +29,54 @@ this->decl = decl; } -int AttribDeclaration::include() +Array *AttribDeclaration::include() { - return TRUE; + return decl; } void AttribDeclaration::addMember(ScopeDsymbol *sd) { unsigned i; + Array *d = include(); - if (include() && decl) + if (d) { - for (i = 0; i < decl->dim; i++) + for (i = 0; i < d->dim; i++) { Dsymbol *s; - s = (Dsymbol *)decl->data[i]; + s = (Dsymbol *)d->data[i]; s->addMember(sd); } } } +void AttribDeclaration::semantic(Scope *sc) +{ + Array *d = include(); + + //printf("\tAttribDeclaration::semantic '%s'\n",toChars()); + if (d) + { + for (unsigned i = 0; i < d->dim; i++) + { + Dsymbol *s = (Dsymbol *)d->data[i]; + + s->semantic(sc); + } + } +} + void AttribDeclaration::semantic2(Scope *sc) { unsigned i; + Array *d = include(); - if (include() && decl) + if (d) { - for (i = 0; i < decl->dim; i++) + for (i = 0; i < d->dim; i++) { Dsymbol *s; - s = (Dsymbol *)decl->data[i]; + s = (Dsymbol *)d->data[i]; s->semantic2(sc); } } @@ -67,13 +85,14 @@ void AttribDeclaration::semantic3(Scope *sc) { unsigned i; + Array *d = include(); - if (include() && decl) + if (d) { - for (i = 0; i < decl->dim; i++) + for (i = 0; i < d->dim; i++) { Dsymbol *s; - s = (Dsymbol *)decl->data[i]; + s = (Dsymbol *)d->data[i]; s->semantic3(sc); } } @@ -82,13 +101,14 @@ void AttribDeclaration::inlineScan() { unsigned i; + Array *d = include(); - if (include() && decl) + if (d) { - for (i = 0; i < decl->dim; i++) + for (i = 0; i < d->dim; i++) { Dsymbol *s; - s = (Dsymbol *)decl->data[i]; + s = (Dsymbol *)d->data[i]; s->inlineScan(); } } @@ -97,18 +117,41 @@ void AttribDeclaration::toObjFile() { unsigned i; + Array *d = include(); - if (include() && decl) + if (d) { - for (i = 0; i < decl->dim; i++) + for (i = 0; i < d->dim; i++) { Dsymbol *s; - s = (Dsymbol *)decl->data[i]; + s = (Dsymbol *)d->data[i]; s->toObjFile(); } } } +int AttribDeclaration::cvMember(unsigned char *p) +{ + unsigned i; + int nwritten = 0; + int n; + Array *d = include(); + + if (d) + { + for (i = 0; i < d->dim; i++) + { Dsymbol *s; + + s = (Dsymbol *)d->data[i]; + n = s->cvMember(p); + if (p) + p += n; + nwritten += n; + } + } + return nwritten; +} + char *AttribDeclaration::kind() { return "attribute"; @@ -116,14 +159,34 @@ Dsymbol *AttribDeclaration::oneMember() { Dsymbol *s; + Array *d = include(); - if (decl && decl->dim == 1) - { s = (Dsymbol *)decl->data[0]; + if (d && d->dim == 1) + { s = (Dsymbol *)d->data[0]; return s->oneMember(); } return NULL; } +/**************************************** + */ + +void AttribDeclaration::addLocalClass(Array *aclasses) +{ unsigned i; + Array *d = include(); + + if (d) + { + for (i = 0; i < d->dim; i++) + { Dsymbol *s; + + s = (Dsymbol *)d->data[i]; + s->addLocalClass(aclasses); + } + } +} + + void AttribDeclaration::toCBuffer(OutBuffer *buf) { if (decl) @@ -145,7 +208,7 @@ buf->writenl(); } -/********************************* StorageClassDeclaration ****************************/ +/************************* StorageClassDeclaration ****************************/ StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl) : AttribDeclaration(decl) @@ -167,7 +230,9 @@ if (decl) { unsigned stc_save = sc->stc; - sc->stc = stc; + if (stc & (STCauto | STCstatic | STCextern)) + sc->stc &= ~(STCauto | STCstatic | STCextern); + sc->stc |= stc; for (unsigned i = 0; i < decl->dim; i++) { Dsymbol *s = (Dsymbol *)decl->data[i]; @@ -367,6 +432,119 @@ AttribDeclaration::toCBuffer(buf); } +/********************************* AnonDeclaration ****************************/ + +AnonDeclaration::AnonDeclaration(int isunion, Array *decl) + : AttribDeclaration(decl) +{ + this->isunion = isunion; +} + +Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s) +{ + AnonDeclaration *ad; + + assert(!s); + ad = new AnonDeclaration(isunion, Dsymbol::arraySyntaxCopy(decl)); + return ad; +} + +void AnonDeclaration::semantic(Scope *sc) +{ + //printf("\tAnonDeclaration::semantic '%s'\n",toChars()); + assert(sc->parent); + + Dsymbol *parent = sc->parent->pastMixin(); + AggregateDeclaration *ad = parent->isAggregateDeclaration(); + + if (!ad || (!ad->isStructDeclaration() && !ad->isClassDeclaration())) + { + error("can only be a part of an aggregate"); + return; + } + + if (decl) + { Scope sc_save = *sc; + AnonymousAggregateDeclaration aad; + int adisunion; + + if (sc->anonAgg) + { ad = sc->anonAgg; + adisunion = sc->inunion; + } + else + adisunion = ad->isUnionDeclaration() != NULL; + + sc->anonAgg = &aad; + sc->stc &= ~(STCauto | STCstatic); + sc->inunion = isunion; + sc->offset = 0; + sc->flags = 0; + aad.structalign = sc->structalign; + + for (unsigned i = 0; i < decl->dim; i++) + { + Dsymbol *s = (Dsymbol *)decl->data[i]; + + s->semantic(sc); + if (isunion) + sc->offset = 0; + } + *sc = sc_save; + + // 0 sized structs are set to 1 byte + if (aad.structsize == 0) + { + aad.structsize = 1; + aad.alignsize = 1; + } + + // Align size of anonymous aggregate +//printf("aad.structalign = %d, aad.alignsize = %d, sc->offset = %d\n", aad.structalign, aad.alignsize, sc->offset); + ad->alignmember(aad.structalign, aad.alignsize, &sc->offset); + //ad->structsize = sc->offset; +//printf("sc->offset = %d\n", sc->offset); + + // Add members of aad to ad + //printf("\tadding members of aad to '%s'\n", ad->toChars()); + for (unsigned i = 0; i < aad.fields.dim; i++) + { + VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; + + v->offset += sc->offset; + ad->fields.push(v); + } + + // Add size of aad to ad + if (adisunion) + { + if (aad.structsize > ad->structsize) + ad->structsize = aad.structsize; + sc->offset = 0; + } + else + { + ad->structsize = sc->offset + aad.structsize; + sc->offset = ad->structsize; + } + + if (ad->alignsize < aad.alignsize) + ad->alignsize = aad.alignsize; + } +} + + +void AnonDeclaration::toCBuffer(OutBuffer *buf) +{ + buf->printf(isunion ? "union" : "struct"); + AttribDeclaration::toCBuffer(buf); +} + +char *AnonDeclaration::kind() +{ + return (char *)(isunion ? "anonymous union" : "anonymous struct"); +} + /********************************* PragmaDeclaration ****************************/ PragmaDeclaration::PragmaDeclaration(Identifier *ident, Array *args, Array *decl) @@ -465,92 +643,12 @@ // Decide if debug code should be included -int DebugDeclaration::include() +Array *DebugDeclaration::include() { assert(condition); - return condition->include(); -} - -void DebugDeclaration::addMember(ScopeDsymbol *sd) -{ - unsigned i; - Array *d = include() ? decl : elsedecl; - - if (d) - { - for (i = 0; i < d->dim; i++) - { Dsymbol *s; - - s = (Dsymbol *)d->data[i]; - s->addMember(sd); - } - } + return condition->include() ? decl : elsedecl; } -void DebugDeclaration::semantic(Scope *sc) -{ - Array *d = include() ? decl : elsedecl; - - //printf("\tDebugDeclaration::semantic '%s'\n",toChars()); - if (d) - { - for (unsigned i = 0; i < d->dim; i++) - { - Dsymbol *s = (Dsymbol *)d->data[i]; - - s->semantic(sc); - } - } -} - - -void DebugDeclaration::semantic2(Scope *sc) -{ - unsigned i; - Array *d = include() ? decl : elsedecl; - - if (d) - { - for (i = 0; i < d->dim; i++) - { Dsymbol *s; - - s = (Dsymbol *)d->data[i]; - s->semantic2(sc); - } - } -} - -void DebugDeclaration::semantic3(Scope *sc) -{ - unsigned i; - Array *d = include() ? decl : elsedecl; - - if (d) - { - for (i = 0; i < d->dim; i++) - { Dsymbol *s; - - s = (Dsymbol *)d->data[i]; - s->semantic3(sc); - } - } -} - -void DebugDeclaration::toObjFile() -{ - unsigned i; - Array *d = include() ? decl : elsedecl; - - if (d) - { - for (i = 0; i < d->dim; i++) - { Dsymbol *s; - - s = (Dsymbol *)d->data[i]; - s->toObjFile(); - } - } -} void DebugDeclaration::toCBuffer(OutBuffer *buf) { diff -uNr gdc-0.8/d/dmd/attrib.h gdc-0.9/d/dmd/attrib.h --- gdc-0.8/d/dmd/attrib.h 2004-04-18 04:14:33.000000000 +0200 +++ gdc-0.9/d/dmd/attrib.h 2004-12-18 21:22:55.000000000 +0100 @@ -30,16 +30,19 @@ Array *decl; // array of Dsymbol's AttribDeclaration(Array *decl); - virtual int include(); + virtual Array *include(); void addMember(ScopeDsymbol *s); + void semantic(Scope *sc); void semantic2(Scope *sc); void semantic3(Scope *sc); void inlineScan(); char *kind(); Dsymbol *oneMember(); + void addLocalClass(Array *); void toCBuffer(OutBuffer *buf); void toObjFile(); // compile to .obj file + int cvMember(unsigned char *p); }; struct StorageClassDeclaration: AttribDeclaration @@ -84,6 +87,17 @@ void toCBuffer(OutBuffer *buf); }; +struct AnonDeclaration : AttribDeclaration +{ + int isunion; + + AnonDeclaration(int isunion, Array *decl); + Dsymbol *syntaxCopy(Dsymbol *s); + void semantic(Scope *sc); + void toCBuffer(OutBuffer *buf); + char *kind(); +}; + struct PragmaDeclaration : AttribDeclaration { Identifier *ident; Array *args; // array of Expression's @@ -101,14 +115,8 @@ DebugDeclaration(Condition *condition, Array *decl, Array *elsedecl); Dsymbol *syntaxCopy(Dsymbol *s); - int include(); - void addMember(ScopeDsymbol *s); - void semantic(Scope *sc); - void semantic2(Scope *sc); - void semantic3(Scope *sc); + Array *include(); void toCBuffer(OutBuffer *buf); - - void toObjFile(); // compile to .obj file }; struct VersionDeclaration : DebugDeclaration diff -uNr gdc-0.8/d/dmd/cast.c gdc-0.9/d/dmd/cast.c --- gdc-0.8/d/dmd/cast.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/cast.c 2004-12-18 21:22:55.000000000 +0100 @@ -68,15 +68,61 @@ } if (t->ty == Tbit && isBit()) return MATCHconvert; + Expression *e = optimize(WANTvalue | WANTflags); + if (e != this) + { //printf("optimzed to %s\n", e->toChars()); + return e->implicitConvTo(t); + } return type->implicitConvTo(t); } int IntegerExp::implicitConvTo(Type *t) { +#if 0 + printf("IntegerExp::implicitConvTo(this=%s, type=%s, t=%s)\n", + toChars(), type->toChars(), t->toChars()); +#endif if (type->equals(t)) return MATCHexact; + switch (type->toBasetype()->ty) + { + case Tbit: + value &= 1; + break; + + case Tint8: + value = (signed char)value; + break; + + case Tchar: + case Tuns8: + value &= 0xFF; + break; + + case Tint16: + value = (short)value; + break; + + case Tuns16: + case Twchar: + value &= 0xFFFF; + break; + + case Tint32: + value = (int)value; + break; + + case Tuns32: + case Tdchar: + value &= 0xFFFFFFFF; + break; + + default: + break; + } + // Only allow conversion if no change in value switch(t->ty) { @@ -90,8 +136,9 @@ goto Lno; goto Lyes; - case Tascii: + case Tchar: case Tuns8: + //printf("value = %llu %llu\n", (integer_t)(unsigned char)value, value); if ((unsigned char)value != value) goto Lno; goto Lyes; @@ -112,40 +159,74 @@ goto Lyes; case Tuns32: - case Tdchar: if ((unsigned)value != value) goto Lno; goto Lyes; + case Tdchar: + if (value > 0x10FFFFUL) + goto Lno; + goto Lyes; + case Twchar: - if ((wchar_t)value != value) + if ((unsigned short)value != value) goto Lno; goto Lyes; case Tfloat32: case Tcomplex32: { - volatile float f = (float)value; - if (f != value) - goto Lno; + volatile float f; + if (type->isunsigned()) + { + f = (float)value; + if (f != value) + goto Lno; + } + else + { + f = (float)(long long)value; + if (f != (long long)value) + goto Lno; + } goto Lyes; } case Tfloat64: case Tcomplex64: { - volatile double d = (double)value; - if (d != value) - goto Lno; + volatile double f; + if (type->isunsigned()) + { + f = (double)value; + if (f != value) + goto Lno; + } + else + { + f = (double)(long long)value; + if (f != (long long)value) + goto Lno; + } goto Lyes; } case Tfloat80: case Tcomplex80: { - volatile long double ld = (long double)value; - if (ld != value) - goto Lno; + volatile long double f; + if (type->isunsigned()) + { + f = (long double)value; + if (f != value) + goto Lno; + } + else + { + f = (long double)(long long)value; + if (f != (long long)value) + goto Lno; + } goto Lyes; } } @@ -303,6 +384,10 @@ { Expression *e; Type *tb; +#if 0 + printf("Expression::castTo(this=%s, type=%s, t=%s)\n", + toChars(), type->toChars(), t->toChars()); +#endif e = this; tb = t->toBasetype(); type = type->toBasetype(); @@ -756,17 +841,32 @@ } else if (t1->isintegral() && t2->isintegral()) { - if (t1->ty > t2->ty) + //printf("t1 = %s, t2 = %s\n", t1->toChars(), t2->toChars()); + int sz1 = t1->size(); + int sz2 = t2->size(); + int sign1 = t1->isunsigned() == 0; + int sign2 = t2->isunsigned() == 0; + + if (sign1 == sign2) + { + if (sz1 < sz2) + goto Lt2; + else + goto Lt1; + } + if (!sign1) { - if (t1->ty >= Tuns32) - e2 = e2->castTo(t1); + if (sz1 >= sz2) + goto Lt1; + else + goto Lt2; } else { - if (t2->ty >= Tuns32) - { e1 = e1->castTo(t2); - t = t2; - } + if (sz2 >= sz1) + goto Lt2; + else + goto Lt1; } } else if (t1->ty == Tpointer && t2->ty == Tpointer) @@ -807,13 +907,11 @@ } else if ((t1->ty == Tsarray || t1->ty == Tarray) && t1->implicitConvTo(t2)) { - e1 = e1->castTo(t2); - t = t2; + goto Lt2; } else if ((t2->ty == Tsarray || t2->ty == Tarray) && t2->implicitConvTo(t1)) { - e2 = e2->castTo(t1); - t = t1; + goto Lt1; } else if (t1->ty == Tclass || t2->ty == Tclass) { int i1; @@ -833,26 +931,22 @@ if (i2) { - e1 = e1->castTo(t2); - t = t2; + goto Lt2; } else if (i1) { - e2 = e2->castTo(t1); - t = t1; + goto Lt1; } else goto Lincompatible; } else if ((e1->op == TOKstring || e1->op == TOKnull) && e1->implicitConvTo(t2)) { - e1 = e1->castTo(t2); - t = t2; + goto Lt2; } else if ((e2->op == TOKstring || e2->op == TOKnull) && e2->implicitConvTo(t1)) { - e2 = e2->castTo(t1); - t = t1; + goto Lt1; } else if (t1->ty == Tsarray && t2->ty == Tsarray && e2->implicitConvTo(t1->next->arrayOf())) @@ -875,10 +969,22 @@ e1->toChars(), Token::toChars(op), e2->toChars(), t1->toChars(), t2->toChars()); } +Lret: if (!type) type = t; //dump(0); return this; + + +Lt1: + e2 = e2->castTo(t1); + t = t1; + goto Lret; + +Lt2: + e1 = e1->castTo(t2); + t = t2; + goto Lret; } /*********************************** @@ -901,7 +1007,7 @@ case Tint16: case Tuns16: case Tbit: - case Tascii: + case Tchar: case Twchar: e = e->castTo(Type::tint32); break; diff -uNr gdc-0.8/d/dmd/class.c gdc-0.9/d/dmd/class.c --- gdc-0.8/d/dmd/class.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/dmd/class.c 2004-12-18 21:22:55.000000000 +0100 @@ -69,10 +69,10 @@ if (!Type::typeinfo && id == Id::TypeInfo) Type::typeinfo = this; - if (!Type::typeinfoclass && id == Id::TypeInfoClass) + if (!Type::typeinfoclass && id == Id::TypeInfo_Class) Type::typeinfoclass = this; - if (!Type::typeinfotypedef && id == Id::TypeInfoTypedef) + if (!Type::typeinfotypedef && id == Id::TypeInfo_Typedef) Type::typeinfotypedef = this; com = 0; @@ -287,11 +287,14 @@ alignsize = 4; } structsize = sc->offset; - for (i = 0; i < members->dim; i++) + Scope scsave = *sc; + int members_dim = members->dim; + for (i = 0; i < members_dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; s->semantic(sc); } + structsize = sc->offset; //members->print(); /* Look for special member functions. @@ -323,6 +326,8 @@ ctor->fbody = new CompoundStatement(0, new Array()); members->push(ctor); ctor->addMember(this); + *sc = scsave; + sc->offset = structsize; ctor->semantic(sc); } @@ -564,6 +569,14 @@ return "class"; } +/**************************************** + */ + +void ClassDeclaration::addLocalClass(Array *aclasses) +{ + aclasses->push(this); +} + /********************************* InterfaceDeclaration ****************************/ InterfaceDeclaration::InterfaceDeclaration(Loc loc, Identifier *id, Array *baseclasses) diff -uNr gdc-0.8/d/dmd/constfold.c gdc-0.9/d/dmd/constfold.c --- gdc-0.8/d/dmd/constfold.c 2004-10-10 18:50:41.000000000 +0200 +++ gdc-0.9/d/dmd/constfold.c 2004-12-18 21:22:55.000000000 +0100 @@ -42,27 +42,32 @@ int Expression::isConst() { //printf("Expression::isConst(): %s\n", toChars()); - return FALSE; + return 0; } int IntegerExp::isConst() { - return TRUE; + return 1; } int RealExp::isConst() { - return TRUE; + return 1; } int ImaginaryExp::isConst() { - return TRUE; + return 1; } int ComplexExp::isConst() { - return TRUE; + return 1; +} + +int SymOffExp::isConst() +{ + return 2; } /* ================================== constFold() ============================== */ @@ -126,12 +131,10 @@ return e1; } + if (type->toBasetype()->ty == Tbit) + return new IntegerExp(loc, e1->toInteger() != 0, type); if (type->isintegral()) - { - IntegerExp * e = new IntegerExp(loc, e1->toInteger(), type); - e->toInteger(); - return e; - } + return new IntegerExp(loc, e1->toInteger(), type); if (type->isreal()) return new RealExp(loc, e1->toReal(), type); if (type->isimaginary()) @@ -140,7 +143,8 @@ return new ComplexExp(loc, e1->toComplex(), type); if (type->isscalar()) return new IntegerExp(loc, e1->toInteger(), type); - error("cannot cast %s to %s", e1->type->toChars(), type->toChars()); + if (type->toBasetype()->ty != Tvoid) + error("cannot cast %s to %s", e1->type->toChars(), type->toChars()); return this; } @@ -151,6 +155,8 @@ //printf("AddExp::constFold(%s)\n", toChars()); e1 = e1->constFold(); e2 = e2->constFold(); + if (e1->op == TOKsymoff && e2->op == TOKsymoff) + return this; if (type->isreal()) { e = new RealExp(loc, e1->toReal() + e2->toReal(), type); @@ -186,6 +192,8 @@ e1 = e1->constFold(); e2 = e2->constFold(); + if (e2->op == TOKsymoff) + return this; if (type->isreal()) { e = new RealExp(loc, e1->toReal() - e2->toReal(), type); @@ -205,13 +213,16 @@ e->type = type; } else + { e = new IntegerExp(loc, e1->toInteger() - e2->toInteger(), type); + } return e; } Expression *MulExp::constFold() { Expression *e; + //printf("MulExp::constFold(%s)\n", toChars()); e1 = e1->constFold(); e2 = e2->constFold(); if (type->isfloating()) diff -uNr gdc-0.8/d/dmd/debcond.c gdc-0.9/d/dmd/debcond.c --- gdc-0.8/d/dmd/debcond.c 2004-09-29 04:25:48.000000000 +0200 +++ gdc-0.9/d/dmd/debcond.c 2004-11-23 01:03:10.000000000 +0100 @@ -110,6 +110,33 @@ void VersionCondition::addGlobalIdent(char *ident) { + static char* reserved[] = + { + "DigitalMars", "X86", "AMD64", + "Windows", "Win32", "Win64", + "linux", + "LittleEndian", "BigEndian", + "none", + }; + + for (unsigned i = 0; i < sizeof(reserved) / sizeof(reserved[0]); i++) + { + if (strcmp(ident, reserved[i]) == 0) + goto Lerror; + } + + if (ident[0] == 'D' && ident[1] == '_') + goto Lerror; + + addPredefinedGlobalIdent(ident); + return; + + Lerror: + error("version identifier '%s' is reserved and cannot be set", ident); +} + +void VersionCondition::addPredefinedGlobalIdent(char *ident) +{ if (!global.params.versionids) global.params.versionids = new Array(); global.params.versionids->push(ident); diff -uNr gdc-0.8/d/dmd/debcond.h gdc-0.9/d/dmd/debcond.h --- gdc-0.8/d/dmd/debcond.h 2004-09-29 04:25:48.000000000 +0200 +++ gdc-0.9/d/dmd/debcond.h 2004-11-23 01:03:10.000000000 +0100 @@ -33,6 +33,7 @@ { static void setGlobalLevel(unsigned level); static void addGlobalIdent(char *ident); + static void addPredefinedGlobalIdent(char *ident); DebugCondition(Module *mod, unsigned level, Identifier *ident); @@ -43,6 +44,7 @@ { static void setGlobalLevel(unsigned level); static void addGlobalIdent(char *ident); + static void addPredefinedGlobalIdent(char *ident); VersionCondition(Module *mod, unsigned level, Identifier *ident); diff -uNr gdc-0.8/d/dmd/declaration.c gdc-0.9/d/dmd/declaration.c --- gdc-0.8/d/dmd/declaration.c 2004-09-29 04:25:48.000000000 +0200 +++ gdc-0.9/d/dmd/declaration.c 2004-12-18 21:22:55.000000000 +0100 @@ -245,31 +245,42 @@ } } L1: + if (overnext) + ScopeDsymbol::multiplyDefined(this, overnext); type = type->semantic(loc, sc); this->inSemantic = 0; return; L2: type = NULL; - FuncDeclaration *f = s->isFuncDeclaration(); - if (f) + VarDeclaration *v = s->isVarDeclaration(); + if (v && v->linkage == LINKdefault) + { + error("forward reference of %s", v->toChars()); + s = NULL; + } + else { + FuncDeclaration *f = s->isFuncDeclaration(); + if (f) + { + if (overnext) + { + FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); + if (!fa->overloadInsert(overnext)) + ScopeDsymbol::multiplyDefined(f, overnext); + overnext = NULL; + s = fa; + } + } if (overnext) + ScopeDsymbol::multiplyDefined(s, overnext); + if (s == this) { - FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); - if (!fa->overloadInsert(overnext)) - ScopeDsymbol::multiplyDefined(f, overnext); - overnext = NULL; - s = fa; + assert(global.errors); + s = NULL; } } - if (overnext) - ScopeDsymbol::multiplyDefined(s, overnext); - if (s == this) - { - assert(global.errors); - s = NULL; - } aliassym = s; this->inSemantic = 0; } @@ -366,6 +377,7 @@ sv = new VarDeclaration(loc, type->syntaxCopy(), ident, init); sv->storage_class = storage_class; + //sv->storage_class |= storage_class & STCauto; } return sv; } @@ -380,6 +392,7 @@ //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); protection = sc->protection; storage_class |= sc->stc; + //printf("sc->stc = %x\n", sc->stc); //printf("storage_class = %x\n", storage_class); Dsymbol *parent = toParent(); @@ -403,51 +416,16 @@ } else { - StructDeclaration *sd = parent->isStructDeclaration(); - if (sd) + AnonymousAggregateDeclaration *aad = sc->anonAgg; + if (aad) { - unsigned memsize; // size of member - unsigned memalignsize; // size of member for alignment purposes - unsigned xalign; // alignment boundaries - - memsize = type->size(); - memalignsize = type->alignsize(); - xalign = type->memalign(sc->structalign); - sd->alignmember(xalign, memalignsize, &sc->offset); - offset = sc->offset; - sc->offset += memsize; - if (sc->offset > sd->structsize) - sd->structsize = sc->offset; - if (sd->alignsize < memalignsize) - sd->alignsize = memalignsize; - - storage_class |= STCfield; - //printf("1 Adding '%s' to '%s'\n", this->toChars(), sd->toChars()); - sd->fields.push(this); - } - - ClassDeclaration *cd = parent->isClassDeclaration(); - if (cd) - { - unsigned memsize; - unsigned memalignsize; - unsigned xalign; - - memsize = type->size(); - memalignsize = type->alignsize(); - xalign = type->memalign(sc->structalign); - cd->alignmember(xalign, memalignsize, &sc->offset); - offset = sc->offset; - //printf("offset of '%s' is x%x\n", toChars(), offset); - sc->offset += memsize; - if (sc->offset > cd->structsize) - cd->structsize = sc->offset; - if (cd->alignsize < memalignsize) - cd->alignsize = memalignsize; - - storage_class |= STCfield; - //printf("2 Adding '%s' to '%s'\n", this->toChars(), cd->toChars()); - cd->fields.push(this); + aad->addField(sc, this); + } + else + { + AggregateDeclaration *ad = parent->isAggregateDeclaration(); + if (ad) + ad->addField(sc, this); } InterfaceDeclaration *id = parent->isInterfaceDeclaration(); @@ -556,6 +534,10 @@ else { init = init->semantic(sc, type); + if (fd && isConst() && !isStatic()) + { // Make it static + storage_class |= STCstatic; + } } } } @@ -721,6 +703,7 @@ void TypeInfoDeclaration::semantic(Scope *sc) { + assert(linkage == LINKc); } /***************************** TypeInfoClassDeclaration ***********************/ diff -uNr gdc-0.8/d/dmd/declaration.h gdc-0.9/d/dmd/declaration.h --- gdc-0.8/d/dmd/declaration.h 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/declaration.h 2004-11-13 17:29:15.000000000 +0100 @@ -122,6 +122,10 @@ Type *getType(); void toCBuffer(OutBuffer *buf); + void toObjFile(); // compile to .obj file + void toDebug(); + int cvMember(unsigned char *p); + TypedefDeclaration *isTypedefDeclaration() { return this; } }; @@ -165,6 +169,7 @@ Symbol *toSymbol(); void toObjFile(); // compile to .obj file + int cvMember(unsigned char *p); // Eliminate need for dynamic_cast VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } @@ -269,6 +274,7 @@ int inlineNest; // !=0 if nested inline int semanticRun; // !=0 if semantic3() had been run int nestedFrameRef; // !=0 if nested variables referenced frame ptr + int introducing; // !=0 if 'introducing' function ForeachStatement *fes; // if foreach body, this is the foreach // Things that should really go into Scope @@ -313,6 +319,7 @@ Symbol *toSymbol(); Symbol *toThunkSymbol(int offset); // thunk version void toObjFile(); // compile to .obj file + int cvMember(unsigned char *p); FuncDeclaration *isFuncDeclaration() { return this; } }; diff -uNr gdc-0.8/d/dmd/dsymbol.c gdc-0.9/d/dmd/dsymbol.c --- gdc-0.8/d/dmd/dsymbol.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/dmd/dsymbol.c 2004-11-13 17:29:15.000000000 +0100 @@ -76,6 +76,36 @@ return ident ? ident->toChars() : (char *)"__anonymous"; } +char *Dsymbol::toPrettyChars() +{ Dsymbol *p; + char *s; + char *q; + size_t len; + + if (!parent) + return toChars(); + + len = 0; + for (p = this; p; p = p->parent) + len += strlen(p->toChars()) + 1; + + s = (char *)mem.malloc(len); + q = s + len - 1; + *q = 0; + for (p = this; 1; p = p->parent) + { + char *t = p->toChars(); + len = strlen(t); + q -= len; + memcpy(q, t, len); + if (q == s) + break; + q--; + *q = '.'; + } + return s; +} + char *Dsymbol::locToChars() { OutBuffer buf; @@ -105,7 +135,12 @@ Dsymbol *Dsymbol::toParent() { - Dsymbol *s = parent; + return parent ? parent->pastMixin() : NULL; +} + +Dsymbol *Dsymbol::pastMixin() +{ + Dsymbol *s = this; while (s && s->isTemplateMixin()) s = s->parent; @@ -251,7 +286,7 @@ printf("%s: ", p); mem.free(p); - printf("%s %s ", kind(), toChars()); + printf("%s %s ", kind(), toPrettyChars()); va_list ap; va_start(ap, format); @@ -274,7 +309,7 @@ printf("%s: ", p); mem.free(p); - printf("%s %s ", kind(), toChars()); + printf("%s %s ", kind(), toPrettyChars()); va_list ap; va_start(ap, format); @@ -411,7 +446,7 @@ { Declaration *d = s->isDeclaration(); if (d && d->protection == PROTprivate) - error("%s.%s is private", d->parent->toChars(), d->toChars()); + error("%s is private", d->toPrettyChars()); } } return s; @@ -465,13 +500,13 @@ //printf("s1 = '%s'\n", s1->toChars()); //printf("s2 = '%s', parent = %p\n", s2->toChars(), s2->parent); #if 1 - s1->error("conflicts with %s.%s at %s", - s2->parent->toChars(), s2->toChars(), + s1->error("conflicts with %s at %s", + s2->toPrettyChars(), s2->locToChars()); #else - s1->error("symbol %s.%s conflicts with %s.%s at %s", - s1->parent->toChars(), s1->toChars(), - s2->parent->toChars(), s2->toChars(), + s1->error("symbol %s conflicts with %s at %s", + s1->toPrettyChars(), + s2->toPrettyChars(), s2->locToChars()); #endif } diff -uNr gdc-0.8/d/dmd/dsymbol.h gdc-0.9/d/dmd/dsymbol.h --- gdc-0.8/d/dmd/dsymbol.h 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/dsymbol.h 2004-11-23 01:03:10.000000000 +0100 @@ -89,12 +89,14 @@ Dsymbol(); Dsymbol(Identifier *); char *toChars(); + char *toPrettyChars(); char *locToChars(); int equals(Object *o); int isAnonymous(); void error(Loc loc, const char *format, ...); void error(const char *format, ...); Module *getModule(); + Dsymbol *pastMixin(); Dsymbol *toParent(); int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol() @@ -127,11 +129,13 @@ virtual enum PROT prot(); virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees virtual Dsymbol *oneMember() { return this; } + virtual void addLocalClass(Array *) { } // Backend virtual Symbol *toSymbol(); // to backend symbol virtual void toObjFile(); // compile to .obj file + virtual int cvMember(unsigned char *p); // emit cv debug info for member Symbol *toImport(); // to backend import symbol static Symbol *toImport(Symbol *s); // to backend import symbol diff -uNr gdc-0.8/d/dmd/enum.h gdc-0.9/d/dmd/enum.h --- gdc-0.8/d/dmd/enum.h 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/enum.h 2004-11-13 17:29:15.000000000 +0100 @@ -7,12 +7,6 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. -/* NOTE: This file has been patched from the original DMD distribution to - work with the GDC compiler. - - Modified by David Friedman, September 2004 -*/ - #ifndef DMD_ENUM_H #define DMD_ENUM_H @@ -44,7 +38,9 @@ Type *getType(); char *kind(); - void toObjFile(); + void toObjFile(); // compile to .obj file + void toDebug(); + int cvMember(unsigned char *p); }; diff -uNr gdc-0.8/d/dmd/expression.c gdc-0.9/d/dmd/expression.c --- gdc-0.8/d/dmd/expression.c 2004-10-18 05:27:20.000000000 +0200 +++ gdc-0.9/d/dmd/expression.c 2004-12-18 21:22:55.000000000 +0100 @@ -61,14 +61,18 @@ { FuncDeclaration *fd; FuncDeclaration *fdthis; + //printf("hasThis()\n"); fdthis = sc->parent->isFuncDeclaration(); + //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis->toChars() : ""); // Go upwards until we find the enclosing member function fd = fdthis; while (1) { if (!fd) + { printf("test1\n"); goto Lno; + } if (!fd->isNested()) break; @@ -86,7 +90,9 @@ } if (!fd->isThis()) + { //printf("test2 '%s'\n", fd->toChars()); goto Lno; + } assert(fd->vthis); return fd; @@ -398,7 +404,6 @@ integer_t Expression::toInteger() { //printf("Expression %s\n", Token::toChars(op)); -//*(char*)0=0; error("Integer constant expression expected instead of %s", toChars()); return 0; } @@ -460,7 +465,7 @@ void Expression::checkIntegral() { if (!type->isintegral()) - error("'%s' is not an integral type", toChars()); + error("'%s' is not of integral type, it is a %s", toChars(), type->toChars()); } void Expression::checkArithmetic() @@ -600,6 +605,11 @@ IntegerExp::IntegerExp(Loc loc, integer_t value, Type *type) : Expression(loc, TOKint64, sizeof(IntegerExp)) { + if (type && !type->isscalar()) + { + error("integral constant must be scalar type, not %s", type->toChars()); + type = Type::terror; + } this->type = type; this->value = value; } @@ -638,7 +648,7 @@ { switch (t->ty) { - case Tbit: value = value != 0; break; + case Tbit: value = (value != 0); break; case Tint8: value = (d_int8) value; break; case Tchar: case Tuns8: value = (d_uns8) value; break; @@ -714,7 +724,8 @@ type = Type::tint32; } else - type = type->semantic(loc, sc); + { type = type->semantic(loc, sc); + } return this; } @@ -862,7 +873,11 @@ complex_t ImaginaryExp::toComplex() { +#ifdef __DMC__ + return value * I; +#else return complex_t(0, value); +#endif } Expression *ImaginaryExp::semantic(Scope *sc) @@ -904,6 +919,7 @@ { this->value = value; this->type = type; + //printf("ComplexExp::ComplexExp(%s)\n", toChars()); } char *ComplexExp::toChars() @@ -1183,6 +1199,7 @@ } error("%s '%s' is not a variable", s->kind(), s->toChars()); + type = Type::terror; return this; } @@ -1375,6 +1392,20 @@ this->committed = 0; } +int StringExp::equals(Object *o) +{ + //printf("StringExp::equals('%s')\n", o->toChars()); + if (o && o->dyncast() == DYNCAST_EXPRESSION) + { Expression *e = (Expression *)o; + + if (e->op == TOKstring) + { + return compare(o) == 0; + } + } + return FALSE; +} + char *StringExp::toChars() { OutBuffer buf; @@ -1420,10 +1451,32 @@ { case 1: return strcmp((char *)string, (char *)se2->string); + case 2: - return wcscmp((wchar_t *)string, (wchar_t *)se2->string); + { unsigned u; + d_wchar *s1 = (d_wchar *)string; + d_wchar *s2 = (d_wchar *)se2->string; + + for (u = 0; u < len; u++) + { + if (s1[u] != s2[u]) + return s1[u] - s2[u]; + } + } + case 4: - /* not implemented */ + { unsigned u; + d_dchar *s1 = (d_dchar *)string; + d_dchar *s2 = (d_dchar *)se2->string; + + for (u = 0; u < len; u++) + { + if (s1[u] != s2[u]) + return s1[u] - s2[u]; + } + } + break; + default: assert(0); } @@ -1669,6 +1722,8 @@ member = f->isCtorDeclaration(); assert(member); + cd->accessCheck(loc, sc, member); + tf = (TypeFunction *)f->type; type = tf->next; @@ -1807,6 +1862,11 @@ return this; } +int SymOffExp::isBool(int result) +{ + return result ? TRUE : FALSE; +} + void SymOffExp::toCBuffer(OutBuffer *buf) { if (offset) @@ -1815,11 +1875,6 @@ buf->printf("&%s", var->toChars()); } -int SymOffExp::isConst() -{ - return TRUE; -} - /******************************** VarExp **************************/ VarExp::VarExp(Loc loc, Declaration *var) @@ -2017,7 +2072,8 @@ { if (!sc->insert(declaration) || (declaration->isFuncDeclaration() && !sc->func->localsymtab->insert(declaration))) - error("declaration %s.%s is already defined", sc->func->toChars(), declaration->toChars()); + //error("declaration %s.%s is already defined", sc->func->toChars(), declaration->toChars()); + error("declaration %s is already defined", declaration->toPrettyChars()); } if (!declaration->isVarDeclaration()) { declaration->semantic(sc); @@ -2272,6 +2328,44 @@ //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; } + /* Special case: rewrite this.id and super.id + * to be classtype.id and baseclasstype.id + * if we have no this pointer. + */ + if ((e1->op == TOKthis || e1->op == TOKsuper) && !hasThis(sc)) + { ClassDeclaration *cd; + StructDeclaration *sd; + AggregateDeclaration *ad; + + ad = sc->getStructClassScope(); + cd = ad->isClassDeclaration(); + if (cd) + { + if (e1->op == TOKthis) + { + e = new TypeDotIdExp(loc, cd->type, ident); + return e->semantic(sc); + } + else if (cd->baseClass && e1->op == TOKsuper) + { + e = new TypeDotIdExp(loc, cd->baseClass->type, ident); + return e->semantic(sc); + } + } + else + { + sd = ad->isStructDeclaration(); + if (sd) + { + if (e1->op == TOKthis) + { + e = new TypeDotIdExp(loc, sd->type, ident); + return e->semantic(sc); + } + } + } + } + UnaExp::semantic(sc); e1 = resolveProperties(sc, e1); @@ -2640,6 +2734,7 @@ #if LOGSEMANTIC printf("DotTypeExp::semantic('%s')\n", toChars()); #endif + UnaExp::semantic(sc); return this; } @@ -2863,7 +2958,7 @@ ClassDeclaration *cd = NULL; if (sc->func) - cd = sc->func->parent->isClassDeclaration(); + cd = sc->func->toParent()->isClassDeclaration(); if (!cd || !cd->baseClass || !sc->func->isCtorDeclaration()) { error("super class constructor call must be in a constructor"); @@ -2898,10 +2993,12 @@ ClassDeclaration *cd = NULL; if (sc->func) - cd = sc->func->parent->isClassDeclaration(); + cd = sc->func->toParent()->isClassDeclaration(); if (!cd || !sc->func->isCtorDeclaration()) { error("class constructor call must be in a constructor"); + type = Type::terror; + return this; } else { @@ -4984,11 +5081,12 @@ return this; BinExp::semanticp(sc); - type = Type::tboolean; + //type = Type::tboolean; Type *t2b = e2->type->toBasetype(); if (t2b->ty != Taarray) { error("rvalue of in expression must be an associative array, not %s", e2->type->toChars()); + type = Type::terror; } else { @@ -4996,13 +5094,16 @@ // Convert key to type of key e1 = e1->implicitCastTo(ta->index); + + // Return type is pointer to value + type = ta->next->pointerTo(); } return this; } int InExp::isBit() { - return TRUE; + return FALSE; } @@ -5046,6 +5147,11 @@ error("array comparison type mismatch, %s vs %s", t1->next->toChars(), t2->next->toChars()); e = this; } + else if (t1->ty == Tstruct || t2->ty == Tstruct) + { + error("need member function opCmp() for struct %s to compare", t1->toChars()); + e = this; + } else e = this; return e; diff -uNr gdc-0.8/d/dmd/expression.h gdc-0.9/d/dmd/expression.h --- gdc-0.8/d/dmd/expression.h 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/expression.h 2004-12-18 21:22:55.000000000 +0100 @@ -265,6 +265,7 @@ unsigned char committed; // !=0 if type is committed StringExp(Loc loc, void *s, unsigned len); + int equals(Object *o); char *toChars(); Expression *semantic(Scope *sc); int implicitConvTo(Type *t); @@ -334,6 +335,8 @@ Expression *semantic(Scope *sc); void toCBuffer(OutBuffer *buf); int isConst(); + int isBool(int result); + Expression *doInline(InlineDoState *ids); elem *toElem(IRState *irs); dt_t **toDt(dt_t **pdt); @@ -884,6 +887,7 @@ AddExp(Loc loc, Expression *e1, Expression *e2); Expression *semantic(Scope *sc); Expression *constFold(); + Expression *optimize(int result); // For operator overloading int isCommutative(); @@ -898,6 +902,7 @@ MinExp(Loc loc, Expression *e1, Expression *e2); Expression *semantic(Scope *sc); Expression *constFold(); + Expression *optimize(int result); // For operator overloading Identifier *opId(); diff -uNr gdc-0.8/d/dmd/func.c gdc-0.9/d/dmd/func.c --- gdc-0.8/d/dmd/func.c 2004-10-15 01:21:22.000000000 +0200 +++ gdc-0.9/d/dmd/func.c 2004-11-13 17:29:15.000000000 +0100 @@ -62,6 +62,7 @@ inlineAsm = 0; semanticRun = 0; nestedFrameRef = 0; + introducing = 0; fes = NULL; } @@ -268,8 +269,10 @@ } } + // This is an 'introducing' function. // Append to end of vtbl[] //printf("\tappend with %p\n", this); + introducing = 1; vi = cd->vtbl.dim; cd->vtbl.push(this); vtblIndex = vi; @@ -1033,7 +1036,8 @@ { //printf("test4\n"); break; } - if (!s->parent || !s->parent->isTemplateInstance()) + if (!s->parent || + (!s->parent->isTemplateInstance())) { //printf("test5\n"); break; } diff -uNr gdc-0.8/d/dmd/html.c gdc-0.9/d/dmd/html.c --- gdc-0.8/d/dmd/html.c 2004-10-23 22:44:51.000000000 +0200 +++ gdc-0.9/d/dmd/html.c 2004-11-23 01:03:10.000000000 +0100 @@ -89,10 +89,12 @@ { switch (*p) { + /* case '"': case '\'': skipString(); continue; + */ case '<': if (p[1] == '!' && p[2] == '-' && p[3] == '-') @@ -102,7 +104,11 @@ } else if ((p[1] == '/' && istagstart(p[2])) || istagstart(p[1])) + { skipTag(); + } + else + p++; continue; case 0: @@ -197,6 +203,8 @@ { error("nested tag"); skipTag(); } + else + p++; // Treat comments as if they were whitespace state = TSrest; continue; @@ -507,6 +515,7 @@ { "quot", 34, "amp", 38, + "apos", 39, "lt", 60, "gt", 62, // "nbsp", 160, diff -uNr gdc-0.8/d/dmd/idgen.c gdc-0.9/d/dmd/idgen.c --- gdc-0.8/d/dmd/idgen.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/dmd/idgen.c 2004-12-18 21:22:55.000000000 +0100 @@ -35,7 +35,7 @@ { "This", "this" }, { "ctor", "_ctor" }, { "dtor", "_dtor" }, - { "classInvariant", "_invariant" }, + { "classInvariant", "__invariant" }, { "unitTest", "_unitTest" }, { "staticCtor", "_staticCtor" }, { "staticDtor", "_staticDtor" }, @@ -44,7 +44,9 @@ { "__sizeof", "sizeof" }, { "alignof" }, { "length" }, + { "ptr" }, { "offset" }, + { "offsetof" }, { "ModuleInfo" }, { "ClassInfo" }, { "classinfo" }, @@ -58,8 +60,8 @@ { "empty", "" }, { "TypeInfo" }, - { "TypeInfoClass" }, - { "TypeInfoTypedef" }, + { "TypeInfo_Class" }, + { "TypeInfo_Typedef" }, { "_arguments" }, { "_argptr" }, diff -uNr gdc-0.8/d/dmd/impcnvgen.c gdc-0.9/d/dmd/impcnvgen.c --- gdc-0.8/d/dmd/impcnvgen.c 2004-04-18 04:14:33.000000000 +0200 +++ gdc-0.9/d/dmd/impcnvgen.c 2004-12-18 21:22:55.000000000 +0100 @@ -16,6 +16,22 @@ enum TY impcnvType1[TMAX][TMAX]; enum TY impcnvType2[TMAX][TMAX]; +int integral_promotion(int t) +{ + switch (t) + { + case Tchar: + case Twchar: + case Tbit: + case Tint8: + case Tuns8: + case Tint16: + case Tuns16: return Tint32; + case Tdchar: return Tuns32; + default: return t; + } +} + void init() { int i, j; @@ -40,9 +56,9 @@ X(Tbit,Tint16, Tint32,Tint32, Tint32) X(Tbit,Tuns16, Tint32,Tint32, Tint32) X(Tbit,Tint32, Tint32,Tint32, Tint32) - X(Tbit,Tuns32, Tint32,Tuns32, Tint32) + X(Tbit,Tuns32, Tuns32,Tuns32, Tuns32) X(Tbit,Tint64, Tint64,Tint64, Tint64) - X(Tbit,Tuns64, Tint64,Tuns64, Tint64) + X(Tbit,Tuns64, Tuns64,Tuns64, Tuns64) X(Tbit,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tbit,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -56,15 +72,14 @@ /* ======================= */ - X(Tint8,Tbit, Tint32,Tint32, Tint32) X(Tint8,Tint8, Tint32,Tint32, Tint32) X(Tint8,Tuns8, Tint32,Tint32, Tint32) X(Tint8,Tint16, Tint32,Tint32, Tint32) X(Tint8,Tuns16, Tint32,Tint32, Tint32) X(Tint8,Tint32, Tint32,Tint32, Tint32) - X(Tint8,Tuns32, Tint32,Tuns32, Tint32) + X(Tint8,Tuns32, Tuns32,Tuns32, Tuns32) X(Tint8,Tint64, Tint64,Tint64, Tint64) - X(Tint8,Tuns64, Tint64,Tuns64, Tint64) + X(Tint8,Tuns64, Tuns64,Tuns64, Tuns64) X(Tint8,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tint8,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -78,15 +93,13 @@ /* ======================= */ - X(Tuns8,Tbit, Tint32,Tint32, Tint32) - X(Tuns8,Tint8, Tint32,Tint32, Tint32) X(Tuns8,Tuns8, Tint32,Tint32, Tint32) X(Tuns8,Tint16, Tint32,Tint32, Tint32) X(Tuns8,Tuns16, Tint32,Tint32, Tint32) X(Tuns8,Tint32, Tint32,Tint32, Tint32) - X(Tuns8,Tuns32, Tint32,Tuns32, Tint32) + X(Tuns8,Tuns32, Tuns32,Tuns32, Tuns32) X(Tuns8,Tint64, Tint64,Tint64, Tint64) - X(Tuns8,Tuns64, Tint64,Tuns64, Tint64) + X(Tuns8,Tuns64, Tuns64,Tuns64, Tuns64) X(Tuns8,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tuns8,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -100,15 +113,12 @@ /* ======================= */ - X(Tint16,Tbit, Tint32,Tint32, Tint32) - X(Tint16,Tint8, Tint32,Tint32, Tint32) - X(Tint16,Tuns8, Tint32,Tint32, Tint32) X(Tint16,Tint16, Tint32,Tint32, Tint32) X(Tint16,Tuns16, Tint32,Tint32, Tint32) X(Tint16,Tint32, Tint32,Tint32, Tint32) - X(Tint16,Tuns32, Tint32,Tuns32, Tint32) + X(Tint16,Tuns32, Tuns32,Tuns32, Tuns32) X(Tint16,Tint64, Tint64,Tint64, Tint64) - X(Tint16,Tuns64, Tint64,Tuns64, Tint64) + X(Tint16,Tuns64, Tuns64,Tuns64, Tuns64) X(Tint16,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tint16,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -122,15 +132,11 @@ /* ======================= */ - X(Tuns16,Tbit, Tint32,Tint32, Tint32) - X(Tuns16,Tint8, Tint32,Tint32, Tint32) - X(Tuns16,Tuns8, Tint32,Tint32, Tint32) - X(Tuns16,Tint16, Tint32,Tint32, Tint32) X(Tuns16,Tuns16, Tint32,Tint32, Tint32) X(Tuns16,Tint32, Tint32,Tint32, Tint32) - X(Tuns16,Tuns32, Tint32,Tuns32, Tint32) + X(Tuns16,Tuns32, Tuns32,Tuns32, Tuns32) X(Tuns16,Tint64, Tint64,Tint64, Tint64) - X(Tuns16,Tuns64, Tint64,Tuns64, Tint64) + X(Tuns16,Tuns64, Tuns64,Tuns64, Tuns64) X(Tuns16,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tuns16,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -144,15 +150,10 @@ /* ======================= */ - X(Tint32,Tbit, Tint32,Tint32, Tint32) - X(Tint32,Tint8, Tint32,Tint32, Tint32) - X(Tint32,Tuns8, Tint32,Tint32, Tint32) - X(Tint32,Tint16, Tint32,Tint32, Tint32) - X(Tint32,Tuns16, Tint32,Tint32, Tint32) X(Tint32,Tint32, Tint32,Tint32, Tint32) - X(Tint32,Tuns32, Tint32,Tuns32, Tint32) + X(Tint32,Tuns32, Tuns32,Tuns32, Tuns32) X(Tint32,Tint64, Tint64,Tint64, Tint64) - X(Tint32,Tuns64, Tint64,Tuns64, Tint64) + X(Tint32,Tuns64, Tuns64,Tuns64, Tuns64) X(Tint32,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tint32,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -166,15 +167,9 @@ /* ======================= */ - X(Tuns32,Tbit, Tuns32,Tint32, Tint32) - X(Tuns32,Tint8, Tuns32,Tint32, Tint32) - X(Tuns32,Tuns8, Tuns32,Tint32, Tint32) - X(Tuns32,Tint16, Tuns32,Tint32, Tint32) - X(Tuns32,Tuns16, Tuns32,Tint32, Tint32) - X(Tuns32,Tint32, Tuns32,Tint32, Tint32) - X(Tuns32,Tuns32, Tuns32,Tuns32, Tint32) - X(Tuns32,Tint64, Tuns64,Tint64, Tint64) - X(Tuns32,Tuns64, Tuns64,Tuns64, Tint64) + X(Tuns32,Tuns32, Tuns32,Tuns32, Tuns32) + X(Tuns32,Tint64, Tint64,Tint64, Tint64) + X(Tuns32,Tuns64, Tuns64,Tuns64, Tuns64) X(Tuns32,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tuns32,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -188,15 +183,8 @@ /* ======================= */ - X(Tint64,Tbit, Tint64,Tint64, Tint64) - X(Tint64,Tint8, Tint64,Tint64, Tint64) - X(Tint64,Tuns8, Tint64,Tint64, Tint64) - X(Tint64,Tint16, Tint64,Tint64, Tint64) - X(Tint64,Tuns16, Tint64,Tint64, Tint64) - X(Tint64,Tint32, Tint64,Tint64, Tint64) - X(Tint64,Tuns32, Tint64,Tint64, Tint64) X(Tint64,Tint64, Tint64,Tint64, Tint64) - X(Tint64,Tuns64, Tint64,Tuns64, Tint64) + X(Tint64,Tuns64, Tuns64,Tuns64, Tuns64) X(Tint64,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tint64,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -210,14 +198,6 @@ /* ======================= */ - X(Tuns64,Tbit, Tuns64,Tint64, Tint64) - X(Tuns64,Tint8, Tuns64,Tint64, Tint64) - X(Tuns64,Tuns8, Tuns64,Tint64, Tint64) - X(Tuns64,Tint16, Tuns64,Tint64, Tint64) - X(Tuns64,Tuns16, Tuns64,Tint64, Tint64) - X(Tuns64,Tint32, Tuns64,Tint64, Tint64) - X(Tuns64,Tuns32, Tuns64,Tint64, Tint64) - X(Tuns64,Tint64, Tuns64,Tint64, Tint64) X(Tuns64,Tuns64, Tuns64,Tuns64, Tuns64) X(Tuns64,Tfloat32, Tfloat32,Tfloat32, Tfloat32) @@ -232,16 +212,6 @@ /* ======================= */ - X(Tfloat32,Tbit, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tint8, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tuns8, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tint16, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tuns16, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tint32, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tuns32, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tint64, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tuns64, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tfloat32,Tfloat64, Tfloat64,Tfloat64, Tfloat64) X(Tfloat32,Tfloat80, Tfloat80,Tfloat80, Tfloat80) @@ -256,17 +226,6 @@ /* ======================= */ - X(Tfloat64,Tbit, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tint8, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tuns8, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tint16, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tuns16, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tint32, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tuns32, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tint64, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tuns64, Tfloat64,Tfloat64, Tfloat64) - - X(Tfloat64,Tfloat32, Tfloat64,Tfloat64, Tfloat64) X(Tfloat64,Tfloat64, Tfloat64,Tfloat64, Tfloat64) X(Tfloat64,Tfloat80, Tfloat80,Tfloat80, Tfloat80) @@ -280,18 +239,6 @@ /* ======================= */ - X(Tfloat80,Tbit, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tint8, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tuns8, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tint16, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tuns16, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tint32, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tuns32, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tint64, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tuns64, Tfloat80,Tfloat80, Tfloat80) - - X(Tfloat80,Tfloat32, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tfloat64, Tfloat80,Tfloat80, Tfloat80) X(Tfloat80,Tfloat80, Tfloat80,Tfloat80, Tfloat80) X(Tfloat80,Timaginary32, Tfloat80,Timaginary80, Tfloat80) @@ -304,20 +251,6 @@ /* ======================= */ - X(Timaginary32,Tbit, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tint8, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tuns8, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tint16, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tuns16, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tint32, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tuns32, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tint64, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tuns64, Timaginary32,Tfloat32, Tfloat32) - - X(Timaginary32,Tfloat32, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tfloat64, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary32,Tfloat80, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary32,Timaginary32, Timaginary32,Timaginary32, Timaginary32) X(Timaginary32,Timaginary64, Timaginary64,Timaginary64, Timaginary64) X(Timaginary32,Timaginary80, Timaginary80,Timaginary80, Timaginary80) @@ -328,21 +261,6 @@ /* ======================= */ - X(Timaginary64,Tbit, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tint8, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tuns8, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tint16, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tuns16, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tint32, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tuns32, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tint64, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tuns64, Timaginary64,Tfloat64, Tfloat64) - - X(Timaginary64,Tfloat32, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tfloat64, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tfloat80, Timaginary80,Tfloat80, Tfloat80) - - X(Timaginary64,Timaginary32, Timaginary64,Timaginary64, Timaginary64) X(Timaginary64,Timaginary64, Timaginary64,Timaginary64, Timaginary64) X(Timaginary64,Timaginary80, Timaginary80,Timaginary80, Timaginary80) @@ -352,22 +270,6 @@ /* ======================= */ - X(Timaginary80,Tbit, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tint8, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tuns8, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tint16, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tuns16, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tint32, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tuns32, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tint64, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tuns64, Timaginary80,Tfloat80, Tfloat80) - - X(Timaginary80,Tfloat32, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tfloat64, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tfloat80, Timaginary80,Tfloat80, Tfloat80) - - X(Timaginary80,Timaginary32, Timaginary80,Timaginary80, Timaginary80) - X(Timaginary80,Timaginary64, Timaginary80,Timaginary80, Timaginary80) X(Timaginary80,Timaginary80, Timaginary80,Timaginary80, Timaginary80) X(Timaginary80,Tcomplex32, Timaginary80,Tcomplex80, Tcomplex80) @@ -376,75 +278,29 @@ /* ======================= */ - X(Tcomplex32,Tbit, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tint8, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tuns8, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tint16, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tuns16, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tint32, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tuns32, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tint64, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tuns64, Tcomplex32,Tfloat32, Tcomplex32) - - X(Tcomplex32,Tfloat32, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tfloat64, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex32,Tfloat80, Tcomplex80,Tfloat80, Tcomplex80) - - X(Tcomplex32,Timaginary32, Tcomplex32,Timaginary32, Tcomplex32) - X(Tcomplex32,Timaginary64, Tcomplex64,Timaginary64, Tcomplex64) - X(Tcomplex32,Timaginary80, Tcomplex80,Timaginary80, Tcomplex80) - X(Tcomplex32,Tcomplex32, Tcomplex32,Tcomplex32, Tcomplex32) X(Tcomplex32,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64) X(Tcomplex32,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80) /* ======================= */ - X(Tcomplex64,Tbit, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tint8, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tuns8, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tint16, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tuns16, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tint32, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tuns32, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tint64, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tuns64, Tcomplex64,Tfloat64, Tcomplex64) - - X(Tcomplex64,Tfloat32, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tfloat64, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tfloat80, Tcomplex80,Tfloat80, Tcomplex80) - - X(Tcomplex64,Timaginary32, Tcomplex64,Timaginary64, Tcomplex64) - X(Tcomplex64,Timaginary64, Tcomplex64,Timaginary64, Tcomplex64) - X(Tcomplex64,Timaginary80, Tcomplex80,Timaginary80, Tcomplex80) - - X(Tcomplex64,Tcomplex32, Tcomplex64,Tcomplex64, Tcomplex64) X(Tcomplex64,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64) X(Tcomplex64,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80) /* ======================= */ - X(Tcomplex80,Tbit, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tint8, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tuns8, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tint16, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tuns16, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tint32, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tuns32, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tint64, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tuns64, Tcomplex80,Tfloat80, Tcomplex80) - - X(Tcomplex80,Tfloat32, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tfloat64, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tfloat80, Tcomplex80,Tfloat80, Tcomplex80) - - X(Tcomplex80,Timaginary32, Tcomplex80,Timaginary80, Tcomplex80) - X(Tcomplex80,Timaginary64, Tcomplex80,Timaginary80, Tcomplex80) - X(Tcomplex80,Timaginary80, Tcomplex80,Timaginary80, Tcomplex80) - - X(Tcomplex80,Tcomplex32, Tcomplex80,Tcomplex80, Tcomplex80) - X(Tcomplex80,Tcomplex64, Tcomplex80,Tcomplex80, Tcomplex80) X(Tcomplex80,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80) + + for (i = 0; i < TMAX; i++) + for (j = 0; j < TMAX; j++) + { + if (impcnvResult[i][j] == Terror) + { + impcnvResult[i][j] = impcnvResult[j][i]; + impcnvType1[i][j] = impcnvType2[j][i]; + impcnvType2[i][j] = impcnvType1[j][i]; + } + } } int main() diff -uNr gdc-0.8/d/dmd/inline.c gdc-0.9/d/dmd/inline.c --- gdc-0.8/d/dmd/inline.c 2004-09-29 04:25:48.000000000 +0200 +++ gdc-0.9/d/dmd/inline.c 2004-12-18 21:22:55.000000000 +0100 @@ -353,6 +353,24 @@ return copy(); } +Expression *SymOffExp::doInline(InlineDoState *ids) +{ + int i; + + //printf("SymOffExp::doInline(%s)\n", toChars()); + for (i = 0; i < ids->from.dim; i++) + { + if (var == (Declaration *)ids->from.data[i]) + { + SymOffExp *se = (SymOffExp *)copy(); + + se->var = (Declaration *)ids->to.data[i]; + return se; + } + } + return this; +} + Expression *VarExp::doInline(InlineDoState *ids) { int i; @@ -986,6 +1004,8 @@ vto->storage_class |= vfrom->storage_class & (STCin | STCout); vto->linkage = vfrom->linkage; vto->parent = iss->fd; + //printf("vto = '%s', vto->storage_class = x%x\n", vto->toChars(), vto->storage_class); + //printf("vto->parent = '%s'\n", iss->fd->toChars()); ve = new VarExp(vto->loc, vto); ve->type = vto->type; diff -uNr gdc-0.8/d/dmd/lexer.c gdc-0.9/d/dmd/lexer.c --- gdc-0.8/d/dmd/lexer.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/lexer.c 2004-12-18 21:22:55.000000000 +0100 @@ -24,9 +24,11 @@ #include #include -#if ! HAVE_DECL_STRTOLD +#ifndef IN_GCC +#if __GNUC__ extern "C" long double strtold(const char *p,char **endp); #endif +#endif #if _WIN32 #include "..\root\mem.h" @@ -1546,7 +1548,9 @@ case FLAGS_decimal: if (n & 0x8000000000000000LL) + { error("signed integer overflow"); result = TOKuns64v; + } else if (n & 0xFFFFFFFF80000000LL) result = TOKint64v; else @@ -1561,9 +1565,17 @@ result = TOKuns32v; break; - case FLAGS_long: case FLAGS_decimal | FLAGS_long: if (n & 0x8000000000000000LL) + { error("signed integer overflow"); + result = TOKuns64v; + } + else + result = TOKint64v; + break; + + case FLAGS_long: + if (n & 0x8000000000000000LL) result = TOKuns64v; else result = TOKint64v; @@ -2093,8 +2105,8 @@ Token::tochars[TOKminusminus] = "--"; Token::tochars[TOKtype] = "type"; Token::tochars[TOKquestion] = "?"; - Token::tochars[TOKneg] = "neg"; - Token::tochars[TOKuadd] = "uadd"; + Token::tochars[TOKneg] = "-"; + Token::tochars[TOKuadd] = "+"; Token::tochars[TOKvar] = "var"; Token::tochars[TOKaddass] = "+="; Token::tochars[TOKminass] = "-="; diff -uNr gdc-0.8/d/dmd/mangle.c gdc-0.9/d/dmd/mangle.c --- gdc-0.8/d/dmd/mangle.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/dmd/mangle.c 2004-12-18 21:22:55.000000000 +0100 @@ -56,6 +56,10 @@ case LINKcpp: return ident->toChars(); + case LINKdefault: + error("forward declaration"); + return ident->toChars(); + default: printf("'%s', linkage = %d\n", toChars(), linkage); assert(0); @@ -133,8 +137,8 @@ * names for them. */ if (ident == Id::TypeInfo || - ident == Id::TypeInfoClass || - ident == Id::TypeInfoTypedef || + ident == Id::TypeInfo_Class || + ident == Id::TypeInfo_Typedef || ident == Id::Exception || ident == Id::Object || ident == Id::ClassInfo || diff -uNr gdc-0.8/d/dmd/mars.c gdc-0.9/d/dmd/mars.c --- gdc-0.8/d/dmd/mars.c 2004-09-29 04:25:48.000000000 +0200 +++ gdc-0.9/d/dmd/mars.c 2004-12-18 21:22:55.000000000 +0100 @@ -11,11 +11,16 @@ #include #include #include +#include #if __DMC__ #include #endif +#if linux +#include +#endif + #include "mem.h" #include "root.h" @@ -44,7 +49,7 @@ copyright = "Copyright (c) 1999-2004 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.102"; + version = "v0.109"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); @@ -181,18 +186,19 @@ global.params.objfiles = new Array(); // Predefine version identifiers - VersionCondition::addGlobalIdent("DigitalMars"); + VersionCondition::addPredefinedGlobalIdent("DigitalMars"); #if _WIN32 - VersionCondition::addGlobalIdent("Windows"); - VersionCondition::addGlobalIdent("Win32"); + VersionCondition::addPredefinedGlobalIdent("Windows"); + VersionCondition::addPredefinedGlobalIdent("Win32"); #endif #if linux - VersionCondition::addGlobalIdent("linux"); + VersionCondition::addPredefinedGlobalIdent("linux"); global.params.isLinux = 1; #endif /* linux */ - VersionCondition::addGlobalIdent("X86"); - VersionCondition::addGlobalIdent("LittleEndian"); - VersionCondition::addGlobalIdent("D_InlineAsm"); + VersionCondition::addPredefinedGlobalIdent("X86"); + VersionCondition::addPredefinedGlobalIdent("LittleEndian"); + VersionCondition::addPredefinedGlobalIdent("D_InlineAsm"); + VersionCondition::addPredefinedGlobalIdent("all"); #if _WIN32 inifile(argv[0], "sc.ini"); @@ -275,12 +281,21 @@ if (p[6] == '=') { if (isdigit(p[7])) - DebugCondition::setGlobalLevel(atoi(p + 7)); - else if (isalpha(p[7])) + { long level; + + errno = 0; + level = strtol(p + 7, &p, 10); + if (*p || errno || level > INT_MAX) + goto Lerror; + DebugCondition::setGlobalLevel((int)level); + } + else if (isalpha(p[7]) || p[7] == '_') DebugCondition::addGlobalIdent(p + 7); else goto Lerror; } + else if (p[6]) + goto Lerror; else global.params.debuglevel = 1; } @@ -292,8 +307,15 @@ if (p[8] == '=') { if (isdigit(p[9])) - VersionCondition::setGlobalLevel(atoi(p + 9)); - else if (isalpha(p[9])) + { long level; + + errno = 0; + level = strtol(p + 9, &p, 10); + if (*p || errno || level > INT_MAX) + goto Lerror; + VersionCondition::setGlobalLevel((int)level); + } + else if (isalpha(p[9]) || p[9] == '_') VersionCondition::addGlobalIdent(p + 9); else goto Lerror; @@ -320,11 +342,11 @@ else { Lerror: - error("unrecognized switch '%s'",p); + error("unrecognized switch '%s'", argv[i]); continue; Lnoarg: - error("argument expected for switch '%s'",p); + error("argument expected for switch '%s'", argv[i]); continue; } } @@ -452,6 +474,15 @@ name = (char *)mem.malloc((ext - p) + 1); memcpy(name, p, ext - p); name[ext - p] = 0; // strip extension + + if (name[0] == 0 || + strcmp(name, "..") == 0 || + strcmp(name, ".") == 0) + { + Linvalid: + error("invalid file name '%s'", (char *)files.data[i]); + fatal(); + } } else { error("unrecognized file extension %s\n", ext); @@ -459,7 +490,11 @@ } } else - name = p; + { name = p; + if (!*name) + goto Linvalid; + } + id = new Identifier(name, 0); m = new Module((char *) files.data[i], id); modules.push(m); diff -uNr gdc-0.8/d/dmd/mars.h gdc-0.9/d/dmd/mars.h --- gdc-0.8/d/dmd/mars.h 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/mars.h 2004-12-18 21:22:55.000000000 +0100 @@ -128,7 +128,9 @@ typedef long double d_float80; // Note: this will be 2 bytes on Win32 systems, and 4 bytes under linux. -typedef wchar_t d_wchar; +typedef d_uns8 d_char; +typedef d_uns16 d_wchar; +typedef d_uns32 d_dchar; #ifdef IN_GCC #include "d-gcc-real.h" diff -uNr gdc-0.8/d/dmd/module.c gdc-0.9/d/dmd/module.c --- gdc-0.8/d/dmd/module.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/module.c 2004-12-18 21:22:55.000000000 +0100 @@ -221,6 +221,7 @@ unsigned char *buf; unsigned buflen; unsigned le; + unsigned bom; //printf("Module::parse()\n"); @@ -241,6 +242,7 @@ * EF BB BF UTF-8 */ + bom = 1; // assume there's a BOM if (buf[0] == 0xFF && buf[1] == 0xFE) { if (buflen >= 4 && buf[2] == 0 && buf[3] == 0) @@ -258,7 +260,7 @@ } dbuf.reserve(buflen / 4); - while (++pu < pumax) + for (pu += bom; pu < pumax; pu++) { unsigned u; u = le ? readlongLE(pu) : readlongBE(pu); @@ -293,7 +295,7 @@ } dbuf.reserve(buflen / 2); - while (++pu < pumax) + for (pu += bom; pu < pumax; pu++) { unsigned u; u = le ? readwordLE(pu) : readwordBE(pu); @@ -354,6 +356,7 @@ * figure out the encoding. */ + bom = 0; if (buflen >= 4) { if (buf[1] == 0 && buf[2] == 0 && buf[3] == 0) { // UTF-32LE diff -uNr gdc-0.8/d/dmd/mtype.c gdc-0.9/d/dmd/mtype.c --- gdc-0.8/d/dmd/mtype.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/mtype.c 2004-12-18 21:22:55.000000000 +0100 @@ -348,6 +348,7 @@ //printf("merge(%s)\n", toChars()); t = this; + assert(t); if (!deco) { OutBuffer buf; @@ -526,6 +527,13 @@ { if (ident == Id::offset) { + if (!global.params.useDeprecated) + error(e->loc, ".offset deprecated, use .offsetof"); + goto Loffset; + } + else if (ident == Id::offsetof) + { + Loffset: if (v->storage_class & STCfield) { e = new IntegerExp(e->loc, v->offset, Type::tint32); @@ -1359,7 +1367,8 @@ e = e->castTo(n->arrayOf()); // convert to dynamic array arguments = new Array(); arguments->push(e); - arguments->push(n->getInternalTypeInfo()); + arguments->push(n->ty == Tsarray ? n->getTypeInfo(sc) // don't convert to dynamic array + : n->getInternalTypeInfo()); e = new CallExp(e->loc, ec, arguments); e->type = next->arrayOf(); } @@ -1554,6 +1563,10 @@ { e = dim; } + else if (ident == Id::ptr) + { + e = e->castTo(next->pointerTo()); + } else { e = TypeArray::dotExp(sc, e, ident); @@ -1685,6 +1698,11 @@ e->type = Type::tsize_t; return e; } + else if (ident == Id::ptr) + { + e = e->castTo(next->pointerTo()); + return e; + } else { e = TypeArray::dotExp(sc, e, ident); @@ -2562,6 +2580,7 @@ Expression *e; //printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc, toChars()); + //printf("\tscopesym = '%s'\n", scopesym->toChars()); *pe = NULL; *pt = NULL; *ps = NULL; @@ -2643,7 +2662,7 @@ if (v) { // It's not a type, it's an expression - if (v->isConst()) + if (v->isConst() && v->getExpInitializer()) { ExpInitializer *ei = v->getExpInitializer(); assert(ei); @@ -2685,7 +2704,18 @@ } if (t->ty == Tident && t != this) { - ((TypeIdentifier *)t)->resolve(loc, sc, pe, &t, ps); + Scope *scx; + + for (scx = sc; 1; scx = scx->enclosing) + { + if (!scx) + { error(loc, "forward reference to '%s'", t->toChars()); + return; + } + if (scx->scopesym == scopesym) + break; + } + ((TypeIdentifier *)t)->resolve(loc, scx, pe, &t, ps); } *pt = t->merge(); } diff -uNr gdc-0.8/d/dmd/opover.c gdc-0.9/d/dmd/opover.c --- gdc-0.8/d/dmd/opover.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/opover.c 2004-11-13 17:29:15.000000000 +0100 @@ -13,7 +13,7 @@ */ -// Issues with using -include total.h (defines integer_t) and then complex.h fails... +// Issues with using -include total.h (defines integer_t) and then complex.h fails... #undef integer_t #include @@ -248,6 +248,7 @@ * and see which is better. */ Expression *e; + FuncDeclaration *lastf; args1.setDim(1); args1.data[0] = (void*) e1; @@ -258,6 +259,7 @@ memset(&m, 0, sizeof(m)); m.last = MATCHnomatch; overloadResolveX(&m, fd, &args2); + lastf = m.lastf; overloadResolveX(&m, fd_r, &args1); if (m.count > 1) @@ -279,10 +281,10 @@ // Rewrite (e1 ++ e2) as e1.postinc() // Rewrite (e1 -- e2) as e1.postdec() e = build_overload(loc, sc, e1, NULL, id); - else if (m.lastf->ident == id) + else if (lastf && m.lastf == lastf || m.last == MATCHnomatch) // Rewrite (e1 op e2) as e1.opfunc(e2) e = build_overload(loc, sc, e1, e2, id); - else if (m.lastf->ident == id_r) + else // Rewrite (e1 op e2) as e2.opfunc_r(e1) e = build_overload(loc, sc, e2, e1, id_r); return e; @@ -307,6 +309,7 @@ * and see which is better. */ Expression *e; + FuncDeclaration *lastf; if (!argsset) { args1.setDim(1); @@ -318,6 +321,7 @@ memset(&m, 0, sizeof(m)); m.last = MATCHnomatch; overloadResolveX(&m, fd_r, &args2); + lastf = m.lastf; overloadResolveX(&m, fd, &args1); if (m.count > 1) @@ -332,12 +336,13 @@ { m.lastf = m.anyf; } - if (m.lastf->ident == id) - // Rewrite (e1 op e2) as e2.opfunc(e1) - e = build_overload(loc, sc, e2, e1, id); - else if (m.lastf->ident == id_r) + + if (lastf && m.lastf == lastf || m.last == MATCHnomatch) // Rewrite (e1 op e2) as e1.opfunc_r(e2) e = build_overload(loc, sc, e1, e2, id_r); + else + // Rewrite (e1 op e2) as e2.opfunc(e1) + e = build_overload(loc, sc, e2, e1, id); // When reversing operands of comparison operators, // need to reverse the sense of the op @@ -402,9 +407,10 @@ s = ad->search(funcid, 0); if (s) - { - s = s->toAlias(); - fd = s->isFuncDeclaration(); + { Dsymbol *s2; + + s2 = s->toAlias(); + fd = s2->isFuncDeclaration(); if (fd && fd->type->ty == Tfunction) return fd; diff -uNr gdc-0.8/d/dmd/optimize.c gdc-0.9/d/dmd/optimize.c --- gdc-0.8/d/dmd/optimize.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/dmd/optimize.c 2004-12-18 21:22:55.000000000 +0100 @@ -30,7 +30,7 @@ { Expression *e; e1 = e1->optimize(result); - if (e1->isConst()) + if (e1->isConst() == 1) e = constFold(); else e = this; @@ -58,7 +58,7 @@ } if (e1->op == TOKvar) { VarExp *ve = (VarExp *)e1; - if (!ve->var->isOut()) + if (!ve->var->isOut() && !ve->var->isImportedSymbol()) { e = new SymOffExp(loc, ve->var, 0); e->type = type; @@ -73,7 +73,8 @@ { integer_t index = ae->e2->toInteger(); VarExp *ve = (VarExp *)ae->e1; - if (ve->type->ty == Tsarray && ve->type->next->ty != Tbit) + if (ve->type->ty == Tsarray && ve->type->next->ty != Tbit + && !ve->var->isImportedSymbol()) { TypeSArray *ts = (TypeSArray *)ve->type; integer_t dim = ts->dim->toInteger(); @@ -142,7 +143,14 @@ } } - return UnaExp::optimize(result); + Expression *e; + + e1 = e1->optimize(result); + if (e1->isConst()) + e = constFold(); + else + e = this; + return e; } Expression *BinExp::optimize(int result) @@ -150,6 +158,30 @@ e1 = e1->optimize(result); e2 = e2->optimize(result); + if (e1->isConst() == 1 && e2->isConst() == 1) + e = constFold(); + else + e = this; + return e; +} + +Expression *AddExp::optimize(int result) +{ Expression *e; + + e1 = e1->optimize(result); + e2 = e2->optimize(result); + if (e1->isConst() && e2->isConst()) + e = constFold(); + else + e = this; + return e; +} + +Expression *MinExp::optimize(int result) +{ Expression *e; + + e1 = e1->optimize(result); + e2 = e2->optimize(result); if (e1->isConst() && e2->isConst()) e = constFold(); else @@ -179,12 +211,12 @@ e1 = e1->optimize(WANTflags); e2 = e2->optimize(WANTflags); e = this; - if (e1->isConst()) + if (e1->isBool(FALSE)) + e = new IntegerExp(loc, 0, type); + else if (e1->isConst()) { if (e2->isConst()) e = constFold(); - else if (e1->isBool(FALSE)) - e = new IntegerExp(loc, 0, type); else if (e1->isBool(TRUE)) e = new BoolExp(loc, e2, type); } @@ -197,12 +229,12 @@ e1 = e1->optimize(WANTflags); e2 = e2->optimize(WANTflags); e = this; - if (e1->isConst()) + if (e1->isBool(TRUE)) + e = new IntegerExp(loc, 1, type); + else if (e1->isConst()) { if (e2->isConst()) e = constFold(); - else if (e1->isBool(TRUE)) - e = new IntegerExp(loc, 1, type); else if (e1->isBool(FALSE)) e = new BoolExp(loc, e2, type); } @@ -215,9 +247,7 @@ //printf("CatExp::optimize(%d)\n", result); e1 = e1->optimize(result); e2 = e2->optimize(result); - if (e1->isConst() && e2->isConst()) - e = constFold(); - else if (e1->op == TOKstring && e2->op == TOKstring) + if (e1->op == TOKstring && e2->op == TOKstring) { // Concatenate the strings void *s; diff -uNr gdc-0.8/d/dmd/parse.c gdc-0.9/d/dmd/parse.c --- gdc-0.8/d/dmd/parse.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/parse.c 2004-12-18 21:22:55.000000000 +0100 @@ -910,7 +910,8 @@ } Dsymbol *Parser::parseAggregate() -{ AggregateDeclaration *a; +{ AggregateDeclaration *a = NULL; + int anon = 0; enum TOK tok; Identifier *id; Array *tpl = NULL; @@ -924,13 +925,13 @@ else { id = token.ident; nextToken(); - } - if (token.value == TOKlparen) - { // Class template declaration. + if (token.value == TOKlparen) + { // Class template declaration. - // Gather template parameter list - tpl = parseTemplateParameterList(); + // Gather template parameter list + tpl = parseTemplateParameterList(); + } } switch (tok) @@ -991,31 +992,47 @@ } case TOKstruct: - a = new StructDeclaration(loc, id); + if (id) + a = new StructDeclaration(loc, id); + else + anon = 1; break; case TOKunion: - a = new UnionDeclaration(loc, id); + if (id) + a = new UnionDeclaration(loc, id); + else + anon = 2; break; default: assert(0); break; } - if (token.value == TOKsemicolon) - nextToken(); + if (a && token.value == TOKsemicolon) + { nextToken(); + } else if (token.value == TOKlcurly) { //printf("aggregate definition\n"); nextToken(); - a->members = parseDeclDefs(0); + Array *decl = parseDeclDefs(0); if (token.value != TOKrcurly) error("struct member expected"); nextToken(); + if (anon) + { + /* Anonymous structs/unions are more like attributes. + */ + return new AnonDeclaration(anon - 1, decl); + } + else + a->members = decl; } else { error("{ } expected following aggregate declaration"); + a = new StructDeclaration(loc, NULL); } if (tpl) @@ -2460,7 +2477,7 @@ while (1) { Type *tb; - Identifier *ai; + Identifier *ai = NULL; Type *at; enum InOut inout; Argument *a; @@ -2472,6 +2489,8 @@ } tb = parseBasicType(); at = parseDeclarator(tb, &ai); + if (!ai) + error("no identifier for declarator"); a = new Argument(inout, at, ai, NULL); arguments->push(a); if (token.value == TOKcomma) diff -uNr gdc-0.8/d/dmd/root.c gdc-0.9/d/dmd/root.c --- gdc-0.8/d/dmd/root.c 2004-10-08 03:26:57.000000000 +0200 +++ gdc-0.9/d/dmd/root.c 2004-11-13 17:29:15.000000000 +0100 @@ -999,7 +999,7 @@ if (!ref) mem.free(buffer); ref = 2; - buffer = MapViewOfFileEx(hFileMap, FILE_MAP_READ,0,0,size,NULL); + buffer = (unsigned char *)MapViewOfFileEx(hFileMap, FILE_MAP_READ,0,0,size,NULL); if (CloseHandle(hFileMap) != TRUE) goto Lerr; if (buffer == NULL) // mapping view failed diff -uNr gdc-0.8/d/dmd/scope.c gdc-0.9/d/dmd/scope.c --- gdc-0.8/d/dmd/scope.c 2004-04-18 04:14:33.000000000 +0200 +++ gdc-0.9/d/dmd/scope.c 2004-12-18 21:22:55.000000000 +0100 @@ -60,6 +60,7 @@ this->noctor = 0; this->callSuper = 0; this->flags = 0; + this->anonAgg = NULL; } Scope::Scope(Scope *enclosing) @@ -85,6 +86,7 @@ this->noctor = enclosing->noctor; this->callSuper = enclosing->callSuper; this->flags = 0; + this->anonAgg = NULL; assert(this != enclosing); } @@ -251,6 +253,32 @@ return NULL; } +/******************************************** + * Search enclosing scopes for ClassDeclaration. + */ + +AggregateDeclaration *Scope::getStructClassScope() +{ Scope *sc; + + for (sc = this; sc; sc = sc->enclosing) + { + AggregateDeclaration *ad; + + if (sc->scopesym) + { + ad = sc->scopesym->isClassDeclaration(); + if (ad) + return ad; + else + { ad = sc->scopesym->isStructDeclaration(); + if (ad) + return ad; + } + } + } + return NULL; +} + /******************************************* * For TemplateDeclarations, we need to remember the Scope * where it was declared. So mark the Scope as not diff -uNr gdc-0.8/d/dmd/scope.h gdc-0.9/d/dmd/scope.h --- gdc-0.8/d/dmd/scope.h 2004-04-18 04:14:33.000000000 +0200 +++ gdc-0.9/d/dmd/scope.h 2004-12-18 21:22:55.000000000 +0100 @@ -24,6 +24,8 @@ struct LabelStatement; struct ForeachStatement; struct ClassDeclaration; +struct AggregateDeclaration; +struct AnonymousAggregateDeclaration; struct FuncDeclaration; enum LINK; enum PROT; @@ -62,6 +64,8 @@ unsigned flags; #define SCOPEctor 1 // constructor type + AnonymousAggregateDeclaration *anonAgg; // for temporary analysis + static Scope *freelist; static void *operator new(size_t sz); static Scope *createGlobal(Module *module); @@ -80,6 +84,7 @@ Dsymbol *insert(Dsymbol *s); ClassDeclaration *getClassScope(); + AggregateDeclaration *getStructClassScope(); void setNoFree(); }; diff -uNr gdc-0.8/d/dmd/statement.c gdc-0.9/d/dmd/statement.c --- gdc-0.8/d/dmd/statement.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/statement.c 2004-12-18 21:22:55.000000000 +0100 @@ -1255,6 +1255,7 @@ { CaseStatement *cs = (CaseStatement *)sw->cases->data[i]; + //printf("comparing '%s' with '%s'\n", exp->toChars(), cs->exp->toChars()); if (cs->exp->equals(exp)) { error("duplicate case %s in switch statement", exp->toChars()); break; @@ -1710,10 +1711,20 @@ Statement *SynchronizedStatement::semantic(Scope *sc) { if (exp) - { + { ClassDeclaration *cd; + exp = exp->semantic(sc); - if (!exp->type->isClassHandle()) + exp = resolveProperties(sc, exp); + cd = exp->type->isClassHandle(); + if (!cd) error("can only synchronize on class objects, not '%s'", exp->type->toChars()); + if (cd->isInterfaceDeclaration()) + { Type *t = new TypeIdentifier(0, Id::Object); + + t = t->semantic(0, sc); + exp = new CastExp(loc, exp, t); + exp = exp->semantic(sc); + } } body = body->semantic(sc); return this; @@ -1837,7 +1848,7 @@ Statement *TryCatchStatement::semantic(Scope *sc) { - body = body->semanticScope(sc, this, NULL); + body = body->semanticScope(sc, NULL /*this*/, NULL); for (int i = 0; i < catches->dim; i++) { Catch *c; diff -uNr gdc-0.8/d/dmd/struct.c gdc-0.9/d/dmd/struct.c --- gdc-0.8/d/dmd/struct.c 2004-05-22 20:15:38.000000000 +0200 +++ gdc-0.9/d/dmd/struct.c 2004-12-18 21:22:55.000000000 +0100 @@ -131,6 +131,30 @@ //printf("result = %d\n",offset); } + +void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v) +{ + unsigned memsize; // size of member + unsigned memalignsize; // size of member for alignment purposes + unsigned xalign; // alignment boundaries + + memsize = v->type->size(); + memalignsize = v->type->alignsize(); + xalign = v->type->memalign(sc->structalign); + alignmember(xalign, memalignsize, &sc->offset); + v->offset = sc->offset; + sc->offset += memsize; + if (sc->offset > structsize) + structsize = sc->offset; + if (alignsize < memalignsize) + alignsize = memalignsize; + + v->storage_class |= STCfield; + //printf(" addField '%s' to '%s' at offset %d\n", v->toChars(), toChars(), v->offset); + fields.push(v); +} + + /********************************* StructDeclaration ****************************/ StructDeclaration::StructDeclaration(Loc loc, Identifier *id) @@ -183,7 +207,8 @@ if (isUnionDeclaration()) sc2->inunion = 1; sc2->stc &= ~(STCauto | STCstatic); - for (i = 0; i < members->dim; i++) + int members_dim = members->dim; + for (i = 0; i < members_dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; s->semantic(sc2); @@ -203,47 +228,59 @@ AggregateDeclaration *sd; - if (isAnonymous() && - (sd = isMember()) != NULL) +#if 0 + if (isAnonymous()) { // Anonymous structures aren't independent, all their members are // added to the enclosing struct. unsigned offset; int isunionsave; - // Align size of enclosing struct - sd->alignmember(structalign, alignsize, &sd->structsize); - - // Add members to enclosing struct - for (i = 0; i < fields.dim; i++) - { - Dsymbol *s = (Dsymbol *)fields.data[i]; - VarDeclaration *vd = s->isVarDeclaration(); - if (vd) - { - vd->addMember(sd); - if (!sd->isUnionDeclaration()) - vd->offset += sd->structsize; - sd->fields.push(vd); - } - else - error("only fields allowed in anonymous struct"); - } - - if (sd->isUnionDeclaration()) + sd = isMember(); + if (!sd) { - if (structsize > sd->structsize) - sd->structsize = structsize; - sc->offset = 0; + error("anonymous struct can only be member of an aggregate"); } else { - sd->structsize += structsize; - sc->offset = sd->structsize; - } + // Align size of enclosing struct + sd->alignmember(structalign, alignsize, &sd->structsize); + + // Add members to enclosing struct + for (i = 0; i < members->dim; i++) + { + Dsymbol *s = (Dsymbol *)members->data[i]; + VarDeclaration *vd = s->isVarDeclaration(); + if (vd && vd->storage_class & STCfield) + { + vd->addMember(sd); + if (!sd->isUnionDeclaration()) + vd->offset += sd->structsize; + sd->fields.push(vd); + sd->members->push(s); + } + else if (!s->isAnonymous()) + { + sd->members->push(s); + } + } - if (sd->alignsize < alignsize) - sd->alignsize = alignsize; + if (sd->isUnionDeclaration()) + { + if (structsize > sd->structsize) + sd->structsize = structsize; + sc->offset = 0; + } + else + { + sd->structsize += structsize; + sc->offset = sd->structsize; + } + + if (sd->alignsize < alignsize) + sd->alignsize = alignsize; + } } +#endif //printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars()); // Determine if struct is all zeros or not diff -uNr gdc-0.8/d/dmd/template.c gdc-0.9/d/dmd/template.c --- gdc-0.8/d/dmd/template.c 2004-09-29 04:25:49.000000000 +0200 +++ gdc-0.9/d/dmd/template.c 2004-11-13 17:29:15.000000000 +0100 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + // Handle template implementation #include @@ -234,6 +240,7 @@ assert(dim >= ti->tiargs->dim); // Set up scope for parameters + assert(scope); ScopeDsymbol *paramsym = new ScopeDsymbol(); paramsym->parent = scope->parent; Scope *paramscope = scope->push(paramsym); @@ -1535,12 +1542,6 @@ else assert(tempdecl->isTemplateDeclaration()); - if (!tempdecl->scope) - { - error("forward reference to template"); - return NULL; - } - /* Since there can be multiple TemplateDeclaration's with the same * name, look for the best match. */ @@ -1561,6 +1562,11 @@ continue; dedtypes.setDim(td->parameters->dim); + if (!td->scope) + { + error("forward reference to template"); + return NULL; + } m = td->matchWithInstance(this, &dedtypes, 0); if (!m) // no match at all continue; diff -uNr gdc-0.8/d/dmd/tocsym.c gdc-0.9/d/dmd/tocsym.c --- gdc-0.8/d/dmd/tocsym.c 2004-09-29 04:25:49.000000000 +0200 +++ gdc-0.9/d/dmd/tocsym.c 2004-12-18 21:22:55.000000000 +0100 @@ -155,6 +155,7 @@ t = type->toCParamtype(); else t = type->toCtype(); + t->Tcount++; if (isDataseg()) { @@ -214,7 +215,6 @@ assert(0); } type_setmangle(&t, m); - t->Tcount++; s->Stype = t; csym = s; @@ -243,7 +243,7 @@ Symbol *TypeInfoDeclaration::toSymbol() { - //printf("TypeInfoDeclaration::toSymbol(%s)\n", toChars()); + //printf("TypeInfoDeclaration::toSymbol(%s), linkage = %d\n", toChars(), linkage); return VarDeclaration::toSymbol(); } diff -uNr gdc-0.8/d/dmd/todt.c gdc-0.9/d/dmd/todt.c --- gdc-0.8/d/dmd/todt.c 2004-10-25 00:28:38.000000000 +0200 +++ gdc-0.9/d/dmd/todt.c 2004-12-18 21:22:55.000000000 +0100 @@ -62,6 +62,7 @@ return NULL; } + dt_t *StructInitializer::toDt() { Array dts; @@ -72,7 +73,7 @@ dt_t **pdtend; unsigned offset; - //printf("StructInitializer::toDt()\n"); + //printf("StructInitializer::toDt('%s')\n", toChars()); dts.setDim(ad->fields.dim); dts.zero(); @@ -121,16 +122,17 @@ unsigned offset2 = v->offset + v->type->size(); // Make sure this field does not overlap any explicitly // initialized field. - for (k = j + 1; k < dts.dim; k++) + for (k = j + 1; 1; k++) { - VarDeclaration *v2 = (VarDeclaration *)ad->fields.data[k]; - - if (v2->offset < offset2 && dts.data[k]) { + if (k == dts.dim) // didn't find any overlap + { v->type->toDt(&d); // provide default initializer break; } + VarDeclaration *v2 = (VarDeclaration *)ad->fields.data[k]; + + if (v2->offset < offset2 && dts.data[k]) + break; // overlap } - if (k == dts.dim) - v->type->toDt(& d); } } if (d) @@ -154,8 +156,10 @@ return dt; } + dt_t *ArrayInitializer::toDt() { + //printf("ArrayInitializer::toDt('%s')\n", toChars()); Type *tb = type->toBasetype(); Type *tn = tb->next->toBasetype(); @@ -242,6 +246,7 @@ unsigned size; unsigned length; unsigned i; + unsigned tadim; dt_t *d; dt_t **pdtend; Type *tb = type->toBasetype(); @@ -251,11 +256,16 @@ if (tb->ty == Tsarray) { - /* Need to resize to the size of the static array, otherwise set() will - affect bits beyond the last specified element. */ - unsigned sdim = ((TypeSArray*)tb)->dim->toInteger(); // missing overflow check - databits.resize(sdim); - initbits.resize(sdim); + /* The 'dim' for ArrayInitializer is only the maximum dimension + * seen in the initializer, not the type. So, for static arrays, + * use instead the dimension of the type in order + * to get the whole thing. + */ + integer_t value = ((TypeSArray*)tb)->dim->toInteger(); + tadim = value; + assert(tadim == value); // truncation overflow should already be checked + databits.resize(tadim); + initbits.resize(tadim); } else { @@ -263,8 +273,10 @@ initbits.resize(dim); } + /* The default initializer may be something other than zero. + */ if (tb->next->defaultInit()->toInteger()) - databits.set(); + databits.set(); size = sizeof(databits.data[0]); @@ -273,23 +285,28 @@ { Expression *idx; Initializer *val; Expression *eval; - unsigned bitval; idx = (Expression *)index.data[i]; if (idx) - length = idx->toInteger(); + { integer_t value; + value = idx->toInteger(); + length = value; + if (length != value) + { error("index overflow %llu", value); + length = 0; + } + } assert(length < dim); val = (Initializer *)value.data[i]; eval = val->toExpression(); - bitval = eval->toInteger(); if (initbits.test(length)) error("duplicate initializations for index %d", length); initbits.set(length); - if (bitval != 0) + if (eval->toInteger()) // any non-zero value is boolean 'true' databits.set(length); else - databits.clear(length); + databits.clear(length); // boolean 'false' length++; } @@ -302,10 +319,7 @@ switch (tb->ty) { case Tsarray: - { unsigned tadim; - TypeSArray *ta = (TypeSArray *)tb; - - tadim = ta->dim->toInteger(); + { if (dim > tadim) error("too many initializers %d for array[%d]", dim, tadim); else @@ -362,6 +376,7 @@ dt_t **IntegerExp::toDt(dt_t **pdt) { unsigned sz; + //printf("IntegerExp::toDt() %d\n", op); sz = type->size(); if (value == 0) pdt = dtnzeros(pdt, sz); @@ -658,7 +673,7 @@ VarDeclaration *v = (VarDeclaration *)fields.data[i]; Initializer *init; - //printf("\tmember '%s' voffset %d, offset = %d\n", v->toChars(), v->offset, offset); + //printf("\tfield '%s' voffset %d, offset = %d\n", v->toChars(), v->offset, offset); dt = NULL; init = v->init; if (init) @@ -699,14 +714,29 @@ dt_t **TypeSArray::toDt(dt_t **pdt) { int i; - int len; + unsigned len; len = dim->toInteger(); if (len) { while (*pdt) pdt = &((*pdt)->DTnext); - if (next->toBasetype()->ty != Tbit) + if (next->toBasetype()->ty == Tbit) + { + Bits databits; + + databits.resize(len); + if (next->defaultInit()->toInteger()) + databits.set(); +#ifdef IN_GCC + pdt = dtnbits(pdt, databits.allocdim * sizeof(databits.data[0]), + (char *)databits.data, sizeof(databits.data[0])); +#else + pdt = dtnbytes(pdt, databits.allocdim * sizeof(databits.data[0]), + (char *)databits.data); +#endif + } + else { next->toDt(pdt); if ((*pdt)->dt == DT_azeros && !(*pdt)->DTnext) @@ -721,19 +751,6 @@ } } } - else - { - Bits databits; - - databits.resize(len); - if (next->defaultInit()->toInteger()) - databits.set(); -#ifdef IN_GCC - pdt = dtnbits(pdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data, sizeof(databits.data[0])); -#else - pdt = dtnbytes(pdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data); -#endif - } } return pdt; } diff -uNr gdc-0.8/d/dmd/toobj.c gdc-0.9/d/dmd/toobj.c --- gdc-0.8/d/dmd/toobj.c 2004-10-08 03:26:57.000000000 +0200 +++ gdc-0.9/d/dmd/toobj.c 2004-11-23 01:03:10.000000000 +0100 @@ -95,14 +95,10 @@ for (i = 0; i < members->dim; i++) { Dsymbol *member; - ClassDeclaration *cd; member = (Dsymbol *)members->data[i]; //printf("\tmember '%s'\n", member->toChars()); - if ((cd = member->isClassDeclaration()) != NULL) - { - aclasses.push(cd); - } + member->addLocalClass(&aclasses); } // importedModules[] @@ -192,6 +188,9 @@ if (!members) return; + if (global.params.symdebug) + toDebug(); + assert(!scope); // semantic() should have been run to completion if (parent && parent->isTemplateInstance()) @@ -599,6 +598,9 @@ //printf("InterfaceDeclaration::toObjFile('%s')\n", toChars()); + if (members && global.params.symdebug) + toDebug(); + if (parent && parent->isTemplateInstance()) scclass = SCcomdat; else @@ -729,6 +731,8 @@ // do not output forward referenced structs's if (!isAnonymous() && members) { + if (global.params.symdebug) + toDebug(); // Generate static initializer toInitializer(); @@ -816,7 +820,43 @@ dim = ((TypeSArray *)tb)->dim->toInteger(); - if (tb->next->toBasetype()->ty != Tbit) + if (tb->next->toBasetype()->ty == Tbit) + { integer_t value; + +#ifndef IN_GCC + value = ie->exp->toInteger(); + value = (value & 1) ? ~(integer_t)0 : (integer_t)0; + if (value == 0) + { + dtnzeros(&s->Sdt, ((unsigned)dim + 31) / 32 * 4); + } + else + { + while (dim >= 32) + { + dtnbytes(&s->Sdt, 4, (char *)&value); + dim -= 32; + } + if (dim) + { + value = (1 << dim) - 1; + dtnbytes(&s->Sdt, 4, (char *)&value); + } + } +#else + + s->Sdt = NULL; + if (ie->exp->toInteger()) { + Bits databits; + databits.resize(dim); + databits.set(); + dtnbits(& s->Sdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data, sizeof(databits.data[0])); + } else { + dtnzeros(&s->Sdt, ((unsigned)dim + 31) / 32 * 4); + } +#endif + } + else { // Duplicate Sdt 'dim-1' times, as we already have the first one while (--dim > 0) @@ -824,20 +864,6 @@ ie->exp->toDt(&s->Sdt); } } - else - { - Bits databits; - - databits.resize(dim); - if (ie->exp->toInteger()) - databits.set(); - s->Sdt = NULL; -#ifdef IN_GCC - dtnbits(& s->Sdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data, sizeof(databits.data[0])); -#else - dtnbytes(& s->Sdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data); -#endif - } } } else @@ -876,3 +902,24 @@ } } +/* ================================================================== */ + +void TypedefDeclaration::toObjFile() +{ + //printf("TypedefDeclaration::toObjFile('%s')\n", toChars()); + + if (global.params.symdebug) + toDebug(); +} + +/* ================================================================== */ + +void EnumDeclaration::toObjFile() +{ + //printf("EnumDeclaration::toObjFile('%s')\n", toChars()); + + if (global.params.symdebug) + toDebug(); +} + + diff -uNr gdc-0.8/d/dmd/typinf.c gdc-0.9/d/dmd/typinf.c --- gdc-0.8/d/dmd/typinf.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/dmd/typinf.c 2004-11-23 01:03:10.000000000 +0100 @@ -63,6 +63,7 @@ Type *t; static TypeInfoDeclaration *internalTI[TMAX]; + //printf("Type::getInternalTypeInfo() %s\n", toChars()); t = toBasetype(); switch (t->ty) { @@ -90,6 +91,7 @@ default: break; } + //printf("\tcalling getTypeInfo() %s\n", t->toChars()); return t->getTypeInfo(NULL); } @@ -102,7 +104,7 @@ { Expression *e; - //printf("Type::getTypeInfo()\n"); + //printf("Type::getTypeInfo() %s\n", toChars()); if (!vtinfo) { vtinfo = getTypeInfoDeclaration(); @@ -125,6 +127,7 @@ TypeInfoDeclaration *Type::getTypeInfoDeclaration() { + //printf("Type::getTypeInfoDeclaration() %s\n", toChars()); return new TypeInfoDeclaration(this, 0); } @@ -146,7 +149,7 @@ void TypeInfoDeclaration::toDt(dt_t **pdt) { - //printf("TypeInfoDeclaration::toDt()\n"); + //printf("TypeInfoDeclaration::toDt() %s\n", toChars()); dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo dtdword(pdt, 0); // monitor } @@ -154,7 +157,7 @@ void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) { //printf("TypeInfoTypedefDeclaration::toDt()\n"); - dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoTypedef + dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef dtdword(pdt, 0); // monitor assert(tinfo->ty == Ttypedef); @@ -296,6 +299,7 @@ } t = Type::typeinfo->type->arrayOf(); + ai->type = t; v = new VarDeclaration(0, t, id, ai); m->members->push(v); m->symtab->insert(v); diff -uNr gdc-0.8/d/dmd/utf.c gdc-0.9/d/dmd/utf.c --- gdc-0.8/d/dmd/utf.c 2004-09-21 01:02:30.000000000 +0200 +++ gdc-0.9/d/dmd/utf.c 2004-11-13 17:29:15.000000000 +0100 @@ -172,6 +172,8 @@ { msg = "illegal UTF-16 value"; goto Lerr; } + else + i++; } else { diff -uNr gdc-0.8/d/dmd-script gdc-0.9/d/dmd-script --- gdc-0.8/d/dmd-script 2004-10-10 18:50:41.000000000 +0200 +++ gdc-0.9/d/dmd-script 2004-12-02 02:12:02.000000000 +0100 @@ -45,6 +45,12 @@ return $^O =~ m/MS(DOS|Win32)|os2/i; # taken from File::Basename } +sub errorExit(@) { + print STDERR "dmd: ", @_, "\n" if @_; + exit 1; +} +use subs qw(errorExit); + my $gcc_version = `gdc -dumpversion`; chomp $gcc_version; $gcc_version =~ m/^(\d+)\.(\d+)/; @@ -56,10 +62,13 @@ foreach my $arg (@ARGV) { if ($arg =~ m/^-c$/ ) { $link = 0; - } elsif ( $arg =~ m/^-d/ ) { + } elsif ( $arg =~ m/^-d$/ ) { push @out, '-fdeprecated'; - } elsif ( $arg =~ m/^-debug(?:=(.*))$/ ) { - push @out, (defined($1) ? '-fdebug=$1' : '-fdebug'); + } elsif ( $arg =~ m/^-debug(?:=(.*))?$/ ) { + push @out, (defined($1) ? "-fdebug=$1" : '-fdebug'); + } elsif ( $arg =~ m/^-debug.*$/ ) { + # Passing this to gdc only gives warnings; exit with an error here + errorExit "unrecognized switch '$arg'"; } elsif ( $arg =~ m/^-gt$/ ) { # there is more to profiling than this ... -finstrument-functions? push @out, '-pg'; @@ -87,7 +96,9 @@ } elsif ( $arg =~ m/^-v$/ ) { push @out, '-v'; # not really equivalent } elsif ( $arg =~ m/^-version=(.*)$/ ) { - push @out, '-fversion=$1'; + push @out, "-fversion=$1"; + } elsif ( $arg =~ m/^-version.*$/ ) { + errorExit "unrecognized switch '$arg'"; } elsif ( $arg =~ m/^-vdmd$/ ) { $show_commands = 1; } elsif ( $arg =~ m/^-q(.*)$/ ) { @@ -97,8 +108,12 @@ # push @out, $arg; } elsif ( $arg =~ m/^-.+$/ ) { push @out, $arg; - } elsif ( $arg =~ m/^[^\.]+$/ || - $arg =~ m/^.+\.d$/) { + } elsif ( $arg =~ m/^.+\.d$/i || + $arg =~ m/^.+\.html$/i) { + $first_input_file = $arg if ! $first_input_file; + push @sources, $arg; + } elsif ( $arg !~ m/\./ ) { + $arg = $arg . ".d"; $first_input_file = $arg if ! $first_input_file; push @sources, $arg; } elsif ( $arg =~ m/^(.+)(\.exe)$/i ) { @@ -116,16 +131,20 @@ # Slightly different from dmd... allows -of to specify # the name of the executable. if ( ! $link && scalar(@sources) > 1 && $output_file ) { - die "object file name specified with multiple source files"; + errorExit "object file name specified with multiple source files"; } if ( $link && ! $output_file && $first_input_file ) { - $output_file = fileparse( $first_input_file, qr{\..*$} ); + $output_file = fileparse( $first_input_file, qr/\..*$/ ); if ( osHasEXE() ) { $output_file .= '.exe'; } } +if (! scalar(@sources) && ! ($link && scalar(@objects))) { + errorExit "no input files"; +} + my $ok = 1; foreach my $srcf_i (@sources) { @@ -165,7 +184,7 @@ print join(' ', @cmd), "\n"; } my $result = system(@cmd); - die if $result & 0xff; # Give up if can't exec or gdc exited with a signal + errorExit if $result & 0xff; # Give up if can't exec or gdc exited with a signal $ok = $ok && $result == 0; } diff -uNr gdc-0.8/d/d-misc.c gdc-0.9/d/d-misc.c --- gdc-0.8/d/d-misc.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/d-misc.c 2004-12-02 03:38:49.000000000 +0100 @@ -16,9 +16,6 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* The value of USING_SJLJ_EXCEPTIONS relies on insn-flags.h, but insn-flags.h - can not be compiled by C++. */ - #include "config.h" #include "system.h" #if D_GCC_VER == 33 @@ -34,8 +31,22 @@ #include "d-lang.h" +/* The value of USING_SJLJ_EXCEPTIONS relies on insn-flags.h, but insn-flags.h + can not be compiled by C++. */ + int d_using_sjlj_exceptions(void) { return USING_SJLJ_EXCEPTIONS; } + +/* ASM_FORMAT_PRIVATE_NAME implicitly casts to char* from void* (alloca call) */ + +char * +d_asm_format_private_name(const char * name, int value) +{ + char * out_name; + ASM_FORMAT_PRIVATE_NAME(out_name, name, value); + // and, since it's alloca... + return xstrdup(out_name); +} diff -uNr gdc-0.8/d/INSTALL gdc-0.9/d/INSTALL --- gdc-0.8/d/INSTALL 2004-10-25 01:05:45.000000000 +0200 +++ gdc-0.9/d/INSTALL 2004-12-18 17:15:00.000000000 +0100 @@ -68,13 +68,13 @@ Notes - * You can build the unittest with "make unittest". The following failures - should be expected: + * To run the unit tests, rebuild phobos with "-funittest" in the DFLAGS and + then "make unittest". The following failures should be expected: o On Darwin and FreeBSD, std.math tests will fail because there is no 80-bit real (or library support for it.) - o On FreeBSD and Linux, std.format:725 will fail for various reasons. - * If you use recls, you need to add -lstdc++ and possibly -shared-libgcc to - the link flags (or run g++ and add -lphobos and -lpthread.) Also add - /lib to LD_LIBRARY_PATH or whatever is necessary for your system - to find shared libraries. OR you try building GCC and your programs with a - static libstdc++. + o On FreeBSD and Linux, the test of the "%A" format will + fail due to a library bug. + * If you use recls, you need to add -lstdc++ to the link flags (or run g++ + and add -lphobos and -lpthread.) Also add /lib to LD_LIBRARY_PATH + or whatever is necessary for your system to find shared libraries. OR you + try building GCC and your programs with a static libstdc++. diff -uNr gdc-0.8/d/INSTALL.html gdc-0.9/d/INSTALL.html --- gdc-0.8/d/INSTALL.html 2004-10-04 01:39:29.000000000 +0200 +++ gdc-0.9/d/INSTALL.html 2004-12-18 17:15:00.000000000 +0100 @@ -19,9 +19,10 @@
  • The usual GCC requirements
  • -
  • An already-installed C++ compiler (bootstrapping is not supported -yet).  G++ 3.x is known to work.  G++ 2.x is known to not work.
  • +
  • An already-installed C++ compiler (if you use make bootstrap, the new g++ +will not be used).  G++ 3.x is known to work.  G++ 2.x is +known to not work.
  • Directories

      @@ -125,20 +126,21 @@

      Notes

        -
      • You can build the unittest with "To run the unit tests, rebuild phobos with "-funittest" in the DFLAGS and then "make unittest".  The following failures should be expected:
        • On Darwin and FreeBSD, std.math tests will fail because there is no 80-bit real (or library support for it.)
        • -
        • On FreeBSD and Linux, std.format:725 will fail for various -reasons.
          +
        • On FreeBSD and Linux, the test of the "%A" format will fail due +to a library bug.
      • If you use recls, you need to add -lstdc++ and possibly -shared-libgcc to the link + style="font-family: monospace;">-lstdc++ to the link flags (or run g++ and add -lphobos and -lpthread.)  Also add being included.. @@ -109,7 +109,7 @@ # The full path for -include ...total.h is only needed for g++ < 3.x # ALL_D_COMPILER_FLAGS causes issues -- c++ instead of C -d/%.dmd.o: $(srcdir)/d/dmd/%.c +d/%.dmd.o: $(srcdir)/d/dmd/%.c d/id.h $(CXX) $(ALL_DMD_COMPILER_FLAGS) -include $(srcdir)/d/dmd/total.h -o d/$*.dmd.o -c $< #hmm $(CC) $(ALL_DMD_COMPILER_FLAGS) -include $(srcdir)/d/dmd/total.h -o d/$*.dmd.o -c -x c++ $< @@ -141,7 +141,9 @@ cd d && ./impcvgen d/id.c: d/idgen cd d && ./idgen - +# idgen also generates id.h; just verify id.h exists +d/id.h: d/id.c + @ ls d/id.h d/id.gen.o: d/id.c d/dmd/idgen.c d/impcnvtab.gen.o: d/impcnvtab.c d/dmd/impcnvgen.c @@ -263,3 +265,7 @@ -mv d/*$(objext) stage3/d d.stage4: stage4-start -mv d/*$(objext) stage4/d + +.PHONY: check-d +check-d: + @ echo "note: check-d does not perform any tests yet." Binary files gdc-0.8/d/phobos/etc/c/recls/recls.lib and gdc-0.9/d/phobos/etc/c/recls/recls.lib differ diff -uNr gdc-0.8/d/phobos/etc/c/zlib/linux.mak gdc-0.9/d/phobos/etc/c/zlib/linux.mak --- gdc-0.8/d/phobos/etc/c/zlib/linux.mak 2004-09-29 04:26:32.000000000 +0200 +++ gdc-0.9/d/phobos/etc/c/zlib/linux.mak 2004-11-13 17:29:15.000000000 +0100 @@ -63,11 +63,11 @@ zlib.a: $(OBJS) ar -r $@ $(OBJS) -examplee: example.o zlib.a - $(LD) $(LDFLAGS) example.o zlib.a +example: example.o zlib.a + $(CC) -o $@ example.o zlib.a -g minigzip: minigzip.o zlib.a - $(LD) $(LDFLAGS) minigzip.o zlib.a + $(CC) -o $@ minigzip.o zlib.a -g test: example minigzip ./example Binary files gdc-0.8/d/phobos/etc/c/zlib/zlib.lib and gdc-0.9/d/phobos/etc/c/zlib/zlib.lib differ diff -uNr gdc-0.8/d/phobos/internal/aaA.d gdc-0.9/d/phobos/internal/aaA.d --- gdc-0.8/d/phobos/internal/aaA.d 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/internal/aaA.d 2004-12-18 21:22:55.000000000 +0100 @@ -1,5 +1,5 @@ //_ aaA.d -// Copyright (c) 2000-2003 by Digital Mars +// Copyright (c) 2000-2004 by Digital Mars // Written by Walter Bright /* NOTE: This file has been patched from the original DMD distribution to @@ -15,6 +15,16 @@ // Implementation of associative array +static uint[] prime_list = [ + 97ul, 389ul, + 1543ul, 6151ul, + 24593ul, 98317ul, + 393241ul, 1572869ul, + 6291469ul, 25165843ul, + 100663319ul, 402653189ul, + 1610612741ul, 4294967291ul +]; + struct Array { int length; @@ -25,7 +35,11 @@ { aaA *left; aaA *right; + union + { + uint nodes; // used in the head element to store the total # of AA elements uint hash; + } /* key */ /* value */ } @@ -42,7 +56,7 @@ { uint i; - for (i = 0; i < aa.length; i++) + for (i = 1; i < aa.length; i++) { if (aa[i]) _aaInvAh_x(aa[i]); @@ -116,19 +130,22 @@ out (result) { assert(result >= 0); - //printf("_aaLen()-\n"); - } - body - { + int len = 0; uint i; - for (i = 0; i < aa.length; i++) + for (i = 1; i < aa.length; i++) { if (aa[i]) len += _aaLen_x(aa[i]); } - return len; + assert(len == result); + + //printf("_aaLen()-\n"); + } + body + { + return aa.length ? aa[0].nodes : 0; } private int _aaLen_x(aaA *e) @@ -187,12 +204,13 @@ { alias aaA *pa; - *aa = new pa[10]; + *aa = new pa[prime_list[0] + 1]; + (*aa)[0] = cast(aaA *) cast(void*) new byte[aaA.sizeof]; } key_hash = keyti.getHash(pkey); //printf("hash = %d\n", key_hash); - i = key_hash % (*aa).length; + i = (key_hash % ((*aa).length - 1)) + 1; pe = &(*aa)[i]; while ((e = *pe) != null) { int c; @@ -217,6 +235,14 @@ memcpy(e + 1, pkey, keysize); e.hash = key_hash; *pe = e; + + uint nodes = ++(*aa)[0].nodes; + //printf("length = %d, nodes = %d\n", (*aa).length, nodes); + if (nodes > (*aa).length * 4) + { + _aaRehash(aa,keyti); + } + Lret: return cast(void *)(e + 1) + keysize; } @@ -224,17 +250,17 @@ /************************************************* * Determine if key is in aa. * Returns: - * 0 not in aa - * !=0 in aa + * null not in aa + * !=null in aa, return pointer to value */ -int _aaIn(aaA*[] aa, TypeInfo keyti, ...) +void* _aaIn(aaA*[] aa, TypeInfo keyti, ...) in { } out (result) { - assert(result == 0 || result == 1); + //assert(result == 0 || result == 1); } body { @@ -253,11 +279,11 @@ uint i; aaA *e; - if (aa.length) + if (aa.length > 1) { key_hash = keyti.getHash(pkey); //printf("hash = %d\n", key_hash); - i = key_hash % aa.length; + i = (key_hash % (aa.length - 1)) + 1; e = aa[i]; while (e != null) { int c; @@ -267,7 +293,7 @@ { c = keyti.compare(pkey, e + 1); if (c == 0) - return 1; + return cast(void *)(e + 1) + keyti.sizeof; } if (c < 0) @@ -278,7 +304,7 @@ } // Not found - return 0; + return null; } /************************************************* @@ -304,11 +330,11 @@ aaA *e; aaA **pe; - if (aa.length) + if (aa.length > 1) { key_hash = keyti.getHash(pkey); //printf("hash = %d\n", key_hash); - i = key_hash % aa.length; + i = (key_hash % (aa.length - 1)) + 1; pe = &aa[i]; while ((e = *pe) != null) // null means not found { int c; @@ -344,6 +370,8 @@ e.right = null; } + aa[0].nodes--; + // Should notify GC that e can be free'd now break; } @@ -370,7 +398,7 @@ a.length = _aaLen(aa); a.ptr = new byte[a.length * v]; resi = 0; - for (uint i = 0; i < aa.length; i++) + for (uint i = 1; i < aa.length; i++) { if (aa[i]) _aaValues_x(aa[i], a.ptr, resi, k, v); @@ -414,16 +442,26 @@ //printf("Rehash\n"); aa = *paa; len = _aaLen(aa); - if (len < 1) - len = 1; + if (len) + { + for (i = 0; i < prime_list.length - 1; i++) + { + if (len <= prime_list[i]) + break; + } + len = prime_list[i] + 1; newaa = new aaA*[len]; + newaa[0] = cast(aaA *) cast(void*) new byte[aaA.sizeof]; - for (i = 0; i < aa.length; i++) + for (i = 1; i < aa.length; i++) { if (aa[i]) _aaRehash_x(newaa, aa[i], keyti); } + newaa[0].nodes = aa[0].nodes; + } + *paa = newaa; return newaa; } @@ -447,7 +485,7 @@ //printf("rehash %p\n", olde); key_hash = olde.hash; - i = key_hash % newaa.length; + i = (key_hash % (newaa.length - 1)) + 1; pe = &newaa[i]; while ((e = *pe) != null) { int c; @@ -492,7 +530,7 @@ len = _aaLen(aa); res = new byte[len * n]; resi = 0; - for (i = 0; i < aa.length; i++) + for (i = 1; i < aa.length; i++) { if (aa[i]) _aaKeys_x(aa[i], res, resi, n); @@ -561,7 +599,7 @@ return result; } - for (uint i = 0; i < aa.length; i++) + for (uint i = 1; i < aa.length; i++) { if (aa[i]) { @@ -601,7 +639,7 @@ return result; } - for (uint i = 0; i < aa.length; i++) + for (uint i = 1; i < aa.length; i++) { if (aa[i]) { diff -uNr gdc-0.8/d/phobos/internal/critical.c gdc-0.9/d/phobos/internal/critical.c --- gdc-0.8/d/phobos/internal/critical.c 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/internal/critical.c 2004-11-23 01:03:10.000000000 +0100 @@ -113,8 +113,16 @@ static pthread_mutexattr_t _criticals_attr; static volatile int inited; +void _STI_critical_init(void); +void _STD_critical_term(void); + void _d_criticalenter(D_CRITICAL_SECTION *dcs) { + if (!inited) + { _STI_critical_init(); + atexit(_STD_critical_term); + } + //printf("_d_criticalenter(dcs = x%x)\n", dcs); if (!dcs->next) { pthread_mutex_lock(&critical_section.cs); @@ -137,7 +145,8 @@ void _STI_critical_init() { if (!inited) - { pthread_mutexattr_init(&_criticals_attr); + { //printf("_STI_critical_init()\n"); + pthread_mutexattr_init(&_criticals_attr); pthread_mutexattr_settype(&_criticals_attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(&critical_section.cs, 0); // the global critical section doesn't need to be recursive inited = 1; @@ -147,7 +156,8 @@ void _STD_critical_term() { if (inited) - { inited = 0; + { //printf("_STI_critical_term()\n"); + inited = 0; while (dcs_list) { pthread_mutex_destroy(&dcs_list->cs); diff -uNr gdc-0.8/d/phobos/internal/gc/gc.d gdc-0.9/d/phobos/internal/gc/gc.d --- gdc-0.8/d/phobos/internal/gc/gc.d 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/internal/gc/gc.d 2004-11-13 17:29:15.000000000 +0100 @@ -453,7 +453,6 @@ px.data = newdata; } px.length = newlength; - //px.data[length * size .. newlength * size] = y[]; memcpy(px.data + length * size, y, y.length * size); return *px; } diff -uNr gdc-0.8/d/phobos/internal/gc/gclinux.d gdc-0.9/d/phobos/internal/gc/gclinux.d --- gdc-0.8/d/phobos/internal/gc/gclinux.d 2004-08-25 02:42:23.000000000 +0200 +++ gdc-0.9/d/phobos/internal/gc/gclinux.d 2004-11-13 17:29:15.000000000 +0100 @@ -1,10 +1,12 @@ -// Copyright (C) 2001-2003 by Digital Mars, www.digitalmars.com +// Copyright (C) 2001-2004 by Digital Mars, www.digitalmars.com // All Rights Reserved // Written by Walter Bright import std.c.linux.linuxextern; +import std.c.linux.linux; +/+ extern (C) { // from @@ -17,6 +19,7 @@ enum { MAP_SHARED = 1, MAP_PRIVATE = 2, MAP_TYPE = 0x0F, MAP_FIXED = 0x10, MAP_FILE = 0, MAP_ANON = 0x20 } } ++/ /*********************************** * Map memory. diff -uNr gdc-0.8/d/phobos/internal/gc/gcx.d gdc-0.9/d/phobos/internal/gc/gcx.d --- gdc-0.8/d/phobos/internal/gc/gcx.d 2004-10-23 22:44:51.000000000 +0200 +++ gdc-0.9/d/phobos/internal/gc/gcx.d 2004-12-18 21:22:55.000000000 +0100 @@ -189,8 +189,8 @@ } else version (GNU) { - setStackBottom(gcc.gcgcc.os_query_stackBottom()); gcc.gcgcc.gc_init_extra(); + setStackBottom(gcc.gcgcc.os_query_stackBottom()); } else version (linux) { @@ -222,14 +222,30 @@ } void *malloc(size_t size) + { void *p; + + if (std.thread.Thread.nthreads == 1) + { + /* The reason this works is because none of the gc code + * can start up a new thread from within mallocNoSync(). + * Skip the sync for speed reasons. + */ + return mallocNoSync(size); + } + else synchronized (gcLock) + { + p = mallocNoSync(size); + } + return p; + } + + void *mallocNoSync(size_t size) { void *p = null; Bins bin; //debug(PRINTF) printf("GC::malloc(size = %d, gcx = %p)\n", size, gcx); assert(gcx); //debug(PRINTF) printf("gcx.self = %x, pthread_self() = %x\n", gcx.self, pthread_self()); - synchronized (gcLock) - { if (size) { size += SENTINEL_EXTRA; @@ -244,7 +260,18 @@ { if (!gcx.allocPage(bin)) // try to find a new page { - if (!gcx.fullcollectshell()) // collect to find a new page + if (std.thread.Thread.nthreads == 1) + { + /* Then we haven't locked it yet. Be sure + * and lock for a collection, since a finalizer + * may start a new thread. + */ + synchronized (gcLock) + { + gcx.fullcollectshell(); + } + } + else if (!gcx.fullcollectshell()) // collect to find a new page { //gcx.newPool(1); } @@ -277,7 +304,6 @@ sentinel_init(p, size); gcx.log_malloc(p, size); } - } return p; } diff -uNr gdc-0.8/d/phobos/internal/gc/linux.mak gdc-0.9/d/phobos/internal/gc/linux.mak --- gdc-0.8/d/phobos/internal/gc/linux.mak 2004-09-29 04:25:49.000000000 +0200 +++ gdc-0.9/d/phobos/internal/gc/linux.mak 2004-11-13 17:29:15.000000000 +0100 @@ -47,4 +47,4 @@ zip dmgc $(SRC) clean: - rm $(OBJS) dmgc.a testgc + rm $(OBJS) dmgc.a testgc testgc.o diff -uNr gdc-0.8/d/phobos/internal/object.d gdc-0.9/d/phobos/internal/object.d --- gdc-0.8/d/phobos/internal/object.d 2004-09-21 01:02:30.000000000 +0200 +++ gdc-0.9/d/phobos/internal/object.d 2004-12-18 21:22:55.000000000 +0100 @@ -3,7 +3,6 @@ extern (C) { int printf(char *, ...); - int wprintf(wchar *, ...); } alias bit bool; @@ -114,7 +113,7 @@ } } -class TypeInfoTypedef : TypeInfo +class TypeInfo_Typedef : TypeInfo { uint getHash(void *p) { return base.getHash(p); } int equals(void *p1, void *p2) { return base.equals(p1, p2); } @@ -125,7 +124,7 @@ TypeInfo base; } -class TypeInfoClass : TypeInfo +class TypeInfo_Class : TypeInfo { char[] toString() { return info.name; } diff -uNr gdc-0.8/d/phobos/internal/switch.d gdc-0.9/d/phobos/internal/switch.d --- gdc-0.8/d/phobos/internal/switch.d 2004-09-21 01:02:30.000000000 +0200 +++ gdc-0.9/d/phobos/internal/switch.d 2004-12-18 21:22:55.000000000 +0100 @@ -273,3 +273,129 @@ } +/********************************** + * Same thing, but for wide chars. + */ + +int _d_switch_dstring(dchar[][] table, dchar[] ca) + in + { + //printf("in _d_switch_dstring()\n"); + assert(table.length >= 0); + assert(ca.length >= 0); + + // Make sure table[] is sorted correctly + int j; + + for (j = 1; j < table.length; j++) + { + int len1 = table[j - 1].length; + int len2 = table[j].length; + + assert(len1 <= len2); + if (len1 == len2) + { + int c; + + c = memcmp(table[j - 1], table[j], len1 * dchar.sizeof); + assert(c < 0); // c==0 means a duplicate + } + } + } + out (result) + { + int i; + int c; + + //printf("out _d_switch_string()\n"); + if (result == -1) + { + // Not found + for (i = 0; i < table.length; i++) + { + if (table[i].length == ca.length) + { c = memcmp(table[i], ca, ca.length * dchar.sizeof); + assert(c != 0); + } + } + } + else + { + assert(0 <= result && result < table.length); + for (i = 0; 1; i++) + { + assert(i < table.length); + if (table[i].length == ca.length) + { + c = memcmp(table[i], ca, ca.length * dchar.sizeof); + if (c == 0) + { + assert(i == result); + break; + } + } + } + } + } + body + { + //printf("body _d_switch_ustring()\n"); + int low; + int high; + int mid; + int c; + dchar[] pca; + + low = 0; + high = table.length; + + /* + // Print table + wprintf("ca[] = '%.*s'\n", ca); + for (mid = 0; mid < high; mid++) + { + pca = table[mid]; + wprintf("table[%d] = %d, '%.*s'\n", mid, pca.length, pca); + } + */ + + // Do binary search + while (low < high) + { + mid = (low + high) >> 1; + pca = table[mid]; + c = ca.length - pca.length; + if (c == 0) + { + c = memcmp(ca, pca, ca.length * dchar.sizeof); + if (c == 0) + { //printf("found %d\n", mid); + return mid; + } + } + if (c < 0) + { + high = mid; + } + else + { + low = mid + 1; + } + } + //printf("not found\n"); + return -1; // not found + } + + +unittest +{ + switch (cast(dchar []) "c") + { + case "coo": + default: + break; + } +} + + + diff -uNr gdc-0.8/d/phobos/linux.mak gdc-0.9/d/phobos/linux.mak --- gdc-0.8/d/phobos/linux.mak 2004-09-29 04:25:49.000000000 +0200 +++ gdc-0.9/d/phobos/linux.mak 2004-12-18 21:22:55.000000000 +0100 @@ -17,7 +17,7 @@ CC=gcc #DMD=/dmd/bin/dmd -DMD=../dmd +DMD=dmd .c.o: $(CC) -c $(CFLAGS) $*.c @@ -56,7 +56,7 @@ crc32.o conv.o arraycast.o errno.o alloca.o cmath2.o \ process.o syserror.o \ socket.o socketstream.o stdarg.o stdio.o format.o \ - perf.o \ + perf.o openrj.o \ ti_wchar.o ti_uint.o ti_short.o ti_ushort.o \ ti_byte.o ti_ubyte.o ti_long.o ti_ulong.o ti_ptr.o \ ti_float.o ti_double.o ti_real.o ti_delegate.o \ @@ -95,10 +95,10 @@ std/intrinsic.d std/array.d std/switcherr.d std/syserror.d \ std/regexp.d std/random.d std/stream.d std/process.d std/recls.d \ std/socket.d std/socketstream.d std/loader.d std/stdarg.d \ - std/stdio.d std/format.d std/perf.d + std/stdio.d std/format.d std/perf.d std/openrj.d SRC_STD_C= std/c/process.d std/c/stdlib.d std/c/time.d std/c/stdio.d \ - std/c/math.d std/c/stdarg.d + std/c/math.d std/c/stdarg.d std/c/stddef.d SRC_TI= \ std/typeinfo/ti_wchar.d std/typeinfo/ti_uint.d \ @@ -246,31 +246,128 @@ etc/c/recls/linux.mak \ etc/c/recls/recls.lib +SRC_STLSOFT_NEW= \ + etc/c/stlsoft/winstl_file_path_buffer.h \ + etc/c/stlsoft/inetstl_connection.h \ + etc/c/stlsoft/inetstl_filesystem_traits.h \ + etc/c/stlsoft/inetstl_findfile_sequence.h \ + etc/c/stlsoft/inetstl_searchspec_sequence.h \ + etc/c/stlsoft/inetstl_session.h \ + etc/c/stlsoft/stlsoft.h \ + etc/c/stlsoft/stlsoft_allocator_base.h \ + etc/c/stlsoft/inetstl.h \ + etc/c/stlsoft/stlsoft_auto_buffer.h \ + etc/c/stlsoft/stlsoft_cccap_dmc.h \ + etc/c/stlsoft/stlsoft_cccap_gcc.h \ + etc/c/stlsoft/stlsoft_char_traits.h \ + etc/c/stlsoft/stlsoft_constraints.h \ + etc/c/stlsoft/stlsoft_exceptions.h \ + etc/c/stlsoft/stlsoft_iterator.h \ + etc/c/stlsoft/stlsoft_meta.h \ + etc/c/stlsoft/stlsoft_new_allocator.h \ + etc/c/stlsoft/stlsoft_any_caster.h \ + etc/c/stlsoft/stlsoft_nulldef.h \ + etc/c/stlsoft/stlsoft_sap_cast.h \ + etc/c/stlsoft/stlsoft_searchspec_sequence.h \ + etc/c/stlsoft/stlsoft_sign_traits.h \ + etc/c/stlsoft/stlsoft_simple_algorithms.h \ + etc/c/stlsoft/stlsoft_simple_string.h \ + etc/c/stlsoft/stlsoft_size_traits.h \ + etc/c/stlsoft/stlsoft_string_access.h \ + etc/c/stlsoft/stlsoft_string_tokeniser.h \ + etc/c/stlsoft/stlsoft_type_traits.h \ + etc/c/stlsoft/unixstl.h \ + etc/c/stlsoft/unixstl_filesystem_traits.h \ + etc/c/stlsoft/unixstl_file_path_buffer.h \ + etc/c/stlsoft/unixstl_glob_sequence.h \ + etc/c/stlsoft/unixstl_string_access.h \ + etc/c/stlsoft/unixstl_thread_mutex.h \ + etc/c/stlsoft/winstl.h \ + etc/c/stlsoft/winstl_atomic_functions.h \ + etc/c/stlsoft/winstl_char_conversions.h \ + etc/c/stlsoft/winstl_filesystem_traits.h \ + etc/c/stlsoft/winstl_spin_mutex.h \ + etc/c/stlsoft/winstl_findfile_sequence.h \ + etc/c/stlsoft/winstl_processheap_allocator.h \ + etc/c/stlsoft/winstl_system_version.h \ + etc/c/stlsoft/stlsoft_null.h + +SRC_RECLS_NEW= \ + etc/c/recls/recls_compiler_gcc.h \ + etc/c/recls/recls_retcodes.h \ + etc/c/recls/EntryFunctions.h \ + etc/c/recls/recls_platform_types.h \ + etc/c/recls/recls.h \ + etc/c/recls/recls_wininet_dl.h \ + etc/c/recls/ReclsFileSearch.h \ + etc/c/recls/ReclsFileSearchDirectoryNode_unix.cpp \ + etc/c/recls/ReclsFileSearchDirectoryNode_unix.h \ + etc/c/recls/ReclsFileSearchDirectoryNode_win32.cpp \ + etc/c/recls/ReclsFileSearchDirectoryNode_win32.h \ + etc/c/recls/recls_wininet_dl.cpp \ + etc/c/recls/ReclsFileSearch_unix.cpp \ + etc/c/recls/ReclsFileSearch_win32.cpp \ + etc/c/recls/recls_win32.h \ + etc/c/recls/ReclsFtpSearch.h \ + etc/c/recls/ReclsFtpSearchDirectoryNode_win32.cpp \ + etc/c/recls/ReclsFtpSearchDirectoryNode_win32.h \ + etc/c/recls/recls_util_win32.cpp \ + etc/c/recls/ReclsFtpSearch_win32.cpp \ + etc/c/recls/recls_util_unix.cpp \ + etc/c/recls/recls_api.cpp \ + etc/c/recls/recls_util.h \ + etc/c/recls/recls_api_unix.cpp \ + etc/c/recls/recls_api_win32.cpp \ + etc/c/recls/recls_util.cpp \ + etc/c/recls/recls_assert.h \ + etc/c/recls/recls_compiler.h \ + etc/c/recls/recls_compiler_dmc.h \ + etc/c/recls/recls_platform.h \ + etc/c/recls/recls_debug.h \ + etc/c/recls/recls_defs.h \ + etc/c/recls/recls_fileinfo.cpp \ + etc/c/recls/recls_fileinfo_unix.cpp \ + etc/c/recls/recls_fileinfo_win32.cpp \ + etc/c/recls/recls_unix.h \ + etc/c/recls/recls_ftp.h \ + etc/c/recls/recls_ftp_api_win32.cpp \ + etc/c/recls/recls_internal.cpp \ + etc/c/recls/recls_internal.h \ + etc/c/recls/recls_roots_win32.cpp \ + etc/c/recls/recls_language.h \ + etc/c/recls/recls_roots_unix.cpp \ + etc/c/recls/win32.mak \ + etc/c/recls/linux.mak + ALLSRCS = $(SRC) $(SRC_STD) $(SRC_STD_C) $(SRC_TI) $(SRC_INT) $(SRC_STD_WIN) \ $(SRC_STD_C_WIN) $(SRC_STD_C_LINUX) $(SRC_ETC) $(SRC_ETC_C) \ $(SRC_ZLIB) $(SRC_GC) \ $(SRC_RECLS) $(SRC_STLSOFT) -libphobos.a : $(OBJS) internal/gc/dmgc.a linux.mak +#libphobos.a : $(OBJS) internal/gc/dmgc.a linux.mak +libphobos.a : $(OBJS) internal/gc/dmgc.a $(ZLIB_OBJS) $(RECLS_OBJS) linux.mak ar -r $@ $(OBJS) $(ZLIB_OBJS) $(GC_OBJS) $(RECLS_OBJS) ########################################################### internal/gc/dmgc.a: - cd internal/gc - make -f linux.mak dmgc.a - cd ../.. +# cd internal/gc +# make -f linux.mak dmgc.a +# cd ../.. + make -C ./internal/gc -f linux.mak dmgc.a $(RECLS_OBJS): - cd etc/c/recls - make -f linux.mak - cd ../../.. +# cd etc/c/recls +# make -f linux.mak +# cd ../../.. + make -C ./etc/c/recls -f linux.mak $(ZLIB_OBJS): - cd etc/c/zlib - make -f linux.mak - cd ../../.. +# cd etc/c/zlib +# make -f linux.mak +# cd ../../.. + make -C ./etc/c/zlib -f linux.mak ### @@ -400,6 +497,9 @@ moduleinit.o : std/moduleinit.d $(DMD) -c $(DFLAGS) std/moduleinit.d +openrj.o : std/openrj.d + $(DMD) -c $(DFLAGS) std/openrj.d + outbuffer.o : std/outbuffer.d $(DMD) -c $(DFLAGS) std/outbuffer.d diff -uNr gdc-0.8/d/phobos/Makefile.in gdc-0.9/d/phobos/Makefile.in --- gdc-0.8/d/phobos/Makefile.in 2004-10-23 22:44:51.000000000 +0200 +++ gdc-0.9/d/phobos/Makefile.in 2004-12-19 17:25:21.000000000 +0100 @@ -76,7 +76,7 @@ crc32.o std/conv.o internal/arraycast.o errno.o \ std/process.o std/syserror.o \ std/socket.o std/socketstream.o std/c/stdarg.o std/stdio.o std/format.o \ - std/perf.o \ + std/perf.o std/openrj.o \ $(subst ti_,std/typeinfo/ti_,$(TI)) \ std/date.o std/dateparse.o std/math2.o etc/c/zlib.o std/zlib.o std/zip.o std/recls.o diff -uNr gdc-0.8/d/phobos/object.d gdc-0.9/d/phobos/object.d --- gdc-0.8/d/phobos/object.d 2004-09-21 01:02:30.000000000 +0200 +++ gdc-0.9/d/phobos/object.d 2004-12-19 17:25:21.000000000 +0100 @@ -3,23 +3,43 @@ module object; -extern (C) -{ int printf(char *, ...); - int wprintf(wchar *, ...); -} - alias bit bool; -version (AMD64) +version (GNU) +{ + version (GNU_BitsPerPointer32) + { + alias uint size_t; + alias int ptrdiff_t; + } + else version (GNU_BitsPerPointer64) + { + alias ulong size_t; + alias long ptrdiff_t; + } + else + { + static assert(0); + } +} +else version (AMD64) { alias ulong size_t; alias long ptrdiff_t; } -else +else version (X86) { alias uint size_t; alias int ptrdiff_t; } +else +{ + static assert(0); +} + +extern (C) +{ int printf(char *, ...); +} class Object { @@ -60,12 +80,12 @@ void swap(void *p1, void *p2); } -class TypeInfoTypedef : TypeInfo +class TypeInfo_Typedef : TypeInfo { TypeInfo base; } -class TypeInfoClass : TypeInfo +class TypeInfo_Class : TypeInfo { ClassInfo info; } diff -uNr gdc-0.8/d/phobos/std/array.d gdc-0.9/d/phobos/std/array.d --- gdc-0.8/d/phobos/std/array.d 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/std/array.d 2004-11-23 01:03:10.000000000 +0100 @@ -1,10 +1,4 @@ -/* NOTE: This file has been patched from the original DMD distribution to - work with the GDC compiler. - - Modified by David Friedman, September 2004 -*/ - module std.array; private import std.c.stdio; @@ -15,6 +9,7 @@ uint linnum; char[] filename; + public: this(char[] filename, uint linnum) { @@ -22,9 +17,9 @@ this.filename = filename; char[] buffer = new char[19 + filename.length + linnum.sizeof * 3 + 1]; - int length; - length = sprintf(buffer, "ArrayBoundsError %.*s(%u)", filename, linnum); - super(buffer[0..length]); + int len; + len = sprintf(buffer, "ArrayBoundsError %.*s(%u)", filename, linnum); + super(buffer[0..len]); } } diff -uNr gdc-0.8/d/phobos/std/c/linux/linux.d gdc-0.9/d/phobos/std/c/linux/linux.d --- gdc-0.8/d/phobos/std/c/linux/linux.d 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/std/c/linux/linux.d 2004-11-13 17:29:15.000000000 +0100 @@ -4,12 +4,6 @@ * Placed into public domain. */ -/* NOTE: This file has been patched from the original DMD distribution to - work with the GDC compiler. - - Modified by David Friedman, September 2004 -*/ - module std.c.linux.linux; import std.c.linux.linuxextern; diff -uNr gdc-0.8/d/phobos/std/c/mach/mach.d gdc-0.9/d/phobos/std/c/mach/mach.d --- gdc-0.8/d/phobos/std/c/mach/mach.d 2004-10-23 22:44:51.000000000 +0200 +++ gdc-0.9/d/phobos/std/c/mach/mach.d 2004-12-19 17:25:21.000000000 +0100 @@ -22,11 +22,11 @@ extern(C): -version (BitsPerWord32) +version (GNU_BitsPerWord32) { private alias uint natural_t; } -else version (BitsPerWord64) +else version (GNU_BitsPerWord64) { private alias ulong natural_t; } diff -uNr gdc-0.8/d/phobos/std/c/process.d gdc-0.9/d/phobos/std/c/process.d --- gdc-0.8/d/phobos/std/c/process.d 2004-04-18 04:14:34.000000000 +0200 +++ gdc-0.9/d/phobos/std/c/process.d 2004-12-18 21:22:55.000000000 +0100 @@ -4,6 +4,8 @@ module std.c.process; +import std.c.stddef; + extern (C): void exit(int); @@ -55,21 +57,21 @@ void _endthreadex(uint); -int _wsystem(wchar *); -int _wspawnl(int, wchar *, wchar *, ...); -int _wspawnle(int, wchar *, wchar *, ...); -int _wspawnlp(int, wchar *, wchar *, ...); -int _wspawnlpe(int, wchar *, wchar *, ...); -int _wspawnv(int, wchar *, wchar **); -int _wspawnve(int, wchar *, wchar **, wchar **); -int _wspawnvp(int, wchar *, wchar **); -int _wspawnvpe(int, wchar *, wchar **, wchar **); - -int _wexecl(wchar *, wchar *, ...); -int _wexecle(wchar *, wchar *, ...); -int _wexeclp(wchar *, wchar *, ...); -int _wexeclpe(wchar *, wchar *, ...); -int _wexecv(wchar *, wchar **); -int _wexecve(wchar *, wchar **, wchar **); -int _wexecvp(wchar *, wchar **); -int _wexecvpe(wchar *, wchar **, wchar **); +int _wsystem(wchar_t *); +int _wspawnl(int, wchar_t *, wchar_t *, ...); +int _wspawnle(int, wchar_t *, wchar_t *, ...); +int _wspawnlp(int, wchar_t *, wchar_t *, ...); +int _wspawnlpe(int, wchar_t *, wchar_t *, ...); +int _wspawnv(int, wchar_t *, wchar_t **); +int _wspawnve(int, wchar_t *, wchar_t **, wchar_t **); +int _wspawnvp(int, wchar_t *, wchar_t **); +int _wspawnvpe(int, wchar_t *, wchar_t **, wchar_t **); + +int _wexecl(wchar_t *, wchar_t *, ...); +int _wexecle(wchar_t *, wchar_t *, ...); +int _wexeclp(wchar_t *, wchar_t *, ...); +int _wexeclpe(wchar_t *, wchar_t *, ...); +int _wexecv(wchar_t *, wchar_t **); +int _wexecve(wchar_t *, wchar_t **, wchar_t **); +int _wexecvp(wchar_t *, wchar_t **); +int _wexecvpe(wchar_t *, wchar_t **, wchar_t **); diff -uNr gdc-0.8/d/phobos/std/c/stdarg.d gdc-0.9/d/phobos/std/c/stdarg.d --- gdc-0.8/d/phobos/std/c/stdarg.d 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/std/c/stdarg.d 2004-12-18 21:22:55.000000000 +0100 @@ -15,28 +15,35 @@ version (GNU) { private import gcc.builtins; alias __builtin_va_list va_list; - alias __builtin_va_start va_start; alias __builtin_va_end va_end; + alias __builtin_va_copy va_copy; - // the va_arg function is magically interpreted by the compiler + // The va_start and va_arg template functions are magically + // handled by the compiler. } else { alias void* va_list; -template va_start(T) +void va_end(va_list ap) { - void va_start(out va_list ap, inout T parmn) - { - ap = cast(va_list)(cast(void*)&parmn + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1))); - } + } -void va_end(va_list ap) +void va_copy(out va_list dest, va_list src) { + dest = src; } } +template va_start(T) +{ + void va_start(out va_list ap, inout T parmn) + { + ap = cast(va_list)(cast(void*)&parmn + ((T.sizeof + int.sizeof - 1) & ~(int.sizeof - 1))); + } +} + template va_arg(T) { T va_arg(inout va_list ap) diff -uNr gdc-0.8/d/phobos/std/c/stddef.d gdc-0.9/d/phobos/std/c/stddef.d --- gdc-0.8/d/phobos/std/c/stddef.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.9/d/phobos/std/c/stddef.d 2004-12-19 17:25:21.000000000 +0100 @@ -0,0 +1,23 @@ +/* + * Written by Walter Bright + * Digital Mars + * www.digitalmars.com + * Placed into Public Domain. + */ + +version (Win32) +{ + alias wchar wchar_t; +} +else version (linux) +{ + alias dchar wchar_t; +} +else version (Unix) +{ + alias dchar wchar_t; +} +else +{ + static assert(0); +} diff -uNr gdc-0.8/d/phobos/std/c/stdio.d gdc-0.9/d/phobos/std/c/stdio.d --- gdc-0.8/d/phobos/std/c/stdio.d 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/std/c/stdio.d 2004-12-18 21:22:55.000000000 +0100 @@ -15,6 +15,7 @@ module std.c.stdio; +import std.c.stddef; private import std.c.stdarg; extern (C): @@ -274,38 +275,38 @@ int kbhit(); char * tempnam (char *dir, char *pfx); -wchar * _wtmpnam(wchar *); -FILE * _wfopen(wchar *, wchar *); -FILE * _wfsopen(wchar *, wchar *, int); -FILE * _wfreopen(wchar *, wchar *, FILE *); -wchar * fgetws(wchar *, int, FILE *); -int fputws(wchar *, FILE *); -wchar * _getws(wchar *); -int _putws(wchar *); -//int wprintf(wchar *, ...); -int fwprintf(FILE *, wchar *, ...); -int vwprintf(wchar *, va_list); -int vfwprintf(FILE *, wchar *, va_list); -int swprintf(wchar *, wchar *, ...); -int vswprintf(wchar *, wchar *, va_list); -int _snwprintf(wchar *, size_t, wchar *, ...); -int _vsnwprintf(wchar *, size_t, wchar *, va_list); -int wscanf(wchar *, ...); -int fwscanf(FILE *, wchar *, ...); -int swscanf(wchar *, wchar *, ...); -int _wremove(wchar *); -void _wperror(wchar *); -FILE * _wfdopen(int, wchar *); -wchar * _wtempnam(wchar *, wchar *); -wchar fgetwc(FILE *); -wchar _fgetwchar(); -wchar fputwc(wchar, FILE *); -wchar _fputwchar(wchar); -wchar ungetwc(wchar, FILE *); - -wchar getwchar() { return fgetwc(stdin); } -wchar putwchar(wchar c) { return fputwc(c,stdout); } -wchar getwc(FILE *fp) { return fgetwc(fp); } -wchar putwc(wchar c, FILE *fp) { return fputwc(c, fp); } +wchar_t * _wtmpnam(wchar_t *); +FILE * _wfopen(wchar_t *, wchar_t *); +FILE * _wfsopen(wchar_t *, wchar_t *, int); +FILE * _wfreopen(wchar_t *, wchar_t *, FILE *); +wchar_t * fgetws(wchar_t *, int, FILE *); +int fputws(wchar_t *, FILE *); +wchar_t * _getws(wchar_t *); +int _putws(wchar_t *); +//int wprintf(wchar_t *, ...); +int fwprintf(FILE *, wchar_t *, ...); +int vwprintf(wchar_t *, va_list); +int vfwprintf(FILE *, wchar_t *, va_list); +int swprintf(wchar_t *, wchar_t *, ...); +int vswprintf(wchar_t *, wchar_t *, va_list); +int _snwprintf(wchar_t *, size_t, wchar_t *, ...); +int _vsnwprintf(wchar_t *, size_t, wchar_t *, va_list); +int wscanf(wchar_t *, ...); +int fwscanf(FILE *, wchar_t *, ...); +int swscanf(wchar_t *, wchar_t *, ...); +int _wremove(wchar_t *); +void _wperror(wchar_t *); +FILE * _wfdopen(int, wchar_t *); +wchar_t * _wtempnam(wchar_t *, wchar_t *); +wchar_t fgetwc(FILE *); +wchar_t _fgetwchar_t(); +wchar_t fputwc(wchar_t, FILE *); +wchar_t _fputwchar_t(wchar_t); +wchar_t ungetwc(wchar_t, FILE *); + +wchar_t getwchar_t() { return fgetwc(stdin); } +wchar_t putwchar_t(wchar_t c) { return fputwc(c,stdout); } +wchar_t getwc(FILE *fp) { return fgetwc(fp); } +wchar_t putwc(wchar_t c, FILE *fp) { return fputwc(c, fp); } int fwide(FILE* fp, int mode); diff -uNr gdc-0.8/d/phobos/std/c/stdlib.d gdc-0.9/d/phobos/std/c/stdlib.d --- gdc-0.8/d/phobos/std/c/stdlib.d 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/std/c/stdlib.d 2004-12-18 21:22:55.000000000 +0100 @@ -18,6 +18,14 @@ _MAX_EXT = 256, } +struct div_t { int quot,rem; } +struct ldiv_t { int quot,rem; } +struct lldiv_t { long quot,rem; } + + div_t div(int,int); + ldiv_t ldiv(int,int); + lldiv_t lldiv(long, long); + const int EXIT_SUCCESS = 0; const int EXIT_FAILURE = 1; @@ -38,6 +46,8 @@ void *realloc(void *, uint); void free(void *); + void *bsearch(void *,void *,size_t,size_t, + int function(void *,void *)); void qsort(void *base, uint nelems, uint elemsize, int (*compare)(void *elem1, void *elem2)); @@ -51,3 +61,14 @@ int getErrno(); int setErrno(int); +double atof(char *); +int atoi(char *); +int atol(char *); +double strtod(char *,char **); +real strtold(char *,char **); +long strtol(char *,char **,int); +uint strtoul(char *,char **,int); +long atoll(char *); +long strtoll(char *,char **,int); +ulong strtoull(char *,char **,int); + diff -uNr gdc-0.8/d/phobos/std/c/time.d gdc-0.9/d/phobos/std/c/time.d --- gdc-0.8/d/phobos/std/c/time.d 2004-09-21 01:02:31.000000000 +0200 +++ gdc-0.9/d/phobos/std/c/time.d 2004-12-18 21:22:55.000000000 +0100 @@ -6,9 +6,30 @@ module std.c.time; +import std.c.stddef; + extern (C): -const uint CLOCKS_PER_SEC = 1000; +version (Windows) +{ const uint CLOCKS_PER_SEC = 1000; +} +else version (GNU) +{ + private import gcc.config; + alias gcc.config.CLOCKS_PER_SEC CLOCKS_PER_SEC; +} +else version (linux) +{ const uint CLOCKS_PER_SEC = 1000000; +} +else version (darwin) +{ + const uint CLOCKS_PER_SEC = 100; +} +else +{ + static assert(0); +} + const uint CLK_TCK = 1000; const uint TIMEOFFSET = 315558000; @@ -50,8 +71,8 @@ void usleep(uint); void msleep(uint); -wchar *_wasctime(tm *); -wchar *_wctime(time_t *); -size_t wcsftime(wchar *, size_t, wchar *, tm *); -wchar *_wstrdate(wchar *); -wchar *_wstrtime(wchar *); +wchar_t *_wasctime(tm *); +wchar_t *_wctime(time_t *); +size_t wcsftime(wchar_t *, size_t, wchar_t *, tm *); +wchar_t *_wstrdate(wchar_t *); +wchar_t *_wstrtime(wchar_t *); diff -uNr gdc-0.8/d/phobos/std/format.d gdc-0.9/d/phobos/std/format.d --- gdc-0.8/d/phobos/std/format.d 2004-09-21 01:02:30.000000000 +0200 +++ gdc-0.9/d/phobos/std/format.d 2004-11-23 01:03:10.000000000 +0100 @@ -409,6 +409,12 @@ } return; + case Mangle.Ttypedef: + ti = (cast(TypeInfo_Typedef)ti).base; + m = cast(Mangle)ti.classinfo.name[9]; + formatArg(fc); + return; + default: goto Lerror; } @@ -468,36 +474,35 @@ !(fc == 'o' && flags & FLhash)) { putstr(null); + return; } - else + if (vnumber < base) { vchar = '0' + vnumber; goto L2; } } - else - { - int n = tmpbuf.length; - char c; - int hexoffset = uc ? ('A' - ('9' + 1)) : ('a' - ('9' + 1)); - while (vnumber) - { - c = (vnumber % base) + '0'; - if (c > '9') - c += hexoffset; - vnumber /= base; - tmpbuf[--n] = c; - } - if (tmpbuf.length - n < precision && precision < tmpbuf.length) - { - int m = tmpbuf.length - precision; - tmpbuf[m .. n] = '0'; - n = m; - } - else if (flags & FLhash && fc == 'o') - prefix = "0"; - putstr(tmpbuf[n .. tmpbuf.length]); + int n = tmpbuf.length; + char c; + int hexoffset = uc ? ('A' - ('9' + 1)) : ('a' - ('9' + 1)); + + while (vnumber) + { + c = (vnumber % base) + '0'; + if (c > '9') + c += hexoffset; + vnumber /= base; + tmpbuf[--n] = c; + } + if (tmpbuf.length - n < precision && precision < tmpbuf.length) + { + int m = tmpbuf.length - precision; + tmpbuf[m .. n] = '0'; + n = m; } + else if (flags & FLhash && fc == 'o') + prefix = "0"; + putstr(tmpbuf[n .. tmpbuf.length]); return; Lreal: diff -uNr gdc-0.8/d/phobos/std/intrinsic.d gdc-0.9/d/phobos/std/intrinsic.d --- gdc-0.8/d/phobos/std/intrinsic.d 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/std/intrinsic.d 2004-10-28 03:43:56.000000000 +0200 @@ -63,7 +63,7 @@ uint bswap(uint v) { - return ((v&0xFF)<<24)|((v&0xFF00)<<8)|((v&0xFF0000)>>8)|((v&0xFF000000)>>24); + return ((v&0xFF)<<24)|((v&0xFF00)<<8)|((v&0xFF0000)>>>8)|((v&0xFF000000)>>>24); } ubyte inp(uint p) { return 0; } diff -uNr gdc-0.8/d/phobos/std/openrj.d gdc-0.9/d/phobos/std/openrj.d --- gdc-0.8/d/phobos/std/openrj.d 1970-01-01 01:00:00.000000000 +0100 +++ gdc-0.9/d/phobos/std/openrj.d 2004-12-18 21:22:55.000000000 +0100 @@ -0,0 +1,66 @@ + +// openrj.d +// placed into Public Domain + +module std.openrj; + +import std.string; + +alias char[][] [char[]] [] openrj_t; + +class OpenrjException : Exception +{ + uint linnum; + + this(uint linnum, char[] msg) + { + this.linnum = linnum; + super(std.string.format("OpenrjException line %s: %s", linnum, msg)); + } +} + +openrj_t parse(char[] db) +{ + openrj_t rj; + char[][] lines; + char[][] [char[]] record; + + lines = std.string.splitlines(db); + + for (uint linnum = 0; linnum < lines.length; linnum++) + { + char[] line = lines[linnum]; + + // Splice lines ending with backslash + while (line.length && line[length - 1] == '\\') + { + if (++linnum == lines.length) + throw new OpenrjException(linnum, "no line after \\ line"); + line = line[0 .. length - 1] ~ lines[linnum]; + } + + if (line[0 .. 2] == "%%") + { + // Comment lines separate records + if (record) + rj ~= record; + record = null; + line = null; + continue; + } + + int colon = std.string.find(line, ':'); + if (colon == -1) + throw new OpenrjException(linnum, "'key : value' expected"); + + char[] key = std.string.strip(line[0 .. colon]); + char[] value = std.string.strip(line[colon + 1 .. length]); + + char[][] fields = record[key]; + fields ~= value; + record[key] = fields; + } + if (record) + rj ~= record; + return rj; +} diff -uNr gdc-0.8/d/phobos/std/process.d gdc-0.9/d/phobos/std/process.d --- gdc-0.8/d/phobos/std/process.d 2004-10-18 05:27:20.000000000 +0200 +++ gdc-0.9/d/phobos/std/process.d 2004-11-23 01:03:10.000000000 +0100 @@ -3,6 +3,10 @@ * Copyright (C) 2003-2004 by Digital Mars, www.digitalmars.com * Written by Matthew Wilson and Walter Bright * + * Incorporating idea (for execvpe() on Linux) from Russ Lewis + * + * Updated: 21st August 2004 + * * This software is provided 'as-is', without any express or implied * warranty. In no event will the authors be held liable for any damages * arising from the use of this software. @@ -20,7 +24,6 @@ * o This notice may not be removed or altered from any source * distribution. */ - /* NOTE: This file has been patched from the original DMD distribution to work with the GDC compiler. @@ -28,6 +31,7 @@ */ + module std.process; private import std.c.stdlib; @@ -43,7 +47,7 @@ { foreach(char[] s; a) { - *az++ = toStringz(s); + *az++ = toStringz(s); } *az = null; } @@ -53,6 +57,7 @@ char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); toAStringz(argv, argv_); + return std.c.process.execv(toStringz(pathname), argv_); } @@ -61,33 +66,69 @@ char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); char** envp_ = cast(char**)alloca((char*).sizeof * (1 + envp.length)); - toAStringz(argv, argv_); toAStringz(envp, envp_); + return std.c.process.execve(toStringz(pathname), argv_, envp_); } int execvp(char[] pathname, char[][] argv) { char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); + toAStringz(argv, argv_); + return std.c.process.execvp(toStringz(pathname), argv_); } +int execvpe(char[] pathname, char[][] argv, char[][] envp) +{ version (GNU_Need_execvpe) { - // TODO: Write this. + // Is pathname rooted? + if(pathname[0] == '/') + { + // Yes, so just call execve() + return execve(pathname, argv, envp); + } + else + { + // No, so must traverse PATHs, looking for first match + char[][] envPaths = std.string.split(std.string.toString(std.c.stdlib.getenv("PATH")), ":"); + int iRet = 0; + + // Note: if any call to execve() succeeds, this process will cease + // execution, so there's no need to check the execve() result through + // the loop. + + foreach(char[] pathDir; envPaths) + { + char[] composite = pathDir ~ "/" ~ pathname; + + iRet = execve(composite, argv, envp); + } + if(0 != iRet) + { + iRet = execve(pathname, argv, envp); + } + + return iRet; + } +} +else version(Windows) +{ + char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); + char** envp_ = cast(char**)alloca((char*).sizeof * (1 + envp.length)); + + toAStringz(argv, argv_); + toAStringz(envp, envp_); + + return std.c.process.execvpe(toStringz(pathname), argv_, envp_); } else { - int execvpe(char[] pathname, char[][] argv, char[][] envp) - { - char** argv_ = cast(char**)alloca((char*).sizeof * (1 + argv.length)); - char** envp_ = cast(char**)alloca((char*).sizeof * (1 + envp.length)); - toAStringz(argv, argv_); - toAStringz(envp, envp_); - return std.c.process.execvpe(toStringz(pathname), argv_, envp_); - } + static assert(0); +} // version } /* ////////////////////////////////////////////////////////////////////////// */ @@ -96,11 +137,35 @@ { int main(char[][] args) { -// int i = execv(args[1], args[2 .. args.length]); - int i = execvp(args[1], args[2 .. args.length]); + if(args.length < 2) + { + printf("Must supply executable (and optional arguments)\n"); + + return 1; + } + else + { + char[][] dummy_env; + + dummy_env ~= "VAL0=value"; + dummy_env ~= "VAL1=value"; + +/+ + foreach(char[] arg; args) + { + printf("%.*s\n", arg); + } ++/ + +// int i = execv(args[1], args[1 .. args.length]); +// int i = execvp(args[1], args[1 .. args.length]); + int i = execvpe(args[1], args[1 .. args.length], dummy_env); - printf("exec??() has returned! Error code: %d; errno: %d\n", i, /* errno */0); + printf("exec??() has returned! Error code: %d; errno: %d\n", i, /* std.c.stdlib.getErrno() */-1); - return 0; + return 0; + } } } + +/* ////////////////////////////////////////////////////////////////////////// */ diff -uNr gdc-0.8/d/phobos/std/recls.d gdc-0.9/d/phobos/std/recls.d --- gdc-0.8/d/phobos/std/recls.d 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/std/recls.d 2004-11-23 01:03:10.000000000 +0100 @@ -640,7 +640,7 @@ public: class Enumerator { - private: + public: this(hrecls_t hSrch, recls_rc_t lastError) { m_hSrch = hSrch; diff -uNr gdc-0.8/d/phobos/std/socket.d gdc-0.9/d/phobos/std/socket.d --- gdc-0.8/d/phobos/std/socket.d 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/std/socket.d 2004-12-18 21:22:55.000000000 +0100 @@ -42,7 +42,7 @@ version(Win32) { - typedef uint socket_t = ~0; + typedef uint socket_t = ~0u; } else version(BsdSockets) { @@ -86,7 +86,7 @@ const int IOCPARM_MASK = 0x7f; const int IOC_IN = cast(int)0x80000000; - const int FIONBIO = IOC_IN | ((uint.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 126; + const int FIONBIO = cast(int)(IOC_IN | ((uint.sizeof & IOCPARM_MASK) << 16) | (102 << 8) | 126); const int SOL_SOCKET = 0xFFFF; const int SO_TYPE = 0x1008; @@ -578,7 +578,7 @@ public: const uint ADDR_ANY = 0; - const uint ADDR_NONE = cast(int)-1; + const uint ADDR_NONE = cast(uint)-1; const ushort PORT_ANY = 0; @@ -1486,7 +1486,7 @@ fe = checkError ? checkError.toFd_set() : null; } - int result = .select(socket_t.max - 1, fr, fw, fe, tv); + int result = .select(cast(int)(socket_t.max - 1), fr, fw, fe, tv); version(Win32) { diff -uNr gdc-0.8/d/phobos/std/stdio.d gdc-0.9/d/phobos/std/stdio.d --- gdc-0.8/d/phobos/std/stdio.d 2004-10-18 05:27:20.000000000 +0200 +++ gdc-0.9/d/phobos/std/stdio.d 2004-12-19 17:25:21.000000000 +0100 @@ -16,37 +16,75 @@ private import std.format; private import std.utf; -private void writex(FILE* fp, TypeInfo[] arguments, std.c.stdio.va_list argptr, int newline) +version (DigitalMars) +{ + version (Windows) + { + version = DIGITAL_MARS_STDIO; + } +} + + +version (DIGITAL_MARS_STDIO) +{ + extern (C) + { + int _fputc_nlock(int, FILE*); + int _fputwc_nlock(int, FILE*); + int __fp_lock(FILE*); + void __fp_unlock(FILE*); + } + alias _fputc_nlock FPUTC; + alias _fputwc_nlock FPUTWC; +} +else +{ + alias std.c.stdio.fputc FPUTC; + alias std.c.stdio.fputwc FPUTWC; + + int __fp_lock(FILE* fp) { return 0; } + void __fp_unlock(FILE* fp) { } +} + +private void writex(FILE* fp, TypeInfo[] arguments, va_list argptr, int newline) { int orientation; version(GNU_Have_fwide) orientation = fwide(fp, 0); - if (orientation <= 0) // byte orientation or no orientation + try { - void putc(dchar c) + /* Do the file stream locking at the outermost level + * rather than character by character. + */ + __fp_lock(fp); + + if (orientation <= 0) // byte orientation or no orientation { - if (c <= 0x7F) + void putc(dchar c) { - std.c.stdio.fputc(c, fp); + if (c <= 0x7F) + { + FPUTC(c, fp); + } + else + { char[4] buf; + char[] b; + + b = std.utf.toUTF8(buf, c); + for (size_t i = 0; i < b.length; i++) + FPUTC(b[i], fp); + } } - else - { char[4] buf; - char[] b; - b = std.utf.toUTF8(buf, c); - for (size_t i = 0; i < b.length; i++) - std.c.stdio.fputc(b[i], fp); - } + std.format.doFormat(&putc, arguments, argptr); + if (newline) + FPUTC('\n', fp); } - - std.format.doFormat(&putc, arguments, argptr); - if (newline) - std.c.stdio.fputc('\n', fp); - } - else if (orientation > 0) // wide orientation - { - version(GNU_Have_fwide) + else if (orientation > 0) // wide orientation { + version (GNU_Have_fwide) + { + version (Windows) { void putcw(dchar c) @@ -54,15 +92,15 @@ assert(isValidDchar(c)); if (c <= 0xFFFF) { - std.c.stdio.fputwc(c, fp); + FPUTWC(c, fp); } else { wchar[2] buf; buf[0] = (((c - 0x10000) >> 10) & 0x3FF) + 0xD800; buf[1] = ((c - 0x10000) & 0x3FF) + 0xDC00; - std.c.stdio.fputwc(buf[0], fp); - std.c.stdio.fputwc(buf[1], fp); + FPUTWC(buf[0], fp); + FPUTWC(buf[1], fp); } } } @@ -70,7 +108,7 @@ { void putcw(dchar c) { - std.c.stdio.fputwc(c, fp); + FPUTWC(c, fp); } } else @@ -80,9 +118,15 @@ std.format.doFormat(&putcw, arguments, argptr); if (newline) - std.c.stdio.fputwc('\n', fp); + FPUTWC('\n', fp); + + } } } + finally + { + __fp_unlock(fp); + } } diff -uNr gdc-0.8/d/phobos/std/stream.d gdc-0.9/d/phobos/std/stream.d --- gdc-0.8/d/phobos/std/stream.d 2004-10-02 19:19:32.000000000 +0200 +++ gdc-0.9/d/phobos/std/stream.d 2004-12-19 17:25:21.000000000 +0100 @@ -1,7 +1,7 @@ /* * Copyright (c) 2001, 2002 * Pavel "EvilOne" Minayev - * with buffering added by Ben Hinkle + * with buffering and endian support added by Ben Hinkle * * Permission to use, copy, modify, distribute and sell this software * and its documentation for any purpose is hereby granted without fee, @@ -27,6 +27,7 @@ * File an OS file stream * BufferedStream a buffered stream wrapping another stream * BufferedFile a buffered File + * EndianStream a wrapper stream for swapping byte order and BOMs * MemoryStream a stream entirely stored in main memory * SliceStream a portion of another stream * TArrayStream a stream wrapping an array-like buffer @@ -74,7 +75,13 @@ alias std.format.va_list va_list; private import std.c.stdio; alias std.c.stdio.va_list c_va_list; -private import std.utf; + +private +{ + import std.system; // for Endian enumeration + import std.intrinsic; // for bswap + import std.utf; +} version (Windows) { @@ -105,10 +112,15 @@ void read(out float x); void read(out double x); void read(out real x); + void read(out ifloat x); + void read(out idouble x); void read(out ireal x); + void read(out cfloat x); + void read(out cdouble x); void read(out creal x); void read(out char x); void read(out wchar x); + void read(out dchar x); // reads a string, written earlier by write() void read(out char[] s); @@ -188,10 +200,15 @@ void write(float x); void write(double x); void write(real x); + void write(ifloat x); + void write(idouble x); void write(ireal x); + void write(cfloat x); + void write(cdouble x); void write(creal x); void write(char x); void write(wchar x); + void write(dchar x); // writes a string, together with its length void write(char[] s); @@ -273,10 +290,15 @@ void read(out float x) { readExact(&x, x.sizeof); } void read(out double x) { readExact(&x, x.sizeof); } void read(out real x) { readExact(&x, x.sizeof); } + void read(out ifloat x) { readExact(&x, x.sizeof); } + void read(out idouble x) { readExact(&x, x.sizeof); } void read(out ireal x) { readExact(&x, x.sizeof); } + void read(out cfloat x) { readExact(&x, x.sizeof); } + void read(out cdouble x) { readExact(&x, x.sizeof); } void read(out creal x) { readExact(&x, x.sizeof); } void read(out char x) { readExact(&x, x.sizeof); } void read(out wchar x) { readExact(&x, x.sizeof); } + void read(out dchar x) { readExact(&x, x.sizeof); } // reads a string, written earlier by write() void read(out char[] s) @@ -878,10 +900,15 @@ void write(float x) { writeExact(&x, x.sizeof); } void write(double x) { writeExact(&x, x.sizeof); } void write(real x) { writeExact(&x, x.sizeof); } + void write(ifloat x) { writeExact(&x, x.sizeof); } + void write(idouble x) { writeExact(&x, x.sizeof); } void write(ireal x) { writeExact(&x, x.sizeof); } + void write(cfloat x) { writeExact(&x, x.sizeof); } + void write(cdouble x) { writeExact(&x, x.sizeof); } void write(creal x) { writeExact(&x, x.sizeof); } void write(char x) { writeExact(&x, x.sizeof); } void write(wchar x) { writeExact(&x, x.sizeof); } + void write(dchar x) { writeExact(&x, x.sizeof); } // writes a string, together with its length void write(char[] s) @@ -1110,13 +1137,11 @@ return crc; } - } // A stream that wraps a source stream in a buffer class BufferedStream : Stream { - Stream s; // source stream ubyte[] buffer; // buffer, if any uint bufferCurPos; // current position in buffer @@ -1475,7 +1500,7 @@ } version (Unix) { - hFile = unix.open(toStringz(filename), access | createMode, share); + hFile = std.c.unix.open(toStringz(filename), access | createMode, share); isopen = hFile != -1; } if (!isopen) @@ -1565,7 +1590,7 @@ } version (Unix) { - unix.close(hFile); + std.c.unix.close(hFile); hFile = -1; } readable = writeable = seekable = false; @@ -1601,7 +1626,7 @@ } version (Unix) { - size = unix.read(hFile, buffer, size); + size = std.c.unix.read(hFile, buffer, size); if (size == -1) size = 0; } @@ -1622,7 +1647,7 @@ } version (Unix) { - size = unix.write(hFile, buffer, size); + size = std.c.unix.write(hFile, buffer, size); } return size; } @@ -1643,7 +1668,7 @@ } version (Unix) { - ulong result = unix.lseek(hFile, offset, rel); + ulong result = std.c.unix.lseek(hFile, offset, rel); if (result == 0xFFFFFFFF) throw new SeekException("unable to move file pointer"); } @@ -1801,6 +1826,310 @@ } +enum BOM { UTF8, UTF16LE, UTF16BE, UTF32LE, UTF32BE } + +private const int NBOMS = 5; +Endian[NBOMS] BOMEndian = [std.system.endian, + Endian.LittleEndian, Endian.BigEndian, + Endian.LittleEndian, Endian.BigEndian]; + +ubyte[][NBOMS] ByteOrderMarks; +ubyte[3] BOM_UTF8_data = [0xEF, 0xBB, 0xBF]; +ubyte[2] BOM_UTF16LE_data = [0xFF, 0xFE]; +ubyte[2] BOM_UTF16BE_data = [0xFE, 0xFF]; +ubyte[4] BOM_UTF32LE_data = [0xFF, 0xFE, 0x00, 0x00]; +ubyte[4] BOM_UTF32BE_data = [0x00, 0x00, 0xFE, 0xFF]; + +// A stream that wraps a source stream with endian support +class EndianStream : Stream +{ + Stream s; // source stream + Endian endian; // endianness of the source stream + + // Construct an Endian stream with specified endianness, defaulting + // to the native endiannes. + this(Stream source, Endian end = std.system.endian) + { + super(); + s = source; + endian = end; + readable = s.readable; + writeable = s.writeable; + seekable = s.seekable; + isopen = s.isOpen(); + } + + /* Return -1 if no BOM and otherwise read the BOM and return it. + * If there is no BOM then the bytes read are pushed back onto + * the ungetc buffer or ungetcw buffer. Pass ungetCharSize == 2 + * to use ungetcw instead of ungetc. + */ + int readBOM(int ungetCharSize = 1) + { + ubyte[4] BOM_buffer; + int n = 0; // the number of read bytes + int result = -1; // the last match or -1 + for (int i=0; i < NBOMS; ++i) + { + int j; + ubyte[] bom = ByteOrderMarks[i]; + for (j=0; j < bom.length; ++j) + { + if (n <= j) // have to read more + { + if (eof()) + break; + readExact(&BOM_buffer[n++],1); + } + if (BOM_buffer[j] != bom[j]) + break; + } + if (j == bom.length) // found a match + result = i; + } + int m = 0; + if (result != -1) + { + endian = BOMEndian[result]; // set stream endianness + m = ByteOrderMarks[result].length; + } + if ((ungetCharSize == 1 && result == -1) || (result == BOM.UTF8)) + { + while (n-- > m) + ungetc(BOM_buffer[n]); + } + else // should eventually support unget for dchar as well + { + if (n & 1) // make sure we have an even number of bytes + readExact(&BOM_buffer[n++],1); + while (n > m) + { + n -= 2; + wchar cw = *(cast(wchar*)&BOM_buffer[n]); + fixBO(&cw,2); + ungetcw(cw); + } + } + return result; + } + + // Correct the byte order of buffer to match native endianness. + // size must be even + final void fixBO(void* buffer, uint size) + { + if (endian != std.system.endian) + { + ubyte* startb = cast(ubyte*)buffer; + uint* start = cast(uint*)buffer; + switch (size) + { + case 0: break; + case 2: + { + ubyte x = *startb; + *startb = *(startb+1); + *(startb+1) = x; + break; + } + case 4: + { + *start = bswap(*start); + break; + } + default: + { + uint* end = cast(uint*)(buffer + size - uint.sizeof); + while (start < end) + { + uint x = bswap(*start); + *start = bswap(*end); + *end = x; + ++start; + --end; + } + startb = cast(ubyte*)start; + ubyte* endb = cast(ubyte*)end; + int len = uint.sizeof - (startb - endb); + if (len > 0) + fixBO(startb,len); + } + } + } + } + + uint readBlock(void* buffer, uint size) + { + return s.readBlock(buffer,size); + } + + void read(out short x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out ushort x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out int x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out uint x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out long x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out ulong x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out float x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out double x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out real x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out ifloat x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out idouble x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out ireal x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out cfloat x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out cdouble x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out creal x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out wchar x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + void read(out dchar x) { readExact(&x, x.sizeof); fixBO(&x,x.sizeof); } + + wchar[] readStringW(uint length) + { + wchar[] result = new wchar[length]; + readExact(result, result.length * wchar.sizeof); + while (length--) + fixBO(&result[length],2); + return result; + } + + // Write the specified BOM to the source stream + void writeBOM(BOM b) + { + ubyte[] bom = ByteOrderMarks[b]; + writeBlock(bom,bom.length); + } + + uint writeBlock(void* buffer, uint size) + { + return s.writeBlock(buffer,size); + } + void write(short x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(ushort x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(int x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(uint x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(long x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(ulong x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(float x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(double x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(real x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(ifloat x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(idouble x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(ireal x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(cfloat x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(cdouble x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(creal x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(wchar x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + void write(dchar x) { fixBO(&x,x.sizeof); writeExact(&x, x.sizeof); } + + void writeStringW(wchar[] str) + { + foreach(wchar cw;str) + { + fixBO(&cw,2); + s.writeExact(&cw, 2); + } + } + + // close stream + override void close() + { + if (isopen) { + s.close(); + isopen = false; + } + } + + override ulong seek(long offset, SeekPos whence) + { + return s.seek(offset,whence); + } + + override void flush() { super.flush(); s.flush(); } + override bit eof() { return s.eof(); } + override ulong size() { return s.size(); } + + unittest { + MemoryStream m; + m = new MemoryStream (); + EndianStream em = new EndianStream(m,Endian.BigEndian); + uint x = 0x11223344; + em.write(x); + assert( m.data[0] == 0x11 ); + assert( m.data[1] == 0x22 ); + assert( m.data[2] == 0x33 ); + assert( m.data[3] == 0x44 ); + em.position(0); + ushort x2 = 0x5566; + em.write(x2); + assert( m.data[0] == 0x55 ); + assert( m.data[1] == 0x66 ); + em.position(0); + static ubyte[12] x3 = [1,2,3,4,5,6,7,8,9,10,11,12]; + em.fixBO(x3,12); + if (std.system.endian == Endian.LittleEndian) { + assert( x3[0] == 12 ); + assert( x3[1] == 11 ); + assert( x3[2] == 10 ); + assert( x3[4] == 8 ); + assert( x3[5] == 7 ); + assert( x3[6] == 6 ); + assert( x3[8] == 4 ); + assert( x3[9] == 3 ); + assert( x3[10] == 2 ); + assert( x3[11] == 1 ); + } + em.endian = Endian.LittleEndian; + em.write(x); + assert( m.data[0] == 0x44 ); + assert( m.data[1] == 0x33 ); + assert( m.data[2] == 0x22 ); + assert( m.data[3] == 0x11 ); + em.position(0); + em.write(x2); + assert( m.data[0] == 0x66 ); + assert( m.data[1] == 0x55 ); + em.position(0); + em.fixBO(x3,12); + if (std.system.endian == Endian.BigEndian) { + assert( x3[0] == 12 ); + assert( x3[1] == 11 ); + assert( x3[2] == 10 ); + assert( x3[4] == 8 ); + assert( x3[5] == 7 ); + assert( x3[6] == 6 ); + assert( x3[8] == 4 ); + assert( x3[9] == 3 ); + assert( x3[10] == 2 ); + assert( x3[11] == 1 ); + } + em.writeBOM(BOM.UTF8); + assert( m.position() == 3 ); + assert( m.data[0] == 0xEF ); + assert( m.data[1] == 0xBB ); + assert( m.data[2] == 0xBF ); + em.writeString ("Hello, world"); + em.position(0); + assert( m.position() == 0 ); + assert( em.readBOM == BOM.UTF8 ); + assert( m.position() == 3 ); + assert( em.getc() == 'H' ); + em.position(0); + em.writeBOM(BOM.UTF16BE); + assert( m.data[0] == 0xFE ); + assert( m.data[1] == 0xFF ); + em.position(0); + em.writeBOM(BOM.UTF16LE); + assert( m.data[0] == 0xFF ); + assert( m.data[1] == 0xFE ); + em.position(0); + em.writeString ("Hello, world"); + em.position(0); + assert( em.readBOM == -1 ); + assert( em.getc() == 'H' ); + assert( em.getc() == 'e' ); + assert( em.getc() == 'l' ); + assert( em.getc() == 'l' ); + em.position(0); + } +} + // Parameterized stream class that wraps an array-like type. // The Buffer type must support .length, opIndex and opSlice class TArrayStream(Buffer): Stream @@ -2178,6 +2507,13 @@ static this() { + // init ByteOrderMarks + ByteOrderMarks[BOM.UTF8] = BOM_UTF8_data; + ByteOrderMarks[BOM.UTF16LE] = BOM_UTF16LE_data; + ByteOrderMarks[BOM.UTF16BE] = BOM_UTF16BE_data; + ByteOrderMarks[BOM.UTF32LE] = BOM_UTF32LE_data; + ByteOrderMarks[BOM.UTF32BE] = BOM_UTF32BE_data; + // open standard I/O devices stdin = new File(GetStdHandle(-10), FileMode.In); stdout = new File(GetStdHandle(-11), FileMode.Out); @@ -2189,6 +2525,13 @@ { static this() { + // init ByteOrderMarks + ByteOrderMarks[BOM.UTF8] = BOM_UTF8_data; + ByteOrderMarks[BOM.UTF16LE] = BOM_UTF16LE_data; + ByteOrderMarks[BOM.UTF16BE] = BOM_UTF16BE_data; + ByteOrderMarks[BOM.UTF32LE] = BOM_UTF32LE_data; + ByteOrderMarks[BOM.UTF32BE] = BOM_UTF32BE_data; + // open standard I/O devices stdin = new File(0, FileMode.In); stdout = new File(1, FileMode.Out); @@ -2196,5 +2539,3 @@ } } -import std.string; -import std.file; diff -uNr gdc-0.8/d/phobos/std/string.d gdc-0.9/d/phobos/std/string.d --- gdc-0.8/d/phobos/std/string.d 2004-10-14 02:28:08.000000000 +0200 +++ gdc-0.9/d/phobos/std/string.d 2004-12-18 21:22:55.000000000 +0100 @@ -69,9 +69,6 @@ } void *memmove(void *, void *, uint); int memicmp(char *, char *, uint); - int atoi(char *); - long atoll(char *); - double atof(char *); char *memchr(char *, char, uint); int wcslen(wchar *); @@ -114,13 +111,13 @@ long atoi(char[] s) { - return atoi(toStringz(s)); + return std.c.stdlib.atoi(toStringz(s)); } real atof(char[] s) { // BUG: should implement atold() - return atof(toStringz(s)); + return std.c.stdlib.atof(toStringz(s)); } /********************************** diff -uNr gdc-0.8/d/phobos/std/switcherr.d gdc-0.9/d/phobos/std/switcherr.d --- gdc-0.8/d/phobos/std/switcherr.d 2004-08-25 02:42:24.000000000 +0200 +++ gdc-0.9/d/phobos/std/switcherr.d 2004-11-13 17:29:15.000000000 +0100 @@ -1,7 +1,9 @@ module std.switcherr; -class SwitchError : Object +import std.stdio; + +class SwitchError : Error { private: @@ -12,8 +14,13 @@ { this.linnum = linnum; this.filename = filename; + + char[] buffer = new char[17 + filename.length + linnum.sizeof * 3 + 1]; + int len = sprintf(buffer, "Switch Default %.*s(%u)", filename, linnum); + super(buffer[0..len]); } + public: /*************************************** diff -uNr gdc-0.8/d/phobos/std/thread.d gdc-0.9/d/phobos/std/thread.d --- gdc-0.8/d/phobos/std/thread.d 2004-10-10 18:50:42.000000000 +0200 +++ gdc-0.9/d/phobos/std/thread.d 2004-11-13 17:29:15.000000000 +0100 @@ -629,7 +629,7 @@ npause++; // count of paused threads } } - + // Wait for each paused thread to acknowledge while (npause--) { diff -uNr gdc-0.8/d/phobos/std/typeinfo/ti_Aa.d gdc-0.9/d/phobos/std/typeinfo/ti_Aa.d --- gdc-0.8/d/phobos/std/typeinfo/ti_Aa.d 2004-09-21 01:02:31.000000000 +0200 +++ gdc-0.9/d/phobos/std/typeinfo/ti_Aa.d 2004-11-13 17:29:15.000000000 +0100 @@ -13,6 +13,13 @@ char *str = s; uint hash = 0; +version (none) +{ + foreach (char c; s) + hash = hash * 31 + c; +} +else +{ while (1) { switch (len) @@ -44,7 +51,7 @@ break; } } - +} return hash; } diff -uNr gdc-0.8/d/phobos/win32.mak gdc-0.9/d/phobos/win32.mak --- gdc-0.8/d/phobos/win32.mak 2004-09-29 04:25:49.000000000 +0200 +++ gdc-0.9/d/phobos/win32.mak 2004-12-18 21:22:55.000000000 +0100 @@ -62,7 +62,7 @@ iunknown.obj crc32.obj conv.obj arraycast.obj utf.obj uri.obj \ Czlib.obj Dzlib.obj zip.obj process.obj registry.obj recls.obj \ socket.obj socketstream.obj loader.obj stdarg.obj format.obj stdio.obj \ - perf.obj \ + perf.obj openrj.obj \ ti_Aa.obj ti_Ag.obj ti_C.obj ti_int.obj ti_char.obj \ ti_wchar.obj ti_uint.obj ti_short.obj ti_ushort.obj \ ti_byte.obj ti_ubyte.obj ti_long.obj ti_ulong.obj ti_ptr.obj \ @@ -85,10 +85,10 @@ std\intrinsic.d std\array.d std\switcherr.d std\syserror.d \ std\regexp.d std\random.d std\stream.d std\process.d std\recls.d \ std\socket.d std\socketstream.d std\loader.d std\stdarg.d std\format.d \ - std\stdio.d std\perf.d + std\stdio.d std\perf.d std\openrj.d SRC_STD_C= std\c\process.d std\c\stdlib.d std\c\time.d std\c\stdio.d \ - std\c\math.d std\c\stdarg.d + std\c\math.d std\c\stdarg.d std\c\stddef.d SRC_TI= \ std\typeinfo\ti_wchar.d std\typeinfo\ti_uint.d \ @@ -236,6 +236,99 @@ etc\c\recls\recls.lib +SRC_STLSOFT_NEW= \ + etc\c\stlsoft\winstl_file_path_buffer.h \ + etc\c\stlsoft\inetstl_connection.h \ + etc\c\stlsoft\inetstl_filesystem_traits.h \ + etc\c\stlsoft\inetstl_findfile_sequence.h \ + etc\c\stlsoft\inetstl_searchspec_sequence.h \ + etc\c\stlsoft\inetstl_session.h \ + etc\c\stlsoft\stlsoft.h \ + etc\c\stlsoft\stlsoft_allocator_base.h \ + etc\c\stlsoft\inetstl.h \ + etc\c\stlsoft\stlsoft_auto_buffer.h \ + etc\c\stlsoft\stlsoft_cccap_dmc.h \ + etc\c\stlsoft\stlsoft_cccap_gcc.h \ + etc\c\stlsoft\stlsoft_char_traits.h \ + etc\c\stlsoft\stlsoft_constraints.h \ + etc\c\stlsoft\stlsoft_exceptions.h \ + etc\c\stlsoft\stlsoft_iterator.h \ + etc\c\stlsoft\stlsoft_meta.h \ + etc\c\stlsoft\stlsoft_new_allocator.h \ + etc\c\stlsoft\stlsoft_any_caster.h \ + etc\c\stlsoft\stlsoft_nulldef.h \ + etc\c\stlsoft\stlsoft_sap_cast.h \ + etc\c\stlsoft\stlsoft_searchspec_sequence.h \ + etc\c\stlsoft\stlsoft_sign_traits.h \ + etc\c\stlsoft\stlsoft_simple_algorithms.h \ + etc\c\stlsoft\stlsoft_simple_string.h \ + etc\c\stlsoft\stlsoft_size_traits.h \ + etc\c\stlsoft\stlsoft_string_access.h \ + etc\c\stlsoft\stlsoft_string_tokeniser.h \ + etc\c\stlsoft\stlsoft_type_traits.h \ + etc\c\stlsoft\unixstl.h \ + etc\c\stlsoft\unixstl_filesystem_traits.h \ + etc\c\stlsoft\unixstl_file_path_buffer.h \ + etc\c\stlsoft\unixstl_glob_sequence.h \ + etc\c\stlsoft\unixstl_string_access.h \ + etc\c\stlsoft\unixstl_thread_mutex.h \ + etc\c\stlsoft\winstl.h \ + etc\c\stlsoft\winstl_atomic_functions.h \ + etc\c\stlsoft\winstl_char_conversions.h \ + etc\c\stlsoft\winstl_filesystem_traits.h \ + etc\c\stlsoft\winstl_spin_mutex.h \ + etc\c\stlsoft\winstl_findfile_sequence.h \ + etc\c\stlsoft\winstl_processheap_allocator.h \ + etc\c\stlsoft\winstl_system_version.h \ + etc\c\stlsoft\stlsoft_null.h + +SRC_RECLS_NEW= \ + etc\c\recls\recls_compiler_gcc.h \ + etc\c\recls\recls_retcodes.h \ + etc\c\recls\EntryFunctions.h \ + etc\c\recls\recls_platform_types.h \ + etc\c\recls\recls.h \ + etc\c\recls\recls_wininet_dl.h \ + etc\c\recls\ReclsFileSearch.h \ + etc\c\recls\ReclsFileSearchDirectoryNode_unix.cpp \ + etc\c\recls\ReclsFileSearchDirectoryNode_unix.h \ + etc\c\recls\ReclsFileSearchDirectoryNode_win32.cpp \ + etc\c\recls\ReclsFileSearchDirectoryNode_win32.h \ + etc\c\recls\recls_wininet_dl.cpp \ + etc\c\recls\ReclsFileSearch_unix.cpp \ + etc\c\recls\ReclsFileSearch_win32.cpp \ + etc\c\recls\recls_win32.h \ + etc\c\recls\ReclsFtpSearch.h \ + etc\c\recls\ReclsFtpSearchDirectoryNode_win32.cpp \ + etc\c\recls\ReclsFtpSearchDirectoryNode_win32.h \ + etc\c\recls\recls_util_win32.cpp \ + etc\c\recls\ReclsFtpSearch_win32.cpp \ + etc\c\recls\recls_util_unix.cpp \ + etc\c\recls\recls_api.cpp \ + etc\c\recls\recls_util.h \ + etc\c\recls\recls_api_unix.cpp \ + etc\c\recls\recls_api_win32.cpp \ + etc\c\recls\recls_util.cpp \ + etc\c\recls\recls_assert.h \ + etc\c\recls\recls_compiler.h \ + etc\c\recls\recls_compiler_dmc.h \ + etc\c\recls\recls_platform.h \ + etc\c\recls\recls_debug.h \ + etc\c\recls\recls_defs.h \ + etc\c\recls\recls_fileinfo.cpp \ + etc\c\recls\recls_fileinfo_unix.cpp \ + etc\c\recls\recls_fileinfo_win32.cpp \ + etc\c\recls\recls_unix.h \ + etc\c\recls\recls_ftp.h \ + etc\c\recls\recls_ftp_api_win32.cpp \ + etc\c\recls\recls_internal.cpp \ + etc\c\recls\recls_internal.h \ + etc\c\recls\recls_roots_win32.cpp \ + etc\c\recls\recls_language.h \ + etc\c\recls\recls_roots_unix.cpp \ + etc\c\recls\win32.mak \ + etc\c\recls\linux.mak + phobos.lib : $(OBJS) minit.obj internal\gc\dmgc.lib etc\c\zlib\zlib.lib \ win32.mak etc\c\recls\recls.lib lib -c phobos.lib $(OBJS) minit.obj internal\gc\dmgc.lib \ @@ -370,6 +463,9 @@ #object.obj : object.d # $(DMD) -c $(DFLAGS) object.d +openrj.obj : std\openrj.d + $(DMD) -c $(DFLAGS) std\openrj.d + outbuffer.obj : std\outbuffer.d $(DMD) -c $(DFLAGS) std\outbuffer.d diff -uNr gdc-0.8/d/README gdc-0.9/d/README --- gdc-0.8/d/README 2004-10-25 01:05:45.000000000 +0200 +++ gdc-0.9/d/README 2004-12-19 17:25:21.000000000 +0100 @@ -1,6 +1,6 @@ -D Front End for GCC - Release 1g +D Front End for GCC - Release 0.9 -Last update: October 3, 2004 +Last update: December 19, 2004 Supported Systems * GCC 3.3.x, 3.4.x @@ -15,9 +15,9 @@ Downloads - * Main package (Release 0.8) - http://home.earthlink.net/~dvdfrdmn/d/gdc-0.8.tgz - http://home.earthlink.net/~dvdfrdmn/d/gdc-0.8.tar.bz2 + * Main package (Release 0.9) + http://home.earthlink.net/~dvdfrdmn/d/gdc-0.9.tgz + http://home.earthlink.net/~dvdfrdmn/d/gdc-0.9.tar.bz2 * Build Instructions http://home.earthlink.net/~dvdfrdmn/d/INSTALL.html (or see INSTALL included in the main package) @@ -36,14 +36,15 @@ Status What's Working - * Most features of DigitalMars D version 0.102 + * Most features of Digital Mars D version 0.109 What's not Working * Inline assembler Gray Area / Known Issues - + * See the DStress (http://svn.kuehne.cn/dstress/www/dstress.html) + page for known failing cases. * Debugging information may have a few problems. In any case, GDB does not support D name mangling. * Templates on Mac OS X. The stock compiler doesn't support one-only @@ -69,7 +70,9 @@ Known Differences from DMD - * Private functions are not exported from the object file. + * Private functions are not normally exported from the object + file. However, as of gdc 0.9, they are exported. This will + probably change again. * The type of _argptr in variadic functions is the target-specific va_list type. It is not portable to assume this is a pointer. The only portable way to use _argptr is the std.stdarg.va_arg template. @@ -78,7 +81,7 @@ The compiler driver is named 'gdc' and accepts the standard GCC options. There is also a script named 'dmd' which has the same interface -as the original dmd. +as the Digital Mars dmd. The mapping from DMD options to GCC is as follows: -c @@ -132,6 +135,28 @@ noticeably. Changes + +0.9: + + * Fixes + o Detect use of non-static methods in a static context + o Enumerated types are signed by default + o Anders Bjšrklund's patch for HTML infinite looping + o va_start is now a template. + o Delegate expressions for struct methods now work + o bswap uses unsigned right shift + o Fixed several problems with the dmd script + o Fixed crash when compiling with debug information + o Handle referenes to instance variables without "this" + o Fixed ICE for interfaces with multiple inheritence + o Fix id.h dependcy so concurrent make will work + * Improvements + o Updated to DMD 0.109 + * Notes + o The (undocumented) BitsPer{Pointer,Word} version + identifiers are now prefixed with "GNU_" + o Private declarations are now exported from object files + 0.8: * Fixes o std.loader module is now enabled @@ -145,6 +170,7 @@ using them o Corrected floating point "min_10_exp" properties o std.date.getLocalTZA returns a correct values + o Using gdc to link with C++ should now just need "-lstdc++" * Improvements o Debugging information is vastly improved o DLLs can be built on Cygwin @@ -163,35 +189,6 @@ o Update to DMD 0.102 o Templates are handled better on targets without template support -1f: - - * Fixes - o Compilation and linking problems when overriding some, but not - all interface methods - o Support all comparison operators for arrays - o Static initializers for structs with anonymous unions of - anonymous structs - o Continue in foreach statements - o Increment key in foreach statements - o ICE when storing to bit variables and for some boolean - expression (for GCC 3.3) - o Critical sections without an object - o Semantics of casting to/from void[] - o Problems with unaligned bit slices - o Use -fdebug= properly - o Bit array assumings in GC code - o Build problems due to missing long double support on the host system. - * Improvements - o Update to DMD 0.82 - o Use parts of the Boehm garbage collector to determine the stack - and data extents. This does not change the behavior of the D - garbage collector. - o Support semantic processing of all source files on the command - line before generating code. - o Added the 'dmd' wrapper script. - o Automatically generate support for the target Unix, math, and C - library configuration. - This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or diff -uNr gdc-0.8/d/root/access.c gdc-0.9/d/root/access.c --- gdc-0.8/d/root/access.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/root/access.c 2004-11-23 01:03:10.000000000 +0100 @@ -314,6 +314,13 @@ } // If both are members of the same module, grant access + while (1) + { Dsymbol *sp = smember->toParent(); + if (sp->isFuncDeclaration() && smember->isFuncDeclaration()) + smember = sp; + else + break; + } if (!cd && toParent() == smember->toParent()) { #if LOG diff -uNr gdc-0.8/d/root/aggregate.h gdc-0.9/d/root/aggregate.h --- gdc-0.8/d/root/aggregate.h 2004-10-15 01:21:22.000000000 +0200 +++ gdc-0.9/d/root/aggregate.h 2004-12-18 21:22:55.000000000 +0100 @@ -35,6 +35,7 @@ struct DeleteDeclaration; struct InterfaceDeclaration; struct ClassInfoDeclaration; +struct VarDeclaration; struct dt_t; @@ -65,6 +66,7 @@ unsigned size(); static void alignmember(unsigned salign, unsigned size, unsigned *poffset); Type *getType(); + void addField(Scope *sc, VarDeclaration *v); // Back end Symbol *stag; // tag symbol for debug data @@ -74,6 +76,16 @@ AggregateDeclaration *isAggregateDeclaration() { return this; } }; +struct AnonymousAggregateDeclaration : AggregateDeclaration +{ + AnonymousAggregateDeclaration() + : AggregateDeclaration(0, NULL) + { + } + + AnonymousAggregateDeclaration *isAnonymousAggregateDeclaration() { return this; } +}; + struct StructDeclaration : AggregateDeclaration { int zeroInit; // !=0 if initialize with 0 fill @@ -87,6 +99,7 @@ void toObjFile(); // compile to .obj file void toDt(dt_t **pdt); + void toDebug(); // to symbolic debug info StructDeclaration *isStructDeclaration() { return this; } }; @@ -171,9 +184,11 @@ void accessCheck(Loc loc, Scope *sc, Dsymbol *smember); int isFriendOf(ClassDeclaration *cd); int hasPackageAccess(Scope *sc); + void addLocalClass(Array *); // Back end void toObjFile(); // compile to .obj file + void toDebug(); unsigned baseVtblOffset(BaseClass *bc); Symbol *toSymbol(); Symbol *toVtblSymbol(); diff -uNr gdc-0.8/d/root/attrib.c gdc-0.9/d/root/attrib.c --- gdc-0.8/d/root/attrib.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/root/attrib.c 2004-12-18 21:22:55.000000000 +0100 @@ -29,36 +29,54 @@ this->decl = decl; } -int AttribDeclaration::include() +Array *AttribDeclaration::include() { - return TRUE; + return decl; } void AttribDeclaration::addMember(ScopeDsymbol *sd) { unsigned i; + Array *d = include(); - if (include() && decl) + if (d) { - for (i = 0; i < decl->dim; i++) + for (i = 0; i < d->dim; i++) { Dsymbol *s; - s = (Dsymbol *)decl->data[i]; + s = (Dsymbol *)d->data[i]; s->addMember(sd); } } } +void AttribDeclaration::semantic(Scope *sc) +{ + Array *d = include(); + + //printf("\tAttribDeclaration::semantic '%s'\n",toChars()); + if (d) + { + for (unsigned i = 0; i < d->dim; i++) + { + Dsymbol *s = (Dsymbol *)d->data[i]; + + s->semantic(sc); + } + } +} + void AttribDeclaration::semantic2(Scope *sc) { unsigned i; + Array *d = include(); - if (include() && decl) + if (d) { - for (i = 0; i < decl->dim; i++) + for (i = 0; i < d->dim; i++) { Dsymbol *s; - s = (Dsymbol *)decl->data[i]; + s = (Dsymbol *)d->data[i]; s->semantic2(sc); } } @@ -67,13 +85,14 @@ void AttribDeclaration::semantic3(Scope *sc) { unsigned i; + Array *d = include(); - if (include() && decl) + if (d) { - for (i = 0; i < decl->dim; i++) + for (i = 0; i < d->dim; i++) { Dsymbol *s; - s = (Dsymbol *)decl->data[i]; + s = (Dsymbol *)d->data[i]; s->semantic3(sc); } } @@ -82,13 +101,14 @@ void AttribDeclaration::inlineScan() { unsigned i; + Array *d = include(); - if (include() && decl) + if (d) { - for (i = 0; i < decl->dim; i++) + for (i = 0; i < d->dim; i++) { Dsymbol *s; - s = (Dsymbol *)decl->data[i]; + s = (Dsymbol *)d->data[i]; s->inlineScan(); } } @@ -97,18 +117,41 @@ void AttribDeclaration::toObjFile() { unsigned i; + Array *d = include(); - if (include() && decl) + if (d) { - for (i = 0; i < decl->dim; i++) + for (i = 0; i < d->dim; i++) { Dsymbol *s; - s = (Dsymbol *)decl->data[i]; + s = (Dsymbol *)d->data[i]; s->toObjFile(); } } } +int AttribDeclaration::cvMember(unsigned char *p) +{ + unsigned i; + int nwritten = 0; + int n; + Array *d = include(); + + if (d) + { + for (i = 0; i < d->dim; i++) + { Dsymbol *s; + + s = (Dsymbol *)d->data[i]; + n = s->cvMember(p); + if (p) + p += n; + nwritten += n; + } + } + return nwritten; +} + char *AttribDeclaration::kind() { return "attribute"; @@ -116,14 +159,34 @@ Dsymbol *AttribDeclaration::oneMember() { Dsymbol *s; + Array *d = include(); - if (decl && decl->dim == 1) - { s = (Dsymbol *)decl->data[0]; + if (d && d->dim == 1) + { s = (Dsymbol *)d->data[0]; return s->oneMember(); } return NULL; } +/**************************************** + */ + +void AttribDeclaration::addLocalClass(Array *aclasses) +{ unsigned i; + Array *d = include(); + + if (d) + { + for (i = 0; i < d->dim; i++) + { Dsymbol *s; + + s = (Dsymbol *)d->data[i]; + s->addLocalClass(aclasses); + } + } +} + + void AttribDeclaration::toCBuffer(OutBuffer *buf) { if (decl) @@ -145,7 +208,7 @@ buf->writenl(); } -/********************************* StorageClassDeclaration ****************************/ +/************************* StorageClassDeclaration ****************************/ StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl) : AttribDeclaration(decl) @@ -167,7 +230,9 @@ if (decl) { unsigned stc_save = sc->stc; - sc->stc = stc; + if (stc & (STCauto | STCstatic | STCextern)) + sc->stc &= ~(STCauto | STCstatic | STCextern); + sc->stc |= stc; for (unsigned i = 0; i < decl->dim; i++) { Dsymbol *s = (Dsymbol *)decl->data[i]; @@ -367,6 +432,119 @@ AttribDeclaration::toCBuffer(buf); } +/********************************* AnonDeclaration ****************************/ + +AnonDeclaration::AnonDeclaration(int isunion, Array *decl) + : AttribDeclaration(decl) +{ + this->isunion = isunion; +} + +Dsymbol *AnonDeclaration::syntaxCopy(Dsymbol *s) +{ + AnonDeclaration *ad; + + assert(!s); + ad = new AnonDeclaration(isunion, Dsymbol::arraySyntaxCopy(decl)); + return ad; +} + +void AnonDeclaration::semantic(Scope *sc) +{ + //printf("\tAnonDeclaration::semantic '%s'\n",toChars()); + assert(sc->parent); + + Dsymbol *parent = sc->parent->pastMixin(); + AggregateDeclaration *ad = parent->isAggregateDeclaration(); + + if (!ad || (!ad->isStructDeclaration() && !ad->isClassDeclaration())) + { + error("can only be a part of an aggregate"); + return; + } + + if (decl) + { Scope sc_save = *sc; + AnonymousAggregateDeclaration aad; + int adisunion; + + if (sc->anonAgg) + { ad = sc->anonAgg; + adisunion = sc->inunion; + } + else + adisunion = ad->isUnionDeclaration() != NULL; + + sc->anonAgg = &aad; + sc->stc &= ~(STCauto | STCstatic); + sc->inunion = isunion; + sc->offset = 0; + sc->flags = 0; + aad.structalign = sc->structalign; + + for (unsigned i = 0; i < decl->dim; i++) + { + Dsymbol *s = (Dsymbol *)decl->data[i]; + + s->semantic(sc); + if (isunion) + sc->offset = 0; + } + *sc = sc_save; + + // 0 sized structs are set to 1 byte + if (aad.structsize == 0) + { + aad.structsize = 1; + aad.alignsize = 1; + } + + // Align size of anonymous aggregate +//printf("aad.structalign = %d, aad.alignsize = %d, sc->offset = %d\n", aad.structalign, aad.alignsize, sc->offset); + ad->alignmember(aad.structalign, aad.alignsize, &sc->offset); + //ad->structsize = sc->offset; +//printf("sc->offset = %d\n", sc->offset); + + // Add members of aad to ad + //printf("\tadding members of aad to '%s'\n", ad->toChars()); + for (unsigned i = 0; i < aad.fields.dim; i++) + { + VarDeclaration *v = (VarDeclaration *)aad.fields.data[i]; + + v->offset += sc->offset; + ad->fields.push(v); + } + + // Add size of aad to ad + if (adisunion) + { + if (aad.structsize > ad->structsize) + ad->structsize = aad.structsize; + sc->offset = 0; + } + else + { + ad->structsize = sc->offset + aad.structsize; + sc->offset = ad->structsize; + } + + if (ad->alignsize < aad.alignsize) + ad->alignsize = aad.alignsize; + } +} + + +void AnonDeclaration::toCBuffer(OutBuffer *buf) +{ + buf->printf(isunion ? "union" : "struct"); + AttribDeclaration::toCBuffer(buf); +} + +char *AnonDeclaration::kind() +{ + return (char *)(isunion ? "anonymous union" : "anonymous struct"); +} + /********************************* PragmaDeclaration ****************************/ PragmaDeclaration::PragmaDeclaration(Identifier *ident, Array *args, Array *decl) @@ -465,92 +643,12 @@ // Decide if debug code should be included -int DebugDeclaration::include() +Array *DebugDeclaration::include() { assert(condition); - return condition->include(); -} - -void DebugDeclaration::addMember(ScopeDsymbol *sd) -{ - unsigned i; - Array *d = include() ? decl : elsedecl; - - if (d) - { - for (i = 0; i < d->dim; i++) - { Dsymbol *s; - - s = (Dsymbol *)d->data[i]; - s->addMember(sd); - } - } + return condition->include() ? decl : elsedecl; } -void DebugDeclaration::semantic(Scope *sc) -{ - Array *d = include() ? decl : elsedecl; - - //printf("\tDebugDeclaration::semantic '%s'\n",toChars()); - if (d) - { - for (unsigned i = 0; i < d->dim; i++) - { - Dsymbol *s = (Dsymbol *)d->data[i]; - - s->semantic(sc); - } - } -} - - -void DebugDeclaration::semantic2(Scope *sc) -{ - unsigned i; - Array *d = include() ? decl : elsedecl; - - if (d) - { - for (i = 0; i < d->dim; i++) - { Dsymbol *s; - - s = (Dsymbol *)d->data[i]; - s->semantic2(sc); - } - } -} - -void DebugDeclaration::semantic3(Scope *sc) -{ - unsigned i; - Array *d = include() ? decl : elsedecl; - - if (d) - { - for (i = 0; i < d->dim; i++) - { Dsymbol *s; - - s = (Dsymbol *)d->data[i]; - s->semantic3(sc); - } - } -} - -void DebugDeclaration::toObjFile() -{ - unsigned i; - Array *d = include() ? decl : elsedecl; - - if (d) - { - for (i = 0; i < d->dim; i++) - { Dsymbol *s; - - s = (Dsymbol *)d->data[i]; - s->toObjFile(); - } - } -} void DebugDeclaration::toCBuffer(OutBuffer *buf) { diff -uNr gdc-0.8/d/root/attrib.h gdc-0.9/d/root/attrib.h --- gdc-0.8/d/root/attrib.h 2004-04-18 04:14:33.000000000 +0200 +++ gdc-0.9/d/root/attrib.h 2004-12-18 21:22:55.000000000 +0100 @@ -30,16 +30,19 @@ Array *decl; // array of Dsymbol's AttribDeclaration(Array *decl); - virtual int include(); + virtual Array *include(); void addMember(ScopeDsymbol *s); + void semantic(Scope *sc); void semantic2(Scope *sc); void semantic3(Scope *sc); void inlineScan(); char *kind(); Dsymbol *oneMember(); + void addLocalClass(Array *); void toCBuffer(OutBuffer *buf); void toObjFile(); // compile to .obj file + int cvMember(unsigned char *p); }; struct StorageClassDeclaration: AttribDeclaration @@ -84,6 +87,17 @@ void toCBuffer(OutBuffer *buf); }; +struct AnonDeclaration : AttribDeclaration +{ + int isunion; + + AnonDeclaration(int isunion, Array *decl); + Dsymbol *syntaxCopy(Dsymbol *s); + void semantic(Scope *sc); + void toCBuffer(OutBuffer *buf); + char *kind(); +}; + struct PragmaDeclaration : AttribDeclaration { Identifier *ident; Array *args; // array of Expression's @@ -101,14 +115,8 @@ DebugDeclaration(Condition *condition, Array *decl, Array *elsedecl); Dsymbol *syntaxCopy(Dsymbol *s); - int include(); - void addMember(ScopeDsymbol *s); - void semantic(Scope *sc); - void semantic2(Scope *sc); - void semantic3(Scope *sc); + Array *include(); void toCBuffer(OutBuffer *buf); - - void toObjFile(); // compile to .obj file }; struct VersionDeclaration : DebugDeclaration diff -uNr gdc-0.8/d/root/cast.c gdc-0.9/d/root/cast.c --- gdc-0.8/d/root/cast.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/cast.c 2004-12-18 21:22:55.000000000 +0100 @@ -68,15 +68,61 @@ } if (t->ty == Tbit && isBit()) return MATCHconvert; + Expression *e = optimize(WANTvalue | WANTflags); + if (e != this) + { //printf("optimzed to %s\n", e->toChars()); + return e->implicitConvTo(t); + } return type->implicitConvTo(t); } int IntegerExp::implicitConvTo(Type *t) { +#if 0 + printf("IntegerExp::implicitConvTo(this=%s, type=%s, t=%s)\n", + toChars(), type->toChars(), t->toChars()); +#endif if (type->equals(t)) return MATCHexact; + switch (type->toBasetype()->ty) + { + case Tbit: + value &= 1; + break; + + case Tint8: + value = (signed char)value; + break; + + case Tchar: + case Tuns8: + value &= 0xFF; + break; + + case Tint16: + value = (short)value; + break; + + case Tuns16: + case Twchar: + value &= 0xFFFF; + break; + + case Tint32: + value = (int)value; + break; + + case Tuns32: + case Tdchar: + value &= 0xFFFFFFFF; + break; + + default: + break; + } + // Only allow conversion if no change in value switch(t->ty) { @@ -90,8 +136,9 @@ goto Lno; goto Lyes; - case Tascii: + case Tchar: case Tuns8: + //printf("value = %llu %llu\n", (integer_t)(unsigned char)value, value); if ((unsigned char)value != value) goto Lno; goto Lyes; @@ -112,40 +159,74 @@ goto Lyes; case Tuns32: - case Tdchar: if ((unsigned)value != value) goto Lno; goto Lyes; + case Tdchar: + if (value > 0x10FFFFUL) + goto Lno; + goto Lyes; + case Twchar: - if ((wchar_t)value != value) + if ((unsigned short)value != value) goto Lno; goto Lyes; case Tfloat32: case Tcomplex32: { - volatile float f = (float)value; - if (f != value) - goto Lno; + volatile float f; + if (type->isunsigned()) + { + f = (float)value; + if (f != value) + goto Lno; + } + else + { + f = (float)(long long)value; + if (f != (long long)value) + goto Lno; + } goto Lyes; } case Tfloat64: case Tcomplex64: { - volatile double d = (double)value; - if (d != value) - goto Lno; + volatile double f; + if (type->isunsigned()) + { + f = (double)value; + if (f != value) + goto Lno; + } + else + { + f = (double)(long long)value; + if (f != (long long)value) + goto Lno; + } goto Lyes; } case Tfloat80: case Tcomplex80: { - volatile long double ld = (long double)value; - if (ld != value) - goto Lno; + volatile long double f; + if (type->isunsigned()) + { + f = (long double)value; + if (f != value) + goto Lno; + } + else + { + f = (long double)(long long)value; + if (f != (long long)value) + goto Lno; + } goto Lyes; } } @@ -303,6 +384,10 @@ { Expression *e; Type *tb; +#if 0 + printf("Expression::castTo(this=%s, type=%s, t=%s)\n", + toChars(), type->toChars(), t->toChars()); +#endif e = this; tb = t->toBasetype(); type = type->toBasetype(); @@ -756,17 +841,32 @@ } else if (t1->isintegral() && t2->isintegral()) { - if (t1->ty > t2->ty) + //printf("t1 = %s, t2 = %s\n", t1->toChars(), t2->toChars()); + int sz1 = t1->size(); + int sz2 = t2->size(); + int sign1 = t1->isunsigned() == 0; + int sign2 = t2->isunsigned() == 0; + + if (sign1 == sign2) + { + if (sz1 < sz2) + goto Lt2; + else + goto Lt1; + } + if (!sign1) { - if (t1->ty >= Tuns32) - e2 = e2->castTo(t1); + if (sz1 >= sz2) + goto Lt1; + else + goto Lt2; } else { - if (t2->ty >= Tuns32) - { e1 = e1->castTo(t2); - t = t2; - } + if (sz2 >= sz1) + goto Lt2; + else + goto Lt1; } } else if (t1->ty == Tpointer && t2->ty == Tpointer) @@ -807,13 +907,11 @@ } else if ((t1->ty == Tsarray || t1->ty == Tarray) && t1->implicitConvTo(t2)) { - e1 = e1->castTo(t2); - t = t2; + goto Lt2; } else if ((t2->ty == Tsarray || t2->ty == Tarray) && t2->implicitConvTo(t1)) { - e2 = e2->castTo(t1); - t = t1; + goto Lt1; } else if (t1->ty == Tclass || t2->ty == Tclass) { int i1; @@ -833,26 +931,22 @@ if (i2) { - e1 = e1->castTo(t2); - t = t2; + goto Lt2; } else if (i1) { - e2 = e2->castTo(t1); - t = t1; + goto Lt1; } else goto Lincompatible; } else if ((e1->op == TOKstring || e1->op == TOKnull) && e1->implicitConvTo(t2)) { - e1 = e1->castTo(t2); - t = t2; + goto Lt2; } else if ((e2->op == TOKstring || e2->op == TOKnull) && e2->implicitConvTo(t1)) { - e2 = e2->castTo(t1); - t = t1; + goto Lt1; } else if (t1->ty == Tsarray && t2->ty == Tsarray && e2->implicitConvTo(t1->next->arrayOf())) @@ -875,10 +969,22 @@ e1->toChars(), Token::toChars(op), e2->toChars(), t1->toChars(), t2->toChars()); } +Lret: if (!type) type = t; //dump(0); return this; + + +Lt1: + e2 = e2->castTo(t1); + t = t1; + goto Lret; + +Lt2: + e1 = e1->castTo(t2); + t = t2; + goto Lret; } /*********************************** @@ -901,7 +1007,7 @@ case Tint16: case Tuns16: case Tbit: - case Tascii: + case Tchar: case Twchar: e = e->castTo(Type::tint32); break; diff -uNr gdc-0.8/d/root/class.c gdc-0.9/d/root/class.c --- gdc-0.8/d/root/class.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/root/class.c 2004-12-18 21:22:55.000000000 +0100 @@ -69,10 +69,10 @@ if (!Type::typeinfo && id == Id::TypeInfo) Type::typeinfo = this; - if (!Type::typeinfoclass && id == Id::TypeInfoClass) + if (!Type::typeinfoclass && id == Id::TypeInfo_Class) Type::typeinfoclass = this; - if (!Type::typeinfotypedef && id == Id::TypeInfoTypedef) + if (!Type::typeinfotypedef && id == Id::TypeInfo_Typedef) Type::typeinfotypedef = this; com = 0; @@ -287,11 +287,14 @@ alignsize = 4; } structsize = sc->offset; - for (i = 0; i < members->dim; i++) + Scope scsave = *sc; + int members_dim = members->dim; + for (i = 0; i < members_dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; s->semantic(sc); } + structsize = sc->offset; //members->print(); /* Look for special member functions. @@ -323,6 +326,8 @@ ctor->fbody = new CompoundStatement(0, new Array()); members->push(ctor); ctor->addMember(this); + *sc = scsave; + sc->offset = structsize; ctor->semantic(sc); } @@ -564,6 +569,14 @@ return "class"; } +/**************************************** + */ + +void ClassDeclaration::addLocalClass(Array *aclasses) +{ + aclasses->push(this); +} + /********************************* InterfaceDeclaration ****************************/ InterfaceDeclaration::InterfaceDeclaration(Loc loc, Identifier *id, Array *baseclasses) diff -uNr gdc-0.8/d/root/constfold.c gdc-0.9/d/root/constfold.c --- gdc-0.8/d/root/constfold.c 2004-10-10 18:50:41.000000000 +0200 +++ gdc-0.9/d/root/constfold.c 2004-12-18 21:22:55.000000000 +0100 @@ -42,27 +42,32 @@ int Expression::isConst() { //printf("Expression::isConst(): %s\n", toChars()); - return FALSE; + return 0; } int IntegerExp::isConst() { - return TRUE; + return 1; } int RealExp::isConst() { - return TRUE; + return 1; } int ImaginaryExp::isConst() { - return TRUE; + return 1; } int ComplexExp::isConst() { - return TRUE; + return 1; +} + +int SymOffExp::isConst() +{ + return 2; } /* ================================== constFold() ============================== */ @@ -126,12 +131,10 @@ return e1; } + if (type->toBasetype()->ty == Tbit) + return new IntegerExp(loc, e1->toInteger() != 0, type); if (type->isintegral()) - { - IntegerExp * e = new IntegerExp(loc, e1->toInteger(), type); - e->toInteger(); - return e; - } + return new IntegerExp(loc, e1->toInteger(), type); if (type->isreal()) return new RealExp(loc, e1->toReal(), type); if (type->isimaginary()) @@ -140,7 +143,8 @@ return new ComplexExp(loc, e1->toComplex(), type); if (type->isscalar()) return new IntegerExp(loc, e1->toInteger(), type); - error("cannot cast %s to %s", e1->type->toChars(), type->toChars()); + if (type->toBasetype()->ty != Tvoid) + error("cannot cast %s to %s", e1->type->toChars(), type->toChars()); return this; } @@ -151,6 +155,8 @@ //printf("AddExp::constFold(%s)\n", toChars()); e1 = e1->constFold(); e2 = e2->constFold(); + if (e1->op == TOKsymoff && e2->op == TOKsymoff) + return this; if (type->isreal()) { e = new RealExp(loc, e1->toReal() + e2->toReal(), type); @@ -186,6 +192,8 @@ e1 = e1->constFold(); e2 = e2->constFold(); + if (e2->op == TOKsymoff) + return this; if (type->isreal()) { e = new RealExp(loc, e1->toReal() - e2->toReal(), type); @@ -205,13 +213,16 @@ e->type = type; } else + { e = new IntegerExp(loc, e1->toInteger() - e2->toInteger(), type); + } return e; } Expression *MulExp::constFold() { Expression *e; + //printf("MulExp::constFold(%s)\n", toChars()); e1 = e1->constFold(); e2 = e2->constFold(); if (type->isfloating()) diff -uNr gdc-0.8/d/root/debcond.c gdc-0.9/d/root/debcond.c --- gdc-0.8/d/root/debcond.c 2004-09-29 04:25:48.000000000 +0200 +++ gdc-0.9/d/root/debcond.c 2004-11-23 01:03:10.000000000 +0100 @@ -110,6 +110,33 @@ void VersionCondition::addGlobalIdent(char *ident) { + static char* reserved[] = + { + "DigitalMars", "X86", "AMD64", + "Windows", "Win32", "Win64", + "linux", + "LittleEndian", "BigEndian", + "none", + }; + + for (unsigned i = 0; i < sizeof(reserved) / sizeof(reserved[0]); i++) + { + if (strcmp(ident, reserved[i]) == 0) + goto Lerror; + } + + if (ident[0] == 'D' && ident[1] == '_') + goto Lerror; + + addPredefinedGlobalIdent(ident); + return; + + Lerror: + error("version identifier '%s' is reserved and cannot be set", ident); +} + +void VersionCondition::addPredefinedGlobalIdent(char *ident) +{ if (!global.params.versionids) global.params.versionids = new Array(); global.params.versionids->push(ident); diff -uNr gdc-0.8/d/root/debcond.h gdc-0.9/d/root/debcond.h --- gdc-0.8/d/root/debcond.h 2004-09-29 04:25:48.000000000 +0200 +++ gdc-0.9/d/root/debcond.h 2004-11-23 01:03:10.000000000 +0100 @@ -33,6 +33,7 @@ { static void setGlobalLevel(unsigned level); static void addGlobalIdent(char *ident); + static void addPredefinedGlobalIdent(char *ident); DebugCondition(Module *mod, unsigned level, Identifier *ident); @@ -43,6 +44,7 @@ { static void setGlobalLevel(unsigned level); static void addGlobalIdent(char *ident); + static void addPredefinedGlobalIdent(char *ident); VersionCondition(Module *mod, unsigned level, Identifier *ident); diff -uNr gdc-0.8/d/root/declaration.c gdc-0.9/d/root/declaration.c --- gdc-0.8/d/root/declaration.c 2004-09-29 04:25:48.000000000 +0200 +++ gdc-0.9/d/root/declaration.c 2004-12-18 21:22:55.000000000 +0100 @@ -245,31 +245,42 @@ } } L1: + if (overnext) + ScopeDsymbol::multiplyDefined(this, overnext); type = type->semantic(loc, sc); this->inSemantic = 0; return; L2: type = NULL; - FuncDeclaration *f = s->isFuncDeclaration(); - if (f) + VarDeclaration *v = s->isVarDeclaration(); + if (v && v->linkage == LINKdefault) + { + error("forward reference of %s", v->toChars()); + s = NULL; + } + else { + FuncDeclaration *f = s->isFuncDeclaration(); + if (f) + { + if (overnext) + { + FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); + if (!fa->overloadInsert(overnext)) + ScopeDsymbol::multiplyDefined(f, overnext); + overnext = NULL; + s = fa; + } + } if (overnext) + ScopeDsymbol::multiplyDefined(s, overnext); + if (s == this) { - FuncAliasDeclaration *fa = new FuncAliasDeclaration(f); - if (!fa->overloadInsert(overnext)) - ScopeDsymbol::multiplyDefined(f, overnext); - overnext = NULL; - s = fa; + assert(global.errors); + s = NULL; } } - if (overnext) - ScopeDsymbol::multiplyDefined(s, overnext); - if (s == this) - { - assert(global.errors); - s = NULL; - } aliassym = s; this->inSemantic = 0; } @@ -366,6 +377,7 @@ sv = new VarDeclaration(loc, type->syntaxCopy(), ident, init); sv->storage_class = storage_class; + //sv->storage_class |= storage_class & STCauto; } return sv; } @@ -380,6 +392,7 @@ //printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars()); protection = sc->protection; storage_class |= sc->stc; + //printf("sc->stc = %x\n", sc->stc); //printf("storage_class = %x\n", storage_class); Dsymbol *parent = toParent(); @@ -403,51 +416,16 @@ } else { - StructDeclaration *sd = parent->isStructDeclaration(); - if (sd) + AnonymousAggregateDeclaration *aad = sc->anonAgg; + if (aad) { - unsigned memsize; // size of member - unsigned memalignsize; // size of member for alignment purposes - unsigned xalign; // alignment boundaries - - memsize = type->size(); - memalignsize = type->alignsize(); - xalign = type->memalign(sc->structalign); - sd->alignmember(xalign, memalignsize, &sc->offset); - offset = sc->offset; - sc->offset += memsize; - if (sc->offset > sd->structsize) - sd->structsize = sc->offset; - if (sd->alignsize < memalignsize) - sd->alignsize = memalignsize; - - storage_class |= STCfield; - //printf("1 Adding '%s' to '%s'\n", this->toChars(), sd->toChars()); - sd->fields.push(this); - } - - ClassDeclaration *cd = parent->isClassDeclaration(); - if (cd) - { - unsigned memsize; - unsigned memalignsize; - unsigned xalign; - - memsize = type->size(); - memalignsize = type->alignsize(); - xalign = type->memalign(sc->structalign); - cd->alignmember(xalign, memalignsize, &sc->offset); - offset = sc->offset; - //printf("offset of '%s' is x%x\n", toChars(), offset); - sc->offset += memsize; - if (sc->offset > cd->structsize) - cd->structsize = sc->offset; - if (cd->alignsize < memalignsize) - cd->alignsize = memalignsize; - - storage_class |= STCfield; - //printf("2 Adding '%s' to '%s'\n", this->toChars(), cd->toChars()); - cd->fields.push(this); + aad->addField(sc, this); + } + else + { + AggregateDeclaration *ad = parent->isAggregateDeclaration(); + if (ad) + ad->addField(sc, this); } InterfaceDeclaration *id = parent->isInterfaceDeclaration(); @@ -556,6 +534,10 @@ else { init = init->semantic(sc, type); + if (fd && isConst() && !isStatic()) + { // Make it static + storage_class |= STCstatic; + } } } } @@ -721,6 +703,7 @@ void TypeInfoDeclaration::semantic(Scope *sc) { + assert(linkage == LINKc); } /***************************** TypeInfoClassDeclaration ***********************/ diff -uNr gdc-0.8/d/root/declaration.h gdc-0.9/d/root/declaration.h --- gdc-0.8/d/root/declaration.h 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/declaration.h 2004-11-13 17:29:15.000000000 +0100 @@ -122,6 +122,10 @@ Type *getType(); void toCBuffer(OutBuffer *buf); + void toObjFile(); // compile to .obj file + void toDebug(); + int cvMember(unsigned char *p); + TypedefDeclaration *isTypedefDeclaration() { return this; } }; @@ -165,6 +169,7 @@ Symbol *toSymbol(); void toObjFile(); // compile to .obj file + int cvMember(unsigned char *p); // Eliminate need for dynamic_cast VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; } @@ -269,6 +274,7 @@ int inlineNest; // !=0 if nested inline int semanticRun; // !=0 if semantic3() had been run int nestedFrameRef; // !=0 if nested variables referenced frame ptr + int introducing; // !=0 if 'introducing' function ForeachStatement *fes; // if foreach body, this is the foreach // Things that should really go into Scope @@ -313,6 +319,7 @@ Symbol *toSymbol(); Symbol *toThunkSymbol(int offset); // thunk version void toObjFile(); // compile to .obj file + int cvMember(unsigned char *p); FuncDeclaration *isFuncDeclaration() { return this; } }; diff -uNr gdc-0.8/d/root/dsymbol.c gdc-0.9/d/root/dsymbol.c --- gdc-0.8/d/root/dsymbol.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/root/dsymbol.c 2004-11-13 17:29:15.000000000 +0100 @@ -76,6 +76,36 @@ return ident ? ident->toChars() : (char *)"__anonymous"; } +char *Dsymbol::toPrettyChars() +{ Dsymbol *p; + char *s; + char *q; + size_t len; + + if (!parent) + return toChars(); + + len = 0; + for (p = this; p; p = p->parent) + len += strlen(p->toChars()) + 1; + + s = (char *)mem.malloc(len); + q = s + len - 1; + *q = 0; + for (p = this; 1; p = p->parent) + { + char *t = p->toChars(); + len = strlen(t); + q -= len; + memcpy(q, t, len); + if (q == s) + break; + q--; + *q = '.'; + } + return s; +} + char *Dsymbol::locToChars() { OutBuffer buf; @@ -105,7 +135,12 @@ Dsymbol *Dsymbol::toParent() { - Dsymbol *s = parent; + return parent ? parent->pastMixin() : NULL; +} + +Dsymbol *Dsymbol::pastMixin() +{ + Dsymbol *s = this; while (s && s->isTemplateMixin()) s = s->parent; @@ -251,7 +286,7 @@ printf("%s: ", p); mem.free(p); - printf("%s %s ", kind(), toChars()); + printf("%s %s ", kind(), toPrettyChars()); va_list ap; va_start(ap, format); @@ -274,7 +309,7 @@ printf("%s: ", p); mem.free(p); - printf("%s %s ", kind(), toChars()); + printf("%s %s ", kind(), toPrettyChars()); va_list ap; va_start(ap, format); @@ -411,7 +446,7 @@ { Declaration *d = s->isDeclaration(); if (d && d->protection == PROTprivate) - error("%s.%s is private", d->parent->toChars(), d->toChars()); + error("%s is private", d->toPrettyChars()); } } return s; @@ -465,13 +500,13 @@ //printf("s1 = '%s'\n", s1->toChars()); //printf("s2 = '%s', parent = %p\n", s2->toChars(), s2->parent); #if 1 - s1->error("conflicts with %s.%s at %s", - s2->parent->toChars(), s2->toChars(), + s1->error("conflicts with %s at %s", + s2->toPrettyChars(), s2->locToChars()); #else - s1->error("symbol %s.%s conflicts with %s.%s at %s", - s1->parent->toChars(), s1->toChars(), - s2->parent->toChars(), s2->toChars(), + s1->error("symbol %s conflicts with %s at %s", + s1->toPrettyChars(), + s2->toPrettyChars(), s2->locToChars()); #endif } diff -uNr gdc-0.8/d/root/dsymbol.h gdc-0.9/d/root/dsymbol.h --- gdc-0.8/d/root/dsymbol.h 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/dsymbol.h 2004-11-23 01:03:10.000000000 +0100 @@ -89,12 +89,14 @@ Dsymbol(); Dsymbol(Identifier *); char *toChars(); + char *toPrettyChars(); char *locToChars(); int equals(Object *o); int isAnonymous(); void error(Loc loc, const char *format, ...); void error(const char *format, ...); Module *getModule(); + Dsymbol *pastMixin(); Dsymbol *toParent(); int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol() @@ -127,11 +129,13 @@ virtual enum PROT prot(); virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees virtual Dsymbol *oneMember() { return this; } + virtual void addLocalClass(Array *) { } // Backend virtual Symbol *toSymbol(); // to backend symbol virtual void toObjFile(); // compile to .obj file + virtual int cvMember(unsigned char *p); // emit cv debug info for member Symbol *toImport(); // to backend import symbol static Symbol *toImport(Symbol *s); // to backend import symbol diff -uNr gdc-0.8/d/root/enum.h gdc-0.9/d/root/enum.h --- gdc-0.8/d/root/enum.h 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/enum.h 2004-11-13 17:29:15.000000000 +0100 @@ -7,12 +7,6 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. -/* NOTE: This file has been patched from the original DMD distribution to - work with the GDC compiler. - - Modified by David Friedman, September 2004 -*/ - #ifndef DMD_ENUM_H #define DMD_ENUM_H @@ -44,7 +38,9 @@ Type *getType(); char *kind(); - void toObjFile(); + void toObjFile(); // compile to .obj file + void toDebug(); + int cvMember(unsigned char *p); }; diff -uNr gdc-0.8/d/root/expression.c gdc-0.9/d/root/expression.c --- gdc-0.8/d/root/expression.c 2004-10-18 05:27:20.000000000 +0200 +++ gdc-0.9/d/root/expression.c 2004-12-18 21:22:55.000000000 +0100 @@ -61,14 +61,18 @@ { FuncDeclaration *fd; FuncDeclaration *fdthis; + //printf("hasThis()\n"); fdthis = sc->parent->isFuncDeclaration(); + //printf("fdthis = %p, '%s'\n", fdthis, fdthis ? fdthis->toChars() : ""); // Go upwards until we find the enclosing member function fd = fdthis; while (1) { if (!fd) + { printf("test1\n"); goto Lno; + } if (!fd->isNested()) break; @@ -86,7 +90,9 @@ } if (!fd->isThis()) + { //printf("test2 '%s'\n", fd->toChars()); goto Lno; + } assert(fd->vthis); return fd; @@ -398,7 +404,6 @@ integer_t Expression::toInteger() { //printf("Expression %s\n", Token::toChars(op)); -//*(char*)0=0; error("Integer constant expression expected instead of %s", toChars()); return 0; } @@ -460,7 +465,7 @@ void Expression::checkIntegral() { if (!type->isintegral()) - error("'%s' is not an integral type", toChars()); + error("'%s' is not of integral type, it is a %s", toChars(), type->toChars()); } void Expression::checkArithmetic() @@ -600,6 +605,11 @@ IntegerExp::IntegerExp(Loc loc, integer_t value, Type *type) : Expression(loc, TOKint64, sizeof(IntegerExp)) { + if (type && !type->isscalar()) + { + error("integral constant must be scalar type, not %s", type->toChars()); + type = Type::terror; + } this->type = type; this->value = value; } @@ -638,7 +648,7 @@ { switch (t->ty) { - case Tbit: value = value != 0; break; + case Tbit: value = (value != 0); break; case Tint8: value = (d_int8) value; break; case Tchar: case Tuns8: value = (d_uns8) value; break; @@ -714,7 +724,8 @@ type = Type::tint32; } else - type = type->semantic(loc, sc); + { type = type->semantic(loc, sc); + } return this; } @@ -862,7 +873,11 @@ complex_t ImaginaryExp::toComplex() { +#ifdef __DMC__ + return value * I; +#else return complex_t(0, value); +#endif } Expression *ImaginaryExp::semantic(Scope *sc) @@ -904,6 +919,7 @@ { this->value = value; this->type = type; + //printf("ComplexExp::ComplexExp(%s)\n", toChars()); } char *ComplexExp::toChars() @@ -1183,6 +1199,7 @@ } error("%s '%s' is not a variable", s->kind(), s->toChars()); + type = Type::terror; return this; } @@ -1375,6 +1392,20 @@ this->committed = 0; } +int StringExp::equals(Object *o) +{ + //printf("StringExp::equals('%s')\n", o->toChars()); + if (o && o->dyncast() == DYNCAST_EXPRESSION) + { Expression *e = (Expression *)o; + + if (e->op == TOKstring) + { + return compare(o) == 0; + } + } + return FALSE; +} + char *StringExp::toChars() { OutBuffer buf; @@ -1420,10 +1451,32 @@ { case 1: return strcmp((char *)string, (char *)se2->string); + case 2: - return wcscmp((wchar_t *)string, (wchar_t *)se2->string); + { unsigned u; + d_wchar *s1 = (d_wchar *)string; + d_wchar *s2 = (d_wchar *)se2->string; + + for (u = 0; u < len; u++) + { + if (s1[u] != s2[u]) + return s1[u] - s2[u]; + } + } + case 4: - /* not implemented */ + { unsigned u; + d_dchar *s1 = (d_dchar *)string; + d_dchar *s2 = (d_dchar *)se2->string; + + for (u = 0; u < len; u++) + { + if (s1[u] != s2[u]) + return s1[u] - s2[u]; + } + } + break; + default: assert(0); } @@ -1669,6 +1722,8 @@ member = f->isCtorDeclaration(); assert(member); + cd->accessCheck(loc, sc, member); + tf = (TypeFunction *)f->type; type = tf->next; @@ -1807,6 +1862,11 @@ return this; } +int SymOffExp::isBool(int result) +{ + return result ? TRUE : FALSE; +} + void SymOffExp::toCBuffer(OutBuffer *buf) { if (offset) @@ -1815,11 +1875,6 @@ buf->printf("&%s", var->toChars()); } -int SymOffExp::isConst() -{ - return TRUE; -} - /******************************** VarExp **************************/ VarExp::VarExp(Loc loc, Declaration *var) @@ -2017,7 +2072,8 @@ { if (!sc->insert(declaration) || (declaration->isFuncDeclaration() && !sc->func->localsymtab->insert(declaration))) - error("declaration %s.%s is already defined", sc->func->toChars(), declaration->toChars()); + //error("declaration %s.%s is already defined", sc->func->toChars(), declaration->toChars()); + error("declaration %s is already defined", declaration->toPrettyChars()); } if (!declaration->isVarDeclaration()) { declaration->semantic(sc); @@ -2272,6 +2328,44 @@ //{ static int z; fflush(stdout); if (++z == 10) *(char*)0=0; } + /* Special case: rewrite this.id and super.id + * to be classtype.id and baseclasstype.id + * if we have no this pointer. + */ + if ((e1->op == TOKthis || e1->op == TOKsuper) && !hasThis(sc)) + { ClassDeclaration *cd; + StructDeclaration *sd; + AggregateDeclaration *ad; + + ad = sc->getStructClassScope(); + cd = ad->isClassDeclaration(); + if (cd) + { + if (e1->op == TOKthis) + { + e = new TypeDotIdExp(loc, cd->type, ident); + return e->semantic(sc); + } + else if (cd->baseClass && e1->op == TOKsuper) + { + e = new TypeDotIdExp(loc, cd->baseClass->type, ident); + return e->semantic(sc); + } + } + else + { + sd = ad->isStructDeclaration(); + if (sd) + { + if (e1->op == TOKthis) + { + e = new TypeDotIdExp(loc, sd->type, ident); + return e->semantic(sc); + } + } + } + } + UnaExp::semantic(sc); e1 = resolveProperties(sc, e1); @@ -2640,6 +2734,7 @@ #if LOGSEMANTIC printf("DotTypeExp::semantic('%s')\n", toChars()); #endif + UnaExp::semantic(sc); return this; } @@ -2863,7 +2958,7 @@ ClassDeclaration *cd = NULL; if (sc->func) - cd = sc->func->parent->isClassDeclaration(); + cd = sc->func->toParent()->isClassDeclaration(); if (!cd || !cd->baseClass || !sc->func->isCtorDeclaration()) { error("super class constructor call must be in a constructor"); @@ -2898,10 +2993,12 @@ ClassDeclaration *cd = NULL; if (sc->func) - cd = sc->func->parent->isClassDeclaration(); + cd = sc->func->toParent()->isClassDeclaration(); if (!cd || !sc->func->isCtorDeclaration()) { error("class constructor call must be in a constructor"); + type = Type::terror; + return this; } else { @@ -4984,11 +5081,12 @@ return this; BinExp::semanticp(sc); - type = Type::tboolean; + //type = Type::tboolean; Type *t2b = e2->type->toBasetype(); if (t2b->ty != Taarray) { error("rvalue of in expression must be an associative array, not %s", e2->type->toChars()); + type = Type::terror; } else { @@ -4996,13 +5094,16 @@ // Convert key to type of key e1 = e1->implicitCastTo(ta->index); + + // Return type is pointer to value + type = ta->next->pointerTo(); } return this; } int InExp::isBit() { - return TRUE; + return FALSE; } @@ -5046,6 +5147,11 @@ error("array comparison type mismatch, %s vs %s", t1->next->toChars(), t2->next->toChars()); e = this; } + else if (t1->ty == Tstruct || t2->ty == Tstruct) + { + error("need member function opCmp() for struct %s to compare", t1->toChars()); + e = this; + } else e = this; return e; diff -uNr gdc-0.8/d/root/expression.h gdc-0.9/d/root/expression.h --- gdc-0.8/d/root/expression.h 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/expression.h 2004-12-18 21:22:55.000000000 +0100 @@ -265,6 +265,7 @@ unsigned char committed; // !=0 if type is committed StringExp(Loc loc, void *s, unsigned len); + int equals(Object *o); char *toChars(); Expression *semantic(Scope *sc); int implicitConvTo(Type *t); @@ -334,6 +335,8 @@ Expression *semantic(Scope *sc); void toCBuffer(OutBuffer *buf); int isConst(); + int isBool(int result); + Expression *doInline(InlineDoState *ids); elem *toElem(IRState *irs); dt_t **toDt(dt_t **pdt); @@ -884,6 +887,7 @@ AddExp(Loc loc, Expression *e1, Expression *e2); Expression *semantic(Scope *sc); Expression *constFold(); + Expression *optimize(int result); // For operator overloading int isCommutative(); @@ -898,6 +902,7 @@ MinExp(Loc loc, Expression *e1, Expression *e2); Expression *semantic(Scope *sc); Expression *constFold(); + Expression *optimize(int result); // For operator overloading Identifier *opId(); diff -uNr gdc-0.8/d/root/func.c gdc-0.9/d/root/func.c --- gdc-0.8/d/root/func.c 2004-10-15 01:21:22.000000000 +0200 +++ gdc-0.9/d/root/func.c 2004-11-13 17:29:15.000000000 +0100 @@ -62,6 +62,7 @@ inlineAsm = 0; semanticRun = 0; nestedFrameRef = 0; + introducing = 0; fes = NULL; } @@ -268,8 +269,10 @@ } } + // This is an 'introducing' function. // Append to end of vtbl[] //printf("\tappend with %p\n", this); + introducing = 1; vi = cd->vtbl.dim; cd->vtbl.push(this); vtblIndex = vi; @@ -1033,7 +1036,8 @@ { //printf("test4\n"); break; } - if (!s->parent || !s->parent->isTemplateInstance()) + if (!s->parent || + (!s->parent->isTemplateInstance())) { //printf("test5\n"); break; } diff -uNr gdc-0.8/d/root/html.c gdc-0.9/d/root/html.c --- gdc-0.8/d/root/html.c 2004-10-23 22:44:51.000000000 +0200 +++ gdc-0.9/d/root/html.c 2004-11-23 01:03:10.000000000 +0100 @@ -89,10 +89,12 @@ { switch (*p) { + /* case '"': case '\'': skipString(); continue; + */ case '<': if (p[1] == '!' && p[2] == '-' && p[3] == '-') @@ -102,7 +104,11 @@ } else if ((p[1] == '/' && istagstart(p[2])) || istagstart(p[1])) + { skipTag(); + } + else + p++; continue; case 0: @@ -197,6 +203,8 @@ { error("nested tag"); skipTag(); } + else + p++; // Treat comments as if they were whitespace state = TSrest; continue; @@ -507,6 +515,7 @@ { "quot", 34, "amp", 38, + "apos", 39, "lt", 60, "gt", 62, // "nbsp", 160, diff -uNr gdc-0.8/d/root/idgen.c gdc-0.9/d/root/idgen.c --- gdc-0.8/d/root/idgen.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/root/idgen.c 2004-12-18 21:22:55.000000000 +0100 @@ -35,7 +35,7 @@ { "This", "this" }, { "ctor", "_ctor" }, { "dtor", "_dtor" }, - { "classInvariant", "_invariant" }, + { "classInvariant", "__invariant" }, { "unitTest", "_unitTest" }, { "staticCtor", "_staticCtor" }, { "staticDtor", "_staticDtor" }, @@ -44,7 +44,9 @@ { "__sizeof", "sizeof" }, { "alignof" }, { "length" }, + { "ptr" }, { "offset" }, + { "offsetof" }, { "ModuleInfo" }, { "ClassInfo" }, { "classinfo" }, @@ -58,8 +60,8 @@ { "empty", "" }, { "TypeInfo" }, - { "TypeInfoClass" }, - { "TypeInfoTypedef" }, + { "TypeInfo_Class" }, + { "TypeInfo_Typedef" }, { "_arguments" }, { "_argptr" }, diff -uNr gdc-0.8/d/root/impcnvgen.c gdc-0.9/d/root/impcnvgen.c --- gdc-0.8/d/root/impcnvgen.c 2004-04-18 04:14:33.000000000 +0200 +++ gdc-0.9/d/root/impcnvgen.c 2004-12-18 21:22:55.000000000 +0100 @@ -16,6 +16,22 @@ enum TY impcnvType1[TMAX][TMAX]; enum TY impcnvType2[TMAX][TMAX]; +int integral_promotion(int t) +{ + switch (t) + { + case Tchar: + case Twchar: + case Tbit: + case Tint8: + case Tuns8: + case Tint16: + case Tuns16: return Tint32; + case Tdchar: return Tuns32; + default: return t; + } +} + void init() { int i, j; @@ -40,9 +56,9 @@ X(Tbit,Tint16, Tint32,Tint32, Tint32) X(Tbit,Tuns16, Tint32,Tint32, Tint32) X(Tbit,Tint32, Tint32,Tint32, Tint32) - X(Tbit,Tuns32, Tint32,Tuns32, Tint32) + X(Tbit,Tuns32, Tuns32,Tuns32, Tuns32) X(Tbit,Tint64, Tint64,Tint64, Tint64) - X(Tbit,Tuns64, Tint64,Tuns64, Tint64) + X(Tbit,Tuns64, Tuns64,Tuns64, Tuns64) X(Tbit,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tbit,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -56,15 +72,14 @@ /* ======================= */ - X(Tint8,Tbit, Tint32,Tint32, Tint32) X(Tint8,Tint8, Tint32,Tint32, Tint32) X(Tint8,Tuns8, Tint32,Tint32, Tint32) X(Tint8,Tint16, Tint32,Tint32, Tint32) X(Tint8,Tuns16, Tint32,Tint32, Tint32) X(Tint8,Tint32, Tint32,Tint32, Tint32) - X(Tint8,Tuns32, Tint32,Tuns32, Tint32) + X(Tint8,Tuns32, Tuns32,Tuns32, Tuns32) X(Tint8,Tint64, Tint64,Tint64, Tint64) - X(Tint8,Tuns64, Tint64,Tuns64, Tint64) + X(Tint8,Tuns64, Tuns64,Tuns64, Tuns64) X(Tint8,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tint8,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -78,15 +93,13 @@ /* ======================= */ - X(Tuns8,Tbit, Tint32,Tint32, Tint32) - X(Tuns8,Tint8, Tint32,Tint32, Tint32) X(Tuns8,Tuns8, Tint32,Tint32, Tint32) X(Tuns8,Tint16, Tint32,Tint32, Tint32) X(Tuns8,Tuns16, Tint32,Tint32, Tint32) X(Tuns8,Tint32, Tint32,Tint32, Tint32) - X(Tuns8,Tuns32, Tint32,Tuns32, Tint32) + X(Tuns8,Tuns32, Tuns32,Tuns32, Tuns32) X(Tuns8,Tint64, Tint64,Tint64, Tint64) - X(Tuns8,Tuns64, Tint64,Tuns64, Tint64) + X(Tuns8,Tuns64, Tuns64,Tuns64, Tuns64) X(Tuns8,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tuns8,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -100,15 +113,12 @@ /* ======================= */ - X(Tint16,Tbit, Tint32,Tint32, Tint32) - X(Tint16,Tint8, Tint32,Tint32, Tint32) - X(Tint16,Tuns8, Tint32,Tint32, Tint32) X(Tint16,Tint16, Tint32,Tint32, Tint32) X(Tint16,Tuns16, Tint32,Tint32, Tint32) X(Tint16,Tint32, Tint32,Tint32, Tint32) - X(Tint16,Tuns32, Tint32,Tuns32, Tint32) + X(Tint16,Tuns32, Tuns32,Tuns32, Tuns32) X(Tint16,Tint64, Tint64,Tint64, Tint64) - X(Tint16,Tuns64, Tint64,Tuns64, Tint64) + X(Tint16,Tuns64, Tuns64,Tuns64, Tuns64) X(Tint16,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tint16,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -122,15 +132,11 @@ /* ======================= */ - X(Tuns16,Tbit, Tint32,Tint32, Tint32) - X(Tuns16,Tint8, Tint32,Tint32, Tint32) - X(Tuns16,Tuns8, Tint32,Tint32, Tint32) - X(Tuns16,Tint16, Tint32,Tint32, Tint32) X(Tuns16,Tuns16, Tint32,Tint32, Tint32) X(Tuns16,Tint32, Tint32,Tint32, Tint32) - X(Tuns16,Tuns32, Tint32,Tuns32, Tint32) + X(Tuns16,Tuns32, Tuns32,Tuns32, Tuns32) X(Tuns16,Tint64, Tint64,Tint64, Tint64) - X(Tuns16,Tuns64, Tint64,Tuns64, Tint64) + X(Tuns16,Tuns64, Tuns64,Tuns64, Tuns64) X(Tuns16,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tuns16,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -144,15 +150,10 @@ /* ======================= */ - X(Tint32,Tbit, Tint32,Tint32, Tint32) - X(Tint32,Tint8, Tint32,Tint32, Tint32) - X(Tint32,Tuns8, Tint32,Tint32, Tint32) - X(Tint32,Tint16, Tint32,Tint32, Tint32) - X(Tint32,Tuns16, Tint32,Tint32, Tint32) X(Tint32,Tint32, Tint32,Tint32, Tint32) - X(Tint32,Tuns32, Tint32,Tuns32, Tint32) + X(Tint32,Tuns32, Tuns32,Tuns32, Tuns32) X(Tint32,Tint64, Tint64,Tint64, Tint64) - X(Tint32,Tuns64, Tint64,Tuns64, Tint64) + X(Tint32,Tuns64, Tuns64,Tuns64, Tuns64) X(Tint32,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tint32,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -166,15 +167,9 @@ /* ======================= */ - X(Tuns32,Tbit, Tuns32,Tint32, Tint32) - X(Tuns32,Tint8, Tuns32,Tint32, Tint32) - X(Tuns32,Tuns8, Tuns32,Tint32, Tint32) - X(Tuns32,Tint16, Tuns32,Tint32, Tint32) - X(Tuns32,Tuns16, Tuns32,Tint32, Tint32) - X(Tuns32,Tint32, Tuns32,Tint32, Tint32) - X(Tuns32,Tuns32, Tuns32,Tuns32, Tint32) - X(Tuns32,Tint64, Tuns64,Tint64, Tint64) - X(Tuns32,Tuns64, Tuns64,Tuns64, Tint64) + X(Tuns32,Tuns32, Tuns32,Tuns32, Tuns32) + X(Tuns32,Tint64, Tint64,Tint64, Tint64) + X(Tuns32,Tuns64, Tuns64,Tuns64, Tuns64) X(Tuns32,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tuns32,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -188,15 +183,8 @@ /* ======================= */ - X(Tint64,Tbit, Tint64,Tint64, Tint64) - X(Tint64,Tint8, Tint64,Tint64, Tint64) - X(Tint64,Tuns8, Tint64,Tint64, Tint64) - X(Tint64,Tint16, Tint64,Tint64, Tint64) - X(Tint64,Tuns16, Tint64,Tint64, Tint64) - X(Tint64,Tint32, Tint64,Tint64, Tint64) - X(Tint64,Tuns32, Tint64,Tint64, Tint64) X(Tint64,Tint64, Tint64,Tint64, Tint64) - X(Tint64,Tuns64, Tint64,Tuns64, Tint64) + X(Tint64,Tuns64, Tuns64,Tuns64, Tuns64) X(Tint64,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tint64,Tfloat64, Tfloat64,Tfloat64, Tfloat64) @@ -210,14 +198,6 @@ /* ======================= */ - X(Tuns64,Tbit, Tuns64,Tint64, Tint64) - X(Tuns64,Tint8, Tuns64,Tint64, Tint64) - X(Tuns64,Tuns8, Tuns64,Tint64, Tint64) - X(Tuns64,Tint16, Tuns64,Tint64, Tint64) - X(Tuns64,Tuns16, Tuns64,Tint64, Tint64) - X(Tuns64,Tint32, Tuns64,Tint64, Tint64) - X(Tuns64,Tuns32, Tuns64,Tint64, Tint64) - X(Tuns64,Tint64, Tuns64,Tint64, Tint64) X(Tuns64,Tuns64, Tuns64,Tuns64, Tuns64) X(Tuns64,Tfloat32, Tfloat32,Tfloat32, Tfloat32) @@ -232,16 +212,6 @@ /* ======================= */ - X(Tfloat32,Tbit, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tint8, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tuns8, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tint16, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tuns16, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tint32, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tuns32, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tint64, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tuns64, Tfloat32,Tfloat32, Tfloat32) - X(Tfloat32,Tfloat32, Tfloat32,Tfloat32, Tfloat32) X(Tfloat32,Tfloat64, Tfloat64,Tfloat64, Tfloat64) X(Tfloat32,Tfloat80, Tfloat80,Tfloat80, Tfloat80) @@ -256,17 +226,6 @@ /* ======================= */ - X(Tfloat64,Tbit, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tint8, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tuns8, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tint16, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tuns16, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tint32, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tuns32, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tint64, Tfloat64,Tfloat64, Tfloat64) - X(Tfloat64,Tuns64, Tfloat64,Tfloat64, Tfloat64) - - X(Tfloat64,Tfloat32, Tfloat64,Tfloat64, Tfloat64) X(Tfloat64,Tfloat64, Tfloat64,Tfloat64, Tfloat64) X(Tfloat64,Tfloat80, Tfloat80,Tfloat80, Tfloat80) @@ -280,18 +239,6 @@ /* ======================= */ - X(Tfloat80,Tbit, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tint8, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tuns8, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tint16, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tuns16, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tint32, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tuns32, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tint64, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tuns64, Tfloat80,Tfloat80, Tfloat80) - - X(Tfloat80,Tfloat32, Tfloat80,Tfloat80, Tfloat80) - X(Tfloat80,Tfloat64, Tfloat80,Tfloat80, Tfloat80) X(Tfloat80,Tfloat80, Tfloat80,Tfloat80, Tfloat80) X(Tfloat80,Timaginary32, Tfloat80,Timaginary80, Tfloat80) @@ -304,20 +251,6 @@ /* ======================= */ - X(Timaginary32,Tbit, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tint8, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tuns8, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tint16, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tuns16, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tint32, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tuns32, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tint64, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tuns64, Timaginary32,Tfloat32, Tfloat32) - - X(Timaginary32,Tfloat32, Timaginary32,Tfloat32, Tfloat32) - X(Timaginary32,Tfloat64, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary32,Tfloat80, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary32,Timaginary32, Timaginary32,Timaginary32, Timaginary32) X(Timaginary32,Timaginary64, Timaginary64,Timaginary64, Timaginary64) X(Timaginary32,Timaginary80, Timaginary80,Timaginary80, Timaginary80) @@ -328,21 +261,6 @@ /* ======================= */ - X(Timaginary64,Tbit, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tint8, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tuns8, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tint16, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tuns16, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tint32, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tuns32, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tint64, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tuns64, Timaginary64,Tfloat64, Tfloat64) - - X(Timaginary64,Tfloat32, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tfloat64, Timaginary64,Tfloat64, Tfloat64) - X(Timaginary64,Tfloat80, Timaginary80,Tfloat80, Tfloat80) - - X(Timaginary64,Timaginary32, Timaginary64,Timaginary64, Timaginary64) X(Timaginary64,Timaginary64, Timaginary64,Timaginary64, Timaginary64) X(Timaginary64,Timaginary80, Timaginary80,Timaginary80, Timaginary80) @@ -352,22 +270,6 @@ /* ======================= */ - X(Timaginary80,Tbit, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tint8, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tuns8, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tint16, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tuns16, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tint32, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tuns32, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tint64, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tuns64, Timaginary80,Tfloat80, Tfloat80) - - X(Timaginary80,Tfloat32, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tfloat64, Timaginary80,Tfloat80, Tfloat80) - X(Timaginary80,Tfloat80, Timaginary80,Tfloat80, Tfloat80) - - X(Timaginary80,Timaginary32, Timaginary80,Timaginary80, Timaginary80) - X(Timaginary80,Timaginary64, Timaginary80,Timaginary80, Timaginary80) X(Timaginary80,Timaginary80, Timaginary80,Timaginary80, Timaginary80) X(Timaginary80,Tcomplex32, Timaginary80,Tcomplex80, Tcomplex80) @@ -376,75 +278,29 @@ /* ======================= */ - X(Tcomplex32,Tbit, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tint8, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tuns8, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tint16, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tuns16, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tint32, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tuns32, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tint64, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tuns64, Tcomplex32,Tfloat32, Tcomplex32) - - X(Tcomplex32,Tfloat32, Tcomplex32,Tfloat32, Tcomplex32) - X(Tcomplex32,Tfloat64, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex32,Tfloat80, Tcomplex80,Tfloat80, Tcomplex80) - - X(Tcomplex32,Timaginary32, Tcomplex32,Timaginary32, Tcomplex32) - X(Tcomplex32,Timaginary64, Tcomplex64,Timaginary64, Tcomplex64) - X(Tcomplex32,Timaginary80, Tcomplex80,Timaginary80, Tcomplex80) - X(Tcomplex32,Tcomplex32, Tcomplex32,Tcomplex32, Tcomplex32) X(Tcomplex32,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64) X(Tcomplex32,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80) /* ======================= */ - X(Tcomplex64,Tbit, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tint8, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tuns8, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tint16, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tuns16, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tint32, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tuns32, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tint64, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tuns64, Tcomplex64,Tfloat64, Tcomplex64) - - X(Tcomplex64,Tfloat32, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tfloat64, Tcomplex64,Tfloat64, Tcomplex64) - X(Tcomplex64,Tfloat80, Tcomplex80,Tfloat80, Tcomplex80) - - X(Tcomplex64,Timaginary32, Tcomplex64,Timaginary64, Tcomplex64) - X(Tcomplex64,Timaginary64, Tcomplex64,Timaginary64, Tcomplex64) - X(Tcomplex64,Timaginary80, Tcomplex80,Timaginary80, Tcomplex80) - - X(Tcomplex64,Tcomplex32, Tcomplex64,Tcomplex64, Tcomplex64) X(Tcomplex64,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64) X(Tcomplex64,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80) /* ======================= */ - X(Tcomplex80,Tbit, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tint8, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tuns8, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tint16, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tuns16, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tint32, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tuns32, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tint64, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tuns64, Tcomplex80,Tfloat80, Tcomplex80) - - X(Tcomplex80,Tfloat32, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tfloat64, Tcomplex80,Tfloat80, Tcomplex80) - X(Tcomplex80,Tfloat80, Tcomplex80,Tfloat80, Tcomplex80) - - X(Tcomplex80,Timaginary32, Tcomplex80,Timaginary80, Tcomplex80) - X(Tcomplex80,Timaginary64, Tcomplex80,Timaginary80, Tcomplex80) - X(Tcomplex80,Timaginary80, Tcomplex80,Timaginary80, Tcomplex80) - - X(Tcomplex80,Tcomplex32, Tcomplex80,Tcomplex80, Tcomplex80) - X(Tcomplex80,Tcomplex64, Tcomplex80,Tcomplex80, Tcomplex80) X(Tcomplex80,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80) + + for (i = 0; i < TMAX; i++) + for (j = 0; j < TMAX; j++) + { + if (impcnvResult[i][j] == Terror) + { + impcnvResult[i][j] = impcnvResult[j][i]; + impcnvType1[i][j] = impcnvType2[j][i]; + impcnvType2[i][j] = impcnvType1[j][i]; + } + } } int main() diff -uNr gdc-0.8/d/root/inline.c gdc-0.9/d/root/inline.c --- gdc-0.8/d/root/inline.c 2004-09-29 04:25:48.000000000 +0200 +++ gdc-0.9/d/root/inline.c 2004-12-18 21:22:55.000000000 +0100 @@ -353,6 +353,24 @@ return copy(); } +Expression *SymOffExp::doInline(InlineDoState *ids) +{ + int i; + + //printf("SymOffExp::doInline(%s)\n", toChars()); + for (i = 0; i < ids->from.dim; i++) + { + if (var == (Declaration *)ids->from.data[i]) + { + SymOffExp *se = (SymOffExp *)copy(); + + se->var = (Declaration *)ids->to.data[i]; + return se; + } + } + return this; +} + Expression *VarExp::doInline(InlineDoState *ids) { int i; @@ -986,6 +1004,8 @@ vto->storage_class |= vfrom->storage_class & (STCin | STCout); vto->linkage = vfrom->linkage; vto->parent = iss->fd; + //printf("vto = '%s', vto->storage_class = x%x\n", vto->toChars(), vto->storage_class); + //printf("vto->parent = '%s'\n", iss->fd->toChars()); ve = new VarExp(vto->loc, vto); ve->type = vto->type; diff -uNr gdc-0.8/d/root/lexer.c gdc-0.9/d/root/lexer.c --- gdc-0.8/d/root/lexer.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/lexer.c 2004-12-18 21:22:55.000000000 +0100 @@ -24,9 +24,11 @@ #include #include -#if ! HAVE_DECL_STRTOLD +#ifndef IN_GCC +#if __GNUC__ extern "C" long double strtold(const char *p,char **endp); #endif +#endif #if _WIN32 #include "..\root\mem.h" @@ -1546,7 +1548,9 @@ case FLAGS_decimal: if (n & 0x8000000000000000LL) + { error("signed integer overflow"); result = TOKuns64v; + } else if (n & 0xFFFFFFFF80000000LL) result = TOKint64v; else @@ -1561,9 +1565,17 @@ result = TOKuns32v; break; - case FLAGS_long: case FLAGS_decimal | FLAGS_long: if (n & 0x8000000000000000LL) + { error("signed integer overflow"); + result = TOKuns64v; + } + else + result = TOKint64v; + break; + + case FLAGS_long: + if (n & 0x8000000000000000LL) result = TOKuns64v; else result = TOKint64v; @@ -2093,8 +2105,8 @@ Token::tochars[TOKminusminus] = "--"; Token::tochars[TOKtype] = "type"; Token::tochars[TOKquestion] = "?"; - Token::tochars[TOKneg] = "neg"; - Token::tochars[TOKuadd] = "uadd"; + Token::tochars[TOKneg] = "-"; + Token::tochars[TOKuadd] = "+"; Token::tochars[TOKvar] = "var"; Token::tochars[TOKaddass] = "+="; Token::tochars[TOKminass] = "-="; diff -uNr gdc-0.8/d/root/mangle.c gdc-0.9/d/root/mangle.c --- gdc-0.8/d/root/mangle.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/root/mangle.c 2004-12-18 21:22:55.000000000 +0100 @@ -56,6 +56,10 @@ case LINKcpp: return ident->toChars(); + case LINKdefault: + error("forward declaration"); + return ident->toChars(); + default: printf("'%s', linkage = %d\n", toChars(), linkage); assert(0); @@ -133,8 +137,8 @@ * names for them. */ if (ident == Id::TypeInfo || - ident == Id::TypeInfoClass || - ident == Id::TypeInfoTypedef || + ident == Id::TypeInfo_Class || + ident == Id::TypeInfo_Typedef || ident == Id::Exception || ident == Id::Object || ident == Id::ClassInfo || diff -uNr gdc-0.8/d/root/mars.c gdc-0.9/d/root/mars.c --- gdc-0.8/d/root/mars.c 2004-09-29 04:25:48.000000000 +0200 +++ gdc-0.9/d/root/mars.c 2004-12-18 21:22:55.000000000 +0100 @@ -11,11 +11,16 @@ #include #include #include +#include #if __DMC__ #include #endif +#if linux +#include +#endif + #include "mem.h" #include "root.h" @@ -44,7 +49,7 @@ copyright = "Copyright (c) 1999-2004 by Digital Mars"; written = "written by Walter Bright"; - version = "v0.102"; + version = "v0.109"; global.structalign = 8; memset(¶ms, 0, sizeof(Param)); @@ -181,18 +186,19 @@ global.params.objfiles = new Array(); // Predefine version identifiers - VersionCondition::addGlobalIdent("DigitalMars"); + VersionCondition::addPredefinedGlobalIdent("DigitalMars"); #if _WIN32 - VersionCondition::addGlobalIdent("Windows"); - VersionCondition::addGlobalIdent("Win32"); + VersionCondition::addPredefinedGlobalIdent("Windows"); + VersionCondition::addPredefinedGlobalIdent("Win32"); #endif #if linux - VersionCondition::addGlobalIdent("linux"); + VersionCondition::addPredefinedGlobalIdent("linux"); global.params.isLinux = 1; #endif /* linux */ - VersionCondition::addGlobalIdent("X86"); - VersionCondition::addGlobalIdent("LittleEndian"); - VersionCondition::addGlobalIdent("D_InlineAsm"); + VersionCondition::addPredefinedGlobalIdent("X86"); + VersionCondition::addPredefinedGlobalIdent("LittleEndian"); + VersionCondition::addPredefinedGlobalIdent("D_InlineAsm"); + VersionCondition::addPredefinedGlobalIdent("all"); #if _WIN32 inifile(argv[0], "sc.ini"); @@ -275,12 +281,21 @@ if (p[6] == '=') { if (isdigit(p[7])) - DebugCondition::setGlobalLevel(atoi(p + 7)); - else if (isalpha(p[7])) + { long level; + + errno = 0; + level = strtol(p + 7, &p, 10); + if (*p || errno || level > INT_MAX) + goto Lerror; + DebugCondition::setGlobalLevel((int)level); + } + else if (isalpha(p[7]) || p[7] == '_') DebugCondition::addGlobalIdent(p + 7); else goto Lerror; } + else if (p[6]) + goto Lerror; else global.params.debuglevel = 1; } @@ -292,8 +307,15 @@ if (p[8] == '=') { if (isdigit(p[9])) - VersionCondition::setGlobalLevel(atoi(p + 9)); - else if (isalpha(p[9])) + { long level; + + errno = 0; + level = strtol(p + 9, &p, 10); + if (*p || errno || level > INT_MAX) + goto Lerror; + VersionCondition::setGlobalLevel((int)level); + } + else if (isalpha(p[9]) || p[9] == '_') VersionCondition::addGlobalIdent(p + 9); else goto Lerror; @@ -320,11 +342,11 @@ else { Lerror: - error("unrecognized switch '%s'",p); + error("unrecognized switch '%s'", argv[i]); continue; Lnoarg: - error("argument expected for switch '%s'",p); + error("argument expected for switch '%s'", argv[i]); continue; } } @@ -452,6 +474,15 @@ name = (char *)mem.malloc((ext - p) + 1); memcpy(name, p, ext - p); name[ext - p] = 0; // strip extension + + if (name[0] == 0 || + strcmp(name, "..") == 0 || + strcmp(name, ".") == 0) + { + Linvalid: + error("invalid file name '%s'", (char *)files.data[i]); + fatal(); + } } else { error("unrecognized file extension %s\n", ext); @@ -459,7 +490,11 @@ } } else - name = p; + { name = p; + if (!*name) + goto Linvalid; + } + id = new Identifier(name, 0); m = new Module((char *) files.data[i], id); modules.push(m); diff -uNr gdc-0.8/d/root/mars.h gdc-0.9/d/root/mars.h --- gdc-0.8/d/root/mars.h 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/mars.h 2004-12-18 21:22:55.000000000 +0100 @@ -128,7 +128,9 @@ typedef long double d_float80; // Note: this will be 2 bytes on Win32 systems, and 4 bytes under linux. -typedef wchar_t d_wchar; +typedef d_uns8 d_char; +typedef d_uns16 d_wchar; +typedef d_uns32 d_dchar; #ifdef IN_GCC #include "d-gcc-real.h" diff -uNr gdc-0.8/d/root/module.c gdc-0.9/d/root/module.c --- gdc-0.8/d/root/module.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/module.c 2004-12-18 21:22:55.000000000 +0100 @@ -221,6 +221,7 @@ unsigned char *buf; unsigned buflen; unsigned le; + unsigned bom; //printf("Module::parse()\n"); @@ -241,6 +242,7 @@ * EF BB BF UTF-8 */ + bom = 1; // assume there's a BOM if (buf[0] == 0xFF && buf[1] == 0xFE) { if (buflen >= 4 && buf[2] == 0 && buf[3] == 0) @@ -258,7 +260,7 @@ } dbuf.reserve(buflen / 4); - while (++pu < pumax) + for (pu += bom; pu < pumax; pu++) { unsigned u; u = le ? readlongLE(pu) : readlongBE(pu); @@ -293,7 +295,7 @@ } dbuf.reserve(buflen / 2); - while (++pu < pumax) + for (pu += bom; pu < pumax; pu++) { unsigned u; u = le ? readwordLE(pu) : readwordBE(pu); @@ -354,6 +356,7 @@ * figure out the encoding. */ + bom = 0; if (buflen >= 4) { if (buf[1] == 0 && buf[2] == 0 && buf[3] == 0) { // UTF-32LE diff -uNr gdc-0.8/d/root/mtype.c gdc-0.9/d/root/mtype.c --- gdc-0.8/d/root/mtype.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/mtype.c 2004-12-18 21:22:55.000000000 +0100 @@ -348,6 +348,7 @@ //printf("merge(%s)\n", toChars()); t = this; + assert(t); if (!deco) { OutBuffer buf; @@ -526,6 +527,13 @@ { if (ident == Id::offset) { + if (!global.params.useDeprecated) + error(e->loc, ".offset deprecated, use .offsetof"); + goto Loffset; + } + else if (ident == Id::offsetof) + { + Loffset: if (v->storage_class & STCfield) { e = new IntegerExp(e->loc, v->offset, Type::tint32); @@ -1359,7 +1367,8 @@ e = e->castTo(n->arrayOf()); // convert to dynamic array arguments = new Array(); arguments->push(e); - arguments->push(n->getInternalTypeInfo()); + arguments->push(n->ty == Tsarray ? n->getTypeInfo(sc) // don't convert to dynamic array + : n->getInternalTypeInfo()); e = new CallExp(e->loc, ec, arguments); e->type = next->arrayOf(); } @@ -1554,6 +1563,10 @@ { e = dim; } + else if (ident == Id::ptr) + { + e = e->castTo(next->pointerTo()); + } else { e = TypeArray::dotExp(sc, e, ident); @@ -1685,6 +1698,11 @@ e->type = Type::tsize_t; return e; } + else if (ident == Id::ptr) + { + e = e->castTo(next->pointerTo()); + return e; + } else { e = TypeArray::dotExp(sc, e, ident); @@ -2562,6 +2580,7 @@ Expression *e; //printf("TypeQualified::resolveHelper(sc = %p, idents = '%s')\n", sc, toChars()); + //printf("\tscopesym = '%s'\n", scopesym->toChars()); *pe = NULL; *pt = NULL; *ps = NULL; @@ -2643,7 +2662,7 @@ if (v) { // It's not a type, it's an expression - if (v->isConst()) + if (v->isConst() && v->getExpInitializer()) { ExpInitializer *ei = v->getExpInitializer(); assert(ei); @@ -2685,7 +2704,18 @@ } if (t->ty == Tident && t != this) { - ((TypeIdentifier *)t)->resolve(loc, sc, pe, &t, ps); + Scope *scx; + + for (scx = sc; 1; scx = scx->enclosing) + { + if (!scx) + { error(loc, "forward reference to '%s'", t->toChars()); + return; + } + if (scx->scopesym == scopesym) + break; + } + ((TypeIdentifier *)t)->resolve(loc, scx, pe, &t, ps); } *pt = t->merge(); } diff -uNr gdc-0.8/d/root/opover.c gdc-0.9/d/root/opover.c --- gdc-0.8/d/root/opover.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/opover.c 2004-11-13 17:29:15.000000000 +0100 @@ -13,7 +13,7 @@ */ -// Issues with using -include total.h (defines integer_t) and then complex.h fails... +// Issues with using -include total.h (defines integer_t) and then complex.h fails... #undef integer_t #include @@ -248,6 +248,7 @@ * and see which is better. */ Expression *e; + FuncDeclaration *lastf; args1.setDim(1); args1.data[0] = (void*) e1; @@ -258,6 +259,7 @@ memset(&m, 0, sizeof(m)); m.last = MATCHnomatch; overloadResolveX(&m, fd, &args2); + lastf = m.lastf; overloadResolveX(&m, fd_r, &args1); if (m.count > 1) @@ -279,10 +281,10 @@ // Rewrite (e1 ++ e2) as e1.postinc() // Rewrite (e1 -- e2) as e1.postdec() e = build_overload(loc, sc, e1, NULL, id); - else if (m.lastf->ident == id) + else if (lastf && m.lastf == lastf || m.last == MATCHnomatch) // Rewrite (e1 op e2) as e1.opfunc(e2) e = build_overload(loc, sc, e1, e2, id); - else if (m.lastf->ident == id_r) + else // Rewrite (e1 op e2) as e2.opfunc_r(e1) e = build_overload(loc, sc, e2, e1, id_r); return e; @@ -307,6 +309,7 @@ * and see which is better. */ Expression *e; + FuncDeclaration *lastf; if (!argsset) { args1.setDim(1); @@ -318,6 +321,7 @@ memset(&m, 0, sizeof(m)); m.last = MATCHnomatch; overloadResolveX(&m, fd_r, &args2); + lastf = m.lastf; overloadResolveX(&m, fd, &args1); if (m.count > 1) @@ -332,12 +336,13 @@ { m.lastf = m.anyf; } - if (m.lastf->ident == id) - // Rewrite (e1 op e2) as e2.opfunc(e1) - e = build_overload(loc, sc, e2, e1, id); - else if (m.lastf->ident == id_r) + + if (lastf && m.lastf == lastf || m.last == MATCHnomatch) // Rewrite (e1 op e2) as e1.opfunc_r(e2) e = build_overload(loc, sc, e1, e2, id_r); + else + // Rewrite (e1 op e2) as e2.opfunc(e1) + e = build_overload(loc, sc, e2, e1, id); // When reversing operands of comparison operators, // need to reverse the sense of the op @@ -402,9 +407,10 @@ s = ad->search(funcid, 0); if (s) - { - s = s->toAlias(); - fd = s->isFuncDeclaration(); + { Dsymbol *s2; + + s2 = s->toAlias(); + fd = s2->isFuncDeclaration(); if (fd && fd->type->ty == Tfunction) return fd; diff -uNr gdc-0.8/d/root/optimize.c gdc-0.9/d/root/optimize.c --- gdc-0.8/d/root/optimize.c 2004-09-21 01:02:29.000000000 +0200 +++ gdc-0.9/d/root/optimize.c 2004-12-18 21:22:55.000000000 +0100 @@ -30,7 +30,7 @@ { Expression *e; e1 = e1->optimize(result); - if (e1->isConst()) + if (e1->isConst() == 1) e = constFold(); else e = this; @@ -58,7 +58,7 @@ } if (e1->op == TOKvar) { VarExp *ve = (VarExp *)e1; - if (!ve->var->isOut()) + if (!ve->var->isOut() && !ve->var->isImportedSymbol()) { e = new SymOffExp(loc, ve->var, 0); e->type = type; @@ -73,7 +73,8 @@ { integer_t index = ae->e2->toInteger(); VarExp *ve = (VarExp *)ae->e1; - if (ve->type->ty == Tsarray && ve->type->next->ty != Tbit) + if (ve->type->ty == Tsarray && ve->type->next->ty != Tbit + && !ve->var->isImportedSymbol()) { TypeSArray *ts = (TypeSArray *)ve->type; integer_t dim = ts->dim->toInteger(); @@ -142,7 +143,14 @@ } } - return UnaExp::optimize(result); + Expression *e; + + e1 = e1->optimize(result); + if (e1->isConst()) + e = constFold(); + else + e = this; + return e; } Expression *BinExp::optimize(int result) @@ -150,6 +158,30 @@ e1 = e1->optimize(result); e2 = e2->optimize(result); + if (e1->isConst() == 1 && e2->isConst() == 1) + e = constFold(); + else + e = this; + return e; +} + +Expression *AddExp::optimize(int result) +{ Expression *e; + + e1 = e1->optimize(result); + e2 = e2->optimize(result); + if (e1->isConst() && e2->isConst()) + e = constFold(); + else + e = this; + return e; +} + +Expression *MinExp::optimize(int result) +{ Expression *e; + + e1 = e1->optimize(result); + e2 = e2->optimize(result); if (e1->isConst() && e2->isConst()) e = constFold(); else @@ -179,12 +211,12 @@ e1 = e1->optimize(WANTflags); e2 = e2->optimize(WANTflags); e = this; - if (e1->isConst()) + if (e1->isBool(FALSE)) + e = new IntegerExp(loc, 0, type); + else if (e1->isConst()) { if (e2->isConst()) e = constFold(); - else if (e1->isBool(FALSE)) - e = new IntegerExp(loc, 0, type); else if (e1->isBool(TRUE)) e = new BoolExp(loc, e2, type); } @@ -197,12 +229,12 @@ e1 = e1->optimize(WANTflags); e2 = e2->optimize(WANTflags); e = this; - if (e1->isConst()) + if (e1->isBool(TRUE)) + e = new IntegerExp(loc, 1, type); + else if (e1->isConst()) { if (e2->isConst()) e = constFold(); - else if (e1->isBool(TRUE)) - e = new IntegerExp(loc, 1, type); else if (e1->isBool(FALSE)) e = new BoolExp(loc, e2, type); } @@ -215,9 +247,7 @@ //printf("CatExp::optimize(%d)\n", result); e1 = e1->optimize(result); e2 = e2->optimize(result); - if (e1->isConst() && e2->isConst()) - e = constFold(); - else if (e1->op == TOKstring && e2->op == TOKstring) + if (e1->op == TOKstring && e2->op == TOKstring) { // Concatenate the strings void *s; diff -uNr gdc-0.8/d/root/parse.c gdc-0.9/d/root/parse.c --- gdc-0.8/d/root/parse.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/parse.c 2004-12-18 21:22:55.000000000 +0100 @@ -910,7 +910,8 @@ } Dsymbol *Parser::parseAggregate() -{ AggregateDeclaration *a; +{ AggregateDeclaration *a = NULL; + int anon = 0; enum TOK tok; Identifier *id; Array *tpl = NULL; @@ -924,13 +925,13 @@ else { id = token.ident; nextToken(); - } - if (token.value == TOKlparen) - { // Class template declaration. + if (token.value == TOKlparen) + { // Class template declaration. - // Gather template parameter list - tpl = parseTemplateParameterList(); + // Gather template parameter list + tpl = parseTemplateParameterList(); + } } switch (tok) @@ -991,31 +992,47 @@ } case TOKstruct: - a = new StructDeclaration(loc, id); + if (id) + a = new StructDeclaration(loc, id); + else + anon = 1; break; case TOKunion: - a = new UnionDeclaration(loc, id); + if (id) + a = new UnionDeclaration(loc, id); + else + anon = 2; break; default: assert(0); break; } - if (token.value == TOKsemicolon) - nextToken(); + if (a && token.value == TOKsemicolon) + { nextToken(); + } else if (token.value == TOKlcurly) { //printf("aggregate definition\n"); nextToken(); - a->members = parseDeclDefs(0); + Array *decl = parseDeclDefs(0); if (token.value != TOKrcurly) error("struct member expected"); nextToken(); + if (anon) + { + /* Anonymous structs/unions are more like attributes. + */ + return new AnonDeclaration(anon - 1, decl); + } + else + a->members = decl; } else { error("{ } expected following aggregate declaration"); + a = new StructDeclaration(loc, NULL); } if (tpl) @@ -2460,7 +2477,7 @@ while (1) { Type *tb; - Identifier *ai; + Identifier *ai = NULL; Type *at; enum InOut inout; Argument *a; @@ -2472,6 +2489,8 @@ } tb = parseBasicType(); at = parseDeclarator(tb, &ai); + if (!ai) + error("no identifier for declarator"); a = new Argument(inout, at, ai, NULL); arguments->push(a); if (token.value == TOKcomma) diff -uNr gdc-0.8/d/root/root.c gdc-0.9/d/root/root.c --- gdc-0.8/d/root/root.c 2004-10-08 03:26:57.000000000 +0200 +++ gdc-0.9/d/root/root.c 2004-11-13 17:29:15.000000000 +0100 @@ -999,7 +999,7 @@ if (!ref) mem.free(buffer); ref = 2; - buffer = MapViewOfFileEx(hFileMap, FILE_MAP_READ,0,0,size,NULL); + buffer = (unsigned char *)MapViewOfFileEx(hFileMap, FILE_MAP_READ,0,0,size,NULL); if (CloseHandle(hFileMap) != TRUE) goto Lerr; if (buffer == NULL) // mapping view failed diff -uNr gdc-0.8/d/root/scope.c gdc-0.9/d/root/scope.c --- gdc-0.8/d/root/scope.c 2004-04-18 04:14:33.000000000 +0200 +++ gdc-0.9/d/root/scope.c 2004-12-18 21:22:55.000000000 +0100 @@ -60,6 +60,7 @@ this->noctor = 0; this->callSuper = 0; this->flags = 0; + this->anonAgg = NULL; } Scope::Scope(Scope *enclosing) @@ -85,6 +86,7 @@ this->noctor = enclosing->noctor; this->callSuper = enclosing->callSuper; this->flags = 0; + this->anonAgg = NULL; assert(this != enclosing); } @@ -251,6 +253,32 @@ return NULL; } +/******************************************** + * Search enclosing scopes for ClassDeclaration. + */ + +AggregateDeclaration *Scope::getStructClassScope() +{ Scope *sc; + + for (sc = this; sc; sc = sc->enclosing) + { + AggregateDeclaration *ad; + + if (sc->scopesym) + { + ad = sc->scopesym->isClassDeclaration(); + if (ad) + return ad; + else + { ad = sc->scopesym->isStructDeclaration(); + if (ad) + return ad; + } + } + } + return NULL; +} + /******************************************* * For TemplateDeclarations, we need to remember the Scope * where it was declared. So mark the Scope as not diff -uNr gdc-0.8/d/root/scope.h gdc-0.9/d/root/scope.h --- gdc-0.8/d/root/scope.h 2004-04-18 04:14:33.000000000 +0200 +++ gdc-0.9/d/root/scope.h 2004-12-18 21:22:55.000000000 +0100 @@ -24,6 +24,8 @@ struct LabelStatement; struct ForeachStatement; struct ClassDeclaration; +struct AggregateDeclaration; +struct AnonymousAggregateDeclaration; struct FuncDeclaration; enum LINK; enum PROT; @@ -62,6 +64,8 @@ unsigned flags; #define SCOPEctor 1 // constructor type + AnonymousAggregateDeclaration *anonAgg; // for temporary analysis + static Scope *freelist; static void *operator new(size_t sz); static Scope *createGlobal(Module *module); @@ -80,6 +84,7 @@ Dsymbol *insert(Dsymbol *s); ClassDeclaration *getClassScope(); + AggregateDeclaration *getStructClassScope(); void setNoFree(); }; diff -uNr gdc-0.8/d/root/statement.c gdc-0.9/d/root/statement.c --- gdc-0.8/d/root/statement.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/statement.c 2004-12-18 21:22:55.000000000 +0100 @@ -1255,6 +1255,7 @@ { CaseStatement *cs = (CaseStatement *)sw->cases->data[i]; + //printf("comparing '%s' with '%s'\n", exp->toChars(), cs->exp->toChars()); if (cs->exp->equals(exp)) { error("duplicate case %s in switch statement", exp->toChars()); break; @@ -1710,10 +1711,20 @@ Statement *SynchronizedStatement::semantic(Scope *sc) { if (exp) - { + { ClassDeclaration *cd; + exp = exp->semantic(sc); - if (!exp->type->isClassHandle()) + exp = resolveProperties(sc, exp); + cd = exp->type->isClassHandle(); + if (!cd) error("can only synchronize on class objects, not '%s'", exp->type->toChars()); + if (cd->isInterfaceDeclaration()) + { Type *t = new TypeIdentifier(0, Id::Object); + + t = t->semantic(0, sc); + exp = new CastExp(loc, exp, t); + exp = exp->semantic(sc); + } } body = body->semantic(sc); return this; @@ -1837,7 +1848,7 @@ Statement *TryCatchStatement::semantic(Scope *sc) { - body = body->semanticScope(sc, this, NULL); + body = body->semanticScope(sc, NULL /*this*/, NULL); for (int i = 0; i < catches->dim; i++) { Catch *c; diff -uNr gdc-0.8/d/root/struct.c gdc-0.9/d/root/struct.c --- gdc-0.8/d/root/struct.c 2004-05-22 20:15:38.000000000 +0200 +++ gdc-0.9/d/root/struct.c 2004-12-18 21:22:55.000000000 +0100 @@ -131,6 +131,30 @@ //printf("result = %d\n",offset); } + +void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v) +{ + unsigned memsize; // size of member + unsigned memalignsize; // size of member for alignment purposes + unsigned xalign; // alignment boundaries + + memsize = v->type->size(); + memalignsize = v->type->alignsize(); + xalign = v->type->memalign(sc->structalign); + alignmember(xalign, memalignsize, &sc->offset); + v->offset = sc->offset; + sc->offset += memsize; + if (sc->offset > structsize) + structsize = sc->offset; + if (alignsize < memalignsize) + alignsize = memalignsize; + + v->storage_class |= STCfield; + //printf(" addField '%s' to '%s' at offset %d\n", v->toChars(), toChars(), v->offset); + fields.push(v); +} + + /********************************* StructDeclaration ****************************/ StructDeclaration::StructDeclaration(Loc loc, Identifier *id) @@ -183,7 +207,8 @@ if (isUnionDeclaration()) sc2->inunion = 1; sc2->stc &= ~(STCauto | STCstatic); - for (i = 0; i < members->dim; i++) + int members_dim = members->dim; + for (i = 0; i < members_dim; i++) { Dsymbol *s = (Dsymbol *)members->data[i]; s->semantic(sc2); @@ -203,47 +228,59 @@ AggregateDeclaration *sd; - if (isAnonymous() && - (sd = isMember()) != NULL) +#if 0 + if (isAnonymous()) { // Anonymous structures aren't independent, all their members are // added to the enclosing struct. unsigned offset; int isunionsave; - // Align size of enclosing struct - sd->alignmember(structalign, alignsize, &sd->structsize); - - // Add members to enclosing struct - for (i = 0; i < fields.dim; i++) - { - Dsymbol *s = (Dsymbol *)fields.data[i]; - VarDeclaration *vd = s->isVarDeclaration(); - if (vd) - { - vd->addMember(sd); - if (!sd->isUnionDeclaration()) - vd->offset += sd->structsize; - sd->fields.push(vd); - } - else - error("only fields allowed in anonymous struct"); - } - - if (sd->isUnionDeclaration()) + sd = isMember(); + if (!sd) { - if (structsize > sd->structsize) - sd->structsize = structsize; - sc->offset = 0; + error("anonymous struct can only be member of an aggregate"); } else { - sd->structsize += structsize; - sc->offset = sd->structsize; - } + // Align size of enclosing struct + sd->alignmember(structalign, alignsize, &sd->structsize); + + // Add members to enclosing struct + for (i = 0; i < members->dim; i++) + { + Dsymbol *s = (Dsymbol *)members->data[i]; + VarDeclaration *vd = s->isVarDeclaration(); + if (vd && vd->storage_class & STCfield) + { + vd->addMember(sd); + if (!sd->isUnionDeclaration()) + vd->offset += sd->structsize; + sd->fields.push(vd); + sd->members->push(s); + } + else if (!s->isAnonymous()) + { + sd->members->push(s); + } + } - if (sd->alignsize < alignsize) - sd->alignsize = alignsize; + if (sd->isUnionDeclaration()) + { + if (structsize > sd->structsize) + sd->structsize = structsize; + sc->offset = 0; + } + else + { + sd->structsize += structsize; + sc->offset = sd->structsize; + } + + if (sd->alignsize < alignsize) + sd->alignsize = alignsize; + } } +#endif //printf("-StructDeclaration::semantic(this=%p, '%s')\n", this, toChars()); // Determine if struct is all zeros or not diff -uNr gdc-0.8/d/root/template.c gdc-0.9/d/root/template.c --- gdc-0.8/d/root/template.c 2004-09-29 04:25:49.000000000 +0200 +++ gdc-0.9/d/root/template.c 2004-11-13 17:29:15.000000000 +0100 @@ -7,6 +7,12 @@ // in artistic.txt, or the GNU General Public License in gnu.txt. // See the included readme.txt for details. +/* NOTE: This file has been patched from the original DMD distribution to + work with the GDC compiler. + + Modified by David Friedman, September 2004 +*/ + // Handle template implementation #include @@ -234,6 +240,7 @@ assert(dim >= ti->tiargs->dim); // Set up scope for parameters + assert(scope); ScopeDsymbol *paramsym = new ScopeDsymbol(); paramsym->parent = scope->parent; Scope *paramscope = scope->push(paramsym); @@ -1535,12 +1542,6 @@ else assert(tempdecl->isTemplateDeclaration()); - if (!tempdecl->scope) - { - error("forward reference to template"); - return NULL; - } - /* Since there can be multiple TemplateDeclaration's with the same * name, look for the best match. */ @@ -1561,6 +1562,11 @@ continue; dedtypes.setDim(td->parameters->dim); + if (!td->scope) + { + error("forward reference to template"); + return NULL; + } m = td->matchWithInstance(this, &dedtypes, 0); if (!m) // no match at all continue; diff -uNr gdc-0.8/d/root/tocsym.c gdc-0.9/d/root/tocsym.c --- gdc-0.8/d/root/tocsym.c 2004-09-29 04:25:49.000000000 +0200 +++ gdc-0.9/d/root/tocsym.c 2004-12-18 21:22:55.000000000 +0100 @@ -155,6 +155,7 @@ t = type->toCParamtype(); else t = type->toCtype(); + t->Tcount++; if (isDataseg()) { @@ -214,7 +215,6 @@ assert(0); } type_setmangle(&t, m); - t->Tcount++; s->Stype = t; csym = s; @@ -243,7 +243,7 @@ Symbol *TypeInfoDeclaration::toSymbol() { - //printf("TypeInfoDeclaration::toSymbol(%s)\n", toChars()); + //printf("TypeInfoDeclaration::toSymbol(%s), linkage = %d\n", toChars(), linkage); return VarDeclaration::toSymbol(); } diff -uNr gdc-0.8/d/root/todt.c gdc-0.9/d/root/todt.c --- gdc-0.8/d/root/todt.c 2004-10-25 00:28:38.000000000 +0200 +++ gdc-0.9/d/root/todt.c 2004-12-18 21:22:55.000000000 +0100 @@ -62,6 +62,7 @@ return NULL; } + dt_t *StructInitializer::toDt() { Array dts; @@ -72,7 +73,7 @@ dt_t **pdtend; unsigned offset; - //printf("StructInitializer::toDt()\n"); + //printf("StructInitializer::toDt('%s')\n", toChars()); dts.setDim(ad->fields.dim); dts.zero(); @@ -121,16 +122,17 @@ unsigned offset2 = v->offset + v->type->size(); // Make sure this field does not overlap any explicitly // initialized field. - for (k = j + 1; k < dts.dim; k++) + for (k = j + 1; 1; k++) { - VarDeclaration *v2 = (VarDeclaration *)ad->fields.data[k]; - - if (v2->offset < offset2 && dts.data[k]) { + if (k == dts.dim) // didn't find any overlap + { v->type->toDt(&d); // provide default initializer break; } + VarDeclaration *v2 = (VarDeclaration *)ad->fields.data[k]; + + if (v2->offset < offset2 && dts.data[k]) + break; // overlap } - if (k == dts.dim) - v->type->toDt(& d); } } if (d) @@ -154,8 +156,10 @@ return dt; } + dt_t *ArrayInitializer::toDt() { + //printf("ArrayInitializer::toDt('%s')\n", toChars()); Type *tb = type->toBasetype(); Type *tn = tb->next->toBasetype(); @@ -242,6 +246,7 @@ unsigned size; unsigned length; unsigned i; + unsigned tadim; dt_t *d; dt_t **pdtend; Type *tb = type->toBasetype(); @@ -251,11 +256,16 @@ if (tb->ty == Tsarray) { - /* Need to resize to the size of the static array, otherwise set() will - affect bits beyond the last specified element. */ - unsigned sdim = ((TypeSArray*)tb)->dim->toInteger(); // missing overflow check - databits.resize(sdim); - initbits.resize(sdim); + /* The 'dim' for ArrayInitializer is only the maximum dimension + * seen in the initializer, not the type. So, for static arrays, + * use instead the dimension of the type in order + * to get the whole thing. + */ + integer_t value = ((TypeSArray*)tb)->dim->toInteger(); + tadim = value; + assert(tadim == value); // truncation overflow should already be checked + databits.resize(tadim); + initbits.resize(tadim); } else { @@ -263,8 +273,10 @@ initbits.resize(dim); } + /* The default initializer may be something other than zero. + */ if (tb->next->defaultInit()->toInteger()) - databits.set(); + databits.set(); size = sizeof(databits.data[0]); @@ -273,23 +285,28 @@ { Expression *idx; Initializer *val; Expression *eval; - unsigned bitval; idx = (Expression *)index.data[i]; if (idx) - length = idx->toInteger(); + { integer_t value; + value = idx->toInteger(); + length = value; + if (length != value) + { error("index overflow %llu", value); + length = 0; + } + } assert(length < dim); val = (Initializer *)value.data[i]; eval = val->toExpression(); - bitval = eval->toInteger(); if (initbits.test(length)) error("duplicate initializations for index %d", length); initbits.set(length); - if (bitval != 0) + if (eval->toInteger()) // any non-zero value is boolean 'true' databits.set(length); else - databits.clear(length); + databits.clear(length); // boolean 'false' length++; } @@ -302,10 +319,7 @@ switch (tb->ty) { case Tsarray: - { unsigned tadim; - TypeSArray *ta = (TypeSArray *)tb; - - tadim = ta->dim->toInteger(); + { if (dim > tadim) error("too many initializers %d for array[%d]", dim, tadim); else @@ -362,6 +376,7 @@ dt_t **IntegerExp::toDt(dt_t **pdt) { unsigned sz; + //printf("IntegerExp::toDt() %d\n", op); sz = type->size(); if (value == 0) pdt = dtnzeros(pdt, sz); @@ -658,7 +673,7 @@ VarDeclaration *v = (VarDeclaration *)fields.data[i]; Initializer *init; - //printf("\tmember '%s' voffset %d, offset = %d\n", v->toChars(), v->offset, offset); + //printf("\tfield '%s' voffset %d, offset = %d\n", v->toChars(), v->offset, offset); dt = NULL; init = v->init; if (init) @@ -699,14 +714,29 @@ dt_t **TypeSArray::toDt(dt_t **pdt) { int i; - int len; + unsigned len; len = dim->toInteger(); if (len) { while (*pdt) pdt = &((*pdt)->DTnext); - if (next->toBasetype()->ty != Tbit) + if (next->toBasetype()->ty == Tbit) + { + Bits databits; + + databits.resize(len); + if (next->defaultInit()->toInteger()) + databits.set(); +#ifdef IN_GCC + pdt = dtnbits(pdt, databits.allocdim * sizeof(databits.data[0]), + (char *)databits.data, sizeof(databits.data[0])); +#else + pdt = dtnbytes(pdt, databits.allocdim * sizeof(databits.data[0]), + (char *)databits.data); +#endif + } + else { next->toDt(pdt); if ((*pdt)->dt == DT_azeros && !(*pdt)->DTnext) @@ -721,19 +751,6 @@ } } } - else - { - Bits databits; - - databits.resize(len); - if (next->defaultInit()->toInteger()) - databits.set(); -#ifdef IN_GCC - pdt = dtnbits(pdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data, sizeof(databits.data[0])); -#else - pdt = dtnbytes(pdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data); -#endif - } } return pdt; } diff -uNr gdc-0.8/d/root/toobj.c gdc-0.9/d/root/toobj.c --- gdc-0.8/d/root/toobj.c 2004-10-08 03:26:57.000000000 +0200 +++ gdc-0.9/d/root/toobj.c 2004-11-23 01:03:10.000000000 +0100 @@ -95,14 +95,10 @@ for (i = 0; i < members->dim; i++) { Dsymbol *member; - ClassDeclaration *cd; member = (Dsymbol *)members->data[i]; //printf("\tmember '%s'\n", member->toChars()); - if ((cd = member->isClassDeclaration()) != NULL) - { - aclasses.push(cd); - } + member->addLocalClass(&aclasses); } // importedModules[] @@ -192,6 +188,9 @@ if (!members) return; + if (global.params.symdebug) + toDebug(); + assert(!scope); // semantic() should have been run to completion if (parent && parent->isTemplateInstance()) @@ -599,6 +598,9 @@ //printf("InterfaceDeclaration::toObjFile('%s')\n", toChars()); + if (members && global.params.symdebug) + toDebug(); + if (parent && parent->isTemplateInstance()) scclass = SCcomdat; else @@ -729,6 +731,8 @@ // do not output forward referenced structs's if (!isAnonymous() && members) { + if (global.params.symdebug) + toDebug(); // Generate static initializer toInitializer(); @@ -816,7 +820,43 @@ dim = ((TypeSArray *)tb)->dim->toInteger(); - if (tb->next->toBasetype()->ty != Tbit) + if (tb->next->toBasetype()->ty == Tbit) + { integer_t value; + +#ifndef IN_GCC + value = ie->exp->toInteger(); + value = (value & 1) ? ~(integer_t)0 : (integer_t)0; + if (value == 0) + { + dtnzeros(&s->Sdt, ((unsigned)dim + 31) / 32 * 4); + } + else + { + while (dim >= 32) + { + dtnbytes(&s->Sdt, 4, (char *)&value); + dim -= 32; + } + if (dim) + { + value = (1 << dim) - 1; + dtnbytes(&s->Sdt, 4, (char *)&value); + } + } +#else + + s->Sdt = NULL; + if (ie->exp->toInteger()) { + Bits databits; + databits.resize(dim); + databits.set(); + dtnbits(& s->Sdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data, sizeof(databits.data[0])); + } else { + dtnzeros(&s->Sdt, ((unsigned)dim + 31) / 32 * 4); + } +#endif + } + else { // Duplicate Sdt 'dim-1' times, as we already have the first one while (--dim > 0) @@ -824,20 +864,6 @@ ie->exp->toDt(&s->Sdt); } } - else - { - Bits databits; - - databits.resize(dim); - if (ie->exp->toInteger()) - databits.set(); - s->Sdt = NULL; -#ifdef IN_GCC - dtnbits(& s->Sdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data, sizeof(databits.data[0])); -#else - dtnbytes(& s->Sdt, databits.allocdim * sizeof(databits.data[0]), (char *)databits.data); -#endif - } } } else @@ -876,3 +902,24 @@ } } +/* ================================================================== */ + +void TypedefDeclaration::toObjFile() +{ + //printf("TypedefDeclaration::toObjFile('%s')\n", toChars()); + + if (global.params.symdebug) + toDebug(); +} + +/* ================================================================== */ + +void EnumDeclaration::toObjFile() +{ + //printf("EnumDeclaration::toObjFile('%s')\n", toChars()); + + if (global.params.symdebug) + toDebug(); +} + + diff -uNr gdc-0.8/d/root/typinf.c gdc-0.9/d/root/typinf.c --- gdc-0.8/d/root/typinf.c 2004-10-02 19:19:31.000000000 +0200 +++ gdc-0.9/d/root/typinf.c 2004-11-23 01:03:10.000000000 +0100 @@ -63,6 +63,7 @@ Type *t; static TypeInfoDeclaration *internalTI[TMAX]; + //printf("Type::getInternalTypeInfo() %s\n", toChars()); t = toBasetype(); switch (t->ty) { @@ -90,6 +91,7 @@ default: break; } + //printf("\tcalling getTypeInfo() %s\n", t->toChars()); return t->getTypeInfo(NULL); } @@ -102,7 +104,7 @@ { Expression *e; - //printf("Type::getTypeInfo()\n"); + //printf("Type::getTypeInfo() %s\n", toChars()); if (!vtinfo) { vtinfo = getTypeInfoDeclaration(); @@ -125,6 +127,7 @@ TypeInfoDeclaration *Type::getTypeInfoDeclaration() { + //printf("Type::getTypeInfoDeclaration() %s\n", toChars()); return new TypeInfoDeclaration(this, 0); } @@ -146,7 +149,7 @@ void TypeInfoDeclaration::toDt(dt_t **pdt) { - //printf("TypeInfoDeclaration::toDt()\n"); + //printf("TypeInfoDeclaration::toDt() %s\n", toChars()); dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo dtdword(pdt, 0); // monitor } @@ -154,7 +157,7 @@ void TypeInfoTypedefDeclaration::toDt(dt_t **pdt) { //printf("TypeInfoTypedefDeclaration::toDt()\n"); - dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoTypedef + dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef dtdword(pdt, 0); // monitor assert(tinfo->ty == Ttypedef); @@ -296,6 +299,7 @@ } t = Type::typeinfo->type->arrayOf(); + ai->type = t; v = new VarDeclaration(0, t, id, ai); m->members->push(v); m->symtab->insert(v); diff -uNr gdc-0.8/d/root/utf.c gdc-0.9/d/root/utf.c --- gdc-0.8/d/root/utf.c 2004-09-21 01:02:30.000000000 +0200 +++ gdc-0.9/d/root/utf.c 2004-11-13 17:29:15.000000000 +0100 @@ -172,6 +172,8 @@ { msg = "illegal UTF-16 value"; goto Lerr; } + else + i++; } else { diff -uNr gdc-0.8/d/symbol.cc gdc-0.9/d/symbol.cc --- gdc-0.8/d/symbol.cc 2004-10-11 02:13:55.000000000 +0200 +++ gdc-0.9/d/symbol.cc 2004-12-02 02:12:02.000000000 +0100 @@ -35,14 +35,15 @@ Stree = 0; // %% make it NULL-TREE, include d-gcc-include ScontextDecl = 0; + Sunique = 0; memset(& Sspecial, 0, sizeof(Sspecial)); } -// %% fwiw, need to dup the string because sometimes the -// string is alloca()'d Symbol * symbol_calloc(const char * string) { + // Need to dup the string because sometimes the string is alloca()'d + Symbol * s = new Symbol; s->Sident = mem.strdup(string); return s; diff -uNr gdc-0.8/d/symbol.h gdc-0.9/d/symbol.h --- gdc-0.8/d/symbol.h 2004-10-14 02:28:08.000000000 +0200 +++ gdc-0.9/d/symbol.h 2004-12-02 02:12:02.000000000 +0100 @@ -149,6 +149,7 @@ // Specific to GNU backend tree Stree; tree ScontextDecl; // The DECL_CONTEXT to use for child declarations, but see IRState::declContext + unsigned Sunique; // For conflicting symbol names union { AggregateDeclaration * aggDecl; // AggregateDeclaration.sinit set in AggregateDeclaration::toInitializer Array * thunks; // of struct Thunk; for FuncDeclarations