mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 10:16:36 +01:00
Minimize differences between original dmd source and ldc1.
Mainly affects formatting but I also found some code differences.
This commit is contained in:
@@ -257,7 +257,7 @@ struct ClassDeclaration : AggregateDeclaration
|
||||
ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
||||
int com; // !=0 if this is a COM class (meaning
|
||||
// it derives from IUnknown)
|
||||
int isscope; // !=0 if this is a scope class
|
||||
int isscope; // !=0 if this is an auto class
|
||||
int isabstract; // !=0 if abstract class
|
||||
#if DMDV1
|
||||
int isnested; // !=0 if is nested
|
||||
|
||||
188
dmd/argtypes.c
Normal file
188
dmd/argtypes.c
Normal file
@@ -0,0 +1,188 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 2010-2011 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// http://www.dsource.org/projects/dmd/browser/branches/dmd-1.x/src/argtypes.c
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mars.h"
|
||||
#include "dsymbol.h"
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
#include "init.h"
|
||||
#include "expression.h"
|
||||
#include "attrib.h"
|
||||
#include "declaration.h"
|
||||
#include "template.h"
|
||||
#include "id.h"
|
||||
#include "enum.h"
|
||||
#include "import.h"
|
||||
#include "aggregate.h"
|
||||
#include "hdrgen.h"
|
||||
|
||||
/****************************************************
|
||||
* This breaks a type down into 'simpler' types that can be passed to a function
|
||||
* in registers, and returned in registers.
|
||||
* It's highly platform dependent.
|
||||
* Returning a tuple of zero length means the type cannot be passed/returned in registers.
|
||||
*/
|
||||
|
||||
|
||||
TypeTuple *Type::toArgTypes()
|
||||
{
|
||||
return NULL; // not valid for a parameter
|
||||
}
|
||||
|
||||
|
||||
TypeTuple *TypeBasic::toArgTypes()
|
||||
{ Type *t1 = NULL;
|
||||
Type *t2 = NULL;
|
||||
switch (ty)
|
||||
{
|
||||
case Tvoid:
|
||||
return NULL;
|
||||
|
||||
case Tbool:
|
||||
case Tint8:
|
||||
case Tuns8:
|
||||
case Tint16:
|
||||
case Tuns16:
|
||||
case Tint32:
|
||||
case Tuns32:
|
||||
case Tfloat32:
|
||||
case Tint64:
|
||||
case Tuns64:
|
||||
case Tfloat64:
|
||||
case Tfloat80:
|
||||
t1 = this;
|
||||
break;
|
||||
|
||||
case Timaginary32:
|
||||
t1 = Type::tfloat32;
|
||||
break;
|
||||
|
||||
case Timaginary64:
|
||||
t1 = Type::tfloat64;
|
||||
break;
|
||||
|
||||
case Timaginary80:
|
||||
t1 = Type::tfloat80;
|
||||
break;
|
||||
|
||||
case Tcomplex32:
|
||||
if (global.params.is64bit)
|
||||
t1 = Type::tfloat64; // weird, eh?
|
||||
else
|
||||
{
|
||||
t1 = Type::tfloat64;
|
||||
t2 = Type::tfloat64;
|
||||
}
|
||||
break;
|
||||
|
||||
case Tcomplex64:
|
||||
//t1 = Type::tfloat64;
|
||||
//t2 = Type::tfloat64;
|
||||
break;
|
||||
|
||||
case Tcomplex80:
|
||||
t1 = Type::tfloat80;
|
||||
t2 = Type::tfloat80;
|
||||
break;
|
||||
|
||||
case Tascii:
|
||||
t1 = Type::tuns8;
|
||||
break;
|
||||
|
||||
case Twchar:
|
||||
t1 = Type::tuns16;
|
||||
break;
|
||||
|
||||
case Tdchar:
|
||||
t1 = Type::tuns32;
|
||||
break;
|
||||
|
||||
default: assert(0);
|
||||
}
|
||||
|
||||
TypeTuple *t;
|
||||
if (t1)
|
||||
{
|
||||
if (t2)
|
||||
t = new TypeTuple(t1, t2);
|
||||
else
|
||||
t = new TypeTuple(t1);
|
||||
}
|
||||
else
|
||||
t = new TypeTuple();
|
||||
return t;
|
||||
}
|
||||
|
||||
TypeTuple *TypeSArray::toArgTypes()
|
||||
{
|
||||
#if DMDV2
|
||||
return new TypeTuple(); // pass on the stack for efficiency
|
||||
#else
|
||||
return new TypeTuple(Type::tvoidptr);
|
||||
#endif
|
||||
}
|
||||
|
||||
TypeTuple *TypeDArray::toArgTypes()
|
||||
{
|
||||
return new TypeTuple(); // pass on the stack for efficiency
|
||||
}
|
||||
|
||||
TypeTuple *TypeAArray::toArgTypes()
|
||||
{
|
||||
return new TypeTuple(Type::tvoidptr);
|
||||
}
|
||||
|
||||
TypeTuple *TypePointer::toArgTypes()
|
||||
{
|
||||
return new TypeTuple(this);
|
||||
}
|
||||
|
||||
TypeTuple *TypeDelegate::toArgTypes()
|
||||
{
|
||||
return new TypeTuple(); // pass on the stack for efficiency
|
||||
}
|
||||
|
||||
TypeTuple *TypeStruct::toArgTypes()
|
||||
{
|
||||
d_uns64 sz = size(0);
|
||||
assert(sz < 0xFFFFFFFF);
|
||||
switch ((unsigned)sz)
|
||||
{
|
||||
case 1:
|
||||
return new TypeTuple(Type::tint8);
|
||||
case 2:
|
||||
return new TypeTuple(Type::tint16);
|
||||
case 4:
|
||||
return new TypeTuple(Type::tint32);
|
||||
case 8:
|
||||
return new TypeTuple(Type::tint64);
|
||||
}
|
||||
return new TypeTuple(); // pass on the stack
|
||||
}
|
||||
|
||||
TypeTuple *TypeEnum::toArgTypes()
|
||||
{
|
||||
return toBasetype()->toArgTypes();
|
||||
}
|
||||
|
||||
TypeTuple *TypeTypedef::toArgTypes()
|
||||
{
|
||||
return sym->basetype->toArgTypes();
|
||||
}
|
||||
|
||||
TypeTuple *TypeClass::toArgTypes()
|
||||
{
|
||||
return new TypeTuple(Type::tvoidptr);
|
||||
}
|
||||
|
||||
@@ -314,57 +314,57 @@ Expression *BinExp::arrayOp(Scope *sc)
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
/* Not in library, so generate it.
|
||||
* Construct the function body:
|
||||
* foreach (i; 0 .. p.length) for (size_t i = 0; i < p.length; i++)
|
||||
* loopbody;
|
||||
* return p;
|
||||
*/
|
||||
/* Not in library, so generate it.
|
||||
* Construct the function body:
|
||||
* foreach (i; 0 .. p.length) for (size_t i = 0; i < p.length; i++)
|
||||
* loopbody;
|
||||
* return p;
|
||||
*/
|
||||
|
||||
Parameters *fparams = new Parameters();
|
||||
Expression *loopbody = buildArrayLoop(fparams);
|
||||
Parameters *fparams = new Parameters();
|
||||
Expression *loopbody = buildArrayLoop(fparams);
|
||||
Parameter *p = (*fparams)[0 /*fparams->dim - 1*/];
|
||||
#if DMDV1
|
||||
// for (size_t i = 0; i < p.length; i++)
|
||||
Initializer *init = new ExpInitializer(0, new IntegerExp(0, 0, Type::tsize_t));
|
||||
Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init);
|
||||
Statement *s1 = new ForStatement(0,
|
||||
// for (size_t i = 0; i < p.length; i++)
|
||||
Initializer *init = new ExpInitializer(0, new IntegerExp(0, 0, Type::tsize_t));
|
||||
Dsymbol *d = new VarDeclaration(0, Type::tsize_t, Id::p, init);
|
||||
Statement *s1 = new ForStatement(0,
|
||||
new ExpStatement(0, d),
|
||||
new CmpExp(TOKlt, 0, new IdentifierExp(0, Id::p), new ArrayLengthExp(0, new IdentifierExp(0, p->ident))),
|
||||
new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id::p)),
|
||||
new ExpStatement(0, loopbody));
|
||||
new CmpExp(TOKlt, 0, new IdentifierExp(0, Id::p), new ArrayLengthExp(0, new IdentifierExp(0, p->ident))),
|
||||
new PostExp(TOKplusplus, 0, new IdentifierExp(0, Id::p)),
|
||||
new ExpStatement(0, loopbody));
|
||||
#else
|
||||
// foreach (i; 0 .. p.length)
|
||||
Statement *s1 = new ForeachRangeStatement(0, TOKforeach,
|
||||
new Parameter(0, NULL, Id::p, NULL),
|
||||
new IntegerExp(0, 0, Type::tint32),
|
||||
new ArrayLengthExp(0, new IdentifierExp(0, p->ident)),
|
||||
new ExpStatement(0, loopbody));
|
||||
// foreach (i; 0 .. p.length)
|
||||
Statement *s1 = new ForeachRangeStatement(0, TOKforeach,
|
||||
new Parameter(0, NULL, Id::p, NULL),
|
||||
new IntegerExp(0, 0, Type::tint32),
|
||||
new ArrayLengthExp(0, new IdentifierExp(0, p->ident)),
|
||||
new ExpStatement(0, loopbody));
|
||||
#endif
|
||||
Statement *s2 = new ReturnStatement(0, new IdentifierExp(0, p->ident));
|
||||
//printf("s2: %s\n", s2->toChars());
|
||||
Statement *fbody = new CompoundStatement(0, s1, s2);
|
||||
Statement *s2 = new ReturnStatement(0, new IdentifierExp(0, p->ident));
|
||||
//printf("s2: %s\n", s2->toChars());
|
||||
Statement *fbody = new CompoundStatement(0, s1, s2);
|
||||
|
||||
/* Construct the function
|
||||
*/
|
||||
TypeFunction *ftype = new TypeFunction(fparams, type, 0, LINKc);
|
||||
//printf("ftype: %s\n", ftype->toChars());
|
||||
/* Construct the function
|
||||
*/
|
||||
TypeFunction *ftype = new TypeFunction(fparams, type, 0, LINKc);
|
||||
//printf("ftype: %s\n", ftype->toChars());
|
||||
fd = new FuncDeclaration(loc, 0, ident, STCundefined, ftype);
|
||||
fd->fbody = fbody;
|
||||
fd->protection = PROTpublic;
|
||||
fd->fbody = fbody;
|
||||
fd->protection = PROTpublic;
|
||||
fd->linkage = LINKc;
|
||||
fd->isArrayOp = 1;
|
||||
|
||||
sc->module->importedFrom->members->push(fd);
|
||||
sc->module->importedFrom->members->push(fd);
|
||||
|
||||
sc = sc->push();
|
||||
sc->parent = sc->module->importedFrom;
|
||||
sc->stc = 0;
|
||||
sc = sc->push();
|
||||
sc->parent = sc->module->importedFrom;
|
||||
sc->stc = 0;
|
||||
sc->linkage = LINKc;
|
||||
fd->semantic(sc);
|
||||
fd->semantic(sc);
|
||||
fd->semantic2(sc);
|
||||
fd->semantic3(sc);
|
||||
sc->pop();
|
||||
sc->pop();
|
||||
#if IN_DMD
|
||||
}
|
||||
else
|
||||
|
||||
14
dmd/attrib.c
14
dmd/attrib.c
@@ -585,8 +585,8 @@ void LinkDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
case LINKwindows: p = "Windows"; break;
|
||||
case LINKpascal: p = "Pascal"; break;
|
||||
|
||||
// LDC
|
||||
case LINKintrinsic: p = "Intrinsic"; break;
|
||||
// LDC
|
||||
case LINKintrinsic: p = "Intrinsic"; break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
@@ -714,12 +714,15 @@ void AlignDeclaration::setScope(Scope *sc)
|
||||
|
||||
void AlignDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
// LDC
|
||||
// we only support packed structs, as from the spec: align(1) struct Packed { ... }
|
||||
// other alignments are simply ignored. my tests show this is what llvm-gcc does too ...
|
||||
// LDC
|
||||
// we only support packed structs, as from the spec: align(1) struct Packed { ... }
|
||||
// other alignments are simply ignored. my tests show this is what llvm-gcc does too ...
|
||||
if (decl)
|
||||
{
|
||||
semanticNewSc(sc, sc->stc, sc->linkage, sc->protection, sc->explicitProtection, salign);
|
||||
}
|
||||
else
|
||||
assert(0 && "what kind of align use triggers this?");
|
||||
}
|
||||
|
||||
|
||||
@@ -1130,6 +1133,7 @@ void PragmaDeclaration::semantic(Scope *sc)
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
goto Lnodecl;
|
||||
}
|
||||
else
|
||||
error("unrecognized pragma(%s)", ident->toChars());
|
||||
|
||||
@@ -57,7 +57,7 @@ struct AttribDeclaration : Dsymbol
|
||||
AttribDeclaration *isAttribDeclaration() { return this; }
|
||||
|
||||
#if IN_DMD
|
||||
virtual void toObjFile(int multiobj); // compile to .obj file
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
int cvMember(unsigned char *p);
|
||||
#endif
|
||||
|
||||
|
||||
14
dmd/cast.c
14
dmd/cast.c
@@ -404,12 +404,11 @@ MATCH StringExp::implicitConvTo(Type *t)
|
||||
printf("StringExp::implicitConvTo(this=%s, committed=%d, type=%s, t=%s)\n",
|
||||
toChars(), committed, type->toChars(), t->toChars());
|
||||
#endif
|
||||
if (!committed)
|
||||
{
|
||||
if (!committed && t->ty == Tpointer && t->next->ty == Tvoid)
|
||||
{
|
||||
return MATCHnomatch;
|
||||
}
|
||||
if (!committed)
|
||||
if (type->ty == Tsarray || type->ty == Tarray || type->ty == Tpointer)
|
||||
{
|
||||
if (type->next->ty == Tchar)
|
||||
@@ -428,15 +427,16 @@ MATCH StringExp::implicitConvTo(Type *t)
|
||||
L1:
|
||||
if (t->next->ty == Tchar)
|
||||
return MATCHexact;
|
||||
else if (t->next->ty == Twchar)
|
||||
return MATCHexact;
|
||||
else if (t->next->ty == Tdchar)
|
||||
return MATCHexact;
|
||||
else if (!committed)
|
||||
{ if (t->next->ty == Twchar)
|
||||
return MATCHexact;
|
||||
else if (t->next->ty == Tdchar)
|
||||
return MATCHexact;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return Expression::implicitConvTo(t);
|
||||
#if 0
|
||||
m = (MATCH)type->implicitConvTo(t);
|
||||
|
||||
@@ -824,7 +824,7 @@ int ClassDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset)
|
||||
{
|
||||
cd->semantic(NULL);
|
||||
if (!cd->baseClass)
|
||||
cd->error("base class is forward referenced by %s", toChars());
|
||||
cd->error("base class is forward referenced by %s", toChars());
|
||||
}
|
||||
|
||||
if (this == cd->baseClass)
|
||||
|
||||
@@ -75,7 +75,7 @@ int ComplexExp::isConst()
|
||||
|
||||
int NullExp::isConst()
|
||||
{
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int SymOffExp::isConst()
|
||||
@@ -1455,7 +1455,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
|
||||
if (t->ty == tn->ty)
|
||||
memcpy((unsigned char *)s, &v, sz);
|
||||
else
|
||||
utf_encode(sz, s, v);
|
||||
utf_encode(sz, s, v);
|
||||
|
||||
// Add terminating 0
|
||||
memset((unsigned char *)s + len * sz, 0, sz);
|
||||
@@ -1579,7 +1579,7 @@ Expression *Cat(Type *type, Expression *e1, Expression *e2)
|
||||
if (homoConcat)
|
||||
memcpy((unsigned char *)s + (sz * es1->len), &v, sz);
|
||||
else
|
||||
utf_encode(sz, (unsigned char *)s + (sz * es1->len), v);
|
||||
utf_encode(sz, (unsigned char *)s + (sz * es1->len), v);
|
||||
|
||||
// Add terminating 0
|
||||
memset((unsigned char *)s + len * sz, 0, sz);
|
||||
|
||||
@@ -591,7 +591,7 @@ void AliasDeclaration::semantic(Scope *sc)
|
||||
}
|
||||
if (!type || type->ty != Terror)
|
||||
{ //printf("setting aliassym %s to %s %s\n", toChars(), s->kind(), s->toChars());
|
||||
aliassym = s;
|
||||
aliassym = s;
|
||||
}
|
||||
this->inSemantic = 0;
|
||||
}
|
||||
@@ -671,7 +671,11 @@ void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (haliassym)
|
||||
{
|
||||
#if !IN_LLVM
|
||||
haliassym->toCBuffer(buf, hgs);
|
||||
#else
|
||||
buf->writestring(haliassym->toChars());
|
||||
#endif
|
||||
buf->writeByte(' ');
|
||||
buf->writestring(ident->toChars());
|
||||
}
|
||||
@@ -683,7 +687,11 @@ void AliasDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (aliassym)
|
||||
{
|
||||
#if !IN_LLVM
|
||||
aliassym->toCBuffer(buf, hgs);
|
||||
#else
|
||||
buf->writestring(aliassym->toChars());
|
||||
#endif
|
||||
buf->writeByte(' ');
|
||||
buf->writestring(ident->toChars());
|
||||
}
|
||||
@@ -1427,7 +1435,7 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
|
||||
fdv->nestedFrameRef = 1;
|
||||
#if IN_LLVM
|
||||
#if DMDV1
|
||||
fdv->nestedVars.insert(this);
|
||||
fdv->nestedVars.insert(this);
|
||||
#endif
|
||||
#endif
|
||||
//printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
|
||||
@@ -1496,7 +1504,7 @@ int VarDeclaration::isSameAsInitializer()
|
||||
}
|
||||
|
||||
/******************************************
|
||||
* If a variable has an scope destructor call, return call for it.
|
||||
* If a variable has a scope destructor call, return call for it.
|
||||
* Otherwise, return NULL.
|
||||
*/
|
||||
|
||||
@@ -1504,7 +1512,7 @@ Expression *VarDeclaration::callScopeDtor(Scope *sc)
|
||||
{ Expression *e = NULL;
|
||||
|
||||
//printf("VarDeclaration::callScopeDtor() %s\n", toChars());
|
||||
if (storage_class & STCscope && !noscope)
|
||||
if (storage_class & (STCauto | STCscope) && !noscope)
|
||||
{
|
||||
for (ClassDeclaration *cd = type->isClassHandle();
|
||||
cd;
|
||||
|
||||
@@ -91,6 +91,8 @@ enum STC
|
||||
#define STCtrusted 0x400000000LL
|
||||
#define STCsystem 0x800000000LL
|
||||
#define STCctfe 0x1000000000LL // can be used in CTFE, even if it is static
|
||||
#define STCdisable 0x2000000000LL // for functions that are not callable
|
||||
#define STCresult 0x4000000000LL // for result variables passed to out contracts
|
||||
|
||||
struct Match
|
||||
{
|
||||
@@ -270,7 +272,7 @@ struct VarDeclaration : Declaration
|
||||
{
|
||||
Initializer *init;
|
||||
unsigned offset;
|
||||
int noscope; // no scope semantics
|
||||
int noscope; // no auto semantics
|
||||
#if DMDV2
|
||||
FuncDeclarations nestedrefs; // referenced by these lexically nested functions
|
||||
bool isargptr; // if parameter that _argptr points to
|
||||
@@ -329,8 +331,8 @@ struct VarDeclaration : Declaration
|
||||
virtual int isSameAsInitializer();
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
Symbol *toSymbol();
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
int cvMember(unsigned char *p);
|
||||
#endif
|
||||
|
||||
@@ -423,8 +425,8 @@ struct TypeInfoDeclaration : VarDeclaration
|
||||
void toJsonBuffer(OutBuffer *buf);
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
Symbol *toSymbol();
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
virtual void toDt(dt_t **pdt);
|
||||
#endif
|
||||
|
||||
|
||||
22
dmd/doc.c
22
dmd/doc.c
@@ -254,11 +254,11 @@ void Module::gendocfile()
|
||||
|
||||
// Set time macros
|
||||
{ time_t t;
|
||||
time(&t);
|
||||
char *p = ctime(&t);
|
||||
p = mem.strdup(p);
|
||||
Macro::define(¯otable, (unsigned char *)"DATETIME", 8, (unsigned char *)p, strlen(p));
|
||||
Macro::define(¯otable, (unsigned char *)"YEAR", 4, (unsigned char *)p + 20, 4);
|
||||
time(&t);
|
||||
char *p = ctime(&t);
|
||||
p = mem.strdup(p);
|
||||
Macro::define(¯otable, (unsigned char *)"DATETIME", 8, (unsigned char *)p, strlen(p));
|
||||
Macro::define(¯otable, (unsigned char *)"YEAR", 4, (unsigned char *)p + 20, 4);
|
||||
}
|
||||
|
||||
char *docfilename = docfile->toChars();
|
||||
@@ -1931,11 +1931,11 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset)
|
||||
buf->remove(iLineStart, i - iLineStart + eollen);
|
||||
i = iLineStart;
|
||||
|
||||
if (inCode && (i <= iCodeStart))
|
||||
{ // Empty code section, just remove it completely.
|
||||
inCode = 0;
|
||||
break;
|
||||
}
|
||||
if (inCode && (i <= iCodeStart))
|
||||
{ // Empty code section, just remove it completely.
|
||||
inCode = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if (inCode)
|
||||
{
|
||||
@@ -2010,7 +2010,7 @@ void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (inCode)
|
||||
if (inCode)
|
||||
s->error("unmatched --- in DDoc comment");
|
||||
;
|
||||
}
|
||||
|
||||
@@ -221,10 +221,10 @@ char *Dsymbol::locToChars()
|
||||
|
||||
if (!loc.filename) // avoid bug 5861.
|
||||
{
|
||||
Module *m = getModule();
|
||||
Module *m = getModule();
|
||||
|
||||
if (m && m->srcfile)
|
||||
loc.filename = m->srcfile->toChars();
|
||||
if (m && m->srcfile)
|
||||
loc.filename = m->srcfile->toChars();
|
||||
}
|
||||
return loc.toChars();
|
||||
}
|
||||
@@ -556,10 +556,10 @@ void Dsymbol::error(const char *format, ...)
|
||||
if (m && m->srcfile)
|
||||
loc.filename = m->srcfile->toChars();
|
||||
}
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
verror(loc, format, ap);
|
||||
va_end(ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Dsymbol::error(Loc loc, const char *format, ...)
|
||||
@@ -1023,7 +1023,7 @@ static int getNthSymbolDg(void *ctx, size_t n, Dsymbol *sym)
|
||||
if (n == p->nth)
|
||||
{ p->sym = sym;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ EnumDeclaration::EnumDeclaration(Loc loc, Identifier *id, Type *memtype)
|
||||
sinit = NULL;
|
||||
#endif
|
||||
isdeprecated = 0;
|
||||
isdone = 0;
|
||||
}
|
||||
|
||||
Dsymbol *EnumDeclaration::syntaxCopy(Dsymbol *s)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
#if _MSC_VER
|
||||
#include <complex>
|
||||
#else
|
||||
#include <complex>
|
||||
#endif
|
||||
|
||||
#if _WIN32 && __DMC__
|
||||
@@ -125,8 +126,8 @@ Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
|
||||
//printf("rewriting e1 to %s's this\n", f->toChars());
|
||||
n++;
|
||||
|
||||
// LDC seems dmd misses it sometimes here :/
|
||||
f->vthis->nestedref = 1;
|
||||
// LDC seems dmd misses it sometimes here :/
|
||||
f->vthis->nestedref = 1;
|
||||
|
||||
e1 = new VarExp(loc, f->vthis);
|
||||
}
|
||||
@@ -780,7 +781,7 @@ void functionParameters(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argum
|
||||
{
|
||||
|
||||
// If not D linkage, do promotions
|
||||
// LDC: don't do promotions on intrinsics
|
||||
// LDC: don't do promotions on intrinsics
|
||||
if (tf->linkage != LINKd && tf->linkage != LINKintrinsic)
|
||||
{
|
||||
// Promote bytes, words, etc., to ints
|
||||
@@ -1357,7 +1358,8 @@ Expressions *Expression::arraySyntaxCopy(Expressions *exps)
|
||||
for (size_t i = 0; i < a->dim; i++)
|
||||
{ Expression *e = (Expression *)exps->data[i];
|
||||
|
||||
e = e->syntaxCopy();
|
||||
if (e)
|
||||
e = e->syntaxCopy();
|
||||
a->data[i] = e;
|
||||
}
|
||||
}
|
||||
@@ -3189,7 +3191,7 @@ void ArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
void ArrayLiteralExp::toMangleBuffer(OutBuffer *buf)
|
||||
{
|
||||
size_t dim = elements ? elements->dim : 0;
|
||||
buf->printf("A%zu", dim);
|
||||
buf->printf("A%u", dim);
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ Expression *e = elements->tdata()[i];
|
||||
e->toMangleBuffer(buf);
|
||||
@@ -3291,7 +3293,7 @@ void AssocArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
void AssocArrayLiteralExp::toMangleBuffer(OutBuffer *buf)
|
||||
{
|
||||
size_t dim = keys->dim;
|
||||
buf->printf("A%zu", dim);
|
||||
buf->printf("A%u", dim);
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ Expression *key = (Expression *)keys->data[i];
|
||||
Expression *value = (Expression *)values->data[i];
|
||||
@@ -3396,23 +3398,23 @@ Expression *StructLiteralExp::semantic(Scope *sc)
|
||||
{ if (v->init->isVoidInitializer())
|
||||
e = NULL;
|
||||
else
|
||||
{ e = v->init->toExpression();
|
||||
if (!e)
|
||||
{ error("cannot make expression out of initializer for %s", v->toChars());
|
||||
{ e = v->init->toExpression();
|
||||
if (!e)
|
||||
{ error("cannot make expression out of initializer for %s", v->toChars());
|
||||
return new ErrorExp();
|
||||
}
|
||||
else if (v->scope)
|
||||
}
|
||||
else if (v->scope)
|
||||
{ // Do deferred semantic analysis
|
||||
Initializer *i2 = v->init->syntaxCopy();
|
||||
Initializer *i2 = v->init->syntaxCopy();
|
||||
i2 = i2->semantic(v->scope, v->type, WANTinterpret);
|
||||
e = i2->toExpression();
|
||||
e = i2->toExpression();
|
||||
// remove v->scope (see bug 3426)
|
||||
// but not if gagged, for we might be called again.
|
||||
if (!global.gag)
|
||||
v->scope = NULL;
|
||||
v->scope = NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
e = v->type->defaultInitLiteral(loc);
|
||||
offset = v->offset + v->type->size();
|
||||
@@ -3545,7 +3547,7 @@ void StructLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
void StructLiteralExp::toMangleBuffer(OutBuffer *buf)
|
||||
{
|
||||
size_t dim = elements ? elements->dim : 0;
|
||||
buf->printf("S%zu", dim);
|
||||
buf->printf("S%u", dim);
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ Expression *e = (Expression *)elements->data[i];
|
||||
if (e)
|
||||
@@ -5047,6 +5049,17 @@ Expression *IsExp::semantic(Scope *sc)
|
||||
goto Lno;
|
||||
break;
|
||||
|
||||
case TOKargTypes:
|
||||
/* Generate a type tuple of the equivalent types used to determine if a
|
||||
* function argument of this type can be passed in registers.
|
||||
* The results of this are highly platform dependent, and intended
|
||||
* primarly for use in implementing va_arg().
|
||||
*/
|
||||
tded = targ->toArgTypes();
|
||||
if (!tded)
|
||||
goto Lno; // not valid for a parameter
|
||||
break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
}
|
||||
@@ -5744,7 +5757,7 @@ Expression *DotIdExp::semantic(Scope *sc)
|
||||
else
|
||||
{
|
||||
if (e1->op != TOKtype)
|
||||
e1 = resolveProperties(sc, e1);
|
||||
e1 = resolveProperties(sc, e1);
|
||||
eleft = NULL;
|
||||
eright = e1;
|
||||
}
|
||||
@@ -6240,7 +6253,7 @@ L1:
|
||||
}
|
||||
else
|
||||
#endif
|
||||
ti->semantic(sc);
|
||||
ti->semantic(sc);
|
||||
if (!ti->inst) // if template failed to expand
|
||||
return new ErrorExp();
|
||||
Dsymbol *s = ti->inst->toAlias();
|
||||
@@ -6450,7 +6463,7 @@ Expression *DelegateExp::semantic(Scope *sc)
|
||||
{
|
||||
m = sc->module;
|
||||
e1 = e1->semantic(sc);
|
||||
// LDC we need a copy as we store the LLVM tpye in TypeFunction, and delegate/members have different types for 'this'
|
||||
// LDC we need a copy as we store the LLVM tpye in TypeFunction, and delegate/members have different types for 'this'
|
||||
type = new TypeDelegate(func->type->syntaxCopy());
|
||||
type = type->semantic(loc, sc);
|
||||
AggregateDeclaration *ad = func->toParent()->isAggregateDeclaration();
|
||||
@@ -7314,14 +7327,14 @@ Expression *AddrExp::semantic(Scope *sc)
|
||||
{
|
||||
VarExp *dve = (VarExp *)e1;
|
||||
FuncDeclaration *f = dve->var->isFuncDeclaration();
|
||||
VarDeclaration *v = dve->var->isVarDeclaration();
|
||||
VarDeclaration *v = dve->var->isVarDeclaration();
|
||||
|
||||
// LDC
|
||||
if (f && f->isIntrinsic())
|
||||
{
|
||||
error("cannot take the address of intrinsic function %s", e1->toChars());
|
||||
return this;
|
||||
}
|
||||
// LDC
|
||||
if (f && f->isIntrinsic())
|
||||
{
|
||||
error("cannot take the address of intrinsic function %s", e1->toChars());
|
||||
return this;
|
||||
}
|
||||
|
||||
if (f && f->isNested())
|
||||
{
|
||||
@@ -9631,7 +9644,7 @@ Expression *MulExp::semantic(Scope *sc)
|
||||
if (t2->isimaginary())
|
||||
{ Expression *e;
|
||||
|
||||
switch (t1->ty)
|
||||
switch (t1->toBasetype()->ty)
|
||||
{
|
||||
case Timaginary32: type = Type::tfloat32; break;
|
||||
case Timaginary64: type = Type::tfloat64; break;
|
||||
@@ -9705,7 +9718,7 @@ Expression *DivExp::semantic(Scope *sc)
|
||||
{
|
||||
if (t2->isimaginary())
|
||||
{
|
||||
switch (t1->ty)
|
||||
switch (t1->toBasetype()->ty)
|
||||
{
|
||||
case Timaginary32: type = Type::tfloat32; break;
|
||||
case Timaginary64: type = Type::tfloat64; break;
|
||||
@@ -9779,7 +9792,7 @@ Expression *ShlExp::semantic(Scope *sc)
|
||||
#if !IN_LLVM
|
||||
e2 = e2->castTo(sc, Type::tshiftcnt);
|
||||
#else
|
||||
e2 = e2->castTo(sc, e1->type);
|
||||
e2 = e2->castTo(sc, e1->type);
|
||||
#endif
|
||||
type = e1->type;
|
||||
}
|
||||
|
||||
@@ -52,7 +52,6 @@ enum TOK;
|
||||
#if IN_DMD
|
||||
// Back end
|
||||
struct IRState;
|
||||
|
||||
struct dt_t;
|
||||
struct elem;
|
||||
struct Symbol; // back end symbol
|
||||
@@ -470,6 +469,9 @@ struct ArrayLiteralExp : Expression
|
||||
int apply(apply_fp_t fp, void *param);
|
||||
Expression *semantic(Scope *sc);
|
||||
int isBool(int result);
|
||||
#if IN_DMD
|
||||
elem *toElem(IRState *irs);
|
||||
#endif
|
||||
int checkSideEffect(int flag);
|
||||
StringExp *toString();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
@@ -478,14 +480,14 @@ struct ArrayLiteralExp : Expression
|
||||
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
|
||||
MATCH implicitConvTo(Type *t);
|
||||
Expression *castTo(Scope *sc, Type *t);
|
||||
#if IN_DMD
|
||||
dt_t **toDt(dt_t **pdt);
|
||||
#endif
|
||||
|
||||
Expression *doInline(InlineDoState *ids);
|
||||
Expression *inlineScan(InlineScanState *iss);
|
||||
|
||||
#if IN_DMD
|
||||
elem *toElem(IRState *irs);
|
||||
dt_t **toDt(dt_t **pdt);
|
||||
#elif IN_LLVM
|
||||
#if IN_LLVM
|
||||
DValue* toElem(IRState* irs);
|
||||
llvm::Constant *toConstElem(IRState *irs);
|
||||
#endif
|
||||
@@ -525,7 +527,7 @@ struct AssocArrayLiteralExp : Expression
|
||||
|
||||
struct StructLiteralExp : Expression
|
||||
{
|
||||
StructDeclaration *sd; // which aggregate this is for
|
||||
StructDeclaration *sd; // which aggregate this is for
|
||||
Expressions *elements; // parallels sd->fields[] with
|
||||
// NULL entries for fields to skip
|
||||
Type *stype; // final type of result (can be different from sd's type)
|
||||
@@ -544,21 +546,24 @@ struct StructLiteralExp : Expression
|
||||
Expression *semantic(Scope *sc);
|
||||
Expression *getField(Type *type, unsigned offset);
|
||||
int getFieldIndex(Type *type, unsigned offset);
|
||||
#if IN_DMD
|
||||
elem *toElem(IRState *irs);
|
||||
#endif
|
||||
int checkSideEffect(int flag);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
void toMangleBuffer(OutBuffer *buf);
|
||||
Expression *optimize(int result);
|
||||
Expression *interpret(InterState *istate, CtfeGoal goal = ctfeNeedRvalue);
|
||||
#if IN_DMD
|
||||
dt_t **toDt(dt_t **pdt);
|
||||
#endif
|
||||
Expression *toLvalue(Scope *sc, Expression *e);
|
||||
|
||||
int inlineCost3(InlineCostState *ics);
|
||||
Expression *doInline(InlineDoState *ids);
|
||||
Expression *inlineScan(InlineScanState *iss);
|
||||
|
||||
#if IN_DMD
|
||||
elem *toElem(IRState *irs);
|
||||
dt_t **toDt(dt_t **pdt);
|
||||
#elif IN_LLVM
|
||||
#if IN_LLVM
|
||||
DValue* toElem(IRState* irs);
|
||||
llvm::Constant *toConstElem(IRState *irs);
|
||||
llvm::StructType *constType;
|
||||
|
||||
82
dmd/func.c
82
dmd/func.c
@@ -55,6 +55,7 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageCla
|
||||
#if IN_GCC
|
||||
v_argptr = NULL;
|
||||
#endif
|
||||
v_argsave = NULL;
|
||||
parameters = NULL;
|
||||
labtab = NULL;
|
||||
overnext = NULL;
|
||||
@@ -216,7 +217,7 @@ void FuncDeclaration::semantic(Scope *sc)
|
||||
error("_ctor is reserved for constructors");
|
||||
|
||||
if (isConst() || isAuto() || isScope())
|
||||
error("functions cannot be const, auto or scope");
|
||||
error("functions cannot be const or auto");
|
||||
|
||||
if (isAbstract() && !isVirtual())
|
||||
error("non-virtual functions cannot be abstract");
|
||||
@@ -1240,11 +1241,11 @@ void FuncDeclaration::semantic3(Scope *sc)
|
||||
error("no match for implicit super() call in constructor");
|
||||
else
|
||||
{
|
||||
Statement *s = new ExpStatement(0, e);
|
||||
fbody = new CompoundStatement(0, s, fbody);
|
||||
Statement *s = new ExpStatement(0, e);
|
||||
fbody = new CompoundStatement(0, s, fbody);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (fes)
|
||||
{ // For foreach(){} body, append a return 0;
|
||||
Expression *e = new IntegerExp(0);
|
||||
@@ -1342,46 +1343,47 @@ void FuncDeclaration::semantic3(Scope *sc)
|
||||
}
|
||||
else
|
||||
{ // Initialize _argptr to point past non-variadic arg
|
||||
VarDeclaration *p;
|
||||
unsigned offset = 0;
|
||||
VarDeclaration *p;
|
||||
unsigned offset = 0;
|
||||
|
||||
Expression *e1 = new VarExp(0, argptr);
|
||||
// Find the last non-ref parameter
|
||||
if (parameters && parameters->dim)
|
||||
{
|
||||
int lastNonref = parameters->dim -1;
|
||||
p = (VarDeclaration *)parameters->data[lastNonref];
|
||||
/* The trouble with out and ref parameters is that taking
|
||||
* the address of it doesn't work, because later processing
|
||||
* adds in an extra level of indirection. So we skip over them.
|
||||
*/
|
||||
while (p->storage_class & (STCout | STCref))
|
||||
Expression *e1 = new VarExp(0, argptr);
|
||||
// Find the last non-ref parameter
|
||||
if (parameters && parameters->dim)
|
||||
{
|
||||
--lastNonref;
|
||||
offset += PTRSIZE;
|
||||
if (lastNonref < 0)
|
||||
{
|
||||
p = v_arguments;
|
||||
break;
|
||||
}
|
||||
int lastNonref = parameters->dim -1;
|
||||
p = (VarDeclaration *)parameters->data[lastNonref];
|
||||
/* The trouble with out and ref parameters is that taking
|
||||
* the address of it doesn't work, because later processing
|
||||
* adds in an extra level of indirection. So we skip over them.
|
||||
*/
|
||||
while (p->storage_class & (STCout | STCref))
|
||||
{
|
||||
--lastNonref;
|
||||
offset += PTRSIZE;
|
||||
if (lastNonref < 0)
|
||||
{
|
||||
p = v_arguments;
|
||||
break;
|
||||
}
|
||||
p = (VarDeclaration *)parameters->data[lastNonref];
|
||||
}
|
||||
}
|
||||
else
|
||||
p = v_arguments; // last parameter is _arguments[]
|
||||
if (p->storage_class & STClazy)
|
||||
// If the last parameter is lazy, it's the size of a delegate
|
||||
offset += PTRSIZE * 2;
|
||||
else
|
||||
offset += p->type->size();
|
||||
offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1); // assume stack aligns on pointer size
|
||||
Expression *e = new SymOffExp(0, p, offset);
|
||||
e->type = Type::tvoidptr;
|
||||
//e = e->semantic(sc);
|
||||
e = new AssignExp(0, e1, e);
|
||||
e->type = t;
|
||||
a->push(new ExpStatement(0, e));
|
||||
}
|
||||
else
|
||||
p = v_arguments; // last parameter is _arguments[]
|
||||
if (p->storage_class & STClazy)
|
||||
// If the last parameter is lazy, it's the size of a delegate
|
||||
offset += PTRSIZE * 2;
|
||||
else
|
||||
offset += p->type->size();
|
||||
offset = (offset + PTRSIZE - 1) & ~(PTRSIZE - 1); // assume stack aligns on pointer size
|
||||
Expression *e = new SymOffExp(0, p, offset);
|
||||
e->type = Type::tvoidptr;
|
||||
//e = e->semantic(sc);
|
||||
e = new AssignExp(0, e1, e);
|
||||
e->type = t;
|
||||
a->push(new ExpStatement(0, e));
|
||||
#endif // IN_GCC
|
||||
#endif
|
||||
}
|
||||
|
||||
if (_arguments)
|
||||
@@ -2632,7 +2634,7 @@ int FuncDeclaration::needsClosure()
|
||||
{ FuncDeclaration *f = (FuncDeclaration *)v->nestedrefs.data[j];
|
||||
assert(f != this);
|
||||
|
||||
//printf("\t\tf = %s, %d, %d\n", f->toChars(), f->isVirtual(), f->tookAddressOf);
|
||||
//printf("\t\tf = %s, %d, %p, %d\n", f->toChars(), f->isVirtual(), f->isThis(), f->tookAddressOf);
|
||||
if (f->isThis() || f->tookAddressOf)
|
||||
goto Lyes; // assume f escapes this function's scope
|
||||
|
||||
|
||||
45
dmd/html.c
45
dmd/html.c
@@ -1,10 +1,10 @@
|
||||
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// 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.
|
||||
// in artistic.txt, or the GNU General Public License in gpl.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
|
||||
@@ -21,8 +21,46 @@
|
||||
#include "mars.h"
|
||||
#include "html.h"
|
||||
|
||||
#if MARS || IN_LLVM
|
||||
#include <assert.h>
|
||||
#include "root.h"
|
||||
//#include "../mars/mars.h"
|
||||
#else
|
||||
#include "outbuf.h"
|
||||
#include "msgs2.h"
|
||||
|
||||
extern void html_err(const char *, unsigned, unsigned, ...);
|
||||
|
||||
static char __file__[] = __FILE__; /* for tassert.h */
|
||||
#include "tassert.h"
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
int memicmp(const char *s1, const char *s2, int n);
|
||||
#if 0
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{ char c1 = s1[i];
|
||||
char c2 = s2[i];
|
||||
|
||||
result = c1 - c2;
|
||||
if (result)
|
||||
{
|
||||
if ('A' <= c1 && c1 <= 'Z')
|
||||
c1 += 'a' - 'A';
|
||||
if ('A' <= c2 && c2 <= 'Z')
|
||||
c2 += 'a' - 'A';
|
||||
result = c1 - c2;
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
extern int HtmlNamedEntity(unsigned char *p, int length);
|
||||
|
||||
@@ -530,7 +568,7 @@ void Html::scanCDATA()
|
||||
* right.
|
||||
*/
|
||||
linnum++;
|
||||
dbuf->writeUTF8('\n');
|
||||
dbuf->writeByte('\n');
|
||||
p += lineSepLength;
|
||||
continue;
|
||||
}
|
||||
@@ -550,6 +588,7 @@ void Html::scanCDATA()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/********************************************
|
||||
* Convert an HTML character entity into a character.
|
||||
* Forms are:
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// 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.
|
||||
// in artistic.txt, or the GNU General Public License in gpl.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_HTML_H
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// http://www.dsource.org/projects/dmd/browser/branches/dmd-1.x/src/idgen.c
|
||||
// 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.
|
||||
@@ -92,6 +93,7 @@ Msgtable msgtable[] =
|
||||
{ "_arguments" },
|
||||
{ "_argptr" },
|
||||
{ "_match" },
|
||||
{ "m_align" },
|
||||
|
||||
{ "LINE", "__LINE__" },
|
||||
{ "FILE", "__FILE__" },
|
||||
|
||||
@@ -15,6 +15,8 @@
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "mars.h"
|
||||
|
||||
/******************************************
|
||||
* Looks for undefined identifier s to see
|
||||
* if it might be undefined because an import
|
||||
|
||||
@@ -484,7 +484,7 @@ Initializer *ArrayInitializer::semantic(Scope *sc, Type *t, int needInterpret)
|
||||
}
|
||||
|
||||
if ((unsigned long) dim * t->nextOf()->size() >= amax)
|
||||
{ error(loc, "array dimension %u exceeds max of %ju", dim, amax / t->nextOf()->size());
|
||||
{ error(loc, "array dimension %u exceeds max of %u", dim, amax / t->nextOf()->size());
|
||||
goto Lerr;
|
||||
}
|
||||
return this;
|
||||
@@ -540,6 +540,7 @@ Expression *ArrayInitializer::toExpression()
|
||||
|
||||
elements = new Expressions();
|
||||
elements->setDim(edim);
|
||||
elements->zero();
|
||||
for (size_t i = 0, j = 0; i < value.dim; i++, j++)
|
||||
{
|
||||
if (index[i])
|
||||
|
||||
@@ -1802,4 +1802,3 @@ Expression *Expression::inlineCopy(Scope *sc)
|
||||
return e;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
215
dmd/interpret.c
215
dmd/interpret.c
@@ -1,4 +1,3 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2011 by Digital Mars
|
||||
// All Rights Reserved
|
||||
@@ -983,14 +982,14 @@ void scrubArray(Loc loc, Expressions *elems);
|
||||
Expression *scrubReturnValue(Loc loc, Expression *e)
|
||||
{
|
||||
if (e->op == TOKclassreference)
|
||||
{
|
||||
{
|
||||
error(loc, "%s class literals cannot be returned from CTFE", ((ClassReferenceExp*)e)->originalClass()->toChars());
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
}
|
||||
if (e->op == TOKslice)
|
||||
{
|
||||
{
|
||||
e = resolveSlice(e);
|
||||
}
|
||||
}
|
||||
if (e->op == TOKstructliteral)
|
||||
{
|
||||
StructLiteralExp *se = (StructLiteralExp *)e;
|
||||
@@ -1038,7 +1037,7 @@ Expression *ReturnStatement::interpret(InterState *istate)
|
||||
START()
|
||||
if (!exp)
|
||||
return EXP_VOID_INTERPRET;
|
||||
assert(istate && istate->fd && istate->fd->type);
|
||||
assert(istate && istate->fd && istate->fd->type);
|
||||
#if DMDV2
|
||||
/* If the function returns a ref AND it's been called from an assignment,
|
||||
* we need to return an lvalue. Otherwise, just do an (rvalue) interpret.
|
||||
@@ -1162,7 +1161,7 @@ Expression *DoStatement::interpret(InterState *istate)
|
||||
if (e == EXP_CONTINUE_INTERPRET)
|
||||
if (!istate->gotoTarget || istate->gotoTarget == this)
|
||||
{
|
||||
goto Lcontinue;
|
||||
goto Lcontinue;
|
||||
}
|
||||
else // else continue at a higher level
|
||||
return e;
|
||||
@@ -1240,7 +1239,7 @@ Expression *ForStatement::interpret(InterState *istate)
|
||||
if (!istate->gotoTarget || istate->gotoTarget == this)
|
||||
{
|
||||
istate->gotoTarget = NULL;
|
||||
return NULL;
|
||||
return NULL;
|
||||
} // else break at a higher level
|
||||
}
|
||||
if (e == EXP_CONTINUE_INTERPRET)
|
||||
@@ -1248,7 +1247,7 @@ Expression *ForStatement::interpret(InterState *istate)
|
||||
if (!istate->gotoTarget || istate->gotoTarget == this)
|
||||
{
|
||||
istate->gotoTarget = NULL;
|
||||
goto Lcontinue;
|
||||
goto Lcontinue;
|
||||
} // else continue at a higher level
|
||||
}
|
||||
if (e)
|
||||
@@ -1339,7 +1338,7 @@ Expression *SwitchStatement::interpret(InterState *istate)
|
||||
if (!istate->gotoTarget || istate->gotoTarget == this)
|
||||
{
|
||||
istate->gotoTarget = NULL;
|
||||
return NULL;
|
||||
return NULL;
|
||||
} // else break at a higher level
|
||||
}
|
||||
return e;
|
||||
@@ -1730,8 +1729,8 @@ Expression *SymOffExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
}
|
||||
if (type->ty != Tpointer)
|
||||
{ // Probably impossible
|
||||
error("Cannot interpret %s at compile time", toChars());
|
||||
return EXP_CANT_INTERPRET;
|
||||
error("Cannot interpret %s at compile time", toChars());
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
Type *pointee = ((TypePointer *)type)->next;
|
||||
Expression *val = getVarExp(loc, istate, var, goal);
|
||||
@@ -1898,8 +1897,8 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal
|
||||
}
|
||||
else
|
||||
{
|
||||
if (e && !e->type)
|
||||
e->type = v->type;
|
||||
if (e && !e->type)
|
||||
e->type = v->type;
|
||||
if (e)
|
||||
e = e->interpret(istate, ctfeNeedAnyValue);
|
||||
if (e == EXP_CANT_INTERPRET && !global.gag && !CtfeStatus::stackTraceCallsToSuppress)
|
||||
@@ -1920,8 +1919,8 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d, CtfeGoal goal
|
||||
{
|
||||
if (v->init->isVoidInitializer())
|
||||
{
|
||||
error(loc, "variable %s is used before initialization", v->toChars());
|
||||
return EXP_CANT_INTERPRET;
|
||||
error(loc, "variable %s is used before initialization", v->toChars());
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
e = v->init->toExpression();
|
||||
e = e->interpret(istate);
|
||||
@@ -2203,7 +2202,7 @@ Expression *ArrayLiteralExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
#if DMDV2
|
||||
if (((TypeNext *)type)->next->mod & (MODconst | MODimmutable))
|
||||
{ // If it's immutable, we don't need to dup it
|
||||
return this;
|
||||
return this;
|
||||
}
|
||||
#endif
|
||||
return copyLiteral(this);
|
||||
@@ -2320,8 +2319,8 @@ Expression *StructLiteralExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
/* We don't know how to deal with overlapping fields
|
||||
*/
|
||||
if (sd->hasUnions)
|
||||
{ error("Unions with overlapping fields are not yet supported in CTFE");
|
||||
return EXP_CANT_INTERPRET;
|
||||
{ error("Unions with overlapping fields are not yet supported in CTFE");
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
if (ownedByCtfe)
|
||||
return copyLiteral(this);
|
||||
@@ -2469,13 +2468,13 @@ Expression *NewExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
Expression *se = newtype->defaultInitLiteral();
|
||||
#if DMDV2
|
||||
if (member)
|
||||
{
|
||||
{
|
||||
int olderrors = global.errors;
|
||||
member->interpret(istate, arguments, se);
|
||||
if (olderrors != global.errors)
|
||||
{
|
||||
error("cannot evaluate %s at compile time", toChars());
|
||||
return EXP_CANT_INTERPRET;
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
}
|
||||
#else // The above code would fail on D1 because it doesn't use STRUCTTHISREF,
|
||||
@@ -2552,7 +2551,7 @@ Expression *UnaExp::interpretCommon(InterState *istate, CtfeGoal goal, Expressi
|
||||
|
||||
#define UNA_INTERPRET(op) \
|
||||
Expression *op##Exp::interpret(InterState *istate, CtfeGoal goal) \
|
||||
{ \
|
||||
{ \
|
||||
return interpretCommon(istate, goal, &op); \
|
||||
}
|
||||
|
||||
@@ -2715,7 +2714,7 @@ Expression *BinExp::interpretCommon(InterState *istate, CtfeGoal goal, fp_t fp)
|
||||
}
|
||||
if (this->e2->type->ty == Tpointer && this->e1->type->isintegral() && op==TOKadd)
|
||||
{
|
||||
e1 = this->e1->interpret(istate);
|
||||
e1 = this->e1->interpret(istate);
|
||||
if (exceptionOrCantInterpret(e1))
|
||||
return e1;
|
||||
e2 = this->e2->interpret(istate, ctfeNeedLvalue);
|
||||
@@ -2751,7 +2750,7 @@ Lcant:
|
||||
|
||||
#define BIN_INTERPRET(op) \
|
||||
Expression *op##Exp::interpret(InterState *istate, CtfeGoal goal) \
|
||||
{ \
|
||||
{ \
|
||||
return interpretCommon(istate, goal, &op); \
|
||||
}
|
||||
|
||||
@@ -2967,28 +2966,28 @@ Expression * modifyStructField(Type *type, StructLiteralExp *se, size_t offset,
|
||||
*/
|
||||
Expression *assignAssocArrayElement(Loc loc, AssocArrayLiteralExp *aae, Expression *index, Expression *newval)
|
||||
{
|
||||
/* Create new associative array literal reflecting updated key/value
|
||||
*/
|
||||
Expressions *keysx = aae->keys;
|
||||
/* Create new associative array literal reflecting updated key/value
|
||||
*/
|
||||
Expressions *keysx = aae->keys;
|
||||
Expressions *valuesx = aae->values;
|
||||
int updated = 0;
|
||||
for (size_t j = valuesx->dim; j; )
|
||||
{ j--;
|
||||
int updated = 0;
|
||||
for (size_t j = valuesx->dim; j; )
|
||||
{ j--;
|
||||
Expression *ekey = aae->keys->tdata()[j];
|
||||
Expression *ex = ctfeEqual(TOKequal, Type::tbool, ekey, index);
|
||||
if (exceptionOrCantInterpret(ex))
|
||||
return ex;
|
||||
if (ex->isBool(TRUE))
|
||||
if (ex->isBool(TRUE))
|
||||
{ valuesx->tdata()[j] = newval;
|
||||
updated = 1;
|
||||
}
|
||||
}
|
||||
if (!updated)
|
||||
{ // Append index/newval to keysx[]/valuesx[]
|
||||
valuesx->push(newval);
|
||||
keysx->push(index);
|
||||
}
|
||||
return newval;
|
||||
updated = 1;
|
||||
}
|
||||
}
|
||||
if (!updated)
|
||||
{ // Append index/newval to keysx[]/valuesx[]
|
||||
valuesx->push(newval);
|
||||
keysx->push(index);
|
||||
}
|
||||
return newval;
|
||||
}
|
||||
|
||||
// Return true if e is derived from UnaryExp.
|
||||
@@ -3009,7 +3008,7 @@ UnaExp *isUnaExp(Expression *e)
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Returns the variable which is eventually modified, or NULL if an rvalue.
|
||||
@@ -3071,7 +3070,7 @@ bool needToCopyLiteral(Expression *expr)
|
||||
continue;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3234,7 +3233,7 @@ Expression *paintTypeOntoLiteral(Type *type, Expression *lit)
|
||||
{
|
||||
IndexExp *ie = (IndexExp *)lit;
|
||||
e = new IndexExp(lit->loc, ie->e1, ie->e2);
|
||||
}
|
||||
}
|
||||
else if (lit->op == TOKarrayliteral)
|
||||
{
|
||||
e = new SliceExp(lit->loc, lit,
|
||||
@@ -3717,8 +3716,8 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
{
|
||||
error("nested structs with constructors are not yet supported in CTFE (Bug 6419)");
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
}
|
||||
}
|
||||
newval = ctfeCast(loc, type, type, newval);
|
||||
if (exceptionOrCantInterpret(newval))
|
||||
return newval;
|
||||
@@ -3752,7 +3751,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
// (We already have 'newval' for arraylength operations)
|
||||
// ---------------------------------------
|
||||
if (wantRef && !fp && this->e1->op != TOKarraylength)
|
||||
{
|
||||
{
|
||||
newval = this->e2->interpret(istate, ctfeNeedLvalue);
|
||||
if (exceptionOrCantInterpret(newval))
|
||||
return newval;
|
||||
@@ -3763,7 +3762,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
newval->type->ty == Tclass))
|
||||
{
|
||||
newval = newval->interpret(istate);
|
||||
}
|
||||
}
|
||||
|
||||
if (newval->op == TOKassocarrayliteral || newval->op == TOKstring ||
|
||||
newval->op==TOKarrayliteral)
|
||||
@@ -3785,7 +3784,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
* create nested AA literals, and change it into a assignment.
|
||||
*/
|
||||
if (e1->op == TOKindex && ((IndexExp *)e1)->e1->type->toBasetype()->ty == Taarray)
|
||||
{
|
||||
{
|
||||
IndexExp *ie = (IndexExp *)e1;
|
||||
int depth = 0; // how many nested AA indices are there?
|
||||
while (ie->e1->op == TOKindex && ((IndexExp *)ie->e1)->e1->type->toBasetype()->ty == Taarray)
|
||||
@@ -4171,7 +4170,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
// aggregate[] = newval
|
||||
// aggregate[low..upp] = newval
|
||||
// ------------------------------
|
||||
SliceExp * sexp = (SliceExp *)e1;
|
||||
SliceExp * sexp = (SliceExp *)e1;
|
||||
// Set the $ variable
|
||||
Expression *oldval = sexp->e1;
|
||||
bool assignmentToSlicedPointer = false;
|
||||
@@ -4198,18 +4197,18 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
sexp->lengthVar->setValue(arraylen);
|
||||
}
|
||||
|
||||
Expression *upper = NULL;
|
||||
Expression *lower = NULL;
|
||||
if (sexp->upr)
|
||||
upper = sexp->upr->interpret(istate);
|
||||
Expression *upper = NULL;
|
||||
Expression *lower = NULL;
|
||||
if (sexp->upr)
|
||||
upper = sexp->upr->interpret(istate);
|
||||
if (exceptionOrCantInterpret(upper))
|
||||
{
|
||||
if (sexp->lengthVar)
|
||||
ctfeStack.pop(sexp->lengthVar); // $ is defined only in [L..U]
|
||||
return upper;
|
||||
}
|
||||
if (sexp->lwr)
|
||||
lower = sexp->lwr->interpret(istate);
|
||||
}
|
||||
if (sexp->lwr)
|
||||
lower = sexp->lwr->interpret(istate);
|
||||
if (sexp->lengthVar)
|
||||
ctfeStack.pop(sexp->lengthVar); // $ is defined only in [L..U]
|
||||
if (exceptionOrCantInterpret(lower))
|
||||
@@ -4223,8 +4222,8 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
{
|
||||
error("Array bounds [0..%d] exceeded in slice [%d..%d]",
|
||||
dim, lowerbound, upperbound);
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
if (upperbound == lowerbound)
|
||||
return newval;
|
||||
|
||||
@@ -4241,7 +4240,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
if (aggregate->op == TOKindex || aggregate->op == TOKdotvar ||
|
||||
aggregate->op == TOKslice ||
|
||||
aggregate->op == TOKstar || aggregate->op == TOKcall)
|
||||
{
|
||||
{
|
||||
aggregate = aggregate->interpret(istate, ctfeNeedLvalue);
|
||||
if (exceptionOrCantInterpret(aggregate))
|
||||
return aggregate;
|
||||
@@ -4262,7 +4261,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
}
|
||||
}
|
||||
if (aggregate->op == TOKvar)
|
||||
{
|
||||
{
|
||||
VarExp *ve = (VarExp *)(aggregate);
|
||||
VarDeclaration *v = ve->var->isVarDeclaration();
|
||||
aggregate = v->getValue();
|
||||
@@ -4305,7 +4304,7 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
}
|
||||
|
||||
if (!wantRef && newval->op == TOKslice)
|
||||
{
|
||||
{
|
||||
newval = resolveSlice(newval);
|
||||
if (newval == EXP_CANT_INTERPRET)
|
||||
{
|
||||
@@ -4320,16 +4319,16 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
}
|
||||
|
||||
// For slice assignment, we check that the lengths match.
|
||||
size_t srclen = 0;
|
||||
if (newval->op == TOKarrayliteral)
|
||||
srclen = ((ArrayLiteralExp *)newval)->elements->dim;
|
||||
else if (newval->op == TOKstring)
|
||||
srclen = ((StringExp *)newval)->len;
|
||||
size_t srclen = 0;
|
||||
if (newval->op == TOKarrayliteral)
|
||||
srclen = ((ArrayLiteralExp *)newval)->elements->dim;
|
||||
else if (newval->op == TOKstring)
|
||||
srclen = ((StringExp *)newval)->len;
|
||||
if (!isBlockAssignment && srclen != (upperbound - lowerbound))
|
||||
{
|
||||
error("Array length mismatch assigning [0..%d] to [%d..%d]", srclen, lowerbound, upperbound);
|
||||
{
|
||||
error("Array length mismatch assigning [0..%d] to [%d..%d]", srclen, lowerbound, upperbound);
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
}
|
||||
|
||||
if (!isBlockAssignment && newval->op == TOKarrayliteral && existingAE)
|
||||
{
|
||||
@@ -4353,14 +4352,14 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
*/
|
||||
sliceAssignArrayLiteralFromString(existingAE, (StringExp *)newval, firstIndex);
|
||||
return newval;
|
||||
}
|
||||
}
|
||||
else if (newval->op == TOKarrayliteral && existingSE)
|
||||
{ /* Mixed slice: it was initialized as a string literal.
|
||||
* Now a slice of it is being set with an array literal.
|
||||
*/
|
||||
sliceAssignStringFromArrayLiteral(existingSE, (ArrayLiteralExp *)newval, firstIndex);
|
||||
return newval;
|
||||
}
|
||||
}
|
||||
else if (existingSE)
|
||||
{ // String literal block slice assign
|
||||
unsigned value = newval->toInteger();
|
||||
@@ -4375,8 +4374,8 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
default:
|
||||
assert(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (goal == ctfeNeedNothing)
|
||||
return NULL; // avoid creating an unused literal
|
||||
SliceExp *retslice = new SliceExp(loc, existingSE,
|
||||
@@ -4384,14 +4383,14 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
new IntegerExp(loc, firstIndex + upperbound-lowerbound, Type::tsize_t));
|
||||
retslice->type = this->type;
|
||||
return retslice->interpret(istate);
|
||||
}
|
||||
}
|
||||
else if (existingAE)
|
||||
{
|
||||
{
|
||||
/* Block assignment, initialization of static arrays
|
||||
* x[] = e
|
||||
* x may be a multidimensional static array. (Note that this
|
||||
* only happens with array literals, never with strings).
|
||||
*/
|
||||
*/
|
||||
Expressions * w = existingAE->elements;
|
||||
assert( existingAE->type->ty == Tsarray ||
|
||||
existingAE->type->ty == Tarray);
|
||||
@@ -4410,13 +4409,13 @@ Expression *BinExp::interpretAssignCommon(InterState *istate, CtfeGoal goal, fp_
|
||||
// Multidimensional array block assign
|
||||
recursiveBlockAssign((ArrayLiteralExp *)w->tdata()[j+firstIndex], newval, wantRef);
|
||||
else
|
||||
{
|
||||
{
|
||||
if (wantRef || cow)
|
||||
existingAE->elements->tdata()[j+firstIndex] = newval;
|
||||
else
|
||||
assignInPlace(existingAE->elements->tdata()[j+firstIndex], newval);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (goal == ctfeNeedNothing)
|
||||
return NULL; // avoid creating an unused literal
|
||||
SliceExp *retslice = new SliceExp(loc, existingAE,
|
||||
@@ -4518,14 +4517,14 @@ Expression *AndAndExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
{
|
||||
error("%s does not evaluate to a boolean", e->toChars());
|
||||
e = EXP_CANT_INTERPRET;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error("%s cannot be interpreted as a boolean", e->toChars());
|
||||
e = EXP_CANT_INTERPRET;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e != EXP_CANT_INTERPRET && goal != ctfeNeedNothing)
|
||||
e = new IntegerExp(loc, result, type);
|
||||
@@ -4567,14 +4566,14 @@ Expression *OrOrExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
{
|
||||
error("%s cannot be interpreted as a boolean", e->toChars());
|
||||
e = EXP_CANT_INTERPRET;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
error("%s cannot be interpreted as a boolean", e->toChars());
|
||||
e = EXP_CANT_INTERPRET;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (e != EXP_CANT_INTERPRET && goal != ctfeNeedNothing)
|
||||
e = new IntegerExp(loc, result, type);
|
||||
@@ -4853,9 +4852,9 @@ Expression *CommaExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
}
|
||||
if (!v->getValue()) {
|
||||
Expression *newval = v->init->toExpression();
|
||||
// Bug 4027. Copy constructors are a weird case where the
|
||||
// initializer is a void function (the variable is modified
|
||||
// through a reference parameter instead).
|
||||
// Bug 4027. Copy constructors are a weird case where the
|
||||
// initializer is a void function (the variable is modified
|
||||
// through a reference parameter instead).
|
||||
newval = newval->interpret(istate);
|
||||
if (exceptionOrCantInterpret(newval))
|
||||
{
|
||||
@@ -4863,11 +4862,11 @@ Expression *CommaExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
ctfeStack.endFrame(0);
|
||||
return newval;
|
||||
}
|
||||
if (newval != EXP_VOID_INTERPRET)
|
||||
if (newval != EXP_VOID_INTERPRET)
|
||||
{
|
||||
// v isn't necessarily null.
|
||||
v->setValueWithoutChecking(copyLiteral(newval));
|
||||
}
|
||||
}
|
||||
}
|
||||
if (goal == ctfeNeedLvalue || goal == ctfeNeedLvalueRef)
|
||||
e = e2;
|
||||
@@ -4906,13 +4905,13 @@ Expression *CondExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
return e;
|
||||
if (isTrueBool(e))
|
||||
e = e1->interpret(istate, goal);
|
||||
else if (e->isBool(FALSE))
|
||||
else if (e->isBool(FALSE))
|
||||
e = e2->interpret(istate, goal);
|
||||
else
|
||||
else
|
||||
{
|
||||
error("%s does not evaluate to boolean result at compile time",
|
||||
econd->toChars());
|
||||
e = EXP_CANT_INTERPRET;
|
||||
e = EXP_CANT_INTERPRET;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
@@ -5007,7 +5006,7 @@ Expression *IndexExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
if (this->e1->type->toBasetype()->ty == Tpointer)
|
||||
{
|
||||
// Indexing a pointer. Note that there is no $ in this case.
|
||||
e1 = this->e1->interpret(istate);
|
||||
e1 = this->e1->interpret(istate);
|
||||
if (exceptionOrCantInterpret(e1))
|
||||
return e1;
|
||||
e2 = this->e2->interpret(istate);
|
||||
@@ -5047,7 +5046,7 @@ Expression *IndexExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
}
|
||||
/* Set the $ variable.
|
||||
* Note that foreach uses indexing but doesn't need $
|
||||
*/
|
||||
*/
|
||||
if (lengthVar && (e1->op == TOKstring || e1->op == TOKarrayliteral
|
||||
|| e1->op == TOKslice))
|
||||
{
|
||||
@@ -5131,7 +5130,7 @@ Expression *SliceExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
if (this->e1->type->toBasetype()->ty == Tpointer)
|
||||
{
|
||||
// Slicing a pointer. Note that there is no $ in this case.
|
||||
e1 = this->e1->interpret(istate);
|
||||
e1 = this->e1->interpret(istate);
|
||||
if (exceptionOrCantInterpret(e1))
|
||||
return e1;
|
||||
if (e1->op == TOKint64)
|
||||
@@ -5258,7 +5257,7 @@ Expression *SliceExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
new IntegerExp(loc, ilwr, lwr->type),
|
||||
new IntegerExp(loc, iupr, upr->type));
|
||||
e->type = type;
|
||||
return e;
|
||||
return e;
|
||||
}
|
||||
if (e1->op == TOKarrayliteral
|
||||
|| e1->op == TOKstring)
|
||||
@@ -5267,7 +5266,7 @@ Expression *SliceExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
{
|
||||
error("slice [%jd..%jd] exceeds array bounds [0..%jd]",
|
||||
ilwr, iupr, dollar);
|
||||
return EXP_CANT_INTERPRET;
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
}
|
||||
e = new SliceExp(loc, e1, lwr, upr);
|
||||
@@ -5434,7 +5433,7 @@ Expression *CastExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
{
|
||||
error("reinterpreting cast from %s* to %s* is not supported in CTFE",
|
||||
elemtype->toChars(), pointee->toChars());
|
||||
return EXP_CANT_INTERPRET;
|
||||
return EXP_CANT_INTERPRET;
|
||||
}
|
||||
if (ultimateSrc->ty == Tvoid)
|
||||
castBackFromVoid = true;
|
||||
@@ -5606,15 +5605,15 @@ Expression *PtrExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
ex = ex->interpret(istate);
|
||||
if (exceptionOrCantInterpret(ex))
|
||||
return ex;
|
||||
if (ex->op == TOKstructliteral)
|
||||
{ StructLiteralExp *se = (StructLiteralExp *)ex;
|
||||
if (ex->op == TOKstructliteral)
|
||||
{ StructLiteralExp *se = (StructLiteralExp *)ex;
|
||||
dinteger_t offset = ae->e2->toInteger();
|
||||
e = se->getField(type, offset);
|
||||
if (!e)
|
||||
e = EXP_CANT_INTERPRET;
|
||||
return e;
|
||||
}
|
||||
e = se->getField(type, offset);
|
||||
if (!e)
|
||||
e = EXP_CANT_INTERPRET;
|
||||
return e;
|
||||
}
|
||||
}
|
||||
e = Ptr(type, e1);
|
||||
}
|
||||
#if DMDV2
|
||||
@@ -5742,7 +5741,7 @@ Expression *DotVarExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
#endif
|
||||
if (ex->op == TOKaddress)
|
||||
ex = ((AddrExp *)ex)->e1;
|
||||
VarDeclaration *v = var->isVarDeclaration();
|
||||
VarDeclaration *v = var->isVarDeclaration();
|
||||
if (!v)
|
||||
error("CTFE internal error: %s", toChars());
|
||||
if (ex->op == TOKnull && ex->type->toBasetype()->ty == Tclass)
|
||||
@@ -5786,11 +5785,11 @@ Expression *DotVarExp::interpret(InterState *istate, CtfeGoal goal)
|
||||
e->type = type;
|
||||
return e;
|
||||
}
|
||||
if (!e)
|
||||
{
|
||||
error("couldn't find field %s in %s", v->toChars(), type->toChars());
|
||||
e = EXP_CANT_INTERPRET;
|
||||
}
|
||||
if (!e)
|
||||
{
|
||||
error("couldn't find field %s in %s", v->toChars(), type->toChars());
|
||||
e = EXP_CANT_INTERPRET;
|
||||
}
|
||||
// If it is an rvalue literal, return it...
|
||||
if (e->op == TOKstructliteral || e->op == TOKarrayliteral ||
|
||||
e->op == TOKassocarrayliteral || e->op == TOKstring)
|
||||
@@ -6253,7 +6252,7 @@ Expression *evaluateIfBuiltin(InterState *istate, Loc loc,
|
||||
for (size_t i = 0; i < args.dim; i++)
|
||||
{
|
||||
Expression *earg = arguments->tdata()[i];
|
||||
earg = earg->interpret(istate);
|
||||
earg = earg->interpret(istate);
|
||||
if (exceptionOrCantInterpret(earg))
|
||||
return earg;
|
||||
args.tdata()[i] = earg;
|
||||
|
||||
@@ -302,10 +302,10 @@ Lexer::Lexer(Module *mod,
|
||||
|
||||
void Lexer::error(const char *format, ...)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
verror(loc, format, ap);
|
||||
va_end(ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
void Lexer::error(Loc loc, const char *format, ...)
|
||||
@@ -3027,6 +3027,7 @@ static Keyword keywords[] =
|
||||
//{ "manifest", TOKmanifest },
|
||||
|
||||
// Added after 1.0
|
||||
{ "__argTypes", TOKargTypes },
|
||||
{ "ref", TOKref },
|
||||
{ "macro", TOKmacro },
|
||||
#if DMDV2
|
||||
|
||||
@@ -152,6 +152,7 @@ enum TOK
|
||||
TOKunittest,
|
||||
|
||||
// Added after 1.0
|
||||
TOKargTypes,
|
||||
TOKref,
|
||||
TOKmacro,
|
||||
#if DMDV2
|
||||
|
||||
@@ -143,9 +143,9 @@ struct Module : Package
|
||||
void parse(); // syntactic parse
|
||||
#endif
|
||||
void importAll(Scope *sc);
|
||||
void semantic(); // semantic analysis
|
||||
void semantic2(); // pass 2 semantic analysis
|
||||
void semantic3(); // pass 3 semantic analysis
|
||||
void semantic(); // semantic analysis
|
||||
void semantic2(); // pass 2 semantic analysis
|
||||
void semantic3(); // pass 3 semantic analysis
|
||||
void inlineScan(); // scan for functions to inline
|
||||
void setHdrfile(); // set hdrfile member
|
||||
void genhdrfile(); // generate D import file
|
||||
|
||||
50
dmd/mtype.c
50
dmd/mtype.c
@@ -95,12 +95,6 @@ int REALALIGNSIZE = 2;
|
||||
int Tsize_t = Tuns32;
|
||||
int Tptrdiff_t = Tint32;
|
||||
|
||||
#if _WIN32 && !(defined __MINGW32__ || defined _MSC_VER)
|
||||
static double zero = 0;
|
||||
double Port::nan = NAN;
|
||||
double Port::infinity = 1/zero;
|
||||
#endif
|
||||
|
||||
/***************************** Type *****************************/
|
||||
|
||||
ClassDeclaration *Type::typeinfo;
|
||||
@@ -2229,7 +2223,7 @@ int TypeSArray::hasPointers()
|
||||
// Arrays of void contain arbitrary data, which may include pointers
|
||||
return TRUE;
|
||||
else
|
||||
return next->hasPointers();
|
||||
return next->hasPointers();
|
||||
}
|
||||
|
||||
/***************************** TypeDArray *****************************/
|
||||
@@ -2477,7 +2471,7 @@ Type *TypeAArray::semantic(Loc loc, Scope *sc)
|
||||
break;
|
||||
}
|
||||
if (next->isscope())
|
||||
error(loc, "cannot have array of scope %s", next->toChars());
|
||||
error(loc, "cannot have array of auto %s", next->toChars());
|
||||
|
||||
return merge();
|
||||
}
|
||||
@@ -2899,7 +2893,7 @@ int Type::covariant(Type *t)
|
||||
size_t dim1 = !t1->parameters ? 0 : t1->parameters->dim;
|
||||
size_t dim2 = !t2->parameters ? 0 : t2->parameters->dim;
|
||||
if (dim1 || dim2)
|
||||
goto Ldistinct;
|
||||
goto Ldistinct;
|
||||
}
|
||||
|
||||
// The argument lists match
|
||||
@@ -3038,8 +3032,8 @@ void TypeFunction::toCBufferWithAttributes(OutBuffer *buf, Identifier *ident, Hd
|
||||
case LINKpascal: p = "Pascal "; break;
|
||||
case LINKcpp: p = "C++ "; break;
|
||||
|
||||
// LDC
|
||||
case LINKintrinsic: p = "Intrinsic"; break;
|
||||
// LDC
|
||||
case LINKintrinsic: p = "Intrinsic"; break;
|
||||
|
||||
default:
|
||||
assert(0);
|
||||
@@ -3474,14 +3468,14 @@ Expression *TypeDelegate::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
#endif
|
||||
if (ident == Id::ptr)
|
||||
{
|
||||
e = new GEPExp(e->loc, e, ident, 0);
|
||||
e = new GEPExp(e->loc, e, ident, 0);
|
||||
e->type = tvoidptr;
|
||||
return e;
|
||||
}
|
||||
else if (ident == Id::funcptr)
|
||||
{
|
||||
e = new GEPExp(e->loc, e, ident, 1);
|
||||
e->type = tvoidptr;
|
||||
e = new GEPExp(e->loc, e, ident, 1);
|
||||
e->type = tvoidptr;
|
||||
return e;
|
||||
}
|
||||
else
|
||||
@@ -4021,7 +4015,7 @@ Dsymbol *TypeInstance::toDsymbol(Scope *sc)
|
||||
|
||||
if (global.endGagging(errors))
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
resolve(loc, sc, &e, &t, &s);
|
||||
|
||||
@@ -4423,6 +4417,7 @@ Expression *TypeEnum::defaultInit(Loc loc)
|
||||
|
||||
int TypeEnum::isZeroInit(Loc loc)
|
||||
{
|
||||
//printf("TypeEnum::isZeroInit() '%s'\n", toChars());
|
||||
if (!sym->isdone && sym->scope)
|
||||
{ // Enum is forward referenced. We need to resolve the whole thing.
|
||||
sym->semantic(NULL);
|
||||
@@ -4961,7 +4956,7 @@ Expression *TypeStruct::defaultInitLiteral(Loc loc)
|
||||
{ if (vd->init->isVoidInitializer())
|
||||
e = NULL;
|
||||
else
|
||||
e = vd->init->toExpression();
|
||||
e = vd->init->toExpression();
|
||||
}
|
||||
else
|
||||
e = vd->type->defaultInitLiteral();
|
||||
@@ -5503,6 +5498,29 @@ TypeTuple::TypeTuple(Expressions *exps)
|
||||
this->arguments = arguments;
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* Type tuple with 0, 1 or 2 types in it.
|
||||
*/
|
||||
TypeTuple::TypeTuple()
|
||||
: Type(Ttuple, NULL)
|
||||
{
|
||||
arguments = new Parameters();
|
||||
}
|
||||
|
||||
TypeTuple::TypeTuple(Type *t1)
|
||||
: Type(Ttuple, NULL)
|
||||
{
|
||||
arguments = new Parameters();
|
||||
arguments->push(new Parameter(0, t1, NULL, NULL));
|
||||
}
|
||||
|
||||
TypeTuple::TypeTuple(Type *t1, Type *t2)
|
||||
: Type(Ttuple, NULL)
|
||||
{
|
||||
arguments = new Parameters();
|
||||
arguments->push(new Parameter(0, t1, NULL, NULL));
|
||||
arguments->push(new Parameter(0, t2, NULL, NULL));
|
||||
}
|
||||
Type *TypeTuple::syntaxCopy()
|
||||
{
|
||||
Parameters *args = Parameter::arraySyntaxCopy(arguments);
|
||||
|
||||
30
dmd/mtype.h
30
dmd/mtype.h
@@ -50,12 +50,11 @@ struct Parameter;
|
||||
#if IN_GCC
|
||||
union tree_node; typedef union tree_node TYPE;
|
||||
typedef TYPE type;
|
||||
#endif
|
||||
|
||||
#if IN_DMD
|
||||
#else
|
||||
typedef struct TYPE type;
|
||||
struct Symbol;
|
||||
#endif
|
||||
struct Symbol;
|
||||
struct TypeTuple;
|
||||
|
||||
enum TY
|
||||
{
|
||||
@@ -270,6 +269,7 @@ struct Type : Object
|
||||
virtual Type *reliesOnTident();
|
||||
virtual Expression *toExpression();
|
||||
virtual int hasPointers();
|
||||
virtual TypeTuple *toArgTypes();
|
||||
Type *next;
|
||||
Type *nextOf() { return next; }
|
||||
|
||||
@@ -359,6 +359,7 @@ struct TypeBasic : Type
|
||||
Expression *defaultInit(Loc loc);
|
||||
int isZeroInit(Loc loc);
|
||||
int builtinTypeInfo();
|
||||
TypeTuple *toArgTypes();
|
||||
|
||||
// For eliminating dynamic_cast
|
||||
TypeBasic *isTypeBasic();
|
||||
@@ -398,6 +399,7 @@ struct TypeSArray : TypeArray
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
Expression *toExpression();
|
||||
int hasPointers();
|
||||
TypeTuple *toArgTypes();
|
||||
|
||||
#if IN_DMD
|
||||
type *toCtype();
|
||||
@@ -424,6 +426,7 @@ struct TypeDArray : TypeArray
|
||||
int builtinTypeInfo();
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
int hasPointers();
|
||||
TypeTuple *toArgTypes();
|
||||
|
||||
#if IN_DMD
|
||||
type *toCtype();
|
||||
@@ -449,6 +452,7 @@ struct TypeAArray : TypeArray
|
||||
int checkBoolean();
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
int hasPointers();
|
||||
TypeTuple *toArgTypes();
|
||||
|
||||
#if IN_DMD
|
||||
// Back end
|
||||
@@ -473,6 +477,7 @@ struct TypePointer : Type
|
||||
int isZeroInit(Loc loc);
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
int hasPointers();
|
||||
TypeTuple *toArgTypes();
|
||||
|
||||
#if IN_DMD
|
||||
type *toCtype();
|
||||
@@ -500,7 +505,11 @@ struct TypeFunction : Type
|
||||
{
|
||||
Parameters *parameters; // function parameters
|
||||
int varargs; // 1: T t, ...) style for variable number of arguments
|
||||
// if extern (C) then this is C style va_args
|
||||
// if extern (D) then D style va_args
|
||||
// 2: T t ...) style for variable number of arguments
|
||||
// where the args are stored in a local, and a
|
||||
// dynamic array is passed to the function
|
||||
enum LINK linkage; // calling convention
|
||||
|
||||
int inuse;
|
||||
@@ -549,6 +558,7 @@ struct TypeDelegate : Type
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);
|
||||
int hasPointers();
|
||||
TypeTuple *toArgTypes();
|
||||
|
||||
#if IN_DMD
|
||||
type *toCtype();
|
||||
@@ -642,6 +652,7 @@ struct TypeStruct : Type
|
||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
int hasPointers();
|
||||
TypeTuple *toArgTypes();
|
||||
#if CPP_MANGLE
|
||||
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
|
||||
#endif
|
||||
@@ -661,10 +672,10 @@ struct TypeEnum : Type
|
||||
EnumDeclaration *sym;
|
||||
|
||||
TypeEnum(EnumDeclaration *sym);
|
||||
Type *syntaxCopy();
|
||||
d_uns64 size(Loc loc);
|
||||
unsigned alignsize();
|
||||
char *toChars();
|
||||
Type *syntaxCopy();
|
||||
Type *semantic(Loc loc, Scope *sc);
|
||||
Dsymbol *toDsymbol(Scope *sc);
|
||||
void toDecoBuffer(OutBuffer *buf, bool mangle);
|
||||
@@ -682,6 +693,10 @@ struct TypeEnum : Type
|
||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
int hasPointers();
|
||||
TypeTuple *toArgTypes();
|
||||
#if CPP_MANGLE
|
||||
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
|
||||
#endif
|
||||
|
||||
#if IN_DMD
|
||||
type *toCtype();
|
||||
@@ -722,6 +737,7 @@ struct TypeTypedef : Type
|
||||
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
int hasPointers();
|
||||
TypeTuple *toArgTypes();
|
||||
|
||||
#if IN_DMD
|
||||
type *toCtype();
|
||||
@@ -752,6 +768,7 @@ struct TypeClass : Type
|
||||
int checkBoolean();
|
||||
TypeInfoDeclaration *getTypeInfoDeclaration();
|
||||
int hasPointers();
|
||||
TypeTuple *toArgTypes();
|
||||
int builtinTypeInfo();
|
||||
#if DMDV2
|
||||
Type *toHeadMutable();
|
||||
@@ -774,6 +791,9 @@ struct TypeTuple : Type
|
||||
|
||||
TypeTuple(Parameters *arguments);
|
||||
TypeTuple(Expressions *exps);
|
||||
TypeTuple();
|
||||
TypeTuple(Type *t1);
|
||||
TypeTuple(Type *t1, Type *t2);
|
||||
Type *syntaxCopy();
|
||||
Type *semantic(Loc loc, Scope *sc);
|
||||
int equals(Object *o);
|
||||
|
||||
19
dmd/parse.c
19
dmd/parse.c
@@ -388,8 +388,8 @@ Dsymbols *Parser::parseDeclDefs(int once)
|
||||
case TOKalign:
|
||||
{ unsigned n;
|
||||
|
||||
// LDC better align code locations
|
||||
Loc alignloc = loc;
|
||||
// LDC better align code locations
|
||||
Loc alignloc = loc;
|
||||
|
||||
s = NULL;
|
||||
nextToken();
|
||||
@@ -685,11 +685,11 @@ enum LINK Parser::parseLinkage()
|
||||
}
|
||||
else if (id == Id::System)
|
||||
{
|
||||
// LDC we configure target at runtime
|
||||
if (global.params.os == OSWindows)
|
||||
link = LINKwindows;
|
||||
else
|
||||
link = LINKc;
|
||||
// LDC we configure target at runtime
|
||||
if (global.params.os == OSWindows)
|
||||
link = LINKwindows;
|
||||
else
|
||||
link = LINKc;
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -2012,7 +2012,7 @@ Type *Parser::parseBasicType2(Type *t)
|
||||
|
||||
//printf("it's an associative array\n");
|
||||
index = parseBasicType();
|
||||
index = parseDeclarator(index, NULL); // [ type ]
|
||||
index = parseDeclarator(index, NULL); // [ type ]
|
||||
check(TOKrbracket);
|
||||
ta = new TypeAArray(t, index);
|
||||
}
|
||||
@@ -3655,7 +3655,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
}
|
||||
break;
|
||||
}
|
||||
s = new AsmBlockStatement(loc, statements);
|
||||
s = new AsmBlockStatement(loc, statements);
|
||||
nextToken();
|
||||
break;
|
||||
}
|
||||
@@ -4494,6 +4494,7 @@ Expression *Parser::parsePrimaryExp()
|
||||
token.value == TOKsuper ||
|
||||
token.value == TOKenum ||
|
||||
token.value == TOKinterface ||
|
||||
token.value == TOKargTypes ||
|
||||
#if DMDV2
|
||||
token.value == TOKconst && peek(&token)->value == TOKrparen ||
|
||||
token.value == TOKinvariant && peek(&token)->value == TOKrparen ||
|
||||
|
||||
@@ -16,9 +16,9 @@
|
||||
#include "mars.h"
|
||||
#include "init.h"
|
||||
#include "identifier.h"
|
||||
#include "scope.h"
|
||||
#include "attrib.h"
|
||||
#include "dsymbol.h"
|
||||
#include "scope.h"
|
||||
#include "declaration.h"
|
||||
#include "aggregate.h"
|
||||
#include "module.h"
|
||||
|
||||
@@ -269,9 +269,9 @@ void ExpStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
}
|
||||
else
|
||||
{
|
||||
buf->writeByte(';');
|
||||
if (!hgs->FLinit.init)
|
||||
buf->writenl();
|
||||
buf->writeByte(';');
|
||||
if (!hgs->FLinit.init)
|
||||
buf->writenl();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1727,9 +1727,9 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
Expression *ec;
|
||||
Expression *e;
|
||||
Parameter *a;
|
||||
TypeDelegate* dgty;
|
||||
TypeDelegate* dgty2;
|
||||
TypeDelegate* fldeTy;
|
||||
TypeDelegate* dgty;
|
||||
TypeDelegate* dgty2;
|
||||
TypeDelegate* fldeTy;
|
||||
|
||||
Type *tret = func->type->nextOf();
|
||||
|
||||
@@ -1838,10 +1838,10 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
FuncDeclaration *fdapply;
|
||||
if (dim == 2) {
|
||||
fdapply = aaApply2_fd;
|
||||
fldeTy = aaApply2_dg;
|
||||
fldeTy = aaApply2_dg;
|
||||
} else {
|
||||
fdapply = aaApply_fd;
|
||||
fldeTy = aaApply_dg;
|
||||
fldeTy = aaApply_dg;
|
||||
}
|
||||
ec = new VarExp(0, fdapply);
|
||||
Expressions *exps = new Expressions();
|
||||
@@ -2937,7 +2937,6 @@ Statement *CaseStatement::semantic(Scope *sc)
|
||||
{ SwitchStatement *sw = sc->sw;
|
||||
|
||||
//printf("CaseStatement::semantic() %s\n", toChars());
|
||||
|
||||
exp = exp->semantic(sc);
|
||||
if (sw)
|
||||
{
|
||||
@@ -3126,7 +3125,6 @@ Statement *DefaultStatement::syntaxCopy()
|
||||
Statement *DefaultStatement::semantic(Scope *sc)
|
||||
{
|
||||
//printf("DefaultStatement::semantic()\n");
|
||||
|
||||
if (sc->sw)
|
||||
{
|
||||
if (sc->sw->sdefault)
|
||||
@@ -4098,7 +4096,7 @@ int TryCatchStatement::blockExit(bool mustNotThrow)
|
||||
if (id == Id::Object)
|
||||
{
|
||||
result &= ~BEthrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (mustNotThrow && (result & BEthrow))
|
||||
{
|
||||
@@ -4635,6 +4633,9 @@ LabelDsymbol::LabelDsymbol(Identifier *ident)
|
||||
: Dsymbol(ident)
|
||||
{
|
||||
statement = NULL;
|
||||
#if IN_GCC
|
||||
asmLabelNum = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
LabelDsymbol *LabelDsymbol::isLabel() // is this a LabelDsymbol()?
|
||||
|
||||
@@ -143,7 +143,7 @@ struct Statement : Object
|
||||
virtual CompoundStatement *isCompoundStatement() { return NULL; }
|
||||
virtual ReturnStatement *isReturnStatement() { return NULL; }
|
||||
virtual IfStatement *isIfStatement() { return NULL; }
|
||||
virtual CaseStatement* isCaseStatement() { return NULL; }
|
||||
virtual CaseStatement *isCaseStatement() { return NULL; }
|
||||
virtual DefaultStatement *isDefaultStatement() { return NULL; }
|
||||
virtual LabelStatement* isLabelStatement() { return NULL; }
|
||||
|
||||
@@ -883,6 +883,9 @@ struct LabelStatement : Statement
|
||||
struct LabelDsymbol : Dsymbol
|
||||
{
|
||||
LabelStatement *statement;
|
||||
#if IN_GCC
|
||||
unsigned asmLabelNum; // GCC-specific
|
||||
#endif
|
||||
|
||||
LabelDsymbol(Identifier *ident);
|
||||
LabelDsymbol *isLabel();
|
||||
|
||||
41
dmd/struct.c
41
dmd/struct.c
@@ -229,7 +229,7 @@ void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v)
|
||||
memalignsize = sc->structalign;
|
||||
if (alignsize < memalignsize)
|
||||
alignsize = memalignsize;
|
||||
//printf("\talignsize = %d\n", alignsize);
|
||||
//printf("\t%s: alignsize = %d\n", toChars(), alignsize);
|
||||
|
||||
v->storage_class |= STCfield;
|
||||
//printf(" addField '%s' to '%s' at offset %d, size = %d\n", v->toChars(), toChars(), v->offset, memsize);
|
||||
@@ -298,6 +298,7 @@ StructDeclaration::StructDeclaration(Loc loc, Identifier *id)
|
||||
hasIdentityAssign = 0;
|
||||
cpctor = NULL;
|
||||
postblit = NULL;
|
||||
eq = NULL;
|
||||
#endif
|
||||
|
||||
// For forward references
|
||||
@@ -320,9 +321,9 @@ void StructDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
Scope *sc2;
|
||||
|
||||
//printf("+StructDeclaration::semantic(this=%p, '%s')\n", this, toChars());
|
||||
//printf("+StructDeclaration::semantic(this=%p, '%s', sizeok = %d)\n", this, toChars(), sizeok);
|
||||
|
||||
//static int count; if (++count == 20) *(char*)0=0;
|
||||
//static int count; if (++count == 20) halt();
|
||||
|
||||
assert(type);
|
||||
if (!members) // if forward reference
|
||||
@@ -479,6 +480,40 @@ void StructDeclaration::semantic(Scope *sc)
|
||||
}
|
||||
#endif
|
||||
#if DMDV2
|
||||
/* Try to find the opEquals function. Build it if necessary.
|
||||
*/
|
||||
TypeFunction *tfeqptr;
|
||||
{ // bool opEquals(const T*) const;
|
||||
Parameters *parameters = new Parameters;
|
||||
#if STRUCTTHISREF
|
||||
// bool opEquals(ref const T) const;
|
||||
Parameter *param = new Parameter(STCref, type->constOf(), NULL, NULL);
|
||||
#else
|
||||
// bool opEquals(const T*) const;
|
||||
Parameter *param = new Parameter(STCin, type->pointerTo(), NULL, NULL);
|
||||
#endif
|
||||
|
||||
parameters->push(param);
|
||||
tfeqptr = new TypeFunction(parameters, Type::tbool, 0, LINKd);
|
||||
tfeqptr->mod = MODconst;
|
||||
tfeqptr = (TypeFunction *)tfeqptr->semantic(0, sc2);
|
||||
|
||||
Dsymbol *s = search_function(this, Id::eq);
|
||||
FuncDeclaration *fdx = s ? s->isFuncDeclaration() : NULL;
|
||||
if (fdx)
|
||||
{
|
||||
eq = fdx->overloadExactMatch(tfeqptr);
|
||||
if (!eq)
|
||||
fdx->error("type signature should be %s not %s", tfeqptr->toChars(), fdx->type->toChars());
|
||||
}
|
||||
|
||||
TemplateDeclaration *td = s ? s->isTemplateDeclaration() : NULL;
|
||||
// BUG: should also check that td is a function template, not just a template
|
||||
|
||||
if (!eq && !td)
|
||||
eq = buildOpEquals(sc2);
|
||||
}
|
||||
|
||||
dtor = buildDtor(sc2);
|
||||
postblit = buildPostBlit(sc2);
|
||||
cpctor = buildCpCtor(sc2);
|
||||
|
||||
@@ -13,14 +13,11 @@
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if !IN_LLVM
|
||||
#endif
|
||||
#include "root.h"
|
||||
#include "aav.h"
|
||||
#include "rmem.h"
|
||||
#include "stringtable.h"
|
||||
#include "mars.h"
|
||||
#include "identifier.h"
|
||||
|
||||
#include "mtype.h"
|
||||
#include "template.h"
|
||||
#include "init.h"
|
||||
@@ -30,6 +27,9 @@
|
||||
#include "aggregate.h"
|
||||
#include "declaration.h"
|
||||
#include "dsymbol.h"
|
||||
#include "mars.h"
|
||||
#include "dsymbol.h"
|
||||
#include "identifier.h"
|
||||
#include "hdrgen.h"
|
||||
|
||||
#if WINDOWS_SEH
|
||||
@@ -235,7 +235,7 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
|
||||
{
|
||||
if (!s2 || !s1->equals(s2) || s1->parent != s2->parent)
|
||||
goto Lnomatch;
|
||||
}
|
||||
}
|
||||
else if (u1)
|
||||
{
|
||||
if (!u2)
|
||||
@@ -1555,7 +1555,7 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
buf->writestring("foo ");
|
||||
#endif
|
||||
if (hgs->ddoc)
|
||||
buf->writestring(kind());
|
||||
buf->writestring(kind());
|
||||
else
|
||||
buf->writestring("template");
|
||||
buf->writeByte(' ');
|
||||
@@ -1822,7 +1822,7 @@ MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame
|
||||
TypeSArray *tp = (TypeSArray *)tparam;
|
||||
if (tp->dim->op == TOKvar &&
|
||||
((VarExp *)tp->dim)->var->storage_class & STCtemplateparameter)
|
||||
{
|
||||
{
|
||||
id = ((VarExp *)tp->dim)->var->ident;
|
||||
}
|
||||
else if (dim->toInteger() != tp->dim->toInteger())
|
||||
@@ -1833,7 +1833,7 @@ MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame
|
||||
TypeAArray *tp = (TypeAArray *)tparam;
|
||||
if (tp->index->ty == Tident &&
|
||||
((TypeIdentifier *)tp->index)->idents.dim == 0)
|
||||
{
|
||||
{
|
||||
id = ((TypeIdentifier *)tp->index)->ident;
|
||||
}
|
||||
}
|
||||
@@ -1842,28 +1842,28 @@ MATCH TypeSArray::deduceType(Scope *sc, Type *tparam, TemplateParameters *parame
|
||||
// This code matches code in TypeInstance::deduceType()
|
||||
int i = templateIdentifierLookup(id, parameters);
|
||||
if (i == -1)
|
||||
goto Lnomatch;
|
||||
goto Lnomatch;
|
||||
TemplateParameter *tprm = parameters->tdata()[i];
|
||||
TemplateValueParameter *tvp = tprm->isTemplateValueParameter();
|
||||
if (!tvp)
|
||||
goto Lnomatch;
|
||||
Expression *e = (Expression *)dedtypes->tdata()[i];
|
||||
if (e)
|
||||
{
|
||||
{
|
||||
if (!dim->equals(e))
|
||||
goto Lnomatch;
|
||||
}
|
||||
else
|
||||
goto Lnomatch;
|
||||
}
|
||||
else
|
||||
{
|
||||
Type *vt = tvp->valType->semantic(0, sc);
|
||||
MATCH m = (MATCH)dim->implicitConvTo(vt);
|
||||
if (!m)
|
||||
goto Lnomatch;
|
||||
dedtypes->tdata()[i] = dim;
|
||||
}
|
||||
return next->deduceType(sc, tparam->nextOf(), parameters, dedtypes);
|
||||
}
|
||||
}
|
||||
}
|
||||
return next->deduceType(sc, tparam->nextOf(), parameters, dedtypes);
|
||||
}
|
||||
}
|
||||
return Type::deduceType(sc, tparam, parameters, dedtypes);
|
||||
|
||||
Lnomatch:
|
||||
@@ -3655,7 +3655,7 @@ void TemplateInstance::semantic(Scope *sc)
|
||||
if (m->semanticRun >= 3)
|
||||
{
|
||||
dosemantic3 = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
for (size_t i = 0; 1; i++)
|
||||
{
|
||||
@@ -3866,10 +3866,10 @@ void TemplateInstance::semantic(Scope *sc)
|
||||
assert(target_symbol_list->tdata()[target_symbol_list_idx] == this);
|
||||
target_symbol_list->remove(target_symbol_list_idx);
|
||||
}
|
||||
semanticRun = 0;
|
||||
inst = NULL;
|
||||
}
|
||||
semanticRun = 0;
|
||||
inst = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if LOG
|
||||
printf("-TemplateInstance::semantic('%s', this=%p)\n", toChars(), this);
|
||||
@@ -4302,9 +4302,9 @@ int TemplateInstance::hasNestedArgs(Objects *args)
|
||||
(ad && ad->isnested) ||
|
||||
(d && !d->isDataseg() &&
|
||||
#if DMDV2
|
||||
!(d->storage_class & STCmanifest) &&
|
||||
!(d->storage_class & STCmanifest) &&
|
||||
#endif
|
||||
(!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) &&
|
||||
(!d->isFuncDeclaration() || d->isFuncDeclaration()->isNested()) &&
|
||||
!isTemplateMixin()
|
||||
))
|
||||
{
|
||||
@@ -4691,7 +4691,7 @@ void TemplateInstance::toObjFile(int multiobj)
|
||||
if (multiobj)
|
||||
// Append to list of object files to be written later
|
||||
//obj_append(this);
|
||||
assert(0 && "multiobj");
|
||||
assert(0 && "multiobj");
|
||||
else
|
||||
{
|
||||
for (size_t i = 0; i < members->dim; i++)
|
||||
|
||||
@@ -384,4 +384,3 @@ Dsymbol *getDsymbol(Object *o);
|
||||
void ObjectToCBuffer(OutBuffer *buf, HdrGenState *hgs, Object *oarg);
|
||||
|
||||
#endif /* DMD_TEMPLATE_H */
|
||||
|
||||
|
||||
Reference in New Issue
Block a user