mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-12 09:53:14 +01:00
[svn r357] Merged DMD 1.033
This commit is contained in:
847
dmd/access.c
847
dmd/access.c
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
151
dmd/attrib.c
151
dmd/attrib.c
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
14
dmd/attrib.h
14
dmd/attrib.h
@@ -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);
|
||||
};
|
||||
|
||||
67
dmd/cast.c
67
dmd/cast.c
@@ -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))
|
||||
{
|
||||
|
||||
21
dmd/class.c
21
dmd/class.c
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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];
|
||||
|
||||
3018
dmd/constfold.c
3018
dmd/constfold.c
File diff suppressed because it is too large
Load Diff
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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();
|
||||
|
||||
50
dmd/doc.c
50
dmd/doc.c
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
16
dmd/enum.c
16
dmd/enum.c
@@ -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";
|
||||
}
|
||||
|
||||
22
dmd/enum.h
22
dmd/enum.h
@@ -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);
|
||||
|
||||
374
dmd/expression.c
374
dmd/expression.c
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
121
dmd/func.c
121
dmd/func.c
@@ -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";
|
||||
}
|
||||
|
||||
4
dmd/id.c
4
dmd/id.c
@@ -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");
|
||||
|
||||
2
dmd/id.h
2
dmd/id.h
@@ -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;
|
||||
|
||||
606
dmd/idgen.c
606
dmd/idgen.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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
1170
dmd/init.c
File diff suppressed because it is too large
Load Diff
@@ -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
|
||||
|
||||
@@ -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;
|
||||
|
||||
20
dmd/lexer.c
20
dmd/lexer.c
@@ -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] = "<";
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
1965
dmd/module.c
1965
dmd/module.c
File diff suppressed because it is too large
Load Diff
372
dmd/module.h
372
dmd/module.h
@@ -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 */
|
||||
|
||||
77
dmd/mtype.c
77
dmd/mtype.c
@@ -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())
|
||||
|
||||
@@ -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);
|
||||
|
||||
1504
dmd/optimize.c
1504
dmd/optimize.c
File diff suppressed because it is too large
Load Diff
10075
dmd/parse.c
10075
dmd/parse.c
File diff suppressed because it is too large
Load Diff
@@ -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
3691
dmd/root.c
File diff suppressed because it is too large
Load Diff
@@ -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);
|
||||
|
||||
437
dmd/statement.c
437
dmd/statement.c
@@ -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;
|
||||
|
||||
1774
dmd/statement.h
1774
dmd/statement.h
File diff suppressed because it is too large
Load Diff
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
};
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
8455
dmd/template.c
8455
dmd/template.c
File diff suppressed because it is too large
Load Diff
@@ -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; }
|
||||
};
|
||||
|
||||
@@ -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";
|
||||
}
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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());
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
15
premake.lua
15
premake.lua
@@ -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" }
|
||||
|
||||
Reference in New Issue
Block a user