[svn r357] Merged DMD 1.033

This commit is contained in:
Tomas Lindquist Olsen
2008-07-12 19:38:31 +02:00
parent fc6e0cfc65
commit 832504e5d7
59 changed files with 18354 additions and 16980 deletions

View File

@@ -1,423 +1,424 @@
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "root.h"
#include "mem.h"
#include "enum.h"
#include "aggregate.h"
#include "init.h"
#include "attrib.h"
#include "scope.h"
#include "id.h"
#include "mtype.h"
#include "declaration.h"
#include "aggregate.h"
#include "expression.h"
#include "module.h"
#define LOG 0
/* Code to do access checks
*/
int hasPackageAccess(Scope *sc, Dsymbol *s);
/****************************************
* Return PROT access for Dsymbol smember in this declaration.
*/
enum PROT AggregateDeclaration::getAccess(Dsymbol *smember)
{
return PROTpublic;
}
enum PROT StructDeclaration::getAccess(Dsymbol *smember)
{
enum PROT access_ret = PROTnone;
#if LOG
printf("+StructDeclaration::getAccess(this = '%s', smember = '%s')\n",
toChars(), smember->toChars());
#endif
if (smember->toParent() == this)
{
access_ret = smember->prot();
}
else if (smember->isDeclaration()->isStatic())
{
access_ret = smember->prot();
}
return access_ret;
}
enum PROT ClassDeclaration::getAccess(Dsymbol *smember)
{
enum PROT access_ret = PROTnone;
#if LOG
printf("+ClassDeclaration::getAccess(this = '%s', smember = '%s')\n",
toChars(), smember->toChars());
#endif
if (smember->toParent() == this)
{
access_ret = smember->prot();
}
else
{
enum PROT access;
int i;
if (smember->isDeclaration()->isStatic())
{
access_ret = smember->prot();
}
for (i = 0; i < baseclasses.dim; i++)
{ BaseClass *b = (BaseClass *)baseclasses.data[i];
access = b->base->getAccess(smember);
switch (access)
{
case PROTnone:
break;
case PROTprivate:
access = PROTnone; // private members of base class not accessible
break;
case PROTpackage:
case PROTprotected:
case PROTpublic:
case PROTexport:
// If access is to be tightened
if (b->protection < access)
access = b->protection;
// Pick path with loosest access
if (access > access_ret)
access_ret = access;
break;
default:
assert(0);
}
}
}
#if LOG
printf("-ClassDeclaration::getAccess(this = '%s', smember = '%s') = %d\n",
toChars(), smember->toChars(), access_ret);
#endif
return access_ret;
}
/********************************************************
* Helper function for ClassDeclaration::accessCheck()
* Returns:
* 0 no access
* 1 access
*/
static int accessCheckX(
Dsymbol *smember,
Dsymbol *sfunc,
AggregateDeclaration *dthis,
AggregateDeclaration *cdscope)
{
assert(dthis);
#if 0
printf("accessCheckX for %s.%s in function %s() in scope %s\n",
dthis->toChars(), smember->toChars(),
sfunc ? sfunc->toChars() : "NULL",
cdscope ? cdscope->toChars() : "NULL");
#endif
if (dthis->hasPrivateAccess(sfunc) ||
dthis->isFriendOf(cdscope))
{
if (smember->toParent() == dthis)
return 1;
else
{
ClassDeclaration *cdthis = dthis->isClassDeclaration();
if (cdthis)
{
for (int i = 0; i < cdthis->baseclasses.dim; i++)
{ BaseClass *b = (BaseClass *)cdthis->baseclasses.data[i];
enum PROT access;
access = b->base->getAccess(smember);
if (access >= PROTprotected ||
accessCheckX(smember, sfunc, b->base, cdscope)
)
return 1;
}
}
}
}
else
{
if (smember->toParent() != dthis)
{
ClassDeclaration *cdthis = dthis->isClassDeclaration();
if (cdthis)
{
for (int i = 0; i < cdthis->baseclasses.dim; i++)
{ BaseClass *b = (BaseClass *)cdthis->baseclasses.data[i];
if (accessCheckX(smember, sfunc, b->base, cdscope))
return 1;
}
}
}
}
return 0;
}
/*******************************
* Do access check for member of this class, this class being the
* type of the 'this' pointer used to access smember.
*/
void AggregateDeclaration::accessCheck(Loc loc, Scope *sc, Dsymbol *smember)
{
int result;
FuncDeclaration *f = sc->func;
AggregateDeclaration *cdscope = sc->getStructClassScope();
enum PROT access;
#if LOG
printf("AggregateDeclaration::accessCheck() for %s.%s in function %s() in scope %s\n",
toChars(), smember->toChars(),
f ? f->toChars() : NULL,
cdscope ? cdscope->toChars() : NULL);
#endif
Dsymbol *smemberparent = smember->toParent();
if (!smemberparent || !smemberparent->isAggregateDeclaration())
{
#if LOG
printf("not an aggregate member\n");
#endif
return; // then it is accessible
}
// BUG: should enable this check
//assert(smember->parent->isBaseOf(this, NULL));
if (smemberparent == this)
{ enum PROT access = smember->prot();
result = access >= PROTpublic ||
hasPrivateAccess(f) ||
isFriendOf(cdscope) ||
(access == PROTpackage && hasPackageAccess(sc, this));
#if LOG
printf("result1 = %d\n", result);
#endif
}
else if ((access = this->getAccess(smember)) >= PROTpublic)
{
result = 1;
#if LOG
printf("result2 = %d\n", result);
#endif
}
else if (access == PROTpackage && hasPackageAccess(sc, this))
{
result = 1;
#if LOG
printf("result3 = %d\n", result);
#endif
}
else
{
result = accessCheckX(smember, f, this, cdscope);
#if LOG
printf("result4 = %d\n", result);
#endif
}
if (!result)
{
error(loc, "member %s is not accessible", smember->toChars());
}
}
/****************************************
* Determine if this is the same or friend of cd.
*/
int AggregateDeclaration::isFriendOf(AggregateDeclaration *cd)
{
#if LOG
printf("AggregateDeclaration::isFriendOf(this = '%s', cd = '%s')\n", toChars(), cd ? cd->toChars() : "null");
#endif
if (this == cd)
return 1;
// Friends if both are in the same module
//if (toParent() == cd->toParent())
if (cd && getModule() == cd->getModule())
{
#if LOG
printf("\tin same module\n");
#endif
return 1;
}
#if LOG
printf("\tnot friend\n");
#endif
return 0;
}
/****************************************
* Determine if scope sc has package level access to s.
*/
int hasPackageAccess(Scope *sc, Dsymbol *s)
{
#if LOG
printf("hasPackageAccess(s = '%s', sc = '%p')\n", s->toChars(), sc);
#endif
for (; s; s = s->parent)
{
if (s->isPackage() && !s->isModule())
break;
}
#if LOG
if (s)
printf("\tthis is in package '%s'\n", s->toChars());
#endif
if (s && s == sc->module->parent)
{
#if LOG
printf("\ts is in same package as sc\n");
#endif
return 1;
}
#if LOG
printf("\tno package access\n");
#endif
return 0;
}
/**********************************
* Determine if smember has access to private members of this declaration.
*/
int AggregateDeclaration::hasPrivateAccess(Dsymbol *smember)
{
if (smember)
{ AggregateDeclaration *cd = NULL;
Dsymbol *smemberparent = smember->toParent();
if (smemberparent)
cd = smemberparent->isAggregateDeclaration();
#if LOG
printf("AggregateDeclaration::hasPrivateAccess(class %s, member %s)\n",
toChars(), smember->toChars());
#endif
if (this == cd) // smember is a member of this class
{
#if LOG
printf("\tyes 1\n");
#endif
return 1; // so we get private access
}
// If both are members of the same module, grant access
while (1)
{ Dsymbol *sp = smember->toParent();
if (sp->isFuncDeclaration() && smember->isFuncDeclaration())
smember = sp;
else
break;
}
if (!cd && toParent() == smember->toParent())
{
#if LOG
printf("\tyes 2\n");
#endif
return 1;
}
if (!cd && getModule() == smember->getModule())
{
#if LOG
printf("\tyes 3\n");
#endif
return 1;
}
}
#if LOG
printf("\tno\n");
#endif
return 0;
}
/****************************************
* Check access to d for expression e.d
*/
void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d)
{
#if LOG
if (e)
{ printf("accessCheck(%s . %s)\n", e->toChars(), d->toChars());
printf("\te->type = %s\n", e->type->toChars());
}
else
{
//printf("accessCheck(%s)\n", d->toChars());
}
#endif
if (!e)
{
if (d->prot() == PROTprivate && d->getModule() != sc->module ||
d->prot() == PROTpackage && !hasPackageAccess(sc, d))
error(loc, "%s %s.%s is not accessible from %s",
d->kind(), d->getModule()->toChars(), d->toChars(), sc->module->toChars());
}
else if (e->type->ty == Tclass)
{ // Do access check
ClassDeclaration *cd;
cd = (ClassDeclaration *)(((TypeClass *)e->type)->sym);
#if 1
if (e->op == TOKsuper)
{ ClassDeclaration *cd2;
cd2 = sc->func->toParent()->isClassDeclaration();
if (cd2)
cd = cd2;
}
#endif
cd->accessCheck(loc, sc, d);
}
else if (e->type->ty == Tstruct)
{ // Do access check
StructDeclaration *cd;
cd = (StructDeclaration *)(((TypeStruct *)e->type)->sym);
cd->accessCheck(loc, sc, d);
}
}
// Copyright (c) 1999-2006 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
// License for redistribution is by either the Artistic License
// in artistic.txt, or the GNU General Public License in gnu.txt.
// See the included readme.txt for details.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "root.h"
#include "mem.h"
#include "enum.h"
#include "aggregate.h"
#include "init.h"
#include "attrib.h"
#include "scope.h"
#include "id.h"
#include "mtype.h"
#include "declaration.h"
#include "aggregate.h"
#include "expression.h"
#include "module.h"
#define LOG 0
/* Code to do access checks
*/
int hasPackageAccess(Scope *sc, Dsymbol *s);
/****************************************
* Return PROT access for Dsymbol smember in this declaration.
*/
enum PROT AggregateDeclaration::getAccess(Dsymbol *smember)
{
return PROTpublic;
}
enum PROT StructDeclaration::getAccess(Dsymbol *smember)
{
enum PROT access_ret = PROTnone;
#if LOG
printf("+StructDeclaration::getAccess(this = '%s', smember = '%s')\n",
toChars(), smember->toChars());
#endif
if (smember->toParent() == this)
{
access_ret = smember->prot();
}
else if (smember->isDeclaration()->isStatic())
{
access_ret = smember->prot();
}
return access_ret;
}
enum PROT ClassDeclaration::getAccess(Dsymbol *smember)
{
enum PROT access_ret = PROTnone;
#if LOG
printf("+ClassDeclaration::getAccess(this = '%s', smember = '%s')\n",
toChars(), smember->toChars());
#endif
if (smember->toParent() == this)
{
access_ret = smember->prot();
}
else
{
enum PROT access;
int i;
if (smember->isDeclaration()->isStatic())
{
access_ret = smember->prot();
}
for (i = 0; i < baseclasses.dim; i++)
{ BaseClass *b = (BaseClass *)baseclasses.data[i];
access = b->base->getAccess(smember);
switch (access)
{
case PROTnone:
break;
case PROTprivate:
access = PROTnone; // private members of base class not accessible
break;
case PROTpackage:
case PROTprotected:
case PROTpublic:
case PROTexport:
// If access is to be tightened
if (b->protection < access)
access = b->protection;
// Pick path with loosest access
if (access > access_ret)
access_ret = access;
break;
default:
assert(0);
}
}
}
#if LOG
printf("-ClassDeclaration::getAccess(this = '%s', smember = '%s') = %d\n",
toChars(), smember->toChars(), access_ret);
#endif
return access_ret;
}
/********************************************************
* Helper function for ClassDeclaration::accessCheck()
* Returns:
* 0 no access
* 1 access
*/
static int accessCheckX(
Dsymbol *smember,
Dsymbol *sfunc,
AggregateDeclaration *dthis,
AggregateDeclaration *cdscope)
{
assert(dthis);
#if 0
printf("accessCheckX for %s.%s in function %s() in scope %s\n",
dthis->toChars(), smember->toChars(),
sfunc ? sfunc->toChars() : "NULL",
cdscope ? cdscope->toChars() : "NULL");
#endif
if (dthis->hasPrivateAccess(sfunc) ||
dthis->isFriendOf(cdscope))
{
if (smember->toParent() == dthis)
return 1;
else
{
ClassDeclaration *cdthis = dthis->isClassDeclaration();
if (cdthis)
{
for (int i = 0; i < cdthis->baseclasses.dim; i++)
{ BaseClass *b = (BaseClass *)cdthis->baseclasses.data[i];
enum PROT access;
access = b->base->getAccess(smember);
if (access >= PROTprotected ||
accessCheckX(smember, sfunc, b->base, cdscope)
)
return 1;
}
}
}
}
else
{
if (smember->toParent() != dthis)
{
ClassDeclaration *cdthis = dthis->isClassDeclaration();
if (cdthis)
{
for (int i = 0; i < cdthis->baseclasses.dim; i++)
{ BaseClass *b = (BaseClass *)cdthis->baseclasses.data[i];
if (accessCheckX(smember, sfunc, b->base, cdscope))
return 1;
}
}
}
}
return 0;
}
/*******************************
* Do access check for member of this class, this class being the
* type of the 'this' pointer used to access smember.
*/
void AggregateDeclaration::accessCheck(Loc loc, Scope *sc, Dsymbol *smember)
{
int result;
FuncDeclaration *f = sc->func;
AggregateDeclaration *cdscope = sc->getStructClassScope();
enum PROT access;
#if LOG
printf("AggregateDeclaration::accessCheck() for %s.%s in function %s() in scope %s\n",
toChars(), smember->toChars(),
f ? f->toChars() : NULL,
cdscope ? cdscope->toChars() : NULL);
#endif
Dsymbol *smemberparent = smember->toParent();
if (!smemberparent || !smemberparent->isAggregateDeclaration())
{
#if LOG
printf("not an aggregate member\n");
#endif
return; // then it is accessible
}
// BUG: should enable this check
//assert(smember->parent->isBaseOf(this, NULL));
if (smemberparent == this)
{ enum PROT access = smember->prot();
result = access >= PROTpublic ||
hasPrivateAccess(f) ||
isFriendOf(cdscope) ||
(access == PROTpackage && hasPackageAccess(sc, this));
#if LOG
printf("result1 = %d\n", result);
#endif
}
else if ((access = this->getAccess(smember)) >= PROTpublic)
{
result = 1;
#if LOG
printf("result2 = %d\n", result);
#endif
}
else if (access == PROTpackage && hasPackageAccess(sc, this))
{
result = 1;
#if LOG
printf("result3 = %d\n", result);
#endif
}
else
{
result = accessCheckX(smember, f, this, cdscope);
#if LOG
printf("result4 = %d\n", result);
#endif
}
if (!result)
{
error(loc, "member %s is not accessible", smember->toChars());
halt();
}
}
/****************************************
* Determine if this is the same or friend of cd.
*/
int AggregateDeclaration::isFriendOf(AggregateDeclaration *cd)
{
#if LOG
printf("AggregateDeclaration::isFriendOf(this = '%s', cd = '%s')\n", toChars(), cd ? cd->toChars() : "null");
#endif
if (this == cd)
return 1;
// Friends if both are in the same module
//if (toParent() == cd->toParent())
if (cd && getModule() == cd->getModule())
{
#if LOG
printf("\tin same module\n");
#endif
return 1;
}
#if LOG
printf("\tnot friend\n");
#endif
return 0;
}
/****************************************
* Determine if scope sc has package level access to s.
*/
int hasPackageAccess(Scope *sc, Dsymbol *s)
{
#if LOG
printf("hasPackageAccess(s = '%s', sc = '%p')\n", s->toChars(), sc);
#endif
for (; s; s = s->parent)
{
if (s->isPackage() && !s->isModule())
break;
}
#if LOG
if (s)
printf("\tthis is in package '%s'\n", s->toChars());
#endif
if (s && s == sc->module->parent)
{
#if LOG
printf("\ts is in same package as sc\n");
#endif
return 1;
}
#if LOG
printf("\tno package access\n");
#endif
return 0;
}
/**********************************
* Determine if smember has access to private members of this declaration.
*/
int AggregateDeclaration::hasPrivateAccess(Dsymbol *smember)
{
if (smember)
{ AggregateDeclaration *cd = NULL;
Dsymbol *smemberparent = smember->toParent();
if (smemberparent)
cd = smemberparent->isAggregateDeclaration();
#if LOG
printf("AggregateDeclaration::hasPrivateAccess(class %s, member %s)\n",
toChars(), smember->toChars());
#endif
if (this == cd) // smember is a member of this class
{
#if LOG
printf("\tyes 1\n");
#endif
return 1; // so we get private access
}
// If both are members of the same module, grant access
while (1)
{ Dsymbol *sp = smember->toParent();
if (sp->isFuncDeclaration() && smember->isFuncDeclaration())
smember = sp;
else
break;
}
if (!cd && toParent() == smember->toParent())
{
#if LOG
printf("\tyes 2\n");
#endif
return 1;
}
if (!cd && getModule() == smember->getModule())
{
#if LOG
printf("\tyes 3\n");
#endif
return 1;
}
}
#if LOG
printf("\tno\n");
#endif
return 0;
}
/****************************************
* Check access to d for expression e.d
*/
void accessCheck(Loc loc, Scope *sc, Expression *e, Declaration *d)
{
#if LOG
if (e)
{ printf("accessCheck(%s . %s)\n", e->toChars(), d->toChars());
printf("\te->type = %s\n", e->type->toChars());
}
else
{
//printf("accessCheck(%s)\n", d->toChars());
}
#endif
if (!e)
{
if (d->prot() == PROTprivate && d->getModule() != sc->module ||
d->prot() == PROTpackage && !hasPackageAccess(sc, d))
error(loc, "%s %s.%s is not accessible from %s",
d->kind(), d->getModule()->toChars(), d->toChars(), sc->module->toChars());
}
else if (e->type->ty == Tclass)
{ // Do access check
ClassDeclaration *cd;
cd = (ClassDeclaration *)(((TypeClass *)e->type)->sym);
#if 1
if (e->op == TOKsuper)
{ ClassDeclaration *cd2;
cd2 = sc->func->toParent()->isClassDeclaration();
if (cd2)
cd = cd2;
}
#endif
cd->accessCheck(loc, sc, d);
}
else if (e->type->ty == Tstruct)
{ // Do access check
StructDeclaration *cd;
cd = (StructDeclaration *)(((TypeStruct *)e->type)->sym);
cd->accessCheck(loc, sc, d);
}
}

View File

