Merged DMD 1.042.

This commit is contained in:
Tomas Lindquist Olsen
2009-04-03 17:59:34 +02:00
parent 57bf95cb42
commit 3d1f8cc565
38 changed files with 6504 additions and 5232 deletions

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -322,7 +322,7 @@ void StorageClassDeclaration::semantic(Scope *sc)
sc->stc = stc;
}
void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc)
{
struct SCstring
{
@@ -350,18 +350,19 @@ void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
// { STCtls, TOKtls },
};
int written = 0;
for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++)
{
if (stc & table[i].stc)
{
if (written)
buf->writeByte(' ');
written = 1;
buf->writestring(Token::toChars(table[i].tok));
buf->writeByte(' ');
}
}
}
void StorageClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
stcToCBuffer(buf, stc);
AttribDeclaration::toCBuffer(buf, hgs);
}
@@ -1193,6 +1194,18 @@ void PragmaDeclaration::toObjFile(int multiobj)
name[se->len] = 0;
obj_includelib(name);
}
#if DMDV2
else if (ident == Id::startaddress)
{
assert(args && args->dim == 1);
Expression *e = (Expression *)args->data[0];
Dsymbol *sa = getDsymbol(e);
FuncDeclaration *f = sa->isFuncDeclaration();
assert(f);
Symbol *s = f->toSymbol();
obj_startaddress(s);
}
#endif
AttribDeclaration::toObjFile(multiobj);
}
#endif

View File

@@ -68,6 +68,8 @@ struct StorageClassDeclaration: AttribDeclaration
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
static void stcToCBuffer(OutBuffer *buf, int stc);
};
struct LinkDeclaration : AttribDeclaration

View File

@@ -1,5 +1,5 @@
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -228,7 +228,7 @@ MATCH IntegerExp::implicitConvTo(Type *t)
case Tchar:
case Tuns8:
//printf("value = %llu %llu\n", (integer_t)(unsigned char)value, value);
//printf("value = %llu %llu\n", (dinteger_t)(unsigned char)value, value);
if ((unsigned char)value != value)
goto Lno;
goto Lyes;

View File

