Merged DMD 2.060 frontend.

Upstream Git tag v2.060 (e8fe11c20249cb9e42538be88c99b74ede4d12e3).
This commit is contained in:
David Nadlinger
2012-09-07 03:51:31 +02:00
parent e03e027002
commit 837ef30fec
85 changed files with 4411 additions and 3780 deletions
+11 -4
View File
@@ -67,7 +67,6 @@ struct AggregateDeclaration : ScopeDsymbol
Type *handle; // 'this' type
unsigned structsize; // size of struct
unsigned alignsize; // size of struct for alignment purposes
unsigned structalign; // struct member alignment in effect
int hasUnions; // set if aggregate has overlapping fields
VarDeclarations fields; // VarDeclaration fields
enum Sizeok sizeok; // set when structsize contains valid data
@@ -96,17 +95,18 @@ struct AggregateDeclaration : ScopeDsymbol
#ifdef IN_GCC
Expressions *attributes; // GCC decl/type attributes
FuncDeclarations methods; // flat list of all methods for debug information
#endif
Expression *getRTInfo; // pointer to GC info generated by object.RTInfo(this)
AggregateDeclaration(Loc loc, Identifier *id);
void semantic2(Scope *sc);
void semantic3(Scope *sc);
void inlineScan();
unsigned size(Loc loc);
static void alignmember(unsigned salign, unsigned size, unsigned *poffset);
static void alignmember(structalign_t salign, unsigned size, unsigned *poffset);
static unsigned placeField(unsigned *nextoffset,
unsigned memsize, unsigned memalignsize, unsigned memalign,
unsigned memsize, unsigned memalignsize, structalign_t memalign,
unsigned *paggsize, unsigned *paggalignsize, bool isunion);
Type *getType();
int firstFieldInUnion(int indx); // first field in union that includes indx
@@ -165,8 +165,14 @@ struct StructDeclaration : AggregateDeclaration
FuncDeclaration *xeq; // TypeInfo_Struct.xopEquals
static FuncDeclaration *xerreq; // object.xopEquals
structalign_t alignment; // alignment applied outside of the struct
#endif
// For 64 bit Efl function call/return ABI
Type *arg1type;
Type *arg2type;
StructDeclaration(Loc loc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
@@ -175,6 +181,7 @@ struct StructDeclaration : AggregateDeclaration
char *mangle();
const char *kind();
void finalizeSize(Scope *sc);
bool isPOD();
#if DMDV1
Expression *cloneMembers();
#endif
+24
View File
@@ -18,6 +18,7 @@
#include "aggregate.h"
#include "dsymbol.h"
#include "mtype.h"
#include "declaration.h"
#if DMDV2
@@ -78,9 +79,32 @@ void AliasThis::semantic(Scope *sc)
::error(loc, "%s is not a member of %s", s->toChars(), ad->toChars());
else
::error(loc, "undefined identifier %s", ident->toChars());
return;
}
else if (ad->aliasthis && s != ad->aliasthis)
error("there can be only one alias this");
/* disable the alias this conversion so the implicit conversion check
* doesn't use it.
*/
/* This should use ad->aliasthis directly, but with static foreach and templates
* ad->type->sym might be different to ad.
*/
AggregateDeclaration *ad2 = ad->type->toDsymbol(NULL)->isAggregateDeclaration();
Dsymbol *save = ad2->aliasthis;
ad2->aliasthis = NULL;
if (Declaration *d = s->isDeclaration())
{
Type *t = d->type;
assert(t);
if (ad->type->implicitConvTo(t))
{
::error(loc, "alias this is not reachable as %s already converts to %s", ad->toChars(), t->toChars());
}
}
ad2->aliasthis = save;
ad->aliasthis = s;
}
else
+260 -12
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 2010-2011 by Digital Mars
// Copyright (c) 2010-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -27,6 +27,9 @@
#include "aggregate.h"
#include "hdrgen.h"
#define tfloat2 tfloat64
//#define tfloat2 tcomplex32
/****************************************************
* This breaks a type down into 'simpler' types that can be passed to a function
* in registers, and returned in registers.
@@ -40,6 +43,10 @@ TypeTuple *Type::toArgTypes()
return NULL; // not valid for a parameter
}
TypeTuple *TypeError::toArgTypes()
{
return new TypeTuple(Type::terror);
}
TypeTuple *TypeBasic::toArgTypes()
{ Type *t1 = NULL;
@@ -78,7 +85,7 @@ TypeTuple *TypeBasic::toArgTypes()
case Tcomplex32:
if (global.params.is64bit)
t1 = Type::tfloat64; // weird, eh?
t1 = Type::tfloat2;
else
{
t1 = Type::tfloat64;
@@ -124,23 +131,39 @@ TypeTuple *TypeBasic::toArgTypes()
return t;
}
#if DMDV2
TypeTuple *TypeVector::toArgTypes()
{
return new TypeTuple(Type::tfloat64);
return new TypeTuple(this);
}
#endif
TypeTuple *TypeSArray::toArgTypes()
{
#if DMDV2
if (dim)
{
/* Should really be done as if it were a struct with dim members
* of the array's elements.
* I.e. int[2] should be done like struct S { int a; int b; }
*/
dinteger_t sz = dim->toInteger();
if (sz == 1)
// T[1] should be passed like T
return next->toArgTypes();
}
return new TypeTuple(); // pass on the stack for efficiency
#else
return new TypeTuple(Type::tvoidptr);
return new TypeTuple(); // pass on the stack for efficiency
#endif
}
TypeTuple *TypeDArray::toArgTypes()
{
return new TypeTuple(); // pass on the stack for efficiency
/* Should be done as if it were:
* struct S { size_t length; void* ptr; }
*/
return new TypeTuple(Type::tsize_t, Type::tvoidptr);
}
TypeTuple *TypeAArray::toArgTypes()
@@ -150,30 +173,255 @@ TypeTuple *TypeAArray::toArgTypes()
TypeTuple *TypePointer::toArgTypes()
{
return new TypeTuple(this);
return new TypeTuple(Type::tvoidptr);
}
TypeTuple *TypeDelegate::toArgTypes()
{
return new TypeTuple(); // pass on the stack for efficiency
/* Should be done as if it were:
* struct S { void* ptr; void* funcptr; }
*/
return new TypeTuple(Type::tvoidptr, Type::tvoidptr);
}
/*************************************
* Convert a floating point type into the equivalent integral type.
*/
Type *mergeFloatToInt(Type *t)
{
switch (t->ty)
{
case Tfloat32:
case Timaginary32:
t = Type::tint32;
break;
case Tfloat64:
case Timaginary64:
case Tcomplex32:
t = Type::tint64;
break;
default:
#ifdef DEBUG
printf("mergeFloatToInt() %s\n", t->toChars());
#endif
assert(0);
}
return t;
}
/*************************************
* This merges two types into an 8byte type.
*/
Type *argtypemerge(Type *t1, Type *t2, unsigned offset2)
{
//printf("argtypemerge(%s, %s, %d)\n", t1 ? t1->toChars() : "", t2 ? t2->toChars() : "", offset2);
if (!t1)
{ assert(!t2 || offset2 == 0);
return t2;
}
if (!t2)
return t1;
unsigned sz1 = t1->size(0);
unsigned sz2 = t2->size(0);
if (t1->ty != t2->ty &&
(t1->ty == Tfloat80 || t2->ty == Tfloat80))
return NULL;
// [float,float] => [cfloat]
if (t1->ty == Tfloat32 && t2->ty == Tfloat32 && offset2 == 4)
return Type::tfloat2;
// Merging floating and non-floating types produces the non-floating type
if (t1->isfloating())
{
if (!t2->isfloating())
t1 = mergeFloatToInt(t1);
}
else if (t2->isfloating())
t2 = mergeFloatToInt(t2);
Type *t;
// Pick type with larger size
if (sz1 < sz2)
t = t2;
else
t = t1;
// If t2 does not lie within t1, need to increase the size of t to enclose both
if (offset2 && sz1 < offset2 + sz2)
{
switch (offset2 + sz2)
{
case 2:
t = Type::tint16;
break;
case 3:
case 4:
t = Type::tint32;
break;
case 5:
case 6:
case 7:
case 8:
t = Type::tint64;
break;
default:
assert(0);
}
}
return t;
}
TypeTuple *TypeStruct::toArgTypes()
{
//printf("TypeStruct::toArgTypes() %s\n", toChars());
if (!sym->isPOD())
{
Lmemory:
//printf("\ttoArgTypes() %s => [ ]\n", toChars());
return new TypeTuple(); // pass on the stack
}
Type *t1 = NULL;
Type *t2 = NULL;
d_uns64 sz = size(0);
assert(sz < 0xFFFFFFFF);
switch ((unsigned)sz)
{
case 1:
return new TypeTuple(Type::tint8);
t1 = Type::tint8;
break;
case 2:
return new TypeTuple(Type::tint16);
t1 = Type::tint16;
break;
case 4:
return new TypeTuple(Type::tint32);
t1 = Type::tint32;
break;
case 8:
return new TypeTuple(Type::tint64);
t1 = Type::tint64;
break;
case 16:
t1 = NULL; // could be a TypeVector
break;
default:
goto Lmemory;
}
return new TypeTuple(); // pass on the stack
if (global.params.is64bit && sym->fields.dim)
{
#if 1
unsigned sz1 = 0;
unsigned sz2 = 0;
t1 = NULL;
for (size_t i = 0; i < sym->fields.dim; i++)
{ VarDeclaration *f = sym->fields[i];
//printf("f->type = %s\n", f->type->toChars());
TypeTuple *tup = f->type->toArgTypes();
if (!tup)
goto Lmemory;
size_t dim = tup->arguments->dim;
Type *ft1 = NULL;
Type *ft2 = NULL;
switch (dim)
{
case 2:
ft1 = (*tup->arguments)[0]->type;
ft2 = (*tup->arguments)[1]->type;
break;
case 1:
if (f->offset < 8)
ft1 = (*tup->arguments)[0]->type;
else
ft2 = (*tup->arguments)[0]->type;
break;
default:
goto Lmemory;
}
if (f->offset & 7)
{
// Misaligned fields goto Lmemory
unsigned alignsz = f->type->alignsize();
if (f->offset & (alignsz - 1))
goto Lmemory;
// Fields that overlap the 8byte boundary goto Lmemory
unsigned fieldsz = f->type->size(0);
if (f->offset < 8 && (f->offset + fieldsz) > 8)
goto Lmemory;
}
// First field in 8byte must be at start of 8byte
assert(t1 || f->offset == 0);
if (ft1)
{
t1 = argtypemerge(t1, ft1, f->offset);
if (!t1)
goto Lmemory;
}
if (ft2)
{
unsigned off2 = f->offset;
if (ft1)
off2 = 8;
assert(t2 || off2 == 8);
t2 = argtypemerge(t2, ft2, off2 - 8);
if (!t2)
goto Lmemory;
}
}
if (t2)
{
if (t1->isfloating() && t2->isfloating())
{
if (t1->ty == Tfloat64 && t2->ty == Tfloat64)
;
else
goto Lmemory;
}
else if (t1->isfloating())
goto Lmemory;
else if (t2->isfloating())
goto Lmemory;
else
;
}
#else
if (sym->fields.dim == 1)
{ VarDeclaration *f = sym->fields[0];
//printf("f->type = %s\n", f->type->toChars());
TypeTuple *tup = f->type->toArgTypes();
if (tup)
{
size_t dim = tup->arguments->dim;
if (dim == 1)
t1 = (*tup->arguments)[0]->type;
}
}
#endif
}
//printf("\ttoArgTypes() %s => [%s,%s]\n", toChars(), t1 ? t1->toChars() : "", t2 ? t2->toChars() : "");
TypeTuple *t;
if (t1)
{
//if (t1) printf("test1: %s => %s\n", toChars(), t1->toChars());
if (t2)
t = new TypeTuple(t1, t2);
else
t = new TypeTuple(t1);
}
else
goto Lmemory;
return t;
}
TypeTuple *TypeEnum::toArgTypes()
+20 -4
View File
@@ -1,5 +1,5 @@
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -142,7 +142,6 @@ Expression *BinExp::arrayOp(Scope *sc)
buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco);
#endif
size_t namelen = buf.offset;
buf.writeByte(0);
char *name = buf.toChars();
Identifier *ident = Lexer::idPool(name);
@@ -349,7 +348,7 @@ Expression *BinExp::arrayOp(Scope *sc)
Initializer *init = new ExpInitializer(0, new IntegerExp(0, 0, Type::tsize_t));
Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init);
Statement *s1 = new ForStatement(0,
new DeclarationStatement(0, d),
new ExpStatement(0, d),
new CmpExp(TOKlt, 0, new IdentifierExp(0, Id::p), new ArrayLengthExp(0, new IdentifierExp(0, p->ident))),
new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id::p)),
new ExpStatement(0, loopbody));
@@ -357,7 +356,7 @@ Expression *BinExp::arrayOp(Scope *sc)
// foreach (i; 0 .. p.length)
Statement *s1 = new ForeachRangeStatement(0, TOKforeach,
new Parameter(0, NULL, Id::p, NULL),
new IntegerExp(0, 0, Type::tint32),
new IntegerExp(0, 0, Type::tsize_t),
new ArrayLengthExp(0, new IdentifierExp(0, p->ident)),
new ExpStatement(0, loopbody));
#endif
@@ -413,6 +412,23 @@ Expression *BinExp::arrayOp(Scope *sc)
return e;
}
Expression *BinAssignExp::arrayOp(Scope *sc)
{
//printf("BinAssignExp::arrayOp() %s\n", toChars());
/* Check that the elements of e1 can be assigned to
*/
Type *tn = e1->type->toBasetype()->nextOf();
if (tn && (!tn->isMutable() || !tn->isAssignable()))
{
error("slice %s is not mutable", e1->toChars());
return new ErrorExp();
}
return BinExp::arrayOp(sc);
}
/******************************************
* Construct the identifier for the array operation function,
* and build the argument list to pass to it.
+53 -26
View File
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h> // memcpy()
#include "rmem.h"
@@ -37,7 +38,7 @@
extern void obj_includelib(const char *name);
#if IN_DMD
void obj_startaddress(Symbol *s);
bool obj_startaddress(Symbol *s);
#endif
@@ -90,7 +91,7 @@ int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
void AttribDeclaration::setScopeNewSc(Scope *sc,
StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
unsigned structalign)
structalign_t structalign)
{
if (decl)
{
@@ -125,7 +126,7 @@ void AttribDeclaration::setScopeNewSc(Scope *sc,
void AttribDeclaration::semanticNewSc(Scope *sc,
StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
unsigned structalign)
structalign_t structalign)
{
if (decl)
{
@@ -760,7 +761,10 @@ void AlignDeclaration::semantic(Scope *sc)
void AlignDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->printf("align (%d)", salign);
if (salign == STRUCTALIGN_DEFAULT)
buf->printf("align");
else
buf->printf("align (%d)", salign);
AttribDeclaration::toCBuffer(buf, hgs);
}
@@ -938,7 +942,7 @@ void PragmaDeclaration::setScope(Scope *sc)
{
Expression *e = (*args)[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
(*args)[0] = e;
StringExp* se = e->toString();
if (!se)
@@ -977,8 +981,8 @@ void PragmaDeclaration::semantic(Scope *sc)
Expression *e = (*args)[i];
e = e->semantic(sc);
if (e->op != TOKerror)
e = e->optimize(WANTvalue | WANTinterpret);
if (e->op != TOKerror && e->op != TOKtype)
e = e->ctfeInterpret();
if (e->op == TOKerror)
{ errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
return;
@@ -1004,7 +1008,7 @@ void PragmaDeclaration::semantic(Scope *sc)
Expression *e = (*args)[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
(*args)[0] = e;
if (e->op == TOKerror)
goto Lnodecl;
@@ -1022,7 +1026,7 @@ void PragmaDeclaration::semantic(Scope *sc)
}
goto Lnodecl;
}
#if IN_GCC
#ifdef IN_GCC
else if (ident == Id::GNU_asm)
{
if (! args || args->dim != 2)
@@ -1046,7 +1050,7 @@ void PragmaDeclaration::semantic(Scope *sc)
e = (*args)[1];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
e = e->toString();
if (e && ((StringExp *)e)->sz == 1)
s = ((StringExp *)e);
@@ -1068,7 +1072,7 @@ void PragmaDeclaration::semantic(Scope *sc)
{
Expression *e = (*args)[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
(*args)[0] = e;
Dsymbol *sa = getDsymbol(e);
if (!sa || !sa->isFuncDeclaration())
@@ -1105,7 +1109,7 @@ void PragmaDeclaration::semantic(Scope *sc)
unsigned errors_save = global.errors;
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
if (i == 0)
printf(" (");
else
@@ -1175,21 +1179,19 @@ void PragmaDeclaration::toObjFile(int multiobj)
char *name = (char *)mem.malloc(se->len + 1);
memcpy(name, se->string, se->len);
name[se->len] = 0;
#if OMFOBJ
/* The OMF format allows library names to be inserted
* into the object file. The linker will then automatically
/* Embed the library names into the object file.
* The linker will then automatically
* search that library, too.
*/
obj_includelib(name);
#elif ELFOBJ || MACHOBJ
/* The format does not allow embedded library names,
* so instead append the library name to the list to be passed
* to the linker.
*/
global.params.libfiles->push(name);
#else
error("pragma lib not supported");
#endif
if (!obj_includelib(name))
{
/* The format does not allow embedded library names,
* so instead append the library name to the list to be passed
* to the linker.
*/
global.params.libfiles->push(name);
}
}
#if DMDV2
else if (ident == Id::startaddress)
@@ -1406,6 +1408,31 @@ Dsymbol *StaticIfDeclaration::syntaxCopy(Dsymbol *s)
return dd;
}
Dsymbols *StaticIfDeclaration::include(Scope *sc, ScopeDsymbol *sd)
{
//printf("StaticIfDeclaration::include(sc = %p) scope = %p\n", sc, scope);
if (condition->inc == 0)
{
Dsymbols *d = ConditionalDeclaration::include(sc, sd);
// Set the scopes lazily.
if (scope && d)
{
for (size_t i = 0; i < d->dim; i++)
{
Dsymbol *s = (*d)[i];
s->setScope(sc);
}
}
return d;
}
else
{
return ConditionalDeclaration::include(sc, sd);
}
}
int StaticIfDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
@@ -1512,7 +1539,7 @@ void CompileDeclaration::compileIt(Scope *sc)
//printf("CompileDeclaration::compileIt(loc = %d) %s\n", loc.linnum, exp->toChars());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->optimize(WANTvalue | WANTinterpret);
exp = exp->ctfeInterpret();
StringExp *se = exp->toString();
if (!se)
{ exp->error("argument to mixin must be a string, not (%s)", exp->toChars());
+4 -3
View File
@@ -37,10 +37,10 @@ struct AttribDeclaration : Dsymbol
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void setScopeNewSc(Scope *sc,
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
unsigned structalign);
structalign_t structalign);
void semanticNewSc(Scope *sc,
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
unsigned structalign);
structalign_t structalign);
void semantic(Scope *sc);
void semantic2(Scope *sc);
void semantic3(Scope *sc);
@@ -122,7 +122,7 @@ struct AlignDeclaration : AttribDeclaration
struct AnonDeclaration : AttribDeclaration
{
bool isunion;
unsigned alignment;
structalign_t alignment;
int sem; // 1 if successful semantic()
AnonDeclaration(Loc loc, int isunion, Dsymbols *decl);
@@ -178,6 +178,7 @@ struct StaticIfDeclaration : ConditionalDeclaration
StaticIfDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
Dsymbol *syntaxCopy(Dsymbol *s);
Dsymbols *include(Scope *sc, ScopeDsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void semantic(Scope *sc);
void importAll(Scope *sc);
+5 -5
View File
@@ -10,9 +10,9 @@
#include <stdio.h>
#include <assert.h>
#include <string.h> // strcmp()
#include <math.h>
#include "mars.h"
#include "declaration.h"
#include "attrib.h"
@@ -44,10 +44,10 @@ enum BUILTIN FuncDeclaration::isBuiltin()
{
static const char FeZe [] = "FNaNbNfeZe"; // @safe pure nothrow real function(real)
static const char FeZe2[] = "FNaNbNeeZe"; // @trusted pure nothrow real function(real)
static const char FuintZint[] = "FNaNbkZi"; // pure nothrow int function(uint)
static const char FuintZuint[] = "FNaNbkZk"; // pure nothrow uint function(uint)
static const char FuintZint[] = "FNaNbNfkZi"; // @safe pure nothrow int function(uint)
static const char FuintZuint[] = "FNaNbNfkZk"; // @safe pure nothrow uint function(uint)
static const char FulongZulong[] = "FNaNbkZk"; // pure nothrow int function(ulong)
static const char FulongZint[] = "FNaNbmZi"; // pure nothrow int function(uint)
static const char FulongZint[] = "FNaNbNfmZi"; // @safe pure nothrow int function(uint)
static const char FrealrealZreal [] = "FNaNbNfeeZe"; // @safe pure nothrow real function(real, real)
static const char FrealZlong [] = "FNaNbNfeZl"; // @safe pure nothrow long function(real)
@@ -167,7 +167,7 @@ uinteger_t eval_bswap(Expression *arg0)
Expression *eval_builtin(Loc loc, enum BUILTIN builtin, Expressions *arguments)
{
assert(arguments && arguments->dim);
Expression *arg0 = arguments->tdata()[0];
Expression *arg0 = (*arguments)[0];
Expression *e = NULL;
switch (builtin)
{
+4 -3
View File
@@ -42,6 +42,7 @@ struct CanThrow
int Expression::canThrow(bool mustNotThrow)
{
//printf("Expression::canThrow(%d) %s\n", mustNotThrow, toChars());
CanThrow ct;
ct.can = FALSE;
ct.mustnot = mustNotThrow;
@@ -132,7 +133,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
{
for (size_t i = 0; i < decl->dim; i++)
{
s = decl->tdata()[i];
s = (*decl)[i];
if (Dsymbol_canThrow(s, mustNotThrow))
return 1;
}
@@ -165,7 +166,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
{
for (size_t i = 0; i < tm->members->dim; i++)
{
Dsymbol *sm = tm->members->tdata()[i];
Dsymbol *sm = (*tm->members)[i];
if (Dsymbol_canThrow(sm, mustNotThrow))
return 1;
}
@@ -174,7 +175,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
else if ((td = s->isTupleDeclaration()) != NULL)
{
for (size_t i = 0; i < td->objects->dim; i++)
{ Object *o = td->objects->tdata()[i];
{ Object *o = (*td->objects)[i];
if (o->dyncast() == DYNCAST_EXPRESSION)
{ Expression *eo = (Expression *)o;
if (eo->op == TOKdsymbol)
+108 -32
View File
@@ -1,5 +1,5 @@
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -9,6 +9,7 @@
#include <stdio.h>
#include <assert.h>
#include <string.h> // mem{set|cpy}()
#include "rmem.h"
@@ -36,9 +37,10 @@ Expression *Expression::implicitCastTo(Scope *sc, Type *t)
MATCH match = implicitConvTo(t);
if (match)
{ TY tyfrom = type->toBasetype()->ty;
TY tyto = t->toBasetype()->ty;
{
#if DMDV1
TY tyfrom = type->toBasetype()->ty;
TY tyto = t->toBasetype()->ty;
if (global.params.warnings &&
Type::impcnvWarn[tyfrom][tyto] &&
op != TOKint64)
@@ -138,7 +140,7 @@ Expression *ErrorExp::implicitCastTo(Scope *sc, Type *t)
Expression *FuncExp::implicitCastTo(Scope *sc, Type *t)
{
//printf("FuncExp::implicitCastTo type = %p %s, t = %s\n", type, type ? type->toChars() : NULL, t->toChars());
return inferType(t);
return inferType(t)->Expression::implicitCastTo(sc, t);
}
/*******************************************
@@ -215,6 +217,7 @@ MATCH IntegerExp::implicitConvTo(Type *t)
TY ty = type->toBasetype()->ty;
TY toty = t->toBasetype()->ty;
TY oldty = ty;
if (m == MATCHnomatch && t->ty == Tenum)
goto Lno;
@@ -282,6 +285,8 @@ MATCH IntegerExp::implicitConvTo(Type *t)
goto Lyes;
case Tchar:
if ((oldty == Twchar || oldty == Tdchar) && value > 0x7F)
goto Lno;
case Tuns8:
//printf("value = %llu %llu\n", (dinteger_t)(unsigned char)value, value);
if ((unsigned char)value != value)
@@ -293,6 +298,9 @@ MATCH IntegerExp::implicitConvTo(Type *t)
goto Lno;
goto Lyes;
case Twchar:
if (oldty == Tdchar && value > 0xD7FF && value < 0xE000)
goto Lno;
case Tuns16:
if ((unsigned short)value != value)
goto Lno;
@@ -319,11 +327,6 @@ MATCH IntegerExp::implicitConvTo(Type *t)
goto Lno;
goto Lyes;
case Twchar:
if ((unsigned short)value != value)
goto Lno;
goto Lyes;
case Tfloat32:
{
volatile float f;
@@ -540,19 +543,28 @@ MATCH ArrayLiteralExp::implicitConvTo(Type *t)
if ((tb->ty == Tarray || tb->ty == Tsarray) &&
(typeb->ty == Tarray || typeb->ty == Tsarray))
{
Type *typen = typeb->nextOf()->toBasetype();
if (tb->ty == Tsarray)
{ TypeSArray *tsa = (TypeSArray *)tb;
if (elements->dim != tsa->dim->toInteger())
result = MATCHnomatch;
}
for (size_t i = 0; i < elements->dim; i++)
{ Expression *e = (*elements)[i];
MATCH m = (MATCH)e->implicitConvTo(tb->nextOf());
if (m < result)
result = m; // remember worst match
if (result == MATCHnomatch)
break; // no need to check for worse
Type *telement = tb->nextOf();
if (!elements->dim)
{ if (typen->ty != Tvoid)
result = typen->implicitConvTo(telement);
}
else
{ for (size_t i = 0; i < elements->dim; i++)
{ Expression *e = (*elements)[i];
if (result == MATCHnomatch)
break; // no need to check for worse
MATCH m = (MATCH)e->implicitConvTo(telement);
if (m < result)
result = m; // remember worst match
}
}
if (!result)
@@ -560,25 +572,46 @@ MATCH ArrayLiteralExp::implicitConvTo(Type *t)
return result;
}
else if (tb->ty == Tvector &&
(typeb->ty == Tarray || typeb->ty == Tsarray))
{
// Convert array literal to vector type
TypeVector *tv = (TypeVector *)tb;
TypeSArray *tbase = (TypeSArray *)tv->basetype;
assert(tbase->ty == Tsarray);
if (elements->dim != tbase->dim->toInteger())
return MATCHnomatch;
Type *telement = tv->elementType();
for (size_t i = 0; i < elements->dim; i++)
{ Expression *e = (*elements)[i];
MATCH m = (MATCH)e->implicitConvTo(telement);
if (m < result)
result = m; // remember worst match
if (result == MATCHnomatch)
break; // no need to check for worse
}
return result;
}
else
return Expression::implicitConvTo(t);
}
MATCH AssocArrayLiteralExp::implicitConvTo(Type *t)
{ MATCH result = MATCHexact;
{
Type *typeb = type->toBasetype();
Type *tb = t->toBasetype();
if (tb->ty == Taarray && typeb->ty == Taarray)
{
MATCH result = MATCHexact;
for (size_t i = 0; i < keys->dim; i++)
{ Expression *e = keys->tdata()[i];
{ Expression *e = (*keys)[i];
MATCH m = (MATCH)e->implicitConvTo(((TypeAArray *)tb)->index);
if (m < result)
result = m; // remember worst match
if (result == MATCHnomatch)
break; // no need to check for worse
e = values->tdata()[i];
e = (*values)[i];
m = (MATCH)e->implicitConvTo(tb->nextOf());
if (m < result)
result = m; // remember worst match
@@ -905,6 +938,9 @@ Expression *Expression::castTo(Scope *sc, Type *t)
}
else if (tb->ty == Tvector && typeb->ty != Tvector)
{
//printf("test1 e = %s, e->type = %s, tb = %s\n", e->toChars(), e->type->toChars(), tb->toChars());
TypeVector *tv = (TypeVector *)tb;
e = new CastExp(loc, e, tv->elementType());
e = new VectorExp(loc, e, tb);
e = e->semantic(sc);
return e;
@@ -1372,9 +1408,9 @@ Expression *TupleExp::castTo(Scope *sc, Type *t)
{ TupleExp *e = (TupleExp *)copy();
e->exps = (Expressions *)exps->copy();
for (size_t i = 0; i < e->exps->dim; i++)
{ Expression *ex = e->exps->tdata()[i];
{ Expression *ex = (*e->exps)[i];
ex = ex->castTo(sc, t);
e->exps->tdata()[i] = ex;
(*e->exps)[i] = ex;
}
return e;
}
@@ -1420,6 +1456,28 @@ Expression *ArrayLiteralExp::castTo(Scope *sc, Type *t)
e->type = tp;
}
}
else if (tb->ty == Tvector &&
(typeb->ty == Tarray || typeb->ty == Tsarray))
{
// Convert array literal to vector type
TypeVector *tv = (TypeVector *)tb;
TypeSArray *tbase = (TypeSArray *)tv->basetype;
assert(tbase->ty == Tsarray);
if (elements->dim != tbase->dim->toInteger())
goto L1;
e = (ArrayLiteralExp *)copy();
e->elements = (Expressions *)elements->copy();
Type *telement = tv->elementType();
for (size_t i = 0; i < elements->dim; i++)
{ Expression *ex = (*elements)[i];
ex = ex->castTo(sc, telement);
(*e->elements)[i] = ex;
}
Expression *ev = new VectorExp(loc, e, tb);
ev = ev->semantic(sc);
return ev;
}
L1:
return e->Expression::castTo(sc, t);
}
@@ -1439,13 +1497,13 @@ Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t)
e->values = (Expressions *)values->copy();
assert(keys->dim == values->dim);
for (size_t i = 0; i < keys->dim; i++)
{ Expression *ex = values->tdata()[i];
{ Expression *ex = (*values)[i];
ex = ex->castTo(sc, tb->nextOf());
e->values->tdata()[i] = ex;
(*e->values)[i] = ex;
ex = keys->tdata()[i];
ex = (*keys)[i];
ex = ex->castTo(sc, ((TypeAArray *)tb)->index);
e->keys->tdata()[i] = ex;
(*e->keys)[i] = ex;
}
e->type = t;
return e;
@@ -1688,7 +1746,7 @@ Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams)
{
if (to->ty == Tdelegate ||
to->ty == Tpointer && to->nextOf()->ty == Tfunction)
{ treq = to;
{ fd->treq = to;
}
return this;
}
@@ -1714,6 +1772,8 @@ Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams)
{
TypeFunction *tfv = (TypeFunction *)t;
TypeFunction *tfl = (TypeFunction *)fd->type;
//printf("\ttfv = %s\n", tfv->toChars());
//printf("\ttfl = %s\n", tfl->toChars());
size_t dim = Parameter::dim(tfl->parameters);
if (Parameter::dim(tfv->parameters) == dim &&
@@ -1740,6 +1800,13 @@ Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams)
}
}
// Set target of return type inference
assert(td->onemember);
FuncLiteralDeclaration *fld = td->onemember->isFuncLiteralDeclaration();
assert(fld);
if (!fld->type->nextOf() && tfv->next)
fld->treq = tfv;
TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
e = (new ScopeExp(loc, ti))->semantic(td->scope);
if (e->op == TOKfunction)
@@ -1759,14 +1826,12 @@ Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams)
to->ty == Tdelegate)
{
Type *typen = type->nextOf();
assert(typen->deco);
//if (typen->covariant(to->nextOf()) == 1)
if (typen->deco)
{
FuncExp *fe = (FuncExp *)copy();
fe->tok = TOKdelegate;
fe->type = (new TypeDelegate(typen))->merge();
e = fe;
//e = fe->Expression::implicitCastTo(sc, to);
}
}
else
@@ -1879,7 +1944,7 @@ bool isVoidArrayLiteral(Expression *e, Type *other)
while (e->op == TOKarrayliteral && e->type->ty == Tarray
&& (((ArrayLiteralExp *)e)->elements->dim == 1))
{
e = ((ArrayLiteralExp *)e)->elements->tdata()[0];
e = (*((ArrayLiteralExp *)e)->elements)[0];
if (other->ty == Tsarray || other->ty == Tarray)
other = other->nextOf();
else
@@ -1910,6 +1975,7 @@ int typeMerge(Scope *sc, Expression *e, Type **pt, Expression **pe1, Expression
//printf("typeMerge() %s op %s\n", (*pe1)->toChars(), (*pe2)->toChars());
//e->dump(0);
MATCH m;
Expression *e1 = *pe1;
Expression *e2 = *pe2;
@@ -2110,10 +2176,20 @@ Lagain:
*/
goto Lx2;
}
else if ((t1->ty == Tsarray || t1->ty == Tarray) && t1->implicitConvTo(t2))
else if ((t1->ty == Tsarray || t1->ty == Tarray) &&
(m = t1->implicitConvTo(t2)) != MATCHnomatch)
{
if (t1->ty == Tsarray && e2->op == TOKarrayliteral)
goto Lt1;
if (m == MATCHconst &&
(e->op == TOKaddass || e->op == TOKminass || e->op == TOKmulass ||
e->op == TOKdivass || e->op == TOKmodass || e->op == TOKpowass ||
e->op == TOKandass || e->op == TOKorass || e->op == TOKxorass)
)
{ // Don't make the lvalue const
t = t2;
goto Lret;
}
goto Lt2;
}
else if ((t2->ty == Tsarray || t2->ty == Tarray) && t2->implicitConvTo(t1))
+64 -47
View File
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h> // mem{cpy|set}()
#include "root.h"
#include "rmem.h"
@@ -177,6 +178,12 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
Type::typeinfowild->error("%s", msg);
Type::typeinfowild = this;
}
if (id == Id::TypeInfo_Vector)
{ if (Type::typeinfovector)
Type::typeinfovector->error("%s", msg);
Type::typeinfovector = this;
}
#endif
}
@@ -241,9 +248,9 @@ Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s)
cd->baseclasses->setDim(this->baseclasses->dim);
for (size_t i = 0; i < cd->baseclasses->dim; i++)
{
BaseClass *b = this->baseclasses->tdata()[i];
BaseClass *b = (*this->baseclasses)[i];
BaseClass *b2 = new BaseClass(b->type->syntaxCopy(), b->protection);
cd->baseclasses->tdata()[i] = b2;
(*cd->baseclasses)[i] = b2;
}
ScopeDsymbol::syntaxCopy(cd);
@@ -292,10 +299,6 @@ void ClassDeclaration::semantic(Scope *sc)
scope = NULL;
}
unsigned dprogress_save = Module::dprogress;
#ifdef IN_GCC
methods.setDim(0);
#endif
int errors = global.gaggedErrors;
if (sc->stc & STCdeprecated)
@@ -308,7 +311,7 @@ void ClassDeclaration::semantic(Scope *sc)
// Expand any tuples in baseclasses[]
for (size_t i = 0; i < baseclasses->dim; )
{ BaseClass *b = baseclasses->tdata()[i];
{ BaseClass *b = (*baseclasses)[i];
b->type = b->type->semantic(loc, sc);
Type *tb = b->type->toBasetype();
@@ -333,7 +336,7 @@ void ClassDeclaration::semantic(Scope *sc)
BaseClass *b;
Type *tb;
b = baseclasses->tdata()[0];
b = (*baseclasses)[0];
//b->type = b->type->semantic(loc, sc);
tb = b->type->toBasetype();
if (tb->ty != Tclass)
@@ -403,7 +406,7 @@ void ClassDeclaration::semantic(Scope *sc)
BaseClass *b;
Type *tb;
b = baseclasses->tdata()[i];
b = (*baseclasses)[i];
b->type = b->type->semantic(loc, sc);
tb = b->type->toBasetype();
if (tb->ty == Tclass)
@@ -432,7 +435,7 @@ void ClassDeclaration::semantic(Scope *sc)
// Check for duplicate interfaces
for (size_t j = (baseClass ? 1 : 0); j < i; j++)
{
BaseClass *b2 = baseclasses->tdata()[j];
BaseClass *b2 = (*baseclasses)[j];
if (b2->base == tc->sym)
error("inherits from duplicate interface %s", b2->base->toChars());
}
@@ -464,22 +467,20 @@ void ClassDeclaration::semantic(Scope *sc)
// If no base class, and this is not an Object, use Object as base class
if (!baseClass && ident != Id::Object)
{
// BUG: what if Object is redefined in an inner scope?
Type *tbase = new TypeIdentifier(0, Id::Object);
BaseClass *b;
TypeClass *tc;
Type *bt;
if (!object)
{
error("missing or corrupt object.d");
fatal();
}
bt = tbase->semantic(loc, sc)->toBasetype();
b = new BaseClass(bt, PROTpublic);
Type *t = object->type;
t = t->semantic(loc, sc)->toBasetype();
assert(t->ty == Tclass);
TypeClass *tc = (TypeClass *)t;
BaseClass *b = new BaseClass(tc, PROTpublic);
baseclasses->shift(b);
assert(b->type->ty == Tclass);
tc = (TypeClass *)(b->type);
baseClass = tc->sym;
assert(!baseClass->isInterfaceDeclaration());
b->base = baseClass;
@@ -535,7 +536,9 @@ void ClassDeclaration::semantic(Scope *sc)
isnested = 1;
if (storage_class & STCstatic)
error("static class cannot inherit from nested class %s", baseClass->toChars());
if (toParent2() != baseClass->toParent2())
if (toParent2() != baseClass->toParent2() &&
(!toParent2() ||
!baseClass->toParent2()->getType()->isBaseOf(toParent2()->getType(), NULL)))
{
if (toParent2())
{
@@ -614,8 +617,7 @@ void ClassDeclaration::semantic(Scope *sc)
}
sc->protection = PROTpublic;
sc->explicitProtection = 0;
sc->structalign = 8;
structalign = sc->structalign;
sc->structalign = STRUCTALIGN_DEFAULT;
if (baseClass)
{ sc->offset = baseClass->structsize;
alignsize = baseClass->alignsize;
@@ -642,9 +644,10 @@ void ClassDeclaration::semantic(Scope *sc)
if (s->isEnumDeclaration() ||
(s->isAggregateDeclaration() && s->ident) ||
s->isTemplateMixin() ||
s->isAttribDeclaration() ||
s->isAliasDeclaration())
{
//printf("setScope %s %s\n", s->kind(), s->toChars());
//printf("[%d] setScope %s %s, sc = %p\n", i, s->kind(), s->toChars(), sc);
s->setScope(sc);
}
}
@@ -682,7 +685,7 @@ void ClassDeclaration::semantic(Scope *sc)
fields.setDim(0);
structsize = 0;
alignsize = 0;
structalign = 0;
// structalign = 0;
sc = sc->pop();
@@ -757,7 +760,7 @@ void ClassDeclaration::semantic(Scope *sc)
BaseClass *b = (*vtblInterfaces)[i];
unsigned thissize = PTRSIZE;
alignmember(structalign, thissize, &sc->offset);
alignmember(STRUCTALIGN_DEFAULT, thissize, &sc->offset);
assert(b->offset == 0);
b->offset = sc->offset;
@@ -774,9 +777,12 @@ void ClassDeclaration::semantic(Scope *sc)
}
structsize = sc->offset;
#if IN_LLVM
if (global.params.is64bit)
structsize = (structsize + structalign - 1) & ~(structalign - 1);
if (sc->structalign == STRUCTALIGN_DEFAULT)
structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
else
structsize = (structsize + sc->structalign - 1) & ~(sc->structalign - 1);
#endif
sizeok = SIZEOKdone;
Module::dprogress++;
@@ -788,7 +794,7 @@ void ClassDeclaration::semantic(Scope *sc)
// Fill in base class vtbl[]s
for (i = 0; i < vtblInterfaces->dim; i++)
{
BaseClass *b = vtblInterfaces->tdata()[i];
BaseClass *b = (*vtblInterfaces)[i];
//b->fillVtbl(this, &b->vtbl, 1);
}
@@ -813,7 +819,7 @@ void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
}
for (size_t i = 0; i < baseclasses->dim; i++)
{
BaseClass *b = baseclasses->tdata()[i];
BaseClass *b = (*baseclasses)[i];
if (i)
buf->writeByte(',');
@@ -827,7 +833,7 @@ void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
buf->writestring(" ");
s->toCBuffer(buf, hgs);
@@ -862,7 +868,7 @@ int ClassDeclaration::isBaseOf2(ClassDeclaration *cd)
return 0;
//printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
for (size_t i = 0; i < cd->baseclasses->dim; i++)
{ BaseClass *b = cd->baseclasses->tdata()[i];
{ BaseClass *b = (*cd->baseclasses)[i];
if (b->base == this || isBaseOf2(b->base))
return 1;
@@ -908,7 +914,7 @@ int ClassDeclaration::isBaseInfoComplete()
if (!baseClass)
return ident == Id::Object;
for (size_t i = 0; i < baseclasses->dim; i++)
{ BaseClass *b = baseclasses->tdata()[i];
{ BaseClass *b = (*baseclasses)[i];
if (!b->base || !b->base->isBaseInfoComplete())
return 0;
}
@@ -946,7 +952,7 @@ Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags)
for (size_t i = 0; i < baseclasses->dim; i++)
{
BaseClass *b = baseclasses->tdata()[i];
BaseClass *b = (*baseclasses)[i];
if (b->base)
{
@@ -1011,7 +1017,7 @@ int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
if (os)
{
for (size_t i = 0; i < os->a.dim; i++)
{ Dsymbol *s2 = os->a.tdata()[i];
{ Dsymbol *s2 = os->a[i];
FuncDeclaration *f2 = s2->isFuncDeclaration();
if (f2 && overloadApply(f2, &isf, fd))
return 0;
@@ -1054,9 +1060,11 @@ FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf)
//printf("\t[%d] = %s\n", i, fd->toChars());
if (ident == fd->ident &&
fd->type->covariant(tf) == 1)
{ //printf("fd->parent->isClassDeclaration() = %p", fd->parent->isClassDeclaration());
{ //printf("fd->parent->isClassDeclaration() = %p\n", fd->parent->isClassDeclaration());
if (!fdmatch)
goto Lfd;
if (fd == fdmatch)
goto Lfdmatch;
{
// Function type matcing: exact > covariant
@@ -1068,6 +1076,15 @@ FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf)
goto Lfdmatch;
}
{
int m1 = (tf->mod == fd ->type->mod) ? MATCHexact : MATCHnomatch;
int m2 = (tf->mod == fdmatch->type->mod) ? MATCHexact : MATCHnomatch;
if (m1 > m2)
goto Lfd;
else if (m1 < m2)
goto Lfdmatch;
}
{
// The way of definition: non-mixin > mixin
int m1 = fd ->parent->isClassDeclaration() ? MATCHexact : MATCHnomatch;
@@ -1158,7 +1175,7 @@ int ClassDeclaration::isAbstract()
return TRUE;
for (size_t i = 1; i < vtbl.dim; i++)
{
FuncDeclaration *fd = vtbl.tdata()[i]->isFuncDeclaration();
FuncDeclaration *fd = vtbl[i]->isFuncDeclaration();
//printf("\tvtbl[%d] = %p\n", i, fd);
if (!fd || fd->isAbstract())
@@ -1266,7 +1283,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
// Expand any tuples in baseclasses[]
for (size_t i = 0; i < baseclasses->dim; )
{ BaseClass *b = (*baseclasses)[0];
{ BaseClass *b = (*baseclasses)[i];
b->type = b->type->semantic(loc, sc);
Type *tb = b->type->toBasetype();
@@ -1294,7 +1311,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
BaseClass *b;
Type *tb;
b = baseclasses->tdata()[i];
b = (*baseclasses)[i];
b->type = b->type->semantic(loc, sc);
tb = b->type->toBasetype();
if (tb->ty == Tclass)
@@ -1312,7 +1329,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
// Check for duplicate interfaces
for (size_t j = 0; j < i; j++)
{
BaseClass *b2 = baseclasses->tdata()[j];
BaseClass *b2 = (*baseclasses)[j];
if (b2->base == tc->sym)
error("inherits from duplicate interface %s", b2->base->toChars());
}
@@ -1373,7 +1390,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
{
vtbl.reserve(d - 1);
for (size_t j = 1; j < d; j++)
vtbl.push(b->base->vtbl.tdata()[j]);
vtbl.push(b->base->vtbl[j]);
}
}
else
@@ -1401,10 +1418,10 @@ void InterfaceDeclaration::semantic(Scope *sc)
sc->linkage = LINKwindows;
else if (isCPPinterface())
sc->linkage = LINKcpp;
sc->structalign = 8;
sc->structalign = STRUCTALIGN_DEFAULT;
sc->protection = PROTpublic;
sc->explicitProtection = 0;
structalign = sc->structalign;
// structalign = sc->structalign;
sc->offset = PTRSIZE * 2;
structsize = sc->offset;
inuse++;
@@ -1426,7 +1443,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
s->semantic(sc);
}
@@ -1526,7 +1543,7 @@ int InterfaceDeclaration::isBaseInfoComplete()
{
assert(!baseClass);
for (size_t i = 0; i < baseclasses->dim; i++)
{ BaseClass *b = baseclasses->tdata()[i];
{ BaseClass *b = (*baseclasses)[i];
if (!b->base || !b->base->isBaseInfoComplete ())
return 0;
}
@@ -1610,7 +1627,7 @@ int BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newins
// first entry is ClassInfo reference
for (size_t j = base->vtblOffset(); j < base->vtbl.dim; j++)
{
FuncDeclaration *ifd = base->vtbl.tdata()[j]->isFuncDeclaration();
FuncDeclaration *ifd = base->vtbl[j]->isFuncDeclaration();
FuncDeclaration *fd;
TypeFunction *tf;
@@ -1647,7 +1664,7 @@ int BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newins
fd = NULL;
}
if (vtbl)
vtbl->tdata()[j] = fd;
(*vtbl)[j] = fd;
}
return result;
+16 -16
View File
@@ -45,7 +45,7 @@ int StructDeclaration::needOpAssign()
*/
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields.tdata()[i];
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
if (v->storage_class & STCref)
@@ -153,7 +153,7 @@ FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
//printf("\tmemberwise copy\n");
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields.tdata()[i];
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
// this.v = s.v;
@@ -214,7 +214,7 @@ int StructDeclaration::needOpEquals()
*/
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields.tdata()[i];
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
if (v->storage_class & STCref)
@@ -304,7 +304,7 @@ FuncDeclaration *StructDeclaration::buildOpEquals(Scope *sc)
//printf("\tmemberwise compare\n");
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields.tdata()[i];
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
if (v->storage_class & STCref)
@@ -513,13 +513,13 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields.tdata()[i];
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
dinteger_t dim = (tv->ty == Tsarray ? 1 : 0);
dinteger_t dim = 1;
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
dim *= ((TypeSArray *)tv)->dim->toInteger();
@@ -528,7 +528,7 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->postblit)
if (sd->postblit && dim)
{
stc |= sd->postblit->storage_class & STCdisable;
@@ -542,7 +542,7 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
Expression *ex = new ThisExp(0);
ex = new DotVarExp(0, ex, v, 0);
if (dim == 0)
if (v->type->toBasetype()->ty == Tstruct)
{ // this.v.postblit()
ex = new DotVarExp(0, ex, sd->postblit, 0);
ex = new CallExp(0, ex);
@@ -581,12 +581,12 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
return NULL;
case 1:
return postblits.tdata()[0];
return postblits[0];
default:
e = NULL;
for (size_t i = 0; i < postblits.dim; i++)
{ FuncDeclaration *fd = postblits.tdata()[i];
{ FuncDeclaration *fd = postblits[i];
stc |= fd->storage_class & STCdisable;
if (stc & STCdisable)
{
@@ -625,13 +625,13 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
#if DMDV2
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields.tdata()[i];
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
dinteger_t dim = (tv->ty == Tsarray ? 1 : 0);
dinteger_t dim = 1;
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
dim *= ((TypeSArray *)tv)->dim->toInteger();
@@ -640,14 +640,14 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (sd->dtor)
if (sd->dtor && dim)
{ Expression *ex;
// this.v
ex = new ThisExp(0);
ex = new DotVarExp(0, ex, v, 0);
if (dim == 0)
if (v->type->toBasetype()->ty == Tstruct)
{ // this.v.dtor()
ex = new DotVarExp(0, ex, sd->dtor, 0);
ex = new CallExp(0, ex);
@@ -686,12 +686,12 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
return NULL;
case 1:
return dtors.tdata()[0];
return dtors[0];
default:
e = NULL;
for (size_t i = 0; i < dtors.dim; i++)
{ FuncDeclaration *fd = dtors.tdata()[i];
{ FuncDeclaration *fd = dtors[i];
Expression *ex = new ThisExp(0);
ex = new DotVarExp(0, ex, fd, 0);
ex = new CallExp(0, ex);
+9 -1
View File
@@ -10,6 +10,7 @@
#include <stdio.h>
#include <assert.h>
#include <string.h> // strcmp()
#include "id.h"
#include "init.h"
@@ -266,7 +267,14 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
sc->flags |= SCOPEstaticif;
Expression *e = exp->semantic(sc);
sc->pop();
e = e->optimize(WANTvalue | WANTinterpret);
if (!e->type->checkBoolean())
{
if (e->type->toBasetype() != Type::terror)
exp->error("expression %s of type %s does not have a boolean value", exp->toChars(), e->type->toChars());
inc = 0;
return 0;
}
e = e->ctfeInterpret();
--nest;
if (e->op == TOKerror)
{ exp = e;
+55 -12
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -11,6 +11,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h> // mem{cpy|set|cmp}()
#include <math.h>
#if __DMC__
@@ -621,7 +622,7 @@ Expression *Pow(Type *type, Expression *e1, Expression *e2)
// Special case: call sqrt directly.
Expressions args;
args.setDim(1);
args.tdata()[0] = e1;
args[0] = e1;
e = eval_builtin(loc, BUILTINsqrt, &args);
if (!e)
e = EXP_CANT_INTERPRET;
@@ -1290,7 +1291,7 @@ Expression *Cast(Type *type, Type *to, Expression *e1)
assert(sd);
Expressions *elements = new Expressions;
for (size_t i = 0; i < sd->fields.dim; i++)
{ Dsymbol *s = sd->fields.tdata()[i];
{ Dsymbol *s = sd->fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v);
@@ -1374,7 +1375,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
}
else if (e1->op == TOKarrayliteral)
{ ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
e = ale->elements->tdata()[i];
e = (*ale->elements)[i];
e->type = type;
if (e->hasSideEffect())
e = EXP_CANT_INTERPRET;
@@ -1392,7 +1393,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
e = new ErrorExp();
}
else
{ e = ale->elements->tdata()[i];
{ e = (*ale->elements)[i];
e->type = type;
if (e->hasSideEffect())
e = EXP_CANT_INTERPRET;
@@ -1407,12 +1408,12 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
for (size_t i = ae->keys->dim; i;)
{
i--;
Expression *ekey = ae->keys->tdata()[i];
Expression *ekey = (*ae->keys)[i];
Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2);
if (ex == EXP_CANT_INTERPRET)
return ex;
if (ex->isBool(TRUE))
{ e = ae->values->tdata()[i];
{ e = (*ae->values)[i];
e->type = type;
if (e->hasSideEffect())
e = EXP_CANT_INTERPRET;
@@ -1483,7 +1484,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
elements->setDim(iupr - ilwr);
memcpy(elements->tdata(),
es1->elements->tdata() + ilwr,
(iupr - ilwr) * sizeof(es1->elements->tdata()[0]));
(iupr - ilwr) * sizeof((*es1->elements)[0]));
e = new ArrayLiteralExp(e1->loc, elements);
e->type = type;
}
@@ -1512,7 +1513,7 @@ void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *n
assert(0);
break;
}
existingAE->elements->tdata()[j+firstIndex]
(*existingAE->elements)[j+firstIndex]
= new IntegerExp(newval->loc, val, elemType);
}
}
@@ -1525,7 +1526,7 @@ void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *n
unsigned char *s = (unsigned char *)existingSE->string;
for (size_t j = 0; j < newae->elements->dim; j++)
{
unsigned value = (unsigned)(newae->elements->tdata()[j]->toInteger());
unsigned value = (unsigned)((*newae->elements)[j]->toInteger());
switch (existingSE->sz)
{
case 1: s[j+firstIndex] = value; break;
@@ -1549,6 +1550,48 @@ void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, int f
memcpy(s + firstIndex * sz, newstr->string, sz * newstr->len);
}
/* Compare a string slice with another string slice.
* Conceptually equivalent to memcmp( se1[lo1..lo1+len], se2[lo2..lo2+len])
*/
int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len)
{
unsigned char *s1 = (unsigned char *)se1->string;
unsigned char *s2 = (unsigned char *)se2->string;
size_t sz = se1->sz;
assert(sz == se2->sz);
return memcmp(s1 + sz * lo1, s2 + sz * lo2, sz * len);
}
/* Compare a string slice with an array literal slice
* Conceptually equivalent to memcmp( se1[lo1..lo1+len], ae2[lo2..lo2+len])
*/
int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len)
{
unsigned char *s = (unsigned char *)se1->string;
size_t sz = se1->sz;
int c = 0;
for (size_t j = 0; j < len; j++)
{
unsigned value = (unsigned)((*ae2->elements)[j + lo2]->toInteger());
unsigned svalue;
switch (sz)
{
case 1: svalue = s[j + lo1]; break;
case 2: svalue = ((unsigned short *)s)[j+lo1]; break;
case 4: svalue = ((unsigned *)s)[j + lo1]; break;
default:
assert(0);
}
int c = svalue - value;
if (c)
return c;
}
return 0;
}
/* Also return EXP_CANT_INTERPRET if this fails
*/
Expression *Cat(Type *type, Expression *e1, Expression *e2)
@@ -1666,7 +1709,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
elems->setDim(len);
for (size_t i= 0; i < ea->elements->dim; ++i)
{
elems->tdata()[i] = ea->elements->tdata()[i];
(*elems)[i] = (*ea->elements)[i];
}
ArrayLiteralExp *dest = new ArrayLiteralExp(e1->loc, elems);
dest->type = type;
@@ -1684,7 +1727,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
elems->setDim(len);
for (size_t i= 0; i < ea->elements->dim; ++i)
{
elems->tdata()[es->len + i] = ea->elements->tdata()[i];
(*elems)[es->len + i] = (*ea->elements)[i];
}
ArrayLiteralExp *dest = new ArrayLiteralExp(e1->loc, elems);
dest->type = type;
+6 -5
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2010 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -9,6 +9,7 @@
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "mars.h"
@@ -69,7 +70,7 @@ int CppMangleState::substitute(OutBuffer *buf, void *p)
{
for (size_t i = 0; i < components.dim; i++)
{
if (p == components.tdata()[i])
if (p == components[i])
{
/* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
*/
@@ -88,7 +89,7 @@ int CppMangleState::exist(void *p)
{
for (size_t i = 0; i < components.dim; i++)
{
if (p == components.tdata()[i])
if (p == components[i])
{
return 1;
}
@@ -160,7 +161,7 @@ char *cpp_mangle(Dsymbol *s)
cms.components.setDim(0);
OutBuffer buf;
#if MACHOBJ
#if TARGET_OSX
buf.writestring("__Z");
#else
buf.writestring("_Z");
@@ -417,7 +418,7 @@ void Parameter::argsCppMangle(OutBuffer *buf, CppMangleState *cms, Parameters *a
if (arguments)
{
for (size_t i = 0; i < arguments->dim; i++)
{ Parameter *arg = arguments->tdata()[i];
{ Parameter *arg = (*arguments)[i];
Type *t = arg->type;
if (arg->storageClass & (STCout | STCref))
t = t->referenceTo();
+119 -59
View File
@@ -122,6 +122,18 @@ void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
}
#endif
Dsymbol *Declaration::search(Loc loc, Identifier *ident, int flags)
{
Dsymbol *s = Dsymbol::search(loc, ident, flags);
if (!s && type)
{
s = type->toDsymbol(NULL);
if (s)
s = s->search(loc, ident, flags);
}
return s;
}
/********************************* TupleDeclaration ****************************/
@@ -159,7 +171,7 @@ Type *TupleDeclaration::getType()
/* It's only a type tuple if all the Object's are types
*/
for (size_t i = 0; i < objects->dim; i++)
{ Object *o = objects->tdata()[i];
{ Object *o = (*objects)[i];
if (o->dyncast() != DYNCAST_TYPE)
{
@@ -176,7 +188,7 @@ Type *TupleDeclaration::getType()
OutBuffer buf;
int hasdeco = 1;
for (size_t i = 0; i < types->dim; i++)
{ Type *t = types->tdata()[i];
{ Type *t = (*types)[i];
//printf("type = %s\n", t->toChars());
#if 0
@@ -187,7 +199,7 @@ Type *TupleDeclaration::getType()
#else
Parameter *arg = new Parameter(0, t, NULL, NULL);
#endif
args->tdata()[i] = arg;
(*args)[i] = arg;
if (!t->deco)
hasdeco = 0;
}
@@ -204,7 +216,7 @@ int TupleDeclaration::needThis()
{
//printf("TupleDeclaration::needThis(%s)\n", toChars());
for (size_t i = 0; i < objects->dim; i++)
{ Object *o = objects->tdata()[i];
{ Object *o = (*objects)[i];
if (o->dyncast() == DYNCAST_EXPRESSION)
{ Expression *e = (Expression *)o;
if (e->op == TOKdsymbol)
@@ -336,7 +348,7 @@ void TypedefDeclaration::semantic2(Scope *sc)
{
Initializer *savedinit = init;
int errors = global.errors;
init = init->semantic(sc, basetype, WANTinterpret);
init = init->semantic(sc, basetype, INITinterpret);
if (errors != global.errors)
{
init = savedinit;
@@ -557,6 +569,17 @@ void AliasDeclaration::semantic(Scope *sc)
s->parent = sc->parent;
}
}
OverloadSet *o = s->toAlias()->isOverloadSet();
if (o)
{
if (overnext)
{
o->push(overnext);
overnext = NULL;
s = o;
s->parent = sc->parent;
}
}
if (overnext)
ScopeDsymbol::multiplyDefined(0, this, overnext);
if (s == this)
@@ -619,7 +642,9 @@ const char *AliasDeclaration::kind()
Type *AliasDeclaration::getType()
{
return type;
if (type)
return type;
return toAlias()->getType();
}
Dsymbol *AliasDeclaration::toAlias()
@@ -632,7 +657,9 @@ Dsymbol *AliasDeclaration::toAlias()
aliassym = new AliasDeclaration(loc, ident, Type::terror);
type = Type::terror;
}
else if (!aliassym && scope)
else if (aliassym || type->deco)
; // semantic is already done.
else if (scope)
semantic(scope);
Dsymbol *s = aliassym ? aliassym->toAlias() : this;
return s;
@@ -845,6 +872,14 @@ void VarDeclaration::semantic(Scope *sc)
this->parent = sc->parent;
//printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
protection = sc->protection;
/* If scope's alignment is the default, use the type's alignment,
* otherwise the scope overrrides.
*/
alignment = sc->structalign;
if (alignment == STRUCTALIGN_DEFAULT)
alignment = type->alignment(); // use type's alignment
//printf("sc->stc = %x\n", sc->stc);
//printf("storage_class = x%x\n", storage_class);
@@ -931,7 +966,7 @@ void VarDeclaration::semantic(Scope *sc)
for (size_t pos = 0; pos < iexps->dim; pos++)
{
Lexpand1:
Expression *e = iexps->tdata()[pos];
Expression *e = (*iexps)[pos];
Parameter *arg = Parameter::getNth(tt->arguments, pos);
arg->type = arg->type->semantic(loc, sc);
//printf("[%d] iexps->dim = %d, ", pos, iexps->dim);
@@ -1028,7 +1063,7 @@ Lnomatch:
Expression *einit = ie;
if (ie && ie->op == TOKtuple)
{ einit = ((TupleExp *)ie)->exps->tdata()[i];
{ einit = (*((TupleExp *)ie)->exps)[i];
}
Initializer *ti = init;
if (einit)
@@ -1051,7 +1086,7 @@ Lnomatch:
}
#endif
Expression *e = new DsymbolExp(loc, v);
exps->tdata()[i] = e;
(*exps)[i] = e;
}
TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
v2->isexp = 1;
@@ -1091,7 +1126,7 @@ Lnomatch:
}
else if (storage_class & STCfinal)
{
error("final cannot be applied to variable");
error("final cannot be applied to variable, perhaps you meant const?");
}
if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls | STCgshared | STCctfe))
@@ -1114,7 +1149,6 @@ Lnomatch:
#endif
{
storage_class |= STCfield;
alignment = sc->structalign;
#if DMDV2
if (tb->ty == Tstruct && ((TypeStruct *)tb)->sym->noDefaultCtor ||
tb->ty == Tclass && ((TypeClass *)tb)->sym->noDefaultCtor)
@@ -1244,6 +1278,19 @@ Lnomatch:
init = new ExpInitializer(loc, e);
goto Ldtor;
}
else if (type->ty == Tstruct &&
(((TypeStruct *)type)->sym->isnested))
{
/* Nested struct requires valid enclosing frame pointer.
* In StructLiteralExp::toElem(), it's calculated.
*/
Expression *e = type->defaultInitLiteral(loc);
Expression *e1 = new VarExp(loc, this);
e = new ConstructExp(loc, e1, e);
e = e->semantic(sc);
init = new ExpInitializer(loc, e);
goto Ldtor;
}
else if (type->ty == Ttypedef)
{ TypeTypedef *td = (TypeTypedef *)type;
if (td->sym->init)
@@ -1313,7 +1360,8 @@ Lnomatch:
Expression *e = init->toExpression();
if (!e)
{
init = init->semantic(sc, type, 0); // Don't need to interpret
// Run semantic, but don't need to interpret
init = init->semantic(sc, type, INITnointerpret);
e = init->toExpression();
if (!e)
{ error("is not a static and cannot have static initializer");
@@ -1395,16 +1443,26 @@ Lnomatch:
{
e = new ConstructExp(loc, new VarExp(loc, this), new IntegerExp(loc, 0, Type::tint32));
}
else if (sd->isNested())
{ e = new AssignExp(loc, new VarExp(loc, this), t->defaultInitLiteral(loc));
e->op = TOKblit;
}
else
{ e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc));
e->op = TOKblit;
}
e->type = t;
(*pinit) = new CommaExp(loc, e, (*pinit));
/* Replace __ctmp being constructed with e1
/* Replace __ctmp being constructed with e1.
* We need to copy constructor call expression,
* because it may be used in other place.
*/
dve->e1 = e1;
DotVarExp *dvx = (DotVarExp *)dve->copy();
dvx->e1 = e1;
CallExp *cx = (CallExp *)ce->copy();
cx->e1 = dvx;
(*pinit) = new CommaExp(loc, e, cx);
(*pinit) = (*pinit)->semantic(sc);
goto Ldtor;
}
@@ -1466,7 +1524,7 @@ Lnomatch:
}
else
{
init = init->semantic(sc, type, WANTinterpret);
init = init->semantic(sc, type, INITinterpret);
}
}
else if (storage_class & (STCconst | STCimmutable | STCmanifest) ||
@@ -1537,7 +1595,7 @@ Lnomatch:
}
else if (si || ai)
{ i2 = init->syntaxCopy();
i2 = i2->semantic(sc, type, WANTinterpret);
i2 = i2->semantic(sc, type, INITinterpret);
}
inuse--;
if (global.endGagging(errors)) // if errors happened
@@ -1552,7 +1610,7 @@ Lnomatch:
else if (ei)
{
if (isDataseg() || (storage_class & STCmanifest))
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
else
e = e->optimize(WANTvalue);
switch (e->op)
@@ -1639,7 +1697,7 @@ void VarDeclaration::semantic2(Scope *sc)
printf("type = %p\n", ei->exp->type);
}
#endif
init = init->semantic(sc, type, WANTinterpret);
init = init->semantic(sc, type, INITinterpret);
inuse--;
}
sem = Semantic2Done;
@@ -1710,9 +1768,8 @@ void VarDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset,
unsigned memsize = t->size(loc); // size of member
unsigned memalignsize = t->alignsize(); // size of member for alignment purposes
unsigned memalign = t->memalign(alignment); // alignment boundaries
offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, memalign,
offset = AggregateDeclaration::placeField(poffset, memsize, memalignsize, alignment,
&ad->structsize, &ad->alignsize, isunion);
//printf("\t%s: alignsize = %d\n", toChars(), alignsize);
@@ -1831,28 +1888,8 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
// The current function
FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
if (fdv && fdthis && fdv != fdthis && fdthis->ident != Id::ensure && fdthis->ident != Id::require)
if (fdv && fdthis && fdv != fdthis)
{
/* __ensure is always called directly,
* so it never becomes closure.
*/
//printf("\tfdv = %s\n", fdv->toChars());
//printf("\tfdthis = %s\n", fdthis->toChars());
if (loc.filename)
fdthis->getLevel(loc, sc, fdv);
// Function literals from fdthis to fdv must be delegates
for (Dsymbol *s = fdthis; s && s != fdv; s = s->toParent2())
{
// function literal has reference to enclosing scope is delegate
if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
{
fld->tok = TOKdelegate;
}
}
// Add fdthis to nestedrefs[] if not already there
for (size_t i = 0; 1; i++)
{
@@ -1865,23 +1902,46 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
break;
}
// Add this to fdv->closureVars[] if not already there
for (size_t i = 0; 1; i++)
if (fdthis->ident != Id::ensure)
{
if (i == fdv->closureVars.dim)
{
fdv->closureVars.push(this);
break;
}
if (fdv->closureVars[i] == this)
break;
}
/* __ensure is always called directly,
* so it never becomes closure.
*/
//printf("fdthis is %s\n", fdthis->toChars());
//printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
// __dollar creates problems because it isn't a real variable Bugzilla 3326
if (ident == Id::dollar)
::error(loc, "cannnot use $ inside a function literal");
//printf("\tfdv = %s\n", fdv->toChars());
//printf("\tfdthis = %s\n", fdthis->toChars());
if (loc.filename)
fdthis->getLevel(loc, sc, fdv);
// Function literals from fdthis to fdv must be delegates
for (Dsymbol *s = fdthis; s && s != fdv; s = s->toParent2())
{
// function literal has reference to enclosing scope is delegate
if (FuncLiteralDeclaration *fld = s->isFuncLiteralDeclaration())
{
fld->tok = TOKdelegate;
}
}
// Add this to fdv->closureVars[] if not already there
for (size_t i = 0; 1; i++)
{
if (i == fdv->closureVars.dim)
{
fdv->closureVars.push(this);
break;
}
if (fdv->closureVars[i] == this)
break;
}
//printf("fdthis is %s\n", fdthis->toChars());
//printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
// __dollar creates problems because it isn't a real variable Bugzilla 3326
if (ident == Id::dollar)
::error(loc, "cannnot use $ inside a function literal");
}
}
}
}
@@ -2353,7 +2413,7 @@ TypeInfoAssociativeArrayDeclaration::TypeInfoAssociativeArrayDeclaration(Type *t
TypeInfoVectorDeclaration::TypeInfoVectorDeclaration(Type *tinfo)
: TypeInfoDeclaration(tinfo, 0)
{
if (!Type::typeinfoarray)
if (!Type::typeinfovector)
{
ObjectNotFound(Id::TypeInfo_Vector);
}
+16 -4
View File
@@ -101,6 +101,12 @@ enum PURE;
#define STCdisable 0x2000000000LL // for functions that are not callable
#define STCresult 0x4000000000LL // for result variables passed to out contracts
#define STCnodefaultctor 0x8000000000LL // must be set inside constructor
#define STCtemp 0x10000000000LL // temporary variable introduced by inlining
// and used only in backend process, so it's rvalue
#ifdef BUG6652
#define STCbug6652 0x800000000000LL //
#endif
struct Match
{
@@ -136,7 +142,7 @@ struct Declaration : Dsymbol
enum LINK linkage;
int inuse; // used to detect cycles
#if IN_GCC
#ifdef IN_GCC
Expressions *attributes; // GCC decl/type attributes
#endif
@@ -148,6 +154,8 @@ struct Declaration : Dsymbol
unsigned size(Loc loc);
void checkModify(Loc loc, Scope *sc, Type *t);
Dsymbol *search(Loc loc, Identifier *ident, int flags);
void emitComment(Scope *sc);
void toJsonBuffer(OutBuffer *buf);
void toDocBuffer(OutBuffer *buf);
@@ -288,7 +296,7 @@ struct VarDeclaration : Declaration
#else
int nestedref; // referenced by a lexically nested function
#endif
unsigned short alignment;
structalign_t alignment;
int ctorinit; // it has been initialized in a ctor
int onstack; // 1: it has been allocated on the stack
// 2: on stack, run destructor anyway
@@ -710,7 +718,7 @@ enum BUILTIN
BUILTINbsr, // core.bitop.bsr
BUILTINbsf, // core.bitop.bsf
BUILTINbswap, // core.bitop.bswap
#if IN_GCC
#ifdef IN_GCC
BUILTINgcc, // GCC builtin
#endif
};
@@ -738,12 +746,14 @@ struct FuncDeclaration : Declaration
Identifier *outId; // identifier for out statement
VarDeclaration *vresult; // variable corresponding to outId
LabelDsymbol *returnLabel; // where the return goes
Scope *scout; // out contract scope for vresult->semantic
DsymbolTable *localsymtab; // used to prevent symbols in different
// scopes from having the same name
VarDeclaration *vthis; // 'this' parameter (member and nested)
VarDeclaration *v_arguments; // '_arguments' parameter
#if IN_GCC
#ifdef IN_GCC
VarDeclaration *v_arguments_var; // '_arguments' variable
VarDeclaration *v_argptr; // '_argptr' variable
#endif
VarDeclaration *v_argsave; // save area for args passed in registers for variadic functions
@@ -861,6 +871,7 @@ struct FuncDeclaration : Declaration
void checkNestedReference(Scope *sc, Loc loc);
int needsClosure();
int hasNestedFrameRefs();
void buildResultVar();
Statement *mergeFrequire(Statement *, Expressions *params = 0);
Statement *mergeFensure(Statement *, Expressions *params = 0);
Parameters *getParameters(int *pvarargs);
@@ -941,6 +952,7 @@ struct FuncAliasDeclaration : FuncDeclaration
struct FuncLiteralDeclaration : FuncDeclaration
{
enum TOK tok; // TOKfunction or TOKdelegate
Type *treq; // target of return type inference
FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, enum TOK tok,
ForeachStatement *fes);
+87 -25
View File
@@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="9,00"
Version="9.00"
Name="dmd_msc"
ProjectGUID="{BAE0389D-7D3F-4D5E-AE0E-C871776E8432}"
RootNamespace="dmd"
@@ -768,6 +768,38 @@
<File
RelativePath=".\unialpha.c"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
</File>
<File
RelativePath=".\unittests.c"
@@ -1301,16 +1333,7 @@
>
</File>
<File
RelativePath=".\root\dchar.c"
>
</File>
<File
RelativePath=".\root\dchar.h"
>
</File>
<File
RelativePath=".\root\dmgcmem.c"
>
RelativePath=".\root\dmgcmem.c" >
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
@@ -1361,16 +1384,7 @@
>
</File>
<File
RelativePath=".\root\lstring.c"
>
</File>
<File
RelativePath=".\root\lstring.h"
>
</File>
<File
RelativePath=".\root\man.c"
>
RelativePath=".\root\man.c" >
</File>
<File
RelativePath=".\root\port.c"
@@ -1422,6 +1436,14 @@
<File
RelativePath=".\root\gc\bits.c"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
ExcludedFromBuild="true"
@@ -1430,6 +1452,14 @@
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
ExcludedFromBuild="true"
@@ -1446,6 +1476,14 @@
<File
RelativePath=".\root\gc\gc.c"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
ExcludedFromBuild="true"
@@ -1454,6 +1492,14 @@
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
ExcludedFromBuild="true"
@@ -1518,6 +1564,14 @@
<File
RelativePath=".\root\gc\win32.c"
>
<FileConfiguration
Name="Debug|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Debug|x64"
ExcludedFromBuild="true"
@@ -1526,6 +1580,14 @@
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
/>
</FileConfiguration>
<FileConfiguration
Name="Release|x64"
ExcludedFromBuild="true"
@@ -1645,7 +1707,7 @@
<Tool
Name="VCCustomBuildTool"
Description="Building and running $(IntDir)\$(InputName).exe"
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo$(IntDir)\$(InputName).obj /Fe$(IntDir)\$(InputName).exe $(InputPath)&#x0D;&#x0A;if errorlevel 1 goto VCReportError&#x0D;&#x0A;$(IntDir)\$(InputName).exe&#x0D;&#x0A;"
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo&quot;$(IntDir)\$(InputName).obj&quot; /Fe&quot;$(IntDir)\$(InputName).exe&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;if errorlevel 1 goto VCReportError&#x0D;&#x0A;&quot;$(IntDir)\$(InputName).exe&quot;&#x0D;&#x0A;"
AdditionalDependencies="cc.h;oper.h"
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
/>
@@ -1656,7 +1718,7 @@
<Tool
Name="VCCustomBuildTool"
Description="Building and running $(IntDir)\$(InputName).exe"
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo$(IntDir)\$(InputName).obj /Fe$(IntDir)\$(InputName).exe $(InputPath)&#x0D;&#x0A;if errorlevel 1 goto VCReportError&#x0D;&#x0A;$(IntDir)\$(InputName).exe&#x0D;&#x0A;"
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo&quot;$(IntDir)\$(InputName).obj&quot; /Fe&quot;$(IntDir)\$(InputName).exe&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;if errorlevel 1 goto VCReportError&#x0D;&#x0A;&quot;$(IntDir)\$(InputName).exe&quot;&#x0D;&#x0A;"
AdditionalDependencies="cc.h;oper.h"
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
/>
@@ -1667,7 +1729,7 @@
<Tool
Name="VCCustomBuildTool"
Description="Building and running $(IntDir)\$(InputName).exe"
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo$(IntDir)\$(InputName).obj /Fe$(IntDir)\$(InputName).exe $(InputPath)&#x0D;&#x0A;if errorlevel 1 goto VCReportError&#x0D;&#x0A;$(IntDir)\$(InputName).exe&#x0D;&#x0A;"
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo&quot;$(IntDir)\$(InputName).obj&quot; /Fe&quot;$(IntDir)\$(InputName).exe&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;if errorlevel 1 goto VCReportError&#x0D;&#x0A;&quot;$(IntDir)\$(InputName).exe&quot;"
AdditionalDependencies="cc.h;oper.h"
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
/>
@@ -1678,7 +1740,7 @@
<Tool
Name="VCCustomBuildTool"
Description="Building and running $(IntDir)\$(InputName).exe"
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo$(IntDir)\$(InputName).obj /Fe$(IntDir)\$(InputName).exe $(InputPath)&#x0D;&#x0A;if errorlevel 1 goto VCReportError&#x0D;&#x0A;$(IntDir)\$(InputName).exe&#x0D;&#x0A;"
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo&quot;$(IntDir)\$(InputName).obj&quot; /Fe&quot;$(IntDir)\$(InputName).exe&quot; &quot;$(InputPath)&quot;&#x0D;&#x0A;if errorlevel 1 goto VCReportError&#x0D;&#x0A;&quot;$(IntDir)\$(InputName).exe&quot;&#x0D;&#x0A;"
AdditionalDependencies="cc.h;oper.h"
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
/>
+9 -8
View File
@@ -19,6 +19,10 @@
#include "rmem.h"
#include "root.h"
#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__
#include "gnuc.h"
#endif
#include "mars.h"
#include "dsymbol.h"
#include "macro.h"
@@ -77,7 +81,9 @@ struct DocComment
Macro **pmacrotable;
Escape **pescapetable;
DocComment();
DocComment() :
summary(NULL), copyright(NULL), macros(NULL), pmacrotable(NULL), pescapetable(NULL)
{ }
static DocComment *parse(Scope *sc, Dsymbol *s, unsigned char *comment);
static void parseMacros(Escape **pescapetable, Macro **pmacrotable, unsigned char *m, unsigned mlen);
@@ -227,7 +233,7 @@ void Module::gendocfile()
// Override with the ddoc macro files from the command line
for (size_t i = 0; i < global.params.ddocfiles->dim; i++)
{
FileName f(global.params.ddocfiles->tdata()[i], 0);
FileName f((*global.params.ddocfiles)[i], 0);
File file(&f);
file.readv();
// BUG: convert file contents to UTF-8 before use
@@ -1014,11 +1020,6 @@ void EnumMember::toDocBuffer(OutBuffer *buf)
/********************************* DocComment *********************************/
DocComment::DocComment()
{
memset(this, 0, sizeof(DocComment));
}
DocComment *DocComment::parse(Scope *sc, Dsymbol *s, unsigned char *comment)
{
//printf("parse(%s): '%s'\n", s->toChars(), comment);
@@ -1780,7 +1781,7 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset)
int leadingBlank = 1;
int inCode = 0;
int inComment = 0; // in <!-- ... --> comment
//int inComment = 0; // in <!-- ... --> comment
unsigned iCodeStart; // start of code section
unsigned iLineStart = offset;
+7 -34
View File
@@ -624,7 +624,7 @@ void Dsymbol::error(const char *format, ...)
}
va_list ap;
va_start(ap, format);
verror(loc, format, ap);
verror(loc, format, ap, kind(), toPrettyChars());
va_end(ap);
}
@@ -632,41 +632,10 @@ void Dsymbol::error(Loc loc, const char *format, ...)
{
va_list ap;
va_start(ap, format);
verror(loc, format, ap);
verror(loc, format, ap, kind(), toPrettyChars());
va_end(ap);
}
void Dsymbol::verror(Loc loc, const char *format, va_list ap)
{
if (!global.gag)
{
char *p = loc.toChars();
if (!*p)
p = locToChars();
if (*p)
fprintf(stdmsg, "%s: ", p);
mem.free(p);
fprintf(stdmsg, "Error: ");
fprintf(stdmsg, "%s %s ", kind(), toPrettyChars());
vfprintf(stdmsg, format, ap);
fprintf(stdmsg, "\n");
fflush(stdmsg);
halt();
}
else
{
global.gaggedErrors++;
}
global.errors++;
//fatal();
}
void Dsymbol::checkDeprecated(Loc loc, Scope *sc)
{
if (!global.params.useDeprecated && isDeprecated())
@@ -903,7 +872,8 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
s = s2;
else if (s2 && s != s2)
{
if (s->toAlias() == s2->toAlias())
if (s->toAlias() == s2->toAlias() ||
s->getType() == s2->getType() && s->getType())
{
/* After following aliases, we found the same
* symbol, so it's not an ambiguity. But if one
@@ -1175,6 +1145,8 @@ int ScopeDsymbol::foreach(Scope *sc, Dsymbols *members, ScopeDsymbol::ForeachDg
result = foreach(sc, tm->members, dg, ctx, &n);
else if (s->isTemplateInstance())
;
else if (s->isUnitTestDeclaration())
;
else
result = dg(ctx, n++, s);
@@ -1423,6 +1395,7 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
VoidInitializer *e = new VoidInitializer(0);
e->type = Type::tsize_t;
v->init = e;
v->storage_class |= STCctfe; // it's never a true static variable
}
*pvar = v;
}
+1 -2
View File
@@ -90,7 +90,7 @@ struct TypeInfoDeclaration;
struct ClassInfoDeclaration;
#endif
#if IN_GCC
#ifdef IN_GCC
union tree_node;
typedef union tree_node TYPE;
#else
@@ -158,7 +158,6 @@ struct Dsymbol : Object
int isAnonymous();
void error(Loc loc, const char *format, ...) IS_PRINTF(3);
void error(const char *format, ...) IS_PRINTF(2);
void verror(Loc loc, const char *format, va_list ap);
void checkDeprecated(Loc loc, Scope *sc);
Module *getModule(); // module where declared
Module *getAccessModule();
+2 -2
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -36,7 +36,7 @@ void dumpExpressions(int i, Expressions *exps)
if (exps)
{
for (size_t j = 0; j < exps->dim; j++)
{ Expression *e = exps->tdata()[j];
{ Expression *e = (*exps)[j];
indent(i);
printf("(\n");
e->dump(i + 2);
+10 -10
View File
@@ -185,11 +185,11 @@ void EnumDeclaration::semantic(Scope *sc)
{
assert(e->dyncast() == DYNCAST_EXPRESSION);
e = e->semantic(sce);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
if (memtype)
{
e = e->implicitCastTo(sce, memtype);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
if (!isAnonymous())
e = e->castTo(sce, type);
t = memtype;
@@ -197,7 +197,7 @@ void EnumDeclaration::semantic(Scope *sc)
else if (em->type)
{
e = e->implicitCastTo(sce, em->type);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
assert(isAnonymous());
t = e->type;
}
@@ -214,7 +214,7 @@ void EnumDeclaration::semantic(Scope *sc)
t = Type::tint32;
e = new IntegerExp(em->loc, 0, Type::tint32);
e = e->implicitCastTo(sce, t);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
if (!isAnonymous())
e = e->castTo(sce, type);
}
@@ -225,7 +225,7 @@ void EnumDeclaration::semantic(Scope *sc)
{
emax = t->getProperty(0, Id::max);
emax = emax->semantic(sce);
emax = emax->optimize(WANTvalue | WANTinterpret);
emax = emax->ctfeInterpret();
}
// Set value to (elast + 1).
@@ -233,7 +233,7 @@ void EnumDeclaration::semantic(Scope *sc)
assert(elast);
e = new EqualExp(TOKequal, em->loc, elast, emax);
e = e->semantic(sce);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
if (e->toInteger())
error("overflow of enum value %s", elast->toChars());
@@ -241,14 +241,14 @@ void EnumDeclaration::semantic(Scope *sc)
e = new AddExp(em->loc, elast, new IntegerExp(em->loc, 1, Type::tint32));
e = e->semantic(sce);
e = e->castTo(sce, elast->type);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
if (t->isfloating())
{
// Check that e != elast (not always true for floats)
Expression *etest = new EqualExp(TOKequal, em->loc, e, elast);
etest = etest->semantic(sce);
etest = etest->optimize(WANTvalue | WANTinterpret);
etest = etest->ctfeInterpret();
if (etest->toInteger())
error("enum member %s has inexact value, due to loss of precision", em->toChars());
}
@@ -298,13 +298,13 @@ void EnumDeclaration::semantic(Scope *sc)
// Compute if(e < minval)
ec = new CmpExp(TOKlt, em->loc, e, minval);
ec = ec->semantic(sce);
ec = ec->optimize(WANTvalue | WANTinterpret);
ec = ec->ctfeInterpret();
if (ec->toInteger())
minval = e;
ec = new CmpExp(TOKgt, em->loc, e, maxval);
ec = ec->semantic(sce);
ec = ec->optimize(WANTvalue | WANTinterpret);
ec = ec->ctfeInterpret();
if (ec->toInteger())
maxval = e;
}
+1 -1
View File
@@ -42,7 +42,7 @@ struct EnumDeclaration : ScopeDsymbol
int isdeprecated;
int isdone; // 0: not done
// 1: semantic() successfully completed
#if IN_GCC
#ifdef IN_GCC
Expressions *attributes; // GCC decl/type attributes
#endif
+530 -350
View File
File diff suppressed because it is too large Load Diff
+15 -5
View File
@@ -18,6 +18,7 @@
#include "intrange.h"
struct Type;
struct TypeVector;
struct Scope;
struct TupleDeclaration;
struct VarDeclaration;
@@ -183,6 +184,11 @@ struct Expression : Object
// Same as WANTvalue, but also expand variables as far as possible
#define WANTexpand 8
// Entry point for CTFE.
// A compile-time result is required. Give an error if not possible
Expression *ctfeInterpret();
// Implementation of CTFE for this expression
virtual Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
virtual int isConst();
@@ -432,7 +438,6 @@ struct StringExp : Expression
StringExp(Loc loc, void *s, size_t len, unsigned char postfix);
//Expression *syntaxCopy();
int equals(Object *o);
char *toChars();
Expression *semantic(Scope *sc);
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
size_t length();
@@ -793,7 +798,6 @@ struct FuncExp : Expression
FuncLiteralDeclaration *fd;
TemplateDeclaration *td;
enum TOK tok;
Type *treq;
FuncExp(Loc loc, FuncLiteralDeclaration *fd, TemplateDeclaration *td = NULL);
Expression *syntaxCopy();
@@ -947,10 +951,11 @@ struct BinExp : Expression
Expression *interpretCommon(InterState *istate, CtfeGoal goal,
Expression *(*fp)(Type *, Expression *, Expression *));
Expression *interpretCommon2(InterState *istate, CtfeGoal goal,
Expression *(*fp)(TOK, Type *, Expression *, Expression *));
Expression *(*fp)(Loc, TOK, Type *, Expression *, Expression *));
Expression *interpretAssignCommon(InterState *istate, CtfeGoal goal,
Expression *(*fp)(Type *, Expression *, Expression *), int post = 0);
Expression *arrayOp(Scope *sc);
Expression *interpretFourPointerRelation(InterState *istate, CtfeGoal goal);
virtual Expression *arrayOp(Scope *sc);
Expression *doInline(InlineDoState *ids);
Expression *inlineScan(InlineScanState *iss);
@@ -971,6 +976,7 @@ struct BinAssignExp : BinExp
}
Expression *semantic(Scope *sc);
Expression *arrayOp(Scope *sc);
Expression *op_overload(Scope *sc);
@@ -1330,7 +1336,7 @@ struct CastExp : UnaExp
struct VectorExp : UnaExp
{
Type *to;
TypeVector *to; // the target vector type before semantic()
unsigned dim; // number of elements in the vector
VectorExp(Loc loc, Expression *e, Type *t);
@@ -1339,6 +1345,7 @@ struct VectorExp : UnaExp
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#if IN_DMD
elem *toElem(IRState *irs);
dt_t **toDt(dt_t **pdt);
#endif
#if IN_LLVM
DValue* toElem(IRState* irs);
@@ -2154,5 +2161,8 @@ void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *n
void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, int firstIndex);
void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, int firstIndex);
int sliceCmpStringWithString(StringExp *se1, StringExp *se2, size_t lo1, size_t lo2, size_t len);
int sliceCmpStringWithArray(StringExp *se1, ArrayLiteralExp *ae2, size_t lo1, size_t lo2, size_t len);
#endif /* DMD_EXPRESSION_H */
+309 -280
View File
@@ -51,13 +51,15 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageCla
outId = NULL;
vresult = NULL;
returnLabel = NULL;
scout = NULL;
fensure = NULL;
fbody = NULL;
localsymtab = NULL;
vthis = NULL;
v_arguments = NULL;
#if IN_GCC
#ifdef IN_GCC
v_argptr = NULL;
v_arguments_var = NULL;
#endif
v_argsave = NULL;
parameters = NULL;
@@ -223,11 +225,9 @@ void FuncDeclaration::semantic(Scope *sc)
if (isCtorDeclaration())
sc->flags |= SCOPEctor;
type = type->semantic(loc, sc);
sc = sc->pop();
/* Apply const, immutable and shared storage class
* to the function type
/* Apply const, immutable, wild and shared storage class
* to the function type. Do this before type semantic.
*/
StorageClass stc = storage_class;
if (type->isImmutable())
@@ -250,35 +250,28 @@ void FuncDeclaration::semantic(Scope *sc)
case STCimmutable | STCshared | STCwild:
// Don't use toInvariant(), as that will do a merge()
type = type->makeInvariant();
goto Lmerge;
break;
case STCconst:
case STCconst | STCwild:
type = type->makeConst();
goto Lmerge;
break;
case STCshared | STCconst:
case STCshared | STCconst | STCwild:
type = type->makeSharedConst();
goto Lmerge;
break;
case STCshared:
type = type->makeShared();
goto Lmerge;
break;
case STCwild:
type = type->makeWild();
goto Lmerge;
break;
case STCshared | STCwild:
type = type->makeSharedWild();
goto Lmerge;
Lmerge:
if (!(type->ty == Tfunction && !type->nextOf()))
/* Can't do merge if return type is not known yet
*/
type->deco = type->merge()->deco;
break;
case 0:
@@ -287,7 +280,11 @@ void FuncDeclaration::semantic(Scope *sc)
default:
assert(0);
}
type = type->semantic(loc, sc);
sc = sc->pop();
}
storage_class &= ~STCref;
if (type->ty != Tfunction)
{
@@ -401,18 +398,6 @@ void FuncDeclaration::semantic(Scope *sc)
if (!fbody && (fensure || frequire) && !(id && isVirtual()))
error("in and out contracts require function body");
/* Template member functions aren't virtual:
* interface TestInterface { void tpl(T)(); }
* and so won't work in interfaces
*/
if ((pd = toParent()) != NULL &&
pd->isTemplateInstance() &&
(pd = toParent2()) != NULL &&
(id = pd->isInterfaceDeclaration()) != NULL)
{
error("template member functions are not allowed in interface %s", id->toChars());
}
cd = parent->isClassDeclaration();
if (cd)
{ int vi;
@@ -550,9 +535,6 @@ void FuncDeclaration::semantic(Scope *sc)
break;
else if (!this->parent->isClassDeclaration() // if both are mixins then error
#if !BREAKABI
&& !isDtorDeclaration()
#endif
#if DMDV2
&& !isPostBlitDeclaration()
#endif
@@ -610,7 +592,7 @@ void FuncDeclaration::semantic(Scope *sc)
return;
default:
{ FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.tdata()[vi];
{ FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl[vi];
Type *ti = NULL;
/* Remember which functions this overrides
@@ -920,7 +902,7 @@ void FuncDeclaration::semantic3(Scope *sc)
{
for (int i = 0; i < fthrows->dim; i++)
{
Type *t = fthrows->tdata()[i];
Type *t = (*fthrows)[i];
t = t->semantic(loc, sc);
if (!t->isClassHandle())
@@ -929,11 +911,17 @@ void FuncDeclaration::semantic3(Scope *sc)
}
#endif
if (!fbody && inferRetType && !type->nextOf())
{
error("has no function body with return type inference");
return;
}
if (frequire)
{
for (int i = 0; i < foverrides.dim; i++)
{
FuncDeclaration *fdv = foverrides.tdata()[i];
FuncDeclaration *fdv = foverrides[i];
if (fdv->fbody && !fdv->frequire)
{
@@ -971,7 +959,7 @@ void FuncDeclaration::semantic3(Scope *sc)
STCproperty | STCsafe | STCtrusted | STCsystem);
sc2->protection = PROTpublic;
sc2->explicitProtection = 0;
sc2->structalign = 8;
sc2->structalign = STRUCTALIGN_DEFAULT;
sc2->incontract = 0;
#if !IN_LLVM
sc2->tf = NULL;
@@ -992,9 +980,6 @@ void FuncDeclaration::semantic3(Scope *sc)
}
else
assert(!isNested() || sc->intypeof); // can't be both member and nested
#if IN_GCC
ad->methods.push(this);
#endif
}
vthis = declareThis(sc2, ad);
@@ -1028,7 +1013,6 @@ void FuncDeclaration::semantic3(Scope *sc)
if (f->linkage == LINKd)
{ // Declare _arguments[]
#if BREAKABI
v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
v_arguments->storage_class = STCparameter;
v_arguments->semantic(sc2);
@@ -1041,18 +1025,10 @@ void FuncDeclaration::semantic3(Scope *sc)
_arguments->semantic(sc2);
sc2->insert(_arguments);
_arguments->parent = this;
#else
t = Type::typeinfo->type->arrayOf();
v_arguments = new VarDeclaration(0, t, Id::_arguments, NULL);
v_arguments->storage_class = STCparameter | STCin;
v_arguments->semantic(sc2);
sc2->insert(v_arguments);
v_arguments->parent = this;
#endif
}
if (f->linkage == LINKd || (f->parameters && Parameter::dim(f->parameters)))
{ // Declare _argptr
#if IN_GCC
#ifdef IN_GCC
t = d_gcc_builtin_va_list_d_type;
#else
t = Type::tvoid->pointerTo();
@@ -1094,7 +1070,7 @@ void FuncDeclaration::semantic3(Scope *sc)
if (f->parameters)
{
for (size_t i = 0; i < f->parameters->dim; i++)
{ Parameter *arg = f->parameters->tdata()[i];
{ Parameter *arg = (*f->parameters)[i];
//printf("[%d] arg->type->ty = %d %s\n", i, arg->type->ty, arg->type->toChars());
if (arg->type->ty == Ttuple)
@@ -1158,7 +1134,7 @@ void FuncDeclaration::semantic3(Scope *sc)
if (f->parameters)
{
for (size_t i = 0; i < f->parameters->dim; i++)
{ Parameter *arg = f->parameters->tdata()[i];
{ Parameter *arg = (*f->parameters)[i];
if (!arg->ident)
continue; // never used, so ignore
@@ -1173,7 +1149,7 @@ void FuncDeclaration::semantic3(Scope *sc)
VarDeclaration *v = sc2->search(0, narg->ident, NULL)->isVarDeclaration();
assert(v);
Expression *e = new VarExp(v->loc, v);
exps->tdata()[j] = e;
(*exps)[j] = e;
}
assert(arg->ident);
TupleDeclaration *v = new TupleDeclaration(loc, arg->ident, exps);
@@ -1187,151 +1163,120 @@ void FuncDeclaration::semantic3(Scope *sc)
}
}
/* Do the semantic analysis on the [in] preconditions and
* [out] postconditions.
*/
sc2->incontract++;
// Precondition invariant
Statement *fpreinv = NULL;
if (addPreInvariant())
{
Expression *e = NULL;
if (isDtorDeclaration())
{
// Call invariant directly only if it exists
InvariantDeclaration *inv = ad->inv;
ClassDeclaration *cd = ad->isClassDeclaration();
if (frequire)
{ /* frequire is composed of the [in] contracts
*/
// BUG: need to error if accessing out parameters
// BUG: need to treat parameters as const
// BUG: need to disallow returns and throws
// BUG: verify that all in and ref parameters are read
frequire = frequire->semantic(sc2);
labtab = NULL; // so body can't refer to labels
while (!inv && cd)
{
cd = cd->baseClass;
if (!cd)
break;
inv = cd->inv;
}
if (inv)
{
e = new DsymbolExp(0, inv);
e = new CallExp(0, e);
e = e->semantic(sc2);
}
}
else
{ // Call invariant virtually
#if IN_LLVM
// We actually need a valid 'var' for codegen.
ThisExp* tv = new ThisExp(0);
tv->var = vthis;
Expression *v = tv;
#else
Expression *v = new ThisExp(0);
#endif
v->type = vthis->type;
#if STRUCTTHISREF
if (ad->isStructDeclaration())
v = v->addressOf(sc);
#endif
Expression *se = new StringExp(0, (char *)"null this");
se = se->semantic(sc);
se->type = Type::tchar->arrayOf();
e = new AssertExp(loc, v, se);
}
if (e)
fpreinv = new ExpStatement(0, e);
}
// Postcondition invariant
Statement *fpostinv = NULL;
if (addPostInvariant())
{
Expression *e = NULL;
if (isCtorDeclaration())
{
// Call invariant directly only if it exists
InvariantDeclaration *inv = ad->inv;
ClassDeclaration *cd = ad->isClassDeclaration();
while (!inv && cd)
{
cd = cd->baseClass;
if (!cd)
break;
inv = cd->inv;
}
if (inv)
{
e = new DsymbolExp(0, inv);
e = new CallExp(0, e);
e = e->semantic(sc2);
}
}
else
{ // Call invariant virtually
#if IN_LLVM
// We actually need a valid 'var' for codegen.
ThisExp* tv = new ThisExp(0);
tv->var = vthis;
Expression *v = tv;
#else
Expression *v = new ThisExp(0);
#endif
v->type = vthis->type;
#if STRUCTTHISREF
if (ad->isStructDeclaration())
v = v->addressOf(sc);
#endif
e = new AssertExp(0, v);
}
if (e)
fpostinv = new ExpStatement(0, e);
}
if (fensure || addPostInvariant())
{ /* fensure is composed of the [out] contracts
*/
if (!type->nextOf()) // if return type is inferred
{ /* This case:
* auto fp = function() out { } body { };
* Can fix by doing semantic() onf fbody first.
*/
error("post conditions are not supported if the return type is inferred");
return;
{
if ((fensure && global.params.useOut) || fpostinv)
{ returnLabel = new LabelDsymbol(Id::returnLabel);
}
// scope of out contract (need for vresult->semantic)
ScopeDsymbol *sym = new ScopeDsymbol();
sym->parent = sc2->scopesym;
scout = sc2->push(sym);
}
if (fbody)
{
ScopeDsymbol *sym = new ScopeDsymbol();
sym->parent = sc2->scopesym;
sc2 = sc2->push(sym);
assert(type->nextOf());
if (type->nextOf()->ty == Tvoid)
{
if (outId)
error("void functions have no result");
}
else
{
if (!outId)
outId = Id::result; // provide a default
}
if (outId)
{ // Declare result variable
Loc loc = this->loc;
if (fensure)
loc = fensure->loc;
VarDeclaration *v = new VarDeclaration(loc, type->nextOf(), outId, NULL);
v->noscope = 1;
v->storage_class |= STCresult;
#if DMDV2
if (!isVirtual())
v->storage_class |= STCconst;
if (f->isref)
{
v->storage_class |= STCref | STCforeach;
}
#endif
sc2->incontract--;
v->semantic(sc2);
sc2->incontract++;
if (!sc2->insert(v))
error("out result %s is already defined", v->toChars());
v->parent = this;
vresult = v;
// vresult gets initialized with the function return value
// in ReturnStatement::semantic()
}
// BUG: need to treat parameters as const
// BUG: need to disallow returns and throws
if (fensure)
{ fensure = fensure->semantic(sc2);
labtab = NULL; // so body can't refer to labels
}
if (!global.params.useOut)
{ fensure = NULL; // discard
vresult = NULL;
}
// Postcondition invariant
if (addPostInvariant())
{
Expression *e = NULL;
if (isCtorDeclaration())
{
// Call invariant directly only if it exists
InvariantDeclaration *inv = ad->inv;
ClassDeclaration *cd = ad->isClassDeclaration();
while (!inv && cd)
{
cd = cd->baseClass;
if (!cd)
break;
inv = cd->inv;
}
if (inv)
{
e = new DsymbolExp(0, inv);
e = new CallExp(0, e);
e = e->semantic(sc2);
}
}
else
{ // Call invariant virtually
ThisExp *tv = new ThisExp(0);
tv->type = vthis->type;
tv->var = vthis;
Expression* v = tv;
#if STRUCTTHISREF
if (ad->isStructDeclaration())
v = v->addressOf(sc);
#endif
e = new AssertExp(0, v);
}
if (e)
{
ExpStatement *s = new ExpStatement(0, e);
if (fensure)
fensure = new CompoundStatement(0, s, fensure);
else
fensure = s;
}
}
if (fensure)
{ returnLabel = new LabelDsymbol(Id::returnLabel);
LabelStatement *ls = new LabelStatement(0, Id::returnLabel, fensure);
returnLabel->statement = ls;
}
sc2 = sc2->pop();
}
sc2->incontract--;
if (fbody)
{ AggregateDeclaration *ad = isAggregateMember();
AggregateDeclaration *ad = isAggregateMember();
/* If this is a class constructor
*/
@@ -1375,7 +1320,7 @@ void FuncDeclaration::semantic3(Scope *sc)
else
{
for (size_t i = 0; i < pd->members->dim; i++)
{ Dsymbol *s = pd->members->tdata()[i];
{ Dsymbol *s = (*pd->members)[i];
s->checkCtorConstInit();
}
@@ -1460,15 +1405,7 @@ void FuncDeclaration::semantic3(Scope *sc)
int offend = blockexit & BEfallthru;
#endif
if (type->nextOf()->ty == Tvoid)
{
if (offend && isMain())
{ // Add a return 0; statement
Statement *s = new ReturnStatement(0, new IntegerExp(0));
fbody = new CompoundStatement(0, fbody, s);
}
}
else
if (type->nextOf()->ty != Tvoid)
{
if (offend)
{ Expression *e;
@@ -1497,6 +1434,66 @@ void FuncDeclaration::semantic3(Scope *sc)
}
}
}
sc2 = sc2->pop();
}
Statement *freq = frequire;
Statement *fens = fensure;
/* Do the semantic analysis on the [in] preconditions and
* [out] postconditions.
*/
if (freq)
{ /* frequire is composed of the [in] contracts
*/
ScopeDsymbol *sym = new ScopeDsymbol();
sym->parent = sc2->scopesym;
sc2 = sc2->push(sym);
sc2->incontract++;
// BUG: need to error if accessing out parameters
// BUG: need to treat parameters as const
// BUG: need to disallow returns and throws
// BUG: verify that all in and ref parameters are read
DsymbolTable *labtab_save = labtab;
labtab = NULL; // so in contract can't refer to out/body labels
freq = freq->semantic(sc2);
labtab = labtab_save;
sc2->incontract--;
sc2 = sc2->pop();
if (!global.params.useIn)
freq = NULL;
}
if (fens)
{ /* fensure is composed of the [out] contracts
*/
if (type->nextOf()->ty == Tvoid && outId)
{
error("void functions have no result");
}
if (type->nextOf()->ty != Tvoid)
buildResultVar();
sc2 = scout; //push
sc2->incontract++;
// BUG: need to treat parameters as const
// BUG: need to disallow returns and throws
DsymbolTable *labtab_save = labtab;
labtab = NULL; // so out contract can't refer to in/body labels
fens = fens->semantic(sc2);
labtab = labtab_save;
sc2->incontract--;
sc2 = sc2->pop();
if (!global.params.useOut)
fens = NULL;
}
{
@@ -1506,7 +1503,7 @@ void FuncDeclaration::semantic3(Scope *sc)
if (parameters)
{ for (size_t i = 0; i < parameters->dim; i++)
{
VarDeclaration *v = parameters->tdata()[i];
VarDeclaration *v = (*parameters)[i];
if (v->storage_class & STCout)
{
assert(v->init);
@@ -1548,7 +1545,7 @@ void FuncDeclaration::semantic3(Scope *sc)
if (parameters && parameters->dim)
{
int lastNonref = parameters->dim -1;
p = parameters->tdata()[lastNonref];
p = (*parameters)[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.
@@ -1562,7 +1559,7 @@ void FuncDeclaration::semantic3(Scope *sc)
p = v_arguments;
break;
}
p = parameters->tdata()[lastNonref];
p = (*parameters)[lastNonref];
}
}
else
@@ -1586,6 +1583,10 @@ void FuncDeclaration::semantic3(Scope *sc)
if (_arguments)
{
#ifdef IN_GCC
v_arguments_var = _arguments;
v_arguments_var->init = new VoidInitializer(loc);
#endif
/* Advance to elements[] member of TypeInfo_Tuple with:
* _arguments = v_arguments.elements;
*/
@@ -1601,74 +1602,32 @@ void FuncDeclaration::semantic3(Scope *sc)
// Merge contracts together with body into one compound statement
if (frequire && global.params.useIn)
{ frequire->incontract = 1;
a->push(frequire);
}
// Precondition invariant
if (addPreInvariant())
if (freq || fpreinv)
{
Expression *e = NULL;
Expression *ee = NULL;
if (isDtorDeclaration())
{
// Call invariant directly only if it exists
InvariantDeclaration *inv = ad->inv;
ClassDeclaration *cd = ad->isClassDeclaration();
if (!freq)
freq = fpreinv;
else if (fpreinv)
freq = new CompoundStatement(0, freq, fpreinv);
while (!inv && cd)
{
cd = cd->baseClass;
if (!cd)
break;
inv = cd->inv;
}
if (inv)
{
e = new DsymbolExp(0, inv);
e = new CallExp(0, e);
e = e->semantic(sc2);
}
}
else
{ // Call invariant virtually
ThisExp* tv = new ThisExp(0);
tv->type = vthis->type;
tv->var = vthis;
Expression *v = tv;
#if STRUCTTHISREF
if (ad->isStructDeclaration())
v = v->addressOf(sc);
#endif
Expression *se = new StringExp(0, (char *)"null this");
se = se->semantic(sc);
#if !IN_LLVM
se->type = Type::tchar->arrayOf();
#endif
e = new AssertExp(loc, v, se);
}
if (ee)
{
ExpStatement *s = new ExpStatement(0, ee);
a->push(s);
}
if (e)
{
ExpStatement *s = new ExpStatement(0, e);
a->push(s);
}
freq->incontract = 1;
a->push(freq);
}
if (fbody)
a->push(fbody);
if (fensure)
if (fens || fpostinv)
{
if (!fens)
fens = fpostinv;
else if (fpostinv)
fens = new CompoundStatement(0, fpostinv, fens);
LabelStatement *ls = new LabelStatement(0, Id::returnLabel, fens);
returnLabel->statement = ls;
a->push(returnLabel->statement);
if (type->nextOf()->ty != Tvoid)
if (type->nextOf()->ty != Tvoid && vresult)
{
#if IN_LLVM
Expression *e = 0;
@@ -1682,7 +1641,6 @@ void FuncDeclaration::semantic3(Scope *sc)
}
#else
// Create: return vresult;
assert(vresult);
Expression *e = new VarExp(0, vresult);
#endif
if (tintro)
@@ -1693,6 +1651,11 @@ void FuncDeclaration::semantic3(Scope *sc)
a->push(s);
}
}
if (isMain() && type->nextOf()->ty == Tvoid)
{ // Add a return 0; statement
Statement *s = new ReturnStatement(0, new IntegerExp(0));
a->push(s);
}
fbody = new CompoundStatement(0, a);
@@ -1740,17 +1703,19 @@ void FuncDeclaration::semantic3(Scope *sc)
if (parameters)
{ for (size_t i = 0; i < parameters->dim; i++)
{
VarDeclaration *v = parameters->tdata()[i];
VarDeclaration *v = (*parameters)[i];
if (v->storage_class & (STCref | STCout))
if (v->storage_class & (STCref | STCout | STClazy))
continue;
#if !SARRAYVALUE
/* Don't do this for static arrays, since static
* arrays are called by reference. Remove this
* when we change them to call by value.
*/
if (v->type->toBasetype()->ty == Tsarray)
continue;
#endif
if (v->noscope)
continue;
@@ -1987,6 +1952,48 @@ void FuncDeclaration::bodyToCBuffer(OutBuffer *buf, HdrGenState *hgs)
}
}
/****************************************************
* Declare result variable lazily.
*/
void FuncDeclaration::buildResultVar()
{
if (vresult)
return;
assert(type->nextOf());
assert(type->nextOf()->toBasetype()->ty != Tvoid);
TypeFunction *tf = (TypeFunction *)(type);
Loc loc = this->loc;
if (fensure)
loc = fensure->loc;
if (!outId)
outId = Id::result; // provide a default
VarDeclaration *v = new VarDeclaration(loc, type->nextOf(), outId, NULL);
v->noscope = 1;
v->storage_class |= STCresult;
#if DMDV2
if (!isVirtual())
v->storage_class |= STCconst;
if (tf->isref)
{
v->storage_class |= STCref | STCforeach;
}
#endif
v->semantic(scout);
if (!scout->insert(v))
error("out result %s is already defined", v->toChars());
v->parent = this;
vresult = v;
// vresult gets initialized with the function return value
// in ReturnStatement::semantic()
}
/****************************************************
* Merge into this function the 'in' contracts of all it overrides.
* 'in's are OR'd together, i.e. only one of them needs to pass.
@@ -2031,7 +2038,7 @@ Statement *FuncDeclaration::mergeFrequire(Statement *sf, Expressions *params)
*/
for (int i = 0; i < foverrides.dim; i++)
{
FuncDeclaration *fdv = foverrides.tdata()[i];
FuncDeclaration *fdv = foverrides[i];
/* The semantic pass on the contracts of the overridden functions must
* be completed before code generation occurs (bug 3602).
@@ -2089,7 +2096,7 @@ Statement *FuncDeclaration::mergeFensure(Statement *sf, Expressions *params)
*/
for (int i = 0; i < foverrides.dim; i++)
{
FuncDeclaration *fdv = foverrides.tdata()[i];
FuncDeclaration *fdv = foverrides[i];
/* The semantic pass on the contracts of the overridden functions must
* be completed before code generation occurs (bug 3602 and 5230).
@@ -2158,14 +2165,28 @@ int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim)
FuncDeclaration *mismatch = NULL;
StorageClass mismatchstc = 0;
int mismatchvi = -1;
int exactvi = -1;
int bestvi = -1;
for (int vi = 0; vi < dim; vi++)
{
FuncDeclaration *fdv = vtbl->tdata()[vi]->isFuncDeclaration();
FuncDeclaration *fdv = (*vtbl)[vi]->isFuncDeclaration();
if (fdv && fdv->ident == ident)
{
if (type->equals(fdv->type)) // if exact match
return vi; // no need to look further
{
if (fdv->parent->isClassDeclaration())
return vi; // no need to look further
if (exactvi >= 0)
{
error("cannot determine overridden function");
return exactvi;
}
exactvi = vi;
bestvi = vi;
continue;
}
StorageClass stc = 0;
int cov = type->covariant(fdv->type, &stc);
@@ -2527,7 +2548,7 @@ if (arguments)
for (i = 0; i < arguments->dim; i++)
{ Expression *arg;
arg = arguments->tdata()[i];
arg = (*arguments)[i];
assert(arg->type);
printf("\t%s: ", arg->toChars());
arg->type->print();
@@ -2570,7 +2591,7 @@ if (arguments)
OutBuffer buf2;
tf->modToBuffer(&buf2);
//printf("tf = %s, args = %s\n", tf->deco, arguments->tdata()[0]->type->deco);
//printf("tf = %s, args = %s\n", tf->deco, (*arguments)[0]->type->deco);
error(loc, "%s%s is not callable using argument types %s",
Parameter::argsTypesToChars(tf->parameters, tf->varargs),
buf2.toChars(),
@@ -2656,7 +2677,7 @@ MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
}
else
e = p->type->defaultInitLiteral(0);
args.tdata()[u] = e;
args[u] = e;
}
MATCH m = (MATCH) tg->callMatch(NULL, &args, 1);
@@ -2797,14 +2818,25 @@ int FuncDeclaration::getLevel(Loc loc, Scope *sc, FuncDeclaration *fd)
//printf("\ts = %s, '%s'\n", s->kind(), s->toChars());
FuncDeclaration *thisfd = s->isFuncDeclaration();
if (thisfd)
{ if (!thisfd->isNested() && !thisfd->vthis)
{ if (!thisfd->isNested() && !thisfd->vthis && !sc->intypeof)
goto Lerr;
}
else
{
AggregateDeclaration *thiscd = s->isAggregateDeclaration();
if (thiscd)
{ if (!thiscd->isNested())
{
/* AggregateDeclaration::isNested returns true only when
* it has a hidden pointer.
* But, calling the function belongs unrelated lexical scope
* is still allowed inside typeof.
*
* struct Map(alias fun) {
* typeof({ return fun(); }) RetType;
* // No member function makes Map struct 'not nested'.
* }
*/
if (!thiscd->isNested() && !sc->intypeof)
goto Lerr;
}
else
@@ -3081,6 +3113,7 @@ int FuncDeclaration::isNested()
FuncDeclaration *f = toAliasFunc();
//printf("\ttoParent2() = '%s'\n", f->toParent2()->toChars());
return ((f->storage_class & STCstatic) == 0) &&
(f->linkage == LINKd) &&
(f->toParent2()->isFuncDeclaration() != NULL);
}
@@ -3222,12 +3255,12 @@ int FuncDeclaration::needsClosure()
//printf("FuncDeclaration::needsClosure() %s\n", toChars());
for (int i = 0; i < closureVars.dim; i++)
{ VarDeclaration *v = closureVars.tdata()[i];
{ VarDeclaration *v = closureVars[i];
assert(v->isVarDeclaration());
//printf("\tv = %s\n", v->toChars());
for (int j = 0; j < v->nestedrefs.dim; j++)
{ FuncDeclaration *f = v->nestedrefs.tdata()[j];
{ FuncDeclaration *f = v->nestedrefs[j];
assert(f != this);
//printf("\t\tf = %s, %d, %p, %d\n", f->toChars(), f->isVirtual(), f->isThis(), f->tookAddressOf);
@@ -3298,7 +3331,7 @@ int FuncDeclaration::hasNestedFrameRefs()
{
for (size_t i = 0; i < foverrides.dim; i++)
{
FuncDeclaration *fdv = foverrides.tdata()[i];
FuncDeclaration *fdv = foverrides[i];
if (fdv->hasNestedFrameRefs())
return 1;
}
@@ -3386,6 +3419,7 @@ FuncLiteralDeclaration::FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type,
this->ident = Lexer::uniqueId(id);
this->tok = tok;
this->fes = fes;
this->treq = NULL;
//printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars());
}
@@ -3399,6 +3433,7 @@ Dsymbol *FuncLiteralDeclaration::syntaxCopy(Dsymbol *s)
else
{ f = new FuncLiteralDeclaration(loc, endloc, type->syntaxCopy(), tok, fes);
f->ident = ident; // keep old identifier
f->treq = treq; // don't need to copy
}
FuncDeclaration::syntaxCopy(f);
return f;
@@ -3713,14 +3748,8 @@ char *DtorDeclaration::toChars()
int DtorDeclaration::isVirtual()
{
/* This should be FALSE so that dtor's don't get put into the vtbl[],
* but doing so will require recompiling everything.
*/
#if BREAKABI
// FALSE so that dtor's don't get put into the vtbl[]
return FALSE;
#else
return FuncDeclaration::isVirtual();
#endif
}
void DtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
+1 -1
View File
@@ -84,7 +84,7 @@ void Module::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
}
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
s->toHBuffer(buf, hgs);
}
+1
View File
@@ -8,6 +8,7 @@
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <string.h> // memset()
struct HdrGenState
{
+3 -1
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -66,6 +66,7 @@ Msgtable msgtable[] =
{ "outer" },
{ "Exception" },
{ "AssociativeArray" },
{ "RTInfo" },
{ "Throwable" },
{ "Error" },
{ "withSym", "__withSym" },
@@ -356,6 +357,7 @@ Msgtable msgtable[] =
{ "derivedMembers" },
{ "isSame" },
{ "compiles" },
{ "parameters" },
};
+35 -7
View File
@@ -45,7 +45,7 @@ Import::Import(Loc loc, Identifiers *packages, Identifier *id, Identifier *alias
this->ident = aliasId;
// import [std].stdio;
else if (packages && packages->dim)
this->ident = packages->tdata()[0];
this->ident = (*packages)[0];
// import [foo];
else
this->ident = id;
@@ -112,8 +112,18 @@ void Import::load(Scope *sc)
if (s->isModule())
mod = (Module *)s;
else
::error(loc, "can only import from a module, not from package %s.%s",
pkg->toPrettyChars(), id->toChars());
{
if (pkg)
{
::error(loc, "can only import from a module, not from package %s.%s",
pkg->toPrettyChars(), id->toChars());
}
else
{
::error(loc, "can only import from a module, not from package %s",
id->toChars());
}
}
#endif
}
@@ -356,8 +366,8 @@ int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
*/
for (size_t i = 0; i < names.dim; i++)
{
Identifier *name = names.tdata()[i];
Identifier *alias = aliases.tdata()[i];
Identifier *name = names[i];
Identifier *alias = aliases[i];
if (!alias)
alias = name;
@@ -413,12 +423,30 @@ void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
if (packages && packages->dim)
{
for (size_t i = 0; i < packages->dim; i++)
{ Identifier *pid = packages->tdata()[i];
{ Identifier *pid = (*packages)[i];
buf->printf("%s.", pid->toChars());
}
}
buf->printf("%s;", id->toChars());
buf->printf("%s", id->toChars());
if (names.dim)
{
buf->writestring(" : ");
for (size_t i = 0; i < names.dim; i++)
{
Identifier *name = names[i];
Identifier *alias = aliases[i];
if (alias)
buf->printf("%s = %s", alias->toChars(), name->toChars());
else
buf->printf("%s", name->toChars());
if (i < names.dim - 1)
buf->writestring(", ");
}
}
buf->printf(";");
buf->writenl();
}
+5 -1
View File
@@ -1,6 +1,6 @@
/*
* Some portions copyright (c) 1994-1995 by Symantec
* Copyright (c) 1999-2011 by Digital Mars
* Copyright (c) 1999-2012 by Digital Mars
* All Rights Reserved
* http://www.digitalmars.com
* Written by Walter Bright
@@ -31,6 +31,10 @@
#include <alloca.h>
#endif
#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__
#include "gnuc.h"
#endif
#include "root.h"
#include "rmem.h"
+64 -13
View File
@@ -35,7 +35,7 @@ Initializer *Initializer::syntaxCopy()
return this;
}
Initializer *Initializer::semantic(Scope *sc, Type *t, int needInterpret)
Initializer *Initializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret)
{
return this;
}
@@ -88,7 +88,7 @@ Initializer *VoidInitializer::syntaxCopy()
}
Initializer *VoidInitializer::semantic(Scope *sc, Type *t, int needInterpret)
Initializer *VoidInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret)
{
//printf("VoidInitializer::semantic(t = %p)\n", t);
type = t;
@@ -145,7 +145,7 @@ void StructInitializer::addInit(Identifier *field, Initializer *value)
this->value.push(value);
}
Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
Initializer *StructInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret)
{
int errors = 0;
@@ -227,7 +227,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
}
if (s && (v = s->isVarDeclaration()) != NULL)
{
val = val->semantic(sc, v->type, needInterpret);
val = val->semantic(sc, v->type->addMod(t->mod), needInterpret);
value[i] = val;
vars[i] = v;
}
@@ -353,8 +353,12 @@ Expression *StructInitializer::toExpression()
else
{
if (!(*elements)[i])
// Default initialize
(*elements)[i] = vd->type->defaultInit();
{ // Default initialize
if (vd->init)
(*elements)[i] = vd->init->toExpression();
else
(*elements)[i] = vd->type->defaultInit();
}
}
offset = vd->offset + vd->type->size();
i++;
@@ -464,7 +468,7 @@ void ArrayInitializer::addInit(Expression *index, Initializer *value)
type = NULL;
}
Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret)
Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret)
{ unsigned i;
unsigned length;
const unsigned amax = 0x80000000;
@@ -482,6 +486,10 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret)
case Tarray:
break;
case Tvector:
t = ((TypeVector *)t)->basetype;
break;
default:
error(loc, "cannot use array to initialize %s", type->toChars());
goto Lerr;
@@ -493,14 +501,39 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret)
Expression *idx = index[i];
if (idx)
{ idx = idx->semantic(sc);
idx = idx->optimize(WANTvalue | WANTinterpret);
idx = idx->ctfeInterpret();
index[i] = idx;
length = idx->toInteger();
}
Initializer *val = value[i];
ExpInitializer *ei = val->isExpInitializer();
if (ei && !idx)
ei->expandTuples = 1;
val = val->semantic(sc, t->nextOf(), needInterpret);
value[i] = val;
ei = val->isExpInitializer();
// found a tuple, expand it
if (ei && ei->exp->op == TOKtuple)
{
TupleExp *te = (TupleExp *)ei->exp;
index.remove(i);
value.remove(i);
for (size_t j = 0; j < te->exps->dim; ++j)
{
Expression *e = (*te->exps)[j];
index.insert(i + j, (Expression *)NULL);
value.insert(i + j, new ExpInitializer(e->loc, e));
}
i--;
continue;
}
else
{
value[i] = val;
}
length++;
if (length == 0)
{ error(loc, "array dimension overflow");
@@ -746,6 +779,7 @@ ExpInitializer::ExpInitializer(Loc loc, Expression *exp)
: Initializer(loc)
{
this->exp = exp;
this->expandTuples = 0;
}
Initializer *ExpInitializer::syntaxCopy()
@@ -757,6 +791,9 @@ bool arrayHasNonConstPointers(Expressions *elems);
bool hasNonConstPointers(Expression *e)
{
if (e->type->ty == Terror)
return false;
if (e->op == TOKnull)
return false;
if (e->op == TOKstructliteral)
@@ -817,15 +854,19 @@ bool arrayHasNonConstPointers(Expressions *elems)
Initializer *ExpInitializer::semantic(Scope *sc, Type *t, int needInterpret)
Initializer *ExpInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret)
{
//printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
int wantOptimize = needInterpret ? WANTinterpret|WANTvalue : WANTvalue;
if (exp->op == TOKerror)
return this;
int olderrors = global.errors;
exp = exp->optimize(wantOptimize);
if (needInterpret)
exp = exp->ctfeInterpret();
else
exp = exp->optimize(WANTvalue);
if (!global.gag && olderrors != global.errors)
return this; // Failed, suppress duplicate error messages
@@ -841,6 +882,11 @@ Initializer *ExpInitializer::semantic(Scope *sc, Type *t, int needInterpret)
Type *tb = t->toBasetype();
if (exp->op == TOKtuple &&
expandTuples &&
!exp->implicitConvTo(t))
return new ExpInitializer(loc, exp);
/* Look for case of initializing a static array with a too-short
* string literal, such as:
* char[5] foo = "abc";
@@ -870,8 +916,13 @@ Initializer *ExpInitializer::semantic(Scope *sc, Type *t, int needInterpret)
}
exp = exp->implicitCastTo(sc, t);
if (exp->op == TOKerror)
return this;
L1:
exp = exp->optimize(wantOptimize);
if (needInterpret)
exp = exp->ctfeInterpret();
else
exp = exp->optimize(WANTvalue);
//printf("-ExpInitializer::semantic(): "); exp->print();
return this;
}
+8 -6
View File
@@ -34,6 +34,7 @@ namespace llvm {
}
#endif
enum NeedInterpret { INITnointerpret, INITinterpret };
struct Initializer : Object
{
@@ -41,8 +42,8 @@ struct Initializer : Object
Initializer(Loc loc);
virtual Initializer *syntaxCopy();
// needInterpret is WANTinterpret if must be a manifest constant, 0 if not.
virtual Initializer *semantic(Scope *sc, Type *t, int needInterpret);
// needInterpret is INITinterpret if must be a manifest constant, 0 if not.
virtual Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret);
virtual Type *inferType(Scope *sc);
virtual Expression *toExpression() = 0;
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
@@ -66,7 +67,7 @@ struct VoidInitializer : Initializer
VoidInitializer(Loc loc);
Initializer *syntaxCopy();
Initializer *semantic(Scope *sc, Type *t, int needInterpret);
Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret);
Expression *toExpression();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -88,7 +89,7 @@ struct StructInitializer : Initializer
StructInitializer(Loc loc);
Initializer *syntaxCopy();
void addInit(Identifier *field, Initializer *value);
Initializer *semantic(Scope *sc, Type *t, int needInterpret);
Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret);
Expression *toExpression();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -113,7 +114,7 @@ struct ArrayInitializer : Initializer
ArrayInitializer(Loc loc);
Initializer *syntaxCopy();
void addInit(Expression *index, Initializer *value);
Initializer *semantic(Scope *sc, Type *t, int needInterpret);
Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret);
int isAssociativeArray();
Type *inferType(Scope *sc);
Expression *toExpression();
@@ -131,10 +132,11 @@ struct ArrayInitializer : Initializer
struct ExpInitializer : Initializer
{
Expression *exp;
int expandTuples;
ExpInitializer(Loc loc, Expression *exp);
Initializer *syntaxCopy();
Initializer *semantic(Scope *sc, Type *t, int needInterpret);
Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret);
Type *inferType(Scope *sc);
Expression *toExpression();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
+78 -18
View File
@@ -1,5 +1,5 @@
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -14,6 +14,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <string.h> // memset()
#include "id.h"
#include "init.h"
@@ -618,11 +619,11 @@ Expressions *arrayExpressiondoInline(Expressions *a, InlineDoState *ids)
newa->setDim(a->dim);
for (size_t i = 0; i < a->dim; i++)
{ Expression *e = a->tdata()[i];
{ Expression *e = (*a)[i];
if (e)
e = e->doInline(ids);
newa->tdata()[i] = e;
(*newa)[i] = e;
}
}
return newa;
@@ -639,11 +640,11 @@ Expression *SymOffExp::doInline(InlineDoState *ids)
//printf("SymOffExp::doInline(%s)\n", toChars());
for (size_t i = 0; i < ids->from.dim; i++)
{
if (var == ids->from.tdata()[i])
if (var == ids->from[i])
{
SymOffExp *se = (SymOffExp *)copy();
se->var = (Declaration *)ids->to.tdata()[i];
se->var = (Declaration *)ids->to[i];
return se;
}
}
@@ -655,11 +656,11 @@ Expression *VarExp::doInline(InlineDoState *ids)
//printf("VarExp::doInline(%s)\n", toChars());
for (size_t i = 0; i < ids->from.dim; i++)
{
if (var == ids->from.tdata()[i])
if (var == ids->from[i])
{
VarExp *ve = (VarExp *)copy();
ve->var = (Declaration *)ids->to.tdata()[i];
ve->var = (Declaration *)ids->to[i];
return ve;
}
}
@@ -709,7 +710,7 @@ Expression *DeclarationExp::doInline(InlineDoState *ids)
if (td)
{
for (size_t i = 0; i < td->objects->dim; i++)
{ DsymbolExp *se = td->objects->tdata()[i];
{ DsymbolExp *se = (*td->objects)[i];
assert(se->op == TOKdsymbol);
se->s;
}
@@ -1098,8 +1099,8 @@ Statement *SwitchStatement::inlineScan(InlineScanState *iss)
for (size_t i = 0; i < cases->dim; i++)
{ CaseStatement *s;
s = cases->tdata()[i];
cases->tdata()[i] = (CaseStatement *)s->inlineScan(iss);
s = (*cases)[i];
(*cases)[i] = (CaseStatement *)s->inlineScan(iss);
}
}
return this;
@@ -1130,6 +1131,65 @@ Statement *ReturnStatement::inlineScan(InlineScanState *iss)
if (exp)
{
exp = exp->inlineScan(iss);
FuncDeclaration *func = iss->fd;
TypeFunction *tf = (TypeFunction *)(func->type);
/* Postblit call on return statement is processed in glue layer
* (Because NRVO may eliminate the copy), but inlining may remove
* ReturnStatement itself. To keep semantics we should insert
* temporary variable for postblit call.
* This is mostly the same as ReturnStatement::toIR.
*/
enum RET retmethod = tf->retStyle();
if (retmethod == RETstack)
{
if (func->nrvo_can && func->nrvo_var)
;
else
{
Type *tb = exp->type->toBasetype();
if (exp->isLvalue() && tb->ty == Tstruct)
{ StructDeclaration *sd = ((TypeStruct *)tb)->sym;
if (sd->postblit)
{ FuncDeclaration *fd = sd->postblit;
if (fd->storage_class & STCdisable)
{
fd->toParent()->error(loc, "is not copyable because it is annotated with @disable");
}
/* Rewirte exp as:
* (__inlinectmp = exp), __inlinectmp.__postblit(), __inlinectmp
* And, __inlinectmp is marked as rvalue (See STCtemp comment)
*/
ExpInitializer *ei = new ExpInitializer(loc, exp);
Identifier* tmp = Identifier::generateId("__inlinectmp");
VarDeclaration *v = new VarDeclaration(loc, exp->type, tmp, ei);
v->storage_class = STCtemp;
v->linkage = LINKd;
v->parent = func;
VarExp *ve = new VarExp(loc, v);
ve->type = exp->type;
ei->exp = new ConstructExp(loc, ve, exp);
ei->exp->type = exp->type;
DeclarationExp *de = new DeclarationExp(0, v);
de->type = Type::tvoid;
Expression *e = new DotVarExp(ve->loc, ve, sd->postblit, 0);
e->type = sd->postblit->type;
e = new CallExp(ve->loc, e);
e->type = Type::tvoid;
exp = Expression::combine(de, e);
exp = Expression::combine(exp, ve);
}
}
}
}
}
return this;
}
@@ -1162,7 +1222,7 @@ Statement *TryCatchStatement::inlineScan(InlineScanState *iss)
if (catches)
{
for (size_t i = 0; i < catches->dim; i++)
{ Catch *c = catches->tdata()[i];
{ Catch *c = (*catches)[i];
if (c->handler)
c->handler = c->handler->inlineScan(iss);
@@ -1212,12 +1272,12 @@ void arrayInlineScan(InlineScanState *iss, Expressions *arguments)
if (arguments)
{
for (size_t i = 0; i < arguments->dim; i++)
{ Expression *e = arguments->tdata()[i];
{ Expression *e = (*arguments)[i];
if (e)
{
e = e->inlineScan(iss);
arguments->tdata()[i] = e;
(*arguments)[i] = e;
}
}
}
@@ -1237,7 +1297,7 @@ void scanVar(Dsymbol *s, InlineScanState *iss)
if (td)
{
for (size_t i = 0; i < td->objects->dim; i++)
{ DsymbolExp *se = (DsymbolExp *)td->objects->tdata()[i];
{ DsymbolExp *se = (DsymbolExp *)(*td->objects)[i];
assert(se->op == TOKdsymbol);
scanVar(se->s, iss);
}
@@ -1546,7 +1606,7 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan, int statementsToo)
{
for (size_t i = 0; i < parameters->dim; i++)
{
VarDeclaration *v = parameters->tdata()[i];
VarDeclaration *v = (*parameters)[i];
if (v->type->toBasetype()->ty == Tsarray)
goto Lno;
}
@@ -1701,9 +1761,9 @@ Expression *FuncDeclaration::expandInline(InlineScanState *iss, Expression *ethi
for (size_t i = 0; i < arguments->dim; i++)
{
VarDeclaration *vfrom = parameters->tdata()[i];
VarDeclaration *vfrom = (*parameters)[i];
VarDeclaration *vto;
Expression *arg = arguments->tdata()[i];
Expression *arg = (*arguments)[i];
ExpInitializer *ei;
VarExp *ve;
@@ -1778,7 +1838,7 @@ Expression *FuncDeclaration::expandInline(InlineScanState *iss, Expression *ethi
Identifier* tmp = Identifier::generateId("__inlineretval");
VarDeclaration* vd = new VarDeclaration(loc, tf->next, tmp, ei);
vd->storage_class = tf->isref ? STCref : 0;
vd->storage_class = (tf->isref ? STCref : 0) | STCtemp;
vd->linkage = tf->linkage;
vd->parent = iss->fd;
+585 -218
View File
File diff suppressed because it is too large Load Diff
+6 -6
View File
@@ -95,14 +95,14 @@ struct IntRange
IntRange(const SignExtendedNumber& a)
: imin(a), imax(a) {}
/// Create a range with the lower and upper bounds.
IntRange(const SignExtendedNumber& lower, const SignExtendedNumber& upper)
IntRange(const SignExtendedNumber& lower, const SignExtendedNumber& upper)
: imin(lower), imax(upper) {}
/// Create the tightest range containing all valid integers in the specified
/// type.
/// type.
static IntRange fromType(Type *type);
/// Create the tightest range containing all valid integers in the type with
/// a forced signedness.
/// a forced signedness.
static IntRange fromType(Type *type, bool isUnsigned);
@@ -131,7 +131,7 @@ struct IntRange
/// Check if this range contains 0.
bool containsZero() const;
/// Compute the range of the negated absolute values of the original range.
/// Compute the range of the negated absolute values of the original range.
IntRange absNeg() const;
/// Compute the union of two ranges.
@@ -139,7 +139,7 @@ struct IntRange
void unionOrAssign(const IntRange& other, bool& union_);
/// Dump the content of the integer range to the console.
const IntRange& dump(const char* funcName, Expression *e) const;
const IntRange& dump(const char* funcName, Expression *e) const;
/// Split the range into two nonnegative- and negative-only subintervals.
void splitBySign(IntRange& negRange, bool& hasNegRange,
+9 -9
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -53,7 +53,7 @@ void json_generate(Modules *modules)
buf.writestring("[\n");
for (size_t i = 0; i < modules->dim; i++)
{ Module *m = modules->tdata()[i];
{ Module *m = (*modules)[i];
if (global.params.verbose)
printf("json gen %s\n", m->toChars());
m->toJsonBuffer(&buf);
@@ -66,7 +66,7 @@ void json_generate(Modules *modules)
char *arg = global.params.xfilename;
if (!arg || !*arg)
{ // Generate lib file name from first obj name
char *n = global.params.objfiles->tdata()[0];
char *n = (*global.params.objfiles)[0];
n = FileName::name(n);
FileName *fn = FileName::forceExt(n, global.json_ext);
@@ -195,7 +195,7 @@ void Module::toJsonBuffer(OutBuffer *buf)
size_t offset = buf->offset;
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
if (offset != buf->offset)
{ buf->writestring(",\n");
offset = buf->offset;
@@ -219,7 +219,7 @@ void AttribDeclaration::toJsonBuffer(OutBuffer *buf)
{
size_t offset = buf->offset;
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = d->tdata()[i];
{ Dsymbol *s = (*d)[i];
//printf("AttribDeclaration::toJsonBuffer %s\n", s->toChars());
if (offset != buf->offset)
{ buf->writestring(",\n");
@@ -332,7 +332,7 @@ void AggregateDeclaration::toJsonBuffer(OutBuffer *buf)
buf->writestring(" : [\n");
size_t offset = buf->offset;
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
if (offset != buf->offset)
{ buf->writestring(",\n");
offset = buf->offset;
@@ -369,7 +369,7 @@ void TemplateDeclaration::toJsonBuffer(OutBuffer *buf)
buf->writestring(" : [\n");
size_t offset = buf->offset;
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
if (offset != buf->offset)
{ buf->writestring(",\n");
offset = buf->offset;
@@ -391,7 +391,7 @@ void EnumDeclaration::toJsonBuffer(OutBuffer *buf)
{
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
s->toJsonBuffer(buf);
buf->writestring(",\n");
}
@@ -423,7 +423,7 @@ void EnumDeclaration::toJsonBuffer(OutBuffer *buf)
buf->writestring(" : [\n");
size_t offset = buf->offset;
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
if (offset != buf->offset)
{ buf->writestring(",\n");
offset = buf->offset;
+28 -171
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -108,14 +108,22 @@ const char *Token::toChars()
switch (value)
{
case TOKint32v:
#if defined(IN_GCC) || defined(IN_LLVM)
sprintf(buffer,"%d",(d_int32)int64value);
#else
sprintf(buffer,"%d",int32value);
#endif
break;
case TOKuns32v:
case TOKcharv:
case TOKwcharv:
case TOKdcharv:
#ifdef defined(IN_GCC) || defined(IN_LLVM)
sprintf(buffer,"%uU",(d_uns32)uns64value);
#else
sprintf(buffer,"%uU",uns32value);
#endif
break;
case TOKint64v:
@@ -126,7 +134,7 @@ const char *Token::toChars()
sprintf(buffer,"%lluUL",(uintmax_t)uns64value);
break;
#if IN_GCC
#ifdef IN_GCC
case TOKfloat32v:
case TOKfloat64v:
case TOKfloat80v:
@@ -171,9 +179,6 @@ const char *Token::toChars()
#endif
case TOKstring:
#if CSTRINGS
p = string;
#else
{ OutBuffer buf;
buf.writeByte('"');
@@ -208,7 +213,6 @@ const char *Token::toChars()
buf.writeByte(0);
p = (char *)buf.extractData();
}
#endif
break;
case TOKidentifier:
@@ -305,7 +309,7 @@ void Lexer::error(const char *format, ...)
{
va_list ap;
va_start(ap, format);
verror(tokenLoc(), format, ap);
::verror(tokenLoc(), format, ap);
va_end(ap);
}
@@ -313,34 +317,10 @@ void Lexer::error(Loc loc, const char *format, ...)
{
va_list ap;
va_start(ap, format);
verror(loc, format, ap);
::verror(loc, format, ap);
va_end(ap);
}
void Lexer::verror(Loc loc, const char *format, va_list ap)
{
if (mod && !global.gag)
{
char *p = loc.toChars();
if (*p)
fprintf(stdmsg, "%s: ", p);
mem.free(p);
vfprintf(stdmsg, format, ap);
fprintf(stdmsg, "\n");
fflush(stdmsg);
if (global.errors >= 20) // moderate blizzard of cascading messages
fatal();
}
else
{
global.gaggedErrors++;
}
global.errors++;
}
TOK Lexer::nextToken()
{ Token *t;
@@ -524,30 +504,6 @@ void Lexer::scan(Token *t)
t->value = number(t);
return;
#if CSTRINGS
case '\'':
t->value = charConstant(t, 0);
return;
case '"':
t->value = stringConstant(t,0);
return;
case 'l':
case 'L':
if (p[1] == '\'')
{
p++;
t->value = charConstant(t, 1);
return;
}
else if (p[1] == '"')
{
p++;
t->value = stringConstant(t, 1);
return;
}
#else
case '\'':
t->value = charConstant(t,0);
return;
@@ -627,12 +583,9 @@ void Lexer::scan(Token *t)
}
#endif
case 'l':
case 'L':
#endif
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'm': case 'n': case 'o':
case 'k': case 'l': case 'm': case 'n': case 'o':
#if DMDV2
case 'p': /*case 'q': case 'r':*/ case 's': case 't':
#else
@@ -642,7 +595,7 @@ void Lexer::scan(Token *t)
case 'z':
case 'A': case 'B': case 'C': case 'D': case 'E':
case 'F': case 'G': case 'H': case 'I': case 'J':
case 'K': case 'M': case 'N': case 'O':
case 'K': case 'L': case 'M': case 'N': case 'O':
case 'P': case 'Q': case 'R': case 'S': case 'T':
case 'U': case 'V': case 'W': case 'X': case 'Y':
case 'Z':
@@ -669,7 +622,7 @@ void Lexer::scan(Token *t)
StringValue *sv = stringtable.update((char *)t->ptr, p - t->ptr);
Identifier *id = (Identifier *) sv->ptrvalue;
if (!id)
{ id = new Identifier(sv->lstring.string,TOKidentifier);
{ id = new Identifier(sv->toDchars(),TOKidentifier);
sv->ptrvalue = id;
}
t->ident = id;
@@ -1228,10 +1181,10 @@ void Lexer::scan(Token *t)
case '#':
{
p++;
Token *n = peek(t);
if (n->value == TOKidentifier && n->ident == Id::line)
Token n;
scan(&n);
if (n.value == TOKidentifier && n.ident == Id::line)
{
nextToken();
poundLine();
continue;
}
@@ -1931,45 +1884,6 @@ void Lexer::stringPostfix(Token *t)
}
}
/***************************************
* Read \u or \U unicode sequence
* Input:
* u 'u' or 'U'
*/
#if 0
unsigned Lexer::wchar(unsigned u)
{
unsigned value;
unsigned n;
unsigned char c;
unsigned nchars;
nchars = (u == 'U') ? 8 : 4;
value = 0;
for (n = 0; 1; n++)
{
++p;
if (n == nchars)
break;
c = *p;
if (!ishex(c))
{ error("\\%c sequence must be followed by %d hex characters", u, nchars);
break;
}
if (isdigit(c))
c -= '0';
else if (islower(c))
c -= 'a' - 10;
else
c -= 'A' - 10;
value <<= 4;
value |= c;
}
return value;
}
#endif
/**************************************
* Read in a number.
* If it's an integer, store it in tok.TKutok.Vlong.
@@ -1996,14 +1910,12 @@ TOK Lexer::number(Token *t)
};
enum FLAGS flags = FLAGS_decimal;
int base;
unsigned c;
unsigned char *start;
TOK result;
//printf("Lexer::number()\n");
state = STATE_initial;
base = 0;
stringbuffer.reset();
start = p;
while (1)
@@ -2022,11 +1934,6 @@ TOK Lexer::number(Token *t)
flags = (FLAGS) (flags & ~FLAGS_decimal);
switch (c)
{
#if ZEROH
case 'H': // 0h
case 'h':
goto hexh;
#endif
case 'X':
case 'x':
state = STATE_hex0;
@@ -2035,15 +1942,14 @@ TOK Lexer::number(Token *t)
case '.':
if (p[1] == '.') // .. is a separate token
goto done;
#if DMDV2
if (isalpha(p[1]) || p[1] == '_')
goto done;
#endif
case 'i':
case 'f':
case 'F':
goto real;
#if ZEROH
case 'E':
case 'e':
goto case_hex;
#endif
case 'B':
case 'b':
state = STATE_binary0;
@@ -2054,14 +1960,6 @@ TOK Lexer::number(Token *t)
state = STATE_octal;
break;
#if ZEROH
case '8': case '9': case 'A':
case 'C': case 'D': case 'F':
case 'a': case 'c': case 'd': case 'f':
case_hex:
state = STATE_hexh;
break;
#endif
case '_':
state = STATE_octal;
p++;
@@ -2080,12 +1978,6 @@ TOK Lexer::number(Token *t)
case STATE_decimal: // reading decimal number
if (!isdigit(c))
{
#if ZEROH
if (ishex(c)
|| c == 'H' || c == 'h'
)
goto hexh;
#endif
if (c == '_') // ignore embedded _
{ p++;
continue;
@@ -2130,41 +2022,10 @@ TOK Lexer::number(Token *t)
state = STATE_hex;
break;
#if ZEROH
hexh:
state = STATE_hexh;
case STATE_hexh: // parse numbers like 0FFh
if (!ishex(c))
{
if (c == 'H' || c == 'h')
{
p++;
base = 16;
goto done;
}
else
{
// Check for something like 1E3 or 0E24
if (memchr((char *)stringbuffer.data, 'E', stringbuffer.offset) ||
memchr((char *)stringbuffer.data, 'e', stringbuffer.offset))
goto real;
error("Hex digit expected, not '%c'", c);
goto done;
}
}
break;
#endif
case STATE_octal: // reading octal number
case STATE_octale: // reading octal number with non-octal digits
if (!isoctal(c))
{
#if ZEROH
if (ishex(c)
|| c == 'H' || c == 'h'
)
goto hexh;
#endif
if (c == '_') // ignore embedded _
{ p++;
continue;
@@ -2186,12 +2047,6 @@ TOK Lexer::number(Token *t)
case STATE_binary: // reading binary number
if (c != '0' && c != '1')
{
#if ZEROH
if (ishex(c)
|| c == 'H' || c == 'h'
)
goto hexh;
#endif
if (c == '_') // ignore embedded _
{ p++;
continue;
@@ -2232,7 +2087,7 @@ done:
// Convert string to integer
#if __DMC__
errno = 0;
n = strtoull((char *)stringbuffer.data,NULL,base);
n = strtoull((char *)stringbuffer.data,NULL,0);
if (errno == ERANGE)
error("integer overflow");
#else
@@ -2636,8 +2491,9 @@ void Lexer::poundLine()
{
p += 8;
filespec = mem.strdup(loc.filename ? loc.filename : mod->ident->toChars());
continue;
}
continue;
goto Lerr;
case '"':
if (filespec)
@@ -2920,7 +2776,7 @@ Identifier *Lexer::idPool(const char *s)
Identifier *id = (Identifier *) sv->ptrvalue;
if (!id)
{
id = new Identifier(sv->lstring.string, TOKidentifier);
id = new Identifier(sv->toDchars(), TOKidentifier);
sv->ptrvalue = id;
}
return id;
@@ -3067,6 +2923,7 @@ static Keyword keywords[] =
// Added after 1.0
{ "__argTypes", TOKargTypes },
{ "__parameters", TOKparameters },
{ "ref", TOKref },
{ "macro", TOKmacro },
#if DMDV2
@@ -3111,7 +2968,7 @@ void Lexer::initKeywords()
const char *s = keywords[u].name;
enum TOK v = keywords[u].value;
StringValue *sv = stringtable.insert(s, strlen(s));
sv->ptrvalue = (void *) new Identifier(sv->lstring.string,v);
sv->ptrvalue = (void *) new Identifier(sv->toDchars(),v);
//printf("tochars[%d] = '%s'\n",v, s);
Token::tochars[v] = s;
+2 -2
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2010 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -156,6 +156,7 @@ enum TOK
TOKref,
TOKmacro,
#if DMDV2
TOKparameters,
TOKtraits,
TOKoverloadset,
TOKpure,
@@ -311,7 +312,6 @@ struct Lexer
TOK inreal(Token *t);
void error(const char *format, ...) IS_PRINTF(2);
void error(Loc loc, const char *format, ...) IS_PRINTF(3);
void verror(Loc loc, const char *format, va_list ap);
void poundLine();
unsigned decodeUTF();
void getDocComment(Token *t, unsigned lineComment);
+8 -46
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -15,53 +15,15 @@
#pragma once
#endif /* __DMC__ */
struct ObjModule;
struct ObjSymbol
class Library
{
char *name;
ObjModule *om;
};
public:
static Library *factory();
#include "arraytypes.h"
typedef ArrayBase<ObjModule> ObjModules;
typedef ArrayBase<ObjSymbol> ObjSymbols;
struct Library
{
File *libfile;
ObjModules objmodules; // ObjModule[]
ObjSymbols objsymbols; // ObjSymbol[]
StringTable tab;
Library();
void setFilename(char *dir, char *filename);
void addObject(const char *module_name, void *buf, size_t buflen);
void addLibrary(void *buf, size_t buflen);
void write();
private:
void addSymbol(ObjModule *om, char *name, int pickAny = 0);
void scanObjModule(ObjModule *om);
unsigned short numDictPages(unsigned padding);
int FillDict(unsigned char *bucketsP, unsigned short uNumPages);
void WriteLibToBuffer(OutBuffer *libbuf);
void error(const char *format, ...)
{
Loc loc;
if (libfile)
{
loc.filename = libfile->name->toChars();
loc.linnum = 0;
}
va_list ap;
va_start(ap, format);
::verror(loc, format, ap);
va_end(ap);
}
virtual void setFilename(char *dir, char *filename) = 0;
virtual void addObject(const char *module_name, void *buf, size_t buflen) = 0;
virtual void addLibrary(void *buf, size_t buflen) = 0;
virtual void write() = 0;
};
#endif /* DMD_LIB_H */
+43 -37
View File
@@ -101,12 +101,12 @@ Global::Global()
"\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates.";
#endif
;
version = "v2.059";
version = "v2.060";
#if IN_LLVM
ldc_version = "LDC trunk";
llvm_version = "LLVM "LDC_LLVM_VERSION_STRING;
#endif
global.structalign = 8;
global.structalign = STRUCTALIGN_DEFAULT;
// This should only be used as a global, so the other fields are
// automatically initialized to zero when the program is loaded.
@@ -197,7 +197,7 @@ void errorSupplemental(Loc loc, const char *format, ...)
va_end( ap );
}
void verror(Loc loc, const char *format, va_list ap)
void verror(Loc loc, const char *format, va_list ap, const char *p1, const char *p2)
{
if (!global.gag)
{
@@ -208,16 +208,22 @@ void verror(Loc loc, const char *format, va_list ap)
mem.free(p);
fprintf(stdmsg, "Error: ");
if (p1)
fprintf(stdmsg, "%s ", p1);
if (p2)
fprintf(stdmsg, "%s ", p2);
#if _MSC_VER
// MS doesn't recognize %zu format
OutBuffer tmp;
tmp.vprintf(format, ap);
#if _MSC_VER
fprintf(stdmsg, "%s", tmp.toChars());
#else
vfprintf(stdmsg, format, ap);
#endif
fprintf(stdmsg, "\n");
fflush(stdmsg);
if (global.errors >= 20) // moderate blizzard of cascading messages
fatal();
//halt();
}
else
@@ -372,8 +378,8 @@ Usage:\n\
-version=level compile in version code >= level\n\
-version=ident compile in version code identified by ident\n\
-vtls list all variables going into thread local storage\n\
-w enable warnings\n\
-wi enable informational warnings\n\
-w warnings as errors (compilation will halt)\n\
-wi warnings as messages (compilation will continue)\n\
-X generate JSON file\n\
-Xffilename write JSON file to filename\n\
", fpic);
@@ -1040,7 +1046,7 @@ int tryMain(int argc, char *argv[])
{
for (size_t i = 0; i < global.params.fileImppath->dim; i++)
{
char *path = global.params.fileImppath->tdata()[i];
char *path = (*global.params.fileImppath)[i];
Strings *a = FileName::splitPath(path);
if (a)
@@ -1061,7 +1067,7 @@ int tryMain(int argc, char *argv[])
char *ext;
char *name;
p = files.tdata()[i];
p = files[i];
#if _WIN32
// Convert / to \ so linker will work
@@ -1079,47 +1085,47 @@ int tryMain(int argc, char *argv[])
*/
if (FileName::equals(ext, global.obj_ext))
{
global.params.objfiles->push(files.tdata()[i]);
libmodules.push(files.tdata()[i]);
global.params.objfiles->push(files[i]);
libmodules.push(files[i]);
continue;
}
if (FileName::equals(ext, global.lib_ext))
{
global.params.libfiles->push(files.tdata()[i]);
libmodules.push(files.tdata()[i]);
global.params.libfiles->push(files[i]);
libmodules.push(files[i]);
continue;
}
if (strcmp(ext, global.ddoc_ext) == 0)
{
global.params.ddocfiles->push(files.tdata()[i]);
global.params.ddocfiles->push(files[i]);
continue;
}
if (FileName::equals(ext, global.json_ext))
{
global.params.doXGeneration = 1;
global.params.xfilename = files.tdata()[i];
global.params.xfilename = files[i];
continue;
}
if (FileName::equals(ext, global.map_ext))
{
global.params.mapfile = files.tdata()[i];
global.params.mapfile = files[i];
continue;
}
#if TARGET_WINDOS
if (FileName::equals(ext, "res"))
{
global.params.resfile = files.tdata()[i];
global.params.resfile = files[i];
continue;
}
if (FileName::equals(ext, "def"))
{
global.params.deffile = files.tdata()[i];
global.params.deffile = files[i];
continue;
}
@@ -1134,10 +1140,7 @@ int tryMain(int argc, char *argv[])
*/
if (FileName::equals(ext, global.mars_ext) ||
FileName::equals(ext, global.hdr_ext) ||
FileName::equals(ext, "dd") ||
FileName::equals(ext, "htm") ||
FileName::equals(ext, "html") ||
FileName::equals(ext, "xhtml"))
FileName::equals(ext, "dd"))
{
ext--; // skip onto '.'
assert(*ext == '.');
@@ -1150,7 +1153,7 @@ int tryMain(int argc, char *argv[])
strcmp(name, ".") == 0)
{
Linvalid:
error(0, "invalid file name '%s'", files.tdata()[i]);
error(0, "invalid file name '%s'", files[i]);
fatal();
}
}
@@ -1232,7 +1235,7 @@ int tryMain(int argc, char *argv[])
// Remove m's object file from list of object files
for (size_t j = 0; j < global.params.objfiles->dim; j++)
{
if (m->objfile->name->str == global.params.objfiles->tdata()[j])
if (m->objfile->name->str == (*global.params.objfiles)[j])
{
global.params.objfiles->remove(j);
break;
@@ -1322,24 +1325,13 @@ int tryMain(int argc, char *argv[])
if (global.errors)
fatal();
if (global.params.moduleDeps != NULL)
{
assert(global.params.moduleDepsFile != NULL);
File deps(global.params.moduleDepsFile);
OutBuffer* ob = global.params.moduleDeps;
deps.setbuffer((void*)ob->data, ob->offset);
deps.writev();
}
// Scan for functions to inline
if (global.params.useInline)
{
/* The problem with useArrayBounds and useAssert is that the
* module being linked to may not have generated them, so if
* we inline functions from those modules, the symbols for them will
* not be found at link time.
* We must do this BEFORE generating the .deps file!
*/
if (!global.params.useArrayBounds && !global.params.useAssert)
{
@@ -1355,7 +1347,21 @@ int tryMain(int argc, char *argv[])
if (global.errors)
fatal();
}
}
if (global.params.moduleDeps != NULL)
{
assert(global.params.moduleDepsFile != NULL);
File deps(global.params.moduleDepsFile);
OutBuffer* ob = global.params.moduleDeps;
deps.setbuffer((void*)ob->data, ob->offset);
deps.writev();
}
// Scan for functions to inline
if (global.params.useInline)
{
for (size_t i = 0; i < modules.dim; i++)
{
m = modules[i];
@@ -1374,7 +1380,7 @@ int tryMain(int argc, char *argv[])
Library *library = NULL;
if (global.params.lib)
{
library = new Library();
library = Library::factory();
library->setFilename(global.params.objdir, global.params.libname);
// Add input object and input library files to output library
@@ -1405,7 +1411,7 @@ int tryMain(int argc, char *argv[])
}
if (!global.errors && modules.dim)
{
obj_end(library, modules.tdata()[0]->objfile);
obj_end(library, modules[0]->objfile);
}
}
else
+13 -5
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -97,11 +97,13 @@ void unittests();
#define DMDV1 0
#define DMDV2 1 // Version 2.0 features
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
#define STRUCTTHISREF DMDV2 // if 'this' for struct is a reference, not a pointer
#define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN
#define SARRAYVALUE DMDV2 // static arrays are value types
#define MODULEINFO_IS_STRUCT DMDV2 // if ModuleInfo is a struct rather than a class
#define BUG6652 1 // Making foreach range statement parameter non-ref in default
// 1: Modifying iteratee in body is warned with -w switch
// 2: Modifying iteratee in body is error without -d switch
// Set if C++ mangling is done by the front end
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS))
@@ -279,6 +281,10 @@ struct Param
#endif
};
typedef unsigned structalign_t;
#define STRUCTALIGN_DEFAULT ~0 // magic value means "match whatever the underlying C compiler does"
// other values are all powers of 2
struct Global
{
const char *mars_ext;
@@ -303,7 +309,9 @@ struct Global
const char *written;
Strings *path; // Array of char*'s which form the import lookup path
Strings *filePath; // Array of char*'s which form the file import lookup path
int structalign;
structalign_t structalign; // default alignment for struct fields
const char *version;
#if IN_LLVM
char *ldc_version;
@@ -475,7 +483,7 @@ typedef uint64_t StorageClass;
void warning(Loc loc, const char *format, ...) IS_PRINTF(2);
void error(Loc loc, const char *format, ...) IS_PRINTF(2);
void errorSupplemental(Loc loc, const char *format, ...);
void verror(Loc loc, const char *format, va_list);
void verror(Loc loc, const char *format, va_list, const char *p1 = NULL, const char *p2 = NULL);
void vwarning(Loc loc, const char *format, va_list);
void verrorSupplemental(Loc loc, const char *format, va_list);
void fatal();
@@ -495,7 +503,7 @@ void util_progress();
#endif
/*** Where to send error messages ***/
#if IN_GCC || IN_LLVM
#if defined(IN_GCC) || IN_LLVM
#define stdmsg stderr
#else
#define stdmsg stderr
+35 -62
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -20,7 +20,7 @@
#include <malloc.h>
#endif
#if IN_GCC
#ifdef IN_GCC
#include "gdc_alloca.h"
#endif
@@ -37,7 +37,10 @@
#include "hdrgen.h"
#include "lexer.h"
#include "html.h"
// stricmp
#if __GNUC__ && !_WIN32
#include "gnuc.h"
#endif
#ifdef IN_GCC
#include "d-dmd-gcc.h"
@@ -88,7 +91,6 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
errors = 0;
numlines = 0;
members = NULL;
isHtml = 0;
isDocFile = 0;
needmoduleinfo = 0;
#ifdef IN_GCC
@@ -146,17 +148,8 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
!srcfilename->equalsExt(global.hdr_ext) &&
!srcfilename->equalsExt("dd"))
{
if (srcfilename->equalsExt("html") ||
srcfilename->equalsExt("htm") ||
srcfilename->equalsExt("xhtml"))
{ if (!global.params.useDeprecated)
error("html source files is deprecated %s", srcfilename->toChars());
isHtml = 1;
}
else
{ error("source file name '%s' must have .%s extension", srcfilename->toChars(), global.mars_ext);
fatal();
}
error("source file name '%s' must have .%s extension", srcfilename->toChars(), global.mars_ext);
fatal();
}
#if !IN_LLVM
char *argobj;
@@ -438,7 +431,7 @@ Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
OutBuffer buf;
for (size_t i = 0; i < packages->dim; i++)
{ Identifier *pid = packages->tdata()[i];
{ Identifier *pid = (*packages)[i];
buf.writestring(pid->toChars());
#if _WIN32
@@ -499,7 +492,7 @@ Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
if (packages)
{
for (size_t i = 0; i < packages->dim; i++)
{ Identifier *pid = packages->tdata()[i];
{ Identifier *pid = (*packages)[i];
printf("%s.", pid->toChars());
}
}
@@ -530,7 +523,7 @@ bool Module::read(Loc loc)
{
for (size_t i = 0; i < global.path->dim; i++)
{
char *p = global.path->tdata()[i];
char *p = (*global.path)[i];
fprintf(stdmsg, "import path[%llu] = %s\n", (ulonglong)i, p);
}
}
@@ -579,24 +572,17 @@ inline unsigned readlongBE(unsigned *p)
#if IN_LLVM
void Module::parse(bool gen_docs)
#elif IN_GCC
void Module::parse(bool dump_source)
#else
void Module::parse()
#endif
{ char *srcname;
unsigned char *buf;
unsigned buflen;
unsigned le;
unsigned bom;
{
//printf("Module::parse()\n");
srcname = srcfile->name->toChars();
char *srcname = srcfile->name->toChars();
//printf("Module::parse(srcname = '%s')\n", srcname);
buf = srcfile->buffer;
buflen = srcfile->len;
unsigned char *buf = srcfile->buffer;
unsigned buflen = srcfile->len;
if (buflen >= 2)
{
@@ -609,7 +595,8 @@ void Module::parse()
* EF BB BF UTF-8
*/
bom = 1; // assume there's a BOM
unsigned le;
unsigned bom = 1; // assume there's a BOM
if (buf[0] == 0xFF && buf[1] == 0xFE)
{
if (buflen >= 4 && buf[2] == 0 && buf[3] == 0)
@@ -760,7 +747,7 @@ void Module::parse()
#ifdef IN_GCC
// dump utf-8 encoded source
if (dump_source)
if (global.params.dump_source)
{ // %% srcname could contain a path ...
d_gcc_dump_source(srcname, "utf-8", buf, buflen);
}
@@ -779,19 +766,6 @@ void Module::parse()
#endif
return;
}
if (isHtml)
{
OutBuffer *dbuf = new OutBuffer();
Html h(srcname, buf, buflen);
h.extractCode(dbuf);
buf = dbuf->data;
buflen = dbuf->offset;
#ifdef IN_GCC
// dump extracted source
if (dump_source)
d_gcc_dump_source(srcname, "d.utf-8", buf, buflen);
#endif
}
#if IN_LLVM
Parser p(this, buf, buflen, gen_docs);
#else
@@ -890,7 +864,7 @@ void Module::importAll(Scope *prevsc)
symtab = new DsymbolTable();
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
s->addMember(NULL, sc->scopesym, 1);
}
}
@@ -903,13 +877,13 @@ void Module::importAll(Scope *prevsc)
*/
setScope(sc); // remember module scope for semantic
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
s->setScope(sc);
}
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
s->importAll(sc);
}
@@ -964,7 +938,7 @@ void Module::semantic(Scope* unused_sc)
// Do semantic() on members that don't depend on others
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
//printf("\tModule('%s'): '%s'.semantic0()\n", toChars(), s->toChars());
s->semantic0(sc);
@@ -972,7 +946,7 @@ void Module::semantic(Scope* unused_sc)
// Pass 1 semantic routines: do public side of the definition
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
//printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars());
s->semantic(sc);
@@ -993,7 +967,7 @@ void Module::semantic2(Scope* unused_sc)
{
for (size_t i = 0; i < deferred.dim; i++)
{
Dsymbol *sd = deferred.tdata()[i];
Dsymbol *sd = deferred[i];
sd->error("unable to resolve forward reference in definition");
}
@@ -1017,7 +991,7 @@ void Module::semantic2(Scope* unused_sc)
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s;
s = members->tdata()[i];
s = (*members)[i];
s->semantic2(sc);
}
@@ -1045,7 +1019,7 @@ void Module::semantic3(Scope* unused_sc)
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s;
s = members->tdata()[i];
s = (*members)[i];
//printf("Module %s: %s.semantic3()\n", toChars(), s->toChars());
s->semantic3(sc);
}
@@ -1068,7 +1042,7 @@ void Module::inlineScan()
//printf("Module = %p\n", sc.scopesym);
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
//if (global.params.verbose)
//printf("inline scan symbol %s\n", s->toChars());
@@ -1093,7 +1067,7 @@ void Module::gensymfile()
buf.writenl();
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = members->tdata()[i];
{ Dsymbol *s = (*members)[i];
s->toCBuffer(&buf, &hgs);
}
@@ -1154,7 +1128,7 @@ Dsymbol *Module::symtabInsert(Dsymbol *s)
void Module::clearCache()
{
for (size_t i = 0; i < amodules.dim; i++)
{ Module *m = amodules.tdata()[i];
{ Module *m = amodules[i];
m->searchCacheIdent = NULL;
}
}
@@ -1168,7 +1142,7 @@ void Module::addDeferredSemantic(Dsymbol *s)
// Don't add it if it is already there
for (size_t i = 0; i < deferred.dim; i++)
{
Dsymbol *sd = deferred.tdata()[i];
Dsymbol *sd = deferred[i];
if (sd == s)
return;
@@ -1238,7 +1212,6 @@ void Module::runDeferredSemantic()
int Module::imports(Module *m)
{
//printf("%s Module::imports(%s)\n", toChars(), m->toChars());
int aimports_dim = aimports.dim;
#if 0
for (size_t i = 0; i < aimports.dim; i++)
{ Module *mi = (Module *)aimports.data[i];
@@ -1246,7 +1219,7 @@ int Module::imports(Module *m)
}
#endif
for (size_t i = 0; i < aimports.dim; i++)
{ Module *mi = aimports.tdata()[i];
{ Module *mi = aimports[i];
if (mi == m)
return TRUE;
if (!mi->insearch)
@@ -1270,7 +1243,7 @@ int Module::selfImports()
if (!selfimports)
{
for (size_t i = 0; i < amodules.dim; i++)
{ Module *mi = amodules.tdata()[i];
{ Module *mi = amodules[i];
//printf("\t[%d] %s\n", i, mi->toChars());
mi->insearch = 0;
}
@@ -1278,7 +1251,7 @@ int Module::selfImports()
selfimports = imports(this) + 1;
for (size_t i = 0; i < amodules.dim; i++)
{ Module *mi = amodules.tdata()[i];
{ Module *mi = amodules[i];
//printf("\t[%d] %s\n", i, mi->toChars());
mi->insearch = 0;
}
@@ -1303,7 +1276,7 @@ char *ModuleDeclaration::toChars()
if (packages && packages->dim)
{
for (size_t i = 0; i < packages->dim; i++)
{ Identifier *pid = packages->tdata()[i];
{ Identifier *pid = (*packages)[i];
buf.writestring(pid->toChars());
buf.writeByte('.');
@@ -1340,7 +1313,7 @@ DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package
if (packages)
{
for (size_t i = 0; i < packages->dim; i++)
{ Identifier *pid = packages->tdata()[i];
{ Identifier *pid = (*packages)[i];
Dsymbol *p;
p = dst->lookup(pid);
-3
View File
@@ -79,7 +79,6 @@ struct Module : Package
unsigned errors; // if any errors in file
unsigned numlines; // number of lines in source file
int isHtml; // if it is an HTML file
int isDocFile; // if it is a documentation input file, not D source
int needmoduleinfo;
#ifdef IN_GCC
@@ -141,8 +140,6 @@ struct Module : Package
bool read(Loc loc); // read file, returns 'true' if succeed, 'false' otherwise.
#if IN_LLVM
void parse(bool gen_docs = false); // syntactic parse
#elif IN_GCC
void parse(bool dump_source = false); // syntactic parse
#else
void parse(); // syntactic parse
#endif
+283 -193
View File
File diff suppressed because it is too large Load Diff
+11 -6
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2010 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -48,7 +48,7 @@ struct HdrGenState;
struct Parameter;
// Back end
#if IN_GCC
#ifdef IN_GCC
union tree_node; typedef union tree_node TYPE;
typedef TYPE type;
#endif
@@ -215,6 +215,7 @@ struct Type : Object
static ClassDeclaration *typeinfowild;
static TemplateDeclaration *associativearray;
static TemplateDeclaration *rtinfo;
static Type *basic[TMAX];
static unsigned char mangleChar[TMAX];
@@ -317,8 +318,8 @@ struct Type : Object
virtual ClassDeclaration *isClassHandle();
virtual Expression *getProperty(Loc loc, Identifier *ident);
virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
virtual structalign_t alignment();
Expression *noMember(Scope *sc, Expression *e, Identifier *ident);
virtual unsigned memalign(unsigned salign);
virtual Expression *defaultInit(Loc loc = 0);
virtual Expression *defaultInitLiteral(Loc loc);
virtual Expression *voidInitLiteral(VarDeclaration *var);
@@ -375,6 +376,7 @@ struct TypeError : Type
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
Expression *defaultInit(Loc loc);
Expression *defaultInitLiteral(Loc loc);
TypeTuple *toArgTypes();
};
struct TypeNext : Type
@@ -409,7 +411,7 @@ struct TypeBasic : Type
d_uns64 size(Loc loc);
unsigned alignsize();
#if IN_LLVM
unsigned memalign(unsigned salign);
unsigned alignment();
#endif
Expression *getProperty(Loc loc, Identifier *ident);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
@@ -488,7 +490,7 @@ struct TypeSArray : TypeArray
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
int isString();
int isZeroInit(Loc loc);
unsigned memalign(unsigned salign);
structalign_t alignment();
MATCH constConv(Type *to);
MATCH implicitConvTo(Type *to);
Expression *defaultInit(Loc loc);
@@ -567,6 +569,7 @@ struct TypeAArray : TypeArray
int isZeroInit(Loc loc);
int checkBoolean();
TypeInfoDeclaration *getTypeInfoDeclaration();
Type *reliesOnTident(TemplateParameters *tparams);
Expression *toExpression();
int hasPointers();
TypeTuple *toArgTypes();
@@ -778,6 +781,7 @@ struct TypeInstance : TypeQualified
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
Type *semantic(Loc loc, Scope *sc);
Dsymbol *toDsymbol(Scope *sc);
Type *reliesOnTident(TemplateParameters *tparams = NULL);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = NULL);
};
@@ -817,7 +821,7 @@ struct TypeStruct : Type
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
unsigned memalign(unsigned salign);
structalign_t alignment();
Expression *defaultInit(Loc loc);
Expression *defaultInitLiteral(Loc loc);
Expression *voidInitLiteral(VarDeclaration *var);
@@ -907,6 +911,7 @@ struct TypeTypedef : Type
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
structalign_t alignment();
Expression *getProperty(Loc loc, Identifier *ident);
int isintegral();
int isfloating();
+91 -60
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -12,6 +12,7 @@
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#include <string.h> // memset()
#if _MSC_VER
#include <complex>
#else
@@ -355,9 +356,11 @@ Expression *UnaExp::op_overload(Scope *sc)
/* Rewrite op(e1) as:
* op(e1.aliasthis)
*/
UnaExp *e = (UnaExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad->aliasthis->ident);
return e->trySemantic(sc);
Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
Expression *e = copy();
((UnaExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
}
#endif
}
@@ -374,7 +377,7 @@ Expression *ArrayExp::op_overload(Scope *sc)
if (fd)
{
for (size_t i = 0; i < arguments->dim; i++)
{ Expression *x = arguments->tdata()[i];
{ Expression *x = (*arguments)[i];
// Create scope for '$' variable for this dimension
ArrayScopeSymbol *sym = new ArrayScopeSymbol(sc, this);
sym->loc = loc;
@@ -393,7 +396,7 @@ Expression *ArrayExp::op_overload(Scope *sc)
x = new CommaExp(0, av, x);
x->semantic(sc);
}
arguments->tdata()[i] = x;
(*arguments)[i] = x;
sc = sc->pop();
}
@@ -412,9 +415,11 @@ Expression *ArrayExp::op_overload(Scope *sc)
/* Rewrite op(e1) as:
* op(e1.aliasthis)
*/
UnaExp *e = (UnaExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad->aliasthis->ident);
return e->trySemantic(sc);
Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
Expression *e = copy();
((UnaExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
}
}
return NULL;
@@ -457,9 +462,11 @@ Expression *CastExp::op_overload(Scope *sc)
/* Rewrite op(e1) as:
* op(e1.aliasthis)
*/
UnaExp *e = (UnaExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad->aliasthis->ident);
return e->trySemantic(sc);
Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
Expression *e = copy();
((UnaExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
}
}
return NULL;
@@ -529,9 +536,9 @@ Expression *BinExp::op_overload(Scope *sc)
*/
args1.setDim(1);
args1.tdata()[0] = e1;
args1[0] = e1;
args2.setDim(1);
args2.tdata()[0] = e2;
args2[0] = e2;
argsset = 1;
Match m;
@@ -622,9 +629,9 @@ L1:
if (!argsset)
{ args1.setDim(1);
args1.tdata()[0] = e1;
args1[0] = e1;
args2.setDim(1);
args2.tdata()[0] = e2;
args2[0] = e2;
}
Match m;
@@ -715,9 +722,11 @@ L1:
/* Rewrite (e1 op e2) as:
* (e1.aliasthis op e2)
*/
BinExp *e = (BinExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad1->aliasthis->ident);
return e->trySemantic(sc);
Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
}
// Try alias this on second operand
@@ -730,9 +739,11 @@ L1:
/* Rewrite (e1 op e2) as:
* (e1 op e2.aliasthis)
*/
BinExp *e = (BinExp *)syntaxCopy();
e->e2 = new DotIdExp(loc, e->e2, ad2->aliasthis->ident);
return e->trySemantic(sc);
Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e2 = e2;
e = e->trySemantic(sc);
return e;
}
#endif
return NULL;
@@ -776,9 +787,9 @@ Expression *BinExp::compare_overload(Scope *sc, Identifier *id)
Expressions args2;
args1.setDim(1);
args1.tdata()[0] = e1;
args1[0] = e1;
args2.setDim(1);
args2.tdata()[0] = e2;
args2[0] = e2;
Match m;
memset(&m, 0, sizeof(m));
@@ -884,9 +895,11 @@ Expression *BinExp::compare_overload(Scope *sc, Identifier *id)
/* Rewrite (e1 op e2) as:
* (e1.aliasthis op e2)
*/
BinExp *e = (BinExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad1->aliasthis->ident);
return e->trySemantic(sc);
Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
}
// Try alias this on second operand
@@ -895,9 +908,11 @@ Expression *BinExp::compare_overload(Scope *sc, Identifier *id)
/* Rewrite (e1 op e2) as:
* (e1 op e2.aliasthis)
*/
BinExp *e = (BinExp *)syntaxCopy();
e->e2 = new DotIdExp(loc, e->e2, ad2->aliasthis->ident);
return e->trySemantic(sc);
Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e2 = e2;
e = e->trySemantic(sc);
return e;
}
return NULL;
@@ -916,12 +931,20 @@ Expression *EqualExp::op_overload(Scope *sc)
if (!(cd1->isCPPinterface() || cd2->isCPPinterface()))
{
/* Rewrite as:
* .object.opEquals(cast(Object)e1, cast(Object)e2)
* .object.opEquals(e1, e2)
*/
Expression *e1x = e1;
Expression *e2x = e2;
/*
* The explicit cast is necessary for interfaces,
* see http://d.puremagic.com/issues/show_bug.cgi?id=4088
*/
Expression *e1x = new CastExp(loc, e1, ClassDeclaration::object->getType());
Expression *e2x = new CastExp(loc, e2, ClassDeclaration::object->getType());
Type *to = ClassDeclaration::object->getType();
if (cd1->isInterfaceDeclaration())
e1x = new CastExp(loc, e1, t1->isMutable() ? to : to->constOf());
if (cd2->isInterfaceDeclaration())
e2x = new CastExp(loc, e2, t2->isMutable() ? to : to->constOf());
Expression *e = new IdentifierExp(loc, Id::empty);
e = new DotIdExp(loc, e, Id::object);
@@ -968,7 +991,7 @@ Expression *BinAssignExp::op_overload(Scope *sc)
Expressions *a = new Expressions();
a->push(e2);
for (size_t i = 0; i < ae->arguments->dim; i++)
a->push(ae->arguments->tdata()[i]);
a->push((*ae->arguments)[i]);
Objects *targsi = opToArg(sc, op);
Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, targsi);
@@ -1085,7 +1108,7 @@ Expression *BinAssignExp::op_overload(Scope *sc)
*/
args2.setDim(1);
args2.tdata()[0] = e2;
args2[0] = e2;
Match m;
memset(&m, 0, sizeof(m));
@@ -1132,9 +1155,11 @@ L1:
/* Rewrite (e1 op e2) as:
* (e1.aliasthis op e2)
*/
BinExp *e = (BinExp *)syntaxCopy();
e->e1 = new DotIdExp(loc, e->e1, ad1->aliasthis->ident);
return e->trySemantic(sc);
Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e1 = e1;
e = e->trySemantic(sc);
return e;
}
// Try alias this on second operand
@@ -1144,9 +1169,11 @@ L1:
/* Rewrite (e1 op e2) as:
* (e1 op e2.aliasthis)
*/
BinExp *e = (BinExp *)syntaxCopy();
e->e2 = new DotIdExp(loc, e->e2, ad2->aliasthis->ident);
return e->trySemantic(sc);
Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident);
Expression *e = copy();
((BinExp *)e)->e2 = e2;
e = e->trySemantic(sc);
return e;
}
#endif
return NULL;
@@ -1209,7 +1236,7 @@ int ForeachStatement::inferAggregate(Scope *sc, Dsymbol *&sapply)
{
Identifier *idapply = (op == TOKforeach) ? Id::apply : Id::applyReverse;
#if DMDV2
Identifier *idhead = (op == TOKforeach) ? Id::Ffront : Id::Fback;
Identifier *idfront = (op == TOKforeach) ? Id::Ffront : Id::Fback;
int sliced = 0;
#endif
Type *tab;
@@ -1262,7 +1289,7 @@ int ForeachStatement::inferAggregate(Scope *sc, Dsymbol *&sapply)
}
}
if (Dsymbol *shead = search_function(ad, idhead))
if (Dsymbol *shead = ad->search(0, idfront, 0))
{ // range aggregate
break;
}
@@ -1316,7 +1343,7 @@ int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
if (sapply) // prefer opApply
{
for (size_t u = 0; u < arguments->dim; u++)
{ Parameter *arg = arguments->tdata()[u];
{ Parameter *arg = (*arguments)[u];
if (arg->type)
arg->type = arg->type->semantic(loc, sc);
}
@@ -1350,14 +1377,14 @@ int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
/* Return if no arguments need types.
*/
for (size_t u = 0; u < arguments->dim; u++)
{ Parameter *arg = arguments->tdata()[u];
{ Parameter *arg = (*arguments)[u];
if (!arg->type)
break;
}
AggregateDeclaration *ad;
Parameter *arg = arguments->tdata()[0];
Parameter *arg = (*arguments)[0];
Type *taggr = aggr->type;
assert(taggr);
Type *tab = taggr->toBasetype();
@@ -1370,7 +1397,7 @@ int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
{
if (!arg->type)
arg->type = Type::tsize_t; // key type
arg = arguments->tdata()[1];
arg = (*arguments)[1];
}
if (!arg->type && tab->ty != Ttuple)
arg->type = tab->nextOf(); // value type
@@ -1383,7 +1410,7 @@ int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
{
if (!arg->type)
arg->type = taa->index; // key type
arg = arguments->tdata()[1];
arg = (*arguments)[1];
}
if (!arg->type)
arg->type = taa->next; // value type
@@ -1403,20 +1430,24 @@ int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
{
if (!arg->type)
{
/* Look for a head() or rear() overload
/* Look for a front() or back() overload
*/
Identifier *id = (op == TOKforeach) ? Id::Ffront : Id::Fback;
Dsymbol *s = search_function(ad, id);
Dsymbol *s = ad->search(0, id, 0);
FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL;
if (!fd)
{ if (s && s->isTemplateDeclaration())
break;
break;
if (fd)
{
// Resolve inout qualifier of front type
arg->type = fd->type->nextOf();
if (arg->type)
arg->type = arg->type->substWildTo(tab->mod);
}
// Resolve inout qualifier of front type
arg->type = fd->type->nextOf();
if (arg->type)
arg->type = arg->type->substWildTo(tab->mod);
else if (s && s->isTemplateDeclaration())
;
else if (s && s->isDeclaration())
arg->type = ((Declaration *)s)->type;
else
break;
}
break;
}
@@ -1522,7 +1553,7 @@ static int inferApplyArgTypesY(TypeFunction *tf, Parameters *arguments, int flag
for (size_t u = 0; u < nparams; u++)
{
Parameter *arg = arguments->tdata()[u];
Parameter *arg = (*arguments)[u];
Parameter *param = Parameter::getNth(tf->parameters, u);
if (arg->type)
{ if (!arg->type->equals(param->type))
@@ -1560,7 +1591,7 @@ void inferApplyArgTypesZ(TemplateDeclaration *tstart, Parameters *arguments)
}
if (!td->parameters || td->parameters->dim != 1)
continue;
TemplateParameter *tp = td->parameters->tdata()[0];
TemplateParameter *tp = (*td->parameters)[0];
TemplateAliasParameter *tap = tp->isTemplateAliasParameter();
if (!tap || !tap->specType || tap->specType->ty != Tfunction)
continue;
+16 -17
View File
@@ -153,7 +153,6 @@ Expression *fromConstInitializer(int result, Expression *e1)
if (e1->op == TOKvar)
{ VarExp *ve = (VarExp *)e1;
VarDeclaration *v = ve->var->isVarDeclaration();
int fwdref = (v && !v->originalType && v->scope);
e = expandVar(result, v);
if (e)
{
@@ -202,10 +201,10 @@ Expression *VarExp::optimize(int result)
Expression *TupleExp::optimize(int result)
{
for (size_t i = 0; i < exps->dim; i++)
{ Expression *e = exps->tdata()[i];
{ Expression *e = (*exps)[i];
e = e->optimize(WANTvalue | (result & WANTinterpret));
exps->tdata()[i] = e;
(*exps)[i] = e;
}
return this;
}
@@ -215,10 +214,10 @@ Expression *ArrayLiteralExp::optimize(int result)
if (elements)
{
for (size_t i = 0; i < elements->dim; i++)
{ Expression *e = elements->tdata()[i];
{ Expression *e = (*elements)[i];
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
elements->tdata()[i] = e;
(*elements)[i] = e;
}
}
return this;
@@ -228,14 +227,14 @@ Expression *AssocArrayLiteralExp::optimize(int result)
{
assert(keys->dim == values->dim);
for (size_t i = 0; i < keys->dim; i++)
{ Expression *e = keys->tdata()[i];
{ Expression *e = (*keys)[i];
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
keys->tdata()[i] = e;
(*keys)[i] = e;
e = values->tdata()[i];
e = (*values)[i];
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
values->tdata()[i] = e;
(*values)[i] = e;
}
return this;
}
@@ -245,11 +244,11 @@ Expression *StructLiteralExp::optimize(int result)
if (elements)
{
for (size_t i = 0; i < elements->dim; i++)
{ Expression *e = elements->tdata()[i];
{ Expression *e = (*elements)[i];
if (!e)
continue;
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
elements->tdata()[i] = e;
(*elements)[i] = e;
}
}
return this;
@@ -495,20 +494,20 @@ Expression *NewExp::optimize(int result)
if (newargs)
{
for (size_t i = 0; i < newargs->dim; i++)
{ Expression *e = newargs->tdata()[i];
{ Expression *e = (*newargs)[i];
e = e->optimize(WANTvalue);
newargs->tdata()[i] = e;
(*newargs)[i] = e;
}
}
if (arguments)
{
for (size_t i = 0; i < arguments->dim; i++)
{ Expression *e = arguments->tdata()[i];
{ Expression *e = (*arguments)[i];
e = e->optimize(WANTvalue);
arguments->tdata()[i] = e;
(*arguments)[i] = e;
}
}
if (result & WANTinterpret)
@@ -527,10 +526,10 @@ Expression *CallExp::optimize(int result)
if (arguments)
{
for (size_t i = 0; i < arguments->dim; i++)
{ Expression *e = arguments->tdata()[i];
{ Expression *e = (*arguments)[i];
e = e->optimize(WANTvalue);
arguments->tdata()[i] = e;
(*arguments)[i] = e;
}
}
+32 -11
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -12,6 +12,7 @@
#include <stdio.h>
#include <assert.h>
#include <string.h> // strlen(),memcpy()
#include "rmem.h"
#include "lexer.h"
@@ -454,7 +455,10 @@ Dsymbols *Parser::parseDeclDefs(int once)
((tk = peek(tk)), 1) &&
skipAttributes(tk, &tk) &&
(tk->value == TOKlparen ||
tk->value == TOKlcurly)
tk->value == TOKlcurly ||
tk->value == TOKin ||
tk->value == TOKout ||
tk->value == TOKbody)
)
{
a = parseDeclarations(storageClass, comment);
@@ -512,7 +516,11 @@ Dsymbols *Parser::parseDeclDefs(int once)
{
nextToken();
if (token.value == TOKint32v && token.uns64value > 0)
{
if (token.uns64value & (token.uns64value - 1))
error("align(%s) must be a power of 2", token.toChars());
n = (unsigned)token.uns64value;
}
else
{ error("positive integer expected, not %s", token.toChars());
n = 1;
@@ -535,7 +543,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
nextToken();
check(TOKlparen);
if (token.value != TOKidentifier)
{ error("pragma(identifier expected");
{ error("pragma(identifier) expected");
goto Lerror;
}
ident = token.ident;
@@ -1370,7 +1378,8 @@ Parameters *Parser::parseParameters(int *pvarargs, TemplateParameters **tpl)
default:
Ldefault:
{ stc = storageClass & (STCin | STCout | STCref | STClazy);
if (stc & (stc - 1)) // if stc is not a power of 2
if (stc & (stc - 1) && // if stc is not a power of 2
!(stc == (STCin | STCref)))
error("incompatible parameter storage classes");
if ((storageClass & (STCconst | STCout)) == (STCconst | STCout))
error("out cannot be const");
@@ -2860,7 +2869,10 @@ Dsymbols *Parser::parseDeclarations(StorageClass storage_class, unsigned char *c
((tk = peek(tk)), 1) &&
skipAttributes(tk, &tk) &&
(tk->value == TOKlparen ||
tk->value == TOKlcurly)
tk->value == TOKlcurly ||
tk->value == TOKin ||
tk->value == TOKout ||
tk->value == TOKbody)
)
{
ts = NULL;
@@ -3347,7 +3359,15 @@ Initializer *Parser::parseInitializer()
if (comma == 1)
error("comma expected separating array initializers, not %s", token.toChars());
value = parseInitializer();
ia->addInit(NULL, value);
if (token.value == TOKcolon)
{
nextToken();
e = value->toExpression();
value = parseInitializer();
}
else
e = NULL;
ia->addInit(e, value);
comma = 1;
continue;
@@ -3601,7 +3621,7 @@ Statement *Parser::parseStatement(int flags)
as->reserve(a->dim);
for (size_t i = 0; i < a->dim; i++)
{
Dsymbol *d = a->tdata()[i];
Dsymbol *d = (*a)[i];
s = new ExpStatement(loc, d);
as->push(s);
}
@@ -3609,7 +3629,7 @@ Statement *Parser::parseStatement(int flags)
}
else if (a->dim == 1)
{
Dsymbol *d = a->tdata()[0];
Dsymbol *d = (*a)[0];
s = new ExpStatement(loc, d);
}
else
@@ -3841,7 +3861,7 @@ Statement *Parser::parseStatement(int flags)
Expression *aggr = parseExpression();
if (token.value == TOKslice && arguments->dim == 1)
{
Parameter *a = arguments->tdata()[0];
Parameter *a = (*arguments)[0];
delete arguments;
nextToken();
Expression *upr = parseExpression();
@@ -4087,7 +4107,7 @@ Statement *Parser::parseStatement(int flags)
// Keep cases in order by building the case statements backwards
for (size_t i = cases.dim; i; i--)
{
exp = cases.tdata()[i - 1];
exp = cases[i - 1];
s = new CaseStatement(loc, exp, s);
}
}
@@ -4242,7 +4262,7 @@ Statement *Parser::parseStatement(int flags)
Loc loc = this->loc;
nextToken();
if (token.value == TOKlcurly)
if (token.value == TOKlcurly || token.value != TOKlparen)
{
t = NULL;
id = NULL;
@@ -5406,6 +5426,7 @@ Expression *Parser::parsePrimaryExp()
token.value == TOKenum ||
token.value == TOKinterface ||
token.value == TOKargTypes ||
token.value == TOKparameters ||
#if DMDV2
token.value == TOKconst && peek(&token)->value == TOKrparen ||
token.value == TOKinvariant && peek(&token)->value == TOKrparen ||
+3 -1
View File
@@ -12,7 +12,9 @@ of the D Programming Language defined in the documents at
http://www.digitalmars.com/d/
These sources are free, they are redistributable and modifiable
under the terms of the GNU General Public License (attached as gpl.txt),
under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option)
any later version (attached as gpl.txt),
or the Artistic License (attached as artistic.txt).
The optimizer and code generator sources are
+9
View File
@@ -1,3 +1,12 @@
// Copyright (c) 2010-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
/**
* Implementation of associative arrays.
*
+8
View File
@@ -1,4 +1,12 @@
// Copyright (c) 2010-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
typedef void* Value;
typedef void* Key;
-1
View File
@@ -40,7 +40,6 @@
#include "port.h"
#include "root.h"
#include "dchar.h"
#include "rmem.h"
+8
View File
@@ -1,4 +1,12 @@
// Copyright (c) 2009-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#define _MT 1
#include <stdio.h>
-482
View File
@@ -1,482 +0,0 @@
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <assert.h>
#include "dchar.h"
#include "rmem.h"
#if M_UNICODE
// Converts a char string to Unicode
dchar *Dchar::dup(char *p)
{
dchar *s;
size_t len;
if (!p)
return NULL;
len = strlen(p);
s = (dchar *)mem.malloc((len + 1) * sizeof(dchar));
for (unsigned i = 0; i < len; i++)
{
s[i] = (dchar)(p[i] & 0xFF);
}
s[len] = 0;
return s;
}
dchar *Dchar::memchr(dchar *p, int c, int count)
{
int u;
for (u = 0; u < count; u++)
{
if (p[u] == c)
return p + u;
}
return NULL;
}
#if _WIN32 && __DMC__
__declspec(naked)
unsigned Dchar::calcHash(const dchar *str, unsigned len)
{
__asm
{
mov ECX,4[ESP]
mov EDX,8[ESP]
xor EAX,EAX
test EDX,EDX
je L92
LC8: cmp EDX,1
je L98
cmp EDX,2
je LAE
add EAX,[ECX]
// imul EAX,EAX,025h
lea EAX,[EAX][EAX*8]
add ECX,4
sub EDX,2
jmp LC8
L98: mov DX,[ECX]
and EDX,0FFFFh
add EAX,EDX
ret
LAE: add EAX,[ECX]
L92: ret
}
}
#else
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
unsigned hash = 0;
for (;;)
{
switch (len)
{
case 0:
return hash;
case 1:
hash += *(const uint16_t *)str;
return hash;
case 2:
hash += *(const uint32_t *)str;
return hash;
default:
hash += *(const uint32_t *)str;
hash *= 37;
str += 2;
len -= 2;
break;
}
}
}
#endif
hash_t Dchar::icalcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
for (;;)
{
switch (len)
{
case 0:
return hash;
case 1:
hash += *(const uint16_t *)str | 0x20;
return hash;
case 2:
hash += *(const uint32_t *)str | 0x200020;
return hash;
default:
hash += *(const uint32_t *)str | 0x200020;
hash *= 37;
str += 2;
len -= 2;
break;
}
}
}
#elif MCBS
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str;
return hash;
case 2:
hash *= 37;
hash += *(const uint16_t *)str;
return hash;
case 3:
hash *= 37;
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
return hash;
default:
hash *= 37;
hash += *(const uint32_t *)str;
str += 4;
len -= 4;
break;
}
}
}
#elif UTF8
// Specification is: http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335
char Dchar::mblen[256] =
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1,
};
dchar *Dchar::dec(dchar *pstart, dchar *p)
{
while ((p[-1] & 0xC0) == 0x80)
p--;
return p;
}
int Dchar::get(dchar *p)
{
unsigned c;
unsigned char *q = (unsigned char *)p;
c = q[0];
switch (mblen[c])
{
case 2:
c = ((c - 0xC0) << 6) |
(q[1] - 0x80);
break;
case 3:
c = ((c - 0xE0) << 12) |
((q[1] - 0x80) << 6) |
(q[2] - 0x80);
break;
case 4:
c = ((c - 0xF0) << 18) |
((q[1] - 0x80) << 12) |
((q[2] - 0x80) << 6) |
(q[3] - 0x80);
break;
case 5:
c = ((c - 0xF8) << 24) |
((q[1] - 0x80) << 18) |
((q[2] - 0x80) << 12) |
((q[3] - 0x80) << 6) |
(q[4] - 0x80);
break;
case 6:
c = ((c - 0xFC) << 30) |
((q[1] - 0x80) << 24) |
((q[2] - 0x80) << 18) |
((q[3] - 0x80) << 12) |
((q[4] - 0x80) << 6) |
(q[5] - 0x80);
break;
}
return c;
}
dchar *Dchar::put(dchar *p, unsigned c)
{
if (c <= 0x7F)
{
*p++ = c;
}
else if (c <= 0x7FF)
{
p[0] = 0xC0 + (c >> 6);
p[1] = 0x80 + (c & 0x3F);
p += 2;
}
else if (c <= 0xFFFF)
{
p[0] = 0xE0 + (c >> 12);
p[1] = 0x80 + ((c >> 6) & 0x3F);
p[2] = 0x80 + (c & 0x3F);
p += 3;
}
else if (c <= 0x1FFFFF)
{
p[0] = 0xF0 + (c >> 18);
p[1] = 0x80 + ((c >> 12) & 0x3F);
p[2] = 0x80 + ((c >> 6) & 0x3F);
p[3] = 0x80 + (c & 0x3F);
p += 4;
}
else if (c <= 0x3FFFFFF)
{
p[0] = 0xF8 + (c >> 24);
p[1] = 0x80 + ((c >> 18) & 0x3F);
p[2] = 0x80 + ((c >> 12) & 0x3F);
p[3] = 0x80 + ((c >> 6) & 0x3F);
p[4] = 0x80 + (c & 0x3F);
p += 5;
}
else if (c <= 0x7FFFFFFF)
{
p[0] = 0xFC + (c >> 30);
p[1] = 0x80 + ((c >> 24) & 0x3F);
p[2] = 0x80 + ((c >> 18) & 0x3F);
p[3] = 0x80 + ((c >> 12) & 0x3F);
p[4] = 0x80 + ((c >> 6) & 0x3F);
p[5] = 0x80 + (c & 0x3F);
p += 6;
}
else
assert(0); // not a UCS-4 character
return p;
}
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str;
return hash;
case 2:
hash *= 37;
#if LITTLE_ENDIAN
hash += *(const uint16_t *)str;
#else
hash += str[0] * 256 + str[1];
#endif
return hash;
case 3:
hash *= 37;
#if LITTLE_ENDIAN
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
#else
hash += (str[0] * 256 + str[1]) * 256 + str[2];
#endif
return hash;
default:
hash *= 37;
#if LITTLE_ENDIAN
hash += *(const uint32_t *)str;
#else
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
#endif
str += 4;
len -= 4;
break;
}
}
}
#else // ascii
hash_t Dchar::calcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str;
return hash;
case 2:
hash *= 37;
#if LITTLE_ENDIAN
hash += *(const uint16_t *)str;
#else
hash += str[0] * 256 + str[1];
#endif
return hash;
case 3:
hash *= 37;
#if LITTLE_ENDIAN
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
#else
hash += (str[0] * 256 + str[1]) * 256 + str[2];
#endif
return hash;
default:
hash *= 37;
#if LITTLE_ENDIAN
hash += *(const uint32_t *)str;
#else
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
#endif
str += 4;
len -= 4;
break;
}
}
}
hash_t Dchar::icalcHash(const dchar *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str | 0x20;
return hash;
case 2:
hash *= 37;
hash += *(const uint16_t *)str | 0x2020;
return hash;
case 3:
hash *= 37;
hash += ((*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2]) | 0x202020;
return hash;
default:
hash *= 37;
hash += *(const uint32_t *)str | 0x20202020;
str += 4;
len -= 4;
break;
}
}
}
#endif
#if 0
#include <stdio.h>
void main()
{
// Print out values to hardcode into Dchar::mblen[]
int c;
int s;
for (c = 0; c < 256; c++)
{
s = 1;
if (c >= 0xC0 && c <= 0xDF)
s = 2;
if (c >= 0xE0 && c <= 0xEF)
s = 3;
if (c >= 0xF0 && c <= 0xF7)
s = 4;
if (c >= 0xF8 && c <= 0xFB)
s = 5;
if (c >= 0xFC && c <= 0xFD)
s = 6;
printf("%d", s);
if ((c & 15) == 15)
printf(",\n");
else
printf(",");
}
}
#endif
-194
View File
@@ -1,194 +0,0 @@
// Copyright (c) 1999-2011 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef DCHAR_H
#define DCHAR_H
#if __GNUC__ && !_WIN32
#include "gnuc.h"
#endif
#if _MSC_VER
// Disable useless warnings about unreferenced functions
#pragma warning (disable : 4514)
#endif
//#include "root.h"
typedef size_t hash_t;
#undef TEXT
// NOTE: All functions accepting pointer arguments must not be NULL
#if M_UNICODE
#include <string.h>
#include <wchar.h>
typedef wchar_t dchar;
#define TEXT(x) L##x
#define Dchar_mbmax 1
struct Dchar
{
static dchar *inc(dchar *p) { return p + 1; }
static dchar *dec(dchar *pstart, dchar *p) { (void)pstart; return p - 1; }
static int len(const dchar *p) { return wcslen(p); }
static dchar get(dchar *p) { return *p; }
static dchar getprev(dchar *pstart, dchar *p) { (void)pstart; return p[-1]; }
static dchar *put(dchar *p, dchar c) { *p = c; return p + 1; }
static int cmp(dchar *s1, dchar *s2)
{
#if __DMC__
if (!*s1 && !*s2) // wcscmp is broken
return 0;
#endif
return wcscmp(s1, s2);
#if 0
return (*s1 == *s2)
? wcscmp(s1, s2)
: ((int)*s1 - (int)*s2);
#endif
}
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars * sizeof(dchar)); }
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
static int isAlpha(dchar c) { return iswalpha(c); }
static int isUpper(dchar c) { return iswupper(c); }
static int isLower(dchar c) { return iswlower(c); }
static int isLocaleUpper(dchar c) { return isUpper(c); }
static int isLocaleLower(dchar c) { return isLower(c); }
static int toLower(dchar c) { return isUpper(c) ? towlower(c) : c; }
static int toLower(dchar *p) { return toLower(*p); }
static int toUpper(dchar c) { return isLower(c) ? towupper(c) : c; }
static dchar *dup(dchar *p) { return ::_wcsdup(p); } // BUG: out of memory?
static dchar *dup(char *p);
static dchar *chr(dchar *p, unsigned c) { return wcschr(p, (dchar)c); }
static dchar *rchr(dchar *p, unsigned c) { return wcsrchr(p, (dchar)c); }
static dchar *memchr(dchar *p, int c, int count);
static dchar *cpy(dchar *s1, dchar *s2) { return wcscpy(s1, s2); }
static dchar *str(dchar *s1, dchar *s2) { return wcsstr(s1, s2); }
static hash_t calcHash(const dchar *str, size_t len);
// Case insensitive versions
static int icmp(dchar *s1, dchar *s2) { return wcsicmp(s1, s2); }
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::wcsnicmp(s1, s2, nchars); }
static hash_t icalcHash(const dchar *str, size_t len);
};
#elif MCBS
#include <limits.h>
#include <mbstring.h>
typedef char dchar;
#define TEXT(x) x
#define Dchar_mbmax MB_LEN_MAX
#elif UTF8
typedef char dchar;
#define TEXT(x) x
#define Dchar_mbmax 6
struct Dchar
{
static char mblen[256];
static dchar *inc(dchar *p) { return p + mblen[*p & 0xFF]; }
static dchar *dec(dchar *pstart, dchar *p);
static int len(const dchar *p) { return strlen(p); }
static int get(dchar *p);
static int getprev(dchar *pstart, dchar *p)
{ return *dec(pstart, p) & 0xFF; }
static dchar *put(dchar *p, unsigned c);
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
static int isAlpha(dchar c) { return c <= 0x7F ? isalpha(c) : 0; }
static int isUpper(dchar c) { return c <= 0x7F ? isupper(c) : 0; }
static int isLower(dchar c) { return c <= 0x7F ? islower(c) : 0; }
static int isLocaleUpper(dchar c) { return isUpper(c); }
static int isLocaleLower(dchar c) { return isLower(c); }
static int toLower(dchar c) { return isUpper(c) ? tolower(c) : c; }
static int toLower(dchar *p) { return toLower(*p); }
static int toUpper(dchar c) { return isLower(c) ? toupper(c) : c; }
static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory?
static dchar *chr(dchar *p, int c) { return strchr(p, c); }
static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
static dchar *memchr(dchar *p, int c, int count)
{ return (dchar *)::memchr(p, c, count); }
static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
static hash_t calcHash(const dchar *str, size_t len);
// Case insensitive versions
static int icmp(dchar *s1, dchar *s2) { return _mbsicmp(s1, s2); }
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::_mbsnicmp(s1, s2, nchars); }
};
#else
#include <string.h>
#ifndef GCC_SAFE_DMD
#include <ctype.h>
#endif
typedef char dchar;
#define TEXT(x) x
#define Dchar_mbmax 1
struct Dchar
{
static dchar *inc(dchar *p) { return p + 1; }
static dchar *dec(dchar *pstart, dchar *p) { (void)pstart; return p - 1; }
static int len(const dchar *p) { return strlen(p); }
static int get(dchar *p) { return *p & 0xFF; }
static int getprev(dchar *pstart, dchar *p) { (void)pstart; return p[-1] & 0xFF; }
static dchar *put(dchar *p, unsigned c) { *p = c; return p + 1; }
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
#ifndef GCC_SAFE_DMD
static int isAlpha(dchar c) { return isalpha((unsigned char)c); }
static int isUpper(dchar c) { return isupper((unsigned char)c); }
static int isLower(dchar c) { return islower((unsigned char)c); }
static int isLocaleUpper(dchar c) { return isupper((unsigned char)c); }
static int isLocaleLower(dchar c) { return islower((unsigned char)c); }
static int toLower(dchar c) { return isupper((unsigned char)c) ? tolower(c) : c; }
static int toLower(dchar *p) { return toLower(*p); }
static int toUpper(dchar c) { return islower((unsigned char)c) ? toupper(c) : c; }
static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory?
#endif
static dchar *chr(dchar *p, int c) { return strchr(p, c); }
static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
static dchar *memchr(dchar *p, int c, int count)
{ return (dchar *)::memchr(p, c, count); }
static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
static hash_t calcHash(const dchar *str, size_t len);
// Case insensitive versions
#ifdef __GNUC__
static int icmp(dchar *s1, dchar *s2) { return strcasecmp(s1, s2); }
#else
static int icmp(dchar *s1, dchar *s2) { return stricmp(s1, s2); }
#endif
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::memicmp(s1, s2, nchars); }
static hash_t icalcHash(const dchar *str, size_t len);
};
#endif
#endif
+8
View File
@@ -1,4 +1,12 @@
// Copyright (c) 2009-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
// Put functions in here missing from gnu C
#include "gnuc.h"
+8
View File
@@ -1,4 +1,12 @@
// Copyright (c) 2009-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef _GNUC_H
#define _GNUC_H 1
-63
View File
@@ -1,63 +0,0 @@
// lstring.c
// Copyright (c) 1999-2002 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdlib.h>
#include "dchar.h"
#include "rmem.h"
#include "lstring.h"
#ifdef _MSC_VER // prevent compiler internal crash
Lstring Lstring::zero;
#else
Lstring Lstring::zero = LSTRING_EMPTY();
#endif
Lstring *Lstring::ctor(const dchar *p, unsigned length)
{
Lstring *s;
s = alloc(length);
memcpy(s->string, p, length * sizeof(dchar));
return s;
}
Lstring *Lstring::alloc(unsigned length)
{
Lstring *s;
s = (Lstring *)mem.malloc(size(length));
s->length = length;
s->string[length] = 0;
return s;
}
Lstring *Lstring::append(const Lstring *s)
{
Lstring *t;
if (!s->length)
return this;
t = alloc(length + s->length);
memcpy(t->string, string, length * sizeof(dchar));
memcpy(t->string + length, s->string, s->length * sizeof(dchar));
return t;
}
Lstring *Lstring::substring(int start, int end)
{
Lstring *t;
if (start == end)
return &zero;
t = alloc(end - start);
memcpy(t->string, string + start, (end - start) * sizeof(dchar));
return t;
}
-74
View File
@@ -1,74 +0,0 @@
// lstring.h
// length-prefixed strings
// Copyright (c) 1999-2002 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef LSTRING_H
#define LSTRING_H 1
#include "dchar.h"
struct Lstring
{
unsigned length;
#ifndef IN_GCC
// Disable warning about nonstandard extension
#pragma warning (disable : 4200)
#endif
dchar string[];
static Lstring zero; // 0 length string
// No constructors because we want to be able to statically
// initialize Lstring's, and Lstrings are of variable size.
#if M_UNICODE
#define LSTRING(p,length) { length, L##p }
#else
#define LSTRING(p,length) { length, p }
#endif
#if __GNUC__
#define LSTRING_EMPTY() { 0 }
#else
#define LSTRING_EMPTY() LSTRING("", 0)
#endif
static Lstring *ctor(const dchar *p) { return ctor(p, Dchar::len(p)); }
static Lstring *ctor(const dchar *p, unsigned length);
static unsigned size(unsigned length) { return sizeof(Lstring) + (length + 1) * sizeof(dchar); }
static Lstring *alloc(unsigned length);
Lstring *clone();
unsigned len() { return length; }
dchar *toDchars() { return string; }
hash_t hash() { return Dchar::calcHash(string, length); }
hash_t ihash() { return Dchar::icalcHash(string, length); }
static int cmp(const Lstring *s1, const Lstring *s2)
{
int c = s2->length - s1->length;
return c ? c : Dchar::memcmp(s1->string, s2->string, s1->length);
}
static int icmp(const Lstring *s1, const Lstring *s2)
{
int c = s2->length - s1->length;
return c ? c : Dchar::memicmp(s1->string, s2->string, s1->length);
}
Lstring *append(const Lstring *s);
Lstring *substring(int start, int end);
};
#endif
+18 -1
View File
@@ -109,6 +109,7 @@ int response_expand(int *pargc, char ***pargv)
char *buffer;
char *bufend;
char *p;
int comment = 0;
cp++;
p = getenv(cp);
@@ -171,15 +172,31 @@ int response_expand(int *pargc, char ***pargv)
goto L2;
case 0xD:
case '\n':
if (comment)
{
comment = 0;
}
case 0:
case ' ':
case '\t':
case '\n':
continue; // scan to start of argument
case '#':
comment = 1;
continue;
case '@':
if (comment)
{
continue;
}
recurse = 1;
default: /* start of new argument */
if (comment)
{
continue;
}
if (addargp(&n,p))
goto noexpand;
instring = 0;
+7 -2
View File
@@ -1,6 +1,11 @@
/* Copyright (c) 2000 Digital Mars */
/* All Rights Reserved */
// Copyright (c) 2000-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
+7 -1
View File
@@ -1,5 +1,11 @@
// Copyright (C) 2000-2011 by Digital Mars
// Copyright (c) 2000-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#ifndef ROOT_MEM_H
#define ROOT_MEM_H
+2 -116
View File
@@ -1,5 +1,5 @@
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -18,6 +18,7 @@
#include <string.h>
#include <stdint.h>
#include <assert.h>
#include <ctype.h>
#if (defined (__SVR4) && defined (__sun))
#include <alloca.h>
@@ -49,7 +50,6 @@
#include "port.h"
#include "root.h"
#include "dchar.h"
#include "rmem.h"
#if 0 //__SC__ //def DEBUG
@@ -142,22 +142,6 @@ void error(const char *format, ...)
exit(EXIT_FAILURE);
}
#if M_UNICODE
void error(const dchar *format, ...)
{
va_list ap;
va_start(ap, format);
printf("Error: ");
vwprintf(format, ap);
va_end( ap );
printf("\n");
fflush(stdout);
exit(EXIT_FAILURE);
}
#endif
void error_mem()
{
error("out of memory");
@@ -206,15 +190,6 @@ char *Object::toChars()
return (char *)"Object";
}
dchar *Object::toDchars()
{
#if M_UNICODE
return L"Object";
#else
return toChars();
#endif
}
int Object::dyncast()
{
return 0;
@@ -1609,30 +1584,6 @@ void OutBuffer::writestring(const char *string)
write(string,strlen(string));
}
void OutBuffer::writedstring(const char *string)
{
#if M_UNICODE
for (; *string; string++)
{
writedchar(*string);
}
#else
write(string,strlen(string));
#endif
}
void OutBuffer::writedstring(const wchar_t *string)
{
#if M_UNICODE
write(string,wcslen(string) * sizeof(wchar_t));
#else
for (; *string; string++)
{
writedchar(*string);
}
#endif
}
void OutBuffer::prependstring(const char *string)
{ unsigned len;
@@ -1646,18 +1597,10 @@ void OutBuffer::prependstring(const char *string)
void OutBuffer::writenl()
{
#if _WIN32
#if M_UNICODE
write4(0x000A000D); // newline is CR,LF on Microsoft OS's
#else
writeword(0x0A0D); // newline is CR,LF on Microsoft OS's
#endif
#else
#if M_UNICODE
writeword('\n');
#else
writeByte('\n');
#endif
#endif
}
void OutBuffer::writeByte(unsigned b)
@@ -1719,13 +1662,6 @@ void OutBuffer::writeUTF8(unsigned b)
assert(0);
}
void OutBuffer::writedchar(unsigned b)
{
reserve(Dchar_mbmax * sizeof(dchar));
offset = (unsigned char *)Dchar::put((dchar *)(this->data + offset), (dchar)b) -
this->data;
}
void OutBuffer::prependbyte(unsigned b)
{
reserve(1);
@@ -1873,46 +1809,6 @@ void OutBuffer::vprintf(const char *format, va_list args)
write(p,count);
}
#if M_UNICODE
void OutBuffer::vprintf(const wchar_t *format, va_list args)
{
dchar buffer[128];
dchar *p;
unsigned psize;
int count;
WORKAROUND_C99_SPECIFIERS_BUG(wstring, fmt, format);
p = buffer;
psize = sizeof(buffer) / sizeof(buffer[0]);
for (;;)
{
#if _WIN32
count = _vsnwprintf(p,psize,format,args);
if (count != -1)
break;
psize *= 2;
#elif POSIX
va_list va;
va_copy(va, args);
count = vsnwprintf(p,psize,format,va);
va_end(va);
if (count == -1)
psize *= 2;
else if (count >= psize)
psize = count + 1;
else
break;
#else
assert(0);
#endif
p = (dchar *) alloca(psize * 2); // buffer too small, try again with larger size
}
write(p,count * 2);
}
#endif
void OutBuffer::printf(const char *format, ...)
{
va_list ap;
@@ -1921,16 +1817,6 @@ void OutBuffer::printf(const char *format, ...)
va_end(ap);
}
#if M_UNICODE
void OutBuffer::printf(const wchar_t *format, ...)
{
va_list ap;
va_start(ap, format);
vprintf(format,ap);
va_end(ap);
}
#endif
void OutBuffer::bracket(char left, char right)
{
reserve(2);
-10
View File
@@ -1,5 +1,4 @@
// Copyright (c) 1999-2011 by Digital Mars
// All Rights Reserved
// written by Walter Bright
@@ -24,7 +23,6 @@
typedef size_t hash_t;
#include "longdouble.h"
#include "dchar.h"
char *wchar2ascii(wchar_t *);
int wcharIsAscii(wchar_t *);
@@ -92,7 +90,6 @@ struct Object
virtual void print();
virtual char *toChars();
virtual dchar *toDchars();
virtual void toBuffer(OutBuffer *buf);
/**
@@ -282,14 +279,11 @@ struct OutBuffer : Object
void write(const void *data, unsigned nbytes);
void writebstring(unsigned char *string);
void writestring(const char *string);
void writedstring(const char *string);
void writedstring(const wchar_t *string);
void prependstring(const char *string);
void writenl(); // write newline
void writeByte(unsigned b);
void writebyte(unsigned b) { writeByte(b); }
void writeUTF8(unsigned b);
void writedchar(unsigned b);
void prependbyte(unsigned b);
void writeword(unsigned w);
void writeUTF16(unsigned w);
@@ -300,10 +294,6 @@ struct OutBuffer : Object
void align(unsigned size);
void vprintf(const char *format, va_list args);
void printf(const char *format, ...);
#if M_UNICODE
void vprintf(const unsigned short *format, va_list args);
void printf(const unsigned short *format, ...);
#endif
void bracket(char left, char right);
unsigned bracket(unsigned i, const char *left, unsigned j, const char *right);
void spread(unsigned offset, unsigned nbytes);
+8
View File
@@ -1,4 +1,12 @@
// Copyright (c) 2010-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
+8
View File
@@ -1,4 +1,12 @@
// Copyright (c) 2010-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
typedef void *(fp_speller_t)(void *, const char *);
extern const char idchars[];
+71 -21
View File
@@ -9,15 +9,70 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h> // uint{8|16|32}_t
#include <string.h> // memcpy()
#include <stdlib.h>
#include "root.h"
#include "rmem.h"
#include "dchar.h"
#include "lstring.h"
#include "rmem.h" // mem
#include "stringtable.h"
hash_t calcHash(const char *str, size_t len)
{
hash_t hash = 0;
while (1)
{
switch (len)
{
case 0:
return hash;
case 1:
hash *= 37;
hash += *(const uint8_t *)str;
return hash;
case 2:
hash *= 37;
#if LITTLE_ENDIAN
hash += *(const uint16_t *)str;
#else
hash += str[0] * 256 + str[1];
#endif
return hash;
case 3:
hash *= 37;
#if LITTLE_ENDIAN
hash += (*(const uint16_t *)str << 8) +
((const uint8_t *)str)[2];
#else
hash += (str[0] * 256 + str[1]) * 256 + str[2];
#endif
return hash;
default:
hash *= 37;
#if LITTLE_ENDIAN
hash += *(const uint32_t *)str;
#else
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
#endif
str += 4;
len -= 4;
break;
}
}
}
void StringValue::ctor(const char *p, unsigned length)
{
this->length = length;
this->lstring[length] = 0;
memcpy(this->lstring, p, length * sizeof(char));
}
void StringTable::init(unsigned size)
{
table = (void **)mem.calloc(size, sizeof(void *));
@@ -46,21 +101,20 @@ struct StringEntry
StringValue value;
static StringEntry *alloc(const dchar *s, unsigned len);
static StringEntry *alloc(const char *s, unsigned len);
};
StringEntry *StringEntry::alloc(const dchar *s, unsigned len)
StringEntry *StringEntry::alloc(const char *s, unsigned len)
{
StringEntry *se;
se = (StringEntry *) mem.calloc(1,sizeof(StringEntry) - sizeof(Lstring) + Lstring::size(len));
se->value.lstring.length = len;
se->hash = Dchar::calcHash(s,len);
memcpy(se->value.lstring.string, s, len * sizeof(dchar));
se = (StringEntry *) mem.calloc(1,sizeof(StringEntry) + len + 1);
se->value.ctor(s, len);
se->hash = calcHash(s,len);
return se;
}
void **StringTable::search(const dchar *s, unsigned len)
void **StringTable::search(const char *s, unsigned len)
{
hash_t hash;
unsigned u;
@@ -68,7 +122,7 @@ void **StringTable::search(const dchar *s, unsigned len)
StringEntry **se;
//printf("StringTable::search(%p,%d)\n",s,len);
hash = Dchar::calcHash(s,len);
hash = calcHash(s,len);
u = hash % tabledim;
se = (StringEntry **)&table[u];
//printf("\thash = %d, u = %d\n",hash,u);
@@ -77,10 +131,10 @@ void **StringTable::search(const dchar *s, unsigned len)
cmp = (*se)->hash - hash;
if (cmp == 0)
{
cmp = (*se)->value.lstring.len() - len;
cmp = (*se)->value.len() - len;
if (cmp == 0)
{
cmp = Dchar::memcmp(s,(*se)->value.lstring.toDchars(),len);
cmp = ::memcmp(s,(*se)->value.toDchars(),len);
if (cmp == 0)
break;
}
@@ -94,7 +148,7 @@ void **StringTable::search(const dchar *s, unsigned len)
return (void **)se;
}
StringValue *StringTable::lookup(const dchar *s, unsigned len)
StringValue *StringTable::lookup(const char *s, unsigned len)
{ StringEntry *se;
se = *(StringEntry **)search(s,len);
@@ -104,7 +158,7 @@ StringValue *StringTable::lookup(const dchar *s, unsigned len)
return NULL;
}
StringValue *StringTable::update(const dchar *s, unsigned len)
StringValue *StringTable::update(const char *s, unsigned len)
{ StringEntry **pse;
StringEntry *se;
@@ -118,7 +172,7 @@ StringValue *StringTable::update(const dchar *s, unsigned len)
return &se->value;
}
StringValue *StringTable::insert(const dchar *s, unsigned len)
StringValue *StringTable::insert(const char *s, unsigned len)
{ StringEntry **pse;
StringEntry *se;
@@ -133,7 +187,3 @@ StringValue *StringTable::insert(const dchar *s, unsigned len)
}
return &se->value;
}
+32 -9
View File
@@ -1,3 +1,4 @@
// Copyright (c) 1999-2011 by Digital Mars
// All Rights Reserved
// written by Walter Bright
@@ -15,34 +16,56 @@
#endif
#include "root.h"
#include "dchar.h"
#include "lstring.h"
struct StringEntry;
// StringValue is a variable-length structure as indicated by the last array
// member with unspecified size. It has neither proper c'tors nor a factory
// method because the only thing which should be creating these is StringTable.
struct StringValue
{
union
{ int intvalue;
{
void *ptrvalue;
dchar *string;
char *string;
};
Lstring lstring;
private:
unsigned length;
#ifndef IN_GCC
// Disable warning about nonstandard extension
#pragma warning (disable : 4200)
#endif
char lstring[];
public:
unsigned len() const { return length; }
const char *toDchars() const { return lstring; }
private:
friend struct StringEntry;
StringValue(); // not constructible
// This is more like a placement new c'tor
void ctor(const char *p, unsigned length);
};
struct StringTable
{
private:
void **table;
unsigned count;
unsigned tabledim;
public:
void init(unsigned size = 37);
~StringTable();
StringValue *lookup(const dchar *s, unsigned len);
StringValue *insert(const dchar *s, unsigned len);
StringValue *update(const dchar *s, unsigned len);
StringValue *lookup(const char *s, unsigned len);
StringValue *insert(const char *s, unsigned len);
StringValue *update(const char *s, unsigned len);
private:
void **search(const dchar *s, unsigned len);
void **search(const char *s, unsigned len);
};
#endif
+1
View File
@@ -9,6 +9,7 @@
#include <stdio.h>
#include <assert.h>
#include <string.h> // strlen()
#include "root.h"
#include "speller.h"
+2 -2
View File
@@ -87,7 +87,7 @@ struct Scope
#define CSXreturn 0x20 // seen a return statement
#define CSXany_ctor 0x40 // either this() or super() was called
unsigned structalign; // alignment for struct members
structalign_t structalign; // alignment for struct members
enum LINK linkage; // linkage for external functions
enum PROT protection; // protection for class members
@@ -102,7 +102,7 @@ struct Scope
#define SCOPEstaticassert 8 // inside static assert
#define SCOPEdebug 0x10 // inside debug conditional
#if IN_GCC
#ifdef IN_GCC
Expressions *attributes; // GCC decl/type attributes
#endif
+179 -69
View File
@@ -28,6 +28,7 @@
#include "parse.h"
#include "template.h"
#include "attrib.h"
#include "import.h"
#if IN_LLVM
#if defined(_MSC_VER)
@@ -426,7 +427,7 @@ Statements *CompileStatement::flatten(Scope *sc)
//printf("CompileStatement::flatten() %s\n", exp->toChars());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->optimize(WANTvalue | WANTinterpret);
exp = exp->ctfeInterpret();
if (exp->op == TOKerror)
return NULL;
StringExp *se = exp->toString();
@@ -1585,6 +1586,10 @@ Statement *ForeachStatement::semantic(Scope *sc)
return s;
}
Type *argtype = (*arguments)[dim-1]->type;
if (argtype)
argtype = argtype->semantic(loc, sc);
TypeTuple *tuple = (TypeTuple *)tab;
Statements *statements = new Statements();
//printf("aggr: op = %d, %s\n", aggr->op, aggr->toChars());
@@ -1599,9 +1604,8 @@ Statement *ForeachStatement::semantic(Scope *sc)
((DotVarExp *)(*te->exps)[0])->e1->isTemp())
{
CommaExp *ce = (CommaExp *)((DotVarExp *)(*te->exps)[0])->e1;
prelude = ce->e1;
((DotVarExp *)(*te->exps)[0])->e1 = ce->e2;
prelude = ce->e1;
((DotVarExp *)(*te->exps)[0])->e1 = ce->e2;
}
}
else if (aggr->op == TOKtype) // type tuple
@@ -1612,8 +1616,8 @@ Statement *ForeachStatement::semantic(Scope *sc)
assert(0);
for (size_t j = 0; j < n; j++)
{ size_t k = (op == TOKforeach) ? j : n - 1 - j;
Expression *e;
Type *t;
Expression *e = NULL;
Type *t = NULL;
if (te)
e = (*te->exps)[k];
else
@@ -1664,14 +1668,20 @@ Statement *ForeachStatement::semantic(Scope *sc)
var = new AliasDeclaration(loc, arg->ident, s);
if (arg->storageClass & STCref)
error("symbol %s cannot be ref", s->toChars());
if (argtype && argtype->ty != Terror)
error("cannot specify element type for symbol %s", s->toChars());
}
else if (e->op == TOKtype)
{
var = new AliasDeclaration(loc, arg->ident, e->type);
if (argtype && argtype->ty != Terror)
error("cannot specify element type for type %s", e->type->toChars());
}
else
{
arg->type = e->type;
if (argtype && argtype->ty != Terror)
arg->type = argtype;
Initializer *ie = new ExpInitializer(0, e);
VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie);
if (arg->storageClass & STCref)
@@ -1688,6 +1698,8 @@ Statement *ForeachStatement::semantic(Scope *sc)
else
{
var = new AliasDeclaration(loc, arg->ident, t);
if (argtype && argtype->ty != Terror)
error("cannot specify element type for symbol %s", s->toChars());
}
DeclarationExp *de = new DeclarationExp(loc, var);
st->push(new ExpStatement(loc, de));
@@ -1757,23 +1769,47 @@ Lagain:
Type *argtype = arg->type->semantic(loc, sc);
VarDeclaration *var;
var = new VarDeclaration(loc, argtype, arg->ident, NULL);
var->storage_class |= STCforeach;
var->storage_class |= arg->storageClass & (STCin | STCout | STCref | STC_TYPECTOR);
if (var->storage_class & (STCref | STCout))
var->storage_class |= STCnodtor;
if (dim == 2 && i == 0)
{ key = var;
//var->storage_class |= STCfinal;
{
#if (BUG6652 == 1 || BUG6652 == 2)
var = new VarDeclaration(loc, arg->type, Lexer::uniqueId("__key"), NULL);
var->storage_class |= arg->storageClass & (STCin | STCout | STC_TYPECTOR);
#else
if (arg->storageClass & STCref)
var = new VarDeclaration(loc, argtype, arg->ident, NULL);
else
var = new VarDeclaration(loc, arg->type, Lexer::uniqueId("__key"), NULL);
var->storage_class |= arg->storageClass & (STCin | STCout | STC_TYPECTOR);
#endif
var->storage_class |= STCforeach;
if (var->storage_class & (STCref | STCout))
var->storage_class |= STCnodtor;
key = var;
}
else
{
var = new VarDeclaration(loc, argtype, arg->ident, NULL);
var->storage_class |= STCforeach;
var->storage_class |= arg->storageClass & (STCin | STCout | STCref | STC_TYPECTOR);
if (var->storage_class & (STCref | STCout))
var->storage_class |= STCnodtor;
value = var;
/* Reference to immutable data should be marked as const
*/
if (var->storage_class & STCref && !tn->isMutable())
if (var->storage_class & STCref)
{
var->storage_class |= STCconst;
/* Reference to immutable data should be marked as const
*/
if (!tn->isMutable())
var->storage_class |= STCconst;
Type *t = tab->nextOf();
if (!t->invariantOf()->equals(argtype->invariantOf()) ||
!MODimplicitConv(t->mod, argtype->mod))
{
error("argument type mismatch, %s to ref %s",
t->toChars(), argtype->toChars());
}
}
}
#if 0
@@ -1831,6 +1867,30 @@ Lagain:
value->init = new ExpInitializer(loc, new IndexExp(loc, new VarExp(loc, tmp), new VarExp(loc, key)));
Statement *ds = new ExpStatement(loc, value);
if (dim == 2)
{ Parameter *arg = (*arguments)[0];
#if (BUG6652 == 1 || BUG6652 == 2)
if ((*arguments)[0]->storageClass & STCref)
{
AliasDeclaration *v = new AliasDeclaration(loc, arg->ident, key);
body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
}
else
{
ExpInitializer *ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
VarDeclaration *v = new VarDeclaration(loc, NULL, arg->ident, ie);
v->storage_class |= STCforeach | STCref | STCbug6652;
body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
}
#else
if (!(arg->storageClass & STCref))
{
ExpInitializer *ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
VarDeclaration *v = new VarDeclaration(loc, NULL, arg->ident, ie);
body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
}
#endif
}
body = new CompoundStatement(loc, ds, body);
s = new ForStatement(loc, forinit, cond, increment, body);
@@ -1901,29 +1961,29 @@ Lagain:
goto Lapply;
{ /* Look for range iteration, i.e. the properties
* .empty, .next, .retreat, .head and .rear
* .empty, .popFront, .popBack, .front and .back
* foreach (e; aggr) { ... }
* translates to:
* for (auto __r = aggr[]; !__r.empty; __r.next)
* { auto e = __r.head;
* for (auto __r = aggr[]; !__r.empty; __r.popFront)
* { auto e = __r.front;
* ...
* }
*/
AggregateDeclaration *ad = (tab->ty == Tclass)
? (AggregateDeclaration *)((TypeClass *)tab)->sym
: (AggregateDeclaration *)((TypeStruct *)tab)->sym;
Identifier *idhead;
Identifier *idnext;
Identifier *idfront;
Identifier *idpopFront;
if (op == TOKforeach)
{ idhead = Id::Ffront;
idnext = Id::FpopFront;
{ idfront = Id::Ffront;
idpopFront = Id::FpopFront;
}
else
{ idhead = Id::Fback;
idnext = Id::FpopBack;
{ idfront = Id::Fback;
idpopFront = Id::FpopBack;
}
Dsymbol *shead = search_function(ad, idhead);
if (!shead)
Dsymbol *sfront = ad->search(0, idfront, 0);
if (!sfront)
goto Lapply;
/* Generate a temporary __r and initialize it with the aggregate.
@@ -1939,13 +1999,13 @@ Lagain:
// __r.next
e = new VarExp(loc, r);
Expression *increment = new CallExp(loc, new DotIdExp(loc, e, idnext));
Expression *increment = new CallExp(loc, new DotIdExp(loc, e, idpopFront));
/* Declaration statement for e:
* auto e = __r.idhead;
* auto e = __r.idfront;
*/
e = new VarExp(loc, r);
Expression *einit = new DotIdExp(loc, e, idhead);
Expression *einit = new DotIdExp(loc, e, idfront);
Statement *makeargs, *forbody;
if (dim == 1)
{
@@ -1968,7 +2028,7 @@ Lagain:
makeargs = new ExpStatement(loc, de);
Expression *ve = new VarExp(loc, vd);
ve->type = shead->isDeclaration()->type;
ve->type = sfront->isDeclaration()->type;
if (ve->type->toBasetype()->ty == Tfunction)
ve->type = ve->type->toBasetype()->nextOf();
if (!ve->type || ve->type->ty == Terror)
@@ -2046,18 +2106,6 @@ Lagain:
Type *tret = func->type->nextOf();
// Need a variable to hold value from any return statements in body.
if (!sc->func->vresult && tret && tret != Type::tvoid)
{
VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL);
v->noscope = 1;
v->semantic(sc);
if (!sc->insert(v))
assert(0);
v->parent = sc->func;
sc->func->vresult = v;
}
TypeFunction *tfld = NULL;
if (sapply)
{ FuncDeclaration *fdapply = sapply->isFuncDeclaration();
@@ -2533,7 +2581,14 @@ Statement *ForeachRangeStatement::semantic(Scope *sc)
*/
ExpInitializer *ie = new ExpInitializer(loc, (op == TOKforeach) ? lwr : upr);
key = new VarDeclaration(loc, arg->type, arg->ident, ie);
#if (BUG6652 == 1 || BUG6652 == 2)
key = new VarDeclaration(loc, arg->type, Lexer::uniqueId("__key"), ie);
#else
if (arg->storageClass & STCref)
key = new VarDeclaration(loc, arg->type, arg->ident, ie);
else
key = new VarDeclaration(loc, arg->type, Lexer::uniqueId("__key"), ie);
#endif
Identifier *id = Lexer::uniqueId("__limit");
ie = new ExpInitializer(loc, (op == TOKforeach) ? upr : lwr);
@@ -2580,6 +2635,28 @@ Statement *ForeachRangeStatement::semantic(Scope *sc)
//increment = new AddAssignExp(loc, new VarExp(loc, key), new IntegerExp(1));
increment = new PreExp(TOKpreplusplus, loc, new VarExp(loc, key));
#if (BUG6652 == 1 || BUG6652 == 2)
if (arg->storageClass & STCref)
{
AliasDeclaration *v = new AliasDeclaration(loc, arg->ident, key);
body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
}
else
{
ExpInitializer *ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
VarDeclaration *v = new VarDeclaration(loc, NULL, arg->ident, ie);
v->storage_class |= STCforeach | STCref | STCbug6652;
body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
}
#else
if (!(arg->storageClass & STCref))
{
ExpInitializer *ie = new ExpInitializer(loc, new IdentifierExp(loc, key->ident));
VarDeclaration *v = new VarDeclaration(loc, NULL, arg->ident, ie);
body = new CompoundStatement(loc, new ExpStatement(loc, v), body);
}
#endif
ForStatement *fs = new ForStatement(loc, forinit, cond, increment, body);
s = fs->semantic(sc);
return s;
@@ -2971,8 +3048,8 @@ Statement *PragmaStatement::semantic(Scope *sc)
Expression *e = (*args)[i];
e = e->semantic(sc);
if (e->op != TOKerror)
e = e->optimize(WANTvalue | WANTinterpret);
if (e->op != TOKerror && e->op != TOKtype)
e = e->ctfeInterpret();
if (e->op == TOKerror)
{ errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
goto Lerror;
@@ -3002,7 +3079,7 @@ Statement *PragmaStatement::semantic(Scope *sc)
Expression *e = (*args)[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
(*args)[0] = e;
StringExp *se = e->toString();
if (!se)
@@ -3033,7 +3110,7 @@ Statement *PragmaStatement::semantic(Scope *sc)
{
Expression *e = (*args)[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
(*args)[0] = e;
Dsymbol *sa = getDsymbol(e);
if (!sa || !sa->isFuncDeclaration())
@@ -3171,6 +3248,10 @@ Statement *SwitchStatement::semantic(Scope *sc)
condition = condition->semantic(sc);
condition = resolveProperties(sc, condition);
TypeEnum *te = NULL;
// preserve enum type for final switches
if (condition->type->ty == Tenum)
te = (TypeEnum *)condition->type;
if (condition->type->isString())
{
// If it's not an array, cast it to one
@@ -3235,8 +3316,8 @@ Statement *SwitchStatement::semantic(Scope *sc)
{ // Don't use toBasetype() because that will skip past enums
t = ((TypeTypedef *)t)->sym->basetype;
}
if (condition->type->ty == Tenum)
{ TypeEnum *te = (TypeEnum *)condition->type;
if (te)
{
EnumDeclaration *ed = te->toDsymbol(sc)->isEnumDeclaration();
assert(ed);
size_t dim = ed->members->dim;
@@ -3247,7 +3328,7 @@ Statement *SwitchStatement::semantic(Scope *sc)
{
for (size_t j = 0; j < cases->dim; j++)
{ CaseStatement *cs = (*cases)[j];
if (cs->exp->equals(em->value))
if (cs->exp->equals(em->value) || cs->exp->toInteger() == em->value->toInteger())
goto L1;
}
error("enum member %s not represented in final switch", em->toChars());
@@ -3397,7 +3478,7 @@ Statement *CaseStatement::semantic(Scope *sc)
}
}
else
exp = exp->optimize(WANTvalue | WANTinterpret);
exp = exp->ctfeInterpret();
if (exp->op != TOKstring && exp->op != TOKint64 && exp->op != TOKerror)
{
@@ -3503,12 +3584,11 @@ Statement *CaseRangeStatement::semantic(Scope *sc)
first = first->semantic(sc);
first = first->implicitCastTo(sc, sw->condition->type);
first = first->optimize(WANTvalue | WANTinterpret);
first = first->ctfeInterpret();
last = last->semantic(sc);
last = last->implicitCastTo(sc, sw->condition->type);
last = last->optimize(WANTvalue | WANTinterpret);
last = last->ctfeInterpret();
if (first->op == TOKerror || last->op == TOKerror)
return statement ? statement->semantic(sc) : NULL;
@@ -3574,12 +3654,12 @@ DefaultStatement::DefaultStatement(Loc loc, Statement *s)
: Statement(loc)
{
this->statement = s;
#if IN_GCC
#ifdef IN_GCC
cblock = NULL;
#endif
#elif IN_LLVM
bodyBB = NULL;
// LDC
enclosingScopeExit = NULL;
#endif
}
Statement *DefaultStatement::syntaxCopy()
@@ -3749,6 +3829,7 @@ ReturnStatement::ReturnStatement(Loc loc, Expression *exp)
: Statement(loc)
{
this->exp = exp;
this->implicit0 = 0;
}
Statement *ReturnStatement::syntaxCopy()
@@ -3766,7 +3847,6 @@ Statement *ReturnStatement::semantic(Scope *sc)
FuncDeclaration *fd = sc->parent->isFuncDeclaration();
Scope *scx = sc;
int implicit0 = 0;
Expression *eorg = NULL;
if (fd->fes)
@@ -3810,8 +3890,11 @@ Statement *ReturnStatement::semantic(Scope *sc)
{
fd->hasReturnExp |= 1;
FuncLiteralDeclaration *fld = fd->isFuncLiteralDeclaration();
if (tret)
exp = exp->inferType(tbret);
else if (fld && fld->treq && fld->treq->nextOf())
exp = exp->inferType(fld->treq->nextOf());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
if (!((TypeFunction *)fd->type)->isref)
@@ -3984,11 +4067,14 @@ Statement *ReturnStatement::semantic(Scope *sc)
// Construct: return vresult;
if (!fd->vresult)
{ // Declare vresult
Scope *sco = fd->scout ? fd->scout : scx;
VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL);
v->noscope = 1;
v->storage_class |= STCresult;
v->semantic(scx);
if (!scx->insert(v))
if (((TypeFunction *)fd->type)->isref)
v->storage_class |= STCref | STCforeach;
v->semantic(sco);
if (!sco->insert(v))
assert(0);
v->parent = fd;
fd->vresult = v;
@@ -4027,7 +4113,7 @@ Statement *ReturnStatement::semantic(Scope *sc)
if (fd->returnLabel && tbret->ty != Tvoid)
{
assert(fd->vresult);
fd->buildResultVar();
VarExp *v = new VarExp(0, fd->vresult);
assert(eorg);
@@ -4357,9 +4443,16 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
{ /* Cast the interface to an object, as the object has the monitor,
* not the interface.
*/
Type *t = new TypeIdentifier(0, Id::Object);
if (!ClassDeclaration::object)
{
error("missing or corrupt object.d");
fatal();
}
Type *t = ClassDeclaration::object->type;
t = t->semantic(0, sc)->toBasetype();
assert(t->ty == Tclass);
t = t->semantic(0, sc);
exp = new CastExp(loc, exp, t);
exp = exp->semantic(sc);
}
@@ -5313,9 +5406,6 @@ LabelDsymbol::LabelDsymbol(Identifier *ident)
: Dsymbol(ident)
{
statement = NULL;
#if IN_GCC
asmLabelNum = 0;
#endif
}
LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()?
@@ -5410,9 +5500,29 @@ Statement *ImportStatement::syntaxCopy()
Statement *ImportStatement::semantic(Scope *sc)
{
for (size_t i = 0; i < imports->dim; i++)
{ Dsymbol *s = (*imports)[i];
{ Import *s = (*imports)[i]->isImport();
for (size_t i = 0; i < s->names.dim; i++)
{
Identifier *name = s->names[i];
Identifier *alias = s->aliases[i];
if (!alias)
alias = name;
TypeIdentifier *tname = new TypeIdentifier(s->loc, name);
AliasDeclaration *ad = new AliasDeclaration(s->loc, alias, tname);
s->aliasdecls.push(ad);
}
s->semantic(sc);
sc->insert(s);
for (size_t i = 0; i < s->aliasdecls.dim; i++)
{
sc->insert(s->aliasdecls[i]);
}
}
return this;
}
+3 -5
View File
@@ -79,7 +79,7 @@ struct DValue;
typedef DValue elem;
#endif
#if IN_GCC
#ifdef IN_GCC
union tree_node; typedef union tree_node block;
//union tree_node; typedef union tree_node elem;
#else
@@ -595,7 +595,7 @@ struct CaseRangeStatement : Statement
struct DefaultStatement : Statement
{
Statement *statement;
#if IN_GCC
#ifdef IN_GCC
block *cblock; // back end: label for the block
#endif
@@ -664,6 +664,7 @@ struct SwitchErrorStatement : Statement
struct ReturnStatement : Statement
{
Expression *exp;
int implicit0;
ReturnStatement(Loc loc, Expression *exp);
Statement *syntaxCopy();
@@ -930,9 +931,6 @@ struct LabelStatement : Statement
struct LabelDsymbol : Dsymbol
{
LabelStatement *statement;
#if IN_GCC
unsigned asmLabelNum; // GCC-specific
#endif
LabelDsymbol(Identifier *ident);
LabelDsymbol *isLabel();
+8 -4
View File
@@ -1,5 +1,5 @@
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -59,10 +59,14 @@ void StaticAssert::semantic2(Scope *sc)
++sc->ignoreTemplates;
Expression *e = exp->semantic(sc);
sc = sc->pop();
if (e->type == Type::terror)
if (!e->type->checkBoolean())
{
if (e->type->toBasetype() != Type::terror)
exp->error("expression %s of type %s does not have a boolean value", exp->toChars(), e->type->toChars());
return;
}
unsigned olderrs = global.errors;
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
if (global.errors != olderrs)
{
errorSupplemental(loc, "while evaluating: static assert(%s)", exp->toChars());
@@ -74,7 +78,7 @@ void StaticAssert::semantic2(Scope *sc)
OutBuffer buf;
msg = msg->semantic(sc);
msg = msg->optimize(WANTvalue | WANTinterpret);
msg = msg->ctfeInterpret();
hgs.console = 1;
msg->toCBuffer(&buf, &hgs);
error("%s", buf.toChars());
+130 -30
View File
@@ -37,7 +37,6 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
scope = 0;
structsize = 0; // size of struct
alignsize = 0; // size of struct for alignment purposes
structalign = 0; // struct member alignment in effect
hasUnions = 0;
sizeok = SIZEOKnone; // size not determined yet
deferred = NULL;
@@ -60,6 +59,7 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
noDefaultCtor = FALSE;
#endif
dtor = NULL;
getRTInfo = NULL;
#if IN_LLVM
availableExternally = true; // assume this unless proven otherwise
@@ -83,7 +83,7 @@ void AggregateDeclaration::semantic2(Scope *sc)
sc = sc->push(this);
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
s->semantic2(sc);
}
sc->pop();
@@ -103,10 +103,25 @@ void AggregateDeclaration::semantic3(Scope *sc)
sc = sc->push(this);
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
s->semantic3(sc);
}
sc->pop();
if (!getRTInfo)
{ // Evaluate: gcinfo!type
Objects *tiargs = new Objects();
tiargs->push(type);
TemplateInstance *ti = new TemplateInstance(loc, Type::rtinfo, tiargs);
ti->semantic(sc);
ti->semantic2(sc);
ti->semantic3(sc);
Dsymbol *s = ti->toAlias();
Expression *e = new DsymbolExp(0, s, 0);
e = e->semantic(ti->tempdecl->scope);
e = e->ctfeInterpret();
getRTInfo = e;
}
}
}
@@ -117,7 +132,7 @@ void AggregateDeclaration::inlineScan()
{
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
//printf("inline scan aggregate symbol '%s'\n", s->toChars());
s->inlineScan();
}
@@ -127,6 +142,8 @@ void AggregateDeclaration::inlineScan()
unsigned AggregateDeclaration::size(Loc loc)
{
//printf("AggregateDeclaration::size() %s, scope = %p\n", toChars(), scope);
if (loc.linnum == 0)
loc = this->loc;
if (!members)
error(loc, "unknown size");
if (sizeok != SIZEOKdone && scope)
@@ -196,20 +213,33 @@ int AggregateDeclaration::isExport()
*/
void AggregateDeclaration::alignmember(
unsigned salign, // struct alignment that is in effect
unsigned size, // alignment requirement of field
structalign_t alignment, // struct alignment that is in effect
unsigned size, // alignment requirement of field
unsigned *poffset)
{
//printf("salign = %d, size = %d, offset = %d\n",salign,size,offset);
if (salign > 1)
//printf("alignment = %d, size = %d, offset = %d\n",alignment,size,offset);
switch (alignment)
{
assert(size != 3);
unsigned sa = size;
if (sa == 0 || salign < sa)
sa = salign;
*poffset = (*poffset + sa - 1) & ~(sa - 1);
case 1:
// No alignment
break;
case STRUCTALIGN_DEFAULT:
{ /* Must match what the corresponding C compiler's default
* alignment behavior is.
*/
assert(size != 3);
unsigned sa = (size == 0 || 8 < size) ? 8 : size;
*poffset = (*poffset + sa - 1) & ~(sa - 1);
break;
}
default:
// Align on alignment boundary, which must be a positive power of 2
assert(alignment > 0 && !(alignment & (alignment - 1)));
*poffset = (*poffset + alignment - 1) & ~(alignment - 1);
break;
}
//printf("result = %d\n",offset);
}
/****************************************
@@ -221,25 +251,36 @@ unsigned AggregateDeclaration::placeField(
unsigned *nextoffset, // next location in aggregate
unsigned memsize, // size of member
unsigned memalignsize, // size of member for alignment purposes
unsigned memalign, // alignment in effect for this member
structalign_t alignment, // alignment in effect for this member
unsigned *paggsize, // size of aggregate (updated)
unsigned *paggalignsize, // size of aggregate for alignment purposes (updated)
bool isunion // the aggregate is a union
)
{
unsigned ofs = *nextoffset;
alignmember(memalign, memalignsize, &ofs);
alignmember(alignment, memalignsize, &ofs);
unsigned memoffset = ofs;
ofs += memsize;
if (ofs > *paggsize)
*paggsize = ofs;
if (!isunion)
*nextoffset = ofs;
if (global.params.is64bit && memalign == 8 && memalignsize == 16)
/* Not sure how to handle this */
;
else if (memalign < memalignsize)
memalignsize = memalign;
if (alignment == STRUCTALIGN_DEFAULT)
{
if (global.params.is64bit && memalignsize == 16)
;
else if (8 < memalignsize)
memalignsize = 8;
else if (alignment < memalignsize)
memalignsize = alignment;
}
else
{
if (memalignsize < alignment)
memalignsize = alignment;
}
if (*paggalignsize < memalignsize)
*paggalignsize = memalignsize;
@@ -265,13 +306,13 @@ int AggregateDeclaration::firstFieldInUnion(int indx)
{
if (isUnionDeclaration())
return 0;
VarDeclaration * vd = fields.tdata()[indx];
VarDeclaration * vd = fields[indx];
int firstNonZero = indx; // first index in the union with non-zero size
for (; ;)
{
if (indx == 0)
return firstNonZero;
VarDeclaration * v = fields.tdata()[indx - 1];
VarDeclaration * v = fields[indx - 1];
if (v->offset != vd->offset)
return firstNonZero;
--indx;
@@ -290,7 +331,7 @@ int AggregateDeclaration::firstFieldInUnion(int indx)
*/
int AggregateDeclaration::numFieldsInUnion(int firstIndex)
{
VarDeclaration * vd = fields.tdata()[firstIndex];
VarDeclaration * vd = fields[firstIndex];
/* If it is a zero-length field, AND we can't find an earlier non-zero
* sized field with the same offset, we assume it's not part of a union.
*/
@@ -300,7 +341,7 @@ int AggregateDeclaration::numFieldsInUnion(int firstIndex)
int count = 1;
for (size_t i = firstIndex+1; i < fields.dim; ++i)
{
VarDeclaration * v = fields.tdata()[i];
VarDeclaration * v = fields[i];
// If offsets are different, they are not in the same union
if (v->offset != vd->offset)
break;
@@ -322,7 +363,10 @@ StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
postblit = NULL;
xeq = NULL;
alignment = 0;
#endif
arg1type = NULL;
arg2type = NULL;
// For forward references
type = new TypeStruct(this);
@@ -389,8 +433,8 @@ void StructDeclaration::semantic(Scope *sc)
#else
handle = type->pointerTo();
#endif
structalign = sc->structalign;
protection = sc->protection;
alignment = sc->structalign;
storage_class |= sc->stc;
if (sc->stc & STCdeprecated)
isdeprecated = true;
@@ -403,7 +447,7 @@ void StructDeclaration::semantic(Scope *sc)
int hasfunctions = 0;
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
//printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars());
s->addMember(sc, this, 1);
if (s->isFuncDeclaration())
@@ -452,6 +496,7 @@ void StructDeclaration::semantic(Scope *sc)
sc2->inunion = 1;
sc2->protection = PROTpublic;
sc2->explicitProtection = 0;
sc2->structalign = STRUCTALIGN_DEFAULT;
size_t members_dim = members->dim;
@@ -507,7 +552,7 @@ void StructDeclaration::semantic(Scope *sc)
fields.setDim(0);
structsize = 0;
alignsize = 0;
structalign = 0;
// structalign = 0;
scope = scx ? scx : new Scope(*sc);
scope->setNoFree();
@@ -631,6 +676,15 @@ void StructDeclaration::semantic(Scope *sc)
aggNew = (NewDeclaration *)search(0, Id::classNew, 0);
aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 0);
TypeTuple *tup = type->toArgTypes();
size_t dim = tup->arguments->dim;
if (dim >= 1)
{ assert(dim <= 2);
arg1type = (*tup->arguments)[0]->type;
if (dim == 2)
arg2type = (*tup->arguments)[1]->type;
}
if (sc->func)
{
semantic2(sc);
@@ -667,6 +721,7 @@ Dsymbol *StructDeclaration::search(Loc loc, Identifier *ident, int flags)
void StructDeclaration::finalizeSize(Scope *sc)
{
//printf("StructDeclaration::finalizeSize() %s\n", toChars());
if (sizeok != SIZEOKnone)
return;
@@ -690,11 +745,56 @@ void StructDeclaration::finalizeSize(Scope *sc)
// Round struct size up to next alignsize boundary.
// This will ensure that arrays of structs will get their internals
// aligned properly.
structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
if (alignment == STRUCTALIGN_DEFAULT)
structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
else
structsize = (structsize + alignment - 1) & ~(alignment - 1);
sizeok = SIZEOKdone;
}
/***************************************
* Return true if struct is POD (Plain Old Data).
* This is defined as:
* not nested
* no postblits, constructors, destructors, or assignment operators
* no fields with with any of those
* The idea being these are compatible with C structs.
*
* Note that D struct constructors can mean POD, since there is always default
* construction with no ctor, but that interferes with OPstrpar which wants it
* on the stack in memory, not in registers.
*/
bool StructDeclaration::isPOD()
{
if (isnested || cpctor || postblit || ctor || dtor)
return false;
/* Recursively check any fields have a constructor.
* We should cache the results of this.
*/
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = fields[i];
VarDeclaration *v = s->isVarDeclaration();
assert(v && v->storage_class & STCfield);
if (v->storage_class & STCref)
continue;
Type *tv = v->type->toBasetype();
while (tv->ty == Tsarray)
{ TypeSArray *ta = (TypeSArray *)tv;
tv = tv->nextOf()->toBasetype();
}
if (tv->ty == Tstruct)
{ TypeStruct *ts = (TypeStruct *)tv;
StructDeclaration *sd = ts->sym;
if (!sd->isPOD())
return false;
}
}
return true;
}
void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->printf("%s ", kind());
@@ -711,7 +811,7 @@ void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = members->tdata()[i];
Dsymbol *s = (*members)[i];
buf->writestring(" ");
s->toCBuffer(buf, hgs);
+429 -259
View File
File diff suppressed because it is too large Load Diff
+16 -16
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2011 by Digital Mars
// Copyright (c) 1999-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -89,7 +89,7 @@ Expression *TraitsExp::semantic(Scope *sc)
#define ISTYPE(cond) \
for (size_t i = 0; i < dim; i++) \
{ Type *t = getType(args->tdata()[i]); \
{ Type *t = getType((*args)[i]); \
if (!t) \
goto Lfalse; \
if (!(cond)) \
@@ -101,7 +101,7 @@ Expression *TraitsExp::semantic(Scope *sc)
#define ISDSYMBOL(cond) \
for (size_t i = 0; i < dim; i++) \
{ Dsymbol *s = getDsymbol(args->tdata()[i]); \
{ Dsymbol *s = getDsymbol((*args)[i]); \
if (!s) \
goto Lfalse; \
if (!(cond)) \
@@ -196,7 +196,7 @@ Expression *TraitsExp::semantic(Scope *sc)
if (dim != 1)
goto Ldimerror;
Object *o = args->tdata()[0];
Object *o = (*args)[0];
Dsymbol *s = getDsymbol(o);
if (!s || !s->ident)
{
@@ -210,7 +210,7 @@ Expression *TraitsExp::semantic(Scope *sc)
{
if (dim != 1)
goto Ldimerror;
Object *o = args->tdata()[0];
Object *o = (*args)[0];
Dsymbol *s = getDsymbol(o);
if (s)
s = s->toParent();
@@ -231,13 +231,13 @@ Expression *TraitsExp::semantic(Scope *sc)
{
if (dim != 2)
goto Ldimerror;
Object *o = args->tdata()[0];
Expression *e = isExpression(args->tdata()[1]);
Object *o = (*args)[0];
Expression *e = isExpression((*args)[1]);
if (!e)
{ error("expression expected as second argument of __traits %s", ident->toChars());
goto Lfalse;
}
e = e->optimize(WANTvalue | WANTinterpret);
e = e->ctfeInterpret();
StringExp *se = e->toString();
if (!se || se->length() == 0)
{ error("string expected as second argument of __traits %s instead of %s", ident->toChars(), e->toChars());
@@ -336,7 +336,7 @@ Expression *TraitsExp::semantic(Scope *sc)
{
if (dim != 1)
goto Ldimerror;
Object *o = args->tdata()[0];
Object *o = (*args)[0];
Dsymbol *s = getDsymbol(o);
ClassDeclaration *cd;
if (!s || (cd = s->isClassDeclaration()) == NULL)
@@ -350,7 +350,7 @@ Expression *TraitsExp::semantic(Scope *sc)
{
if (dim != 1)
goto Ldimerror;
Object *o = args->tdata()[0];
Object *o = (*args)[0];
Dsymbol *s = getDsymbol(o);
ScopeDsymbol *sd;
if (!s)
@@ -380,7 +380,7 @@ Expression *TraitsExp::semantic(Scope *sc)
/* Skip if already present in idents[]
*/
for (size_t j = 0; j < idents->dim; j++)
{ Identifier *id = idents->tdata()[j];
{ Identifier *id = (*idents)[j];
if (id == sm->ident)
return 0;
#ifdef DEBUG
@@ -421,9 +421,9 @@ Expression *TraitsExp::semantic(Scope *sc)
assert(sizeof(Expressions) == sizeof(Identifiers));
Expressions *exps = (Expressions *)idents;
for (size_t i = 0; i < idents->dim; i++)
{ Identifier *id = idents->tdata()[i];
{ Identifier *id = (*idents)[i];
StringExp *se = new StringExp(loc, id->toChars());
exps->tdata()[i] = se;
(*exps)[i] = se;
}
#if DMDV1
@@ -448,7 +448,7 @@ Expression *TraitsExp::semantic(Scope *sc)
goto Lfalse;
for (size_t i = 0; i < dim; i++)
{ Object *o = args->tdata()[i];
{ Object *o = (*args)[i];
Expression *e;
unsigned errors = global.startGagging();
@@ -491,8 +491,8 @@ Expression *TraitsExp::semantic(Scope *sc)
if (dim != 2)
goto Ldimerror;
TemplateInstance::semanticTiargs(loc, sc, args, 0);
Object *o1 = args->tdata()[0];
Object *o2 = args->tdata()[1];
Object *o1 = (*args)[0];
Object *o2 = (*args)[1];
Dsymbol *s1 = getDsymbol(o1);
Dsymbol *s2 = getDsymbol(o2);
-323
View File
@@ -1,323 +0,0 @@
// Copyright (c) 2003 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <assert.h>
/*******************************
* Return !=0 if unicode alpha.
* Use table from C99 Appendix D.
*/
int isUniAlpha(unsigned u)
{
static unsigned short table[][2] =
{
{ 0x00AA, 0x00AA },
{ 0x00B5, 0x00B5 },
{ 0x00B7, 0x00B7 },
{ 0x00BA, 0x00BA },
{ 0x00C0, 0x00D6 },
{ 0x00D8, 0x00F6 },
{ 0x00F8, 0x01F5 },
{ 0x01FA, 0x0217 },
{ 0x0250, 0x02A8 },
{ 0x02B0, 0x02B8 },
{ 0x02BB, 0x02BB },
{ 0x02BD, 0x02C1 },
{ 0x02D0, 0x02D1 },
{ 0x02E0, 0x02E4 },
{ 0x037A, 0x037A },
{ 0x0386, 0x0386 },
{ 0x0388, 0x038A },
{ 0x038C, 0x038C },
{ 0x038E, 0x03A1 },
{ 0x03A3, 0x03CE },
{ 0x03D0, 0x03D6 },
{ 0x03DA, 0x03DA },
{ 0x03DC, 0x03DC },
{ 0x03DE, 0x03DE },
{ 0x03E0, 0x03E0 },
{ 0x03E2, 0x03F3 },
{ 0x0401, 0x040C },
{ 0x040E, 0x044F },
{ 0x0451, 0x045C },
{ 0x045E, 0x0481 },
{ 0x0490, 0x04C4 },
{ 0x04C7, 0x04C8 },
{ 0x04CB, 0x04CC },
{ 0x04D0, 0x04EB },
{ 0x04EE, 0x04F5 },
{ 0x04F8, 0x04F9 },
{ 0x0531, 0x0556 },
{ 0x0559, 0x0559 },
{ 0x0561, 0x0587 },
{ 0x05B0, 0x05B9 },
{ 0x05BB, 0x05BD },
{ 0x05BF, 0x05BF },
{ 0x05C1, 0x05C2 },
{ 0x05D0, 0x05EA },
{ 0x05F0, 0x05F2 },
{ 0x0621, 0x063A },
{ 0x0640, 0x0652 },
{ 0x0660, 0x0669 },
{ 0x0670, 0x06B7 },
{ 0x06BA, 0x06BE },
{ 0x06C0, 0x06CE },
{ 0x06D0, 0x06DC },
{ 0x06E5, 0x06E8 },
{ 0x06EA, 0x06ED },
{ 0x06F0, 0x06F9 },
{ 0x0901, 0x0903 },
{ 0x0905, 0x0939 },
{ 0x093D, 0x093D },
{ 0x093E, 0x094D },
{ 0x0950, 0x0952 },
{ 0x0958, 0x0963 },
{ 0x0966, 0x096F },
{ 0x0981, 0x0983 },
{ 0x0985, 0x098C },
{ 0x098F, 0x0990 },
{ 0x0993, 0x09A8 },
{ 0x09AA, 0x09B0 },
{ 0x09B2, 0x09B2 },
{ 0x09B6, 0x09B9 },
{ 0x09BE, 0x09C4 },
{ 0x09C7, 0x09C8 },
{ 0x09CB, 0x09CD },
{ 0x09DC, 0x09DD },
{ 0x09DF, 0x09E3 },
{ 0x09E6, 0x09EF },
{ 0x09F0, 0x09F1 },
{ 0x0A02, 0x0A02 },
{ 0x0A05, 0x0A0A },
{ 0x0A0F, 0x0A10 },
{ 0x0A13, 0x0A28 },
{ 0x0A2A, 0x0A30 },
{ 0x0A32, 0x0A33 },
{ 0x0A35, 0x0A36 },
{ 0x0A38, 0x0A39 },
{ 0x0A3E, 0x0A42 },
{ 0x0A47, 0x0A48 },
{ 0x0A4B, 0x0A4D },
{ 0x0A59, 0x0A5C },
{ 0x0A5E, 0x0A5E },
{ 0x0A66, 0x0A6F },
{ 0x0A74, 0x0A74 },
{ 0x0A81, 0x0A83 },
{ 0x0A85, 0x0A8B },
{ 0x0A8D, 0x0A8D },
{ 0x0A8F, 0x0A91 },
{ 0x0A93, 0x0AA8 },
{ 0x0AAA, 0x0AB0 },
{ 0x0AB2, 0x0AB3 },
{ 0x0AB5, 0x0AB9 },
{ 0x0ABD, 0x0AC5 },
{ 0x0AC7, 0x0AC9 },
{ 0x0ACB, 0x0ACD },
{ 0x0AD0, 0x0AD0 },
{ 0x0AE0, 0x0AE0 },
{ 0x0AE6, 0x0AEF },
{ 0x0B01, 0x0B03 },
{ 0x0B05, 0x0B0C },
{ 0x0B0F, 0x0B10 },
{ 0x0B13, 0x0B28 },
{ 0x0B2A, 0x0B30 },
{ 0x0B32, 0x0B33 },
{ 0x0B36, 0x0B39 },
{ 0x0B3D, 0x0B3D },
{ 0x0B3E, 0x0B43 },
{ 0x0B47, 0x0B48 },
{ 0x0B4B, 0x0B4D },
{ 0x0B5C, 0x0B5D },
{ 0x0B5F, 0x0B61 },
{ 0x0B66, 0x0B6F },
{ 0x0B82, 0x0B83 },
{ 0x0B85, 0x0B8A },
{ 0x0B8E, 0x0B90 },
{ 0x0B92, 0x0B95 },
{ 0x0B99, 0x0B9A },
{ 0x0B9C, 0x0B9C },
{ 0x0B9E, 0x0B9F },
{ 0x0BA3, 0x0BA4 },
{ 0x0BA8, 0x0BAA },
{ 0x0BAE, 0x0BB5 },
{ 0x0BB7, 0x0BB9 },
{ 0x0BBE, 0x0BC2 },
{ 0x0BC6, 0x0BC8 },
{ 0x0BCA, 0x0BCD },
{ 0x0BE7, 0x0BEF },
{ 0x0C01, 0x0C03 },
{ 0x0C05, 0x0C0C },
{ 0x0C0E, 0x0C10 },
{ 0x0C12, 0x0C28 },
{ 0x0C2A, 0x0C33 },
{ 0x0C35, 0x0C39 },
{ 0x0C3E, 0x0C44 },
{ 0x0C46, 0x0C48 },
{ 0x0C4A, 0x0C4D },
{ 0x0C60, 0x0C61 },
{ 0x0C66, 0x0C6F },
{ 0x0C82, 0x0C83 },
{ 0x0C85, 0x0C8C },
{ 0x0C8E, 0x0C90 },
{ 0x0C92, 0x0CA8 },
{ 0x0CAA, 0x0CB3 },
{ 0x0CB5, 0x0CB9 },
{ 0x0CBE, 0x0CC4 },
{ 0x0CC6, 0x0CC8 },
{ 0x0CCA, 0x0CCD },
{ 0x0CDE, 0x0CDE },
{ 0x0CE0, 0x0CE1 },
{ 0x0CE6, 0x0CEF },
{ 0x0D02, 0x0D03 },
{ 0x0D05, 0x0D0C },
{ 0x0D0E, 0x0D10 },
{ 0x0D12, 0x0D28 },
{ 0x0D2A, 0x0D39 },
{ 0x0D3E, 0x0D43 },
{ 0x0D46, 0x0D48 },
{ 0x0D4A, 0x0D4D },
{ 0x0D60, 0x0D61 },
{ 0x0D66, 0x0D6F },
{ 0x0E01, 0x0E3A },
{ 0x0E40, 0x0E5B },
// { 0x0E50, 0x0E59 },
{ 0x0E81, 0x0E82 },
{ 0x0E84, 0x0E84 },
{ 0x0E87, 0x0E88 },
{ 0x0E8A, 0x0E8A },
{ 0x0E8D, 0x0E8D },
{ 0x0E94, 0x0E97 },
{ 0x0E99, 0x0E9F },
{ 0x0EA1, 0x0EA3 },
{ 0x0EA5, 0x0EA5 },
{ 0x0EA7, 0x0EA7 },
{ 0x0EAA, 0x0EAB },
{ 0x0EAD, 0x0EAE },
{ 0x0EB0, 0x0EB9 },
{ 0x0EBB, 0x0EBD },
{ 0x0EC0, 0x0EC4 },
{ 0x0EC6, 0x0EC6 },
{ 0x0EC8, 0x0ECD },
{ 0x0ED0, 0x0ED9 },
{ 0x0EDC, 0x0EDD },
{ 0x0F00, 0x0F00 },
{ 0x0F18, 0x0F19 },
{ 0x0F20, 0x0F33 },
{ 0x0F35, 0x0F35 },
{ 0x0F37, 0x0F37 },
{ 0x0F39, 0x0F39 },
{ 0x0F3E, 0x0F47 },
{ 0x0F49, 0x0F69 },
{ 0x0F71, 0x0F84 },
{ 0x0F86, 0x0F8B },
{ 0x0F90, 0x0F95 },
{ 0x0F97, 0x0F97 },
{ 0x0F99, 0x0FAD },
{ 0x0FB1, 0x0FB7 },
{ 0x0FB9, 0x0FB9 },
{ 0x10A0, 0x10C5 },
{ 0x10D0, 0x10F6 },
{ 0x1E00, 0x1E9B },
{ 0x1EA0, 0x1EF9 },
{ 0x1F00, 0x1F15 },
{ 0x1F18, 0x1F1D },
{ 0x1F20, 0x1F45 },
{ 0x1F48, 0x1F4D },
{ 0x1F50, 0x1F57 },
{ 0x1F59, 0x1F59 },
{ 0x1F5B, 0x1F5B },
{ 0x1F5D, 0x1F5D },
{ 0x1F5F, 0x1F7D },
{ 0x1F80, 0x1FB4 },
{ 0x1FB6, 0x1FBC },
{ 0x1FBE, 0x1FBE },
{ 0x1FC2, 0x1FC4 },
{ 0x1FC6, 0x1FCC },
{ 0x1FD0, 0x1FD3 },
{ 0x1FD6, 0x1FDB },
{ 0x1FE0, 0x1FEC },
{ 0x1FF2, 0x1FF4 },
{ 0x1FF6, 0x1FFC },
{ 0x203F, 0x2040 },
{ 0x207F, 0x207F },
{ 0x2102, 0x2102 },
{ 0x2107, 0x2107 },
{ 0x210A, 0x2113 },
{ 0x2115, 0x2115 },
{ 0x2118, 0x211D },
{ 0x2124, 0x2124 },
{ 0x2126, 0x2126 },
{ 0x2128, 0x2128 },
{ 0x212A, 0x2131 },
{ 0x2133, 0x2138 },
{ 0x2160, 0x2182 },
{ 0x3005, 0x3007 },
{ 0x3021, 0x3029 },
{ 0x3041, 0x3093 },
{ 0x309B, 0x309C },
{ 0x30A1, 0x30F6 },
{ 0x30FB, 0x30FC },
{ 0x3105, 0x312C },
{ 0x4E00, 0x9FA5 },
{ 0xAC00, 0xD7A3 },
};
#ifdef DEBUG
for (int i = 0; i < sizeof(table) / sizeof(table[0]); i++)
{
//printf("%x\n", table[i][0]);
assert(table[i][0] <= table[i][1]);
if (i < sizeof(table) / sizeof(table[0]) - 1)
assert(table[i][1] < table[i + 1][0]);
}
#endif
if (u > 0xD7A3)
goto Lisnot;
// Binary search
int mid;
int low;
int high;
low = 0;
high = sizeof(table) / sizeof(table[0]) - 1;
while (low <= high)
{
mid = (low + high) >> 1;
if (u < table[mid][0])
high = mid - 1;
else if (u > table[mid][1])
low = mid + 1;
else
goto Lis;
}
Lisnot:
#ifdef DEBUG
for (int i = 0; i < sizeof(table) / sizeof(table[0]); i++)
{
assert(u < table[i][0] || u > table[i][1]);
}
#endif
return 0;
Lis:
#ifdef DEBUG
for (int i = 0; i < sizeof(table) / sizeof(table[0]); i++)
{
if (u >= table[i][0] && u <= table[i][1])
return 1;
}
assert(0); // should have been in table
#endif
return 1;
}
+8
View File
@@ -1,4 +1,12 @@
// Copyright (c) 2010-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include "mars.h"
+228 -237
View File
@@ -1,5 +1,5 @@
// utf.c
// Copyright (c) 2003-2009 by Digital Mars
// Copyright (c) 2003-2012 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -7,22 +7,32 @@
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
// Description of UTF-8 at:
// http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
/// Description of UTF-8 in [1]. Unicode non-characters and private-use
/// code points described in [2],[4].
///
/// References:
/// [1] http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
/// [2] http://en.wikipedia.org/wiki/Unicode
/// [3] http://unicode.org/faq/utf_bom.html
/// [4] http://www.unicode.org/versions/Unicode6.1.0/ch03.pdf
#include <stdio.h>
#include <string.h>
#include <assert.h>
#include "utf.h"
int utf_isValidDchar(dchar_t c)
namespace
{
return c < 0xD800 ||
(c > 0xDFFF && c <= 0x10FFFF && c != 0xFFFE && c != 0xFFFF);
}
static const unsigned char UTF8stride[256] =
/* The following encodings are valid, except for the 5 and 6 byte
* combinations:
* 0xxxxxxx
* 110xxxxx 10xxxxxx
* 1110xxxx 10xxxxxx 10xxxxxx
* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
const unsigned UTF8_STRIDE[256] =
{
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
@@ -42,237 +52,73 @@ static const unsigned char UTF8stride[256] =
4,4,4,4,4,4,4,4,5,5,5,5,6,6,0xFF,0xFF,
};
/**
* stride() returns the length of a UTF-8 sequence starting at index i
* in string s.
* Returns:
* The number of bytes in the UTF-8 sequence or
* 0xFF meaning s[i] is not the start of of UTF-8 sequence.
*/
} // namespace
unsigned stride(unsigned char* s, size_t i)
namespace Unicode
{
unsigned result = UTF8stride[s[i]];
return result;
// UTF-8 decoding errors
char const UTF8_DECODE_OUTSIDE_CODE_SPACE[] = "Outside Unicode code space";
char const UTF8_DECODE_TRUNCATED_SEQUENCE[] = "Truncated UTF-8 sequence";
char const UTF8_DECODE_OVERLONG[] = "Overlong UTF-8 sequence";
char const UTF8_DECODE_INVALID_TRAILER[] = "Invalid trailing code unit";
char const UTF8_DECODE_INVALID_CODE_POINT[] = "Invalid code point decoded";
// UTF-16 decoding errors
char const UTF16_DECODE_TRUNCATED_SEQUENCE[]= "Truncated UTF-16 sequence";
char const UTF16_DECODE_INVALID_SURROGATE[] = "Invalid low surrogate";
char const UTF16_DECODE_UNPAIRED_SURROGATE[]= "Unpaired surrogate";
char const UTF16_DECODE_INVALID_CODE_POINT[]= "Invalid code point decoded";
} // namespace Unicode
using namespace Unicode;
/// The Unicode code space is the range of code points [0x000000,0x10FFFF]
/// except the UTF-16 surrogate pairs in the range [0xD800,0xDFFF]
/// and non-characters (which end in 0xFFFE or 0xFFFF).
bool utf_isValidDchar(dchar_t c)
{
// TODO: Whether non-char code points should be rejected is pending review
return c <= 0x10FFFF // largest character code point
&& !(0xD800 <= c && c <= 0xDFFF) // surrogate pairs
&& (c & 0xFFFFFE) != 0x00FFFE // non-characters
// && (c & 0xFFFE) != 0xFFFE // non-characters
// && !(0x00FDD0 <= c && c <= 0x00FDEF) // non-characters
;
}
/********************************************
* Decode a single UTF-8 character sequence.
* Returns:
* NULL success
* !=NULL error message string
/*******************************
* Return !=0 if unicode alpha.
* Use table from C99 Appendix D.
*/
const char *utf_decodeChar(unsigned char *s, size_t len, size_t *pidx, dchar_t *presult)
bool isUniAlpha(dchar_t c)
{
dchar_t V;
size_t i = *pidx;
unsigned char u = s[i];
//printf("utf_decodeChar(s = %02x, %02x, %02x len = %d)\n", u, s[1], s[2], len);
assert(i >= 0 && i < len);
if (u & 0x80)
{ unsigned n;
unsigned char u2;
/* The following encodings are valid, except for the 5 and 6 byte
* combinations:
* 0xxxxxxx
* 110xxxxx 10xxxxxx
* 1110xxxx 10xxxxxx 10xxxxxx
* 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
* 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
* 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
*/
for (n = 1; ; n++)
{
if (n > 4)
goto Lerr; // only do the first 4 of 6 encodings
if (((u << n) & 0x80) == 0)
{
if (n == 1)
goto Lerr;
break;
}
}
// Pick off (7 - n) significant bits of B from first byte of octet
V = (dchar_t)(u & ((1 << (7 - n)) - 1));
if (i + (n - 1) >= len)
goto Lerr; // off end of string
/* The following combinations are overlong, and illegal:
* 1100000x (10xxxxxx)
* 11100000 100xxxxx (10xxxxxx)
* 11110000 1000xxxx (10xxxxxx 10xxxxxx)
* 11111000 10000xxx (10xxxxxx 10xxxxxx 10xxxxxx)
* 11111100 100000xx (10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx)
*/
u2 = s[i + 1];
if ((u & 0xFE) == 0xC0 ||
(u == 0xE0 && (u2 & 0xE0) == 0x80) ||
(u == 0xF0 && (u2 & 0xF0) == 0x80) ||
(u == 0xF8 && (u2 & 0xF8) == 0x80) ||
(u == 0xFC && (u2 & 0xFC) == 0x80))
goto Lerr; // overlong combination
for (unsigned j = 1; j != n; j++)
{
u = s[i + j];
if ((u & 0xC0) != 0x80)
goto Lerr; // trailing bytes are 10xxxxxx
V = (V << 6) | (u & 0x3F);
}
if (!utf_isValidDchar(V))
goto Lerr;
i += n;
}
else
static size_t const END = sizeof(ALPHA_TABLE) / sizeof(ALPHA_TABLE[0]);
size_t high = END - 1;
// Shortcut search if c is out of range
size_t low
= (c < ALPHA_TABLE[0][0] || ALPHA_TABLE[high][1] < c) ? high + 1 : 0;
// Binary search
while (low <= high)
{
V = (dchar_t) u;
i++;
}
assert(utf_isValidDchar(V));
*pidx = i;
*presult = V;
return NULL;
Lerr:
*presult = (dchar_t) s[i];
*pidx = i + 1;
return "invalid UTF-8 sequence";
}
/***************************************************
* Validate a UTF-8 string.
* Returns:
* NULL success
* !=NULL error message string
*/
const char *utf_validateString(unsigned char *s, size_t len)
{
size_t idx;
const char *err = NULL;
dchar_t dc;
for (idx = 0; idx < len; )
{
err = utf_decodeChar(s, len, &idx, &dc);
if (err)
break;
}
return err;
}
/********************************************
* Decode a single UTF-16 character sequence.
* Returns:
* NULL success
* !=NULL error message string
*/
const char *utf_decodeWchar(unsigned short *s, size_t len, size_t *pidx, dchar_t *presult)
{
const char *msg;
size_t i = *pidx;
unsigned u = s[i];
assert(i >= 0 && i < len);
if (u & ~0x7F)
{ if (u >= 0xD800 && u <= 0xDBFF)
{ unsigned u2;
if (i + 1 == len)
{ msg = "surrogate UTF-16 high value past end of string";
goto Lerr;
}
u2 = s[i + 1];
if (u2 < 0xDC00 || u2 > 0xDFFF)
{ msg = "surrogate UTF-16 low value out of range";
goto Lerr;
}
u = ((u - 0xD7C0) << 10) + (u2 - 0xDC00);
i += 2;
}
else if (u >= 0xDC00 && u <= 0xDFFF)
{ msg = "unpaired surrogate UTF-16 value";
goto Lerr;
}
else if (u == 0xFFFE || u == 0xFFFF)
{ msg = "illegal UTF-16 value";
goto Lerr;
}
size_t mid = (low + high) >> 1;
if (c < ALPHA_TABLE[mid][0])
high = mid - 1;
else if (ALPHA_TABLE[mid][1] < c)
low = mid + 1;
else
i++;
{
assert(ALPHA_TABLE[mid][0] <= c && c <= ALPHA_TABLE[mid][1]);
return true;
}
}
else
{
i++;
}
assert(utf_isValidDchar(u));
*pidx = i;
*presult = (dchar_t)u;
return NULL;
Lerr:
*presult = (dchar_t)s[i];
*pidx = i + 1;
return msg;
return false;
}
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.
* Returns the code length of c in code units.
*/
int utf_codeLengthChar(dchar_t c)
@@ -291,10 +137,10 @@ int utf_codeLengthWchar(dchar_t c)
}
/**
* Returns the code length of c in the encoding.
* Returns the code length of c in code units for 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)
@@ -305,16 +151,161 @@ int utf_codeLength(int sz, dchar_t c)
return 1;
}
void utf_encode(int sz, void *s, dchar_t c)
void utf_encodeChar(utf8_t *s, dchar_t c)
{
if (sz == 1)
utf_encodeChar((unsigned char *)s, c);
else if (sz == 2)
utf_encodeWchar((unsigned short *)s, c);
assert(s != NULL);
assert(utf_isValidDchar(c));
if (c <= 0x7F)
{
s[0] = static_cast<utf8_t>(c);
}
else if (c <= 0x07FF)
{
s[0] = static_cast<utf8_t>(0xC0 | (c >> 6));
s[1] = static_cast<utf8_t>(0x80 | (c & 0x3F));
}
else if (c <= 0xFFFF)
{
s[0] = static_cast<utf8_t>(0xE0 | (c >> 12));
s[1] = static_cast<utf8_t>(0x80 | ((c >> 6) & 0x3F));
s[2] = static_cast<utf8_t>(0x80 | (c & 0x3F));
}
else if (c <= 0x10FFFF)
{
s[0] = static_cast<utf8_t>(0xF0 | (c >> 18));
s[1] = static_cast<utf8_t>(0x80 | ((c >> 12) & 0x3F));
s[2] = static_cast<utf8_t>(0x80 | ((c >> 6) & 0x3F));
s[3] = static_cast<utf8_t>(0x80 | (c & 0x3F));
}
else
assert(0);
}
void utf_encodeWchar(utf16_t *s, dchar_t c)
{
assert(s != NULL);
assert(utf_isValidDchar(c));
if (c <= 0xFFFF)
{
s[0] = static_cast<utf16_t>(c);
}
else
{
assert(sz == 4);
memcpy((unsigned char *)s, &c, sz);
s[0] = static_cast<utf16_t>((((c - 0x010000) >> 10) & 0x03FF) + 0xD800);
s[1] = static_cast<utf16_t>(((c - 0x010000) & 0x03FF) + 0xDC00);
}
}
void utf_encode(int sz, void *s, dchar_t c)
{
if (sz == 1)
utf_encodeChar((utf8_t *)s, c);
else if (sz == 2)
utf_encodeWchar((utf16_t *)s, c);
else
{
assert(sz == 4);
*((utf32_t *)s) = c;
}
}
/********************************************
* Decode a UTF-8 sequence as a single UTF-32 code point.
* Returns:
* NULL success
* !=NULL error message string
*/
const char *utf_decodeChar(utf8_t const *s, size_t len, size_t *pidx, dchar_t *presult)
{
assert(s != NULL);
assert(pidx != NULL);
assert(presult != NULL);
size_t i = (*pidx)++;
assert(i < len);
utf8_t u = s[i];
// Pre-stage results for ASCII and error cases
*presult = u;
//printf("utf_decodeChar(s = %02x, %02x, %02x len = %d)\n", u, s[1], s[2], len);
// Get expected sequence length
unsigned n = UTF8_STRIDE[u];
switch (n)
{
case 1: // ASCII
return UTF8_DECODE_OK;
case 2: case 3: case 4: // multi-byte UTF-8
break;
default: // 5- or 6-byte sequence
return UTF8_DECODE_OUTSIDE_CODE_SPACE;
}
if (len < i + n) // source too short
return UTF8_DECODE_TRUNCATED_SEQUENCE;
// Pick off 7 - n low bits from first code unit
utf32_t c = u & ((1 << (7 - n)) - 1);
/* The following combinations are overlong, and illegal:
* 1100000x (10xxxxxx)
* 11100000 100xxxxx (10xxxxxx)
* 11110000 1000xxxx (10xxxxxx 10xxxxxx)
* 11111000 10000xxx (10xxxxxx 10xxxxxx 10xxxxxx)
* 11111100 100000xx (10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx)
*/
utf8_t u2 = s[++i];
if ((u & 0xFE) == 0xC0 || // overlong combination
(u == 0xE0 && (u2 & 0xE0) == 0x80) ||
(u == 0xF0 && (u2 & 0xF0) == 0x80) ||
(u == 0xF8 && (u2 & 0xF8) == 0x80) ||
(u == 0xFC && (u2 & 0xFC) == 0x80))
return UTF8_DECODE_OVERLONG;
// Decode remaining bits
for (n += i - 1; i != n; ++i)
{
u = s[i];
if ((u & 0xC0) != 0x80) // trailing bytes are 10xxxxxx
return UTF8_DECODE_INVALID_TRAILER;
c = (c << 6) | (u & 0x3F);
}
if (!utf_isValidDchar(c))
return UTF8_DECODE_INVALID_CODE_POINT;
*pidx = i;
*presult = c;
return UTF8_DECODE_OK;
}
/********************************************
* Decode a UTF-16 sequence as a single UTF-32 code point.
* Returns:
* NULL success
* !=NULL error message string
*/
const char *utf_decodeWchar(utf16_t const *s, size_t len, size_t *pidx, dchar_t *presult)
{
assert(s != NULL);
assert(pidx != NULL);
assert(presult != NULL);
size_t i = (*pidx)++;
assert(i < len);
// Pre-stage results for ASCII and error cases
utf32_t u = *presult = s[i];
if (u < 0x80) // ASCII
return UTF16_DECODE_OK;
if (0xD800 <= u && u <= 0xDBFF) // Surrogate pair
{ if (len <= i + 1)
return UTF16_DECODE_TRUNCATED_SEQUENCE;
utf16_t u2 = s[i + 1];
if (u2 < 0xDC00 || 0xDFFF < u)
return UTF16_DECODE_INVALID_SURROGATE;
u = ((u - 0xD7C0) << 10) + (u2 - 0xDC00);
++*pidx;
}
else if (0xDC00 <= u && u <= 0xDFFF)
return UTF16_DECODE_UNPAIRED_SURROGATE;
if (!utf_isValidDchar(u))
return UTF16_DECODE_INVALID_CODE_POINT;
*presult = u;
return UTF16_DECODE_OK;
}
+99 -10
View File
@@ -11,25 +11,114 @@
#ifndef DMD_UTF_H
#define DMD_UTF_H
#include <stdlib.h>
typedef unsigned dchar_t;
/// A UTF-8 code unit
typedef unsigned char utf8_t;
/// A UTF-16 code unit
typedef unsigned short utf16_t;
/// A UTF-32 code unit
typedef unsigned int utf32_t;
typedef utf32_t dchar_t;
int utf_isValidDchar(dchar_t c);
namespace Unicode
{
const char *utf_decodeChar(unsigned char *s, size_t len, size_t *pidx, dchar_t *presult);
const char *utf_decodeWchar(unsigned short *s, size_t len, size_t *pidx, dchar_t *presult);
static utf16_t const ALPHA_TABLE[][2] =
{
{ 0x00AA, 0x00AA }, { 0x00B5, 0x00B5 }, { 0x00B7, 0x00B7 }, { 0x00BA, 0x00BA },
{ 0x00C0, 0x00D6 }, { 0x00D8, 0x00F6 }, { 0x00F8, 0x01F5 }, { 0x01FA, 0x0217 },
{ 0x0250, 0x02A8 }, { 0x02B0, 0x02B8 }, { 0x02BB, 0x02BB }, { 0x02BD, 0x02C1 },
{ 0x02D0, 0x02D1 }, { 0x02E0, 0x02E4 }, { 0x037A, 0x037A }, { 0x0386, 0x0386 },
{ 0x0388, 0x038A }, { 0x038C, 0x038C }, { 0x038E, 0x03A1 }, { 0x03A3, 0x03CE },
{ 0x03D0, 0x03D6 }, { 0x03DA, 0x03DA }, { 0x03DC, 0x03DC }, { 0x03DE, 0x03DE },
{ 0x03E0, 0x03E0 }, { 0x03E2, 0x03F3 }, { 0x0401, 0x040C }, { 0x040E, 0x044F },
{ 0x0451, 0x045C }, { 0x045E, 0x0481 }, { 0x0490, 0x04C4 }, { 0x04C7, 0x04C8 },
{ 0x04CB, 0x04CC }, { 0x04D0, 0x04EB }, { 0x04EE, 0x04F5 }, { 0x04F8, 0x04F9 },
{ 0x0531, 0x0556 }, { 0x0559, 0x0559 }, { 0x0561, 0x0587 }, { 0x05B0, 0x05B9 },
{ 0x05BB, 0x05BD }, { 0x05BF, 0x05BF }, { 0x05C1, 0x05C2 }, { 0x05D0, 0x05EA },
{ 0x05F0, 0x05F2 }, { 0x0621, 0x063A }, { 0x0640, 0x0652 }, { 0x0660, 0x0669 },
{ 0x0670, 0x06B7 }, { 0x06BA, 0x06BE }, { 0x06C0, 0x06CE }, { 0x06D0, 0x06DC },
{ 0x06E5, 0x06E8 }, { 0x06EA, 0x06ED }, { 0x06F0, 0x06F9 }, { 0x0901, 0x0903 },
{ 0x0905, 0x0939 }, { 0x093D, 0x094D }, { 0x0950, 0x0952 }, { 0x0958, 0x0963 },
{ 0x0966, 0x096F }, { 0x0981, 0x0983 }, { 0x0985, 0x098C }, { 0x098F, 0x0990 },
{ 0x0993, 0x09A8 }, { 0x09AA, 0x09B0 }, { 0x09B2, 0x09B2 }, { 0x09B6, 0x09B9 },
{ 0x09BE, 0x09C4 }, { 0x09C7, 0x09C8 }, { 0x09CB, 0x09CD }, { 0x09DC, 0x09DD },
{ 0x09DF, 0x09E3 }, { 0x09E6, 0x09F1 }, { 0x0A02, 0x0A02 }, { 0x0A05, 0x0A0A },
{ 0x0A0F, 0x0A10 }, { 0x0A13, 0x0A28 }, { 0x0A2A, 0x0A30 }, { 0x0A32, 0x0A33 },
{ 0x0A35, 0x0A36 }, { 0x0A38, 0x0A39 }, { 0x0A3E, 0x0A42 }, { 0x0A47, 0x0A48 },
{ 0x0A4B, 0x0A4D }, { 0x0A59, 0x0A5C }, { 0x0A5E, 0x0A5E }, { 0x0A66, 0x0A6F },
{ 0x0A74, 0x0A74 }, { 0x0A81, 0x0A83 }, { 0x0A85, 0x0A8B }, { 0x0A8D, 0x0A8D },
{ 0x0A8F, 0x0A91 }, { 0x0A93, 0x0AA8 }, { 0x0AAA, 0x0AB0 }, { 0x0AB2, 0x0AB3 },
{ 0x0AB5, 0x0AB9 }, { 0x0ABD, 0x0AC5 }, { 0x0AC7, 0x0AC9 }, { 0x0ACB, 0x0ACD },
{ 0x0AD0, 0x0AD0 }, { 0x0AE0, 0x0AE0 }, { 0x0AE6, 0x0AEF }, { 0x0B01, 0x0B03 },
{ 0x0B05, 0x0B0C }, { 0x0B0F, 0x0B10 }, { 0x0B13, 0x0B28 }, { 0x0B2A, 0x0B30 },
{ 0x0B32, 0x0B33 }, { 0x0B36, 0x0B39 }, { 0x0B3D, 0x0B43 }, { 0x0B47, 0x0B48 },
{ 0x0B4B, 0x0B4D }, { 0x0B5C, 0x0B5D }, { 0x0B5F, 0x0B61 }, { 0x0B66, 0x0B6F },
{ 0x0B82, 0x0B83 }, { 0x0B85, 0x0B8A }, { 0x0B8E, 0x0B90 }, { 0x0B92, 0x0B95 },
{ 0x0B99, 0x0B9A }, { 0x0B9C, 0x0B9C }, { 0x0B9E, 0x0B9F }, { 0x0BA3, 0x0BA4 },
{ 0x0BA8, 0x0BAA }, { 0x0BAE, 0x0BB5 }, { 0x0BB7, 0x0BB9 }, { 0x0BBE, 0x0BC2 },
{ 0x0BC6, 0x0BC8 }, { 0x0BCA, 0x0BCD }, { 0x0BE7, 0x0BEF }, { 0x0C01, 0x0C03 },
{ 0x0C05, 0x0C0C }, { 0x0C0E, 0x0C10 }, { 0x0C12, 0x0C28 }, { 0x0C2A, 0x0C33 },
{ 0x0C35, 0x0C39 }, { 0x0C3E, 0x0C44 }, { 0x0C46, 0x0C48 }, { 0x0C4A, 0x0C4D },
{ 0x0C60, 0x0C61 }, { 0x0C66, 0x0C6F }, { 0x0C82, 0x0C83 }, { 0x0C85, 0x0C8C },
{ 0x0C8E, 0x0C90 }, { 0x0C92, 0x0CA8 }, { 0x0CAA, 0x0CB3 }, { 0x0CB5, 0x0CB9 },
{ 0x0CBE, 0x0CC4 }, { 0x0CC6, 0x0CC8 }, { 0x0CCA, 0x0CCD }, { 0x0CDE, 0x0CDE },
{ 0x0CE0, 0x0CE1 }, { 0x0CE6, 0x0CEF }, { 0x0D02, 0x0D03 }, { 0x0D05, 0x0D0C },
{ 0x0D0E, 0x0D10 }, { 0x0D12, 0x0D28 }, { 0x0D2A, 0x0D39 }, { 0x0D3E, 0x0D43 },
{ 0x0D46, 0x0D48 }, { 0x0D4A, 0x0D4D }, { 0x0D60, 0x0D61 }, { 0x0D66, 0x0D6F },
{ 0x0E01, 0x0E3A }, { 0x0E40, 0x0E5B }, /* { 0x0E50, 0x0E59 }, */ { 0x0E81, 0x0E82 },
{ 0x0E84, 0x0E84 }, { 0x0E87, 0x0E88 }, { 0x0E8A, 0x0E8A }, { 0x0E8D, 0x0E8D },
{ 0x0E94, 0x0E97 }, { 0x0E99, 0x0E9F }, { 0x0EA1, 0x0EA3 }, { 0x0EA5, 0x0EA5 },
{ 0x0EA7, 0x0EA7 }, { 0x0EAA, 0x0EAB }, { 0x0EAD, 0x0EAE }, { 0x0EB0, 0x0EB9 },
{ 0x0EBB, 0x0EBD }, { 0x0EC0, 0x0EC4 }, { 0x0EC6, 0x0EC6 }, { 0x0EC8, 0x0ECD },
{ 0x0ED0, 0x0ED9 }, { 0x0EDC, 0x0EDD }, { 0x0F00, 0x0F00 }, { 0x0F18, 0x0F19 },
{ 0x0F20, 0x0F33 }, { 0x0F35, 0x0F35 }, { 0x0F37, 0x0F37 }, { 0x0F39, 0x0F39 },
{ 0x0F3E, 0x0F47 }, { 0x0F49, 0x0F69 }, { 0x0F71, 0x0F84 }, { 0x0F86, 0x0F8B },
{ 0x0F90, 0x0F95 }, { 0x0F97, 0x0F97 }, { 0x0F99, 0x0FAD }, { 0x0FB1, 0x0FB7 },
{ 0x0FB9, 0x0FB9 }, { 0x10A0, 0x10C5 }, { 0x10D0, 0x10F6 }, { 0x1E00, 0x1E9B },
{ 0x1EA0, 0x1EF9 }, { 0x1F00, 0x1F15 }, { 0x1F18, 0x1F1D }, { 0x1F20, 0x1F45 },
{ 0x1F48, 0x1F4D }, { 0x1F50, 0x1F57 }, { 0x1F59, 0x1F59 }, { 0x1F5B, 0x1F5B },
{ 0x1F5D, 0x1F5D }, { 0x1F5F, 0x1F7D }, { 0x1F80, 0x1FB4 }, { 0x1FB6, 0x1FBC },
{ 0x1FBE, 0x1FBE }, { 0x1FC2, 0x1FC4 }, { 0x1FC6, 0x1FCC }, { 0x1FD0, 0x1FD3 },
{ 0x1FD6, 0x1FDB }, { 0x1FE0, 0x1FEC }, { 0x1FF2, 0x1FF4 }, { 0x1FF6, 0x1FFC },
{ 0x203F, 0x2040 }, { 0x207F, 0x207F }, { 0x2102, 0x2102 }, { 0x2107, 0x2107 },
{ 0x210A, 0x2113 }, { 0x2115, 0x2115 }, { 0x2118, 0x211D }, { 0x2124, 0x2124 },
{ 0x2126, 0x2126 }, { 0x2128, 0x2128 }, { 0x212A, 0x2131 }, { 0x2133, 0x2138 },
{ 0x2160, 0x2182 }, { 0x3005, 0x3007 }, { 0x3021, 0x3029 }, { 0x3041, 0x3093 },
{ 0x309B, 0x309C }, { 0x30A1, 0x30F6 }, { 0x30FB, 0x30FC }, { 0x3105, 0x312C },
{ 0x4E00, 0x9FA5 }, { 0xAC00, 0xD7A3 },
};
const char *utf_validateString(unsigned char *s, size_t len);
char const *const UTF8_DECODE_OK = NULL;
extern char const UTF8_DECODE_OUTSIDE_CODE_SPACE[];
extern char const UTF8_DECODE_TRUNCATED_SEQUENCE[];
extern char const UTF8_DECODE_OVERLONG[];
extern char const UTF8_DECODE_INVALID_TRAILER[];
extern char const UTF8_DECODE_INVALID_CODE_POINT[];
extern int isUniAlpha(dchar_t);
char const *const UTF16_DECODE_OK = NULL;
extern char const UTF16_DECODE_TRUNCATED_SEQUENCE[];
extern char const UTF16_DECODE_INVALID_SURROGATE[];
extern char const UTF16_DECODE_UNPAIRED_SURROGATE[];
extern char const UTF16_DECODE_INVALID_CODE_POINT[];
void utf_encodeChar(unsigned char *s, dchar_t c);
void utf_encodeWchar(unsigned short *s, dchar_t c);
} // namespace Unicode
/// \return true if \a c is a valid, non-private UTF-32 code point
bool utf_isValidDchar(dchar_t c);
bool isUniAlpha(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_encodeChar(utf8_t *s, dchar_t c);
void utf_encodeWchar(utf16_t *s, dchar_t c);
void utf_encode(int sz, void *s, dchar_t c);
#endif
const char *utf_decodeChar(utf8_t const *s, size_t len, size_t *pidx, dchar_t *presult);
const char *utf_decodeWchar(utf16_t const *s, size_t len, size_t *pidx, dchar_t *presult);
#endif // DMD_UTF_H
+6 -4
View File
@@ -23,6 +23,11 @@
#include "rmem.h"
#include "root.h"
// stricmp
#if __GNUC__ && !_WIN32
#include "gnuc.h"
#endif
#include "mars.h"
#include "module.h"
#include "mtype.h"
@@ -834,10 +839,7 @@ int main(int argc, char** argv)
#endif
if (stricmp(ext, global.mars_ext) == 0 ||
stricmp(ext, global.hdr_ext) == 0 ||
stricmp(ext, "htm") == 0 ||
stricmp(ext, "html") == 0 ||
stricmp(ext, "xhtml") == 0)
stricmp(ext, global.hdr_ext) == 0)
{
ext--; // skip onto '.'
assert(*ext == '.');
+1 -1
View File
@@ -384,5 +384,5 @@ if(PHOBOS2_DIR)
install(DIRECTORY ${PHOBOS2_DIR}/etc DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.d")
install(FILES ${PHOBOS2_DIR}/crc32.d DESTINATION ${INCLUDE_INSTALL_DIR})
endif(PHOBOS2_DIR)
install(FILES ${RUNTIME_DIR}/import/object.di DESTINATION ${INCLUDE_INSTALL_DIR}/ldc)
install(FILES ${RUNTIME_DIR}/src/object.di DESTINATION ${INCLUDE_INSTALL_DIR}/ldc)
install(DIRECTORY ${RUNTIME_DIR}/import/ldc DESTINATION ${INCLUDE_INSTALL_DIR} FILES_MATCHING PATTERN "*.di")