@@ -64,14 +64,15 @@ struct AggregateDeclaration : ScopeDsymbol
// 2: cannot determine size; fwd referenced
int isdeprecated; // !=0 if deprecated
Scope *scope; // !=NULL means context to use
FuncDeclarations dtors; // Array of destructors
FuncDeclaration *dtor; // aggregate destructor
// Special member functions
InvariantDeclaration *inv; // invariant
NewDeclaration *aggNew; // allocator
DeleteDeclaration *aggDelete; // deallocator
FuncDeclarations dtors; // Array of destructors
FuncDeclaration *dtor; // aggregate destructor
#ifdef IN_GCC
Array methods; // flat list of all methods for debug information
#endif
@@ -119,19 +120,26 @@ struct AnonymousAggregateDeclaration : AggregateDeclaration
struct StructDeclaration : AggregateDeclaration
{
int zeroInit; // !=0 if initialize with 0 fill
#if DMDV2
int hasIdentityAssign; // !=0 if has identity opAssign
FuncDeclaration *cpctor; // generated copy-constructor, if any
FuncDeclarations postblits; // Array of postblit functions
FuncDeclaration *postblit; // aggregate postblit
#endif
StructDeclaration(Loc loc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *mangle();
char *kind();
const char *kind();
Expression *cloneMembers();
void toDocBuffer(OutBuffer *buf);
PROT getAccess(Dsymbol *smember); // determine access to smember
void toObjFile(); // compile to .obj file
void toObjFile(int multiobj); // compile to .obj file
void toDt(dt_t **pdt);
void toDebug(); // to symbolic debug info
@@ -142,7 +150,7 @@ struct UnionDeclaration : StructDeclaration
{
UnionDeclaration(Loc loc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *s);
char *kind();
const char *kind();
UnionDeclaration *isUnionDeclaration() { return this; }
};
@@ -168,7 +176,7 @@ struct BaseClass
void copyBaseInterfaces(BaseClasses *);
};
#if V2
#if DMDV2
#define CLASSINFO_SIZE (0x3C+16) // value of ClassInfo.size
#else
#define CLASSINFO_SIZE (0x3C+12) // value of ClassInfo.size
@@ -218,7 +226,7 @@ struct ClassDeclaration : AggregateDeclaration
virtual int isBaseOf(ClassDeclaration *cd, int *poffset);
Dsymbol *search(Loc, Identifier *ident, int flags);
#if V2
#if DMDV2
int isFuncHidden(FuncDeclaration *fd);
#endif
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
@@ -226,12 +234,12 @@ struct ClassDeclaration : AggregateDeclaration
int isNested();
int isCOMclass();
virtual int isCOMinterface();
#if V2
#if DMDV2
virtual int isCPPinterface();
#endif
int isAbstract();
virtual int vtblOffset();
char *kind();
const char *kind();
char *mangle();
void toDocBuffer(OutBuffer *buf);
@@ -240,7 +248,7 @@ struct ClassDeclaration : AggregateDeclaration
void addLocalClass(ClassDeclarations *);
// Back end
void toObjFile(); // compile to .obj file
void toObjFile(int multiobj); // compile to .obj file
void toDebug();
unsigned baseVtblOffset(BaseClass *bc);
Symbol *toSymbol();
@@ -258,7 +266,7 @@ struct ClassDeclaration : AggregateDeclaration
struct InterfaceDeclaration : ClassDeclaration
{
#if V2
#if DMDV2
int cpp; // !=0 if this is a C++ interface
#endif
InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
@@ -266,14 +274,14 @@ struct InterfaceDeclaration : ClassDeclaration
void semantic(Scope *sc);
int isBaseOf(ClassDeclaration *cd, int *poffset);
int isBaseOf(BaseClass *bc, int *poffset);
char *kind();
const char *kind();
int vtblOffset();
#if V2
#if DMDV2
int isCPPinterface();
#endif
virtual int isCOMinterface();
void toObjFile(); // compile to .obj file
void toObjFile(int multiobj); // compile to .obj file
Symbol *toSymbol();
InterfaceDeclaration *isInterfaceDeclaration() { return this; }

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -35,6 +35,7 @@
#include "../gen/logger.h"
extern void obj_includelib(char *name);
void obj_startaddress(Symbol *s);
/********************************* AttribDeclaration ****************************/
@@ -52,16 +53,13 @@ Array *AttribDeclaration::include(Scope *sc, ScopeDsymbol *sd)
int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
unsigned i;
int m = 0;
Array *d = include(sc, sd);
if (d)
{
for (i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = (Dsymbol *)d->data[i];
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
m |= s->addMember(sc, sd, m | memnum);
}
}
@@ -72,7 +70,7 @@ void AttribDeclaration::semantic(Scope *sc)
{
Array *d = include(sc, NULL);
//printf("\tAttribDeclaration::semantic '%s'\n",toChars());
//printf("\tAttribDeclaration::semantic '%s', d = %p\n",toChars(), d);
if (d)
{
for (unsigned i = 0; i < d->dim; i++)
@@ -86,15 +84,12 @@ void AttribDeclaration::semantic(Scope *sc)
void AttribDeclaration::semantic2(Scope *sc)
{
unsigned i;
Array *d = include(sc, NULL);
if (d)
{
for (i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = (Dsymbol *)d->data[i];
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
s->semantic2(sc);
}
}
@@ -102,15 +97,12 @@ void AttribDeclaration::semantic2(Scope *sc)
void AttribDeclaration::semantic3(Scope *sc)
{
unsigned i;
Array *d = include(sc, NULL);
if (d)
{
for (i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = (Dsymbol *)d->data[i];
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
s->semantic3(sc);
}
}
@@ -118,15 +110,12 @@ void AttribDeclaration::semantic3(Scope *sc)
void AttribDeclaration::inlineScan()
{
unsigned i;
Array *d = include(NULL, NULL);
if (d)
{
for (i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = (Dsymbol *)d->data[i];
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
//printf("AttribDeclaration::inlineScan %s\n", s->toChars());
s->inlineScan();
}
@@ -137,15 +126,12 @@ void AttribDeclaration::addComment(unsigned char *comment)
{
if (comment)
{
unsigned i;
Array *d = include(NULL, NULL);
if (d)
{
for (i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = (Dsymbol *)d->data[i];
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
//printf("AttribDeclaration::addComment %s\n", s->toChars());
s->addComment(comment);
}
@@ -163,50 +149,41 @@ void AttribDeclaration::emitComment(Scope *sc)
// if (sc->docbuf)
// return;
unsigned i;
Array *d = include(NULL, NULL);
if (d)
{
for (i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = (Dsymbol *)d->data[i];
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
//printf("AttribDeclaration::emitComment %s\n", s->toChars());
s->emitComment(sc);
}
}
}
void AttribDeclaration::toObjFile()
void AttribDeclaration::toObjFile(int multiobj)
{
unsigned i;
Array *d = include(NULL, NULL);
if (d)
{
for (i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = (Dsymbol *)d->data[i];
s->toObjFile();
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
s->toObjFile(multiobj);
}
}
}
int AttribDeclaration::cvMember(unsigned char *p)
{
unsigned i;
int nwritten = 0;
int n;
Array *d = include(NULL, NULL);
if (d)
{
for (i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = (Dsymbol *)d->data[i];
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
n = s->cvMember(p);
if (p)
p += n;
@@ -232,7 +209,7 @@ int AttribDeclaration::hasPointers()
return 0;
}
char *AttribDeclaration::kind()
const char *AttribDeclaration::kind()
{
return "attribute";
}
@@ -246,15 +223,12 @@ int AttribDeclaration::oneMember(Dsymbol **ps)
void AttribDeclaration::checkCtorConstInit()
{
unsigned i;
Array *d = include(NULL, NULL);
if (d)
{
for (i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = (Dsymbol *)d->data[i];
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
s->checkCtorConstInit();
}
}
@@ -264,15 +238,13 @@ void AttribDeclaration::checkCtorConstInit()
*/
void AttribDeclaration::addLocalClass(ClassDeclarations *aclasses)
{ unsigned i;
{
Array *d = include(NULL, NULL);
if (d)
{
for (i = 0; i < d->dim; i++)
{ Dsymbol *s;
s = (Dsymbol *)d->data[i];
for (unsigned i = 0; i < d->dim; i++)
{ Dsymbol *s = (Dsymbol *)d->data[i];
s->addLocalClass(aclasses);
}
}
@@ -723,7 +695,7 @@ void AnonDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring("}\n");
}
char *AnonDeclaration::kind()
const char *AnonDeclaration::kind()
{
return (char *)(isunion ? "anonymous union" : "anonymous struct");
}
@@ -1023,12 +995,12 @@ int PragmaDeclaration::oneMember(Dsymbol **ps)
return TRUE;
}
char *PragmaDeclaration::kind()
const char *PragmaDeclaration::kind()
{
return "pragma";
}
void PragmaDeclaration::toObjFile()
void PragmaDeclaration::toObjFile(int multiobj)
{
if (ident == Id::lib)
{
@@ -1044,7 +1016,7 @@ void PragmaDeclaration::toObjFile()
name[se->len] = 0;
obj_includelib(name);
}
AttribDeclaration::toObjFile();
AttribDeclaration::toObjFile(multiobj);
}
void PragmaDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
@@ -1214,6 +1186,7 @@ Dsymbol *StaticIfDeclaration::syntaxCopy(Dsymbol *s)
int StaticIfDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
//printf("StaticIfDeclaration::addMember() '%s'\n",toChars());
/* This is deferred until semantic(), so that
* expressions in the condition can refer to declarations
* in the same scope, such as:
@@ -1240,7 +1213,7 @@ void StaticIfDeclaration::semantic(Scope *sc)
{
Array *d = include(sc, sd);
//printf("\tStaticIfDeclaration::semantic '%s'\n",toChars());
//printf("\tStaticIfDeclaration::semantic '%s', d = %p\n",toChars(), d);
if (d)
{
if (!addisdone)
@@ -1257,7 +1230,7 @@ void StaticIfDeclaration::semantic(Scope *sc)
}
}
char *StaticIfDeclaration::kind()
const char *StaticIfDeclaration::kind()
{
return "static if";
}
@@ -1268,8 +1241,10 @@ char *StaticIfDeclaration::kind()
CompileDeclaration::CompileDeclaration(Loc loc, Expression *exp)
: AttribDeclaration(NULL)
{
this->loc = loc;
this->exp = exp;
this->sd = NULL;
this->compiled = 0;
}
Dsymbol *CompileDeclaration::syntaxCopy(Dsymbol *s)
@@ -1281,32 +1256,50 @@ Dsymbol *CompileDeclaration::syntaxCopy(Dsymbol *s)
int CompileDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
{
//printf("CompileDeclaration::addMember(sc = %p)\n", sc);
this->sd = sd;
if (memnum == 0)
{ /* No members yet, so parse the mixin now
*/
compileIt(sc);
memnum |= AttribDeclaration::addMember(sc, sd, memnum);
compiled = 1;
}
return memnum;
}
void CompileDeclaration::compileIt(Scope *sc)
{
//printf("CompileDeclaration::compileIt()\n");
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->optimize(WANTvalue | WANTinterpret);
if (exp->op != TOKstring)
{ exp->error("argument to mixin must be a string, not (%s)", exp->toChars());
}
else
{
StringExp *se = (StringExp *)exp;
se = se->toUTF8(sc);
Parser p(sc->module, (unsigned char *)se->string, se->len, 0);
p.loc = loc;
p.nextToken();
decl = p.parseDeclDefs(0);
if (p.token.value != TOKeof)
exp->error("incomplete mixin declaration (%s)", se->toChars());
}
}
void CompileDeclaration::semantic(Scope *sc)
{
//printf("CompileDeclaration::semantic()\n");
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->optimize(WANTvalue | WANTinterpret);
if (exp->op != TOKstring)
{ error("argument to mixin must be a string, not (%s)", exp->toChars());
return;
}
StringExp *se = (StringExp *)exp;
se = se->toUTF8(sc);
Parser p(sc->module, (unsigned char *)se->string, se->len, 0);
p.loc = loc;
p.nextToken();
decl = p.parseDeclDefs(0);
if (p.token.value != TOKeof)
{
error("incomplete mixin declaration (%s)", se->toChars());
}
AttribDeclaration::addMember(sc, sd, 0);
if (!compiled)
{
compileIt(sc);
AttribDeclaration::addMember(sc, sd, 0);
compiled = 1;
}
AttribDeclaration::semantic(sc);
}

View File

@@ -42,7 +42,7 @@ struct AttribDeclaration : Dsymbol
void inlineScan();
void addComment(unsigned char *comment);
void emitComment(Scope *sc);
char *kind();
const char *kind();
int oneMember(Dsymbol **ps);
int hasPointers();
void checkCtorConstInit();
@@ -50,7 +50,7 @@ struct AttribDeclaration : Dsymbol
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
AttribDeclaration *isAttribDeclaration() { return this; }
void toObjFile(); // compile to .obj file
void toObjFile(int multiobj); // compile to .obj file
int cvMember(unsigned char *p);
};
@@ -106,7 +106,7 @@ struct AnonDeclaration : AttribDeclaration
Dsymbol *syntaxCopy(Dsymbol *s);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *kind();
const char *kind();
};
struct PragmaDeclaration : AttribDeclaration
@@ -118,8 +118,8 @@ struct PragmaDeclaration : AttribDeclaration
void semantic(Scope *sc);
int oneMember(Dsymbol **ps);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *kind();
void toObjFile(); // compile to .obj file
const char *kind();
void toObjFile(int multiobj); // compile to .obj file
};
struct ConditionalDeclaration : AttribDeclaration
@@ -145,7 +145,7 @@ struct StaticIfDeclaration : ConditionalDeclaration
Dsymbol *syntaxCopy(Dsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void semantic(Scope *sc);
char *kind();
const char *kind();
};
// Mixin declarations
@@ -155,10 +155,12 @@ struct CompileDeclaration : AttribDeclaration
Expression *exp;
ScopeDsymbol *sd;
int compiled;
CompileDeclaration(Loc loc, Expression *exp);
Dsymbol *syntaxCopy(Dsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *sd, int memnum);
void compileIt(Scope *sc);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};

View File

@@ -1,5 +1,5 @@
// Copyright (c) 1999-2006 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -1345,31 +1345,52 @@ Expression *BinExp::typeCombine(Scope *sc)
goto Lt1;
}
else if (t1->ty == Tclass || t2->ty == Tclass)
{ int i1;
int i2;
i1 = e2->implicitConvTo(t1);
i2 = e1->implicitConvTo(t2);
if (i1 && i2)
{
while (1)
{
// We have the case of class vs. void*, so pick class
if (t1->ty == Tpointer)
i1 = 0;
else if (t2->ty == Tpointer)
i2 = 0;
}
int i1 = e2->implicitConvTo(t1);
int i2 = e1->implicitConvTo(t2);
if (i2)
{
goto Lt2;
if (i1 && i2)
{
// We have the case of class vs. void*, so pick class
if (t1->ty == Tpointer)
i1 = 0;
else if (t2->ty == Tpointer)
i2 = 0;
}
if (i2)
{
goto Lt2;
}
else if (i1)
{
goto Lt1;
}
else if (t1->ty == Tclass && t2->ty == Tclass)
{ TypeClass *tc1 = (TypeClass *)t1;
TypeClass *tc2 = (TypeClass *)t2;
/* Pick 'tightest' type
*/
ClassDeclaration *cd1 = tc1->sym->baseClass;
ClassDeclaration *cd2 = tc1->sym->baseClass;
if (cd1 && cd2)
{ t1 = cd1->type;
t2 = cd2->type;
}
else if (cd1)
t1 = cd1->type;
else if (cd2)
t2 = cd2->type;
else
goto Lincompatible;
}
else
goto Lincompatible;
}
else if (i1)
{
goto Lt1;
}
else
goto Lincompatible;
}
else if ((e1->op == TOKstring || e1->op == TOKnull) && e1->implicitConvTo(t2))
{

View File

@@ -147,7 +147,7 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
Type::typeinfotypelist = this;
}
#if V2
#if DMDV2
if (id == Id::TypeInfo_Const)
{ if (Type::typeinfoconst)
Type::typeinfoconst->error("%s", msg);
@@ -261,7 +261,7 @@ void ClassDeclaration::semantic(Scope *sc)
#endif
if (sc->stc & STCdeprecated)
{ //printf("test1: %s is deprecated\n", toChars());
{
isdeprecated = 1;
}
@@ -302,6 +302,7 @@ void ClassDeclaration::semantic(Scope *sc)
else
{
tc = (TypeClass *)(tb);
if (tc->sym->isDeprecated())
{
if (!isDeprecated())
@@ -565,7 +566,7 @@ void ClassDeclaration::semantic(Scope *sc)
scope->setNoFree();
scope->module->addDeferredSemantic(this);
//printf("\tsemantic('%s') failed\n", toChars());
//printf("\tsemantic('%s') failed due to forward references\n", toChars());
return;
}
@@ -599,7 +600,7 @@ void ClassDeclaration::semantic(Scope *sc)
if (!ctor && baseClass && baseClass->ctor)
{
//printf("Creating default this(){} for class %s\n", toChars());
ctor = new CtorDeclaration(0, 0, NULL, 0);
ctor = new CtorDeclaration(loc, 0, NULL, 0);
ctor->fbody = new CompoundStatement(0, new Statements());
members->push(ctor);
ctor->addMember(sc, this, 1);
@@ -796,7 +797,7 @@ Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags)
* Return 1 if function is hidden (not findable through search).
*/
#if V2
#if DMDV2
int isf(void *param, FuncDeclaration *fd)
{
//printf("param = %p, fd = %p %s\n", param, fd, fd->toChars());
@@ -857,12 +858,11 @@ FuncDeclaration *ClassDeclaration::findFunc(Identifier *ident, TypeFunction *tf)
}
void ClassDeclaration::interfaceSemantic(Scope *sc)
{ int i;
{
vtblInterfaces = new BaseClasses();
vtblInterfaces->reserve(interfaces_dim);
for (i = 0; i < interfaces_dim; i++)
for (size_t i = 0; i < interfaces_dim; i++)
{
BaseClass *b = interfaces[i];
@@ -911,6 +911,7 @@ int ClassDeclaration::isAbstract()
return FALSE;
}
/****************************************
* Returns !=0 if there's an extra member which is the 'this'
* pointer to the enclosing context (enclosing class or function)
@@ -936,7 +937,7 @@ int ClassDeclaration::vtblOffset()
/****************************************
*/
char *ClassDeclaration::kind()
const char *ClassDeclaration::kind()
{
return "class";
}
@@ -1234,7 +1235,7 @@ int InterfaceDeclaration::isCOMinterface()
/*******************************************
*/
char *InterfaceDeclaration::kind()
const char *InterfaceDeclaration::kind()
{
return "interface";
}

View File

@@ -28,7 +28,7 @@
* (can be NULL for members that don't need one)
*/
#if V2
#if DMDV2
Expression *StructDeclaration::cloneMembers()
{
Expression *e = NULL;
@@ -89,7 +89,7 @@ FuncDeclaration *AggregateDeclaration::buildDtor(Scope *sc)
//printf("StructDeclaration::buildDtor() %s\n", toChars());
Expression *e = NULL;
#if V2
#if DMDV2
for (size_t i = 0; i < fields.dim; i++)
{
Dsymbol *s = (Dsymbol *)fields.data[i];

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-2007 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -39,7 +39,7 @@ void Declaration::semantic(Scope *sc)
{
}
char *Declaration::kind()
const char *Declaration::kind()
{
return "declaration";
}
@@ -80,6 +80,76 @@ enum PROT Declaration::prot()
return protection;
}
/*************************************
* Check to see if declaration can be modified in this context (sc).
* Issue error if not.
*/
#if DMDV2
void Declaration::checkModify(Loc loc, Scope *sc, Type *t)
{
if (sc->incontract && isParameter())
error(loc, "cannot modify parameter '%s' in contract", toChars());
if (isCtorinit())
{ // It's only modifiable if inside the right constructor
Dsymbol *s = sc->func;
while (1)
{
FuncDeclaration *fd = NULL;
if (s)
fd = s->isFuncDeclaration();
if (fd &&
((fd->isCtorDeclaration() && storage_class & STCfield) ||
(fd->isStaticCtorDeclaration() && !(storage_class & STCfield))) &&
fd->toParent() == toParent()
)
{
VarDeclaration *v = isVarDeclaration();
assert(v);
v->ctorinit = 1;
//printf("setting ctorinit\n");
}
else
{
if (s)
{ s = s->toParent2();
continue;
}
else
{
const char *p = isStatic() ? "static " : "";
error(loc, "can only initialize %sconst %s inside %sconstructor",
p, toChars(), p);
}
}
break;
}
}
else
{
VarDeclaration *v = isVarDeclaration();
if (v && v->canassign == 0)
{
char *p = NULL;
if (isConst())
p = "const";
else if (isInvariant())
p = "invariant";
else if (storage_class & STCmanifest)
p = "manifest constant";
else if (!t->isAssignable())
p = "struct with immutable members";
if (p)
{ error(loc, "cannot modify %s", p);
halt();
}
}
}
}
#endif
/********************************* TupleDeclaration ****************************/
TupleDeclaration::TupleDeclaration(Loc loc, Identifier *id, Objects *objects)
@@ -97,7 +167,7 @@ Dsymbol *TupleDeclaration::syntaxCopy(Dsymbol *s)
return NULL;
}
char *TupleDeclaration::kind()
const char *TupleDeclaration::kind()
{
return "tuple";
}
@@ -231,6 +301,7 @@ void TypedefDeclaration::semantic(Scope *sc)
type = type->semantic(loc, sc);
if (sc->parent->isFuncDeclaration() && init)
semantic2(sc);
storage_class |= sc->stc & STCdeprecated;
}
else if (sem == 1)
{
@@ -257,7 +328,7 @@ void TypedefDeclaration::semantic2(Scope *sc)
}
}
char *TypedefDeclaration::kind()
const char *TypedefDeclaration::kind()
{
return "typedef";
}
@@ -318,6 +389,7 @@ AliasDeclaration::AliasDeclaration(Loc loc, Identifier *id, Dsymbol *s)
Dsymbol *AliasDeclaration::syntaxCopy(Dsymbol *s)
{
//printf("AliasDeclaration::syntaxCopy()\n");
assert(!s);
AliasDeclaration *sa;
if (type)
@@ -466,7 +538,7 @@ int AliasDeclaration::overloadInsert(Dsymbol *s)
}
}
char *AliasDeclaration::kind()
const char *AliasDeclaration::kind()
{
return "alias";
}
@@ -601,7 +673,9 @@ Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
void VarDeclaration::semantic(Scope *sc)
{
//printf("VarDeclaration::semantic('%s', parent = '%s')\n", toChars(), sc->parent->toChars());
//printf("type = %s\n", type->toChars());
//printf(" type = %s\n", type ? type->toChars() : "null");
//printf(" stc = x%x\n", sc->stc);
//printf(" storage_class = x%x\n", storage_class);
//printf("linkage = %d\n", sc->linkage);
//if (strcmp(toChars(), "mul") == 0) halt();
@@ -629,6 +703,7 @@ void VarDeclaration::semantic(Scope *sc)
originalType = type;
type = type->semantic(loc, sc);
}
//printf(" semantic type = %s\n", type ? type->toChars() : "null");
type->checkDeprecated(loc, sc);
linkage = sc->linkage;
@@ -636,7 +711,7 @@ void VarDeclaration::semantic(Scope *sc)
//printf("this = %p, parent = %p, '%s'\n", this, parent, parent->toChars());
protection = sc->protection;
//printf("sc->stc = %x\n", sc->stc);
//printf("storage_class = %x\n", storage_class);
//printf("storage_class = x%x\n", storage_class);
Dsymbol *parent = toParent();
FuncDeclaration *fd = parent->isFuncDeclaration();
@@ -749,6 +824,8 @@ void VarDeclaration::semantic(Scope *sc)
error("field not allowed in interface");
}
/* Templates cannot add fields to aggregates
*/
TemplateInstance *ti = parent->isTemplateInstance();
if (ti)
{
@@ -853,10 +930,6 @@ void VarDeclaration::semantic(Scope *sc)
// possibilities.
if (fd && !isStatic() && !isConst() && !init->isVoidInitializer())
{
Expression *e1;
Type *t;
int dim;
//printf("fd = '%s', var = '%s'\n", fd->toChars(), toChars());
if (!ei)
{
@@ -874,15 +947,15 @@ void VarDeclaration::semantic(Scope *sc)
init = ei;
}
e1 = new VarExp(loc, this);
Expression *e1 = new VarExp(loc, this);
t = type->toBasetype();
Type *t = type->toBasetype();
if (t->ty == Tsarray)
{
ei->exp = ei->exp->semantic(sc);
if (!ei->exp->implicitConvTo(type))
{
dim = ((TypeSArray *)t)->dim->toInteger();
int dim = ((TypeSArray *)t)->dim->toInteger();
// If multidimensional static array, treat as one large array
while (1)
{
@@ -974,7 +1047,7 @@ ExpInitializer *VarDeclaration::getExpInitializer()
ei = init->isExpInitializer();
else
{
Expression *e = type->defaultInit();
Expression *e = type->defaultInit(loc);
if (e)
ei = new ExpInitializer(loc, e);
else
@@ -1001,7 +1074,7 @@ void VarDeclaration::semantic2(Scope *sc)
}
}
char *VarDeclaration::kind()
const char *VarDeclaration::kind()
{
return "variable";
}
@@ -1020,6 +1093,17 @@ void VarDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring("const ");
if (storage_class & STCstatic)
buf->writestring("static ");
if (storage_class & STCauto)
buf->writestring("auto ");
#if DMDV2
if (storage_class & STCmanifest)
buf->writestring("manifest ");
if (storage_class & STCinvariant)
buf->writestring("invariant ");
if (storage_class & STCtls)
buf->writestring("__thread ");
#endif
if (type)
type->toCBuffer(buf, ident, hgs);
else
@@ -1052,15 +1136,18 @@ void VarDeclaration::checkCtorConstInit()
}
/************************************
* Check to see if variable is a reference to an enclosing function
* or not.
* Check to see if this variable is actually in an enclosing function
* rather than the current one.
*/
void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
{
//printf("VarDeclaration::checkNestedReference() %s\n", toChars());
if (parent && !isDataseg() && parent != sc->parent)
{
// The function that this variable is in
FuncDeclaration *fdv = toParent()->isFuncDeclaration();
// The current function
FuncDeclaration *fdthis = sc->parent->isFuncDeclaration();
if (fdv && fdthis)
@@ -1077,6 +1164,7 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
/*******************************
* Does symbol go into data segment?
* Includes extern variables.
*/
int VarDeclaration::isDataseg()
@@ -1201,7 +1289,7 @@ void TypeInfoDeclaration::semantic(Scope *sc)
/***************************** TypeInfoConstDeclaration **********************/
#if V2
#if DMDV2
TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
: TypeInfoDeclaration(tinfo, 0)
{
@@ -1210,7 +1298,7 @@ TypeInfoConstDeclaration::TypeInfoConstDeclaration(Type *tinfo)
/***************************** TypeInfoInvariantDeclaration **********************/
#if V2
#if DMDV2
TypeInfoInvariantDeclaration::TypeInfoInvariantDeclaration(Type *tinfo)
: TypeInfoDeclaration(tinfo, 0)
{

View File

@@ -73,6 +73,7 @@ enum STC
STCnothrow = 0x2000000, // never throws exceptions
STCpure = 0x4000000, // pure function
STCtls = 0x8000000, // thread local
STCalias = 0x10000000, // alias parameter
};
struct Match
@@ -101,7 +102,7 @@ struct Declaration : Dsymbol
Declaration(Identifier *id);
void semantic(Scope *sc);
char *kind();
const char *kind();
unsigned size(Loc loc);
void checkModify(Loc loc, Scope *sc, Type *t);
@@ -150,7 +151,7 @@ struct TupleDeclaration : Declaration
TupleDeclaration(Loc loc, Identifier *ident, Objects *objects);
Dsymbol *syntaxCopy(Dsymbol *);
char *kind();
const char *kind();
Type *getType();
int needThis();
@@ -174,7 +175,7 @@ struct TypedefDeclaration : Declaration
void semantic(Scope *sc);
void semantic2(Scope *sc);
char *mangle();
char *kind();
const char *kind();
Type *getType();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#ifdef _DH
@@ -184,7 +185,7 @@ struct TypedefDeclaration : Declaration
void toDocBuffer(OutBuffer *buf);
void toObjFile(); // compile to .obj file
void toObjFile(int multiobj); // compile to .obj file
void toDebug();
int cvMember(unsigned char *p);
@@ -207,7 +208,7 @@ struct AliasDeclaration : Declaration
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
int overloadInsert(Dsymbol *s);
char *kind();
const char *kind();
Type *getType();
Dsymbol *toAlias();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -242,7 +243,7 @@ struct VarDeclaration : Declaration
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
void semantic2(Scope *sc);
char *kind();
const char *kind();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
#ifdef _DH
Type *htype;
@@ -259,7 +260,7 @@ struct VarDeclaration : Declaration
Dsymbol *toAlias();
Symbol *toSymbol();
void toObjFile(); // compile to .obj file
void toObjFile(int multiobj); // compile to .obj file
int cvMember(unsigned char *p);
// Eliminate need for dynamic_cast
@@ -325,7 +326,7 @@ struct TypeInfoDeclaration : VarDeclaration
void emitComment(Scope *sc);
Symbol *toSymbol();
void toObjFile(); // compile to .obj file
void toObjFile(int multiobj); // compile to .obj file
virtual void toDt(dt_t **pdt);
virtual TypeInfoDeclaration* isTypeInfoDeclaration() { return this; }
@@ -467,6 +468,32 @@ struct TypeInfoTupleDeclaration : TypeInfoDeclaration
void llvmDefine();
};
#if DMDV2
struct TypeInfoConstDeclaration : TypeInfoDeclaration
{
TypeInfoConstDeclaration(Type *tinfo);
void toDt(dt_t **pdt);
// LLVMDC
void llvmDeclare();
void llvmDefine();
};
struct TypeInfoInvariantDeclaration : TypeInfoDeclaration
{
TypeInfoInvariantDeclaration(Type *tinfo);
void toDt(dt_t **pdt);
// LLVMDC
void llvmDeclare();
void llvmDefine();
};
#endif
/**************************************************************/
struct ThisDeclaration : VarDeclaration
{
ThisDeclaration(Type *t);
@@ -481,8 +508,7 @@ enum ILS
};
/**************************************************************/
#if V2
#if DMDV2
enum BUILTIN
{
@@ -548,7 +574,7 @@ struct FuncDeclaration : Declaration
VarDeclaration *nrvo_var; // variable to replace with shidden
Symbol *shidden; // hidden pointer passed to function
#if V2
#if DMDV2
enum BUILTIN builtin; // set if this is a known, builtin
// function we can evaluate at compile
// time
@@ -597,7 +623,7 @@ struct FuncDeclaration : Declaration
void inlineScan();
int canInline(int hasthis, int hdrscan = 0);
Expression *doInline(InlineScanState *iss, Expression *ethis, Array *arguments);
char *kind();
const char *kind();
void toDocBuffer(OutBuffer *buf);
static FuncDeclaration *genCfunc(Type *treturn, char *name);
@@ -605,7 +631,7 @@ struct FuncDeclaration : Declaration
Symbol *toSymbol();
Symbol *toThunkSymbol(int offset); // thunk version
void toObjFile(); // compile to .obj file
void toObjFile(int multiobj); // compile to .obj file
int cvMember(unsigned char *p);
FuncDeclaration *isFuncDeclaration() { return this; }
@@ -627,7 +653,7 @@ struct FuncAliasDeclaration : FuncDeclaration
FuncAliasDeclaration(FuncDeclaration *funcalias);
FuncAliasDeclaration *isFuncAliasDeclaration() { return this; }
char *kind();
const char *kind();
Symbol *toSymbol();
};
@@ -640,9 +666,10 @@ struct FuncLiteralDeclaration : FuncDeclaration
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Dsymbol *syntaxCopy(Dsymbol *);
int isNested();
int isVirtual();
FuncLiteralDeclaration *isFuncLiteralDeclaration() { return this; }
char *kind();
const char *kind();
};
struct CtorDeclaration : FuncDeclaration
@@ -653,7 +680,7 @@ struct CtorDeclaration : FuncDeclaration
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *kind();
const char *kind();
char *toChars();
int isVirtual();
int addPreInvariant();
@@ -663,6 +690,24 @@ struct CtorDeclaration : FuncDeclaration
CtorDeclaration *isCtorDeclaration() { return this; }
};
#if DMDV2
struct PostBlitDeclaration : FuncDeclaration
{
PostBlitDeclaration(Loc loc, Loc endloc);
PostBlitDeclaration(Loc loc, Loc endloc, Identifier *id);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
int isVirtual();
int addPreInvariant();
int addPostInvariant();
int overloadInsert(Dsymbol *s);
void emitComment(Scope *sc);
PostBlitDeclaration *isPostBlitDeclaration() { return this; }
};
#endif
struct DtorDeclaration : FuncDeclaration
{
DtorDeclaration(Loc loc, Loc endloc);
@@ -696,7 +741,8 @@ struct StaticCtorDeclaration : FuncDeclaration
};
struct StaticDtorDeclaration : FuncDeclaration
{
{ VarDeclaration *vgate; // 'gate' variable
StaticDtorDeclaration(Loc loc, Loc endloc);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
@@ -748,7 +794,7 @@ struct NewDeclaration : FuncDeclaration
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *kind();
const char *kind();
int isVirtual();
int addPreInvariant();
int addPostInvariant();
@@ -764,7 +810,7 @@ struct DeleteDeclaration : FuncDeclaration
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *kind();
const char *kind();
int isDelete();
int isVirtual();
int addPreInvariant();

View File

@@ -400,7 +400,7 @@ void Dsymbol::emitDitto(Scope *sc)
void ScopeDsymbol::emitMemberComments(Scope *sc)
{
//printf("ScopeDsymbol::emitMemberComments()\n");
//printf("ScopeDsymbol::emitMemberComments() %s\n", toChars());
OutBuffer *buf = sc->docbuf;
if (members)
@@ -417,8 +417,9 @@ void ScopeDsymbol::emitMemberComments(Scope *sc)
else if (isTemplateDeclaration())
m = "$(DDOC_TEMPLATE_MEMBERS \n";
// BUG: if no members are actually printed, we should not emit DDOC_MEMBERS
unsigned offset1 = buf->offset; // save starting offset
buf->writestring(m);
unsigned offset2 = buf->offset; // to see if we write anything
sc = sc->push(this);
for (int i = 0; i < members->dim; i++)
{
@@ -427,7 +428,14 @@ void ScopeDsymbol::emitMemberComments(Scope *sc)
s->emitComment(sc);
}
sc->pop();
buf->writestring(")\n");
if (buf->offset == offset2)
{
/* Didn't write out any members, so back out last write
*/
buf->offset = offset1;
}
else
buf->writestring(")\n");
}
}
@@ -448,7 +456,9 @@ void emitProtection(OutBuffer *buf, PROT prot)
void Dsymbol::emitComment(Scope *sc) { }
void InvariantDeclaration::emitComment(Scope *sc) { }
//void PostBlitDeclaration::emitComment(Scope *sc) { }
#if DMDV2
void PostBlitDeclaration::emitComment(Scope *sc) { }
#endif
void DtorDeclaration::emitComment(Scope *sc) { }
void StaticCtorDeclaration::emitComment(Scope *sc) { }
void StaticDtorDeclaration::emitComment(Scope *sc) { }
@@ -525,12 +535,8 @@ void TemplateDeclaration::emitComment(Scope *sc)
//printf("TemplateDeclaration::emitComment() '%s', kind = %s\n", toChars(), kind());
if (prot() == PROTprivate)
return;
if (!comment)
return;
OutBuffer *buf = sc->docbuf;
DocComment *dc = DocComment::parse(sc, this, comment);
unsigned o;
unsigned char *com = comment;
int hasmembers = 1;
Dsymbol *ss = this;
@@ -542,12 +548,22 @@ void TemplateDeclaration::emitComment(Scope *sc)
{
ss = onemember->isFuncDeclaration();
if (ss)
hasmembers = 0;
{ hasmembers = 0;
if (com != ss->comment)
com = Lexer::combineComments(com, ss->comment);
}
else
ss = this;
}
}
if (!com)
return;
OutBuffer *buf = sc->docbuf;
DocComment *dc = DocComment::parse(sc, this, com);
unsigned o;
if (!dc)
{
ss->emitDitto(sc);
@@ -667,7 +683,7 @@ void prefix(OutBuffer *buf, Dsymbol *s)
buf->writestring("static ");
if (d->isConst())
buf->writestring("const ");
#if V2
#if DMDV2
if (d->isInvariant())
buf->writestring("invariant ");
#endif
@@ -743,7 +759,9 @@ void FuncDeclaration::toDocBuffer(OutBuffer *buf)
if (parent &&
(td = parent->isTemplateDeclaration()) != NULL &&
td->onemember == this)
{ HdrGenState hgs;
{ /* It's a function template
*/
HdrGenState hgs;
unsigned o = buf->offset;
TypeFunction *tf = (TypeFunction *)type;
@@ -1581,7 +1599,13 @@ Argument *isFunctionParameter(Dsymbol *s, unsigned char *p, unsigned len)
*/
if (f && f->type)
{
TypeFunction *tf = (TypeFunction *)f->type;
TypeFunction *tf;
if (f->originalType)
{
tf = (TypeFunction *)f->originalType;
}
else
tf = (TypeFunction *)f->type;
if (tf->parameters)
{

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -201,7 +201,7 @@ char *Dsymbol::locToChars()
return loc.toChars();
}
char *Dsymbol::kind()
const char *Dsymbol::kind()
{
return "symbol";
}
@@ -244,6 +244,16 @@ Dsymbol *Dsymbol::toParent2()
return s;
}
TemplateInstance *Dsymbol::inTemplateInstance()
{
for (Dsymbol *parent = this->parent; parent; parent = parent->parent)
{
TemplateInstance *ti = parent->isTemplateInstance();
if (ti)
return ti;
}
return NULL;
}
int Dsymbol::isAnonymous()
{
@@ -270,6 +280,16 @@ void Dsymbol::inlineScan()
// Most Dsymbols have no further semantic analysis needed
}
/*********************************************
* Search for ident as member of s.
* Input:
* flags: 1 don't find private members
* 2 don't give error messages
* 4 return NULL if ambiguous
* Returns:
* NULL if not found
*/
Dsymbol *Dsymbol::search(Loc loc, Identifier *ident, int flags)
{
//printf("Dsymbol::search(this=%p,%s, ident='%s')\n", this, toChars(), ident->toChars());
@@ -389,7 +409,9 @@ LabelDsymbol *Dsymbol::isLabel() // is this a LabelDsymbol()?
AggregateDeclaration *Dsymbol::isMember() // is this a member of an AggregateDeclaration?
{
//printf("Dsymbol::isMember() %s\n", toChars());
Dsymbol *parent = toParent();
//printf("parent is %s %s\n", parent->kind(), parent->toChars());
return parent ? parent->isAggregateDeclaration() : NULL;
}
@@ -502,6 +524,10 @@ void Dsymbol::checkDeprecated(Loc loc, Scope *sc)
{
if (sc->scopesym && sc->scopesym->isDeprecated())
return;
// If inside a StorageClassDeclaration that is deprecated
if (sc->stc & STCdeprecated)
return;
}
error(loc, "is deprecated");
@@ -617,12 +643,11 @@ Dsymbol *ScopeDsymbol::syntaxCopy(Dsymbol *s)
}
Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
{ Dsymbol *s;
int i;
{
//printf("%s->ScopeDsymbol::search(ident='%s', flags=x%x)\n", toChars(), ident->toChars(), flags);
// Look in symbols declared in this module
s = symtab ? symtab->lookup(ident) : NULL;
Dsymbol *s = symtab ? symtab->lookup(ident) : NULL;
if (s)
{
//printf("\ts = '%s.%s'\n",toChars(),s->toChars());
@@ -630,7 +655,7 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
else if (imports)
{
// Look in imported modules
for (i = 0; i < imports->dim; i++)
for (int i = 0; i < imports->dim; i++)
{ ScopeDsymbol *ss = (ScopeDsymbol *)imports->data[i];
Dsymbol *s2;
@@ -639,6 +664,8 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
continue;
//printf("\tscanning import '%s', prots = %d, isModule = %p, isImport = %p\n", ss->toChars(), prots[i], ss->isModule(), ss->isImport());
/* Don't find private members if ss is a module
*/
s2 = ss->search(loc, ident, ss->isModule() ? 1 : 0);
if (!s)
s = s2;
@@ -646,6 +673,10 @@ Dsymbol *ScopeDsymbol::search(Loc loc, Identifier *ident, int flags)
{
if (s->toAlias() == s2->toAlias())
{
/* After following aliases, we found the same symbol,
* so it's not an ambiguity.
* But if one alias is deprecated, prefer the other.
*/
if (s->isDeprecated())
s = s2;
}
@@ -768,7 +799,7 @@ Dsymbol *ScopeDsymbol::nameCollision(Dsymbol *s)
return sprev;
}
char *ScopeDsymbol::kind()
const char *ScopeDsymbol::kind()
{
return "ScopeDsymbol";
}
@@ -780,7 +811,7 @@ char *ScopeDsymbol::kind()
* Returns NULL if not found
*/
#if V2
#if DMDV2
FuncDeclaration *ScopeDsymbol::findGetMembers()
{
Dsymbol *s = search_function(this, Id::getmembers);

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -123,12 +123,13 @@ struct Dsymbol : Object
Dsymbol *pastMixin();
Dsymbol *toParent();
Dsymbol *toParent2();
TemplateInstance *inTemplateInstance();
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
static Array *arraySyntaxCopy(Array *a);
virtual char *kind();
virtual const char *kind();
virtual Dsymbol *toAlias(); // resolve real symbol
virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
virtual void semantic(Scope *sc);
@@ -150,7 +151,7 @@ struct Dsymbol : Object
virtual AggregateDeclaration *isThis(); // is a 'this' required to access the member
virtual ClassDeclaration *isClassMember(); // are we a member of a class?
virtual int isExport(); // is Dsymbol exported?
virtual int isImportedSymbol(); // is Dsymbol imported?
virtual int isImportedSymbol(); // is Dsymbol imported?
virtual int isDeprecated(); // is Dsymbol deprecated?
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
@@ -172,7 +173,7 @@ struct Dsymbol : Object
// Backend
virtual Symbol *toSymbol(); // to backend symbol
virtual void toObjFile(); // compile to .obj file
virtual void toObjFile(int multiobj); // compile to .obj file
virtual int cvMember(unsigned char *p); // emit cv debug info for member
Symbol *toImport(); // to backend import symbol
@@ -247,7 +248,7 @@ struct ScopeDsymbol : Dsymbol
void defineRef(Dsymbol *s);
static void multiplyDefined(Loc loc, Dsymbol *s1, Dsymbol *s2);
Dsymbol *nameCollision(Dsymbol *s);
char *kind();
const char *kind();
void emitMemberComments(Scope *sc);

View File

@@ -1,5 +1,5 @@
// Copyright (c) 1999-2006 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -14,6 +14,7 @@
#include "enum.h"
#include "mtype.h"
#include "scope.h"
#include "declaration.h"
/********************************* EnumDeclaration ****************************/
@@ -27,6 +28,7 @@ EnumDeclaration::EnumDeclaration(Loc loc, Identifier *id, Type *memtype)
minval = 0;
defaultval = 0;
sinit = NULL;
isdeprecated = 0;
}
Dsymbol *EnumDeclaration::syntaxCopy(Dsymbol *s)
@@ -57,6 +59,9 @@ void EnumDeclaration::semantic(Scope *sc)
return;
if (!memtype)
memtype = Type::tint32;
if (sc->stc & STCdeprecated)
isdeprecated = 1;
parent = sc->scopesym;
memtype = memtype->semantic(loc, sc);
@@ -265,11 +270,16 @@ Type *EnumDeclaration::getType()
return type;
}
char *EnumDeclaration::kind()
const char *EnumDeclaration::kind()
{
return "enum";
}
int EnumDeclaration::isDeprecated()
{
return isdeprecated;
}
/********************************* EnumMember ****************************/
EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value)
@@ -306,7 +316,7 @@ void EnumMember::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
}
}
char *EnumMember::kind()
const char *EnumMember::kind()
{
return "enum member";
}

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -30,9 +30,19 @@ struct EnumDeclaration : ScopeDsymbol
{
Type *type; // the TypeEnum
Type *memtype; // type of the members
#if DMDV1
integer_t maxval;
integer_t minval;
integer_t defaultval; // default initializer
#else
Expression *maxval;
Expression *minval;
Expression *defaultval; // default initializer
Scope *scope; // !=NULL means context to use
#endif
int isdeprecated;
EnumDeclaration(Loc loc, Identifier *id, Type *memtype);
Dsymbol *syntaxCopy(Dsymbol *s);
@@ -40,14 +50,18 @@ struct EnumDeclaration : ScopeDsymbol
int oneMember(Dsymbol **ps);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Type *getType();
char *kind();
const char *kind();
#if DMDV2
Dsymbol *search(Loc, Identifier *ident, int flags);
#endif
int isDeprecated(); // is Dsymbol deprecated?
void emitComment(Scope *sc);
void toDocBuffer(OutBuffer *buf);
EnumDeclaration *isEnumDeclaration() { return this; }
void toObjFile(); // compile to .obj file
void toObjFile(int multiobj); // compile to .obj file
void toDebug();
int cvMember(unsigned char *p);
@@ -63,7 +77,7 @@ struct EnumMember : Dsymbol
EnumMember(Loc loc, Identifier *id, Expression *value);
Dsymbol *syntaxCopy(Dsymbol *s);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *kind();
const char *kind();
void emitComment(Scope *sc);
void toDocBuffer(OutBuffer *buf);

View File

@@ -111,6 +111,9 @@ void initPrecedence()
precedence[TOKassert] = PREC_primary;
precedence[TOKfunction] = PREC_primary;
precedence[TOKvar] = PREC_primary;
#if DMDV2
precedence[TOKdefault] = PREC_primary;
#endif
// post
precedence[TOKdotti] = PREC_primary;
@@ -195,6 +198,89 @@ void initPrecedence()
precedence[TOKcomma] = PREC_expr;
}
/*************************************************************
* Given var, we need to get the
* right 'this' pointer if var is in an outer class, but our
* existing 'this' pointer is in an inner class.
* Input:
* e1 existing 'this'
* ad struct or class we need the correct 'this' for
* var the specific member of ad we're accessing
*/
Expression *getRightThis(Loc loc, Scope *sc, AggregateDeclaration *ad,
Expression *e1, Declaration *var)
{
//printf("\ngetRightThis(e1 = %s, ad = %s, var = %s)\n", e1->toChars(), ad->toChars(), var->toChars());
L1:
Type *t = e1->type->toBasetype();
//printf("e1->type = %s, var->type = %s\n", e1->type->toChars(), var->type->toChars());
/* If e1 is not the 'this' pointer for ad
*/
if (ad &&
!(t->ty == Tpointer && t->nextOf()->ty == Tstruct &&
((TypeStruct *)t->nextOf())->sym == ad)
&&
!(t->ty == Tstruct &&
((TypeStruct *)t)->sym == ad)
)
{
ClassDeclaration *cd = ad->isClassDeclaration();
ClassDeclaration *tcd = t->isClassHandle();
/* e1 is the right this if ad is a base class of e1
*/
if (!cd || !tcd ||
!(tcd == cd || cd->isBaseOf(tcd, NULL))
)
{
/* Only classes can be inner classes with an 'outer'
* member pointing to the enclosing class instance
*/
if (tcd && tcd->isNested())
{ /* e1 is the 'this' pointer for an inner class: tcd.
* Rewrite it as the 'this' pointer for the outer class.
*/
e1 = new DotVarExp(loc, e1, tcd->vthis);
e1->type = tcd->vthis->type;
// Do not call checkNestedRef()
//e1 = e1->semantic(sc);
// Skip up over nested functions, and get the enclosing
// class type.
int n = 0;
Dsymbol *s;
for (s = tcd->toParent();
s && s->isFuncDeclaration();
s = s->toParent())
{ FuncDeclaration *f = s->isFuncDeclaration();
if (f->vthis)
{
//printf("rewriting e1 to %s's this\n", f->toChars());
n++;
e1 = new VarExp(loc, f->vthis);
}
}
if (s && s->isClassDeclaration())
{ e1->type = s->isClassDeclaration()->type;
if (n > 1)
e1 = e1->semantic(sc);
}
else
e1 = e1->semantic(sc);
goto L1;
}
/* Can't find a path from e1 to ad
*/
e1->error("this for %s needs to be type %s not type %s",
var->toChars(), ad->toChars(), t->toChars());
}
}
return e1;
}
/*****************************************
* Determine if 'this' is available.
* If it is, return the FuncDeclaration that has it.
@@ -383,6 +469,32 @@ void preFunctionArguments(Loc loc, Scope *sc, Expressions *exps)
}
}
/*********************************************
* Call copy constructor for struct value argument.
*/
#if DMDV2
Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
{
Type *tb = e->type->toBasetype();
assert(tb->ty == Tstruct);
StructDeclaration *sd = ((TypeStruct *)tb)->sym;
if (sd->cpctor)
{
/* Create a variable tmp, and replace the argument e with:
* (tmp = e),tmp
* and let AssignExp() handle the construction.
* This is not the most efficent, ideally tmp would be constructed
* directly onto the stack.
*/
Identifier *idtmp = Lexer::uniqueId("__tmp");
VarDeclaration *tmp = new VarDeclaration(loc, tb, idtmp, new ExpInitializer(0, e));
Expression *ae = new DeclarationExp(loc, tmp);
e = new CommaExp(loc, ae, new VarExp(loc, tmp));
e = e->semantic(sc);
}
return e;
}
#endif
/****************************************
* Now that we know the exact type of the function we're calling,
@@ -432,7 +544,15 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
error(loc, "expected %"PRIuSIZE" arguments, not %"PRIuSIZE, nparams, nargs);
break;
}
arg = p->defaultArg->copy();
arg = p->defaultArg;
#if DMDV2
if (arg->op == TOKdefault)
{ DefaultInitExp *de = (DefaultInitExp *)arg;
arg = de->resolve(loc, sc);
}
else
#endif
arg = arg->copy();
arguments->push(arg);
nargs++;
}
@@ -572,7 +692,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
tb = arg->type->toBasetype();
if (tb->ty == Tsarray)
{ TypeSArray *ts = (TypeSArray *)tb;
Type *ta = tb->next->arrayOf();
Type *ta = ts->next->arrayOf();
if (ts->size(arg->loc) == 0)
{ arg = new NullExp(arg->loc);
arg->type = ta;
@@ -580,7 +700,19 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
else
arg = arg->castTo(sc, ta);
}
#if DMDV2
if (tb->ty == Tstruct)
{
arg = callCpCtor(loc, sc, arg);
}
// Give error for overloaded function addresses
if (arg->op == TOKsymoff)
{ SymOffExp *se = (SymOffExp *)arg;
if (se->hasOverloads && !se->var->isFuncDeclaration()->isUnique())
arg->error("function %s is overloaded", arg->toChars());
}
#endif
arg->rvalue();
}
arg = arg->optimize(WANTvalue);
@@ -609,6 +741,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr)
{
//if (precedence[e->op] == 0) e->dump(0);
if (precedence[e->op] < pr)
{
buf->writeByte('(');
@@ -706,7 +839,7 @@ Expression *Expression::copy()
Expression *Expression::semantic(Scope *sc)
{
#if LOGSEMANTIC
printf("Expression::semantic()\n");
printf("Expression::semantic() %s\n", toChars());
#endif
if (type)
type = type->semantic(loc, sc);
@@ -747,6 +880,7 @@ void Expression::rvalue()
dump(0);
halt();
#endif
type = Type::tint32;
}
}
@@ -939,7 +1073,7 @@ Expression *Expression::checkToPointer()
e = new NullExp(loc);
else
e = new AddrExp(loc, this);
e->type = tb->next->pointerTo();
e->type = ts->next->pointerTo();
}
return e;
}
@@ -970,7 +1104,7 @@ Expression *Expression::deref()
{ Expression *e;
e = new PtrExp(loc, this);
e->type = type->next;
e->type = ((TypeReference *)type)->next;
return e;
}
return this;
@@ -994,6 +1128,18 @@ int Expression::isBit()
return FALSE;
}
/********************************
* Can this expression throw an exception?
* Valid only after semantic() pass.
*/
int Expression::canThrow()
{
return TRUE;
}
Expressions *Expression::arraySyntaxCopy(Expressions *exps)
{ Expressions *a = NULL;
@@ -1019,6 +1165,7 @@ IntegerExp::IntegerExp(Loc loc, integer_t value, Type *type)
//printf("IntegerExp(value = %lld, type = '%s')\n", value, type ? type->toChars() : "");
if (type && !type->isscalar())
{
//printf("%s, loc = %d\n", toChars(), loc.linnum);
error("integral constant must be scalar type, not %s", type->toChars());
type = Type::terror;
}
@@ -1093,9 +1240,13 @@ integer_t IntegerExp::toInteger()
}
default:
print();
type->print();
assert(0);
/* This can happen if errors, such as
* the type is painted on like in fromConstInitializer().
*/
if (!global.errors)
{ type->print();
assert(0);
}
break;
}
break;
@@ -1246,10 +1397,17 @@ void IntegerExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
goto L3;
default:
/* This can happen if errors, such as
* the type is painted on like in fromConstInitializer().
*/
if (!global.errors)
{
#ifdef DEBUG
t->print();
t->print();
#endif
assert(0);
assert(0);
}
break;
}
}
else if (v & 0x8000000000000000LL)
@@ -1993,7 +2151,8 @@ Expression *ThisExp::semantic(Scope *sc)
fd->nestedFrameRef = 1;
}
#endif
sc->callSuper |= CSXthis;
if (!sc->intypeof)
sc->callSuper |= CSXthis;
return this;
Lerr:
@@ -2102,7 +2261,8 @@ Expression *SuperExp::semantic(Scope *sc)
}
#endif
sc->callSuper |= CSXsuper;
if (!sc->intypeof)
sc->callSuper |= CSXsuper;
return this;
@@ -3396,6 +3556,7 @@ Expression *NewAnonClassExp::semantic(Scope *sc)
{
#if LOGSEMANTIC
printf("NewAnonClassExp::semantic() %s\n", toChars());
//printf("thisexp = %p\n", thisexp);
//printf("type: %s\n", type->toChars());
#endif
@@ -3982,6 +4143,8 @@ Expression *TypeidExp::semantic(Scope *sc)
#endif
typeidType = typeidType->semantic(loc, sc);
e = typeidType->getTypeInfo(sc);
if (e->loc.linnum == 0)
e->loc = loc; // so there's at least some line number info
return e;
}
@@ -4258,7 +4421,7 @@ void IsExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring(" == ");
tspec->toCBuffer(buf, NULL, hgs);
}
#if V2
#if DMDV2
if (parameters)
{ // First parameter is already output, so start with second
for (int i = 1; i < parameters->dim; i++)
@@ -4830,6 +4993,16 @@ Expression *DotIdExp::semantic(Scope *sc)
return new TypeExp(loc, t);
}
TupleDeclaration *tup = s->isTupleDeclaration();
if (tup)
{
if (eleft)
error("cannot have e.tuple");
e = new TupleExp(loc, tup);
e = e->semantic(sc);
return e;
}
ScopeDsymbol *sds = s->isScopeDsymbol();
if (sds)
{
@@ -4973,55 +5146,19 @@ Expression *DotVarExp::semantic(Scope *sc)
if (!var->isFuncDeclaration()) // for functions, do checks after overload resolution
{
AggregateDeclaration *ad = var->toParent()->isAggregateDeclaration();
L1:
Type *t = e1->type->toBasetype();
e1 = getRightThis(loc, sc, ad, e1, var);
if (!sc->noaccesscheck)
accessCheck(loc, sc, e1, var);
if (ad &&
!(t->ty == Tpointer && t->next->ty == Tstruct &&
((TypeStruct *)t->next)->sym == ad)
&&
!(t->ty == Tstruct &&
((TypeStruct *)t)->sym == ad)
)
{
ClassDeclaration *cd = ad->isClassDeclaration();
ClassDeclaration *tcd = t->isClassHandle();
if (!cd || !tcd ||
!(tcd == cd || cd->isBaseOf(tcd, NULL))
)
{
if (tcd && tcd->isNested())
{ // Try again with outer scope
e1 = new DotVarExp(loc, e1, tcd->vthis);
e1 = e1->semantic(sc);
// Skip over nested functions, and get the enclosing
// class type.
Dsymbol *s = tcd->toParent();
while (s && s->isFuncDeclaration())
{ FuncDeclaration *f = s->isFuncDeclaration();
if (f->vthis)
{
e1 = new VarExp(loc, f->vthis);
}
s = s->toParent();
}
if (s && s->isClassDeclaration())
e1->type = s->isClassDeclaration()->type;
e1 = e1->semantic(sc);
goto L1;
}
#ifdef DEBUG
printf("2: ");
#endif
error("this for %s needs to be type %s not type %s",
var->toChars(), ad->toChars(), t->toChars());
VarDeclaration *v = var->isVarDeclaration();
if (v && v->isConst())
{ ExpInitializer *ei = v->getExpInitializer();
if (ei)
{ Expression *e = ei->exp->copy();
e = e->semantic(sc);
return e;
}
}
accessCheck(loc, sc, e1, var);
}
}
//printf("-DotVarExp::semantic('%s')\n", toChars());
@@ -5211,7 +5348,7 @@ Expression *DotTemplateInstanceExp::semantic(Scope *sc)
return e;
Lerr:
return new IntegerExp(0);
return new IntegerExp(loc, 0, Type::tint32);
}
void DotTemplateInstanceExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
@@ -5239,44 +5376,9 @@ Expression *DelegateExp::semantic(Scope *sc)
e1 = e1->semantic(sc);
type = new TypeDelegate(func->type);
type = type->semantic(loc, sc);
//-----------------
/* For func, we need to get the
* right 'this' pointer if func is in an outer class, but our
* existing 'this' pointer is in an inner class.
* This code is analogous to that used for variables
* in DotVarExp::semantic().
*/
AggregateDeclaration *ad = func->toParent()->isAggregateDeclaration();
L10:
Type *t = e1->type;
if (func->needThis() && ad &&
!(t->ty == Tpointer && t->next->ty == Tstruct &&
((TypeStruct *)t->next)->sym == ad) &&
!(t->ty == Tstruct && ((TypeStruct *)t)->sym == ad)
)
{
ClassDeclaration *cd = ad->isClassDeclaration();
ClassDeclaration *tcd = t->isClassHandle();
if (!cd || !tcd ||
!(tcd == cd || cd->isBaseOf(tcd, NULL))
)
{
if (tcd && tcd->isNested())
{ // Try again with outer scope
e1 = new DotVarExp(loc, e1, tcd->vthis);
e1 = e1->semantic(sc);
goto L10;
}
#ifdef DEBUG
printf("3: ");
#endif
error("this for %s needs to be type %s not type %s",
func->toChars(), ad->toChars(), t->toChars());
}
}
//-----------------
if (func->needThis())
e1 = getRightThis(loc, sc, ad, e1, func);
}
return this;
}
@@ -5535,7 +5637,7 @@ Lagain:
DotTemplateExp *dte;
AggregateDeclaration *ad;
UnaExp *ue = (UnaExp *)(e1);
if (e1->op == TOKdotvar)
{ // Do overload resolution
dve = (DotVarExp *)(e1);
@@ -5560,40 +5662,20 @@ Lagain:
}
ad = td->toParent()->isAggregateDeclaration();
}
/* Now that we have the right function f, we need to get the
* right 'this' pointer if f is in an outer class, but our
* existing 'this' pointer is in an inner class.
* This code is analogous to that used for variables
* in DotVarExp::semantic().
if (f->needThis())
{
ue->e1 = getRightThis(loc, sc, ad, ue->e1, f);
}
/* Cannot call public functions from inside invariant
* (because then the invariant would have infinite recursion)
*/
L10:
Type *t = ue->e1->type->toBasetype();
if (f->needThis() && ad &&
!(t->ty == Tpointer && t->next->ty == Tstruct &&
((TypeStruct *)t->next)->sym == ad) &&
!(t->ty == Tstruct && ((TypeStruct *)t)->sym == ad)
if (sc->func && sc->func->isInvariantDeclaration() &&
ue->e1->op == TOKthis &&
f->addPostInvariant()
)
{
ClassDeclaration *cd = ad->isClassDeclaration();
ClassDeclaration *tcd = t->isClassHandle();
if (!cd || !tcd ||
!(tcd == cd || cd->isBaseOf(tcd, NULL))
)
{
if (tcd && tcd->isNested())
{ // Try again with outer scope
ue->e1 = new DotVarExp(loc, ue->e1, tcd->vthis);
ue->e1 = ue->e1->semantic(sc);
goto L10;
}
#ifdef DEBUG
printf("1: ");
#endif
error("this for %s needs to be type %s not type %s",
f->toChars(), ad->toChars(), t->toChars());
}
error("cannot call public/export function %s from invariant", f->toChars());
}
checkDeprecated(sc, f);
@@ -5647,15 +5729,18 @@ Lagain:
}
else
{
if (!sc->intypeof)
{
#if 0
if (sc->callSuper & (CSXthis | CSXsuper))
error("reference to this before super()");
if (sc->callSuper & (CSXthis | CSXsuper))
error("reference to this before super()");
#endif
if (sc->noctor || sc->callSuper & CSXlabel)
error("constructor calls not allowed in loops or after labels");
if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
error("multiple constructor calls");
sc->callSuper |= CSXany_ctor | CSXsuper_ctor;
if (sc->noctor || sc->callSuper & CSXlabel)
error("constructor calls not allowed in loops or after labels");
if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
error("multiple constructor calls");
sc->callSuper |= CSXany_ctor | CSXsuper_ctor;
}
f = f->overloadResolve(loc, arguments);
checkDeprecated(sc, f);
@@ -5680,15 +5765,18 @@ Lagain:
}
else
{
if (!sc->intypeof)
{
#if 0
if (sc->callSuper & (CSXthis | CSXsuper))
error("reference to this before super()");
if (sc->callSuper & (CSXthis | CSXsuper))
error("reference to this before super()");
#endif
if (sc->noctor || sc->callSuper & CSXlabel)
error("constructor calls not allowed in loops or after labels");
if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
error("multiple constructor calls");
sc->callSuper |= CSXany_ctor | CSXthis_ctor;
if (sc->noctor || sc->callSuper & CSXlabel)
error("constructor calls not allowed in loops or after labels");
if (sc->callSuper & (CSXsuper_ctor | CSXthis_ctor))
error("multiple constructor calls");
sc->callSuper |= CSXany_ctor | CSXthis_ctor;
}
f = cd->ctor;
f = f->overloadResolve(loc, arguments);

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -140,6 +140,7 @@ struct Expression : Object
virtual int isBool(int result);
virtual int isBit();
virtual int checkSideEffect(int flag);
virtual int canThrow();
virtual int inlineCost(InlineCostState *ics);
virtual Expression *doInline(InlineDoState *ids);

View File

@@ -103,6 +103,7 @@ void FuncDeclaration::semantic(Scope *sc)
StructDeclaration *sd;
ClassDeclaration *cd;
InterfaceDeclaration *id;
Dsymbol *pd;
#if 0
printf("FuncDeclaration::semantic(sc = %p, this = %p, '%s', linkage = %d)\n", sc, this, toPrettyChars(), sc->linkage);
@@ -208,6 +209,18 @@ void FuncDeclaration::semantic(Scope *sc)
error("function body is not abstract in interface %s", id->toChars());
}
/* Template member functions aren't virtual:
* interface TestInterface { void tpl(T)(); }
* and so won't work in interfaces
*/
if ((pd = toParent()) != NULL &&
pd->isTemplateInstance() &&
(pd = toParent2()) != NULL &&
(id = pd->isInterfaceDeclaration()) != NULL)
{
error("template member function not allowed in interface %s", id->toChars());
}
cd = parent->isClassDeclaration();
if (cd)
{ int vi;
@@ -306,7 +319,7 @@ void FuncDeclaration::semantic(Scope *sc)
if (fdv->isFinal())
error("cannot override final function %s", fdv->toPrettyChars());
#if V2
#if DMDV2
if (!isOverride() && global.params.warnings)
warning("%s: overrides base class function %s, but is not marked with 'override'", locToChars() fdv->toPrettyChars());
#endif
@@ -322,7 +335,7 @@ void FuncDeclaration::semantic(Scope *sc)
#if !BREAKABI
&& !isDtorDeclaration()
#endif
#if V2
#if DMDV2
&& !isPostBlitDeclaration()
#endif
)
@@ -978,7 +991,8 @@ void FuncDeclaration::semantic3(Scope *sc)
f = (TypeFunction *)type;
}
int offend = fbody ? fbody->fallOffEnd() : TRUE;
int offend = fbody ? fbody->blockExit() & BEfallthru : TRUE;
//int offend = fbody ? fbody->fallOffEnd() : TRUE;
if (isStaticCtorDeclaration())
{ /* It's a static constructor. Ensure that all
@@ -1471,7 +1485,7 @@ int fp1(void *param, FuncDeclaration *f)
return 1;
}
#if V2
#if DMDV2
/* Allow covariant matches, if it's just a const conversion
* of the return type
*/
@@ -1777,6 +1791,7 @@ LabelDsymbol *FuncDeclaration::searchLabel(Identifier *ident)
}
return (LabelDsymbol *)s;
}
/****************************************
* If non-static member function that has a 'this' pointer,
* return the aggregate it is a member of.
@@ -2031,17 +2046,18 @@ FuncDeclaration *FuncDeclaration::genCfunc(Type *treturn, Identifier *id)
return fd;
}
char *FuncDeclaration::kind()
const char *FuncDeclaration::kind()
{
return "function";
}
/*******************************
* Look at all the variables in this function that are referenced
* by nested functions, and determine if a closure needs to be
* created for them.
*/
#if V2
#if DMDV2
int FuncDeclaration::needsClosure()
{
/* Need a closure for all the closureVars[] if any of the
@@ -2051,7 +2067,11 @@ int FuncDeclaration::needsClosure()
* 1) is a virtual function
* 2) has its address taken
* 3) has a parent that escapes
* escapes.
*
* Note that since a non-virtual function can be called by
* a virtual one, if that non-virtual function accesses a closure
* var, the closure still has to be taken. Hence, we check for isThis()
* instead of isVirtual(). (thanks to David Friedman)
*/
//printf("FuncDeclaration::needsClosure() %s\n", toChars());
@@ -2065,14 +2085,14 @@ int FuncDeclaration::needsClosure()
assert(f != this);
//printf("\t\tf = %s, %d, %d\n", f->toChars(), f->isVirtual(), f->tookAddressOf);
if (f->isVirtual() || f->tookAddressOf)
if (f->isThis() || f->tookAddressOf)
goto Lyes; // assume f escapes this function's scope
// Look to see if any parents of f that are below this escape
for (Dsymbol *s = f->parent; s != this; s = s->parent)
{
f = s->isFuncDeclaration();
if (f && (f->isVirtual() || f->tookAddressOf))
if (f && (f->isThis() || f->tookAddressOf))
goto Lyes;
}
}
@@ -2097,7 +2117,7 @@ FuncAliasDeclaration::FuncAliasDeclaration(FuncDeclaration *funcalias)
this->funcalias = funcalias;
}
char *FuncAliasDeclaration::kind()
const char *FuncAliasDeclaration::kind()
{
return "function alias";
}
@@ -2142,7 +2162,12 @@ int FuncLiteralDeclaration::isNested()
return (tok == TOKdelegate);
}
char *FuncLiteralDeclaration::kind()
int FuncLiteralDeclaration::isVirtual()
{
return FALSE;
}
const char *FuncLiteralDeclaration::kind()
{
// GCC requires the (char*) casts
return (tok == TOKdelegate) ? (char*)"delegate" : (char*)"function";
@@ -2214,6 +2239,8 @@ void CtorDeclaration::semantic(Scope *sc)
else
tret = cd->type; //->referenceTo();
type = new TypeFunction(arguments, tret, varargs, LINKd);
if (!originalType)
originalType = type;
sc->flags |= SCOPEctor;
type = type->semantic(loc, sc);
@@ -2240,7 +2267,7 @@ void CtorDeclaration::semantic(Scope *sc)
cd->defaultCtor = this;
}
char *CtorDeclaration::kind()
const char *CtorDeclaration::kind()
{
return "constructor";
}
@@ -2377,6 +2404,34 @@ void StaticCtorDeclaration::semantic(Scope *sc)
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
/* If the static ctor appears within a template instantiation,
* it could get called multiple times by the module constructors
* for different modules. Thus, protect it with a gate.
*/
if (inTemplateInstance())
{
/* Add this prefix to the function:
* static int gate;
* if (++gate != 1) return;
* Note that this is not thread safe; should not have threads
* during static construction.
*/
Identifier *id = Lexer::idPool("__gate");
VarDeclaration *v = new VarDeclaration(0, Type::tint32, id, NULL);
v->storage_class = STCstatic;
Statements *sa = new Statements();
Statement *s = new DeclarationStatement(0, v);
sa->push(s);
Expression *e = new IdentifierExp(0, id);
e = new AddAssignExp(0, e, new IntegerExp(1));
e = new EqualExp(TOKnotequal, 0, e, new IntegerExp(1));
s = new IfStatement(0, NULL, e, new ReturnStatement(0, NULL), NULL);
sa->push(s);
if (fbody)
sa->push(fbody);
fbody = new CompoundStatement(0, sa);
}
FuncDeclaration::semantic(sc);
// We're going to need ModuleInfo
@@ -2432,6 +2487,7 @@ StaticDtorDeclaration::StaticDtorDeclaration(Loc loc, Loc endloc)
: FuncDeclaration(loc, endloc,
Identifier::generateId("_staticDtor"), STCstatic, NULL)
{
vgate = NULL;
}
Dsymbol *StaticDtorDeclaration::syntaxCopy(Dsymbol *s)
@@ -2455,6 +2511,36 @@ void StaticDtorDeclaration::semantic(Scope *sc)
}
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
/* If the static ctor appears within a template instantiation,
* it could get called multiple times by the module constructors
* for different modules. Thus, protect it with a gate.
*/
if (inTemplateInstance())
{
/* Add this prefix to the function:
* static int gate;
* if (--gate != 0) return;
* Increment gate during constructor execution.
* Note that this is not thread safe; should not have threads
* during static destruction.
*/
Identifier *id = Lexer::idPool("__gate");
VarDeclaration *v = new VarDeclaration(0, Type::tint32, id, NULL);
v->storage_class = STCstatic;
Statements *sa = new Statements();
Statement *s = new DeclarationStatement(0, v);
sa->push(s);
Expression *e = new IdentifierExp(0, id);
e = new AddAssignExp(0, e, new IntegerExp(-1));
e = new EqualExp(TOKnotequal, 0, e, new IntegerExp(1));
s = new IfStatement(0, NULL, e, new ReturnStatement(0, NULL), NULL);
sa->push(s);
if (fbody)
sa->push(fbody);
fbody = new CompoundStatement(0, sa);
vgate = v;
}
FuncDeclaration::semantic(sc);
// We're going to need ModuleInfo
@@ -2583,12 +2669,7 @@ void InvariantDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
static Identifier *unitTestId()
{
static int n;
char buffer[10 + sizeof(n)*3 + 1];
sprintf(buffer,"__unittest%d", n);
n++;
return Lexer::idPool(buffer);
return Lexer::uniqueId("__unittest");
}
UnitTestDeclaration::UnitTestDeclaration(Loc loc, Loc endloc)
@@ -2713,7 +2794,7 @@ void NewDeclaration::semantic(Scope *sc)
FuncDeclaration::semantic(sc);
}
char *NewDeclaration::kind()
const char *NewDeclaration::kind()
{
return "allocator";
}
@@ -2797,7 +2878,7 @@ void DeleteDeclaration::semantic(Scope *sc)
FuncDeclaration::semantic(sc);
}
char *DeleteDeclaration::kind()
const char *DeleteDeclaration::kind()
{
return "deallocator";
}

View File

@@ -40,6 +40,8 @@ Identifier *Id::line;
Identifier *Id::empty;
Identifier *Id::p;
Identifier *Id::coverage;
Identifier *Id::__vptr;
Identifier *Id::__monitor;
Identifier *Id::TypeInfo;
Identifier *Id::TypeInfo_Class;
Identifier *Id::TypeInfo_Interface;
@@ -213,6 +215,8 @@ void Id::initialize()
empty = Lexer::idPool("");
p = Lexer::idPool("p");
coverage = Lexer::idPool("__coverage");
__vptr = Lexer::idPool("__vptr");
__monitor = Lexer::idPool("__monitor");
TypeInfo = Lexer::idPool("TypeInfo");
TypeInfo_Class = Lexer::idPool("TypeInfo_Class");
TypeInfo_Interface = Lexer::idPool("TypeInfo_Interface");

View File

@@ -42,6 +42,8 @@ struct Id
static Identifier *empty;
static Identifier *p;
static Identifier *coverage;
static Identifier *__vptr;
static Identifier *__monitor;
static Identifier *TypeInfo;
static Identifier *TypeInfo_Class;
static Identifier *TypeInfo_Interface;

View File

@@ -1,302 +1,304 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 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.
// Program to generate string files in d data structures.
// Saves much tedious typing, and eliminates typo problems.
// Generates:
// id.h
// id.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
struct Msgtable
{
char *ident; // name to use in DMD source
char *name; // name in D executable
};
Msgtable msgtable[] =
{
{ "IUnknown" },
{ "Object" },
{ "object" },
{ "max" },
{ "min" },
{ "This", "this" },
{ "ctor", "_ctor" },
{ "dtor", "_dtor" },
{ "classInvariant", "__invariant" },
{ "unitTest", "_unitTest" },
{ "init" },
{ "size" },
{ "__sizeof", "sizeof" },
{ "alignof" },
{ "mangleof" },
{ "stringof" },
{ "tupleof" },
{ "length" },
{ "remove" },
{ "ptr" },
{ "funcptr" },
{ "dollar", "__dollar" },
{ "offset" },
{ "offsetof" },
{ "ModuleInfo" },
{ "ClassInfo" },
{ "classinfo" },
{ "typeinfo" },
{ "outer" },
{ "Exception" },
{ "withSym", "__withSym" },
{ "result", "__result" },
{ "returnLabel", "__returnLabel" },
{ "delegate" },
{ "line" },
{ "empty", "" },
{ "p" },
{ "coverage", "__coverage" },
{ "TypeInfo" },
{ "TypeInfo_Class" },
{ "TypeInfo_Interface" },
{ "TypeInfo_Struct" },
{ "TypeInfo_Enum" },
{ "TypeInfo_Typedef" },
{ "TypeInfo_Pointer" },
{ "TypeInfo_Array" },
{ "TypeInfo_StaticArray" },
{ "TypeInfo_AssociativeArray" },
{ "TypeInfo_Function" },
{ "TypeInfo_Delegate" },
{ "TypeInfo_Tuple" },
{ "TypeInfo_Const" },
{ "TypeInfo_Invariant" },
{ "elements" },
{ "_arguments_typeinfo" },
{ "_arguments" },
{ "_argptr" },
{ "_match" },
{ "LINE", "__LINE__" },
{ "FILE", "__FILE__" },
{ "DATE", "__DATE__" },
{ "TIME", "__TIME__" },
{ "TIMESTAMP", "__TIMESTAMP__" },
{ "VENDOR", "__VENDOR__" },
{ "VERSIONX", "__VERSION__" },
{ "nan" },
{ "infinity" },
{ "dig" },
{ "epsilon" },
{ "mant_dig" },
{ "max_10_exp" },
{ "max_exp" },
{ "min_10_exp" },
{ "min_exp" },
{ "re" },
{ "im" },
{ "C" },
{ "D" },
{ "Windows" },
{ "Pascal" },
{ "System" },
{ "exit" },
{ "success" },
{ "failure" },
{ "keys" },
{ "values" },
{ "rehash" },
{ "sort" },
{ "reverse" },
{ "dup" },
{ "idup" },
// For inline assembler
{ "___out", "out" },
{ "___in", "in" },
{ "__int", "int" },
{ "__dollar", "$" },
{ "__LOCAL_SIZE" },
// For operator overloads
{ "uadd", "opPos" },
{ "neg", "opNeg" },
{ "com", "opCom" },
{ "add", "opAdd" },
{ "add_r", "opAdd_r" },
{ "sub", "opSub" },
{ "sub_r", "opSub_r" },
{ "mul", "opMul" },
{ "mul_r", "opMul_r" },
{ "div", "opDiv" },
{ "div_r", "opDiv_r" },
{ "mod", "opMod" },
{ "mod_r", "opMod_r" },
{ "eq", "opEquals" },
{ "cmp", "opCmp" },
{ "iand", "opAnd" },
{ "iand_r", "opAnd_r" },
{ "ior", "opOr" },
{ "ior_r", "opOr_r" },
{ "ixor", "opXor" },
{ "ixor_r", "opXor_r" },
{ "shl", "opShl" },
{ "shl_r", "opShl_r" },
{ "shr", "opShr" },
{ "shr_r", "opShr_r" },
{ "ushr", "opUShr" },
{ "ushr_r", "opUShr_r" },
{ "cat", "opCat" },
{ "cat_r", "opCat_r" },
{ "assign", "opAssign" },
{ "addass", "opAddAssign" },
{ "subass", "opSubAssign" },
{ "mulass", "opMulAssign" },
{ "divass", "opDivAssign" },
{ "modass", "opModAssign" },
{ "andass", "opAndAssign" },
{ "orass", "opOrAssign" },
{ "xorass", "opXorAssign" },
{ "shlass", "opShlAssign" },
{ "shrass", "opShrAssign" },
{ "ushrass", "opUShrAssign" },
{ "catass", "opCatAssign" },
{ "postinc", "opPostInc" },
{ "postdec", "opPostDec" },
{ "index", "opIndex" },
{ "indexass", "opIndexAssign" },
{ "slice", "opSlice" },
{ "sliceass", "opSliceAssign" },
{ "call", "opCall" },
{ "cast", "opCast" },
{ "match", "opMatch" },
{ "next", "opNext" },
{ "opIn" },
{ "opIn_r" },
{ "classNew", "new" },
{ "classDelete", "delete" },
// For foreach
{ "apply", "opApply" },
{ "applyReverse", "opApplyReverse" },
{ "adDup", "_adDupT" },
{ "adReverse", "_adReverse" },
// For internal functions
{ "aaLen", "_aaLen" },
{ "aaKeys", "_aaKeys" },
{ "aaValues", "_aaValues" },
{ "aaRehash", "_aaRehash" },
// For pragma's
{ "lib" },
{ "msg" },
{ "GNU_asm" },
{ "LLVM_intrinsic" },
{ "LLVM_internal" },
// For toHash/toString
{ "tohash", "toHash" },
{ "tostring", "toString" },
// Special functions
{ "alloca" },
{ "main" },
{ "WinMain" },
{ "DllMain" },
};
int main()
{
FILE *fp;
unsigned i;
{
fp = fopen("id.h","w");
if (!fp)
{ printf("can't open id.h\n");
exit(EXIT_FAILURE);
}
fprintf(fp, "// File generated by idgen.c\n");
#if __DMC__
fprintf(fp, "#pragma once\n");
#endif
fprintf(fp, "#ifndef DMD_ID_H\n");
fprintf(fp, "#define DMD_ID_H 1\n");
fprintf(fp, "struct Identifier;\n");
fprintf(fp, "struct Id\n");
fprintf(fp, "{\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ char *id = msgtable[i].ident;
fprintf(fp," static Identifier *%s;\n", id);
}
fprintf(fp, " static void initialize();\n");
fprintf(fp, "};\n");
fprintf(fp, "#endif\n");
fclose(fp);
}
{
fp = fopen("id.c","w");
if (!fp)
{ printf("can't open id.c\n");
exit(EXIT_FAILURE);
}
fprintf(fp, "// File generated by idgen.c\n");
fprintf(fp, "#include \"id.h\"\n");
fprintf(fp, "#include \"identifier.h\"\n");
fprintf(fp, "#include \"lexer.h\"\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ char *id = msgtable[i].ident;
char *p = msgtable[i].name;
if (!p)
p = id;
fprintf(fp,"Identifier *Id::%s;\n", id);
}
fprintf(fp, "void Id::initialize()\n");
fprintf(fp, "{\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ char *id = msgtable[i].ident;
char *p = msgtable[i].name;
if (!p)
p = id;
fprintf(fp," %s = Lexer::idPool(\"%s\");\n", id, p);
}
fprintf(fp, "}\n");
fclose(fp);
}
return EXIT_SUCCESS;
}
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 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.
// Program to generate string files in d data structures.
// Saves much tedious typing, and eliminates typo problems.
// Generates:
// id.h
// id.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
struct Msgtable
{
char *ident; // name to use in DMD source
char *name; // name in D executable
};
Msgtable msgtable[] =
{
{ "IUnknown" },
{ "Object" },
{ "object" },
{ "max" },
{ "min" },
{ "This", "this" },
{ "ctor", "_ctor" },
{ "dtor", "_dtor" },
{ "classInvariant", "__invariant" },
{ "unitTest", "_unitTest" },
{ "init" },
{ "size" },
{ "__sizeof", "sizeof" },
{ "alignof" },
{ "mangleof" },
{ "stringof" },
{ "tupleof" },
{ "length" },
{ "remove" },
{ "ptr" },
{ "funcptr" },
{ "dollar", "__dollar" },
{ "offset" },
{ "offsetof" },
{ "ModuleInfo" },
{ "ClassInfo" },
{ "classinfo" },
{ "typeinfo" },
{ "outer" },
{ "Exception" },
{ "withSym", "__withSym" },
{ "result", "__result" },
{ "returnLabel", "__returnLabel" },
{ "delegate" },
{ "line" },
{ "empty", "" },
{ "p" },
{ "coverage", "__coverage" },
{ "__vptr" },
{ "__monitor" },
{ "TypeInfo" },
{ "TypeInfo_Class" },
{ "TypeInfo_Interface" },
{ "TypeInfo_Struct" },
{ "TypeInfo_Enum" },
{ "TypeInfo_Typedef" },
{ "TypeInfo_Pointer" },
{ "TypeInfo_Array" },
{ "TypeInfo_StaticArray" },
{ "TypeInfo_AssociativeArray" },
{ "TypeInfo_Function" },
{ "TypeInfo_Delegate" },
{ "TypeInfo_Tuple" },
{ "TypeInfo_Const" },
{ "TypeInfo_Invariant" },
{ "elements" },
{ "_arguments_typeinfo" },
{ "_arguments" },
{ "_argptr" },
{ "_match" },
{ "LINE", "__LINE__" },
{ "FILE", "__FILE__" },
{ "DATE", "__DATE__" },
{ "TIME", "__TIME__" },
{ "TIMESTAMP", "__TIMESTAMP__" },
{ "VENDOR", "__VENDOR__" },
{ "VERSIONX", "__VERSION__" },
{ "nan" },
{ "infinity" },
{ "dig" },
{ "epsilon" },
{ "mant_dig" },
{ "max_10_exp" },
{ "max_exp" },
{ "min_10_exp" },
{ "min_exp" },
{ "re" },
{ "im" },
{ "C" },
{ "D" },
{ "Windows" },
{ "Pascal" },
{ "System" },
{ "exit" },
{ "success" },
{ "failure" },
{ "keys" },
{ "values" },
{ "rehash" },
{ "sort" },
{ "reverse" },
{ "dup" },
{ "idup" },
// For inline assembler
{ "___out", "out" },
{ "___in", "in" },
{ "__int", "int" },
{ "__dollar", "$" },
{ "__LOCAL_SIZE" },
// For operator overloads
{ "uadd", "opPos" },
{ "neg", "opNeg" },
{ "com", "opCom" },
{ "add", "opAdd" },
{ "add_r", "opAdd_r" },
{ "sub", "opSub" },
{ "sub_r", "opSub_r" },
{ "mul", "opMul" },
{ "mul_r", "opMul_r" },
{ "div", "opDiv" },
{ "div_r", "opDiv_r" },
{ "mod", "opMod" },
{ "mod_r", "opMod_r" },
{ "eq", "opEquals" },
{ "cmp", "opCmp" },
{ "iand", "opAnd" },
{ "iand_r", "opAnd_r" },
{ "ior", "opOr" },
{ "ior_r", "opOr_r" },
{ "ixor", "opXor" },
{ "ixor_r", "opXor_r" },
{ "shl", "opShl" },
{ "shl_r", "opShl_r" },
{ "shr", "opShr" },
{ "shr_r", "opShr_r" },
{ "ushr", "opUShr" },
{ "ushr_r", "opUShr_r" },
{ "cat", "opCat" },
{ "cat_r", "opCat_r" },
{ "assign", "opAssign" },
{ "addass", "opAddAssign" },
{ "subass", "opSubAssign" },
{ "mulass", "opMulAssign" },
{ "divass", "opDivAssign" },
{ "modass", "opModAssign" },
{ "andass", "opAndAssign" },
{ "orass", "opOrAssign" },
{ "xorass", "opXorAssign" },
{ "shlass", "opShlAssign" },
{ "shrass", "opShrAssign" },
{ "ushrass", "opUShrAssign" },
{ "catass", "opCatAssign" },
{ "postinc", "opPostInc" },
{ "postdec", "opPostDec" },
{ "index", "opIndex" },
{ "indexass", "opIndexAssign" },
{ "slice", "opSlice" },
{ "sliceass", "opSliceAssign" },
{ "call", "opCall" },
{ "cast", "opCast" },
{ "match", "opMatch" },
{ "next", "opNext" },
{ "opIn" },
{ "opIn_r" },
{ "classNew", "new" },
{ "classDelete", "delete" },
// For foreach
{ "apply", "opApply" },
{ "applyReverse", "opApplyReverse" },
{ "adDup", "_adDupT" },
{ "adReverse", "_adReverse" },
// For internal functions
{ "aaLen", "_aaLen" },
{ "aaKeys", "_aaKeys" },
{ "aaValues", "_aaValues" },
{ "aaRehash", "_aaRehash" },
// For pragma's
{ "lib" },
{ "msg" },
{ "GNU_asm" },
{ "LLVM_intrinsic" },
{ "LLVM_internal" },
// For toHash/toString
{ "tohash", "toHash" },
{ "tostring", "toString" },
// Special functions
{ "alloca" },
{ "main" },
{ "WinMain" },
{ "DllMain" },
};
int main()
{
FILE *fp;
unsigned i;
{
fp = fopen("id.h","w");
if (!fp)
{ printf("can't open id.h\n");
exit(EXIT_FAILURE);
}
fprintf(fp, "// File generated by idgen.c\n");
#if __DMC__
fprintf(fp, "#pragma once\n");
#endif
fprintf(fp, "#ifndef DMD_ID_H\n");
fprintf(fp, "#define DMD_ID_H 1\n");
fprintf(fp, "struct Identifier;\n");
fprintf(fp, "struct Id\n");
fprintf(fp, "{\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ char *id = msgtable[i].ident;
fprintf(fp," static Identifier *%s;\n", id);
}
fprintf(fp, " static void initialize();\n");
fprintf(fp, "};\n");
fprintf(fp, "#endif\n");
fclose(fp);
}
{
fp = fopen("id.c","w");
if (!fp)
{ printf("can't open id.c\n");
exit(EXIT_FAILURE);
}
fprintf(fp, "// File generated by idgen.c\n");
fprintf(fp, "#include \"id.h\"\n");
fprintf(fp, "#include \"identifier.h\"\n");
fprintf(fp, "#include \"lexer.h\"\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ char *id = msgtable[i].ident;
char *p = msgtable[i].name;
if (!p)
p = id;
fprintf(fp,"Identifier *Id::%s;\n", id);
}
fprintf(fp, "void Id::initialize()\n");
fprintf(fp, "{\n");
for (i = 0; i < sizeof(msgtable) / sizeof(msgtable[0]); i++)
{ char *id = msgtable[i].ident;
char *p = msgtable[i].name;
if (!p)
p = id;
fprintf(fp," %s = Lexer::idPool(\"%s\");\n", id, p);
}
fprintf(fp, "}\n");
fclose(fp);
}
return EXIT_SUCCESS;
}

View File

@@ -55,7 +55,7 @@ void Import::addAlias(Identifier *name, Identifier *alias)
aliases.push(alias);
}
char *Import::kind()
const char *Import::kind()
{
return isstatic ? (char *)"static import" : (char *)"import";
}

View File

@@ -48,7 +48,7 @@ struct Import : Dsymbol
int isstatic);
void addAlias(Identifier *name, Identifier *alias);
char *kind();
const char *kind();
Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
void load(Scope *sc);
void semantic(Scope *sc);

