mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-03-01 18:13:18 +01:00
Updated to dmdfe 2.052
This commit is contained in:
@@ -18,6 +18,8 @@ cmake_install.cmake
|
||||
.DS_Store
|
||||
CMakeLists.txt.user*
|
||||
.directory
|
||||
druntime
|
||||
phobos
|
||||
druntime-orig
|
||||
phobos-orig
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -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);
|
||||
|
||||
27
dmd2/cast.c
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;
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
36
dmd2/doc.c
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('(');
|
||||
|
||||
@@ -15,5 +15,6 @@
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
void escapeDdocString(OutBuffer *buf, unsigned start);
|
||||
|
||||
#endif
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
3519
dmd2/entity.c
3519
dmd2/entity.c
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
|
||||
133
dmd2/func.c
133
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;
|
||||
|
||||
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()");
|
||||
|
||||
@@ -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[] =
|
||||
{
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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";
|
||||
|
||||
43
dmd2/mtype.c
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);
|
||||
}
|
||||
|
||||
@@ -730,6 +730,7 @@ struct TypeInstance : TypeQualified
|
||||
struct TypeTypeof : TypeQualified
|
||||
{
|
||||
Expression *exp;
|
||||
int inuse;
|
||||
|
||||
TypeTypeof(Loc loc, Expression *exp);
|
||||
Type *syntaxCopy();
|
||||
|
||||
12
dmd2/parse.c
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();
|
||||
|
||||
@@ -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
16
dmd2/rmem.h
Normal 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__
|
||||
@@ -4,6 +4,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if __sun&&__SVR4
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include "speller.h"
|
||||
|
||||
const char idchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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 = ≺ // 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);
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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];
|
||||
|
||||
91
dmd2/utf.c
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
11
dmd2/utf.h
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
|
||||
|
||||
Reference in New Issue
Block a user