Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Updated to dmdfe 2.052

  • Loading branch information...
commit 293f5bf8800478a08e08231a50430590b61b40d9 1 parent b0d97b1
@AlexeyProkhin AlexeyProkhin authored
View
2  .hgignore
@@ -18,6 +18,8 @@ cmake_install.cmake
.DS_Store
CMakeLists.txt.user*
.directory
+druntime
+phobos
druntime-orig
phobos-orig
View
1  dmd2/aggregate.h
@@ -231,6 +231,7 @@ struct ClassDeclaration : AggregateDeclaration
{
static ClassDeclaration *object;
static ClassDeclaration *classinfo;
+ static ClassDeclaration *throwable;
ClassDeclaration *baseClass; // NULL only if this is Object
#if DMDV1
View
14 dmd2/argtypes.c
@@ -155,7 +155,19 @@ TypeTuple *TypeDelegate::toArgTypes()
TypeTuple *TypeStruct::toArgTypes()
{
- return new TypeTuple(); // pass on the stack for efficiency
+ int sz = size(0);
+ switch (sz)
+ {
+ case 1:
+ return new TypeTuple(Type::tint8);
+ case 2:
+ return new TypeTuple(Type::tint16);
+ case 4:
+ return new TypeTuple(Type::tint32);
+ case 8:
+ return new TypeTuple(Type::tint64);
+ }
+ return new TypeTuple(); // pass on the stack
}
TypeTuple *TypeEnum::toArgTypes()
View
4 dmd2/arrayop.c
@@ -356,9 +356,7 @@ Expression *BinExp::arrayOp(Scope *sc)
fd->fbody = fbody;
fd->protection = PROTpublic;
fd->linkage = LINKd;
-
- // special attention for array ops
- fd->isArrayOp = true;
+ fd->isArrayOp = 1;
sc->module->importedFrom->members->push(fd);
View
1  dmd2/attrib.c
@@ -206,6 +206,7 @@ void AttribDeclaration::inlineScan()
void AttribDeclaration::addComment(unsigned char *comment)
{
+ //printf("AttribDeclaration::addComment %s\n", comment);
if (comment)
{
Dsymbols *d = include(NULL, NULL);
View
27 dmd2/cast.c
@@ -426,12 +426,7 @@ MATCH StructLiteralExp::implicitConvTo(Type *t)
for (int i = 0; i < elements->dim; i++)
{ Expression *e = (Expression *)elements->data[i];
Type *te = e->type;
- if (t->mod == 0)
- te = te->mutableOf();
- else
- { assert(t->mod == MODimmutable);
- te = te->invariantOf();
- }
+ te = te->castMod(t->mod);
MATCH m2 = e->implicitConvTo(te);
//printf("\t%s => %s, match = %d\n", e->toChars(), te->toChars(), m2);
if (m2 < m)
@@ -827,9 +822,17 @@ Expression *Expression::castTo(Scope *sc, Type *t)
}
else if (typeb->ty == Tclass)
{ TypeClass *ts = (TypeClass *)typeb;
- if (tb->ty != Tclass &&
- ts->sym->aliasthis)
- { /* Forward the cast to our alias this member, rewrite to:
+ if (ts->sym->aliasthis)
+ {
+ if (tb->ty == Tclass)
+ {
+ ClassDeclaration *cdfrom = typeb->isClassHandle();
+ ClassDeclaration *cdto = tb->isClassHandle();
+ int offset;
+ if (cdto->isBaseOf(cdfrom, &offset))
+ goto L1;
+ }
+ /* Forward the cast to our alias this member, rewrite to:
* cast(to)e1.aliasthis
*/
Expression *e1 = new DotIdExp(loc, this, ts->sym->aliasthis->ident);
@@ -837,6 +840,7 @@ Expression *Expression::castTo(Scope *sc, Type *t)
e = e->semantic(sc);
return e;
}
+ L1: ;
}
e = new CastExp(loc, e, tb);
}
@@ -2152,6 +2156,11 @@ IntRange AndExp::getIntRange()
return ir;
}
+/*
+ * Adam D. Ruppe's algo for bitwise OR:
+ * http://www.digitalmars.com/d/archives/digitalmars/D/value_range_propagation_for_logical_OR_108765.html#N108793
+ */
+
IntRange OrExp::getIntRange()
{
IntRange ir;
View
7 dmd2/class.c
@@ -31,6 +31,7 @@
ClassDeclaration *ClassDeclaration::classinfo;
ClassDeclaration *ClassDeclaration::object;
+ClassDeclaration *ClassDeclaration::throwable;
ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses)
: AggregateDeclaration(loc, id)
@@ -183,6 +184,12 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
object = this;
}
+ if (id == Id::Throwable)
+ { if (throwable)
+ throwable->error("%s", msg);
+ throwable = this;
+ }
+
//if (id == Id::ClassInfo)
if (id == Id::TypeInfo_Class)
{ if (classinfo)
View
16 dmd2/constfold.c
@@ -25,6 +25,7 @@
#include "expression.h"
#include "aggregate.h"
#include "declaration.h"
+#include "utf.h"
#if __FreeBSD__
#define fmodl fmod // hack for now, fix later
@@ -1361,10 +1362,12 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
if (e1->op == TOKnull && (e2->op == TOKint64 || e2->op == TOKstructliteral))
{ e = e2;
+ t = t1;
goto L2;
}
else if ((e1->op == TOKint64 || e1->op == TOKstructliteral) && e2->op == TOKnull)
{ e = e1;
+ t = t2;
L2:
Type *tn = e->type->toBasetype();
if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
@@ -1372,12 +1375,15 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
// Create a StringExp
void *s;
StringExp *es;
- size_t len = 1;
- int sz = tn->size();
+ if (t->nextOf())
+ t = t->nextOf()->toBasetype();
+ int sz = t->size();
+
dinteger_t v = e->toInteger();
+ size_t len = utf_codeLength(sz, v);
s = mem.malloc((len + 1) * sz);
- memcpy((unsigned char *)s, &v, sz);
+ utf_encode(sz, s, v);
// Add terminating 0
memset((unsigned char *)s + len * sz, 0, sz);
@@ -1467,13 +1473,13 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
StringExp *es1 = (StringExp *)e1;
StringExp *es;
Type *t;
- size_t len = es1->len + 1;
int sz = es1->sz;
dinteger_t v = e2->toInteger();
+ size_t len = es1->len + utf_codeLength(sz, v);
s = mem.malloc((len + 1) * sz);
memcpy(s, es1->string, es1->len * sz);
- memcpy((unsigned char *)s + es1->len * sz, &v, sz);
+ utf_encode(sz, (unsigned char *)s + (sz * es1->len), v);
// Add terminating 0
memset((unsigned char *)s + len * sz, 0, sz);
View
1  dmd2/declaration.c
@@ -620,6 +620,7 @@ Dsymbol *AliasDeclaration::toAlias()
if (inSemantic)
{ error("recursive alias declaration");
aliassym = new TypedefDeclaration(loc, ident, Type::terror, NULL);
+ type = Type::terror;
}
else if (!aliassym && scope)
semantic(scope);
View
4 dmd2/declaration.h
@@ -715,6 +715,7 @@ struct FuncDeclaration : Declaration
ILS inlineStatus;
int inlineNest; // !=0 if nested inline
int cantInterpret; // !=0 if cannot interpret function
+ int isArrayOp; // !=0 if array operation
enum PASS semanticRun;
// this function's frame ptr
ForeachStatement *fes; // if foreach body, this is the foreach
@@ -840,9 +841,6 @@ struct FuncDeclaration : Declaration
typedef std::map<const char*, LabelStatement*> LabelMap;
LabelMap labmap;
- // if this is an array operation it gets a little special attention
- bool isArrayOp;
-
// Functions that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
bool availableExternally;
View
36 dmd2/doc.c
@@ -363,6 +363,36 @@ void Module::gendocfile()
/****************************************************
* Having unmatched parentheses can hose the output of Ddoc,
* as the macros depend on properly nested parentheses.
+ * This function replaces all ( with $(LPAREN) and ) with $(RPAREN)
+ * to preserve text literally. This also means macros in the
+ * text won't be expanded.
+ */
+void escapeDdocString(OutBuffer *buf, unsigned start)
+{
+ for (unsigned u = start; u < buf->offset; u++)
+ {
+ unsigned char c = buf->data[u];
+ switch(c)
+ {
+ case '(':
+ buf->remove(u, 1); //remove the (
+ buf->insert(u, "$(LPAREN)", 9); //insert this instead
+ u += 8; //skip over newly inserted macro
+ break;
+
+ case ')':
+ buf->remove(u, 1); //remove the )
+ buf->insert(u, "$(RPAREN)", 9); //insert this instead
+ u += 8; //skip over newly inserted macro
+ break;
+ }
+ }
+}
+
+/****************************************************
+ * Having unmatched parentheses can hose the output of Ddoc,
+ * as the macros depend on properly nested parentheses.
+
* Fix by replacing unmatched ( with $(LPAREN) and unmatched ) with $(RPAREN).
*/
void escapeStrayParenthesis(OutBuffer *buf, unsigned start, Loc loc)
@@ -836,7 +866,11 @@ void FuncDeclaration::toDocBuffer(OutBuffer *buf)
hgs.ddoc = 1;
prefix(buf, td);
if (tf)
- tf->next->toCBuffer(buf, NULL, &hgs);
+ { if (tf->nextOf())
+ tf->nextOf()->toCBuffer(buf, NULL, &hgs);
+ else
+ buf->writestring("auto");
+ }
buf->writeByte(' ');
buf->writestring(ident->toChars());
buf->writeByte('(');
View
1  dmd2/doc.h
@@ -15,5 +15,6 @@
#pragma once
#endif /* __DMC__ */
+void escapeDdocString(OutBuffer *buf, unsigned start);
#endif
View
3  dmd2/dsymbol.c
@@ -84,7 +84,8 @@ int Dsymbol::equals(Object *o)
if (this == o)
return TRUE;
s = (Dsymbol *)(o);
- if (s && ident->equals(s->ident))
+ // Overload sets don't have an ident
+ if (s && ident && s->ident && ident->equals(s->ident))
return TRUE;
return FALSE;
}
View
3,519 dmd2/entity.c
2,272 additions, 1,247 deletions not shown
View
66 dmd2/expression.c
@@ -137,6 +137,14 @@ Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
e1 = new VarExp(loc, f->vthis);
}
+ else
+ {
+ e1->error("need 'this' of type %s to access member %s"
+ " from static function %s",
+ ad->toChars(), var->toChars(), f->toChars());
+ e1 = new ErrorExp();
+ return e1;
+ }
}
if (s && s->isClassDeclaration())
{ e1->type = s->isClassDeclaration()->type;
@@ -2401,6 +2409,11 @@ Expression *DsymbolExp::semantic(Scope *sc)
if (!f->originalType && f->scope) // semantic not yet run
f->semantic(f->scope);
+
+ // if inferring return type, sematic3 needs to be run
+ if (f->inferRetType && f->scope && f->type && !f->type->nextOf())
+ f->semantic3(f->scope);
+
if (f->isUnitTestDeclaration())
{
error("cannot call unittest function %s", toChars());
@@ -4304,6 +4317,9 @@ Expression *VarExp::semantic(Scope *sc)
#endif
}
+ if (type && !type->deco)
+ type = type->semantic(loc, sc);
+
/* Fix for 1161 doesn't work because it causes protection
* problems when instantiating imported templates passing private
* variables as alias template parameters.
@@ -4772,9 +4788,14 @@ Expression *DeclarationExp::semantic(Scope *sc)
error("declaration %s is already defined", s->toPrettyChars());
else if (sc->func)
{ VarDeclaration *v = s->isVarDeclaration();
- if (s->isFuncDeclaration() &&
+ if ( (s->isFuncDeclaration() || s->isTypedefDeclaration() ||
+ s->isAggregateDeclaration() || s->isEnumDeclaration() ||
+ s->isInterfaceDeclaration()) &&
!sc->func->localsymtab->insert(s))
- error("declaration %s is already defined in another scope in %s", s->toPrettyChars(), sc->func->toChars());
+ {
+ error("declaration %s is already defined in another scope in %s",
+ s->toPrettyChars(), sc->func->toChars());
+ }
else if (!global.params.useDeprecated)
{ // Disallow shadowing
@@ -5410,6 +5431,8 @@ Expression *BinExp::semantic(Scope *sc)
error("%s has no value", e2->toChars());
return new ErrorExp();
}
+ if (e1->op == TOKerror || e2->op == TOKerror)
+ return new ErrorExp();
return this;
}
@@ -6026,7 +6049,8 @@ Expression *DotIdExp::semantic(Scope *sc, int flag)
e->type = v->type;
}
}
- return e->deref();
+ e = e->deref();
+ return e->semantic(sc);
}
FuncDeclaration *f = s->isFuncDeclaration();
@@ -8659,6 +8683,8 @@ Expression *IndexExp::semantic(Scope *sc)
if (!e1->type)
e1 = e1->semantic(sc);
assert(e1->type); // semantic() should already be run on it
+ if (e1->op == TOKerror)
+ goto Lerr;
e = this;
// Note that unlike C we do not implement the int[ptr]
@@ -8768,6 +8794,8 @@ Expression *IndexExp::semantic(Scope *sc)
}
default:
+ if (e1->op == TOKerror)
+ goto Lerr;
error("%s must be an array or pointer type, not %s",
e1->toChars(), e1->type->toChars());
case Terror:
@@ -9055,7 +9083,9 @@ Expression *AssignExp::semantic(Scope *sc)
}
}
- BinExp::semantic(sc);
+ Expression *e = BinExp::semantic(sc);
+ if (e->op == TOKerror)
+ return e;
if (e1->op == TOKdottd)
{ // Rewrite a.b=e2, when b is a template, as a.b(e2)
@@ -9188,10 +9218,23 @@ Expression *AssignExp::semantic(Scope *sc)
}
if (t1->ty == Tsarray && !refinit)
- { // Convert e1 to e1[]
- Expression *e = new SliceExp(e1->loc, e1, NULL, NULL);
- e1 = e->semantic(sc);
- t1 = e1->type->toBasetype();
+ {
+ if (e1->op == TOKindex &&
+ ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray)
+ {
+ // Assignment to an AA of fixed-length arrays.
+ // Convert T[n][U] = T[] into T[n][U] = T[n]
+ e2 = e2->implicitCastTo(sc, e1->type);
+ if (e2->type == Type::terror)
+ return e2;
+ }
+ else
+ {
+ // Convert e1 to e1[]
+ Expression *e = new SliceExp(e1->loc, e1, NULL, NULL);
+ e1 = e->semantic(sc);
+ t1 = e1->type->toBasetype();
+ }
}
e2->rvalue();
@@ -9233,8 +9276,13 @@ Expression *AssignExp::semantic(Scope *sc)
else if (t1->ty == Tsarray)
{
/* Should have already converted e1 => e1[]
+ * unless it is an AA
*/
- assert(op == TOKconstruct);
+ if (!(e1->op == TOKindex && t2->ty == Tsarray &&
+ ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray))
+ {
+ assert(op == TOKconstruct);
+ }
//error("cannot assign to static array %s", e1->toChars());
}
else if (e1->op == TOKslice)
View
125 dmd2/func.c
@@ -1,5 +1,5 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2010 by Digital Mars
+// Copyright (c) 1999-2011 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -66,6 +66,7 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageCla
inlineNest = 0;
inlineAsm = 0;
cantInterpret = 0;
+ isArrayOp = 0;
semanticRun = PASSinit;
#if DMDV1
nestedFrameRef = 0;
@@ -972,9 +973,24 @@ void FuncDeclaration::semantic3(Scope *sc)
if (f->varargs == 1)
{
#if TARGET_NET
- varArgs(sc2, f, argptr, _arguments);
+ varArgs(sc2, f, argptr, _arguments);
#else
- Type *t;
+ Type *t;
+
+ if (global.params.is64bit)
+ { // Declare save area for varargs registers
+ Type *t = new TypeIdentifier(loc, Id::va_argsave_t);
+ t = t->semantic(loc, sc);
+ if (t == Type::terror)
+ error("must import core.vararg to use variadic functions");
+ else
+ {
+ v_argsave = new VarDeclaration(loc, t, Id::va_argsave, NULL);
+ v_argsave->semantic(sc2);
+ sc2->insert(v_argsave);
+ v_argsave->parent = this;
+ }
+ }
if (f->linkage == LINKd)
{ // Declare _arguments[]
@@ -1014,20 +1030,6 @@ void FuncDeclaration::semantic3(Scope *sc)
}
#endif
}
- if (global.params.is64bit && f->varargs && f->linkage == LINKc)
- { // Declare save area for varargs registers
- Type *t = new TypeIdentifier(loc, Id::va_argsave_t);
- t = t->semantic(loc, sc);
- if (t == Type::terror)
- error("must import std.c.stdarg to use variadic functions");
- else
- {
- v_argsave = new VarDeclaration(loc, t, Id::va_argsave, NULL);
- v_argsave->semantic(sc2);
- sc2->insert(v_argsave);
- v_argsave->parent = this;
- }
- }
#if IN_LLVM
// LDC make sure argument type is semanticed.
@@ -1458,53 +1460,65 @@ void FuncDeclaration::semantic3(Scope *sc)
// we'll handle variadics ourselves
#if !IN_LLVM
if (argptr)
- { // Initialize _argptr to point past non-variadic arg
+ { // Initialize _argptr
#if IN_GCC
// Handled in FuncDeclaration::toObjFile
v_argptr = argptr;
v_argptr->init = new VoidInitializer(loc);
#else
Type *t = argptr->type;
- VarDeclaration *p;
- unsigned offset = 0;
+ if (global.params.isX86_64)
+ { // Initialize _argptr to point to v_argsave
+ Expression *e1 = new VarExp(0, argptr);
+ Expression *e = new SymOffExp(0, v_argsave, 6*8 + 8*16);
+ e->type = argptr->type;
+ e = new AssignExp(0, e1, e);
+ e = e->semantic(sc);
+ a->push(new ExpStatement(0, e));
+ }
+ else
+ { // Initialize _argptr to point past non-variadic arg
+ VarDeclaration *p;
+ unsigned offset = 0;
- Expression *e1 = new VarExp(0, argptr);
- // Find the last non-ref parameter
- if (parameters && parameters->dim)
- {
- int lastNonref = parameters->dim -1;
- p = (VarDeclaration *)parameters->data[lastNonref];
- /* The trouble with out and ref parameters is that taking
- * the address of it doesn't work, because later processing
- * adds in an extra level of indirection. So we skip over them.
- */
- while (p->storage_class & (STCout | STCref))
+ Expression *e1 = new VarExp(0, argptr);
+ // Find the last non-ref parameter
+ if (parameters && parameters->dim)
{
- --lastNonref;
- offset += PTRSIZE;
- if (lastNonref < 0)
+ int lastNonref = parameters->dim -1;
+ p = (VarDeclaration *)parameters->data[lastNonref];
+ /* The trouble with out and ref parameters is that taking
+ * the address of it doesn't work, because later processing
+ * adds in an extra level of indirection. So we skip over them.
+ */
+ while (p->storage_class & (STCout | STCref))
{
- p = v_arguments;
- break;
+ --lastNonref;
+ offset += PTRSIZE;
+ if (lastNonref < 0)
+ {
+ p = v_arguments;
+ break;
+ }
+ p = (VarDeclaration *)parameters->data[lastNonref];
}
- p = (VarDeclaration *)parameters->data[lastNonref];
}
+ else
+ p = v_arguments; // last parameter is _arguments[]
+ if (p->storage_class & STClazy)
+ // If the last parameter is lazy, it's the size of a delegate
+ offset += PTRSIZE * 2;
+ else
+ offset += p->type->size();
+ offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1); // assume stack aligns on pointer size
+ Expression *e = new SymOffExp(0, p, offset);
+ e->type = Type::tvoidptr;
+ //e = e->semantic(sc);
+ e = new AssignExp(0, e1, e);
+ e->type = t;
+ a->push(new ExpStatement(0, e));
+ p->isargptr = TRUE;
}
- else
- p = v_arguments; // last parameter is _arguments[]
- if (p->storage_class & STClazy)
- // If the last parameter is lazy, it's the size of a delegate
- offset += PTRSIZE * 2;
- else
- offset += p->type->size();
- offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1); // assume stack aligns on pointer size
- Expression *e = new SymOffExp(0, p, offset);
- e->type = Type::tvoidptr;
- //e = e->semantic(sc);
- e = new AssignExp(0, e1, e);
- e->type = t;
- a->push(new ExpStatement(0, e));
- p->isargptr = TRUE;
#endif
}
@@ -1710,7 +1724,9 @@ void FuncDeclaration::semantic3(Scope *sc)
if (isSynchronized())
{ /* Wrap the entire function body in a synchronized statement
*/
- ClassDeclaration *cd = parent->isClassDeclaration();
+ AggregateDeclaration *ad = isThis();
+ ClassDeclaration *cd = ad ? ad->isClassDeclaration() : NULL;
+
if (cd)
{
#if TARGET_WINDOS
@@ -3427,7 +3443,8 @@ int StaticCtorDeclaration::addPostInvariant()
void StaticCtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
if (hgs->hdrgen)
- { buf->writestring("static this();\n");
+ { buf->writestring("static this();");
+ buf->writenl();
return;
}
buf->writestring("static this()");
View
2  dmd2/imphint.c
@@ -46,7 +46,7 @@ const char *importHint(const char *s)
{ "core.stdc.stdio",
"std.stdio",
"std.math",
- "std.c.stdarg",
+ "core.vararg",
};
static const char *names[] =
{
View
10 dmd2/interpret.c
@@ -3132,7 +3132,7 @@ Expression *AssertExp::interpret(InterState *istate)
{ // Special case: deal with compiler-inserted assert(&this, "null this")
AddrExp *ade = (AddrExp *)this->e1;
if (ade->e1->op == TOKthis && istate->localThis)
- if (ade->e1->op == TOKdotvar
+ if (istate->localThis->op == TOKdotvar
&& ((DotVarExp *)(istate->localThis))->e1->op == TOKthis)
return getVarExp(loc, istate, ((DotVarExp*)(istate->localThis))->var);
else
@@ -3141,7 +3141,13 @@ Expression *AssertExp::interpret(InterState *istate)
if (this->e1->op == TOKthis)
{
if (istate->localThis)
- return istate->localThis->interpret(istate);
+ {
+ if (istate->localThis->op == TOKdotvar
+ && ((DotVarExp *)(istate->localThis))->e1->op == TOKthis)
+ return getVarExp(loc, istate, ((DotVarExp*)(istate->localThis))->var);
+ else
+ return istate->localThis->interpret(istate);
+ }
}
e1 = this->e1->interpret(istate);
if (e1 == EXP_CANT_INTERPRET)
View
6 dmd2/mars.c
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2010 by Digital Mars
+// Copyright (c) 1999-2011 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -94,13 +94,13 @@ Global::Global()
#endif
#endif
- copyright = "Copyright (c) 1999-2010 by Digital Mars";
+ copyright = "Copyright (c) 1999-2011 by Digital Mars";
written = "written by Walter Bright"
#if TARGET_NET
"\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates.";
#endif
;
- version = "v2.051";
+ version = "v2.052";
#if IN_LLVM
ldc_version = "LDC trunk";
llvm_version = "LLVM 2.8";
View
43 dmd2/mtype.c
@@ -52,6 +52,7 @@
#include "import.h"
#include "aggregate.h"
#include "hdrgen.h"
+#include "doc.h"
#if IN_LLVM
//#include "gen/tollvm.h"
@@ -1781,10 +1782,13 @@ Expression *Type::getProperty(Loc loc, Identifier *ident)
s = toDsymbol(NULL);
if (s)
s = s->search_correct(ident);
- if (s)
- error(loc, "no property '%s' for type '%s', did you mean '%s'?", ident->toChars(), toChars(), s->toChars());
- else
- error(loc, "no property '%s' for type '%s'", ident->toChars(), toChars());
+ if (this != Type::terror)
+ {
+ if (s)
+ error(loc, "no property '%s' for type '%s', did you mean '%s'?", ident->toChars(), toChars(), s->toChars());
+ else
+ error(loc, "no property '%s' for type '%s'", ident->toChars(), toChars());
+ }
e = new ErrorExp();
}
return e;
@@ -2551,12 +2555,21 @@ unsigned TypeBasic::alignsize()
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
case Tint64:
case Tuns64:
+ sz = global.params.isX86_64 ? 8 : 4;
+ break;
+
case Tfloat64:
case Timaginary64:
+ sz = global.params.isX86_64 ? 8 : 4;
+ break;
+
case Tcomplex32:
- case Tcomplex64:
sz = 4;
break;
+
+ case Tcomplex64:
+ sz = global.params.isX86_64 ? 8 : 4;
+ break;
#endif
#if IN_DMD
default:
@@ -6183,6 +6196,7 @@ TypeTypeof::TypeTypeof(Loc loc, Expression *exp)
: TypeQualified(Ttypeof, loc)
{
this->exp = exp;
+ inuse = 0;
}
Type *TypeTypeof::syntaxCopy()
@@ -6225,6 +6239,13 @@ Type *TypeTypeof::semantic(Loc loc, Scope *sc)
//printf("TypeTypeof::semantic() %s\n", toChars());
//static int nest; if (++nest == 50) *(char*)0=0;
+ if (inuse)
+ {
+ inuse = 2;
+ error(loc, "circular typeof definition");
+ return Type::terror;
+ }
+ inuse++;
#if 0
/* Special case for typeof(this) and typeof(super) since both
@@ -6327,9 +6348,11 @@ Type *TypeTypeof::semantic(Loc loc, Scope *sc)
goto Lerr;
}
}
+ inuse--;
return t;
Lerr:
+ inuse--;
return terror;
}
@@ -7333,9 +7356,12 @@ static MATCH aliasthisConvTo(AggregateDeclaration *ad, Type *from, Type *to)
Expression *ethis = from->defaultInit(0);
fd = fd->overloadResolve(0, ethis, NULL);
if (fd)
+ {
t = ((TypeFunction *)fd->type)->next;
+ }
}
- return t->implicitConvTo(to);
+ MATCH m = t->implicitConvTo(to);
+ return m;
}
return MATCHnomatch;
}
@@ -8348,7 +8374,12 @@ void Parameter::argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Parameters *argu
if (arg->defaultArg)
{
argbuf.writestring(" = ");
+ unsigned o = argbuf.offset;
arg->defaultArg->toCBuffer(&argbuf, hgs);
+ if (hgs->ddoc)
+ {
+ escapeDdocString(&argbuf, o);
+ }
}
buf->write(&argbuf);
}
View
1  dmd2/mtype.h
@@ -730,6 +730,7 @@ struct TypeInstance : TypeQualified
struct TypeTypeof : TypeQualified
{
Expression *exp;
+ int inuse;
TypeTypeof(Loc loc, Expression *exp);
Type *syntaxCopy();
View
12 dmd2/parse.c
@@ -230,7 +230,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
case TOKtypeof:
case TOKdot:
Ldeclaration:
- a = parseDeclarations(STCundefined);
+ a = parseDeclarations(STCundefined, NULL);
decldefs->append(a);
continue;
@@ -431,7 +431,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
peek(tk)->value == TOKlcurly)
)
{
- a = parseDeclarations(storageClass);
+ a = parseDeclarations(storageClass, comment);
decldefs->append(a);
continue;
}
@@ -2651,7 +2651,7 @@ Type *Parser::parseDeclarator(Type *t, Identifier **pident, TemplateParameters *
* Return array of Declaration *'s.
*/
-Dsymbols *Parser::parseDeclarations(StorageClass storage_class)
+Dsymbols *Parser::parseDeclarations(StorageClass storage_class, unsigned char *comment)
{
StorageClass stc;
Type *ts;
@@ -2660,10 +2660,12 @@ Dsymbols *Parser::parseDeclarations(StorageClass storage_class)
Identifier *ident;
Dsymbols *a;
enum TOK tok = TOKreserved;
- unsigned char *comment = token.blockComment;
enum LINK link = linkage;
//printf("parseDeclarations() %s\n", token.toChars());
+ if (!comment)
+ comment = token.blockComment;
+
if (storage_class)
{ ts = NULL; // infer type
goto L2;
@@ -3483,7 +3485,7 @@ Statement *Parser::parseStatement(int flags)
Ldeclaration:
{ Array *a;
- a = parseDeclarations(STCundefined);
+ a = parseDeclarations(STCundefined, NULL);
if (a->dim > 1)
{
Statements *as = new Statements();
View
2  dmd2/parse.h
@@ -108,7 +108,7 @@ struct Parser : Lexer
Type *parseBasicType();
Type *parseBasicType2(Type *t);
Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL);
- Dsymbols *parseDeclarations(StorageClass storage_class);
+ Dsymbols *parseDeclarations(StorageClass storage_class, unsigned char *comment);
void parseContracts(FuncDeclaration *f);
Statement *parseStatement(int flags);
Initializer *parseInitializer();
View
16 dmd2/rmem.h
@@ -0,0 +1,16 @@
+#ifndef __RMEM_H__
+#define __RMEM_H__
+
+// jam memory stuff here
+
+#include "mem.h"
+
+#if (defined (__SVR4) && defined (__sun))
+#include <alloca.h>
+#endif
+
+#ifdef __MINGW32__
+#include <malloc.h>
+#endif
+
+#endif // __RMEM_H__
View
4 dmd2/root/speller.c
@@ -4,6 +4,10 @@
#include <stdlib.h>
#include <assert.h>
+#if __sun&&__SVR4
+#include <alloca.h>
+#endif
+
#include "speller.h"
const char idchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
View
44 dmd2/statement.c
@@ -42,7 +42,10 @@ int os_critsecsize()
return sizeof(pthread_mutex_t);
}
#elif IN_DMD
-extern int os_critsecsize();
+
+extern int os_critsecsize32();
+extern int os_critsecsize64();
+
#endif
/******************************** Statement ***************************/
@@ -2402,12 +2405,6 @@ Statement *IfStatement::semantic(Scope *sc)
{
condition = condition->semantic(sc);
condition = resolveProperties(sc, condition);
- condition = condition->checkToBoolean(sc);
-
- // If we can short-circuit evaluate the if statement, don't do the
- // semantic analysis of the skipped code.
- // This feature allows a limited form of conditional compilation.
- condition = condition->optimize(WANTflags);
// Evaluate at runtime
unsigned cs0 = sc->callSuper;
@@ -2431,15 +2428,25 @@ Statement *IfStatement::semantic(Scope *sc)
match->parent = sc->func;
/* Generate:
- * (arg = condition)
+ * ((arg = condition), arg)
*/
VarExp *v = new VarExp(0, match);
condition = new AssignExp(loc, v, condition);
+ condition = new CommaExp(loc, condition, v);
condition = condition->semantic(scd);
}
else
scd = sc->push();
+ // Convert to boolean after declaring arg so this works:
+ // if (S arg = S()) {}
+ // where S is a struct that defines opCast!bool.
+ condition = condition->checkToBoolean(sc);
+
+ // If we can short-circuit evaluate the if statement, don't do the
+ // semantic analysis of the skipped code.
+ // This feature allows a limited form of conditional compilation.
+ condition = condition->optimize(WANTflags);
ifbody = ifbody->semanticNoScope(scd);
scd->pop();
@@ -4041,11 +4048,11 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
cs->push(new DeclarationStatement(loc, new DeclarationExp(loc, tmp)));
#if IN_LLVM
- // LDC: Build args
- Parameters* args = new Parameters;
- args->push(new Parameter(STCin, t->pointerTo(), NULL, NULL));
+ // LDC: Build args
+ Parameters* args = new Parameters;
+ args->push(new Parameter(STCin, t->pointerTo(), NULL, NULL));
- FuncDeclaration *fdenter = FuncDeclaration::genCfunc(args, Type::tvoid, Id::criticalenter);
+ FuncDeclaration *fdenter = FuncDeclaration::genCfunc(args, Type::tvoid, Id::criticalenter);
#else
FuncDeclaration *fdenter = FuncDeclaration::genCfunc(Type::tvoid, Id::criticalenter);
#endif
@@ -4373,12 +4380,13 @@ void Catch::semantic(Scope *sc)
sc = sc->push(sym);
if (!type)
- type = new TypeIdentifier(0, Id::Object);
+ type = new TypeIdentifier(0, Id::Throwable);
type = type->semantic(loc, sc);
- if (!type->toBasetype()->isClassHandle())
+ ClassDeclaration *cd = type->toBasetype()->isClassHandle();
+ if (!cd || ((cd != ClassDeclaration::throwable) && !ClassDeclaration::throwable->isBaseOf(cd, NULL)))
{
if (type != Type::terror)
- { error(loc, "can only catch class objects, not '%s'", type->toChars());
+ { error(loc, "can only catch class objects derived from Throwable, not '%s'", type->toChars());
type = Type::terror;
}
}
@@ -4603,8 +4611,10 @@ Statement *ThrowStatement::semantic(Scope *sc)
#endif
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
- if (!exp->type->toBasetype()->isClassHandle())
- error("can only throw class objects, not type %s", exp->type->toChars());
+ ClassDeclaration *cd = exp->type->toBasetype()->isClassHandle();
+ if (!cd || ((cd != ClassDeclaration::throwable) && !ClassDeclaration::throwable->isBaseOf(cd, NULL)))
+ error("can only throw class objects derived from Throwable, not type %s", exp->type->toChars());
+
return this;
}
View
57 dmd2/template.c
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
-// Copyright (c) 1999-2010 by Digital Mars
+// Copyright (c) 1999-2011 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -433,19 +433,27 @@ void TemplateDeclaration::semantic(Scope *sc)
{
// Generate this function as it may be used
// when template is instantiated in other modules
-
- // FIXME: LDC
- //sc->module->toModuleArray();
+ // FIXME: LDC
+ //sc->module->toModuleArray();
}
if (/*global.params.useAssert &&*/ sc->module)
{
// Generate this function as it may be used
// when template is instantiated in other modules
+ // FIXME: LDC
+ //sc->module->toModuleAssert();
+ }
- // FIXME: LDC
- //sc->module->toModuleAssert();
+#if DMDV2
+ if (/*global.params.useUnitTests &&*/ sc->module)
+ {
+ // Generate this function as it may be used
+ // when template is instantiated in other modules
+ // FIXME: LDC
+ // sc->module->toModuleUnittest();
}
+#endif
/* Remember Scope for later instantiations, but make
* a copy since attributes can change.
@@ -1085,6 +1093,14 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec
Type *tthis = ethis->type;
unsigned mod = fd->type->mod;
StorageClass stc = scope->stc;
+ // Propagate parent storage class (see bug 5504)
+ Dsymbol *p = parent;
+ while (p->isTemplateDeclaration() || p->isTemplateInstance())
+ p = p->parent;
+ AggregateDeclaration *ad = p->isAggregateDeclaration();
+ if (ad)
+ stc |= ad->storage_class;
+
if (stc & (STCshared | STCsynchronized))
mod |= MODshared;
if (stc & STCimmutable)
@@ -1327,23 +1343,23 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Scope *sc, Loc loc, Objec
{
if (arrayObjectMatch(p->dedargs, dedargs, this, sc))
{
- //printf("recursive, no match %p %s\n", this, this->toChars());
- nmatches++;
+ //printf("recursive, no match p->sc=%p %p %s\n", p->sc, this, this->toChars());
+ /* It must be a subscope of p->sc, other scope chains are not recursive
+ * instantiations.
+ */
+ for (Scope *scx = sc; scx; scx = scx->enclosing)
+ {
+ if (scx == p->sc)
+ goto Lnomatch;
+ }
}
/* BUG: should also check for ref param differences
*/
}
- /* Look for 2 matches at least, because sometimes semantic3() gets run causing what appears to
- * be recursion but isn't.
- * Template A's constraint instantiates B, B's semantic3() run includes something that has A in its constraint.
- * Perhaps a better solution is to always defer semantic3() rather than doing it eagerly. The risk
- * with that is what if semantic3() fails, but our constraint "succeeded"?
- */
- if (nmatches >= 2)
- goto Lnomatch;
Previous pr;
pr.prev = previous;
+ pr.sc = paramscope;
pr.dedargs = dedargs;
previous = &pr; // add this to threaded list
@@ -2540,7 +2556,7 @@ void deduceBaseClassParameters(BaseClass *b,
Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes,
Objects *best, int &numBaseClassMatches)
{
- TemplateInstance *parti = b->base->parent->isTemplateInstance();
+ TemplateInstance *parti = b->base ? b->base->parent->isTemplateInstance() : NULL;
if (parti)
{
// Make a temporary copy of dedtypes so we don't destroy it
@@ -3286,7 +3302,10 @@ void TemplateValueParameter::semantic(Scope *sc)
valType = valType->semantic(loc, sc);
if (!(valType->isintegral() || valType->isfloating() || valType->isString()) &&
valType->ty != Tident)
- error(loc, "arithmetic/string type expected for value-parameter, not %s", valType->toChars());
+ {
+ if (valType != Type::terror)
+ error(loc, "arithmetic/string type expected for value-parameter, not %s", valType->toChars());
+ }
if (specValue)
{ Expression *e = specValue;
@@ -3736,7 +3755,7 @@ void TemplateInstance::semantic(Scope *sc)
void TemplateInstance::semantic(Scope *sc, Expressions *fargs)
{
- //printf("TemplateInstance::semantic('%s', this=%p, gag = %d)\n", toChars(), this, global.gag);
+ //printf("TemplateInstance::semantic('%s', this=%p, gag = %d, sc = %p)\n", toChars(), this, global.gag, sc);
if (global.errors && name != Id::AssociativeArray)
{
//printf("not instantiating %s due to %d errors\n", toChars(), global.errors);
View
1  dmd2/template.h
@@ -70,6 +70,7 @@ struct TemplateDeclaration : ScopeDsymbol
struct Previous
{ Previous *prev;
+ Scope *sc;
Objects *dedargs;
};
Previous *previous; // threaded list of previous instantiation attempts on stack
View
10 dmd2/traits.c
@@ -76,8 +76,11 @@ Expression *TraitsExp::semantic(Scope *sc)
#if LOGSEMANTIC
printf("TraitsExp::semantic() %s\n", toChars());
#endif
- if (ident != Id::compiles && ident != Id::isSame)
+ if (ident != Id::compiles && ident != Id::isSame &&
+ ident != Id::identifier)
+ {
TemplateInstance::semanticTiargs(loc, sc, args, 1);
+ }
size_t dim = args ? args->dim : 0;
Object *o;
Declaration *d;
@@ -176,6 +179,11 @@ Expression *TraitsExp::semantic(Scope *sc)
}
else if (ident == Id::identifier)
{ // Get identifier for symbol as a string literal
+
+ // Specify 0 for the flags argument to semanticTiargs() so that
+ // a symbol should not be folded to a constant.
+ TemplateInstance::semanticTiargs(loc, sc, args, 0);
+
if (dim != 1)
goto Ldimerror;
Object *o = (Object *)args->data[0];
View
91 dmd2/utf.c
@@ -11,6 +11,7 @@
// http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
#include <stdio.h>
+#include <string.h>
#include <assert.h>
#include "utf.h"
@@ -227,3 +228,93 @@ const char *utf_decodeWchar(unsigned short *s, size_t len, size_t *pidx, dchar_t
return msg;
}
+void utf_encodeChar(unsigned char *s, dchar_t c)
+{
+ if (c <= 0x7F)
+ {
+ s[0] = (char) c;
+ }
+ else if (c <= 0x7FF)
+ {
+ s[0] = (char)(0xC0 | (c >> 6));
+ s[1] = (char)(0x80 | (c & 0x3F));
+ }
+ else if (c <= 0xFFFF)
+ {
+ s[0] = (char)(0xE0 | (c >> 12));
+ s[1] = (char)(0x80 | ((c >> 6) & 0x3F));
+ s[2] = (char)(0x80 | (c & 0x3F));
+ }
+ else if (c <= 0x10FFFF)
+ {
+ s[0] = (char)(0xF0 | (c >> 18));
+ s[1] = (char)(0x80 | ((c >> 12) & 0x3F));
+ s[2] = (char)(0x80 | ((c >> 6) & 0x3F));
+ s[3] = (char)(0x80 | (c & 0x3F));
+ }
+ else
+ assert(0);
+}
+
+void utf_encodeWchar(unsigned short *s, dchar_t c)
+{
+ if (c <= 0xFFFF)
+ {
+ s[0] = (wchar_t) c;
+ }
+ else
+ {
+ s[0] = (wchar_t) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
+ s[1] = (wchar_t) (((c - 0x10000) & 0x3FF) + 0xDC00);
+ }
+}
+
+
+/**
+ * Returns the code length of c in the encoding.
+ * The code is returned in character count, not in bytes.
+ */
+
+int utf_codeLengthChar(dchar_t c)
+{
+ return
+ c <= 0x7F ? 1
+ : c <= 0x7FF ? 2
+ : c <= 0xFFFF ? 3
+ : c <= 0x10FFFF ? 4
+ : (assert(false), 6);
+}
+
+int utf_codeLengthWchar(dchar_t c)
+{
+ return c <= 0xFFFF ? 1 : 2;
+}
+
+/**
+ * Returns the code length of c in the encoding.
+ * sz is the encoding: 1 = utf8, 2 = utf16, 4 = utf32.
+ * The code is returned in character count, not in bytes.
+ */
+int utf_codeLength(int sz, dchar_t c)
+{
+ if (sz == 1)
+ return utf_codeLengthChar(c);
+ if (sz == 2)
+ return utf_codeLengthWchar(c);
+ assert(sz == 4);
+ return 1;
+}
+
+void utf_encode(int sz, void *s, dchar_t c)
+{
+ if (sz == 1)
+ utf_encodeChar((unsigned char *)s, c);
+ else if (sz == 2)
+ utf_encodeWchar((unsigned short *)s, c);
+ else
+ {
+ assert(sz == 4);
+ memcpy((unsigned char *)s, &c, sz);
+ }
+}
+
View
11 dmd2/utf.h
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// utf.h
-// Copyright (c) 2003-2008 by Digital Mars
+// Copyright (c) 2003-2010 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -23,4 +23,13 @@ const char *utf_validateString(unsigned char *s, size_t len);
extern int isUniAlpha(dchar_t);
+void utf_encodeChar(unsigned char *s, dchar_t c);
+void utf_encodeWchar(unsigned short *s, dchar_t c);
+
+int utf_codeLengthChar(dchar_t c);
+int utf_codeLengthWchar(dchar_t c);
+
+int utf_codeLength(int sz, dchar_t c);
+void utf_encode(int sz, void *s, dchar_t c);
+
#endif
Please sign in to comment.
Something went wrong with that request. Please try again.