1170
dmd/init.c

File diff suppressed because it is too large Load Diff

View File

@@ -860,7 +860,7 @@ Statement *ForeachStatement::inlineScan(InlineScanState *iss)
}
#if V2
#if DMDV2
Statement *ForeachRangeStatement::inlineScan(InlineScanState *iss)
{
lwr = lwr->inlineScan(iss);
@@ -1290,7 +1290,7 @@ int FuncDeclaration::canInline(int hasthis, int hdrscan)
#endif
isSynchronized() ||
isImportedSymbol() ||
#if V2
#if DMDV2
closureVars.dim || // no nested references to this frame
#else
nestedFrameRef || // no nested references to this frame

View File

@@ -729,7 +729,7 @@ Expression *ForeachStatement::interpret(InterState *istate)
return e;
}
#if V2
#if DMDV2
Expression *ForeachRangeStatement::interpret(InterState *istate)
{
#if LOG
@@ -989,7 +989,7 @@ Expression *getVarExp(Loc loc, InterState *istate, Declaration *d)
SymbolDeclaration *s = d->isSymbolDeclaration();
if (v)
{
#if V2
#if DMDV2
if ((v->isConst() || v->isInvariant()) && v->init && !v->value)
#else
if (v->isConst() && v->init)
@@ -1045,7 +1045,7 @@ Expression *DeclarationExp::interpret(InterState *istate)
else if (v->init->isVoidInitializer())
e = NULL;
}
#if V2
#if DMDV2
else if (s == v && (v->isConst() || v->isInvariant()) && v->init)
#else
else if (s == v && v->isConst() && v->init)
@@ -1855,7 +1855,7 @@ Expression *CallExp::interpret(InterState *istate)
FuncDeclaration *fd = ((VarExp *)e1)->var->isFuncDeclaration();
if (fd)
{
#if V2
#if DMDV2
enum BUILTIN b = fd->isBuiltin();
if (b)
{ Expressions args;

View File

@@ -568,7 +568,7 @@ void Lexer::scan(Token *t)
t->value = hexStringConstant(t);
return;
#if V2
#if DMDV2
case 'q':
if (p[1] == '"')
{
@@ -627,7 +627,7 @@ void Lexer::scan(Token *t)
case 'a': case 'b': case 'c': case 'd': case 'e':
case 'f': case 'g': case 'h': case 'i': case 'j':
case 'k': case 'm': case 'n': case 'o':
#if V2
#if DMDV2
case 'p': /*case 'q': case 'r':*/ case 's': case 't':
#else
case 'p': case 'q': /*case 'r':*/ case 's': case 't':
@@ -677,6 +677,7 @@ void Lexer::scan(Token *t)
sprintf(timestamp, "%.24s", p);
}
#if DMDV1
if (mod && id == Id::FILE)
{
t->ustring = (unsigned char *)(loc.filename ? loc.filename : mod->ident->toChars());
@@ -687,7 +688,9 @@ void Lexer::scan(Token *t)
t->value = TOKint64v;
t->uns64value = loc.linnum;
}
else if (id == Id::DATE)
else
#endif
if (id == Id::DATE)
{
t->ustring = (unsigned char *)date;
goto Lstring;
@@ -730,7 +733,7 @@ void Lexer::scan(Token *t)
t->value = TOKint64v;
t->uns64value = major * 1000 + minor;
}
#if V2
#if DMDV2
else if (id == Id::EOFX)
{
t->value = TOKeof;
@@ -1476,7 +1479,7 @@ TOK Lexer::hexStringConstant(Token *t)
}
#if V2
#if DMDV2
/**************************************
* Lex delimited strings:
* q"(foo(xxx))" // "foo(xxx)"
@@ -2917,11 +2920,14 @@ static Keyword keywords[] =
// Added after 1.0
{ "ref", TOKref },
{ "macro", TOKmacro },
#if V2
#if DMDV2
{ "pure", TOKpure },
{ "nothrow", TOKnothrow },
{ "__thread", TOKtls },
{ "__traits", TOKtraits },
{ "__overloadset", TOKoverloadset },
{ "__FILE__", TOKfile },
{ "__LINE__", TOKline },
#endif
};
@@ -2974,7 +2980,7 @@ void Lexer::initKeywords()
Token::tochars[TOKxorass] = "^=";
Token::tochars[TOKassign] = "=";
Token::tochars[TOKconstruct] = "=";
#if V2
#if DMDV2
Token::tochars[TOKblit] = "=";
#endif
Token::tochars[TOKlt] = "<";

View File

@@ -150,10 +150,14 @@ enum TOK
// Added after 1.0
TOKref,
TOKmacro,
#if V2
#if DMDV2
TOKtraits,
TOKoverloadset,
TOKpure,
TOKnothrow,
TOKtls,
TOKline,
TOKfile,
#endif
TOKMAX
@@ -273,7 +277,7 @@ struct Lexer
unsigned escapeSequence();
TOK wysiwygStringConstant(Token *t, int tc);
TOK hexStringConstant(Token *t);
#if V2
#if DMDV2
TOK delimitedStringConstant(Token *t);
TOK tokenStringConstant(Token *t);
#endif

View File

@@ -1043,7 +1043,7 @@ int main(int argc, char *argv[])
if (global.params.verbose)
printf("code %s\n", m->toChars());
if (global.params.obj)
m->genobjfile();
m->genobjfile(0);
if (global.errors)
m->deleteObjFile();
else

View File

@@ -32,7 +32,7 @@
/* Changes for the GDC compiler by David Friedman */
#endif
#define V2 0 // Version 2.0 features
#define DMDV2 0 // Version 2.0 features
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
struct Array;
@@ -300,7 +300,7 @@ enum MATCH
{
MATCHnomatch, // no match
MATCHconvert, // match with conversions
#if V2
#if DMDV2
MATCHconst, // match with conversion to const
#endif
MATCHexact // exact match

File diff suppressed because it is too large Load Diff

View File

@@ -1,185 +1,187 @@
// Compiler implementation of the D programming language
// 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_MODULE_H
#define DMD_MODULE_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "dsymbol.h"
struct ModuleInfoDeclaration;
struct ClassDeclaration;
struct ModuleDeclaration;
struct Macro;
struct Escape;
struct VarDeclaration;
// Back end
#if IN_LLVM
struct DValue;
typedef DValue elem;
#else
#ifdef IN_GCC
union tree_node; typedef union tree_node elem;
#else
struct elem;
#endif
#endif
struct Package : ScopeDsymbol
{
Package(Identifier *ident);
char *kind();
static DsymbolTable *resolve(Array *packages, Dsymbol **pparent, Package **ppkg);
Package *isPackage() { return this; }
virtual void semantic(Scope *sc) { }
};
struct Module : Package
{
static Module *rootModule;
static DsymbolTable *modules; // symbol table of all modules
static Array amodules; // array of all modules
static Array deferred; // deferred Dsymbol's needing semantic() run on them
static unsigned dprogress; // progress resolving the deferred list
static void init();
static ClassDeclaration *moduleinfo;
const char *arg; // original argument name
ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration
File *srcfile; // input source file
File *objfile; // output .obj file
File *bcfile; // output .bc file
File *llfile; // output .ll file
File *hdrfile; // 'header' file
File *symfile; // output symbol file
File *docfile; // output documentation file
unsigned errors; // if any errors in file
unsigned numlines; // number of lines in source file
int isHtml; // if it is an HTML file
int isDocFile; // if it is a documentation input file, not D source
int needmoduleinfo;
#ifdef IN_GCC
int strictlyneedmoduleinfo;
#endif
int insearch;
Identifier *searchCacheIdent;
Dsymbol *searchCacheSymbol; // cached value of search
int searchCacheFlags; // cached flags
int semanticstarted; // has semantic() been started?
int semanticdone; // has semantic() been done?
int root; // != 0 if this is a 'root' module,
// i.e. a module that will be taken all the
// way to an object file
Module *importedFrom; // module from command line we're imported from,
// i.e. a module that will be taken all the
// way to an object file
Array *decldefs; // top level declarations for this Module
Array aimports; // all imported modules
ModuleInfoDeclaration *vmoduleinfo;
unsigned debuglevel; // debug level
Array *debugids; // debug identifiers
Array *debugidsNot; // forward referenced debug identifiers
unsigned versionlevel; // version level
Array *versionids; // version identifiers
Array *versionidsNot; // forward referenced version identifiers
Macro *macrotable; // document comment macros
Escape *escapetable; // document comment escapes
Module(char *arg, Identifier *ident, int doDocComment, int doHdrGen);
~Module();
static Module *load(Loc loc, Array *packages, Identifier *ident);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *kind();
void setDocfile(); // set docfile member
void read(Loc loc); // read file
#if IN_GCC
void parse(bool dump_source = false); // syntactic parse
#else
void parse(); // syntactic parse
#endif
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
#ifdef _DH
void genhdrfile(); // generate D import file
#endif
void genobjfile();
void gensymfile();
void gendocfile();
int needModuleInfo();
Dsymbol *search(Loc loc, Identifier *ident, int flags);
void deleteObjFile();
void addDeferredSemantic(Dsymbol *s);
void runDeferredSemantic();
// Back end
Symbol *cov; // private uint[] __coverage;
unsigned *covb; // bit array of valid code line numbers
Symbol *sictor; // module order independent constructor
Symbol *sctor; // module constructor
Symbol *sdtor; // module destructor
Symbol *stest; // module unit test
Symbol *sfilename; // symbol for filename
Symbol *massert; // module assert function
Symbol *toModuleAssert(); // get module assert function
Symbol *marray; // module array bounds function
Symbol *toModuleArray(); // get module array bounds function
static Symbol *gencritsec();
elem *toEfilename();
elem *toEmodulename();
Symbol *toSymbol();
void genmoduleinfo();
// LLVMDC
Module *isModule() { return this; }
};
struct ModuleDeclaration
{
Identifier *id;
Array *packages; // array of Identifier's representing packages
ModuleDeclaration(Array *packages, Identifier *id);
char *toChars();
};
#endif /* DMD_MODULE_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_MODULE_H
#define DMD_MODULE_H
#ifdef __DMC__
#pragma once
#endif /* __DMC__ */
#include "root.h"
#include "dsymbol.h"
struct ModuleInfoDeclaration;
struct ClassDeclaration;
struct ModuleDeclaration;
struct Macro;
struct Escape;
struct VarDeclaration;
struct Library;
// Back end
#if IN_LLVM
struct DValue;
typedef DValue elem;
#else
#ifdef IN_GCC
union tree_node; typedef union tree_node elem;
#else
struct elem;
#endif
#endif
struct Package : ScopeDsymbol
{
Package(Identifier *ident);
const char *kind();
static DsymbolTable *resolve(Array *packages, Dsymbol **pparent, Package **ppkg);
Package *isPackage() { return this; }
virtual void semantic(Scope *sc) { }
};
struct Module : Package
{
static Module *rootModule;
static DsymbolTable *modules; // symbol table of all modules
static Array amodules; // array of all modules
static Array deferred; // deferred Dsymbol's needing semantic() run on them
static unsigned dprogress; // progress resolving the deferred list
static void init();
static ClassDeclaration *moduleinfo;
const char *arg; // original argument name
ModuleDeclaration *md; // if !NULL, the contents of the ModuleDeclaration declaration
File *srcfile; // input source file
File *objfile; // output .obj file
File *bcfile; // output .bc file
File *llfile; // output .ll file
File *hdrfile; // 'header' file
File *symfile; // output symbol file
File *docfile; // output documentation file
unsigned errors; // if any errors in file
unsigned numlines; // number of lines in source file
int isHtml; // if it is an HTML file
int isDocFile; // if it is a documentation input file, not D source
int needmoduleinfo;
#ifdef IN_GCC
int strictlyneedmoduleinfo;
#endif
int insearch;
Identifier *searchCacheIdent;
Dsymbol *searchCacheSymbol; // cached value of search
int searchCacheFlags; // cached flags
int semanticstarted; // has semantic() been started?
int semanticdone; // has semantic() been done?
int root; // != 0 if this is a 'root' module,
// i.e. a module that will be taken all the
// way to an object file
Module *importedFrom; // module from command line we're imported from,
// i.e. a module that will be taken all the
// way to an object file
Array *decldefs; // top level declarations for this Module
Array aimports; // all imported modules
ModuleInfoDeclaration *vmoduleinfo;
unsigned debuglevel; // debug level
Array *debugids; // debug identifiers
Array *debugidsNot; // forward referenced debug identifiers
unsigned versionlevel; // version level
Array *versionids; // version identifiers
Array *versionidsNot; // forward referenced version identifiers
Macro *macrotable; // document comment macros
Escape *escapetable; // document comment escapes
Module(char *arg, Identifier *ident, int doDocComment, int doHdrGen);
~Module();
static Module *load(Loc loc, Array *packages, Identifier *ident);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
const char *kind();
void setDocfile(); // set docfile member
void read(Loc loc); // read file
#if IN_GCC
void parse(bool dump_source = false); // syntactic parse
#else
void parse(); // syntactic parse
#endif
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
#ifdef _DH
void genhdrfile(); // generate D import file
#endif
void genobjfile(int multiobj);
void gensymfile();
void gendocfile();
int needModuleInfo();
Dsymbol *search(Loc loc, Identifier *ident, int flags);
void deleteObjFile();
void addDeferredSemantic(Dsymbol *s);
void runDeferredSemantic();
// Back end
int doppelganger; // sub-module
Symbol *cov; // private uint[] __coverage;
unsigned *covb; // bit array of valid code line numbers
Symbol *sictor; // module order independent constructor
Symbol *sctor; // module constructor
Symbol *sdtor; // module destructor
Symbol *stest; // module unit test
Symbol *sfilename; // symbol for filename
Symbol *massert; // module assert function
Symbol *toModuleAssert(); // get module assert function
Symbol *marray; // module array bounds function
Symbol *toModuleArray(); // get module array bounds function
static Symbol *gencritsec();
elem *toEfilename();
elem *toEmodulename();
Symbol *toSymbol();
void genmoduleinfo();
// LLVMDC
Module *isModule() { return this; }
};
struct ModuleDeclaration
{
Identifier *id;
Array *packages; // array of Identifier's representing packages
ModuleDeclaration(Array *packages, Identifier *id);
char *toChars();
};
#endif /* DMD_MODULE_H */

View File

@@ -115,7 +115,7 @@ Type::Type(TY ty, Type *next)
this->mod = 0;
this->next = next;
this->deco = NULL;
#if V2
#if DMDV2
this->cto = NULL;
this->ito = NULL;
#endif
@@ -2226,6 +2226,35 @@ Type *TypeAArray::semantic(Loc loc, Scope *sc)
return merge();
}
void TypeAArray::resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps)
{
//printf("TypeAArray::resolve() %s\n", toChars());
// Deal with the case where we thought the index was a type, but
// in reality it was an expression.
if (index->ty == Tident || index->ty == Tinstance || index->ty == Tsarray)
{
Expression *e;
Type *t;
Dsymbol *s;
index->resolve(loc, sc, &e, &t, &s);
if (e)
{ // It was an expression -
// Rewrite as a static array
TypeSArray *tsa = new TypeSArray(next, e);
return tsa->resolve(loc, sc, pe, pt, ps);
}
else if (t)
index = t;
else
index->error(loc, "index is not a type or an expression");
}
Type::resolve(loc, sc, pe, pt, ps);
}
Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
{
#if LOGDOTEXP
@@ -3151,6 +3180,7 @@ void TypeQualified::resolveHelper(Loc loc, Scope *sc,
if (s)
{
//printf("\t1: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
s->checkDeprecated(loc, sc); // check for deprecated aliases
s = s->toAlias();
//printf("\t2: s = '%s' %p, kind = '%s'\n",s->toChars(), s, s->kind());
for (i = 0; i < idents.dim; i++)
@@ -3548,7 +3578,7 @@ Dsymbol *TypeTypeof::toDsymbol(Scope *sc)
{
Type *t;
t = semantic(0, sc);
t = semantic(loc, sc);
if (t == this)
return NULL;
return t->toDsymbol(sc);
@@ -3624,6 +3654,10 @@ Type *TypeTypeof::semantic(Loc loc, Scope *sc)
sc->intypeof++;
exp = exp->semantic(sc);
sc->intypeof--;
if (exp->op == TOKtype)
{
error(loc, "argument %s to typeof is not an expression", exp->toChars());
}
t = exp->type;
if (!t)
{
@@ -4174,6 +4208,7 @@ Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident)
{
/* Create a TupleExp
*/
e = e->semantic(sc); // do this before turning on noaccesscheck
Expressions *exps = new Expressions;
exps->reserve(sym->fields.dim);
for (size_t i = 0; i < sym->fields.dim; i++)
@@ -4182,7 +4217,10 @@ Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident)
exps->push(fe);
}
e = new TupleExp(e->loc, exps);
sc = sc->push();
sc->noaccesscheck = 1;
e = e->semantic(sc);
sc->pop();
return e;
}
@@ -4206,6 +4244,8 @@ L1:
//return getProperty(e->loc, ident);
return Type::dotExp(sc, e, ident);
}
if (!s->isFuncDeclaration()) // because of overloading
s->checkDeprecated(e->loc, sc);
s = s->toAlias();
v = s->isVarDeclaration();
@@ -4459,6 +4499,7 @@ Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident)
{
/* Create a TupleExp
*/
e = e->semantic(sc); // do this before turning on noaccesscheck
Expressions *exps = new Expressions;
exps->reserve(sym->fields.dim);
for (size_t i = 0; i < sym->fields.dim; i++)
@@ -4467,7 +4508,10 @@ Expression *TypeClass::dotExp(Scope *sc, Expression *e, Identifier *ident)
exps->push(fe);
}
e = new TupleExp(e->loc, exps);
sc = sc->push();
sc->noaccesscheck = 1;
e = e->semantic(sc);
sc->pop();
return e;
}
@@ -4541,6 +4585,7 @@ L1:
e = new PtrExp(e->loc, e);
e->type = ct->next->next->next;
}
}
#else
@@ -4565,9 +4610,31 @@ L1:
e->type = t->pointerTo();
}
e = new PtrExp(e->loc, e, t);
}
#endif
}
#endif // !LLVMDC
return e;
}
if (ident == Id::__vptr)
{ /* The pointer to the vtbl[]
* *cast(void***)e
*/
e = e->castTo(sc, tvoidptr->pointerTo()->pointerTo());
e = new PtrExp(e->loc, e);
e = e->semantic(sc);
return e;
}
if (ident == Id::__monitor)
{ /* The handle to the monitor (call it a void*)
* *(cast(void**)e + 1)
*/
e = e->castTo(sc, tvoidptr->pointerTo());
e = new AddExp(e->loc, e, new IntegerExp(1));
e = new PtrExp(e->loc, e);
e = e->semantic(sc);
return e;
}
@@ -4587,6 +4654,8 @@ L1:
return Type::dotExp(sc, e, ident);
}
}
if (!s->isFuncDeclaration()) // because of overloading
s->checkDeprecated(e->loc, sc);
s = s->toAlias();
v = s->isVarDeclaration();
if (v && v->isConst())

