diff --git a/dmd2/canthrow.c b/dmd2/canthrow.c index a7280c1d..885b241a 100644 --- a/dmd2/canthrow.c +++ b/dmd2/canthrow.c @@ -42,7 +42,6 @@ struct CanThrow int Expression::canThrow(bool mustNotThrow) { - //printf("Expression::canThrow(%d) %s\n", mustNotThrow, toChars()); CanThrow ct; ct.can = FALSE; ct.mustnot = mustNotThrow; diff --git a/dmd2/dsymbol.c b/dmd2/dsymbol.c index 0ccec83b..45c2641c 100644 --- a/dmd2/dsymbol.c +++ b/dmd2/dsymbol.c @@ -846,18 +846,20 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) //printf("\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\n", ss->toChars(), prots[i], ss->isModule(), ss->isImport()); /* Don't find private members if ss is a module */ - s2 = ss->search(loc, ident, ss->isImport() ? 1 : 0); + s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0); if (!s) s = s2; else if (s2 && s != s2) { if (s->toAlias() == s2->toAlias()) { - /* After following aliases, we found the same symbol, - * so it's not an ambiguity. - * But if one alias is deprecated, prefer the other. + /* After following aliases, we found the same + * symbol, so it's not an ambiguity. But if one + * alias is deprecated or less accessible, prefer + * the other. */ - if (s->isDeprecated()) + if (s->isDeprecated() || + s2->prot() > s->prot() && s2->prot() != PROTnone) s = s2; } else @@ -887,7 +889,8 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags) { Dsymbol *s3 = a->a[j]; if (s2->toAlias() == s3->toAlias()) { - if (s3->isDeprecated()) + if (s3->isDeprecated() || + s2->prot() > s3->prot() && s2->prot() != PROTnone) a->a[j] = s2; goto Lcontinue; } diff --git a/dmd2/import.c b/dmd2/import.c index b19f19f4..bd43af90 100644 --- a/dmd2/import.c +++ b/dmd2/import.c @@ -27,7 +27,7 @@ Import::Import(Loc loc, Identifiers *packages, Identifier *id, Identifier *aliasId, int isstatic) - : Dsymbol() + : Dsymbol(NULL) { assert(id); this->loc = loc; @@ -35,8 +35,20 @@ Import::Import(Loc loc, Identifiers *packages, Identifier *id, Identifier *alias this->id = id; this->aliasId = aliasId; this->isstatic = isstatic; - pkg = NULL; - mod = NULL; + this->protection = PROTprivate; // default to private + this->pkg = NULL; + this->mod = NULL; + + // Set symbol name (bracketed) + // import [cstdio] = std.stdio; + if (aliasId) + this->ident = aliasId; + // import [std].stdio; + else if (packages && packages->dim) + this->ident = packages->tdata()[0]; + // import [foo]; + else + this->ident = id; } void Import::addAlias(Identifier *name, Identifier *alias) @@ -44,6 +56,9 @@ void Import::addAlias(Identifier *name, Identifier *alias) if (isstatic) error("cannot have an import bind list"); + if (!aliasId) + this->ident = NULL; // make it an anonymous import + names.push(name); aliases.push(alias); } @@ -53,16 +68,22 @@ const char *Import::kind() return isstatic ? (char *)"static import" : (char *)"import"; } +enum PROT Import::prot() +{ + return protection; +} Dsymbol *Import::syntaxCopy(Dsymbol *s) { assert(!s); - Import *si = new Import(loc, packages, id, aliasId, isstatic); + Import *si; + + si = new Import(loc, packages, id, aliasId, isstatic); for (size_t i = 0; i < names.dim; i++) { - si->addAlias(names[i], aliases[i]); + si->addAlias(names.tdata()[i], aliases.tdata()[i]); } return si; @@ -130,12 +151,12 @@ void Import::importAll(Scope *sc) load(sc); mod->importAll(0); - /* Default to private importing - */ - enum PROT prot = sc->protection; - if (!sc->explicitProtection) - prot = PROTprivate; - sc->scopesym->importScope(this, prot); + if (!isstatic && !aliasId && !names.dim) + { + if (sc->explicitProtection) + protection = sc->protection; + sc->scopesym->importScope(mod, protection); + } } } @@ -165,17 +186,17 @@ void Import::semantic(Scope *sc) //printf("%s imports %s\n", sc->module->toChars(), mod->toChars()); sc->module->aimports.push(mod); - /* Default to private importing - */ - enum PROT prot = sc->protection; - if (!sc->explicitProtection) - prot = PROTprivate; - for (Scope *scd = sc; scd; scd = scd->enclosing) + if (!isstatic && !aliasId && !names.dim) { - if (scd->scopesym) + if (sc->explicitProtection) + protection = sc->protection; + for (Scope *scd = sc; scd; scd = scd->enclosing) { - scd->scopesym->importScope(this, prot); - break; + if (scd->scopesym) + { + scd->scopesym->importScope(mod, protection); + break; + } } } @@ -186,12 +207,25 @@ void Import::semantic(Scope *sc) sc->module->needmoduleinfo = 1; } - if (aliasId) - { - AliasDeclaration *ad = new AliasDeclaration(loc, aliasId, mod); - sc->insert(ad); - ad->semantic(sc); + sc = sc->push(mod); + /* BUG: Protection checks can't be enabled yet. The issue is + * that Dsymbol::search errors before overload resolution. + */ +#if 0 + sc->protection = protection; +#else + sc->protection = PROTpublic; +#endif + for (size_t i = 0; i < aliasdecls.dim; i++) + { Dsymbol *s = aliasdecls.tdata()[i]; + + //printf("\tImport alias semantic('%s')\n", s->toChars()); + if (!mod->search(loc, names.tdata()[i], 0)) + error("%s not found", (names.tdata()[i])->toChars()); + + s->semantic(sc); } + sc = sc->pop(); } if (global.params.moduleDeps != NULL) @@ -225,7 +259,7 @@ void Import::semantic(Scope *sc) { for (size_t i = 0; i < packages->dim; i++) { - Identifier *pid = (*packages)[i]; + Identifier *pid = packages->tdata()[i]; ob->printf("%s.", pid->toChars()); } } @@ -245,8 +279,8 @@ void Import::semantic(Scope *sc) else ob->writebyte(','); - Identifier *name = names[i]; - Identifier *alias = aliases[i]; + Identifier *name = names.tdata()[i]; + Identifier *alias = aliases.tdata()[i]; if (!alias) { @@ -258,7 +292,7 @@ void Import::semantic(Scope *sc) } if (aliasId) - ob->printf(" -> %s", aliasId->toChars()); + ob->printf(" -> %s", aliasId->toChars()); ob->writenl(); } @@ -276,6 +310,48 @@ void Import::semantic2(Scope *sc) } } +Dsymbol *Import::toAlias() +{ + if (aliasId) + return mod; + return this; +} + +/***************************** + * Add import to sd's symbol table. + */ + +int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum) +{ + int result = 0; + + if (names.dim == 0) + return Dsymbol::addMember(sc, sd, memnum); + + if (aliasId) + result = Dsymbol::addMember(sc, sd, memnum); + + /* Instead of adding the import to sd's symbol table, + * add each of the alias=name pairs + */ + for (size_t i = 0; i < names.dim; i++) + { + Identifier *name = names.tdata()[i]; + Identifier *alias = aliases.tdata()[i]; + + if (!alias) + alias = name; + + TypeIdentifier *tname = new TypeIdentifier(loc, name); + AliasDeclaration *ad = new AliasDeclaration(loc, alias, tname); + result |= ad->addMember(sc, sd, memnum); + + aliasdecls.push(ad); + } + + return result; +} + Dsymbol *Import::search(Loc loc, Identifier *ident, int flags) { //printf("%s.Import::search(ident = '%s', flags = x%x)\n", toChars(), ident->toChars(), flags); @@ -285,50 +361,14 @@ Dsymbol *Import::search(Loc loc, Identifier *ident, int flags) mod->semantic(); } - if (names.dim) // selective import - { - for (size_t i = 0; i < names.dim; i++) - { - Identifier *name = (Identifier *)names[i]; - Identifier *alias = (Identifier *)aliases[i]; + // Forward it to the package/module + return pkg->search(loc, ident, flags); +} - if (!alias) - alias = name; - - if (alias->equals(ident)) - return mod->search(loc, name, flags); - } - - // What should happen when renamed and selective imports are mixed? - // This makes the whole module available with the renamed id. - if (aliasId && aliasId->equals(ident)) - return mod; - } - else // non-selective import - { - // For renamed imports, only the alias name is visible. - if (aliasId) - { - if (aliasId->equals(ident)) - return mod; - return 0; - } - - // For non-static imports, prefer symbols in the module over the module name. - if (!isstatic) - { - Dsymbol *s = mod->search(loc, ident, flags); - if (s) - return s; - } - - // Make the start of the package name available. - if (pkg->ident->equals(ident)) - { - return pkg; - } - } - return 0; +int Import::overloadInsert(Dsymbol *s) +{ + // Allow multiple imports of the same name + return s->isImport() != NULL; } void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs) @@ -346,7 +386,7 @@ void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs) if (packages && packages->dim) { for (size_t i = 0; i < packages->dim; i++) - { Identifier *pid = (*packages)[i]; + { Identifier *pid = packages->tdata()[i]; buf->printf("%s.", pid->toChars()); } @@ -355,7 +395,3 @@ void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs) buf->writenl(); } -char *Import::toChars() -{ - return id->toChars(); -} diff --git a/dmd2/import.h b/dmd2/import.h index b8979923..a3ef1a55 100644 --- a/dmd2/import.h +++ b/dmd2/import.h @@ -1,6 +1,6 @@ // Compiler implementation of the D programming language -// Copyright (c) 1999-2012 by Digital Mars +// Copyright (c) 1999-2007 by Digital Mars // All Rights Reserved // written by Walter Bright // http://www.digitalmars.com @@ -28,16 +28,18 @@ struct HdrGenState; struct Import : Dsymbol { - // isstatic import aliasId = packages.id; Identifiers *packages; // array of Identifier's representing packages Identifier *id; // module Identifier Identifier *aliasId; int isstatic; // !=0 if static import + enum PROT protection; // Pairs of alias=name to bind into current namespace Identifiers names; Identifiers aliases; + AliasDeclarations aliasdecls; // AliasDeclarations for names/aliases + Module *mod; Package *pkg; // leftmost package/module @@ -46,14 +48,17 @@ struct Import : Dsymbol void addAlias(Identifier *name, Identifier *alias); const char *kind(); + enum PROT prot(); Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees void load(Scope *sc); void importAll(Scope *sc); void semantic(Scope *sc); void semantic2(Scope *sc); + Dsymbol *toAlias(); + int addMember(Scope *sc, ScopeDsymbol *s, int memnum); Dsymbol *search(Loc loc, Identifier *ident, int flags); + int overloadInsert(Dsymbol *s); void toCBuffer(OutBuffer *buf, HdrGenState *hgs); - char *toChars(); Import *isImport() { return this; } }; diff --git a/dmd2/intrange.h b/dmd2/intrange.h index 2904dab9..77685b02 100644 --- a/dmd2/intrange.h +++ b/dmd2/intrange.h @@ -95,14 +95,14 @@ struct IntRange IntRange(const SignExtendedNumber& a) : imin(a), imax(a) {} /// Create a range with the lower and upper bounds. - IntRange(const SignExtendedNumber& lower, const SignExtendedNumber& upper) + IntRange(const SignExtendedNumber& lower, const SignExtendedNumber& upper) : imin(lower), imax(upper) {} - + /// Create the tightest range containing all valid integers in the specified - /// type. + /// type. static IntRange fromType(Type *type); /// Create the tightest range containing all valid integers in the type with - /// a forced signedness. + /// a forced signedness. static IntRange fromType(Type *type, bool isUnsigned); @@ -131,7 +131,7 @@ struct IntRange /// Check if this range contains 0. bool containsZero() const; - /// Compute the range of the negated absolute values of the original range. + /// Compute the range of the negated absolute values of the original range. IntRange absNeg() const; /// Compute the union of two ranges. @@ -139,7 +139,7 @@ struct IntRange void unionOrAssign(const IntRange& other, bool& union_); /// Dump the content of the integer range to the console. - const IntRange& dump(const char* funcName, Expression *e) const; + const IntRange& dump(const char* funcName, Expression *e) const; /// Split the range into two nonnegative- and negative-only subintervals. void splitBySign(IntRange& negRange, bool& hasNegRange, diff --git a/dmd2/root/linux.c b/dmd2/root/linux.c deleted file mode 100644 index 5d50ad51..00000000 --- a/dmd2/root/linux.c +++ /dev/null @@ -1,96 +0,0 @@ -// Copyright (c) 2000-2011 by Digital Mars -// All Rights Reserved -// written by Walter Bright -// http://www.digitalmars.com -// License for redistribution is by either the Artistic License -// in artistic.txt, or the GNU General Public License in gnu.txt. -// See the included readme.txt for details. - - -#include -#include -#include - - -/************************************* - * This is all necessary to get fd initialized at startup. - */ - -#define FDMAP 0 - -#if FDMAP -#include - -struct OS_INIT -{ - static int fd; - - OS_INIT(); -}; - -OS_INIT os_init; - -int OS_INIT::fd = 0; - -OS_INIT::OS_INIT() -{ - fd = open("/dev/zero", O_RDONLY); -} -#endif - -/*********************************** - * Map memory. - */ - -void *os_mem_map(unsigned nbytes) -{ void *p; - - errno = 0; -#if FDMAP - p = mmap(NULL, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE, OS_INIT::fd, 0); -#else - p = mmap(NULL, nbytes, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0); -#endif - return (p == MAP_FAILED) ? NULL : p; -} - -/*********************************** - * Commit memory. - * Returns: - * 0 success - * !=0 failure - */ - -int os_mem_commit(void *base, unsigned offset, unsigned nbytes) -{ - return 0; -} - - -/*********************************** - * Decommit memory. - * Returns: - * 0 success - * !=0 failure - */ - -int os_mem_decommit(void *base, unsigned offset, unsigned nbytes) -{ - return 0; -} - -/*********************************** - * Unmap memory allocated with os_mem_map(). - * Returns: - * 0 success - * !=0 failure - */ - -int os_mem_unmap(void *base, unsigned nbytes) -{ - return munmap(base, nbytes); -} - - - - diff --git a/dmd2/template.c b/dmd2/template.c index e4e2e158..18923b0c 100644 --- a/dmd2/template.c +++ b/dmd2/template.c @@ -1095,6 +1095,9 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec if (tp_is_declared) goto L2; + // Apply function parameter storage classes to parameter type + tid = (TypeIdentifier *)tid->addStorageClass(fparam->storageClass); + /* The types of the function arguments * now form the tuple argument. */ @@ -1105,7 +1108,172 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec t->objects.setDim(tuple_dim); for (size_t i = 0; i < tuple_dim; i++) { Expression *farg = fargs->tdata()[fptupindex + i]; - t->objects.tdata()[i] = farg->type; + unsigned mod = farg->type->mod; + Type *tt; + MATCH m; + + #define X(U,T) ((U) << 4) | (T) + if (tid->mod & MODwild) + { + switch (X(tid->mod, mod)) + { + case X(MODwild, MODwild): + case X(MODwild | MODshared, MODwild | MODshared): + case X(MODwild, 0): + case X(MODwild, MODconst): + case X(MODwild, MODimmutable): + case X(MODwild | MODshared, MODshared): + case X(MODwild | MODshared, MODconst | MODshared): + + if (mod & MODwild) + wildmatch |= MODwild; + else if (mod == 0) + wildmatch |= MODmutable; + else + wildmatch |= (mod & ~MODshared); + tt = farg->type->mutableOf(); + m = MATCHconst; + goto Lx; + + default: + break; + } + } + + switch (X(tid->mod, mod)) + { + case X(0, 0): + case X(0, MODconst): + case X(0, MODimmutable): + case X(0, MODshared): + case X(0, MODconst | MODshared): + case X(0, MODwild): + case X(0, MODwild | MODshared): + // foo(U:U) T => T + // foo(U:U) const(T) => const(T) + // foo(U:U) immutable(T) => immutable(T) + // foo(U:U) shared(T) => shared(T) + // foo(U:U) const(shared(T)) => const(shared(T)) + // foo(U:U) wild(T) => wild(T) + // foo(U:U) wild(shared(T)) => wild(shared(T)) + + tt = farg->type; + m = MATCHexact; + break; + + case X(MODconst, MODconst): + case X(MODimmutable, MODimmutable): + case X(MODshared, MODshared): + case X(MODconst | MODshared, MODconst | MODshared): + case X(MODwild, MODwild): + case X(MODwild | MODshared, MODwild | MODshared): + // foo(U:const(U)) const(T) => T + // foo(U:immutable(U)) immutable(T) => T + // foo(U:shared(U)) shared(T) => T + // foo(U:const(shared(U)) const(shared(T)) => T + // foo(U:wild(U)) wild(T) => T + // foo(U:wild(shared(U)) wild(shared(T)) => T + + tt = farg->type->mutableOf()->unSharedOf(); + m = MATCHexact; + break; + + case X(MODconst, 0): + case X(MODconst, MODimmutable): + case X(MODconst, MODconst | MODshared): + case X(MODconst | MODshared, MODimmutable): + case X(MODconst, MODwild): + case X(MODconst, MODwild | MODshared): + // foo(U:const(U)) T => T + // foo(U:const(U)) immutable(T) => T + // foo(U:const(U)) const(shared(T)) => shared(T) + // foo(U:const(shared(U)) immutable(T) => T + // foo(U:const(U)) wild(shared(T)) => shared(T) + + tt = farg->type->mutableOf(); + m = MATCHconst; + break; + + case X(MODshared, MODconst | MODshared): + case X(MODconst | MODshared, MODshared): + case X(MODshared, MODwild | MODshared): + // foo(U:shared(U)) const(shared(T)) => const(T) + // foo(U:const(shared(U)) shared(T) => T + // foo(U:shared(U)) wild(shared(T)) => wild(T) + tt = farg->type->unSharedOf(); + m = MATCHconst; + break; + + case X(MODimmutable, 0): + case X(MODimmutable, MODconst): + case X(MODimmutable, MODshared): + case X(MODimmutable, MODconst | MODshared): + case X(MODconst, MODshared): + case X(MODshared, 0): + case X(MODshared, MODconst): + case X(MODshared, MODimmutable): + case X(MODconst | MODshared, 0): + case X(MODconst | MODshared, MODconst): + case X(MODimmutable, MODwild): + case X(MODshared, MODwild): + case X(MODconst | MODshared, MODwild): + case X(MODwild, 0): + case X(MODwild, MODconst): + case X(MODwild, MODimmutable): + case X(MODwild, MODshared): + case X(MODwild, MODconst | MODshared): + case X(MODwild | MODshared, 0): + case X(MODwild | MODshared, MODconst): + case X(MODwild | MODshared, MODimmutable): + case X(MODwild | MODshared, MODshared): + case X(MODwild | MODshared, MODconst | MODshared): + case X(MODwild | MODshared, MODwild): + case X(MODimmutable, MODwild | MODshared): + case X(MODconst | MODshared, MODwild | MODshared): + case X(MODwild, MODwild | MODshared): + + // foo(U:immutable(U)) T => nomatch + // foo(U:immutable(U)) const(T) => nomatch + // foo(U:immutable(U)) shared(T) => nomatch + // foo(U:immutable(U)) const(shared(T)) => nomatch + // foo(U:const(U)) shared(T) => nomatch + // foo(U:shared(U)) T => nomatch + // foo(U:shared(U)) const(T) => nomatch + // foo(U:shared(U)) immutable(T) => nomatch + // foo(U:const(shared(U)) T => nomatch + // foo(U:const(shared(U)) const(T) => nomatch + // foo(U:immutable(U)) wild(T) => nomatch + // foo(U:shared(U)) wild(T) => nomatch + // foo(U:const(shared(U)) wild(T) => nomatch + // foo(U:wild(U)) T => nomatch + // foo(U:wild(U)) const(T) => nomatch + // foo(U:wild(U)) immutable(T) => nomatch + // foo(U:wild(U)) shared(T) => nomatch + // foo(U:wild(U)) const(shared(T)) => nomatch + // foo(U:wild(shared(U)) T => nomatch + // foo(U:wild(shared(U)) const(T) => nomatch + // foo(U:wild(shared(U)) immutable(T) => nomatch + // foo(U:wild(shared(U)) shared(T) => nomatch + // foo(U:wild(shared(U)) const(shared(T)) => nomatch + // foo(U:wild(shared(U)) wild(T) => nomatch + // foo(U:immutable(U)) wild(shared(T)) => nomatch + // foo(U:const(shared(U))) wild(shared(T)) => nomatch + // foo(U:wild(U)) wild(shared(T)) => nomatch + m = MATCHnomatch; + break; + + default: + assert(0); + } + #undef X + + Lx: + if (m == MATCHnomatch) + goto Lnomatch; + if (m < match) + match = m; + + t->objects.tdata()[i] = tt; } declareParameter(paramscope, tp, t); goto L2; diff --git a/runtime/CMakeLists.txt b/runtime/CMakeLists.txt index 94bae5d5..27fdfc8f 100644 --- a/runtime/CMakeLists.txt +++ b/runtime/CMakeLists.txt @@ -85,6 +85,7 @@ if(PHOBOS2_DIR) file(GLOB PHOBOS2_D ${PHOBOS2_DIR}/std/*.d) file(GLOB_RECURSE PHOBOS2_D_INTERNAL ${PHOBOS2_DIR}/std/internal/*.d) file(GLOB PHOBOS2_D_C ${PHOBOS2_DIR}/std/c/*.d) + file(GLOB PHOBOS2_ETC ${PHOBOS2_DIR}/etc/c/*.d) if(UNIX) file(GLOB PHOBOS2_D_C_SYS ${PHOBOS2_DIR}/std/c/linux/*.d) elseif(WIN32) @@ -106,7 +107,7 @@ if(PHOBOS2_DIR) ${PHOBOS2_D_WIN} ${PHOBOS2_D_C} ${PHOBOS2_D_C_SYS} - ${PHOBOS2_DIR}/etc/c/zlib.d + ${PHOBOS2_ETC} ${PHOBOS2_DIR}/crc32.d ) list(REMOVE_ITEM PHOBOS2_D diff --git a/runtime/druntime b/runtime/druntime index f2ce5491..3645d7e4 160000 --- a/runtime/druntime +++ b/runtime/druntime @@ -1 +1 @@ -Subproject commit f2ce54913beaa90f59721bb3c5eb68f9b3938404 +Subproject commit 3645d7e4d137848b5826100820cf1f9e9e064291