Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Merge 2.058beta

  • Loading branch information...
commit e74e55df89d4314b4f587acfb1e73dbd7230b200 1 parent f2ed2e9
@AlexeyProkhin AlexeyProkhin authored
Showing with 5,248 additions and 2,961 deletions.
  1. +15 −22 dmd2/access.c
  2. +4 −1 dmd2/aggregate.h
  3. +165 −0 dmd2/apply.c
  4. +5 −0 dmd2/argtypes.c
  5. +1 −1  dmd2/arrayop.c
  6. +11 −7 dmd2/attrib.c
  7. +4 −4 dmd2/attrib.h
  8. +190 −0 dmd2/canthrow.c
  9. +119 −24 dmd2/cast.c
  10. +56 −9 dmd2/class.c
  11. +89 −51 dmd2/constfold.c
  12. +8 −0 dmd2/cppmangle.c
  13. +72 −21 dmd2/declaration.c
  14. +19 −9 dmd2/declaration.h
  15. +71 −149 dmd2/delegatize.c
  16. +2 −2 dmd2/doc.c
  17. +40 −35 dmd2/dsymbol.c
  18. +5 −5 dmd2/dsymbol.h
  19. +3 −3 dmd2/enum.c
  20. +1 −1  dmd2/enum.h
  21. +837 −694 dmd2/expression.c
  22. +69 −76 dmd2/expression.h
  23. +151 −19 dmd2/func.c
  24. +66 −14 dmd2/html.c
  25. +16 −8 dmd2/html.h
  26. +9 −12 dmd2/idgen.c
  27. +74 −98 dmd2/import.c
  28. +3 −6 dmd2/import.h
  29. +8 −0 dmd2/init.c
  30. +347 −142 dmd2/inline.c
  31. +621 −391 dmd2/interpret.c
  32. +23 −12 dmd2/lexer.c
  33. +3 −1 dmd2/lexer.h
  34. +70 −23 dmd2/mars.c
  35. +2 −0  dmd2/mars.h
  36. +0 −273 dmd2/mem.c
  37. +0 −51 dmd2/mem.h
  38. +13 −7 dmd2/module.c
  39. +483 −121 dmd2/mtype.c
  40. +33 −0 dmd2/mtype.h
  41. +0 −61 dmd2/objfile.h
  42. +226 −98 dmd2/opover.c
  43. +24 −14 dmd2/optimize.c
  44. +198 −99 dmd2/parse.c
  45. +4 −2 dmd2/parse.h
  46. +2 −9 dmd2/root/port.c
  47. +155 −0 dmd2/root/rmem.c
  48. +250 −0 dmd2/sideeffect.c
  49. +209 −207 dmd2/statement.c
  50. +22 −3 dmd2/statement.h
  51. +8 −3 dmd2/staticassert.c
  52. +1 −1  dmd2/staticassert.h
  53. +46 −37 dmd2/struct.c
  54. +333 −103 dmd2/template.c
  55. +11 −8 dmd2/template.h
  56. +31 −12 dmd2/traits.c
  57. +0 −1  gen/asmstmt.cpp
  58. +0 −1  gen/dvalue.h
  59. +1 −1  gen/tocall.cpp
  60. +5 −4 gen/toir.cpp
  61. +9 −3 gen/typinf.cpp
  62. +3 −0  runtime/CMakeLists.txt
  63. +1 −1  runtime/druntime
  64. +1 −1  runtime/phobos
