Updated to dmdfe 2.052

This commit is contained in:
Alexey Prokhin
2011-02-20 19:00:52 +03:00
parent b0d97b139a
commit 293f5bf880
31 changed files with 2753 additions and 1394 deletions

View File

@@ -18,6 +18,8 @@ cmake_install.cmake
.DS_Store
CMakeLists.txt.user*
.directory
druntime
phobos
druntime-orig
phobos-orig

View File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -15,5 +15,6 @@
#pragma once
#endif /* __DMC__ */
void escapeDdocString(OutBuffer *buf, unsigned start);
#endif

View File

@@ -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;
}

File diff suppressed because it is too large Load Diff

View File

@@ -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 @@ Lagain:
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 File

@@ -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;
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))
{
--lastNonref;
offset += PTRSIZE;
if (lastNonref < 0)
{
p = v_arguments;
break;
}
p = (VarDeclaration *)parameters->data[lastNonref];
}
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
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;
{ // 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))
{
--lastNonref;
offset += PTRSIZE;
if (lastNonref < 0)
{
p = v_arguments;
break;
}
p = (VarDeclaration *)parameters->data[lastNonref];
}
}
else
p = v_arguments; // last parameter is _arguments[]
if (p->storage_class & STClazy)
// If the last parameter is lazy, it's the size of a delegate
offset += PTRSIZE * 2;
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 File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -730,6 +730,7 @@ struct TypeInstance : TypeQualified
struct TypeTypeof : TypeQualified
{
Expression *exp;
int inuse;
TypeTypeof(Loc loc, Expression *exp);
Type *syntaxCopy();

View File

@@ -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 File

@@ -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();

16
dmd2/rmem.h Normal file
View File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -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,20 +433,28 @@ 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 @@ L2:
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 @@ Lmatch:
{
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 File

@@ -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 File

@@ -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 File

@@ -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 File

@@ -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