@@ -562,7 +562,7 @@ void ClassDeclaration::semantic(Scope *sc)
// sc->offset += PTRSIZE; // room for uplevel context pointer
}
else
{ sc->offset = 2*PTRSIZE; // allow room for vptr[] and monitor
{ sc->offset = PTRSIZE * 2; // allow room for vptr[] and monitor
alignsize = PTRSIZE;
}
structsize = sc->offset;
@@ -1152,7 +1152,7 @@ void InterfaceDeclaration::semantic(Scope *sc)
sc->linkage = LINKwindows;
sc->structalign = 8;
structalign = sc->structalign;
sc->offset = 2*PTRSIZE;
sc->offset = PTRSIZE * 2;
inuse++;
for (i = 0; i < members->dim; i++)
{

View File

@@ -129,7 +129,14 @@ void VersionCondition::checkPredefined(Loc loc, const char *ident)
{
"DigitalMars", "X86", "X86_64",
"Windows", "Win32", "Win64",
"linux", "Posix", "OSX", "FreeBSD",
"linux",
#if DMDV2
/* Although Posix is predefined by D1, disallowing its
* redefinition breaks makefiles and older builds.
*/
"Posix",
#endif
"OSX", "FreeBSD",
"LittleEndian", "BigEndian",
"all",
"none",

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -555,7 +555,7 @@ Expression *Shr(Type *type, Expression *e1, Expression *e2)
{ Expression *e;
Loc loc = e1->loc;
unsigned count;
integer_t value;
dinteger_t value;
value = e1->toInteger();
count = e2->toInteger();
@@ -604,7 +604,7 @@ Expression *Ushr(Type *type, Expression *e1, Expression *e2)
{ Expression *e;
Loc loc = e1->loc;
unsigned count;
integer_t value;
dinteger_t value;
value = e1->toInteger();
count = e2->toInteger();
@@ -887,7 +887,7 @@ Expression *Identity(enum TOK op, Type *type, Expression *e1, Expression *e2)
Expression *Cmp(enum TOK op, Type *type, Expression *e1, Expression *e2)
{ Expression *e;
Loc loc = e1->loc;
integer_t n;
dinteger_t n;
real_t r1;
real_t r2;
@@ -1058,7 +1058,7 @@ Expression *Cast(Type *type, Type *to, Expression *e1)
else if (type->isintegral())
{
if (e1->type->isfloating())
{ integer_t result;
{ dinteger_t result;
real_t r = e1->toReal();
switch (type->toBasetype()->ty)
@@ -1251,7 +1251,7 @@ Expression *Slice(Type *type, Expression *e1, Expression *lwr, Expression *upr)
if (iupr > es1->len || ilwr > iupr)
e1->error("string slice [%ju .. %ju] is out of bounds", ilwr, iupr);
else
{ integer_t value;
{ dinteger_t value;
void *s;
size_t len = iupr - ilwr;
int sz = es1->sz;
@@ -1317,7 +1317,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
StringExp *es;
size_t len = 1;
int sz = tn->size();
integer_t v = e->toInteger();
dinteger_t v = e->toInteger();
s = mem.malloc((len + 1) * sz);
memcpy((unsigned char *)s, &v, sz);
@@ -1384,7 +1384,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
Type *t;
size_t len = es1->len + 1;
int sz = es1->sz;
integer_t v = e2->toInteger();
dinteger_t v = e2->toInteger();
s = mem.malloc((len + 1) * sz);
memcpy(s, es1->string, es1->len * sz);
@@ -1409,7 +1409,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
Type *t;
size_t len = 1 + es2->len;
int sz = es2->sz;
integer_t v = e1->toInteger();
dinteger_t v = e1->toInteger();
s = mem.malloc((len + 1) * sz);
memcpy((unsigned char *)s, &v, sz);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,5 @@
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com

View File

@@ -32,9 +32,9 @@ struct EnumDeclaration : ScopeDsymbol
Type *memtype; // type of the members
#if DMDV1
integer_t maxval;
integer_t minval;
integer_t defaultval; // default initializer
dinteger_t maxval;
dinteger_t minval;
dinteger_t defaultval; // default initializer
#else
Expression *maxval;
Expression *minval;

View File

@@ -34,15 +34,6 @@ int isnan(double);
#endif
#endif
#if IN_GCC
// Issues with using -include total.h (defines integer_t) and then complex.h fails...
#undef integer_t
#endif
#ifdef __APPLE__
#define integer_t dmd_integer_t
#endif
#include "rmem.h"
//#include "port.h"
@@ -700,7 +691,6 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
arg = arg->checkToPointer();
}
#endif
#if DMDV2
if (tb->ty == Tstruct && !(p->storageClass & (STCref | STCout)))
{
@@ -1000,7 +990,7 @@ Expression *Expression::combine(Expression *e1, Expression *e2)
return e1;
}
integer_t Expression::toInteger()
dinteger_t Expression::toInteger()
{
//printf("Expression %s\n", Token::toChars(op));
error("Integer constant expression expected instead of %s", toChars());
@@ -1289,7 +1279,7 @@ Expressions *Expression::arraySyntaxCopy(Expressions *exps)
/******************************** IntegerExp **************************/
IntegerExp::IntegerExp(Loc loc, integer_t value, Type *type)
IntegerExp::IntegerExp(Loc loc, dinteger_t value, Type *type)
: Expression(loc, TOKint64, sizeof(IntegerExp))
{
//printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : "");
@@ -1303,7 +1293,7 @@ IntegerExp::IntegerExp(Loc loc, integer_t value, Type *type)
this->value = value;
}
IntegerExp::IntegerExp(integer_t value)
IntegerExp::IntegerExp(dinteger_t value)
: Expression(0, TOKint64, sizeof(IntegerExp))
{
this->type = Type::tint32;
@@ -1333,7 +1323,7 @@ char *IntegerExp::toChars()
#endif
}
integer_t IntegerExp::toInteger()
dinteger_t IntegerExp::toInteger()
{ Type *t;
t = type;
@@ -1355,11 +1345,12 @@ integer_t IntegerExp::toInteger()
case Tint64: value = (d_int64) value; break;
case Tuns64: value = (d_uns64) value; break;
case Tpointer:
// FIXME: Other pointer widths than 32 and 64?
if (PTRSIZE == 4)
value = (d_uns32) value;
else
else if (PTRSIZE == 8)
value = (d_uns64) value;
else
assert(0);
break;
case Tenum:
@@ -1423,7 +1414,7 @@ Expression *IntegerExp::semantic(Scope *sc)
if (!type)
{
// Determine what the type of this number is
integer_t number = value;
dinteger_t number = value;
if (number & 0x8000000000000000LL)
type = Type::tuns64;
@@ -1451,7 +1442,7 @@ Expression *IntegerExp::toLvalue(Scope *sc, Expression *e)
void IntegerExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
integer_t v = toInteger();
dinteger_t v = toInteger();
if (type)
{ Type *t = type;
@@ -1520,7 +1511,7 @@ void IntegerExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
break;
case Tuns64:
L4:
L4:
buf->printf("%juLU", v);
break;
@@ -1533,11 +1524,12 @@ void IntegerExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring("cast(");
buf->writestring(t->toChars());
buf->writeByte(')');
// FIXME: Other pointer widths than 32 and 64?
if (PTRSIZE == 4)
goto L3;
else
else if (PTRSIZE == 8)
goto L4;
else
assert(0);
default:
/* This can happen if errors, such as
@@ -1592,7 +1584,7 @@ char *RealExp::toChars()
return mem.strdup(buffer);
}
integer_t RealExp::toInteger()
dinteger_t RealExp::toInteger()
{
#ifdef IN_GCC
return toReal().toInt();
@@ -1817,7 +1809,7 @@ char *ComplexExp::toChars()
return mem.strdup(buffer);
}
integer_t ComplexExp::toInteger()
dinteger_t ComplexExp::toInteger()
{
#ifdef IN_GCC
return (sinteger_t) toReal().toInt();
@@ -2163,9 +2155,11 @@ Lagain:
imp = s->isImport();
if (imp)
{
ScopeExp *ie;
ie = new ScopeExp(loc, imp->pkg);
if (!imp->pkg)
{ error("forward reference of import %s", imp->toChars());
return this;
}
ScopeExp *ie = new ScopeExp(loc, imp->pkg);
return ie->semantic(sc);
}
pkg = s->isPackage();
@@ -3650,7 +3644,7 @@ Lagain:
if (cd->aggNew)
{
// Prepend the size_t size argument to newargs[]
// Prepend the size argument to newargs[]
Expression *e = new IntegerExp(loc, cd->size(loc), Type::tsize_t);
if (!newargs)
newargs = new Expressions();
@@ -4319,7 +4313,8 @@ char *FuncExp::toChars()
void FuncExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring(fd->toChars());
fd->toCBuffer(buf, hgs);
//buf->writestring(fd->toChars());
}
@@ -7593,8 +7588,8 @@ Expression *IndexExp::semantic(Scope *sc)
e2 = e2->optimize(WANTvalue);
if (e2->op == TOKint64)
{
integer_t index = e2->toInteger();
integer_t length = tsa->dim->toInteger();
dinteger_t index = e2->toInteger();
dinteger_t length = tsa->dim->toInteger();
if (index < 0 || index >= length)
error("array index [%lld] is outside array bounds [0 .. %lld]",
index, length);

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -105,7 +105,7 @@ struct Expression : Object
static Expression *combine(Expression *e1, Expression *e2);
static Expressions *arraySyntaxCopy(Expressions *exps);
virtual integer_t toInteger();
virtual dinteger_t toInteger();
virtual uinteger_t toUInteger();
virtual real_t toReal();
virtual real_t toImaginary();
@@ -175,16 +175,16 @@ struct Expression : Object
struct IntegerExp : Expression
{
integer_t value;
dinteger_t value;
IntegerExp(Loc loc, integer_t value, Type *type);
IntegerExp(integer_t value);
IntegerExp(Loc loc, dinteger_t value, Type *type);
IntegerExp(dinteger_t value);
int equals(Object *o);
Expression *semantic(Scope *sc);
Expression *interpret(InterState *istate);
char *toChars();
void dump(int indent);
integer_t toInteger();
dinteger_t toInteger();
real_t toReal();
real_t toImaginary();
complex_t toComplex();
@@ -212,7 +212,7 @@ struct RealExp : Expression
Expression *semantic(Scope *sc);
Expression *interpret(InterState *istate);
char *toChars();
integer_t toInteger();
dinteger_t toInteger();
uinteger_t toUInteger();
real_t toReal();
real_t toImaginary();
@@ -240,7 +240,7 @@ struct ComplexExp : Expression
Expression *semantic(Scope *sc);
Expression *interpret(InterState *istate);
char *toChars();
integer_t toInteger();
dinteger_t toInteger();
uinteger_t toUInteger();
real_t toReal();
real_t toImaginary();

View File

@@ -1237,7 +1237,7 @@ void FuncDeclaration::semantic3(Scope *sc)
{ // Call invariant virtually
ThisExp *v = new ThisExp(0);
v->type = vthis->type;
Expression *se = new StringExp(0, "null this");
Expression *se = new StringExp(0, (char *)"null this");
se = se->semantic(sc);
se->type = Type::tchar->arrayOf();
e = new AssertExp(loc, v, se);
@@ -2878,7 +2878,7 @@ void NewDeclaration::semantic(Scope *sc)
type = type->semantic(loc, sc);
assert(type->ty == Tfunction);
// Check that there is at least one argument of type uint
// Check that there is at least one argument of type size_t
TypeFunction *tf = (TypeFunction *)type;
if (Argument::dim(tf->parameters) < 1)
{

View File

@@ -45,9 +45,9 @@ char *Identifier::toChars()
return (char *)string;
}
char *Identifier::toHChars2()
const char *Identifier::toHChars2()
{
char *p = NULL;
const char *p = NULL;
if (this == Id::ctor) p = "this";
else if (this == Id::dtor) p = "~this";

View File

@@ -37,7 +37,7 @@ struct Identifier : Object
#ifdef _DH
char *toHChars();
#endif
char *toHChars2();
const char *toHChars2();
int dyncast();
static Identifier *generateId(const char *prefix);

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -8,7 +8,7 @@
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#define __C99FEATURES__ 1
#include <cmath>
/* Lexical Analyzer */
@@ -20,19 +20,7 @@
#include <wchar.h>
#include <stdlib.h>
#include <assert.h>
#include <math.h>
#if _MSC_VER
#include <time.h>
#else
#include <sys/time.h>
#endif
#ifdef IN_GCC
#include <time.h>
#elif __GNUC__
#include <time.h>
#endif
#include <time.h> // for time() and ctime()
#include "rmem.h"
@@ -49,10 +37,6 @@
extern "C" char * __cdecl __locale_decpoint;
#endif
#if _MSC_VER // workaround VC++ bug, labels and types should be in separate namespaces
#define Lstring Lstr
#endif
extern int HtmlNamedEntity(unsigned char *p, int length);
#define LS 0x2028 // UTF line separator
@@ -682,7 +666,7 @@ void Lexer::scan(Token *t)
if (mod && id == Id::FILE)
{
t->ustring = (unsigned char *)(loc.filename ? loc.filename : mod->ident->toChars());
goto Lstring;
goto Lstr;
}
else if (mod && id == Id::LINE)
{
@@ -694,22 +678,22 @@ void Lexer::scan(Token *t)
if (id == Id::DATE)
{
t->ustring = (unsigned char *)date;
goto Lstring;
goto Lstr;
}
else if (id == Id::TIME)
{
t->ustring = (unsigned char *)time;
goto Lstring;
goto Lstr;
}
else if (id == Id::VENDOR)
{
t->ustring = (unsigned char *)"LDC";
goto Lstring;
goto Lstr;
}
else if (id == Id::TIMESTAMP)
{
t->ustring = (unsigned char *)timestamp;
Lstring:
Lstr:
t->value = TOKstring;
Llen:
t->postfix = 0;
@@ -3097,4 +3081,6 @@ void Lexer::initKeywords()
Token::tochars[TOKdeclaration] = "declaration";
Token::tochars[TOKdottd] = "dottd";
Token::tochars[TOKon_scope_exit] = "scope(exit)";
Token::tochars[TOKon_scope_success] = "scope(success)";
Token::tochars[TOKon_scope_failure] = "scope(failure)";
}

View File

@@ -1,305 +1,305 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 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 DMD_LEXER_H
#define DMD_LEXER_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "mars.h"
struct StringTable;
struct Identifier;
struct Module;
/* Tokens:
( )
[ ]
{ }
< > <= >= == != === !==
<< >> <<= >>= >>> >>>=
+ - += -=
* / % *= /= %=
& | ^ &= |= ^=
= ! ~
++ --
. -> : ,
? && ||
*/
enum TOK
{
TOKreserved,
// Other
TOKlparen, TOKrparen,
TOKlbracket, TOKrbracket,
TOKlcurly, TOKrcurly,
TOKcolon, TOKneg,
TOKsemicolon, TOKdotdotdot,
TOKeof, TOKcast,
TOKnull, TOKassert,
TOKtrue, TOKfalse,
TOKarray, TOKcall,
TOKaddress, TOKtypedot,
TOKtype, TOKthrow,
TOKnew, TOKdelete,
TOKstar, TOKsymoff,
TOKvar, TOKdotvar,
TOKdotti, TOKdotexp,
TOKdottype, TOKslice,
TOKarraylength, TOKversion,
TOKmodule, TOKdollar,
TOKtemplate, TOKdottd,
TOKdeclaration, TOKtypeof,
TOKpragma, TOKdsymbol,
TOKtypeid, TOKuadd,
TOKremove,
TOKnewanonclass, TOKcomment,
TOKarrayliteral, TOKassocarrayliteral,
TOKstructliteral,
// Operators
TOKlt, TOKgt,
TOKle, TOKge,
TOKequal, TOKnotequal,
TOKidentity, TOKnotidentity,
TOKindex, TOKis,
TOKtobool,
// 60
// NCEG floating point compares
// !<>= <> <>= !> !>= !< !<= !<>
TOKunord,TOKlg,TOKleg,TOKule,TOKul,TOKuge,TOKug,TOKue,
TOKshl, TOKshr,
TOKshlass, TOKshrass,
TOKushr, TOKushrass,
TOKcat, TOKcatass, // ~ ~=
TOKadd, TOKmin, TOKaddass, TOKminass,
TOKmul, TOKdiv, TOKmod,
TOKmulass, TOKdivass, TOKmodass,
TOKand, TOKor, TOKxor,
TOKandass, TOKorass, TOKxorass,
TOKassign, TOKnot, TOKtilde,
TOKplusplus, TOKminusminus, TOKconstruct, TOKblit,
TOKdot, TOKarrow, TOKcomma,
TOKquestion, TOKandand, TOKoror,
// 104
// Numeric literals
TOKint32v, TOKuns32v,
TOKint64v, TOKuns64v,
TOKfloat32v, TOKfloat64v, TOKfloat80v,
TOKimaginary32v, TOKimaginary64v, TOKimaginary80v,
// Char constants
TOKcharv, TOKwcharv, TOKdcharv,
// Leaf operators
TOKidentifier, TOKstring,
TOKthis, TOKsuper,
TOKhalt, TOKtuple,
// Basic types
TOKvoid,
TOKint8, TOKuns8,
TOKint16, TOKuns16,
TOKint32, TOKuns32,
TOKint64, TOKuns64,
TOKfloat32, TOKfloat64, TOKfloat80,
TOKimaginary32, TOKimaginary64, TOKimaginary80,
TOKcomplex32, TOKcomplex64, TOKcomplex80,
TOKchar, TOKwchar, TOKdchar, TOKbit, TOKbool,
TOKcent, TOKucent,
// Aggregates
TOKstruct, TOKclass, TOKinterface, TOKunion, TOKenum, TOKimport,
TOKtypedef, TOKalias, TOKoverride, TOKdelegate, TOKfunction,
TOKmixin,
TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile,
TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
TOKauto, TOKpackage, TOKmanifest,
// Statements
TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,
TOKcase, TOKdefault, TOKbreak, TOKcontinue, TOKwith,
TOKsynchronized, TOKreturn, TOKgoto, TOKtry, TOKcatch, TOKfinally,
TOKasm, TOKforeach, TOKforeach_reverse,
TOKscope,
TOKon_scope_exit, TOKon_scope_failure, TOKon_scope_success,
// Contracts
TOKbody, TOKinvariant,
// Testing
TOKunittest,
// Added after 1.0
TOKref,
TOKmacro,
#if DMDV2
TOKtraits,
TOKoverloadset,
TOKpure,
TOKnothrow,
TOKtls,
TOKline,
TOKfile,
TOKshared,
#endif
// LDC specific
#if IN_LLVM
TOKgep,
#endif
TOKMAX
};
#define CASE_BASIC_TYPES \
case TOKwchar: case TOKdchar: \
case TOKbit: case TOKbool: case TOKchar: \
case TOKint8: case TOKuns8: \
case TOKint16: case TOKuns16: \
case TOKint32: case TOKuns32: \
case TOKint64: case TOKuns64: \
case TOKfloat32: case TOKfloat64: case TOKfloat80: \
case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: \
case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: \
case TOKvoid
#define CASE_BASIC_TYPES_X(t) \
case TOKvoid: t = Type::tvoid; goto LabelX; \
case TOKint8: t = Type::tint8; goto LabelX; \
case TOKuns8: t = Type::tuns8; goto LabelX; \
case TOKint16: t = Type::tint16; goto LabelX; \
case TOKuns16: t = Type::tuns16; goto LabelX; \
case TOKint32: t = Type::tint32; goto LabelX; \
case TOKuns32: t = Type::tuns32; goto LabelX; \
case TOKint64: t = Type::tint64; goto LabelX; \
case TOKuns64: t = Type::tuns64; goto LabelX; \
case TOKfloat32: t = Type::tfloat32; goto LabelX; \
case TOKfloat64: t = Type::tfloat64; goto LabelX; \
case TOKfloat80: t = Type::tfloat80; goto LabelX; \
case TOKimaginary32: t = Type::timaginary32; goto LabelX; \
case TOKimaginary64: t = Type::timaginary64; goto LabelX; \
case TOKimaginary80: t = Type::timaginary80; goto LabelX; \
case TOKcomplex32: t = Type::tcomplex32; goto LabelX; \
case TOKcomplex64: t = Type::tcomplex64; goto LabelX; \
case TOKcomplex80: t = Type::tcomplex80; goto LabelX; \
case TOKbit: t = Type::tbit; goto LabelX; \
case TOKbool: t = Type::tbool; goto LabelX; \
case TOKchar: t = Type::tchar; goto LabelX; \
case TOKwchar: t = Type::twchar; goto LabelX; \
case TOKdchar: t = Type::tdchar; goto LabelX; \
LabelX
struct Token
{
Token *next;
unsigned char *ptr; // pointer to first character of this token within buffer
enum TOK value;
unsigned char *blockComment; // doc comment string prior to this token
unsigned char *lineComment; // doc comment for previous token
union
{
// Integers
d_int64 int64value;
d_uns64 uns64value;
// Floats
#ifdef IN_GCC
// real_t float80value; // can't use this in a union!
#else
d_float80 float80value;
#endif
struct
{ unsigned char *ustring; // UTF8 string
unsigned len;
unsigned char postfix; // 'c', 'w', 'd'
};
Identifier *ident;
};
#ifdef IN_GCC
real_t float80value; // can't use this in a union!
#endif
static const char *tochars[TOKMAX];
static void *operator new(size_t sz);
int isKeyword();
void print();
const char *toChars();
static const char *toChars(enum TOK);
};
struct Lexer
{
static StringTable stringtable;
static OutBuffer stringbuffer;
static Token *freelist;
Loc loc; // for error messages
unsigned char *base; // pointer to start of buffer
unsigned char *end; // past end of buffer
unsigned char *p; // current character
Token token;
Module *mod;
int doDocComment; // collect doc comment information
int anyToken; // !=0 means seen at least one token
int commentToken; // !=0 means comments are TOKcomment's
Lexer(Module *mod,
unsigned char *base, unsigned begoffset, unsigned endoffset,
int doDocComment, int commentToken);
static void initKeywords();
static Identifier *idPool(const char *s);
static Identifier *uniqueId(const char *s);
static Identifier *uniqueId(const char *s, int num);
TOK nextToken();
TOK peekNext();
void scan(Token *t);
Token *peek(Token *t);
Token *peekPastParen(Token *t);
unsigned escapeSequence();
TOK wysiwygStringConstant(Token *t, int tc);
TOK hexStringConstant(Token *t);
#if DMDV2
TOK delimitedStringConstant(Token *t);
TOK tokenStringConstant(Token *t);
#endif
TOK escapeStringConstant(Token *t, int wide);
TOK charConstant(Token *t, int wide);
void stringPostfix(Token *t);
unsigned wchar(unsigned u);
TOK number(Token *t);
TOK inreal(Token *t);
void error(const char *format, ...);
void error(Loc loc, const char *format, ...);
void pragma();
unsigned decodeUTF();
void getDocComment(Token *t, unsigned lineComment);
static int isValidIdentifier(char *p);
static unsigned char *combineComments(unsigned char *c1, unsigned char *c2);
};
#endif /* DMD_LEXER_H */
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 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 DMD_LEXER_H
#define DMD_LEXER_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "mars.h"
struct StringTable;
struct Identifier;
struct Module;
/* Tokens:
( )
[ ]
{ }
< > <= >= == != === !==
<< >> <<= >>= >>> >>>=
+ - += -=
* / % *= /= %=
& | ^ &= |= ^=
= ! ~
++ --
. -> : ,
? && ||
*/
enum TOK
{
TOKreserved,
// Other
TOKlparen, TOKrparen,
TOKlbracket, TOKrbracket,
TOKlcurly, TOKrcurly,
TOKcolon, TOKneg,
TOKsemicolon, TOKdotdotdot,
TOKeof, TOKcast,
TOKnull, TOKassert,
TOKtrue, TOKfalse,
TOKarray, TOKcall,
TOKaddress, TOKtypedot,
TOKtype, TOKthrow,
TOKnew, TOKdelete,
TOKstar, TOKsymoff,
TOKvar, TOKdotvar,
TOKdotti, TOKdotexp,
TOKdottype, TOKslice,
TOKarraylength, TOKversion,
TOKmodule, TOKdollar,
TOKtemplate, TOKdottd,
TOKdeclaration, TOKtypeof,
TOKpragma, TOKdsymbol,
TOKtypeid, TOKuadd,
TOKremove,
TOKnewanonclass, TOKcomment,
TOKarrayliteral, TOKassocarrayliteral,
TOKstructliteral,
// Operators
TOKlt, TOKgt,
TOKle, TOKge,
TOKequal, TOKnotequal,
TOKidentity, TOKnotidentity,
TOKindex, TOKis,
TOKtobool,
// 60
// NCEG floating point compares
// !<>= <> <>= !> !>= !< !<= !<>
TOKunord,TOKlg,TOKleg,TOKule,TOKul,TOKuge,TOKug,TOKue,
TOKshl, TOKshr,
TOKshlass, TOKshrass,
TOKushr, TOKushrass,
TOKcat, TOKcatass, // ~ ~=
TOKadd, TOKmin, TOKaddass, TOKminass,
TOKmul, TOKdiv, TOKmod,
TOKmulass, TOKdivass, TOKmodass,
TOKand, TOKor, TOKxor,
TOKandass, TOKorass, TOKxorass,
TOKassign, TOKnot, TOKtilde,
TOKplusplus, TOKminusminus, TOKconstruct, TOKblit,
TOKdot, TOKarrow, TOKcomma,
TOKquestion, TOKandand, TOKoror,
// 104
// Numeric literals
TOKint32v, TOKuns32v,
TOKint64v, TOKuns64v,
TOKfloat32v, TOKfloat64v, TOKfloat80v,
TOKimaginary32v, TOKimaginary64v, TOKimaginary80v,
// Char constants
TOKcharv, TOKwcharv, TOKdcharv,
// Leaf operators
TOKidentifier, TOKstring,
TOKthis, TOKsuper,
TOKhalt, TOKtuple,
// Basic types
TOKvoid,
TOKint8, TOKuns8,
TOKint16, TOKuns16,
TOKint32, TOKuns32,
TOKint64, TOKuns64,
TOKfloat32, TOKfloat64, TOKfloat80,
TOKimaginary32, TOKimaginary64, TOKimaginary80,
TOKcomplex32, TOKcomplex64, TOKcomplex80,
TOKchar, TOKwchar, TOKdchar, TOKbit, TOKbool,
TOKcent, TOKucent,
// Aggregates
TOKstruct, TOKclass, TOKinterface, TOKunion, TOKenum, TOKimport,
TOKtypedef, TOKalias, TOKoverride, TOKdelegate, TOKfunction,
TOKmixin,
TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile,
TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
TOKauto, TOKpackage, TOKmanifest,
// Statements
TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,
TOKcase, TOKdefault, TOKbreak, TOKcontinue, TOKwith,
TOKsynchronized, TOKreturn, TOKgoto, TOKtry, TOKcatch, TOKfinally,
TOKasm, TOKforeach, TOKforeach_reverse,
TOKscope,
TOKon_scope_exit, TOKon_scope_failure, TOKon_scope_success,
// Contracts
TOKbody, TOKinvariant,
// Testing
TOKunittest,
// Added after 1.0
TOKref,
TOKmacro,
#if DMDV2
TOKtraits,
TOKoverloadset,
TOKpure,
TOKnothrow,
TOKtls,
TOKline,
TOKfile,
TOKshared,
#endif
// LDC specific
#if IN_LLVM
TOKgep,
#endif
TOKMAX
};
#define CASE_BASIC_TYPES \
case TOKwchar: case TOKdchar: \
case TOKbit: case TOKbool: case TOKchar: \
case TOKint8: case TOKuns8: \
case TOKint16: case TOKuns16: \
case TOKint32: case TOKuns32: \
case TOKint64: case TOKuns64: \
case TOKfloat32: case TOKfloat64: case TOKfloat80: \
case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: \
case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: \
case TOKvoid
#define CASE_BASIC_TYPES_X(t) \
case TOKvoid: t = Type::tvoid; goto LabelX; \
case TOKint8: t = Type::tint8; goto LabelX; \
case TOKuns8: t = Type::tuns8; goto LabelX; \
case TOKint16: t = Type::tint16; goto LabelX; \
case TOKuns16: t = Type::tuns16; goto LabelX; \
case TOKint32: t = Type::tint32; goto LabelX; \
case TOKuns32: t = Type::tuns32; goto LabelX; \
case TOKint64: t = Type::tint64; goto LabelX; \
case TOKuns64: t = Type::tuns64; goto LabelX; \
case TOKfloat32: t = Type::tfloat32; goto LabelX; \
case TOKfloat64: t = Type::tfloat64; goto LabelX; \
case TOKfloat80: t = Type::tfloat80; goto LabelX; \
case TOKimaginary32: t = Type::timaginary32; goto LabelX; \
case TOKimaginary64: t = Type::timaginary64; goto LabelX; \
case TOKimaginary80: t = Type::timaginary80; goto LabelX; \
case TOKcomplex32: t = Type::tcomplex32; goto LabelX; \
case TOKcomplex64: t = Type::tcomplex64; goto LabelX; \
case TOKcomplex80: t = Type::tcomplex80; goto LabelX; \
case TOKbit: t = Type::tbit; goto LabelX; \
case TOKbool: t = Type::tbool; goto LabelX; \
case TOKchar: t = Type::tchar; goto LabelX; \
case TOKwchar: t = Type::twchar; goto LabelX; \
case TOKdchar: t = Type::tdchar; goto LabelX; \
LabelX
struct Token
{
Token *next;
unsigned char *ptr; // pointer to first character of this token within buffer
enum TOK value;
unsigned char *blockComment; // doc comment string prior to this token
unsigned char *lineComment; // doc comment for previous token
union
{
// Integers
d_int64 int64value;
d_uns64 uns64value;
// Floats
#ifdef IN_GCC
// real_t float80value; // can't use this in a union!
#else
d_float80 float80value;
#endif
struct
{ unsigned char *ustring; // UTF8 string
unsigned len;
unsigned char postfix; // 'c', 'w', 'd'
};
Identifier *ident;
};
#ifdef IN_GCC
real_t float80value; // can't use this in a union!
#endif
static const char *tochars[TOKMAX];
static void *operator new(size_t sz);
int isKeyword();
void print();
const char *toChars();
static const char *toChars(enum TOK);
};
struct Lexer
{
static StringTable stringtable;
static OutBuffer stringbuffer;
static Token *freelist;
Loc loc; // for error messages
unsigned char *base; // pointer to start of buffer
unsigned char *end; // past end of buffer
unsigned char *p; // current character
Token token;
Module *mod;
int doDocComment; // collect doc comment information
int anyToken; // !=0 means seen at least one token
int commentToken; // !=0 means comments are TOKcomment's
Lexer(Module *mod,
unsigned char *base, unsigned begoffset, unsigned endoffset,
int doDocComment, int commentToken);
static void initKeywords();
static Identifier *idPool(const char *s);
static Identifier *uniqueId(const char *s);
static Identifier *uniqueId(const char *s, int num);
TOK nextToken();
TOK peekNext();
void scan(Token *t);
Token *peek(Token *t);
Token *peekPastParen(Token *t);
unsigned escapeSequence();
TOK wysiwygStringConstant(Token *t, int tc);
TOK hexStringConstant(Token *t);
#if DMDV2
TOK delimitedStringConstant(Token *t);
TOK tokenStringConstant(Token *t);
#endif
TOK escapeStringConstant(Token *t, int wide);
TOK charConstant(Token *t, int wide);
void stringPostfix(Token *t);
unsigned wchar(unsigned u);
TOK number(Token *t);
TOK inreal(Token *t);
void error(const char *format, ...);
void error(Loc loc, const char *format, ...);
void pragma();
unsigned decodeUTF();
void getDocComment(Token *t, unsigned lineComment);
static int isValidIdentifier(char *p);
static unsigned char *combineComments(unsigned char *c1, unsigned char *c2);
};
#endif /* DMD_LEXER_H */

View File

@@ -117,7 +117,7 @@ char *Declaration::mangle()
return ident->toChars();
case LINKcpp:
#if V2 && (TARGET_LINUX || TARGET_OSX)
#if DMDV2 && (TARGET_LINUX || TARGET_OSX)
return cpp_mangle(this);
#else
// Windows C++ mangling is done by C++ back end

View File

@@ -1,3 +1,4 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
@@ -15,10 +16,6 @@
#include <string>
#include <cstdarg>
#if __DMC__
#include <dos.h>
#endif
#if POSIX
#include <errno.h>
#elif _WIN32
@@ -59,7 +56,7 @@ Global::Global()
copyright = "Copyright (c) 1999-2009 by Digital Mars and Tomas Lindquist Olsen";
written = "written by Walter Bright and Tomas Lindquist Olsen";
version = "v1.041";
version = "v1.042";
ldc_version = LDC_REV;
llvm_version = LLVM_REV_STR;
global.structalign = 8;

View File

@@ -57,6 +57,7 @@ the target object file format:
*/
#include <stdio.h>
#include <stdint.h>
#include <stdarg.h>
#include <stddef.h>
@@ -77,7 +78,8 @@ the target object file format:
#define DMDV2 0 // Version 2.0 features
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
#define STRUCTTHISREF V2 // 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
/* Other targets are TARGET_LINUX and TARGET_OSX, which are
* set on the command line via the compiler makefile.
@@ -261,11 +263,6 @@ extern Global global;
#define WINDOWS_SEH (_WIN32 && __DMC__)
#if __GNUC__
//#define memicmp strncasecmp
//#define stricmp strcasecmp
#endif
#ifdef __DMC__
typedef _Complex long double complex_t;
#else
@@ -274,12 +271,13 @@ extern Global global;
#endif
#ifdef __APPLE__
//#include "complex.h"//This causes problems with include the c++ <complex> and not the C "complex.h"
#define integer_t dmd_integer_t
#endif
#endif
// Be careful not to care about sign when using integer_t
typedef uint64_t integer_t;
// Be careful not to care about sign when using dinteger_t
//typedef uint64_t integer_t;
typedef uint64_t dinteger_t; // use this instead of integer_t to
// avoid conflicts with system #include's
// Signed and unsigned variants
typedef int64_t sinteger_t;

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com

View File

@@ -25,10 +25,6 @@
#include <assert.h>
#include <float.h>
#ifdef __DMC__
#include <fp.h>
#endif
#if _MSC_VER
#include <malloc.h>
#include <complex>
@@ -37,19 +33,10 @@
#include <complex.h>
#elif __MINGW32__
#include <malloc.h>
#else
//#define signbit 56
#endif
#if __GNUC__
#if !(defined (__SVR4) && defined (__sun))
#include <bits/nan.h>
#include <bits/mathdef.h>
#endif
#endif
static double zero = 0;
#include "rmem.h"
#include "port.h"
#include "dsymbol.h"
#include "mtype.h"
@@ -85,15 +72,18 @@ FuncDeclaration *hasThis(Scope *sc);
*/
int PTRSIZE = 4;
#if IN_LLVM
int REALSIZE = 8;
int REALPAD = 0;
#elif TARGET_LINUX
#if TARGET_OSX
int REALSIZE = 16;
int REALPAD = 6;
int REALALIGNSIZE = 16;
#elif TARGET_LINUX || TARGET_FREEBSD
int REALSIZE = 12;
int REALPAD = 2;
int REALALIGNSIZE = 4;
#else
int REALSIZE = 10;
int REALPAD = 0;
int REALALIGNSIZE = 2;
#endif
int Tsize_t = Tuns32;
int Tptrdiff_t = Tint32;
@@ -1119,24 +1109,7 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident)
case Tfloat64:
case Tfloat80:
{
#if IN_GCC
// mode doesn't matter, will be converted in RealExp anyway
fvalue = real_t::getnan(real_t::LongDouble);
#elif __GNUC__
// gcc nan's have the sign bit set by default, so turn it off
// Need the volatile to prevent gcc from doing incorrect
// constant folding.
volatile d_float80 foo;
foo = NAN;
if (std::signbit(foo)) // signbit sometimes, not always, set
foo = -foo; // turn off sign bit
fvalue = foo;
#elif _MSC_VER
unsigned long nan[2]= { 0xFFFFFFFF, 0x7FFFFFFF };
fvalue = *(double*)nan;
#else
fvalue = NAN;
#endif
fvalue = Port::nan;
goto Lfvalue;
}
}
@@ -1154,15 +1127,7 @@ Expression *TypeBasic::getProperty(Loc loc, Identifier *ident)
case Tfloat32:
case Tfloat64:
case Tfloat80:
#if IN_GCC
fvalue = real_t::getinfinity();
#elif __GNUC__
fvalue = 1 / zero;
#elif _MSC_VER
fvalue = std::numeric_limits<long double>::infinity();
#else
fvalue = INFINITY;
#endif
fvalue = Port::infinity;
goto Lfvalue;
}
}
@@ -1378,7 +1343,7 @@ Expression *TypeBasic::dotExp(Scope *sc, Expression *e, Identifier *ident)
}
Expression *TypeBasic::defaultInit(Loc loc)
{ integer_t value = 0;
{ dinteger_t value = 0;
#if LOGDEFAULTINIT
printf("TypeBasic::defaultInit() '%s'\n", toChars());
@@ -1735,7 +1700,7 @@ Type *TypeSArray::syntaxCopy()
}
d_uns64 TypeSArray::size(Loc loc)
{ integer_t sz;
{ dinteger_t sz;
if (!dim)
return Type::size(loc);
@@ -1747,7 +1712,7 @@ d_uns64 TypeSArray::size(Loc loc)
sz = ((sz + 31) & ~31) / 8; // size in bytes, rounded up to 32 bit dwords
}
else
{ integer_t n, n2;
{ dinteger_t n, n2;
n = next->size();
n2 = n * sz;
@@ -1896,7 +1861,7 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
Type *tbn = next->toBasetype();
if (dim)
{ integer_t n, n2;
{ dinteger_t n, n2;
dim = semanticLength(sc, tbn, dim);
@@ -1909,10 +1874,10 @@ Type *TypeSArray::semantic(Loc loc, Scope *sc)
*/
return this;
}
integer_t d1 = dim->toInteger();
dinteger_t d1 = dim->toInteger();
dim = dim->castTo(sc, tsize_t);
dim = dim->optimize(WANTvalue);
integer_t d2 = dim->toInteger();
dinteger_t d2 = dim->toInteger();
if (d1 != d2)
goto Loverflow;
@@ -3052,7 +3017,7 @@ int TypeFunction::callMatch(Expressions *args)
if (varargs == 2 && u + 1 == nparams) // if last varargs param
{ Type *tb = p->type->toBasetype();
TypeSArray *tsa;
integer_t sz;
dinteger_t sz;
switch (tb->ty)
{

View File

@@ -18,10 +18,6 @@
#include <complex>
#endif
#ifdef __APPLE__
#define integer_t dmd_integer_t
#endif
#include "rmem.h"
//#include "port.h"

File diff suppressed because it is too large Load Diff

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -32,6 +32,9 @@
#include "enum.h"
#include "id.h"
#include "version.h"
#if DMDV2
#include "aliasthis.h"
#endif
// How multiple declarations are parsed.
// If 1, treat as C.
@@ -75,6 +78,25 @@ Array *Parser::parseModule()
unsigned char *comment = token.blockComment;
nextToken();
#if DMDV2
if (token.value == TOKlparen)
{
nextToken();
if (token.value != TOKidentifier)
{ error("module (system) identifier expected");
goto Lerr;
}
Identifier *id = token.ident;
if (id == Id::system)
safe = TRUE;
else
error("(safe) expected, not %s", id->toChars());
nextToken();
check(TOKrparen);
}
#endif
if (token.value != TOKidentifier)
{ error("Identifier expected following module");
goto Lerr;
@@ -259,6 +281,13 @@ Array *Parser::parseDeclDefs(int once)
case TOKabstract: stc = STCabstract; goto Lstc;
case TOKsynchronized: stc = STCsynchronized; goto Lstc;
case TOKdeprecated: stc = STCdeprecated; goto Lstc;
#if DMDV2
case TOKnothrow: stc = STCnothrow; goto Lstc;
case TOKpure: stc = STCpure; goto Lstc;
case TOKref: stc = STCref; goto Lstc;
case TOKtls: stc = STCtls; goto Lstc;
//case TOKmanifest: stc = STCmanifest; goto Lstc;
#endif
Lstc:
nextToken();
@@ -342,6 +371,16 @@ Array *Parser::parseDeclDefs(int once)
Lprot:
nextToken();
switch (token.value)
{
case TOKprivate:
case TOKpackage:
case TOKprotected:
case TOKpublic:
case TOKexport:
error("redundant protection attribute");
break;
}
a = parseBlock();
s = new ProtDeclaration(prot, a);
break;
@@ -802,7 +841,7 @@ StaticDtorDeclaration *Parser::parseStaticDtor()
/*****************************************
* Parse an invariant definition:
* invariant { body }
* invariant() { body }
* Current token is 'invariant'.
*/
@@ -987,7 +1026,7 @@ Arguments *Parser::parseParameters(int *pvarargs)
EnumDeclaration *Parser::parseEnum()
{ EnumDeclaration *e;
Identifier *id;
Type *t;
Type *memtype;
Loc loc = this->loc;
//printf("Parser::parseEnum()\n");
@@ -1002,12 +1041,12 @@ EnumDeclaration *Parser::parseEnum()
if (token.value == TOKcolon)
{
nextToken();
t = parseBasicType();
memtype = parseBasicType();
}
else
t = NULL;
memtype = NULL;
e = new EnumDeclaration(loc, id, t);
e = new EnumDeclaration(loc, id, memtype);
if (token.value == TOKsemicolon && id)
nextToken();
else if (token.value == TOKlcurly)
@@ -1058,6 +1097,10 @@ EnumDeclaration *Parser::parseEnum()
return e;
}
/********************************
* Parse struct, union, interface, class.
*/
Dsymbol *Parser::parseAggregate()
{ AggregateDeclaration *a = NULL;
int anon = 0;
@@ -1160,7 +1203,7 @@ Dsymbol *Parser::parseAggregate()
// Wrap a template around the aggregate declaration
decldefs = new Array();
decldefs->push(a);
tempdecl = new TemplateDeclaration(loc, id, tpl, decldefs);
tempdecl = new TemplateDeclaration(loc, id, tpl, NULL, decldefs);
return tempdecl;
}
@@ -1265,7 +1308,7 @@ TemplateDeclaration *Parser::parseTemplateDeclaration()
nextToken();
}
tempdecl = new TemplateDeclaration(loc, id, tpl, decldefs);
tempdecl = new TemplateDeclaration(loc, id, tpl, NULL, decldefs);
return tempdecl;
Lerr:
@@ -1650,6 +1693,60 @@ Import *Parser::parseImport(Array *decldefs, int isstatic)
return NULL;
}
#if DMDV2
Type *Parser::parseType(Identifier **pident, TemplateParameters **tpl)
{ Type *t;
/* Take care of the storage class prefixes that
* serve as type attributes:
* const shared, shared const, const, invariant, shared
*/
if (token.value == TOKconst && peekNext() == TOKshared && peekNext2() != TOKlparen ||
token.value == TOKshared && peekNext() == TOKconst && peekNext2() != TOKlparen)
{
nextToken();
nextToken();
/* shared const type
*/
t = parseType(pident, tpl);
t = t->makeSharedConst();
return t;
}
else if (token.value == TOKconst && peekNext() != TOKlparen)
{
nextToken();
/* const type
*/
t = parseType(pident, tpl);
t = t->makeConst();
return t;
}
else if ((token.value == TOKinvariant || token.value == TOKimmutable) &&
peekNext() != TOKlparen)
{
nextToken();
/* invariant type
*/
t = parseType(pident, tpl);
t = t->makeInvariant();
return t;
}
else if (token.value == TOKshared && peekNext() != TOKlparen)
{
nextToken();
/* shared type
*/
t = parseType(pident, tpl);
t = t->makeShared();
return t;
}
else
t = parseBasicType();
t = parseDeclarator(t, pident, tpl);
return t;
}
#endif
Type *Parser::parseBasicType()
{ Type *t;
Identifier *id;
@@ -1889,6 +1986,7 @@ Type *Parser::parseDeclarator(Type *t, Identifier **pident, TemplateParameters *
break;
}
// parse DeclaratorSuffixes
while (1)
{
switch (token.value)
@@ -1924,6 +2022,7 @@ Type *Parser::parseDeclarator(Type *t, Identifier **pident, TemplateParameters *
ta = new TypeSArray(t, e);
check(TOKrbracket);
}
/* Insert ta into
* ts -> ... -> t
* so that
@@ -1986,7 +2085,7 @@ Array *Parser::parseDeclarations()
Type *tfirst;
Identifier *ident;
Array *a;
enum TOK tok;
enum TOK tok = TOKreserved;
unsigned char *comment = token.blockComment;
enum LINK link = linkage;
@@ -2018,6 +2117,13 @@ Array *Parser::parseDeclarations()
case TOKabstract: stc = STCabstract; goto L1;
case TOKsynchronized: stc = STCsynchronized; goto L1;
case TOKdeprecated: stc = STCdeprecated; goto L1;
#if DMDV2
case TOKnothrow: stc = STCnothrow; goto L1;
case TOKpure: stc = STCpure; goto L1;
case TOKref: stc = STCref; goto L1;
case TOKtls: stc = STCtls; goto L1;
case TOKenum: stc = STCmanifest; goto L1;
#endif
L1:
if (storage_class & stc)
error("redundant storage class '%s'", token.toChars());
@@ -2108,9 +2214,8 @@ Array *Parser::parseDeclarations()
if (tok == TOKtypedef || tok == TOKalias)
{ Declaration *v;
Initializer *init;
Initializer *init = NULL;
init = NULL;
if (token.value == TOKassign)
{
nextToken();
@@ -2150,13 +2255,12 @@ Array *Parser::parseDeclarations()
}
}
else if (t->ty == Tfunction)
{ FuncDeclaration *f;
Dsymbol *s;
f = new FuncDeclaration(loc, 0, ident, storage_class, t);
{ FuncDeclaration *f =
new FuncDeclaration(loc, 0, ident, storage_class, t);
addComment(f, comment);
parseContracts(f);
addComment(f, NULL);
Dsymbol *s;
if (link == linkage)
{
s = f;
@@ -2174,23 +2278,22 @@ Array *Parser::parseDeclarations()
// Wrap a template around the aggregate declaration
decldefs = new Array();
decldefs->push(s);
tempdecl = new TemplateDeclaration(loc, s->ident, tpl, decldefs);
tempdecl = new TemplateDeclaration(loc, s->ident, tpl, NULL, decldefs);
s = tempdecl;
}
addComment(s, comment);
a->push(s);
}
else
{ VarDeclaration *v;
Initializer *init;
init = NULL;
{
Initializer *init = NULL;
if (token.value == TOKassign)
{
nextToken();
init = parseInitializer();
}
v = new VarDeclaration(loc, t, ident, init);
VarDeclaration *v = new VarDeclaration(loc, t, ident, init);
v->storage_class = storage_class;
if (link == linkage)
a->push(v);
@@ -2363,6 +2466,7 @@ L1:
}
/*****************************************
* Parse initializer for variable declaration.
*/
Initializer *Parser::parseInitializer()
@@ -2620,13 +2724,14 @@ Statement *Parser::parseStatement(int flags)
switch (token.value)
{
case TOKidentifier:
// Need to look ahead to see if it is a declaration, label, or expression
/* A leading identifier can be a declaration, label, or expression.
* The easiest case to check first is label:
*/
t = peek(&token);
if (t->value == TOKcolon)
{ // It's a label
Identifier *ident;
ident = token.ident;
Identifier *ident = token.ident;
nextToken();
nextToken();
s = parseStatement(PSsemi);
@@ -2718,6 +2823,10 @@ Statement *Parser::parseStatement(int flags)
case TOKextern:
case TOKfinal:
case TOKinvariant:
#if DMDV2
case TOKimmutable:
case TOKshared:
#endif
// case TOKtypeof:
Ldeclaration:
{ Array *a;
@@ -2733,7 +2842,7 @@ Statement *Parser::parseStatement(int flags)
s = new DeclarationStatement(loc, d);
as->push(s);
}
s = new CompoundStatement(loc, as);
s = new CompoundDeclarationStatement(loc, as);
}
else if (a->dim == 1)
{
@@ -3443,7 +3552,7 @@ void Parser::check(Loc loc, enum TOK value)
nextToken();
}
void Parser::check(enum TOK value, char *string)
void Parser::check(enum TOK value, const char *string)
{
if (token.value != value)
error("found '%s' when expecting '%s' following '%s'",
@@ -3461,6 +3570,7 @@ void Parser::check(enum TOK value, char *string)
int Parser::isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt)
{
//printf("isDeclaration(needId = %d)\n", needId);
int haveId = 0;
#if DMDV2
@@ -3551,9 +3661,11 @@ int Parser::isBasicType(Token **pt)
goto Lfalse;
}
*pt = t;
//printf("is\n");
return TRUE;
Lfalse:
//printf("is not\n");
return FALSE;
}
@@ -3678,6 +3790,25 @@ int Parser::isDeclarator(Token **pt, int *haveId, enum TOK endtok)
parens = FALSE;
if (!isParameters(&t))
return FALSE;
#if DMDV2
while (1)
{
switch (t->value)
{
case TOKconst:
case TOKinvariant:
case TOKimmutable:
case TOKshared:
case TOKpure:
case TOKnothrow:
t = peek(t);
continue;
default:
break;
}
break;
}
#endif
continue;
// Valid tokens that follow a declaration
@@ -4203,6 +4334,12 @@ Expression *Parser::parsePrimaryExp()
token.value == TOKsuper ||
token.value == TOKenum ||
token.value == TOKinterface ||
#if DMDV2
token.value == TOKconst && peek(&token)->value == TOKrparen ||
token.value == TOKinvariant && peek(&token)->value == TOKrparen ||
token.value == TOKimmutable && peek(&token)->value == TOKrparen ||
token.value == TOKshared && peek(&token)->value == TOKrparen ||
#endif
token.value == TOKfunction ||
token.value == TOKdelegate ||
token.value == TOKreturn))

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2008 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -100,7 +100,7 @@ struct Parser : Lexer
Initializer *parseInitializer();
void check(Loc loc, enum TOK value);
void check(enum TOK value);
void check(enum TOK value, char *string);
void check(enum TOK value, const char *string);
int isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt);
int isBasicType(Token **pt);
int isDeclarator(Token **pt, int *haveId, enum TOK endtok);

View File

@@ -1,5 +1,5 @@
// Copyright (c) 1999-2006 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com

177
dmd/root/async.c Normal file
View File

@@ -0,0 +1,177 @@
#define _MT 1
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#if _WIN32
#include <windows.h>
#include <stdio.h>
#include <errno.h>
#include <process.h>
#include "root.h"
#include "rmem.h"
static unsigned __stdcall startthread(void *p);
struct FileData
{
File *file;
int result;
HANDLE event;
};
struct AsyncRead
{
static AsyncRead *create(size_t nfiles);
void addFile(File *file);
void start();
int read(size_t i);
static void dispose(AsyncRead *);
HANDLE hThread;
size_t filesdim;
size_t filesmax;
FileData files[1];
};
AsyncRead *AsyncRead::create(size_t nfiles)
{
AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
(nfiles - 1) * sizeof(FileData));
aw->filesmax = nfiles;
return aw;
}
void AsyncRead::addFile(File *file)
{
//printf("addFile(file = %p)\n", file);
//printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax);
assert(filesdim < filesmax);
files[filesdim].file = file;
files[filesdim].event = CreateEvent(NULL, TRUE, FALSE, NULL);
ResetEvent(files[filesdim].event);
filesdim++;
}
void AsyncRead::start()
{
unsigned threadaddr;
hThread = (HANDLE) _beginthreadex(NULL,
0,
&startthread,
this,
0,
(unsigned *)&threadaddr);
if (hThread)
{
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
}
else
{
assert(0);
}
}
int AsyncRead::read(size_t i)
{
FileData *f = &files[i];
WaitForSingleObject(f->event, INFINITE);
Sleep(0); // give up time slice
return f->result;
}
void AsyncRead::dispose(AsyncRead *aw)
{
delete aw;
}
unsigned __stdcall startthread(void *p)
{
AsyncRead *aw = (AsyncRead *)p;
for (size_t i = 0; i < aw->filesdim; i++)
{ FileData *f = &aw->files[i];
f->result = f->file->read();
SetEvent(f->event);
}
_endthreadex(EXIT_SUCCESS);
return EXIT_SUCCESS; // if skidding
}
#else
#include <stdio.h>
#include <errno.h>
#include "root.h"
#include "rmem.h"
struct FileData
{
File *file;
int result;
//HANDLE event;
};
struct AsyncRead
{
static AsyncRead *create(size_t nfiles);
void addFile(File *file);
void start();
int read(size_t i);
static void dispose(AsyncRead *);
//HANDLE hThread;
size_t filesdim;
size_t filesmax;
FileData files[1];
};
AsyncRead *AsyncRead::create(size_t nfiles)
{
AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
(nfiles - 1) * sizeof(FileData));
aw->filesmax = nfiles;
return aw;
}
void AsyncRead::addFile(File *file)
{
//printf("addFile(file = %p)\n", file);
//printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax);
assert(filesdim < filesmax);
files[filesdim].file = file;
//files[filesdim].event = CreateEvent(NULL, TRUE, FALSE, NULL);
//ResetEvent(files[filesdim].event);
filesdim++;
}
void AsyncRead::start()
{
}
int AsyncRead::read(size_t i)
{
FileData *f = &files[i];
f->result = f->file->read();
return f->result;
}
void AsyncRead::dispose(AsyncRead *aw)
{
delete aw;
}
#endif

33
dmd/root/async.h Normal file
View File

@@ -0,0 +1,33 @@
// Copyright (c) 2009-2009 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 ASYNC_H
#define ASYNC_H
#if __DMC__
#pragma once
#endif
/*******************
* Simple interface to read files asynchronously in another
* thread.
*/
struct AsyncRead
{
static AsyncRead *create(size_t nfiles);
void addFile(File *file);
void start();
int read(size_t i);
static void dispose(AsyncRead *);
};
#endif

754
dmd/root/port.c Normal file
View File

@@ -0,0 +1,754 @@
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
#include "port.h"
#if __DMC__
#include <math.h>
#include <float.h>
#include <fp.h>
#include <time.h>
#include <stdlib.h>
#include <string.h>
double Port::nan = NAN;
double Port::infinity = INFINITY;
double Port::dbl_max = DBL_MAX;
double Port::dbl_min = DBL_MIN;
int Port::isNan(double r)
{
return ::isnan(r);
}
int Port::isNan(long double r)
{
return ::isnan(r);
}
int Port::isSignallingNan(double r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 51 of 0..63 for 64 bit doubles.
*/
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
}
int Port::isSignallingNan(long double r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 62 of 0..79 for 80 bit reals.
*/
return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40);
}
int Port::isFinite(double r)
{
return ::isfinite(r);
}
int Port::isInfinity(double r)
{
return (::fpclassify(r) == FP_INFINITE);
}
int Port::Signbit(double r)
{
return ::signbit(r);
}
double Port::floor(double d)
{
return ::floor(d);
}
double Port::pow(double x, double y)
{
return ::pow(x, y);
}
unsigned long long Port::strtoull(const char *p, char **pend, int base)
{
return ::strtoull(p, pend, base);
}
char *Port::ull_to_string(char *buffer, ulonglong ull)
{
sprintf(buffer, "%llu", ull);
return buffer;
}
wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull)
{
swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull);
return buffer;
}
double Port::ull_to_double(ulonglong ull)
{
return (double) ull;
}
const char *Port::list_separator()
{
// LOCALE_SLIST for Windows
return ",";
}
const wchar_t *Port::wlist_separator()
{
// LOCALE_SLIST for Windows
return L",";
}
char *Port::strupr(char *s)
{
return ::strupr(s);
}
#endif
#if _MSC_VER
// Disable useless warnings about unreferenced functions
#pragma warning (disable : 4514)
#include <math.h>
#include <float.h>
#include <time.h>
#include <errno.h>
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
static unsigned long nanarray[2]= { 0xFFFFFFFF, 0x7FFFFFFF };
//static unsigned long nanarray[2] = {0,0x7FF80000 };
double Port::nan = (*(double *)nanarray);
//static unsigned long infinityarray[2] = {0,0x7FF00000 };
static double zero = 0;
double Port::infinity = 1 / zero;
double Port::dbl_max = DBL_MAX;
double Port::dbl_min = DBL_MIN;
struct PortInitializer
{
PortInitializer();
};
static PortInitializer portinitializer;
PortInitializer::PortInitializer()
{
Port::infinity = std::numeric_limits<long double>::infinity();
}
int Port::isNan(double r)
{
return ::_isnan(r);
}
int Port::isNan(long double r)
{
return ::_isnan(r);
}
int Port::isSignallingNan(double r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 51 of 0..63 for 64 bit doubles.
*/
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
}
int Port::isSignallingNan(long double r)
{
/* MSVC doesn't have 80 bit long doubles
*/
return isSignallingNan((double) r);
}
int Port::isFinite(double r)
{
return ::_finite(r);
}
int Port::isInfinity(double r)
{
return (::_fpclass(r) & (_FPCLASS_NINF | _FPCLASS_PINF));
}
int Port::Signbit(double r)
{
return (long)(((long *)&(r))[1] & 0x80000000);
}
double Port::floor(double d)
{
return ::floor(d);
}
double Port::pow(double x, double y)
{
if (y == 0)
return 1; // even if x is NAN
return ::pow(x, y);
}
unsigned _int64 Port::strtoull(const char *p, char **pend, int base)
{
unsigned _int64 number = 0;
int c;
int error;
#define ULLONG_MAX ((unsigned _int64)~0I64)
while (isspace(*p)) /* skip leading white space */
p++;
if (*p == '+')
p++;
switch (base)
{ case 0:
base = 10; /* assume decimal base */
if (*p == '0')
{ base = 8; /* could be octal */
p++;
switch (*p)
{ case 'x':
case 'X':
base = 16; /* hex */
p++;
break;
#if BINARY
case 'b':
case 'B':
base = 2; /* binary */
p++;
break;
#endif
}
}
break;
case 16: /* skip over '0x' and '0X' */
if (*p == '0' && (p[1] == 'x' || p[1] == 'X'))
p += 2;
break;
#if BINARY
case 2: /* skip over '0b' and '0B' */
if (*p == '0' && (p[1] == 'b' || p[1] == 'B'))
p += 2;
break;
#endif
}
error = 0;
for (;;)
{ c = *p;
if (isdigit(c))
c -= '0';
else if (isalpha(c))
c = (c & ~0x20) - ('A' - 10);
else /* unrecognized character */
break;
if (c >= base) /* not in number base */
break;
if ((ULLONG_MAX - c) / base < number)
error = 1;
number = number * base + c;
p++;
}
if (pend)
*pend = (char *)p;
if (error)
{ number = ULLONG_MAX;
errno = ERANGE;
}
return number;
}
char *Port::ull_to_string(char *buffer, ulonglong ull)
{
_ui64toa(ull, buffer, 10);
return buffer;
}
wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull)
{
_ui64tow(ull, buffer, 10);
return buffer;
}
double Port::ull_to_double(ulonglong ull)
{ double d;
if ((__int64) ull < 0)
{
// MSVC doesn't implement the conversion
d = (double) (__int64)(ull - 0x8000000000000000i64);
d += (double)(signed __int64)(0x7FFFFFFFFFFFFFFFi64) + 1.0;
}
else
d = (double)(__int64)ull;
return d;
}
const char *Port::list_separator()
{
// LOCALE_SLIST for Windows
return ",";
}
const wchar_t *Port::wlist_separator()
{
// LOCALE_SLIST for Windows
return L",";
}
char *Port::strupr(char *s)
{
return ::strupr(s);
}
#endif
#if linux || __APPLE__ || __FreeBSD__
#include <math.h>
#if linux
#include <bits/nan.h>
#include <bits/mathdef.h>
#endif
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
static double zero = 0;
double Port::nan = NAN;
double Port::infinity = 1 / zero;
double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
struct PortInitializer
{
PortInitializer();
};
static PortInitializer portinitializer;
PortInitializer::PortInitializer()
{
// gcc nan's have the sign bit set by default, so turn it off
// Need the volatile to prevent gcc from doing incorrect
// constant folding.
volatile long double foo;
foo = NAN;
if (signbit(foo)) // signbit sometimes, not always, set
foo = -foo; // turn off sign bit
Port::nan = foo;
}
#undef isnan
int Port::isNan(double r)
{
#if __APPLE__
return __inline_isnan(r);
#else
return ::isnan(r);
#endif
}
int Port::isNan(long double r)
{
#if __APPLE__
return __inline_isnan(r);
#else
return ::isnan(r);
#endif
}
int Port::isSignallingNan(double r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 51 of 0..63 for 64 bit doubles.
*/
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
}
int Port::isSignallingNan(long double r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 62 of 0..79 for 80 bit reals.
*/
return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40);
}
#undef isfinite
int Port::isFinite(double r)
{
return ::finite(r);
}
#undef isinf
int Port::isInfinity(double r)
{
#if __APPLE__
return fpclassify(r) == FP_INFINITE;
#else
return ::isinf(r);
#endif
}
#undef signbit
int Port::Signbit(double r)
{
return (long)(((long *)&r)[1] & 0x80000000);
}
double Port::floor(double d)
{
return ::floor(d);
}
double Port::pow(double x, double y)
{
return ::pow(x, y);
}
unsigned long long Port::strtoull(const char *p, char **pend, int base)
{
return ::strtoull(p, pend, base);
}
char *Port::ull_to_string(char *buffer, ulonglong ull)
{
sprintf(buffer, "%llu", ull);
return buffer;
}
wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull)
{
swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull);
return buffer;
}
double Port::ull_to_double(ulonglong ull)
{
return (double) ull;
}
const char *Port::list_separator()
{
return ",";
}
const wchar_t *Port::wlist_separator()
{
return L",";
}
char *Port::strupr(char *s)
{
char *t = s;
while (*s)
{
*s = toupper(*s);
s++;
}
return t;
}
#endif
#if defined (__SVR4) && defined (__sun)
#define __C99FEATURES__ 1 // Needed on Solaris for NaN and more
#include <math.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
static double zero = 0;
double Port::nan = NAN;
double Port::infinity = 1 / zero;
double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
struct PortInitializer
{
PortInitializer();
};
static PortInitializer portinitializer;
PortInitializer::PortInitializer()
{
// gcc nan's have the sign bit set by default, so turn it off
// Need the volatile to prevent gcc from doing incorrect
// constant folding.
volatile long double foo;
foo = NAN;
if (signbit(foo)) // signbit sometimes, not always, set
foo = -foo; // turn off sign bit
Port::nan = foo;
}
#undef isnan
int Port::isNan(double r)
{
#if __APPLE__
return __inline_isnan(r);
#else
return ::isnan(r);
#endif
}
int Port::isNan(long double r)
{
#if __APPLE__
return __inline_isnan(r);
#else
return ::isnan(r);
#endif
}
int Port::isSignallingNan(double r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 51 of 0..63 for 64 bit doubles.
*/
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
}
int Port::isSignallingNan(long double r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 62 of 0..79 for 80 bit reals.
*/
return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40);
}
#undef isfinite
int Port::isFinite(double r)
{
return ::finite(r);
}
#undef isinf
int Port::isInfinity(double r)
{
return ::isinf(r);
}
#undef signbit
int Port::Signbit(double r)
{
return (long)(((long *)&r)[1] & 0x80000000);
}
double Port::floor(double d)
{
return ::floor(d);
}
double Port::pow(double x, double y)
{
return ::pow(x, y);
}
unsigned long long Port::strtoull(const char *p, char **pend, int base)
{
return ::strtoull(p, pend, base);
}
char *Port::ull_to_string(char *buffer, ulonglong ull)
{
sprintf(buffer, "%llu", ull);
return buffer;
}
wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull)
{
swprintf(buffer, sizeof(ulonglong) * 3 + 1, L"%llu", ull);
return buffer;
}
double Port::ull_to_double(ulonglong ull)
{
return (double) ull;
}
const char *Port::list_separator()
{
return ",";
}
const wchar_t *Port::wlist_separator()
{
return L",";
}
char *Port::strupr(char *s)
{
char *t = s;
while (*s)
{
*s = toupper(*s);
s++;
}
return t;
}
#endif
#if IN_GCC
#include <math.h>
#include <bits/nan.h>
#include <bits/mathdef.h>
#include <time.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
static double zero = 0;
double Port::nan = NAN;
double Port::infinity = 1 / zero;
double Port::dbl_max = 1.7976931348623157e308;
double Port::dbl_min = 5e-324;
#include "d-gcc-real.h"
extern "C" bool real_isnan (const real_t *);
struct PortInitializer
{
PortInitializer();
};
static PortInitializer portinitializer;
PortInitializer::PortInitializer()
{
Port::infinity = real_t::getinfinity();
Port::nan = real_t::getnan(real_t::LongDouble);
}
#undef isnan
int Port::isNan(double r)
{
#if __APPLE__
return __inline_isnan(r);
#else
return ::isnan(r);
#endif
}
int Port::isNan(long double r)
{
return real_isnan(&r);
}
int Port::isSignallingNan(double r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 51 of 0..63 for 64 bit doubles.
*/
return isNan(r) && !((((unsigned char*)&r)[6]) & 8);
}
int Port::isSignallingNan(long double r)
{
/* A signalling NaN is a NaN with 0 as the most significant bit of
* its significand, which is bit 62 of 0..79 for 80 bit reals.
*/
return isNan(r) && !((((unsigned char*)&r)[7]) & 0x40);
}
#undef isfinite
int Port::isFinite(double r)
{
return ::finite(r);
}
#undef isinf
int Port::isInfinity(double r)
{
return ::isinf(r);
}
#undef signbit
int Port::Signbit(double r)
{
return (long)(((long *)&r)[1] & 0x80000000);
}
double Port::floor(double d)
{
return ::floor(d);
}
double Port::pow(double x, double y)
{
return ::pow(x, y);
}
unsigned long long Port::strtoull(const char *p, char **pend, int base)
{
return ::strtoull(p, pend, base);
}
char *Port::ull_to_string(char *buffer, ulonglong ull)
{
sprintf(buffer, "%llu", ull);
return buffer;
}
wchar_t *Port::ull_to_string(wchar_t *buffer, ulonglong ull)
{
swprintf(buffer, L"%llu", ull);
return buffer;
}
double Port::ull_to_double(ulonglong ull)
{
return (double) ull;
}
const char *Port::list_separator()
{
return ",";
}
const wchar_t *Port::wlist_separator()
{
return L",";
}
char *Port::strupr(char *s)
{
char *t = s;
while (*s)
{
*s = toupper(*s);
s++;
}
return t;
}
#endif

View File

@@ -1,8 +1,8 @@
// Copyright (c) 1999-2002 by Digital Mars
// Copyright (c) 1999-2009 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// http://www.digitalmars.com
#ifndef PORT_H
#define PORT_H
@@ -42,6 +42,11 @@ struct Port
#undef signbit
#endif
static int isNan(double);
static int isNan(long double);
static int isSignallingNan(double);
static int isSignallingNan(long double);
static int isFinite(double);
static int isInfinity(double);
static int Signbit(double);
@@ -58,8 +63,10 @@ struct Port
static double ull_to_double(ulonglong ull);
// Get locale-dependent list separator
static char *list_separator();
static wchar_t *wlist_separator();
static const char *list_separator();
static const wchar_t *wlist_separator();
static char *strupr(char *);
};
#endif

View File

@@ -583,9 +583,17 @@ char *FileName::name(const char *str)
return e + 1;
#if _WIN32
case '/':
case '\\':
case ':':
return e + 1;
case ':':
/* The ':' is a drive letter only if it is the second
* character or the last character,
* otherwise it is an ADS (Alternate Data Stream) separator.
* Consider ADS separators as part of the file name.
*/
if (e == str + 1 || e == str + len - 1)
return e + 1;
#endif
default:
if (e == str)
@@ -620,7 +628,7 @@ char *FileName::path(const char *str)
n--;
#if _WIN32
if (n[-1] == '\\')
if (n[-1] == '\\' || n[-1] == '/')
n--;
#endif
}
@@ -822,8 +830,8 @@ void FileName::ensurePathExists(const char *path)
if (*p)
{
#if _WIN32
size_t len = strlen(p);
if (len > 2 && p[-1] == ':')
size_t len = strlen(path);
if (len > 2 && p[-1] == ':' && path + 2 == p)
{ mem.free(p);
return;
}

View File

@@ -1,114 +1,120 @@
// Copyright (c) 1999-2005 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 DMD_SCOPE_H
#define DMD_SCOPE_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
struct Dsymbol;
struct ScopeDsymbol;
struct Array;
struct Identifier;
struct Module;
struct Statement;
struct SwitchStatement;
struct TryFinallyStatement;
struct LabelStatement;
struct ForeachStatement;
struct ClassDeclaration;
struct AggregateDeclaration;
struct AnonymousAggregateDeclaration;
struct FuncDeclaration;
struct DocComment;
struct EnclosingHandler;
struct AnonDeclaration;
enum LINK;
enum PROT;
struct Scope
{
Scope *enclosing; // enclosing Scope
Module *module; // Root module
ScopeDsymbol *scopesym; // current symbol
ScopeDsymbol *sd; // if in static if, and declaring new symbols,
// sd gets the addMember()
FuncDeclaration *func; // function we are in
Dsymbol *parent; // parent to use
LabelStatement *slabel; // enclosing labelled statement
SwitchStatement *sw; // enclosing switch statement
TryFinallyStatement *enclosingFinally; // enclosing try finally statement; set inside its finally block
Statement *enclosingScopeExit; // enclosing statement that wants to do something on scope exit
TemplateInstance *tinst; // enclosing template instance
Statement *sbreak; // enclosing statement that supports "break"
Statement *scontinue; // enclosing statement that supports "continue"
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
unsigned offset; // next offset to use in aggregate
int inunion; // we're processing members of a union
int incontract; // we're inside contract code
int nofree; // set if shouldn't free it
int noctor; // set if constructor calls aren't allowed
int intypeof; // in typeof(exp)
int parameterSpecialization; // if in template parameter specialization
int noaccesscheck; // don't do access checks
unsigned callSuper; // primitive flow analysis for constructors
#define CSXthis_ctor 1 // called this()
#define CSXsuper_ctor 2 // called super()
#define CSXthis 4 // referenced this
#define CSXsuper 8 // referenced super
#define CSXlabel 0x10 // seen a label
#define CSXreturn 0x20 // seen a return statement
#define CSXany_ctor 0x40 // either this() or super() was called
unsigned structalign; // alignment for struct members
enum LINK linkage; // linkage for external functions
enum PROT protection; // protection for class members
int explicitProtection; // set if in an explicit protection attribute
unsigned stc; // storage class
unsigned flags;
#define SCOPEctor 1 // constructor type
#define SCOPEstaticif 2 // inside static if
#define SCOPEfree 4 // is on free list
AnonymousAggregateDeclaration *anonAgg; // for temporary analysis
DocComment *lastdc; // documentation comment for last symbol at this scope
unsigned lastoffset; // offset in docbuf of where to insert next dec
OutBuffer *docbuf; // buffer for documentation output
static Scope *freelist;
static void *operator new(size_t sz);
static Scope *createGlobal(Module *module);
Scope();
Scope(Module *module);
Scope(Scope *enclosing);
Scope *push();
Scope *push(ScopeDsymbol *ss);
Scope *pop();
void mergeCallSuper(Loc loc, unsigned cs);
Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym);
Dsymbol *insert(Dsymbol *s);
ClassDeclaration *getClassScope();
AggregateDeclaration *getStructClassScope();
void setNoFree();
};
#endif /* DMD_SCOPE_H */
// Copyright (c) 1999-2009 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 DMD_SCOPE_H
#define DMD_SCOPE_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
struct Dsymbol;
struct ScopeDsymbol;
struct Array;
struct Identifier;
struct Module;
struct Statement;
struct SwitchStatement;
struct TryFinallyStatement;
struct LabelStatement;
struct ForeachStatement;
struct ClassDeclaration;
struct AggregateDeclaration;
struct AnonymousAggregateDeclaration;
struct FuncDeclaration;
struct DocComment;
struct EnclosingHandler;
struct AnonDeclaration;
#if __GNUC__
#include "dsymbol.h" // PROT
#include "mars.h" // LINK
#else
enum LINK;
enum PROT;
#endif
struct Scope
{
Scope *enclosing; // enclosing Scope
Module *module; // Root module
ScopeDsymbol *scopesym; // current symbol
ScopeDsymbol *sd; // if in static if, and declaring new symbols,
// sd gets the addMember()
FuncDeclaration *func; // function we are in
Dsymbol *parent; // parent to use
LabelStatement *slabel; // enclosing labelled statement
SwitchStatement *sw; // enclosing switch statement
TryFinallyStatement *enclosingFinally; // enclosing try finally statement; set inside its finally block
Statement *enclosingScopeExit; // enclosing statement that wants to do something on scope exit
TemplateInstance *tinst; // enclosing template instance
Statement *sbreak; // enclosing statement that supports "break"
Statement *scontinue; // enclosing statement that supports "continue"
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
unsigned offset; // next offset to use in aggregate
int inunion; // we're processing members of a union
int incontract; // we're inside contract code
int nofree; // set if shouldn't free it
int noctor; // set if constructor calls aren't allowed
int intypeof; // in typeof(exp)
int parameterSpecialization; // if in template parameter specialization
int noaccesscheck; // don't do access checks
unsigned callSuper; // primitive flow analysis for constructors
#define CSXthis_ctor 1 // called this()
#define CSXsuper_ctor 2 // called super()
#define CSXthis 4 // referenced this
#define CSXsuper 8 // referenced super
#define CSXlabel 0x10 // seen a label
#define CSXreturn 0x20 // seen a return statement
#define CSXany_ctor 0x40 // either this() or super() was called
unsigned structalign; // alignment for struct members
enum LINK linkage; // linkage for external functions
enum PROT protection; // protection for class members
int explicitProtection; // set if in an explicit protection attribute
unsigned stc; // storage class
unsigned flags;
#define SCOPEctor 1 // constructor type
#define SCOPEstaticif 2 // inside static if
#define SCOPEfree 4 // is on free list
AnonymousAggregateDeclaration *anonAgg; // for temporary analysis
DocComment *lastdc; // documentation comment for last symbol at this scope
unsigned lastoffset; // offset in docbuf of where to insert next dec
OutBuffer *docbuf; // buffer for documentation output
static Scope *freelist;
static void *operator new(size_t sz);
static Scope *createGlobal(Module *module);
Scope();
Scope(Module *module);
Scope(Scope *enclosing);
Scope *push();
Scope *push(ScopeDsymbol *ss);
Scope *pop();
void mergeCallSuper(Loc loc, unsigned cs);
Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym);
Dsymbol *insert(Dsymbol *s);
ClassDeclaration *getClassScope();
AggregateDeclaration *getStructClassScope();
void setNoFree();
};
#endif /* DMD_SCOPE_H */

View File

@@ -27,6 +27,7 @@
#include "hdrgen.h"
#include "parse.h"
#include "template.h"
#include "attrib.h"
/******************************** Statement ***************************/
@@ -207,6 +208,10 @@ Statement *ExpStatement::semantic(Scope *sc)
exp = resolveProperties(sc, exp);
exp->checkSideEffect(0);
exp = exp->optimize(0);
if (exp->op == TOKdeclaration && !isDeclarationStatement())
{ Statement *s = new DeclarationStatement(loc, exp);
return s;
}
//exp = exp->optimize(isDeclarationStatement() ? WANTvalue : 0);
}
return this;
@@ -576,6 +581,82 @@ int CompoundStatement::comeFrom()
}
/******************************** CompoundDeclarationStatement ***************************/
CompoundDeclarationStatement::CompoundDeclarationStatement(Loc loc, Statements *s)
: CompoundStatement(loc, s)
{
statements = s;
}
Statement *CompoundDeclarationStatement::syntaxCopy()
{
Statements *a = new Statements();
a->setDim(statements->dim);
for (size_t i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *)statements->data[i];
if (s)
s = s->syntaxCopy();
a->data[i] = s;
}
CompoundDeclarationStatement *cs = new CompoundDeclarationStatement(loc, a);
return cs;
}
void CompoundDeclarationStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
int nwritten = 0;
for (int i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *) statements->data[i];
if (s)
{ DeclarationStatement *ds = s->isDeclarationStatement();
assert(ds);
DeclarationExp *de = (DeclarationExp *)ds->exp;
assert(de->op == TOKdeclaration);
Declaration *d = de->declaration->isDeclaration();
assert(d);
VarDeclaration *v = d->isVarDeclaration();
if (v)
{
/* This essentially copies the part of VarDeclaration::toCBuffer()
* that does not print the type.
* Should refactor this.
*/
if (nwritten)
{
buf->writeByte(',');
buf->writestring(v->ident->toChars());
}
else
{
StorageClassDeclaration::stcToCBuffer(buf, v->storage_class);
if (v->type)
v->type->toCBuffer(buf, v->ident, hgs);
else
buf->writestring(v->ident->toChars());
}
if (v->init)
{ buf->writestring(" = ");
#if DMDV2
ExpInitializer *ie = v->init->isExpInitializer();
if (ie && (ie->exp->op == TOKconstruct || ie->exp->op == TOKblit))
((AssignExp *)ie->exp)->e2->toCBuffer(buf, hgs);
else
#endif
v->init->toCBuffer(buf, hgs);
}
}
else
d->toCBuffer(buf, hgs);
nwritten++;
}
}
buf->writeByte(';');
if (!hgs->FLinit.init)
buf->writenl();
}
/**************************** UnrolledLoopStatement ***************************/
UnrolledLoopStatement::UnrolledLoopStatement(Loc loc, Statements *s)
@@ -889,6 +970,7 @@ int WhileStatement::blockExit()
return result;
}
int WhileStatement::comeFrom()
{
if (body)
@@ -974,6 +1056,7 @@ int DoStatement::blockExit()
return result;
}
int DoStatement::comeFrom()
{
if (body)
@@ -1103,6 +1186,7 @@ int ForStatement::blockExit()
return result;
}
int ForStatement::comeFrom()
{
//printf("ForStatement::comeFrom()\n");
@@ -1120,11 +1204,7 @@ void ForStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
if (init)
{
hgs->FLinit.init++;
hgs->FLinit.decl = 0;
init->toCBuffer(buf, hgs);
if (hgs->FLinit.decl > 0)
buf->writebyte(';');
hgs->FLinit.decl = 0;
hgs->FLinit.init--;
}
else
@@ -1249,17 +1329,16 @@ Statement *ForeachStatement::semantic(Scope *sc)
if (arg->storageClass & (STCout | STCref | STClazy))
error("no storage class for key %s", arg->ident->toChars());
TY keyty = arg->type->ty;
if (global.params.is64bit)
{
if (keyty != Tint32 && keyty != Tuns32 && keyty != Tint64 && keyty != Tuns64)
{
error("foreach: key type must be int, uint, long or ulong, not %s", key->type->toChars());
}
}
else if (keyty != Tint32 && keyty != Tuns32)
{
error("foreach: key type must be int or uint, not %s", key->type->toChars());
}
if (keyty != Tint32 && keyty != Tuns32)
{
if (global.params.is64bit)
{
if (keyty != Tint64 && keyty != Tuns64)
error("foreach: key type must be int or uint, long or ulong, not %s", arg->type->toChars());
}
else
error("foreach: key type must be int or uint, not %s", arg->type->toChars());
}
Initializer *ie = new ExpInitializer(0, new IntegerExp(k));
VarDeclaration *var = new VarDeclaration(loc, arg->type, arg->ident, ie);
var->storage_class |= STCconst;
@@ -1391,20 +1470,16 @@ Statement *ForeachStatement::semantic(Scope *sc)
tab->toChars(), value->type->toChars());
}
if (key)
{
if (global.params.is64bit)
{
if (key->type->ty != Tint32 && key->type->ty != Tuns32 && key->type->ty != Tint64 && key->type->ty != Tuns64)
{
error("foreach: key type must be int, uint, long or ulong, not %s", key->type->toChars());
}
}
else if (key->type->ty != Tint32 && key->type->ty != Tuns32)
{
error("foreach: key type must be int or uint, not %s", key->type->toChars());
}
}
if (key && key->type->ty != Tint32 && key->type->ty != Tuns32)
{
if (global.params.is64bit)
{
if (key->type->ty != Tint64 && key->type->ty != Tuns64)
error("foreach: key type must be int or uint, long or ulong, not %s", key->type->toChars());
}
else
error("foreach: key type must be int or uint, not %s", key->type->toChars());
}
if (key && key->storage_class & (STCout | STCref))
error("foreach: key cannot be out or ref");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -14,12 +14,7 @@
#include <assert.h>
#if !IN_LLVM
#if _WIN32
#include <windows.h>
long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep);
#endif
#endif
#include "root.h"
#include "rmem.h"
#include "stringtable.h"
@@ -36,6 +31,11 @@ long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep);
#include "dsymbol.h"
#include "hdrgen.h"
#if WINDOWS_SEH
#include <windows.h>
long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep);
#endif
#define LOG 0
/********************************************
@@ -159,6 +159,8 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
}
}
//printf("t1 = %s\n", t1->toChars());
//printf("t2 = %s\n", t2->toChars());
if (!t2 || !t1->equals(t2))
goto Lnomatch;
}
@@ -186,7 +188,7 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
{
goto Lnomatch;
}
#if V2
#if DMDV2
VarDeclaration *v1 = s1->isVarDeclaration();
VarDeclaration *v2 = s2->isVarDeclaration();
if (v1 && v2 && v1->storage_class & v2->storage_class & STCmanifest)
@@ -263,7 +265,7 @@ void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg)
}
}
#if V2
#if DMDV2
Object *objectSyntaxCopy(Object *o)
{
if (!o)
@@ -281,7 +283,8 @@ Object *objectSyntaxCopy(Object *o)
/* ======================== TemplateDeclaration ============================= */
TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, Array *decldefs)
TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id,
TemplateParameters *parameters, Expression *constraint, Array *decldefs)
: ScopeDsymbol(id)
{
#if LOG
@@ -303,9 +306,7 @@ TemplateDeclaration::TemplateDeclaration(Loc loc, Identifier *id, TemplateParame
this->loc = loc;
this->parameters = parameters;
this->origParameters = parameters;
#if V2
this->constraint = constraint;
#endif
this->members = decldefs;
this->overnext = NULL;
this->overroot = NULL;
@@ -330,13 +331,11 @@ Dsymbol *TemplateDeclaration::syntaxCopy(Dsymbol *)
p->data[i] = (void *)tp->syntaxCopy();
}
}
#if V2
Expression *e = NULL;
if (constraint)
e = constraint->syntaxCopy();
#endif
d = Dsymbol::arraySyntaxCopy(members);
td = new TemplateDeclaration(loc, ident, p, d);
td = new TemplateDeclaration(loc, ident, p, e, d);
#if IN_LLVM
// LDC
@@ -673,11 +672,11 @@ Lret:
/********************************************
* Determine partial specialization order of 'this' vs td2.
* Returns:
* 1 this is at least as specialized as td2
* match this is at least as specialized as td2
* 0 td2 is more specialized than this
*/
int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
MATCH TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
{
/* This works by taking the template parameters to this template
* declaration and feeding them to td2 as if it were a template
@@ -715,7 +714,8 @@ int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
dedtypes.setDim(td2->parameters->dim);
// Attempt a type deduction
if (td2->matchWithInstance(&ti, &dedtypes, 1))
MATCH m = td2->matchWithInstance(&ti, &dedtypes, 1);
if (m)
{
/* A non-variadic template is more specialized than a
* variadic one.
@@ -724,15 +724,15 @@ int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
goto L1;
#if LOG_LEASTAS
printf(" matches, so is least as specialized\n");
printf(" matches %d, so is least as specialized\n", m);
#endif
return 1;
return m;
}
L1:
#if LOG_LEASTAS
printf(" doesn't match, so is not as specialized\n");
#endif
return 0;
return MATCHnomatch;
}
@@ -762,7 +762,6 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
MATCH match = MATCHexact;
FuncDeclaration *fd = onemember->toAlias()->isFuncDeclaration();
TypeFunction *fdtype; // type of fd
TemplateTupleParameter *tp;
Objects dedtypes; // for T:T*, the dedargs is the T*, dedtypes is the T
#if 0
@@ -786,7 +785,18 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
paramsym->parent = scope->parent;
Scope *paramscope = scope->push(paramsym);
tp = isVariadic();
TemplateTupleParameter *tp = isVariadic();
#if 0
for (i = 0; i < dedargs->dim; i++)
{
printf("\tdedarg[%d] = ", i);
Object *oarg = (Object *)dedargs->data[i];
if (oarg) printf("%s", oarg->toChars());
printf("\n");
}
#endif
nargsi = 0;
if (targsi)
@@ -802,11 +812,11 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
memcpy(dedargs->data, targsi->data, nargsi * sizeof(*dedargs->data));
for (i = 0; i < nargsi; i++)
for (size_t i = 0; i < nargsi; i++)
{ assert(i < parameters->dim);
TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
MATCH m;
Declaration *sparam;
Declaration *sparam = NULL;
m = tp->matchArg(paramscope, dedargs, i, parameters, &dedtypes, &sparam);
//printf("\tdeduceType m = %d\n", m);
@@ -820,6 +830,15 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
goto Lnomatch;
}
}
#if 0
for (i = 0; i < dedargs->dim; i++)
{
printf("\tdedarg[%d] = ", i);
Object *oarg = (Object *)dedargs->data[i];
if (oarg) printf("%s", oarg->toChars());
printf("\n");
}
#endif
assert(fd->type->ty == Tfunction);
fdtype = (TypeFunction *)fd->type;
@@ -833,7 +852,6 @@ MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
* template Foo(T, A...) { void Foo(T t, A a); }
* void main() { Foo(1,2,3); }
*/
tp = isVariadic();
if (tp) // if variadic
{
if (nfparams == 0) // if no function parameters
@@ -906,7 +924,7 @@ L2:
{ MATCH m;
Type *t = new TypeIdentifier(0, ttp->ident);
m = ethis->type->deduceType(scope, t, parameters, &dedtypes);
m = ethis->type->deduceType(paramscope, t, parameters, &dedtypes);
if (!m)
goto Lnomatch;
if (m < match)
@@ -946,9 +964,25 @@ L2:
printf("\tfarg->type = %s\n", farg->type->toChars());
printf("\tfparam->type = %s\n", fparam->type->toChars());
#endif
Type *argtype = farg->type;
#if DMDV2
/* Allow string literals which are type [] to match with [dim]
*/
if (farg->op == TOKstring)
{ StringExp *se = (StringExp *)farg;
if (!se->committed && argtype->ty == Tarray &&
fparam->type->toBasetype()->ty == Tsarray)
{
argtype = new TypeSArray(argtype->nextOf(), new IntegerExp(se->loc, se->len, Type::tindex));
argtype = argtype->semantic(se->loc, NULL);
argtype = argtype->invariantOf();
}
}
#endif
MATCH m;
m = farg->type->deduceType(scope, fparam->type, parameters, &dedtypes);
m = argtype->deduceType(paramscope, fparam->type, parameters, &dedtypes);
//printf("\tdeduceType m = %d\n", m);
/* If no match, see if there's a conversion to a delegate
@@ -960,7 +994,7 @@ L2:
if (!tf->varargs && Argument::dim(tf->parameters) == 0)
{
m = farg->type->deduceType(scope, tf->next, parameters, &dedtypes);
m = farg->type->deduceType(paramscope, tf->next, parameters, &dedtypes);
if (!m && tf->next->toBasetype()->ty == Tvoid)
m = MATCHconvert;
}
@@ -988,7 +1022,7 @@ L2:
// Perhaps we can do better with this, see TypeFunction::callMatch()
case Tsarray:
{ TypeSArray *tsa = (TypeSArray *)tb;
integer_t sz = tsa->dim->toInteger();
dinteger_t sz = tsa->dim->toInteger();
if (sz != nfargs - i)
goto Lnomatch;
}
@@ -1020,7 +1054,7 @@ L2:
}
else
{
m = arg->type->deduceType(scope, ta->next, parameters, &dedtypes);
m = arg->type->deduceType(paramscope, ta->next, parameters, &dedtypes);
//m = arg->implicitConvTo(ta->next);
}
if (m == MATCHnomatch)
@@ -1053,6 +1087,8 @@ Lmatch:
Object *oarg = (Object *)dedargs->data[i];
Object *oded = (Object *)dedtypes.data[i];
//printf("1dedargs[%d] = %p, dedtypes[%d] = %p\n", i, oarg, i, oded);
//if (oarg) printf("oarg: %s\n", oarg->toChars());
//if (oded) printf("oded: %s\n", oded->toChars());
if (!oarg)
{
if (oded)
@@ -1134,6 +1170,22 @@ void TemplateDeclaration::declareParameter(Scope *sc, TemplateParameter *tp, Obj
Dsymbol *s;
// See if tp->ident already exists with a matching definition
Dsymbol *scopesym;
s = sc->search(loc, tp->ident, &scopesym);
if (s && scopesym == sc->scopesym)
{
TupleDeclaration *td = s->isTupleDeclaration();
if (va && td)
{ Tuple tup;
tup.objects = *td->objects;
if (match(va, &tup, this, sc))
{
return;
}
}
}
if (targ)
{
//printf("type %s\n", targ->toChars());
@@ -1267,8 +1319,8 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
{
// Disambiguate by picking the most specialized TemplateDeclaration
int c1 = td->leastAsSpecialized(td_best);
int c2 = td_best->leastAsSpecialized(td);
MATCH c1 = td->leastAsSpecialized(td_best);
MATCH c2 = td_best->leastAsSpecialized(td);
//printf("c1 = %d, c2 = %d\n", c1, c2);
if (c1 > c2)
@@ -1298,7 +1350,7 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
}
if (!td_best)
{
error(loc, "does not match any template declaration");
error(loc, "does not match any function template declaration");
goto Lerror;
}
if (td_ambig)
@@ -1319,6 +1371,9 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
return fd;
Lerror:
#if DMDV2
if (!(flags & 1))
#endif
{
HdrGenState hgs;
@@ -1537,8 +1592,29 @@ Lexact:
Lnomatch:
return MATCHnomatch;
#if DMDV2
Lconst:
return MATCHconst;
#endif
}
#if DMDV2
MATCH TypeDArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
Objects *dedtypes)
{
#if 0
printf("TypeDArray::deduceType()\n");
printf("\tthis = %d, ", ty); print();
printf("\ttparam = %d, ", tparam->ty); tparam->print();
#endif
return Type::deduceType(sc, tparam, parameters, dedtypes);
Lnomatch:
return MATCHnomatch;
}
#endif
MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
Objects *dedtypes)
{
@@ -1765,8 +1841,11 @@ MATCH TypeInstance::deduceType(Scope *sc,
Type *tparam, TemplateParameters *parameters,
Objects *dedtypes)
{
//printf("TypeInstance::deduceType(tparam = %s) %s\n", tparam->toChars(), toChars());
//printf("\ttparam = %d, ", tparam->ty); tparam->print();
#if 0
printf("TypeInstance::deduceType()\n");
printf("\tthis = %d, ", ty); print();
printf("\ttparam = %d, ", tparam->ty); tparam->print();
#endif
// Extra check
if (tparam && tparam->ty == Tinstance)
@@ -1802,14 +1881,14 @@ MATCH TypeInstance::deduceType(Scope *sc,
TemplateAliasParameter *ta = tpx->isTemplateAliasParameter();
if (!ta)
goto Lnomatch;
Dsymbol *sa = tempinst->tempdecl;
Object *sa = tempinst->tempdecl;
if (!sa)
goto Lnomatch;
if (ta->specAlias && sa != ta->specAlias)
goto Lnomatch;
if (dedtypes->data[i])
{ // Must match already deduced symbol
Dsymbol *s = (Dsymbol *)dedtypes->data[i];
Object *s = (Object *)dedtypes->data[i];
if (s != sa)
goto Lnomatch;
@@ -1821,12 +1900,13 @@ MATCH TypeInstance::deduceType(Scope *sc,
goto Lnomatch;
L2:
if (tempinst->tiargs->dim != tp->tempinst->tiargs->dim)
goto Lnomatch;
for (int i = 0; i < tempinst->tiargs->dim; i++)
{
//printf("\ttest: tempinst->tiargs[%d]\n", i);
if (i >= tp->tempinst->tiargs->dim)
goto Lnomatch;
int j;
Object *o1 = (Object *)tempinst->tiargs->data[i];
Object *o2 = (Object *)tp->tempinst->tiargs->data[i];
@@ -1853,6 +1933,43 @@ MATCH TypeInstance::deduceType(Scope *sc,
if (v2) printf("v2 = %s\n", v2->toChars());
#endif
TemplateTupleParameter *ttp;
if (t2 &&
t2->ty == Tident &&
i == tp->tempinst->tiargs->dim - 1 &&
i == tempinst->tempdecl->parameters->dim - 1 &&
(ttp = tempinst->tempdecl->isVariadic()) != NULL)
{
/* Given:
* struct A(B...) {}
* alias A!(int, float) X;
* static if (!is(X Y == A!(Z), Z))
* deduce that Z is a tuple(int, float)
*/
j = templateParameterLookup(t2, parameters);
if (j == -1)
goto Lnomatch;
/* Create tuple from remaining args
*/
Tuple *vt = new Tuple();
int vtdim = tempinst->tiargs->dim - i;
vt->objects.setDim(vtdim);
for (size_t k = 0; k < vtdim; k++)
vt->objects.data[k] = (void *)tempinst->tiargs->data[i + k];
Tuple *v = (Tuple *)dedtypes->data[j];
if (v)
{
if (!match(v, vt, tempinst->tempdecl, sc))
goto Lnomatch;
}
else
dedtypes->data[j] = vt;
break; //return MATCHexact;
}
if (t1 && t2)
{
if (!t1->deduceType(sc, t2, parameters, dedtypes))
@@ -3299,11 +3416,9 @@ void TemplateInstance::semantic(Scope *sc)
sc2->parent = /*isnested ? sc->parent :*/ this;
sc2->tinst = this;
#if !IN_LLVM
#if _WIN32
#if WINDOWS_SEH
__try
{
#endif
#endif
for (int i = 0; i < members->dim; i++)
{
@@ -3317,8 +3432,7 @@ void TemplateInstance::semantic(Scope *sc)
//printf("test4: isnested = %d, s->parent = %s\n", isnested, s->parent->toChars());
sc2->module->runDeferredSemantic();
}
#if !IN_LLVM
#if _WIN32
#if WINDOWS_SEH
}
__except (__ehfilter(GetExceptionInformation()))
{
@@ -3326,7 +3440,6 @@ void TemplateInstance::semantic(Scope *sc)
error("recursive expansion");
fatal();
}
#endif
#endif
/* If any of the instantiation members didn't get semantic() run
@@ -3385,10 +3498,15 @@ void TemplateInstance::semanticTiargs(Scope *sc)
if (semantictiargsdone)
return;
semantictiargsdone = 1;
semanticTiargs(loc, sc, tiargs);
semanticTiargs(loc, sc, tiargs, 0);
}
void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs)
/**********************************
* Input:
* flags 1: replace const variables with their initializers
*/
void TemplateInstance::semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags)
{
// Run semantic on each argument, place results in tiargs[]
//printf("+TemplateInstance::semanticTiargs() %s\n", toChars());
@@ -3636,8 +3754,8 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc)
{
// Disambiguate by picking the most specialized TemplateDeclaration
int c1 = td->leastAsSpecialized(td_best);
int c2 = td_best->leastAsSpecialized(td);
MATCH c1 = td->leastAsSpecialized(td_best);
MATCH c2 = td_best->leastAsSpecialized(td);
//printf("c1 = %d, c2 = %d\n", c1, c2);
if (c1 > c2)
@@ -3667,7 +3785,11 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc)
if (!td_best)
{
error("%s does not match any template declaration", toChars());
if (tempdecl && !tempdecl->overnext)
// Only one template, so we can give better error message
error("%s does not match template declaration %s", toChars(), tempdecl->toChars());
else
error("%s does not match any template declaration", toChars());
return NULL;
}
if (td_ambig)
@@ -3777,7 +3899,7 @@ int TemplateInstance::hasNestedArgs(Objects *args)
nested |= 1;
}
else
error("cannot use local '%s' as template parameter", d->toChars());
error("cannot use local '%s' as parameter to non-global template %s", d->toChars(), tempdecl->toChars());
}
}
else if (va)