View
37 dmd2/access.c
@@ -1,5 +1,5 @@
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -91,7 +91,7 @@ enum PROT ClassDeclaration::getAccess(Dsymbol *smember)
break;
case PROTprivate:
- access = PROTnone; // private members of base class not accessible
+ access_ret = PROTnone; // private members of base class not accessible
break;
case PROTpackage:
@@ -265,7 +265,7 @@ int AggregateDeclaration::isFriendOf(AggregateDeclaration *cd)
// Friends if both are in the same module
//if (toParent() == cd->toParent())
- if (cd && getModule() == cd->getModule())
+ if (cd && getAccessModule() == cd->getAccessModule())
{
#if LOG
printf("\tin same module\n");
@@ -354,7 +354,7 @@ int AggregateDeclaration::hasPrivateAccess(Dsymbol *smember)
#endif
return 1;
}
- if (!cd && getModule() == smember->getModule())
+ if (!cd && getAccessModule() == smember->getAccessModule())
{
#if LOG
printf("\tyes 3\n");
@@ -381,39 +381,32 @@ void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d)
}
else
{
- //printf("accessCheck(%s)\n", d->toChars());
+ printf("accessCheck(%s)\n", d->toPrettyChars());
}
#endif
if (!e)
{
- if (d->getModule() != sc->module)
- if (d->prot() == PROTprivate ||
- d->prot() == PROTpackage && !hasPackageAccess(sc, d))
-
- error(loc, "%s %s.%s is not accessible from %s",
- d->kind(), d->getModule()->toChars(), d->toChars(), sc->module->toChars());
+ if (d->prot() == PROTprivate && d->getAccessModule() != sc->module ||
+ d->prot() == PROTpackage && !hasPackageAccess(sc, d))
+ {
+ error(loc, "%s %s is not accessible from module %s",
+ d->kind(), d->toPrettyChars(), sc->module->toChars());
+ }
}
else if (e->type->ty == Tclass)
{ // Do access check
- ClassDeclaration *cd;
-
- cd = (ClassDeclaration *)(((TypeClass *)e->type)->sym);
-#if 1
+ ClassDeclaration *cd = (ClassDeclaration *)(((TypeClass *)e->type)->sym);
if (e->op == TOKsuper)
- { ClassDeclaration *cd2;
-
- cd2 = sc->func->toParent()->isClassDeclaration();
+ {
+ ClassDeclaration *cd2 = sc->func->toParent()->isClassDeclaration();
if (cd2)
cd = cd2;
}
-#endif
cd->accessCheck(loc, sc, d);
}
else if (e->type->ty == Tstruct)
{ // Do access check
- StructDeclaration *cd;
-
- cd = (StructDeclaration *)(((TypeStruct *)e->type)->sym);
+ StructDeclaration *cd = (StructDeclaration *)(((TypeStruct *)e->type)->sym);
cd->accessCheck(loc, sc, d);
}
}
View
5 dmd2/aggregate.h
@@ -68,7 +68,7 @@ struct AggregateDeclaration : ScopeDsymbol
// 1: size is correct
// 2: cannot determine size; fwd referenced
Dsymbol *deferred; // any deferred semantic2() or semantic3() symbol
- int isdeprecated; // !=0 if deprecated
+ bool isdeprecated; // !=0 if deprecated
#if DMDV2
int isnested; // !=0 if is nested
@@ -107,6 +107,7 @@ struct AggregateDeclaration : ScopeDsymbol
int isDeprecated(); // is aggregate deprecated?
FuncDeclaration *buildDtor(Scope *sc);
int isNested();
+ int isExport();
void emitComment(Scope *sc);
void toJsonBuffer(OutBuffer *buf);
@@ -166,6 +167,7 @@ struct StructDeclaration : AggregateDeclaration
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *mangle();
const char *kind();
+ void finalizeSize();
#if DMDV1
Expression *cloneMembers();
#endif
@@ -284,6 +286,7 @@ struct ClassDeclaration : AggregateDeclaration
virtual int isBaseInfoComplete();
Dsymbol *search(Loc, Identifier *ident, int flags);
+ Dsymbol *searchBase(Loc, Identifier *ident);
#if DMDV2
int isFuncHidden(FuncDeclaration *fd);
#endif
View
165 dmd2/apply.c
@@ -0,0 +1,165 @@
+
+// Compiler implementation of the D programming language
+// Copyright (c) 1999-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 <stdio.h>
+#include <assert.h>
+
+#include "mars.h"
+#include "expression.h"
+
+
+/**************************************
+ * An Expression tree walker that will visit each Expression e in the tree,
+ * in depth-first evaluation order, and call fp(e,param) on it.
+ * fp() signals whether the walking continues with its return value:
+ * Returns:
+ * 0 continue
+ * 1 done
+ * It's a bit slower than using virtual functions, but more encapsulated and less brittle.
+ * Creating an iterator for this would be much more complex.
+ */
+
+typedef int (*fp_t)(Expression *, void *);
+
+int Expression::apply(fp_t fp, void *param)
+{
+ return (*fp)(this, param);
+}
+
+/******************************
+ * Perform apply() on an array of Expressions.
+ */
+
+int arrayExpressionApply(Expressions *a, fp_t fp, void *param)
+{
+ //printf("arrayExpressionApply(%p)\n", a);
+ if (a)
+ {
+ for (size_t i = 0; i < a->dim; i++)
+ { Expression *e = (*a)[i];
+
+ if (e)
+ {
+ if (e->apply(fp, param))
+ return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+int NewExp::apply(int (*fp)(Expression *, void *), void *param)
+{
+ //printf("NewExp::apply(): %s\n", toChars());
+
+ return ((thisexp ? thisexp->apply(fp, param) : 0) ||
+ arrayExpressionApply(newargs, fp, param) ||
+ arrayExpressionApply(arguments, fp, param) ||
+ (*fp)(this, param));
+}
+
+int NewAnonClassExp::apply(int (*fp)(Expression *, void *), void *param)
+{
+ //printf("NewAnonClassExp::apply(): %s\n", toChars());
+
+ return ((thisexp ? thisexp->apply(fp, param) : 0) ||
+ arrayExpressionApply(newargs, fp, param) ||
+ arrayExpressionApply(arguments, fp, param) ||
+ (*fp)(this, param));
+}
+
+int UnaExp::apply(fp_t fp, void *param)
+{
+ return e1->apply(fp, param) ||
+ (*fp)(this, param);
+}
+
+int BinExp::apply(fp_t fp, void *param)
+{
+ return e1->apply(fp, param) ||
+ e2->apply(fp, param) ||
+ (*fp)(this, param);
+}
+
+int AssertExp::apply(fp_t fp, void *param)
+{
+ //printf("CallExp::apply(fp_t fp, void *param): %s\n", toChars());
+ return e1->apply(fp, param) ||
+ (msg ? msg->apply(fp, param) : 0) ||
+ (*fp)(this, param);
+}
+
+
+int CallExp::apply(fp_t fp, void *param)
+{
+ //printf("CallExp::apply(fp_t fp, void *param): %s\n", toChars());
+ return e1->apply(fp, param) ||
+ arrayExpressionApply(arguments, fp, param) ||
+ (*fp)(this, param);
+}
+
+
+int ArrayExp::apply(fp_t fp, void *param)
+{
+ //printf("ArrayExp::apply(fp_t fp, void *param): %s\n", toChars());
+ return e1->apply(fp, param) ||
+ arrayExpressionApply(arguments, fp, param) ||
+ (*fp)(this, param);
+}
+
+
+int SliceExp::apply(fp_t fp, void *param)
+{
+ return e1->apply(fp, param) ||
+ (lwr ? lwr->apply(fp, param) : 0) ||
+ (upr ? upr->apply(fp, param) : 0) ||
+ (*fp)(this, param);
+}
+
+
+int ArrayLiteralExp::apply(fp_t fp, void *param)
+{
+ return arrayExpressionApply(elements, fp, param) ||
+ (*fp)(this, param);
+}
+
+
+int AssocArrayLiteralExp::apply(fp_t fp, void *param)
+{
+ return arrayExpressionApply(keys, fp, param) ||
+ arrayExpressionApply(values, fp, param) ||
+ (*fp)(this, param);
+}
+
+
+int StructLiteralExp::apply(fp_t fp, void *param)
+{
+ return arrayExpressionApply(elements, fp, param) ||
+ (*fp)(this, param);
+}
+
+
+int TupleExp::apply(fp_t fp, void *param)
+{
+ return arrayExpressionApply(exps, fp, param) ||
+ (*fp)(this, param);
+}
+
+
+int CondExp::apply(fp_t fp, void *param)
+{
+ return econd->apply(fp, param) ||
+ e1->apply(fp, param) ||
+ e2->apply(fp, param) ||
+ (*fp)(this, param);
+}
+
+
+
View
5 dmd2/argtypes.c
@@ -124,6 +124,11 @@ TypeTuple *TypeBasic::toArgTypes()
return t;
}
+TypeTuple *TypeVector::toArgTypes()
+{
+ return new TypeTuple(Type::tfloat64);
+}
+
TypeTuple *TypeSArray::toArgTypes()
{
#if DMDV2
View
2  dmd2/arrayop.c
@@ -578,7 +578,7 @@ Expression *Str##AssignExp::buildArrayLoop(Parameters *fparams) \
Expression *ex1 = e1->buildArrayLoop(fparams); \
Parameter *param = (*fparams)[0]; \
param->storageClass = 0; \
- Expression *e = new Str##AssignExp(0, ex1, ex2); \
+ Expression *e = new Str##AssignExp(loc, ex1, ex2); \
return e; \
}
View
18 dmd2/attrib.c
@@ -310,11 +310,11 @@ const char *AttribDeclaration::kind()
return "attribute";
}
-int AttribDeclaration::oneMember(Dsymbol **ps)
+int AttribDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
{
Dsymbols *d = include(NULL, NULL);
- return Dsymbol::oneMembers(d, ps);
+ return Dsymbol::oneMembers(d, ps, ident);
}
void AttribDeclaration::checkCtorConstInit()
@@ -392,10 +392,10 @@ Dsymbol *StorageClassDeclaration::syntaxCopy(Dsymbol *s)
return scd;
}
-int StorageClassDeclaration::oneMember(Dsymbol **ps)
+int StorageClassDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
{
- int t = Dsymbol::oneMembers(decl, ps);
+ int t = Dsymbol::oneMembers(decl, ps, ident);
if (t && *ps)
{
/* This is to deal with the following case:
@@ -1150,6 +1150,7 @@ void PragmaDeclaration::semantic(Scope *sc)
else
error("unrecognized pragma(%s)", ident->toChars());
+Ldecl:
if (decl)
{
for (unsigned i = 0; i < decl->dim; i++)
@@ -1167,10 +1168,13 @@ void PragmaDeclaration::semantic(Scope *sc)
Lnodecl:
if (decl)
+ {
error("pragma is missing closing ';'");
+ goto Ldecl; // do them anyway, to avoid segfaults.
+ }
}
-int PragmaDeclaration::oneMember(Dsymbol **ps)
+int PragmaDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
{
*ps = NULL;
return TRUE;
@@ -1263,13 +1267,13 @@ Dsymbol *ConditionalDeclaration::syntaxCopy(Dsymbol *s)
}
-int ConditionalDeclaration::oneMember(Dsymbol **ps)
+int ConditionalDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
{
//printf("ConditionalDeclaration::oneMember(), inc = %d\n", condition->inc);
if (condition->inc)
{
Dsymbols *d = condition->include(NULL, NULL) ? decl : elsedecl;
- return Dsymbol::oneMembers(d, ps);
+ return Dsymbol::oneMembers(d, ps, ident);
}
*ps = NULL;
return TRUE;
View
8 dmd2/attrib.h
@@ -47,7 +47,7 @@ struct AttribDeclaration : Dsymbol
void addComment(unsigned char *comment);
void emitComment(Scope *sc);
const char *kind();
- int oneMember(Dsymbol **ps);
+ int oneMember(Dsymbol **ps, Identifier *ident);
int hasPointers();
bool hasStaticCtorOrDtor();
void checkCtorConstInit();
@@ -74,7 +74,7 @@ struct StorageClassDeclaration: AttribDeclaration
Dsymbol *syntaxCopy(Dsymbol *s);
void setScope(Scope *sc);
void semantic(Scope *sc);
- int oneMember(Dsymbol **ps);
+ int oneMember(Dsymbol **ps, Identifier *ident);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
static void stcToCBuffer(OutBuffer *buf, StorageClass stc);
@@ -138,7 +138,7 @@ struct PragmaDeclaration : AttribDeclaration
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void setScope(Scope *sc);
- int oneMember(Dsymbol **ps);
+ int oneMember(Dsymbol **ps, Identifier *ident);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
@@ -158,7 +158,7 @@ struct ConditionalDeclaration : AttribDeclaration
ConditionalDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
Dsymbol *syntaxCopy(Dsymbol *s);
- int oneMember(Dsymbol **ps);
+ int oneMember(Dsymbol **ps, Identifier *ident);
void emitComment(Scope *sc);
Dsymbols *include(Scope *sc, ScopeDsymbol *s);
void addComment(unsigned char *comment);
View
190 dmd2/canthrow.c
@@ -0,0 +1,190 @@
+
+// Compiler implementation of the D programming language
+// Copyright (c) 1999-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 <stdio.h>
+#include <assert.h>
+
+#include "mars.h"
+#include "init.h"
+#include "expression.h"
+#include "template.h"
+#include "statement.h"
+#include "mtype.h"
+#include "utf.h"
+#include "declaration.h"
+#include "aggregate.h"
+#include "scope.h"
+#include "attrib.h"
+
+int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow);
+int lambdaCanThrow(Expression *e, void *param);
+
+/********************************************
+ * Convert from expression to delegate that returns the expression,
+ * i.e. convert:
+ * expr
+ * to:
+ * t delegate() { return expr; }
+ */
+
+struct CanThrow
+{
+ bool can;
+ bool mustnot;
+};
+
+int Expression::canThrow(bool mustNotThrow)
+{
+ //printf("Expression::canThrow(%d) %s\n", mustNotThrow, toChars());
+ CanThrow ct;
+ ct.can = FALSE;
+ ct.mustnot = mustNotThrow;
+ apply(&lambdaCanThrow, &ct);
+ return ct.can;
+}
+
+int lambdaCanThrow(Expression *e, void *param)
+{
+ CanThrow *pct = (CanThrow *)param;
+ switch (e->op)
+ {
+ case TOKdeclaration:
+ { DeclarationExp *de = (DeclarationExp *)e;
+ pct->can = Dsymbol_canThrow(de->declaration, pct->mustnot);
+ break;
+ }
+
+ case TOKcall:
+ { CallExp *ce = (CallExp *)e;
+
+ if (global.errors && !ce->e1->type)
+ break; // error recovery
+
+ /* If calling a function or delegate that is typed as nothrow,
+ * then this expression cannot throw.
+ * Note that pure functions can throw.
+ */
+ Type *t = ce->e1->type->toBasetype();
+ if (t->ty == Tfunction && ((TypeFunction *)t)->isnothrow)
+ ;
+ else if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->isnothrow)
+ ;
+ else
+ {
+ if (pct->mustnot)
+ e->error("%s is not nothrow", ce->e1->toChars());
+ pct->can = TRUE;
+ }
+ break;
+ }
+
+ case TOKnew:
+ { NewExp *ne = (NewExp *)e;
+ if (ne->member)
+ {
+ // See if constructor call can throw
+ Type *t = ne->member->type->toBasetype();
+ if (t->ty == Tfunction && !((TypeFunction *)t)->isnothrow)
+ {
+ if (pct->mustnot)
+ e->error("constructor %s is not nothrow", ne->member->toChars());
+ pct->can = TRUE;
+ }
+ }
+ // regard storage allocation failures as not recoverable
+ break;
+ }
+
+ case TOKnewanonclass:
+ assert(0); // should have been lowered by semantic()
+ break;
+
+ default:
+ break;
+ }
+ return pct->can; // stop walking if we determine this expression can throw
+}
+
+/**************************************
+ * Does symbol, when initialized, throw?
+ * Mirrors logic in Dsymbol_toElem().
+ */
+
+int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
+{
+ AttribDeclaration *ad;
+ VarDeclaration *vd;
+ TemplateMixin *tm;
+ TupleDeclaration *td;
+
+ //printf("Dsymbol_toElem() %s\n", s->toChars());
+ ad = s->isAttribDeclaration();
+ if (ad)
+ {
+ Dsymbols *decl = ad->include(NULL, NULL);
+ if (decl && decl->dim)
+ {
+ for (size_t i = 0; i < decl->dim; i++)
+ {
+ s = decl->tdata()[i];
+ if (Dsymbol_canThrow(s, mustNotThrow))
+ return 1;
+ }
+ }
+ }
+ else if ((vd = s->isVarDeclaration()) != NULL)
+ {
+ s = s->toAlias();
+ if (s != vd)
+ return Dsymbol_canThrow(s, mustNotThrow);
+ if (vd->storage_class & STCmanifest)
+ ;
+ else if (vd->isStatic() || vd->storage_class & (STCextern | STCtls | STCgshared))
+ ;
+ else
+ {
+ if (vd->init)
+ { ExpInitializer *ie = vd->init->isExpInitializer();
+ if (ie && ie->exp->canThrow(mustNotThrow))
+ return 1;
+ }
+ if (vd->edtor && !vd->noscope)
+ return vd->edtor->canThrow(mustNotThrow);
+ }
+ }
+ else if ((tm = s->isTemplateMixin()) != NULL)
+ {
+ //printf("%s\n", tm->toChars());
+ if (tm->members)
+ {
+ for (size_t i = 0; i < tm->members->dim; i++)
+ {
+ Dsymbol *sm = tm->members->tdata()[i];
+ if (Dsymbol_canThrow(sm, mustNotThrow))
+ return 1;
+ }
+ }
+ }
+ else if ((td = s->isTupleDeclaration()) != NULL)
+ {
+ for (size_t i = 0; i < td->objects->dim; i++)
+ { Object *o = td->objects->tdata()[i];
+ if (o->dyncast() == DYNCAST_EXPRESSION)
+ { Expression *eo = (Expression *)o;
+ if (eo->op == TOKdsymbol)
+ { DsymbolExp *se = (DsymbolExp *)eo;
+ if (Dsymbol_canThrow(se->s, mustNotThrow))
+ return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
View
143 dmd2/cast.c
@@ -209,6 +209,12 @@ MATCH IntegerExp::implicitConvTo(Type *t)
if (m == MATCHnomatch && t->ty == Tenum)
goto Lno;
+ if (t->ty == Tvector)
+ { TypeVector *tv = (TypeVector *)t;
+ TypeBasic *tb = tv->elementType();
+ toty = tb->ty;
+ }
+
switch (ty)
{
case Tbool:
@@ -713,6 +719,18 @@ MATCH DelegateExp::implicitConvTo(Type *t)
return result;
}
+MATCH FuncExp::implicitConvTo(Type *t)
+{
+ //printf("FuncExp::implicitCastTo type = %p %s, t = %s\n", type, type ? type->toChars() : NULL, t->toChars());
+ if (type && type != Type::tvoid && tok == TOKreserved && type->ty == Tpointer
+ && (t->ty == Tpointer || t->ty == Tdelegate))
+ { // Allow implicit function to delegate conversion
+ if (type->nextOf()->covariant(t->nextOf()) == 1)
+ return t->ty == Tpointer ? MATCHconst : MATCHconvert;
+ }
+ return Expression::implicitConvTo(t);
+}
+
MATCH OrExp::implicitConvTo(Type *t)
{
MATCH result = Expression::implicitConvTo(t);
@@ -860,6 +878,12 @@ Expression *Expression::castTo(Scope *sc, Type *t)
}
L1: ;
}
+ else if (tb->ty == Tvector && typeb->ty != Tvector)
+ {
+ e = new VectorExp(loc, e, tb);
+ e = e->semantic(sc);
+ return e;
+ }
e = new CastExp(loc, e, tb);
}
}
@@ -1522,6 +1546,22 @@ Expression *DelegateExp::castTo(Scope *sc, Type *t)
return e;
}
+Expression *FuncExp::castTo(Scope *sc, Type *t)
+{
+ //printf("FuncExp::castTo type = %s, t = %s\n", type->toChars(), t->toChars());
+ if (tok == TOKreserved)
+ { assert(type && type != Type::tvoid);
+ if (type->ty == Tpointer && t->ty == Tdelegate)
+ {
+ Expression *e = copy();
+ e->type = new TypeDelegate(fd->type);
+ e->type = e->type->semantic(loc, sc);
+ return e;
+ }
+ }
+ return Expression::castTo(sc, t);
+}
+
Expression *CondExp::castTo(Scope *sc, Type *t)
{
Expression *e = this;
@@ -1738,13 +1778,16 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
t = t2;
else if (t2n->ty == Tvoid)
;
+ else if (t1->implicitConvTo(t2))
+ {
+ goto Lt2;
+ }
+ else if (t2->implicitConvTo(t1))
+ {
+ goto Lt1;
+ }
else if (t1n->ty == Tfunction && t2n->ty == Tfunction)
{
- if (t1->implicitConvTo(t2))
- goto Lt2;
- if (t2->implicitConvTo(t1))
- goto Lt1;
-
TypeFunction *tf1 = (TypeFunction *)t1n;
TypeFunction *tf2 = (TypeFunction *)t2n;
TypeFunction *d = (TypeFunction *)tf1->syntaxCopy();
@@ -1782,8 +1825,11 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
}
else if (t1n->mod != t2n->mod)
{
- t1 = t1n->mutableOf()->constOf()->pointerTo();
- t2 = t2n->mutableOf()->constOf()->pointerTo();
+ if (!t1n->isImmutable() && !t2n->isImmutable() && t1n->isShared() != t2n->isShared())
+ goto Lincompatible;
+ unsigned char mod = MODmerge(t1n->mod, t2n->mod);
+ t1 = t1n->castMod(mod)->pointerTo();
+ t2 = t2n->castMod(mod)->pointerTo();
t = t1;
goto Lagain;
}
@@ -1807,7 +1853,19 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
goto Lincompatible;
}
else
+ {
+ t1 = t1n->constOf()->pointerTo();
+ t2 = t2n->constOf()->pointerTo();
+ if (t1->implicitConvTo(t2))
+ {
+ goto Lt2;
+ }
+ else if (t2->implicitConvTo(t1))
+ {
+ goto Lt1;
+ }
goto Lincompatible;
+ }
}
else if ((t1->ty == Tsarray || t1->ty == Tarray) &&
(e2->op == TOKnull && t2->ty == Tpointer && t2->nextOf()->ty == Tvoid ||
@@ -1840,10 +1898,14 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
}
else if ((t1->ty == Tsarray || t1->ty == Tarray) && t1->implicitConvTo(t2))
{
+ if (t1->ty == Tsarray && e2->op == TOKarrayliteral)
+ goto Lt1;
goto Lt2;
}
else if ((t2->ty == Tsarray || t2->ty == Tarray) && t2->implicitConvTo(t1))
{
+ if (t2->ty == Tsarray && e1->op == TOKarrayliteral)
+ goto Lt2;
goto Lt1;
}
/* If one is mutable and the other invariant, then retry
@@ -1853,30 +1915,54 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
(t2->ty == Tsarray || t2->ty == Tarray || t2->ty == Tpointer) &&
t1->nextOf()->mod != t2->nextOf()->mod
)
- { unsigned char mod = MODmerge(t1->nextOf()->mod, t2->nextOf()->mod);
+ {
+ Type *t1n = t1->nextOf();
+ Type *t2n = t2->nextOf();
+ unsigned char mod;
+ if (e1->op == TOKnull && e2->op != TOKnull)
+ mod = t2n->mod;
+ else if (e1->op != TOKnull && e2->op == TOKnull)
+ mod = t1n->mod;
+ else if (!t1n->isImmutable() && !t2n->isImmutable() && t1n->isShared() != t2n->isShared())
+ goto Lincompatible;
+ else
+ mod = MODmerge(t1n->mod, t2n->mod);
if (t1->ty == Tpointer)
- t1 = t1->nextOf()->castMod(mod)->pointerTo();
+ t1 = t1n->castMod(mod)->pointerTo();
else
- t1 = t1->nextOf()->castMod(mod)->arrayOf();
+ t1 = t1n->castMod(mod)->arrayOf();
if (t2->ty == Tpointer)
- t2 = t2->nextOf()->castMod(mod)->pointerTo();
+ t2 = t2n->castMod(mod)->pointerTo();
else
- t2 = t2->nextOf()->castMod(mod)->arrayOf();
+ t2 = t2n->castMod(mod)->arrayOf();
t = t1;
goto Lagain;
}
- else if (t1->ty == Tclass || t2->ty == Tclass)
+ else if (t1->ty == Tclass && t2->ty == Tclass)
{
if (t1->mod != t2->mod)
- { unsigned char mod = MODmerge(t1->mod, t2->mod);
+ {
+ unsigned char mod;
+ if (e1->op == TOKnull && e2->op != TOKnull)
+ mod = t2->mod;
+ else if (e1->op != TOKnull && e2->op == TOKnull)
+ mod = t1->mod;
+ else if (!t1->isImmutable() && !t2->isImmutable() && t1->isShared() != t2->isShared())
+ goto Lincompatible;
+ else
+ mod = MODmerge(t1->mod, t2->mod);
t1 = t1->castMod(mod);
t2 = t2->castMod(mod);
t = t1;
goto Lagain;
}
-
+ goto Lcc;
+ }
+ else if (t1->ty == Tclass || t2->ty == Tclass)
+ {
+Lcc:
while (1)
{
int i1 = e2->implicitConvTo(t1);
@@ -1943,6 +2029,8 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
{
if (t1->mod != t2->mod)
{
+ if (!t1->isImmutable() && !t2->isImmutable() && t1->isShared() != t2->isShared())
+ goto Lincompatible;
unsigned char mod = MODmerge(t1->mod, t2->mod);
t1 = t1->castMod(mod);
t2 = t2->castMod(mod);
@@ -1998,15 +2086,6 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
}
else if (t1->ty == Tstruct || t2->ty == Tstruct)
{
- if (t1->mod != t2->mod)
- {
- unsigned char mod = MODmerge(t1->mod, t2->mod);
- t1 = t1->castMod(mod);
- t2 = t2->castMod(mod);
- t = t1;
- goto Lagain;
- }
-
if (t1->ty == Tstruct && ((TypeStruct *)t1)->sym->aliasthis)
{
e1 = new DotIdExp(e1->loc, e1, ((TypeStruct *)t1)->sym->aliasthis->ident);
@@ -2051,9 +2130,25 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
e1 = e1->castTo(sc, t);
e2 = e2->castTo(sc, t);
}
+ else if (t1->ty == Tvector && t2->ty != Tvector &&
+ e2->implicitConvTo(t1))
+ {
+ e2 = e2->castTo(sc, t1);
+ t2 = t1;
+ goto Lagain;
+ }
+ else if (t2->ty == Tvector && t1->ty != Tvector &&
+ e1->implicitConvTo(t2))
+ {
+ e1 = e1->castTo(sc, t2);
+ t1 = t2;
+ goto Lagain;
+ }
else if (t1->isintegral() && t2->isintegral())
{
assert(t1->ty == t2->ty);
+ if (!t1->isImmutable() && !t2->isImmutable() && t1->isShared() != t2->isShared())
+ goto Lincompatible;
unsigned char mod = MODmerge(t1->mod, t2->mod);
t1 = t1->castMod(mod);
View
65 dmd2/class.c
@@ -296,9 +296,11 @@ void ClassDeclaration::semantic(Scope *sc)
methods.setDim(0);
#endif
+ int errors = global.gaggedErrors;
+
if (sc->stc & STCdeprecated)
{
- isdeprecated = 1;
+ isdeprecated = true;
}
if (sc->linkage == LINKcpp)
@@ -307,9 +309,7 @@ void ClassDeclaration::semantic(Scope *sc)
// Expand any tuples in baseclasses[]
for (size_t i = 0; i < baseclasses->dim; )
{ BaseClass *b = baseclasses->tdata()[i];
-//printf("test1 %s %s\n", toChars(), b->type->toChars());
b->type = b->type->semantic(loc, sc);
-//printf("test2\n");
Type *tb = b->type->toBasetype();
if (tb->ty == Ttuple)
@@ -349,7 +349,7 @@ void ClassDeclaration::semantic(Scope *sc)
if (!isDeprecated())
{
// Deriving from deprecated class makes this one deprecated too
- isdeprecated = 1;
+ isdeprecated = true;
tc->checkDeprecated(loc, sc);
}
@@ -422,7 +422,7 @@ void ClassDeclaration::semantic(Scope *sc)
if (!isDeprecated())
{
// Deriving from deprecated class makes this one deprecated too
- isdeprecated = 1;
+ isdeprecated = true;
tc->checkDeprecated(loc, sc);
}
@@ -657,9 +657,15 @@ void ClassDeclaration::semantic(Scope *sc)
s->semantic(sc);
}
- if (sizeok == 2)
- { // semantic() failed because of forward references.
+ if (global.gag && global.gaggedErrors != errors)
+ { // The type is no good, yet the error messages were gagged.
+ type = Type::terror;
+ }
+
+ if (sizeok == 2) // failed due to forward references
+ { // semantic() failed due to forward references
// Unwind what we did, and defer it for later
+
fields.setDim(0);
structsize = 0;
alignsize = 0;
@@ -772,7 +778,7 @@ void ClassDeclaration::semantic(Scope *sc)
#endif
//printf("-ClassDeclaration::semantic(%s), type = %p\n", toChars(), type);
- if (deferred)
+ if (deferred && !global.gag)
{
deferred->semantic2(sc);
deferred->semantic3(sc);
@@ -938,6 +944,23 @@ Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags)
return s;
}
+Dsymbol *ClassDeclaration::searchBase(Loc loc, Identifier *ident)
+{
+ // Search bases classes in depth-first, left to right order
+
+ for (size_t i = 0; i < baseclasses->dim; i++)
+ {
+ BaseClass *b = (*baseclasses)[i];
+ Dsymbol *cdb = b->type->isClassHandle();
+ if (cdb->ident->equals(ident))
+ return cdb;
+ cdb = ((ClassDeclaration *)cdb)->searchBase(loc, ident);
+ if (cdb)
+ return cdb;
+ }
+ return NULL;
+}
+
/**********************************************************
* fd is in the vtbl[] for this class.
* Return 1 if function is hidden (not findable through search).
@@ -1212,9 +1235,11 @@ void InterfaceDeclaration::semantic(Scope *sc)
scope = NULL;
}
+ int errors = global.gaggedErrors;
+
if (sc->stc & STCdeprecated)
{
- isdeprecated = 1;
+ isdeprecated = true;
}
// Expand any tuples in baseclasses[]
@@ -1360,11 +1385,33 @@ void InterfaceDeclaration::semantic(Scope *sc)
structalign = sc->structalign;
sc->offset = PTRSIZE * 2;
inuse++;
+
+ /* Set scope so if there are forward references, we still might be able to
+ * resolve individual members like enums.
+ */
+ for (size_t i = 0; i < members->dim; i++)
+ { Dsymbol *s = (*members)[i];
+ /* There are problems doing this in the general case because
+ * Scope keeps track of things like 'offset'
+ */
+ if (s->isEnumDeclaration() || (s->isAggregateDeclaration() && s->ident))
+ {
+ //printf("setScope %s %s\n", s->kind(), s->toChars());
+ s->setScope(sc);
+ }
+ }
+
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
s->semantic(sc);
}
+
+ if (global.gag && global.gaggedErrors != errors)
+ { // The type is no good, yet the error messages were gagged.
+ type = Type::terror;
+ }
+
inuse--;
//members->print();
sc->pop();
View
140 dmd2/constfold.c
@@ -1376,7 +1376,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
{ ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
e = ale->elements->tdata()[i];
e->type = type;
- if (e->checkSideEffect(2))
+ if (e->hasSideEffect())
e = EXP_CANT_INTERPRET;
}
}
@@ -1394,7 +1394,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
else
{ e = ale->elements->tdata()[i];
e->type = type;
- if (e->checkSideEffect(2))
+ if (e->hasSideEffect())
e = EXP_CANT_INTERPRET;
}
}
@@ -1414,7 +1414,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
if (ex->isBool(TRUE))
{ e = ae->values->tdata()[i];
e->type = type;
- if (e->checkSideEffect(2))
+ if (e->hasSideEffect())
e = EXP_CANT_INTERPRET;
break;
}
@@ -1467,7 +1467,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
}
else if (e1->op == TOKarrayliteral &&
lwr->op == TOKint64 && upr->op == TOKint64 &&
- !e1->checkSideEffect(2))
+ !e1->hasSideEffect())
{ ArrayLiteralExp *es1 = (ArrayLiteralExp *)e1;
uinteger_t ilwr = lwr->toInteger();
uinteger_t iupr = upr->toInteger();
@@ -1491,6 +1491,64 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
return e;
}
+/* Set a slice of char array literal 'existingAE' from a string 'newval'.
+ * existingAE[firstIndex..firstIndex+newval.length] = newval.
+ */
+void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *newval, int firstIndex)
+{
+ size_t newlen = newval->len;
+ size_t sz = newval->sz;
+ unsigned char *s = (unsigned char *)newval->string;
+ Type *elemType = existingAE->type->nextOf();
+ for (size_t j = 0; j < newlen; j++)
+ {
+ dinteger_t val;
+ switch (sz)
+ {
+ case 1: val = s[j]; break;
+ case 2: val = ((unsigned short *)s)[j]; break;
+ case 4: val = ((unsigned *)s)[j]; break;
+ default:
+ assert(0);
+ break;
+ }
+ existingAE->elements->tdata()[j+firstIndex]
+ = new IntegerExp(newval->loc, val, elemType);
+ }
+}
+
+/* Set a slice of string 'existingSE' from a char array literal 'newae'.
+ * existingSE[firstIndex..firstIndex+newae.length] = newae.
+ */
+void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, int firstIndex)
+{
+ unsigned char *s = (unsigned char *)existingSE->string;
+ for (size_t j = 0; j < newae->elements->dim; j++)
+ {
+ unsigned value = (unsigned)(newae->elements->tdata()[j]->toInteger());
+ switch (existingSE->sz)
+ {
+ case 1: s[j+firstIndex] = value; break;
+ case 2: ((unsigned short *)s)[j+firstIndex] = value; break;
+ case 4: ((unsigned *)s)[j+firstIndex] = value; break;
+ default:
+ assert(0);
+ break;
+ }
+ }
+}
+
+/* Set a slice of string 'existingSE' from a string 'newstr'.
+ * existingSE[firstIndex..firstIndex+newstr.length] = newstr.
+ */
+void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, int firstIndex)
+{
+ unsigned char *s = (unsigned char *)existingSE->string;
+ size_t sz = existingSE->sz;
+ assert(sz == newstr->sz);
+ memcpy(s + firstIndex * sz, newstr->string, sz * newstr->len);
+}
+
/* Also return EXP_CANT_INTERPRET if this fails
*/
Expression *Cat(Type *type, Expression *e1, Expression *e2)
@@ -1600,62 +1658,42 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
else if (e2->op == TOKstring && e1->op == TOKarrayliteral &&
t1->nextOf()->isintegral())
{
- // Concatenate the strings
- StringExp *es1 = (StringExp *)e2;
- ArrayLiteralExp *es2 = (ArrayLiteralExp *)e1;
- size_t len = es1->len + es2->elements->dim;
- int sz = es1->sz;
-
- void *s = mem.malloc((len + 1) * sz);
- memcpy((char *)s + sz * es2->elements->dim, es1->string, es1->len * sz);
- for (size_t i = 0; i < es2->elements->dim; i++)
- { Expression *es2e = es2->elements->tdata()[i];
- if (es2e->op != TOKint64)
- return EXP_CANT_INTERPRET;
- dinteger_t v = es2e->toInteger();
- memcpy((unsigned char *)s + i * sz, &v, sz);
+ // [chars] ~ string --> [chars]
+ StringExp *es = (StringExp *)e2;
+ ArrayLiteralExp *ea = (ArrayLiteralExp *)e1;
+ size_t len = es->len + ea->elements->dim;
+ Expressions * elems = new Expressions;
+ elems->setDim(len);
+ for (size_t i= 0; i < ea->elements->dim; ++i)
+ {
+ elems->tdata()[i] = ea->elements->tdata()[i];
}
-
- // Add terminating 0
- memset((unsigned char *)s + len * sz, 0, sz);
-
- StringExp *es = new StringExp(loc, s, len);
- es->sz = sz;
- es->committed = 0;
- es->type = type;
- e = es;
+ ArrayLiteralExp *dest = new ArrayLiteralExp(e1->loc, elems);
+ dest->type = type;
+ sliceAssignArrayLiteralFromString(dest, es, ea->elements->dim);
+ return dest;
}
else if (e1->op == TOKstring && e2->op == TOKarrayliteral &&
t2->nextOf()->isintegral())
{
- // Concatenate the strings
- StringExp *es1 = (StringExp *)e1;
- ArrayLiteralExp *es2 = (ArrayLiteralExp *)e2;
- size_t len = es1->len + es2->elements->dim;
- int sz = es1->sz;
-
- void *s = mem.malloc((len + 1) * sz);
- memcpy(s, es1->string, es1->len * sz);
- for (size_t i = 0; i < es2->elements->dim; i++)
- { Expression *es2e = es2->elements->tdata()[i];
- if (es2e->op != TOKint64)
- return EXP_CANT_INTERPRET;
- dinteger_t v = es2e->toInteger();
- memcpy((unsigned char *)s + (es1->len + i) * sz, &v, sz);
+ // string ~ [chars] --> [chars]
+ StringExp *es = (StringExp *)e1;
+ ArrayLiteralExp *ea = (ArrayLiteralExp *)e2;
+ size_t len = es->len + ea->elements->dim;
+ Expressions * elems = new Expressions;
+ elems->setDim(len);
+ for (size_t i= 0; i < ea->elements->dim; ++i)
+ {
+ elems->tdata()[es->len + i] = ea->elements->tdata()[i];
}
-
- // Add terminating 0
- memset((unsigned char *)s + len * sz, 0, sz);
-
- StringExp *es = new StringExp(loc, s, len);
- es->sz = sz;
- es->committed = 0; //es1->committed;
- es->type = type;
- e = es;
+ ArrayLiteralExp *dest = new ArrayLiteralExp(e1->loc, elems);
+ dest->type = type;
+ sliceAssignArrayLiteralFromString(dest, es, 0);
+ return dest;
}
else if (e1->op == TOKstring && e2->op == TOKint64)
{
- // Concatenate the strings
+ // string ~ char --> string
void *s;
StringExp *es1 = (StringExp *)e1;
StringExp *es;
View
8 dmd2/cppmangle.c
@@ -266,6 +266,14 @@ void TypeBasic::toCppMangle(OutBuffer *buf, CppMangleState *cms)
}
+void TypeVector::toCppMangle(OutBuffer *buf, CppMangleState *cms)
+{
+ if (!cms->substitute(buf, this))
+ { buf->writestring("U8__vector");
+ basetype->toCppMangle(buf, cms);
+ }
+}
+
void TypeSArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
{
if (!cms->substitute(buf, this))
View
93 dmd2/declaration.c
@@ -457,6 +457,7 @@ void AliasDeclaration::semantic(Scope *sc)
#endif
storage_class |= sc->stc & STCdeprecated;
+ protection = sc->protection;
// Given:
// alias foo.bar.abc def;
@@ -1274,14 +1275,25 @@ void VarDeclaration::semantic(Scope *sc)
StructInitializer *si = init->isStructInitializer();
ExpInitializer *ei = init->isExpInitializer();
- // See if initializer is a NewExp that can be allocated on the stack
- if (ei && isScope() && ei->exp->op == TOKnew)
- { NewExp *ne = (NewExp *)ei->exp;
- if (!(ne->newargs && ne->newargs->dim))
- { ne->onstack = 1;
- onstack = 1;
- if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL))
- onstack = 2;
+ if (ei && ei->exp->op == TOKfunction && !inferred)
+ ((FuncExp *)ei->exp)->setType(type);
+
+ if (ei && isScope())
+ {
+ // See if initializer is a NewExp that can be allocated on the stack
+ if (ei->exp->op == TOKnew)
+ { NewExp *ne = (NewExp *)ei->exp;
+ if (!(ne->newargs && ne->newargs->dim))
+ { ne->onstack = 1;
+ onstack = 1;
+ if (type->isBaseOf(ne->newtype->semantic(loc, sc), NULL))
+ onstack = 2;
+ }
+ }
+ // or a delegate that doesn't escape a reference to the function
+ else if (ei->exp->op == TOKfunction)
+ { FuncDeclaration *f = ((FuncExp *)ei->exp)->fd;
+ f->tookAddressOf--;
}
}
@@ -1368,6 +1380,13 @@ void VarDeclaration::semantic(Scope *sc)
* variable with a bit copy of the default
* initializer
*/
+
+ /* Remove ref if this declaration is ref binding.
+ * ref Type __self = (__ctmp = 0, __ctmp).this(...);
+ * -> Type __self = (__self = 0, __self.this(...));
+ */
+ storage_class &= ~(STCref | STCforeach | STCparameter);
+
Expression *e;
if (sd->zeroInit == 1)
{
@@ -1714,25 +1733,45 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
* so it never becomes closure.
*/
+ //printf("\tfdv = %s\n", fdv->toChars());
+ //printf("\tfdthis = %s\n", fdthis->toChars());
+
if (loc.filename)
- fdthis->getLevel(loc, fdv);
+ fdthis->getLevel(loc, sc, fdv);
- for (size_t i = 0; i < nestedrefs.dim; i++)
- { FuncDeclaration *f = nestedrefs.tdata()[i];
- if (f == fdthis)
- goto L1;
+ // Function literals from fdthis to fdv must be delegates
+ for (Dsymbol *s = fdthis; s && s != fdv; s = s->toParent2())
+ {
+ // function literal has reference to enclosing scope is delegate
+ if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
+ {
+ fld->tok = TOKdelegate;
+ }
}
- nestedrefs.push(fdthis);
- L1: ;
+ // Add fdthis to nestedrefs[] if not already there
+ for (size_t i = 0; 1; i++)
+ {
+ if (i == nestedrefs.dim)
+ {
+ nestedrefs.push(fdthis);
+ break;
+ }
+ if (nestedrefs[i] == fdthis)
+ break;
+ }
- for (size_t i = 0; i < fdv->closureVars.dim; i++)
- { Dsymbol *s = fdv->closureVars.tdata()[i];
- if (s == this)
- goto L2;
+ // Add this to fdv->closureVars[] if not already there
+ for (size_t i = 0; 1; i++)
+ {
+ if (i == fdv->closureVars.dim)
+ {
+ fdv->closureVars.push(this);
+ break;
+ }
+ if (fdv->closureVars[i] == this)
+ break;
}
- fdv->closureVars.push(this);
- L2: ;
//printf("fdthis is %s\n", fdthis->toChars());
//printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
@@ -2205,6 +2244,18 @@ TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *t
type = Type::typeinfoassociativearray->type;
}
+/***************************** TypeInfoVectorDeclaration ***********************/
+
+TypeInfoVectorDeclaration::TypeInfoVectorDeclaration(Type *tinfo)
+ : TypeInfoDeclaration(tinfo, 0)
+{
+ if (!Type::typeinfoarray)
+ {
+ ObjectNotFound(Id::TypeInfo_Vector);
+ }
+ type = Type::typeinfovector->type;
+}
+
/***************************** TypeInfoEnumDeclaration ***********************/
TypeInfoEnumDeclaration::TypeInfoEnumDeclaration(Type *tinfo)
View
28 dmd2/declaration.h
@@ -294,10 +294,7 @@ struct VarDeclaration : Declaration
bool hasValue();
void setValueNull();
void setValueWithoutChecking(Expression *newval);
- void createRefValue(Expression *newval);
- void setRefValue(Expression *newval);
- void setStackValue(Expression *newval);
- void createStackValue(Expression *newval);
+ void setValue(Expression *newval);
#if DMDV2
VarDeclaration *rundtor; // if !NULL, rundtor is tested at runtime to see
@@ -655,6 +652,15 @@ struct TypeInfoWildDeclaration : TypeInfoDeclaration
void llvmDefine();
#endif
};
+
+struct TypeInfoVectorDeclaration : TypeInfoDeclaration
+{
+ TypeInfoVectorDeclaration(Type *tinfo);
+
+#if IN_DMD
+ void toDt(dt_t **pdt);
+#endif
+};
#endif
/**************************************************************/
@@ -734,11 +740,12 @@ struct FuncDeclaration : Declaration
Loc endloc; // location of closing curly bracket
int vtblIndex; // for member functions, index into vtbl[]
int naked; // !=0 if naked
- ILS inlineStatus;
+ ILS inlineStatusStmt;
+ ILS inlineStatusExp;
int inlineNest; // !=0 if nested inline
- int cantInterpret; // !=0 if cannot interpret function
int isArrayOp; // !=0 if array operation
enum PASS semanticRun;
+ int semantic3Errors; // !=0 if errors in semantic3
// this function's frame ptr
ForeachStatement *fes; // if foreach body, this is the foreach
int introducing; // !=0 if 'introducing' function
@@ -801,7 +808,7 @@ struct FuncDeclaration : Declaration
LabelDsymbol *searchLabel(Identifier *ident);
AggregateDeclaration *isThis();
AggregateDeclaration *isMember2();
- int getLevel(Loc loc, FuncDeclaration *fd); // lexical nesting level difference
+ int getLevel(Loc loc, Scope *sc, FuncDeclaration *fd); // lexical nesting level difference
void appendExp(Expression *e);
void appendState(Statement *s);
char *mangle();
@@ -823,18 +830,21 @@ struct FuncDeclaration : Declaration
bool setUnsafe();
virtual int isNested();
int needThis();
+ int isVirtualMethod();
virtual int isVirtual();
virtual int isFinal();
virtual int addPreInvariant();
virtual int addPostInvariant();
Expression *interpret(InterState *istate, Expressions *arguments, Expression *thisexp = NULL);
void inlineScan();
- int canInline(int hasthis, int hdrscan = 0);
- Expression *doInline(InlineScanState *iss, Expression *ethis, Expressions *arguments);
+ int canInline(int hasthis, int hdrscan = false, int statementsToo = true);
+ Expression *expandInline(InlineScanState *iss, Expression *ethis, Expressions *arguments, Statement **ps);
const char *kind();
void toDocBuffer(OutBuffer *buf);
FuncDeclaration *isUnique();
+ void checkNestedReference(Scope *sc, Loc loc);
int needsClosure();
+ int hasNestedFrameRefs();
Statement *mergeFrequire(Statement *, Expressions *params = 0);
Statement *mergeFensure(Statement *, Expressions *params = 0);
Parameters *getParameters(int *pvarargs);
View
220 dmd2/delegatize.c
@@ -28,6 +28,9 @@
* t delegate() { return expr; }
*/
+int lambdaSetParent(Expression *e, void *param);
+int lambdaCheckForNestedRef(Expression *e, void *param);
+
Expression *Expression::toDelegate(Scope *sc, Type *t)
{
//printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), toChars());
@@ -35,15 +38,12 @@ Expression *Expression::toDelegate(Scope *sc, Type *t)
FuncLiteralDeclaration *fld =
new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);
Expression *e;
-#if 1
sc = sc->push();
sc->parent = fld; // set current function to be the delegate
e = this;
- e->scanForNestedRef(sc);
+ e->apply(&lambdaSetParent, sc);
+ e->apply(&lambdaCheckForNestedRef, sc);
sc = sc->pop();
-#else
- e = this->syntaxCopy();
-#endif
Statement *s;
if (t->ty == Tvoid)
s = new ExpStatement(loc, e);
@@ -55,164 +55,86 @@ Expression *Expression::toDelegate(Scope *sc, Type *t)
return e;
}
-/******************************
- * Perform scanForNestedRef() on an array of Expressions.
+/******************************************
+ * Patch the parent of declarations to be the new function literal.
*/
-
-void arrayExpressionScanForNestedRef(Scope *sc, Expressions *a)
+int lambdaSetParent(Expression *e, void *param)
{
- //printf("arrayExpressionScanForNestedRef(%p)\n", a);
- if (a)
+ Scope *sc = (Scope *)param;
+ /* We could use virtual functions instead of a switch,
+ * but it doesn't seem worth the bother.
+ */
+ switch (e->op)
{
- for (size_t i = 0; i < a->dim; i++)
- { Expression *e = (*a)[i];
+ case TOKdeclaration:
+ { DeclarationExp *de = (DeclarationExp *)e;
+ de->declaration->parent = sc->parent;
+ break;
+ }
- if (e)
- {
- e->scanForNestedRef(sc);
+ case TOKindex:
+ { IndexExp *de = (IndexExp *)e;
+ if (de->lengthVar)
+ { //printf("lengthVar\n");
+ de->lengthVar->parent = sc->parent;
}
+ break;
}
- }
-}
-
-void Expression::scanForNestedRef(Scope *sc)
-{
- //printf("Expression::scanForNestedRef(%s)\n", toChars());
-}
-
-void SymOffExp::scanForNestedRef(Scope *sc)
-{
- //printf("SymOffExp::scanForNestedRef(%s)\n", toChars());
- VarDeclaration *v = var->isVarDeclaration();
- if (v)
- v->checkNestedReference(sc, 0);
-}
-
-void VarExp::scanForNestedRef(Scope *sc)
-{
- //printf("VarExp::scanForNestedRef(%s)\n", toChars());
- VarDeclaration *v = var->isVarDeclaration();
- if (v)
- v->checkNestedReference(sc, 0);
-}
-
-void ThisExp::scanForNestedRef(Scope *sc)
-{
- assert(var);
- var->isVarDeclaration()->checkNestedReference(sc, 0);
-}
-
-void SuperExp::scanForNestedRef(Scope *sc)
-{
- ThisExp::scanForNestedRef(sc);
-}
-
-void FuncExp::scanForNestedRef(Scope *sc)
-{
- //printf("FuncExp::scanForNestedRef(%s)\n", toChars());
- //fd->parent = sc->parent;
-}
-
-void DeclarationExp::scanForNestedRef(Scope *sc)
-{
- //printf("DeclarationExp::scanForNestedRef() %s\n", toChars());
- declaration->parent = sc->parent;
-}
-void NewExp::scanForNestedRef(Scope *sc)
-{
- //printf("NewExp::scanForNestedRef(Scope *sc): %s\n", toChars());
-
- if (thisexp)
- thisexp->scanForNestedRef(sc);
- arrayExpressionScanForNestedRef(sc, newargs);
- arrayExpressionScanForNestedRef(sc, arguments);
-}
-
-void UnaExp::scanForNestedRef(Scope *sc)
-{
- e1->scanForNestedRef(sc);
-}
-
-void BinExp::scanForNestedRef(Scope *sc)
-{
- e1->scanForNestedRef(sc);
- e2->scanForNestedRef(sc);
-}
-
-void CallExp::scanForNestedRef(Scope *sc)
-{
- //printf("CallExp::scanForNestedRef(Scope *sc): %s\n", toChars());
- e1->scanForNestedRef(sc);
- arrayExpressionScanForNestedRef(sc, arguments);
-}
-
-
-void IndexExp::scanForNestedRef(Scope *sc)
-{
- e1->scanForNestedRef(sc);
-
- if (lengthVar)
- { //printf("lengthVar\n");
- lengthVar->parent = sc->parent;
- }
- e2->scanForNestedRef(sc);
-}
-
-
-void SliceExp::scanForNestedRef(Scope *sc)
-{
- e1->scanForNestedRef(sc);
+ case TOKslice:
+ { SliceExp *se = (SliceExp *)e;
+ if (se->lengthVar)
+ { //printf("lengthVar\n");
+ se->lengthVar->parent = sc->parent;
+ }
+ break;
+ }
- if (lengthVar)
- { //printf("lengthVar\n");
- lengthVar->parent = sc->parent;
+ default:
+ break;
}
- if (lwr)
- lwr->scanForNestedRef(sc);
- if (upr)
- upr->scanForNestedRef(sc);
-}
-
-
-void ArrayLiteralExp::scanForNestedRef(Scope *sc)
-{
- arrayExpressionScanForNestedRef(sc, elements);
-}
-
-
-void AssocArrayLiteralExp::scanForNestedRef(Scope *sc)
-{
- arrayExpressionScanForNestedRef(sc, keys);
- arrayExpressionScanForNestedRef(sc, values);
+ return 0;
}
-
-void StructLiteralExp::scanForNestedRef(Scope *sc)
-{
- arrayExpressionScanForNestedRef(sc, elements);
-}
-
-
-void TupleExp::scanForNestedRef(Scope *sc)
+/*******************************************
+ * Look for references to variables in a scope enclosing the new function literal.
+ */
+int lambdaCheckForNestedRef(Expression *e, void *param)
{
- arrayExpressionScanForNestedRef(sc, exps);
-}
-
+ Scope *sc = (Scope *)param;
+ /* We could use virtual functions instead of a switch,
+ * but it doesn't seem worth the bother.
+ */
+ switch (e->op)
+ {
+ case TOKsymoff:
+ { SymOffExp *se = (SymOffExp *)e;
+ VarDeclaration *v = se->var->isVarDeclaration();
+ if (v)
+ v->checkNestedReference(sc, 0);
+ break;
+ }
-void ArrayExp::scanForNestedRef(Scope *sc)
-{
- e1->scanForNestedRef(sc);
- arrayExpressionScanForNestedRef(sc, arguments);
-}
+ case TOKvar:
+ { VarExp *ve = (VarExp *)e;
+ VarDeclaration *v = ve->var->isVarDeclaration();
+ if (v)
+ v->checkNestedReference(sc, 0);
+ break;
+ }
+ case TOKthis:
+ case TOKsuper:
+ { ThisExp *te = (ThisExp *)e;
+ VarDeclaration *v = te->var->isVarDeclaration();
+ if (v)
+ v->checkNestedReference(sc, 0);
+ break;
+ }
-void CondExp::scanForNestedRef(Scope *sc)
-{
- econd->scanForNestedRef(sc);
- e1->scanForNestedRef(sc);
- e2->scanForNestedRef(sc);
+ default:
+ break;
+ }
+ return 0;
}
-
-
View
4 dmd2/doc.c
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2011 by Digital Mars
+// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -1116,7 +1116,7 @@ void DocComment::parseSections(unsigned char *comment)
goto L1;
if (*p == '\n')
{ p++;
- if (*p == '\n' && !summary && !namelen)
+ if (*p == '\n' && !summary && !namelen && !inCode)
{
pend = p;
p++;
View
75 dmd2/dsymbol.c
@@ -111,7 +111,7 @@ Dsymbol *Dsymbol::syntaxCopy(Dsymbol *s)
* TRUE, *ps = symbol: The one and only one symbol
*/
-int Dsymbol::oneMember(Dsymbol **ps)
+int Dsymbol::oneMember(Dsymbol **ps, Identifier *ident)
{
//printf("Dsymbol::oneMember()\n");
*ps = this;
@@ -122,7 +122,7 @@ int Dsymbol::oneMember(Dsymbol **ps)
* Same as Dsymbol::oneMember(), but look at an array of Dsymbols.
*/
-int Dsymbol::oneMembers(Dsymbols *members, Dsymbol **ps)
+int Dsymbol::oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident)
{
//printf("Dsymbol::oneMembers() %d\n", members ? members->dim : 0);
Dsymbol *s = NULL;
@@ -132,7 +132,7 @@ int Dsymbol::oneMembers(Dsymbols *members, Dsymbol **ps)
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *sx = (*members)[i];
- int x = sx->oneMember(ps);
+ int x = sx->oneMember(ps, ident);
//printf("\t[%d] kind %s = %d, s = %p\n", i, sx->kind(), x, *ps);
if (!x)
{
@@ -142,6 +142,11 @@ int Dsymbol::oneMembers(Dsymbols *members, Dsymbol **ps)
}
if (*ps)
{
+ if (ident)
+ {
+ if (!(*ps)->ident || !(*ps)->ident->equals(ident))
+ continue;
+ }
if (s) // more than one symbol
{ *ps = NULL;
//printf("\tfalse 2\n");
@@ -653,19 +658,16 @@ void Dsymbol::checkDeprecated(Loc loc, Scope *sc)
Module *Dsymbol::getModule()
{
- Module *m;
- Dsymbol *s;
-
//printf("Dsymbol::getModule()\n");
TemplateDeclaration *td = getFuncTemplateDecl(this);
if (td)
return td->getModule();
- s = this;
+ Dsymbol *s = this;
while (s)
{
- //printf("\ts = '%s'\n", s->toChars());
- m = s->isModule();
+ //printf("\ts = %s '%s'\n", s->kind(), s->toPrettyChars());
+ Module *m = s->isModule();
if (m)
return m;
s = s->parent;
@@ -673,30 +675,32 @@ Module *Dsymbol::getModule()
return NULL;
}
-
/**********************************
- * Determine which Module a Dsymbol will be compiled in.
- * This may be different from getModule for templates.
+ * Determine which Module a Dsymbol is in, as far as access rights go.
*/
-Module *Dsymbol::getCompilationModule()
+Module *Dsymbol::getAccessModule()
{
- Module *m;
- TemplateInstance *ti;
- Dsymbol *s;
+ //printf("Dsymbol::getAccessModule()\n");
+ TemplateDeclaration *td = getFuncTemplateDecl(this);
+ if (td)
+ return td->getAccessModule();
- //printf("Dsymbol::getModule()\n");
- s = this;
+ Dsymbol *s = this;
while (s)
{
- //printf("\ts = '%s'\n", s->toChars());
- m = s->isModule();
- if (m)
- return m;
- ti = s->isTemplateInstance();
- if (ti && ti->tmodule)
- return ti->tmodule;
- s = s->parent;
+ //printf("\ts = %s '%s'\n", s->kind(), s->toPrettyChars());
+ Module *m = s->isModule();
+ if (m)
+ return m;
+ TemplateInstance *ti = s->isTemplateInstance();
+ if (ti && ti->isnested)
+ /* Because of local template instantiation, the parent isn't where the access
+ * rights come from - it's the template declaration
+ */
+ s = ti->tempdecl;
+ else
+ s = s->parent;
}
return NULL;
}
@@ -832,7 +836,7 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
// Look in imported modules
for (size_t i = 0; i < imports->dim; i++)
- { ScopeDsymbol *ss = (*imports)[i];
+ { Dsymbol *ss = (*imports)[i];
Dsymbol *s2;
// If private import, don't search it
@@ -842,7 +846,7 @@ 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->isModule() ? 1 : 0);
+ s2 = ss->search(loc, ident, ss->isImport() ? 1 : 0);
if (!s)
s = s2;
else if (s2 && s != s2)
@@ -895,7 +899,7 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
if (flags & 4) // if return NULL on ambiguity
return NULL;
if (!(flags & 2))
- ss->multiplyDefined(loc, s, s2);
+ ScopeDsymbol::multiplyDefined(loc, s, s2);
break;
}
}
@@ -922,7 +926,7 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
return s;
}
-void ScopeDsymbol::importScope(ScopeDsymbol *s, enum PROT protection)
+void ScopeDsymbol::importScope(Dsymbol *s, enum PROT protection)
{
//printf("%s->ScopeDsymbol::importScope(%s, %d)\n", toChars(), s->toChars(), protection);
@@ -930,11 +934,11 @@ void ScopeDsymbol::importScope(ScopeDsymbol *s, enum PROT protection)
if (s != this)
{
if (!imports)
- imports = new ScopeDsymbols();
+ imports = new Dsymbols();
else
{
for (size_t i = 0; i < imports->dim; i++)
- { ScopeDsymbol *ss = (*imports)[i];
+ { Dsymbol *ss = (*imports)[i];
if (ss == s) // if already imported
{
if (protection > prots[i])
@@ -1051,8 +1055,7 @@ static int dimDg(void *ctx, size_t n, Dsymbol *)
size_t ScopeDsymbol::dim(Dsymbols *members)
{
size_t n = 0;
- if (members)
- foreach(members, &dimDg, &n);
+ foreach(members, &dimDg, &n);
return n;
}
#endif
@@ -1102,7 +1105,9 @@ Dsymbol *ScopeDsymbol::getNth(Dsymbols *members, size_t nth, size_t *pn)
#if DMDV2
int ScopeDsymbol::foreach(Dsymbols *members, ScopeDsymbol::ForeachDg dg, void *ctx, size_t *pn)
{
- assert(members);
+ assert(dg);
+ if (!members)
+ return 0;
size_t n = pn ? *pn : 0; // take over index
int result = 0;
View
10 dmd2/dsymbol.h
@@ -154,7 +154,7 @@ struct Dsymbol : Object
void verror(Loc loc, const char *format, va_list ap);
void checkDeprecated(Loc loc, Scope *sc);
Module *getModule(); // module where declared
- Module *getCompilationModule(); // possibly different for templates
+ Module *getAccessModule();
Dsymbol *pastMixin();
Dsymbol *toParent();
Dsymbol *toParent2();
@@ -203,8 +203,8 @@ struct Dsymbol : Object
virtual int needThis(); // need a 'this' pointer?
virtual enum PROT prot();
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
- virtual int oneMember(Dsymbol **ps);
- static int oneMembers(Dsymbols *members, Dsymbol **ps);
+ virtual int oneMember(Dsymbol **ps, Identifier *ident);
+ static int oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident = NULL);
virtual int hasPointers();
virtual bool hasStaticCtorOrDtor();
virtual void addLocalClass(ClassDeclarations *) { }
@@ -291,14 +291,14 @@ struct ScopeDsymbol : Dsymbol
Dsymbols *members; // all Dsymbol's in this scope
DsymbolTable *symtab; // members[] sorted into table
- ScopeDsymbols *imports; // imported ScopeDsymbol's
+ Dsymbols *imports; // imported Dsymbol's
unsigned char *prots; // array of PROT, one for each import
ScopeDsymbol();
ScopeDsymbol(Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
Dsymbol *search(Loc loc, Identifier *ident, int flags);
- void importScope(ScopeDsymbol *s, enum PROT protection);
+ void importScope(Dsymbol *s, enum PROT protection);
int isforwardRef();
void defineRef(Dsymbol *s);
static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2);
View
6 dmd2/enum.c
@@ -300,11 +300,11 @@ void EnumDeclaration::semantic(Scope *sc)
//members->print();
}
-int EnumDeclaration::oneMember(Dsymbol **ps)
+int EnumDeclaration::oneMember(Dsymbol **ps, Identifier *ident)
{
if (isAnonymous())
- return Dsymbol::oneMembers(members, ps);
- return Dsymbol::oneMember(ps);
+ return Dsymbol::oneMembers(members, ps, ident);
+ return Dsymbol::oneMember(ps, ident);
}
void EnumDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
View
2  dmd2/enum.h
@@ -47,7 +47,7 @@ struct EnumDeclaration : ScopeDsymbol
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic0(Scope *sc);
void semantic(Scope *sc);
- int oneMember(Dsymbol **ps);
+ int oneMember(Dsymbol **ps, Identifier *ident = NULL);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Type *getType();
const char *kind();
View
1,531 dmd2/expression.c
@@ -235,19 +235,63 @@ FuncDeclaration *hasThis(Scope *sc)
Expression *resolveProperties(Scope *sc, Expression *e)
{
//printf("resolveProperties(%s)\n", e->toChars());
+
+ TemplateDeclaration *td;
+ Objects *targsi;
+ Expression *ethis;
+ if (e->op == TOKdotti)
+ {
+ DotTemplateInstanceExp* dti = (DotTemplateInstanceExp *)e;
+ td = dti->getTempdecl(sc);
+ dti->ti->semanticTiargs(sc);
+ targsi = dti->ti->tiargs;
+ ethis = dti->e1;
+ goto L1;
+ }
+ else if (e->op == TOKdottd)
+ {
+ DotTemplateExp *dte = (DotTemplateExp *)e;
+ td = dte->td;
+ targsi = NULL;
+ ethis = dte->e1;
+ goto L1;
+ }
+ else if (e->op == TOKtemplate)
+ {
+ td = ((TemplateExp *)e)->td;
+ targsi = NULL;
+ ethis = NULL;
+ L1:
+ assert(td);
+ unsigned errors = global.startGagging();
+ FuncDeclaration *fd = td->deduceFunctionTemplate(sc, e->loc, targsi, ethis, NULL, 1);
+ if (global.endGagging(errors))
+ fd = NULL; // eat "is not a function template" error
+ if (fd && fd->type)
+ { assert(fd->type->ty == Tfunction);
+ TypeFunction *tf = (TypeFunction *)fd->type;
+ if (!tf->isproperty && global.params.enforcePropertySyntax)
+ { error(e->loc, "not a property %s", e->toChars());
+ return new ErrorExp();
+ }
+ e = new CallExp(e->loc, e);
+ e = e->semantic(sc);
+ }
+ goto return_expr;
+ }
+
if (e->type)
{
Type *t = e->type->toBasetype();
if (t->ty == Tfunction || e->op == TOKoverloadset)
{
-#if 1
if (t->ty == Tfunction && !((TypeFunction *)t)->isproperty &&
global.params.enforcePropertySyntax)
{
- error(e->loc, "not a property %s\n", e->toChars());
+ error(e->loc, "not a property %s", e->toChars());
+ return new ErrorExp();
}
-#endif
e = new CallExp(e->loc, e);
e = e->semantic(sc);
}
@@ -271,10 +315,12 @@ Expression *resolveProperties(Scope *sc, Expression *e)
}
}
- else if (e->op == TOKdottd)
+
+return_expr:
+ if (!e->type)
{
- e = new CallExp(e->loc, e);
- e = e->semantic(sc);
+ error(e->loc, "cannot resolve type for %s", e->toChars());
+ e->type = new TypeError();
}
return e;
}
@@ -568,16 +614,6 @@ void preFunctionParameters(Loc loc, Scope *sc, Expressions *exps)
for (size_t i = 0; i < exps->dim; i++)
{ Expression *arg = (*exps)[i];
- if (!arg->type)
- {
-#ifdef DEBUG
- if (!global.gag)
- printf("1: \n");
-#endif
- arg->error("%s is not an expression", arg->toChars());
- arg = new ErrorExp();
- }
-
arg = resolveProperties(sc, arg);
(*exps)[i] = arg;
@@ -697,7 +733,9 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
size_t nparams = Parameter::dim(tf->parameters);
if (nargs > nparams && tf->varargs == 0)
- error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf->toChars());
+ { error(loc, "expected %zu arguments, not %zu for non-variadic function type %s", nparams, nargs, tf->toChars());
+ return Type::terror;
+ }
// If inferring return type, and semantic3() needs to be run if not already run
if (!tf->next && fd->inferRetType)
@@ -714,6 +752,19 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
unsigned n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)
unsigned wildmatch = 0;
+ if (ethis && tf->isWild())
+ {
+ Type *t = ethis->type;
+ if (t->isWild())
+ wildmatch |= MODwild;
+ else if (t->isConst())
+ wildmatch |= MODconst;
+ else if (t->isImmutable())
+ wildmatch |= MODimmutable;
+ else
+ wildmatch |= MODmutable;
+ }
+
int done = 0;
for (size_t i = 0; i < n; i++)
{
@@ -723,7 +774,6 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
arg = arguments->tdata()[i];
else
arg = NULL;
- Type *tb;
if (i < nparams)
{
@@ -736,7 +786,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
if (tf->varargs == 2 && i + 1 == nparams)
goto L2;
error(loc, "expected %zu function arguments, not %zu", nparams, nargs);
- return tf->next;
+ return Type::terror;
}
arg = p->defaultArg;
arg = arg->inlineCopy(sc);
@@ -746,6 +796,15 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
arguments->push(arg);
nargs++;
}
+ else if (arg->op == TOKfunction)
+ { FuncExp *fe = (FuncExp *)arg;
+ Type *pt = p->type;
+ if (tf->varargs == 2 && i + 1 == nparams && pt->nextOf())
+ pt = pt->nextOf();
+ fe->setType(pt);
+ arg = fe->semantic(sc);
+ arguments->tdata()[i] = arg;
+ }
if (tf->varargs == 2 && i + 1 == nparams)
{
@@ -756,7 +815,7 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
goto L2;
else if (nargs != nparams)
{ error(loc, "expected %zu function arguments, not %zu", nparams, nargs);
- return tf->next;
+ return Type::terror;
}
goto L1;
}
@@ -824,13 +883,15 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
default:
if (!arg)
{ error(loc, "not enough arguments");
- return tf->next;
+ return Type::terror;
}
break;
}
arg = arg->semantic(sc);
//printf("\targ = '%s'\n", arg->toChars());
arguments->setDim(i + 1);
+ arguments->tdata()[i] = arg;
+ nargs = i + 1;
done = 1;
}
@@ -841,7 +902,42 @@ Type *functionParameters(Loc loc, Scope *sc, TypeFunction *tf,
if (mod)
{
wildmatch |= mod;
- arg = arg->implicitCastTo(sc, p->type->substWildTo(mod));
+ }
+ }
+ }
+ if (done)
+ break;
+ }
+ if (wildmatch)
+ { /* Calculate wild matching modifier
+ */
+ if (wildmatch & MODconst || wildmatch & (wildmatch - 1))
+ wildmatch = MODconst;
+ else if (wildmatch & MODimmutable)
+ wildmatch = MODimmutable;
+ else if (wildmatch & MODwild)
+ wildmatch = MODwild;
+ else
+ { assert(wildmatch & MODmutable);
+ wildmatch = MODmutable;
+ }