mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-09-20 04:10:18 +02:00
Merge branch 'dmd-2.060' into master.
Conflicts: dmd2/func.c dmd2/mars.c
This commit is contained in:
@@ -4,3 +4,6 @@
|
|||||||
[submodule "phobos"]
|
[submodule "phobos"]
|
||||||
path = runtime/phobos
|
path = runtime/phobos
|
||||||
url = git://github.com/ldc-developers/phobos.git
|
url = git://github.com/ldc-developers/phobos.git
|
||||||
|
[submodule "tests/d2/dmd-testsuite"]
|
||||||
|
path = tests/d2/dmd-testsuite
|
||||||
|
url = git://github.com/ldc-developers/dmd-testsuite.git
|
||||||
|
|||||||
+11
-4
@@ -67,7 +67,6 @@ struct AggregateDeclaration : ScopeDsymbol
|
|||||||
Type *handle; // 'this' type
|
Type *handle; // 'this' type
|
||||||
unsigned structsize; // size of struct
|
unsigned structsize; // size of struct
|
||||||
unsigned alignsize; // size of struct for alignment purposes
|
unsigned alignsize; // size of struct for alignment purposes
|
||||||
unsigned structalign; // struct member alignment in effect
|
|
||||||
int hasUnions; // set if aggregate has overlapping fields
|
int hasUnions; // set if aggregate has overlapping fields
|
||||||
VarDeclarations fields; // VarDeclaration fields
|
VarDeclarations fields; // VarDeclaration fields
|
||||||
enum Sizeok sizeok; // set when structsize contains valid data
|
enum Sizeok sizeok; // set when structsize contains valid data
|
||||||
@@ -96,17 +95,18 @@ struct AggregateDeclaration : ScopeDsymbol
|
|||||||
|
|
||||||
#ifdef IN_GCC
|
#ifdef IN_GCC
|
||||||
Expressions *attributes; // GCC decl/type attributes
|
Expressions *attributes; // GCC decl/type attributes
|
||||||
FuncDeclarations methods; // flat list of all methods for debug information
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
Expression *getRTInfo; // pointer to GC info generated by object.RTInfo(this)
|
||||||
|
|
||||||
AggregateDeclaration(Loc loc, Identifier *id);
|
AggregateDeclaration(Loc loc, Identifier *id);
|
||||||
void semantic2(Scope *sc);
|
void semantic2(Scope *sc);
|
||||||
void semantic3(Scope *sc);
|
void semantic3(Scope *sc);
|
||||||
void inlineScan();
|
void inlineScan();
|
||||||
unsigned size(Loc loc);
|
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,
|
static unsigned placeField(unsigned *nextoffset,
|
||||||
unsigned memsize, unsigned memalignsize, unsigned memalign,
|
unsigned memsize, unsigned memalignsize, structalign_t memalign,
|
||||||
unsigned *paggsize, unsigned *paggalignsize, bool isunion);
|
unsigned *paggsize, unsigned *paggalignsize, bool isunion);
|
||||||
Type *getType();
|
Type *getType();
|
||||||
int firstFieldInUnion(int indx); // first field in union that includes indx
|
int firstFieldInUnion(int indx); // first field in union that includes indx
|
||||||
@@ -165,8 +165,14 @@ struct StructDeclaration : AggregateDeclaration
|
|||||||
|
|
||||||
FuncDeclaration *xeq; // TypeInfo_Struct.xopEquals
|
FuncDeclaration *xeq; // TypeInfo_Struct.xopEquals
|
||||||
static FuncDeclaration *xerreq; // object.xopEquals
|
static FuncDeclaration *xerreq; // object.xopEquals
|
||||||
|
|
||||||
|
structalign_t alignment; // alignment applied outside of the struct
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// For 64 bit Efl function call/return ABI
|
||||||
|
Type *arg1type;
|
||||||
|
Type *arg2type;
|
||||||
|
|
||||||
StructDeclaration(Loc loc, Identifier *id);
|
StructDeclaration(Loc loc, Identifier *id);
|
||||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||||
void semantic(Scope *sc);
|
void semantic(Scope *sc);
|
||||||
@@ -175,6 +181,7 @@ struct StructDeclaration : AggregateDeclaration
|
|||||||
char *mangle();
|
char *mangle();
|
||||||
const char *kind();
|
const char *kind();
|
||||||
void finalizeSize(Scope *sc);
|
void finalizeSize(Scope *sc);
|
||||||
|
bool isPOD();
|
||||||
#if DMDV1
|
#if DMDV1
|
||||||
Expression *cloneMembers();
|
Expression *cloneMembers();
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -18,6 +18,7 @@
|
|||||||
#include "aggregate.h"
|
#include "aggregate.h"
|
||||||
#include "dsymbol.h"
|
#include "dsymbol.h"
|
||||||
#include "mtype.h"
|
#include "mtype.h"
|
||||||
|
#include "declaration.h"
|
||||||
|
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
|
|
||||||
@@ -78,9 +79,32 @@ void AliasThis::semantic(Scope *sc)
|
|||||||
::error(loc, "%s is not a member of %s", s->toChars(), ad->toChars());
|
::error(loc, "%s is not a member of %s", s->toChars(), ad->toChars());
|
||||||
else
|
else
|
||||||
::error(loc, "undefined identifier %s", ident->toChars());
|
::error(loc, "undefined identifier %s", ident->toChars());
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
else if (ad->aliasthis && s != ad->aliasthis)
|
else if (ad->aliasthis && s != ad->aliasthis)
|
||||||
error("there can be only one alias this");
|
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;
|
ad->aliasthis = s;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|||||||
+260
-12
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 2010-2011 by Digital Mars
|
// Copyright (c) 2010-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -27,6 +27,9 @@
|
|||||||
#include "aggregate.h"
|
#include "aggregate.h"
|
||||||
#include "hdrgen.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
|
* This breaks a type down into 'simpler' types that can be passed to a function
|
||||||
* in registers, and returned in registers.
|
* in registers, and returned in registers.
|
||||||
@@ -40,6 +43,10 @@ TypeTuple *Type::toArgTypes()
|
|||||||
return NULL; // not valid for a parameter
|
return NULL; // not valid for a parameter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TypeTuple *TypeError::toArgTypes()
|
||||||
|
{
|
||||||
|
return new TypeTuple(Type::terror);
|
||||||
|
}
|
||||||
|
|
||||||
TypeTuple *TypeBasic::toArgTypes()
|
TypeTuple *TypeBasic::toArgTypes()
|
||||||
{ Type *t1 = NULL;
|
{ Type *t1 = NULL;
|
||||||
@@ -78,7 +85,7 @@ TypeTuple *TypeBasic::toArgTypes()
|
|||||||
|
|
||||||
case Tcomplex32:
|
case Tcomplex32:
|
||||||
if (global.params.is64bit)
|
if (global.params.is64bit)
|
||||||
t1 = Type::tfloat64; // weird, eh?
|
t1 = Type::tfloat2;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
t1 = Type::tfloat64;
|
t1 = Type::tfloat64;
|
||||||
@@ -124,23 +131,39 @@ TypeTuple *TypeBasic::toArgTypes()
|
|||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DMDV2
|
||||||
TypeTuple *TypeVector::toArgTypes()
|
TypeTuple *TypeVector::toArgTypes()
|
||||||
{
|
{
|
||||||
return new TypeTuple(Type::tfloat64);
|
return new TypeTuple(this);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
TypeTuple *TypeSArray::toArgTypes()
|
TypeTuple *TypeSArray::toArgTypes()
|
||||||
{
|
{
|
||||||
#if DMDV2
|
#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
|
return new TypeTuple(); // pass on the stack for efficiency
|
||||||
#else
|
#else
|
||||||
return new TypeTuple(Type::tvoidptr);
|
return new TypeTuple(); // pass on the stack for efficiency
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeTuple *TypeDArray::toArgTypes()
|
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()
|
TypeTuple *TypeAArray::toArgTypes()
|
||||||
@@ -150,30 +173,255 @@ TypeTuple *TypeAArray::toArgTypes()
|
|||||||
|
|
||||||
TypeTuple *TypePointer::toArgTypes()
|
TypeTuple *TypePointer::toArgTypes()
|
||||||
{
|
{
|
||||||
return new TypeTuple(this);
|
return new TypeTuple(Type::tvoidptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeTuple *TypeDelegate::toArgTypes()
|
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()
|
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);
|
d_uns64 sz = size(0);
|
||||||
assert(sz < 0xFFFFFFFF);
|
assert(sz < 0xFFFFFFFF);
|
||||||
switch ((unsigned)sz)
|
switch ((unsigned)sz)
|
||||||
{
|
{
|
||||||
case 1:
|
case 1:
|
||||||
return new TypeTuple(Type::tint8);
|
t1 = Type::tint8;
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
return new TypeTuple(Type::tint16);
|
t1 = Type::tint16;
|
||||||
|
break;
|
||||||
case 4:
|
case 4:
|
||||||
return new TypeTuple(Type::tint32);
|
t1 = Type::tint32;
|
||||||
|
break;
|
||||||
case 8:
|
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()
|
TypeTuple *TypeEnum::toArgTypes()
|
||||||
|
|||||||
+20
-4
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -142,7 +142,6 @@ Expression *BinExp::arrayOp(Scope *sc)
|
|||||||
buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco);
|
buf.writestring(type->toBasetype()->nextOf()->toBasetype()->deco);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
size_t namelen = buf.offset;
|
|
||||||
buf.writeByte(0);
|
buf.writeByte(0);
|
||||||
char *name = buf.toChars();
|
char *name = buf.toChars();
|
||||||
Identifier *ident = Lexer::idPool(name);
|
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));
|
Initializer *init = new ExpInitializer(0, new IntegerExp(0, 0, Type::tsize_t));
|
||||||
Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init);
|
Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init);
|
||||||
Statement *s1 = new ForStatement(0,
|
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 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 PostExp(TOKplusplus, 0, new IdentifierExp(0, Id::p)),
|
||||||
new ExpStatement(0, loopbody));
|
new ExpStatement(0, loopbody));
|
||||||
@@ -357,7 +356,7 @@ Expression *BinExp::arrayOp(Scope *sc)
|
|||||||
// foreach (i; 0 .. p.length)
|
// foreach (i; 0 .. p.length)
|
||||||
Statement *s1 = new ForeachRangeStatement(0, TOKforeach,
|
Statement *s1 = new ForeachRangeStatement(0, TOKforeach,
|
||||||
new Parameter(0, NULL, Id::p, NULL),
|
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 ArrayLengthExp(0, new IdentifierExp(0, p->ident)),
|
||||||
new ExpStatement(0, loopbody));
|
new ExpStatement(0, loopbody));
|
||||||
#endif
|
#endif
|
||||||
@@ -413,6 +412,23 @@ Expression *BinExp::arrayOp(Scope *sc)
|
|||||||
return e;
|
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,
|
* Construct the identifier for the array operation function,
|
||||||
* and build the argument list to pass to it.
|
* and build the argument list to pass to it.
|
||||||
|
|||||||
+117
-117
@@ -1,117 +1,117 @@
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
The "Artistic License"
|
The "Artistic License"
|
||||||
|
|
||||||
Preamble
|
Preamble
|
||||||
|
|
||||||
The intent of this document is to state the conditions under which a
|
The intent of this document is to state the conditions under which a
|
||||||
Package may be copied, such that the Copyright Holder maintains some
|
Package may be copied, such that the Copyright Holder maintains some
|
||||||
semblance of artistic control over the development of the package,
|
semblance of artistic control over the development of the package,
|
||||||
while giving the users of the package the right to use and distribute
|
while giving the users of the package the right to use and distribute
|
||||||
the Package in a more-or-less customary fashion, plus the right to make
|
the Package in a more-or-less customary fashion, plus the right to make
|
||||||
reasonable modifications.
|
reasonable modifications.
|
||||||
|
|
||||||
Definitions:
|
Definitions:
|
||||||
|
|
||||||
"Package" refers to the collection of files distributed by the
|
"Package" refers to the collection of files distributed by the
|
||||||
Copyright Holder, and derivatives of that collection of files
|
Copyright Holder, and derivatives of that collection of files
|
||||||
created through textual modification.
|
created through textual modification.
|
||||||
|
|
||||||
"Standard Version" refers to such a Package if it has not been
|
"Standard Version" refers to such a Package if it has not been
|
||||||
modified, or has been modified in accordance with the wishes
|
modified, or has been modified in accordance with the wishes
|
||||||
of the Copyright Holder as specified below.
|
of the Copyright Holder as specified below.
|
||||||
|
|
||||||
"Copyright Holder" is whoever is named in the copyright or
|
"Copyright Holder" is whoever is named in the copyright or
|
||||||
copyrights for the package.
|
copyrights for the package.
|
||||||
|
|
||||||
"You" is you, if you're thinking about copying or distributing
|
"You" is you, if you're thinking about copying or distributing
|
||||||
this Package.
|
this Package.
|
||||||
|
|
||||||
"Reasonable copying fee" is whatever you can justify on the
|
"Reasonable copying fee" is whatever you can justify on the
|
||||||
basis of media cost, duplication charges, time of people involved,
|
basis of media cost, duplication charges, time of people involved,
|
||||||
and so on. (You will not be required to justify it to the
|
and so on. (You will not be required to justify it to the
|
||||||
Copyright Holder, but only to the computing community at large
|
Copyright Holder, but only to the computing community at large
|
||||||
as a market that must bear the fee.)
|
as a market that must bear the fee.)
|
||||||
|
|
||||||
"Freely Available" means that no fee is charged for the item
|
"Freely Available" means that no fee is charged for the item
|
||||||
itself, though there may be fees involved in handling the item.
|
itself, though there may be fees involved in handling the item.
|
||||||
It also means that recipients of the item may redistribute it
|
It also means that recipients of the item may redistribute it
|
||||||
under the same conditions they received it.
|
under the same conditions they received it.
|
||||||
|
|
||||||
1. You may make and give away verbatim copies of the source form of the
|
1. You may make and give away verbatim copies of the source form of the
|
||||||
Standard Version of this Package without restriction, provided that you
|
Standard Version of this Package without restriction, provided that you
|
||||||
duplicate all of the original copyright notices and associated disclaimers.
|
duplicate all of the original copyright notices and associated disclaimers.
|
||||||
|
|
||||||
2. You may apply bug fixes, portability fixes and other modifications
|
2. You may apply bug fixes, portability fixes and other modifications
|
||||||
derived from the Public Domain or from the Copyright Holder. A Package
|
derived from the Public Domain or from the Copyright Holder. A Package
|
||||||
modified in such a way shall still be considered the Standard Version.
|
modified in such a way shall still be considered the Standard Version.
|
||||||
|
|
||||||
3. You may otherwise modify your copy of this Package in any way, provided
|
3. You may otherwise modify your copy of this Package in any way, provided
|
||||||
that you insert a prominent notice in each changed file stating how and
|
that you insert a prominent notice in each changed file stating how and
|
||||||
when you changed that file, and provided that you do at least ONE of the
|
when you changed that file, and provided that you do at least ONE of the
|
||||||
following:
|
following:
|
||||||
|
|
||||||
a) place your modifications in the Public Domain or otherwise make them
|
a) place your modifications in the Public Domain or otherwise make them
|
||||||
Freely Available, such as by posting said modifications to Usenet or
|
Freely Available, such as by posting said modifications to Usenet or
|
||||||
an equivalent medium, or placing the modifications on a major archive
|
an equivalent medium, or placing the modifications on a major archive
|
||||||
site such as uunet.uu.net, or by allowing the Copyright Holder to include
|
site such as uunet.uu.net, or by allowing the Copyright Holder to include
|
||||||
your modifications in the Standard Version of the Package.
|
your modifications in the Standard Version of the Package.
|
||||||
|
|
||||||
b) use the modified Package only within your corporation or organization.
|
b) use the modified Package only within your corporation or organization.
|
||||||
|
|
||||||
c) rename any non-standard executables so the names do not conflict
|
c) rename any non-standard executables so the names do not conflict
|
||||||
with standard executables, which must also be provided, and provide
|
with standard executables, which must also be provided, and provide
|
||||||
a separate manual page for each non-standard executable that clearly
|
a separate manual page for each non-standard executable that clearly
|
||||||
documents how it differs from the Standard Version.
|
documents how it differs from the Standard Version.
|
||||||
|
|
||||||
d) make other distribution arrangements with the Copyright Holder.
|
d) make other distribution arrangements with the Copyright Holder.
|
||||||
|
|
||||||
4. You may distribute the programs of this Package in object code or
|
4. You may distribute the programs of this Package in object code or
|
||||||
executable form, provided that you do at least ONE of the following:
|
executable form, provided that you do at least ONE of the following:
|
||||||
|
|
||||||
a) distribute a Standard Version of the executables and library files,
|
a) distribute a Standard Version of the executables and library files,
|
||||||
together with instructions (in the manual page or equivalent) on where
|
together with instructions (in the manual page or equivalent) on where
|
||||||
to get the Standard Version.
|
to get the Standard Version.
|
||||||
|
|
||||||
b) accompany the distribution with the machine-readable source of
|
b) accompany the distribution with the machine-readable source of
|
||||||
the Package with your modifications.
|
the Package with your modifications.
|
||||||
|
|
||||||
c) give non-standard executables non-standard names, and clearly
|
c) give non-standard executables non-standard names, and clearly
|
||||||
document the differences in manual pages (or equivalent), together
|
document the differences in manual pages (or equivalent), together
|
||||||
with instructions on where to get the Standard Version.
|
with instructions on where to get the Standard Version.
|
||||||
|
|
||||||
d) make other distribution arrangements with the Copyright Holder.
|
d) make other distribution arrangements with the Copyright Holder.
|
||||||
|
|
||||||
5. You may charge a reasonable copying fee for any distribution of this
|
5. You may charge a reasonable copying fee for any distribution of this
|
||||||
Package. You may charge any fee you choose for support of this
|
Package. You may charge any fee you choose for support of this
|
||||||
Package. You may not charge a fee for this Package itself. However,
|
Package. You may not charge a fee for this Package itself. However,
|
||||||
you may distribute this Package in aggregate with other (possibly
|
you may distribute this Package in aggregate with other (possibly
|
||||||
commercial) programs as part of a larger (possibly commercial) software
|
commercial) programs as part of a larger (possibly commercial) software
|
||||||
distribution provided that you do not advertise this Package as a
|
distribution provided that you do not advertise this Package as a
|
||||||
product of your own. You may embed this Package's interpreter within
|
product of your own. You may embed this Package's interpreter within
|
||||||
an executable of yours (by linking); this shall be construed as a mere
|
an executable of yours (by linking); this shall be construed as a mere
|
||||||
form of aggregation, provided that the complete Standard Version of the
|
form of aggregation, provided that the complete Standard Version of the
|
||||||
interpreter is so embedded.
|
interpreter is so embedded.
|
||||||
|
|
||||||
6. The source code and object code supplied as input to or produced as
|
6. The source code and object code supplied as input to or produced as
|
||||||
output from the programs of this Package do not automatically fall
|
output from the programs of this Package do not automatically fall
|
||||||
under the copyright of this Package, but belong to whoever generated
|
under the copyright of this Package, but belong to whoever generated
|
||||||
them, and may be sold commercially, and may be aggregated with this
|
them, and may be sold commercially, and may be aggregated with this
|
||||||
Package.
|
Package.
|
||||||
|
|
||||||
7. Aggregation of this Package with a commercial distribution is always
|
7. Aggregation of this Package with a commercial distribution is always
|
||||||
permitted provided that the use of this Package is embedded; that is,
|
permitted provided that the use of this Package is embedded; that is,
|
||||||
when no overt attempt is made to make this Package's interfaces visible
|
when no overt attempt is made to make this Package's interfaces visible
|
||||||
to the end user of the commercial distribution. Such use shall not be
|
to the end user of the commercial distribution. Such use shall not be
|
||||||
construed as a distribution of this Package.
|
construed as a distribution of this Package.
|
||||||
|
|
||||||
8. The name of the Copyright Holder may not be used to endorse or promote
|
8. The name of the Copyright Holder may not be used to endorse or promote
|
||||||
products derived from this software without specific prior written permission.
|
products derived from this software without specific prior written permission.
|
||||||
|
|
||||||
9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
9. THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
|
||||||
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||||
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
|
||||||
The End
|
The End
|
||||||
|
|||||||
+53
-26
@@ -11,6 +11,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h> // memcpy()
|
||||||
|
|
||||||
#include "rmem.h"
|
#include "rmem.h"
|
||||||
|
|
||||||
@@ -37,7 +38,7 @@
|
|||||||
extern void obj_includelib(const char *name);
|
extern void obj_includelib(const char *name);
|
||||||
|
|
||||||
#if IN_DMD
|
#if IN_DMD
|
||||||
void obj_startaddress(Symbol *s);
|
bool obj_startaddress(Symbol *s);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
@@ -90,7 +91,7 @@ int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
|
|||||||
|
|
||||||
void AttribDeclaration::setScopeNewSc(Scope *sc,
|
void AttribDeclaration::setScopeNewSc(Scope *sc,
|
||||||
StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
|
StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
|
||||||
unsigned structalign)
|
structalign_t structalign)
|
||||||
{
|
{
|
||||||
if (decl)
|
if (decl)
|
||||||
{
|
{
|
||||||
@@ -125,7 +126,7 @@ void AttribDeclaration::setScopeNewSc(Scope *sc,
|
|||||||
|
|
||||||
void AttribDeclaration::semanticNewSc(Scope *sc,
|
void AttribDeclaration::semanticNewSc(Scope *sc,
|
||||||
StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
|
StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
|
||||||
unsigned structalign)
|
structalign_t structalign)
|
||||||
{
|
{
|
||||||
if (decl)
|
if (decl)
|
||||||
{
|
{
|
||||||
@@ -760,7 +761,10 @@ void AlignDeclaration::semantic(Scope *sc)
|
|||||||
|
|
||||||
void AlignDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
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);
|
AttribDeclaration::toCBuffer(buf, hgs);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -938,7 +942,7 @@ void PragmaDeclaration::setScope(Scope *sc)
|
|||||||
{
|
{
|
||||||
Expression *e = (*args)[0];
|
Expression *e = (*args)[0];
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
(*args)[0] = e;
|
(*args)[0] = e;
|
||||||
StringExp* se = e->toString();
|
StringExp* se = e->toString();
|
||||||
if (!se)
|
if (!se)
|
||||||
@@ -977,8 +981,8 @@ void PragmaDeclaration::semantic(Scope *sc)
|
|||||||
Expression *e = (*args)[i];
|
Expression *e = (*args)[i];
|
||||||
|
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
if (e->op != TOKerror)
|
if (e->op != TOKerror && e->op != TOKtype)
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
if (e->op == TOKerror)
|
if (e->op == TOKerror)
|
||||||
{ errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
|
{ errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
|
||||||
return;
|
return;
|
||||||
@@ -1004,7 +1008,7 @@ void PragmaDeclaration::semantic(Scope *sc)
|
|||||||
Expression *e = (*args)[0];
|
Expression *e = (*args)[0];
|
||||||
|
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
(*args)[0] = e;
|
(*args)[0] = e;
|
||||||
if (e->op == TOKerror)
|
if (e->op == TOKerror)
|
||||||
goto Lnodecl;
|
goto Lnodecl;
|
||||||
@@ -1022,7 +1026,7 @@ void PragmaDeclaration::semantic(Scope *sc)
|
|||||||
}
|
}
|
||||||
goto Lnodecl;
|
goto Lnodecl;
|
||||||
}
|
}
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
else if (ident == Id::GNU_asm)
|
else if (ident == Id::GNU_asm)
|
||||||
{
|
{
|
||||||
if (! args || args->dim != 2)
|
if (! args || args->dim != 2)
|
||||||
@@ -1046,7 +1050,7 @@ void PragmaDeclaration::semantic(Scope *sc)
|
|||||||
|
|
||||||
e = (*args)[1];
|
e = (*args)[1];
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
e = e->toString();
|
e = e->toString();
|
||||||
if (e && ((StringExp *)e)->sz == 1)
|
if (e && ((StringExp *)e)->sz == 1)
|
||||||
s = ((StringExp *)e);
|
s = ((StringExp *)e);
|
||||||
@@ -1068,7 +1072,7 @@ void PragmaDeclaration::semantic(Scope *sc)
|
|||||||
{
|
{
|
||||||
Expression *e = (*args)[0];
|
Expression *e = (*args)[0];
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
(*args)[0] = e;
|
(*args)[0] = e;
|
||||||
Dsymbol *sa = getDsymbol(e);
|
Dsymbol *sa = getDsymbol(e);
|
||||||
if (!sa || !sa->isFuncDeclaration())
|
if (!sa || !sa->isFuncDeclaration())
|
||||||
@@ -1105,7 +1109,7 @@ void PragmaDeclaration::semantic(Scope *sc)
|
|||||||
unsigned errors_save = global.errors;
|
unsigned errors_save = global.errors;
|
||||||
|
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
if (i == 0)
|
if (i == 0)
|
||||||
printf(" (");
|
printf(" (");
|
||||||
else
|
else
|
||||||
@@ -1175,21 +1179,19 @@ void PragmaDeclaration::toObjFile(int multiobj)
|
|||||||
char *name = (char *)mem.malloc(se->len + 1);
|
char *name = (char *)mem.malloc(se->len + 1);
|
||||||
memcpy(name, se->string, se->len);
|
memcpy(name, se->string, se->len);
|
||||||
name[se->len] = 0;
|
name[se->len] = 0;
|
||||||
#if OMFOBJ
|
|
||||||
/* The OMF format allows library names to be inserted
|
/* Embed the library names into the object file.
|
||||||
* into the object file. The linker will then automatically
|
* The linker will then automatically
|
||||||
* search that library, too.
|
* search that library, too.
|
||||||
*/
|
*/
|
||||||
obj_includelib(name);
|
if (!obj_includelib(name))
|
||||||
#elif ELFOBJ || MACHOBJ
|
{
|
||||||
/* The format does not allow embedded library names,
|
/* The format does not allow embedded library names,
|
||||||
* so instead append the library name to the list to be passed
|
* so instead append the library name to the list to be passed
|
||||||
* to the linker.
|
* to the linker.
|
||||||
*/
|
*/
|
||||||
global.params.libfiles->push(name);
|
global.params.libfiles->push(name);
|
||||||
#else
|
}
|
||||||
error("pragma lib not supported");
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
else if (ident == Id::startaddress)
|
else if (ident == Id::startaddress)
|
||||||
@@ -1406,6 +1408,31 @@ Dsymbol *StaticIfDeclaration::syntaxCopy(Dsymbol *s)
|
|||||||
return dd;
|
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)
|
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());
|
//printf("CompileDeclaration::compileIt(loc = %d) %s\n", loc.linnum, exp->toChars());
|
||||||
exp = exp->semantic(sc);
|
exp = exp->semantic(sc);
|
||||||
exp = resolveProperties(sc, exp);
|
exp = resolveProperties(sc, exp);
|
||||||
exp = exp->optimize(WANTvalue | WANTinterpret);
|
exp = exp->ctfeInterpret();
|
||||||
StringExp *se = exp->toString();
|
StringExp *se = exp->toString();
|
||||||
if (!se)
|
if (!se)
|
||||||
{ exp->error("argument to mixin must be a string, not (%s)", exp->toChars());
|
{ exp->error("argument to mixin must be a string, not (%s)", exp->toChars());
|
||||||
|
|||||||
+4
-3
@@ -37,10 +37,10 @@ struct AttribDeclaration : Dsymbol
|
|||||||
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||||
void setScopeNewSc(Scope *sc,
|
void setScopeNewSc(Scope *sc,
|
||||||
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
||||||
unsigned structalign);
|
structalign_t structalign);
|
||||||
void semanticNewSc(Scope *sc,
|
void semanticNewSc(Scope *sc,
|
||||||
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
||||||
unsigned structalign);
|
structalign_t structalign);
|
||||||
void semantic(Scope *sc);
|
void semantic(Scope *sc);
|
||||||
void semantic2(Scope *sc);
|
void semantic2(Scope *sc);
|
||||||
void semantic3(Scope *sc);
|
void semantic3(Scope *sc);
|
||||||
@@ -122,7 +122,7 @@ struct AlignDeclaration : AttribDeclaration
|
|||||||
struct AnonDeclaration : AttribDeclaration
|
struct AnonDeclaration : AttribDeclaration
|
||||||
{
|
{
|
||||||
bool isunion;
|
bool isunion;
|
||||||
unsigned alignment;
|
structalign_t alignment;
|
||||||
int sem; // 1 if successful semantic()
|
int sem; // 1 if successful semantic()
|
||||||
|
|
||||||
AnonDeclaration(Loc loc, int isunion, Dsymbols *decl);
|
AnonDeclaration(Loc loc, int isunion, Dsymbols *decl);
|
||||||
@@ -178,6 +178,7 @@ struct StaticIfDeclaration : ConditionalDeclaration
|
|||||||
|
|
||||||
StaticIfDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
|
StaticIfDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
|
||||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||||
|
Dsymbols *include(Scope *sc, ScopeDsymbol *s);
|
||||||
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||||
void semantic(Scope *sc);
|
void semantic(Scope *sc);
|
||||||
void importAll(Scope *sc);
|
void importAll(Scope *sc);
|
||||||
|
|||||||
+5
-5
@@ -10,9 +10,9 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h> // strcmp()
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
|
|
||||||
#include "mars.h"
|
#include "mars.h"
|
||||||
#include "declaration.h"
|
#include "declaration.h"
|
||||||
#include "attrib.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 FeZe [] = "FNaNbNfeZe"; // @safe pure nothrow real function(real)
|
||||||
static const char FeZe2[] = "FNaNbNeeZe"; // @trusted 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 FuintZint[] = "FNaNbNfkZi"; // @safe pure nothrow int function(uint)
|
||||||
static const char FuintZuint[] = "FNaNbkZk"; // pure nothrow uint 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 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 FrealrealZreal [] = "FNaNbNfeeZe"; // @safe pure nothrow real function(real, real)
|
||||||
static const char FrealZlong [] = "FNaNbNfeZl"; // @safe pure nothrow long function(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)
|
Expression *eval_builtin(Loc loc, enum BUILTIN builtin, Expressions *arguments)
|
||||||
{
|
{
|
||||||
assert(arguments && arguments->dim);
|
assert(arguments && arguments->dim);
|
||||||
Expression *arg0 = arguments->tdata()[0];
|
Expression *arg0 = (*arguments)[0];
|
||||||
Expression *e = NULL;
|
Expression *e = NULL;
|
||||||
switch (builtin)
|
switch (builtin)
|
||||||
{
|
{
|
||||||
|
|||||||
+4
-3
@@ -42,6 +42,7 @@ struct CanThrow
|
|||||||
|
|
||||||
int Expression::canThrow(bool mustNotThrow)
|
int Expression::canThrow(bool mustNotThrow)
|
||||||
{
|
{
|
||||||
|
//printf("Expression::canThrow(%d) %s\n", mustNotThrow, toChars());
|
||||||
CanThrow ct;
|
CanThrow ct;
|
||||||
ct.can = FALSE;
|
ct.can = FALSE;
|
||||||
ct.mustnot = mustNotThrow;
|
ct.mustnot = mustNotThrow;
|
||||||
@@ -132,7 +133,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < decl->dim; i++)
|
for (size_t i = 0; i < decl->dim; i++)
|
||||||
{
|
{
|
||||||
s = decl->tdata()[i];
|
s = (*decl)[i];
|
||||||
if (Dsymbol_canThrow(s, mustNotThrow))
|
if (Dsymbol_canThrow(s, mustNotThrow))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -165,7 +166,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < tm->members->dim; i++)
|
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))
|
if (Dsymbol_canThrow(sm, mustNotThrow))
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -174,7 +175,7 @@ int Dsymbol_canThrow(Dsymbol *s, bool mustNotThrow)
|
|||||||
else if ((td = s->isTupleDeclaration()) != NULL)
|
else if ((td = s->isTupleDeclaration()) != NULL)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < td->objects->dim; i++)
|
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)
|
if (o->dyncast() == DYNCAST_EXPRESSION)
|
||||||
{ Expression *eo = (Expression *)o;
|
{ Expression *eo = (Expression *)o;
|
||||||
if (eo->op == TOKdsymbol)
|
if (eo->op == TOKdsymbol)
|
||||||
|
|||||||
+108
-32
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h> // mem{set|cpy}()
|
||||||
|
|
||||||
#include "rmem.h"
|
#include "rmem.h"
|
||||||
|
|
||||||
@@ -36,9 +37,10 @@ Expression *Expression::implicitCastTo(Scope *sc, Type *t)
|
|||||||
|
|
||||||
MATCH match = implicitConvTo(t);
|
MATCH match = implicitConvTo(t);
|
||||||
if (match)
|
if (match)
|
||||||
{ TY tyfrom = type->toBasetype()->ty;
|
{
|
||||||
TY tyto = t->toBasetype()->ty;
|
|
||||||
#if DMDV1
|
#if DMDV1
|
||||||
|
TY tyfrom = type->toBasetype()->ty;
|
||||||
|
TY tyto = t->toBasetype()->ty;
|
||||||
if (global.params.warnings &&
|
if (global.params.warnings &&
|
||||||
Type::impcnvWarn[tyfrom][tyto] &&
|
Type::impcnvWarn[tyfrom][tyto] &&
|
||||||
op != TOKint64)
|
op != TOKint64)
|
||||||
@@ -138,7 +140,7 @@ Expression *ErrorExp::implicitCastTo(Scope *sc, Type *t)
|
|||||||
Expression *FuncExp::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());
|
//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 ty = type->toBasetype()->ty;
|
||||||
TY toty = t->toBasetype()->ty;
|
TY toty = t->toBasetype()->ty;
|
||||||
|
TY oldty = ty;
|
||||||
|
|
||||||
if (m == MATCHnomatch && t->ty == Tenum)
|
if (m == MATCHnomatch && t->ty == Tenum)
|
||||||
goto Lno;
|
goto Lno;
|
||||||
@@ -282,6 +285,8 @@ MATCH IntegerExp::implicitConvTo(Type *t)
|
|||||||
goto Lyes;
|
goto Lyes;
|
||||||
|
|
||||||
case Tchar:
|
case Tchar:
|
||||||
|
if ((oldty == Twchar || oldty == Tdchar) && value > 0x7F)
|
||||||
|
goto Lno;
|
||||||
case Tuns8:
|
case Tuns8:
|
||||||
//printf("value = %llu %llu\n", (dinteger_t)(unsigned char)value, value);
|
//printf("value = %llu %llu\n", (dinteger_t)(unsigned char)value, value);
|
||||||
if ((unsigned char)value != value)
|
if ((unsigned char)value != value)
|
||||||
@@ -293,6 +298,9 @@ MATCH IntegerExp::implicitConvTo(Type *t)
|
|||||||
goto Lno;
|
goto Lno;
|
||||||
goto Lyes;
|
goto Lyes;
|
||||||
|
|
||||||
|
case Twchar:
|
||||||
|
if (oldty == Tdchar && value > 0xD7FF && value < 0xE000)
|
||||||
|
goto Lno;
|
||||||
case Tuns16:
|
case Tuns16:
|
||||||
if ((unsigned short)value != value)
|
if ((unsigned short)value != value)
|
||||||
goto Lno;
|
goto Lno;
|
||||||
@@ -319,11 +327,6 @@ MATCH IntegerExp::implicitConvTo(Type *t)
|
|||||||
goto Lno;
|
goto Lno;
|
||||||
goto Lyes;
|
goto Lyes;
|
||||||
|
|
||||||
case Twchar:
|
|
||||||
if ((unsigned short)value != value)
|
|
||||||
goto Lno;
|
|
||||||
goto Lyes;
|
|
||||||
|
|
||||||
case Tfloat32:
|
case Tfloat32:
|
||||||
{
|
{
|
||||||
volatile float f;
|
volatile float f;
|
||||||
@@ -540,19 +543,28 @@ MATCH ArrayLiteralExp::implicitConvTo(Type *t)
|
|||||||
if ((tb->ty == Tarray || tb->ty == Tsarray) &&
|
if ((tb->ty == Tarray || tb->ty == Tsarray) &&
|
||||||
(typeb->ty == Tarray || typeb->ty == Tsarray))
|
(typeb->ty == Tarray || typeb->ty == Tsarray))
|
||||||
{
|
{
|
||||||
|
Type *typen = typeb->nextOf()->toBasetype();
|
||||||
|
|
||||||
if (tb->ty == Tsarray)
|
if (tb->ty == Tsarray)
|
||||||
{ TypeSArray *tsa = (TypeSArray *)tb;
|
{ TypeSArray *tsa = (TypeSArray *)tb;
|
||||||
if (elements->dim != tsa->dim->toInteger())
|
if (elements->dim != tsa->dim->toInteger())
|
||||||
result = MATCHnomatch;
|
result = MATCHnomatch;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < elements->dim; i++)
|
Type *telement = tb->nextOf();
|
||||||
{ Expression *e = (*elements)[i];
|
if (!elements->dim)
|
||||||
MATCH m = (MATCH)e->implicitConvTo(tb->nextOf());
|
{ if (typen->ty != Tvoid)
|
||||||
if (m < result)
|
result = typen->implicitConvTo(telement);
|
||||||
result = m; // remember worst match
|
}
|
||||||
if (result == MATCHnomatch)
|
else
|
||||||
break; // no need to check for worse
|
{ 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)
|
if (!result)
|
||||||
@@ -560,25 +572,46 @@ MATCH ArrayLiteralExp::implicitConvTo(Type *t)
|
|||||||
|
|
||||||
return result;
|
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
|
else
|
||||||
return Expression::implicitConvTo(t);
|
return Expression::implicitConvTo(t);
|
||||||
}
|
}
|
||||||
|
|
||||||
MATCH AssocArrayLiteralExp::implicitConvTo(Type *t)
|
MATCH AssocArrayLiteralExp::implicitConvTo(Type *t)
|
||||||
{ MATCH result = MATCHexact;
|
{
|
||||||
|
|
||||||
Type *typeb = type->toBasetype();
|
Type *typeb = type->toBasetype();
|
||||||
Type *tb = t->toBasetype();
|
Type *tb = t->toBasetype();
|
||||||
if (tb->ty == Taarray && typeb->ty == Taarray)
|
if (tb->ty == Taarray && typeb->ty == Taarray)
|
||||||
{
|
{
|
||||||
|
MATCH result = MATCHexact;
|
||||||
for (size_t i = 0; i < keys->dim; i++)
|
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);
|
MATCH m = (MATCH)e->implicitConvTo(((TypeAArray *)tb)->index);
|
||||||
if (m < result)
|
if (m < result)
|
||||||
result = m; // remember worst match
|
result = m; // remember worst match
|
||||||
if (result == MATCHnomatch)
|
if (result == MATCHnomatch)
|
||||||
break; // no need to check for worse
|
break; // no need to check for worse
|
||||||
e = values->tdata()[i];
|
e = (*values)[i];
|
||||||
m = (MATCH)e->implicitConvTo(tb->nextOf());
|
m = (MATCH)e->implicitConvTo(tb->nextOf());
|
||||||
if (m < result)
|
if (m < result)
|
||||||
result = m; // remember worst match
|
result = m; // remember worst match
|
||||||
@@ -905,6 +938,9 @@ Expression *Expression::castTo(Scope *sc, Type *t)
|
|||||||
}
|
}
|
||||||
else if (tb->ty == Tvector && typeb->ty != Tvector)
|
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 = new VectorExp(loc, e, tb);
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
return e;
|
return e;
|
||||||
@@ -1372,9 +1408,9 @@ Expression *TupleExp::castTo(Scope *sc, Type *t)
|
|||||||
{ TupleExp *e = (TupleExp *)copy();
|
{ TupleExp *e = (TupleExp *)copy();
|
||||||
e->exps = (Expressions *)exps->copy();
|
e->exps = (Expressions *)exps->copy();
|
||||||
for (size_t i = 0; i < e->exps->dim; i++)
|
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);
|
ex = ex->castTo(sc, t);
|
||||||
e->exps->tdata()[i] = ex;
|
(*e->exps)[i] = ex;
|
||||||
}
|
}
|
||||||
return e;
|
return e;
|
||||||
}
|
}
|
||||||
@@ -1420,6 +1456,28 @@ Expression *ArrayLiteralExp::castTo(Scope *sc, Type *t)
|
|||||||
e->type = tp;
|
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:
|
L1:
|
||||||
return e->Expression::castTo(sc, t);
|
return e->Expression::castTo(sc, t);
|
||||||
}
|
}
|
||||||
@@ -1439,13 +1497,13 @@ Expression *AssocArrayLiteralExp::castTo(Scope *sc, Type *t)
|
|||||||
e->values = (Expressions *)values->copy();
|
e->values = (Expressions *)values->copy();
|
||||||
assert(keys->dim == values->dim);
|
assert(keys->dim == values->dim);
|
||||||
for (size_t i = 0; i < keys->dim; i++)
|
for (size_t i = 0; i < keys->dim; i++)
|
||||||
{ Expression *ex = values->tdata()[i];
|
{ Expression *ex = (*values)[i];
|
||||||
ex = ex->castTo(sc, tb->nextOf());
|
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);
|
ex = ex->castTo(sc, ((TypeAArray *)tb)->index);
|
||||||
e->keys->tdata()[i] = ex;
|
(*e->keys)[i] = ex;
|
||||||
}
|
}
|
||||||
e->type = t;
|
e->type = t;
|
||||||
return e;
|
return e;
|
||||||
@@ -1688,7 +1746,7 @@ Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams)
|
|||||||
{
|
{
|
||||||
if (to->ty == Tdelegate ||
|
if (to->ty == Tdelegate ||
|
||||||
to->ty == Tpointer && to->nextOf()->ty == Tfunction)
|
to->ty == Tpointer && to->nextOf()->ty == Tfunction)
|
||||||
{ treq = to;
|
{ fd->treq = to;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -1714,6 +1772,8 @@ Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams)
|
|||||||
{
|
{
|
||||||
TypeFunction *tfv = (TypeFunction *)t;
|
TypeFunction *tfv = (TypeFunction *)t;
|
||||||
TypeFunction *tfl = (TypeFunction *)fd->type;
|
TypeFunction *tfl = (TypeFunction *)fd->type;
|
||||||
|
//printf("\ttfv = %s\n", tfv->toChars());
|
||||||
|
//printf("\ttfl = %s\n", tfl->toChars());
|
||||||
size_t dim = Parameter::dim(tfl->parameters);
|
size_t dim = Parameter::dim(tfl->parameters);
|
||||||
|
|
||||||
if (Parameter::dim(tfv->parameters) == dim &&
|
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);
|
TemplateInstance *ti = new TemplateInstance(loc, td, tiargs);
|
||||||
e = (new ScopeExp(loc, ti))->semantic(td->scope);
|
e = (new ScopeExp(loc, ti))->semantic(td->scope);
|
||||||
if (e->op == TOKfunction)
|
if (e->op == TOKfunction)
|
||||||
@@ -1759,14 +1826,12 @@ Expression *FuncExp::inferType(Type *to, int flag, TemplateParameters *tparams)
|
|||||||
to->ty == Tdelegate)
|
to->ty == Tdelegate)
|
||||||
{
|
{
|
||||||
Type *typen = type->nextOf();
|
Type *typen = type->nextOf();
|
||||||
assert(typen->deco);
|
if (typen->deco)
|
||||||
//if (typen->covariant(to->nextOf()) == 1)
|
|
||||||
{
|
{
|
||||||
FuncExp *fe = (FuncExp *)copy();
|
FuncExp *fe = (FuncExp *)copy();
|
||||||
fe->tok = TOKdelegate;
|
fe->tok = TOKdelegate;
|
||||||
fe->type = (new TypeDelegate(typen))->merge();
|
fe->type = (new TypeDelegate(typen))->merge();
|
||||||
e = fe;
|
e = fe;
|
||||||
//e = fe->Expression::implicitCastTo(sc, to);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1879,7 +1944,7 @@ bool isVoidArrayLiteral(Expression *e, Type *other)
|
|||||||
while (e->op == TOKarrayliteral && e->type->ty == Tarray
|
while (e->op == TOKarrayliteral && e->type->ty == Tarray
|
||||||
&& (((ArrayLiteralExp *)e)->elements->dim == 1))
|
&& (((ArrayLiteralExp *)e)->elements->dim == 1))
|
||||||
{
|
{
|
||||||
e = ((ArrayLiteralExp *)e)->elements->tdata()[0];
|
e = (*((ArrayLiteralExp *)e)->elements)[0];
|
||||||
if (other->ty == Tsarray || other->ty == Tarray)
|
if (other->ty == Tsarray || other->ty == Tarray)
|
||||||
other = other->nextOf();
|
other = other->nextOf();
|
||||||
else
|
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());
|
//printf("typeMerge() %s op %s\n", (*pe1)->toChars(), (*pe2)->toChars());
|
||||||
//e->dump(0);
|
//e->dump(0);
|
||||||
|
|
||||||
|
MATCH m;
|
||||||
Expression *e1 = *pe1;
|
Expression *e1 = *pe1;
|
||||||
Expression *e2 = *pe2;
|
Expression *e2 = *pe2;
|
||||||
|
|
||||||
@@ -2110,10 +2176,20 @@ Lagain:
|
|||||||
*/
|
*/
|
||||||
goto Lx2;
|
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)
|
if (t1->ty == Tsarray && e2->op == TOKarrayliteral)
|
||||||
goto Lt1;
|
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;
|
goto Lt2;
|
||||||
}
|
}
|
||||||
else if ((t2->ty == Tsarray || t2->ty == Tarray) && t2->implicitConvTo(t1))
|
else if ((t2->ty == Tsarray || t2->ty == Tarray) && t2->implicitConvTo(t1))
|
||||||
|
|||||||
+64
-47
@@ -11,6 +11,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h> // mem{cpy|set}()
|
||||||
|
|
||||||
#include "root.h"
|
#include "root.h"
|
||||||
#include "rmem.h"
|
#include "rmem.h"
|
||||||
@@ -177,6 +178,12 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
|
|||||||
Type::typeinfowild->error("%s", msg);
|
Type::typeinfowild->error("%s", msg);
|
||||||
Type::typeinfowild = this;
|
Type::typeinfowild = this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (id == Id::TypeInfo_Vector)
|
||||||
|
{ if (Type::typeinfovector)
|
||||||
|
Type::typeinfovector->error("%s", msg);
|
||||||
|
Type::typeinfovector = this;
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -241,9 +248,9 @@ Dsymbol *ClassDeclaration::syntaxCopy(Dsymbol *s)
|
|||||||
cd->baseclasses->setDim(this->baseclasses->dim);
|
cd->baseclasses->setDim(this->baseclasses->dim);
|
||||||
for (size_t i = 0; i < cd->baseclasses->dim; i++)
|
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);
|
BaseClass *b2 = new BaseClass(b->type->syntaxCopy(), b->protection);
|
||||||
cd->baseclasses->tdata()[i] = b2;
|
(*cd->baseclasses)[i] = b2;
|
||||||
}
|
}
|
||||||
|
|
||||||
ScopeDsymbol::syntaxCopy(cd);
|
ScopeDsymbol::syntaxCopy(cd);
|
||||||
@@ -292,10 +299,6 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
scope = NULL;
|
scope = NULL;
|
||||||
}
|
}
|
||||||
unsigned dprogress_save = Module::dprogress;
|
unsigned dprogress_save = Module::dprogress;
|
||||||
#ifdef IN_GCC
|
|
||||||
methods.setDim(0);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
int errors = global.gaggedErrors;
|
int errors = global.gaggedErrors;
|
||||||
|
|
||||||
if (sc->stc & STCdeprecated)
|
if (sc->stc & STCdeprecated)
|
||||||
@@ -308,7 +311,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
|
|
||||||
// Expand any tuples in baseclasses[]
|
// Expand any tuples in baseclasses[]
|
||||||
for (size_t i = 0; i < baseclasses->dim; )
|
for (size_t i = 0; i < baseclasses->dim; )
|
||||||
{ BaseClass *b = baseclasses->tdata()[i];
|
{ BaseClass *b = (*baseclasses)[i];
|
||||||
b->type = b->type->semantic(loc, sc);
|
b->type = b->type->semantic(loc, sc);
|
||||||
Type *tb = b->type->toBasetype();
|
Type *tb = b->type->toBasetype();
|
||||||
|
|
||||||
@@ -333,7 +336,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
BaseClass *b;
|
BaseClass *b;
|
||||||
Type *tb;
|
Type *tb;
|
||||||
|
|
||||||
b = baseclasses->tdata()[0];
|
b = (*baseclasses)[0];
|
||||||
//b->type = b->type->semantic(loc, sc);
|
//b->type = b->type->semantic(loc, sc);
|
||||||
tb = b->type->toBasetype();
|
tb = b->type->toBasetype();
|
||||||
if (tb->ty != Tclass)
|
if (tb->ty != Tclass)
|
||||||
@@ -403,7 +406,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
BaseClass *b;
|
BaseClass *b;
|
||||||
Type *tb;
|
Type *tb;
|
||||||
|
|
||||||
b = baseclasses->tdata()[i];
|
b = (*baseclasses)[i];
|
||||||
b->type = b->type->semantic(loc, sc);
|
b->type = b->type->semantic(loc, sc);
|
||||||
tb = b->type->toBasetype();
|
tb = b->type->toBasetype();
|
||||||
if (tb->ty == Tclass)
|
if (tb->ty == Tclass)
|
||||||
@@ -432,7 +435,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
// Check for duplicate interfaces
|
// Check for duplicate interfaces
|
||||||
for (size_t j = (baseClass ? 1 : 0); j < i; j++)
|
for (size_t j = (baseClass ? 1 : 0); j < i; j++)
|
||||||
{
|
{
|
||||||
BaseClass *b2 = baseclasses->tdata()[j];
|
BaseClass *b2 = (*baseclasses)[j];
|
||||||
if (b2->base == tc->sym)
|
if (b2->base == tc->sym)
|
||||||
error("inherits from duplicate interface %s", b2->base->toChars());
|
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 no base class, and this is not an Object, use Object as base class
|
||||||
if (!baseClass && ident != Id::Object)
|
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)
|
if (!object)
|
||||||
{
|
{
|
||||||
error("missing or corrupt object.d");
|
error("missing or corrupt object.d");
|
||||||
fatal();
|
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);
|
baseclasses->shift(b);
|
||||||
assert(b->type->ty == Tclass);
|
|
||||||
tc = (TypeClass *)(b->type);
|
|
||||||
baseClass = tc->sym;
|
baseClass = tc->sym;
|
||||||
assert(!baseClass->isInterfaceDeclaration());
|
assert(!baseClass->isInterfaceDeclaration());
|
||||||
b->base = baseClass;
|
b->base = baseClass;
|
||||||
@@ -535,7 +536,9 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
isnested = 1;
|
isnested = 1;
|
||||||
if (storage_class & STCstatic)
|
if (storage_class & STCstatic)
|
||||||
error("static class cannot inherit from nested class %s", baseClass->toChars());
|
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())
|
if (toParent2())
|
||||||
{
|
{
|
||||||
@@ -614,8 +617,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
}
|
}
|
||||||
sc->protection = PROTpublic;
|
sc->protection = PROTpublic;
|
||||||
sc->explicitProtection = 0;
|
sc->explicitProtection = 0;
|
||||||
sc->structalign = 8;
|
sc->structalign = STRUCTALIGN_DEFAULT;
|
||||||
structalign = sc->structalign;
|
|
||||||
if (baseClass)
|
if (baseClass)
|
||||||
{ sc->offset = baseClass->structsize;
|
{ sc->offset = baseClass->structsize;
|
||||||
alignsize = baseClass->alignsize;
|
alignsize = baseClass->alignsize;
|
||||||
@@ -642,9 +644,10 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
if (s->isEnumDeclaration() ||
|
if (s->isEnumDeclaration() ||
|
||||||
(s->isAggregateDeclaration() && s->ident) ||
|
(s->isAggregateDeclaration() && s->ident) ||
|
||||||
s->isTemplateMixin() ||
|
s->isTemplateMixin() ||
|
||||||
|
s->isAttribDeclaration() ||
|
||||||
s->isAliasDeclaration())
|
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);
|
s->setScope(sc);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -682,7 +685,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
fields.setDim(0);
|
fields.setDim(0);
|
||||||
structsize = 0;
|
structsize = 0;
|
||||||
alignsize = 0;
|
alignsize = 0;
|
||||||
structalign = 0;
|
// structalign = 0;
|
||||||
|
|
||||||
sc = sc->pop();
|
sc = sc->pop();
|
||||||
|
|
||||||
@@ -757,7 +760,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
BaseClass *b = (*vtblInterfaces)[i];
|
BaseClass *b = (*vtblInterfaces)[i];
|
||||||
unsigned thissize = PTRSIZE;
|
unsigned thissize = PTRSIZE;
|
||||||
|
|
||||||
alignmember(structalign, thissize, &sc->offset);
|
alignmember(STRUCTALIGN_DEFAULT, thissize, &sc->offset);
|
||||||
assert(b->offset == 0);
|
assert(b->offset == 0);
|
||||||
b->offset = sc->offset;
|
b->offset = sc->offset;
|
||||||
|
|
||||||
@@ -774,9 +777,12 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
}
|
}
|
||||||
structsize = sc->offset;
|
structsize = sc->offset;
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
if (global.params.is64bit)
|
if (sc->structalign == STRUCTALIGN_DEFAULT)
|
||||||
structsize = (structsize + structalign - 1) & ~(structalign - 1);
|
structsize = (structsize + alignsize - 1) & ~(alignsize - 1);
|
||||||
|
else
|
||||||
|
structsize = (structsize + sc->structalign - 1) & ~(sc->structalign - 1);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
sizeok = SIZEOKdone;
|
sizeok = SIZEOKdone;
|
||||||
Module::dprogress++;
|
Module::dprogress++;
|
||||||
|
|
||||||
@@ -788,7 +794,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
|||||||
// Fill in base class vtbl[]s
|
// Fill in base class vtbl[]s
|
||||||
for (i = 0; i < vtblInterfaces->dim; i++)
|
for (i = 0; i < vtblInterfaces->dim; i++)
|
||||||
{
|
{
|
||||||
BaseClass *b = vtblInterfaces->tdata()[i];
|
BaseClass *b = (*vtblInterfaces)[i];
|
||||||
|
|
||||||
//b->fillVtbl(this, &b->vtbl, 1);
|
//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++)
|
for (size_t i = 0; i < baseclasses->dim; i++)
|
||||||
{
|
{
|
||||||
BaseClass *b = baseclasses->tdata()[i];
|
BaseClass *b = (*baseclasses)[i];
|
||||||
|
|
||||||
if (i)
|
if (i)
|
||||||
buf->writeByte(',');
|
buf->writeByte(',');
|
||||||
@@ -827,7 +833,7 @@ void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
|||||||
buf->writenl();
|
buf->writenl();
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = members->tdata()[i];
|
Dsymbol *s = (*members)[i];
|
||||||
|
|
||||||
buf->writestring(" ");
|
buf->writestring(" ");
|
||||||
s->toCBuffer(buf, hgs);
|
s->toCBuffer(buf, hgs);
|
||||||
@@ -862,7 +868,7 @@ int ClassDeclaration::isBaseOf2(ClassDeclaration *cd)
|
|||||||
return 0;
|
return 0;
|
||||||
//printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
|
//printf("ClassDeclaration::isBaseOf2(this = '%s', cd = '%s')\n", toChars(), cd->toChars());
|
||||||
for (size_t i = 0; i < cd->baseclasses->dim; i++)
|
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))
|
if (b->base == this || isBaseOf2(b->base))
|
||||||
return 1;
|
return 1;
|
||||||
@@ -908,7 +914,7 @@ int ClassDeclaration::isBaseInfoComplete()
|
|||||||
if (!baseClass)
|
if (!baseClass)
|
||||||
return ident == Id::Object;
|
return ident == Id::Object;
|
||||||
for (size_t i = 0; i < baseclasses->dim; i++)
|
for (size_t i = 0; i < baseclasses->dim; i++)
|
||||||
{ BaseClass *b = baseclasses->tdata()[i];
|
{ BaseClass *b = (*baseclasses)[i];
|
||||||
if (!b->base || !b->base->isBaseInfoComplete())
|
if (!b->base || !b->base->isBaseInfoComplete())
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -946,7 +952,7 @@ Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags)
|
|||||||
|
|
||||||
for (size_t i = 0; i < baseclasses->dim; i++)
|
for (size_t i = 0; i < baseclasses->dim; i++)
|
||||||
{
|
{
|
||||||
BaseClass *b = baseclasses->tdata()[i];
|
BaseClass *b = (*baseclasses)[i];
|
||||||
|
|
||||||
if (b->base)
|
if (b->base)
|
||||||
{
|
{
|
||||||
@@ -1011,7 +1017,7 @@ int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
|
|||||||
if (os)
|
if (os)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < os->a.dim; i++)
|
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();
|
FuncDeclaration *f2 = s2->isFuncDeclaration();
|
||||||
if (f2 && overloadApply(f2, &isf, fd))
|
if (f2 && overloadApply(f2, &isf, fd))
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1054,9 +1060,11 @@ FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf)
|
|||||||
//printf("\t[%d] = %s\n", i, fd->toChars());
|
//printf("\t[%d] = %s\n", i, fd->toChars());
|
||||||
if (ident == fd->ident &&
|
if (ident == fd->ident &&
|
||||||
fd->type->covariant(tf) == 1)
|
fd->type->covariant(tf) == 1)
|
||||||
{ //printf("fd->parent->isClassDeclaration() = %p", fd->parent->isClassDeclaration());
|
{ //printf("fd->parent->isClassDeclaration() = %p\n", fd->parent->isClassDeclaration());
|
||||||
if (!fdmatch)
|
if (!fdmatch)
|
||||||
goto Lfd;
|
goto Lfd;
|
||||||
|
if (fd == fdmatch)
|
||||||
|
goto Lfdmatch;
|
||||||
|
|
||||||
{
|
{
|
||||||
// Function type matcing: exact > covariant
|
// Function type matcing: exact > covariant
|
||||||
@@ -1068,6 +1076,15 @@ FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf)
|
|||||||
goto Lfdmatch;
|
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
|
// The way of definition: non-mixin > mixin
|
||||||
int m1 = fd ->parent->isClassDeclaration() ? MATCHexact : MATCHnomatch;
|
int m1 = fd ->parent->isClassDeclaration() ? MATCHexact : MATCHnomatch;
|
||||||
@@ -1158,7 +1175,7 @@ int ClassDeclaration::isAbstract()
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
for (size_t i = 1; i < vtbl.dim; i++)
|
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);
|
//printf("\tvtbl[%d] = %p\n", i, fd);
|
||||||
if (!fd || fd->isAbstract())
|
if (!fd || fd->isAbstract())
|
||||||
@@ -1266,7 +1283,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
|
|||||||
|
|
||||||
// Expand any tuples in baseclasses[]
|
// Expand any tuples in baseclasses[]
|
||||||
for (size_t i = 0; i < baseclasses->dim; )
|
for (size_t i = 0; i < baseclasses->dim; )
|
||||||
{ BaseClass *b = (*baseclasses)[0];
|
{ BaseClass *b = (*baseclasses)[i];
|
||||||
b->type = b->type->semantic(loc, sc);
|
b->type = b->type->semantic(loc, sc);
|
||||||
Type *tb = b->type->toBasetype();
|
Type *tb = b->type->toBasetype();
|
||||||
|
|
||||||
@@ -1294,7 +1311,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
|
|||||||
BaseClass *b;
|
BaseClass *b;
|
||||||
Type *tb;
|
Type *tb;
|
||||||
|
|
||||||
b = baseclasses->tdata()[i];
|
b = (*baseclasses)[i];
|
||||||
b->type = b->type->semantic(loc, sc);
|
b->type = b->type->semantic(loc, sc);
|
||||||
tb = b->type->toBasetype();
|
tb = b->type->toBasetype();
|
||||||
if (tb->ty == Tclass)
|
if (tb->ty == Tclass)
|
||||||
@@ -1312,7 +1329,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
|
|||||||
// Check for duplicate interfaces
|
// Check for duplicate interfaces
|
||||||
for (size_t j = 0; j < i; j++)
|
for (size_t j = 0; j < i; j++)
|
||||||
{
|
{
|
||||||
BaseClass *b2 = baseclasses->tdata()[j];
|
BaseClass *b2 = (*baseclasses)[j];
|
||||||
if (b2->base == tc->sym)
|
if (b2->base == tc->sym)
|
||||||
error("inherits from duplicate interface %s", b2->base->toChars());
|
error("inherits from duplicate interface %s", b2->base->toChars());
|
||||||
}
|
}
|
||||||
@@ -1373,7 +1390,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
|
|||||||
{
|
{
|
||||||
vtbl.reserve(d - 1);
|
vtbl.reserve(d - 1);
|
||||||
for (size_t j = 1; j < d; j++)
|
for (size_t j = 1; j < d; j++)
|
||||||
vtbl.push(b->base->vtbl.tdata()[j]);
|
vtbl.push(b->base->vtbl[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1401,10 +1418,10 @@ void InterfaceDeclaration::semantic(Scope *sc)
|
|||||||
sc->linkage = LINKwindows;
|
sc->linkage = LINKwindows;
|
||||||
else if (isCPPinterface())
|
else if (isCPPinterface())
|
||||||
sc->linkage = LINKcpp;
|
sc->linkage = LINKcpp;
|
||||||
sc->structalign = 8;
|
sc->structalign = STRUCTALIGN_DEFAULT;
|
||||||
sc->protection = PROTpublic;
|
sc->protection = PROTpublic;
|
||||||
sc->explicitProtection = 0;
|
sc->explicitProtection = 0;
|
||||||
structalign = sc->structalign;
|
// structalign = sc->structalign;
|
||||||
sc->offset = PTRSIZE * 2;
|
sc->offset = PTRSIZE * 2;
|
||||||
structsize = sc->offset;
|
structsize = sc->offset;
|
||||||
inuse++;
|
inuse++;
|
||||||
@@ -1426,7 +1443,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
|
|||||||
|
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = members->tdata()[i];
|
Dsymbol *s = (*members)[i];
|
||||||
s->semantic(sc);
|
s->semantic(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1526,7 +1543,7 @@ int InterfaceDeclaration::isBaseInfoComplete()
|
|||||||
{
|
{
|
||||||
assert(!baseClass);
|
assert(!baseClass);
|
||||||
for (size_t i = 0; i < baseclasses->dim; i++)
|
for (size_t i = 0; i < baseclasses->dim; i++)
|
||||||
{ BaseClass *b = baseclasses->tdata()[i];
|
{ BaseClass *b = (*baseclasses)[i];
|
||||||
if (!b->base || !b->base->isBaseInfoComplete ())
|
if (!b->base || !b->base->isBaseInfoComplete ())
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -1610,7 +1627,7 @@ int BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newins
|
|||||||
// first entry is ClassInfo reference
|
// first entry is ClassInfo reference
|
||||||
for (size_t j = base->vtblOffset(); j < base->vtbl.dim; j++)
|
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;
|
FuncDeclaration *fd;
|
||||||
TypeFunction *tf;
|
TypeFunction *tf;
|
||||||
|
|
||||||
@@ -1647,7 +1664,7 @@ int BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newins
|
|||||||
fd = NULL;
|
fd = NULL;
|
||||||
}
|
}
|
||||||
if (vtbl)
|
if (vtbl)
|
||||||
vtbl->tdata()[j] = fd;
|
(*vtbl)[j] = fd;
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
|
|||||||
+16
-16
@@ -45,7 +45,7 @@ int StructDeclaration::needOpAssign()
|
|||||||
*/
|
*/
|
||||||
for (size_t i = 0; i < fields.dim; i++)
|
for (size_t i = 0; i < fields.dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = fields.tdata()[i];
|
Dsymbol *s = fields[i];
|
||||||
VarDeclaration *v = s->isVarDeclaration();
|
VarDeclaration *v = s->isVarDeclaration();
|
||||||
assert(v && v->storage_class & STCfield);
|
assert(v && v->storage_class & STCfield);
|
||||||
if (v->storage_class & STCref)
|
if (v->storage_class & STCref)
|
||||||
@@ -153,7 +153,7 @@ FuncDeclaration *StructDeclaration::buildOpAssign(Scope *sc)
|
|||||||
//printf("\tmemberwise copy\n");
|
//printf("\tmemberwise copy\n");
|
||||||
for (size_t i = 0; i < fields.dim; i++)
|
for (size_t i = 0; i < fields.dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = fields.tdata()[i];
|
Dsymbol *s = fields[i];
|
||||||
VarDeclaration *v = s->isVarDeclaration();
|
VarDeclaration *v = s->isVarDeclaration();
|
||||||
assert(v && v->storage_class & STCfield);
|
assert(v && v->storage_class & STCfield);
|
||||||
// this.v = s.v;
|
// this.v = s.v;
|
||||||
@@ -214,7 +214,7 @@ int StructDeclaration::needOpEquals()
|
|||||||
*/
|
*/
|
||||||
for (size_t i = 0; i < fields.dim; i++)
|
for (size_t i = 0; i < fields.dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = fields.tdata()[i];
|
Dsymbol *s = fields[i];
|
||||||
VarDeclaration *v = s->isVarDeclaration();
|
VarDeclaration *v = s->isVarDeclaration();
|
||||||
assert(v && v->storage_class & STCfield);
|
assert(v && v->storage_class & STCfield);
|
||||||
if (v->storage_class & STCref)
|
if (v->storage_class & STCref)
|
||||||
@@ -304,7 +304,7 @@ FuncDeclaration *StructDeclaration::buildOpEquals(Scope *sc)
|
|||||||
//printf("\tmemberwise compare\n");
|
//printf("\tmemberwise compare\n");
|
||||||
for (size_t i = 0; i < fields.dim; i++)
|
for (size_t i = 0; i < fields.dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = fields.tdata()[i];
|
Dsymbol *s = fields[i];
|
||||||
VarDeclaration *v = s->isVarDeclaration();
|
VarDeclaration *v = s->isVarDeclaration();
|
||||||
assert(v && v->storage_class & STCfield);
|
assert(v && v->storage_class & STCfield);
|
||||||
if (v->storage_class & STCref)
|
if (v->storage_class & STCref)
|
||||||
@@ -513,13 +513,13 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
|
|||||||
|
|
||||||
for (size_t i = 0; i < fields.dim; i++)
|
for (size_t i = 0; i < fields.dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = fields.tdata()[i];
|
Dsymbol *s = fields[i];
|
||||||
VarDeclaration *v = s->isVarDeclaration();
|
VarDeclaration *v = s->isVarDeclaration();
|
||||||
assert(v && v->storage_class & STCfield);
|
assert(v && v->storage_class & STCfield);
|
||||||
if (v->storage_class & STCref)
|
if (v->storage_class & STCref)
|
||||||
continue;
|
continue;
|
||||||
Type *tv = v->type->toBasetype();
|
Type *tv = v->type->toBasetype();
|
||||||
dinteger_t dim = (tv->ty == Tsarray ? 1 : 0);
|
dinteger_t dim = 1;
|
||||||
while (tv->ty == Tsarray)
|
while (tv->ty == Tsarray)
|
||||||
{ TypeSArray *ta = (TypeSArray *)tv;
|
{ TypeSArray *ta = (TypeSArray *)tv;
|
||||||
dim *= ((TypeSArray *)tv)->dim->toInteger();
|
dim *= ((TypeSArray *)tv)->dim->toInteger();
|
||||||
@@ -528,7 +528,7 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
|
|||||||
if (tv->ty == Tstruct)
|
if (tv->ty == Tstruct)
|
||||||
{ TypeStruct *ts = (TypeStruct *)tv;
|
{ TypeStruct *ts = (TypeStruct *)tv;
|
||||||
StructDeclaration *sd = ts->sym;
|
StructDeclaration *sd = ts->sym;
|
||||||
if (sd->postblit)
|
if (sd->postblit && dim)
|
||||||
{
|
{
|
||||||
stc |= sd->postblit->storage_class & STCdisable;
|
stc |= sd->postblit->storage_class & STCdisable;
|
||||||
|
|
||||||
@@ -542,7 +542,7 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
|
|||||||
Expression *ex = new ThisExp(0);
|
Expression *ex = new ThisExp(0);
|
||||||
ex = new DotVarExp(0, ex, v, 0);
|
ex = new DotVarExp(0, ex, v, 0);
|
||||||
|
|
||||||
if (dim == 0)
|
if (v->type->toBasetype()->ty == Tstruct)
|
||||||
{ // this.v.postblit()
|
{ // this.v.postblit()
|
||||||
ex = new DotVarExp(0, ex, sd->postblit, 0);
|
ex = new DotVarExp(0, ex, sd->postblit, 0);
|
||||||
ex = new CallExp(0, ex);
|
ex = new CallExp(0, ex);
|
||||||
@@ -581,12 +581,12 @@ FuncDeclaration *StructDeclaration::buildPostBlit(Scope *sc)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
return postblits.tdata()[0];
|
return postblits[0];
|
||||||
|
|
||||||
default:
|
default:
|
||||||
e = NULL;
|
e = NULL;
|
||||||
for (size_t i = 0; i < postblits.dim; i++)
|
for (size_t i = 0; i < postblits.dim; i++)
|
||||||
{ FuncDeclaration *fd = postblits.tdata()[i];
|
{ FuncDeclaration *fd = postblits[i];
|
||||||
stc |= fd->storage_class & STCdisable;
|
stc |= fd->storage_class & STCdisable;
|
||||||
if (stc & STCdisable)
|
if (stc & STCdisable)
|
||||||
{
|
{
|
||||||
@@ -625,13 +625,13 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
|
|||||||
#if DMDV2
|
#if DMDV2
|
||||||
for (size_t i = 0; i < fields.dim; i++)
|
for (size_t i = 0; i < fields.dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = fields.tdata()[i];
|
Dsymbol *s = fields[i];
|
||||||
VarDeclaration *v = s->isVarDeclaration();
|
VarDeclaration *v = s->isVarDeclaration();
|
||||||
assert(v && v->storage_class & STCfield);
|
assert(v && v->storage_class & STCfield);
|
||||||
if (v->storage_class & STCref)
|
if (v->storage_class & STCref)
|
||||||
continue;
|
continue;
|
||||||
Type *tv = v->type->toBasetype();
|
Type *tv = v->type->toBasetype();
|
||||||
dinteger_t dim = (tv->ty == Tsarray ? 1 : 0);
|
dinteger_t dim = 1;
|
||||||
while (tv->ty == Tsarray)
|
while (tv->ty == Tsarray)
|
||||||
{ TypeSArray *ta = (TypeSArray *)tv;
|
{ TypeSArray *ta = (TypeSArray *)tv;
|
||||||
dim *= ((TypeSArray *)tv)->dim->toInteger();
|
dim *= ((TypeSArray *)tv)->dim->toInteger();
|
||||||
@@ -640,14 +640,14 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
|
|||||||
if (tv->ty == Tstruct)
|
if (tv->ty == Tstruct)
|
||||||
{ TypeStruct *ts = (TypeStruct *)tv;
|
{ TypeStruct *ts = (TypeStruct *)tv;
|
||||||
StructDeclaration *sd = ts->sym;
|
StructDeclaration *sd = ts->sym;
|
||||||
if (sd->dtor)
|
if (sd->dtor && dim)
|
||||||
{ Expression *ex;
|
{ Expression *ex;
|
||||||
|
|
||||||
// this.v
|
// this.v
|
||||||
ex = new ThisExp(0);
|
ex = new ThisExp(0);
|
||||||
ex = new DotVarExp(0, ex, v, 0);
|
ex = new DotVarExp(0, ex, v, 0);
|
||||||
|
|
||||||
if (dim == 0)
|
if (v->type->toBasetype()->ty == Tstruct)
|
||||||
{ // this.v.dtor()
|
{ // this.v.dtor()
|
||||||
ex = new DotVarExp(0, ex, sd->dtor, 0);
|
ex = new DotVarExp(0, ex, sd->dtor, 0);
|
||||||
ex = new CallExp(0, ex);
|
ex = new CallExp(0, ex);
|
||||||
@@ -686,12 +686,12 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
return dtors.tdata()[0];
|
return dtors[0];
|
||||||
|
|
||||||
default:
|
default:
|
||||||
e = NULL;
|
e = NULL;
|
||||||
for (size_t i = 0; i < dtors.dim; i++)
|
for (size_t i = 0; i < dtors.dim; i++)
|
||||||
{ FuncDeclaration *fd = dtors.tdata()[i];
|
{ FuncDeclaration *fd = dtors[i];
|
||||||
Expression *ex = new ThisExp(0);
|
Expression *ex = new ThisExp(0);
|
||||||
ex = new DotVarExp(0, ex, fd, 0);
|
ex = new DotVarExp(0, ex, fd, 0);
|
||||||
ex = new CallExp(0, ex);
|
ex = new CallExp(0, ex);
|
||||||
|
|||||||
+9
-1
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h> // strcmp()
|
||||||
|
|
||||||
#include "id.h"
|
#include "id.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
@@ -266,7 +267,14 @@ int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
|
|||||||
sc->flags |= SCOPEstaticif;
|
sc->flags |= SCOPEstaticif;
|
||||||
Expression *e = exp->semantic(sc);
|
Expression *e = exp->semantic(sc);
|
||||||
sc->pop();
|
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;
|
--nest;
|
||||||
if (e->op == TOKerror)
|
if (e->op == TOKerror)
|
||||||
{ exp = e;
|
{ exp = e;
|
||||||
|
|||||||
+55
-12
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -11,6 +11,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h> // mem{cpy|set|cmp}()
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
#if __DMC__
|
#if __DMC__
|
||||||
@@ -621,7 +622,7 @@ Expression *Pow(Type *type, Expression *e1, Expression *e2)
|
|||||||
// Special case: call sqrt directly.
|
// Special case: call sqrt directly.
|
||||||
Expressions args;
|
Expressions args;
|
||||||
args.setDim(1);
|
args.setDim(1);
|
||||||
args.tdata()[0] = e1;
|
args[0] = e1;
|
||||||
e = eval_builtin(loc, BUILTINsqrt, &args);
|
e = eval_builtin(loc, BUILTINsqrt, &args);
|
||||||
if (!e)
|
if (!e)
|
||||||
e = EXP_CANT_INTERPRET;
|
e = EXP_CANT_INTERPRET;
|
||||||
@@ -1290,7 +1291,7 @@ Expression *Cast(Type *type, Type *to, Expression *e1)
|
|||||||
assert(sd);
|
assert(sd);
|
||||||
Expressions *elements = new Expressions;
|
Expressions *elements = new Expressions;
|
||||||
for (size_t i = 0; i < sd->fields.dim; i++)
|
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();
|
VarDeclaration *v = s->isVarDeclaration();
|
||||||
assert(v);
|
assert(v);
|
||||||
|
|
||||||
@@ -1374,7 +1375,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
|
|||||||
}
|
}
|
||||||
else if (e1->op == TOKarrayliteral)
|
else if (e1->op == TOKarrayliteral)
|
||||||
{ ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
|
{ ArrayLiteralExp *ale = (ArrayLiteralExp *)e1;
|
||||||
e = ale->elements->tdata()[i];
|
e = (*ale->elements)[i];
|
||||||
e->type = type;
|
e->type = type;
|
||||||
if (e->hasSideEffect())
|
if (e->hasSideEffect())
|
||||||
e = EXP_CANT_INTERPRET;
|
e = EXP_CANT_INTERPRET;
|
||||||
@@ -1392,7 +1393,7 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
|
|||||||
e = new ErrorExp();
|
e = new ErrorExp();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ e = ale->elements->tdata()[i];
|
{ e = (*ale->elements)[i];
|
||||||
e->type = type;
|
e->type = type;
|
||||||
if (e->hasSideEffect())
|
if (e->hasSideEffect())
|
||||||
e = EXP_CANT_INTERPRET;
|
e = EXP_CANT_INTERPRET;
|
||||||
@@ -1407,12 +1408,12 @@ Expression *Index(Type *type, Expression *e1, Expression *e2)
|
|||||||
for (size_t i = ae->keys->dim; i;)
|
for (size_t i = ae->keys->dim; i;)
|
||||||
{
|
{
|
||||||
i--;
|
i--;
|
||||||
Expression *ekey = ae->keys->tdata()[i];
|
Expression *ekey = (*ae->keys)[i];
|
||||||
Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2);
|
Expression *ex = Equal(TOKequal, Type::tbool, ekey, e2);
|
||||||
if (ex == EXP_CANT_INTERPRET)
|
if (ex == EXP_CANT_INTERPRET)
|
||||||
return ex;
|
return ex;
|
||||||
if (ex->isBool(TRUE))
|
if (ex->isBool(TRUE))
|
||||||
{ e = ae->values->tdata()[i];
|
{ e = (*ae->values)[i];
|
||||||
e->type = type;
|
e->type = type;
|
||||||
if (e->hasSideEffect())
|
if (e->hasSideEffect())
|
||||||
e = EXP_CANT_INTERPRET;
|
e = EXP_CANT_INTERPRET;
|
||||||
@@ -1483,7 +1484,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
|
|||||||
elements->setDim(iupr - ilwr);
|
elements->setDim(iupr - ilwr);
|
||||||
memcpy(elements->tdata(),
|
memcpy(elements->tdata(),
|
||||||
es1->elements->tdata() + ilwr,
|
es1->elements->tdata() + ilwr,
|
||||||
(iupr - ilwr) * sizeof(es1->elements->tdata()[0]));
|
(iupr - ilwr) * sizeof((*es1->elements)[0]));
|
||||||
e = new ArrayLiteralExp(e1->loc, elements);
|
e = new ArrayLiteralExp(e1->loc, elements);
|
||||||
e->type = type;
|
e->type = type;
|
||||||
}
|
}
|
||||||
@@ -1512,7 +1513,7 @@ void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *n
|
|||||||
assert(0);
|
assert(0);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
existingAE->elements->tdata()[j+firstIndex]
|
(*existingAE->elements)[j+firstIndex]
|
||||||
= new IntegerExp(newval->loc, val, elemType);
|
= new IntegerExp(newval->loc, val, elemType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1525,7 +1526,7 @@ void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *n
|
|||||||
unsigned char *s = (unsigned char *)existingSE->string;
|
unsigned char *s = (unsigned char *)existingSE->string;
|
||||||
for (size_t j = 0; j < newae->elements->dim; j++)
|
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)
|
switch (existingSE->sz)
|
||||||
{
|
{
|
||||||
case 1: s[j+firstIndex] = value; break;
|
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);
|
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
|
/* Also return EXP_CANT_INTERPRET if this fails
|
||||||
*/
|
*/
|
||||||
Expression *Cat(Type *type, Expression *e1, Expression *e2)
|
Expression *Cat(Type *type, Expression *e1, Expression *e2)
|
||||||
@@ -1666,7 +1709,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
|
|||||||
elems->setDim(len);
|
elems->setDim(len);
|
||||||
for (size_t i= 0; i < ea->elements->dim; ++i)
|
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);
|
ArrayLiteralExp *dest = new ArrayLiteralExp(e1->loc, elems);
|
||||||
dest->type = type;
|
dest->type = type;
|
||||||
@@ -1684,7 +1727,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
|
|||||||
elems->setDim(len);
|
elems->setDim(len);
|
||||||
for (size_t i= 0; i < ea->elements->dim; ++i)
|
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);
|
ArrayLiteralExp *dest = new ArrayLiteralExp(e1->loc, elems);
|
||||||
dest->type = type;
|
dest->type = type;
|
||||||
|
|||||||
+6
-5
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2010 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -9,6 +9,7 @@
|
|||||||
// See the included readme.txt for details.
|
// See the included readme.txt for details.
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
|
||||||
#include "mars.h"
|
#include "mars.h"
|
||||||
@@ -69,7 +70,7 @@ int CppMangleState::substitute(OutBuffer *buf, void *p)
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < components.dim; i++)
|
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_, ...
|
/* 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++)
|
for (size_t i = 0; i < components.dim; i++)
|
||||||
{
|
{
|
||||||
if (p == components.tdata()[i])
|
if (p == components[i])
|
||||||
{
|
{
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -160,7 +161,7 @@ char *cpp_mangle(Dsymbol *s)
|
|||||||
cms.components.setDim(0);
|
cms.components.setDim(0);
|
||||||
|
|
||||||
OutBuffer buf;
|
OutBuffer buf;
|
||||||
#if MACHOBJ
|
#if TARGET_OSX
|
||||||
buf.writestring("__Z");
|
buf.writestring("__Z");
|
||||||
#else
|
#else
|
||||||
buf.writestring("_Z");
|
buf.writestring("_Z");
|
||||||
@@ -417,7 +418,7 @@ void Parameter::argsCppMangle(OutBuffer *buf, CppMangleState *cms, Parameters *a
|
|||||||
if (arguments)
|
if (arguments)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < arguments->dim; i++)
|
for (size_t i = 0; i < arguments->dim; i++)
|
||||||
{ Parameter *arg = arguments->tdata()[i];
|
{ Parameter *arg = (*arguments)[i];
|
||||||
Type *t = arg->type;
|
Type *t = arg->type;
|
||||||
if (arg->storageClass & (STCout | STCref))
|
if (arg->storageClass & (STCout | STCref))
|
||||||
t = t->referenceTo();
|
t = t->referenceTo();
|
||||||
|
|||||||
+119
-59
@@ -122,6 +122,18 @@ void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
|
|||||||
}
|
}
|
||||||
#endif
|
#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 ****************************/
|
/********************************* TupleDeclaration ****************************/
|
||||||
|
|
||||||
@@ -159,7 +171,7 @@ Type *TupleDeclaration::getType()
|
|||||||
/* It's only a type tuple if all the Object's are types
|
/* It's only a type tuple if all the Object's are types
|
||||||
*/
|
*/
|
||||||
for (size_t i = 0; i < objects->dim; i++)
|
for (size_t i = 0; i < objects->dim; i++)
|
||||||
{ Object *o = objects->tdata()[i];
|
{ Object *o = (*objects)[i];
|
||||||
|
|
||||||
if (o->dyncast() != DYNCAST_TYPE)
|
if (o->dyncast() != DYNCAST_TYPE)
|
||||||
{
|
{
|
||||||
@@ -176,7 +188,7 @@ Type *TupleDeclaration::getType()
|
|||||||
OutBuffer buf;
|
OutBuffer buf;
|
||||||
int hasdeco = 1;
|
int hasdeco = 1;
|
||||||
for (size_t i = 0; i < types->dim; i++)
|
for (size_t i = 0; i < types->dim; i++)
|
||||||
{ Type *t = types->tdata()[i];
|
{ Type *t = (*types)[i];
|
||||||
|
|
||||||
//printf("type = %s\n", t->toChars());
|
//printf("type = %s\n", t->toChars());
|
||||||
#if 0
|
#if 0
|
||||||
@@ -187,7 +199,7 @@ Type *TupleDeclaration::getType()
|
|||||||
#else
|
#else
|
||||||
Parameter *arg = new Parameter(0, t, NULL, NULL);
|
Parameter *arg = new Parameter(0, t, NULL, NULL);
|
||||||
#endif
|
#endif
|
||||||
args->tdata()[i] = arg;
|
(*args)[i] = arg;
|
||||||
if (!t->deco)
|
if (!t->deco)
|
||||||
hasdeco = 0;
|
hasdeco = 0;
|
||||||
}
|
}
|
||||||
@@ -204,7 +216,7 @@ int TupleDeclaration::needThis()
|
|||||||
{
|
{
|
||||||
//printf("TupleDeclaration::needThis(%s)\n", toChars());
|
//printf("TupleDeclaration::needThis(%s)\n", toChars());
|
||||||
for (size_t i = 0; i < objects->dim; i++)
|
for (size_t i = 0; i < objects->dim; i++)
|
||||||
{ Object *o = objects->tdata()[i];
|
{ Object *o = (*objects)[i];
|
||||||
if (o->dyncast() == DYNCAST_EXPRESSION)
|
if (o->dyncast() == DYNCAST_EXPRESSION)
|
||||||
{ Expression *e = (Expression *)o;
|
{ Expression *e = (Expression *)o;
|
||||||
if (e->op == TOKdsymbol)
|
if (e->op == TOKdsymbol)
|
||||||
@@ -336,7 +348,7 @@ void TypedefDeclaration::semantic2(Scope *sc)
|
|||||||
{
|
{
|
||||||
Initializer *savedinit = init;
|
Initializer *savedinit = init;
|
||||||
int errors = global.errors;
|
int errors = global.errors;
|
||||||
init = init->semantic(sc, basetype, WANTinterpret);
|
init = init->semantic(sc, basetype, INITinterpret);
|
||||||
if (errors != global.errors)
|
if (errors != global.errors)
|
||||||
{
|
{
|
||||||
init = savedinit;
|
init = savedinit;
|
||||||
@@ -557,6 +569,17 @@ void AliasDeclaration::semantic(Scope *sc)
|
|||||||
s->parent = sc->parent;
|
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)
|
if (overnext)
|
||||||
ScopeDsymbol::multiplyDefined(0, this, overnext);
|
ScopeDsymbol::multiplyDefined(0, this, overnext);
|
||||||
if (s == this)
|
if (s == this)
|
||||||
@@ -619,7 +642,9 @@ const char *AliasDeclaration::kind()
|
|||||||
|
|
||||||
Type *AliasDeclaration::getType()
|
Type *AliasDeclaration::getType()
|
||||||
{
|
{
|
||||||
return type;
|
if (type)
|
||||||
|
return type;
|
||||||
|
return toAlias()->getType();
|
||||||
}
|
}
|
||||||
|
|
||||||
Dsymbol *AliasDeclaration::toAlias()
|
Dsymbol *AliasDeclaration::toAlias()
|
||||||
@@ -632,7 +657,9 @@ Dsymbol *AliasDeclaration::toAlias()
|
|||||||
aliassym = new AliasDeclaration(loc, ident, Type::terror);
|
aliassym = new AliasDeclaration(loc, ident, Type::terror);
|
||||||
type = Type::terror;
|
type = Type::terror;
|
||||||
}
|
}
|
||||||
else if (!aliassym && scope)
|
else if (aliassym || type->deco)
|
||||||
|
; // semantic is already done.
|
||||||
|
else if (scope)
|
||||||
semantic(scope);
|
semantic(scope);
|
||||||
Dsymbol *s = aliassym ? aliassym->toAlias() : this;
|
Dsymbol *s = aliassym ? aliassym->toAlias() : this;
|
||||||
return s;
|
return s;
|
||||||
@@ -845,6 +872,14 @@ void VarDeclaration::semantic(Scope *sc)
|
|||||||
this->parent = sc->parent;
|
this->parent = sc->parent;
|
||||||
//printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
|
//printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
|
||||||
protection = sc->protection;
|
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("sc->stc = %x\n", sc->stc);
|
||||||
//printf("storage_class = x%x\n", storage_class);
|
//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++)
|
for (size_t pos = 0; pos < iexps->dim; pos++)
|
||||||
{
|
{
|
||||||
Lexpand1:
|
Lexpand1:
|
||||||
Expression *e = iexps->tdata()[pos];
|
Expression *e = (*iexps)[pos];
|
||||||
Parameter *arg = Parameter::getNth(tt->arguments, pos);
|
Parameter *arg = Parameter::getNth(tt->arguments, pos);
|
||||||
arg->type = arg->type->semantic(loc, sc);
|
arg->type = arg->type->semantic(loc, sc);
|
||||||
//printf("[%d] iexps->dim = %d, ", pos, iexps->dim);
|
//printf("[%d] iexps->dim = %d, ", pos, iexps->dim);
|
||||||
@@ -1028,7 +1063,7 @@ Lnomatch:
|
|||||||
|
|
||||||
Expression *einit = ie;
|
Expression *einit = ie;
|
||||||
if (ie && ie->op == TOKtuple)
|
if (ie && ie->op == TOKtuple)
|
||||||
{ einit = ((TupleExp *)ie)->exps->tdata()[i];
|
{ einit = (*((TupleExp *)ie)->exps)[i];
|
||||||
}
|
}
|
||||||
Initializer *ti = init;
|
Initializer *ti = init;
|
||||||
if (einit)
|
if (einit)
|
||||||
@@ -1051,7 +1086,7 @@ Lnomatch:
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
Expression *e = new DsymbolExp(loc, v);
|
Expression *e = new DsymbolExp(loc, v);
|
||||||
exps->tdata()[i] = e;
|
(*exps)[i] = e;
|
||||||
}
|
}
|
||||||
TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
|
TupleDeclaration *v2 = new TupleDeclaration(loc, ident, exps);
|
||||||
v2->isexp = 1;
|
v2->isexp = 1;
|
||||||
@@ -1091,7 +1126,7 @@ Lnomatch:
|
|||||||
}
|
}
|
||||||
else if (storage_class & STCfinal)
|
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))
|
if (storage_class & (STCstatic | STCextern | STCmanifest | STCtemplateparameter | STCtls | STCgshared | STCctfe))
|
||||||
@@ -1114,7 +1149,6 @@ Lnomatch:
|
|||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
storage_class |= STCfield;
|
storage_class |= STCfield;
|
||||||
alignment = sc->structalign;
|
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
if (tb->ty == Tstruct && ((TypeStruct *)tb)->sym->noDefaultCtor ||
|
if (tb->ty == Tstruct && ((TypeStruct *)tb)->sym->noDefaultCtor ||
|
||||||
tb->ty == Tclass && ((TypeClass *)tb)->sym->noDefaultCtor)
|
tb->ty == Tclass && ((TypeClass *)tb)->sym->noDefaultCtor)
|
||||||
@@ -1244,6 +1278,19 @@ Lnomatch:
|
|||||||
init = new ExpInitializer(loc, e);
|
init = new ExpInitializer(loc, e);
|
||||||
goto Ldtor;
|
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)
|
else if (type->ty == Ttypedef)
|
||||||
{ TypeTypedef *td = (TypeTypedef *)type;
|
{ TypeTypedef *td = (TypeTypedef *)type;
|
||||||
if (td->sym->init)
|
if (td->sym->init)
|
||||||
@@ -1313,7 +1360,8 @@ Lnomatch:
|
|||||||
Expression *e = init->toExpression();
|
Expression *e = init->toExpression();
|
||||||
if (!e)
|
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();
|
e = init->toExpression();
|
||||||
if (!e)
|
if (!e)
|
||||||
{ error("is not a static and cannot have static initializer");
|
{ 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));
|
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
|
else
|
||||||
{ e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc));
|
{ e = new AssignExp(loc, new VarExp(loc, this), t->defaultInit(loc));
|
||||||
e->op = TOKblit;
|
e->op = TOKblit;
|
||||||
}
|
}
|
||||||
e->type = t;
|
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);
|
(*pinit) = (*pinit)->semantic(sc);
|
||||||
goto Ldtor;
|
goto Ldtor;
|
||||||
}
|
}
|
||||||
@@ -1466,7 +1524,7 @@ Lnomatch:
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
init = init->semantic(sc, type, WANTinterpret);
|
init = init->semantic(sc, type, INITinterpret);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (storage_class & (STCconst | STCimmutable | STCmanifest) ||
|
else if (storage_class & (STCconst | STCimmutable | STCmanifest) ||
|
||||||
@@ -1537,7 +1595,7 @@ Lnomatch:
|
|||||||
}
|
}
|
||||||
else if (si || ai)
|
else if (si || ai)
|
||||||
{ i2 = init->syntaxCopy();
|
{ i2 = init->syntaxCopy();
|
||||||
i2 = i2->semantic(sc, type, WANTinterpret);
|
i2 = i2->semantic(sc, type, INITinterpret);
|
||||||
}
|
}
|
||||||
inuse--;
|
inuse--;
|
||||||
if (global.endGagging(errors)) // if errors happened
|
if (global.endGagging(errors)) // if errors happened
|
||||||
@@ -1552,7 +1610,7 @@ Lnomatch:
|
|||||||
else if (ei)
|
else if (ei)
|
||||||
{
|
{
|
||||||
if (isDataseg() || (storage_class & STCmanifest))
|
if (isDataseg() || (storage_class & STCmanifest))
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
else
|
else
|
||||||
e = e->optimize(WANTvalue);
|
e = e->optimize(WANTvalue);
|
||||||
switch (e->op)
|
switch (e->op)
|
||||||
@@ -1639,7 +1697,7 @@ void VarDeclaration::semantic2(Scope *sc)
|
|||||||
printf("type = %p\n", ei->exp->type);
|
printf("type = %p\n", ei->exp->type);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
init = init->semantic(sc, type, WANTinterpret);
|
init = init->semantic(sc, type, INITinterpret);
|
||||||
inuse--;
|
inuse--;
|
||||||
}
|
}
|
||||||
sem = Semantic2Done;
|
sem = Semantic2Done;
|
||||||
@@ -1710,9 +1768,8 @@ void VarDeclaration::setFieldOffset(AggregateDeclaration *ad, unsigned *poffset,
|
|||||||
|
|
||||||
unsigned memsize = t->size(loc); // size of member
|
unsigned memsize = t->size(loc); // size of member
|
||||||
unsigned memalignsize = t->alignsize(); // size of member for alignment purposes
|
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);
|
&ad->structsize, &ad->alignsize, isunion);
|
||||||
|
|
||||||
//printf("\t%s: alignsize = %d\n", toChars(), alignsize);
|
//printf("\t%s: alignsize = %d\n", toChars(), alignsize);
|
||||||
@@ -1831,28 +1888,8 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
|
|||||||
// The current function
|
// The current function
|
||||||
FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
|
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
|
// Add fdthis to nestedrefs[] if not already there
|
||||||
for (size_t i = 0; 1; i++)
|
for (size_t i = 0; 1; i++)
|
||||||
{
|
{
|
||||||
@@ -1865,23 +1902,46 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add this to fdv->closureVars[] if not already there
|
if (fdthis->ident != Id::ensure)
|
||||||
for (size_t i = 0; 1; i++)
|
|
||||||
{
|
{
|
||||||
if (i == fdv->closureVars.dim)
|
/* __ensure is always called directly,
|
||||||
{
|
* so it never becomes closure.
|
||||||
fdv->closureVars.push(this);
|
*/
|
||||||
break;
|
|
||||||
}
|
|
||||||
if (fdv->closureVars[i] == this)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
//printf("fdthis is %s\n", fdthis->toChars());
|
//printf("\tfdv = %s\n", fdv->toChars());
|
||||||
//printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
|
//printf("\tfdthis = %s\n", fdthis->toChars());
|
||||||
// __dollar creates problems because it isn't a real variable Bugzilla 3326
|
|
||||||
if (ident == Id::dollar)
|
if (loc.filename)
|
||||||
::error(loc, "cannnot use $ inside a function literal");
|
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)
|
TypeInfoVectorDeclaration::TypeInfoVectorDeclaration(Type *tinfo)
|
||||||
: TypeInfoDeclaration(tinfo, 0)
|
: TypeInfoDeclaration(tinfo, 0)
|
||||||
{
|
{
|
||||||
if (!Type::typeinfoarray)
|
if (!Type::typeinfovector)
|
||||||
{
|
{
|
||||||
ObjectNotFound(Id::TypeInfo_Vector);
|
ObjectNotFound(Id::TypeInfo_Vector);
|
||||||
}
|
}
|
||||||
|
|||||||
+16
-4
@@ -101,6 +101,12 @@ enum PURE;
|
|||||||
#define STCdisable 0x2000000000LL // for functions that are not callable
|
#define STCdisable 0x2000000000LL // for functions that are not callable
|
||||||
#define STCresult 0x4000000000LL // for result variables passed to out contracts
|
#define STCresult 0x4000000000LL // for result variables passed to out contracts
|
||||||
#define STCnodefaultctor 0x8000000000LL // must be set inside constructor
|
#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
|
struct Match
|
||||||
{
|
{
|
||||||
@@ -136,7 +142,7 @@ struct Declaration : Dsymbol
|
|||||||
enum LINK linkage;
|
enum LINK linkage;
|
||||||
int inuse; // used to detect cycles
|
int inuse; // used to detect cycles
|
||||||
|
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
Expressions *attributes; // GCC decl/type attributes
|
Expressions *attributes; // GCC decl/type attributes
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -148,6 +154,8 @@ struct Declaration : Dsymbol
|
|||||||
unsigned size(Loc loc);
|
unsigned size(Loc loc);
|
||||||
void checkModify(Loc loc, Scope *sc, Type *t);
|
void checkModify(Loc loc, Scope *sc, Type *t);
|
||||||
|
|
||||||
|
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||||
|
|
||||||
void emitComment(Scope *sc);
|
void emitComment(Scope *sc);
|
||||||
void toJsonBuffer(OutBuffer *buf);
|
void toJsonBuffer(OutBuffer *buf);
|
||||||
void toDocBuffer(OutBuffer *buf);
|
void toDocBuffer(OutBuffer *buf);
|
||||||
@@ -288,7 +296,7 @@ struct VarDeclaration : Declaration
|
|||||||
#else
|
#else
|
||||||
int nestedref; // referenced by a lexically nested function
|
int nestedref; // referenced by a lexically nested function
|
||||||
#endif
|
#endif
|
||||||
unsigned short alignment;
|
structalign_t alignment;
|
||||||
int ctorinit; // it has been initialized in a ctor
|
int ctorinit; // it has been initialized in a ctor
|
||||||
int onstack; // 1: it has been allocated on the stack
|
int onstack; // 1: it has been allocated on the stack
|
||||||
// 2: on stack, run destructor anyway
|
// 2: on stack, run destructor anyway
|
||||||
@@ -710,7 +718,7 @@ enum BUILTIN
|
|||||||
BUILTINbsr, // core.bitop.bsr
|
BUILTINbsr, // core.bitop.bsr
|
||||||
BUILTINbsf, // core.bitop.bsf
|
BUILTINbsf, // core.bitop.bsf
|
||||||
BUILTINbswap, // core.bitop.bswap
|
BUILTINbswap, // core.bitop.bswap
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
BUILTINgcc, // GCC builtin
|
BUILTINgcc, // GCC builtin
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
@@ -738,12 +746,14 @@ struct FuncDeclaration : Declaration
|
|||||||
Identifier *outId; // identifier for out statement
|
Identifier *outId; // identifier for out statement
|
||||||
VarDeclaration *vresult; // variable corresponding to outId
|
VarDeclaration *vresult; // variable corresponding to outId
|
||||||
LabelDsymbol *returnLabel; // where the return goes
|
LabelDsymbol *returnLabel; // where the return goes
|
||||||
|
Scope *scout; // out contract scope for vresult->semantic
|
||||||
|
|
||||||
DsymbolTable *localsymtab; // used to prevent symbols in different
|
DsymbolTable *localsymtab; // used to prevent symbols in different
|
||||||
// scopes from having the same name
|
// scopes from having the same name
|
||||||
VarDeclaration *vthis; // 'this' parameter (member and nested)
|
VarDeclaration *vthis; // 'this' parameter (member and nested)
|
||||||
VarDeclaration *v_arguments; // '_arguments' parameter
|
VarDeclaration *v_arguments; // '_arguments' parameter
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
|
VarDeclaration *v_arguments_var; // '_arguments' variable
|
||||||
VarDeclaration *v_argptr; // '_argptr' variable
|
VarDeclaration *v_argptr; // '_argptr' variable
|
||||||
#endif
|
#endif
|
||||||
VarDeclaration *v_argsave; // save area for args passed in registers for variadic functions
|
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);
|
void checkNestedReference(Scope *sc, Loc loc);
|
||||||
int needsClosure();
|
int needsClosure();
|
||||||
int hasNestedFrameRefs();
|
int hasNestedFrameRefs();
|
||||||
|
void buildResultVar();
|
||||||
Statement *mergeFrequire(Statement *, Expressions *params = 0);
|
Statement *mergeFrequire(Statement *, Expressions *params = 0);
|
||||||
Statement *mergeFensure(Statement *, Expressions *params = 0);
|
Statement *mergeFensure(Statement *, Expressions *params = 0);
|
||||||
Parameters *getParameters(int *pvarargs);
|
Parameters *getParameters(int *pvarargs);
|
||||||
@@ -941,6 +952,7 @@ struct FuncAliasDeclaration : FuncDeclaration
|
|||||||
struct FuncLiteralDeclaration : FuncDeclaration
|
struct FuncLiteralDeclaration : FuncDeclaration
|
||||||
{
|
{
|
||||||
enum TOK tok; // TOKfunction or TOKdelegate
|
enum TOK tok; // TOKfunction or TOKdelegate
|
||||||
|
Type *treq; // target of return type inference
|
||||||
|
|
||||||
FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, enum TOK tok,
|
FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type, enum TOK tok,
|
||||||
ForeachStatement *fes);
|
ForeachStatement *fes);
|
||||||
|
|||||||
@@ -20,6 +20,10 @@
|
|||||||
#include "aggregate.h"
|
#include "aggregate.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
|
|
||||||
|
#if IN_LLVM
|
||||||
|
#include "init.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
/********************************************
|
/********************************************
|
||||||
* Convert from expression to delegate that returns the expression,
|
* Convert from expression to delegate that returns the expression,
|
||||||
* i.e. convert:
|
* i.e. convert:
|
||||||
@@ -110,6 +114,36 @@ int lambdaCheckForNestedRef(Expression *e, void *param)
|
|||||||
*/
|
*/
|
||||||
switch (e->op)
|
switch (e->op)
|
||||||
{
|
{
|
||||||
|
#if IN_LLVM
|
||||||
|
// We also need to consider the initializers of VarDeclarations in
|
||||||
|
// DeclarationExps, such as generated for postblit invocation for
|
||||||
|
// function parameters.
|
||||||
|
//
|
||||||
|
// Without this check, e.g. the nested reference to a in the delegate
|
||||||
|
// create for the lazy argument is not picked up in the following case:
|
||||||
|
// ---
|
||||||
|
// struct HasPostblit { this(this) {} }
|
||||||
|
// struct Foo { HasPostblit _data; }
|
||||||
|
// void receiver(Foo) {}
|
||||||
|
// void lazyFunc(E)(lazy E e) { e(); }
|
||||||
|
// void test() { Foo a; lazyFunc(receiver(a)); }
|
||||||
|
// ---
|
||||||
|
case TOKdeclaration:
|
||||||
|
{ DeclarationExp *de = (DeclarationExp *)e;
|
||||||
|
if (VarDeclaration *vd = de->declaration->isVarDeclaration())
|
||||||
|
{
|
||||||
|
if (vd->init)
|
||||||
|
{
|
||||||
|
if (ExpInitializer* ei = vd->init->isExpInitializer())
|
||||||
|
{
|
||||||
|
ei->exp->apply(&lambdaCheckForNestedRef, sc);
|
||||||
|
}
|
||||||
|
// TODO: Other classes of initializers?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
case TOKsymoff:
|
case TOKsymoff:
|
||||||
{ SymOffExp *se = (SymOffExp *)e;
|
{ SymOffExp *se = (SymOffExp *)e;
|
||||||
VarDeclaration *v = se->var->isVarDeclaration();
|
VarDeclaration *v = se->var->isVarDeclaration();
|
||||||
|
|||||||
+87
-25
@@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="Windows-1252"?>
|
<?xml version="1.0" encoding="Windows-1252"?>
|
||||||
<VisualStudioProject
|
<VisualStudioProject
|
||||||
ProjectType="Visual C++"
|
ProjectType="Visual C++"
|
||||||
Version="9,00"
|
Version="9.00"
|
||||||
Name="dmd_msc"
|
Name="dmd_msc"
|
||||||
ProjectGUID="{BAE0389D-7D3F-4D5E-AE0E-C871776E8432}"
|
ProjectGUID="{BAE0389D-7D3F-4D5E-AE0E-C871776E8432}"
|
||||||
RootNamespace="dmd"
|
RootNamespace="dmd"
|
||||||
@@ -768,6 +768,38 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\unialpha.c"
|
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>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\unittests.c"
|
RelativePath=".\unittests.c"
|
||||||
@@ -1301,16 +1333,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\root\dchar.c"
|
RelativePath=".\root\dmgcmem.c" >
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\root\dchar.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\root\dmgcmem.c"
|
|
||||||
>
|
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Debug|Win32"
|
Name="Debug|Win32"
|
||||||
ExcludedFromBuild="true"
|
ExcludedFromBuild="true"
|
||||||
@@ -1361,16 +1384,7 @@
|
|||||||
>
|
>
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\root\lstring.c"
|
RelativePath=".\root\man.c" >
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\root\lstring.h"
|
|
||||||
>
|
|
||||||
</File>
|
|
||||||
<File
|
|
||||||
RelativePath=".\root\man.c"
|
|
||||||
>
|
|
||||||
</File>
|
</File>
|
||||||
<File
|
<File
|
||||||
RelativePath=".\root\port.c"
|
RelativePath=".\root\port.c"
|
||||||
@@ -1422,6 +1436,14 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\root\gc\bits.c"
|
RelativePath=".\root\gc\bits.c"
|
||||||
>
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
ExcludedFromBuild="true"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Debug|x64"
|
Name="Debug|x64"
|
||||||
ExcludedFromBuild="true"
|
ExcludedFromBuild="true"
|
||||||
@@ -1430,6 +1452,14 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
ExcludedFromBuild="true"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Release|x64"
|
Name="Release|x64"
|
||||||
ExcludedFromBuild="true"
|
ExcludedFromBuild="true"
|
||||||
@@ -1446,6 +1476,14 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\root\gc\gc.c"
|
RelativePath=".\root\gc\gc.c"
|
||||||
>
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
ExcludedFromBuild="true"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Debug|x64"
|
Name="Debug|x64"
|
||||||
ExcludedFromBuild="true"
|
ExcludedFromBuild="true"
|
||||||
@@ -1454,6 +1492,14 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
ExcludedFromBuild="true"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Release|x64"
|
Name="Release|x64"
|
||||||
ExcludedFromBuild="true"
|
ExcludedFromBuild="true"
|
||||||
@@ -1518,6 +1564,14 @@
|
|||||||
<File
|
<File
|
||||||
RelativePath=".\root\gc\win32.c"
|
RelativePath=".\root\gc\win32.c"
|
||||||
>
|
>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Debug|Win32"
|
||||||
|
ExcludedFromBuild="true"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Debug|x64"
|
Name="Debug|x64"
|
||||||
ExcludedFromBuild="true"
|
ExcludedFromBuild="true"
|
||||||
@@ -1526,6 +1580,14 @@
|
|||||||
Name="VCCLCompilerTool"
|
Name="VCCLCompilerTool"
|
||||||
/>
|
/>
|
||||||
</FileConfiguration>
|
</FileConfiguration>
|
||||||
|
<FileConfiguration
|
||||||
|
Name="Release|Win32"
|
||||||
|
ExcludedFromBuild="true"
|
||||||
|
>
|
||||||
|
<Tool
|
||||||
|
Name="VCCLCompilerTool"
|
||||||
|
/>
|
||||||
|
</FileConfiguration>
|
||||||
<FileConfiguration
|
<FileConfiguration
|
||||||
Name="Release|x64"
|
Name="Release|x64"
|
||||||
ExcludedFromBuild="true"
|
ExcludedFromBuild="true"
|
||||||
@@ -1645,7 +1707,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"
|
Name="VCCustomBuildTool"
|
||||||
Description="Building and running $(IntDir)\$(InputName).exe"
|
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)
if errorlevel 1 goto VCReportError
$(IntDir)\$(InputName).exe
"
|
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo"$(IntDir)\$(InputName).obj" /Fe"$(IntDir)\$(InputName).exe" "$(InputPath)"
if errorlevel 1 goto VCReportError
"$(IntDir)\$(InputName).exe"
"
|
||||||
AdditionalDependencies="cc.h;oper.h"
|
AdditionalDependencies="cc.h;oper.h"
|
||||||
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
|
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
|
||||||
/>
|
/>
|
||||||
@@ -1656,7 +1718,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"
|
Name="VCCustomBuildTool"
|
||||||
Description="Building and running $(IntDir)\$(InputName).exe"
|
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)
if errorlevel 1 goto VCReportError
$(IntDir)\$(InputName).exe
"
|
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo"$(IntDir)\$(InputName).obj" /Fe"$(IntDir)\$(InputName).exe" "$(InputPath)"
if errorlevel 1 goto VCReportError
"$(IntDir)\$(InputName).exe"
"
|
||||||
AdditionalDependencies="cc.h;oper.h"
|
AdditionalDependencies="cc.h;oper.h"
|
||||||
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
|
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
|
||||||
/>
|
/>
|
||||||
@@ -1667,7 +1729,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"
|
Name="VCCustomBuildTool"
|
||||||
Description="Building and running $(IntDir)\$(InputName).exe"
|
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)
if errorlevel 1 goto VCReportError
$(IntDir)\$(InputName).exe
"
|
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo"$(IntDir)\$(InputName).obj" /Fe"$(IntDir)\$(InputName).exe" "$(InputPath)"
if errorlevel 1 goto VCReportError
"$(IntDir)\$(InputName).exe""
|
||||||
AdditionalDependencies="cc.h;oper.h"
|
AdditionalDependencies="cc.h;oper.h"
|
||||||
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
|
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
|
||||||
/>
|
/>
|
||||||
@@ -1678,7 +1740,7 @@
|
|||||||
<Tool
|
<Tool
|
||||||
Name="VCCustomBuildTool"
|
Name="VCCustomBuildTool"
|
||||||
Description="Building and running $(IntDir)\$(InputName).exe"
|
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)
if errorlevel 1 goto VCReportError
$(IntDir)\$(InputName).exe
"
|
CommandLine="cl /TP /Itk /Iroot /Ivcbuild /I. /FIwarnings.h /Fo"$(IntDir)\$(InputName).obj" /Fe"$(IntDir)\$(InputName).exe" "$(InputPath)"
if errorlevel 1 goto VCReportError
"$(IntDir)\$(InputName).exe"
"
|
||||||
AdditionalDependencies="cc.h;oper.h"
|
AdditionalDependencies="cc.h;oper.h"
|
||||||
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
|
Outputs="optab.c;debtab.c;cdxxx.c;elxxx.c;tytab.c;fltables.c"
|
||||||
/>
|
/>
|
||||||
|
|||||||
+2230
-2229
File diff suppressed because it is too large
Load Diff
+1501
-1528
File diff suppressed because it is too large
Load Diff
+395
-396
@@ -1,396 +1,395 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2012 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
// License for redistribution is by either the Artistic License
|
// License for redistribution is by either the Artistic License
|
||||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||||
// See the included readme.txt for details.
|
// See the included readme.txt for details.
|
||||||
|
|
||||||
#ifndef DMD_DSYMBOL_H
|
#ifndef DMD_DSYMBOL_H
|
||||||
#define DMD_DSYMBOL_H
|
#define DMD_DSYMBOL_H
|
||||||
|
|
||||||
#ifdef __DMC__
|
#ifdef __DMC__
|
||||||
#pragma once
|
#pragma once
|
||||||
#endif /* __DMC__ */
|
#endif /* __DMC__ */
|
||||||
|
|
||||||
#include "root.h"
|
#include "root.h"
|
||||||
#include "stringtable.h"
|
#include "stringtable.h"
|
||||||
|
|
||||||
#include "mars.h"
|
#include "mars.h"
|
||||||
#include "arraytypes.h"
|
#include "arraytypes.h"
|
||||||
|
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#undef min
|
#undef min
|
||||||
#undef max
|
#undef max
|
||||||
#endif
|
#endif
|
||||||
#include "../ir/irdsymbol.h"
|
#include "../ir/irdsymbol.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct Identifier;
|
struct Identifier;
|
||||||
struct Scope;
|
struct Scope;
|
||||||
struct DsymbolTable;
|
struct DsymbolTable;
|
||||||
struct Declaration;
|
struct Declaration;
|
||||||
struct ThisDeclaration;
|
struct ThisDeclaration;
|
||||||
struct TupleDeclaration;
|
struct TupleDeclaration;
|
||||||
struct TypedefDeclaration;
|
struct TypedefDeclaration;
|
||||||
struct AliasDeclaration;
|
struct AliasDeclaration;
|
||||||
struct AggregateDeclaration;
|
struct AggregateDeclaration;
|
||||||
struct EnumDeclaration;
|
struct EnumDeclaration;
|
||||||
struct ClassDeclaration;
|
struct ClassDeclaration;
|
||||||
struct InterfaceDeclaration;
|
struct InterfaceDeclaration;
|
||||||
struct StructDeclaration;
|
struct StructDeclaration;
|
||||||
struct UnionDeclaration;
|
struct UnionDeclaration;
|
||||||
struct FuncDeclaration;
|
struct FuncDeclaration;
|
||||||
struct FuncAliasDeclaration;
|
struct FuncAliasDeclaration;
|
||||||
struct FuncLiteralDeclaration;
|
struct FuncLiteralDeclaration;
|
||||||
struct CtorDeclaration;
|
struct CtorDeclaration;
|
||||||
struct PostBlitDeclaration;
|
struct PostBlitDeclaration;
|
||||||
struct DtorDeclaration;
|
struct DtorDeclaration;
|
||||||
struct StaticCtorDeclaration;
|
struct StaticCtorDeclaration;
|
||||||
struct StaticDtorDeclaration;
|
struct StaticDtorDeclaration;
|
||||||
struct SharedStaticCtorDeclaration;
|
struct SharedStaticCtorDeclaration;
|
||||||
struct SharedStaticDtorDeclaration;
|
struct SharedStaticDtorDeclaration;
|
||||||
struct InvariantDeclaration;
|
struct InvariantDeclaration;
|
||||||
struct UnitTestDeclaration;
|
struct UnitTestDeclaration;
|
||||||
struct NewDeclaration;
|
struct NewDeclaration;
|
||||||
struct VarDeclaration;
|
struct VarDeclaration;
|
||||||
struct AttribDeclaration;
|
struct AttribDeclaration;
|
||||||
#if IN_DMD
|
#if IN_DMD
|
||||||
struct Symbol;
|
struct Symbol;
|
||||||
#endif
|
#endif
|
||||||
struct Package;
|
struct Package;
|
||||||
struct Module;
|
struct Module;
|
||||||
struct Import;
|
struct Import;
|
||||||
struct Type;
|
struct Type;
|
||||||
struct TypeTuple;
|
struct TypeTuple;
|
||||||
struct WithStatement;
|
struct WithStatement;
|
||||||
struct LabelDsymbol;
|
struct LabelDsymbol;
|
||||||
struct ScopeDsymbol;
|
struct ScopeDsymbol;
|
||||||
struct TemplateDeclaration;
|
struct TemplateDeclaration;
|
||||||
struct TemplateInstance;
|
struct TemplateInstance;
|
||||||
struct TemplateMixin;
|
struct TemplateMixin;
|
||||||
struct EnumMember;
|
struct EnumMember;
|
||||||
struct ScopeDsymbol;
|
struct ScopeDsymbol;
|
||||||
struct WithScopeSymbol;
|
struct WithScopeSymbol;
|
||||||
struct ArrayScopeSymbol;
|
struct ArrayScopeSymbol;
|
||||||
struct StaticStructInitDeclaration;
|
struct StaticStructInitDeclaration;
|
||||||
struct Expression;
|
struct Expression;
|
||||||
struct DeleteDeclaration;
|
struct DeleteDeclaration;
|
||||||
struct HdrGenState;
|
struct HdrGenState;
|
||||||
struct OverloadSet;
|
struct OverloadSet;
|
||||||
struct AA;
|
struct AA;
|
||||||
#if TARGET_NET
|
#if TARGET_NET
|
||||||
struct PragmaScope;
|
struct PragmaScope;
|
||||||
#endif
|
#endif
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
struct TypeInfoDeclaration;
|
struct TypeInfoDeclaration;
|
||||||
struct ClassInfoDeclaration;
|
struct ClassInfoDeclaration;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
union tree_node;
|
union tree_node;
|
||||||
typedef union tree_node TYPE;
|
typedef union tree_node TYPE;
|
||||||
#else
|
#else
|
||||||
struct TYPE;
|
struct TYPE;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
class Ir;
|
class Ir;
|
||||||
class IrSymbol;
|
class IrSymbol;
|
||||||
namespace llvm
|
namespace llvm
|
||||||
{
|
{
|
||||||
class Value;
|
class Value;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
#if IN_DMD
|
#if IN_DMD
|
||||||
// Back end
|
// Back end
|
||||||
struct Classsym;
|
struct Classsym;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
enum PROT
|
enum PROT
|
||||||
{
|
{
|
||||||
PROTundefined,
|
PROTundefined,
|
||||||
PROTnone, // no access
|
PROTnone, // no access
|
||||||
PROTprivate,
|
PROTprivate,
|
||||||
PROTpackage,
|
PROTpackage,
|
||||||
PROTprotected,
|
PROTprotected,
|
||||||
PROTpublic,
|
PROTpublic,
|
||||||
PROTexport,
|
PROTexport,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* State of symbol in winding its way through the passes of the compiler
|
/* State of symbol in winding its way through the passes of the compiler
|
||||||
*/
|
*/
|
||||||
enum PASS
|
enum PASS
|
||||||
{
|
{
|
||||||
PASSinit, // initial state
|
PASSinit, // initial state
|
||||||
PASSsemantic, // semantic() started
|
PASSsemantic, // semantic() started
|
||||||
PASSsemanticdone, // semantic() done
|
PASSsemanticdone, // semantic() done
|
||||||
PASSsemantic2, // semantic2() run
|
PASSsemantic2, // semantic2() run
|
||||||
PASSsemantic3, // semantic3() started
|
PASSsemantic3, // semantic3() started
|
||||||
PASSsemantic3done, // semantic3() done
|
PASSsemantic3done, // semantic3() done
|
||||||
PASSobj, // toObjFile() run
|
PASSobj, // toObjFile() run
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef int (*Dsymbol_apply_ft_t)(Dsymbol *, void *);
|
typedef int (*Dsymbol_apply_ft_t)(Dsymbol *, void *);
|
||||||
|
|
||||||
struct Dsymbol : Object
|
struct Dsymbol : Object
|
||||||
{
|
{
|
||||||
Identifier *ident;
|
Identifier *ident;
|
||||||
Identifier *c_ident;
|
Identifier *c_ident;
|
||||||
Dsymbol *parent;
|
Dsymbol *parent;
|
||||||
#if IN_DMD
|
#if IN_DMD
|
||||||
Symbol *csym; // symbol for code generator
|
Symbol *csym; // symbol for code generator
|
||||||
Symbol *isym; // import version of csym
|
Symbol *isym; // import version of csym
|
||||||
#endif
|
#endif
|
||||||
unsigned char *comment; // documentation comment for this Dsymbol
|
unsigned char *comment; // documentation comment for this Dsymbol
|
||||||
Loc loc; // where defined
|
Loc loc; // where defined
|
||||||
Scope *scope; // !=NULL means context to use for semantic()
|
Scope *scope; // !=NULL means context to use for semantic()
|
||||||
bool errors; // this symbol failed to pass semantic()
|
bool errors; // this symbol failed to pass semantic()
|
||||||
|
|
||||||
Dsymbol();
|
Dsymbol();
|
||||||
Dsymbol(Identifier *);
|
Dsymbol(Identifier *);
|
||||||
char *toChars();
|
char *toChars();
|
||||||
char *locToChars();
|
char *locToChars();
|
||||||
int equals(Object *o);
|
int equals(Object *o);
|
||||||
int isAnonymous();
|
int isAnonymous();
|
||||||
void error(Loc loc, const char *format, ...) IS_PRINTF(3);
|
void error(Loc loc, const char *format, ...) IS_PRINTF(3);
|
||||||
void error(const char *format, ...) IS_PRINTF(2);
|
void error(const char *format, ...) IS_PRINTF(2);
|
||||||
void verror(Loc loc, const char *format, va_list ap);
|
void checkDeprecated(Loc loc, Scope *sc);
|
||||||
void checkDeprecated(Loc loc, Scope *sc);
|
Module *getModule(); // module where declared
|
||||||
Module *getModule(); // module where declared
|
Module *getAccessModule();
|
||||||
Module *getAccessModule();
|
Dsymbol *pastMixin();
|
||||||
Dsymbol *pastMixin();
|
Dsymbol *toParent();
|
||||||
Dsymbol *toParent();
|
Dsymbol *toParent2();
|
||||||
Dsymbol *toParent2();
|
TemplateInstance *inTemplateInstance();
|
||||||
TemplateInstance *inTemplateInstance();
|
TemplateInstance *isSpeculative();
|
||||||
TemplateInstance *isSpeculative();
|
|
||||||
|
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
|
||||||
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
|
|
||||||
|
static Dsymbols *arraySyntaxCopy(Dsymbols *a);
|
||||||
static Dsymbols *arraySyntaxCopy(Dsymbols *a);
|
|
||||||
|
virtual const char *toPrettyChars();
|
||||||
virtual const char *toPrettyChars();
|
virtual const char *kind();
|
||||||
virtual const char *kind();
|
virtual Dsymbol *toAlias(); // resolve real symbol
|
||||||
virtual Dsymbol *toAlias(); // resolve real symbol
|
virtual int apply(Dsymbol_apply_ft_t fp, void *param);
|
||||||
virtual int apply(Dsymbol_apply_ft_t fp, void *param);
|
virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||||
virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
virtual void setScope(Scope *sc);
|
||||||
virtual void setScope(Scope *sc);
|
virtual void importAll(Scope *sc);
|
||||||
virtual void importAll(Scope *sc);
|
virtual void semantic0(Scope *sc);
|
||||||
virtual void semantic0(Scope *sc);
|
virtual void semantic(Scope *sc);
|
||||||
virtual void semantic(Scope *sc);
|
virtual void semantic2(Scope *sc);
|
||||||
virtual void semantic2(Scope *sc);
|
virtual void semantic3(Scope *sc);
|
||||||
virtual void semantic3(Scope *sc);
|
virtual void inlineScan();
|
||||||
virtual void inlineScan();
|
virtual Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||||
virtual Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
Dsymbol *search_correct(Identifier *id);
|
||||||
Dsymbol *search_correct(Identifier *id);
|
Dsymbol *searchX(Loc loc, Scope *sc, Identifier *id);
|
||||||
Dsymbol *searchX(Loc loc, Scope *sc, Identifier *id);
|
virtual int overloadInsert(Dsymbol *s);
|
||||||
virtual int overloadInsert(Dsymbol *s);
|
char *toHChars();
|
||||||
char *toHChars();
|
virtual void toHBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||||
virtual void toHBuffer(OutBuffer *buf, HdrGenState *hgs);
|
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||||
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
virtual void toDocBuffer(OutBuffer *buf);
|
||||||
virtual void toDocBuffer(OutBuffer *buf);
|
virtual void toJsonBuffer(OutBuffer *buf);
|
||||||
virtual void toJsonBuffer(OutBuffer *buf);
|
virtual unsigned size(Loc loc);
|
||||||
virtual unsigned size(Loc loc);
|
virtual int isforwardRef();
|
||||||
virtual int isforwardRef();
|
virtual void defineRef(Dsymbol *s);
|
||||||
virtual void defineRef(Dsymbol *s);
|
virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member
|
||||||
virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member
|
AggregateDeclaration *isAggregateMember(); // are we a member of an aggregate?
|
||||||
AggregateDeclaration *isAggregateMember(); // are we a member of an aggregate?
|
ClassDeclaration *isClassMember(); // are we a member of a class?
|
||||||
ClassDeclaration *isClassMember(); // are we a member of a class?
|
virtual int isExport(); // is Dsymbol exported?
|
||||||
virtual int isExport(); // is Dsymbol exported?
|
virtual int isImportedSymbol(); // is Dsymbol imported?
|
||||||
virtual int isImportedSymbol(); // is Dsymbol imported?
|
virtual int isDeprecated(); // is Dsymbol deprecated?
|
||||||
virtual int isDeprecated(); // is Dsymbol deprecated?
|
#if DMDV2
|
||||||
#if DMDV2
|
virtual int isOverloadable();
|
||||||
virtual int isOverloadable();
|
virtual int hasOverloads();
|
||||||
virtual int hasOverloads();
|
#endif
|
||||||
#endif
|
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
|
||||||
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
|
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
|
||||||
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
|
virtual Type *getType(); // is this a type?
|
||||||
virtual Type *getType(); // is this a type?
|
virtual char *mangle();
|
||||||
virtual char *mangle();
|
virtual int needThis(); // need a 'this' pointer?
|
||||||
virtual int needThis(); // need a 'this' pointer?
|
virtual enum PROT prot();
|
||||||
virtual enum PROT prot();
|
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
|
||||||
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
|
virtual int oneMember(Dsymbol **ps, Identifier *ident);
|
||||||
virtual int oneMember(Dsymbol **ps, Identifier *ident);
|
static int oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident = NULL);
|
||||||
static int oneMembers(Dsymbols *members, Dsymbol **ps, Identifier *ident = NULL);
|
virtual void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
|
||||||
virtual void setFieldOffset(AggregateDeclaration *ad, unsigned *poffset, bool isunion);
|
virtual int hasPointers();
|
||||||
virtual int hasPointers();
|
virtual bool hasStaticCtorOrDtor();
|
||||||
virtual bool hasStaticCtorOrDtor();
|
virtual void addLocalClass(ClassDeclarations *) { }
|
||||||
virtual void addLocalClass(ClassDeclarations *) { }
|
virtual void checkCtorConstInit() { }
|
||||||
virtual void checkCtorConstInit() { }
|
|
||||||
|
virtual void addComment(unsigned char *comment);
|
||||||
virtual void addComment(unsigned char *comment);
|
virtual void emitComment(Scope *sc);
|
||||||
virtual void emitComment(Scope *sc);
|
void emitDitto(Scope *sc);
|
||||||
void emitDitto(Scope *sc);
|
|
||||||
|
#if IN_DMD
|
||||||
#if IN_DMD
|
// Backend
|
||||||
// Backend
|
|
||||||
|
virtual Symbol *toSymbol(); // to backend symbol
|
||||||
virtual Symbol *toSymbol(); // to backend symbol
|
virtual void toObjFile(int multiobj); // compile to .obj file
|
||||||
virtual void toObjFile(int multiobj); // compile to .obj file
|
virtual int cvMember(unsigned char *p); // emit cv debug info for member
|
||||||
virtual int cvMember(unsigned char *p); // emit cv debug info for member
|
|
||||||
|
Symbol *toImport(); // to backend import symbol
|
||||||
Symbol *toImport(); // to backend import symbol
|
static Symbol *toImport(Symbol *s); // to backend import symbol
|
||||||
static Symbol *toImport(Symbol *s); // to backend import symbol
|
|
||||||
|
Symbol *toSymbolX(const char *prefix, int sclass, TYPE *t, const char *suffix); // helper
|
||||||
Symbol *toSymbolX(const char *prefix, int sclass, TYPE *t, const char *suffix); // helper
|
#endif
|
||||||
#endif
|
|
||||||
|
// Eliminate need for dynamic_cast
|
||||||
// Eliminate need for dynamic_cast
|
virtual Package *isPackage() { return NULL; }
|
||||||
virtual Package *isPackage() { return NULL; }
|
virtual Module *isModule() { return NULL; }
|
||||||
virtual Module *isModule() { return NULL; }
|
virtual EnumMember *isEnumMember() { return NULL; }
|
||||||
virtual EnumMember *isEnumMember() { return NULL; }
|
virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; }
|
||||||
virtual TemplateDeclaration *isTemplateDeclaration() { return NULL; }
|
virtual TemplateInstance *isTemplateInstance() { return NULL; }
|
||||||
virtual TemplateInstance *isTemplateInstance() { return NULL; }
|
virtual TemplateMixin *isTemplateMixin() { return NULL; }
|
||||||
virtual TemplateMixin *isTemplateMixin() { return NULL; }
|
virtual Declaration *isDeclaration() { return NULL; }
|
||||||
virtual Declaration *isDeclaration() { return NULL; }
|
virtual ThisDeclaration *isThisDeclaration() { return NULL; }
|
||||||
virtual ThisDeclaration *isThisDeclaration() { return NULL; }
|
virtual TupleDeclaration *isTupleDeclaration() { return NULL; }
|
||||||
virtual TupleDeclaration *isTupleDeclaration() { return NULL; }
|
virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; }
|
||||||
virtual TypedefDeclaration *isTypedefDeclaration() { return NULL; }
|
virtual AliasDeclaration *isAliasDeclaration() { return NULL; }
|
||||||
virtual AliasDeclaration *isAliasDeclaration() { return NULL; }
|
virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; }
|
||||||
virtual AggregateDeclaration *isAggregateDeclaration() { return NULL; }
|
virtual FuncDeclaration *isFuncDeclaration() { return NULL; }
|
||||||
virtual FuncDeclaration *isFuncDeclaration() { return NULL; }
|
virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; }
|
||||||
virtual FuncAliasDeclaration *isFuncAliasDeclaration() { return NULL; }
|
virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; }
|
||||||
virtual FuncLiteralDeclaration *isFuncLiteralDeclaration() { return NULL; }
|
virtual CtorDeclaration *isCtorDeclaration() { return NULL; }
|
||||||
virtual CtorDeclaration *isCtorDeclaration() { return NULL; }
|
virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; }
|
||||||
virtual PostBlitDeclaration *isPostBlitDeclaration() { return NULL; }
|
virtual DtorDeclaration *isDtorDeclaration() { return NULL; }
|
||||||
virtual DtorDeclaration *isDtorDeclaration() { return NULL; }
|
virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; }
|
||||||
virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; }
|
virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; }
|
||||||
virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; }
|
virtual SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return NULL; }
|
||||||
virtual SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return NULL; }
|
virtual SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return NULL; }
|
||||||
virtual SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return NULL; }
|
virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; }
|
||||||
virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; }
|
virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; }
|
||||||
virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; }
|
virtual NewDeclaration *isNewDeclaration() { return NULL; }
|
||||||
virtual NewDeclaration *isNewDeclaration() { return NULL; }
|
virtual VarDeclaration *isVarDeclaration() { return NULL; }
|
||||||
virtual VarDeclaration *isVarDeclaration() { return NULL; }
|
virtual ClassDeclaration *isClassDeclaration() { return NULL; }
|
||||||
virtual ClassDeclaration *isClassDeclaration() { return NULL; }
|
virtual StructDeclaration *isStructDeclaration() { return NULL; }
|
||||||
virtual StructDeclaration *isStructDeclaration() { return NULL; }
|
virtual UnionDeclaration *isUnionDeclaration() { return NULL; }
|
||||||
virtual UnionDeclaration *isUnionDeclaration() { return NULL; }
|
virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; }
|
||||||
virtual InterfaceDeclaration *isInterfaceDeclaration() { return NULL; }
|
virtual ScopeDsymbol *isScopeDsymbol() { return NULL; }
|
||||||
virtual ScopeDsymbol *isScopeDsymbol() { return NULL; }
|
virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; }
|
||||||
virtual WithScopeSymbol *isWithScopeSymbol() { return NULL; }
|
virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; }
|
||||||
virtual ArrayScopeSymbol *isArrayScopeSymbol() { return NULL; }
|
virtual Import *isImport() { return NULL; }
|
||||||
virtual Import *isImport() { return NULL; }
|
virtual EnumDeclaration *isEnumDeclaration() { return NULL; }
|
||||||
virtual EnumDeclaration *isEnumDeclaration() { return NULL; }
|
virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; }
|
||||||
virtual DeleteDeclaration *isDeleteDeclaration() { return NULL; }
|
virtual StaticStructInitDeclaration *isStaticStructInitDeclaration() { return NULL; }
|
||||||
virtual StaticStructInitDeclaration *isStaticStructInitDeclaration() { return NULL; }
|
virtual AttribDeclaration *isAttribDeclaration() { return NULL; }
|
||||||
virtual AttribDeclaration *isAttribDeclaration() { return NULL; }
|
virtual OverloadSet *isOverloadSet() { return NULL; }
|
||||||
virtual OverloadSet *isOverloadSet() { return NULL; }
|
virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return NULL; }
|
||||||
virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return NULL; }
|
virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; }
|
||||||
virtual ClassInfoDeclaration* isClassInfoDeclaration() { return NULL; }
|
#if TARGET_NET
|
||||||
#if TARGET_NET
|
virtual PragmaScope* isPragmaScope() { return NULL; }
|
||||||
virtual PragmaScope* isPragmaScope() { return NULL; }
|
#endif
|
||||||
#endif
|
#if IN_LLVM
|
||||||
#if IN_LLVM
|
/// Codegen traversal
|
||||||
/// Codegen traversal
|
virtual void codegen(Ir* ir);
|
||||||
virtual void codegen(Ir* ir);
|
|
||||||
|
// llvm stuff
|
||||||
// llvm stuff
|
int llvmInternal;
|
||||||
int llvmInternal;
|
|
||||||
|
IrDsymbol ir;
|
||||||
IrDsymbol ir;
|
IrSymbol* irsym;
|
||||||
IrSymbol* irsym;
|
#endif
|
||||||
#endif
|
};
|
||||||
};
|
|
||||||
|
// Dsymbol that generates a scope
|
||||||
// Dsymbol that generates a scope
|
|
||||||
|
struct ScopeDsymbol : Dsymbol
|
||||||
struct ScopeDsymbol : Dsymbol
|
{
|
||||||
{
|
Dsymbols *members; // all Dsymbol's in this scope
|
||||||
Dsymbols *members; // all Dsymbol's in this scope
|
DsymbolTable *symtab; // members[] sorted into table
|
||||||
DsymbolTable *symtab; // members[] sorted into table
|
|
||||||
|
Dsymbols *imports; // imported Dsymbol's
|
||||||
Dsymbols *imports; // imported Dsymbol's
|
unsigned char *prots; // array of PROT, one for each import
|
||||||
unsigned char *prots; // array of PROT, one for each import
|
|
||||||
|
ScopeDsymbol();
|
||||||
ScopeDsymbol();
|
ScopeDsymbol(Identifier *id);
|
||||||
ScopeDsymbol(Identifier *id);
|
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
void importScope(Dsymbol *s, enum PROT protection);
|
||||||
void importScope(Dsymbol *s, enum PROT protection);
|
int isforwardRef();
|
||||||
int isforwardRef();
|
void defineRef(Dsymbol *s);
|
||||||
void defineRef(Dsymbol *s);
|
static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2);
|
||||||
static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2);
|
Dsymbol *nameCollision(Dsymbol *s);
|
||||||
Dsymbol *nameCollision(Dsymbol *s);
|
const char *kind();
|
||||||
const char *kind();
|
FuncDeclaration *findGetMembers();
|
||||||
FuncDeclaration *findGetMembers();
|
virtual Dsymbol *symtabInsert(Dsymbol *s);
|
||||||
virtual Dsymbol *symtabInsert(Dsymbol *s);
|
bool hasStaticCtorOrDtor();
|
||||||
bool hasStaticCtorOrDtor();
|
|
||||||
|
void emitMemberComments(Scope *sc);
|
||||||
void emitMemberComments(Scope *sc);
|
|
||||||
|
static size_t dim(Dsymbols *members);
|
||||||
static size_t dim(Dsymbols *members);
|
static Dsymbol *getNth(Dsymbols *members, size_t nth, size_t *pn = NULL);
|
||||||
static Dsymbol *getNth(Dsymbols *members, size_t nth, size_t *pn = NULL);
|
|
||||||
|
typedef int (*ForeachDg)(void *ctx, size_t idx, Dsymbol *s);
|
||||||
typedef int (*ForeachDg)(void *ctx, size_t idx, Dsymbol *s);
|
static int foreach(Scope *sc, Dsymbols *members, ForeachDg dg, void *ctx, size_t *pn=NULL);
|
||||||
static int foreach(Scope *sc, Dsymbols *members, ForeachDg dg, void *ctx, size_t *pn=NULL);
|
|
||||||
|
ScopeDsymbol *isScopeDsymbol() { return this; }
|
||||||
ScopeDsymbol *isScopeDsymbol() { return this; }
|
};
|
||||||
};
|
|
||||||
|
// With statement scope
|
||||||
// With statement scope
|
|
||||||
|
struct WithScopeSymbol : ScopeDsymbol
|
||||||
struct WithScopeSymbol : ScopeDsymbol
|
{
|
||||||
{
|
WithStatement *withstate;
|
||||||
WithStatement *withstate;
|
|
||||||
|
WithScopeSymbol(WithStatement *withstate);
|
||||||
WithScopeSymbol(WithStatement *withstate);
|
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
|
||||||
|
WithScopeSymbol *isWithScopeSymbol() { return this; }
|
||||||
WithScopeSymbol *isWithScopeSymbol() { return this; }
|
};
|
||||||
};
|
|
||||||
|
// Array Index/Slice scope
|
||||||
// Array Index/Slice scope
|
|
||||||
|
struct ArrayScopeSymbol : ScopeDsymbol
|
||||||
struct ArrayScopeSymbol : ScopeDsymbol
|
{
|
||||||
{
|
Expression *exp; // IndexExp or SliceExp
|
||||||
Expression *exp; // IndexExp or SliceExp
|
TypeTuple *type; // for tuple[length]
|
||||||
TypeTuple *type; // for tuple[length]
|
TupleDeclaration *td; // for tuples of objects
|
||||||
TupleDeclaration *td; // for tuples of objects
|
Scope *sc;
|
||||||
Scope *sc;
|
|
||||||
|
ArrayScopeSymbol(Scope *sc, Expression *e);
|
||||||
ArrayScopeSymbol(Scope *sc, Expression *e);
|
ArrayScopeSymbol(Scope *sc, TypeTuple *t);
|
||||||
ArrayScopeSymbol(Scope *sc, TypeTuple *t);
|
ArrayScopeSymbol(Scope *sc, TupleDeclaration *td);
|
||||||
ArrayScopeSymbol(Scope *sc, TupleDeclaration *td);
|
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
|
||||||
|
ArrayScopeSymbol *isArrayScopeSymbol() { return this; }
|
||||||
ArrayScopeSymbol *isArrayScopeSymbol() { return this; }
|
};
|
||||||
};
|
|
||||||
|
// Overload Sets
|
||||||
// Overload Sets
|
|
||||||
|
#if DMDV2
|
||||||
#if DMDV2
|
struct OverloadSet : Dsymbol
|
||||||
struct OverloadSet : Dsymbol
|
{
|
||||||
{
|
Dsymbols a; // array of Dsymbols
|
||||||
Dsymbols a; // array of Dsymbols
|
|
||||||
|
OverloadSet();
|
||||||
OverloadSet();
|
void push(Dsymbol *s);
|
||||||
void push(Dsymbol *s);
|
OverloadSet *isOverloadSet() { return this; }
|
||||||
OverloadSet *isOverloadSet() { return this; }
|
const char *kind();
|
||||||
const char *kind();
|
};
|
||||||
};
|
#endif
|
||||||
#endif
|
|
||||||
|
// Table of Dsymbol's
|
||||||
// Table of Dsymbol's
|
|
||||||
|
struct DsymbolTable : Object
|
||||||
struct DsymbolTable : Object
|
{
|
||||||
{
|
AA *tab;
|
||||||
AA *tab;
|
|
||||||
|
DsymbolTable();
|
||||||
DsymbolTable();
|
~DsymbolTable();
|
||||||
~DsymbolTable();
|
|
||||||
|
// Look up Identifier. Return Dsymbol if found, NULL if not.
|
||||||
// Look up Identifier. Return Dsymbol if found, NULL if not.
|
Dsymbol *lookup(Identifier *ident);
|
||||||
Dsymbol *lookup(Identifier *ident);
|
|
||||||
|
// Insert Dsymbol in table. Return NULL if already there.
|
||||||
// Insert Dsymbol in table. Return NULL if already there.
|
Dsymbol *insert(Dsymbol *s);
|
||||||
Dsymbol *insert(Dsymbol *s);
|
|
||||||
|
// Look for Dsymbol in table. If there, return it. If not, insert s and return that.
|
||||||
// Look for Dsymbol in table. If there, return it. If not, insert s and return that.
|
Dsymbol *update(Dsymbol *s);
|
||||||
Dsymbol *update(Dsymbol *s);
|
Dsymbol *insert(Identifier *ident, Dsymbol *s); // when ident and s are not the same
|
||||||
Dsymbol *insert(Identifier *ident, Dsymbol *s); // when ident and s are not the same
|
};
|
||||||
};
|
|
||||||
|
#endif /* DMD_DSYMBOL_H */
|
||||||
#endif /* DMD_DSYMBOL_H */
|
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -36,7 +36,7 @@ void dumpExpressions(int i, Expressions *exps)
|
|||||||
if (exps)
|
if (exps)
|
||||||
{
|
{
|
||||||
for (size_t j = 0; j < exps->dim; j++)
|
for (size_t j = 0; j < exps->dim; j++)
|
||||||
{ Expression *e = exps->tdata()[j];
|
{ Expression *e = (*exps)[j];
|
||||||
indent(i);
|
indent(i);
|
||||||
printf("(\n");
|
printf("(\n");
|
||||||
e->dump(i + 2);
|
e->dump(i + 2);
|
||||||
|
|||||||
+10
-10
@@ -185,11 +185,11 @@ void EnumDeclaration::semantic(Scope *sc)
|
|||||||
{
|
{
|
||||||
assert(e->dyncast() == DYNCAST_EXPRESSION);
|
assert(e->dyncast() == DYNCAST_EXPRESSION);
|
||||||
e = e->semantic(sce);
|
e = e->semantic(sce);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
if (memtype)
|
if (memtype)
|
||||||
{
|
{
|
||||||
e = e->implicitCastTo(sce, memtype);
|
e = e->implicitCastTo(sce, memtype);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
if (!isAnonymous())
|
if (!isAnonymous())
|
||||||
e = e->castTo(sce, type);
|
e = e->castTo(sce, type);
|
||||||
t = memtype;
|
t = memtype;
|
||||||
@@ -197,7 +197,7 @@ void EnumDeclaration::semantic(Scope *sc)
|
|||||||
else if (em->type)
|
else if (em->type)
|
||||||
{
|
{
|
||||||
e = e->implicitCastTo(sce, em->type);
|
e = e->implicitCastTo(sce, em->type);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
assert(isAnonymous());
|
assert(isAnonymous());
|
||||||
t = e->type;
|
t = e->type;
|
||||||
}
|
}
|
||||||
@@ -214,7 +214,7 @@ void EnumDeclaration::semantic(Scope *sc)
|
|||||||
t = Type::tint32;
|
t = Type::tint32;
|
||||||
e = new IntegerExp(em->loc, 0, Type::tint32);
|
e = new IntegerExp(em->loc, 0, Type::tint32);
|
||||||
e = e->implicitCastTo(sce, t);
|
e = e->implicitCastTo(sce, t);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
if (!isAnonymous())
|
if (!isAnonymous())
|
||||||
e = e->castTo(sce, type);
|
e = e->castTo(sce, type);
|
||||||
}
|
}
|
||||||
@@ -225,7 +225,7 @@ void EnumDeclaration::semantic(Scope *sc)
|
|||||||
{
|
{
|
||||||
emax = t->getProperty(0, Id::max);
|
emax = t->getProperty(0, Id::max);
|
||||||
emax = emax->semantic(sce);
|
emax = emax->semantic(sce);
|
||||||
emax = emax->optimize(WANTvalue | WANTinterpret);
|
emax = emax->ctfeInterpret();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set value to (elast + 1).
|
// Set value to (elast + 1).
|
||||||
@@ -233,7 +233,7 @@ void EnumDeclaration::semantic(Scope *sc)
|
|||||||
assert(elast);
|
assert(elast);
|
||||||
e = new EqualExp(TOKequal, em->loc, elast, emax);
|
e = new EqualExp(TOKequal, em->loc, elast, emax);
|
||||||
e = e->semantic(sce);
|
e = e->semantic(sce);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
if (e->toInteger())
|
if (e->toInteger())
|
||||||
error("overflow of enum value %s", elast->toChars());
|
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 = new AddExp(em->loc, elast, new IntegerExp(em->loc, 1, Type::tint32));
|
||||||
e = e->semantic(sce);
|
e = e->semantic(sce);
|
||||||
e = e->castTo(sce, elast->type);
|
e = e->castTo(sce, elast->type);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
|
|
||||||
if (t->isfloating())
|
if (t->isfloating())
|
||||||
{
|
{
|
||||||
// Check that e != elast (not always true for floats)
|
// Check that e != elast (not always true for floats)
|
||||||
Expression *etest = new EqualExp(TOKequal, em->loc, e, elast);
|
Expression *etest = new EqualExp(TOKequal, em->loc, e, elast);
|
||||||
etest = etest->semantic(sce);
|
etest = etest->semantic(sce);
|
||||||
etest = etest->optimize(WANTvalue | WANTinterpret);
|
etest = etest->ctfeInterpret();
|
||||||
if (etest->toInteger())
|
if (etest->toInteger())
|
||||||
error("enum member %s has inexact value, due to loss of precision", em->toChars());
|
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)
|
// Compute if(e < minval)
|
||||||
ec = new CmpExp(TOKlt, em->loc, e, minval);
|
ec = new CmpExp(TOKlt, em->loc, e, minval);
|
||||||
ec = ec->semantic(sce);
|
ec = ec->semantic(sce);
|
||||||
ec = ec->optimize(WANTvalue | WANTinterpret);
|
ec = ec->ctfeInterpret();
|
||||||
if (ec->toInteger())
|
if (ec->toInteger())
|
||||||
minval = e;
|
minval = e;
|
||||||
|
|
||||||
ec = new CmpExp(TOKgt, em->loc, e, maxval);
|
ec = new CmpExp(TOKgt, em->loc, e, maxval);
|
||||||
ec = ec->semantic(sce);
|
ec = ec->semantic(sce);
|
||||||
ec = ec->optimize(WANTvalue | WANTinterpret);
|
ec = ec->ctfeInterpret();
|
||||||
if (ec->toInteger())
|
if (ec->toInteger())
|
||||||
maxval = e;
|
maxval = e;
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -42,7 +42,7 @@ struct EnumDeclaration : ScopeDsymbol
|
|||||||
int isdeprecated;
|
int isdeprecated;
|
||||||
int isdone; // 0: not done
|
int isdone; // 0: not done
|
||||||
// 1: semantic() successfully completed
|
// 1: semantic() successfully completed
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
Expressions *attributes; // GCC decl/type attributes
|
Expressions *attributes; // GCC decl/type attributes
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+530
-350
File diff suppressed because it is too large
Load Diff
+15
-5
@@ -18,6 +18,7 @@
|
|||||||
#include "intrange.h"
|
#include "intrange.h"
|
||||||
|
|
||||||
struct Type;
|
struct Type;
|
||||||
|
struct TypeVector;
|
||||||
struct Scope;
|
struct Scope;
|
||||||
struct TupleDeclaration;
|
struct TupleDeclaration;
|
||||||
struct VarDeclaration;
|
struct VarDeclaration;
|
||||||
@@ -183,6 +184,11 @@ struct Expression : Object
|
|||||||
// Same as WANTvalue, but also expand variables as far as possible
|
// Same as WANTvalue, but also expand variables as far as possible
|
||||||
#define WANTexpand 8
|
#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 Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
|
||||||
|
|
||||||
virtual int isConst();
|
virtual int isConst();
|
||||||
@@ -432,7 +438,6 @@ struct StringExp : Expression
|
|||||||
StringExp(Loc loc, void *s, size_t len, unsigned char postfix);
|
StringExp(Loc loc, void *s, size_t len, unsigned char postfix);
|
||||||
//Expression *syntaxCopy();
|
//Expression *syntaxCopy();
|
||||||
int equals(Object *o);
|
int equals(Object *o);
|
||||||
char *toChars();
|
|
||||||
Expression *semantic(Scope *sc);
|
Expression *semantic(Scope *sc);
|
||||||
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
|
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
|
||||||
size_t length();
|
size_t length();
|
||||||
@@ -793,7 +798,6 @@ struct FuncExp : Expression
|
|||||||
FuncLiteralDeclaration *fd;
|
FuncLiteralDeclaration *fd;
|
||||||
TemplateDeclaration *td;
|
TemplateDeclaration *td;
|
||||||
enum TOK tok;
|
enum TOK tok;
|
||||||
Type *treq;
|
|
||||||
|
|
||||||
FuncExp(Loc loc, FuncLiteralDeclaration *fd, TemplateDeclaration *td = NULL);
|
FuncExp(Loc loc, FuncLiteralDeclaration *fd, TemplateDeclaration *td = NULL);
|
||||||
Expression *syntaxCopy();
|
Expression *syntaxCopy();
|
||||||
@@ -947,10 +951,11 @@ struct BinExp : Expression
|
|||||||
Expression *interpretCommon(InterState *istate, CtfeGoal goal,
|
Expression *interpretCommon(InterState *istate, CtfeGoal goal,
|
||||||
Expression *(*fp)(Type *, Expression *, Expression *));
|
Expression *(*fp)(Type *, Expression *, Expression *));
|
||||||
Expression *interpretCommon2(InterState *istate, CtfeGoal goal,
|
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 *interpretAssignCommon(InterState *istate, CtfeGoal goal,
|
||||||
Expression *(*fp)(Type *, Expression *, Expression *), int post = 0);
|
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 *doInline(InlineDoState *ids);
|
||||||
Expression *inlineScan(InlineScanState *iss);
|
Expression *inlineScan(InlineScanState *iss);
|
||||||
@@ -971,6 +976,7 @@ struct BinAssignExp : BinExp
|
|||||||
}
|
}
|
||||||
|
|
||||||
Expression *semantic(Scope *sc);
|
Expression *semantic(Scope *sc);
|
||||||
|
Expression *arrayOp(Scope *sc);
|
||||||
|
|
||||||
Expression *op_overload(Scope *sc);
|
Expression *op_overload(Scope *sc);
|
||||||
|
|
||||||
@@ -1330,7 +1336,7 @@ struct CastExp : UnaExp
|
|||||||
|
|
||||||
struct VectorExp : UnaExp
|
struct VectorExp : UnaExp
|
||||||
{
|
{
|
||||||
Type *to;
|
TypeVector *to; // the target vector type before semantic()
|
||||||
unsigned dim; // number of elements in the vector
|
unsigned dim; // number of elements in the vector
|
||||||
|
|
||||||
VectorExp(Loc loc, Expression *e, Type *t);
|
VectorExp(Loc loc, Expression *e, Type *t);
|
||||||
@@ -1339,6 +1345,7 @@ struct VectorExp : UnaExp
|
|||||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||||
#if IN_DMD
|
#if IN_DMD
|
||||||
elem *toElem(IRState *irs);
|
elem *toElem(IRState *irs);
|
||||||
|
dt_t **toDt(dt_t **pdt);
|
||||||
#endif
|
#endif
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
DValue* toElem(IRState* irs);
|
DValue* toElem(IRState* irs);
|
||||||
@@ -2154,5 +2161,8 @@ void sliceAssignArrayLiteralFromString(ArrayLiteralExp *existingAE, StringExp *n
|
|||||||
void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, int firstIndex);
|
void sliceAssignStringFromArrayLiteral(StringExp *existingSE, ArrayLiteralExp *newae, int firstIndex);
|
||||||
void sliceAssignStringFromString(StringExp *existingSE, StringExp *newstr, 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 */
|
#endif /* DMD_EXPRESSION_H */
|
||||||
|
|||||||
+309
-280
@@ -51,13 +51,15 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageCla
|
|||||||
outId = NULL;
|
outId = NULL;
|
||||||
vresult = NULL;
|
vresult = NULL;
|
||||||
returnLabel = NULL;
|
returnLabel = NULL;
|
||||||
|
scout = NULL;
|
||||||
fensure = NULL;
|
fensure = NULL;
|
||||||
fbody = NULL;
|
fbody = NULL;
|
||||||
localsymtab = NULL;
|
localsymtab = NULL;
|
||||||
vthis = NULL;
|
vthis = NULL;
|
||||||
v_arguments = NULL;
|
v_arguments = NULL;
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
v_argptr = NULL;
|
v_argptr = NULL;
|
||||||
|
v_arguments_var = NULL;
|
||||||
#endif
|
#endif
|
||||||
v_argsave = NULL;
|
v_argsave = NULL;
|
||||||
parameters = NULL;
|
parameters = NULL;
|
||||||
@@ -223,11 +225,9 @@ void FuncDeclaration::semantic(Scope *sc)
|
|||||||
|
|
||||||
if (isCtorDeclaration())
|
if (isCtorDeclaration())
|
||||||
sc->flags |= SCOPEctor;
|
sc->flags |= SCOPEctor;
|
||||||
type = type->semantic(loc, sc);
|
|
||||||
sc = sc->pop();
|
|
||||||
|
|
||||||
/* Apply const, immutable and shared storage class
|
/* Apply const, immutable, wild and shared storage class
|
||||||
* to the function type
|
* to the function type. Do this before type semantic.
|
||||||
*/
|
*/
|
||||||
StorageClass stc = storage_class;
|
StorageClass stc = storage_class;
|
||||||
if (type->isImmutable())
|
if (type->isImmutable())
|
||||||
@@ -250,35 +250,28 @@ void FuncDeclaration::semantic(Scope *sc)
|
|||||||
case STCimmutable | STCshared | STCwild:
|
case STCimmutable | STCshared | STCwild:
|
||||||
// Don't use toInvariant(), as that will do a merge()
|
// Don't use toInvariant(), as that will do a merge()
|
||||||
type = type->makeInvariant();
|
type = type->makeInvariant();
|
||||||
goto Lmerge;
|
break;
|
||||||
|
|
||||||
case STCconst:
|
case STCconst:
|
||||||
case STCconst | STCwild:
|
case STCconst | STCwild:
|
||||||
type = type->makeConst();
|
type = type->makeConst();
|
||||||
goto Lmerge;
|
break;
|
||||||
|
|
||||||
case STCshared | STCconst:
|
case STCshared | STCconst:
|
||||||
case STCshared | STCconst | STCwild:
|
case STCshared | STCconst | STCwild:
|
||||||
type = type->makeSharedConst();
|
type = type->makeSharedConst();
|
||||||
goto Lmerge;
|
break;
|
||||||
|
|
||||||
case STCshared:
|
case STCshared:
|
||||||
type = type->makeShared();
|
type = type->makeShared();
|
||||||
goto Lmerge;
|
break;
|
||||||
|
|
||||||
case STCwild:
|
case STCwild:
|
||||||
type = type->makeWild();
|
type = type->makeWild();
|
||||||
goto Lmerge;
|
break;
|
||||||
|
|
||||||
case STCshared | STCwild:
|
case STCshared | STCwild:
|
||||||
type = type->makeSharedWild();
|
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;
|
break;
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
@@ -287,7 +280,11 @@ void FuncDeclaration::semantic(Scope *sc)
|
|||||||
default:
|
default:
|
||||||
assert(0);
|
assert(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type = type->semantic(loc, sc);
|
||||||
|
sc = sc->pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
storage_class &= ~STCref;
|
storage_class &= ~STCref;
|
||||||
if (type->ty != Tfunction)
|
if (type->ty != Tfunction)
|
||||||
{
|
{
|
||||||
@@ -401,18 +398,6 @@ void FuncDeclaration::semantic(Scope *sc)
|
|||||||
if (!fbody && (fensure || frequire) && !(id && isVirtual()))
|
if (!fbody && (fensure || frequire) && !(id && isVirtual()))
|
||||||
error("in and out contracts require function body");
|
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();
|
cd = parent->isClassDeclaration();
|
||||||
if (cd)
|
if (cd)
|
||||||
{ int vi;
|
{ int vi;
|
||||||
@@ -550,9 +535,6 @@ void FuncDeclaration::semantic(Scope *sc)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
else if (!this->parent->isClassDeclaration() // if both are mixins then error
|
else if (!this->parent->isClassDeclaration() // if both are mixins then error
|
||||||
#if !BREAKABI
|
|
||||||
&& !isDtorDeclaration()
|
|
||||||
#endif
|
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
&& !isPostBlitDeclaration()
|
&& !isPostBlitDeclaration()
|
||||||
#endif
|
#endif
|
||||||
@@ -610,7 +592,7 @@ void FuncDeclaration::semantic(Scope *sc)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
{ FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl.tdata()[vi];
|
{ FuncDeclaration *fdv = (FuncDeclaration *)b->base->vtbl[vi];
|
||||||
Type *ti = NULL;
|
Type *ti = NULL;
|
||||||
|
|
||||||
/* Remember which functions this overrides
|
/* Remember which functions this overrides
|
||||||
@@ -920,7 +902,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
{
|
{
|
||||||
for (int i = 0; i < fthrows->dim; i++)
|
for (int i = 0; i < fthrows->dim; i++)
|
||||||
{
|
{
|
||||||
Type *t = fthrows->tdata()[i];
|
Type *t = (*fthrows)[i];
|
||||||
|
|
||||||
t = t->semantic(loc, sc);
|
t = t->semantic(loc, sc);
|
||||||
if (!t->isClassHandle())
|
if (!t->isClassHandle())
|
||||||
@@ -929,11 +911,17 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if (!fbody && inferRetType && !type->nextOf())
|
||||||
|
{
|
||||||
|
error("has no function body with return type inference");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (frequire)
|
if (frequire)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < foverrides.dim; i++)
|
for (int i = 0; i < foverrides.dim; i++)
|
||||||
{
|
{
|
||||||
FuncDeclaration *fdv = foverrides.tdata()[i];
|
FuncDeclaration *fdv = foverrides[i];
|
||||||
|
|
||||||
if (fdv->fbody && !fdv->frequire)
|
if (fdv->fbody && !fdv->frequire)
|
||||||
{
|
{
|
||||||
@@ -971,7 +959,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
STCproperty | STCsafe | STCtrusted | STCsystem);
|
STCproperty | STCsafe | STCtrusted | STCsystem);
|
||||||
sc2->protection = PROTpublic;
|
sc2->protection = PROTpublic;
|
||||||
sc2->explicitProtection = 0;
|
sc2->explicitProtection = 0;
|
||||||
sc2->structalign = 8;
|
sc2->structalign = STRUCTALIGN_DEFAULT;
|
||||||
sc2->incontract = 0;
|
sc2->incontract = 0;
|
||||||
#if !IN_LLVM
|
#if !IN_LLVM
|
||||||
sc2->tf = NULL;
|
sc2->tf = NULL;
|
||||||
@@ -992,9 +980,6 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert(!isNested() || sc->intypeof); // can't be both member and nested
|
assert(!isNested() || sc->intypeof); // can't be both member and nested
|
||||||
#if IN_GCC
|
|
||||||
ad->methods.push(this);
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
vthis = declareThis(sc2, ad);
|
vthis = declareThis(sc2, ad);
|
||||||
|
|
||||||
@@ -1028,7 +1013,6 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
|
|
||||||
if (f->linkage == LINKd)
|
if (f->linkage == LINKd)
|
||||||
{ // Declare _arguments[]
|
{ // Declare _arguments[]
|
||||||
#if BREAKABI
|
|
||||||
v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
|
v_arguments = new VarDeclaration(0, Type::typeinfotypelist->type, Id::_arguments_typeinfo, NULL);
|
||||||
v_arguments->storage_class = STCparameter;
|
v_arguments->storage_class = STCparameter;
|
||||||
v_arguments->semantic(sc2);
|
v_arguments->semantic(sc2);
|
||||||
@@ -1041,18 +1025,10 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
_arguments->semantic(sc2);
|
_arguments->semantic(sc2);
|
||||||
sc2->insert(_arguments);
|
sc2->insert(_arguments);
|
||||||
_arguments->parent = this;
|
_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)))
|
if (f->linkage == LINKd || (f->parameters && Parameter::dim(f->parameters)))
|
||||||
{ // Declare _argptr
|
{ // Declare _argptr
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
t = d_gcc_builtin_va_list_d_type;
|
t = d_gcc_builtin_va_list_d_type;
|
||||||
#else
|
#else
|
||||||
t = Type::tvoid->pointerTo();
|
t = Type::tvoid->pointerTo();
|
||||||
@@ -1094,7 +1070,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
if (f->parameters)
|
if (f->parameters)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < f->parameters->dim; i++)
|
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());
|
//printf("[%d] arg->type->ty = %d %s\n", i, arg->type->ty, arg->type->toChars());
|
||||||
if (arg->type->ty == Ttuple)
|
if (arg->type->ty == Ttuple)
|
||||||
@@ -1158,7 +1134,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
if (f->parameters)
|
if (f->parameters)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < f->parameters->dim; i++)
|
for (size_t i = 0; i < f->parameters->dim; i++)
|
||||||
{ Parameter *arg = f->parameters->tdata()[i];
|
{ Parameter *arg = (*f->parameters)[i];
|
||||||
|
|
||||||
if (!arg->ident)
|
if (!arg->ident)
|
||||||
continue; // never used, so ignore
|
continue; // never used, so ignore
|
||||||
@@ -1173,7 +1149,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
VarDeclaration *v = sc2->search(0, narg->ident, NULL)->isVarDeclaration();
|
VarDeclaration *v = sc2->search(0, narg->ident, NULL)->isVarDeclaration();
|
||||||
assert(v);
|
assert(v);
|
||||||
Expression *e = new VarExp(v->loc, v);
|
Expression *e = new VarExp(v->loc, v);
|
||||||
exps->tdata()[j] = e;
|
(*exps)[j] = e;
|
||||||
}
|
}
|
||||||
assert(arg->ident);
|
assert(arg->ident);
|
||||||
TupleDeclaration *v = new TupleDeclaration(loc, arg->ident, exps);
|
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
|
// Precondition invariant
|
||||||
* [out] postconditions.
|
Statement *fpreinv = NULL;
|
||||||
*/
|
if (addPreInvariant())
|
||||||
sc2->incontract++;
|
{
|
||||||
|
Expression *e = NULL;
|
||||||
|
if (isDtorDeclaration())
|
||||||
|
{
|
||||||
|
// Call invariant directly only if it exists
|
||||||
|
InvariantDeclaration *inv = ad->inv;
|
||||||
|
ClassDeclaration *cd = ad->isClassDeclaration();
|
||||||
|
|
||||||
if (frequire)
|
while (!inv && cd)
|
||||||
{ /* frequire is composed of the [in] contracts
|
{
|
||||||
*/
|
cd = cd->baseClass;
|
||||||
// BUG: need to error if accessing out parameters
|
if (!cd)
|
||||||
// BUG: need to treat parameters as const
|
break;
|
||||||
// BUG: need to disallow returns and throws
|
inv = cd->inv;
|
||||||
// BUG: verify that all in and ref parameters are read
|
}
|
||||||
frequire = frequire->semantic(sc2);
|
if (inv)
|
||||||
labtab = NULL; // so body can't refer to labels
|
{
|
||||||
|
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())
|
if (fensure || addPostInvariant())
|
||||||
{ /* fensure is composed of the [out] contracts
|
{
|
||||||
*/
|
if ((fensure && global.params.useOut) || fpostinv)
|
||||||
if (!type->nextOf()) // if return type is inferred
|
{ returnLabel = new LabelDsymbol(Id::returnLabel);
|
||||||
{ /* 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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();
|
ScopeDsymbol *sym = new ScopeDsymbol();
|
||||||
sym->parent = sc2->scopesym;
|
sym->parent = sc2->scopesym;
|
||||||
sc2 = sc2->push(sym);
|
sc2 = sc2->push(sym);
|
||||||
|
|
||||||
assert(type->nextOf());
|
AggregateDeclaration *ad = isAggregateMember();
|
||||||
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();
|
|
||||||
|
|
||||||
/* If this is a class constructor
|
/* If this is a class constructor
|
||||||
*/
|
*/
|
||||||
@@ -1375,7 +1320,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < pd->members->dim; i++)
|
for (size_t i = 0; i < pd->members->dim; i++)
|
||||||
{ Dsymbol *s = pd->members->tdata()[i];
|
{ Dsymbol *s = (*pd->members)[i];
|
||||||
|
|
||||||
s->checkCtorConstInit();
|
s->checkCtorConstInit();
|
||||||
}
|
}
|
||||||
@@ -1460,15 +1405,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
|
|
||||||
int offend = blockexit & BEfallthru;
|
int offend = blockexit & BEfallthru;
|
||||||
#endif
|
#endif
|
||||||
if (type->nextOf()->ty == Tvoid)
|
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 (offend)
|
if (offend)
|
||||||
{ Expression *e;
|
{ 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)
|
if (parameters)
|
||||||
{ for (size_t i = 0; i < parameters->dim; i++)
|
{ for (size_t i = 0; i < parameters->dim; i++)
|
||||||
{
|
{
|
||||||
VarDeclaration *v = parameters->tdata()[i];
|
VarDeclaration *v = (*parameters)[i];
|
||||||
if (v->storage_class & STCout)
|
if (v->storage_class & STCout)
|
||||||
{
|
{
|
||||||
assert(v->init);
|
assert(v->init);
|
||||||
@@ -1548,7 +1545,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
if (parameters && parameters->dim)
|
if (parameters && parameters->dim)
|
||||||
{
|
{
|
||||||
int lastNonref = parameters->dim -1;
|
int lastNonref = parameters->dim -1;
|
||||||
p = parameters->tdata()[lastNonref];
|
p = (*parameters)[lastNonref];
|
||||||
/* The trouble with out and ref parameters is that taking
|
/* The trouble with out and ref parameters is that taking
|
||||||
* the address of it doesn't work, because later processing
|
* the address of it doesn't work, because later processing
|
||||||
* adds in an extra level of indirection. So we skip over them.
|
* adds in an extra level of indirection. So we skip over them.
|
||||||
@@ -1562,7 +1559,7 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
p = v_arguments;
|
p = v_arguments;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
p = parameters->tdata()[lastNonref];
|
p = (*parameters)[lastNonref];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -1586,6 +1583,10 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
|
|
||||||
if (_arguments)
|
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:
|
/* Advance to elements[] member of TypeInfo_Tuple with:
|
||||||
* _arguments = v_arguments.elements;
|
* _arguments = v_arguments.elements;
|
||||||
*/
|
*/
|
||||||
@@ -1601,74 +1602,32 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
|
|
||||||
// Merge contracts together with body into one compound statement
|
// Merge contracts together with body into one compound statement
|
||||||
|
|
||||||
if (frequire && global.params.useIn)
|
if (freq || fpreinv)
|
||||||
{ frequire->incontract = 1;
|
|
||||||
a->push(frequire);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Precondition invariant
|
|
||||||
if (addPreInvariant())
|
|
||||||
{
|
{
|
||||||
Expression *e = NULL;
|
if (!freq)
|
||||||
Expression *ee = NULL;
|
freq = fpreinv;
|
||||||
if (isDtorDeclaration())
|
else if (fpreinv)
|
||||||
{
|
freq = new CompoundStatement(0, freq, fpreinv);
|
||||||
// Call invariant directly only if it exists
|
|
||||||
InvariantDeclaration *inv = ad->inv;
|
|
||||||
ClassDeclaration *cd = ad->isClassDeclaration();
|
|
||||||
|
|
||||||
while (!inv && cd)
|
freq->incontract = 1;
|
||||||
{
|
a->push(freq);
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fbody)
|
if (fbody)
|
||||||
a->push(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);
|
a->push(returnLabel->statement);
|
||||||
|
|
||||||
if (type->nextOf()->ty != Tvoid)
|
if (type->nextOf()->ty != Tvoid && vresult)
|
||||||
{
|
{
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
Expression *e = 0;
|
Expression *e = 0;
|
||||||
@@ -1682,7 +1641,6 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
// Create: return vresult;
|
// Create: return vresult;
|
||||||
assert(vresult);
|
|
||||||
Expression *e = new VarExp(0, vresult);
|
Expression *e = new VarExp(0, vresult);
|
||||||
#endif
|
#endif
|
||||||
if (tintro)
|
if (tintro)
|
||||||
@@ -1693,6 +1651,11 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
a->push(s);
|
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);
|
fbody = new CompoundStatement(0, a);
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
@@ -1701,17 +1664,19 @@ void FuncDeclaration::semantic3(Scope *sc)
|
|||||||
if (parameters)
|
if (parameters)
|
||||||
{ for (size_t i = 0; i < parameters->dim; i++)
|
{ 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;
|
continue;
|
||||||
|
|
||||||
|
#if !SARRAYVALUE
|
||||||
/* Don't do this for static arrays, since static
|
/* Don't do this for static arrays, since static
|
||||||
* arrays are called by reference. Remove this
|
* arrays are called by reference. Remove this
|
||||||
* when we change them to call by value.
|
* when we change them to call by value.
|
||||||
*/
|
*/
|
||||||
if (v->type->toBasetype()->ty == Tsarray)
|
if (v->type->toBasetype()->ty == Tsarray)
|
||||||
continue;
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
if (v->noscope)
|
if (v->noscope)
|
||||||
continue;
|
continue;
|
||||||
@@ -1948,6 +1913,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.
|
* 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.
|
* 'in's are OR'd together, i.e. only one of them needs to pass.
|
||||||
@@ -1992,7 +1999,7 @@ Statement *FuncDeclaration::mergeFrequire(Statement *sf, Expressions *params)
|
|||||||
*/
|
*/
|
||||||
for (int i = 0; i < foverrides.dim; i++)
|
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
|
/* The semantic pass on the contracts of the overridden functions must
|
||||||
* be completed before code generation occurs (bug 3602).
|
* be completed before code generation occurs (bug 3602).
|
||||||
@@ -2050,7 +2057,7 @@ Statement *FuncDeclaration::mergeFensure(Statement *sf, Expressions *params)
|
|||||||
*/
|
*/
|
||||||
for (int i = 0; i < foverrides.dim; i++)
|
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
|
/* The semantic pass on the contracts of the overridden functions must
|
||||||
* be completed before code generation occurs (bug 3602 and 5230).
|
* be completed before code generation occurs (bug 3602 and 5230).
|
||||||
@@ -2119,14 +2126,28 @@ int FuncDeclaration::findVtblIndex(Dsymbols *vtbl, int dim)
|
|||||||
FuncDeclaration *mismatch = NULL;
|
FuncDeclaration *mismatch = NULL;
|
||||||
StorageClass mismatchstc = 0;
|
StorageClass mismatchstc = 0;
|
||||||
int mismatchvi = -1;
|
int mismatchvi = -1;
|
||||||
|
int exactvi = -1;
|
||||||
int bestvi = -1;
|
int bestvi = -1;
|
||||||
for (int vi = 0; vi < dim; vi++)
|
for (int vi = 0; vi < dim; vi++)
|
||||||
{
|
{
|
||||||
FuncDeclaration *fdv = vtbl->tdata()[vi]->isFuncDeclaration();
|
FuncDeclaration *fdv = (*vtbl)[vi]->isFuncDeclaration();
|
||||||
if (fdv && fdv->ident == ident)
|
if (fdv && fdv->ident == ident)
|
||||||
{
|
{
|
||||||
if (type->equals(fdv->type)) // if exact match
|
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;
|
StorageClass stc = 0;
|
||||||
int cov = type->covariant(fdv->type, &stc);
|
int cov = type->covariant(fdv->type, &stc);
|
||||||
@@ -2488,7 +2509,7 @@ if (arguments)
|
|||||||
for (i = 0; i < arguments->dim; i++)
|
for (i = 0; i < arguments->dim; i++)
|
||||||
{ Expression *arg;
|
{ Expression *arg;
|
||||||
|
|
||||||
arg = arguments->tdata()[i];
|
arg = (*arguments)[i];
|
||||||
assert(arg->type);
|
assert(arg->type);
|
||||||
printf("\t%s: ", arg->toChars());
|
printf("\t%s: ", arg->toChars());
|
||||||
arg->type->print();
|
arg->type->print();
|
||||||
@@ -2531,7 +2552,7 @@ if (arguments)
|
|||||||
OutBuffer buf2;
|
OutBuffer buf2;
|
||||||
tf->modToBuffer(&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",
|
error(loc, "%s%s is not callable using argument types %s",
|
||||||
Parameter::argsTypesToChars(tf->parameters, tf->varargs),
|
Parameter::argsTypesToChars(tf->parameters, tf->varargs),
|
||||||
buf2.toChars(),
|
buf2.toChars(),
|
||||||
@@ -2617,7 +2638,7 @@ MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
e = p->type->defaultInitLiteral(0);
|
e = p->type->defaultInitLiteral(0);
|
||||||
args.tdata()[u] = e;
|
args[u] = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
MATCH m = (MATCH) tg->callMatch(NULL, &args, 1);
|
MATCH m = (MATCH) tg->callMatch(NULL, &args, 1);
|
||||||
@@ -2758,14 +2779,25 @@ int FuncDeclaration::getLevel(Loc loc, Scope *sc, FuncDeclaration *fd)
|
|||||||
//printf("\ts = %s, '%s'\n", s->kind(), s->toChars());
|
//printf("\ts = %s, '%s'\n", s->kind(), s->toChars());
|
||||||
FuncDeclaration *thisfd = s->isFuncDeclaration();
|
FuncDeclaration *thisfd = s->isFuncDeclaration();
|
||||||
if (thisfd)
|
if (thisfd)
|
||||||
{ if (!thisfd->isNested() && !thisfd->vthis)
|
{ if (!thisfd->isNested() && !thisfd->vthis && !sc->intypeof)
|
||||||
goto Lerr;
|
goto Lerr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AggregateDeclaration *thiscd = s->isAggregateDeclaration();
|
AggregateDeclaration *thiscd = s->isAggregateDeclaration();
|
||||||
if (thiscd)
|
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;
|
goto Lerr;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -3042,6 +3074,7 @@ int FuncDeclaration::isNested()
|
|||||||
FuncDeclaration *f = toAliasFunc();
|
FuncDeclaration *f = toAliasFunc();
|
||||||
//printf("\ttoParent2() = '%s'\n", f->toParent2()->toChars());
|
//printf("\ttoParent2() = '%s'\n", f->toParent2()->toChars());
|
||||||
return ((f->storage_class & STCstatic) == 0) &&
|
return ((f->storage_class & STCstatic) == 0) &&
|
||||||
|
(f->linkage == LINKd) &&
|
||||||
(f->toParent2()->isFuncDeclaration() != NULL);
|
(f->toParent2()->isFuncDeclaration() != NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3183,12 +3216,12 @@ int FuncDeclaration::needsClosure()
|
|||||||
|
|
||||||
//printf("FuncDeclaration::needsClosure() %s\n", toChars());
|
//printf("FuncDeclaration::needsClosure() %s\n", toChars());
|
||||||
for (int i = 0; i < closureVars.dim; i++)
|
for (int i = 0; i < closureVars.dim; i++)
|
||||||
{ VarDeclaration *v = closureVars.tdata()[i];
|
{ VarDeclaration *v = closureVars[i];
|
||||||
assert(v->isVarDeclaration());
|
assert(v->isVarDeclaration());
|
||||||
//printf("\tv = %s\n", v->toChars());
|
//printf("\tv = %s\n", v->toChars());
|
||||||
|
|
||||||
for (int j = 0; j < v->nestedrefs.dim; j++)
|
for (int j = 0; j < v->nestedrefs.dim; j++)
|
||||||
{ FuncDeclaration *f = v->nestedrefs.tdata()[j];
|
{ FuncDeclaration *f = v->nestedrefs[j];
|
||||||
assert(f != this);
|
assert(f != this);
|
||||||
|
|
||||||
//printf("\t\tf = %s, %d, %p, %d\n", f->toChars(), f->isVirtual(), f->isThis(), f->tookAddressOf);
|
//printf("\t\tf = %s, %d, %p, %d\n", f->toChars(), f->isVirtual(), f->isThis(), f->tookAddressOf);
|
||||||
@@ -3259,7 +3292,7 @@ int FuncDeclaration::hasNestedFrameRefs()
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < foverrides.dim; i++)
|
for (size_t i = 0; i < foverrides.dim; i++)
|
||||||
{
|
{
|
||||||
FuncDeclaration *fdv = foverrides.tdata()[i];
|
FuncDeclaration *fdv = foverrides[i];
|
||||||
if (fdv->hasNestedFrameRefs())
|
if (fdv->hasNestedFrameRefs())
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -3347,6 +3380,7 @@ FuncLiteralDeclaration::FuncLiteralDeclaration(Loc loc, Loc endloc, Type *type,
|
|||||||
this->ident = Lexer::uniqueId(id);
|
this->ident = Lexer::uniqueId(id);
|
||||||
this->tok = tok;
|
this->tok = tok;
|
||||||
this->fes = fes;
|
this->fes = fes;
|
||||||
|
this->treq = NULL;
|
||||||
//printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars());
|
//printf("FuncLiteralDeclaration() id = '%s', type = '%s'\n", this->ident->toChars(), type->toChars());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3360,6 +3394,7 @@ Dsymbol *FuncLiteralDeclaration::syntaxCopy(Dsymbol *s)
|
|||||||
else
|
else
|
||||||
{ f = new FuncLiteralDeclaration(loc, endloc, type->syntaxCopy(), tok, fes);
|
{ f = new FuncLiteralDeclaration(loc, endloc, type->syntaxCopy(), tok, fes);
|
||||||
f->ident = ident; // keep old identifier
|
f->ident = ident; // keep old identifier
|
||||||
|
f->treq = treq; // don't need to copy
|
||||||
}
|
}
|
||||||
FuncDeclaration::syntaxCopy(f);
|
FuncDeclaration::syntaxCopy(f);
|
||||||
return f;
|
return f;
|
||||||
@@ -3674,14 +3709,8 @@ char *DtorDeclaration::toChars()
|
|||||||
|
|
||||||
int DtorDeclaration::isVirtual()
|
int DtorDeclaration::isVirtual()
|
||||||
{
|
{
|
||||||
/* This should be FALSE so that dtor's don't get put into the vtbl[],
|
// FALSE so that dtor's don't get put into the vtbl[]
|
||||||
* but doing so will require recompiling everything.
|
|
||||||
*/
|
|
||||||
#if BREAKABI
|
|
||||||
return FALSE;
|
return FALSE;
|
||||||
#else
|
|
||||||
return FuncDeclaration::isVirtual();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void DtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
void DtorDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||||
|
|||||||
+248
-248
@@ -1,248 +1,248 @@
|
|||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
Version 1, February 1989
|
Version 1, February 1989
|
||||||
|
|
||||||
Copyright (C) 1989 Free Software Foundation, Inc.
|
Copyright (C) 1989 Free Software Foundation, Inc.
|
||||||
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
59 Temple Place, Suite 330, Boston, MA 02111-1307, USA
|
||||||
Everyone is permitted to copy and distribute verbatim copies
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
of this license document, but changing it is not allowed.
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
Preamble
|
Preamble
|
||||||
|
|
||||||
The license agreements of most software companies try to keep users
|
The license agreements of most software companies try to keep users
|
||||||
at the mercy of those companies. By contrast, our General Public
|
at the mercy of those companies. By contrast, our General Public
|
||||||
License is intended to guarantee your freedom to share and change free
|
License is intended to guarantee your freedom to share and change free
|
||||||
software--to make sure the software is free for all its users. The
|
software--to make sure the software is free for all its users. The
|
||||||
General Public License applies to the Free Software Foundation's
|
General Public License applies to the Free Software Foundation's
|
||||||
software and to any other program whose authors commit to using it.
|
software and to any other program whose authors commit to using it.
|
||||||
You can use it for your programs, too.
|
You can use it for your programs, too.
|
||||||
|
|
||||||
When we speak of free software, we are referring to freedom, not
|
When we speak of free software, we are referring to freedom, not
|
||||||
price. Specifically, the General Public License is designed to make
|
price. Specifically, the General Public License is designed to make
|
||||||
sure that you have the freedom to give away or sell copies of free
|
sure that you have the freedom to give away or sell copies of free
|
||||||
software, that you receive source code or can get it if you want it,
|
software, that you receive source code or can get it if you want it,
|
||||||
that you can change the software or use pieces of it in new free
|
that you can change the software or use pieces of it in new free
|
||||||
programs; and that you know you can do these things.
|
programs; and that you know you can do these things.
|
||||||
|
|
||||||
To protect your rights, we need to make restrictions that forbid
|
To protect your rights, we need to make restrictions that forbid
|
||||||
anyone to deny you these rights or to ask you to surrender the rights.
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
These restrictions translate to certain responsibilities for you if you
|
These restrictions translate to certain responsibilities for you if you
|
||||||
distribute copies of the software, or if you modify it.
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
For example, if you distribute copies of a such a program, whether
|
For example, if you distribute copies of a such a program, whether
|
||||||
gratis or for a fee, you must give the recipients all the rights that
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
you have. You must make sure that they, too, receive or can get the
|
you have. You must make sure that they, too, receive or can get the
|
||||||
source code. And you must tell them their rights.
|
source code. And you must tell them their rights.
|
||||||
|
|
||||||
We protect your rights with two steps: (1) copyright the software, and
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
(2) offer you this license which gives you legal permission to copy,
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
distribute and/or modify the software.
|
distribute and/or modify the software.
|
||||||
|
|
||||||
Also, for each author's protection and ours, we want to make certain
|
Also, for each author's protection and ours, we want to make certain
|
||||||
that everyone understands that there is no warranty for this free
|
that everyone understands that there is no warranty for this free
|
||||||
software. If the software is modified by someone else and passed on, we
|
software. If the software is modified by someone else and passed on, we
|
||||||
want its recipients to know that what they have is not the original, so
|
want its recipients to know that what they have is not the original, so
|
||||||
that any problems introduced by others will not reflect on the original
|
that any problems introduced by others will not reflect on the original
|
||||||
authors' reputations.
|
authors' reputations.
|
||||||
|
|
||||||
The precise terms and conditions for copying, distribution and
|
The precise terms and conditions for copying, distribution and
|
||||||
modification follow.
|
modification follow.
|
||||||
|
|
||||||
GNU GENERAL PUBLIC LICENSE
|
GNU GENERAL PUBLIC LICENSE
|
||||||
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
0. This License Agreement applies to any program or other work which
|
0. This License Agreement applies to any program or other work which
|
||||||
contains a notice placed by the copyright holder saying it may be
|
contains a notice placed by the copyright holder saying it may be
|
||||||
distributed under the terms of this General Public License. The
|
distributed under the terms of this General Public License. The
|
||||||
"Program", below, refers to any such program or work, and a "work based
|
"Program", below, refers to any such program or work, and a "work based
|
||||||
on the Program" means either the Program or any work containing the
|
on the Program" means either the Program or any work containing the
|
||||||
Program or a portion of it, either verbatim or with modifications. Each
|
Program or a portion of it, either verbatim or with modifications. Each
|
||||||
licensee is addressed as "you".
|
licensee is addressed as "you".
|
||||||
|
|
||||||
1. You may copy and distribute verbatim copies of the Program's source
|
1. You may copy and distribute verbatim copies of the Program's source
|
||||||
code as you receive it, in any medium, provided that you conspicuously and
|
code as you receive it, in any medium, provided that you conspicuously and
|
||||||
appropriately publish on each copy an appropriate copyright notice and
|
appropriately publish on each copy an appropriate copyright notice and
|
||||||
disclaimer of warranty; keep intact all the notices that refer to this
|
disclaimer of warranty; keep intact all the notices that refer to this
|
||||||
General Public License and to the absence of any warranty; and give any
|
General Public License and to the absence of any warranty; and give any
|
||||||
other recipients of the Program a copy of this General Public License
|
other recipients of the Program a copy of this General Public License
|
||||||
along with the Program. You may charge a fee for the physical act of
|
along with the Program. You may charge a fee for the physical act of
|
||||||
transferring a copy.
|
transferring a copy.
|
||||||
|
|
||||||
2. You may modify your copy or copies of the Program or any portion of
|
2. You may modify your copy or copies of the Program or any portion of
|
||||||
it, and copy and distribute such modifications under the terms of Paragraph
|
it, and copy and distribute such modifications under the terms of Paragraph
|
||||||
1 above, provided that you also do the following:
|
1 above, provided that you also do the following:
|
||||||
|
|
||||||
a) cause the modified files to carry prominent notices stating that
|
a) cause the modified files to carry prominent notices stating that
|
||||||
you changed the files and the date of any change; and
|
you changed the files and the date of any change; and
|
||||||
|
|
||||||
b) cause the whole of any work that you distribute or publish, that
|
b) cause the whole of any work that you distribute or publish, that
|
||||||
in whole or in part contains the Program or any part thereof, either
|
in whole or in part contains the Program or any part thereof, either
|
||||||
with or without modifications, to be licensed at no charge to all
|
with or without modifications, to be licensed at no charge to all
|
||||||
third parties under the terms of this General Public License (except
|
third parties under the terms of this General Public License (except
|
||||||
that you may choose to grant warranty protection to some or all
|
that you may choose to grant warranty protection to some or all
|
||||||
third parties, at your option).
|
third parties, at your option).
|
||||||
|
|
||||||
c) If the modified program normally reads commands interactively when
|
c) If the modified program normally reads commands interactively when
|
||||||
run, you must cause it, when started running for such interactive use
|
run, you must cause it, when started running for such interactive use
|
||||||
in the simplest and most usual way, to print or display an
|
in the simplest and most usual way, to print or display an
|
||||||
announcement including an appropriate copyright notice and a notice
|
announcement including an appropriate copyright notice and a notice
|
||||||
that there is no warranty (or else, saying that you provide a
|
that there is no warranty (or else, saying that you provide a
|
||||||
warranty) and that users may redistribute the program under these
|
warranty) and that users may redistribute the program under these
|
||||||
conditions, and telling the user how to view a copy of this General
|
conditions, and telling the user how to view a copy of this General
|
||||||
Public License.
|
Public License.
|
||||||
|
|
||||||
d) You may charge a fee for the physical act of transferring a
|
d) You may charge a fee for the physical act of transferring a
|
||||||
copy, and you may at your option offer warranty protection in
|
copy, and you may at your option offer warranty protection in
|
||||||
exchange for a fee.
|
exchange for a fee.
|
||||||
|
|
||||||
Mere aggregation of another independent work with the Program (or its
|
Mere aggregation of another independent work with the Program (or its
|
||||||
derivative) on a volume of a storage or distribution medium does not bring
|
derivative) on a volume of a storage or distribution medium does not bring
|
||||||
the other work under the scope of these terms.
|
the other work under the scope of these terms.
|
||||||
|
|
||||||
3. You may copy and distribute the Program (or a portion or derivative of
|
3. You may copy and distribute the Program (or a portion or derivative of
|
||||||
it, under Paragraph 2) in object code or executable form under the terms of
|
it, under Paragraph 2) in object code or executable form under the terms of
|
||||||
Paragraphs 1 and 2 above provided that you also do one of the following:
|
Paragraphs 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
a) accompany it with the complete corresponding machine-readable
|
a) accompany it with the complete corresponding machine-readable
|
||||||
source code, which must be distributed under the terms of
|
source code, which must be distributed under the terms of
|
||||||
Paragraphs 1 and 2 above; or,
|
Paragraphs 1 and 2 above; or,
|
||||||
|
|
||||||
b) accompany it with a written offer, valid for at least three
|
b) accompany it with a written offer, valid for at least three
|
||||||
years, to give any third party free (except for a nominal charge
|
years, to give any third party free (except for a nominal charge
|
||||||
for the cost of distribution) a complete machine-readable copy of the
|
for the cost of distribution) a complete machine-readable copy of the
|
||||||
corresponding source code, to be distributed under the terms of
|
corresponding source code, to be distributed under the terms of
|
||||||
Paragraphs 1 and 2 above; or,
|
Paragraphs 1 and 2 above; or,
|
||||||
|
|
||||||
c) accompany it with the information you received as to where the
|
c) accompany it with the information you received as to where the
|
||||||
corresponding source code may be obtained. (This alternative is
|
corresponding source code may be obtained. (This alternative is
|
||||||
allowed only for noncommercial distribution and only if you
|
allowed only for noncommercial distribution and only if you
|
||||||
received the program in object code or executable form alone.)
|
received the program in object code or executable form alone.)
|
||||||
|
|
||||||
Source code for a work means the preferred form of the work for making
|
Source code for a work means the preferred form of the work for making
|
||||||
modifications to it. For an executable file, complete source code means
|
modifications to it. For an executable file, complete source code means
|
||||||
all the source code for all modules it contains; but, as a special
|
all the source code for all modules it contains; but, as a special
|
||||||
exception, it need not include source code for modules which are standard
|
exception, it need not include source code for modules which are standard
|
||||||
libraries that accompany the operating system on which the executable
|
libraries that accompany the operating system on which the executable
|
||||||
file runs, or for standard header files or definitions files that
|
file runs, or for standard header files or definitions files that
|
||||||
accompany that operating system.
|
accompany that operating system.
|
||||||
|
|
||||||
4. You may not copy, modify, sublicense, distribute or transfer the
|
4. You may not copy, modify, sublicense, distribute or transfer the
|
||||||
Program except as expressly provided under this General Public License.
|
Program except as expressly provided under this General Public License.
|
||||||
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
|
Any attempt otherwise to copy, modify, sublicense, distribute or transfer
|
||||||
the Program is void, and will automatically terminate your rights to use
|
the Program is void, and will automatically terminate your rights to use
|
||||||
the Program under this License. However, parties who have received
|
the Program under this License. However, parties who have received
|
||||||
copies, or rights to use copies, from you under this General Public
|
copies, or rights to use copies, from you under this General Public
|
||||||
License will not have their licenses terminated so long as such parties
|
License will not have their licenses terminated so long as such parties
|
||||||
remain in full compliance.
|
remain in full compliance.
|
||||||
|
|
||||||
5. By copying, distributing or modifying the Program (or any work based
|
5. By copying, distributing or modifying the Program (or any work based
|
||||||
on the Program) you indicate your acceptance of this license to do so,
|
on the Program) you indicate your acceptance of this license to do so,
|
||||||
and all its terms and conditions.
|
and all its terms and conditions.
|
||||||
|
|
||||||
6. Each time you redistribute the Program (or any work based on the
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
Program), the recipient automatically receives a license from the original
|
Program), the recipient automatically receives a license from the original
|
||||||
licensor to copy, distribute or modify the Program subject to these
|
licensor to copy, distribute or modify the Program subject to these
|
||||||
terms and conditions. You may not impose any further restrictions on the
|
terms and conditions. You may not impose any further restrictions on the
|
||||||
recipients' exercise of the rights granted herein.
|
recipients' exercise of the rights granted herein.
|
||||||
|
|
||||||
7. The Free Software Foundation may publish revised and/or new versions
|
7. The Free Software Foundation may publish revised and/or new versions
|
||||||
of the General Public License from time to time. Such new versions will
|
of the General Public License from time to time. Such new versions will
|
||||||
be similar in spirit to the present version, but may differ in detail to
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
address new problems or concerns.
|
address new problems or concerns.
|
||||||
|
|
||||||
Each version is given a distinguishing version number. If the Program
|
Each version is given a distinguishing version number. If the Program
|
||||||
specifies a version number of the license which applies to it and "any
|
specifies a version number of the license which applies to it and "any
|
||||||
later version", you have the option of following the terms and conditions
|
later version", you have the option of following the terms and conditions
|
||||||
either of that version or of any later version published by the Free
|
either of that version or of any later version published by the Free
|
||||||
Software Foundation. If the Program does not specify a version number of
|
Software Foundation. If the Program does not specify a version number of
|
||||||
the license, you may choose any version ever published by the Free Software
|
the license, you may choose any version ever published by the Free Software
|
||||||
Foundation.
|
Foundation.
|
||||||
|
|
||||||
8. If you wish to incorporate parts of the Program into other free
|
8. If you wish to incorporate parts of the Program into other free
|
||||||
programs whose distribution conditions are different, write to the author
|
programs whose distribution conditions are different, write to the author
|
||||||
to ask for permission. For software which is copyrighted by the Free
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
Software Foundation, write to the Free Software Foundation; we sometimes
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
make exceptions for this. Our decision will be guided by the two goals
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
of preserving the free status of all derivatives of our free software and
|
of preserving the free status of all derivatives of our free software and
|
||||||
of promoting the sharing and reuse of software generally.
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
NO WARRANTY
|
NO WARRANTY
|
||||||
|
|
||||||
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
9. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
REPAIR OR CORRECTION.
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
10. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
POSSIBILITY OF SUCH DAMAGES.
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
END OF TERMS AND CONDITIONS
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
Appendix: How to Apply These Terms to Your New Programs
|
Appendix: How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
If you develop a new program, and you want it to be of the greatest
|
If you develop a new program, and you want it to be of the greatest
|
||||||
possible use to humanity, the best way to achieve this is to make it
|
possible use to humanity, the best way to achieve this is to make it
|
||||||
free software which everyone can redistribute and change under these
|
free software which everyone can redistribute and change under these
|
||||||
terms.
|
terms.
|
||||||
|
|
||||||
To do so, attach the following notices to the program. It is safest to
|
To do so, attach the following notices to the program. It is safest to
|
||||||
attach them to the start of each source file to most effectively convey
|
attach them to the start of each source file to most effectively convey
|
||||||
the exclusion of warranty; and each file should have at least the
|
the exclusion of warranty; and each file should have at least the
|
||||||
"copyright" line and a pointer to where the full notice is found.
|
"copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
<one line to give the program's name and a brief idea of what it does.>
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
Copyright (C) 19yy <name of author>
|
Copyright (C) 19yy <name of author>
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
This program is free software; you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
the Free Software Foundation; either version 1, or (at your option)
|
the Free Software Foundation; either version 1, or (at your option)
|
||||||
any later version.
|
any later version.
|
||||||
|
|
||||||
This program is distributed in the hope that it will be useful,
|
This program is distributed in the hope that it will be useful,
|
||||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
GNU General Public License for more details.
|
GNU General Public License for more details.
|
||||||
|
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with this program; if not, write to the Free Software Foundation,
|
along with this program; if not, write to the Free Software Foundation,
|
||||||
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
||||||
|
|
||||||
Also add information on how to contact you by electronic and paper mail.
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
If the program is interactive, make it output a short notice like this
|
If the program is interactive, make it output a short notice like this
|
||||||
when it starts in an interactive mode:
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
Gnomovision version 69, Copyright (C) 19xx name of author
|
Gnomovision version 69, Copyright (C) 19xx name of author
|
||||||
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
This is free software, and you are welcome to redistribute it
|
This is free software, and you are welcome to redistribute it
|
||||||
under certain conditions; type `show c' for details.
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
The hypothetical commands `show w' and `show c' should show the
|
The hypothetical commands `show w' and `show c' should show the
|
||||||
appropriate parts of the General Public License. Of course, the
|
appropriate parts of the General Public License. Of course, the
|
||||||
commands you use may be called something other than `show w' and `show
|
commands you use may be called something other than `show w' and `show
|
||||||
c'; they could even be mouse-clicks or menu items--whatever suits your
|
c'; they could even be mouse-clicks or menu items--whatever suits your
|
||||||
program.
|
program.
|
||||||
|
|
||||||
You should also get your employer (if you work as a programmer) or your
|
You should also get your employer (if you work as a programmer) or your
|
||||||
school, if any, to sign a "copyright disclaimer" for the program, if
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
necessary. Here a sample; alter the names:
|
necessary. Here a sample; alter the names:
|
||||||
|
|
||||||
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the
|
||||||
program `Gnomovision' (a program to direct compilers to make passes
|
program `Gnomovision' (a program to direct compilers to make passes
|
||||||
at assemblers) written by James Hacker.
|
at assemblers) written by James Hacker.
|
||||||
|
|
||||||
<signature of Ty Coon>, 1 April 1989
|
<signature of Ty Coon>, 1 April 1989
|
||||||
Ty Coon, President of Vice
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
That's all there is to it!
|
That's all there is to it!
|
||||||
|
|||||||
+1
-1
@@ -84,7 +84,7 @@ void Module::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
|||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{ Dsymbol *s = members->tdata()[i];
|
{ Dsymbol *s = (*members)[i];
|
||||||
|
|
||||||
s->toHBuffer(buf, hgs);
|
s->toHBuffer(buf, hgs);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||||
// See the included readme.txt for details.
|
// See the included readme.txt for details.
|
||||||
|
|
||||||
|
#include <string.h> // memset()
|
||||||
|
|
||||||
struct HdrGenState
|
struct HdrGenState
|
||||||
{
|
{
|
||||||
|
|||||||
+3
-1
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -66,6 +66,7 @@ Msgtable msgtable[] =
|
|||||||
{ "outer" },
|
{ "outer" },
|
||||||
{ "Exception" },
|
{ "Exception" },
|
||||||
{ "AssociativeArray" },
|
{ "AssociativeArray" },
|
||||||
|
{ "RTInfo" },
|
||||||
{ "Throwable" },
|
{ "Throwable" },
|
||||||
{ "Error" },
|
{ "Error" },
|
||||||
{ "withSym", "__withSym" },
|
{ "withSym", "__withSym" },
|
||||||
@@ -356,6 +357,7 @@ Msgtable msgtable[] =
|
|||||||
{ "derivedMembers" },
|
{ "derivedMembers" },
|
||||||
{ "isSame" },
|
{ "isSame" },
|
||||||
{ "compiles" },
|
{ "compiles" },
|
||||||
|
{ "parameters" },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+35
-7
@@ -45,7 +45,7 @@ Import::Import(Loc loc, Identifiers *packages, Identifier *id, Identifier *alias
|
|||||||
this->ident = aliasId;
|
this->ident = aliasId;
|
||||||
// import [std].stdio;
|
// import [std].stdio;
|
||||||
else if (packages && packages->dim)
|
else if (packages && packages->dim)
|
||||||
this->ident = packages->tdata()[0];
|
this->ident = (*packages)[0];
|
||||||
// import [foo];
|
// import [foo];
|
||||||
else
|
else
|
||||||
this->ident = id;
|
this->ident = id;
|
||||||
@@ -112,8 +112,18 @@ void Import::load(Scope *sc)
|
|||||||
if (s->isModule())
|
if (s->isModule())
|
||||||
mod = (Module *)s;
|
mod = (Module *)s;
|
||||||
else
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -356,8 +366,8 @@ int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
|
|||||||
*/
|
*/
|
||||||
for (size_t i = 0; i < names.dim; i++)
|
for (size_t i = 0; i < names.dim; i++)
|
||||||
{
|
{
|
||||||
Identifier *name = names.tdata()[i];
|
Identifier *name = names[i];
|
||||||
Identifier *alias = aliases.tdata()[i];
|
Identifier *alias = aliases[i];
|
||||||
|
|
||||||
if (!alias)
|
if (!alias)
|
||||||
alias = name;
|
alias = name;
|
||||||
@@ -413,12 +423,30 @@ void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
|||||||
if (packages && packages->dim)
|
if (packages && packages->dim)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < packages->dim; i++)
|
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.", 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();
|
buf->writenl();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+5
-1
@@ -1,6 +1,6 @@
|
|||||||
/*
|
/*
|
||||||
* Some portions copyright (c) 1994-1995 by Symantec
|
* 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
|
* All Rights Reserved
|
||||||
* http://www.digitalmars.com
|
* http://www.digitalmars.com
|
||||||
* Written by Walter Bright
|
* Written by Walter Bright
|
||||||
@@ -31,6 +31,10 @@
|
|||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if linux || __APPLE__ || __FreeBSD__ || __OpenBSD__
|
||||||
|
#include "gnuc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "root.h"
|
#include "root.h"
|
||||||
#include "rmem.h"
|
#include "rmem.h"
|
||||||
|
|
||||||
|
|||||||
+64
-13
@@ -35,7 +35,7 @@ Initializer *Initializer::syntaxCopy()
|
|||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Initializer *Initializer::semantic(Scope *sc, Type *t, int needInterpret)
|
Initializer *Initializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret)
|
||||||
{
|
{
|
||||||
return this;
|
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);
|
//printf("VoidInitializer::semantic(t = %p)\n", t);
|
||||||
type = t;
|
type = t;
|
||||||
@@ -145,7 +145,7 @@ void StructInitializer::addInit(Identifier *field, Initializer *value)
|
|||||||
this->value.push(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;
|
int errors = 0;
|
||||||
|
|
||||||
@@ -227,7 +227,7 @@ Initializer *StructInitializer::semantic(Scope *sc, Type *t, int needInterpret)
|
|||||||
}
|
}
|
||||||
if (s && (v = s->isVarDeclaration()) != NULL)
|
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;
|
value[i] = val;
|
||||||
vars[i] = v;
|
vars[i] = v;
|
||||||
}
|
}
|
||||||
@@ -353,8 +353,12 @@ Expression *StructInitializer::toExpression()
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!(*elements)[i])
|
if (!(*elements)[i])
|
||||||
// Default initialize
|
{ // Default initialize
|
||||||
(*elements)[i] = vd->type->defaultInit();
|
if (vd->init)
|
||||||
|
(*elements)[i] = vd->init->toExpression();
|
||||||
|
else
|
||||||
|
(*elements)[i] = vd->type->defaultInit();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
offset = vd->offset + vd->type->size();
|
offset = vd->offset + vd->type->size();
|
||||||
i++;
|
i++;
|
||||||
@@ -464,7 +468,7 @@ void ArrayInitializer::addInit(Expression *index, Initializer *value)
|
|||||||
type = NULL;
|
type = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret)
|
Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, NeedInterpret needInterpret)
|
||||||
{ unsigned i;
|
{ unsigned i;
|
||||||
unsigned length;
|
unsigned length;
|
||||||
const unsigned amax = 0x80000000;
|
const unsigned amax = 0x80000000;
|
||||||
@@ -482,6 +486,10 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret)
|
|||||||
case Tarray:
|
case Tarray:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case Tvector:
|
||||||
|
t = ((TypeVector *)t)->basetype;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
error(loc, "cannot use array to initialize %s", type->toChars());
|
error(loc, "cannot use array to initialize %s", type->toChars());
|
||||||
goto Lerr;
|
goto Lerr;
|
||||||
@@ -493,14 +501,39 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret)
|
|||||||
Expression *idx = index[i];
|
Expression *idx = index[i];
|
||||||
if (idx)
|
if (idx)
|
||||||
{ idx = idx->semantic(sc);
|
{ idx = idx->semantic(sc);
|
||||||
idx = idx->optimize(WANTvalue | WANTinterpret);
|
idx = idx->ctfeInterpret();
|
||||||
index[i] = idx;
|
index[i] = idx;
|
||||||
length = idx->toInteger();
|
length = idx->toInteger();
|
||||||
}
|
}
|
||||||
|
|
||||||
Initializer *val = value[i];
|
Initializer *val = value[i];
|
||||||
|
ExpInitializer *ei = val->isExpInitializer();
|
||||||
|
if (ei && !idx)
|
||||||
|
ei->expandTuples = 1;
|
||||||
val = val->semantic(sc, t->nextOf(), needInterpret);
|
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++;
|
length++;
|
||||||
if (length == 0)
|
if (length == 0)
|
||||||
{ error(loc, "array dimension overflow");
|
{ error(loc, "array dimension overflow");
|
||||||
@@ -746,6 +779,7 @@ ExpInitializer::ExpInitializer(Loc loc, Expression *exp)
|
|||||||
: Initializer(loc)
|
: Initializer(loc)
|
||||||
{
|
{
|
||||||
this->exp = exp;
|
this->exp = exp;
|
||||||
|
this->expandTuples = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Initializer *ExpInitializer::syntaxCopy()
|
Initializer *ExpInitializer::syntaxCopy()
|
||||||
@@ -757,6 +791,9 @@ bool arrayHasNonConstPointers(Expressions *elems);
|
|||||||
|
|
||||||
bool hasNonConstPointers(Expression *e)
|
bool hasNonConstPointers(Expression *e)
|
||||||
{
|
{
|
||||||
|
if (e->type->ty == Terror)
|
||||||
|
return false;
|
||||||
|
|
||||||
if (e->op == TOKnull)
|
if (e->op == TOKnull)
|
||||||
return false;
|
return false;
|
||||||
if (e->op == TOKstructliteral)
|
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());
|
//printf("ExpInitializer::semantic(%s), type = %s\n", exp->toChars(), t->toChars());
|
||||||
exp = exp->semantic(sc);
|
exp = exp->semantic(sc);
|
||||||
exp = resolveProperties(sc, exp);
|
exp = resolveProperties(sc, exp);
|
||||||
int wantOptimize = needInterpret ? WANTinterpret|WANTvalue : WANTvalue;
|
if (exp->op == TOKerror)
|
||||||
|
return this;
|
||||||
|
|
||||||
int olderrors = global.errors;
|
int olderrors = global.errors;
|
||||||
exp = exp->optimize(wantOptimize);
|
if (needInterpret)
|
||||||
|
exp = exp->ctfeInterpret();
|
||||||
|
else
|
||||||
|
exp = exp->optimize(WANTvalue);
|
||||||
if (!global.gag && olderrors != global.errors)
|
if (!global.gag && olderrors != global.errors)
|
||||||
return this; // Failed, suppress duplicate error messages
|
return this; // Failed, suppress duplicate error messages
|
||||||
|
|
||||||
@@ -841,6 +882,11 @@ Initializer *ExpInitializer::semantic(Scope *sc, Type *t, int needInterpret)
|
|||||||
|
|
||||||
Type *tb = t->toBasetype();
|
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
|
/* Look for case of initializing a static array with a too-short
|
||||||
* string literal, such as:
|
* string literal, such as:
|
||||||
* char[5] foo = "abc";
|
* char[5] foo = "abc";
|
||||||
@@ -870,8 +916,13 @@ Initializer *ExpInitializer::semantic(Scope *sc, Type *t, int needInterpret)
|
|||||||
}
|
}
|
||||||
|
|
||||||
exp = exp->implicitCastTo(sc, t);
|
exp = exp->implicitCastTo(sc, t);
|
||||||
|
if (exp->op == TOKerror)
|
||||||
|
return this;
|
||||||
L1:
|
L1:
|
||||||
exp = exp->optimize(wantOptimize);
|
if (needInterpret)
|
||||||
|
exp = exp->ctfeInterpret();
|
||||||
|
else
|
||||||
|
exp = exp->optimize(WANTvalue);
|
||||||
//printf("-ExpInitializer::semantic(): "); exp->print();
|
//printf("-ExpInitializer::semantic(): "); exp->print();
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
+8
-6
@@ -34,6 +34,7 @@ namespace llvm {
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
enum NeedInterpret { INITnointerpret, INITinterpret };
|
||||||
|
|
||||||
struct Initializer : Object
|
struct Initializer : Object
|
||||||
{
|
{
|
||||||
@@ -41,8 +42,8 @@ struct Initializer : Object
|
|||||||
|
|
||||||
Initializer(Loc loc);
|
Initializer(Loc loc);
|
||||||
virtual Initializer *syntaxCopy();
|
virtual Initializer *syntaxCopy();
|
||||||
// needInterpret is WANTinterpret if must be a manifest constant, 0 if not.
|
// needInterpret is INITinterpret if must be a manifest constant, 0 if not.
|
||||||
virtual Initializer *semantic(Scope *sc, Type *t, int needInterpret);
|
virtual Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret);
|
||||||
virtual Type *inferType(Scope *sc);
|
virtual Type *inferType(Scope *sc);
|
||||||
virtual Expression *toExpression() = 0;
|
virtual Expression *toExpression() = 0;
|
||||||
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
|
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
|
||||||
@@ -66,7 +67,7 @@ struct VoidInitializer : Initializer
|
|||||||
|
|
||||||
VoidInitializer(Loc loc);
|
VoidInitializer(Loc loc);
|
||||||
Initializer *syntaxCopy();
|
Initializer *syntaxCopy();
|
||||||
Initializer *semantic(Scope *sc, Type *t, int needInterpret);
|
Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret);
|
||||||
Expression *toExpression();
|
Expression *toExpression();
|
||||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||||
|
|
||||||
@@ -88,7 +89,7 @@ struct StructInitializer : Initializer
|
|||||||
StructInitializer(Loc loc);
|
StructInitializer(Loc loc);
|
||||||
Initializer *syntaxCopy();
|
Initializer *syntaxCopy();
|
||||||
void addInit(Identifier *field, Initializer *value);
|
void addInit(Identifier *field, Initializer *value);
|
||||||
Initializer *semantic(Scope *sc, Type *t, int needInterpret);
|
Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret);
|
||||||
Expression *toExpression();
|
Expression *toExpression();
|
||||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||||
|
|
||||||
@@ -113,7 +114,7 @@ struct ArrayInitializer : Initializer
|
|||||||
ArrayInitializer(Loc loc);
|
ArrayInitializer(Loc loc);
|
||||||
Initializer *syntaxCopy();
|
Initializer *syntaxCopy();
|
||||||
void addInit(Expression *index, Initializer *value);
|
void addInit(Expression *index, Initializer *value);
|
||||||
Initializer *semantic(Scope *sc, Type *t, int needInterpret);
|
Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret);
|
||||||
int isAssociativeArray();
|
int isAssociativeArray();
|
||||||
Type *inferType(Scope *sc);
|
Type *inferType(Scope *sc);
|
||||||
Expression *toExpression();
|
Expression *toExpression();
|
||||||
@@ -131,10 +132,11 @@ struct ArrayInitializer : Initializer
|
|||||||
struct ExpInitializer : Initializer
|
struct ExpInitializer : Initializer
|
||||||
{
|
{
|
||||||
Expression *exp;
|
Expression *exp;
|
||||||
|
int expandTuples;
|
||||||
|
|
||||||
ExpInitializer(Loc loc, Expression *exp);
|
ExpInitializer(Loc loc, Expression *exp);
|
||||||
Initializer *syntaxCopy();
|
Initializer *syntaxCopy();
|
||||||
Initializer *semantic(Scope *sc, Type *t, int needInterpret);
|
Initializer *semantic(Scope *sc, Type *t, NeedInterpret needInterpret);
|
||||||
Type *inferType(Scope *sc);
|
Type *inferType(Scope *sc);
|
||||||
Expression *toExpression();
|
Expression *toExpression();
|
||||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||||
|
|||||||
+78
-18
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -14,6 +14,7 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h> // memset()
|
||||||
|
|
||||||
#include "id.h"
|
#include "id.h"
|
||||||
#include "init.h"
|
#include "init.h"
|
||||||
@@ -618,11 +619,11 @@ Expressions *arrayExpressiondoInline(Expressions *a, InlineDoState *ids)
|
|||||||
newa->setDim(a->dim);
|
newa->setDim(a->dim);
|
||||||
|
|
||||||
for (size_t i = 0; i < a->dim; i++)
|
for (size_t i = 0; i < a->dim; i++)
|
||||||
{ Expression *e = a->tdata()[i];
|
{ Expression *e = (*a)[i];
|
||||||
|
|
||||||
if (e)
|
if (e)
|
||||||
e = e->doInline(ids);
|
e = e->doInline(ids);
|
||||||
newa->tdata()[i] = e;
|
(*newa)[i] = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newa;
|
return newa;
|
||||||
@@ -639,11 +640,11 @@ Expression *SymOffExp::doInline(InlineDoState *ids)
|
|||||||
//printf("SymOffExp::doInline(%s)\n", toChars());
|
//printf("SymOffExp::doInline(%s)\n", toChars());
|
||||||
for (size_t i = 0; i < ids->from.dim; i++)
|
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();
|
SymOffExp *se = (SymOffExp *)copy();
|
||||||
|
|
||||||
se->var = (Declaration *)ids->to.tdata()[i];
|
se->var = (Declaration *)ids->to[i];
|
||||||
return se;
|
return se;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -655,11 +656,11 @@ Expression *VarExp::doInline(InlineDoState *ids)
|
|||||||
//printf("VarExp::doInline(%s)\n", toChars());
|
//printf("VarExp::doInline(%s)\n", toChars());
|
||||||
for (size_t i = 0; i < ids->from.dim; i++)
|
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();
|
VarExp *ve = (VarExp *)copy();
|
||||||
|
|
||||||
ve->var = (Declaration *)ids->to.tdata()[i];
|
ve->var = (Declaration *)ids->to[i];
|
||||||
return ve;
|
return ve;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -709,7 +710,7 @@ Expression *DeclarationExp::doInline(InlineDoState *ids)
|
|||||||
if (td)
|
if (td)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < td->objects->dim; i++)
|
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);
|
assert(se->op == TOKdsymbol);
|
||||||
se->s;
|
se->s;
|
||||||
}
|
}
|
||||||
@@ -1098,8 +1099,8 @@ Statement *SwitchStatement::inlineScan(InlineScanState *iss)
|
|||||||
for (size_t i = 0; i < cases->dim; i++)
|
for (size_t i = 0; i < cases->dim; i++)
|
||||||
{ CaseStatement *s;
|
{ CaseStatement *s;
|
||||||
|
|
||||||
s = cases->tdata()[i];
|
s = (*cases)[i];
|
||||||
cases->tdata()[i] = (CaseStatement *)s->inlineScan(iss);
|
(*cases)[i] = (CaseStatement *)s->inlineScan(iss);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@@ -1130,6 +1131,65 @@ Statement *ReturnStatement::inlineScan(InlineScanState *iss)
|
|||||||
if (exp)
|
if (exp)
|
||||||
{
|
{
|
||||||
exp = exp->inlineScan(iss);
|
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;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -1162,7 +1222,7 @@ Statement *TryCatchStatement::inlineScan(InlineScanState *iss)
|
|||||||
if (catches)
|
if (catches)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < catches->dim; i++)
|
for (size_t i = 0; i < catches->dim; i++)
|
||||||
{ Catch *c = catches->tdata()[i];
|
{ Catch *c = (*catches)[i];
|
||||||
|
|
||||||
if (c->handler)
|
if (c->handler)
|
||||||
c->handler = c->handler->inlineScan(iss);
|
c->handler = c->handler->inlineScan(iss);
|
||||||
@@ -1212,12 +1272,12 @@ void arrayInlineScan(InlineScanState *iss, Expressions *arguments)
|
|||||||
if (arguments)
|
if (arguments)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < arguments->dim; i++)
|
for (size_t i = 0; i < arguments->dim; i++)
|
||||||
{ Expression *e = arguments->tdata()[i];
|
{ Expression *e = (*arguments)[i];
|
||||||
|
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
e = e->inlineScan(iss);
|
e = e->inlineScan(iss);
|
||||||
arguments->tdata()[i] = e;
|
(*arguments)[i] = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1237,7 +1297,7 @@ void scanVar(Dsymbol *s, InlineScanState *iss)
|
|||||||
if (td)
|
if (td)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < td->objects->dim; i++)
|
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);
|
assert(se->op == TOKdsymbol);
|
||||||
scanVar(se->s, iss);
|
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++)
|
for (size_t i = 0; i < parameters->dim; i++)
|
||||||
{
|
{
|
||||||
VarDeclaration *v = parameters->tdata()[i];
|
VarDeclaration *v = (*parameters)[i];
|
||||||
if (v->type->toBasetype()->ty == Tsarray)
|
if (v->type->toBasetype()->ty == Tsarray)
|
||||||
goto Lno;
|
goto Lno;
|
||||||
}
|
}
|
||||||
@@ -1701,9 +1761,9 @@ Expression *FuncDeclaration::expandInline(InlineScanState *iss, Expression *ethi
|
|||||||
|
|
||||||
for (size_t i = 0; i < arguments->dim; i++)
|
for (size_t i = 0; i < arguments->dim; i++)
|
||||||
{
|
{
|
||||||
VarDeclaration *vfrom = parameters->tdata()[i];
|
VarDeclaration *vfrom = (*parameters)[i];
|
||||||
VarDeclaration *vto;
|
VarDeclaration *vto;
|
||||||
Expression *arg = arguments->tdata()[i];
|
Expression *arg = (*arguments)[i];
|
||||||
ExpInitializer *ei;
|
ExpInitializer *ei;
|
||||||
VarExp *ve;
|
VarExp *ve;
|
||||||
|
|
||||||
@@ -1778,7 +1838,7 @@ Expression *FuncDeclaration::expandInline(InlineScanState *iss, Expression *ethi
|
|||||||
|
|
||||||
Identifier* tmp = Identifier::generateId("__inlineretval");
|
Identifier* tmp = Identifier::generateId("__inlineretval");
|
||||||
VarDeclaration* vd = new VarDeclaration(loc, tf->next, tmp, ei);
|
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->linkage = tf->linkage;
|
||||||
vd->parent = iss->fd;
|
vd->parent = iss->fd;
|
||||||
|
|
||||||
|
|||||||
+585
-218
File diff suppressed because it is too large
Load Diff
+9
-9
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -53,7 +53,7 @@ void json_generate(Modules *modules)
|
|||||||
|
|
||||||
buf.writestring("[\n");
|
buf.writestring("[\n");
|
||||||
for (size_t i = 0; i < modules->dim; i++)
|
for (size_t i = 0; i < modules->dim; i++)
|
||||||
{ Module *m = modules->tdata()[i];
|
{ Module *m = (*modules)[i];
|
||||||
if (global.params.verbose)
|
if (global.params.verbose)
|
||||||
printf("json gen %s\n", m->toChars());
|
printf("json gen %s\n", m->toChars());
|
||||||
m->toJsonBuffer(&buf);
|
m->toJsonBuffer(&buf);
|
||||||
@@ -66,7 +66,7 @@ void json_generate(Modules *modules)
|
|||||||
char *arg = global.params.xfilename;
|
char *arg = global.params.xfilename;
|
||||||
if (!arg || !*arg)
|
if (!arg || !*arg)
|
||||||
{ // Generate lib file name from first obj name
|
{ // 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);
|
n = FileName::name(n);
|
||||||
FileName *fn = FileName::forceExt(n, global.json_ext);
|
FileName *fn = FileName::forceExt(n, global.json_ext);
|
||||||
@@ -195,7 +195,7 @@ void Module::toJsonBuffer(OutBuffer *buf)
|
|||||||
|
|
||||||
size_t offset = buf->offset;
|
size_t offset = buf->offset;
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{ Dsymbol *s = members->tdata()[i];
|
{ Dsymbol *s = (*members)[i];
|
||||||
if (offset != buf->offset)
|
if (offset != buf->offset)
|
||||||
{ buf->writestring(",\n");
|
{ buf->writestring(",\n");
|
||||||
offset = buf->offset;
|
offset = buf->offset;
|
||||||
@@ -219,7 +219,7 @@ void AttribDeclaration::toJsonBuffer(OutBuffer *buf)
|
|||||||
{
|
{
|
||||||
size_t offset = buf->offset;
|
size_t offset = buf->offset;
|
||||||
for (unsigned i = 0; i < d->dim; i++)
|
for (unsigned i = 0; i < d->dim; i++)
|
||||||
{ Dsymbol *s = d->tdata()[i];
|
{ Dsymbol *s = (*d)[i];
|
||||||
//printf("AttribDeclaration::toJsonBuffer %s\n", s->toChars());
|
//printf("AttribDeclaration::toJsonBuffer %s\n", s->toChars());
|
||||||
if (offset != buf->offset)
|
if (offset != buf->offset)
|
||||||
{ buf->writestring(",\n");
|
{ buf->writestring(",\n");
|
||||||
@@ -332,7 +332,7 @@ void AggregateDeclaration::toJsonBuffer(OutBuffer *buf)
|
|||||||
buf->writestring(" : [\n");
|
buf->writestring(" : [\n");
|
||||||
size_t offset = buf->offset;
|
size_t offset = buf->offset;
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{ Dsymbol *s = members->tdata()[i];
|
{ Dsymbol *s = (*members)[i];
|
||||||
if (offset != buf->offset)
|
if (offset != buf->offset)
|
||||||
{ buf->writestring(",\n");
|
{ buf->writestring(",\n");
|
||||||
offset = buf->offset;
|
offset = buf->offset;
|
||||||
@@ -369,7 +369,7 @@ void TemplateDeclaration::toJsonBuffer(OutBuffer *buf)
|
|||||||
buf->writestring(" : [\n");
|
buf->writestring(" : [\n");
|
||||||
size_t offset = buf->offset;
|
size_t offset = buf->offset;
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{ Dsymbol *s = members->tdata()[i];
|
{ Dsymbol *s = (*members)[i];
|
||||||
if (offset != buf->offset)
|
if (offset != buf->offset)
|
||||||
{ buf->writestring(",\n");
|
{ buf->writestring(",\n");
|
||||||
offset = buf->offset;
|
offset = buf->offset;
|
||||||
@@ -391,7 +391,7 @@ void EnumDeclaration::toJsonBuffer(OutBuffer *buf)
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = members->tdata()[i];
|
Dsymbol *s = (*members)[i];
|
||||||
s->toJsonBuffer(buf);
|
s->toJsonBuffer(buf);
|
||||||
buf->writestring(",\n");
|
buf->writestring(",\n");
|
||||||
}
|
}
|
||||||
@@ -423,7 +423,7 @@ void EnumDeclaration::toJsonBuffer(OutBuffer *buf)
|
|||||||
buf->writestring(" : [\n");
|
buf->writestring(" : [\n");
|
||||||
size_t offset = buf->offset;
|
size_t offset = buf->offset;
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{ Dsymbol *s = members->tdata()[i];
|
{ Dsymbol *s = (*members)[i];
|
||||||
if (offset != buf->offset)
|
if (offset != buf->offset)
|
||||||
{ buf->writestring(",\n");
|
{ buf->writestring(",\n");
|
||||||
offset = buf->offset;
|
offset = buf->offset;
|
||||||
|
|||||||
+28
-171
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -108,14 +108,22 @@ const char *Token::toChars()
|
|||||||
switch (value)
|
switch (value)
|
||||||
{
|
{
|
||||||
case TOKint32v:
|
case TOKint32v:
|
||||||
|
#if defined(IN_GCC) || defined(IN_LLVM)
|
||||||
sprintf(buffer,"%d",(d_int32)int64value);
|
sprintf(buffer,"%d",(d_int32)int64value);
|
||||||
|
#else
|
||||||
|
sprintf(buffer,"%d",int32value);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOKuns32v:
|
case TOKuns32v:
|
||||||
case TOKcharv:
|
case TOKcharv:
|
||||||
case TOKwcharv:
|
case TOKwcharv:
|
||||||
case TOKdcharv:
|
case TOKdcharv:
|
||||||
|
#ifdef defined(IN_GCC) || defined(IN_LLVM)
|
||||||
sprintf(buffer,"%uU",(d_uns32)uns64value);
|
sprintf(buffer,"%uU",(d_uns32)uns64value);
|
||||||
|
#else
|
||||||
|
sprintf(buffer,"%uU",uns32value);
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOKint64v:
|
case TOKint64v:
|
||||||
@@ -126,7 +134,7 @@ const char *Token::toChars()
|
|||||||
sprintf(buffer,"%lluUL",(uintmax_t)uns64value);
|
sprintf(buffer,"%lluUL",(uintmax_t)uns64value);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
case TOKfloat32v:
|
case TOKfloat32v:
|
||||||
case TOKfloat64v:
|
case TOKfloat64v:
|
||||||
case TOKfloat80v:
|
case TOKfloat80v:
|
||||||
@@ -171,9 +179,6 @@ const char *Token::toChars()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
case TOKstring:
|
case TOKstring:
|
||||||
#if CSTRINGS
|
|
||||||
p = string;
|
|
||||||
#else
|
|
||||||
{ OutBuffer buf;
|
{ OutBuffer buf;
|
||||||
|
|
||||||
buf.writeByte('"');
|
buf.writeByte('"');
|
||||||
@@ -208,7 +213,6 @@ const char *Token::toChars()
|
|||||||
buf.writeByte(0);
|
buf.writeByte(0);
|
||||||
p = (char *)buf.extractData();
|
p = (char *)buf.extractData();
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TOKidentifier:
|
case TOKidentifier:
|
||||||
@@ -305,7 +309,7 @@ void Lexer::error(const char *format, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
verror(tokenLoc(), format, ap);
|
::verror(tokenLoc(), format, ap);
|
||||||
va_end(ap);
|
va_end(ap);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,34 +317,10 @@ void Lexer::error(Loc loc, const char *format, ...)
|
|||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
va_start(ap, format);
|
va_start(ap, format);
|
||||||
verror(loc, format, ap);
|
::verror(loc, format, ap);
|
||||||
va_end(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()
|
TOK Lexer::nextToken()
|
||||||
{ Token *t;
|
{ Token *t;
|
||||||
|
|
||||||
@@ -524,30 +504,6 @@ void Lexer::scan(Token *t)
|
|||||||
t->value = number(t);
|
t->value = number(t);
|
||||||
return;
|
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 '\'':
|
case '\'':
|
||||||
t->value = charConstant(t,0);
|
t->value = charConstant(t,0);
|
||||||
return;
|
return;
|
||||||
@@ -627,12 +583,9 @@ void Lexer::scan(Token *t)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
case 'l':
|
|
||||||
case 'L':
|
|
||||||
#endif
|
|
||||||
case 'a': case 'b': case 'c': case 'd': case 'e':
|
case 'a': case 'b': case 'c': case 'd': case 'e':
|
||||||
case 'f': case 'g': case 'h': case 'i': case 'j':
|
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
|
#if DMDV2
|
||||||
case 'p': /*case 'q': case 'r':*/ case 's': case 't':
|
case 'p': /*case 'q': case 'r':*/ case 's': case 't':
|
||||||
#else
|
#else
|
||||||
@@ -642,7 +595,7 @@ void Lexer::scan(Token *t)
|
|||||||
case 'z':
|
case 'z':
|
||||||
case 'A': case 'B': case 'C': case 'D': case 'E':
|
case 'A': case 'B': case 'C': case 'D': case 'E':
|
||||||
case 'F': case 'G': case 'H': case 'I': case 'J':
|
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 'P': case 'Q': case 'R': case 'S': case 'T':
|
||||||
case 'U': case 'V': case 'W': case 'X': case 'Y':
|
case 'U': case 'V': case 'W': case 'X': case 'Y':
|
||||||
case 'Z':
|
case 'Z':
|
||||||
@@ -669,7 +622,7 @@ void Lexer::scan(Token *t)
|
|||||||
StringValue *sv = stringtable.update((char *)t->ptr, p - t->ptr);
|
StringValue *sv = stringtable.update((char *)t->ptr, p - t->ptr);
|
||||||
Identifier *id = (Identifier *) sv->ptrvalue;
|
Identifier *id = (Identifier *) sv->ptrvalue;
|
||||||
if (!id)
|
if (!id)
|
||||||
{ id = new Identifier(sv->lstring.string,TOKidentifier);
|
{ id = new Identifier(sv->toDchars(),TOKidentifier);
|
||||||
sv->ptrvalue = id;
|
sv->ptrvalue = id;
|
||||||
}
|
}
|
||||||
t->ident = id;
|
t->ident = id;
|
||||||
@@ -1228,10 +1181,10 @@ void Lexer::scan(Token *t)
|
|||||||
case '#':
|
case '#':
|
||||||
{
|
{
|
||||||
p++;
|
p++;
|
||||||
Token *n = peek(t);
|
Token n;
|
||||||
if (n->value == TOKidentifier && n->ident == Id::line)
|
scan(&n);
|
||||||
|
if (n.value == TOKidentifier && n.ident == Id::line)
|
||||||
{
|
{
|
||||||
nextToken();
|
|
||||||
poundLine();
|
poundLine();
|
||||||
continue;
|
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.
|
* Read in a number.
|
||||||
* If it's an integer, store it in tok.TKutok.Vlong.
|
* 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;
|
enum FLAGS flags = FLAGS_decimal;
|
||||||
|
|
||||||
int base;
|
|
||||||
unsigned c;
|
unsigned c;
|
||||||
unsigned char *start;
|
unsigned char *start;
|
||||||
TOK result;
|
TOK result;
|
||||||
|
|
||||||
//printf("Lexer::number()\n");
|
//printf("Lexer::number()\n");
|
||||||
state = STATE_initial;
|
state = STATE_initial;
|
||||||
base = 0;
|
|
||||||
stringbuffer.reset();
|
stringbuffer.reset();
|
||||||
start = p;
|
start = p;
|
||||||
while (1)
|
while (1)
|
||||||
@@ -2022,11 +1934,6 @@ TOK Lexer::number(Token *t)
|
|||||||
flags = (FLAGS) (flags & ~FLAGS_decimal);
|
flags = (FLAGS) (flags & ~FLAGS_decimal);
|
||||||
switch (c)
|
switch (c)
|
||||||
{
|
{
|
||||||
#if ZEROH
|
|
||||||
case 'H': // 0h
|
|
||||||
case 'h':
|
|
||||||
goto hexh;
|
|
||||||
#endif
|
|
||||||
case 'X':
|
case 'X':
|
||||||
case 'x':
|
case 'x':
|
||||||
state = STATE_hex0;
|
state = STATE_hex0;
|
||||||
@@ -2035,15 +1942,14 @@ TOK Lexer::number(Token *t)
|
|||||||
case '.':
|
case '.':
|
||||||
if (p[1] == '.') // .. is a separate token
|
if (p[1] == '.') // .. is a separate token
|
||||||
goto done;
|
goto done;
|
||||||
|
#if DMDV2
|
||||||
|
if (isalpha(p[1]) || p[1] == '_')
|
||||||
|
goto done;
|
||||||
|
#endif
|
||||||
case 'i':
|
case 'i':
|
||||||
case 'f':
|
case 'f':
|
||||||
case 'F':
|
case 'F':
|
||||||
goto real;
|
goto real;
|
||||||
#if ZEROH
|
|
||||||
case 'E':
|
|
||||||
case 'e':
|
|
||||||
goto case_hex;
|
|
||||||
#endif
|
|
||||||
case 'B':
|
case 'B':
|
||||||
case 'b':
|
case 'b':
|
||||||
state = STATE_binary0;
|
state = STATE_binary0;
|
||||||
@@ -2054,14 +1960,6 @@ TOK Lexer::number(Token *t)
|
|||||||
state = STATE_octal;
|
state = STATE_octal;
|
||||||
break;
|
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 '_':
|
case '_':
|
||||||
state = STATE_octal;
|
state = STATE_octal;
|
||||||
p++;
|
p++;
|
||||||
@@ -2080,12 +1978,6 @@ TOK Lexer::number(Token *t)
|
|||||||
case STATE_decimal: // reading decimal number
|
case STATE_decimal: // reading decimal number
|
||||||
if (!isdigit(c))
|
if (!isdigit(c))
|
||||||
{
|
{
|
||||||
#if ZEROH
|
|
||||||
if (ishex(c)
|
|
||||||
|| c == 'H' || c == 'h'
|
|
||||||
)
|
|
||||||
goto hexh;
|
|
||||||
#endif
|
|
||||||
if (c == '_') // ignore embedded _
|
if (c == '_') // ignore embedded _
|
||||||
{ p++;
|
{ p++;
|
||||||
continue;
|
continue;
|
||||||
@@ -2130,41 +2022,10 @@ TOK Lexer::number(Token *t)
|
|||||||
state = STATE_hex;
|
state = STATE_hex;
|
||||||
break;
|
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_octal: // reading octal number
|
||||||
case STATE_octale: // reading octal number with non-octal digits
|
case STATE_octale: // reading octal number with non-octal digits
|
||||||
if (!isoctal(c))
|
if (!isoctal(c))
|
||||||
{
|
{
|
||||||
#if ZEROH
|
|
||||||
if (ishex(c)
|
|
||||||
|| c == 'H' || c == 'h'
|
|
||||||
)
|
|
||||||
goto hexh;
|
|
||||||
#endif
|
|
||||||
if (c == '_') // ignore embedded _
|
if (c == '_') // ignore embedded _
|
||||||
{ p++;
|
{ p++;
|
||||||
continue;
|
continue;
|
||||||
@@ -2186,12 +2047,6 @@ TOK Lexer::number(Token *t)
|
|||||||
case STATE_binary: // reading binary number
|
case STATE_binary: // reading binary number
|
||||||
if (c != '0' && c != '1')
|
if (c != '0' && c != '1')
|
||||||
{
|
{
|
||||||
#if ZEROH
|
|
||||||
if (ishex(c)
|
|
||||||
|| c == 'H' || c == 'h'
|
|
||||||
)
|
|
||||||
goto hexh;
|
|
||||||
#endif
|
|
||||||
if (c == '_') // ignore embedded _
|
if (c == '_') // ignore embedded _
|
||||||
{ p++;
|
{ p++;
|
||||||
continue;
|
continue;
|
||||||
@@ -2232,7 +2087,7 @@ done:
|
|||||||
// Convert string to integer
|
// Convert string to integer
|
||||||
#if __DMC__
|
#if __DMC__
|
||||||
errno = 0;
|
errno = 0;
|
||||||
n = strtoull((char *)stringbuffer.data,NULL,base);
|
n = strtoull((char *)stringbuffer.data,NULL,0);
|
||||||
if (errno == ERANGE)
|
if (errno == ERANGE)
|
||||||
error("integer overflow");
|
error("integer overflow");
|
||||||
#else
|
#else
|
||||||
@@ -2636,8 +2491,9 @@ void Lexer::poundLine()
|
|||||||
{
|
{
|
||||||
p += 8;
|
p += 8;
|
||||||
filespec = mem.strdup(loc.filename ? loc.filename : mod->ident->toChars());
|
filespec = mem.strdup(loc.filename ? loc.filename : mod->ident->toChars());
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
continue;
|
goto Lerr;
|
||||||
|
|
||||||
case '"':
|
case '"':
|
||||||
if (filespec)
|
if (filespec)
|
||||||
@@ -2920,7 +2776,7 @@ Identifier *Lexer::idPool(const char *s)
|
|||||||
Identifier *id = (Identifier *) sv->ptrvalue;
|
Identifier *id = (Identifier *) sv->ptrvalue;
|
||||||
if (!id)
|
if (!id)
|
||||||
{
|
{
|
||||||
id = new Identifier(sv->lstring.string, TOKidentifier);
|
id = new Identifier(sv->toDchars(), TOKidentifier);
|
||||||
sv->ptrvalue = id;
|
sv->ptrvalue = id;
|
||||||
}
|
}
|
||||||
return id;
|
return id;
|
||||||
@@ -3067,6 +2923,7 @@ static Keyword keywords[] =
|
|||||||
|
|
||||||
// Added after 1.0
|
// Added after 1.0
|
||||||
{ "__argTypes", TOKargTypes },
|
{ "__argTypes", TOKargTypes },
|
||||||
|
{ "__parameters", TOKparameters },
|
||||||
{ "ref", TOKref },
|
{ "ref", TOKref },
|
||||||
{ "macro", TOKmacro },
|
{ "macro", TOKmacro },
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
@@ -3111,7 +2968,7 @@ void Lexer::initKeywords()
|
|||||||
const char *s = keywords[u].name;
|
const char *s = keywords[u].name;
|
||||||
enum TOK v = keywords[u].value;
|
enum TOK v = keywords[u].value;
|
||||||
StringValue *sv = stringtable.insert(s, strlen(s));
|
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);
|
//printf("tochars[%d] = '%s'\n",v, s);
|
||||||
Token::tochars[v] = s;
|
Token::tochars[v] = s;
|
||||||
|
|||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2010 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -156,6 +156,7 @@ enum TOK
|
|||||||
TOKref,
|
TOKref,
|
||||||
TOKmacro,
|
TOKmacro,
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
|
TOKparameters,
|
||||||
TOKtraits,
|
TOKtraits,
|
||||||
TOKoverloadset,
|
TOKoverloadset,
|
||||||
TOKpure,
|
TOKpure,
|
||||||
@@ -311,7 +312,6 @@ struct Lexer
|
|||||||
TOK inreal(Token *t);
|
TOK inreal(Token *t);
|
||||||
void error(const char *format, ...) IS_PRINTF(2);
|
void error(const char *format, ...) IS_PRINTF(2);
|
||||||
void error(Loc loc, const char *format, ...) IS_PRINTF(3);
|
void error(Loc loc, const char *format, ...) IS_PRINTF(3);
|
||||||
void verror(Loc loc, const char *format, va_list ap);
|
|
||||||
void poundLine();
|
void poundLine();
|
||||||
unsigned decodeUTF();
|
unsigned decodeUTF();
|
||||||
void getDocComment(Token *t, unsigned lineComment);
|
void getDocComment(Token *t, unsigned lineComment);
|
||||||
|
|||||||
+8
-46
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2008 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -15,53 +15,15 @@
|
|||||||
#pragma once
|
#pragma once
|
||||||
#endif /* __DMC__ */
|
#endif /* __DMC__ */
|
||||||
|
|
||||||
struct ObjModule;
|
class Library
|
||||||
|
|
||||||
struct ObjSymbol
|
|
||||||
{
|
{
|
||||||
char *name;
|
public:
|
||||||
ObjModule *om;
|
static Library *factory();
|
||||||
};
|
|
||||||
|
|
||||||
#include "arraytypes.h"
|
virtual void setFilename(char *dir, char *filename) = 0;
|
||||||
|
virtual void addObject(const char *module_name, void *buf, size_t buflen) = 0;
|
||||||
typedef ArrayBase<ObjModule> ObjModules;
|
virtual void addLibrary(void *buf, size_t buflen) = 0;
|
||||||
typedef ArrayBase<ObjSymbol> ObjSymbols;
|
virtual void write() = 0;
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* DMD_LIB_H */
|
#endif /* DMD_LIB_H */
|
||||||
|
|||||||
+1
-1
@@ -266,7 +266,7 @@ char *TemplateMixin::mangle()
|
|||||||
p += 2;
|
p += 2;
|
||||||
buf.writestring(p);
|
buf.writestring(p);
|
||||||
}
|
}
|
||||||
buf.printf("%zu%s", strlen(id), id);
|
buf.printf("%llu%s", (ulonglong)strlen(id), id);
|
||||||
id = buf.toChars();
|
id = buf.toChars();
|
||||||
buf.data = NULL;
|
buf.data = NULL;
|
||||||
//printf("TemplateMixin::mangle() %s = %s\n", toChars(), id);
|
//printf("TemplateMixin::mangle() %s = %s\n", toChars(), id);
|
||||||
|
|||||||
+1640
-1634
File diff suppressed because it is too large
Load Diff
+13
-5
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -97,11 +97,13 @@ void unittests();
|
|||||||
|
|
||||||
#define DMDV1 0
|
#define DMDV1 0
|
||||||
#define DMDV2 1 // Version 2.0 features
|
#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 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 SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN
|
||||||
#define SARRAYVALUE DMDV2 // static arrays are value types
|
#define SARRAYVALUE DMDV2 // static arrays are value types
|
||||||
#define MODULEINFO_IS_STRUCT DMDV2 // if ModuleInfo is a struct rather than a class
|
#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
|
// Set if C++ mangling is done by the front end
|
||||||
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS))
|
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_OPENBSD || TARGET_SOLARIS))
|
||||||
@@ -279,6 +281,10 @@ struct Param
|
|||||||
#endif
|
#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
|
struct Global
|
||||||
{
|
{
|
||||||
const char *mars_ext;
|
const char *mars_ext;
|
||||||
@@ -301,7 +307,9 @@ struct Global
|
|||||||
const char *written;
|
const char *written;
|
||||||
Strings *path; // Array of char*'s which form the import lookup path
|
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
|
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;
|
const char *version;
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
char *ldc_version;
|
char *ldc_version;
|
||||||
@@ -473,7 +481,7 @@ typedef uint64_t StorageClass;
|
|||||||
void warning(Loc loc, const char *format, ...) IS_PRINTF(2);
|
void warning(Loc loc, const char *format, ...) IS_PRINTF(2);
|
||||||
void error(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 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 vwarning(Loc loc, const char *format, va_list);
|
||||||
void verrorSupplemental(Loc loc, const char *format, va_list);
|
void verrorSupplemental(Loc loc, const char *format, va_list);
|
||||||
void fatal();
|
void fatal();
|
||||||
@@ -493,7 +501,7 @@ void util_progress();
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*** Where to send error messages ***/
|
/*** Where to send error messages ***/
|
||||||
#if IN_GCC || IN_LLVM
|
#if defined(IN_GCC) || IN_LLVM
|
||||||
#define stdmsg stderr
|
#define stdmsg stderr
|
||||||
#else
|
#else
|
||||||
#define stdmsg stderr
|
#define stdmsg stderr
|
||||||
|
|||||||
+35
-62
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
#include "gdc_alloca.h"
|
#include "gdc_alloca.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -37,7 +37,10 @@
|
|||||||
#include "hdrgen.h"
|
#include "hdrgen.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
|
|
||||||
#include "html.h"
|
// stricmp
|
||||||
|
#if __GNUC__ && !_WIN32
|
||||||
|
#include "gnuc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef IN_GCC
|
#ifdef IN_GCC
|
||||||
#include "d-dmd-gcc.h"
|
#include "d-dmd-gcc.h"
|
||||||
@@ -88,7 +91,6 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
|
|||||||
errors = 0;
|
errors = 0;
|
||||||
numlines = 0;
|
numlines = 0;
|
||||||
members = NULL;
|
members = NULL;
|
||||||
isHtml = 0;
|
|
||||||
isDocFile = 0;
|
isDocFile = 0;
|
||||||
needmoduleinfo = 0;
|
needmoduleinfo = 0;
|
||||||
#ifdef IN_GCC
|
#ifdef IN_GCC
|
||||||
@@ -146,17 +148,8 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
|
|||||||
!srcfilename->equalsExt(global.hdr_ext) &&
|
!srcfilename->equalsExt(global.hdr_ext) &&
|
||||||
!srcfilename->equalsExt("dd"))
|
!srcfilename->equalsExt("dd"))
|
||||||
{
|
{
|
||||||
if (srcfilename->equalsExt("html") ||
|
error("source file name '%s' must have .%s extension", srcfilename->toChars(), global.mars_ext);
|
||||||
srcfilename->equalsExt("htm") ||
|
fatal();
|
||||||
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();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#if !IN_LLVM
|
#if !IN_LLVM
|
||||||
char *argobj;
|
char *argobj;
|
||||||
@@ -438,7 +431,7 @@ Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
|
|||||||
OutBuffer buf;
|
OutBuffer buf;
|
||||||
|
|
||||||
for (size_t i = 0; i < packages->dim; i++)
|
for (size_t i = 0; i < packages->dim; i++)
|
||||||
{ Identifier *pid = packages->tdata()[i];
|
{ Identifier *pid = (*packages)[i];
|
||||||
|
|
||||||
buf.writestring(pid->toChars());
|
buf.writestring(pid->toChars());
|
||||||
#if _WIN32
|
#if _WIN32
|
||||||
@@ -499,7 +492,7 @@ Module *Module::load(Loc loc, Identifiers *packages, Identifier *ident)
|
|||||||
if (packages)
|
if (packages)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < packages->dim; i++)
|
for (size_t i = 0; i < packages->dim; i++)
|
||||||
{ Identifier *pid = packages->tdata()[i];
|
{ Identifier *pid = (*packages)[i];
|
||||||
printf("%s.", pid->toChars());
|
printf("%s.", pid->toChars());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -530,7 +523,7 @@ bool Module::read(Loc loc)
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < global.path->dim; i++)
|
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);
|
fprintf(stdmsg, "import path[%llu] = %s\n", (ulonglong)i, p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -579,24 +572,17 @@ inline unsigned readlongBE(unsigned *p)
|
|||||||
|
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
void Module::parse(bool gen_docs)
|
void Module::parse(bool gen_docs)
|
||||||
#elif IN_GCC
|
|
||||||
void Module::parse(bool dump_source)
|
|
||||||
#else
|
#else
|
||||||
void Module::parse()
|
void Module::parse()
|
||||||
#endif
|
#endif
|
||||||
{ char *srcname;
|
{
|
||||||
unsigned char *buf;
|
|
||||||
unsigned buflen;
|
|
||||||
unsigned le;
|
|
||||||
unsigned bom;
|
|
||||||
|
|
||||||
//printf("Module::parse()\n");
|
//printf("Module::parse()\n");
|
||||||
|
|
||||||
srcname = srcfile->name->toChars();
|
char *srcname = srcfile->name->toChars();
|
||||||
//printf("Module::parse(srcname = '%s')\n", srcname);
|
//printf("Module::parse(srcname = '%s')\n", srcname);
|
||||||
|
|
||||||
buf = srcfile->buffer;
|
unsigned char *buf = srcfile->buffer;
|
||||||
buflen = srcfile->len;
|
unsigned buflen = srcfile->len;
|
||||||
|
|
||||||
if (buflen >= 2)
|
if (buflen >= 2)
|
||||||
{
|
{
|
||||||
@@ -609,7 +595,8 @@ void Module::parse()
|
|||||||
* EF BB BF UTF-8
|
* 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 (buf[0] == 0xFF && buf[1] == 0xFE)
|
||||||
{
|
{
|
||||||
if (buflen >= 4 && buf[2] == 0 && buf[3] == 0)
|
if (buflen >= 4 && buf[2] == 0 && buf[3] == 0)
|
||||||
@@ -760,7 +747,7 @@ void Module::parse()
|
|||||||
|
|
||||||
#ifdef IN_GCC
|
#ifdef IN_GCC
|
||||||
// dump utf-8 encoded source
|
// dump utf-8 encoded source
|
||||||
if (dump_source)
|
if (global.params.dump_source)
|
||||||
{ // %% srcname could contain a path ...
|
{ // %% srcname could contain a path ...
|
||||||
d_gcc_dump_source(srcname, "utf-8", buf, buflen);
|
d_gcc_dump_source(srcname, "utf-8", buf, buflen);
|
||||||
}
|
}
|
||||||
@@ -779,19 +766,6 @@ void Module::parse()
|
|||||||
#endif
|
#endif
|
||||||
return;
|
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
|
#if IN_LLVM
|
||||||
Parser p(this, buf, buflen, gen_docs);
|
Parser p(this, buf, buflen, gen_docs);
|
||||||
#else
|
#else
|
||||||
@@ -890,7 +864,7 @@ void Module::importAll(Scope *prevsc)
|
|||||||
symtab = new DsymbolTable();
|
symtab = new DsymbolTable();
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = members->tdata()[i];
|
Dsymbol *s = (*members)[i];
|
||||||
s->addMember(NULL, sc->scopesym, 1);
|
s->addMember(NULL, sc->scopesym, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -903,13 +877,13 @@ void Module::importAll(Scope *prevsc)
|
|||||||
*/
|
*/
|
||||||
setScope(sc); // remember module scope for semantic
|
setScope(sc); // remember module scope for semantic
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{ Dsymbol *s = members->tdata()[i];
|
{ Dsymbol *s = (*members)[i];
|
||||||
s->setScope(sc);
|
s->setScope(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = members->tdata()[i];
|
Dsymbol *s = (*members)[i];
|
||||||
s->importAll(sc);
|
s->importAll(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -964,7 +938,7 @@ void Module::semantic(Scope* unused_sc)
|
|||||||
|
|
||||||
// Do semantic() on members that don't depend on others
|
// Do semantic() on members that don't depend on others
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
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());
|
//printf("\tModule('%s'): '%s'.semantic0()\n", toChars(), s->toChars());
|
||||||
s->semantic0(sc);
|
s->semantic0(sc);
|
||||||
@@ -972,7 +946,7 @@ void Module::semantic(Scope* unused_sc)
|
|||||||
|
|
||||||
// Pass 1 semantic routines: do public side of the definition
|
// Pass 1 semantic routines: do public side of the definition
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
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());
|
//printf("\tModule('%s'): '%s'.semantic()\n", toChars(), s->toChars());
|
||||||
s->semantic(sc);
|
s->semantic(sc);
|
||||||
@@ -993,7 +967,7 @@ void Module::semantic2(Scope* unused_sc)
|
|||||||
{
|
{
|
||||||
for (size_t i = 0; i < deferred.dim; i++)
|
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");
|
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++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{ Dsymbol *s;
|
{ Dsymbol *s;
|
||||||
|
|
||||||
s = members->tdata()[i];
|
s = (*members)[i];
|
||||||
s->semantic2(sc);
|
s->semantic2(sc);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1045,7 +1019,7 @@ void Module::semantic3(Scope* unused_sc)
|
|||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{ Dsymbol *s;
|
{ Dsymbol *s;
|
||||||
|
|
||||||
s = members->tdata()[i];
|
s = (*members)[i];
|
||||||
//printf("Module %s: %s.semantic3()\n", toChars(), s->toChars());
|
//printf("Module %s: %s.semantic3()\n", toChars(), s->toChars());
|
||||||
s->semantic3(sc);
|
s->semantic3(sc);
|
||||||
}
|
}
|
||||||
@@ -1068,7 +1042,7 @@ void Module::inlineScan()
|
|||||||
//printf("Module = %p\n", sc.scopesym);
|
//printf("Module = %p\n", sc.scopesym);
|
||||||
|
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{ Dsymbol *s = members->tdata()[i];
|
{ Dsymbol *s = (*members)[i];
|
||||||
//if (global.params.verbose)
|
//if (global.params.verbose)
|
||||||
//printf("inline scan symbol %s\n", s->toChars());
|
//printf("inline scan symbol %s\n", s->toChars());
|
||||||
|
|
||||||
@@ -1093,7 +1067,7 @@ void Module::gensymfile()
|
|||||||
buf.writenl();
|
buf.writenl();
|
||||||
|
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{ Dsymbol *s = members->tdata()[i];
|
{ Dsymbol *s = (*members)[i];
|
||||||
|
|
||||||
s->toCBuffer(&buf, &hgs);
|
s->toCBuffer(&buf, &hgs);
|
||||||
}
|
}
|
||||||
@@ -1154,7 +1128,7 @@ Dsymbol *Module::symtabInsert(Dsymbol *s)
|
|||||||
void Module::clearCache()
|
void Module::clearCache()
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < amodules.dim; i++)
|
for (size_t i = 0; i < amodules.dim; i++)
|
||||||
{ Module *m = amodules.tdata()[i];
|
{ Module *m = amodules[i];
|
||||||
m->searchCacheIdent = NULL;
|
m->searchCacheIdent = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1168,7 +1142,7 @@ void Module::addDeferredSemantic(Dsymbol *s)
|
|||||||
// Don't add it if it is already there
|
// Don't add it if it is already there
|
||||||
for (size_t i = 0; i < deferred.dim; i++)
|
for (size_t i = 0; i < deferred.dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *sd = deferred.tdata()[i];
|
Dsymbol *sd = deferred[i];
|
||||||
|
|
||||||
if (sd == s)
|
if (sd == s)
|
||||||
return;
|
return;
|
||||||
@@ -1238,7 +1212,6 @@ void Module::runDeferredSemantic()
|
|||||||
int Module::imports(Module *m)
|
int Module::imports(Module *m)
|
||||||
{
|
{
|
||||||
//printf("%s Module::imports(%s)\n", toChars(), m->toChars());
|
//printf("%s Module::imports(%s)\n", toChars(), m->toChars());
|
||||||
int aimports_dim = aimports.dim;
|
|
||||||
#if 0
|
#if 0
|
||||||
for (size_t i = 0; i < aimports.dim; i++)
|
for (size_t i = 0; i < aimports.dim; i++)
|
||||||
{ Module *mi = (Module *)aimports.data[i];
|
{ Module *mi = (Module *)aimports.data[i];
|
||||||
@@ -1246,7 +1219,7 @@ int Module::imports(Module *m)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
for (size_t i = 0; i < aimports.dim; i++)
|
for (size_t i = 0; i < aimports.dim; i++)
|
||||||
{ Module *mi = aimports.tdata()[i];
|
{ Module *mi = aimports[i];
|
||||||
if (mi == m)
|
if (mi == m)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
if (!mi->insearch)
|
if (!mi->insearch)
|
||||||
@@ -1270,7 +1243,7 @@ int Module::selfImports()
|
|||||||
if (!selfimports)
|
if (!selfimports)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < amodules.dim; i++)
|
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());
|
//printf("\t[%d] %s\n", i, mi->toChars());
|
||||||
mi->insearch = 0;
|
mi->insearch = 0;
|
||||||
}
|
}
|
||||||
@@ -1278,7 +1251,7 @@ int Module::selfImports()
|
|||||||
selfimports = imports(this) + 1;
|
selfimports = imports(this) + 1;
|
||||||
|
|
||||||
for (size_t i = 0; i < amodules.dim; i++)
|
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());
|
//printf("\t[%d] %s\n", i, mi->toChars());
|
||||||
mi->insearch = 0;
|
mi->insearch = 0;
|
||||||
}
|
}
|
||||||
@@ -1303,7 +1276,7 @@ char *ModuleDeclaration::toChars()
|
|||||||
if (packages && packages->dim)
|
if (packages && packages->dim)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < packages->dim; i++)
|
for (size_t i = 0; i < packages->dim; i++)
|
||||||
{ Identifier *pid = packages->tdata()[i];
|
{ Identifier *pid = (*packages)[i];
|
||||||
|
|
||||||
buf.writestring(pid->toChars());
|
buf.writestring(pid->toChars());
|
||||||
buf.writeByte('.');
|
buf.writeByte('.');
|
||||||
@@ -1340,7 +1313,7 @@ DsymbolTable *Package::resolve(Identifiers *packages, Dsymbol **pparent, Package
|
|||||||
if (packages)
|
if (packages)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < packages->dim; i++)
|
for (size_t i = 0; i < packages->dim; i++)
|
||||||
{ Identifier *pid = packages->tdata()[i];
|
{ Identifier *pid = (*packages)[i];
|
||||||
Dsymbol *p;
|
Dsymbol *p;
|
||||||
|
|
||||||
p = dst->lookup(pid);
|
p = dst->lookup(pid);
|
||||||
|
|||||||
@@ -79,7 +79,6 @@ struct Module : Package
|
|||||||
|
|
||||||
unsigned errors; // if any errors in file
|
unsigned errors; // if any errors in file
|
||||||
unsigned numlines; // number of lines in source 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 isDocFile; // if it is a documentation input file, not D source
|
||||||
int needmoduleinfo;
|
int needmoduleinfo;
|
||||||
#ifdef IN_GCC
|
#ifdef IN_GCC
|
||||||
@@ -141,8 +140,6 @@ struct Module : Package
|
|||||||
bool read(Loc loc); // read file, returns 'true' if succeed, 'false' otherwise.
|
bool read(Loc loc); // read file, returns 'true' if succeed, 'false' otherwise.
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
void parse(bool gen_docs = false); // syntactic parse
|
void parse(bool gen_docs = false); // syntactic parse
|
||||||
#elif IN_GCC
|
|
||||||
void parse(bool dump_source = false); // syntactic parse
|
|
||||||
#else
|
#else
|
||||||
void parse(); // syntactic parse
|
void parse(); // syntactic parse
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+283
-193
File diff suppressed because it is too large
Load Diff
+11
-6
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2010 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -48,7 +48,7 @@ struct HdrGenState;
|
|||||||
struct Parameter;
|
struct Parameter;
|
||||||
|
|
||||||
// Back end
|
// Back end
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
union tree_node; typedef union tree_node TYPE;
|
union tree_node; typedef union tree_node TYPE;
|
||||||
typedef TYPE type;
|
typedef TYPE type;
|
||||||
#endif
|
#endif
|
||||||
@@ -215,6 +215,7 @@ struct Type : Object
|
|||||||
static ClassDeclaration *typeinfowild;
|
static ClassDeclaration *typeinfowild;
|
||||||
|
|
||||||
static TemplateDeclaration *associativearray;
|
static TemplateDeclaration *associativearray;
|
||||||
|
static TemplateDeclaration *rtinfo;
|
||||||
|
|
||||||
static Type *basic[TMAX];
|
static Type *basic[TMAX];
|
||||||
static unsigned char mangleChar[TMAX];
|
static unsigned char mangleChar[TMAX];
|
||||||
@@ -317,8 +318,8 @@ struct Type : Object
|
|||||||
virtual ClassDeclaration *isClassHandle();
|
virtual ClassDeclaration *isClassHandle();
|
||||||
virtual Expression *getProperty(Loc loc, Identifier *ident);
|
virtual Expression *getProperty(Loc loc, Identifier *ident);
|
||||||
virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
virtual Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
|
virtual structalign_t alignment();
|
||||||
Expression *noMember(Scope *sc, Expression *e, Identifier *ident);
|
Expression *noMember(Scope *sc, Expression *e, Identifier *ident);
|
||||||
virtual unsigned memalign(unsigned salign);
|
|
||||||
virtual Expression *defaultInit(Loc loc = 0);
|
virtual Expression *defaultInit(Loc loc = 0);
|
||||||
virtual Expression *defaultInitLiteral(Loc loc);
|
virtual Expression *defaultInitLiteral(Loc loc);
|
||||||
virtual Expression *voidInitLiteral(VarDeclaration *var);
|
virtual Expression *voidInitLiteral(VarDeclaration *var);
|
||||||
@@ -375,6 +376,7 @@ struct TypeError : Type
|
|||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
Expression *defaultInit(Loc loc);
|
Expression *defaultInit(Loc loc);
|
||||||
Expression *defaultInitLiteral(Loc loc);
|
Expression *defaultInitLiteral(Loc loc);
|
||||||
|
TypeTuple *toArgTypes();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct TypeNext : Type
|
struct TypeNext : Type
|
||||||
@@ -409,7 +411,7 @@ struct TypeBasic : Type
|
|||||||
d_uns64 size(Loc loc);
|
d_uns64 size(Loc loc);
|
||||||
unsigned alignsize();
|
unsigned alignsize();
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
unsigned memalign(unsigned salign);
|
unsigned alignment();
|
||||||
#endif
|
#endif
|
||||||
Expression *getProperty(Loc loc, Identifier *ident);
|
Expression *getProperty(Loc loc, Identifier *ident);
|
||||||
Expression *dotExp(Scope *sc, Expression *e, 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);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
int isString();
|
int isString();
|
||||||
int isZeroInit(Loc loc);
|
int isZeroInit(Loc loc);
|
||||||
unsigned memalign(unsigned salign);
|
structalign_t alignment();
|
||||||
MATCH constConv(Type *to);
|
MATCH constConv(Type *to);
|
||||||
MATCH implicitConvTo(Type *to);
|
MATCH implicitConvTo(Type *to);
|
||||||
Expression *defaultInit(Loc loc);
|
Expression *defaultInit(Loc loc);
|
||||||
@@ -567,6 +569,7 @@ struct TypeAArray : TypeArray
|
|||||||
int isZeroInit(Loc loc);
|
int isZeroInit(Loc loc);
|
||||||
int checkBoolean();
|
int checkBoolean();
|
||||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||||
|
Type *reliesOnTident(TemplateParameters *tparams);
|
||||||
Expression *toExpression();
|
Expression *toExpression();
|
||||||
int hasPointers();
|
int hasPointers();
|
||||||
TypeTuple *toArgTypes();
|
TypeTuple *toArgTypes();
|
||||||
@@ -778,6 +781,7 @@ struct TypeInstance : TypeQualified
|
|||||||
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
|
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
|
||||||
Type *semantic(Loc loc, Scope *sc);
|
Type *semantic(Loc loc, Scope *sc);
|
||||||
Dsymbol *toDsymbol(Scope *sc);
|
Dsymbol *toDsymbol(Scope *sc);
|
||||||
|
Type *reliesOnTident(TemplateParameters *tparams = NULL);
|
||||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes, unsigned *wildmatch = 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 toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
|
||||||
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
unsigned memalign(unsigned salign);
|
structalign_t alignment();
|
||||||
Expression *defaultInit(Loc loc);
|
Expression *defaultInit(Loc loc);
|
||||||
Expression *defaultInitLiteral(Loc loc);
|
Expression *defaultInitLiteral(Loc loc);
|
||||||
Expression *voidInitLiteral(VarDeclaration *var);
|
Expression *voidInitLiteral(VarDeclaration *var);
|
||||||
@@ -907,6 +911,7 @@ struct TypeTypedef : Type
|
|||||||
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
|
void toDecoBuffer(OutBuffer *buf, int flag, bool mangle);
|
||||||
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
|
||||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||||
|
structalign_t alignment();
|
||||||
Expression *getProperty(Loc loc, Identifier *ident);
|
Expression *getProperty(Loc loc, Identifier *ident);
|
||||||
int isintegral();
|
int isintegral();
|
||||||
int isfloating();
|
int isfloating();
|
||||||
|
|||||||
+91
-60
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h> // memset()
|
||||||
#if _MSC_VER
|
#if _MSC_VER
|
||||||
#include <complex>
|
#include <complex>
|
||||||
#else
|
#else
|
||||||
@@ -355,9 +356,11 @@ Expression *UnaExp::op_overload(Scope *sc)
|
|||||||
/* Rewrite op(e1) as:
|
/* Rewrite op(e1) as:
|
||||||
* op(e1.aliasthis)
|
* op(e1.aliasthis)
|
||||||
*/
|
*/
|
||||||
UnaExp *e = (UnaExp *)syntaxCopy();
|
Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
|
||||||
e->e1 = new DotIdExp(loc, e->e1, ad->aliasthis->ident);
|
Expression *e = copy();
|
||||||
return e->trySemantic(sc);
|
((UnaExp *)e)->e1 = e1;
|
||||||
|
e = e->trySemantic(sc);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -374,7 +377,7 @@ Expression *ArrayExp::op_overload(Scope *sc)
|
|||||||
if (fd)
|
if (fd)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < arguments->dim; i++)
|
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
|
// Create scope for '$' variable for this dimension
|
||||||
ArrayScopeSymbol *sym = new ArrayScopeSymbol(sc, this);
|
ArrayScopeSymbol *sym = new ArrayScopeSymbol(sc, this);
|
||||||
sym->loc = loc;
|
sym->loc = loc;
|
||||||
@@ -393,7 +396,7 @@ Expression *ArrayExp::op_overload(Scope *sc)
|
|||||||
x = new CommaExp(0, av, x);
|
x = new CommaExp(0, av, x);
|
||||||
x->semantic(sc);
|
x->semantic(sc);
|
||||||
}
|
}
|
||||||
arguments->tdata()[i] = x;
|
(*arguments)[i] = x;
|
||||||
sc = sc->pop();
|
sc = sc->pop();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -412,9 +415,11 @@ Expression *ArrayExp::op_overload(Scope *sc)
|
|||||||
/* Rewrite op(e1) as:
|
/* Rewrite op(e1) as:
|
||||||
* op(e1.aliasthis)
|
* op(e1.aliasthis)
|
||||||
*/
|
*/
|
||||||
UnaExp *e = (UnaExp *)syntaxCopy();
|
Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
|
||||||
e->e1 = new DotIdExp(loc, e->e1, ad->aliasthis->ident);
|
Expression *e = copy();
|
||||||
return e->trySemantic(sc);
|
((UnaExp *)e)->e1 = e1;
|
||||||
|
e = e->trySemantic(sc);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -457,9 +462,11 @@ Expression *CastExp::op_overload(Scope *sc)
|
|||||||
/* Rewrite op(e1) as:
|
/* Rewrite op(e1) as:
|
||||||
* op(e1.aliasthis)
|
* op(e1.aliasthis)
|
||||||
*/
|
*/
|
||||||
UnaExp *e = (UnaExp *)syntaxCopy();
|
Expression *e1 = new DotIdExp(loc, this->e1, ad->aliasthis->ident);
|
||||||
e->e1 = new DotIdExp(loc, e->e1, ad->aliasthis->ident);
|
Expression *e = copy();
|
||||||
return e->trySemantic(sc);
|
((UnaExp *)e)->e1 = e1;
|
||||||
|
e = e->trySemantic(sc);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -529,9 +536,9 @@ Expression *BinExp::op_overload(Scope *sc)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
args1.setDim(1);
|
args1.setDim(1);
|
||||||
args1.tdata()[0] = e1;
|
args1[0] = e1;
|
||||||
args2.setDim(1);
|
args2.setDim(1);
|
||||||
args2.tdata()[0] = e2;
|
args2[0] = e2;
|
||||||
argsset = 1;
|
argsset = 1;
|
||||||
|
|
||||||
Match m;
|
Match m;
|
||||||
@@ -622,9 +629,9 @@ L1:
|
|||||||
|
|
||||||
if (!argsset)
|
if (!argsset)
|
||||||
{ args1.setDim(1);
|
{ args1.setDim(1);
|
||||||
args1.tdata()[0] = e1;
|
args1[0] = e1;
|
||||||
args2.setDim(1);
|
args2.setDim(1);
|
||||||
args2.tdata()[0] = e2;
|
args2[0] = e2;
|
||||||
}
|
}
|
||||||
|
|
||||||
Match m;
|
Match m;
|
||||||
@@ -715,9 +722,11 @@ L1:
|
|||||||
/* Rewrite (e1 op e2) as:
|
/* Rewrite (e1 op e2) as:
|
||||||
* (e1.aliasthis op e2)
|
* (e1.aliasthis op e2)
|
||||||
*/
|
*/
|
||||||
BinExp *e = (BinExp *)syntaxCopy();
|
Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident);
|
||||||
e->e1 = new DotIdExp(loc, e->e1, ad1->aliasthis->ident);
|
Expression *e = copy();
|
||||||
return e->trySemantic(sc);
|
((BinExp *)e)->e1 = e1;
|
||||||
|
e = e->trySemantic(sc);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try alias this on second operand
|
// Try alias this on second operand
|
||||||
@@ -730,9 +739,11 @@ L1:
|
|||||||
/* Rewrite (e1 op e2) as:
|
/* Rewrite (e1 op e2) as:
|
||||||
* (e1 op e2.aliasthis)
|
* (e1 op e2.aliasthis)
|
||||||
*/
|
*/
|
||||||
BinExp *e = (BinExp *)syntaxCopy();
|
Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident);
|
||||||
e->e2 = new DotIdExp(loc, e->e2, ad2->aliasthis->ident);
|
Expression *e = copy();
|
||||||
return e->trySemantic(sc);
|
((BinExp *)e)->e2 = e2;
|
||||||
|
e = e->trySemantic(sc);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -776,9 +787,9 @@ Expression *BinExp::compare_overload(Scope *sc, Identifier *id)
|
|||||||
Expressions args2;
|
Expressions args2;
|
||||||
|
|
||||||
args1.setDim(1);
|
args1.setDim(1);
|
||||||
args1.tdata()[0] = e1;
|
args1[0] = e1;
|
||||||
args2.setDim(1);
|
args2.setDim(1);
|
||||||
args2.tdata()[0] = e2;
|
args2[0] = e2;
|
||||||
|
|
||||||
Match m;
|
Match m;
|
||||||
memset(&m, 0, sizeof(m));
|
memset(&m, 0, sizeof(m));
|
||||||
@@ -884,9 +895,11 @@ Expression *BinExp::compare_overload(Scope *sc, Identifier *id)
|
|||||||
/* Rewrite (e1 op e2) as:
|
/* Rewrite (e1 op e2) as:
|
||||||
* (e1.aliasthis op e2)
|
* (e1.aliasthis op e2)
|
||||||
*/
|
*/
|
||||||
BinExp *e = (BinExp *)syntaxCopy();
|
Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident);
|
||||||
e->e1 = new DotIdExp(loc, e->e1, ad1->aliasthis->ident);
|
Expression *e = copy();
|
||||||
return e->trySemantic(sc);
|
((BinExp *)e)->e1 = e1;
|
||||||
|
e = e->trySemantic(sc);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try alias this on second operand
|
// Try alias this on second operand
|
||||||
@@ -895,9 +908,11 @@ Expression *BinExp::compare_overload(Scope *sc, Identifier *id)
|
|||||||
/* Rewrite (e1 op e2) as:
|
/* Rewrite (e1 op e2) as:
|
||||||
* (e1 op e2.aliasthis)
|
* (e1 op e2.aliasthis)
|
||||||
*/
|
*/
|
||||||
BinExp *e = (BinExp *)syntaxCopy();
|
Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident);
|
||||||
e->e2 = new DotIdExp(loc, e->e2, ad2->aliasthis->ident);
|
Expression *e = copy();
|
||||||
return e->trySemantic(sc);
|
((BinExp *)e)->e2 = e2;
|
||||||
|
e = e->trySemantic(sc);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -916,12 +931,20 @@ Expression *EqualExp::op_overload(Scope *sc)
|
|||||||
if (!(cd1->isCPPinterface() || cd2->isCPPinterface()))
|
if (!(cd1->isCPPinterface() || cd2->isCPPinterface()))
|
||||||
{
|
{
|
||||||
/* Rewrite as:
|
/* 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,
|
* The explicit cast is necessary for interfaces,
|
||||||
* see http://d.puremagic.com/issues/show_bug.cgi?id=4088
|
* see http://d.puremagic.com/issues/show_bug.cgi?id=4088
|
||||||
*/
|
*/
|
||||||
Expression *e1x = new CastExp(loc, e1, ClassDeclaration::object->getType());
|
Type *to = ClassDeclaration::object->getType();
|
||||||
Expression *e2x = new CastExp(loc, e2, 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);
|
Expression *e = new IdentifierExp(loc, Id::empty);
|
||||||
e = new DotIdExp(loc, e, Id::object);
|
e = new DotIdExp(loc, e, Id::object);
|
||||||
@@ -968,7 +991,7 @@ Expression *BinAssignExp::op_overload(Scope *sc)
|
|||||||
Expressions *a = new Expressions();
|
Expressions *a = new Expressions();
|
||||||
a->push(e2);
|
a->push(e2);
|
||||||
for (size_t i = 0; i < ae->arguments->dim; i++)
|
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);
|
Objects *targsi = opToArg(sc, op);
|
||||||
Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, targsi);
|
Expression *e = new DotTemplateInstanceExp(loc, ae->e1, fd->ident, targsi);
|
||||||
@@ -1085,7 +1108,7 @@ Expression *BinAssignExp::op_overload(Scope *sc)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
args2.setDim(1);
|
args2.setDim(1);
|
||||||
args2.tdata()[0] = e2;
|
args2[0] = e2;
|
||||||
|
|
||||||
Match m;
|
Match m;
|
||||||
memset(&m, 0, sizeof(m));
|
memset(&m, 0, sizeof(m));
|
||||||
@@ -1132,9 +1155,11 @@ L1:
|
|||||||
/* Rewrite (e1 op e2) as:
|
/* Rewrite (e1 op e2) as:
|
||||||
* (e1.aliasthis op e2)
|
* (e1.aliasthis op e2)
|
||||||
*/
|
*/
|
||||||
BinExp *e = (BinExp *)syntaxCopy();
|
Expression *e1 = new DotIdExp(loc, this->e1, ad1->aliasthis->ident);
|
||||||
e->e1 = new DotIdExp(loc, e->e1, ad1->aliasthis->ident);
|
Expression *e = copy();
|
||||||
return e->trySemantic(sc);
|
((BinExp *)e)->e1 = e1;
|
||||||
|
e = e->trySemantic(sc);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try alias this on second operand
|
// Try alias this on second operand
|
||||||
@@ -1144,9 +1169,11 @@ L1:
|
|||||||
/* Rewrite (e1 op e2) as:
|
/* Rewrite (e1 op e2) as:
|
||||||
* (e1 op e2.aliasthis)
|
* (e1 op e2.aliasthis)
|
||||||
*/
|
*/
|
||||||
BinExp *e = (BinExp *)syntaxCopy();
|
Expression *e2 = new DotIdExp(loc, this->e2, ad2->aliasthis->ident);
|
||||||
e->e2 = new DotIdExp(loc, e->e2, ad2->aliasthis->ident);
|
Expression *e = copy();
|
||||||
return e->trySemantic(sc);
|
((BinExp *)e)->e2 = e2;
|
||||||
|
e = e->trySemantic(sc);
|
||||||
|
return e;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -1209,7 +1236,7 @@ int ForeachStatement::inferAggregate(Scope *sc, Dsymbol *&sapply)
|
|||||||
{
|
{
|
||||||
Identifier *idapply = (op == TOKforeach) ? Id::apply : Id::applyReverse;
|
Identifier *idapply = (op == TOKforeach) ? Id::apply : Id::applyReverse;
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
Identifier *idhead = (op == TOKforeach) ? Id::Ffront : Id::Fback;
|
Identifier *idfront = (op == TOKforeach) ? Id::Ffront : Id::Fback;
|
||||||
int sliced = 0;
|
int sliced = 0;
|
||||||
#endif
|
#endif
|
||||||
Type *tab;
|
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
|
{ // range aggregate
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1316,7 +1343,7 @@ int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
|
|||||||
if (sapply) // prefer opApply
|
if (sapply) // prefer opApply
|
||||||
{
|
{
|
||||||
for (size_t u = 0; u < arguments->dim; u++)
|
for (size_t u = 0; u < arguments->dim; u++)
|
||||||
{ Parameter *arg = arguments->tdata()[u];
|
{ Parameter *arg = (*arguments)[u];
|
||||||
if (arg->type)
|
if (arg->type)
|
||||||
arg->type = arg->type->semantic(loc, sc);
|
arg->type = arg->type->semantic(loc, sc);
|
||||||
}
|
}
|
||||||
@@ -1350,14 +1377,14 @@ int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
|
|||||||
/* Return if no arguments need types.
|
/* Return if no arguments need types.
|
||||||
*/
|
*/
|
||||||
for (size_t u = 0; u < arguments->dim; u++)
|
for (size_t u = 0; u < arguments->dim; u++)
|
||||||
{ Parameter *arg = arguments->tdata()[u];
|
{ Parameter *arg = (*arguments)[u];
|
||||||
if (!arg->type)
|
if (!arg->type)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
AggregateDeclaration *ad;
|
AggregateDeclaration *ad;
|
||||||
|
|
||||||
Parameter *arg = arguments->tdata()[0];
|
Parameter *arg = (*arguments)[0];
|
||||||
Type *taggr = aggr->type;
|
Type *taggr = aggr->type;
|
||||||
assert(taggr);
|
assert(taggr);
|
||||||
Type *tab = taggr->toBasetype();
|
Type *tab = taggr->toBasetype();
|
||||||
@@ -1370,7 +1397,7 @@ int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
|
|||||||
{
|
{
|
||||||
if (!arg->type)
|
if (!arg->type)
|
||||||
arg->type = Type::tsize_t; // key type
|
arg->type = Type::tsize_t; // key type
|
||||||
arg = arguments->tdata()[1];
|
arg = (*arguments)[1];
|
||||||
}
|
}
|
||||||
if (!arg->type && tab->ty != Ttuple)
|
if (!arg->type && tab->ty != Ttuple)
|
||||||
arg->type = tab->nextOf(); // value type
|
arg->type = tab->nextOf(); // value type
|
||||||
@@ -1383,7 +1410,7 @@ int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
|
|||||||
{
|
{
|
||||||
if (!arg->type)
|
if (!arg->type)
|
||||||
arg->type = taa->index; // key type
|
arg->type = taa->index; // key type
|
||||||
arg = arguments->tdata()[1];
|
arg = (*arguments)[1];
|
||||||
}
|
}
|
||||||
if (!arg->type)
|
if (!arg->type)
|
||||||
arg->type = taa->next; // value type
|
arg->type = taa->next; // value type
|
||||||
@@ -1403,20 +1430,24 @@ int ForeachStatement::inferApplyArgTypes(Scope *sc, Dsymbol *&sapply)
|
|||||||
{
|
{
|
||||||
if (!arg->type)
|
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;
|
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;
|
FuncDeclaration *fd = s ? s->isFuncDeclaration() : NULL;
|
||||||
if (!fd)
|
if (fd)
|
||||||
{ if (s && s->isTemplateDeclaration())
|
{
|
||||||
break;
|
// Resolve inout qualifier of front type
|
||||||
break;
|
arg->type = fd->type->nextOf();
|
||||||
|
if (arg->type)
|
||||||
|
arg->type = arg->type->substWildTo(tab->mod);
|
||||||
}
|
}
|
||||||
// Resolve inout qualifier of front type
|
else if (s && s->isTemplateDeclaration())
|
||||||
arg->type = fd->type->nextOf();
|
;
|
||||||
if (arg->type)
|
else if (s && s->isDeclaration())
|
||||||
arg->type = arg->type->substWildTo(tab->mod);
|
arg->type = ((Declaration *)s)->type;
|
||||||
|
else
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -1522,7 +1553,7 @@ static int inferApplyArgTypesY(TypeFunction *tf, Parameters *arguments, int flag
|
|||||||
|
|
||||||
for (size_t u = 0; u < nparams; u++)
|
for (size_t u = 0; u < nparams; u++)
|
||||||
{
|
{
|
||||||
Parameter *arg = arguments->tdata()[u];
|
Parameter *arg = (*arguments)[u];
|
||||||
Parameter *param = Parameter::getNth(tf->parameters, u);
|
Parameter *param = Parameter::getNth(tf->parameters, u);
|
||||||
if (arg->type)
|
if (arg->type)
|
||||||
{ if (!arg->type->equals(param->type))
|
{ if (!arg->type->equals(param->type))
|
||||||
@@ -1560,7 +1591,7 @@ void inferApplyArgTypesZ(TemplateDeclaration *tstart, Parameters *arguments)
|
|||||||
}
|
}
|
||||||
if (!td->parameters || td->parameters->dim != 1)
|
if (!td->parameters || td->parameters->dim != 1)
|
||||||
continue;
|
continue;
|
||||||
TemplateParameter *tp = td->parameters->tdata()[0];
|
TemplateParameter *tp = (*td->parameters)[0];
|
||||||
TemplateAliasParameter *tap = tp->isTemplateAliasParameter();
|
TemplateAliasParameter *tap = tp->isTemplateAliasParameter();
|
||||||
if (!tap || !tap->specType || tap->specType->ty != Tfunction)
|
if (!tap || !tap->specType || tap->specType->ty != Tfunction)
|
||||||
continue;
|
continue;
|
||||||
|
|||||||
+16
-17
@@ -153,7 +153,6 @@ Expression *fromConstInitializer(int result, Expression *e1)
|
|||||||
if (e1->op == TOKvar)
|
if (e1->op == TOKvar)
|
||||||
{ VarExp *ve = (VarExp *)e1;
|
{ VarExp *ve = (VarExp *)e1;
|
||||||
VarDeclaration *v = ve->var->isVarDeclaration();
|
VarDeclaration *v = ve->var->isVarDeclaration();
|
||||||
int fwdref = (v && !v->originalType && v->scope);
|
|
||||||
e = expandVar(result, v);
|
e = expandVar(result, v);
|
||||||
if (e)
|
if (e)
|
||||||
{
|
{
|
||||||
@@ -202,10 +201,10 @@ Expression *VarExp::optimize(int result)
|
|||||||
Expression *TupleExp::optimize(int result)
|
Expression *TupleExp::optimize(int result)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < exps->dim; i++)
|
for (size_t i = 0; i < exps->dim; i++)
|
||||||
{ Expression *e = exps->tdata()[i];
|
{ Expression *e = (*exps)[i];
|
||||||
|
|
||||||
e = e->optimize(WANTvalue | (result & WANTinterpret));
|
e = e->optimize(WANTvalue | (result & WANTinterpret));
|
||||||
exps->tdata()[i] = e;
|
(*exps)[i] = e;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -215,10 +214,10 @@ Expression *ArrayLiteralExp::optimize(int result)
|
|||||||
if (elements)
|
if (elements)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < elements->dim; i++)
|
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)));
|
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
|
||||||
elements->tdata()[i] = e;
|
(*elements)[i] = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@@ -228,14 +227,14 @@ Expression *AssocArrayLiteralExp::optimize(int result)
|
|||||||
{
|
{
|
||||||
assert(keys->dim == values->dim);
|
assert(keys->dim == values->dim);
|
||||||
for (size_t i = 0; i < keys->dim; i++)
|
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)));
|
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)));
|
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
|
||||||
values->tdata()[i] = e;
|
(*values)[i] = e;
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
@@ -245,11 +244,11 @@ Expression *StructLiteralExp::optimize(int result)
|
|||||||
if (elements)
|
if (elements)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < elements->dim; i++)
|
for (size_t i = 0; i < elements->dim; i++)
|
||||||
{ Expression *e = elements->tdata()[i];
|
{ Expression *e = (*elements)[i];
|
||||||
if (!e)
|
if (!e)
|
||||||
continue;
|
continue;
|
||||||
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
|
e = e->optimize(WANTvalue | (result & (WANTinterpret | WANTexpand)));
|
||||||
elements->tdata()[i] = e;
|
(*elements)[i] = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
@@ -495,20 +494,20 @@ Expression *NewExp::optimize(int result)
|
|||||||
if (newargs)
|
if (newargs)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < newargs->dim; i++)
|
for (size_t i = 0; i < newargs->dim; i++)
|
||||||
{ Expression *e = newargs->tdata()[i];
|
{ Expression *e = (*newargs)[i];
|
||||||
|
|
||||||
e = e->optimize(WANTvalue);
|
e = e->optimize(WANTvalue);
|
||||||
newargs->tdata()[i] = e;
|
(*newargs)[i] = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (arguments)
|
if (arguments)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < arguments->dim; i++)
|
for (size_t i = 0; i < arguments->dim; i++)
|
||||||
{ Expression *e = arguments->tdata()[i];
|
{ Expression *e = (*arguments)[i];
|
||||||
|
|
||||||
e = e->optimize(WANTvalue);
|
e = e->optimize(WANTvalue);
|
||||||
arguments->tdata()[i] = e;
|
(*arguments)[i] = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (result & WANTinterpret)
|
if (result & WANTinterpret)
|
||||||
@@ -527,10 +526,10 @@ Expression *CallExp::optimize(int result)
|
|||||||
if (arguments)
|
if (arguments)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < arguments->dim; i++)
|
for (size_t i = 0; i < arguments->dim; i++)
|
||||||
{ Expression *e = arguments->tdata()[i];
|
{ Expression *e = (*arguments)[i];
|
||||||
|
|
||||||
e = e->optimize(WANTvalue);
|
e = e->optimize(WANTvalue);
|
||||||
arguments->tdata()[i] = e;
|
(*arguments)[i] = e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+32
-11
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -12,6 +12,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h> // strlen(),memcpy()
|
||||||
|
|
||||||
#include "rmem.h"
|
#include "rmem.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
@@ -454,7 +455,10 @@ Dsymbols *Parser::parseDeclDefs(int once)
|
|||||||
((tk = peek(tk)), 1) &&
|
((tk = peek(tk)), 1) &&
|
||||||
skipAttributes(tk, &tk) &&
|
skipAttributes(tk, &tk) &&
|
||||||
(tk->value == TOKlparen ||
|
(tk->value == TOKlparen ||
|
||||||
tk->value == TOKlcurly)
|
tk->value == TOKlcurly ||
|
||||||
|
tk->value == TOKin ||
|
||||||
|
tk->value == TOKout ||
|
||||||
|
tk->value == TOKbody)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
a = parseDeclarations(storageClass, comment);
|
a = parseDeclarations(storageClass, comment);
|
||||||
@@ -512,7 +516,11 @@ Dsymbols *Parser::parseDeclDefs(int once)
|
|||||||
{
|
{
|
||||||
nextToken();
|
nextToken();
|
||||||
if (token.value == TOKint32v && token.uns64value > 0)
|
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;
|
n = (unsigned)token.uns64value;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{ error("positive integer expected, not %s", token.toChars());
|
{ error("positive integer expected, not %s", token.toChars());
|
||||||
n = 1;
|
n = 1;
|
||||||
@@ -535,7 +543,7 @@ Dsymbols *Parser::parseDeclDefs(int once)
|
|||||||
nextToken();
|
nextToken();
|
||||||
check(TOKlparen);
|
check(TOKlparen);
|
||||||
if (token.value != TOKidentifier)
|
if (token.value != TOKidentifier)
|
||||||
{ error("pragma(identifier expected");
|
{ error("pragma(identifier) expected");
|
||||||
goto Lerror;
|
goto Lerror;
|
||||||
}
|
}
|
||||||
ident = token.ident;
|
ident = token.ident;
|
||||||
@@ -1370,7 +1378,8 @@ Parameters *Parser::parseParameters(int *pvarargs, TemplateParameters **tpl)
|
|||||||
default:
|
default:
|
||||||
Ldefault:
|
Ldefault:
|
||||||
{ stc = storageClass & (STCin | STCout | STCref | STClazy);
|
{ 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");
|
error("incompatible parameter storage classes");
|
||||||
if ((storageClass & (STCconst | STCout)) == (STCconst | STCout))
|
if ((storageClass & (STCconst | STCout)) == (STCconst | STCout))
|
||||||
error("out cannot be const");
|
error("out cannot be const");
|
||||||
@@ -2860,7 +2869,10 @@ Dsymbols *Parser::parseDeclarations(StorageClass storage_class, unsigned char *c
|
|||||||
((tk = peek(tk)), 1) &&
|
((tk = peek(tk)), 1) &&
|
||||||
skipAttributes(tk, &tk) &&
|
skipAttributes(tk, &tk) &&
|
||||||
(tk->value == TOKlparen ||
|
(tk->value == TOKlparen ||
|
||||||
tk->value == TOKlcurly)
|
tk->value == TOKlcurly ||
|
||||||
|
tk->value == TOKin ||
|
||||||
|
tk->value == TOKout ||
|
||||||
|
tk->value == TOKbody)
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
ts = NULL;
|
ts = NULL;
|
||||||
@@ -3347,7 +3359,15 @@ Initializer *Parser::parseInitializer()
|
|||||||
if (comma == 1)
|
if (comma == 1)
|
||||||
error("comma expected separating array initializers, not %s", token.toChars());
|
error("comma expected separating array initializers, not %s", token.toChars());
|
||||||
value = parseInitializer();
|
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;
|
comma = 1;
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -3601,7 +3621,7 @@ Statement *Parser::parseStatement(int flags)
|
|||||||
as->reserve(a->dim);
|
as->reserve(a->dim);
|
||||||
for (size_t i = 0; i < a->dim; i++)
|
for (size_t i = 0; i < a->dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *d = a->tdata()[i];
|
Dsymbol *d = (*a)[i];
|
||||||
s = new ExpStatement(loc, d);
|
s = new ExpStatement(loc, d);
|
||||||
as->push(s);
|
as->push(s);
|
||||||
}
|
}
|
||||||
@@ -3609,7 +3629,7 @@ Statement *Parser::parseStatement(int flags)
|
|||||||
}
|
}
|
||||||
else if (a->dim == 1)
|
else if (a->dim == 1)
|
||||||
{
|
{
|
||||||
Dsymbol *d = a->tdata()[0];
|
Dsymbol *d = (*a)[0];
|
||||||
s = new ExpStatement(loc, d);
|
s = new ExpStatement(loc, d);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -3841,7 +3861,7 @@ Statement *Parser::parseStatement(int flags)
|
|||||||
Expression *aggr = parseExpression();
|
Expression *aggr = parseExpression();
|
||||||
if (token.value == TOKslice && arguments->dim == 1)
|
if (token.value == TOKslice && arguments->dim == 1)
|
||||||
{
|
{
|
||||||
Parameter *a = arguments->tdata()[0];
|
Parameter *a = (*arguments)[0];
|
||||||
delete arguments;
|
delete arguments;
|
||||||
nextToken();
|
nextToken();
|
||||||
Expression *upr = parseExpression();
|
Expression *upr = parseExpression();
|
||||||
@@ -4087,7 +4107,7 @@ Statement *Parser::parseStatement(int flags)
|
|||||||
// Keep cases in order by building the case statements backwards
|
// Keep cases in order by building the case statements backwards
|
||||||
for (size_t i = cases.dim; i; i--)
|
for (size_t i = cases.dim; i; i--)
|
||||||
{
|
{
|
||||||
exp = cases.tdata()[i - 1];
|
exp = cases[i - 1];
|
||||||
s = new CaseStatement(loc, exp, s);
|
s = new CaseStatement(loc, exp, s);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -4242,7 +4262,7 @@ Statement *Parser::parseStatement(int flags)
|
|||||||
Loc loc = this->loc;
|
Loc loc = this->loc;
|
||||||
|
|
||||||
nextToken();
|
nextToken();
|
||||||
if (token.value == TOKlcurly)
|
if (token.value == TOKlcurly || token.value != TOKlparen)
|
||||||
{
|
{
|
||||||
t = NULL;
|
t = NULL;
|
||||||
id = NULL;
|
id = NULL;
|
||||||
@@ -5406,6 +5426,7 @@ Expression *Parser::parsePrimaryExp()
|
|||||||
token.value == TOKenum ||
|
token.value == TOKenum ||
|
||||||
token.value == TOKinterface ||
|
token.value == TOKinterface ||
|
||||||
token.value == TOKargTypes ||
|
token.value == TOKargTypes ||
|
||||||
|
token.value == TOKparameters ||
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
token.value == TOKconst && peek(&token)->value == TOKrparen ||
|
token.value == TOKconst && peek(&token)->value == TOKrparen ||
|
||||||
token.value == TOKinvariant && peek(&token)->value == TOKrparen ||
|
token.value == TOKinvariant && peek(&token)->value == TOKrparen ||
|
||||||
|
|||||||
+26
-24
@@ -1,24 +1,26 @@
|
|||||||
|
|
||||||
The D Programming Language
|
The D Programming Language
|
||||||
Compiler Front End Source
|
Compiler Front End Source
|
||||||
Copyright (c) 1999-2009, by Digital Mars
|
Copyright (c) 1999-2009, by Digital Mars
|
||||||
http://www.digitalmars.com
|
http://www.digitalmars.com
|
||||||
All Rights Reserved
|
All Rights Reserved
|
||||||
|
|
||||||
|
|
||||||
This is the source code to the front end Digital Mars D compiler.
|
This is the source code to the front end Digital Mars D compiler.
|
||||||
It covers the lexical analysis, parsing, and semantic analysis
|
It covers the lexical analysis, parsing, and semantic analysis
|
||||||
of the D Programming Language defined in the documents at
|
of the D Programming Language defined in the documents at
|
||||||
http://www.digitalmars.com/d/
|
http://www.digitalmars.com/d/
|
||||||
|
|
||||||
These sources are free, they are redistributable and modifiable
|
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
|
||||||
or the Artistic License (attached as artistic.txt).
|
the Free Software Foundation; either version 1, or (at your option)
|
||||||
|
any later version (attached as gpl.txt),
|
||||||
The optimizer and code generator sources are
|
or the Artistic License (attached as artistic.txt).
|
||||||
covered under a separate license, backendlicense.txt.
|
|
||||||
|
The optimizer and code generator sources are
|
||||||
It does not apply to anything else distributed by Digital Mars,
|
covered under a separate license, backendlicense.txt.
|
||||||
including D compiler executables.
|
|
||||||
|
It does not apply to anything else distributed by Digital Mars,
|
||||||
-Walter Bright
|
including D compiler executables.
|
||||||
|
|
||||||
|
-Walter Bright
|
||||||
|
|||||||
@@ -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.
|
* Implementation of associative arrays.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -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* Value;
|
||||||
typedef void* Key;
|
typedef void* Key;
|
||||||
|
|
||||||
|
|||||||
@@ -40,7 +40,6 @@
|
|||||||
|
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "root.h"
|
#include "root.h"
|
||||||
#include "dchar.h"
|
|
||||||
#include "rmem.h"
|
#include "rmem.h"
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
#define _MT 1
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|||||||
@@ -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
|
|
||||||
@@ -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
|
|
||||||
|
|
||||||
@@ -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
|
// Put functions in here missing from gnu C
|
||||||
|
|
||||||
#include "gnuc.h"
|
#include "gnuc.h"
|
||||||
|
|||||||
@@ -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
|
#ifndef _GNUC_H
|
||||||
#define _GNUC_H 1
|
#define _GNUC_H 1
|
||||||
|
|
||||||
|
|||||||
@@ -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;
|
|
||||||
}
|
|
||||||
@@ -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
@@ -109,6 +109,7 @@ int response_expand(int *pargc, char ***pargv)
|
|||||||
char *buffer;
|
char *buffer;
|
||||||
char *bufend;
|
char *bufend;
|
||||||
char *p;
|
char *p;
|
||||||
|
int comment = 0;
|
||||||
|
|
||||||
cp++;
|
cp++;
|
||||||
p = getenv(cp);
|
p = getenv(cp);
|
||||||
@@ -171,15 +172,31 @@ int response_expand(int *pargc, char ***pargv)
|
|||||||
goto L2;
|
goto L2;
|
||||||
|
|
||||||
case 0xD:
|
case 0xD:
|
||||||
|
case '\n':
|
||||||
|
if (comment)
|
||||||
|
{
|
||||||
|
comment = 0;
|
||||||
|
}
|
||||||
case 0:
|
case 0:
|
||||||
case ' ':
|
case ' ':
|
||||||
case '\t':
|
case '\t':
|
||||||
case '\n':
|
|
||||||
continue; // scan to start of argument
|
continue; // scan to start of argument
|
||||||
|
|
||||||
|
case '#':
|
||||||
|
comment = 1;
|
||||||
|
continue;
|
||||||
|
|
||||||
case '@':
|
case '@':
|
||||||
|
if (comment)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
recurse = 1;
|
recurse = 1;
|
||||||
default: /* start of new argument */
|
default: /* start of new argument */
|
||||||
|
if (comment)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (addargp(&n,p))
|
if (addargp(&n,p))
|
||||||
goto noexpand;
|
goto noexpand;
|
||||||
instring = 0;
|
instring = 0;
|
||||||
|
|||||||
+7
-2
@@ -1,6 +1,11 @@
|
|||||||
|
|
||||||
/* Copyright (c) 2000 Digital Mars */
|
// Copyright (c) 2000-2012 by Digital Mars
|
||||||
/* All Rights Reserved */
|
// 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 <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
+7
-1
@@ -1,5 +1,11 @@
|
|||||||
// Copyright (C) 2000-2011 by Digital Mars
|
|
||||||
|
// Copyright (c) 2000-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// 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
|
#ifndef ROOT_MEM_H
|
||||||
#define ROOT_MEM_H
|
#define ROOT_MEM_H
|
||||||
|
|||||||
+2
-116
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -18,6 +18,7 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
#if (defined (__SVR4) && defined (__sun))
|
#if (defined (__SVR4) && defined (__sun))
|
||||||
#include <alloca.h>
|
#include <alloca.h>
|
||||||
@@ -49,7 +50,6 @@
|
|||||||
|
|
||||||
#include "port.h"
|
#include "port.h"
|
||||||
#include "root.h"
|
#include "root.h"
|
||||||
#include "dchar.h"
|
|
||||||
#include "rmem.h"
|
#include "rmem.h"
|
||||||
|
|
||||||
#if 0 //__SC__ //def DEBUG
|
#if 0 //__SC__ //def DEBUG
|
||||||
@@ -142,22 +142,6 @@ void error(const char *format, ...)
|
|||||||
exit(EXIT_FAILURE);
|
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()
|
void error_mem()
|
||||||
{
|
{
|
||||||
error("out of memory");
|
error("out of memory");
|
||||||
@@ -206,15 +190,6 @@ char *Object::toChars()
|
|||||||
return (char *)"Object";
|
return (char *)"Object";
|
||||||
}
|
}
|
||||||
|
|
||||||
dchar *Object::toDchars()
|
|
||||||
{
|
|
||||||
#if M_UNICODE
|
|
||||||
return L"Object";
|
|
||||||
#else
|
|
||||||
return toChars();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int Object::dyncast()
|
int Object::dyncast()
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -1609,30 +1584,6 @@ void OutBuffer::writestring(const char *string)
|
|||||||
write(string,strlen(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)
|
void OutBuffer::prependstring(const char *string)
|
||||||
{ unsigned len;
|
{ unsigned len;
|
||||||
|
|
||||||
@@ -1646,18 +1597,10 @@ void OutBuffer::prependstring(const char *string)
|
|||||||
void OutBuffer::writenl()
|
void OutBuffer::writenl()
|
||||||
{
|
{
|
||||||
#if _WIN32
|
#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
|
writeword(0x0A0D); // newline is CR,LF on Microsoft OS's
|
||||||
#endif
|
|
||||||
#else
|
|
||||||
#if M_UNICODE
|
|
||||||
writeword('\n');
|
|
||||||
#else
|
#else
|
||||||
writeByte('\n');
|
writeByte('\n');
|
||||||
#endif
|
#endif
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void OutBuffer::writeByte(unsigned b)
|
void OutBuffer::writeByte(unsigned b)
|
||||||
@@ -1719,13 +1662,6 @@ void OutBuffer::writeUTF8(unsigned b)
|
|||||||
assert(0);
|
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)
|
void OutBuffer::prependbyte(unsigned b)
|
||||||
{
|
{
|
||||||
reserve(1);
|
reserve(1);
|
||||||
@@ -1873,46 +1809,6 @@ void OutBuffer::vprintf(const char *format, va_list args)
|
|||||||
write(p,count);
|
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, ...)
|
void OutBuffer::printf(const char *format, ...)
|
||||||
{
|
{
|
||||||
va_list ap;
|
va_list ap;
|
||||||
@@ -1921,16 +1817,6 @@ void OutBuffer::printf(const char *format, ...)
|
|||||||
va_end(ap);
|
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)
|
void OutBuffer::bracket(char left, char right)
|
||||||
{
|
{
|
||||||
reserve(2);
|
reserve(2);
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
|
|
||||||
|
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2011 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
@@ -24,7 +23,6 @@
|
|||||||
typedef size_t hash_t;
|
typedef size_t hash_t;
|
||||||
|
|
||||||
#include "longdouble.h"
|
#include "longdouble.h"
|
||||||
#include "dchar.h"
|
|
||||||
|
|
||||||
char *wchar2ascii(wchar_t *);
|
char *wchar2ascii(wchar_t *);
|
||||||
int wcharIsAscii(wchar_t *);
|
int wcharIsAscii(wchar_t *);
|
||||||
@@ -92,7 +90,6 @@ struct Object
|
|||||||
virtual void print();
|
virtual void print();
|
||||||
|
|
||||||
virtual char *toChars();
|
virtual char *toChars();
|
||||||
virtual dchar *toDchars();
|
|
||||||
virtual void toBuffer(OutBuffer *buf);
|
virtual void toBuffer(OutBuffer *buf);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -282,14 +279,11 @@ struct OutBuffer : Object
|
|||||||
void write(const void *data, unsigned nbytes);
|
void write(const void *data, unsigned nbytes);
|
||||||
void writebstring(unsigned char *string);
|
void writebstring(unsigned char *string);
|
||||||
void writestring(const char *string);
|
void writestring(const char *string);
|
||||||
void writedstring(const char *string);
|
|
||||||
void writedstring(const wchar_t *string);
|
|
||||||
void prependstring(const char *string);
|
void prependstring(const char *string);
|
||||||
void writenl(); // write newline
|
void writenl(); // write newline
|
||||||
void writeByte(unsigned b);
|
void writeByte(unsigned b);
|
||||||
void writebyte(unsigned b) { writeByte(b); }
|
void writebyte(unsigned b) { writeByte(b); }
|
||||||
void writeUTF8(unsigned b);
|
void writeUTF8(unsigned b);
|
||||||
void writedchar(unsigned b);
|
|
||||||
void prependbyte(unsigned b);
|
void prependbyte(unsigned b);
|
||||||
void writeword(unsigned w);
|
void writeword(unsigned w);
|
||||||
void writeUTF16(unsigned w);
|
void writeUTF16(unsigned w);
|
||||||
@@ -300,10 +294,6 @@ struct OutBuffer : Object
|
|||||||
void align(unsigned size);
|
void align(unsigned size);
|
||||||
void vprintf(const char *format, va_list args);
|
void vprintf(const char *format, va_list args);
|
||||||
void printf(const char *format, ...);
|
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);
|
void bracket(char left, char right);
|
||||||
unsigned bracket(unsigned i, const char *left, unsigned j, const char *right);
|
unsigned bracket(unsigned i, const char *left, unsigned j, const char *right);
|
||||||
void spread(unsigned offset, unsigned nbytes);
|
void spread(unsigned offset, unsigned nbytes);
|
||||||
|
|||||||
@@ -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 <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|||||||
@@ -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 *);
|
typedef void *(fp_speller_t)(void *, const char *);
|
||||||
|
|
||||||
extern const char idchars[];
|
extern const char idchars[];
|
||||||
|
|||||||
+71
-21
@@ -9,15 +9,70 @@
|
|||||||
|
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <stdint.h> // uint{8|16|32}_t
|
||||||
|
#include <string.h> // memcpy()
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "root.h"
|
#include "root.h"
|
||||||
#include "rmem.h"
|
#include "rmem.h" // mem
|
||||||
#include "dchar.h"
|
|
||||||
#include "lstring.h"
|
|
||||||
#include "stringtable.h"
|
#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)
|
void StringTable::init(unsigned size)
|
||||||
{
|
{
|
||||||
table = (void **)mem.calloc(size, sizeof(void *));
|
table = (void **)mem.calloc(size, sizeof(void *));
|
||||||
@@ -46,21 +101,20 @@ struct StringEntry
|
|||||||
|
|
||||||
StringValue value;
|
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;
|
StringEntry *se;
|
||||||
|
|
||||||
se = (StringEntry *) mem.calloc(1,sizeof(StringEntry) - sizeof(Lstring) + Lstring::size(len));
|
se = (StringEntry *) mem.calloc(1,sizeof(StringEntry) + len + 1);
|
||||||
se->value.lstring.length = len;
|
se->value.ctor(s, len);
|
||||||
se->hash = Dchar::calcHash(s,len);
|
se->hash = calcHash(s,len);
|
||||||
memcpy(se->value.lstring.string, s, len * sizeof(dchar));
|
|
||||||
return se;
|
return se;
|
||||||
}
|
}
|
||||||
|
|
||||||
void **StringTable::search(const dchar *s, unsigned len)
|
void **StringTable::search(const char *s, unsigned len)
|
||||||
{
|
{
|
||||||
hash_t hash;
|
hash_t hash;
|
||||||
unsigned u;
|
unsigned u;
|
||||||
@@ -68,7 +122,7 @@ void **StringTable::search(const dchar *s, unsigned len)
|
|||||||
StringEntry **se;
|
StringEntry **se;
|
||||||
|
|
||||||
//printf("StringTable::search(%p,%d)\n",s,len);
|
//printf("StringTable::search(%p,%d)\n",s,len);
|
||||||
hash = Dchar::calcHash(s,len);
|
hash = calcHash(s,len);
|
||||||
u = hash % tabledim;
|
u = hash % tabledim;
|
||||||
se = (StringEntry **)&table[u];
|
se = (StringEntry **)&table[u];
|
||||||
//printf("\thash = %d, u = %d\n",hash,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;
|
cmp = (*se)->hash - hash;
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
{
|
{
|
||||||
cmp = (*se)->value.lstring.len() - len;
|
cmp = (*se)->value.len() - len;
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
{
|
{
|
||||||
cmp = Dchar::memcmp(s,(*se)->value.lstring.toDchars(),len);
|
cmp = ::memcmp(s,(*se)->value.toDchars(),len);
|
||||||
if (cmp == 0)
|
if (cmp == 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -94,7 +148,7 @@ void **StringTable::search(const dchar *s, unsigned len)
|
|||||||
return (void **)se;
|
return (void **)se;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringValue *StringTable::lookup(const dchar *s, unsigned len)
|
StringValue *StringTable::lookup(const char *s, unsigned len)
|
||||||
{ StringEntry *se;
|
{ StringEntry *se;
|
||||||
|
|
||||||
se = *(StringEntry **)search(s,len);
|
se = *(StringEntry **)search(s,len);
|
||||||
@@ -104,7 +158,7 @@ StringValue *StringTable::lookup(const dchar *s, unsigned len)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringValue *StringTable::update(const dchar *s, unsigned len)
|
StringValue *StringTable::update(const char *s, unsigned len)
|
||||||
{ StringEntry **pse;
|
{ StringEntry **pse;
|
||||||
StringEntry *se;
|
StringEntry *se;
|
||||||
|
|
||||||
@@ -118,7 +172,7 @@ StringValue *StringTable::update(const dchar *s, unsigned len)
|
|||||||
return &se->value;
|
return &se->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringValue *StringTable::insert(const dchar *s, unsigned len)
|
StringValue *StringTable::insert(const char *s, unsigned len)
|
||||||
{ StringEntry **pse;
|
{ StringEntry **pse;
|
||||||
StringEntry *se;
|
StringEntry *se;
|
||||||
|
|
||||||
@@ -133,7 +187,3 @@ StringValue *StringTable::insert(const dchar *s, unsigned len)
|
|||||||
}
|
}
|
||||||
return &se->value;
|
return &se->value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+32
-9
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2011 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
@@ -15,34 +16,56 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "root.h"
|
#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
|
struct StringValue
|
||||||
{
|
{
|
||||||
union
|
union
|
||||||
{ int intvalue;
|
{
|
||||||
void *ptrvalue;
|
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
|
struct StringTable
|
||||||
{
|
{
|
||||||
|
private:
|
||||||
void **table;
|
void **table;
|
||||||
unsigned count;
|
unsigned count;
|
||||||
unsigned tabledim;
|
unsigned tabledim;
|
||||||
|
|
||||||
|
public:
|
||||||
void init(unsigned size = 37);
|
void init(unsigned size = 37);
|
||||||
~StringTable();
|
~StringTable();
|
||||||
|
|
||||||
StringValue *lookup(const dchar *s, unsigned len);
|
StringValue *lookup(const char *s, unsigned len);
|
||||||
StringValue *insert(const dchar *s, unsigned len);
|
StringValue *insert(const char *s, unsigned len);
|
||||||
StringValue *update(const dchar *s, unsigned len);
|
StringValue *update(const char *s, unsigned len);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void **search(const dchar *s, unsigned len);
|
void **search(const char *s, unsigned len);
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,6 +9,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include <string.h> // strlen()
|
||||||
|
|
||||||
#include "root.h"
|
#include "root.h"
|
||||||
#include "speller.h"
|
#include "speller.h"
|
||||||
|
|||||||
+2
-2
@@ -87,7 +87,7 @@ struct Scope
|
|||||||
#define CSXreturn 0x20 // seen a return statement
|
#define CSXreturn 0x20 // seen a return statement
|
||||||
#define CSXany_ctor 0x40 // either this() or super() was called
|
#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 LINK linkage; // linkage for external functions
|
||||||
|
|
||||||
enum PROT protection; // protection for class members
|
enum PROT protection; // protection for class members
|
||||||
@@ -102,7 +102,7 @@ struct Scope
|
|||||||
#define SCOPEstaticassert 8 // inside static assert
|
#define SCOPEstaticassert 8 // inside static assert
|
||||||
#define SCOPEdebug 0x10 // inside debug conditional
|
#define SCOPEdebug 0x10 // inside debug conditional
|
||||||
|
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
Expressions *attributes; // GCC decl/type attributes
|
Expressions *attributes; // GCC decl/type attributes
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|||||||
+180
-70
@@ -28,6 +28,7 @@
|
|||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "template.h"
|
#include "template.h"
|
||||||
#include "attrib.h"
|
#include "attrib.h"
|
||||||
|
#include "import.h"
|
||||||
|
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
@@ -426,7 +427,7 @@ Statements *CompileStatement::flatten(Scope *sc)
|
|||||||
//printf("CompileStatement::flatten() %s\n", exp->toChars());
|
//printf("CompileStatement::flatten() %s\n", exp->toChars());
|
||||||
exp = exp->semantic(sc);
|
exp = exp->semantic(sc);
|
||||||
exp = resolveProperties(sc, exp);
|
exp = resolveProperties(sc, exp);
|
||||||
exp = exp->optimize(WANTvalue | WANTinterpret);
|
exp = exp->ctfeInterpret();
|
||||||
if (exp->op == TOKerror)
|
if (exp->op == TOKerror)
|
||||||
return NULL;
|
return NULL;
|
||||||
StringExp *se = exp->toString();
|
StringExp *se = exp->toString();
|
||||||
@@ -1585,6 +1586,10 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
|||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Type *argtype = (*arguments)[dim-1]->type;
|
||||||
|
if (argtype)
|
||||||
|
argtype = argtype->semantic(loc, sc);
|
||||||
|
|
||||||
TypeTuple *tuple = (TypeTuple *)tab;
|
TypeTuple *tuple = (TypeTuple *)tab;
|
||||||
Statements *statements = new Statements();
|
Statements *statements = new Statements();
|
||||||
//printf("aggr: op = %d, %s\n", aggr->op, aggr->toChars());
|
//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())
|
((DotVarExp *)(*te->exps)[0])->e1->isTemp())
|
||||||
{
|
{
|
||||||
CommaExp *ce = (CommaExp *)((DotVarExp *)(*te->exps)[0])->e1;
|
CommaExp *ce = (CommaExp *)((DotVarExp *)(*te->exps)[0])->e1;
|
||||||
|
prelude = ce->e1;
|
||||||
prelude = ce->e1;
|
((DotVarExp *)(*te->exps)[0])->e1 = ce->e2;
|
||||||
((DotVarExp *)(*te->exps)[0])->e1 = ce->e2;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (aggr->op == TOKtype) // type tuple
|
else if (aggr->op == TOKtype) // type tuple
|
||||||
@@ -1612,8 +1616,8 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
|||||||
assert(0);
|
assert(0);
|
||||||
for (size_t j = 0; j < n; j++)
|
for (size_t j = 0; j < n; j++)
|
||||||
{ size_t k = (op == TOKforeach) ? j : n - 1 - j;
|
{ size_t k = (op == TOKforeach) ? j : n - 1 - j;
|
||||||
Expression *e;
|
Expression *e = NULL;
|
||||||
Type *t;
|
Type *t = NULL;
|
||||||
if (te)
|
if (te)
|
||||||
e = (*te->exps)[k];
|
e = (*te->exps)[k];
|
||||||
else
|
else
|
||||||
@@ -1664,14 +1668,20 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
|||||||
var = new AliasDeclaration(loc, arg->ident, s);
|
var = new AliasDeclaration(loc, arg->ident, s);
|
||||||
if (arg->storageClass & STCref)
|
if (arg->storageClass & STCref)
|
||||||
error("symbol %s cannot be ref", s->toChars());
|
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)
|
else if (e->op == TOKtype)
|
||||||
{
|
{
|
||||||
var = new AliasDeclaration(loc, arg->ident, e->type);
|
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
|
else
|
||||||
{
|
{
|
||||||
arg->type = e->type;
|
arg->type = e->type;
|
||||||
|
if (argtype && argtype->ty != Terror)
|
||||||
|
arg->type = argtype;
|
||||||
Initializer *ie = new ExpInitializer(0, e);
|
Initializer *ie = new ExpInitializer(0, e);
|
||||||
VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie);
|
VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie);
|
||||||
if (arg->storageClass & STCref)
|
if (arg->storageClass & STCref)
|
||||||
@@ -1688,6 +1698,8 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
var = new AliasDeclaration(loc, arg->ident, t);
|
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);
|
DeclarationExp *de = new DeclarationExp(loc, var);
|
||||||
st->push(new ExpStatement(loc, de));
|
st->push(new ExpStatement(loc, de));
|
||||||
@@ -1757,23 +1769,47 @@ Lagain:
|
|||||||
Type *argtype = arg->type->semantic(loc, sc);
|
Type *argtype = arg->type->semantic(loc, sc);
|
||||||
VarDeclaration *var;
|
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)
|
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
|
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;
|
value = var;
|
||||||
/* Reference to immutable data should be marked as const
|
if (var->storage_class & STCref)
|
||||||
*/
|
|
||||||
if (var->storage_class & STCref && !tn->isMutable())
|
|
||||||
{
|
{
|
||||||
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
|
#if 0
|
||||||
@@ -1831,6 +1867,30 @@ Lagain:
|
|||||||
value->init = new ExpInitializer(loc, new IndexExp(loc, new VarExp(loc, tmp), new VarExp(loc, key)));
|
value->init = new ExpInitializer(loc, new IndexExp(loc, new VarExp(loc, tmp), new VarExp(loc, key)));
|
||||||
Statement *ds = new ExpStatement(loc, value);
|
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);
|
body = new CompoundStatement(loc, ds, body);
|
||||||
|
|
||||||
s = new ForStatement(loc, forinit, cond, increment, body);
|
s = new ForStatement(loc, forinit, cond, increment, body);
|
||||||
@@ -1901,29 +1961,29 @@ Lagain:
|
|||||||
goto Lapply;
|
goto Lapply;
|
||||||
|
|
||||||
{ /* Look for range iteration, i.e. the properties
|
{ /* Look for range iteration, i.e. the properties
|
||||||
* .empty, .next, .retreat, .head and .rear
|
* .empty, .popFront, .popBack, .front and .back
|
||||||
* foreach (e; aggr) { ... }
|
* foreach (e; aggr) { ... }
|
||||||
* translates to:
|
* translates to:
|
||||||
* for (auto __r = aggr[]; !__r.empty; __r.next)
|
* for (auto __r = aggr[]; !__r.empty; __r.popFront)
|
||||||
* { auto e = __r.head;
|
* { auto e = __r.front;
|
||||||
* ...
|
* ...
|
||||||
* }
|
* }
|
||||||
*/
|
*/
|
||||||
AggregateDeclaration *ad = (tab->ty == Tclass)
|
AggregateDeclaration *ad = (tab->ty == Tclass)
|
||||||
? (AggregateDeclaration *)((TypeClass *)tab)->sym
|
? (AggregateDeclaration *)((TypeClass *)tab)->sym
|
||||||
: (AggregateDeclaration *)((TypeStruct *)tab)->sym;
|
: (AggregateDeclaration *)((TypeStruct *)tab)->sym;
|
||||||
Identifier *idhead;
|
Identifier *idfront;
|
||||||
Identifier *idnext;
|
Identifier *idpopFront;
|
||||||
if (op == TOKforeach)
|
if (op == TOKforeach)
|
||||||
{ idhead = Id::Ffront;
|
{ idfront = Id::Ffront;
|
||||||
idnext = Id::FpopFront;
|
idpopFront = Id::FpopFront;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ idhead = Id::Fback;
|
{ idfront = Id::Fback;
|
||||||
idnext = Id::FpopBack;
|
idpopFront = Id::FpopBack;
|
||||||
}
|
}
|
||||||
Dsymbol *shead = search_function(ad, idhead);
|
Dsymbol *sfront = ad->search(0, idfront, 0);
|
||||||
if (!shead)
|
if (!sfront)
|
||||||
goto Lapply;
|
goto Lapply;
|
||||||
|
|
||||||
/* Generate a temporary __r and initialize it with the aggregate.
|
/* Generate a temporary __r and initialize it with the aggregate.
|
||||||
@@ -1939,13 +1999,13 @@ Lagain:
|
|||||||
|
|
||||||
// __r.next
|
// __r.next
|
||||||
e = new VarExp(loc, r);
|
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:
|
/* Declaration statement for e:
|
||||||
* auto e = __r.idhead;
|
* auto e = __r.idfront;
|
||||||
*/
|
*/
|
||||||
e = new VarExp(loc, r);
|
e = new VarExp(loc, r);
|
||||||
Expression *einit = new DotIdExp(loc, e, idhead);
|
Expression *einit = new DotIdExp(loc, e, idfront);
|
||||||
Statement *makeargs, *forbody;
|
Statement *makeargs, *forbody;
|
||||||
if (dim == 1)
|
if (dim == 1)
|
||||||
{
|
{
|
||||||
@@ -1968,7 +2028,7 @@ Lagain:
|
|||||||
makeargs = new ExpStatement(loc, de);
|
makeargs = new ExpStatement(loc, de);
|
||||||
|
|
||||||
Expression *ve = new VarExp(loc, vd);
|
Expression *ve = new VarExp(loc, vd);
|
||||||
ve->type = shead->isDeclaration()->type;
|
ve->type = sfront->isDeclaration()->type;
|
||||||
if (ve->type->toBasetype()->ty == Tfunction)
|
if (ve->type->toBasetype()->ty == Tfunction)
|
||||||
ve->type = ve->type->toBasetype()->nextOf();
|
ve->type = ve->type->toBasetype()->nextOf();
|
||||||
if (!ve->type || ve->type->ty == Terror)
|
if (!ve->type || ve->type->ty == Terror)
|
||||||
@@ -2046,18 +2106,6 @@ Lagain:
|
|||||||
|
|
||||||
Type *tret = func->type->nextOf();
|
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;
|
TypeFunction *tfld = NULL;
|
||||||
if (sapply)
|
if (sapply)
|
||||||
{ FuncDeclaration *fdapply = sapply->isFuncDeclaration();
|
{ FuncDeclaration *fdapply = sapply->isFuncDeclaration();
|
||||||
@@ -2533,7 +2581,14 @@ Statement *ForeachRangeStatement::semantic(Scope *sc)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
ExpInitializer *ie = new ExpInitializer(loc, (op == TOKforeach) ? lwr : upr);
|
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");
|
Identifier *id = Lexer::uniqueId("__limit");
|
||||||
ie = new ExpInitializer(loc, (op == TOKforeach) ? upr : lwr);
|
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 AddAssignExp(loc, new VarExp(loc, key), new IntegerExp(1));
|
||||||
increment = new PreExp(TOKpreplusplus, loc, new VarExp(loc, key));
|
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);
|
ForStatement *fs = new ForStatement(loc, forinit, cond, increment, body);
|
||||||
s = fs->semantic(sc);
|
s = fs->semantic(sc);
|
||||||
return s;
|
return s;
|
||||||
@@ -2971,8 +3048,8 @@ Statement *PragmaStatement::semantic(Scope *sc)
|
|||||||
Expression *e = (*args)[i];
|
Expression *e = (*args)[i];
|
||||||
|
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
if (e->op != TOKerror)
|
if (e->op != TOKerror && e->op != TOKtype)
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
if (e->op == TOKerror)
|
if (e->op == TOKerror)
|
||||||
{ errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
|
{ errorSupplemental(loc, "while evaluating pragma(msg, %s)", (*args)[i]->toChars());
|
||||||
goto Lerror;
|
goto Lerror;
|
||||||
@@ -3002,7 +3079,7 @@ Statement *PragmaStatement::semantic(Scope *sc)
|
|||||||
Expression *e = (*args)[0];
|
Expression *e = (*args)[0];
|
||||||
|
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
(*args)[0] = e;
|
(*args)[0] = e;
|
||||||
StringExp *se = e->toString();
|
StringExp *se = e->toString();
|
||||||
if (!se)
|
if (!se)
|
||||||
@@ -3033,7 +3110,7 @@ Statement *PragmaStatement::semantic(Scope *sc)
|
|||||||
{
|
{
|
||||||
Expression *e = (*args)[0];
|
Expression *e = (*args)[0];
|
||||||
e = e->semantic(sc);
|
e = e->semantic(sc);
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
(*args)[0] = e;
|
(*args)[0] = e;
|
||||||
Dsymbol *sa = getDsymbol(e);
|
Dsymbol *sa = getDsymbol(e);
|
||||||
if (!sa || !sa->isFuncDeclaration())
|
if (!sa || !sa->isFuncDeclaration())
|
||||||
@@ -3171,6 +3248,10 @@ Statement *SwitchStatement::semantic(Scope *sc)
|
|||||||
|
|
||||||
condition = condition->semantic(sc);
|
condition = condition->semantic(sc);
|
||||||
condition = resolveProperties(sc, condition);
|
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 (condition->type->isString())
|
||||||
{
|
{
|
||||||
// If it's not an array, cast it to one
|
// 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
|
{ // Don't use toBasetype() because that will skip past enums
|
||||||
t = ((TypeTypedef *)t)->sym->basetype;
|
t = ((TypeTypedef *)t)->sym->basetype;
|
||||||
}
|
}
|
||||||
if (condition->type->ty == Tenum)
|
if (te)
|
||||||
{ TypeEnum *te = (TypeEnum *)condition->type;
|
{
|
||||||
EnumDeclaration *ed = te->toDsymbol(sc)->isEnumDeclaration();
|
EnumDeclaration *ed = te->toDsymbol(sc)->isEnumDeclaration();
|
||||||
assert(ed);
|
assert(ed);
|
||||||
size_t dim = ed->members->dim;
|
size_t dim = ed->members->dim;
|
||||||
@@ -3247,7 +3328,7 @@ Statement *SwitchStatement::semantic(Scope *sc)
|
|||||||
{
|
{
|
||||||
for (size_t j = 0; j < cases->dim; j++)
|
for (size_t j = 0; j < cases->dim; j++)
|
||||||
{ CaseStatement *cs = (*cases)[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;
|
goto L1;
|
||||||
}
|
}
|
||||||
error("enum member %s not represented in final switch", em->toChars());
|
error("enum member %s not represented in final switch", em->toChars());
|
||||||
@@ -3397,7 +3478,7 @@ Statement *CaseStatement::semantic(Scope *sc)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
exp = exp->optimize(WANTvalue | WANTinterpret);
|
exp = exp->ctfeInterpret();
|
||||||
|
|
||||||
if (exp->op != TOKstring && exp->op != TOKint64 && exp->op != TOKerror)
|
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->semantic(sc);
|
||||||
first = first->implicitCastTo(sc, sw->condition->type);
|
first = first->implicitCastTo(sc, sw->condition->type);
|
||||||
first = first->optimize(WANTvalue | WANTinterpret);
|
first = first->ctfeInterpret();
|
||||||
|
|
||||||
|
|
||||||
last = last->semantic(sc);
|
last = last->semantic(sc);
|
||||||
last = last->implicitCastTo(sc, sw->condition->type);
|
last = last->implicitCastTo(sc, sw->condition->type);
|
||||||
last = last->optimize(WANTvalue | WANTinterpret);
|
last = last->ctfeInterpret();
|
||||||
|
|
||||||
if (first->op == TOKerror || last->op == TOKerror)
|
if (first->op == TOKerror || last->op == TOKerror)
|
||||||
return statement ? statement->semantic(sc) : NULL;
|
return statement ? statement->semantic(sc) : NULL;
|
||||||
@@ -3574,12 +3654,12 @@ DefaultStatement::DefaultStatement(Loc loc, Statement *s)
|
|||||||
: Statement(loc)
|
: Statement(loc)
|
||||||
{
|
{
|
||||||
this->statement = s;
|
this->statement = s;
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
cblock = NULL;
|
cblock = NULL;
|
||||||
#endif
|
#elif IN_LLVM
|
||||||
bodyBB = NULL;
|
bodyBB = NULL;
|
||||||
// LDC
|
|
||||||
enclosingScopeExit = NULL;
|
enclosingScopeExit = NULL;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *DefaultStatement::syntaxCopy()
|
Statement *DefaultStatement::syntaxCopy()
|
||||||
@@ -3749,6 +3829,7 @@ ReturnStatement::ReturnStatement(Loc loc, Expression *exp)
|
|||||||
: Statement(loc)
|
: Statement(loc)
|
||||||
{
|
{
|
||||||
this->exp = exp;
|
this->exp = exp;
|
||||||
|
this->implicit0 = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Statement *ReturnStatement::syntaxCopy()
|
Statement *ReturnStatement::syntaxCopy()
|
||||||
@@ -3766,7 +3847,6 @@ Statement *ReturnStatement::semantic(Scope *sc)
|
|||||||
|
|
||||||
FuncDeclaration *fd = sc->parent->isFuncDeclaration();
|
FuncDeclaration *fd = sc->parent->isFuncDeclaration();
|
||||||
Scope *scx = sc;
|
Scope *scx = sc;
|
||||||
int implicit0 = 0;
|
|
||||||
Expression *eorg = NULL;
|
Expression *eorg = NULL;
|
||||||
|
|
||||||
if (fd->fes)
|
if (fd->fes)
|
||||||
@@ -3810,8 +3890,11 @@ Statement *ReturnStatement::semantic(Scope *sc)
|
|||||||
{
|
{
|
||||||
fd->hasReturnExp |= 1;
|
fd->hasReturnExp |= 1;
|
||||||
|
|
||||||
|
FuncLiteralDeclaration *fld = fd->isFuncLiteralDeclaration();
|
||||||
if (tret)
|
if (tret)
|
||||||
exp = exp->inferType(tbret);
|
exp = exp->inferType(tbret);
|
||||||
|
else if (fld && fld->treq && fld->treq->nextOf())
|
||||||
|
exp = exp->inferType(fld->treq->nextOf());
|
||||||
exp = exp->semantic(sc);
|
exp = exp->semantic(sc);
|
||||||
exp = resolveProperties(sc, exp);
|
exp = resolveProperties(sc, exp);
|
||||||
if (!((TypeFunction *)fd->type)->isref)
|
if (!((TypeFunction *)fd->type)->isref)
|
||||||
@@ -3984,11 +4067,14 @@ Statement *ReturnStatement::semantic(Scope *sc)
|
|||||||
// Construct: return vresult;
|
// Construct: return vresult;
|
||||||
if (!fd->vresult)
|
if (!fd->vresult)
|
||||||
{ // Declare vresult
|
{ // Declare vresult
|
||||||
|
Scope *sco = fd->scout ? fd->scout : scx;
|
||||||
VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL);
|
VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL);
|
||||||
v->noscope = 1;
|
v->noscope = 1;
|
||||||
v->storage_class |= STCresult;
|
v->storage_class |= STCresult;
|
||||||
v->semantic(scx);
|
if (((TypeFunction *)fd->type)->isref)
|
||||||
if (!scx->insert(v))
|
v->storage_class |= STCref | STCforeach;
|
||||||
|
v->semantic(sco);
|
||||||
|
if (!sco->insert(v))
|
||||||
assert(0);
|
assert(0);
|
||||||
v->parent = fd;
|
v->parent = fd;
|
||||||
fd->vresult = v;
|
fd->vresult = v;
|
||||||
@@ -4027,7 +4113,7 @@ Statement *ReturnStatement::semantic(Scope *sc)
|
|||||||
|
|
||||||
if (fd->returnLabel && tbret->ty != Tvoid)
|
if (fd->returnLabel && tbret->ty != Tvoid)
|
||||||
{
|
{
|
||||||
assert(fd->vresult);
|
fd->buildResultVar();
|
||||||
VarExp *v = new VarExp(0, fd->vresult);
|
VarExp *v = new VarExp(0, fd->vresult);
|
||||||
|
|
||||||
assert(eorg);
|
assert(eorg);
|
||||||
@@ -4357,9 +4443,16 @@ Statement *SynchronizedStatement::semantic(Scope *sc)
|
|||||||
{ /* Cast the interface to an object, as the object has the monitor,
|
{ /* Cast the interface to an object, as the object has the monitor,
|
||||||
* not the interface.
|
* 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 = new CastExp(loc, exp, t);
|
||||||
exp = exp->semantic(sc);
|
exp = exp->semantic(sc);
|
||||||
}
|
}
|
||||||
@@ -5313,9 +5406,6 @@ LabelDsymbol::LabelDsymbol(Identifier *ident)
|
|||||||
: Dsymbol(ident)
|
: Dsymbol(ident)
|
||||||
{
|
{
|
||||||
statement = NULL;
|
statement = NULL;
|
||||||
#if IN_GCC
|
|
||||||
asmLabelNum = 0;
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()?
|
LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()?
|
||||||
@@ -5353,7 +5443,7 @@ int AsmStatement::comeFrom()
|
|||||||
int AsmStatement::blockExit(bool mustNotThrow)
|
int AsmStatement::blockExit(bool mustNotThrow)
|
||||||
{
|
{
|
||||||
if (mustNotThrow)
|
if (mustNotThrow)
|
||||||
error("asm statements are assumed to throw", toChars());
|
error("asm statements are assumed to throw");
|
||||||
// Assume the worst
|
// Assume the worst
|
||||||
return BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt;
|
return BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt;
|
||||||
}
|
}
|
||||||
@@ -5410,9 +5500,29 @@ Statement *ImportStatement::syntaxCopy()
|
|||||||
Statement *ImportStatement::semantic(Scope *sc)
|
Statement *ImportStatement::semantic(Scope *sc)
|
||||||
{
|
{
|
||||||
for (size_t i = 0; i < imports->dim; i++)
|
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);
|
s->semantic(sc);
|
||||||
sc->insert(s);
|
sc->insert(s);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < s->aliasdecls.dim; i++)
|
||||||
|
{
|
||||||
|
sc->insert(s->aliasdecls[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
+3
-5
@@ -79,7 +79,7 @@ struct DValue;
|
|||||||
typedef DValue elem;
|
typedef DValue elem;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
union tree_node; typedef union tree_node block;
|
union tree_node; typedef union tree_node block;
|
||||||
//union tree_node; typedef union tree_node elem;
|
//union tree_node; typedef union tree_node elem;
|
||||||
#else
|
#else
|
||||||
@@ -595,7 +595,7 @@ struct CaseRangeStatement : Statement
|
|||||||
struct DefaultStatement : Statement
|
struct DefaultStatement : Statement
|
||||||
{
|
{
|
||||||
Statement *statement;
|
Statement *statement;
|
||||||
#if IN_GCC
|
#ifdef IN_GCC
|
||||||
block *cblock; // back end: label for the block
|
block *cblock; // back end: label for the block
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -664,6 +664,7 @@ struct SwitchErrorStatement : Statement
|
|||||||
struct ReturnStatement : Statement
|
struct ReturnStatement : Statement
|
||||||
{
|
{
|
||||||
Expression *exp;
|
Expression *exp;
|
||||||
|
int implicit0;
|
||||||
|
|
||||||
ReturnStatement(Loc loc, Expression *exp);
|
ReturnStatement(Loc loc, Expression *exp);
|
||||||
Statement *syntaxCopy();
|
Statement *syntaxCopy();
|
||||||
@@ -930,9 +931,6 @@ struct LabelStatement : Statement
|
|||||||
struct LabelDsymbol : Dsymbol
|
struct LabelDsymbol : Dsymbol
|
||||||
{
|
{
|
||||||
LabelStatement *statement;
|
LabelStatement *statement;
|
||||||
#if IN_GCC
|
|
||||||
unsigned asmLabelNum; // GCC-specific
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LabelDsymbol(Identifier *ident);
|
LabelDsymbol(Identifier *ident);
|
||||||
LabelDsymbol *isLabel();
|
LabelDsymbol *isLabel();
|
||||||
|
|||||||
+8
-4
@@ -1,5 +1,5 @@
|
|||||||
|
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -59,10 +59,14 @@ void StaticAssert::semantic2(Scope *sc)
|
|||||||
++sc->ignoreTemplates;
|
++sc->ignoreTemplates;
|
||||||
Expression *e = exp->semantic(sc);
|
Expression *e = exp->semantic(sc);
|
||||||
sc = sc->pop();
|
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;
|
return;
|
||||||
|
}
|
||||||
unsigned olderrs = global.errors;
|
unsigned olderrs = global.errors;
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
if (global.errors != olderrs)
|
if (global.errors != olderrs)
|
||||||
{
|
{
|
||||||
errorSupplemental(loc, "while evaluating: static assert(%s)", exp->toChars());
|
errorSupplemental(loc, "while evaluating: static assert(%s)", exp->toChars());
|
||||||
@@ -74,7 +78,7 @@ void StaticAssert::semantic2(Scope *sc)
|
|||||||
OutBuffer buf;
|
OutBuffer buf;
|
||||||
|
|
||||||
msg = msg->semantic(sc);
|
msg = msg->semantic(sc);
|
||||||
msg = msg->optimize(WANTvalue | WANTinterpret);
|
msg = msg->ctfeInterpret();
|
||||||
hgs.console = 1;
|
hgs.console = 1;
|
||||||
msg->toCBuffer(&buf, &hgs);
|
msg->toCBuffer(&buf, &hgs);
|
||||||
error("%s", buf.toChars());
|
error("%s", buf.toChars());
|
||||||
|
|||||||
+130
-30
@@ -37,7 +37,6 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
|
|||||||
scope = 0;
|
scope = 0;
|
||||||
structsize = 0; // size of struct
|
structsize = 0; // size of struct
|
||||||
alignsize = 0; // size of struct for alignment purposes
|
alignsize = 0; // size of struct for alignment purposes
|
||||||
structalign = 0; // struct member alignment in effect
|
|
||||||
hasUnions = 0;
|
hasUnions = 0;
|
||||||
sizeok = SIZEOKnone; // size not determined yet
|
sizeok = SIZEOKnone; // size not determined yet
|
||||||
deferred = NULL;
|
deferred = NULL;
|
||||||
@@ -60,6 +59,7 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
|
|||||||
noDefaultCtor = FALSE;
|
noDefaultCtor = FALSE;
|
||||||
#endif
|
#endif
|
||||||
dtor = NULL;
|
dtor = NULL;
|
||||||
|
getRTInfo = NULL;
|
||||||
|
|
||||||
#if IN_LLVM
|
#if IN_LLVM
|
||||||
availableExternally = true; // assume this unless proven otherwise
|
availableExternally = true; // assume this unless proven otherwise
|
||||||
@@ -83,7 +83,7 @@ void AggregateDeclaration::semantic2(Scope *sc)
|
|||||||
sc = sc->push(this);
|
sc = sc->push(this);
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = members->tdata()[i];
|
Dsymbol *s = (*members)[i];
|
||||||
s->semantic2(sc);
|
s->semantic2(sc);
|
||||||
}
|
}
|
||||||
sc->pop();
|
sc->pop();
|
||||||
@@ -103,10 +103,25 @@ void AggregateDeclaration::semantic3(Scope *sc)
|
|||||||
sc = sc->push(this);
|
sc = sc->push(this);
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = members->tdata()[i];
|
Dsymbol *s = (*members)[i];
|
||||||
s->semantic3(sc);
|
s->semantic3(sc);
|
||||||
}
|
}
|
||||||
sc->pop();
|
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++)
|
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());
|
//printf("inline scan aggregate symbol '%s'\n", s->toChars());
|
||||||
s->inlineScan();
|
s->inlineScan();
|
||||||
}
|
}
|
||||||
@@ -127,6 +142,8 @@ void AggregateDeclaration::inlineScan()
|
|||||||
unsigned AggregateDeclaration::size(Loc loc)
|
unsigned AggregateDeclaration::size(Loc loc)
|
||||||
{
|
{
|
||||||
//printf("AggregateDeclaration::size() %s, scope = %p\n", toChars(), scope);
|
//printf("AggregateDeclaration::size() %s, scope = %p\n", toChars(), scope);
|
||||||
|
if (loc.linnum == 0)
|
||||||
|
loc = this->loc;
|
||||||
if (!members)
|
if (!members)
|
||||||
error(loc, "unknown size");
|
error(loc, "unknown size");
|
||||||
if (sizeok != SIZEOKdone && scope)
|
if (sizeok != SIZEOKdone && scope)
|
||||||
@@ -196,20 +213,33 @@ int AggregateDeclaration::isExport()
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
void AggregateDeclaration::alignmember(
|
void AggregateDeclaration::alignmember(
|
||||||
unsigned salign, // struct alignment that is in effect
|
structalign_t alignment, // struct alignment that is in effect
|
||||||
unsigned size, // alignment requirement of field
|
unsigned size, // alignment requirement of field
|
||||||
unsigned *poffset)
|
unsigned *poffset)
|
||||||
{
|
{
|
||||||
//printf("salign = %d, size = %d, offset = %d\n",salign,size,offset);
|
//printf("alignment = %d, size = %d, offset = %d\n",alignment,size,offset);
|
||||||
if (salign > 1)
|
switch (alignment)
|
||||||
{
|
{
|
||||||
assert(size != 3);
|
case 1:
|
||||||
unsigned sa = size;
|
// No alignment
|
||||||
if (sa == 0 || salign < sa)
|
break;
|
||||||
sa = salign;
|
|
||||||
*poffset = (*poffset + sa - 1) & ~(sa - 1);
|
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 *nextoffset, // next location in aggregate
|
||||||
unsigned memsize, // size of member
|
unsigned memsize, // size of member
|
||||||
unsigned memalignsize, // size of member for alignment purposes
|
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 *paggsize, // size of aggregate (updated)
|
||||||
unsigned *paggalignsize, // size of aggregate for alignment purposes (updated)
|
unsigned *paggalignsize, // size of aggregate for alignment purposes (updated)
|
||||||
bool isunion // the aggregate is a union
|
bool isunion // the aggregate is a union
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
unsigned ofs = *nextoffset;
|
unsigned ofs = *nextoffset;
|
||||||
alignmember(memalign, memalignsize, &ofs);
|
alignmember(alignment, memalignsize, &ofs);
|
||||||
unsigned memoffset = ofs;
|
unsigned memoffset = ofs;
|
||||||
ofs += memsize;
|
ofs += memsize;
|
||||||
if (ofs > *paggsize)
|
if (ofs > *paggsize)
|
||||||
*paggsize = ofs;
|
*paggsize = ofs;
|
||||||
if (!isunion)
|
if (!isunion)
|
||||||
*nextoffset = ofs;
|
*nextoffset = ofs;
|
||||||
if (global.params.is64bit && memalign == 8 && memalignsize == 16)
|
|
||||||
/* Not sure how to handle this */
|
if (alignment == STRUCTALIGN_DEFAULT)
|
||||||
;
|
{
|
||||||
else if (memalign < memalignsize)
|
if (global.params.is64bit && memalignsize == 16)
|
||||||
memalignsize = memalign;
|
;
|
||||||
|
else if (8 < memalignsize)
|
||||||
|
memalignsize = 8;
|
||||||
|
else if (alignment < memalignsize)
|
||||||
|
memalignsize = alignment;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (memalignsize < alignment)
|
||||||
|
memalignsize = alignment;
|
||||||
|
}
|
||||||
|
|
||||||
if (*paggalignsize < memalignsize)
|
if (*paggalignsize < memalignsize)
|
||||||
*paggalignsize = memalignsize;
|
*paggalignsize = memalignsize;
|
||||||
|
|
||||||
@@ -265,13 +306,13 @@ int AggregateDeclaration::firstFieldInUnion(int indx)
|
|||||||
{
|
{
|
||||||
if (isUnionDeclaration())
|
if (isUnionDeclaration())
|
||||||
return 0;
|
return 0;
|
||||||
VarDeclaration * vd = fields.tdata()[indx];
|
VarDeclaration * vd = fields[indx];
|
||||||
int firstNonZero = indx; // first index in the union with non-zero size
|
int firstNonZero = indx; // first index in the union with non-zero size
|
||||||
for (; ;)
|
for (; ;)
|
||||||
{
|
{
|
||||||
if (indx == 0)
|
if (indx == 0)
|
||||||
return firstNonZero;
|
return firstNonZero;
|
||||||
VarDeclaration * v = fields.tdata()[indx - 1];
|
VarDeclaration * v = fields[indx - 1];
|
||||||
if (v->offset != vd->offset)
|
if (v->offset != vd->offset)
|
||||||
return firstNonZero;
|
return firstNonZero;
|
||||||
--indx;
|
--indx;
|
||||||
@@ -290,7 +331,7 @@ int AggregateDeclaration::firstFieldInUnion(int indx)
|
|||||||
*/
|
*/
|
||||||
int AggregateDeclaration::numFieldsInUnion(int firstIndex)
|
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
|
/* 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.
|
* 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;
|
int count = 1;
|
||||||
for (size_t i = firstIndex+1; i < fields.dim; ++i)
|
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 offsets are different, they are not in the same union
|
||||||
if (v->offset != vd->offset)
|
if (v->offset != vd->offset)
|
||||||
break;
|
break;
|
||||||
@@ -322,7 +363,10 @@ StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
|
|||||||
postblit = NULL;
|
postblit = NULL;
|
||||||
|
|
||||||
xeq = NULL;
|
xeq = NULL;
|
||||||
|
alignment = 0;
|
||||||
#endif
|
#endif
|
||||||
|
arg1type = NULL;
|
||||||
|
arg2type = NULL;
|
||||||
|
|
||||||
// For forward references
|
// For forward references
|
||||||
type = new TypeStruct(this);
|
type = new TypeStruct(this);
|
||||||
@@ -389,8 +433,8 @@ void StructDeclaration::semantic(Scope *sc)
|
|||||||
#else
|
#else
|
||||||
handle = type->pointerTo();
|
handle = type->pointerTo();
|
||||||
#endif
|
#endif
|
||||||
structalign = sc->structalign;
|
|
||||||
protection = sc->protection;
|
protection = sc->protection;
|
||||||
|
alignment = sc->structalign;
|
||||||
storage_class |= sc->stc;
|
storage_class |= sc->stc;
|
||||||
if (sc->stc & STCdeprecated)
|
if (sc->stc & STCdeprecated)
|
||||||
isdeprecated = true;
|
isdeprecated = true;
|
||||||
@@ -403,7 +447,7 @@ void StructDeclaration::semantic(Scope *sc)
|
|||||||
int hasfunctions = 0;
|
int hasfunctions = 0;
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
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());
|
//printf("adding member '%s' to '%s'\n", s->toChars(), this->toChars());
|
||||||
s->addMember(sc, this, 1);
|
s->addMember(sc, this, 1);
|
||||||
if (s->isFuncDeclaration())
|
if (s->isFuncDeclaration())
|
||||||
@@ -452,6 +496,7 @@ void StructDeclaration::semantic(Scope *sc)
|
|||||||
sc2->inunion = 1;
|
sc2->inunion = 1;
|
||||||
sc2->protection = PROTpublic;
|
sc2->protection = PROTpublic;
|
||||||
sc2->explicitProtection = 0;
|
sc2->explicitProtection = 0;
|
||||||
|
sc2->structalign = STRUCTALIGN_DEFAULT;
|
||||||
|
|
||||||
size_t members_dim = members->dim;
|
size_t members_dim = members->dim;
|
||||||
|
|
||||||
@@ -507,7 +552,7 @@ void StructDeclaration::semantic(Scope *sc)
|
|||||||
fields.setDim(0);
|
fields.setDim(0);
|
||||||
structsize = 0;
|
structsize = 0;
|
||||||
alignsize = 0;
|
alignsize = 0;
|
||||||
structalign = 0;
|
// structalign = 0;
|
||||||
|
|
||||||
scope = scx ? scx : new Scope(*sc);
|
scope = scx ? scx : new Scope(*sc);
|
||||||
scope->setNoFree();
|
scope->setNoFree();
|
||||||
@@ -631,6 +676,15 @@ void StructDeclaration::semantic(Scope *sc)
|
|||||||
aggNew = (NewDeclaration *)search(0, Id::classNew, 0);
|
aggNew = (NewDeclaration *)search(0, Id::classNew, 0);
|
||||||
aggDelete = (DeleteDeclaration *)search(0, Id::classDelete, 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)
|
if (sc->func)
|
||||||
{
|
{
|
||||||
semantic2(sc);
|
semantic2(sc);
|
||||||
@@ -667,6 +721,7 @@ Dsymbol *StructDeclaration::search(Loc loc, Identifier *ident, int flags)
|
|||||||
|
|
||||||
void StructDeclaration::finalizeSize(Scope *sc)
|
void StructDeclaration::finalizeSize(Scope *sc)
|
||||||
{
|
{
|
||||||
|
//printf("StructDeclaration::finalizeSize() %s\n", toChars());
|
||||||
if (sizeok != SIZEOKnone)
|
if (sizeok != SIZEOKnone)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -690,11 +745,56 @@ void StructDeclaration::finalizeSize(Scope *sc)
|
|||||||
// Round struct size up to next alignsize boundary.
|
// Round struct size up to next alignsize boundary.
|
||||||
// This will ensure that arrays of structs will get their internals
|
// This will ensure that arrays of structs will get their internals
|
||||||
// aligned properly.
|
// 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;
|
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)
|
void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||||
{
|
{
|
||||||
buf->printf("%s ", kind());
|
buf->printf("%s ", kind());
|
||||||
@@ -711,7 +811,7 @@ void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
|||||||
buf->writenl();
|
buf->writenl();
|
||||||
for (size_t i = 0; i < members->dim; i++)
|
for (size_t i = 0; i < members->dim; i++)
|
||||||
{
|
{
|
||||||
Dsymbol *s = members->tdata()[i];
|
Dsymbol *s = (*members)[i];
|
||||||
|
|
||||||
buf->writestring(" ");
|
buf->writestring(" ");
|
||||||
s->toCBuffer(buf, hgs);
|
s->toCBuffer(buf, hgs);
|
||||||
|
|||||||
+6611
-6441
File diff suppressed because it is too large
Load Diff
+46
-46
@@ -1,46 +1,46 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2006 by Digital Mars
|
// Copyright (c) 1999-2006 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
// License for redistribution is by either the Artistic License
|
// License for redistribution is by either the Artistic License
|
||||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||||
// See the included readme.txt for details.
|
// See the included readme.txt for details.
|
||||||
|
|
||||||
#ifndef DMD_TOTAL_H
|
#ifndef DMD_TOTAL_H
|
||||||
#define DMD_TOTAL_H
|
#define DMD_TOTAL_H
|
||||||
|
|
||||||
#ifdef __DMC__
|
#ifdef __DMC__
|
||||||
#pragma once
|
#pragma once
|
||||||
#endif /* __DMC__ */
|
#endif /* __DMC__ */
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <wchar.h>
|
#include <wchar.h>
|
||||||
|
|
||||||
#include "root.h"
|
#include "root.h"
|
||||||
#include "stringtable.h"
|
#include "stringtable.h"
|
||||||
|
|
||||||
#include "arraytypes.h"
|
#include "arraytypes.h"
|
||||||
#include "mars.h"
|
#include "mars.h"
|
||||||
#include "lexer.h"
|
#include "lexer.h"
|
||||||
#include "parse.h"
|
#include "parse.h"
|
||||||
#include "identifier.h"
|
#include "identifier.h"
|
||||||
#include "enum.h"
|
#include "enum.h"
|
||||||
#include "aggregate.h"
|
#include "aggregate.h"
|
||||||
#include "mtype.h"
|
#include "mtype.h"
|
||||||
#include "expression.h"
|
#include "expression.h"
|
||||||
#include "declaration.h"
|
#include "declaration.h"
|
||||||
#include "statement.h"
|
#include "statement.h"
|
||||||
#include "scope.h"
|
#include "scope.h"
|
||||||
#include "import.h"
|
#include "import.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "id.h"
|
#include "id.h"
|
||||||
#include "cond.h"
|
#include "cond.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
#include "lib.h"
|
#include "lib.h"
|
||||||
|
|
||||||
#endif /* DMD_TOTAL_H */
|
#endif /* DMD_TOTAL_H */
|
||||||
|
|||||||
+16
-16
@@ -1,6 +1,6 @@
|
|||||||
|
|
||||||
// Compiler implementation of the D programming language
|
// Compiler implementation of the D programming language
|
||||||
// Copyright (c) 1999-2011 by Digital Mars
|
// Copyright (c) 1999-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -89,7 +89,7 @@ Expression *TraitsExp::semantic(Scope *sc)
|
|||||||
|
|
||||||
#define ISTYPE(cond) \
|
#define ISTYPE(cond) \
|
||||||
for (size_t i = 0; i < dim; i++) \
|
for (size_t i = 0; i < dim; i++) \
|
||||||
{ Type *t = getType(args->tdata()[i]); \
|
{ Type *t = getType((*args)[i]); \
|
||||||
if (!t) \
|
if (!t) \
|
||||||
goto Lfalse; \
|
goto Lfalse; \
|
||||||
if (!(cond)) \
|
if (!(cond)) \
|
||||||
@@ -101,7 +101,7 @@ Expression *TraitsExp::semantic(Scope *sc)
|
|||||||
|
|
||||||
#define ISDSYMBOL(cond) \
|
#define ISDSYMBOL(cond) \
|
||||||
for (size_t i = 0; i < dim; i++) \
|
for (size_t i = 0; i < dim; i++) \
|
||||||
{ Dsymbol *s = getDsymbol(args->tdata()[i]); \
|
{ Dsymbol *s = getDsymbol((*args)[i]); \
|
||||||
if (!s) \
|
if (!s) \
|
||||||
goto Lfalse; \
|
goto Lfalse; \
|
||||||
if (!(cond)) \
|
if (!(cond)) \
|
||||||
@@ -196,7 +196,7 @@ Expression *TraitsExp::semantic(Scope *sc)
|
|||||||
|
|
||||||
if (dim != 1)
|
if (dim != 1)
|
||||||
goto Ldimerror;
|
goto Ldimerror;
|
||||||
Object *o = args->tdata()[0];
|
Object *o = (*args)[0];
|
||||||
Dsymbol *s = getDsymbol(o);
|
Dsymbol *s = getDsymbol(o);
|
||||||
if (!s || !s->ident)
|
if (!s || !s->ident)
|
||||||
{
|
{
|
||||||
@@ -210,7 +210,7 @@ Expression *TraitsExp::semantic(Scope *sc)
|
|||||||
{
|
{
|
||||||
if (dim != 1)
|
if (dim != 1)
|
||||||
goto Ldimerror;
|
goto Ldimerror;
|
||||||
Object *o = args->tdata()[0];
|
Object *o = (*args)[0];
|
||||||
Dsymbol *s = getDsymbol(o);
|
Dsymbol *s = getDsymbol(o);
|
||||||
if (s)
|
if (s)
|
||||||
s = s->toParent();
|
s = s->toParent();
|
||||||
@@ -231,13 +231,13 @@ Expression *TraitsExp::semantic(Scope *sc)
|
|||||||
{
|
{
|
||||||
if (dim != 2)
|
if (dim != 2)
|
||||||
goto Ldimerror;
|
goto Ldimerror;
|
||||||
Object *o = args->tdata()[0];
|
Object *o = (*args)[0];
|
||||||
Expression *e = isExpression(args->tdata()[1]);
|
Expression *e = isExpression((*args)[1]);
|
||||||
if (!e)
|
if (!e)
|
||||||
{ error("expression expected as second argument of __traits %s", ident->toChars());
|
{ error("expression expected as second argument of __traits %s", ident->toChars());
|
||||||
goto Lfalse;
|
goto Lfalse;
|
||||||
}
|
}
|
||||||
e = e->optimize(WANTvalue | WANTinterpret);
|
e = e->ctfeInterpret();
|
||||||
StringExp *se = e->toString();
|
StringExp *se = e->toString();
|
||||||
if (!se || se->length() == 0)
|
if (!se || se->length() == 0)
|
||||||
{ error("string expected as second argument of __traits %s instead of %s", ident->toChars(), e->toChars());
|
{ 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)
|
if (dim != 1)
|
||||||
goto Ldimerror;
|
goto Ldimerror;
|
||||||
Object *o = args->tdata()[0];
|
Object *o = (*args)[0];
|
||||||
Dsymbol *s = getDsymbol(o);
|
Dsymbol *s = getDsymbol(o);
|
||||||
ClassDeclaration *cd;
|
ClassDeclaration *cd;
|
||||||
if (!s || (cd = s->isClassDeclaration()) == NULL)
|
if (!s || (cd = s->isClassDeclaration()) == NULL)
|
||||||
@@ -350,7 +350,7 @@ Expression *TraitsExp::semantic(Scope *sc)
|
|||||||
{
|
{
|
||||||
if (dim != 1)
|
if (dim != 1)
|
||||||
goto Ldimerror;
|
goto Ldimerror;
|
||||||
Object *o = args->tdata()[0];
|
Object *o = (*args)[0];
|
||||||
Dsymbol *s = getDsymbol(o);
|
Dsymbol *s = getDsymbol(o);
|
||||||
ScopeDsymbol *sd;
|
ScopeDsymbol *sd;
|
||||||
if (!s)
|
if (!s)
|
||||||
@@ -380,7 +380,7 @@ Expression *TraitsExp::semantic(Scope *sc)
|
|||||||
/* Skip if already present in idents[]
|
/* Skip if already present in idents[]
|
||||||
*/
|
*/
|
||||||
for (size_t j = 0; j < idents->dim; j++)
|
for (size_t j = 0; j < idents->dim; j++)
|
||||||
{ Identifier *id = idents->tdata()[j];
|
{ Identifier *id = (*idents)[j];
|
||||||
if (id == sm->ident)
|
if (id == sm->ident)
|
||||||
return 0;
|
return 0;
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
@@ -421,9 +421,9 @@ Expression *TraitsExp::semantic(Scope *sc)
|
|||||||
assert(sizeof(Expressions) == sizeof(Identifiers));
|
assert(sizeof(Expressions) == sizeof(Identifiers));
|
||||||
Expressions *exps = (Expressions *)idents;
|
Expressions *exps = (Expressions *)idents;
|
||||||
for (size_t i = 0; i < idents->dim; i++)
|
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());
|
StringExp *se = new StringExp(loc, id->toChars());
|
||||||
exps->tdata()[i] = se;
|
(*exps)[i] = se;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DMDV1
|
#if DMDV1
|
||||||
@@ -448,7 +448,7 @@ Expression *TraitsExp::semantic(Scope *sc)
|
|||||||
goto Lfalse;
|
goto Lfalse;
|
||||||
|
|
||||||
for (size_t i = 0; i < dim; i++)
|
for (size_t i = 0; i < dim; i++)
|
||||||
{ Object *o = args->tdata()[i];
|
{ Object *o = (*args)[i];
|
||||||
Expression *e;
|
Expression *e;
|
||||||
|
|
||||||
unsigned errors = global.startGagging();
|
unsigned errors = global.startGagging();
|
||||||
@@ -491,8 +491,8 @@ Expression *TraitsExp::semantic(Scope *sc)
|
|||||||
if (dim != 2)
|
if (dim != 2)
|
||||||
goto Ldimerror;
|
goto Ldimerror;
|
||||||
TemplateInstance::semanticTiargs(loc, sc, args, 0);
|
TemplateInstance::semanticTiargs(loc, sc, args, 0);
|
||||||
Object *o1 = args->tdata()[0];
|
Object *o1 = (*args)[0];
|
||||||
Object *o2 = args->tdata()[1];
|
Object *o2 = (*args)[1];
|
||||||
Dsymbol *s1 = getDsymbol(o1);
|
Dsymbol *s1 = getDsymbol(o1);
|
||||||
Dsymbol *s2 = getDsymbol(o2);
|
Dsymbol *s2 = getDsymbol(o2);
|
||||||
|
|
||||||
|
|||||||
-323
@@ -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;
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -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 <stdio.h>
|
||||||
|
|
||||||
#include "mars.h"
|
#include "mars.h"
|
||||||
|
|||||||
+228
-237
@@ -1,5 +1,5 @@
|
|||||||
// utf.c
|
// utf.c
|
||||||
// Copyright (c) 2003-2009 by Digital Mars
|
// Copyright (c) 2003-2012 by Digital Mars
|
||||||
// All Rights Reserved
|
// All Rights Reserved
|
||||||
// written by Walter Bright
|
// written by Walter Bright
|
||||||
// http://www.digitalmars.com
|
// http://www.digitalmars.com
|
||||||
@@ -7,22 +7,32 @@
|
|||||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||||
// See the included readme.txt for details.
|
// See the included readme.txt for details.
|
||||||
|
|
||||||
// Description of UTF-8 at:
|
/// Description of UTF-8 in [1]. Unicode non-characters and private-use
|
||||||
// http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8
|
/// 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 <assert.h>
|
||||||
|
|
||||||
#include "utf.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,
|
||||||
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,
|
4,4,4,4,4,4,4,4,5,5,5,5,6,6,0xFF,0xFF,
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
} // namespace
|
||||||
* 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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
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.
|
* Return !=0 if unicode alpha.
|
||||||
* Returns:
|
* Use table from C99 Appendix D.
|
||||||
* NULL success
|
|
||||||
* !=NULL error message string
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
const char *utf_decodeChar(unsigned char *s, size_t len, size_t *pidx, dchar_t *presult)
|
bool isUniAlpha(dchar_t c)
|
||||||
{
|
{
|
||||||
dchar_t V;
|
static size_t const END = sizeof(ALPHA_TABLE) / sizeof(ALPHA_TABLE[0]);
|
||||||
size_t i = *pidx;
|
size_t high = END - 1;
|
||||||
unsigned char u = s[i];
|
// Shortcut search if c is out of range
|
||||||
|
size_t low
|
||||||
//printf("utf_decodeChar(s = %02x, %02x, %02x len = %d)\n", u, s[1], s[2], len);
|
= (c < ALPHA_TABLE[0][0] || ALPHA_TABLE[high][1] < c) ? high + 1 : 0;
|
||||||
|
// Binary search
|
||||||
assert(i >= 0 && i < len);
|
while (low <= high)
|
||||||
|
|
||||||
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
|
|
||||||
{
|
{
|
||||||
V = (dchar_t) u;
|
size_t mid = (low + high) >> 1;
|
||||||
i++;
|
if (c < ALPHA_TABLE[mid][0])
|
||||||
}
|
high = mid - 1;
|
||||||
|
else if (ALPHA_TABLE[mid][1] < c)
|
||||||
assert(utf_isValidDchar(V));
|
low = mid + 1;
|
||||||
*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;
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
i++;
|
{
|
||||||
|
assert(ALPHA_TABLE[mid][0] <= c && c <= ALPHA_TABLE[mid][1]);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
return false;
|
||||||
{
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
|
|
||||||
assert(utf_isValidDchar(u));
|
|
||||||
*pidx = i;
|
|
||||||
*presult = (dchar_t)u;
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
Lerr:
|
|
||||||
*presult = (dchar_t)s[i];
|
|
||||||
*pidx = i + 1;
|
|
||||||
return msg;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void utf_encodeChar(unsigned char *s, dchar_t c)
|
|
||||||
{
|
|
||||||
if (c <= 0x7F)
|
|
||||||
{
|
|
||||||
s[0] = (char) c;
|
|
||||||
}
|
|
||||||
else if (c <= 0x7FF)
|
|
||||||
{
|
|
||||||
s[0] = (char)(0xC0 | (c >> 6));
|
|
||||||
s[1] = (char)(0x80 | (c & 0x3F));
|
|
||||||
}
|
|
||||||
else if (c <= 0xFFFF)
|
|
||||||
{
|
|
||||||
s[0] = (char)(0xE0 | (c >> 12));
|
|
||||||
s[1] = (char)(0x80 | ((c >> 6) & 0x3F));
|
|
||||||
s[2] = (char)(0x80 | (c & 0x3F));
|
|
||||||
}
|
|
||||||
else if (c <= 0x10FFFF)
|
|
||||||
{
|
|
||||||
s[0] = (char)(0xF0 | (c >> 18));
|
|
||||||
s[1] = (char)(0x80 | ((c >> 12) & 0x3F));
|
|
||||||
s[2] = (char)(0x80 | ((c >> 6) & 0x3F));
|
|
||||||
s[3] = (char)(0x80 | (c & 0x3F));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
void utf_encodeWchar(unsigned short *s, dchar_t c)
|
|
||||||
{
|
|
||||||
if (c <= 0xFFFF)
|
|
||||||
{
|
|
||||||
s[0] = (wchar_t) c;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
s[0] = (wchar_t) ((((c - 0x10000) >> 10) & 0x3FF) + 0xD800);
|
|
||||||
s[1] = (wchar_t) (((c - 0x10000) & 0x3FF) + 0xDC00);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the code length of c in the encoding.
|
* Returns the code length of c in code units.
|
||||||
* The code is returned in character count, not in bytes.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int utf_codeLengthChar(dchar_t c)
|
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.
|
* 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)
|
int utf_codeLength(int sz, dchar_t c)
|
||||||
{
|
{
|
||||||
if (sz == 1)
|
if (sz == 1)
|
||||||
@@ -305,16 +151,161 @@ int utf_codeLength(int sz, dchar_t c)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void utf_encode(int sz, void *s, dchar_t c)
|
void utf_encodeChar(utf8_t *s, dchar_t c)
|
||||||
{
|
{
|
||||||
if (sz == 1)
|
assert(s != NULL);
|
||||||
utf_encodeChar((unsigned char *)s, c);
|
assert(utf_isValidDchar(c));
|
||||||
else if (sz == 2)
|
if (c <= 0x7F)
|
||||||
utf_encodeWchar((unsigned short *)s, c);
|
{
|
||||||
|
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
|
else
|
||||||
{
|
{
|
||||||
assert(sz == 4);
|
s[0] = static_cast<utf16_t>((((c - 0x010000) >> 10) & 0x03FF) + 0xD800);
|
||||||
memcpy((unsigned char *)s, &c, sz);
|
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
@@ -11,25 +11,114 @@
|
|||||||
#ifndef DMD_UTF_H
|
#ifndef DMD_UTF_H
|
||||||
#define 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);
|
static utf16_t const ALPHA_TABLE[][2] =
|
||||||
const char *utf_decodeWchar(unsigned short *s, size_t len, size_t *pidx, dchar_t *presult);
|
{
|
||||||
|
{ 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);
|
} // namespace Unicode
|
||||||
void utf_encodeWchar(unsigned short *s, dchar_t c);
|
|
||||||
|
/// \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_codeLengthChar(dchar_t c);
|
||||||
int utf_codeLengthWchar(dchar_t c);
|
int utf_codeLengthWchar(dchar_t c);
|
||||||
|
|
||||||
int utf_codeLength(int sz, 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);
|
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
@@ -593,7 +593,8 @@ Params parseArgs(int originalArgc, char** originalArgv, ls::Path ldcPath)
|
|||||||
goto Lerror;
|
goto Lerror;
|
||||||
result.debugLevel = (int)level;
|
result.debugLevel = (int)level;
|
||||||
}
|
}
|
||||||
result.debugIdentifiers.push_back(p + 7);
|
else
|
||||||
|
result.debugIdentifiers.push_back(p + 7);
|
||||||
}
|
}
|
||||||
else if (p[6])
|
else if (p[6])
|
||||||
goto Lerror;
|
goto Lerror;
|
||||||
@@ -616,7 +617,8 @@ Params parseArgs(int originalArgc, char** originalArgv, ls::Path ldcPath)
|
|||||||
goto Lerror;
|
goto Lerror;
|
||||||
result.versionLevel = (int)level;
|
result.versionLevel = (int)level;
|
||||||
}
|
}
|
||||||
result.versionIdentifiers.push_back(p + 9);
|
else
|
||||||
|
result.versionIdentifiers.push_back(p + 9);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
goto Lerror;
|
goto Lerror;
|
||||||
@@ -769,11 +771,11 @@ void buildCommandLine(std::vector<const char*>& r, const Params& p)
|
|||||||
if (p.debugFlag) r.push_back("-d-debug");
|
if (p.debugFlag) r.push_back("-d-debug");
|
||||||
if (p.debugLevel) r.push_back(concat("-d-debug=", p.debugLevel));
|
if (p.debugLevel) r.push_back(concat("-d-debug=", p.debugLevel));
|
||||||
pushSwitches("-d-debug=", p.debugIdentifiers, r);
|
pushSwitches("-d-debug=", p.debugIdentifiers, r);
|
||||||
if (p.debugLevel) r.push_back(concat("-d-version=", p.versionLevel));
|
if (p.versionLevel) r.push_back(concat("-d-version=", p.versionLevel));
|
||||||
pushSwitches("-d-version=", p.versionIdentifiers, r);
|
pushSwitches("-d-version=", p.versionIdentifiers, r);
|
||||||
pushSwitches("-L=", p.linkerSwitches, r);
|
pushSwitches("-L=", p.linkerSwitches, r);
|
||||||
if (p.defaultLibName) r.push_back(concat("-defaultlib=", p.defaultLibName));
|
if (p.defaultLibName) r.push_back(concat("-defaultlib=", p.defaultLibName));
|
||||||
if (p.debugLibName) r.push_back(concat("-deps=", p.moduleDepsFile));
|
if (p.debugLibName) r.push_back(concat("-debuglib=", p.debugLibName));
|
||||||
if (p.hiddenDebugB) r.push_back("-hidden-debug-b");
|
if (p.hiddenDebugB) r.push_back("-hidden-debug-b");
|
||||||
if (p.hiddenDebugC) r.push_back("-hidden-debug-c");
|
if (p.hiddenDebugC) r.push_back("-hidden-debug-c");
|
||||||
if (p.hiddenDebugF) r.push_back("-hidden-debug-f");
|
if (p.hiddenDebugF) r.push_back("-hidden-debug-f");
|
||||||
|
|||||||
+7
-168
@@ -58,167 +58,6 @@ void linkModules(llvm::Module* dst, const Module_vector& MV)
|
|||||||
|
|
||||||
static llvm::sys::Path gExePath;
|
static llvm::sys::Path gExePath;
|
||||||
|
|
||||||
int linkExecutable(const char* argv0)
|
|
||||||
{
|
|
||||||
Logger::println("*** Linking executable ***");
|
|
||||||
|
|
||||||
// error string
|
|
||||||
std::string errstr;
|
|
||||||
|
|
||||||
// find the llvm-ld program
|
|
||||||
llvm::sys::Path ldpath = llvm::sys::Program::FindProgramByName("llvm-ld");
|
|
||||||
if (ldpath.isEmpty())
|
|
||||||
{
|
|
||||||
ldpath.set("llvm-ld");
|
|
||||||
}
|
|
||||||
|
|
||||||
// build arguments
|
|
||||||
std::vector<const char*> args;
|
|
||||||
|
|
||||||
// first the program name ??
|
|
||||||
args.push_back("llvm-ld");
|
|
||||||
|
|
||||||
// output filename
|
|
||||||
std::string exestr;
|
|
||||||
if (global.params.exefile)
|
|
||||||
{ // explicit
|
|
||||||
exestr = global.params.exefile;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{ // inferred
|
|
||||||
// try root module name
|
|
||||||
if (Module::rootModule)
|
|
||||||
exestr = Module::rootModule->toChars();
|
|
||||||
else
|
|
||||||
exestr = "a.out";
|
|
||||||
}
|
|
||||||
if (global.params.os == OSWindows && !(exestr.substr(exestr.length()-4) == ".exe"))
|
|
||||||
exestr.append(".exe");
|
|
||||||
|
|
||||||
std::string outopt = "-o=" + exestr;
|
|
||||||
args.push_back(outopt.c_str());
|
|
||||||
|
|
||||||
// set the global gExePath
|
|
||||||
gExePath.set(exestr);
|
|
||||||
assert(gExePath.isValid());
|
|
||||||
|
|
||||||
// create path to exe
|
|
||||||
llvm::sys::Path exedir(llvm::sys::path::parent_path(gExePath.str()));
|
|
||||||
if (!llvm::sys::fs::exists(exedir.str()))
|
|
||||||
{
|
|
||||||
exedir.createDirectoryOnDisk(true, &errstr);
|
|
||||||
if (!errstr.empty())
|
|
||||||
{
|
|
||||||
error("failed to create path to linking output: %s\n%s", exedir.c_str(), errstr.c_str());
|
|
||||||
fatal();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// strip debug info
|
|
||||||
if (!global.params.symdebug)
|
|
||||||
args.push_back("-strip-debug");
|
|
||||||
|
|
||||||
// optimization level
|
|
||||||
if (!optimize())
|
|
||||||
args.push_back("-disable-opt");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
switch(optLevel())
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
args.push_back("-disable-opt");
|
|
||||||
break;
|
|
||||||
case 1:
|
|
||||||
args.push_back("-globaldce");
|
|
||||||
args.push_back("-disable-opt");
|
|
||||||
args.push_back("-globaldce");
|
|
||||||
args.push_back("-mem2reg");
|
|
||||||
case 2:
|
|
||||||
case 3:
|
|
||||||
case 4:
|
|
||||||
case 5:
|
|
||||||
// use default optimization
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// inlining
|
|
||||||
if (!(global.params.useInline || doInline()))
|
|
||||||
{
|
|
||||||
args.push_back("-disable-inlining");
|
|
||||||
}
|
|
||||||
|
|
||||||
// additional linker switches
|
|
||||||
for (unsigned i = 0; i < global.params.linkswitches->dim; i++)
|
|
||||||
{
|
|
||||||
char *p = static_cast<char *>(global.params.linkswitches->data[i]);
|
|
||||||
args.push_back(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
// native please
|
|
||||||
args.push_back("-native");
|
|
||||||
|
|
||||||
|
|
||||||
// user libs
|
|
||||||
for (unsigned i = 0; i < global.params.libfiles->dim; i++)
|
|
||||||
{
|
|
||||||
char *p = static_cast<char *>(global.params.libfiles->data[i]);
|
|
||||||
args.push_back(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
// default libs
|
|
||||||
switch(global.params.os) {
|
|
||||||
case OSLinux:
|
|
||||||
case OSMacOSX:
|
|
||||||
args.push_back("-ldl");
|
|
||||||
case OSFreeBSD:
|
|
||||||
args.push_back("-lpthread");
|
|
||||||
args.push_back("-lm");
|
|
||||||
break;
|
|
||||||
case OSHaiku:
|
|
||||||
args.push_back("-lroot");
|
|
||||||
break;
|
|
||||||
case OSWindows:
|
|
||||||
// FIXME: I'd assume kernel32 etc
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
// object files
|
|
||||||
for (unsigned i = 0; i < global.params.objfiles->dim; i++)
|
|
||||||
{
|
|
||||||
char *p = static_cast<char *>(global.params.objfiles->data[i]);
|
|
||||||
args.push_back(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
// print link command?
|
|
||||||
if (!quiet || global.params.verbose)
|
|
||||||
{
|
|
||||||
// Print it
|
|
||||||
for (int i = 0; i < args.size(); i++)
|
|
||||||
printf("%s ", args[i]);
|
|
||||||
printf("\n");
|
|
||||||
fflush(stdout);
|
|
||||||
}
|
|
||||||
|
|
||||||
// terminate args list
|
|
||||||
args.push_back(NULL);
|
|
||||||
|
|
||||||
// try to call linker!!!
|
|
||||||
if (int status = llvm::sys::Program::ExecuteAndWait(ldpath, &args[0], NULL, NULL, 0,0, &errstr))
|
|
||||||
{
|
|
||||||
error("linking failed:\nstatus: %d", status);
|
|
||||||
if (!errstr.empty())
|
|
||||||
error("message: %s", errstr.c_str());
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
int linkObjToBinary(bool sharedLib)
|
int linkObjToBinary(bool sharedLib)
|
||||||
{
|
{
|
||||||
Logger::println("*** Linking executable ***");
|
Logger::println("*** Linking executable ***");
|
||||||
@@ -244,6 +83,13 @@ int linkObjToBinary(bool sharedLib)
|
|||||||
args.push_back(p);
|
args.push_back(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// user libs
|
||||||
|
for (unsigned i = 0; i < global.params.libfiles->dim; i++)
|
||||||
|
{
|
||||||
|
char *p = static_cast<char *>(global.params.libfiles->data[i]);
|
||||||
|
args.push_back(p);
|
||||||
|
}
|
||||||
|
|
||||||
// output filename
|
// output filename
|
||||||
std::string output;
|
std::string output;
|
||||||
if (!sharedLib && global.params.exefile)
|
if (!sharedLib && global.params.exefile)
|
||||||
@@ -308,13 +154,6 @@ int linkObjToBinary(bool sharedLib)
|
|||||||
args.push_back(p);
|
args.push_back(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
// user libs
|
|
||||||
for (unsigned i = 0; i < global.params.libfiles->dim; i++)
|
|
||||||
{
|
|
||||||
char *p = static_cast<char *>(global.params.libfiles->data[i]);
|
|
||||||
args.push_back(p);
|
|
||||||
}
|
|
||||||
|
|
||||||
// default libs
|
// default libs
|
||||||
bool addSoname = false;
|
bool addSoname = false;
|
||||||
switch(global.params.os) {
|
switch(global.params.os) {
|
||||||
|
|||||||
+2
-9
@@ -18,13 +18,6 @@ namespace llvm
|
|||||||
*/
|
*/
|
||||||
void linkModules(llvm::Module* dst, const std::vector<llvm::Module*>& MV);
|
void linkModules(llvm::Module* dst, const std::vector<llvm::Module*>& MV);
|
||||||
|
|
||||||
/**
|
|
||||||
* Link an executable.
|
|
||||||
* @param argv0 the argv[0] value as passed to main
|
|
||||||
* @return 0 on success.
|
|
||||||
*/
|
|
||||||
int linkExecutable(const char* argv0);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Link an executable only from object files.
|
* Link an executable only from object files.
|
||||||
* @param argv0 the argv[0] value as passed to main
|
* @param argv0 the argv[0] value as passed to main
|
||||||
@@ -38,12 +31,12 @@ int linkObjToBinary(bool sharedLib);
|
|||||||
void createStaticLibrary();
|
void createStaticLibrary();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the executable that was previously linked with linkExecutable.
|
* Delete the executable that was previously linked with linkObjToBinary.
|
||||||
*/
|
*/
|
||||||
void deleteExecutable();
|
void deleteExecutable();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Runs the executable that was previously linked with linkExecutable.
|
* Runs the executable that was previously linked with linkObjToBinary.
|
||||||
* @return the return status of the executable.
|
* @return the return status of the executable.
|
||||||
*/
|
*/
|
||||||
int runExecutable();
|
int runExecutable();
|
||||||
|
|||||||
+6
-4
@@ -23,6 +23,11 @@
|
|||||||
#include "rmem.h"
|
#include "rmem.h"
|
||||||
#include "root.h"
|
#include "root.h"
|
||||||
|
|
||||||
|
// stricmp
|
||||||
|
#if __GNUC__ && !_WIN32
|
||||||
|
#include "gnuc.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "mars.h"
|
#include "mars.h"
|
||||||
#include "module.h"
|
#include "module.h"
|
||||||
#include "mtype.h"
|
#include "mtype.h"
|
||||||
@@ -835,10 +840,7 @@ int main(int argc, char** argv)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (stricmp(ext, global.mars_ext) == 0 ||
|
if (stricmp(ext, global.mars_ext) == 0 ||
|
||||||
stricmp(ext, global.hdr_ext) == 0 ||
|
stricmp(ext, global.hdr_ext) == 0)
|
||||||
stricmp(ext, "htm") == 0 ||
|
|
||||||
stricmp(ext, "html") == 0 ||
|
|
||||||
stricmp(ext, "xhtml") == 0)
|
|
||||||
{
|
{
|
||||||
ext--; // skip onto '.'
|
ext--; // skip onto '.'
|
||||||
assert(*ext == '.');
|
assert(*ext == '.');
|
||||||
|
|||||||
+4
-1
@@ -208,7 +208,10 @@ void DtoArrayAssign(DValue *array, DValue *value, int op)
|
|||||||
|
|
||||||
assert(value && array);
|
assert(value && array);
|
||||||
assert(op != TOKblit);
|
assert(op != TOKblit);
|
||||||
Type *t = value->type->toBasetype();
|
|
||||||
|
// Use array->type instead of value->type so as to not accidentally pick
|
||||||
|
// up a superfluous const layer (TypeInfo_Const doesn't pass on postblit()).
|
||||||
|
Type *t = array->type->toBasetype();
|
||||||
assert(t->nextOf());
|
assert(t->nextOf());
|
||||||
Type *elemType = t->nextOf()->toBasetype();
|
Type *elemType = t->nextOf()->toBasetype();
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -2189,7 +2189,7 @@ namespace AsmParserx8632
|
|||||||
*/
|
*/
|
||||||
if ( isDollar ( e ) )
|
if ( isDollar ( e ) )
|
||||||
{
|
{
|
||||||
error ( "dollar labels are not supported", stmt->loc.toChars() );
|
stmt->error("dollar labels are not supported");
|
||||||
asmcode->dollarLabel = 1;
|
asmcode->dollarLabel = 1;
|
||||||
}
|
}
|
||||||
else if ( e->op == TOKdsymbol )
|
else if ( e->op == TOKdsymbol )
|
||||||
|
|||||||
+1
-1
@@ -2325,7 +2325,7 @@ namespace AsmParserx8664
|
|||||||
*/
|
*/
|
||||||
if ( isDollar ( e ) )
|
if ( isDollar ( e ) )
|
||||||
{
|
{
|
||||||
error ( "dollar labels are not supported", stmt->loc.toChars() );
|
stmt->error("dollar labels are not supported");
|
||||||
asmcode->dollarLabel = 1;
|
asmcode->dollarLabel = 1;
|
||||||
}
|
}
|
||||||
else if ( e->op == TOKdsymbol )
|
else if ( e->op == TOKdsymbol )
|
||||||
|
|||||||
+1
-1
@@ -187,7 +187,7 @@ int AsmStatement::blockExit(bool mustNotThrow)
|
|||||||
//printf("AsmStatement::blockExit(%p)\n", this);
|
//printf("AsmStatement::blockExit(%p)\n", this);
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
if (mustNotThrow)
|
if (mustNotThrow)
|
||||||
error("asm statements are assumed to throw", toChars());
|
error("asm statements are assumed to throw");
|
||||||
#endif
|
#endif
|
||||||
// Assume the worst
|
// Assume the worst
|
||||||
return BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt;
|
return BEfallthru | BEthrow | BEreturn | BEgoto | BEhalt;
|
||||||
|
|||||||
+14
-10
@@ -676,7 +676,7 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
|||||||
// OffsetTypeInfo[] offTi;
|
// OffsetTypeInfo[] offTi;
|
||||||
// void *defaultConstructor;
|
// void *defaultConstructor;
|
||||||
// version(D_Version2)
|
// version(D_Version2)
|
||||||
// const(MemberInfo[]) function(string) xgetMembers;
|
// immutable(void)* m_RTInfo;
|
||||||
// else
|
// else
|
||||||
// TypeInfo typeinfo; // since dmd 1.045
|
// TypeInfo typeinfo; // since dmd 1.045
|
||||||
// }
|
// }
|
||||||
@@ -761,10 +761,12 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
|||||||
b.push_funcptr(cd->inv, invVar->type);
|
b.push_funcptr(cd->inv, invVar->type);
|
||||||
|
|
||||||
// uint flags
|
// uint flags
|
||||||
|
unsigned flags;
|
||||||
if (cd->isInterfaceDeclaration())
|
if (cd->isInterfaceDeclaration())
|
||||||
b.push_uint(4 | cd->isCOMinterface() | 32);
|
flags = 4 | cd->isCOMinterface() | 32;
|
||||||
else
|
else
|
||||||
b.push_uint(build_classinfo_flags(cd));
|
flags = build_classinfo_flags(cd);
|
||||||
|
b.push_uint(flags);
|
||||||
|
|
||||||
// deallocator
|
// deallocator
|
||||||
b.push_funcptr(cd->aggDelete, Type::tvoid->pointerTo());
|
b.push_funcptr(cd->aggDelete, Type::tvoid->pointerTo());
|
||||||
@@ -790,16 +792,18 @@ LLConstant* DtoDefineClassInfo(ClassDeclaration* cd)
|
|||||||
b.push_funcptr(cd->defaultCtor, defConstructorVar->type);
|
b.push_funcptr(cd->defaultCtor, defConstructorVar->type);
|
||||||
|
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
|
// immutable(void)* m_RTInfo;
|
||||||
// xgetMembers
|
// The cases where getRTInfo is null are not quite here, but the code is
|
||||||
VarDeclaration* xgetVar = static_cast<VarDeclaration*>(cinfo->fields.data[11]);
|
// modelled after what DMD does.
|
||||||
b.push_funcptr(cd->findGetMembers(), xgetVar->type);
|
if (cd->getRTInfo)
|
||||||
|
b.push(cd->getRTInfo->toConstElem(gIR));
|
||||||
|
else if (flags & 2)
|
||||||
|
b.push_size_as_vp(0); // no pointers
|
||||||
|
else
|
||||||
|
b.push_size_as_vp(1); // has pointers
|
||||||
#else
|
#else
|
||||||
|
|
||||||
// typeinfo - since 1.045
|
// typeinfo - since 1.045
|
||||||
b.push_typeinfo(cd->type);
|
b.push_typeinfo(cd->type);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/*size_t n = inits.size();
|
/*size_t n = inits.size();
|
||||||
|
|||||||
+11
-2
@@ -16,6 +16,8 @@ DVarValue::DVarValue(Type* t, VarDeclaration* vd, LLValue* llvmValue)
|
|||||||
: DValue(t), var(vd), val(llvmValue)
|
: DValue(t), var(vd), val(llvmValue)
|
||||||
{
|
{
|
||||||
assert(isaPointer(llvmValue));
|
assert(isaPointer(llvmValue));
|
||||||
|
assert(!isSpecialRefVar(vd) ||
|
||||||
|
isaPointer(isaPointer(llvmValue)->getElementType()));
|
||||||
}
|
}
|
||||||
|
|
||||||
DVarValue::DVarValue(Type* t, LLValue* llvmValue)
|
DVarValue::DVarValue(Type* t, LLValue* llvmValue)
|
||||||
@@ -27,6 +29,8 @@ DVarValue::DVarValue(Type* t, LLValue* llvmValue)
|
|||||||
LLValue* DVarValue::getLVal()
|
LLValue* DVarValue::getLVal()
|
||||||
{
|
{
|
||||||
assert(val);
|
assert(val);
|
||||||
|
if (var && isSpecialRefVar(var))
|
||||||
|
return DtoLoad(val);
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,9 +38,14 @@ LLValue* DVarValue::getRVal()
|
|||||||
{
|
{
|
||||||
assert(val);
|
assert(val);
|
||||||
Type* bt = type->toBasetype();
|
Type* bt = type->toBasetype();
|
||||||
|
|
||||||
|
LLValue* tmp = val;
|
||||||
|
if (var && isSpecialRefVar(var))
|
||||||
|
tmp = DtoLoad(tmp);
|
||||||
|
|
||||||
if (DtoIsPassedByRef(bt))
|
if (DtoIsPassedByRef(bt))
|
||||||
return val;
|
return tmp;
|
||||||
return DtoLoad(val);
|
return DtoLoad(tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|||||||
+5
-6
@@ -807,16 +807,15 @@ void DtoDefineFunction(FuncDeclaration* fd)
|
|||||||
|
|
||||||
DtoCreateNestedContext(fd);
|
DtoCreateNestedContext(fd);
|
||||||
|
|
||||||
|
if (fd->vresult && !
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
if (fd->vresult && fd->vresult->nestedrefs.dim) // FIXME: not sure here :/
|
fd->vresult->nestedrefs.dim // FIXME: not sure here :/
|
||||||
#else
|
#else
|
||||||
if (fd->vresult && fd->vresult->nestedref)
|
fd->vresult->nestedref
|
||||||
#endif
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
DtoNestedInit(fd->vresult);
|
DtoVarDeclaration(fd->vresult);
|
||||||
} else if (fd->vresult) {
|
|
||||||
fd->vresult->ir.irLocal = new IrLocal(fd->vresult);
|
|
||||||
fd->vresult->ir.irLocal->value = DtoAlloca(fd->vresult->type, fd->vresult->toChars());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// copy _argptr and _arguments to a memory location
|
// copy _argptr and _arguments to a memory location
|
||||||
|
|||||||
+175
-175
@@ -1,175 +1,175 @@
|
|||||||
/* DMDFE backend stubs
|
/* DMDFE backend stubs
|
||||||
* This file contains the implementations of the backend routines.
|
* This file contains the implementations of the backend routines.
|
||||||
* For dmdfe these do nothing but print a message saying the module
|
* For dmdfe these do nothing but print a message saying the module
|
||||||
* has been parsed. Substitute your own behaviors for these routimes.
|
* has been parsed. Substitute your own behaviors for these routimes.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <cstdarg>
|
#include <cstdarg>
|
||||||
|
|
||||||
#include "gen/llvm.h"
|
#include "gen/llvm.h"
|
||||||
|
|
||||||
#include "mtype.h"
|
#include "mtype.h"
|
||||||
#include "declaration.h"
|
#include "declaration.h"
|
||||||
#include "statement.h"
|
#include "statement.h"
|
||||||
|
|
||||||
#include "gen/irstate.h"
|
#include "gen/irstate.h"
|
||||||
#include "tollvm.h"
|
#include "tollvm.h"
|
||||||
|
|
||||||
IRState* gIR = 0;
|
IRState* gIR = 0;
|
||||||
llvm::TargetMachine* gTargetMachine = 0;
|
llvm::TargetMachine* gTargetMachine = 0;
|
||||||
const llvm::TargetData* gTargetData = 0;
|
const llvm::TargetData* gTargetData = 0;
|
||||||
TargetABI* gABI = 0;
|
TargetABI* gABI = 0;
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
IRScope::IRScope()
|
IRScope::IRScope()
|
||||||
: builder(gIR->context())
|
: builder(gIR->context())
|
||||||
{
|
{
|
||||||
begin = end = NULL;
|
begin = end = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
IRScope::IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e)
|
IRScope::IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e)
|
||||||
: builder(b)
|
: builder(b)
|
||||||
{
|
{
|
||||||
begin = b;
|
begin = b;
|
||||||
end = e;
|
end = e;
|
||||||
}
|
}
|
||||||
|
|
||||||
const IRScope& IRScope::operator=(const IRScope& rhs)
|
const IRScope& IRScope::operator=(const IRScope& rhs)
|
||||||
{
|
{
|
||||||
begin = rhs.begin;
|
begin = rhs.begin;
|
||||||
end = rhs.end;
|
end = rhs.end;
|
||||||
builder.SetInsertPoint(begin);
|
builder.SetInsertPoint(begin);
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
IRTargetScope::IRTargetScope()
|
IRTargetScope::IRTargetScope()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
IRTargetScope::IRTargetScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* continueTarget, llvm::BasicBlock* breakTarget)
|
IRTargetScope::IRTargetScope(Statement* s, EnclosingHandler* enclosinghandler, llvm::BasicBlock* continueTarget, llvm::BasicBlock* breakTarget)
|
||||||
{
|
{
|
||||||
this->s = s;
|
this->s = s;
|
||||||
this->enclosinghandler = enclosinghandler;
|
this->enclosinghandler = enclosinghandler;
|
||||||
this->breakTarget = breakTarget;
|
this->breakTarget = breakTarget;
|
||||||
this->continueTarget = continueTarget;
|
this->continueTarget = continueTarget;
|
||||||
}
|
}
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
IRState::IRState(llvm::Module* m)
|
IRState::IRState(llvm::Module* m)
|
||||||
: module(m), dibuilder(*m)
|
: module(m), dibuilder(*m)
|
||||||
{
|
{
|
||||||
interfaceInfoType = NULL;
|
interfaceInfoType = NULL;
|
||||||
mutexType = NULL;
|
mutexType = NULL;
|
||||||
moduleRefType = NULL;
|
moduleRefType = NULL;
|
||||||
|
|
||||||
dmodule = 0;
|
dmodule = 0;
|
||||||
emitMain = false;
|
emitMain = false;
|
||||||
mainFunc = 0;
|
mainFunc = 0;
|
||||||
ir.state = this;
|
ir.state = this;
|
||||||
asmBlock = NULL;
|
asmBlock = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
IrFunction* IRState::func()
|
IrFunction* IRState::func()
|
||||||
{
|
{
|
||||||
assert(!functions.empty() && "Function stack is empty!");
|
assert(!functions.empty() && "Function stack is empty!");
|
||||||
return functions.back();
|
return functions.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Function* IRState::topfunc()
|
llvm::Function* IRState::topfunc()
|
||||||
{
|
{
|
||||||
assert(!functions.empty() && "Function stack is empty!");
|
assert(!functions.empty() && "Function stack is empty!");
|
||||||
return functions.back()->func;
|
return functions.back()->func;
|
||||||
}
|
}
|
||||||
|
|
||||||
TypeFunction* IRState::topfunctype()
|
TypeFunction* IRState::topfunctype()
|
||||||
{
|
{
|
||||||
assert(!functions.empty() && "Function stack is empty!");
|
assert(!functions.empty() && "Function stack is empty!");
|
||||||
return functions.back()->type;
|
return functions.back()->type;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::Instruction* IRState::topallocapoint()
|
llvm::Instruction* IRState::topallocapoint()
|
||||||
{
|
{
|
||||||
assert(!functions.empty() && "AllocaPoint stack is empty!");
|
assert(!functions.empty() && "AllocaPoint stack is empty!");
|
||||||
return functions.back()->allocapoint;
|
return functions.back()->allocapoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
IrStruct* IRState::topstruct()
|
IrStruct* IRState::topstruct()
|
||||||
{
|
{
|
||||||
assert(!structs.empty() && "Struct vector is empty!");
|
assert(!structs.empty() && "Struct vector is empty!");
|
||||||
return structs.back();
|
return structs.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
IRScope& IRState::scope()
|
IRScope& IRState::scope()
|
||||||
{
|
{
|
||||||
assert(!scopes.empty());
|
assert(!scopes.empty());
|
||||||
return scopes.back();
|
return scopes.back();
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::BasicBlock* IRState::scopebb()
|
llvm::BasicBlock* IRState::scopebb()
|
||||||
{
|
{
|
||||||
IRScope& s = scope();
|
IRScope& s = scope();
|
||||||
assert(s.begin);
|
assert(s.begin);
|
||||||
return s.begin;
|
return s.begin;
|
||||||
}
|
}
|
||||||
llvm::BasicBlock* IRState::scopeend()
|
llvm::BasicBlock* IRState::scopeend()
|
||||||
{
|
{
|
||||||
IRScope& s = scope();
|
IRScope& s = scope();
|
||||||
assert(s.end);
|
assert(s.end);
|
||||||
return s.end;
|
return s.end;
|
||||||
}
|
}
|
||||||
bool IRState::scopereturned()
|
bool IRState::scopereturned()
|
||||||
{
|
{
|
||||||
//return scope().returned;
|
//return scope().returned;
|
||||||
return !scopebb()->empty() && scopebb()->back().isTerminator();
|
return !scopebb()->empty() && scopebb()->back().isTerminator();
|
||||||
}
|
}
|
||||||
|
|
||||||
LLCallSite IRState::CreateCallOrInvoke(LLValue* Callee, const char* Name)
|
LLCallSite IRState::CreateCallOrInvoke(LLValue* Callee, const char* Name)
|
||||||
{
|
{
|
||||||
LLSmallVector<LLValue*, 1> args;
|
LLSmallVector<LLValue*, 1> args;
|
||||||
return CreateCallOrInvoke(Callee, args, Name);
|
return CreateCallOrInvoke(Callee, args, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLCallSite IRState::CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name)
|
LLCallSite IRState::CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name)
|
||||||
{
|
{
|
||||||
LLSmallVector<LLValue*, 1> args;
|
LLSmallVector<LLValue*, 1> args;
|
||||||
args.push_back(Arg1);
|
args.push_back(Arg1);
|
||||||
return CreateCallOrInvoke(Callee, args, Name);
|
return CreateCallOrInvoke(Callee, args, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLCallSite IRState::CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name)
|
LLCallSite IRState::CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name)
|
||||||
{
|
{
|
||||||
LLSmallVector<LLValue*, 2> args;
|
LLSmallVector<LLValue*, 2> args;
|
||||||
args.push_back(Arg1);
|
args.push_back(Arg1);
|
||||||
args.push_back(Arg2);
|
args.push_back(Arg2);
|
||||||
return CreateCallOrInvoke(Callee, args, Name);
|
return CreateCallOrInvoke(Callee, args, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLCallSite IRState::CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name)
|
LLCallSite IRState::CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name)
|
||||||
{
|
{
|
||||||
LLSmallVector<LLValue*, 3> args;
|
LLSmallVector<LLValue*, 3> args;
|
||||||
args.push_back(Arg1);
|
args.push_back(Arg1);
|
||||||
args.push_back(Arg2);
|
args.push_back(Arg2);
|
||||||
args.push_back(Arg3);
|
args.push_back(Arg3);
|
||||||
return CreateCallOrInvoke(Callee, args, Name);
|
return CreateCallOrInvoke(Callee, args, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
LLCallSite IRState::CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, LLValue* Arg4, const char* Name)
|
LLCallSite IRState::CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, LLValue* Arg4, const char* Name)
|
||||||
{
|
{
|
||||||
LLSmallVector<LLValue*, 4> args;
|
LLSmallVector<LLValue*, 4> args;
|
||||||
args.push_back(Arg1);
|
args.push_back(Arg1);
|
||||||
args.push_back(Arg2);
|
args.push_back(Arg2);
|
||||||
args.push_back(Arg3);
|
args.push_back(Arg3);
|
||||||
args.push_back(Arg4);
|
args.push_back(Arg4);
|
||||||
return CreateCallOrInvoke(Callee, args, Name);
|
return CreateCallOrInvoke(Callee, args, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
IRBuilder<>* IRBuilderHelper::operator->()
|
IRBuilder<>* IRBuilderHelper::operator->()
|
||||||
{
|
{
|
||||||
IRBuilder<>& b = state->scope().builder;
|
IRBuilder<>& b = state->scope().builder;
|
||||||
assert(b.GetInsertBlock() != NULL);
|
assert(b.GetInsertBlock() != NULL);
|
||||||
return &b;
|
return &b;
|
||||||
}
|
}
|
||||||
|
|||||||
+234
-234
@@ -1,234 +1,234 @@
|
|||||||
#ifndef LDC_GEN_IRSTATE_H
|
#ifndef LDC_GEN_IRSTATE_H
|
||||||
#define LDC_GEN_IRSTATE_H
|
#define LDC_GEN_IRSTATE_H
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <deque>
|
#include <deque>
|
||||||
#include <list>
|
#include <list>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
|
|
||||||
#include "root.h"
|
#include "root.h"
|
||||||
#include "aggregate.h"
|
#include "aggregate.h"
|
||||||
|
|
||||||
#include "ir/irfunction.h"
|
#include "ir/irfunction.h"
|
||||||
#include "ir/irstruct.h"
|
#include "ir/irstruct.h"
|
||||||
#include "ir/irvar.h"
|
#include "ir/irvar.h"
|
||||||
|
|
||||||
#if LDC_LLVM_VER >= 302
|
#if LDC_LLVM_VER >= 302
|
||||||
#include "llvm/DIBuilder.h"
|
#include "llvm/DIBuilder.h"
|
||||||
#else
|
#else
|
||||||
#include "llvm/Analysis/DIBuilder.h"
|
#include "llvm/Analysis/DIBuilder.h"
|
||||||
#endif
|
#endif
|
||||||
#include "llvm/Support/CallSite.h"
|
#include "llvm/Support/CallSite.h"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
class LLVMContext;
|
class LLVMContext;
|
||||||
class TargetMachine;
|
class TargetMachine;
|
||||||
}
|
}
|
||||||
|
|
||||||
// global ir state for current module
|
// global ir state for current module
|
||||||
struct IRState;
|
struct IRState;
|
||||||
struct TargetABI;
|
struct TargetABI;
|
||||||
|
|
||||||
extern IRState* gIR;
|
extern IRState* gIR;
|
||||||
extern llvm::TargetMachine* gTargetMachine;
|
extern llvm::TargetMachine* gTargetMachine;
|
||||||
extern const llvm::TargetData* gTargetData;
|
extern const llvm::TargetData* gTargetData;
|
||||||
extern TargetABI* gABI;
|
extern TargetABI* gABI;
|
||||||
|
|
||||||
struct TypeFunction;
|
struct TypeFunction;
|
||||||
struct TypeStruct;
|
struct TypeStruct;
|
||||||
struct ClassDeclaration;
|
struct ClassDeclaration;
|
||||||
struct FuncDeclaration;
|
struct FuncDeclaration;
|
||||||
struct Module;
|
struct Module;
|
||||||
struct TypeStruct;
|
struct TypeStruct;
|
||||||
struct BaseClass;
|
struct BaseClass;
|
||||||
struct AnonDeclaration;
|
struct AnonDeclaration;
|
||||||
|
|
||||||
struct IrModule;
|
struct IrModule;
|
||||||
|
|
||||||
// represents a scope
|
// represents a scope
|
||||||
struct IRScope
|
struct IRScope
|
||||||
{
|
{
|
||||||
llvm::BasicBlock* begin;
|
llvm::BasicBlock* begin;
|
||||||
llvm::BasicBlock* end;
|
llvm::BasicBlock* end;
|
||||||
IRBuilder<> builder;
|
IRBuilder<> builder;
|
||||||
|
|
||||||
IRScope();
|
IRScope();
|
||||||
IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e);
|
IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e);
|
||||||
|
|
||||||
const IRScope& operator=(const IRScope& rhs);
|
const IRScope& operator=(const IRScope& rhs);
|
||||||
|
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
// list of variables needing destruction
|
// list of variables needing destruction
|
||||||
std::vector<VarDeclaration*> varsInScope;
|
std::vector<VarDeclaration*> varsInScope;
|
||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IRBuilderHelper
|
struct IRBuilderHelper
|
||||||
{
|
{
|
||||||
IRState* state;
|
IRState* state;
|
||||||
IRBuilder<>* operator->();
|
IRBuilder<>* operator->();
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IRAsmStmt
|
struct IRAsmStmt
|
||||||
{
|
{
|
||||||
IRAsmStmt()
|
IRAsmStmt()
|
||||||
: isBranchToLabel(NULL) {}
|
: isBranchToLabel(NULL) {}
|
||||||
|
|
||||||
std::string code;
|
std::string code;
|
||||||
std::string out_c;
|
std::string out_c;
|
||||||
std::string in_c;
|
std::string in_c;
|
||||||
std::vector<LLValue*> out;
|
std::vector<LLValue*> out;
|
||||||
std::vector<LLValue*> in;
|
std::vector<LLValue*> in;
|
||||||
|
|
||||||
// if this is nonzero, it contains the target label
|
// if this is nonzero, it contains the target label
|
||||||
Identifier* isBranchToLabel;
|
Identifier* isBranchToLabel;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct IRAsmBlock
|
struct IRAsmBlock
|
||||||
{
|
{
|
||||||
std::deque<IRAsmStmt*> s;
|
std::deque<IRAsmStmt*> s;
|
||||||
std::set<std::string> clobs;
|
std::set<std::string> clobs;
|
||||||
size_t outputcount;
|
size_t outputcount;
|
||||||
|
|
||||||
// stores the labels within the asm block
|
// stores the labels within the asm block
|
||||||
std::vector<Identifier*> internalLabels;
|
std::vector<Identifier*> internalLabels;
|
||||||
|
|
||||||
AsmBlockStatement* asmBlock;
|
AsmBlockStatement* asmBlock;
|
||||||
LLType* retty;
|
LLType* retty;
|
||||||
unsigned retn;
|
unsigned retn;
|
||||||
bool retemu; // emulate abi ret with a temporary
|
bool retemu; // emulate abi ret with a temporary
|
||||||
LLValue* (*retfixup)(IRBuilderHelper b, LLValue* orig); // Modifies retval
|
LLValue* (*retfixup)(IRBuilderHelper b, LLValue* orig); // Modifies retval
|
||||||
|
|
||||||
IRAsmBlock(AsmBlockStatement* b)
|
IRAsmBlock(AsmBlockStatement* b)
|
||||||
: outputcount(0), asmBlock(b), retty(NULL), retn(0), retemu(false),
|
: outputcount(0), asmBlock(b), retty(NULL), retn(0), retemu(false),
|
||||||
retfixup(NULL)
|
retfixup(NULL)
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
|
|
||||||
// represents the module
|
// represents the module
|
||||||
struct IRState
|
struct IRState
|
||||||
{
|
{
|
||||||
IRState(llvm::Module* m);
|
IRState(llvm::Module* m);
|
||||||
|
|
||||||
// module
|
// module
|
||||||
Module* dmodule;
|
Module* dmodule;
|
||||||
llvm::Module* module;
|
llvm::Module* module;
|
||||||
|
|
||||||
// interface info type, used in DtoInterfaceInfoType
|
// interface info type, used in DtoInterfaceInfoType
|
||||||
LLStructType* interfaceInfoType;
|
LLStructType* interfaceInfoType;
|
||||||
LLStructType* mutexType;
|
LLStructType* mutexType;
|
||||||
LLStructType* moduleRefType;
|
LLStructType* moduleRefType;
|
||||||
|
|
||||||
// helper to get the LLVMContext of the module
|
// helper to get the LLVMContext of the module
|
||||||
llvm::LLVMContext& context() const { return module->getContext(); }
|
llvm::LLVMContext& context() const { return module->getContext(); }
|
||||||
|
|
||||||
// functions
|
// functions
|
||||||
typedef std::vector<IrFunction*> FunctionVector;
|
typedef std::vector<IrFunction*> FunctionVector;
|
||||||
FunctionVector functions;
|
FunctionVector functions;
|
||||||
IrFunction* func();
|
IrFunction* func();
|
||||||
|
|
||||||
llvm::Function* topfunc();
|
llvm::Function* topfunc();
|
||||||
TypeFunction* topfunctype();
|
TypeFunction* topfunctype();
|
||||||
llvm::Instruction* topallocapoint();
|
llvm::Instruction* topallocapoint();
|
||||||
|
|
||||||
// structs
|
// structs
|
||||||
typedef std::vector<IrStruct*> StructVector;
|
typedef std::vector<IrStruct*> StructVector;
|
||||||
StructVector structs;
|
StructVector structs;
|
||||||
IrStruct* topstruct();
|
IrStruct* topstruct();
|
||||||
|
|
||||||
// D main function
|
// D main function
|
||||||
bool emitMain;
|
bool emitMain;
|
||||||
llvm::Function* mainFunc;
|
llvm::Function* mainFunc;
|
||||||
|
|
||||||
// basic block scopes
|
// basic block scopes
|
||||||
std::vector<IRScope> scopes;
|
std::vector<IRScope> scopes;
|
||||||
IRScope& scope();
|
IRScope& scope();
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
std::vector<VarDeclaration*> &varsInScope() { return scope().varsInScope; }
|
std::vector<VarDeclaration*> &varsInScope() { return scope().varsInScope; }
|
||||||
#endif
|
#endif
|
||||||
llvm::BasicBlock* scopebb();
|
llvm::BasicBlock* scopebb();
|
||||||
llvm::BasicBlock* scopeend();
|
llvm::BasicBlock* scopeend();
|
||||||
bool scopereturned();
|
bool scopereturned();
|
||||||
|
|
||||||
// create a call or invoke, depending on the landing pad info
|
// create a call or invoke, depending on the landing pad info
|
||||||
// the template function is defined further down in this file
|
// the template function is defined further down in this file
|
||||||
template <typename T>
|
template <typename T>
|
||||||
llvm::CallSite CreateCallOrInvoke(LLValue* Callee, const T& args, const char* Name="");
|
llvm::CallSite CreateCallOrInvoke(LLValue* Callee, const T& args, const char* Name="");
|
||||||
llvm::CallSite CreateCallOrInvoke(LLValue* Callee, const char* Name="");
|
llvm::CallSite CreateCallOrInvoke(LLValue* Callee, const char* Name="");
|
||||||
llvm::CallSite CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name="");
|
llvm::CallSite CreateCallOrInvoke(LLValue* Callee, LLValue* Arg1, const char* Name="");
|
||||||
llvm::CallSite CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name="");
|
llvm::CallSite CreateCallOrInvoke2(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, const char* Name="");
|
||||||
llvm::CallSite CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name="");
|
llvm::CallSite CreateCallOrInvoke3(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, const char* Name="");
|
||||||
llvm::CallSite CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, LLValue* Arg4, const char* Name="");
|
llvm::CallSite CreateCallOrInvoke4(LLValue* Callee, LLValue* Arg1, LLValue* Arg2, LLValue* Arg3, LLValue* Arg4, const char* Name="");
|
||||||
|
|
||||||
// this holds the array being indexed or sliced so $ will work
|
// this holds the array being indexed or sliced so $ will work
|
||||||
// might be a better way but it works. problem is I only get a
|
// might be a better way but it works. problem is I only get a
|
||||||
// VarDeclaration for __dollar, but I can't see how to get the
|
// VarDeclaration for __dollar, but I can't see how to get the
|
||||||
// array pointer from this :(
|
// array pointer from this :(
|
||||||
std::vector<DValue*> arrays;
|
std::vector<DValue*> arrays;
|
||||||
|
|
||||||
// builder helper
|
// builder helper
|
||||||
IRBuilderHelper ir;
|
IRBuilderHelper ir;
|
||||||
|
|
||||||
// debug info helper
|
// debug info helper
|
||||||
llvm::DIBuilder dibuilder;
|
llvm::DIBuilder dibuilder;
|
||||||
|
|
||||||
// static ctors/dtors/unittests
|
// static ctors/dtors/unittests
|
||||||
typedef std::list<FuncDeclaration*> FuncDeclList;
|
typedef std::list<FuncDeclaration*> FuncDeclList;
|
||||||
typedef std::list<VarDeclaration*> GatesList;
|
typedef std::list<VarDeclaration*> GatesList;
|
||||||
FuncDeclList ctors;
|
FuncDeclList ctors;
|
||||||
FuncDeclList dtors;
|
FuncDeclList dtors;
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
FuncDeclList sharedCtors;
|
FuncDeclList sharedCtors;
|
||||||
FuncDeclList sharedDtors;
|
FuncDeclList sharedDtors;
|
||||||
GatesList gates;
|
GatesList gates;
|
||||||
GatesList sharedGates;
|
GatesList sharedGates;
|
||||||
#endif
|
#endif
|
||||||
FuncDeclList unitTests;
|
FuncDeclList unitTests;
|
||||||
|
|
||||||
// all template instances that had members emitted
|
// all template instances that had members emitted
|
||||||
// currently only filled for singleobj
|
// currently only filled for singleobj
|
||||||
// used to make sure the complete template instance gets emitted in the
|
// used to make sure the complete template instance gets emitted in the
|
||||||
// first file that touches a member, see #318
|
// first file that touches a member, see #318
|
||||||
typedef std::set<TemplateInstance*> TemplateInstanceSet;
|
typedef std::set<TemplateInstance*> TemplateInstanceSet;
|
||||||
TemplateInstanceSet seenTemplateInstances;
|
TemplateInstanceSet seenTemplateInstances;
|
||||||
|
|
||||||
// for inline asm
|
// for inline asm
|
||||||
IRAsmBlock* asmBlock;
|
IRAsmBlock* asmBlock;
|
||||||
std::ostringstream nakedAsm;
|
std::ostringstream nakedAsm;
|
||||||
|
|
||||||
// 'used' array solely for keeping a reference to globals
|
// 'used' array solely for keeping a reference to globals
|
||||||
std::vector<LLConstant*> usedArray;
|
std::vector<LLConstant*> usedArray;
|
||||||
};
|
};
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, const T &args, const char* Name)
|
llvm::CallSite IRState::CreateCallOrInvoke(LLValue* Callee, const T &args, const char* Name)
|
||||||
{
|
{
|
||||||
llvm::BasicBlock* pad = func()->gen->landingPad;
|
llvm::BasicBlock* pad = func()->gen->landingPad;
|
||||||
if(pad)
|
if(pad)
|
||||||
{
|
{
|
||||||
// intrinsics don't support invoking and 'nounwind' functions don't need it.
|
// intrinsics don't support invoking and 'nounwind' functions don't need it.
|
||||||
LLFunction* funcval = llvm::dyn_cast<LLFunction>(Callee);
|
LLFunction* funcval = llvm::dyn_cast<LLFunction>(Callee);
|
||||||
if (funcval && (funcval->isIntrinsic() || funcval->doesNotThrow()))
|
if (funcval && (funcval->isIntrinsic() || funcval->doesNotThrow()))
|
||||||
{
|
{
|
||||||
llvm::CallInst* call = ir->CreateCall(Callee, args, Name);
|
llvm::CallInst* call = ir->CreateCall(Callee, args, Name);
|
||||||
call->setAttributes(funcval->getAttributes());
|
call->setAttributes(funcval->getAttributes());
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
|
|
||||||
llvm::BasicBlock* postinvoke = llvm::BasicBlock::Create(gIR->context(), "postinvoke", topfunc(), scopeend());
|
llvm::BasicBlock* postinvoke = llvm::BasicBlock::Create(gIR->context(), "postinvoke", topfunc(), scopeend());
|
||||||
llvm::InvokeInst* invoke = ir->CreateInvoke(Callee, postinvoke, pad, args, Name);
|
llvm::InvokeInst* invoke = ir->CreateInvoke(Callee, postinvoke, pad, args, Name);
|
||||||
if (LLFunction* fn = llvm::dyn_cast<LLFunction>(Callee))
|
if (LLFunction* fn = llvm::dyn_cast<LLFunction>(Callee))
|
||||||
invoke->setAttributes(fn->getAttributes());
|
invoke->setAttributes(fn->getAttributes());
|
||||||
scope() = IRScope(postinvoke, scopeend());
|
scope() = IRScope(postinvoke, scopeend());
|
||||||
return invoke;
|
return invoke;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
llvm::CallInst* call = ir->CreateCall(Callee, args, Name);
|
llvm::CallInst* call = ir->CreateCall(Callee, args, Name);
|
||||||
if (LLFunction* fn = llvm::dyn_cast<LLFunction>(Callee))
|
if (LLFunction* fn = llvm::dyn_cast<LLFunction>(Callee))
|
||||||
call->setAttributes(fn->getAttributes());
|
call->setAttributes(fn->getAttributes());
|
||||||
return call;
|
return call;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // LDC_GEN_IRSTATE_H
|
#endif // LDC_GEN_IRSTATE_H
|
||||||
|
|||||||
+128
-215
@@ -393,19 +393,7 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs, int op)
|
|||||||
Type* t2 = rhs->getType()->toBasetype();
|
Type* t2 = rhs->getType()->toBasetype();
|
||||||
|
|
||||||
if (t->ty == Tstruct) {
|
if (t->ty == Tstruct) {
|
||||||
if (!stripModifiers(t)->equals(stripModifiers(t2))) {
|
DtoAggrCopy(lhs->getLVal(), rhs->getRVal());
|
||||||
// FIXME: use 'rhs' for something !?!
|
|
||||||
DtoAggrZeroInit(lhs->getLVal());
|
|
||||||
#if DMDV2
|
|
||||||
TypeStruct *ts = static_cast<TypeStruct*>(lhs->getType());
|
|
||||||
if (ts->sym->isNested() && ts->sym->vthis)
|
|
||||||
DtoResolveNestedContext(loc, ts->sym, lhs->getLVal());
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
DtoAggrCopy(lhs->getLVal(), rhs->getRVal());
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
else if (t->ty == Tarray) {
|
else if (t->ty == Tarray) {
|
||||||
// lhs is slice
|
// lhs is slice
|
||||||
@@ -1013,6 +1001,110 @@ void DtoConstInitGlobal(VarDeclaration* vd)
|
|||||||
/*////////////////////////////////////////////////////////////////////////////////////////
|
/*////////////////////////////////////////////////////////////////////////////////////////
|
||||||
// DECLARATION EXP HELPER
|
// DECLARATION EXP HELPER
|
||||||
////////////////////////////////////////////////////////////////////////////////////////*/
|
////////////////////////////////////////////////////////////////////////////////////////*/
|
||||||
|
|
||||||
|
// TODO: Merge with DtoRawVarDeclaration!
|
||||||
|
void DtoVarDeclaration(VarDeclaration* vd)
|
||||||
|
{
|
||||||
|
assert(!vd->isDataseg() && "Statics/globals are handled in DtoDeclarationExp.");
|
||||||
|
assert(!vd->aliassym && "Aliases are handled in DtoDeclarationExp.");
|
||||||
|
|
||||||
|
Logger::println("vdtype = %s", vd->type->toChars());
|
||||||
|
|
||||||
|
#if DMDV2
|
||||||
|
if (vd->nestedrefs.dim)
|
||||||
|
#else
|
||||||
|
if (vd->nestedref)
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
Logger::println("has nestedref set (referenced by nested function/delegate)");
|
||||||
|
assert(vd->ir.irLocal && "irLocal is expected to be already set by DtoCreateNestedContext");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(vd->ir.irLocal)
|
||||||
|
{
|
||||||
|
// Nothing to do if it has already been allocated.
|
||||||
|
}
|
||||||
|
#if DMDV2
|
||||||
|
/* Named Return Value Optimization (NRVO):
|
||||||
|
T f(){
|
||||||
|
T ret; // &ret == hidden pointer
|
||||||
|
ret = ...
|
||||||
|
return ret; // NRVO.
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
else if (gIR->func()->retArg && gIR->func()->decl->nrvo_can && gIR->func()->decl->nrvo_var == vd) {
|
||||||
|
assert(!isSpecialRefVar(vd) && "Can this happen?");
|
||||||
|
vd->ir.irLocal = new IrLocal(vd);
|
||||||
|
vd->ir.irLocal->value = gIR->func()->retArg;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
// normal stack variable, allocate storage on the stack if it has not already been done
|
||||||
|
else {
|
||||||
|
vd->ir.irLocal = new IrLocal(vd);
|
||||||
|
|
||||||
|
#if DMDV2
|
||||||
|
/* NRVO again:
|
||||||
|
T t = f(); // t's memory address is taken hidden pointer
|
||||||
|
*/
|
||||||
|
ExpInitializer *ei = 0;
|
||||||
|
if (vd->type->toBasetype()->ty == Tstruct && vd->init &&
|
||||||
|
!!(ei = vd->init->isExpInitializer()))
|
||||||
|
{
|
||||||
|
if (ei->exp->op == TOKconstruct) {
|
||||||
|
AssignExp *ae = static_cast<AssignExp*>(ei->exp);
|
||||||
|
if (ae->e2->op == TOKcall) {
|
||||||
|
CallExp *ce = static_cast<CallExp *>(ae->e2);
|
||||||
|
TypeFunction *tf = static_cast<TypeFunction *>(ce->e1->type->toBasetype());
|
||||||
|
if (tf->ty == Tfunction && tf->fty.arg_sret) {
|
||||||
|
LLValue* const val = ce->toElem(gIR)->getLVal();
|
||||||
|
if (isSpecialRefVar(vd))
|
||||||
|
{
|
||||||
|
vd->ir.irLocal->value = DtoAlloca(
|
||||||
|
vd->type->pointerTo(), vd->toChars());
|
||||||
|
DtoStore(val, vd->ir.irLocal->value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
vd->ir.irLocal->value = val;
|
||||||
|
}
|
||||||
|
goto Lexit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
Type* type = isSpecialRefVar(vd) ? vd->type->pointerTo() : vd->type;
|
||||||
|
LLType* lltype = DtoType(type);
|
||||||
|
|
||||||
|
llvm::Value* allocainst;
|
||||||
|
if(gTargetData->getTypeSizeInBits(lltype) == 0)
|
||||||
|
allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
|
||||||
|
else
|
||||||
|
allocainst = DtoAlloca(type, vd->toChars());
|
||||||
|
|
||||||
|
vd->ir.irLocal->value = allocainst;
|
||||||
|
|
||||||
|
DtoDwarfLocalVariable(allocainst, vd);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (Logger::enabled())
|
||||||
|
Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n';
|
||||||
|
|
||||||
|
DtoInitializer(vd->ir.irLocal->value, vd->init); // TODO: Remove altogether?
|
||||||
|
|
||||||
|
#if DMDV2
|
||||||
|
Lexit:
|
||||||
|
/* Mark the point of construction of a variable that needs to be destructed.
|
||||||
|
*/
|
||||||
|
if (vd->edtor && !vd->noscope)
|
||||||
|
{
|
||||||
|
// Put vd on list of things needing destruction
|
||||||
|
gIR->varsInScope().push_back(vd);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
DValue* DtoDeclarationExp(Dsymbol* declaration)
|
DValue* DtoDeclarationExp(Dsymbol* declaration)
|
||||||
{
|
{
|
||||||
Logger::print("DtoDeclarationExp: %s\n", declaration->toChars());
|
Logger::print("DtoDeclarationExp: %s\n", declaration->toChars());
|
||||||
@@ -1036,123 +1128,8 @@ DValue* DtoDeclarationExp(Dsymbol* declaration)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (global.params.llvmAnnotate)
|
DtoVarDeclaration(vd);
|
||||||
DtoAnnotation(declaration->toChars());
|
|
||||||
|
|
||||||
Logger::println("vdtype = %s", vd->type->toChars());
|
|
||||||
|
|
||||||
// ref vardecls are generated when DMD lowers foreach to a for statement,
|
|
||||||
// and this is a hack to support them for this case only
|
|
||||||
if(vd->isRef())
|
|
||||||
{
|
|
||||||
if (!vd->ir.irLocal)
|
|
||||||
vd->ir.irLocal = new IrLocal(vd);
|
|
||||||
|
|
||||||
ExpInitializer* ex = vd->init->isExpInitializer();
|
|
||||||
assert(ex && "ref vars must have expression initializer");
|
|
||||||
assert(ex->exp);
|
|
||||||
AssignExp* as = ex->exp->isAssignExp();
|
|
||||||
assert(as && "ref vars must be initialized by an assign exp");
|
|
||||||
DValue *val = as->e2->toElem(gIR);
|
|
||||||
if (val->isLVal())
|
|
||||||
{
|
|
||||||
vd->ir.irLocal->value = val->getLVal();
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
LLValue *newVal = DtoAlloca(val->type);
|
|
||||||
DtoStore(val->getRVal(), newVal);
|
|
||||||
vd->ir.irLocal->value = newVal;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// referenced by nested delegate?
|
|
||||||
#if DMDV2
|
|
||||||
if (vd->nestedrefs.dim) {
|
|
||||||
#else
|
|
||||||
if (vd->nestedref) {
|
|
||||||
#endif
|
|
||||||
Logger::println("has nestedref set");
|
|
||||||
assert(vd->ir.irLocal);
|
|
||||||
DtoNestedInit(vd);
|
|
||||||
// is it already allocated?
|
|
||||||
} else if(vd->ir.irLocal) {
|
|
||||||
// nothing to do...
|
|
||||||
}
|
|
||||||
#if DMDV2
|
|
||||||
/* Named Return Value Optimization (NRVO):
|
|
||||||
T f(){
|
|
||||||
T ret; // &ret == hidden pointer
|
|
||||||
ret = ...
|
|
||||||
return ret; // NRVO.
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
else if (gIR->func()->retArg && gIR->func()->decl->nrvo_can && gIR->func()->decl->nrvo_var == vd) {
|
|
||||||
vd->ir.irLocal = new IrLocal(vd);
|
|
||||||
vd->ir.irLocal->value = gIR->func()->retArg;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
// normal stack variable, allocate storage on the stack if it has not already been done
|
|
||||||
else if(!vd->isRef()) {
|
|
||||||
vd->ir.irLocal = new IrLocal(vd);
|
|
||||||
|
|
||||||
#if DMDV2
|
|
||||||
/* NRVO again:
|
|
||||||
T t = f(); // t's memory address is taken hidden pointer
|
|
||||||
*/
|
|
||||||
ExpInitializer *ei = 0;
|
|
||||||
if (vd->type->toBasetype()->ty == Tstruct && vd->init &&
|
|
||||||
!!(ei = vd->init->isExpInitializer()))
|
|
||||||
{
|
|
||||||
if (ei->exp->op == TOKconstruct) {
|
|
||||||
AssignExp *ae = static_cast<AssignExp*>(ei->exp);
|
|
||||||
if (ae->e2->op == TOKcall) {
|
|
||||||
CallExp *ce = static_cast<CallExp *>(ae->e2);
|
|
||||||
TypeFunction *tf = static_cast<TypeFunction *>(ce->e1->type->toBasetype());
|
|
||||||
if (tf->ty == Tfunction && tf->fty.arg_sret) {
|
|
||||||
vd->ir.irLocal->value = ce->toElem(gIR)->getLVal();
|
|
||||||
goto Lexit;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
LLType* lltype = DtoType(vd->type);
|
|
||||||
|
|
||||||
llvm::Value* allocainst;
|
|
||||||
if(gTargetData->getTypeSizeInBits(lltype) == 0)
|
|
||||||
allocainst = llvm::ConstantPointerNull::get(getPtrToType(lltype));
|
|
||||||
else
|
|
||||||
allocainst = DtoAlloca(vd->type, vd->toChars());
|
|
||||||
|
|
||||||
//allocainst->setAlignment(vd->type->alignsize()); // TODO
|
|
||||||
vd->ir.irLocal->value = allocainst;
|
|
||||||
|
|
||||||
DtoDwarfLocalVariable(allocainst, vd);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
assert(vd->ir.irLocal->value);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Logger::enabled())
|
|
||||||
Logger::cout() << "llvm value for decl: " << *vd->ir.irLocal->value << '\n';
|
|
||||||
if (!vd->isRef())
|
|
||||||
DtoInitializer(vd->ir.irLocal->value, vd->init); // TODO: Remove altogether?
|
|
||||||
|
|
||||||
#if DMDV2
|
|
||||||
Lexit:
|
|
||||||
/* Mark the point of construction of a variable that needs to be destructed.
|
|
||||||
*/
|
|
||||||
if (vd->edtor && !vd->noscope)
|
|
||||||
{
|
|
||||||
// Put vd on list of things needing destruction
|
|
||||||
gIR->varsInScope().push_back(vd);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return new DVarValue(vd->type, vd, vd->ir.getIrValue());
|
return new DVarValue(vd->type, vd, vd->ir.getIrValue());
|
||||||
}
|
}
|
||||||
// struct declaration
|
// struct declaration
|
||||||
@@ -1276,8 +1253,6 @@ LLValue* DtoRawVarDeclaration(VarDeclaration* var, LLValue* addr)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
assert(!addr || addr == var->ir.irLocal->value);
|
assert(!addr || addr == var->ir.irLocal->value);
|
||||||
|
|
||||||
DtoNestedInit(var);
|
|
||||||
}
|
}
|
||||||
// normal local variable
|
// normal local variable
|
||||||
else
|
else
|
||||||
@@ -1461,7 +1436,7 @@ static LLConstant* expand_to_sarray(Type *base, Expression* exp)
|
|||||||
TypeSArray* tsa = static_cast<TypeSArray*>(t);
|
TypeSArray* tsa = static_cast<TypeSArray*>(t);
|
||||||
dims.push_back(tsa->dim->toInteger());
|
dims.push_back(tsa->dim->toInteger());
|
||||||
assert(t->nextOf());
|
assert(t->nextOf());
|
||||||
t = t->nextOf()->toBasetype();
|
t = stripModifiers(t->nextOf()->toBasetype());
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t i = dims.size();
|
size_t i = dims.size();
|
||||||
@@ -1482,8 +1457,8 @@ static LLConstant* expand_to_sarray(Type *base, Expression* exp)
|
|||||||
LLConstant* DtoConstExpInit(Loc loc, Type* type, Expression* exp)
|
LLConstant* DtoConstExpInit(Loc loc, Type* type, Expression* exp)
|
||||||
{
|
{
|
||||||
#if DMDV2
|
#if DMDV2
|
||||||
Type* expbase = exp->type->toBasetype()->mutableOf()->merge();
|
Type* expbase = stripModifiers(exp->type->toBasetype())->merge();
|
||||||
Type* base = type->toBasetype()->mutableOf()->merge();
|
Type* base = stripModifiers(type->toBasetype())->merge();
|
||||||
#else
|
#else
|
||||||
Type* expbase = exp->type->toBasetype();
|
Type* expbase = exp->type->toBasetype();
|
||||||
Type* base = type->toBasetype();
|
Type* base = type->toBasetype();
|
||||||
@@ -1501,9 +1476,18 @@ LLConstant* DtoConstExpInit(Loc loc, Type* type, Expression* exp)
|
|||||||
Logger::println("type is a static array, building constant array initializer to single value");
|
Logger::println("type is a static array, building constant array initializer to single value");
|
||||||
return expand_to_sarray(base, exp);
|
return expand_to_sarray(base, exp);
|
||||||
}
|
}
|
||||||
|
#if DMDV2
|
||||||
|
else if (base->ty == Tvector)
|
||||||
|
{
|
||||||
|
LLConstant* val = exp->toConstElem(gIR);
|
||||||
|
TypeVector* tv = (TypeVector*)base;
|
||||||
|
return llvm::ConstantVector::getSplat(tv->size(loc), val);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
error("cannot yet convert default initializer %s of type %s to %s", exp->toChars(), exp->type->toChars(), type->toChars());
|
error(loc, "LDC internal error: cannot yet convert default initializer %s of type %s to %s",
|
||||||
|
exp->toChars(), exp->type->toChars(), type->toChars());
|
||||||
fatal();
|
fatal();
|
||||||
}
|
}
|
||||||
assert(0);
|
assert(0);
|
||||||
@@ -1769,85 +1753,7 @@ Type * stripModifiers( Type * type )
|
|||||||
#if DMDV2
|
#if DMDV2
|
||||||
if (type->ty == Tfunction)
|
if (type->ty == Tfunction)
|
||||||
return type;
|
return type;
|
||||||
Type *t = type;
|
return type->castMod(0);
|
||||||
while (t->mod)
|
|
||||||
{
|
|
||||||
switch (t->mod)
|
|
||||||
{
|
|
||||||
case MODconst:
|
|
||||||
t = type->cto;
|
|
||||||
break;
|
|
||||||
case MODshared:
|
|
||||||
t = type->sto;
|
|
||||||
break;
|
|
||||||
case MODimmutable:
|
|
||||||
t = type->ito;
|
|
||||||
break;
|
|
||||||
case MODshared | MODconst:
|
|
||||||
t = type->scto;
|
|
||||||
break;
|
|
||||||
case MODwild:
|
|
||||||
t = type->wto;
|
|
||||||
break;
|
|
||||||
case MODshared | MODwild:
|
|
||||||
t = type->swto;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
assert(0 && "Unhandled type modifier");
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!t)
|
|
||||||
{
|
|
||||||
unsigned sz = type->sizeTy[type->ty];
|
|
||||||
t = static_cast<Type *>(malloc(sz));
|
|
||||||
memcpy(t, type, sz);
|
|
||||||
t->mod = 0;
|
|
||||||
t->deco = NULL;
|
|
||||||
t->arrayof = NULL;
|
|
||||||
t->pto = NULL;
|
|
||||||
t->rto = NULL;
|
|
||||||
t->cto = NULL;
|
|
||||||
t->ito = NULL;
|
|
||||||
t->sto = NULL;
|
|
||||||
t->scto = NULL;
|
|
||||||
t->wto = NULL;
|
|
||||||
t->swto = NULL;
|
|
||||||
t->vtinfo = NULL;
|
|
||||||
t = t->merge();
|
|
||||||
|
|
||||||
t->fixTo(type);
|
|
||||||
switch (type->mod)
|
|
||||||
{
|
|
||||||
case MODconst:
|
|
||||||
t->cto = type;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MODimmutable:
|
|
||||||
t->ito = type;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MODshared:
|
|
||||||
t->sto = type;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MODshared | MODconst:
|
|
||||||
t->scto = type;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MODwild:
|
|
||||||
t->wto = type;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MODshared | MODwild:
|
|
||||||
t->swto = type;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
assert(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return t;
|
|
||||||
#else
|
#else
|
||||||
return type;
|
return type;
|
||||||
#endif
|
#endif
|
||||||
@@ -1895,7 +1801,7 @@ void callPostblit(Loc &loc, Expression *exp, LLValue *val)
|
|||||||
{
|
{
|
||||||
|
|
||||||
Type *tb = exp->type->toBasetype();
|
Type *tb = exp->type->toBasetype();
|
||||||
if ((exp->op == TOKvar || exp->op == TOKdotvar || exp->op == TOKstar || exp->op == TOKthis) &&
|
if ((exp->op == TOKvar || exp->op == TOKdotvar || exp->op == TOKstar || exp->op == TOKthis || exp->op == TOKindex) &&
|
||||||
tb->ty == Tstruct)
|
tb->ty == Tstruct)
|
||||||
{ StructDeclaration *sd = static_cast<TypeStruct *>(tb)->sym;
|
{ StructDeclaration *sd = static_cast<TypeStruct *>(tb)->sym;
|
||||||
if (sd->postblit)
|
if (sd->postblit)
|
||||||
@@ -1914,6 +1820,13 @@ void callPostblit(Loc &loc, Expression *exp, LLValue *val)
|
|||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
bool isSpecialRefVar(VarDeclaration* vd)
|
||||||
|
{
|
||||||
|
return (vd->storage_class & STCref) && (vd->storage_class & STCforeach);
|
||||||
|
}
|
||||||
|
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void printLabelName(std::ostream& target, const char* func_mangle, const char* label_name)
|
void printLabelName(std::ostream& target, const char* func_mangle, const char* label_name)
|
||||||
{
|
{
|
||||||
target << gTargetMachine->getMCAsmInfo()->getPrivateGlobalPrefix() <<
|
target << gTargetMachine->getMCAsmInfo()->getPrivateGlobalPrefix() <<
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user