View File

@@ -355,6 +355,7 @@ struct TypeAArray : TypeArray
Type *syntaxCopy();
d_uns64 size(Loc loc);
Type *semantic(Loc loc, Scope *sc);
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
void toDecoBuffer(OutBuffer *buf);
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
Expression *dotExp(Scope *sc, Expression *e, Identifier *ident);

File diff suppressed because it is too large Load Diff

10075
dmd/parse.c

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-2006 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -20,6 +20,7 @@
#include "enum.h"
struct Type;
struct TypeQualified;
struct Expression;
struct Declaration;
struct Statement;
@@ -27,6 +28,7 @@ struct Import;
struct Initializer;
struct FuncDeclaration;
struct CtorDeclaration;
struct PostBlitDeclaration;
struct DtorDeclaration;
struct StaticCtorDeclaration;
struct StaticDtorDeclaration;

3691
dmd/root.c

File diff suppressed because it is too large Load Diff

View File

@@ -125,6 +125,7 @@ struct FileName : String
static int absolute(const char *name);
static char *ext(const char *);
char *ext();
static char *removeExt(const char *str);
static char *name(const char *);
char *name();
static char *path(const char *);
@@ -263,7 +264,7 @@ struct OutBuffer : Object
void reset();
void write(const void *data, unsigned nbytes);
void writebstring(unsigned char *string);
void writestring(char *string);
void writestring(const char *string);
void writedstring(const char *string);
void writedstring(const wchar_t *string);
void prependstring(char *string);

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2007 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -113,6 +113,16 @@ int Statement::usesEH()
return FALSE;
}
/* Only valid after semantic analysis
*/
int Statement::blockExit()
{
printf("Statement::blockExit(%p)\n", this);
printf("%s\n", toChars());
assert(0);
return BEany;
}
// TRUE if statement may fall off the end without a throw or return
int Statement::fallOffEnd()
@@ -197,6 +207,25 @@ Statement *ExpStatement::semantic(Scope *sc)
return this;
}
int ExpStatement::blockExit()
{ int result = BEfallthru;
if (exp)
{
if (exp->op == TOKhalt)
return BEhalt;
if (exp->op == TOKassert)
{ AssertExp *a = (AssertExp *)exp;
if (a->e1->isBool(FALSE)) // if it's an assert(0)
return BEhalt;
}
if (exp->canThrow())
result |= BEthrow;
}
return result;
}
int ExpStatement::fallOffEnd()
{
if (exp)
@@ -237,15 +266,15 @@ void CompileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
}
Statement *CompileStatement::semantic(Scope *sc)
Statements *CompileStatement::flatten(Scope *sc)
{
//printf("CompileStatement::semantic() %s\n", exp->toChars());
//printf("CompileStatement::flatten() %s\n", exp->toChars());
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->optimize(WANTvalue | WANTinterpret);
if (exp->op != TOKstring)
{ error("argument to mixin must be a string, not (%s)", exp->toChars());
return this;
return NULL;
}
StringExp *se = (StringExp *)exp;
se = se->toUTF8(sc);
@@ -253,14 +282,22 @@ Statement *CompileStatement::semantic(Scope *sc)
p.loc = loc;
p.nextToken();
Statements *statements = new Statements();
Statements *a = new Statements();
while (p.token.value != TOKeof)
{
Statement *s = p.parseStatement(PSsemi | PScurlyscope);
statements->push(s);
a->push(s);
}
return a;
}
Statement *s = new CompoundStatement(loc, statements);
Statement *CompileStatement::semantic(Scope *sc)
{
//printf("CompileStatement::semantic() %s\n", exp->toChars());
Statements *a = flatten(sc);
if (!a)
return NULL;
Statement *s = new CompoundStatement(loc, a);
return s->semantic(sc);
}
@@ -468,7 +505,9 @@ Statement *CompoundStatement::semantic(Scope *sc)
i++;
}
if (statements->dim == 1 && !isAsmBlockStatement())
return s;
{
return (Statement *)statements->data[0];
}
return this;
}
@@ -478,13 +517,11 @@ Statements *CompoundStatement::flatten(Scope *sc)
}
ReturnStatement *CompoundStatement::isReturnStatement()
{ int i;
{
ReturnStatement *rs = NULL;
for (i = 0; i < statements->dim; i++)
{ Statement *s;
s = (Statement *) statements->data[i];
for (int i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *) statements->data[i];
if (s)
{
rs = s->isReturnStatement();
@@ -496,12 +533,9 @@ ReturnStatement *CompoundStatement::isReturnStatement()
}
void CompoundStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ int i;
for (i = 0; i < statements->dim; i++)
{ Statement *s;
s = (Statement *) statements->data[i];
{
for (int i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *) statements->data[i];
if (s)
s->toCBuffer(buf, hgs);
}
@@ -510,15 +544,38 @@ void CompoundStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
int CompoundStatement::usesEH()
{
for (int i = 0; i < statements->dim; i++)
{ Statement *s;
s = (Statement *) statements->data[i];
{ Statement *s = (Statement *) statements->data[i];
if (s && s->usesEH())
return TRUE;
}
return FALSE;
}
int CompoundStatement::blockExit()
{
//printf("CompoundStatement::blockExit(%p) %d\n", this, statements->dim);
int result = BEfallthru;
for (size_t i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *) statements->data[i];
if (s)
{
//printf("result = x%x\n", result);
//printf("%s\n", s->toChars());
if (!(result & BEfallthru) && !s->comeFrom())
{
if (global.params.warnings)
{ fprintf(stdmsg, "warning - ");
s->error("statement is not reachable");
}
}
result &= ~BEfallthru;
result |= s->blockExit();
}
}
return result;
}
int CompoundStatement::fallOffEnd()
{ int falloff = TRUE;
@@ -634,15 +691,27 @@ int UnrolledLoopStatement::hasContinue()
int UnrolledLoopStatement::usesEH()
{
for (size_t i = 0; i < statements->dim; i++)
{ Statement *s;
s = (Statement *) statements->data[i];
{ Statement *s = (Statement *) statements->data[i];
if (s && s->usesEH())
return TRUE;
}
return FALSE;
}
int UnrolledLoopStatement::blockExit()
{
int result = BEfallthru;
for (size_t i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *) statements->data[i];
if (s)
{
int r = s->blockExit();
result |= r & ~(BEbreak | BEcontinue);
}
}
return result;
}
int UnrolledLoopStatement::fallOffEnd()
{
//printf("UnrolledLoopStatement::fallOffEnd()\n");
@@ -655,7 +724,6 @@ int UnrolledLoopStatement::fallOffEnd()
return TRUE;
}
int UnrolledLoopStatement::comeFrom()
{ int comefrom = FALSE;
@@ -743,6 +811,12 @@ int ScopeStatement::usesEH()
return statement ? statement->usesEH() : FALSE;
}
int ScopeStatement::blockExit()
{
//printf("ScopeStatement::blockExit(%p)\n", statement);
return statement ? statement->blockExit() : BEfallthru;
}
int ScopeStatement::fallOffEnd()
{
return statement ? statement->fallOffEnd() : TRUE;
@@ -844,6 +918,35 @@ int WhileStatement::usesEH()
return body ? body->usesEH() : 0;
}
int WhileStatement::blockExit()
{
//printf("WhileStatement::blockExit(%p)\n", this);
int result = BEnone;
if (condition->canThrow())
result |= BEthrow;
if (condition->isBool(TRUE))
{
if (body)
{ result |= body->blockExit();
if (result & BEbreak)
result |= BEfallthru;
}
}
else if (condition->isBool(FALSE))
{
result |= BEfallthru;
}
else
{
if (body)
result |= body->blockExit();
result |= BEfallthru;
}
result &= ~(BEbreak | BEcontinue);
return result;
}
int WhileStatement::fallOffEnd()
{
if (body)
@@ -917,6 +1020,28 @@ int DoStatement::usesEH()
return body ? body->usesEH() : 0;
}
int DoStatement::blockExit()
{ int result;
if (body)
{ result = body->blockExit();
if (result == BEbreak)
return BEfallthru;
if (result & BEcontinue)
result |= BEfallthru;
}
else
result = BEfallthru;
if (result & BEfallthru)
{ if (condition->canThrow())
result |= BEthrow;
if (!(result & BEbreak) && condition->isBool(TRUE))
result &= ~BEfallthru;
}
result &= ~(BEbreak | BEcontinue);
return result;
}
int DoStatement::fallOffEnd()
{
if (body)
@@ -1024,6 +1149,31 @@ int ForStatement::usesEH()
return (init && init->usesEH()) || body->usesEH();
}
int ForStatement::blockExit()
{ int result = BEfallthru;
if (init)
{ result = init->blockExit();
if (!(result & BEfallthru))
return result;
}
if (condition)
{ if (condition->canThrow())
result |= BEthrow;
}
else
result &= ~BEfallthru; // the body must do the exiting
if (body)
{ int r = body->blockExit();
if (r & BEbreak)
result |= BEfallthru;
result |= r & ~(BEbreak | BEcontinue);
}
if (increment && increment->canThrow())
result |= BEthrow;
return result;
}
int ForStatement::fallOffEnd()
{
if (body)
@@ -1216,10 +1366,6 @@ Statement *ForeachStatement::semantic(Scope *sc)
VarDeclaration *v = new VarDeclaration(loc, arg->type, arg->ident, ie);
if (e->isConst())
v->storage_class |= STCconst;
#if V2
else
v->storage_class |= STCfinal;
#endif
var = v;
}
}
@@ -1589,6 +1735,19 @@ int ForeachStatement::usesEH()
return body->usesEH();
}
int ForeachStatement::blockExit()
{ int result = BEfallthru;
if (aggr->canThrow())
result |= BEthrow;
if (body)
{
result |= body->blockExit() & ~(BEbreak | BEcontinue);
}
return result;
}
int ForeachStatement::fallOffEnd()
{
if (body)
@@ -1607,7 +1766,6 @@ void ForeachStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring(Token::toChars(op));
buf->writestring(" (");
int i;
for (int i = 0; i < arguments->dim; i++)
{
Argument *a = (Argument *)arguments->data[i];
@@ -1718,6 +1876,42 @@ int IfStatement::usesEH()
return (ifbody && ifbody->usesEH()) || (elsebody && elsebody->usesEH());
}
int IfStatement::blockExit()
{
//printf("IfStatement::blockExit(%p)\n", this);
int result = BEnone;
if (condition->canThrow())
result |= BEthrow;
if (condition->isBool(TRUE))
{
if (ifbody)
result |= ifbody->blockExit();
else
result |= BEfallthru;
}
else if (condition->isBool(FALSE))
{
if (elsebody)
result |= elsebody->blockExit();
else
result |= BEfallthru;
}
else
{
if (ifbody)
result |= ifbody->blockExit();
else
result |= BEfallthru;
if (elsebody)
result |= elsebody->blockExit();
else
result |= BEfallthru;
}
//printf("IfStatement::blockExit(%p) = x%x\n", this, result);
return result;
}
int IfStatement::fallOffEnd()
{
if (!ifbody || ifbody->fallOffEnd() ||
@@ -1812,13 +2006,21 @@ void ConditionalStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
condition->toCBuffer(buf, hgs);
buf->writenl();
buf->writeByte('{');
buf->writenl();
if (ifbody)
ifbody->toCBuffer(buf, hgs);
buf->writeByte('}');
buf->writenl();
if (elsebody)
{
buf->writestring("else");
buf->writenl();
buf->writeByte('{');
buf->writenl();
elsebody->toCBuffer(buf, hgs);
buf->writeByte('}');
buf->writenl();
}
buf->writenl();
}
@@ -1908,6 +2110,18 @@ int PragmaStatement::usesEH()
return body && body->usesEH();
}
int PragmaStatement::blockExit()
{
int result = BEfallthru;
#if 0 // currently, no code is generated for Pragma's, so it's just fallthru
if (arrayExpressionCanThrow(args))
result |= BEthrow;
if (body)
result |= body->blockExit();
#endif
return result;
}
int PragmaStatement::fallOffEnd()
{
if (body)
@@ -2097,6 +2311,24 @@ int SwitchStatement::usesEH()
return body ? body->usesEH() : 0;
}
int SwitchStatement::blockExit()
{ int result = BEnone;
if (condition->canThrow())
result |= BEthrow;
if (body)
{ result |= body->blockExit();
if (result & BEbreak)
{ result |= BEfallthru;
result &= ~BEbreak;
}
}
else
result |= BEfallthru;
return result;
}
int SwitchStatement::fallOffEnd()
{
if (body)
@@ -2204,6 +2436,11 @@ int CaseStatement::usesEH()
return statement->usesEH();
}
int CaseStatement::blockExit()
{
return statement->blockExit();
}
int CaseStatement::fallOffEnd()
{
return statement->fallOffEnd();
@@ -2243,6 +2480,7 @@ Statement *DefaultStatement::syntaxCopy()
Statement *DefaultStatement::semantic(Scope *sc)
{
//printf("DefaultStatement::semantic()\n");
if (sc->sw)
{
if (sc->sw->sdefault)
@@ -2262,6 +2500,11 @@ int DefaultStatement::usesEH()
return statement->usesEH();
}
int DefaultStatement::blockExit()
{
return statement->blockExit();
}
int DefaultStatement::fallOffEnd()
{
return statement->fallOffEnd();
@@ -2302,6 +2545,11 @@ Statement *GotoDefaultStatement::semantic(Scope *sc)
return this;
}
int GotoDefaultStatement::blockExit()
{
return BEgoto;
}
int GotoDefaultStatement::fallOffEnd()
{
return FALSE;
@@ -2351,6 +2599,11 @@ Statement *GotoCaseStatement::semantic(Scope *sc)
return this;
}
int GotoCaseStatement::blockExit()
{
return BEgoto;
}
int GotoCaseStatement::fallOffEnd()
{
return FALSE;
@@ -2374,6 +2627,11 @@ SwitchErrorStatement::SwitchErrorStatement(Loc loc)
{
}
int SwitchErrorStatement::blockExit()
{
return BEthrow;
}
int SwitchErrorStatement::fallOffEnd()
{
return FALSE;
@@ -2427,6 +2685,8 @@ Statement *ReturnStatement::semantic(Scope *sc)
Type *tret = fd->type->nextOf();
if (fd->tintro)
/* We'll be implicitly casting the return expression to tintro
*/
tret = fd->tintro->nextOf();
Type *tbret = NULL;
@@ -2636,9 +2896,13 @@ Statement *ReturnStatement::semantic(Scope *sc)
}
if (exp && tbret->ty == Tvoid && !fd->isMain())
{ Statement *s;
s = new ExpStatement(loc, exp);
{
/* Replace:
* return exp;
* with:
* exp; return;
*/
Statement *s = new ExpStatement(loc, exp);
loc = 0;
exp = NULL;
return new CompoundStatement(loc, s, this);
@@ -2647,6 +2911,14 @@ Statement *ReturnStatement::semantic(Scope *sc)
return this;
}
int ReturnStatement::blockExit()
{ int result = BEreturn;
if (exp && exp->canThrow())
result |= BEthrow;
return result;
}
int ReturnStatement::fallOffEnd()
{
return FALSE;
@@ -2678,6 +2950,7 @@ Statement *BreakStatement::syntaxCopy()
Statement *BreakStatement::semantic(Scope *sc)
{
//printf("BreakStatement::semantic()\n");
enclosinghandler = sc->tfOfTry;
// If:
// break Identifier;
@@ -2739,6 +3012,12 @@ Statement *BreakStatement::semantic(Scope *sc)
return this;
}
int BreakStatement::blockExit()
{
//printf("BreakStatement::blockExit(%p) = x%x\n", this, ident ? BEgoto : BEbreak);
return ident ? BEgoto : BEbreak;
}
int BreakStatement::fallOffEnd()
{
return FALSE;
@@ -2842,6 +3121,11 @@ Statement *ContinueStatement::semantic(Scope *sc)
return this;
}
int ContinueStatement::blockExit()
{
return ident ? BEgoto : BEcontinue;
}
int ContinueStatement::fallOffEnd()
{
return FALSE;
@@ -2932,6 +3216,11 @@ int SynchronizedStatement::usesEH()
return TRUE;
}
int SynchronizedStatement::blockExit()
{
return body ? body->blockExit() : BEfallthru;
}
int SynchronizedStatement::fallOffEnd()
{
return body ? body->fallOffEnd() : TRUE;
@@ -3042,6 +3331,18 @@ int WithStatement::usesEH()
return body ? body->usesEH() : 0;
}
int WithStatement::blockExit()
{
int result = BEnone;
if (exp->canThrow())
result = BEthrow;
if (body)
result |= body->blockExit();
else
result |= BEfallthru;
return result;
}
int WithStatement::fallOffEnd()
{
return body ? body->fallOffEnd() : TRUE;
@@ -3075,14 +3376,14 @@ Statement *TryCatchStatement::semantic(Scope *sc)
{
body = body->semanticScope(sc, NULL /*this*/, NULL);
for (int i = 0; i < catches->dim; i++)
{ Catch *c;
c = (Catch *)catches->data[i];
/* Even if body is NULL, still do semantic analysis on catches
*/
for (size_t i = 0; i < catches->dim; i++)
{ Catch *c = (Catch *)catches->data[i];
c->semantic(sc);
// Determine if current catch 'hides' any previous catches
for (int j = 0; j < i; j++)
for (size_t j = 0; j < i; j++)
{ Catch *cj = (Catch *)catches->data[j];
char *si = c->loc.toChars();
char *sj = cj->loc.toChars();
@@ -3104,6 +3405,20 @@ int TryCatchStatement::usesEH()
return TRUE;
}
int TryCatchStatement::blockExit()
{ int result;
assert(body);
result = body->blockExit();
for (size_t i = 0; i < catches->dim; i++)
{
Catch *c = (Catch *)catches->data[i];
result |= c->blockExit();
}
return result;
}
int TryCatchStatement::fallOffEnd()
{
int result = FALSE;
@@ -3126,8 +3441,7 @@ void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
if (body)
body->toCBuffer(buf, hgs);
int i;
for (i = 0; i < catches->dim; i++)
for (size_t i = 0; i < catches->dim; i++)
{
Catch *c = (Catch *)catches->data[i];
c->toCBuffer(buf, hgs);
@@ -3193,6 +3507,11 @@ void Catch::semantic(Scope *sc)
sc->pop();
}
int Catch::blockExit()
{
return handler ? handler->blockExit() : BEfallthru;
}
void Catch::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("catch");
@@ -3204,7 +3523,8 @@ void Catch::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
buf->writebyte('{');
buf->writenl();
handler->toCBuffer(buf, hgs);
if (handler)
handler->toCBuffer(buf, hgs);
buf->writebyte('}');
buf->writenl();
}
@@ -3269,6 +3589,12 @@ int TryFinallyStatement::usesEH()
return TRUE;
}
int TryFinallyStatement::blockExit()
{
int result = body->blockExit();
return result;
}
int TryFinallyStatement::fallOffEnd()
{ int result;
@@ -3300,6 +3626,11 @@ Statement *OnScopeStatement::semantic(Scope *sc)
return this;
}
int OnScopeStatement::blockExit()
{ // At this point, this statement is just an empty placeholder
return BEfallthru;
}
void OnScopeStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring(Token::toChars(tok));
@@ -3391,6 +3722,11 @@ Statement *ThrowStatement::semantic(Scope *sc)
return this;
}
int ThrowStatement::blockExit()
{
return BEthrow; // obviously
}
int ThrowStatement::fallOffEnd()
{
return FALSE;
@@ -3449,6 +3785,11 @@ Statements *VolatileStatement::flatten(Scope *sc)
return a;
}
int VolatileStatement::blockExit()
{
return statement ? statement->blockExit() : BEfallthru;
}
int VolatileStatement::fallOffEnd()
{
return statement ? statement->fallOffEnd() : TRUE;
@@ -3512,6 +3853,12 @@ Statement *GotoStatement::semantic(Scope *sc)
return this;
}
int GotoStatement::blockExit()
{
//printf("GotoStatement::blockExit(%p)\n", this);
return BEgoto;
}
int GotoStatement::fallOffEnd()
{
return FALSE;
@@ -3601,6 +3948,12 @@ int LabelStatement::usesEH()
return statement ? statement->usesEH() : FALSE;
}
int LabelStatement::blockExit()
{
//printf("LabelStatement::blockExit(%p)\n", this);
return statement ? statement->blockExit() : BEfallthru;
}
int LabelStatement::fallOffEnd()
{
return statement ? statement->fallOffEnd() : TRUE;

File diff suppressed because it is too large Load Diff

View File

@@ -86,11 +86,11 @@ void StaticAssert::inlineScan()
{
}
void StaticAssert::toObjFile()
void StaticAssert::toObjFile(int multiobj)
{
}
char *StaticAssert::kind()
const char *StaticAssert::kind()
{
return "static assert";
}

View File

@@ -35,8 +35,8 @@ struct StaticAssert : Dsymbol
void semantic2(Scope *sc);
void inlineScan();
int oneMember(Dsymbol **ps);
void toObjFile();
char *kind();
void toObjFile(int multiobj);
const char *kind();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};

View File

@@ -1,8 +1,8 @@
// Copyright (c) 1999-2006 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// 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.

View File

@@ -1,7 +1,7 @@
// Copyright (c) 1999-2002 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// www.digitalmars.com
// 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.

View File

@@ -254,6 +254,8 @@ void StructDeclaration::semantic(Scope *sc)
handle = type->pointerTo();
structalign = sc->structalign;
protection = sc->protection;
if (sc->stc & STCdeprecated)
isdeprecated = 1;
assert(!isAnonymous());
if (sc->stc & STCabstract)
error("structs, unions cannot be abstract");
@@ -450,7 +452,7 @@ void StructDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
}
char *StructDeclaration::kind()
const char *StructDeclaration::kind()
{
return "struct";
}
@@ -475,7 +477,7 @@ Dsymbol *UnionDeclaration::syntaxCopy(Dsymbol *s)
}
char *UnionDeclaration::kind()
const char *UnionDeclaration::kind()
{
return "union";
}

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,7 @@ struct Identifier;
struct TemplateInstance;
struct TemplateParameter;
struct TemplateTypeParameter;
struct TemplateThisParameter;
struct TemplateValueParameter;
struct TemplateAliasParameter;
struct TemplateTupleParameter;
@@ -52,7 +53,7 @@ struct TemplateDeclaration : ScopeDsymbol
TemplateParameters *origParameters; // originals for Ddoc
Array instances; // array of TemplateInstance's
Array instances; // array of TemplateInstance's
TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
TemplateDeclaration *overroot; // first in overnext list
@@ -65,7 +66,7 @@ struct TemplateDeclaration : ScopeDsymbol
void semantic(Scope *sc);
int overloadInsert(Dsymbol *s);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *kind();
const char *kind();
char *toChars();
void emitComment(Scope *sc);
@@ -152,6 +153,23 @@ struct TemplateTypeParameter : TemplateParameter
void *dummyArg();
};
#if DMDV2
struct TemplateThisParameter : TemplateTypeParameter
{
/* Syntax:
* this ident : specType = defaultType
*/
Type *specType; // type parameter: if !=NULL, this is the type specialization
Type *defaultType;
TemplateThisParameter(Loc loc, Identifier *ident, Type *specType, Type *defaultType);
TemplateThisParameter *isTemplateThisParameter();
TemplateParameter *syntaxCopy();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};
#endif
struct TemplateValueParameter : TemplateParameter
{
/* Syntax:
@@ -251,6 +269,7 @@ struct TemplateInstance : ScopeDsymbol
// sole member
WithScopeSymbol *withsym; // if a member of a with statement
int semanticdone; // has semantic() been done?
int semantictiargsdone; // has semanticTiargs() been done?
int nest; // for recursion detection
int havetempdecl; // 1 if used second constructor
Dsymbol *isnested; // if referencing local symbols, this is the context
@@ -272,12 +291,12 @@ struct TemplateInstance : ScopeDsymbol
void inlineScan();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Dsymbol *toAlias(); // resolve real symbol
char *kind();
const char *kind();
int oneMember(Dsymbol **ps);
char *toChars();
char *mangle();
void toObjFile(); // compile to .obj file
void toObjFile(int multiobj); // compile to .obj file
// Internal
static void semanticTiargs(Loc loc, Scope *sc, Objects *tiargs);
@@ -305,14 +324,14 @@ struct TemplateMixin : TemplateInstance
void semantic2(Scope *sc);
void semantic3(Scope *sc);
void inlineScan();
char *kind();
const char *kind();
int oneMember(Dsymbol **ps);
int hasPointers();
char *toChars();
char *mangle();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void toObjFile(); // compile to .obj file
void toObjFile(int multiobj); // compile to .obj file
TemplateMixin *isTemplateMixin() { return this; }
};

View File

@@ -93,7 +93,7 @@ void DebugSymbol::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
}
char *DebugSymbol::kind()
const char *DebugSymbol::kind()
{
return "debug";
}
@@ -173,7 +173,7 @@ void VersionSymbol::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writenl();
}
char *VersionSymbol::kind()
const char *VersionSymbol::kind()
{
return "version";
}

View File

@@ -31,7 +31,7 @@ struct DebugSymbol : Dsymbol
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *kind();
const char *kind();
};
struct VersionSymbol : Dsymbol
@@ -45,7 +45,7 @@ struct VersionSymbol : Dsymbol
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *kind();
const char *kind();
};
#endif /* DMD_VERSION_H */

View File

@@ -165,6 +165,12 @@ Statement *AsmStatement::semantic(Scope *sc)
return this;
}
int AsmStatement::blockExit()
{
//printf("AsmStatement::blockExit(%p)\n", this);
return BEfallthru | BEreturn | BEgoto | BEhalt;
}
void
AsmStatement::toIR(IRState * irs)
{

View File

@@ -80,7 +80,7 @@ static void LLVM_AddBaseClassData(BaseClasses* bcs)
for (int k=0; k < arr->dim; k++) {
VarDeclaration* v = (VarDeclaration*)(arr->data[k]);
v->toObjFile();
v->toObjFile(0); // TODO: multiobj
}
}
}
@@ -147,7 +147,7 @@ void DtoResolveClass(ClassDeclaration* cd)
if(cd->members) {
for (int k=0; k < cd->members->dim; k++) {
Dsymbol* dsym = (Dsymbol*)(cd->members->data[k]);
dsym->toObjFile();
dsym->toObjFile(0); // TODO: multiobj
}
}

View File

@@ -1,12 +1,12 @@
#include "gen/llvm.h"
#include "declaration.h"
#include "gen/tollvm.h"
#include "gen/irstate.h"
#include "gen/logger.h"
#include "gen/dvalue.h"
#include "declaration.h"
/////////////////////////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////////////////////////

View File

@@ -86,7 +86,7 @@ const llvm::FunctionType* DtoFunctionType(Type* type, const LLType* thistype, bo
if (typesafeVararg) {
ClassDeclaration* ti = Type::typeinfo;
ti->toObjFile();
ti->toObjFile(0); // TODO: multiobj
DtoForceConstInitDsymbol(ti);
assert(ti->ir.irStruct->constInit);
std::vector<const LLType*> types;

View File

@@ -131,7 +131,7 @@ void DtoResolveStruct(StructDeclaration* sd)
Array* arr = &sd->fields;
for (int k=0; k < arr->dim; k++) {
VarDeclaration* v = (VarDeclaration*)arr->data[k];
v->toObjFile();
v->toObjFile(0); // TODO: multiobj
}
bool thisModule = false;
@@ -144,11 +144,11 @@ void DtoResolveStruct(StructDeclaration* sd)
Dsymbol* s = (Dsymbol*)arr->data[k];
if (FuncDeclaration* fd = s->isFuncDeclaration()) {
if (thisModule || (fd->prot() != PROTprivate)) {
fd->toObjFile();
fd->toObjFile(0); // TODO: multiobj
}
}
else if (s->isAttribDeclaration()) {
s->toObjFile();
s->toObjFile(0); // TODO: multiobj
}
else {
Logger::println("Ignoring dsymbol '%s' in this->members of kind '%s'", s->toPrettyChars(), s->kind());

View File

@@ -52,7 +52,7 @@ DValue* DeclarationExp::toElem(IRState* p)
// static
if (vd->isDataseg())
{
vd->toObjFile(); // TODO
vd->toObjFile(0); // TODO: multiobj
}
else
{
@@ -245,7 +245,7 @@ DValue* VarExp::toElem(IRState* p)
else {
// take care of forward references of global variables
if (vd->isDataseg() || (vd->storage_class & STCextern)) {
vd->toObjFile();
vd->toObjFile(0); // TODO: multiobj
DtoConstInitGlobal(vd);
}
if (!vd->ir.getIrValue() || DtoType(vd->type)->isAbstract()) {

View File

@@ -53,7 +53,7 @@ void llvmdc_optimize_module(llvm::Module* m, char lvl, bool doinline);
//////////////////////////////////////////////////////////////////////////////////////////
void Module::genobjfile()
void Module::genobjfile(int multiobj)
{
Logger::cout() << "Generating module: " << (md ? md->toChars() : toChars()) << '\n';
LOG_SCOPE;
@@ -120,7 +120,7 @@ void Module::genobjfile()
for (int k=0; k < members->dim; k++) {
Dsymbol* dsym = (Dsymbol*)(members->data[k]);
assert(dsym);
dsym->toObjFile();
dsym->toObjFile(multiobj);
}
// main driver loop
@@ -550,7 +550,7 @@ void Module::genmoduleinfo()
/* ================================================================== */
void Dsymbol::toObjFile()
void Dsymbol::toObjFile(int multiobj)
{
Logger::println("Ignoring Dsymbol::toObjFile for %s", toChars());
}
@@ -564,7 +564,7 @@ void Declaration::toObjFile()
/* ================================================================== */
void InterfaceDeclaration::toObjFile()
void InterfaceDeclaration::toObjFile(int multiobj)
{
//Logger::println("Ignoring InterfaceDeclaration::toObjFile for %s", toChars());
gIR->resolveList.push_back(this);
@@ -572,14 +572,14 @@ void InterfaceDeclaration::toObjFile()
/* ================================================================== */
void StructDeclaration::toObjFile()
void StructDeclaration::toObjFile(int multiobj)
{
gIR->resolveList.push_back(this);
}
/* ================================================================== */
void ClassDeclaration::toObjFile()
void ClassDeclaration::toObjFile(int multiobj)
{
gIR->resolveList.push_back(this);
}
@@ -596,7 +596,7 @@ unsigned ClassDeclaration::baseVtblOffset(BaseClass *bc)
/* ================================================================== */
void VarDeclaration::toObjFile()
void VarDeclaration::toObjFile(int multiobj)
{
Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars());
LOG_SCOPE;
@@ -604,7 +604,7 @@ void VarDeclaration::toObjFile()
if (aliassym)
{
Logger::println("alias sym");
toAlias()->toObjFile();
toAlias()->toObjFile(multiobj);
return;
}
@@ -669,7 +669,7 @@ void VarDeclaration::toObjFile()
/* ================================================================== */
void TypedefDeclaration::toObjFile()
void TypedefDeclaration::toObjFile(int multiobj)
{
static int tdi = 0;
Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars());
@@ -681,14 +681,14 @@ void TypedefDeclaration::toObjFile()
/* ================================================================== */
void EnumDeclaration::toObjFile()
void EnumDeclaration::toObjFile(int multiobj)
{
Logger::println("Ignoring EnumDeclaration::toObjFile for %s", toChars());
}
/* ================================================================== */
void FuncDeclaration::toObjFile()
void FuncDeclaration::toObjFile(int multiobj)
{
gIR->resolveList.push_back(this);
}

View File

@@ -123,7 +123,7 @@ Expression *Type::getTypeInfo(Scope *sc)
}
else // if in obj generation pass
{
t->vtinfo->toObjFile();
t->vtinfo->toObjFile(0); // TODO: multiobj
}
}
}
@@ -244,7 +244,7 @@ Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
// MAGIC PLACE
//////////////////////////////////////////////////////////////////////////////
void TypeInfoDeclaration::toObjFile()
void TypeInfoDeclaration::toObjFile(int multiobj)
{
gIR->resolveList.push_back(this);
}

View File

@@ -18,6 +18,9 @@ else
end
end
-- D version - don't change these !!!
DMDV1 = "1"
-- idgen
package = newpackage()
package.name = "idgen"
@@ -26,6 +29,7 @@ package.language = "c++"
package.files = { "dmd/idgen.c" }
package.buildoptions = { "-x c++" }
package.postbuildcommands = { "./idgen", "mv -f id.c id.h dmd" }
package.defines = { "DMDV1="..DMDV1 }
-- impcnvgen
package = newpackage()
@@ -35,6 +39,14 @@ package.language = "c++"
package.files = { "dmd/impcnvgen.c" }
package.buildoptions = { "-x c++" }
package.postbuildcommands = { "./impcnvgen", "mv -f impcnvtab.c dmd" }
package.defines = { "DMDV1="..DMDV1 }
--md5
package = newpackage()
package.name = "md5"
package.kind = "lib"
package.language = "c"
package.files = { "dmd/md5.c" }
-- llvmdc
package = newpackage()
@@ -43,7 +55,7 @@ package.name = "llvmdc"
package.kind = "exe"
package.language = "c++"
package.files = { matchfiles("dmd/*.c"), matchfiles("gen/*.cpp"), matchfiles("ir/*.cpp") }
package.excludes = { "dmd/idgen.c", "dmd/impcnvgen.c" }
package.excludes = { "dmd/idgen.c", "dmd/impcnvgen.c", "dmd/md5.c" }
package.buildoptions = { "-x c++", "`llvm-config --cxxflags`" }
package.linkoptions = {
-- long but it's faster than just 'all'
@@ -55,6 +67,7 @@ package.defines = {
"_DH",
"OPAQUE_VTBLS="..OPAQUE_VTBLS,
"USE_BOEHM_GC="..USE_BOEHM_GC,
"DMDV1="..DMDV1,
}
package.config.Release.defines = { "LLVMD_NO_LOGGER" }
package.config.Debug.buildoptions = { "-g -O0" }