View File

@@ -54,9 +54,7 @@ struct TemplateDeclaration : ScopeDsymbol
TemplateParameters *parameters; // array of TemplateParameter's
TemplateParameters *origParameters; // originals for Ddoc
#if DMDV2
Expression *constraint;
#endif
Array instances; // array of TemplateInstance's
TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
@@ -66,10 +64,7 @@ struct TemplateDeclaration : ScopeDsymbol
Dsymbol *onemember; // if !=NULL then one member of this template
TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters,
#if DMDV2
Expression *constraint,
#endif
Array *decldefs);
Expression *constraint, Array *decldefs);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
int overloadInsert(Dsymbol *s);
@@ -81,7 +76,7 @@ struct TemplateDeclaration : ScopeDsymbol
// void toDocBuffer(OutBuffer *buf);
MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag);
int leastAsSpecialized(TemplateDeclaration *td2);
MATCH leastAsSpecialized(TemplateDeclaration *td2);
MATCH deduceFunctionTemplateMatch(Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, Objects *dedargs);
FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, int flags = 0);
@@ -108,6 +103,8 @@ struct TemplateParameter
* template Foo(valType ident : specValue)
* For alias-parameter:
* template Foo(alias ident)
* For this-parameter:
* template Foo(this ident)
*/
Loc loc;
@@ -216,7 +213,7 @@ struct TemplateValueParameter : TemplateParameter
struct TemplateAliasParameter : TemplateParameter
{
/* Syntax:
* ident : specAlias = defaultAlias
* specType ident : specAlias = defaultAlias
*/
Type *specAliasT;
@@ -317,7 +314,7 @@ struct TemplateInstance : ScopeDsymbol
#endif
// Internal
static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs);
static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs, int flags);
void semanticTiargs(Scope *sc);
TemplateDeclaration *findTemplateDeclaration(Scope *sc);
TemplateDeclaration *findBestMatch(Scope *sc);