mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-02-22 14:43:14 +01:00
Updated to 2.049
This commit is contained in:
@@ -10,11 +10,14 @@ syntax: glob
|
||||
*.so
|
||||
*.swp
|
||||
*.rej
|
||||
*~
|
||||
Makefile
|
||||
CMakeFiles
|
||||
CMakeCache.txt
|
||||
cmake_install.cmake
|
||||
.DS_Store
|
||||
CMakeLists.txt.user
|
||||
.directory
|
||||
|
||||
syntax: regexp
|
||||
^obj/
|
||||
|
||||
850
dmd2/access.c
850
dmd2/access.c
@@ -1,425 +1,425 @@
|
||||
|
||||
// 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 "rmem.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->getModule() != sc->module)
|
||||
if (d->prot() == PROTprivate ||
|
||||
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 "rmem.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->getModule() != sc->module)
|
||||
if (d->prot() == PROTprivate ||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
675
dmd2/aggregate.h
675
dmd2/aggregate.h
@@ -1,325 +1,350 @@
|
||||
|
||||
// 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_AGGREGATE_H
|
||||
#define DMD_AGGREGATE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
#include "dsymbol.h"
|
||||
|
||||
#if IN_LLVM
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#endif
|
||||
|
||||
struct Identifier;
|
||||
struct Type;
|
||||
struct TypeFunction;
|
||||
struct Expression;
|
||||
struct FuncDeclaration;
|
||||
struct CtorDeclaration;
|
||||
struct DtorDeclaration;
|
||||
struct InvariantDeclaration;
|
||||
struct NewDeclaration;
|
||||
struct DeleteDeclaration;
|
||||
struct InterfaceDeclaration;
|
||||
struct ClassInfoDeclaration;
|
||||
struct VarDeclaration;
|
||||
struct dt_t;
|
||||
|
||||
#if IN_LLVM
|
||||
namespace llvm
|
||||
{
|
||||
class Type;
|
||||
class Value;
|
||||
class Constant;
|
||||
class ConstantStruct;
|
||||
class GlobalVariable;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct AggregateDeclaration : ScopeDsymbol
|
||||
{
|
||||
Type *type;
|
||||
unsigned storage_class;
|
||||
enum PROT protection;
|
||||
Type *handle; // 'this' type
|
||||
unsigned structsize; // size of struct
|
||||
unsigned alignsize; // size of struct for alignment purposes
|
||||
unsigned structalign; // struct member alignment in effect
|
||||
int hasUnions; // set if aggregate has overlapping fields
|
||||
Array fields; // VarDeclaration fields
|
||||
unsigned sizeok; // set when structsize contains valid data
|
||||
// 0: no size
|
||||
// 1: size is correct
|
||||
// 2: cannot determine size; fwd referenced
|
||||
int isdeprecated; // !=0 if deprecated
|
||||
Scope *scope; // !=NULL means context to use
|
||||
|
||||
int isnested; // !=0 if is nested
|
||||
VarDeclaration *vthis; // 'this' parameter if this aggregate is nested
|
||||
|
||||
// Special member functions
|
||||
InvariantDeclaration *inv; // invariant
|
||||
NewDeclaration *aggNew; // allocator
|
||||
DeleteDeclaration *aggDelete; // deallocator
|
||||
|
||||
#if DMDV2
|
||||
//CtorDeclaration *ctor;
|
||||
Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration
|
||||
CtorDeclaration *defaultCtor; // default constructor
|
||||
Dsymbol *aliasthis; // forward unresolved lookups to aliasthis
|
||||
#endif
|
||||
|
||||
FuncDeclarations dtors; // Array of destructors
|
||||
FuncDeclaration *dtor; // aggregate destructor
|
||||
|
||||
#ifdef IN_GCC
|
||||
Array methods; // flat list of all methods for debug information
|
||||
#endif
|
||||
|
||||
AggregateDeclaration(Loc loc, Identifier *id);
|
||||
void semantic2(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void inlineScan();
|
||||
unsigned size(Loc loc);
|
||||
static void alignmember(unsigned salign, unsigned size, unsigned *poffset);
|
||||
Type *getType();
|
||||
void addField(Scope *sc, VarDeclaration *v);
|
||||
int isDeprecated(); // is aggregate deprecated?
|
||||
FuncDeclaration *buildDtor(Scope *sc);
|
||||
int isNested();
|
||||
|
||||
void emitComment(Scope *sc);
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
// For access checking
|
||||
virtual PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
int isFriendOf(AggregateDeclaration *cd);
|
||||
int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class?
|
||||
void accessCheck(Loc loc, Scope *sc, Dsymbol *smember);
|
||||
|
||||
enum PROT prot();
|
||||
|
||||
#if IN_DMD
|
||||
// Back end
|
||||
Symbol *stag; // tag symbol for debug data
|
||||
Symbol *sinit;
|
||||
Symbol *toInitializer();
|
||||
#endif
|
||||
|
||||
AggregateDeclaration *isAggregateDeclaration() { return this; }
|
||||
|
||||
#if IN_LLVM
|
||||
// Aggregates that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
|
||||
bool availableExternally;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct AnonymousAggregateDeclaration : AggregateDeclaration
|
||||
{
|
||||
AnonymousAggregateDeclaration()
|
||||
: AggregateDeclaration(0, NULL)
|
||||
{
|
||||
}
|
||||
|
||||
AnonymousAggregateDeclaration *isAnonymousAggregateDeclaration() { return this; }
|
||||
};
|
||||
|
||||
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();
|
||||
const char *kind();
|
||||
int needOpAssign();
|
||||
FuncDeclaration *buildOpAssign(Scope *sc);
|
||||
FuncDeclaration *buildPostBlit(Scope *sc);
|
||||
FuncDeclaration *buildCpCtor(Scope *sc);
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
void toDt(dt_t **pdt);
|
||||
void toDebug(); // to symbolic debug info
|
||||
#endif
|
||||
|
||||
StructDeclaration *isStructDeclaration() { return this; }
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct UnionDeclaration : StructDeclaration
|
||||
{
|
||||
UnionDeclaration(Loc loc, Identifier *id);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
const char *kind();
|
||||
|
||||
UnionDeclaration *isUnionDeclaration() { return this; }
|
||||
};
|
||||
|
||||
// warning: two classes with the same base class share the same
|
||||
// BaseClass instance.
|
||||
struct BaseClass
|
||||
{
|
||||
Type *type; // (before semantic processing)
|
||||
enum PROT protection; // protection for the base interface
|
||||
|
||||
ClassDeclaration *base;
|
||||
int offset; // 'this' pointer offset
|
||||
Array vtbl; // for interfaces: Array of FuncDeclaration's
|
||||
// making up the vtbl[]
|
||||
|
||||
int baseInterfaces_dim;
|
||||
BaseClass *baseInterfaces; // if BaseClass is an interface, these
|
||||
// are a copy of the InterfaceDeclaration::interfaces
|
||||
|
||||
BaseClass();
|
||||
BaseClass(Type *type, enum PROT protection);
|
||||
|
||||
int fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance);
|
||||
void copyBaseInterfaces(BaseClasses *);
|
||||
};
|
||||
|
||||
#if DMDV2
|
||||
#define CLASSINFO_SIZE (0x3C+16+4) // value of ClassInfo.size
|
||||
#else
|
||||
#define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
|
||||
#endif
|
||||
|
||||
struct ClassDeclaration : AggregateDeclaration
|
||||
{
|
||||
static ClassDeclaration *object;
|
||||
static ClassDeclaration *classinfo;
|
||||
|
||||
ClassDeclaration *baseClass; // NULL only if this is Object
|
||||
FuncDeclaration *staticCtor;
|
||||
FuncDeclaration *staticDtor;
|
||||
Array vtbl; // Array of FuncDeclaration's making up the vtbl[]
|
||||
Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[]
|
||||
|
||||
BaseClasses baseclasses; // Array of BaseClass's; first is super,
|
||||
// rest are Interface's
|
||||
|
||||
int interfaces_dim;
|
||||
BaseClass **interfaces; // interfaces[interfaces_dim] for this class
|
||||
// (does not include baseClass)
|
||||
|
||||
BaseClasses *vtblInterfaces; // array of base interfaces that have
|
||||
// their own vtbl[]
|
||||
|
||||
ClassInfoDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
||||
int com; // !=0 if this is a COM class (meaning
|
||||
// it derives from IUnknown)
|
||||
int isauto; // !=0 if this is an auto class
|
||||
int isabstract; // !=0 if abstract class
|
||||
|
||||
int inuse; // to prevent recursive attempts
|
||||
|
||||
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
int isBaseOf2(ClassDeclaration *cd);
|
||||
|
||||
#define OFFSET_RUNTIME 0x76543210
|
||||
virtual int isBaseOf(ClassDeclaration *cd, int *poffset);
|
||||
|
||||
Dsymbol *search(Loc, Identifier *ident, int flags);
|
||||
#if DMDV2
|
||||
int isFuncHidden(FuncDeclaration *fd);
|
||||
#endif
|
||||
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
|
||||
void interfaceSemantic(Scope *sc);
|
||||
int isCOMclass();
|
||||
virtual int isCOMinterface();
|
||||
#if DMDV2
|
||||
virtual int isCPPinterface();
|
||||
#endif
|
||||
int isAbstract();
|
||||
virtual int vtblOffset();
|
||||
const char *kind();
|
||||
char *mangle();
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
|
||||
void addLocalClass(ClassDeclarations *);
|
||||
|
||||
#if IN_DMD
|
||||
// Back end
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
void toDebug();
|
||||
unsigned baseVtblOffset(BaseClass *bc);
|
||||
Symbol *toSymbol();
|
||||
Symbol *toVtblSymbol();
|
||||
void toDt(dt_t **pdt);
|
||||
void toDt2(dt_t **pdt, ClassDeclaration *cd);
|
||||
|
||||
Symbol *vtblsym;
|
||||
#endif
|
||||
|
||||
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
|
||||
|
||||
#if IN_LLVM
|
||||
virtual void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct InterfaceDeclaration : ClassDeclaration
|
||||
{
|
||||
#if DMDV2
|
||||
int cpp; // !=0 if this is a C++ interface
|
||||
#endif
|
||||
InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
int isBaseOf(ClassDeclaration *cd, int *poffset);
|
||||
int isBaseOf(BaseClass *bc, int *poffset);
|
||||
const char *kind();
|
||||
int vtblOffset();
|
||||
#if DMDV2
|
||||
int isCPPinterface();
|
||||
#endif
|
||||
virtual int isCOMinterface();
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
Symbol *toSymbol();
|
||||
#endif
|
||||
|
||||
InterfaceDeclaration *isInterfaceDeclaration() { return this; }
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* DMD_AGGREGATE_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_AGGREGATE_H
|
||||
#define DMD_AGGREGATE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
|
||||
#include "dsymbol.h"
|
||||
|
||||
#if IN_LLVM
|
||||
#include <vector>
|
||||
#include <set>
|
||||
#include <map>
|
||||
#endif
|
||||
|
||||
struct Identifier;
|
||||
struct Type;
|
||||
struct TypeFunction;
|
||||
struct Expression;
|
||||
struct FuncDeclaration;
|
||||
struct CtorDeclaration;
|
||||
struct DtorDeclaration;
|
||||
struct InvariantDeclaration;
|
||||
struct NewDeclaration;
|
||||
struct DeleteDeclaration;
|
||||
struct InterfaceDeclaration;
|
||||
struct TypeInfoClassDeclaration;
|
||||
struct VarDeclaration;
|
||||
struct dt_t;
|
||||
|
||||
#if IN_LLVM
|
||||
namespace llvm
|
||||
{
|
||||
class Type;
|
||||
class Value;
|
||||
class Constant;
|
||||
class ConstantStruct;
|
||||
class GlobalVariable;
|
||||
}
|
||||
#endif
|
||||
|
||||
struct AggregateDeclaration : ScopeDsymbol
|
||||
{
|
||||
Type *type;
|
||||
StorageClass storage_class;
|
||||
enum PROT protection;
|
||||
Type *handle; // 'this' type
|
||||
unsigned structsize; // size of struct
|
||||
unsigned alignsize; // size of struct for alignment purposes
|
||||
unsigned structalign; // struct member alignment in effect
|
||||
int hasUnions; // set if aggregate has overlapping fields
|
||||
Array fields; // VarDeclaration fields
|
||||
unsigned sizeok; // set when structsize contains valid data
|
||||
// 0: no size
|
||||
// 1: size is correct
|
||||
// 2: cannot determine size; fwd referenced
|
||||
int isdeprecated; // !=0 if deprecated
|
||||
Scope *scope; // !=NULL means context to use
|
||||
|
||||
#if DMDV2
|
||||
int isnested; // !=0 if is nested
|
||||
VarDeclaration *vthis; // 'this' parameter if this aggregate is nested
|
||||
#endif
|
||||
// Special member functions
|
||||
InvariantDeclaration *inv; // invariant
|
||||
NewDeclaration *aggNew; // allocator
|
||||
DeleteDeclaration *aggDelete; // deallocator
|
||||
|
||||
#if DMDV2
|
||||
//CtorDeclaration *ctor;
|
||||
Dsymbol *ctor; // CtorDeclaration or TemplateDeclaration
|
||||
CtorDeclaration *defaultCtor; // default constructor
|
||||
Dsymbol *aliasthis; // forward unresolved lookups to aliasthis
|
||||
#endif
|
||||
|
||||
FuncDeclarations dtors; // Array of destructors
|
||||
FuncDeclaration *dtor; // aggregate destructor
|
||||
|
||||
#ifdef IN_GCC
|
||||
Array methods; // flat list of all methods for debug information
|
||||
#endif
|
||||
|
||||
AggregateDeclaration(Loc loc, Identifier *id);
|
||||
void semantic2(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void inlineScan();
|
||||
unsigned size(Loc loc);
|
||||
static void alignmember(unsigned salign, unsigned size, unsigned *poffset);
|
||||
Type *getType();
|
||||
void addField(Scope *sc, VarDeclaration *v);
|
||||
int isDeprecated(); // is aggregate deprecated?
|
||||
FuncDeclaration *buildDtor(Scope *sc);
|
||||
int isNested();
|
||||
|
||||
void emitComment(Scope *sc);
|
||||
void toJsonBuffer(OutBuffer *buf);
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
// For access checking
|
||||
virtual PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
int isFriendOf(AggregateDeclaration *cd);
|
||||
int hasPrivateAccess(Dsymbol *smember); // does smember have private access to members of this class?
|
||||
void accessCheck(Loc loc, Scope *sc, Dsymbol *smember);
|
||||
|
||||
enum PROT prot();
|
||||
|
||||
#if IN_DMD
|
||||
// Back end
|
||||
Symbol *stag; // tag symbol for debug data
|
||||
Symbol *sinit;
|
||||
Symbol *toInitializer();
|
||||
#endif
|
||||
|
||||
AggregateDeclaration *isAggregateDeclaration() { return this; }
|
||||
|
||||
#if IN_LLVM
|
||||
// Aggregates that wouldn't have gotten semantic3'ed if we weren't inlining set this flag.
|
||||
bool availableExternally;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct AnonymousAggregateDeclaration : AggregateDeclaration
|
||||
{
|
||||
AnonymousAggregateDeclaration()
|
||||
: AggregateDeclaration(0, NULL)
|
||||
{
|
||||
}
|
||||
|
||||
AnonymousAggregateDeclaration *isAnonymousAggregateDeclaration() { return this; }
|
||||
};
|
||||
|
||||
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
|
||||
FuncDeclaration *eq; // bool opEquals(ref const T), 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);
|
||||
Dsymbol *search(Loc, Identifier *ident, int flags);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
char *mangle();
|
||||
const char *kind();
|
||||
#if DMDV1
|
||||
Expression *cloneMembers();
|
||||
#endif
|
||||
#if DMDV2
|
||||
int needOpAssign();
|
||||
int needOpEquals();
|
||||
FuncDeclaration *buildOpAssign(Scope *sc);
|
||||
FuncDeclaration *buildOpEquals(Scope *sc);
|
||||
FuncDeclaration *buildPostBlit(Scope *sc);
|
||||
FuncDeclaration *buildCpCtor(Scope *sc);
|
||||
#endif
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
void toDt(dt_t **pdt);
|
||||
void toDebug(); // to symbolic debug info
|
||||
#endif
|
||||
|
||||
StructDeclaration *isStructDeclaration() { return this; }
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct UnionDeclaration : StructDeclaration
|
||||
{
|
||||
UnionDeclaration(Loc loc, Identifier *id);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
const char *kind();
|
||||
|
||||
UnionDeclaration *isUnionDeclaration() { return this; }
|
||||
};
|
||||
|
||||
// warning: two classes with the same base class share the same
|
||||
// BaseClass instance.
|
||||
struct BaseClass
|
||||
{
|
||||
Type *type; // (before semantic processing)
|
||||
enum PROT protection; // protection for the base interface
|
||||
|
||||
ClassDeclaration *base;
|
||||
int offset; // 'this' pointer offset
|
||||
Array vtbl; // for interfaces: Array of FuncDeclaration's
|
||||
// making up the vtbl[]
|
||||
|
||||
int baseInterfaces_dim;
|
||||
BaseClass *baseInterfaces; // if BaseClass is an interface, these
|
||||
// are a copy of the InterfaceDeclaration::interfaces
|
||||
|
||||
BaseClass();
|
||||
BaseClass(Type *type, enum PROT protection);
|
||||
|
||||
int fillVtbl(ClassDeclaration *cd, Array *vtbl, int newinstance);
|
||||
void copyBaseInterfaces(BaseClasses *);
|
||||
};
|
||||
|
||||
#if DMDV2
|
||||
#define CLASSINFO_SIZE_64 0x98 // value of ClassInfo.size
|
||||
#define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
|
||||
#else
|
||||
#define CLASSINFO_SIZE (0x3C+12+4) // value of ClassInfo.size
|
||||
#endif
|
||||
|
||||
struct ClassDeclaration : AggregateDeclaration
|
||||
{
|
||||
static ClassDeclaration *object;
|
||||
static ClassDeclaration *classinfo;
|
||||
|
||||
ClassDeclaration *baseClass; // NULL only if this is Object
|
||||
#if DMDV1
|
||||
CtorDeclaration *ctor;
|
||||
CtorDeclaration *defaultCtor; // default constructor
|
||||
#endif
|
||||
FuncDeclaration *staticCtor;
|
||||
FuncDeclaration *staticDtor;
|
||||
Array vtbl; // Array of FuncDeclaration's making up the vtbl[]
|
||||
Array vtblFinal; // More FuncDeclaration's that aren't in vtbl[]
|
||||
|
||||
BaseClasses *baseclasses; // Array of BaseClass's; first is super,
|
||||
// rest are Interface's
|
||||
|
||||
int interfaces_dim;
|
||||
BaseClass **interfaces; // interfaces[interfaces_dim] for this class
|
||||
// (does not include baseClass)
|
||||
|
||||
BaseClasses *vtblInterfaces; // array of base interfaces that have
|
||||
// their own vtbl[]
|
||||
|
||||
TypeInfoClassDeclaration *vclassinfo; // the ClassInfo object for this ClassDeclaration
|
||||
int com; // !=0 if this is a COM class (meaning
|
||||
// it derives from IUnknown)
|
||||
int isscope; // !=0 if this is an auto class
|
||||
int isabstract; // !=0 if abstract class
|
||||
#if DMDV1
|
||||
int isnested; // !=0 if is nested
|
||||
VarDeclaration *vthis; // 'this' parameter if this class is nested
|
||||
#endif
|
||||
int inuse; // to prevent recursive attempts
|
||||
|
||||
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
int isBaseOf2(ClassDeclaration *cd);
|
||||
|
||||
#define OFFSET_RUNTIME 0x76543210
|
||||
virtual int isBaseOf(ClassDeclaration *cd, int *poffset);
|
||||
|
||||
virtual int isBaseInfoComplete();
|
||||
Dsymbol *search(Loc, Identifier *ident, int flags);
|
||||
#if DMDV2
|
||||
int isFuncHidden(FuncDeclaration *fd);
|
||||
#endif
|
||||
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
|
||||
void interfaceSemantic(Scope *sc);
|
||||
#if DMDV1
|
||||
int isNested();
|
||||
#endif
|
||||
int isCOMclass();
|
||||
virtual int isCOMinterface();
|
||||
#if DMDV2
|
||||
virtual int isCPPinterface();
|
||||
#endif
|
||||
int isAbstract();
|
||||
virtual int vtblOffset();
|
||||
const char *kind();
|
||||
char *mangle();
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
PROT getAccess(Dsymbol *smember); // determine access to smember
|
||||
|
||||
void addLocalClass(ClassDeclarations *);
|
||||
|
||||
#if IN_DMD
|
||||
// Back end
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
void toDebug();
|
||||
unsigned baseVtblOffset(BaseClass *bc);
|
||||
Symbol *toSymbol();
|
||||
Symbol *toVtblSymbol();
|
||||
void toDt(dt_t **pdt);
|
||||
void toDt2(dt_t **pdt, ClassDeclaration *cd);
|
||||
|
||||
Symbol *vtblsym;
|
||||
#endif
|
||||
|
||||
ClassDeclaration *isClassDeclaration() { return (ClassDeclaration *)this; }
|
||||
|
||||
#if IN_LLVM
|
||||
virtual void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct InterfaceDeclaration : ClassDeclaration
|
||||
{
|
||||
#if DMDV2
|
||||
int cpp; // !=0 if this is a C++ interface
|
||||
#endif
|
||||
InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
int isBaseOf(ClassDeclaration *cd, int *poffset);
|
||||
int isBaseOf(BaseClass *bc, int *poffset);
|
||||
const char *kind();
|
||||
int isBaseInfoComplete();
|
||||
int vtblOffset();
|
||||
#if DMDV2
|
||||
int isCPPinterface();
|
||||
#endif
|
||||
virtual int isCOMinterface();
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
Symbol *toSymbol();
|
||||
#endif
|
||||
|
||||
InterfaceDeclaration *isInterfaceDeclaration() { return this; }
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
#endif /* DMD_AGGREGATE_H */
|
||||
|
||||
144
dmd2/aliasthis.c
144
dmd2/aliasthis.c
@@ -1,72 +1,72 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 2009-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mars.h"
|
||||
#include "identifier.h"
|
||||
#include "aliasthis.h"
|
||||
#include "scope.h"
|
||||
#include "aggregate.h"
|
||||
#include "dsymbol.h"
|
||||
|
||||
#if DMDV2
|
||||
|
||||
|
||||
AliasThis::AliasThis(Loc loc, Identifier *ident)
|
||||
: Dsymbol(NULL) // it's anonymous (no identifier)
|
||||
{
|
||||
this->loc = loc;
|
||||
this->ident = ident;
|
||||
}
|
||||
|
||||
Dsymbol *AliasThis::syntaxCopy(Dsymbol *s)
|
||||
{
|
||||
assert(!s);
|
||||
/* Since there is no semantic information stored here,
|
||||
* we don't need to copy it.
|
||||
*/
|
||||
return this;
|
||||
}
|
||||
|
||||
void AliasThis::semantic(Scope *sc)
|
||||
{
|
||||
Dsymbol *parent = sc->parent;
|
||||
if (parent)
|
||||
parent = parent->pastMixin();
|
||||
AggregateDeclaration *ad = NULL;
|
||||
if (parent)
|
||||
ad = parent->isAggregateDeclaration();
|
||||
if (ad)
|
||||
{
|
||||
if (ad->aliasthis)
|
||||
error("there can be only one alias this");
|
||||
assert(ad->members);
|
||||
Dsymbol *s = ad->search(loc, ident, 0);
|
||||
ad->aliasthis = s;
|
||||
}
|
||||
else
|
||||
error("alias this can only appear in struct or class declaration, not %s", parent ? parent->toChars() : "nowhere");
|
||||
}
|
||||
|
||||
const char *AliasThis::kind()
|
||||
{
|
||||
return "alias this";
|
||||
}
|
||||
|
||||
void AliasThis::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
buf->writestring("alias ");
|
||||
buf->writestring(ident->toChars());
|
||||
buf->writestring(" this;\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 2009-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mars.h"
|
||||
#include "identifier.h"
|
||||
#include "aliasthis.h"
|
||||
#include "scope.h"
|
||||
#include "aggregate.h"
|
||||
#include "dsymbol.h"
|
||||
|
||||
#if DMDV2
|
||||
|
||||
|
||||
AliasThis::AliasThis(Loc loc, Identifier *ident)
|
||||
: Dsymbol(NULL) // it's anonymous (no identifier)
|
||||
{
|
||||
this->loc = loc;
|
||||
this->ident = ident;
|
||||
}
|
||||
|
||||
Dsymbol *AliasThis::syntaxCopy(Dsymbol *s)
|
||||
{
|
||||
assert(!s);
|
||||
/* Since there is no semantic information stored here,
|
||||
* we don't need to copy it.
|
||||
*/
|
||||
return this;
|
||||
}
|
||||
|
||||
void AliasThis::semantic(Scope *sc)
|
||||
{
|
||||
Dsymbol *parent = sc->parent;
|
||||
if (parent)
|
||||
parent = parent->pastMixin();
|
||||
AggregateDeclaration *ad = NULL;
|
||||
if (parent)
|
||||
ad = parent->isAggregateDeclaration();
|
||||
if (ad)
|
||||
{
|
||||
if (ad->aliasthis)
|
||||
error("there can be only one alias this");
|
||||
assert(ad->members);
|
||||
Dsymbol *s = ad->search(loc, ident, 0);
|
||||
ad->aliasthis = s;
|
||||
}
|
||||
else
|
||||
error("alias this can only appear in struct or class declaration, not %s", parent ? parent->toChars() : "nowhere");
|
||||
}
|
||||
|
||||
const char *AliasThis::kind()
|
||||
{
|
||||
return "alias this";
|
||||
}
|
||||
|
||||
void AliasThis::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
buf->writestring("alias ");
|
||||
buf->writestring(ident->toChars());
|
||||
buf->writestring(" this;\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,41 +1,41 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 2009-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_ALIASTHIS_H
|
||||
#define DMD_ALIASTHIS_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "mars.h"
|
||||
#include "dsymbol.h"
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
#if DMDV2
|
||||
|
||||
struct AliasThis : Dsymbol
|
||||
{
|
||||
// alias Identifier this;
|
||||
Identifier *ident;
|
||||
|
||||
AliasThis(Loc loc, Identifier *ident);
|
||||
|
||||
Dsymbol *syntaxCopy(Dsymbol *);
|
||||
void semantic(Scope *sc);
|
||||
const char *kind();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
AliasThis *isAliasThis() { return this; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 2009-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_ALIASTHIS_H
|
||||
#define DMD_ALIASTHIS_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "mars.h"
|
||||
#include "dsymbol.h"
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
#if DMDV2
|
||||
|
||||
struct AliasThis : Dsymbol
|
||||
{
|
||||
// alias Identifier this;
|
||||
Identifier *ident;
|
||||
|
||||
AliasThis(Loc loc, Identifier *ident);
|
||||
|
||||
Dsymbol *syntaxCopy(Dsymbol *);
|
||||
void semantic(Scope *sc);
|
||||
const char *kind();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
AliasThis *isAliasThis() { return this; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
1154
dmd2/arrayop.c
1154
dmd2/arrayop.c
File diff suppressed because it is too large
Load Diff
@@ -1,51 +1,51 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 2006-2007 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_ARRAYTYPES_H
|
||||
#define DMD_ARRAYTYPES_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
|
||||
#include "root.h"
|
||||
|
||||
struct Expression;
|
||||
struct Statement;
|
||||
struct BaseClass;
|
||||
struct TemplateParameter;
|
||||
struct FuncDeclaration;
|
||||
struct Identifier;
|
||||
struct Initializer;
|
||||
|
||||
struct TemplateParameters : Array { };
|
||||
|
||||
struct Expressions : Array { };
|
||||
|
||||
struct Statements : Array { };
|
||||
|
||||
struct BaseClasses : Array { };
|
||||
|
||||
struct ClassDeclarations : Array { };
|
||||
|
||||
struct Dsymbols : Array { };
|
||||
|
||||
struct Objects : Array { };
|
||||
|
||||
struct FuncDeclarations : Array { };
|
||||
|
||||
struct Arguments : Array { };
|
||||
|
||||
struct Identifiers : Array { };
|
||||
|
||||
struct Initializers : Array { };
|
||||
|
||||
#endif
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 2006-2007 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_ARRAYTYPES_H
|
||||
#define DMD_ARRAYTYPES_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
|
||||
#include "root.h"
|
||||
|
||||
struct Expression;
|
||||
struct Statement;
|
||||
struct BaseClass;
|
||||
struct TemplateParameter;
|
||||
struct FuncDeclaration;
|
||||
struct Identifier;
|
||||
struct Initializer;
|
||||
|
||||
struct TemplateParameters : Array { };
|
||||
|
||||
struct Expressions : Array { };
|
||||
|
||||
struct Statements : Array { };
|
||||
|
||||
struct BaseClasses : Array { };
|
||||
|
||||
struct ClassDeclarations : Array { };
|
||||
|
||||
struct Dsymbols : Array { };
|
||||
|
||||
struct Objects : Array { };
|
||||
|
||||
struct FuncDeclarations : Array { };
|
||||
|
||||
struct Parameters : Array { };
|
||||
|
||||
struct Identifiers : Array { };
|
||||
|
||||
struct Initializers : Array { };
|
||||
|
||||
#endif
|
||||
|
||||
3445
dmd2/attrib.c
3445
dmd2/attrib.c
File diff suppressed because it is too large
Load Diff
397
dmd2/attrib.h
397
dmd2/attrib.h
@@ -1,195 +1,202 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_ATTRIB_H
|
||||
#define DMD_ATTRIB_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "dsymbol.h"
|
||||
|
||||
struct Expression;
|
||||
struct Statement;
|
||||
struct LabelDsymbol;
|
||||
struct Initializer;
|
||||
struct Module;
|
||||
struct Condition;
|
||||
#ifdef _DH
|
||||
struct HdrGenState;
|
||||
#endif
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
struct AttribDeclaration : Dsymbol
|
||||
{
|
||||
Array *decl; // array of Dsymbol's
|
||||
|
||||
AttribDeclaration(Array *decl);
|
||||
virtual Array *include(Scope *sc, ScopeDsymbol *s);
|
||||
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||
void setScopeNewSc(Scope *sc,
|
||||
unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
||||
unsigned structalign);
|
||||
void semanticNewSc(Scope *sc,
|
||||
unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
||||
unsigned structalign);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void inlineScan();
|
||||
void addComment(unsigned char *comment);
|
||||
void emitComment(Scope *sc);
|
||||
const char *kind();
|
||||
int oneMember(Dsymbol **ps);
|
||||
int hasPointers();
|
||||
void checkCtorConstInit();
|
||||
void addLocalClass(ClassDeclarations *);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
AttribDeclaration *isAttribDeclaration() { return this; }
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
int cvMember(unsigned char *p);
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
virtual void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct StorageClassDeclaration: AttribDeclaration
|
||||
{
|
||||
unsigned stc;
|
||||
|
||||
StorageClassDeclaration(unsigned stc, Array *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void setScope(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
static void stcToCBuffer(OutBuffer *buf, int stc);
|
||||
};
|
||||
|
||||
struct LinkDeclaration : AttribDeclaration
|
||||
{
|
||||
enum LINK linkage;
|
||||
|
||||
LinkDeclaration(enum LINK p, Array *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void setScope(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
char *toChars();
|
||||
};
|
||||
|
||||
struct ProtDeclaration : AttribDeclaration
|
||||
{
|
||||
enum PROT protection;
|
||||
|
||||
ProtDeclaration(enum PROT p, Array *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void setScope(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
static void protectionToCBuffer(OutBuffer *buf, enum PROT protection);
|
||||
};
|
||||
|
||||
struct AlignDeclaration : AttribDeclaration
|
||||
{
|
||||
unsigned salign;
|
||||
|
||||
AlignDeclaration(Loc loc, unsigned sa, Array *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void setScope(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
};
|
||||
|
||||
struct AnonDeclaration : AttribDeclaration
|
||||
{
|
||||
int isunion;
|
||||
int sem; // 1 if successful semantic()
|
||||
|
||||
AnonDeclaration(Loc loc, int isunion, Array *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
const char *kind();
|
||||
};
|
||||
|
||||
struct PragmaDeclaration : AttribDeclaration
|
||||
{
|
||||
Expressions *args; // array of Expression's
|
||||
|
||||
PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Array *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void setScope(Scope *sc);
|
||||
int oneMember(Dsymbol **ps);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
const char *kind();
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ConditionalDeclaration : AttribDeclaration
|
||||
{
|
||||
Condition *condition;
|
||||
Array *elsedecl; // array of Dsymbol's for else block
|
||||
|
||||
ConditionalDeclaration(Condition *condition, Array *decl, Array *elsedecl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
int oneMember(Dsymbol **ps);
|
||||
void emitComment(Scope *sc);
|
||||
Array *include(Scope *sc, ScopeDsymbol *s);
|
||||
void addComment(unsigned char *comment);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
};
|
||||
|
||||
struct StaticIfDeclaration : ConditionalDeclaration
|
||||
{
|
||||
ScopeDsymbol *sd;
|
||||
int addisdone;
|
||||
|
||||
StaticIfDeclaration(Condition *condition, Array *decl, Array *elsedecl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||
void semantic(Scope *sc);
|
||||
const char *kind();
|
||||
};
|
||||
|
||||
// Mixin declarations
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
#endif /* DMD_ATTRIB_H */
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2010 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_ATTRIB_H
|
||||
#define DMD_ATTRIB_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "dsymbol.h"
|
||||
|
||||
struct Expression;
|
||||
struct Statement;
|
||||
struct LabelDsymbol;
|
||||
struct Initializer;
|
||||
struct Module;
|
||||
struct Condition;
|
||||
#ifdef _DH
|
||||
struct HdrGenState;
|
||||
#endif
|
||||
|
||||
/**************************************************************/
|
||||
|
||||
struct AttribDeclaration : Dsymbol
|
||||
{
|
||||
Dsymbols *decl; // array of Dsymbol's
|
||||
|
||||
AttribDeclaration(Dsymbols *decl);
|
||||
virtual Dsymbols *include(Scope *sc, ScopeDsymbol *s);
|
||||
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||
void setScopeNewSc(Scope *sc,
|
||||
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
||||
unsigned structalign);
|
||||
void semanticNewSc(Scope *sc,
|
||||
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
|
||||
unsigned structalign);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void inlineScan();
|
||||
void addComment(unsigned char *comment);
|
||||
void emitComment(Scope *sc);
|
||||
const char *kind();
|
||||
int oneMember(Dsymbol **ps);
|
||||
int hasPointers();
|
||||
void checkCtorConstInit();
|
||||
void addLocalClass(ClassDeclarations *);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
void toJsonBuffer(OutBuffer *buf);
|
||||
AttribDeclaration *isAttribDeclaration() { return this; }
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
int cvMember(unsigned char *p);
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
virtual void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct StorageClassDeclaration: AttribDeclaration
|
||||
{
|
||||
StorageClass stc;
|
||||
|
||||
StorageClassDeclaration(StorageClass stc, Dsymbols *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void setScope(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
static void stcToCBuffer(OutBuffer *buf, StorageClass stc);
|
||||
};
|
||||
|
||||
struct LinkDeclaration : AttribDeclaration
|
||||
{
|
||||
enum LINK linkage;
|
||||
|
||||
LinkDeclaration(enum LINK p, Dsymbols *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void setScope(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void semantic3(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
char *toChars();
|
||||
};
|
||||
|
||||
struct ProtDeclaration : AttribDeclaration
|
||||
{
|
||||
enum PROT protection;
|
||||
|
||||
ProtDeclaration(enum PROT p, Dsymbols *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void importAll(Scope *sc);
|
||||
void setScope(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
static void protectionToCBuffer(OutBuffer *buf, enum PROT protection);
|
||||
};
|
||||
|
||||
struct AlignDeclaration : AttribDeclaration
|
||||
{
|
||||
unsigned salign;
|
||||
|
||||
AlignDeclaration(Loc loc, unsigned sa, Dsymbols *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void setScope(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
};
|
||||
|
||||
struct AnonDeclaration : AttribDeclaration
|
||||
{
|
||||
int isunion;
|
||||
int sem; // 1 if successful semantic()
|
||||
|
||||
AnonDeclaration(Loc loc, int isunion, Dsymbols *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
const char *kind();
|
||||
};
|
||||
|
||||
struct PragmaDeclaration : AttribDeclaration
|
||||
{
|
||||
Expressions *args; // array of Expression's
|
||||
|
||||
PragmaDeclaration(Loc loc, Identifier *ident, Expressions *args, Dsymbols *decl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
void setScope(Scope *sc);
|
||||
int oneMember(Dsymbol **ps);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
const char *kind();
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
struct ConditionalDeclaration : AttribDeclaration
|
||||
{
|
||||
Condition *condition;
|
||||
Dsymbols *elsedecl; // array of Dsymbol's for else block
|
||||
|
||||
ConditionalDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
int oneMember(Dsymbol **ps);
|
||||
void emitComment(Scope *sc);
|
||||
Dsymbols *include(Scope *sc, ScopeDsymbol *s);
|
||||
void addComment(unsigned char *comment);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
void toJsonBuffer(OutBuffer *buf);
|
||||
void importAll(Scope *sc);
|
||||
void setScope(Scope *sc);
|
||||
};
|
||||
|
||||
struct StaticIfDeclaration : ConditionalDeclaration
|
||||
{
|
||||
ScopeDsymbol *sd;
|
||||
int addisdone;
|
||||
|
||||
StaticIfDeclaration(Condition *condition, Dsymbols *decl, Dsymbols *elsedecl);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||
void semantic(Scope *sc);
|
||||
void importAll(Scope *sc);
|
||||
void setScope(Scope *sc);
|
||||
const char *kind();
|
||||
};
|
||||
|
||||
// Mixin declarations
|
||||
|
||||
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);
|
||||
};
|
||||
|
||||
#endif /* DMD_ATTRIB_H */
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
|
||||
The Software is not generally available software. It has not undergone
|
||||
testing and may contain errors. The Software was not designed to operate
|
||||
after December 31, 1999. It may be incomplete and it may not function
|
||||
properly. No support or maintenance is provided with this Software. Do
|
||||
not install or distribute the Software if
|
||||
you are not accustomed to using or distributing experimental software.
|
||||
Do not use this software for life critical applications, or applications
|
||||
that could cause significant harm or property damage.
|
||||
|
||||
Digital Mars licenses the Software to you on an "AS IS" basis, without
|
||||
warranty of any kind. DIGITAL MARS AND SYMANTEC HEREBY EXPRESSLY DISCLAIM
|
||||
ALL WARRANTIES AND CONDITIONS, EITHER EXPRESS OR IMPLIED, INCLUDING,
|
||||
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OR CONDITIONS OF MERCHANTABILITY,
|
||||
NONINFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. You are solely
|
||||
responsible for determining the appropriateness of using this Software and
|
||||
assume all risks associated with the use of this Software, including but not
|
||||
limited to the risks of program errors, damage
|
||||
to or loss of data, programs or equipment, unavailability or interruption of
|
||||
operations and third party claims. You agree to defend, indemnify and hold
|
||||
Digital Mars and Symantec, its subsidiaries, affiliates, directors, officers,
|
||||
employees and agents harmless from all claims or demands made against them
|
||||
(and any related losses, damages, expenses
|
||||
and costs) arising out of your use of the Software. DIGITAL MARS AND SYMANTEC
|
||||
WILL NOT BE LIABLE FOR ANY DIRECT DAMAGES OR FOR ANY SPECIAL, INCIDENTAL, OR
|
||||
INDIRECT DAMAGES OR FOR ANY ECONOMIC CONSEQUENTIAL DAMAGES (INCLUDING
|
||||
LOST PROFITS OR SAVINGS), EVEN IF DIGITAL MARS OR SYMANTEC HAS BEEN ADVISED
|
||||
OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
Digital Mars and Symantec will not be liable for the loss of, or damage to,
|
||||
your records or data, the records or
|
||||
data of any third party, or any damages claimed by you based on a third party
|
||||
claim.
|
||||
|
||||
If you send any messages to Digital Mars, on either the Digital Mars
|
||||
newsgroups, the Digital Mars mailing list, or via email, you agree not
|
||||
to make any claims of intellectual
|
||||
property rights over the contents of those messages.
|
||||
|
||||
The Software is copyrighted and comes with a single user license,
|
||||
and may not be redistributed. If you wish to obtain a redistribution license,
|
||||
please contact Digital Mars.
|
||||
|
||||
243
dmd2/builtin.c
243
dmd2/builtin.c
@@ -1,116 +1,127 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#include "mars.h"
|
||||
#include "declaration.h"
|
||||
#include "attrib.h"
|
||||
#include "expression.h"
|
||||
#include "scope.h"
|
||||
#include "mtype.h"
|
||||
#include "aggregate.h"
|
||||
#include "identifier.h"
|
||||
#include "id.h"
|
||||
#include "module.h"
|
||||
|
||||
#if DMDV2
|
||||
|
||||
/**********************************
|
||||
* Determine if function is a builtin one that we can
|
||||
* evaluate at compile time.
|
||||
*/
|
||||
enum BUILTIN FuncDeclaration::isBuiltin()
|
||||
{
|
||||
static const char FeZe[] = "FNaNbeZe"; // pure nothrow real function(real)
|
||||
|
||||
//printf("FuncDeclaration::isBuiltin() %s\n", toChars());
|
||||
if (builtin == BUILTINunknown)
|
||||
{
|
||||
builtin = BUILTINnot;
|
||||
if (parent && parent->isModule())
|
||||
{
|
||||
// If it's in the std.math package
|
||||
if (parent->ident == Id::math &&
|
||||
parent->parent && parent->parent->ident == Id::std &&
|
||||
!parent->parent->parent)
|
||||
{
|
||||
//printf("deco = %s\n", type->deco);
|
||||
if (strcmp(type->deco, FeZe) == 0)
|
||||
{
|
||||
if (ident == Id::sin)
|
||||
builtin = BUILTINsin;
|
||||
else if (ident == Id::cos)
|
||||
builtin = BUILTINcos;
|
||||
else if (ident == Id::tan)
|
||||
builtin = BUILTINtan;
|
||||
else if (ident == Id::_sqrt)
|
||||
builtin = BUILTINsqrt;
|
||||
else if (ident == Id::fabs)
|
||||
builtin = BUILTINfabs;
|
||||
//printf("builtin = %d\n", builtin);
|
||||
}
|
||||
// if float or double versions
|
||||
else if (strcmp(type->deco, "FNaNbdZd") == 0 ||
|
||||
strcmp(type->deco, "FNaNbfZf") == 0)
|
||||
{
|
||||
if (ident == Id::_sqrt)
|
||||
builtin = BUILTINsqrt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return builtin;
|
||||
}
|
||||
|
||||
|
||||
/**************************************
|
||||
* Evaluate builtin function.
|
||||
* Return result; NULL if cannot evaluate it.
|
||||
*/
|
||||
|
||||
Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments)
|
||||
{
|
||||
assert(arguments && arguments->dim);
|
||||
Expression *arg0 = (Expression *)arguments->data[0];
|
||||
Expression *e = NULL;
|
||||
switch (builtin)
|
||||
{
|
||||
case BUILTINsin:
|
||||
if (arg0->op == TOKfloat64)
|
||||
e = new RealExp(0, sinl(arg0->toReal()), arg0->type);
|
||||
break;
|
||||
|
||||
case BUILTINcos:
|
||||
if (arg0->op == TOKfloat64)
|
||||
e = new RealExp(0, cosl(arg0->toReal()), arg0->type);
|
||||
break;
|
||||
|
||||
case BUILTINtan:
|
||||
if (arg0->op == TOKfloat64)
|
||||
e = new RealExp(0, tanl(arg0->toReal()), arg0->type);
|
||||
break;
|
||||
|
||||
case BUILTINsqrt:
|
||||
if (arg0->op == TOKfloat64)
|
||||
e = new RealExp(0, sqrtl(arg0->toReal()), arg0->type);
|
||||
break;
|
||||
|
||||
case BUILTINfabs:
|
||||
if (arg0->op == TOKfloat64)
|
||||
e = new RealExp(0, fabsl(arg0->toReal()), arg0->type);
|
||||
break;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
#include <math.h>
|
||||
|
||||
#if __FreeBSD__
|
||||
extern "C"
|
||||
{
|
||||
long double sinl(long double);
|
||||
long double cosl(long double);
|
||||
long double tanl(long double);
|
||||
long double sqrtl(long double);
|
||||
}
|
||||
#endif
|
||||
|
||||
#include "mars.h"
|
||||
#include "declaration.h"
|
||||
#include "attrib.h"
|
||||
#include "expression.h"
|
||||
#include "scope.h"
|
||||
#include "mtype.h"
|
||||
#include "aggregate.h"
|
||||
#include "identifier.h"
|
||||
#include "id.h"
|
||||
#include "module.h"
|
||||
|
||||
#if DMDV2
|
||||
|
||||
/**********************************
|
||||
* Determine if function is a builtin one that we can
|
||||
* evaluate at compile time.
|
||||
*/
|
||||
enum BUILTIN FuncDeclaration::isBuiltin()
|
||||
{
|
||||
static const char FeZe [] = "FNaNbNfeZe"; // @safe pure nothrow real function(real)
|
||||
static const char FeZe2[] = "FNaNbNeeZe"; // @trusted pure nothrow real function(real)
|
||||
|
||||
//printf("FuncDeclaration::isBuiltin() %s\n", toChars());
|
||||
if (builtin == BUILTINunknown)
|
||||
{
|
||||
builtin = BUILTINnot;
|
||||
if (parent && parent->isModule())
|
||||
{
|
||||
// If it's in the std.math package
|
||||
if (parent->ident == Id::math &&
|
||||
parent->parent && parent->parent->ident == Id::std &&
|
||||
!parent->parent->parent)
|
||||
{
|
||||
//printf("deco = %s\n", type->deco);
|
||||
if (strcmp(type->deco, FeZe) == 0 || strcmp(type->deco, FeZe2) == 0)
|
||||
{
|
||||
if (ident == Id::sin)
|
||||
builtin = BUILTINsin;
|
||||
else if (ident == Id::cos)
|
||||
builtin = BUILTINcos;
|
||||
else if (ident == Id::tan)
|
||||
builtin = BUILTINtan;
|
||||
else if (ident == Id::_sqrt)
|
||||
builtin = BUILTINsqrt;
|
||||
else if (ident == Id::fabs)
|
||||
builtin = BUILTINfabs;
|
||||
//printf("builtin = %d\n", builtin);
|
||||
}
|
||||
// if float or double versions
|
||||
else if (strcmp(type->deco, "FNaNbNfdZd") == 0 ||
|
||||
strcmp(type->deco, "FNaNbNffZf") == 0)
|
||||
{
|
||||
if (ident == Id::_sqrt)
|
||||
builtin = BUILTINsqrt;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return builtin;
|
||||
}
|
||||
|
||||
|
||||
/**************************************
|
||||
* Evaluate builtin function.
|
||||
* Return result; NULL if cannot evaluate it.
|
||||
*/
|
||||
|
||||
Expression *eval_builtin(enum BUILTIN builtin, Expressions *arguments)
|
||||
{
|
||||
assert(arguments && arguments->dim);
|
||||
Expression *arg0 = (Expression *)arguments->data[0];
|
||||
Expression *e = NULL;
|
||||
switch (builtin)
|
||||
{
|
||||
case BUILTINsin:
|
||||
if (arg0->op == TOKfloat64)
|
||||
e = new RealExp(0, sinl(arg0->toReal()), arg0->type);
|
||||
break;
|
||||
|
||||
case BUILTINcos:
|
||||
if (arg0->op == TOKfloat64)
|
||||
e = new RealExp(0, cosl(arg0->toReal()), arg0->type);
|
||||
break;
|
||||
|
||||
case BUILTINtan:
|
||||
if (arg0->op == TOKfloat64)
|
||||
e = new RealExp(0, tanl(arg0->toReal()), arg0->type);
|
||||
break;
|
||||
|
||||
case BUILTINsqrt:
|
||||
if (arg0->op == TOKfloat64)
|
||||
e = new RealExp(0, sqrtl(arg0->toReal()), arg0->type);
|
||||
break;
|
||||
|
||||
case BUILTINfabs:
|
||||
if (arg0->op == TOKfloat64)
|
||||
e = new RealExp(0, fabsl(arg0->toReal()), arg0->type);
|
||||
break;
|
||||
}
|
||||
return e;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
4284
dmd2/cast.c
4284
dmd2/cast.c
File diff suppressed because it is too large
Load Diff
3010
dmd2/class.c
3010
dmd2/class.c
File diff suppressed because it is too large
Load Diff
1013
dmd2/clone.c
1013
dmd2/clone.c
File diff suppressed because it is too large
Load Diff
148
dmd2/complex_t.h
148
dmd2/complex_t.h
@@ -1,74 +1,74 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright and Burton Radons
|
||||
// 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_COMPLEX_T_H
|
||||
#define DMD_COMPLEX_T_H
|
||||
|
||||
/* Roll our own complex type for compilers that don't support complex
|
||||
*/
|
||||
|
||||
struct complex_t
|
||||
{
|
||||
long double re;
|
||||
long double im;
|
||||
|
||||
complex_t() { this->re = 0; this->im = 0; }
|
||||
complex_t(long double re) { this->re = re; this->im = 0; }
|
||||
complex_t(long double re, long double im) { this->re = re; this->im = im; }
|
||||
|
||||
complex_t operator + (complex_t y) { complex_t r; r.re = re + y.re; r.im = im + y.im; return r; }
|
||||
complex_t operator - (complex_t y) { complex_t r; r.re = re - y.re; r.im = im - y.im; return r; }
|
||||
complex_t operator - () { complex_t r; r.re = -re; r.im = -im; return r; }
|
||||
complex_t operator * (complex_t y) { return complex_t(re * y.re - im * y.im, im * y.re + re * y.im); }
|
||||
|
||||
complex_t operator / (complex_t y)
|
||||
{
|
||||
long double abs_y_re = y.re < 0 ? -y.re : y.re;
|
||||
long double abs_y_im = y.im < 0 ? -y.im : y.im;
|
||||
long double r, den;
|
||||
|
||||
if (abs_y_re < abs_y_im)
|
||||
{
|
||||
r = y.re / y.im;
|
||||
den = y.im + r * y.re;
|
||||
return complex_t((re * r + im) / den,
|
||||
(im * r - re) / den);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = y.im / y.re;
|
||||
den = y.re + r * y.im;
|
||||
return complex_t((re + r * im) / den,
|
||||
(im - r * re) / den);
|
||||
}
|
||||
}
|
||||
|
||||
operator bool () { return re || im; }
|
||||
|
||||
int operator == (complex_t y) { return re == y.re && im == y.im; }
|
||||
int operator != (complex_t y) { return re != y.re || im != y.im; }
|
||||
};
|
||||
|
||||
inline complex_t operator * (long double x, complex_t y) { return complex_t(x) * y; }
|
||||
inline complex_t operator * (complex_t x, long double y) { return x * complex_t(y); }
|
||||
inline complex_t operator / (complex_t x, long double y) { return x / complex_t(y); }
|
||||
|
||||
|
||||
inline long double creall(complex_t x)
|
||||
{
|
||||
return x.re;
|
||||
}
|
||||
|
||||
inline long double cimagl(complex_t x)
|
||||
{
|
||||
return x.im;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright and Burton Radons
|
||||
// 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_COMPLEX_T_H
|
||||
#define DMD_COMPLEX_T_H
|
||||
|
||||
/* Roll our own complex type for compilers that don't support complex
|
||||
*/
|
||||
|
||||
struct complex_t
|
||||
{
|
||||
long double re;
|
||||
long double im;
|
||||
|
||||
complex_t() { this->re = 0; this->im = 0; }
|
||||
complex_t(long double re) { this->re = re; this->im = 0; }
|
||||
complex_t(long double re, long double im) { this->re = re; this->im = im; }
|
||||
|
||||
complex_t operator + (complex_t y) { complex_t r; r.re = re + y.re; r.im = im + y.im; return r; }
|
||||
complex_t operator - (complex_t y) { complex_t r; r.re = re - y.re; r.im = im - y.im; return r; }
|
||||
complex_t operator - () { complex_t r; r.re = -re; r.im = -im; return r; }
|
||||
complex_t operator * (complex_t y) { return complex_t(re * y.re - im * y.im, im * y.re + re * y.im); }
|
||||
|
||||
complex_t operator / (complex_t y)
|
||||
{
|
||||
long double abs_y_re = y.re < 0 ? -y.re : y.re;
|
||||
long double abs_y_im = y.im < 0 ? -y.im : y.im;
|
||||
long double r, den;
|
||||
|
||||
if (abs_y_re < abs_y_im)
|
||||
{
|
||||
r = y.re / y.im;
|
||||
den = y.im + r * y.re;
|
||||
return complex_t((re * r + im) / den,
|
||||
(im * r - re) / den);
|
||||
}
|
||||
else
|
||||
{
|
||||
r = y.im / y.re;
|
||||
den = y.re + r * y.im;
|
||||
return complex_t((re + r * im) / den,
|
||||
(im - r * re) / den);
|
||||
}
|
||||
}
|
||||
|
||||
operator bool () { return re || im; }
|
||||
|
||||
int operator == (complex_t y) { return re == y.re && im == y.im; }
|
||||
int operator != (complex_t y) { return re != y.re || im != y.im; }
|
||||
};
|
||||
|
||||
inline complex_t operator * (long double x, complex_t y) { return complex_t(x) * y; }
|
||||
inline complex_t operator * (complex_t x, long double y) { return x * complex_t(y); }
|
||||
inline complex_t operator / (complex_t x, long double y) { return x / complex_t(y); }
|
||||
|
||||
|
||||
inline long double creall(complex_t x)
|
||||
{
|
||||
return x.re;
|
||||
}
|
||||
|
||||
inline long double cimagl(complex_t x)
|
||||
{
|
||||
return x.im;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
812
dmd2/cond.c
812
dmd2/cond.c
@@ -1,406 +1,406 @@
|
||||
|
||||
// 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.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "id.h"
|
||||
#include "init.h"
|
||||
#include "declaration.h"
|
||||
#include "identifier.h"
|
||||
#include "expression.h"
|
||||
#include "cond.h"
|
||||
#include "module.h"
|
||||
#include "template.h"
|
||||
#include "lexer.h"
|
||||
#ifdef _DH
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
#endif
|
||||
|
||||
int findCondition(Array *ids, Identifier *ident)
|
||||
{
|
||||
if (ids)
|
||||
{
|
||||
for (int i = 0; i < ids->dim; i++)
|
||||
{
|
||||
const char *id = (const char *)ids->data[i];
|
||||
|
||||
if (strcmp(id, ident->toChars()) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
|
||||
Condition::Condition(Loc loc)
|
||||
{
|
||||
this->loc = loc;
|
||||
inc = 0;
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
|
||||
DVCondition::DVCondition(Module *mod, unsigned level, Identifier *ident)
|
||||
: Condition(0)
|
||||
{
|
||||
this->mod = mod;
|
||||
this->level = level;
|
||||
this->ident = ident;
|
||||
}
|
||||
|
||||
Condition *DVCondition::syntaxCopy()
|
||||
{
|
||||
return this; // don't need to copy
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
|
||||
void DebugCondition::setGlobalLevel(unsigned level)
|
||||
{
|
||||
global.params.debuglevel = level;
|
||||
}
|
||||
|
||||
void DebugCondition::addGlobalIdent(const char *ident)
|
||||
{
|
||||
if (!global.params.debugids)
|
||||
global.params.debugids = new Array();
|
||||
global.params.debugids->push((void *)ident);
|
||||
}
|
||||
|
||||
|
||||
DebugCondition::DebugCondition(Module *mod, unsigned level, Identifier *ident)
|
||||
: DVCondition(mod, level, ident)
|
||||
{
|
||||
}
|
||||
|
||||
int DebugCondition::include(Scope *sc, ScopeDsymbol *s)
|
||||
{
|
||||
//printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel);
|
||||
if (inc == 0)
|
||||
{
|
||||
inc = 2;
|
||||
if (ident)
|
||||
{
|
||||
if (findCondition(mod->debugids, ident))
|
||||
inc = 1;
|
||||
else if (findCondition(global.params.debugids, ident))
|
||||
inc = 1;
|
||||
else
|
||||
{ if (!mod->debugidsNot)
|
||||
mod->debugidsNot = new Array();
|
||||
mod->debugidsNot->push(ident->toChars());
|
||||
}
|
||||
}
|
||||
else if (level <= global.params.debuglevel || level <= mod->debuglevel)
|
||||
inc = 1;
|
||||
}
|
||||
return (inc == 1);
|
||||
}
|
||||
|
||||
void DebugCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (ident)
|
||||
buf->printf("debug (%s)", ident->toChars());
|
||||
else
|
||||
buf->printf("debug (%u)", level);
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
|
||||
void VersionCondition::setGlobalLevel(unsigned level)
|
||||
{
|
||||
global.params.versionlevel = level;
|
||||
}
|
||||
|
||||
void VersionCondition::checkPredefined(Loc loc, const char *ident)
|
||||
{
|
||||
static const char* reserved[] =
|
||||
{
|
||||
"DigitalMars", "X86", "X86_64",
|
||||
"Windows", "Win32", "Win64",
|
||||
"linux",
|
||||
#if DMDV2
|
||||
/* Although Posix is predefined by D1, disallowing its
|
||||
* redefinition breaks makefiles and older builds.
|
||||
*/
|
||||
"Posix",
|
||||
"D_NET",
|
||||
#endif
|
||||
"OSX", "FreeBSD",
|
||||
"Solaris",
|
||||
"LittleEndian", "BigEndian",
|
||||
"all",
|
||||
"none",
|
||||
|
||||
#if IN_LLVM
|
||||
"LLVM", "LDC", "LLVM64",
|
||||
"PPC", "PPC64",
|
||||
"darwin","solaris","freebsd"
|
||||
#endif
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < sizeof(reserved) / sizeof(reserved[0]); i++)
|
||||
{
|
||||
if (strcmp(ident, reserved[i]) == 0)
|
||||
goto Lerror;
|
||||
}
|
||||
|
||||
if (ident[0] == 'D' && ident[1] == '_')
|
||||
goto Lerror;
|
||||
|
||||
return;
|
||||
|
||||
Lerror:
|
||||
error(loc, "version identifier '%s' is reserved and cannot be set", ident);
|
||||
}
|
||||
|
||||
void VersionCondition::addGlobalIdent(const char *ident)
|
||||
{
|
||||
checkPredefined(0, ident);
|
||||
addPredefinedGlobalIdent(ident);
|
||||
}
|
||||
|
||||
void VersionCondition::addPredefinedGlobalIdent(const char *ident)
|
||||
{
|
||||
if (!global.params.versionids)
|
||||
global.params.versionids = new Array();
|
||||
global.params.versionids->push((void *)ident);
|
||||
}
|
||||
|
||||
|
||||
VersionCondition::VersionCondition(Module *mod, unsigned level, Identifier *ident)
|
||||
: DVCondition(mod, level, ident)
|
||||
{
|
||||
}
|
||||
|
||||
int VersionCondition::include(Scope *sc, ScopeDsymbol *s)
|
||||
{
|
||||
//printf("VersionCondition::include() level = %d, versionlevel = %d\n", level, global.params.versionlevel);
|
||||
//if (ident) printf("\tident = '%s'\n", ident->toChars());
|
||||
if (inc == 0)
|
||||
{
|
||||
inc = 2;
|
||||
if (ident)
|
||||
{
|
||||
if (findCondition(mod->versionids, ident))
|
||||
inc = 1;
|
||||
else if (findCondition(global.params.versionids, ident))
|
||||
inc = 1;
|
||||
else
|
||||
{
|
||||
if (!mod->versionidsNot)
|
||||
mod->versionidsNot = new Array();
|
||||
mod->versionidsNot->push(ident->toChars());
|
||||
}
|
||||
}
|
||||
else if (level <= global.params.versionlevel || level <= mod->versionlevel)
|
||||
inc = 1;
|
||||
}
|
||||
return (inc == 1);
|
||||
}
|
||||
|
||||
void VersionCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (ident)
|
||||
buf->printf("version (%s)", ident->toChars());
|
||||
else
|
||||
buf->printf("version (%u)", level);
|
||||
}
|
||||
|
||||
|
||||
/**************************** StaticIfCondition *******************************/
|
||||
|
||||
StaticIfCondition::StaticIfCondition(Loc loc, Expression *exp)
|
||||
: Condition(loc)
|
||||
{
|
||||
this->exp = exp;
|
||||
}
|
||||
|
||||
Condition *StaticIfCondition::syntaxCopy()
|
||||
{
|
||||
return new StaticIfCondition(loc, exp->syntaxCopy());
|
||||
}
|
||||
|
||||
int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
|
||||
{
|
||||
#if 0
|
||||
printf("StaticIfCondition::include(sc = %p, s = %p)\n", sc, s);
|
||||
if (s)
|
||||
{
|
||||
printf("\ts = '%s', kind = %s\n", s->toChars(), s->kind());
|
||||
}
|
||||
#endif
|
||||
if (inc == 0)
|
||||
{
|
||||
if (!sc)
|
||||
{
|
||||
error(loc, "static if conditional cannot be at global scope");
|
||||
inc = 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sc = sc->push(sc->scopesym);
|
||||
sc->sd = s; // s gets any addMember()
|
||||
sc->flags |= SCOPEstaticif;
|
||||
Expression *e = exp->semantic(sc);
|
||||
sc->pop();
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (e->isBool(TRUE))
|
||||
inc = 1;
|
||||
else if (e->isBool(FALSE))
|
||||
inc = 2;
|
||||
else
|
||||
{
|
||||
e->error("expression %s is not constant or does not evaluate to a bool", e->toChars());
|
||||
inc = 2;
|
||||
}
|
||||
}
|
||||
return (inc == 1);
|
||||
}
|
||||
|
||||
void StaticIfCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
buf->writestring("static if(");
|
||||
exp->toCBuffer(buf, hgs);
|
||||
buf->writeByte(')');
|
||||
}
|
||||
|
||||
|
||||
/**************************** IftypeCondition *******************************/
|
||||
|
||||
IftypeCondition::IftypeCondition(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec)
|
||||
: Condition(loc)
|
||||
{
|
||||
this->targ = targ;
|
||||
this->id = id;
|
||||
this->tok = tok;
|
||||
this->tspec = tspec;
|
||||
}
|
||||
|
||||
Condition *IftypeCondition::syntaxCopy()
|
||||
{
|
||||
return new IftypeCondition(loc,
|
||||
targ->syntaxCopy(),
|
||||
id,
|
||||
tok,
|
||||
tspec ? tspec->syntaxCopy() : NULL);
|
||||
}
|
||||
|
||||
int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd)
|
||||
{
|
||||
//printf("IftypeCondition::include()\n");
|
||||
if (inc == 0)
|
||||
{
|
||||
if (!sc)
|
||||
{
|
||||
error(loc, "iftype conditional cannot be at global scope");
|
||||
inc = 2;
|
||||
return 0;
|
||||
}
|
||||
Type *t = targ->trySemantic(loc, sc);
|
||||
if (t)
|
||||
targ = t;
|
||||
else
|
||||
inc = 2; // condition is false
|
||||
|
||||
if (!t)
|
||||
{
|
||||
}
|
||||
else if (id && tspec)
|
||||
{
|
||||
/* Evaluate to TRUE if targ matches tspec.
|
||||
* If TRUE, declare id as an alias for the specialized type.
|
||||
*/
|
||||
|
||||
MATCH m;
|
||||
TemplateTypeParameter tp(loc, id, NULL, NULL);
|
||||
|
||||
TemplateParameters parameters;
|
||||
parameters.setDim(1);
|
||||
parameters.data[0] = (void *)&tp;
|
||||
|
||||
Objects dedtypes;
|
||||
dedtypes.setDim(1);
|
||||
|
||||
m = targ->deduceType(NULL, tspec, ¶meters, &dedtypes);
|
||||
if (m == MATCHnomatch ||
|
||||
(m != MATCHexact && tok == TOKequal))
|
||||
inc = 2;
|
||||
else
|
||||
{
|
||||
inc = 1;
|
||||
Type *tded = (Type *)dedtypes.data[0];
|
||||
if (!tded)
|
||||
tded = targ;
|
||||
Dsymbol *s = new AliasDeclaration(loc, id, tded);
|
||||
s->semantic(sc);
|
||||
sc->insert(s);
|
||||
if (sd)
|
||||
s->addMember(sc, sd, 1);
|
||||
}
|
||||
}
|
||||
else if (id)
|
||||
{
|
||||
/* Declare id as an alias for type targ. Evaluate to TRUE
|
||||
*/
|
||||
Dsymbol *s = new AliasDeclaration(loc, id, targ);
|
||||
s->semantic(sc);
|
||||
sc->insert(s);
|
||||
if (sd)
|
||||
s->addMember(sc, sd, 1);
|
||||
inc = 1;
|
||||
}
|
||||
else if (tspec)
|
||||
{
|
||||
/* Evaluate to TRUE if targ matches tspec
|
||||
*/
|
||||
tspec = tspec->semantic(loc, sc);
|
||||
//printf("targ = %s\n", targ->toChars());
|
||||
//printf("tspec = %s\n", tspec->toChars());
|
||||
if (tok == TOKcolon)
|
||||
{ if (targ->implicitConvTo(tspec))
|
||||
inc = 1;
|
||||
else
|
||||
inc = 2;
|
||||
}
|
||||
else /* == */
|
||||
{ if (targ->equals(tspec))
|
||||
inc = 1;
|
||||
else
|
||||
inc = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
inc = 1;
|
||||
//printf("inc = %d\n", inc);
|
||||
}
|
||||
return (inc == 1);
|
||||
}
|
||||
|
||||
void IftypeCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
buf->writestring("iftype(");
|
||||
targ->toCBuffer(buf, id, hgs);
|
||||
if (tspec)
|
||||
{
|
||||
if (tok == TOKcolon)
|
||||
buf->writestring(" : ");
|
||||
else
|
||||
buf->writestring(" == ");
|
||||
tspec->toCBuffer(buf, NULL, hgs);
|
||||
}
|
||||
buf->writeByte(')');
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "id.h"
|
||||
#include "init.h"
|
||||
#include "declaration.h"
|
||||
#include "identifier.h"
|
||||
#include "expression.h"
|
||||
#include "cond.h"
|
||||
#include "module.h"
|
||||
#include "template.h"
|
||||
#include "lexer.h"
|
||||
#ifdef _DH
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
#endif
|
||||
|
||||
int findCondition(Array *ids, Identifier *ident)
|
||||
{
|
||||
if (ids)
|
||||
{
|
||||
for (int i = 0; i < ids->dim; i++)
|
||||
{
|
||||
const char *id = (const char *)ids->data[i];
|
||||
|
||||
if (strcmp(id, ident->toChars()) == 0)
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
|
||||
Condition::Condition(Loc loc)
|
||||
{
|
||||
this->loc = loc;
|
||||
inc = 0;
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
|
||||
DVCondition::DVCondition(Module *mod, unsigned level, Identifier *ident)
|
||||
: Condition(0)
|
||||
{
|
||||
this->mod = mod;
|
||||
this->level = level;
|
||||
this->ident = ident;
|
||||
}
|
||||
|
||||
Condition *DVCondition::syntaxCopy()
|
||||
{
|
||||
return this; // don't need to copy
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
|
||||
void DebugCondition::setGlobalLevel(unsigned level)
|
||||
{
|
||||
global.params.debuglevel = level;
|
||||
}
|
||||
|
||||
void DebugCondition::addGlobalIdent(const char *ident)
|
||||
{
|
||||
if (!global.params.debugids)
|
||||
global.params.debugids = new Array();
|
||||
global.params.debugids->push((void *)ident);
|
||||
}
|
||||
|
||||
|
||||
DebugCondition::DebugCondition(Module *mod, unsigned level, Identifier *ident)
|
||||
: DVCondition(mod, level, ident)
|
||||
{
|
||||
}
|
||||
|
||||
int DebugCondition::include(Scope *sc, ScopeDsymbol *s)
|
||||
{
|
||||
//printf("DebugCondition::include() level = %d, debuglevel = %d\n", level, global.params.debuglevel);
|
||||
if (inc == 0)
|
||||
{
|
||||
inc = 2;
|
||||
if (ident)
|
||||
{
|
||||
if (findCondition(mod->debugids, ident))
|
||||
inc = 1;
|
||||
else if (findCondition(global.params.debugids, ident))
|
||||
inc = 1;
|
||||
else
|
||||
{ if (!mod->debugidsNot)
|
||||
mod->debugidsNot = new Array();
|
||||
mod->debugidsNot->push(ident->toChars());
|
||||
}
|
||||
}
|
||||
else if (level <= global.params.debuglevel || level <= mod->debuglevel)
|
||||
inc = 1;
|
||||
}
|
||||
return (inc == 1);
|
||||
}
|
||||
|
||||
void DebugCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (ident)
|
||||
buf->printf("debug (%s)", ident->toChars());
|
||||
else
|
||||
buf->printf("debug (%u)", level);
|
||||
}
|
||||
|
||||
/* ============================================================ */
|
||||
|
||||
void VersionCondition::setGlobalLevel(unsigned level)
|
||||
{
|
||||
global.params.versionlevel = level;
|
||||
}
|
||||
|
||||
void VersionCondition::checkPredefined(Loc loc, const char *ident)
|
||||
{
|
||||
static const char* reserved[] =
|
||||
{
|
||||
"DigitalMars", "X86", "X86_64",
|
||||
"Windows", "Win32", "Win64",
|
||||
"linux",
|
||||
#if DMDV2
|
||||
/* Although Posix is predefined by D1, disallowing its
|
||||
* redefinition breaks makefiles and older builds.
|
||||
*/
|
||||
"Posix",
|
||||
"D_NET",
|
||||
#endif
|
||||
"OSX", "FreeBSD",
|
||||
"Solaris",
|
||||
"LittleEndian", "BigEndian",
|
||||
"all",
|
||||
"none",
|
||||
|
||||
#if IN_LLVM
|
||||
"LLVM", "LDC", "LLVM64",
|
||||
"PPC", "PPC64",
|
||||
"darwin","solaris","freebsd"
|
||||
#endif
|
||||
};
|
||||
|
||||
for (unsigned i = 0; i < sizeof(reserved) / sizeof(reserved[0]); i++)
|
||||
{
|
||||
if (strcmp(ident, reserved[i]) == 0)
|
||||
goto Lerror;
|
||||
}
|
||||
|
||||
if (ident[0] == 'D' && ident[1] == '_')
|
||||
goto Lerror;
|
||||
|
||||
return;
|
||||
|
||||
Lerror:
|
||||
error(loc, "version identifier '%s' is reserved and cannot be set", ident);
|
||||
}
|
||||
|
||||
void VersionCondition::addGlobalIdent(const char *ident)
|
||||
{
|
||||
checkPredefined(0, ident);
|
||||
addPredefinedGlobalIdent(ident);
|
||||
}
|
||||
|
||||
void VersionCondition::addPredefinedGlobalIdent(const char *ident)
|
||||
{
|
||||
if (!global.params.versionids)
|
||||
global.params.versionids = new Array();
|
||||
global.params.versionids->push((void *)ident);
|
||||
}
|
||||
|
||||
|
||||
VersionCondition::VersionCondition(Module *mod, unsigned level, Identifier *ident)
|
||||
: DVCondition(mod, level, ident)
|
||||
{
|
||||
}
|
||||
|
||||
int VersionCondition::include(Scope *sc, ScopeDsymbol *s)
|
||||
{
|
||||
//printf("VersionCondition::include() level = %d, versionlevel = %d\n", level, global.params.versionlevel);
|
||||
//if (ident) printf("\tident = '%s'\n", ident->toChars());
|
||||
if (inc == 0)
|
||||
{
|
||||
inc = 2;
|
||||
if (ident)
|
||||
{
|
||||
if (findCondition(mod->versionids, ident))
|
||||
inc = 1;
|
||||
else if (findCondition(global.params.versionids, ident))
|
||||
inc = 1;
|
||||
else
|
||||
{
|
||||
if (!mod->versionidsNot)
|
||||
mod->versionidsNot = new Array();
|
||||
mod->versionidsNot->push(ident->toChars());
|
||||
}
|
||||
}
|
||||
else if (level <= global.params.versionlevel || level <= mod->versionlevel)
|
||||
inc = 1;
|
||||
}
|
||||
return (inc == 1);
|
||||
}
|
||||
|
||||
void VersionCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (ident)
|
||||
buf->printf("version (%s)", ident->toChars());
|
||||
else
|
||||
buf->printf("version (%u)", level);
|
||||
}
|
||||
|
||||
|
||||
/**************************** StaticIfCondition *******************************/
|
||||
|
||||
StaticIfCondition::StaticIfCondition(Loc loc, Expression *exp)
|
||||
: Condition(loc)
|
||||
{
|
||||
this->exp = exp;
|
||||
}
|
||||
|
||||
Condition *StaticIfCondition::syntaxCopy()
|
||||
{
|
||||
return new StaticIfCondition(loc, exp->syntaxCopy());
|
||||
}
|
||||
|
||||
int StaticIfCondition::include(Scope *sc, ScopeDsymbol *s)
|
||||
{
|
||||
#if 0
|
||||
printf("StaticIfCondition::include(sc = %p, s = %p)\n", sc, s);
|
||||
if (s)
|
||||
{
|
||||
printf("\ts = '%s', kind = %s\n", s->toChars(), s->kind());
|
||||
}
|
||||
#endif
|
||||
if (inc == 0)
|
||||
{
|
||||
if (!sc)
|
||||
{
|
||||
error(loc, "static if conditional cannot be at global scope");
|
||||
inc = 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
sc = sc->push(sc->scopesym);
|
||||
sc->sd = s; // s gets any addMember()
|
||||
sc->flags |= SCOPEstaticif;
|
||||
Expression *e = exp->semantic(sc);
|
||||
sc->pop();
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (e->isBool(TRUE))
|
||||
inc = 1;
|
||||
else if (e->isBool(FALSE))
|
||||
inc = 2;
|
||||
else
|
||||
{
|
||||
e->error("expression %s is not constant or does not evaluate to a bool", e->toChars());
|
||||
inc = 2;
|
||||
}
|
||||
}
|
||||
return (inc == 1);
|
||||
}
|
||||
|
||||
void StaticIfCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
buf->writestring("static if(");
|
||||
exp->toCBuffer(buf, hgs);
|
||||
buf->writeByte(')');
|
||||
}
|
||||
|
||||
|
||||
/**************************** IftypeCondition *******************************/
|
||||
|
||||
IftypeCondition::IftypeCondition(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec)
|
||||
: Condition(loc)
|
||||
{
|
||||
this->targ = targ;
|
||||
this->id = id;
|
||||
this->tok = tok;
|
||||
this->tspec = tspec;
|
||||
}
|
||||
|
||||
Condition *IftypeCondition::syntaxCopy()
|
||||
{
|
||||
return new IftypeCondition(loc,
|
||||
targ->syntaxCopy(),
|
||||
id,
|
||||
tok,
|
||||
tspec ? tspec->syntaxCopy() : NULL);
|
||||
}
|
||||
|
||||
int IftypeCondition::include(Scope *sc, ScopeDsymbol *sd)
|
||||
{
|
||||
//printf("IftypeCondition::include()\n");
|
||||
if (inc == 0)
|
||||
{
|
||||
if (!sc)
|
||||
{
|
||||
error(loc, "iftype conditional cannot be at global scope");
|
||||
inc = 2;
|
||||
return 0;
|
||||
}
|
||||
Type *t = targ->trySemantic(loc, sc);
|
||||
if (t)
|
||||
targ = t;
|
||||
else
|
||||
inc = 2; // condition is false
|
||||
|
||||
if (!t)
|
||||
{
|
||||
}
|
||||
else if (id && tspec)
|
||||
{
|
||||
/* Evaluate to TRUE if targ matches tspec.
|
||||
* If TRUE, declare id as an alias for the specialized type.
|
||||
*/
|
||||
|
||||
MATCH m;
|
||||
TemplateTypeParameter tp(loc, id, NULL, NULL);
|
||||
|
||||
TemplateParameters parameters;
|
||||
parameters.setDim(1);
|
||||
parameters.data[0] = (void *)&tp;
|
||||
|
||||
Objects dedtypes;
|
||||
dedtypes.setDim(1);
|
||||
|
||||
m = targ->deduceType(NULL, tspec, ¶meters, &dedtypes);
|
||||
if (m == MATCHnomatch ||
|
||||
(m != MATCHexact && tok == TOKequal))
|
||||
inc = 2;
|
||||
else
|
||||
{
|
||||
inc = 1;
|
||||
Type *tded = (Type *)dedtypes.data[0];
|
||||
if (!tded)
|
||||
tded = targ;
|
||||
Dsymbol *s = new AliasDeclaration(loc, id, tded);
|
||||
s->semantic(sc);
|
||||
sc->insert(s);
|
||||
if (sd)
|
||||
s->addMember(sc, sd, 1);
|
||||
}
|
||||
}
|
||||
else if (id)
|
||||
{
|
||||
/* Declare id as an alias for type targ. Evaluate to TRUE
|
||||
*/
|
||||
Dsymbol *s = new AliasDeclaration(loc, id, targ);
|
||||
s->semantic(sc);
|
||||
sc->insert(s);
|
||||
if (sd)
|
||||
s->addMember(sc, sd, 1);
|
||||
inc = 1;
|
||||
}
|
||||
else if (tspec)
|
||||
{
|
||||
/* Evaluate to TRUE if targ matches tspec
|
||||
*/
|
||||
tspec = tspec->semantic(loc, sc);
|
||||
//printf("targ = %s\n", targ->toChars());
|
||||
//printf("tspec = %s\n", tspec->toChars());
|
||||
if (tok == TOKcolon)
|
||||
{ if (targ->implicitConvTo(tspec))
|
||||
inc = 1;
|
||||
else
|
||||
inc = 2;
|
||||
}
|
||||
else /* == */
|
||||
{ if (targ->equals(tspec))
|
||||
inc = 1;
|
||||
else
|
||||
inc = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
inc = 1;
|
||||
//printf("inc = %d\n", inc);
|
||||
}
|
||||
return (inc == 1);
|
||||
}
|
||||
|
||||
void IftypeCondition::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
buf->writestring("iftype(");
|
||||
targ->toCBuffer(buf, id, hgs);
|
||||
if (tspec)
|
||||
{
|
||||
if (tok == TOKcolon)
|
||||
buf->writestring(" : ");
|
||||
else
|
||||
buf->writestring(" == ");
|
||||
tspec->toCBuffer(buf, NULL, hgs);
|
||||
}
|
||||
buf->writeByte(')');
|
||||
}
|
||||
|
||||
|
||||
|
||||
12
dmd2/cond.h
12
dmd2/cond.h
@@ -30,9 +30,9 @@ int findCondition(Array *ids, Identifier *ident);
|
||||
struct Condition
|
||||
{
|
||||
Loc loc;
|
||||
int inc; // 0: not computed yet
|
||||
// 1: include
|
||||
// 2: do not include
|
||||
int inc; // 0: not computed yet
|
||||
// 1: include
|
||||
// 2: do not include
|
||||
|
||||
Condition(Loc loc);
|
||||
|
||||
@@ -92,9 +92,9 @@ struct IftypeCondition : Condition
|
||||
/* iftype (targ id tok tspec)
|
||||
*/
|
||||
Type *targ;
|
||||
Identifier *id; // can be NULL
|
||||
enum TOK tok; // ':' or '=='
|
||||
Type *tspec; // can be NULL
|
||||
Identifier *id; // can be NULL
|
||||
enum TOK tok; // ':' or '=='
|
||||
Type *tspec; // can be NULL
|
||||
|
||||
IftypeCondition(Loc loc, Type *targ, Identifier *id, enum TOK tok, Type *tspec);
|
||||
Condition *syntaxCopy();
|
||||
|
||||
3248
dmd2/constfold.c
3248
dmd2/constfold.c
File diff suppressed because it is too large
Load Diff
770
dmd2/cppmangle.c
770
dmd2/cppmangle.c
@@ -1,381 +1,389 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mars.h"
|
||||
#include "dsymbol.h"
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
#include "init.h"
|
||||
#include "expression.h"
|
||||
#include "attrib.h"
|
||||
#include "declaration.h"
|
||||
#include "template.h"
|
||||
#include "id.h"
|
||||
#include "enum.h"
|
||||
#include "import.h"
|
||||
#include "aggregate.h"
|
||||
|
||||
#if CPP_MANGLE
|
||||
|
||||
/* Do mangling for C++ linkage.
|
||||
* Follows Itanium C++ ABI 1.86
|
||||
* No attempt is made to support mangling of templates, operator
|
||||
* overloading, or special functions.
|
||||
*
|
||||
* So why don't we use the C++ ABI for D name mangling?
|
||||
* Because D supports a lot of things (like modules) that the C++
|
||||
* ABI has no concept of. These affect every D mangled name,
|
||||
* so nothing would be compatible anyway.
|
||||
*/
|
||||
|
||||
struct CppMangleState
|
||||
{
|
||||
static Array components;
|
||||
|
||||
int substitute(OutBuffer *buf, void *p);
|
||||
};
|
||||
|
||||
Array CppMangleState::components;
|
||||
|
||||
|
||||
void writeBase36(OutBuffer *buf, unsigned i)
|
||||
{
|
||||
if (i >= 36)
|
||||
{
|
||||
writeBase36(buf, i / 36);
|
||||
i %= 36;
|
||||
}
|
||||
if (i < 10)
|
||||
buf->writeByte(i + '0');
|
||||
else if (i < 36)
|
||||
buf->writeByte(i - 10 + 'A');
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
int CppMangleState::substitute(OutBuffer *buf, void *p)
|
||||
{
|
||||
for (size_t i = 0; i < components.dim; i++)
|
||||
{
|
||||
if (p == components.data[i])
|
||||
{
|
||||
/* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
|
||||
*/
|
||||
buf->writeByte('S');
|
||||
if (i)
|
||||
writeBase36(buf, i - 1);
|
||||
buf->writeByte('_');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
components.push(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void source_name(OutBuffer *buf, Dsymbol *s)
|
||||
{
|
||||
char *name = s->ident->toChars();
|
||||
buf->printf("%d%s", strlen(name), name);
|
||||
}
|
||||
|
||||
void prefix_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s)
|
||||
{
|
||||
if (!cms->substitute(buf, s))
|
||||
{
|
||||
Dsymbol *p = s->toParent();
|
||||
if (p && !p->isModule())
|
||||
{
|
||||
prefix_name(buf, cms, p);
|
||||
}
|
||||
source_name(buf, s);
|
||||
}
|
||||
}
|
||||
|
||||
void cpp_mangle_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s)
|
||||
{
|
||||
Dsymbol *p = s->toParent();
|
||||
if (p && !p->isModule())
|
||||
{
|
||||
buf->writeByte('N');
|
||||
|
||||
FuncDeclaration *fd = s->isFuncDeclaration();
|
||||
if (fd->isConst())
|
||||
buf->writeByte('K');
|
||||
|
||||
prefix_name(buf, cms, p);
|
||||
source_name(buf, s);
|
||||
|
||||
buf->writeByte('E');
|
||||
}
|
||||
else
|
||||
source_name(buf, s);
|
||||
}
|
||||
|
||||
|
||||
char *cpp_mangle(Dsymbol *s)
|
||||
{
|
||||
/*
|
||||
* <mangled-name> ::= _Z <encoding>
|
||||
* <encoding> ::= <function name> <bare-function-type>
|
||||
* ::= <data name>
|
||||
* ::= <special-name>
|
||||
*/
|
||||
|
||||
CppMangleState cms;
|
||||
memset(&cms, 0, sizeof(cms));
|
||||
cms.components.setDim(0);
|
||||
|
||||
OutBuffer buf;
|
||||
#if MACHOBJ
|
||||
buf.writestring("__Z");
|
||||
#else
|
||||
buf.writestring("_Z");
|
||||
#endif
|
||||
|
||||
cpp_mangle_name(&buf, &cms, s);
|
||||
|
||||
FuncDeclaration *fd = s->isFuncDeclaration();
|
||||
if (fd)
|
||||
{ // add <bare-function-type>
|
||||
TypeFunction *tf = (TypeFunction *)fd->type;
|
||||
assert(tf->ty == Tfunction);
|
||||
Argument::argsCppMangle(&buf, &cms, tf->parameters, tf->varargs);
|
||||
}
|
||||
buf.writeByte(0);
|
||||
return (char *)buf.extractData();
|
||||
}
|
||||
|
||||
/* ============= Type Encodings ============================================= */
|
||||
|
||||
void Type::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
/* Make this the 'vendor extended type' when there is no
|
||||
* C++ analog.
|
||||
* u <source-name>
|
||||
*/
|
||||
if (!cms->substitute(buf, this))
|
||||
{ assert(deco);
|
||||
buf->printf("u%d%s", strlen(deco), deco);
|
||||
}
|
||||
}
|
||||
|
||||
void TypeBasic::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{ char c;
|
||||
char p = 0;
|
||||
|
||||
/* ABI spec says:
|
||||
* v void
|
||||
* w wchar_t
|
||||
* b bool
|
||||
* c char
|
||||
* a signed char
|
||||
* h unsigned char
|
||||
* s short
|
||||
* t unsigned short
|
||||
* i int
|
||||
* j unsigned int
|
||||
* l long
|
||||
* m unsigned long
|
||||
* x long long, __int64
|
||||
* y unsigned long long, __int64
|
||||
* n __int128
|
||||
* o unsigned __int128
|
||||
* f float
|
||||
* d double
|
||||
* e long double, __float80
|
||||
* g __float128
|
||||
* z ellipsis
|
||||
* u <source-name> # vendor extended type
|
||||
*/
|
||||
|
||||
switch (ty)
|
||||
{
|
||||
case Tvoid: c = 'v'; break;
|
||||
case Tint8: c = 'a'; break;
|
||||
case Tuns8: c = 'h'; break;
|
||||
case Tint16: c = 's'; break;
|
||||
case Tuns16: c = 't'; break;
|
||||
case Tint32: c = 'i'; break;
|
||||
case Tuns32: c = 'j'; break;
|
||||
case Tfloat32: c = 'f'; break;
|
||||
case Tint64: c = 'x'; break;
|
||||
case Tuns64: c = 'y'; break;
|
||||
case Tfloat64: c = 'd'; break;
|
||||
case Tfloat80: c = 'e'; break;
|
||||
case Tbool: c = 'b'; break;
|
||||
case Tchar: c = 'c'; break;
|
||||
case Twchar: c = 't'; break;
|
||||
case Tdchar: c = 'w'; break;
|
||||
|
||||
case Timaginary32: p = 'G'; c = 'f'; break;
|
||||
case Timaginary64: p = 'G'; c = 'd'; break;
|
||||
case Timaginary80: p = 'G'; c = 'e'; break;
|
||||
case Tcomplex32: p = 'C'; c = 'f'; break;
|
||||
case Tcomplex64: p = 'C'; c = 'd'; break;
|
||||
case Tcomplex80: p = 'C'; c = 'e'; break;
|
||||
|
||||
default: assert(0);
|
||||
}
|
||||
if (p)
|
||||
{
|
||||
if (cms->substitute(buf, this))
|
||||
return;
|
||||
buf->writeByte(p);
|
||||
}
|
||||
buf->writeByte(c);
|
||||
}
|
||||
|
||||
|
||||
void TypeSArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, this))
|
||||
{ buf->printf("A%ju_", dim ? dim->toInteger() : 0);
|
||||
next->toCppMangle(buf, cms);
|
||||
}
|
||||
}
|
||||
|
||||
void TypeDArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
Type::toCppMangle(buf, cms);
|
||||
}
|
||||
|
||||
|
||||
void TypeAArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
Type::toCppMangle(buf, cms);
|
||||
}
|
||||
|
||||
|
||||
void TypePointer::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, this))
|
||||
{ buf->writeByte('P');
|
||||
next->toCppMangle(buf, cms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TypeReference::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, this))
|
||||
{ buf->writeByte('R');
|
||||
next->toCppMangle(buf, cms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TypeFunction::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{ /*
|
||||
* <function-type> ::= F [Y] <bare-function-type> E
|
||||
* <bare-function-type> ::= <signature type>+
|
||||
* # types are possible return type, then parameter types
|
||||
*/
|
||||
|
||||
/* ABI says:
|
||||
"The type of a non-static member function is considered to be different,
|
||||
for the purposes of substitution, from the type of a namespace-scope or
|
||||
static member function whose type appears similar. The types of two
|
||||
non-static member functions are considered to be different, for the
|
||||
purposes of substitution, if the functions are members of different
|
||||
classes. In other words, for the purposes of substitution, the class of
|
||||
which the function is a member is considered part of the type of
|
||||
function."
|
||||
|
||||
BUG: Right now, types of functions are never merged, so our simplistic
|
||||
component matcher always finds them to be different.
|
||||
We should use Type::equals on these, and use different
|
||||
TypeFunctions for non-static member functions, and non-static
|
||||
member functions of different classes.
|
||||
*/
|
||||
if (!cms->substitute(buf, this))
|
||||
{
|
||||
buf->writeByte('F');
|
||||
if (linkage == LINKc)
|
||||
buf->writeByte('Y');
|
||||
next->toCppMangle(buf, cms);
|
||||
Argument::argsCppMangle(buf, cms, parameters, varargs);
|
||||
buf->writeByte('E');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TypeDelegate::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
Type::toCppMangle(buf, cms);
|
||||
}
|
||||
|
||||
|
||||
void TypeStruct::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, sym))
|
||||
cpp_mangle_name(buf, cms, sym);
|
||||
}
|
||||
|
||||
|
||||
void TypeEnum::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, sym))
|
||||
cpp_mangle_name(buf, cms, sym);
|
||||
}
|
||||
|
||||
|
||||
void TypeTypedef::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
Type::toCppMangle(buf, cms);
|
||||
}
|
||||
|
||||
|
||||
void TypeClass::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, this))
|
||||
{ buf->writeByte('P');
|
||||
if (!cms->substitute(buf, sym))
|
||||
cpp_mangle_name(buf, cms, sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Argument::argsCppMangle(OutBuffer *buf, CppMangleState *cms, Arguments *arguments, int varargs)
|
||||
{ int n = 0;
|
||||
if (arguments)
|
||||
{
|
||||
for (size_t i = 0; i < arguments->dim; i++)
|
||||
{ Argument *arg = (Argument *)arguments->data[i];
|
||||
Type *t = arg->type;
|
||||
if (arg->storageClass & (STCout | STCref))
|
||||
t = t->referenceTo();
|
||||
else if (arg->storageClass & STClazy)
|
||||
{ // Mangle as delegate
|
||||
Type *td = new TypeFunction(NULL, t, 0, LINKd);
|
||||
td = new TypeDelegate(td);
|
||||
t = t->merge();
|
||||
}
|
||||
if (t->ty == Tsarray)
|
||||
{ // Mangle static arrays as pointers
|
||||
t = t->pointerTo();
|
||||
}
|
||||
t->toCppMangle(buf, cms);
|
||||
|
||||
n++;
|
||||
}
|
||||
}
|
||||
if (varargs)
|
||||
buf->writestring("z");
|
||||
else if (!n)
|
||||
buf->writeByte('v'); // encode ( ) arguments
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2010 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 <assert.h>
|
||||
|
||||
#include "mars.h"
|
||||
#include "dsymbol.h"
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
#include "init.h"
|
||||
#include "expression.h"
|
||||
#include "attrib.h"
|
||||
#include "declaration.h"
|
||||
#include "template.h"
|
||||
#include "id.h"
|
||||
#include "enum.h"
|
||||
#include "import.h"
|
||||
#include "aggregate.h"
|
||||
|
||||
#if CPP_MANGLE
|
||||
|
||||
/* Do mangling for C++ linkage.
|
||||
* Follows Itanium C++ ABI 1.86
|
||||
* No attempt is made to support mangling of templates, operator
|
||||
* overloading, or special functions.
|
||||
*
|
||||
* So why don't we use the C++ ABI for D name mangling?
|
||||
* Because D supports a lot of things (like modules) that the C++
|
||||
* ABI has no concept of. These affect every D mangled name,
|
||||
* so nothing would be compatible anyway.
|
||||
*/
|
||||
|
||||
struct CppMangleState
|
||||
{
|
||||
static Array components;
|
||||
|
||||
int substitute(OutBuffer *buf, void *p);
|
||||
};
|
||||
|
||||
Array CppMangleState::components;
|
||||
|
||||
|
||||
void writeBase36(OutBuffer *buf, unsigned i)
|
||||
{
|
||||
if (i >= 36)
|
||||
{
|
||||
writeBase36(buf, i / 36);
|
||||
i %= 36;
|
||||
}
|
||||
if (i < 10)
|
||||
buf->writeByte(i + '0');
|
||||
else if (i < 36)
|
||||
buf->writeByte(i - 10 + 'A');
|
||||
else
|
||||
assert(0);
|
||||
}
|
||||
|
||||
int CppMangleState::substitute(OutBuffer *buf, void *p)
|
||||
{
|
||||
for (size_t i = 0; i < components.dim; i++)
|
||||
{
|
||||
if (p == components.data[i])
|
||||
{
|
||||
/* Sequence is S_, S0_, .., S9_, SA_, ..., SZ_, S10_, ...
|
||||
*/
|
||||
buf->writeByte('S');
|
||||
if (i)
|
||||
writeBase36(buf, i - 1);
|
||||
buf->writeByte('_');
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
components.push(p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void source_name(OutBuffer *buf, Dsymbol *s)
|
||||
{
|
||||
char *name = s->ident->toChars();
|
||||
buf->printf("%d%s", strlen(name), name);
|
||||
}
|
||||
|
||||
void prefix_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s)
|
||||
{
|
||||
if (!cms->substitute(buf, s))
|
||||
{
|
||||
Dsymbol *p = s->toParent();
|
||||
if (p && !p->isModule())
|
||||
{
|
||||
prefix_name(buf, cms, p);
|
||||
}
|
||||
source_name(buf, s);
|
||||
}
|
||||
}
|
||||
|
||||
void cpp_mangle_name(OutBuffer *buf, CppMangleState *cms, Dsymbol *s)
|
||||
{
|
||||
Dsymbol *p = s->toParent();
|
||||
if (p && !p->isModule())
|
||||
{
|
||||
buf->writeByte('N');
|
||||
|
||||
FuncDeclaration *fd = s->isFuncDeclaration();
|
||||
if (!fd)
|
||||
{
|
||||
s->error("C++ static variables not supported");
|
||||
}
|
||||
else
|
||||
if (fd->isConst())
|
||||
buf->writeByte('K');
|
||||
|
||||
prefix_name(buf, cms, p);
|
||||
source_name(buf, s);
|
||||
|
||||
buf->writeByte('E');
|
||||
}
|
||||
else
|
||||
source_name(buf, s);
|
||||
}
|
||||
|
||||
|
||||
char *cpp_mangle(Dsymbol *s)
|
||||
{
|
||||
/*
|
||||
* <mangled-name> ::= _Z <encoding>
|
||||
* <encoding> ::= <function name> <bare-function-type>
|
||||
* ::= <data name>
|
||||
* ::= <special-name>
|
||||
*/
|
||||
|
||||
CppMangleState cms;
|
||||
memset(&cms, 0, sizeof(cms));
|
||||
cms.components.setDim(0);
|
||||
|
||||
OutBuffer buf;
|
||||
#if MACHOBJ
|
||||
buf.writestring("__Z");
|
||||
#else
|
||||
buf.writestring("_Z");
|
||||
#endif
|
||||
|
||||
cpp_mangle_name(&buf, &cms, s);
|
||||
|
||||
FuncDeclaration *fd = s->isFuncDeclaration();
|
||||
if (fd)
|
||||
{ // add <bare-function-type>
|
||||
TypeFunction *tf = (TypeFunction *)fd->type;
|
||||
assert(tf->ty == Tfunction);
|
||||
Parameter::argsCppMangle(&buf, &cms, tf->parameters, tf->varargs);
|
||||
}
|
||||
buf.writeByte(0);
|
||||
return (char *)buf.extractData();
|
||||
}
|
||||
|
||||
/* ============= Type Encodings ============================================= */
|
||||
|
||||
void Type::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
/* Make this the 'vendor extended type' when there is no
|
||||
* C++ analog.
|
||||
* u <source-name>
|
||||
*/
|
||||
if (!cms->substitute(buf, this))
|
||||
{ assert(deco);
|
||||
buf->printf("u%d%s", strlen(deco), deco);
|
||||
}
|
||||
}
|
||||
|
||||
void TypeBasic::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{ char c;
|
||||
char p = 0;
|
||||
|
||||
/* ABI spec says:
|
||||
* v void
|
||||
* w wchar_t
|
||||
* b bool
|
||||
* c char
|
||||
* a signed char
|
||||
* h unsigned char
|
||||
* s short
|
||||
* t unsigned short
|
||||
* i int
|
||||
* j unsigned int
|
||||
* l long
|
||||
* m unsigned long
|
||||
* x long long, __int64
|
||||
* y unsigned long long, __int64
|
||||
* n __int128
|
||||
* o unsigned __int128
|
||||
* f float
|
||||
* d double
|
||||
* e long double, __float80
|
||||
* g __float128
|
||||
* z ellipsis
|
||||
* u <source-name> # vendor extended type
|
||||
*/
|
||||
|
||||
if (isConst())
|
||||
buf->writeByte('K');
|
||||
|
||||
switch (ty)
|
||||
{
|
||||
case Tvoid: c = 'v'; break;
|
||||
case Tint8: c = 'a'; break;
|
||||
case Tuns8: c = 'h'; break;
|
||||
case Tint16: c = 's'; break;
|
||||
case Tuns16: c = 't'; break;
|
||||
case Tint32: c = 'i'; break;
|
||||
case Tuns32: c = 'j'; break;
|
||||
case Tfloat32: c = 'f'; break;
|
||||
case Tint64: c = 'x'; break;
|
||||
case Tuns64: c = 'y'; break;
|
||||
case Tfloat64: c = 'd'; break;
|
||||
case Tfloat80: c = 'e'; break;
|
||||
case Tbool: c = 'b'; break;
|
||||
case Tchar: c = 'c'; break;
|
||||
case Twchar: c = 't'; break;
|
||||
case Tdchar: c = 'w'; break;
|
||||
|
||||
case Timaginary32: p = 'G'; c = 'f'; break;
|
||||
case Timaginary64: p = 'G'; c = 'd'; break;
|
||||
case Timaginary80: p = 'G'; c = 'e'; break;
|
||||
case Tcomplex32: p = 'C'; c = 'f'; break;
|
||||
case Tcomplex64: p = 'C'; c = 'd'; break;
|
||||
case Tcomplex80: p = 'C'; c = 'e'; break;
|
||||
|
||||
default: assert(0);
|
||||
}
|
||||
if (p)
|
||||
{
|
||||
if (cms->substitute(buf, this))
|
||||
return;
|
||||
buf->writeByte(p);
|
||||
}
|
||||
buf->writeByte(c);
|
||||
}
|
||||
|
||||
|
||||
void TypeSArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, this))
|
||||
{ buf->printf("A%ju_", dim ? dim->toInteger() : 0);
|
||||
next->toCppMangle(buf, cms);
|
||||
}
|
||||
}
|
||||
|
||||
void TypeDArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
Type::toCppMangle(buf, cms);
|
||||
}
|
||||
|
||||
|
||||
void TypeAArray::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
Type::toCppMangle(buf, cms);
|
||||
}
|
||||
|
||||
|
||||
void TypePointer::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, this))
|
||||
{ buf->writeByte('P');
|
||||
next->toCppMangle(buf, cms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TypeReference::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, this))
|
||||
{ buf->writeByte('R');
|
||||
next->toCppMangle(buf, cms);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TypeFunction::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{ /*
|
||||
* <function-type> ::= F [Y] <bare-function-type> E
|
||||
* <bare-function-type> ::= <signature type>+
|
||||
* # types are possible return type, then parameter types
|
||||
*/
|
||||
|
||||
/* ABI says:
|
||||
"The type of a non-static member function is considered to be different,
|
||||
for the purposes of substitution, from the type of a namespace-scope or
|
||||
static member function whose type appears similar. The types of two
|
||||
non-static member functions are considered to be different, for the
|
||||
purposes of substitution, if the functions are members of different
|
||||
classes. In other words, for the purposes of substitution, the class of
|
||||
which the function is a member is considered part of the type of
|
||||
function."
|
||||
|
||||
BUG: Right now, types of functions are never merged, so our simplistic
|
||||
component matcher always finds them to be different.
|
||||
We should use Type::equals on these, and use different
|
||||
TypeFunctions for non-static member functions, and non-static
|
||||
member functions of different classes.
|
||||
*/
|
||||
if (!cms->substitute(buf, this))
|
||||
{
|
||||
buf->writeByte('F');
|
||||
if (linkage == LINKc)
|
||||
buf->writeByte('Y');
|
||||
next->toCppMangle(buf, cms);
|
||||
Parameter::argsCppMangle(buf, cms, parameters, varargs);
|
||||
buf->writeByte('E');
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void TypeDelegate::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
Type::toCppMangle(buf, cms);
|
||||
}
|
||||
|
||||
|
||||
void TypeStruct::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, sym))
|
||||
cpp_mangle_name(buf, cms, sym);
|
||||
}
|
||||
|
||||
|
||||
void TypeEnum::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, sym))
|
||||
cpp_mangle_name(buf, cms, sym);
|
||||
}
|
||||
|
||||
|
||||
void TypeTypedef::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
Type::toCppMangle(buf, cms);
|
||||
}
|
||||
|
||||
|
||||
void TypeClass::toCppMangle(OutBuffer *buf, CppMangleState *cms)
|
||||
{
|
||||
if (!cms->substitute(buf, this))
|
||||
{ buf->writeByte('P');
|
||||
if (!cms->substitute(buf, sym))
|
||||
cpp_mangle_name(buf, cms, sym);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void Parameter::argsCppMangle(OutBuffer *buf, CppMangleState *cms, Parameters *arguments, int varargs)
|
||||
{ int n = 0;
|
||||
if (arguments)
|
||||
{
|
||||
for (size_t i = 0; i < arguments->dim; i++)
|
||||
{ Parameter *arg = (Parameter *)arguments->data[i];
|
||||
Type *t = arg->type;
|
||||
if (arg->storageClass & (STCout | STCref))
|
||||
t = t->referenceTo();
|
||||
else if (arg->storageClass & STClazy)
|
||||
{ // Mangle as delegate
|
||||
Type *td = new TypeFunction(NULL, t, 0, LINKd);
|
||||
td = new TypeDelegate(td);
|
||||
t = t->merge();
|
||||
}
|
||||
if (t->ty == Tsarray)
|
||||
{ // Mangle static arrays as pointers
|
||||
t = t->pointerTo();
|
||||
}
|
||||
t->toCppMangle(buf, cms);
|
||||
|
||||
n++;
|
||||
}
|
||||
}
|
||||
if (varargs)
|
||||
buf->writestring("z");
|
||||
else if (!n)
|
||||
buf->writeByte('v'); // encode ( ) arguments
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
3707
dmd2/declaration.c
3707
dmd2/declaration.c
File diff suppressed because it is too large
Load Diff
2042
dmd2/declaration.h
2042
dmd2/declaration.h
File diff suppressed because it is too large
Load Diff
@@ -1,214 +1,214 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 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 <assert.h>
|
||||
|
||||
#include "mars.h"
|
||||
#include "expression.h"
|
||||
#include "statement.h"
|
||||
#include "mtype.h"
|
||||
#include "utf.h"
|
||||
#include "declaration.h"
|
||||
#include "aggregate.h"
|
||||
#include "scope.h"
|
||||
|
||||
/********************************************
|
||||
* Convert from expression to delegate that returns the expression,
|
||||
* i.e. convert:
|
||||
* expr
|
||||
* to:
|
||||
* t delegate() { return expr; }
|
||||
*/
|
||||
|
||||
Expression *Expression::toDelegate(Scope *sc, Type *t)
|
||||
{
|
||||
//printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), toChars());
|
||||
TypeFunction *tf = new TypeFunction(NULL, t, 0, LINKd);
|
||||
FuncLiteralDeclaration *fld =
|
||||
new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);
|
||||
Expression *e;
|
||||
#if 1
|
||||
sc = sc->push();
|
||||
sc->parent = fld; // set current function to be the delegate
|
||||
e = this;
|
||||
e->scanForNestedRef(sc);
|
||||
sc = sc->pop();
|
||||
#else
|
||||
e = this->syntaxCopy();
|
||||
#endif
|
||||
Statement *s = new ReturnStatement(loc, e);
|
||||
fld->fbody = s;
|
||||
e = new FuncExp(loc, fld);
|
||||
e = e->semantic(sc);
|
||||
return e;
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Perform scanForNestedRef() on an array of Expressions.
|
||||
*/
|
||||
|
||||
void arrayExpressionScanForNestedRef(Scope *sc, Expressions *a)
|
||||
{
|
||||
//printf("arrayExpressionScanForNestedRef(%p)\n", a);
|
||||
if (a)
|
||||
{
|
||||
for (int i = 0; i < a->dim; i++)
|
||||
{ Expression *e = (Expression *)a->data[i];
|
||||
|
||||
if (e)
|
||||
{
|
||||
e->scanForNestedRef(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Expression::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("Expression::scanForNestedRef(%s)\n", toChars());
|
||||
}
|
||||
|
||||
void SymOffExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("SymOffExp::scanForNestedRef(%s)\n", toChars());
|
||||
VarDeclaration *v = var->isVarDeclaration();
|
||||
if (v)
|
||||
v->checkNestedReference(sc, 0);
|
||||
}
|
||||
|
||||
void VarExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("VarExp::scanForNestedRef(%s)\n", toChars());
|
||||
VarDeclaration *v = var->isVarDeclaration();
|
||||
if (v)
|
||||
v->checkNestedReference(sc, 0);
|
||||
}
|
||||
|
||||
void ThisExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
assert(var);
|
||||
var->isVarDeclaration()->checkNestedReference(sc, 0);
|
||||
}
|
||||
|
||||
void SuperExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
ThisExp::scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
void FuncExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("FuncExp::scanForNestedRef(%s)\n", toChars());
|
||||
//fd->parent = sc->parent;
|
||||
}
|
||||
|
||||
void DeclarationExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("DeclarationExp::scanForNestedRef() %s\n", toChars());
|
||||
declaration->parent = sc->parent;
|
||||
}
|
||||
|
||||
void NewExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("NewExp::scanForNestedRef(Scope *sc): %s\n", toChars());
|
||||
|
||||
if (thisexp)
|
||||
thisexp->scanForNestedRef(sc);
|
||||
arrayExpressionScanForNestedRef(sc, newargs);
|
||||
arrayExpressionScanForNestedRef(sc, arguments);
|
||||
}
|
||||
|
||||
void UnaExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
e1->scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
void BinExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
e1->scanForNestedRef(sc);
|
||||
e2->scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
void CallExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("CallExp::scanForNestedRef(Scope *sc): %s\n", toChars());
|
||||
e1->scanForNestedRef(sc);
|
||||
arrayExpressionScanForNestedRef(sc, arguments);
|
||||
}
|
||||
|
||||
|
||||
void IndexExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
e1->scanForNestedRef(sc);
|
||||
|
||||
if (lengthVar)
|
||||
{ //printf("lengthVar\n");
|
||||
lengthVar->parent = sc->parent;
|
||||
}
|
||||
e2->scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
|
||||
void SliceExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
e1->scanForNestedRef(sc);
|
||||
|
||||
if (lengthVar)
|
||||
{ //printf("lengthVar\n");
|
||||
lengthVar->parent = sc->parent;
|
||||
}
|
||||
if (lwr)
|
||||
lwr->scanForNestedRef(sc);
|
||||
if (upr)
|
||||
upr->scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
|
||||
void ArrayLiteralExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
arrayExpressionScanForNestedRef(sc, elements);
|
||||
}
|
||||
|
||||
|
||||
void AssocArrayLiteralExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
arrayExpressionScanForNestedRef(sc, keys);
|
||||
arrayExpressionScanForNestedRef(sc, values);
|
||||
}
|
||||
|
||||
|
||||
void StructLiteralExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
arrayExpressionScanForNestedRef(sc, elements);
|
||||
}
|
||||
|
||||
|
||||
void TupleExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
arrayExpressionScanForNestedRef(sc, exps);
|
||||
}
|
||||
|
||||
|
||||
void ArrayExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
e1->scanForNestedRef(sc);
|
||||
arrayExpressionScanForNestedRef(sc, arguments);
|
||||
}
|
||||
|
||||
|
||||
void CondExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
econd->scanForNestedRef(sc);
|
||||
e1->scanForNestedRef(sc);
|
||||
e2->scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 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 <assert.h>
|
||||
|
||||
#include "mars.h"
|
||||
#include "expression.h"
|
||||
#include "statement.h"
|
||||
#include "mtype.h"
|
||||
#include "utf.h"
|
||||
#include "declaration.h"
|
||||
#include "aggregate.h"
|
||||
#include "scope.h"
|
||||
|
||||
/********************************************
|
||||
* Convert from expression to delegate that returns the expression,
|
||||
* i.e. convert:
|
||||
* expr
|
||||
* to:
|
||||
* t delegate() { return expr; }
|
||||
*/
|
||||
|
||||
Expression *Expression::toDelegate(Scope *sc, Type *t)
|
||||
{
|
||||
//printf("Expression::toDelegate(t = %s) %s\n", t->toChars(), toChars());
|
||||
TypeFunction *tf = new TypeFunction(NULL, t, 0, LINKd);
|
||||
FuncLiteralDeclaration *fld =
|
||||
new FuncLiteralDeclaration(loc, loc, tf, TOKdelegate, NULL);
|
||||
Expression *e;
|
||||
#if 1
|
||||
sc = sc->push();
|
||||
sc->parent = fld; // set current function to be the delegate
|
||||
e = this;
|
||||
e->scanForNestedRef(sc);
|
||||
sc = sc->pop();
|
||||
#else
|
||||
e = this->syntaxCopy();
|
||||
#endif
|
||||
Statement *s = new ReturnStatement(loc, e);
|
||||
fld->fbody = s;
|
||||
e = new FuncExp(loc, fld);
|
||||
e = e->semantic(sc);
|
||||
return e;
|
||||
}
|
||||
|
||||
/******************************
|
||||
* Perform scanForNestedRef() on an array of Expressions.
|
||||
*/
|
||||
|
||||
void arrayExpressionScanForNestedRef(Scope *sc, Expressions *a)
|
||||
{
|
||||
//printf("arrayExpressionScanForNestedRef(%p)\n", a);
|
||||
if (a)
|
||||
{
|
||||
for (int i = 0; i < a->dim; i++)
|
||||
{ Expression *e = (Expression *)a->data[i];
|
||||
|
||||
if (e)
|
||||
{
|
||||
e->scanForNestedRef(sc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Expression::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("Expression::scanForNestedRef(%s)\n", toChars());
|
||||
}
|
||||
|
||||
void SymOffExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("SymOffExp::scanForNestedRef(%s)\n", toChars());
|
||||
VarDeclaration *v = var->isVarDeclaration();
|
||||
if (v)
|
||||
v->checkNestedReference(sc, 0);
|
||||
}
|
||||
|
||||
void VarExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("VarExp::scanForNestedRef(%s)\n", toChars());
|
||||
VarDeclaration *v = var->isVarDeclaration();
|
||||
if (v)
|
||||
v->checkNestedReference(sc, 0);
|
||||
}
|
||||
|
||||
void ThisExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
assert(var);
|
||||
var->isVarDeclaration()->checkNestedReference(sc, 0);
|
||||
}
|
||||
|
||||
void SuperExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
ThisExp::scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
void FuncExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("FuncExp::scanForNestedRef(%s)\n", toChars());
|
||||
//fd->parent = sc->parent;
|
||||
}
|
||||
|
||||
void DeclarationExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("DeclarationExp::scanForNestedRef() %s\n", toChars());
|
||||
declaration->parent = sc->parent;
|
||||
}
|
||||
|
||||
void NewExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("NewExp::scanForNestedRef(Scope *sc): %s\n", toChars());
|
||||
|
||||
if (thisexp)
|
||||
thisexp->scanForNestedRef(sc);
|
||||
arrayExpressionScanForNestedRef(sc, newargs);
|
||||
arrayExpressionScanForNestedRef(sc, arguments);
|
||||
}
|
||||
|
||||
void UnaExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
e1->scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
void BinExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
e1->scanForNestedRef(sc);
|
||||
e2->scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
void CallExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
//printf("CallExp::scanForNestedRef(Scope *sc): %s\n", toChars());
|
||||
e1->scanForNestedRef(sc);
|
||||
arrayExpressionScanForNestedRef(sc, arguments);
|
||||
}
|
||||
|
||||
|
||||
void IndexExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
e1->scanForNestedRef(sc);
|
||||
|
||||
if (lengthVar)
|
||||
{ //printf("lengthVar\n");
|
||||
lengthVar->parent = sc->parent;
|
||||
}
|
||||
e2->scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
|
||||
void SliceExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
e1->scanForNestedRef(sc);
|
||||
|
||||
if (lengthVar)
|
||||
{ //printf("lengthVar\n");
|
||||
lengthVar->parent = sc->parent;
|
||||
}
|
||||
if (lwr)
|
||||
lwr->scanForNestedRef(sc);
|
||||
if (upr)
|
||||
upr->scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
|
||||
void ArrayLiteralExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
arrayExpressionScanForNestedRef(sc, elements);
|
||||
}
|
||||
|
||||
|
||||
void AssocArrayLiteralExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
arrayExpressionScanForNestedRef(sc, keys);
|
||||
arrayExpressionScanForNestedRef(sc, values);
|
||||
}
|
||||
|
||||
|
||||
void StructLiteralExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
arrayExpressionScanForNestedRef(sc, elements);
|
||||
}
|
||||
|
||||
|
||||
void TupleExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
arrayExpressionScanForNestedRef(sc, exps);
|
||||
}
|
||||
|
||||
|
||||
void ArrayExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
e1->scanForNestedRef(sc);
|
||||
arrayExpressionScanForNestedRef(sc, arguments);
|
||||
}
|
||||
|
||||
|
||||
void CondExp::scanForNestedRef(Scope *sc)
|
||||
{
|
||||
econd->scanForNestedRef(sc);
|
||||
e1->scanForNestedRef(sc);
|
||||
e2->scanForNestedRef(sc);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
2232
dmd2/doc.c
2232
dmd2/doc.c
File diff suppressed because it is too large
Load Diff
38
dmd2/doc.h
38
dmd2/doc.h
@@ -1,19 +1,19 @@
|
||||
|
||||
// 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.
|
||||
|
||||
#ifndef DMD_DOC_H
|
||||
#define DMD_DOC_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// 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.
|
||||
|
||||
#ifndef DMD_DOC_H
|
||||
#define DMD_DOC_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
938
dmd2/dsymbol.c
938
dmd2/dsymbol.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-2009 by Digital Mars
|
||||
// Copyright (c) 1999-2010 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
@@ -47,6 +47,8 @@ struct PostBlitDeclaration;
|
||||
struct DtorDeclaration;
|
||||
struct StaticCtorDeclaration;
|
||||
struct StaticDtorDeclaration;
|
||||
struct SharedStaticCtorDeclaration;
|
||||
struct SharedStaticDtorDeclaration;
|
||||
struct InvariantDeclaration;
|
||||
struct UnitTestDeclaration;
|
||||
struct NewDeclaration;
|
||||
@@ -75,6 +77,7 @@ struct Expression;
|
||||
struct DeleteDeclaration;
|
||||
struct HdrGenState;
|
||||
struct OverloadSet;
|
||||
struct AA;
|
||||
#if TARGET_NET
|
||||
struct PragmaScope;
|
||||
#endif
|
||||
@@ -106,7 +109,7 @@ struct Classsym;
|
||||
enum PROT
|
||||
{
|
||||
PROTundefined,
|
||||
PROTnone, // no access
|
||||
PROTnone, // no access
|
||||
PROTprivate,
|
||||
PROTpackage,
|
||||
PROTprotected,
|
||||
@@ -114,6 +117,18 @@ enum PROT
|
||||
PROTexport,
|
||||
};
|
||||
|
||||
/* State of symbol in winding its way through the passes of the compiler
|
||||
*/
|
||||
enum PASS
|
||||
{
|
||||
PASSinit, // initial state
|
||||
PASSsemantic, // semantic() started
|
||||
PASSsemanticdone, // semantic() done
|
||||
PASSsemantic2, // semantic2() run
|
||||
PASSsemantic3, // semantic3() started
|
||||
PASSsemantic3done, // semantic3() done
|
||||
PASSobj, // toObjFile() run
|
||||
};
|
||||
|
||||
struct Dsymbol : Object
|
||||
{
|
||||
@@ -121,12 +136,12 @@ struct Dsymbol : Object
|
||||
Identifier *c_ident;
|
||||
Dsymbol *parent;
|
||||
#if IN_DMD
|
||||
Symbol *csym; // symbol for code generator
|
||||
Symbol *isym; // import version of csym
|
||||
Symbol *csym; // symbol for code generator
|
||||
Symbol *isym; // import version of csym
|
||||
#endif
|
||||
unsigned char *comment; // documentation comment for this Dsymbol
|
||||
Loc loc; // where defined
|
||||
Scope *scope; // !=NULL means context to use for semantic()
|
||||
unsigned char *comment; // documentation comment for this Dsymbol
|
||||
Loc loc; // where defined
|
||||
Scope *scope; // !=NULL means context to use for semantic()
|
||||
|
||||
Dsymbol();
|
||||
Dsymbol(Identifier *);
|
||||
@@ -144,20 +159,23 @@ struct Dsymbol : Object
|
||||
Dsymbol *toParent2();
|
||||
TemplateInstance *inTemplateInstance();
|
||||
|
||||
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
|
||||
int dyncast() { return DYNCAST_DSYMBOL; } // kludge for template.isSymbol()
|
||||
|
||||
static Array *arraySyntaxCopy(Array *a);
|
||||
static Dsymbols *arraySyntaxCopy(Dsymbols *a);
|
||||
|
||||
virtual const char *toPrettyChars();
|
||||
virtual const char *kind();
|
||||
virtual Dsymbol *toAlias(); // resolve real symbol
|
||||
virtual Dsymbol *toAlias(); // resolve real symbol
|
||||
virtual int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||
virtual void setScope(Scope *sc);
|
||||
virtual void importAll(Scope *sc);
|
||||
virtual void semantic0(Scope *sc);
|
||||
virtual void semantic(Scope *sc);
|
||||
virtual void semantic2(Scope *sc);
|
||||
virtual void semantic3(Scope *sc);
|
||||
virtual void inlineScan();
|
||||
virtual Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
Dsymbol *search_correct(Identifier *id);
|
||||
Dsymbol *searchX(Loc loc, Scope *sc, Identifier *id);
|
||||
virtual int overloadInsert(Dsymbol *s);
|
||||
#ifdef _DH
|
||||
@@ -166,24 +184,25 @@ struct Dsymbol : Object
|
||||
#endif
|
||||
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
virtual void toDocBuffer(OutBuffer *buf);
|
||||
virtual void toJsonBuffer(OutBuffer *buf);
|
||||
virtual unsigned size(Loc loc);
|
||||
virtual int isforwardRef();
|
||||
virtual void defineRef(Dsymbol *s);
|
||||
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 isDeprecated(); // is Dsymbol deprecated?
|
||||
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 isDeprecated(); // is Dsymbol deprecated?
|
||||
#if DMDV2
|
||||
virtual int isOverloadable();
|
||||
#endif
|
||||
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
|
||||
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
|
||||
virtual Type *getType(); // is this a type?
|
||||
virtual LabelDsymbol *isLabel(); // is this a LabelDsymbol?
|
||||
virtual AggregateDeclaration *isMember(); // is this symbol a member of an AggregateDeclaration?
|
||||
virtual Type *getType(); // is this a type?
|
||||
virtual char *mangle();
|
||||
virtual int needThis(); // need a 'this' pointer?
|
||||
virtual int needThis(); // need a 'this' pointer?
|
||||
virtual enum PROT prot();
|
||||
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
|
||||
virtual Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
|
||||
virtual int oneMember(Dsymbol **ps);
|
||||
static int oneMembers(Array *members, Dsymbol **ps);
|
||||
virtual int hasPointers();
|
||||
@@ -197,14 +216,14 @@ struct Dsymbol : Object
|
||||
#if IN_DMD
|
||||
// Backend
|
||||
|
||||
virtual Symbol *toSymbol(); // to backend symbol
|
||||
virtual void toObjFile(int multiobj); // compile to .obj file
|
||||
virtual int cvMember(unsigned char *p); // emit cv debug info for member
|
||||
virtual Symbol *toSymbol(); // to backend symbol
|
||||
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
|
||||
static Symbol *toImport(Symbol *s); // to backend import symbol
|
||||
Symbol *toImport(); // to backend import symbol
|
||||
static Symbol *toImport(Symbol *s); // to backend import symbol
|
||||
|
||||
Symbol *toSymbolX(const char *prefix, int sclass, TYPE *t, const char *suffix); // helper
|
||||
Symbol *toSymbolX(const char *prefix, int sclass, TYPE *t, const char *suffix); // helper
|
||||
#endif
|
||||
|
||||
// Eliminate need for dynamic_cast
|
||||
@@ -228,6 +247,8 @@ struct Dsymbol : Object
|
||||
virtual DtorDeclaration *isDtorDeclaration() { return NULL; }
|
||||
virtual StaticCtorDeclaration *isStaticCtorDeclaration() { return NULL; }
|
||||
virtual StaticDtorDeclaration *isStaticDtorDeclaration() { return NULL; }
|
||||
virtual SharedStaticCtorDeclaration *isSharedStaticCtorDeclaration() { return NULL; }
|
||||
virtual SharedStaticDtorDeclaration *isSharedStaticDtorDeclaration() { return NULL; }
|
||||
virtual InvariantDeclaration *isInvariantDeclaration() { return NULL; }
|
||||
virtual UnitTestDeclaration *isUnitTestDeclaration() { return NULL; }
|
||||
virtual NewDeclaration *isNewDeclaration() { return NULL; }
|
||||
@@ -268,11 +289,11 @@ struct Dsymbol : Object
|
||||
|
||||
struct ScopeDsymbol : Dsymbol
|
||||
{
|
||||
Array *members; // all Dsymbol's in this scope
|
||||
DsymbolTable *symtab; // members[] sorted into table
|
||||
Dsymbols *members; // all Dsymbol's in this scope
|
||||
DsymbolTable *symtab; // members[] sorted into table
|
||||
|
||||
Array *imports; // imported ScopeDsymbol's
|
||||
unsigned char *prots; // array of PROT, one for each import
|
||||
Array *imports; // imported ScopeDsymbol's
|
||||
unsigned char *prots; // array of PROT, one for each import
|
||||
|
||||
ScopeDsymbol();
|
||||
ScopeDsymbol(Identifier *id);
|
||||
@@ -285,6 +306,7 @@ struct ScopeDsymbol : Dsymbol
|
||||
Dsymbol *nameCollision(Dsymbol *s);
|
||||
const char *kind();
|
||||
FuncDeclaration *findGetMembers();
|
||||
virtual Dsymbol *symtabInsert(Dsymbol *s);
|
||||
|
||||
void emitMemberComments(Scope *sc);
|
||||
|
||||
@@ -310,9 +332,9 @@ struct WithScopeSymbol : ScopeDsymbol
|
||||
|
||||
struct ArrayScopeSymbol : ScopeDsymbol
|
||||
{
|
||||
Expression *exp; // IndexExp or SliceExp
|
||||
TypeTuple *type; // for tuple[length]
|
||||
TupleDeclaration *td; // for tuples of objects
|
||||
Expression *exp; // IndexExp or SliceExp
|
||||
TypeTuple *type; // for tuple[length]
|
||||
TupleDeclaration *td; // for tuples of objects
|
||||
Scope *sc;
|
||||
|
||||
ArrayScopeSymbol(Scope *sc, Expression *e);
|
||||
@@ -328,7 +350,7 @@ struct ArrayScopeSymbol : ScopeDsymbol
|
||||
#if DMDV2
|
||||
struct OverloadSet : Dsymbol
|
||||
{
|
||||
Dsymbols a; // array of Dsymbols
|
||||
Dsymbols a; // array of Dsymbols
|
||||
|
||||
OverloadSet();
|
||||
void push(Dsymbol *s);
|
||||
@@ -341,7 +363,11 @@ struct OverloadSet : Dsymbol
|
||||
|
||||
struct DsymbolTable : Object
|
||||
{
|
||||
#if STRINGTABLE
|
||||
StringTable *tab;
|
||||
#else
|
||||
AA *tab;
|
||||
#endif
|
||||
|
||||
DsymbolTable();
|
||||
~DsymbolTable();
|
||||
@@ -354,7 +380,7 @@ struct DsymbolTable : Object
|
||||
|
||||
// Look for Dsymbol in table. If there, return it. If not, insert s and return that.
|
||||
Dsymbol *update(Dsymbol *s);
|
||||
Dsymbol *insert(Identifier *ident, Dsymbol *s); // when ident and s are not the same
|
||||
Dsymbol *insert(Identifier *ident, Dsymbol *s); // when ident and s are not the same
|
||||
};
|
||||
|
||||
#endif /* DMD_DSYMBOL_H */
|
||||
|
||||
288
dmd2/dump.c
288
dmd2/dump.c
@@ -1,144 +1,144 @@
|
||||
|
||||
// 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.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mars.h"
|
||||
#include "mtype.h"
|
||||
#include "declaration.h"
|
||||
#include "expression.h"
|
||||
#include "template.h"
|
||||
|
||||
static void indent(int indent)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static char *type_print(Type *type)
|
||||
{
|
||||
return type ? type->toChars() : (char *) "null";
|
||||
}
|
||||
|
||||
void dumpExpressions(int i, Expressions *exps)
|
||||
{
|
||||
for (size_t j = 0; j < exps->dim; j++)
|
||||
{ Expression *e = (Expression *)exps->data[j];
|
||||
indent(i);
|
||||
printf("(\n");
|
||||
e->dump(i + 2);
|
||||
indent(i);
|
||||
printf(")\n");
|
||||
}
|
||||
}
|
||||
|
||||
void Expression::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s\n", this, Token::toChars(op), type_print(type));
|
||||
}
|
||||
|
||||
void IntegerExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %jd type=%s\n", this, (intmax_t)value, type_print(type));
|
||||
}
|
||||
|
||||
void IdentifierExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p ident '%s' type=%s\n", this, ident->toChars(), type_print(type));
|
||||
}
|
||||
|
||||
void DsymbolExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s\n", this, s->toChars(), type_print(type));
|
||||
}
|
||||
|
||||
void VarExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s var=%s type=%s\n", this, Token::toChars(op), var->toChars(), type_print(type));
|
||||
}
|
||||
|
||||
void UnaExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s e1=%p\n", this, Token::toChars(op), type_print(type), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
}
|
||||
|
||||
void CallExp::dump(int i)
|
||||
{
|
||||
UnaExp::dump(i);
|
||||
dumpExpressions(i, arguments);
|
||||
}
|
||||
|
||||
void SliceExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s e1=%p\n", this, Token::toChars(op), type_print(type), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
if (lwr)
|
||||
lwr->dump(i + 2);
|
||||
if (upr)
|
||||
upr->dump(i + 2);
|
||||
}
|
||||
|
||||
void DotIdExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s ident=%s e1=%p\n", this, Token::toChars(op), type_print(type), ident->toChars(), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
}
|
||||
|
||||
void DotVarExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s var='%s' e1=%p\n", this, Token::toChars(op), type_print(type), var->toChars(), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
}
|
||||
|
||||
void DotTemplateInstanceExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s ti='%s' e1=%p\n", this, Token::toChars(op), type_print(type), ti->toChars(), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
}
|
||||
|
||||
void DelegateExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s func=%s type=%s e1=%p\n", this, Token::toChars(op), func->toChars(), type_print(type), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
}
|
||||
|
||||
void BinExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s e1=%p e2=%p\n", this, Token::toChars(op), type_print(type), e1, e2);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
if (e2)
|
||||
e2->dump(i + 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// 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.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "mars.h"
|
||||
#include "mtype.h"
|
||||
#include "declaration.h"
|
||||
#include "expression.h"
|
||||
#include "template.h"
|
||||
|
||||
static void indent(int indent)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < indent; i++)
|
||||
printf(" ");
|
||||
}
|
||||
|
||||
static char *type_print(Type *type)
|
||||
{
|
||||
return type ? type->toChars() : (char *) "null";
|
||||
}
|
||||
|
||||
void dumpExpressions(int i, Expressions *exps)
|
||||
{
|
||||
for (size_t j = 0; j < exps->dim; j++)
|
||||
{ Expression *e = (Expression *)exps->data[j];
|
||||
indent(i);
|
||||
printf("(\n");
|
||||
e->dump(i + 2);
|
||||
indent(i);
|
||||
printf(")\n");
|
||||
}
|
||||
}
|
||||
|
||||
void Expression::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s\n", this, Token::toChars(op), type_print(type));
|
||||
}
|
||||
|
||||
void IntegerExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %jd type=%s\n", this, (intmax_t)value, type_print(type));
|
||||
}
|
||||
|
||||
void IdentifierExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p ident '%s' type=%s\n", this, ident->toChars(), type_print(type));
|
||||
}
|
||||
|
||||
void DsymbolExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s\n", this, s->toChars(), type_print(type));
|
||||
}
|
||||
|
||||
void VarExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s var=%s type=%s\n", this, Token::toChars(op), var->toChars(), type_print(type));
|
||||
}
|
||||
|
||||
void UnaExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s e1=%p\n", this, Token::toChars(op), type_print(type), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
}
|
||||
|
||||
void CallExp::dump(int i)
|
||||
{
|
||||
UnaExp::dump(i);
|
||||
dumpExpressions(i, arguments);
|
||||
}
|
||||
|
||||
void SliceExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s e1=%p\n", this, Token::toChars(op), type_print(type), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
if (lwr)
|
||||
lwr->dump(i + 2);
|
||||
if (upr)
|
||||
upr->dump(i + 2);
|
||||
}
|
||||
|
||||
void DotIdExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s ident=%s e1=%p\n", this, Token::toChars(op), type_print(type), ident->toChars(), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
}
|
||||
|
||||
void DotVarExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s var='%s' e1=%p\n", this, Token::toChars(op), type_print(type), var->toChars(), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
}
|
||||
|
||||
void DotTemplateInstanceExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s ti='%s' e1=%p\n", this, Token::toChars(op), type_print(type), ti->toChars(), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
}
|
||||
|
||||
void DelegateExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s func=%s type=%s e1=%p\n", this, Token::toChars(op), func->toChars(), type_print(type), e1);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
}
|
||||
|
||||
void BinExp::dump(int i)
|
||||
{
|
||||
indent(i);
|
||||
printf("%p %s type=%s e1=%p e2=%p\n", this, Token::toChars(op), type_print(type), e1, e2);
|
||||
if (e1)
|
||||
e1->dump(i + 2);
|
||||
if (e2)
|
||||
e2->dump(i + 2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
2456
dmd2/entity.c
2456
dmd2/entity.c
File diff suppressed because it is too large
Load Diff
821
dmd2/enum.c
821
dmd2/enum.c
@@ -1,393 +1,428 @@
|
||||
|
||||
// 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.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "enum.h"
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
#include "id.h"
|
||||
#include "expression.h"
|
||||
#include "module.h"
|
||||
#include "declaration.h"
|
||||
|
||||
/********************************* EnumDeclaration ****************************/
|
||||
|
||||
EnumDeclaration::EnumDeclaration(Loc loc, Identifier *id, Type *memtype)
|
||||
: ScopeDsymbol(id)
|
||||
{
|
||||
this->loc = loc;
|
||||
type = new TypeEnum(this);
|
||||
this->memtype = memtype;
|
||||
maxval = NULL;
|
||||
minval = NULL;
|
||||
defaultval = NULL;
|
||||
#if IN_DMD
|
||||
sinit = NULL;
|
||||
#endif
|
||||
isdeprecated = 0;
|
||||
}
|
||||
|
||||
Dsymbol *EnumDeclaration::syntaxCopy(Dsymbol *s)
|
||||
{
|
||||
Type *t = NULL;
|
||||
if (memtype)
|
||||
t = memtype->syntaxCopy();
|
||||
|
||||
EnumDeclaration *ed;
|
||||
if (s)
|
||||
{ ed = (EnumDeclaration *)s;
|
||||
ed->memtype = t;
|
||||
}
|
||||
else
|
||||
ed = new EnumDeclaration(loc, ident, t);
|
||||
ScopeDsymbol::syntaxCopy(ed);
|
||||
return ed;
|
||||
}
|
||||
|
||||
void EnumDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
Type *t;
|
||||
Scope *sce;
|
||||
|
||||
//printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc->scopesym, sc->scopesym->toChars(), toChars());
|
||||
//printf("EnumDeclaration::semantic() %s\n", toChars());
|
||||
if (!members) // enum ident;
|
||||
return;
|
||||
|
||||
if (!memtype && !isAnonymous())
|
||||
{ // Set memtype if we can to reduce fwd reference errors
|
||||
memtype = Type::tint32; // case 1) enum ident { ... }
|
||||
}
|
||||
|
||||
if (symtab) // if already done
|
||||
{ if (!scope)
|
||||
return; // semantic() already completed
|
||||
}
|
||||
else
|
||||
symtab = new DsymbolTable();
|
||||
|
||||
Scope *scx = NULL;
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scx = scope; // save so we don't make redundant copies
|
||||
scope = NULL;
|
||||
}
|
||||
|
||||
if (sc->stc & STCdeprecated)
|
||||
isdeprecated = 1;
|
||||
|
||||
parent = sc->parent;
|
||||
|
||||
/* The separate, and distinct, cases are:
|
||||
* 1. enum { ... }
|
||||
* 2. enum : memtype { ... }
|
||||
* 3. enum ident { ... }
|
||||
* 4. enum ident : memtype { ... }
|
||||
*/
|
||||
|
||||
if (memtype)
|
||||
{
|
||||
memtype = memtype->semantic(loc, sc);
|
||||
|
||||
/* Check to see if memtype is forward referenced
|
||||
*/
|
||||
if (memtype->ty == Tenum)
|
||||
{ EnumDeclaration *sym = (EnumDeclaration *)memtype->toDsymbol(sc);
|
||||
if (!sym->memtype || !sym->members || !sym->symtab || sym->scope)
|
||||
{ // memtype is forward referenced, so try again later
|
||||
scope = scx ? scx : new Scope(*sc);
|
||||
scope->setNoFree();
|
||||
scope->module->addDeferredSemantic(this);
|
||||
printf("\tdeferring %s\n", toChars());
|
||||
return;
|
||||
}
|
||||
}
|
||||
#if 0 // Decided to abandon this restriction for D 2.0
|
||||
if (!memtype->isintegral())
|
||||
{ error("base type must be of integral type, not %s", memtype->toChars());
|
||||
memtype = Type::tint32;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
type = type->semantic(loc, sc);
|
||||
if (isAnonymous())
|
||||
sce = sc;
|
||||
else
|
||||
{ sce = sc->push(this);
|
||||
sce->parent = this;
|
||||
}
|
||||
if (members->dim == 0)
|
||||
error("enum %s must have at least one member", toChars());
|
||||
int first = 1;
|
||||
Expression *elast = NULL;
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{
|
||||
EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
|
||||
Expression *e;
|
||||
|
||||
if (!em)
|
||||
/* The e->semantic(sce) can insert other symbols, such as
|
||||
* template instances and function literals.
|
||||
*/
|
||||
continue;
|
||||
|
||||
//printf(" Enum member '%s'\n",em->toChars());
|
||||
if (em->type)
|
||||
em->type = em->type->semantic(em->loc, sce);
|
||||
e = em->value;
|
||||
if (e)
|
||||
{
|
||||
assert(e->dyncast() == DYNCAST_EXPRESSION);
|
||||
e = e->semantic(sce);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (memtype)
|
||||
{
|
||||
e = e->implicitCastTo(sce, memtype);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (!isAnonymous())
|
||||
e = e->castTo(sce, type);
|
||||
t = memtype;
|
||||
}
|
||||
else if (em->type)
|
||||
{
|
||||
e = e->implicitCastTo(sce, em->type);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
assert(isAnonymous());
|
||||
t = e->type;
|
||||
}
|
||||
else
|
||||
t = e->type;
|
||||
}
|
||||
else if (first)
|
||||
{
|
||||
if (memtype)
|
||||
t = memtype;
|
||||
else if (em->type)
|
||||
t = em->type;
|
||||
else
|
||||
t = Type::tint32;
|
||||
e = new IntegerExp(em->loc, 0, Type::tint32);
|
||||
e = e->implicitCastTo(sce, t);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (!isAnonymous())
|
||||
e = e->castTo(sce, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set value to (elast + 1).
|
||||
// But first check that (elast != t.max)
|
||||
assert(elast);
|
||||
e = new EqualExp(TOKequal, em->loc, elast, t->getProperty(0, Id::max));
|
||||
e = e->semantic(sce);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (e->toInteger())
|
||||
error("overflow of enum value %s", elast->toChars());
|
||||
|
||||
// Now set e to (elast + 1)
|
||||
e = new AddExp(em->loc, elast, new IntegerExp(em->loc, 1, Type::tint32));
|
||||
e = e->semantic(sce);
|
||||
e = e->castTo(sce, elast->type);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
}
|
||||
elast = e;
|
||||
em->value = e;
|
||||
|
||||
// Add to symbol table only after evaluating 'value'
|
||||
if (isAnonymous())
|
||||
{
|
||||
/* Anonymous enum members get added to enclosing scope.
|
||||
*/
|
||||
for (Scope *scx = sce; scx; scx = scx->enclosing)
|
||||
{
|
||||
if (scx->scopesym)
|
||||
{
|
||||
if (!scx->scopesym->symtab)
|
||||
scx->scopesym->symtab = new DsymbolTable();
|
||||
em->addMember(sce, scx->scopesym, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
em->addMember(sc, this, 1);
|
||||
|
||||
/* Compute .min, .max and .default values.
|
||||
* If enum doesn't have a name, we can never identify the enum type,
|
||||
* so there is no purpose for a .min, .max or .default
|
||||
*/
|
||||
if (!isAnonymous())
|
||||
{
|
||||
if (first)
|
||||
{ defaultval = e;
|
||||
minval = e;
|
||||
maxval = e;
|
||||
}
|
||||
else
|
||||
{ Expression *ec;
|
||||
|
||||
/* In order to work successfully with UDTs,
|
||||
* build expressions to do the comparisons,
|
||||
* and let the semantic analyzer and constant
|
||||
* folder give us the result.
|
||||
*/
|
||||
|
||||
// Compute if(e < minval)
|
||||
ec = new CmpExp(TOKlt, em->loc, e, minval);
|
||||
ec = ec->semantic(sce);
|
||||
ec = ec->optimize(WANTvalue | WANTinterpret);
|
||||
if (ec->toInteger())
|
||||
minval = e;
|
||||
|
||||
ec = new CmpExp(TOKgt, em->loc, e, maxval);
|
||||
ec = ec->semantic(sce);
|
||||
ec = ec->optimize(WANTvalue | WANTinterpret);
|
||||
if (ec->toInteger())
|
||||
maxval = e;
|
||||
}
|
||||
}
|
||||
first = 0;
|
||||
}
|
||||
//printf("defaultval = %lld\n", defaultval);
|
||||
|
||||
//if (defaultval) printf("defaultval: %s %s\n", defaultval->toChars(), defaultval->type->toChars());
|
||||
if (sc != sce)
|
||||
sce->pop();
|
||||
//members->print();
|
||||
}
|
||||
|
||||
int EnumDeclaration::oneMember(Dsymbol **ps)
|
||||
{
|
||||
if (isAnonymous())
|
||||
return Dsymbol::oneMembers(members, ps);
|
||||
return Dsymbol::oneMember(ps);
|
||||
}
|
||||
|
||||
void EnumDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{ int i;
|
||||
|
||||
buf->writestring("enum ");
|
||||
if (ident)
|
||||
{ buf->writestring(ident->toChars());
|
||||
buf->writeByte(' ');
|
||||
}
|
||||
if (memtype)
|
||||
{
|
||||
buf->writestring(": ");
|
||||
memtype->toCBuffer(buf, NULL, hgs);
|
||||
}
|
||||
if (!members)
|
||||
{
|
||||
buf->writeByte(';');
|
||||
buf->writenl();
|
||||
return;
|
||||
}
|
||||
buf->writenl();
|
||||
buf->writeByte('{');
|
||||
buf->writenl();
|
||||
for (i = 0; i < members->dim; i++)
|
||||
{
|
||||
EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
|
||||
if (!em)
|
||||
continue;
|
||||
//buf->writestring(" ");
|
||||
em->toCBuffer(buf, hgs);
|
||||
buf->writeByte(',');
|
||||
buf->writenl();
|
||||
}
|
||||
buf->writeByte('}');
|
||||
buf->writenl();
|
||||
}
|
||||
|
||||
Type *EnumDeclaration::getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
const char *EnumDeclaration::kind()
|
||||
{
|
||||
return "enum";
|
||||
}
|
||||
|
||||
int EnumDeclaration::isDeprecated()
|
||||
{
|
||||
return isdeprecated;
|
||||
}
|
||||
|
||||
Dsymbol *EnumDeclaration::search(Loc loc, Identifier *ident, int flags)
|
||||
{
|
||||
//printf("%s.EnumDeclaration::search('%s')\n", toChars(), ident->toChars());
|
||||
if (scope)
|
||||
// Try one last time to resolve this enum
|
||||
semantic(scope);
|
||||
|
||||
if (!members || !symtab || scope)
|
||||
{ error("is forward referenced when looking for '%s'", ident->toChars());
|
||||
//*(char*)0=0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Dsymbol *s = ScopeDsymbol::search(loc, ident, flags);
|
||||
return s;
|
||||
}
|
||||
|
||||
/********************************* EnumMember ****************************/
|
||||
|
||||
EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value, Type *type)
|
||||
: Dsymbol(id)
|
||||
{
|
||||
this->value = value;
|
||||
this->type = type;
|
||||
this->loc = loc;
|
||||
}
|
||||
|
||||
Dsymbol *EnumMember::syntaxCopy(Dsymbol *s)
|
||||
{
|
||||
Expression *e = NULL;
|
||||
if (value)
|
||||
e = value->syntaxCopy();
|
||||
|
||||
Type *t = NULL;
|
||||
if (type)
|
||||
t = type->syntaxCopy();
|
||||
|
||||
EnumMember *em;
|
||||
if (s)
|
||||
{ em = (EnumMember *)s;
|
||||
em->loc = loc;
|
||||
em->value = e;
|
||||
em->type = t;
|
||||
}
|
||||
else
|
||||
em = new EnumMember(loc, ident, e, t);
|
||||
return em;
|
||||
}
|
||||
|
||||
void EnumMember::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (type)
|
||||
type->toCBuffer(buf, ident, hgs);
|
||||
else
|
||||
buf->writestring(ident->toChars());
|
||||
if (value)
|
||||
{
|
||||
buf->writestring(" = ");
|
||||
value->toCBuffer(buf, hgs);
|
||||
}
|
||||
}
|
||||
|
||||
const char *EnumMember::kind()
|
||||
{
|
||||
return "enum member";
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Copyright (c) 1999-2010 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 <assert.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "enum.h"
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
#include "id.h"
|
||||
#include "expression.h"
|
||||
#include "module.h"
|
||||
#include "declaration.h"
|
||||
|
||||
/********************************* EnumDeclaration ****************************/
|
||||
|
||||
EnumDeclaration::EnumDeclaration(Loc loc, Identifier *id, Type *memtype)
|
||||
: ScopeDsymbol(id)
|
||||
{
|
||||
this->loc = loc;
|
||||
type = new TypeEnum(this);
|
||||
this->memtype = memtype;
|
||||
maxval = NULL;
|
||||
minval = NULL;
|
||||
defaultval = NULL;
|
||||
#if IN_DMD
|
||||
sinit = NULL;
|
||||
#endif
|
||||
isdeprecated = 0;
|
||||
isdone = 0;
|
||||
}
|
||||
|
||||
Dsymbol *EnumDeclaration::syntaxCopy(Dsymbol *s)
|
||||
{
|
||||
Type *t = NULL;
|
||||
if (memtype)
|
||||
t = memtype->syntaxCopy();
|
||||
|
||||
EnumDeclaration *ed;
|
||||
if (s)
|
||||
{ ed = (EnumDeclaration *)s;
|
||||
ed->memtype = t;
|
||||
}
|
||||
else
|
||||
ed = new EnumDeclaration(loc, ident, t);
|
||||
ScopeDsymbol::syntaxCopy(ed);
|
||||
return ed;
|
||||
}
|
||||
|
||||
void EnumDeclaration::semantic0(Scope *sc)
|
||||
{
|
||||
/* This function is a hack to get around a significant problem.
|
||||
* The members of anonymous enums, like:
|
||||
* enum { A, B, C }
|
||||
* don't get installed into the symbol table until after they are
|
||||
* semantically analyzed, yet they're supposed to go into the enclosing
|
||||
* scope's table. Hence, when forward referenced, they come out as
|
||||
* 'undefined'. The real fix is to add them in at addSymbol() time.
|
||||
* But to get code to compile, we'll just do this quick hack at the moment
|
||||
* to compile it if it doesn't depend on anything else.
|
||||
*/
|
||||
|
||||
if (isdone || !scope)
|
||||
return;
|
||||
if (!isAnonymous() || memtype)
|
||||
return;
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{
|
||||
EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
|
||||
if (em && (em->type || em->value))
|
||||
return;
|
||||
}
|
||||
|
||||
// Can do it
|
||||
semantic(sc);
|
||||
}
|
||||
|
||||
void EnumDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
Type *t;
|
||||
Scope *sce;
|
||||
|
||||
//printf("EnumDeclaration::semantic(sd = %p, '%s') %s\n", sc->scopesym, sc->scopesym->toChars(), toChars());
|
||||
//printf("EnumDeclaration::semantic() %s\n", toChars());
|
||||
if (!members) // enum ident;
|
||||
return;
|
||||
|
||||
if (!memtype && !isAnonymous())
|
||||
{ // Set memtype if we can to reduce fwd reference errors
|
||||
memtype = Type::tint32; // case 1) enum ident { ... }
|
||||
}
|
||||
|
||||
if (symtab) // if already done
|
||||
{ if (isdone || !scope)
|
||||
return; // semantic() already completed
|
||||
}
|
||||
else
|
||||
symtab = new DsymbolTable();
|
||||
|
||||
Scope *scx = NULL;
|
||||
if (scope)
|
||||
{ sc = scope;
|
||||
scx = scope; // save so we don't make redundant copies
|
||||
scope = NULL;
|
||||
}
|
||||
|
||||
unsigned dprogress_save = Module::dprogress;
|
||||
|
||||
if (sc->stc & STCdeprecated)
|
||||
isdeprecated = 1;
|
||||
|
||||
parent = sc->parent;
|
||||
|
||||
/* The separate, and distinct, cases are:
|
||||
* 1. enum { ... }
|
||||
* 2. enum : memtype { ... }
|
||||
* 3. enum ident { ... }
|
||||
* 4. enum ident : memtype { ... }
|
||||
*/
|
||||
|
||||
if (memtype)
|
||||
{
|
||||
memtype = memtype->semantic(loc, sc);
|
||||
|
||||
/* Check to see if memtype is forward referenced
|
||||
*/
|
||||
if (memtype->ty == Tenum)
|
||||
{ EnumDeclaration *sym = (EnumDeclaration *)memtype->toDsymbol(sc);
|
||||
if (!sym->memtype || !sym->members || !sym->symtab || sym->scope)
|
||||
{ // memtype is forward referenced, so try again later
|
||||
scope = scx ? scx : new Scope(*sc);
|
||||
scope->setNoFree();
|
||||
scope->module->addDeferredSemantic(this);
|
||||
Module::dprogress = dprogress_save;
|
||||
//printf("\tdeferring %s\n", toChars());
|
||||
return;
|
||||
}
|
||||
}
|
||||
#if 0 // Decided to abandon this restriction for D 2.0
|
||||
if (!memtype->isintegral())
|
||||
{ error("base type must be of integral type, not %s", memtype->toChars());
|
||||
memtype = Type::tint32;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
isdone = 1;
|
||||
Module::dprogress++;
|
||||
|
||||
type = type->semantic(loc, sc);
|
||||
if (isAnonymous())
|
||||
sce = sc;
|
||||
else
|
||||
{ sce = sc->push(this);
|
||||
sce->parent = this;
|
||||
}
|
||||
if (members->dim == 0)
|
||||
error("enum %s must have at least one member", toChars());
|
||||
int first = 1;
|
||||
Expression *elast = NULL;
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{
|
||||
EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
|
||||
Expression *e;
|
||||
|
||||
if (!em)
|
||||
/* The e->semantic(sce) can insert other symbols, such as
|
||||
* template instances and function literals.
|
||||
*/
|
||||
continue;
|
||||
|
||||
//printf(" Enum member '%s'\n",em->toChars());
|
||||
if (em->type)
|
||||
em->type = em->type->semantic(em->loc, sce);
|
||||
e = em->value;
|
||||
if (e)
|
||||
{
|
||||
assert(e->dyncast() == DYNCAST_EXPRESSION);
|
||||
e = e->semantic(sce);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (memtype)
|
||||
{
|
||||
e = e->implicitCastTo(sce, memtype);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (!isAnonymous())
|
||||
e = e->castTo(sce, type);
|
||||
t = memtype;
|
||||
}
|
||||
else if (em->type)
|
||||
{
|
||||
e = e->implicitCastTo(sce, em->type);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
assert(isAnonymous());
|
||||
t = e->type;
|
||||
}
|
||||
else
|
||||
t = e->type;
|
||||
}
|
||||
else if (first)
|
||||
{
|
||||
if (memtype)
|
||||
t = memtype;
|
||||
else if (em->type)
|
||||
t = em->type;
|
||||
else
|
||||
t = Type::tint32;
|
||||
e = new IntegerExp(em->loc, 0, Type::tint32);
|
||||
e = e->implicitCastTo(sce, t);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (!isAnonymous())
|
||||
e = e->castTo(sce, type);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set value to (elast + 1).
|
||||
// But first check that (elast != t.max)
|
||||
assert(elast);
|
||||
e = new EqualExp(TOKequal, em->loc, elast, t->getProperty(0, Id::max));
|
||||
e = e->semantic(sce);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (e->toInteger())
|
||||
error("overflow of enum value %s", elast->toChars());
|
||||
|
||||
// Now set e to (elast + 1)
|
||||
e = new AddExp(em->loc, elast, new IntegerExp(em->loc, 1, Type::tint32));
|
||||
e = e->semantic(sce);
|
||||
e = e->castTo(sce, elast->type);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
}
|
||||
elast = e;
|
||||
em->value = e;
|
||||
|
||||
// Add to symbol table only after evaluating 'value'
|
||||
if (isAnonymous())
|
||||
{
|
||||
/* Anonymous enum members get added to enclosing scope.
|
||||
*/
|
||||
for (Scope *scx = sce; scx; scx = scx->enclosing)
|
||||
{
|
||||
if (scx->scopesym)
|
||||
{
|
||||
if (!scx->scopesym->symtab)
|
||||
scx->scopesym->symtab = new DsymbolTable();
|
||||
em->addMember(sce, scx->scopesym, 1);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
em->addMember(sc, this, 1);
|
||||
|
||||
/* Compute .min, .max and .default values.
|
||||
* If enum doesn't have a name, we can never identify the enum type,
|
||||
* so there is no purpose for a .min, .max or .default
|
||||
*/
|
||||
if (!isAnonymous())
|
||||
{
|
||||
if (first)
|
||||
{ defaultval = e;
|
||||
minval = e;
|
||||
maxval = e;
|
||||
}
|
||||
else
|
||||
{ Expression *ec;
|
||||
|
||||
/* In order to work successfully with UDTs,
|
||||
* build expressions to do the comparisons,
|
||||
* and let the semantic analyzer and constant
|
||||
* folder give us the result.
|
||||
*/
|
||||
|
||||
// Compute if(e < minval)
|
||||
ec = new CmpExp(TOKlt, em->loc, e, minval);
|
||||
ec = ec->semantic(sce);
|
||||
ec = ec->optimize(WANTvalue | WANTinterpret);
|
||||
if (ec->toInteger())
|
||||
minval = e;
|
||||
|
||||
ec = new CmpExp(TOKgt, em->loc, e, maxval);
|
||||
ec = ec->semantic(sce);
|
||||
ec = ec->optimize(WANTvalue | WANTinterpret);
|
||||
if (ec->toInteger())
|
||||
maxval = e;
|
||||
}
|
||||
}
|
||||
first = 0;
|
||||
}
|
||||
//printf("defaultval = %lld\n", defaultval);
|
||||
|
||||
//if (defaultval) printf("defaultval: %s %s\n", defaultval->toChars(), defaultval->type->toChars());
|
||||
if (sc != sce)
|
||||
sce->pop();
|
||||
//members->print();
|
||||
}
|
||||
|
||||
int EnumDeclaration::oneMember(Dsymbol **ps)
|
||||
{
|
||||
if (isAnonymous())
|
||||
return Dsymbol::oneMembers(members, ps);
|
||||
return Dsymbol::oneMember(ps);
|
||||
}
|
||||
|
||||
void EnumDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{ int i;
|
||||
|
||||
buf->writestring("enum ");
|
||||
if (ident)
|
||||
{ buf->writestring(ident->toChars());
|
||||
buf->writeByte(' ');
|
||||
}
|
||||
if (memtype)
|
||||
{
|
||||
buf->writestring(": ");
|
||||
memtype->toCBuffer(buf, NULL, hgs);
|
||||
}
|
||||
if (!members)
|
||||
{
|
||||
buf->writeByte(';');
|
||||
buf->writenl();
|
||||
return;
|
||||
}
|
||||
buf->writenl();
|
||||
buf->writeByte('{');
|
||||
buf->writenl();
|
||||
for (i = 0; i < members->dim; i++)
|
||||
{
|
||||
EnumMember *em = ((Dsymbol *)members->data[i])->isEnumMember();
|
||||
if (!em)
|
||||
continue;
|
||||
//buf->writestring(" ");
|
||||
em->toCBuffer(buf, hgs);
|
||||
buf->writeByte(',');
|
||||
buf->writenl();
|
||||
}
|
||||
buf->writeByte('}');
|
||||
buf->writenl();
|
||||
}
|
||||
|
||||
Type *EnumDeclaration::getType()
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
const char *EnumDeclaration::kind()
|
||||
{
|
||||
return "enum";
|
||||
}
|
||||
|
||||
int EnumDeclaration::isDeprecated()
|
||||
{
|
||||
return isdeprecated;
|
||||
}
|
||||
|
||||
Dsymbol *EnumDeclaration::search(Loc loc, Identifier *ident, int flags)
|
||||
{
|
||||
//printf("%s.EnumDeclaration::search('%s')\n", toChars(), ident->toChars());
|
||||
if (scope)
|
||||
// Try one last time to resolve this enum
|
||||
semantic(scope);
|
||||
|
||||
if (!members || !symtab || scope)
|
||||
{ error("is forward referenced when looking for '%s'", ident->toChars());
|
||||
//*(char*)0=0;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Dsymbol *s = ScopeDsymbol::search(loc, ident, flags);
|
||||
return s;
|
||||
}
|
||||
|
||||
/********************************* EnumMember ****************************/
|
||||
|
||||
EnumMember::EnumMember(Loc loc, Identifier *id, Expression *value, Type *type)
|
||||
: Dsymbol(id)
|
||||
{
|
||||
this->value = value;
|
||||
this->type = type;
|
||||
this->loc = loc;
|
||||
}
|
||||
|
||||
Dsymbol *EnumMember::syntaxCopy(Dsymbol *s)
|
||||
{
|
||||
Expression *e = NULL;
|
||||
if (value)
|
||||
e = value->syntaxCopy();
|
||||
|
||||
Type *t = NULL;
|
||||
if (type)
|
||||
t = type->syntaxCopy();
|
||||
|
||||
EnumMember *em;
|
||||
if (s)
|
||||
{ em = (EnumMember *)s;
|
||||
em->loc = loc;
|
||||
em->value = e;
|
||||
em->type = t;
|
||||
}
|
||||
else
|
||||
em = new EnumMember(loc, ident, e, t);
|
||||
return em;
|
||||
}
|
||||
|
||||
void EnumMember::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (type)
|
||||
type->toCBuffer(buf, ident, hgs);
|
||||
else
|
||||
buf->writestring(ident->toChars());
|
||||
if (value)
|
||||
{
|
||||
buf->writestring(" = ");
|
||||
value->toCBuffer(buf, hgs);
|
||||
}
|
||||
}
|
||||
|
||||
const char *EnumMember::kind()
|
||||
{
|
||||
return "enum member";
|
||||
}
|
||||
|
||||
|
||||
|
||||
193
dmd2/enum.h
193
dmd2/enum.h
@@ -1,94 +1,99 @@
|
||||
|
||||
// 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_ENUM_H
|
||||
#define DMD_ENUM_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
#include "dsymbol.h"
|
||||
|
||||
struct Identifier;
|
||||
struct Type;
|
||||
struct Expression;
|
||||
#ifdef _DH
|
||||
struct HdrGenState;
|
||||
#endif
|
||||
|
||||
|
||||
struct EnumDeclaration : ScopeDsymbol
|
||||
{ /* enum ident : memtype { ... }
|
||||
*/
|
||||
Type *type; // the TypeEnum
|
||||
Type *memtype; // type of the members
|
||||
|
||||
#if DMDV1
|
||||
dinteger_t maxval;
|
||||
dinteger_t minval;
|
||||
dinteger_t defaultval; // default initializer
|
||||
#else
|
||||
Expression *maxval;
|
||||
Expression *minval;
|
||||
Expression *defaultval; // default initializer
|
||||
#endif
|
||||
int isdeprecated;
|
||||
|
||||
EnumDeclaration(Loc loc, Identifier *id, Type *memtype);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic(Scope *sc);
|
||||
int oneMember(Dsymbol **ps);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Type *getType();
|
||||
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; }
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
void toDebug();
|
||||
int cvMember(unsigned char *p);
|
||||
|
||||
Symbol *sinit;
|
||||
Symbol *toInitializer();
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct EnumMember : Dsymbol
|
||||
{
|
||||
Expression *value;
|
||||
Type *type;
|
||||
|
||||
EnumMember(Loc loc, Identifier *id, Expression *value, Type *type);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
const char *kind();
|
||||
|
||||
void emitComment(Scope *sc);
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
EnumMember *isEnumMember() { return this; }
|
||||
};
|
||||
|
||||
#endif /* DMD_ENUM_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_ENUM_H
|
||||
#define DMD_ENUM_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
#include "dsymbol.h"
|
||||
|
||||
struct Identifier;
|
||||
struct Type;
|
||||
struct Expression;
|
||||
#ifdef _DH
|
||||
struct HdrGenState;
|
||||
#endif
|
||||
|
||||
|
||||
struct EnumDeclaration : ScopeDsymbol
|
||||
{ /* enum ident : memtype { ... }
|
||||
*/
|
||||
Type *type; // the TypeEnum
|
||||
Type *memtype; // type of the members
|
||||
|
||||
#if DMDV1
|
||||
dinteger_t maxval;
|
||||
dinteger_t minval;
|
||||
dinteger_t defaultval; // default initializer
|
||||
#else
|
||||
Expression *maxval;
|
||||
Expression *minval;
|
||||
Expression *defaultval; // default initializer
|
||||
#endif
|
||||
int isdeprecated;
|
||||
int isdone; // 0: not done
|
||||
// 1: semantic() successfully completed
|
||||
|
||||
EnumDeclaration(Loc loc, Identifier *id, Type *memtype);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void semantic0(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
int oneMember(Dsymbol **ps);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
Type *getType();
|
||||
const char *kind();
|
||||
#if DMDV2
|
||||
Dsymbol *search(Loc, Identifier *ident, int flags);
|
||||
#endif
|
||||
int isDeprecated(); // is Dsymbol deprecated?
|
||||
|
||||
void emitComment(Scope *sc);
|
||||
void toJsonBuffer(OutBuffer *buf);
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
EnumDeclaration *isEnumDeclaration() { return this; }
|
||||
|
||||
#if IN_DMD
|
||||
void toObjFile(int multiobj); // compile to .obj file
|
||||
void toDebug();
|
||||
int cvMember(unsigned char *p);
|
||||
|
||||
Symbol *sinit;
|
||||
Symbol *toInitializer();
|
||||
#endif
|
||||
|
||||
#if IN_LLVM
|
||||
void codegen(Ir*);
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct EnumMember : Dsymbol
|
||||
{
|
||||
Expression *value;
|
||||
Type *type;
|
||||
|
||||
EnumMember(Loc loc, Identifier *id, Expression *value, Type *type);
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
const char *kind();
|
||||
|
||||
void emitComment(Scope *sc);
|
||||
void toJsonBuffer(OutBuffer *buf);
|
||||
void toDocBuffer(OutBuffer *buf);
|
||||
|
||||
EnumMember *isEnumMember() { return this; }
|
||||
};
|
||||
|
||||
#endif /* DMD_ENUM_H */
|
||||
|
||||
21502
dmd2/expression.c
21502
dmd2/expression.c
File diff suppressed because it is too large
Load Diff
4092
dmd2/expression.h
4092
dmd2/expression.h
File diff suppressed because it is too large
Load Diff
7222
dmd2/func.c
7222
dmd2/func.c
File diff suppressed because it is too large
Load Diff
208
dmd2/hdrgen.c
208
dmd2/hdrgen.c
@@ -1,104 +1,104 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// Initial header generation implementation by Dave Fladebo
|
||||
// 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.
|
||||
|
||||
// Routines to emit header files
|
||||
|
||||
#ifdef _DH
|
||||
|
||||
#define PRETTY_PRINT
|
||||
#define TEST_EMIT_ALL 0 // For Testing
|
||||
|
||||
#define LOG 0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#if __DMC__
|
||||
#include <complex.h>
|
||||
#endif
|
||||
|
||||
#include "rmem.h"
|
||||
|
||||
#include "id.h"
|
||||
#include "init.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "cond.h"
|
||||
#include "enum.h"
|
||||
#include "import.h"
|
||||
#include "module.h"
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
#include "staticassert.h"
|
||||
#include "template.h"
|
||||
#include "utf.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "declaration.h"
|
||||
#include "aggregate.h"
|
||||
#include "expression.h"
|
||||
#include "statement.h"
|
||||
#include "mtype.h"
|
||||
#include "hdrgen.h"
|
||||
|
||||
void argsToCBuffer(OutBuffer *buf, Array *arguments, HdrGenState *hgs);
|
||||
|
||||
void Module::genhdrfile()
|
||||
{
|
||||
OutBuffer hdrbufr;
|
||||
|
||||
hdrbufr.printf("// D import file generated from '%s'", srcfile->toChars());
|
||||
hdrbufr.writenl();
|
||||
|
||||
HdrGenState hgs;
|
||||
memset(&hgs, 0, sizeof(hgs));
|
||||
hgs.hdrgen = 1;
|
||||
|
||||
toCBuffer(&hdrbufr, &hgs);
|
||||
|
||||
// Transfer image to file
|
||||
hdrfile->setbuffer(hdrbufr.data, hdrbufr.offset);
|
||||
hdrbufr.data = NULL;
|
||||
|
||||
char *pt = FileName::path(hdrfile->toChars());
|
||||
if (*pt)
|
||||
FileName::ensurePathExists(pt);
|
||||
mem.free(pt);
|
||||
hdrfile->writev();
|
||||
}
|
||||
|
||||
|
||||
void Module::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (md)
|
||||
{
|
||||
buf->writestring("module ");
|
||||
buf->writestring(md->toChars());
|
||||
buf->writebyte(';');
|
||||
buf->writenl();
|
||||
}
|
||||
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
|
||||
s->toHBuffer(buf, hgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Dsymbol::toHBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
toCBuffer(buf, hgs);
|
||||
}
|
||||
|
||||
|
||||
/*************************************/
|
||||
|
||||
#endif // #ifdef _DH
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// Initial header generation implementation by Dave Fladebo
|
||||
// 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.
|
||||
|
||||
// Routines to emit header files
|
||||
|
||||
#ifdef _DH
|
||||
|
||||
#define PRETTY_PRINT
|
||||
#define TEST_EMIT_ALL 0 // For Testing
|
||||
|
||||
#define LOG 0
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
#if __DMC__
|
||||
#include <complex.h>
|
||||
#endif
|
||||
|
||||
#include "rmem.h"
|
||||
|
||||
#include "id.h"
|
||||
#include "init.h"
|
||||
|
||||
#include "attrib.h"
|
||||
#include "cond.h"
|
||||
#include "enum.h"
|
||||
#include "import.h"
|
||||
#include "module.h"
|
||||
#include "mtype.h"
|
||||
#include "scope.h"
|
||||
#include "staticassert.h"
|
||||
#include "template.h"
|
||||
#include "utf.h"
|
||||
#include "version.h"
|
||||
|
||||
#include "declaration.h"
|
||||
#include "aggregate.h"
|
||||
#include "expression.h"
|
||||
#include "statement.h"
|
||||
#include "mtype.h"
|
||||
#include "hdrgen.h"
|
||||
|
||||
void argsToCBuffer(OutBuffer *buf, Array *arguments, HdrGenState *hgs);
|
||||
|
||||
void Module::genhdrfile()
|
||||
{
|
||||
OutBuffer hdrbufr;
|
||||
|
||||
hdrbufr.printf("// D import file generated from '%s'", srcfile->toChars());
|
||||
hdrbufr.writenl();
|
||||
|
||||
HdrGenState hgs;
|
||||
memset(&hgs, 0, sizeof(hgs));
|
||||
hgs.hdrgen = 1;
|
||||
|
||||
toCBuffer(&hdrbufr, &hgs);
|
||||
|
||||
// Transfer image to file
|
||||
hdrfile->setbuffer(hdrbufr.data, hdrbufr.offset);
|
||||
hdrbufr.data = NULL;
|
||||
|
||||
char *pt = FileName::path(hdrfile->toChars());
|
||||
if (*pt)
|
||||
FileName::ensurePathExists(pt);
|
||||
mem.free(pt);
|
||||
hdrfile->writev();
|
||||
}
|
||||
|
||||
|
||||
void Module::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (md)
|
||||
{
|
||||
buf->writestring("module ");
|
||||
buf->writestring(md->toChars());
|
||||
buf->writebyte(';');
|
||||
buf->writenl();
|
||||
}
|
||||
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
|
||||
s->toHBuffer(buf, hgs);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Dsymbol::toHBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
toCBuffer(buf, hgs);
|
||||
}
|
||||
|
||||
|
||||
/*************************************/
|
||||
|
||||
#endif // #ifdef _DH
|
||||
|
||||
@@ -1,34 +1,34 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// initial header generation implementation by Dave Fladebo
|
||||
// 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.
|
||||
|
||||
|
||||
struct HdrGenState
|
||||
{
|
||||
int hdrgen; // 1 if generating header file
|
||||
int ddoc; // 1 if generating Ddoc file
|
||||
int console; // 1 if writing to console
|
||||
int tpltMember;
|
||||
int inCallExp;
|
||||
int inPtrExp;
|
||||
int inSlcExp;
|
||||
int inDotExp;
|
||||
int inBinExp;
|
||||
int inArrExp;
|
||||
int emitInst;
|
||||
struct
|
||||
{
|
||||
int init;
|
||||
int decl;
|
||||
} FLinit;
|
||||
|
||||
HdrGenState() { memset(this, 0, sizeof(HdrGenState)); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// initial header generation implementation by Dave Fladebo
|
||||
// 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.
|
||||
|
||||
|
||||
struct HdrGenState
|
||||
{
|
||||
int hdrgen; // 1 if generating header file
|
||||
int ddoc; // 1 if generating Ddoc file
|
||||
int console; // 1 if writing to console
|
||||
int tpltMember;
|
||||
int inCallExp;
|
||||
int inPtrExp;
|
||||
int inSlcExp;
|
||||
int inDotExp;
|
||||
int inBinExp;
|
||||
int inArrExp;
|
||||
int emitInst;
|
||||
struct
|
||||
{
|
||||
int init;
|
||||
int decl;
|
||||
} FLinit;
|
||||
|
||||
HdrGenState() { memset(this, 0, sizeof(HdrGenState)); }
|
||||
};
|
||||
|
||||
|
||||
|
||||
1440
dmd2/html.c
1440
dmd2/html.c
File diff suppressed because it is too large
Load Diff
84
dmd2/html.h
84
dmd2/html.h
@@ -1,42 +1,42 @@
|
||||
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_HTML_H
|
||||
#define DMD_HTML_H 1
|
||||
|
||||
struct OutBuffer;
|
||||
|
||||
struct Html
|
||||
{
|
||||
const char *sourcename;
|
||||
|
||||
unsigned char *base; // pointer to start of buffer
|
||||
unsigned char *end; // past end of buffer
|
||||
unsigned char *p; // current character
|
||||
unsigned linnum; // current line number
|
||||
OutBuffer *dbuf; // code source buffer
|
||||
int inCode; // !=0 if in code
|
||||
|
||||
|
||||
Html(const char *sourcename, unsigned char *base, unsigned length);
|
||||
|
||||
void error(const char *format, ...) IS_PRINTF(2);
|
||||
void extractCode(OutBuffer *buf);
|
||||
void skipTag();
|
||||
void skipString();
|
||||
unsigned char *skipWhite(unsigned char *q);
|
||||
void scanComment();
|
||||
int isCommentStart();
|
||||
void scanCDATA();
|
||||
int isCDATAStart();
|
||||
int charEntity();
|
||||
static int namedEntity(unsigned char *p, int length);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_HTML_H
|
||||
#define DMD_HTML_H 1
|
||||
|
||||
struct OutBuffer;
|
||||
|
||||
struct Html
|
||||
{
|
||||
const char *sourcename;
|
||||
|
||||
unsigned char *base; // pointer to start of buffer
|
||||
unsigned char *end; // past end of buffer
|
||||
unsigned char *p; // current character
|
||||
unsigned linnum; // current line number
|
||||
OutBuffer *dbuf; // code source buffer
|
||||
int inCode; // !=0 if in code
|
||||
|
||||
|
||||
Html(const char *sourcename, unsigned char *base, unsigned length);
|
||||
|
||||
void error(const char *format, ...) IS_PRINTF(2);
|
||||
void extractCode(OutBuffer *buf);
|
||||
void skipTag();
|
||||
void skipString();
|
||||
unsigned char *skipWhite(unsigned char *q);
|
||||
void scanComment();
|
||||
int isCommentStart();
|
||||
void scanCDATA();
|
||||
int isCDATAStart();
|
||||
int charEntity();
|
||||
static int namedEntity(unsigned char *p, int length);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
473
dmd2/id.c
473
dmd2/id.c
@@ -1,473 +0,0 @@
|
||||
// File generated by idgen.c
|
||||
#include "id.h"
|
||||
#include "identifier.h"
|
||||
#include "lexer.h"
|
||||
Identifier *Id::IUnknown;
|
||||
Identifier *Id::Object;
|
||||
Identifier *Id::object;
|
||||
Identifier *Id::max;
|
||||
Identifier *Id::min;
|
||||
Identifier *Id::This;
|
||||
Identifier *Id::ctor;
|
||||
Identifier *Id::dtor;
|
||||
Identifier *Id::cpctor;
|
||||
Identifier *Id::_postblit;
|
||||
Identifier *Id::classInvariant;
|
||||
Identifier *Id::unitTest;
|
||||
Identifier *Id::init;
|
||||
Identifier *Id::size;
|
||||
Identifier *Id::__sizeof;
|
||||
Identifier *Id::alignof;
|
||||
Identifier *Id::mangleof;
|
||||
Identifier *Id::stringof;
|
||||
Identifier *Id::tupleof;
|
||||
Identifier *Id::length;
|
||||
Identifier *Id::remove;
|
||||
Identifier *Id::ptr;
|
||||
Identifier *Id::funcptr;
|
||||
Identifier *Id::dollar;
|
||||
Identifier *Id::offset;
|
||||
Identifier *Id::offsetof;
|
||||
Identifier *Id::ModuleInfo;
|
||||
Identifier *Id::ClassInfo;
|
||||
Identifier *Id::classinfo;
|
||||
Identifier *Id::typeinfo;
|
||||
Identifier *Id::outer;
|
||||
Identifier *Id::Exception;
|
||||
Identifier *Id::Throwable;
|
||||
Identifier *Id::withSym;
|
||||
Identifier *Id::result;
|
||||
Identifier *Id::returnLabel;
|
||||
Identifier *Id::delegate;
|
||||
Identifier *Id::line;
|
||||
Identifier *Id::empty;
|
||||
Identifier *Id::p;
|
||||
Identifier *Id::coverage;
|
||||
Identifier *Id::__vptr;
|
||||
Identifier *Id::__monitor;
|
||||
Identifier *Id::system;
|
||||
Identifier *Id::TypeInfo;
|
||||
Identifier *Id::TypeInfo_Class;
|
||||
Identifier *Id::TypeInfo_Interface;
|
||||
Identifier *Id::TypeInfo_Struct;
|
||||
Identifier *Id::TypeInfo_Enum;
|
||||
Identifier *Id::TypeInfo_Typedef;
|
||||
Identifier *Id::TypeInfo_Pointer;
|
||||
Identifier *Id::TypeInfo_Array;
|
||||
Identifier *Id::TypeInfo_StaticArray;
|
||||
Identifier *Id::TypeInfo_AssociativeArray;
|
||||
Identifier *Id::TypeInfo_Function;
|
||||
Identifier *Id::TypeInfo_Delegate;
|
||||
Identifier *Id::TypeInfo_Tuple;
|
||||
Identifier *Id::TypeInfo_Const;
|
||||
Identifier *Id::TypeInfo_Invariant;
|
||||
Identifier *Id::TypeInfo_Shared;
|
||||
Identifier *Id::elements;
|
||||
Identifier *Id::_arguments_typeinfo;
|
||||
Identifier *Id::_arguments;
|
||||
Identifier *Id::_argptr;
|
||||
Identifier *Id::_match;
|
||||
Identifier *Id::destroy;
|
||||
Identifier *Id::postblit;
|
||||
Identifier *Id::LINE;
|
||||
Identifier *Id::FILE;
|
||||
Identifier *Id::DATE;
|
||||
Identifier *Id::TIME;
|
||||
Identifier *Id::TIMESTAMP;
|
||||
Identifier *Id::VENDOR;
|
||||
Identifier *Id::VERSIONX;
|
||||
Identifier *Id::EOFX;
|
||||
Identifier *Id::nan;
|
||||
Identifier *Id::infinity;
|
||||
Identifier *Id::dig;
|
||||
Identifier *Id::epsilon;
|
||||
Identifier *Id::mant_dig;
|
||||
Identifier *Id::max_10_exp;
|
||||
Identifier *Id::max_exp;
|
||||
Identifier *Id::min_10_exp;
|
||||
Identifier *Id::min_exp;
|
||||
Identifier *Id::re;
|
||||
Identifier *Id::im;
|
||||
Identifier *Id::C;
|
||||
Identifier *Id::D;
|
||||
Identifier *Id::Windows;
|
||||
Identifier *Id::Pascal;
|
||||
Identifier *Id::System;
|
||||
Identifier *Id::exit;
|
||||
Identifier *Id::success;
|
||||
Identifier *Id::failure;
|
||||
Identifier *Id::keys;
|
||||
Identifier *Id::values;
|
||||
Identifier *Id::rehash;
|
||||
Identifier *Id::sort;
|
||||
Identifier *Id::reverse;
|
||||
Identifier *Id::dup;
|
||||
Identifier *Id::idup;
|
||||
Identifier *Id::property;
|
||||
Identifier *Id::___out;
|
||||
Identifier *Id::___in;
|
||||
Identifier *Id::__int;
|
||||
Identifier *Id::__dollar;
|
||||
Identifier *Id::__LOCAL_SIZE;
|
||||
Identifier *Id::uadd;
|
||||
Identifier *Id::neg;
|
||||
Identifier *Id::com;
|
||||
Identifier *Id::add;
|
||||
Identifier *Id::add_r;
|
||||
Identifier *Id::sub;
|
||||
Identifier *Id::sub_r;
|
||||
Identifier *Id::mul;
|
||||
Identifier *Id::mul_r;
|
||||
Identifier *Id::div;
|
||||
Identifier *Id::div_r;
|
||||
Identifier *Id::mod;
|
||||
Identifier *Id::mod_r;
|
||||
Identifier *Id::eq;
|
||||
Identifier *Id::cmp;
|
||||
Identifier *Id::iand;
|
||||
Identifier *Id::iand_r;
|
||||
Identifier *Id::ior;
|
||||
Identifier *Id::ior_r;
|
||||
Identifier *Id::ixor;
|
||||
Identifier *Id::ixor_r;
|
||||
Identifier *Id::shl;
|
||||
Identifier *Id::shl_r;
|
||||
Identifier *Id::shr;
|
||||
Identifier *Id::shr_r;
|
||||
Identifier *Id::ushr;
|
||||
Identifier *Id::ushr_r;
|
||||
Identifier *Id::cat;
|
||||
Identifier *Id::cat_r;
|
||||
Identifier *Id::assign;
|
||||
Identifier *Id::addass;
|
||||
Identifier *Id::subass;
|
||||
Identifier *Id::mulass;
|
||||
Identifier *Id::divass;
|
||||
Identifier *Id::modass;
|
||||
Identifier *Id::andass;
|
||||
Identifier *Id::orass;
|
||||
Identifier *Id::xorass;
|
||||
Identifier *Id::shlass;
|
||||
Identifier *Id::shrass;
|
||||
Identifier *Id::ushrass;
|
||||
Identifier *Id::catass;
|
||||
Identifier *Id::postinc;
|
||||
Identifier *Id::postdec;
|
||||
Identifier *Id::index;
|
||||
Identifier *Id::indexass;
|
||||
Identifier *Id::slice;
|
||||
Identifier *Id::sliceass;
|
||||
Identifier *Id::call;
|
||||
Identifier *Id::cast;
|
||||
Identifier *Id::match;
|
||||
Identifier *Id::next;
|
||||
Identifier *Id::opIn;
|
||||
Identifier *Id::opIn_r;
|
||||
Identifier *Id::opStar;
|
||||
Identifier *Id::opDot;
|
||||
Identifier *Id::opImplicitCast;
|
||||
Identifier *Id::classNew;
|
||||
Identifier *Id::classDelete;
|
||||
Identifier *Id::apply;
|
||||
Identifier *Id::applyReverse;
|
||||
Identifier *Id::Fempty;
|
||||
Identifier *Id::Fhead;
|
||||
Identifier *Id::Ftoe;
|
||||
Identifier *Id::Fnext;
|
||||
Identifier *Id::Fretreat;
|
||||
Identifier *Id::adDup;
|
||||
Identifier *Id::adReverse;
|
||||
Identifier *Id::aaLen;
|
||||
Identifier *Id::aaKeys;
|
||||
Identifier *Id::aaValues;
|
||||
Identifier *Id::aaRehash;
|
||||
Identifier *Id::monitorenter;
|
||||
Identifier *Id::monitorexit;
|
||||
Identifier *Id::criticalenter;
|
||||
Identifier *Id::criticalexit;
|
||||
Identifier *Id::GNU_asm;
|
||||
Identifier *Id::lib;
|
||||
Identifier *Id::msg;
|
||||
Identifier *Id::startaddress;
|
||||
Identifier *Id::intrinsic;
|
||||
Identifier *Id::va_intrinsic;
|
||||
Identifier *Id::no_typeinfo;
|
||||
Identifier *Id::no_moduleinfo;
|
||||
Identifier *Id::Alloca;
|
||||
Identifier *Id::vastart;
|
||||
Identifier *Id::vacopy;
|
||||
Identifier *Id::vaend;
|
||||
Identifier *Id::vaarg;
|
||||
Identifier *Id::ldc;
|
||||
Identifier *Id::allow_inline;
|
||||
Identifier *Id::llvm_inline_asm;
|
||||
Identifier *Id::tohash;
|
||||
Identifier *Id::tostring;
|
||||
Identifier *Id::getmembers;
|
||||
Identifier *Id::main;
|
||||
Identifier *Id::WinMain;
|
||||
Identifier *Id::DllMain;
|
||||
Identifier *Id::tls_get_addr;
|
||||
Identifier *Id::std;
|
||||
Identifier *Id::math;
|
||||
Identifier *Id::sin;
|
||||
Identifier *Id::cos;
|
||||
Identifier *Id::tan;
|
||||
Identifier *Id::_sqrt;
|
||||
Identifier *Id::fabs;
|
||||
Identifier *Id::isAbstractClass;
|
||||
Identifier *Id::isArithmetic;
|
||||
Identifier *Id::isAssociativeArray;
|
||||
Identifier *Id::isFinalClass;
|
||||
Identifier *Id::isFloating;
|
||||
Identifier *Id::isIntegral;
|
||||
Identifier *Id::isScalar;
|
||||
Identifier *Id::isStaticArray;
|
||||
Identifier *Id::isUnsigned;
|
||||
Identifier *Id::isVirtualFunction;
|
||||
Identifier *Id::isAbstractFunction;
|
||||
Identifier *Id::isFinalFunction;
|
||||
Identifier *Id::hasMember;
|
||||
Identifier *Id::getMember;
|
||||
Identifier *Id::getVirtualFunctions;
|
||||
Identifier *Id::classInstanceSize;
|
||||
Identifier *Id::allMembers;
|
||||
Identifier *Id::derivedMembers;
|
||||
Identifier *Id::isSame;
|
||||
Identifier *Id::compiles;
|
||||
void Id::initialize()
|
||||
{
|
||||
IUnknown = Lexer::idPool("IUnknown");
|
||||
Object = Lexer::idPool("Object");
|
||||
object = Lexer::idPool("object");
|
||||
max = Lexer::idPool("max");
|
||||
min = Lexer::idPool("min");
|
||||
This = Lexer::idPool("this");
|
||||
ctor = Lexer::idPool("__ctor");
|
||||
dtor = Lexer::idPool("__dtor");
|
||||
cpctor = Lexer::idPool("__cpctor");
|
||||
_postblit = Lexer::idPool("__postblit");
|
||||
classInvariant = Lexer::idPool("__invariant");
|
||||
unitTest = Lexer::idPool("__unitTest");
|
||||
init = Lexer::idPool("init");
|
||||
size = Lexer::idPool("size");
|
||||
__sizeof = Lexer::idPool("sizeof");
|
||||
alignof = Lexer::idPool("alignof");
|
||||
mangleof = Lexer::idPool("mangleof");
|
||||
stringof = Lexer::idPool("stringof");
|
||||
tupleof = Lexer::idPool("tupleof");
|
||||
length = Lexer::idPool("length");
|
||||
remove = Lexer::idPool("remove");
|
||||
ptr = Lexer::idPool("ptr");
|
||||
funcptr = Lexer::idPool("funcptr");
|
||||
dollar = Lexer::idPool("__dollar");
|
||||
offset = Lexer::idPool("offset");
|
||||
offsetof = Lexer::idPool("offsetof");
|
||||
ModuleInfo = Lexer::idPool("ModuleInfo");
|
||||
ClassInfo = Lexer::idPool("ClassInfo");
|
||||
classinfo = Lexer::idPool("classinfo");
|
||||
typeinfo = Lexer::idPool("typeinfo");
|
||||
outer = Lexer::idPool("outer");
|
||||
Exception = Lexer::idPool("Exception");
|
||||
Throwable = Lexer::idPool("Throwable");
|
||||
withSym = Lexer::idPool("__withSym");
|
||||
result = Lexer::idPool("__result");
|
||||
returnLabel = Lexer::idPool("__returnLabel");
|
||||
delegate = Lexer::idPool("delegate");
|
||||
line = Lexer::idPool("line");
|
||||
empty = Lexer::idPool("");
|
||||
p = Lexer::idPool("p");
|
||||
coverage = Lexer::idPool("__coverage");
|
||||
__vptr = Lexer::idPool("__vptr");
|
||||
__monitor = Lexer::idPool("__monitor");
|
||||
system = Lexer::idPool("system");
|
||||
TypeInfo = Lexer::idPool("TypeInfo");
|
||||
TypeInfo_Class = Lexer::idPool("TypeInfo_Class");
|
||||
TypeInfo_Interface = Lexer::idPool("TypeInfo_Interface");
|
||||
TypeInfo_Struct = Lexer::idPool("TypeInfo_Struct");
|
||||
TypeInfo_Enum = Lexer::idPool("TypeInfo_Enum");
|
||||
TypeInfo_Typedef = Lexer::idPool("TypeInfo_Typedef");
|
||||
TypeInfo_Pointer = Lexer::idPool("TypeInfo_Pointer");
|
||||
TypeInfo_Array = Lexer::idPool("TypeInfo_Array");
|
||||
TypeInfo_StaticArray = Lexer::idPool("TypeInfo_StaticArray");
|
||||
TypeInfo_AssociativeArray = Lexer::idPool("TypeInfo_AssociativeArray");
|
||||
TypeInfo_Function = Lexer::idPool("TypeInfo_Function");
|
||||
TypeInfo_Delegate = Lexer::idPool("TypeInfo_Delegate");
|
||||
TypeInfo_Tuple = Lexer::idPool("TypeInfo_Tuple");
|
||||
TypeInfo_Const = Lexer::idPool("TypeInfo_Const");
|
||||
TypeInfo_Invariant = Lexer::idPool("TypeInfo_Invariant");
|
||||
TypeInfo_Shared = Lexer::idPool("TypeInfo_Shared");
|
||||
elements = Lexer::idPool("elements");
|
||||
_arguments_typeinfo = Lexer::idPool("_arguments_typeinfo");
|
||||
_arguments = Lexer::idPool("_arguments");
|
||||
_argptr = Lexer::idPool("_argptr");
|
||||
_match = Lexer::idPool("_match");
|
||||
destroy = Lexer::idPool("destroy");
|
||||
postblit = Lexer::idPool("postblit");
|
||||
LINE = Lexer::idPool("__LINE__");
|
||||
FILE = Lexer::idPool("__FILE__");
|
||||
DATE = Lexer::idPool("__DATE__");
|
||||
TIME = Lexer::idPool("__TIME__");
|
||||
TIMESTAMP = Lexer::idPool("__TIMESTAMP__");
|
||||
VENDOR = Lexer::idPool("__VENDOR__");
|
||||
VERSIONX = Lexer::idPool("__VERSION__");
|
||||
EOFX = Lexer::idPool("__EOF__");
|
||||
nan = Lexer::idPool("nan");
|
||||
infinity = Lexer::idPool("infinity");
|
||||
dig = Lexer::idPool("dig");
|
||||
epsilon = Lexer::idPool("epsilon");
|
||||
mant_dig = Lexer::idPool("mant_dig");
|
||||
max_10_exp = Lexer::idPool("max_10_exp");
|
||||
max_exp = Lexer::idPool("max_exp");
|
||||
min_10_exp = Lexer::idPool("min_10_exp");
|
||||
min_exp = Lexer::idPool("min_exp");
|
||||
re = Lexer::idPool("re");
|
||||
im = Lexer::idPool("im");
|
||||
C = Lexer::idPool("C");
|
||||
D = Lexer::idPool("D");
|
||||
Windows = Lexer::idPool("Windows");
|
||||
Pascal = Lexer::idPool("Pascal");
|
||||
System = Lexer::idPool("System");
|
||||
exit = Lexer::idPool("exit");
|
||||
success = Lexer::idPool("success");
|
||||
failure = Lexer::idPool("failure");
|
||||
keys = Lexer::idPool("keys");
|
||||
values = Lexer::idPool("values");
|
||||
rehash = Lexer::idPool("rehash");
|
||||
sort = Lexer::idPool("sort");
|
||||
reverse = Lexer::idPool("reverse");
|
||||
dup = Lexer::idPool("dup");
|
||||
idup = Lexer::idPool("idup");
|
||||
property = Lexer::idPool("property");
|
||||
___out = Lexer::idPool("out");
|
||||
___in = Lexer::idPool("in");
|
||||
__int = Lexer::idPool("int");
|
||||
__dollar = Lexer::idPool("$");
|
||||
__LOCAL_SIZE = Lexer::idPool("__LOCAL_SIZE");
|
||||
uadd = Lexer::idPool("opPos");
|
||||
neg = Lexer::idPool("opNeg");
|
||||
com = Lexer::idPool("opCom");
|
||||
add = Lexer::idPool("opAdd");
|
||||
add_r = Lexer::idPool("opAdd_r");
|
||||
sub = Lexer::idPool("opSub");
|
||||
sub_r = Lexer::idPool("opSub_r");
|
||||
mul = Lexer::idPool("opMul");
|
||||
mul_r = Lexer::idPool("opMul_r");
|
||||
div = Lexer::idPool("opDiv");
|
||||
div_r = Lexer::idPool("opDiv_r");
|
||||
mod = Lexer::idPool("opMod");
|
||||
mod_r = Lexer::idPool("opMod_r");
|
||||
eq = Lexer::idPool("opEquals");
|
||||
cmp = Lexer::idPool("opCmp");
|
||||
iand = Lexer::idPool("opAnd");
|
||||
iand_r = Lexer::idPool("opAnd_r");
|
||||
ior = Lexer::idPool("opOr");
|
||||
ior_r = Lexer::idPool("opOr_r");
|
||||
ixor = Lexer::idPool("opXor");
|
||||
ixor_r = Lexer::idPool("opXor_r");
|
||||
shl = Lexer::idPool("opShl");
|
||||
shl_r = Lexer::idPool("opShl_r");
|
||||
shr = Lexer::idPool("opShr");
|
||||
shr_r = Lexer::idPool("opShr_r");
|
||||
ushr = Lexer::idPool("opUShr");
|
||||
ushr_r = Lexer::idPool("opUShr_r");
|
||||
cat = Lexer::idPool("opCat");
|
||||
cat_r = Lexer::idPool("opCat_r");
|
||||
assign = Lexer::idPool("opAssign");
|
||||
addass = Lexer::idPool("opAddAssign");
|
||||
subass = Lexer::idPool("opSubAssign");
|
||||
mulass = Lexer::idPool("opMulAssign");
|
||||
divass = Lexer::idPool("opDivAssign");
|
||||
modass = Lexer::idPool("opModAssign");
|
||||
andass = Lexer::idPool("opAndAssign");
|
||||
orass = Lexer::idPool("opOrAssign");
|
||||
xorass = Lexer::idPool("opXorAssign");
|
||||
shlass = Lexer::idPool("opShlAssign");
|
||||
shrass = Lexer::idPool("opShrAssign");
|
||||
ushrass = Lexer::idPool("opUShrAssign");
|
||||
catass = Lexer::idPool("opCatAssign");
|
||||
postinc = Lexer::idPool("opPostInc");
|
||||
postdec = Lexer::idPool("opPostDec");
|
||||
index = Lexer::idPool("opIndex");
|
||||
indexass = Lexer::idPool("opIndexAssign");
|
||||
slice = Lexer::idPool("opSlice");
|
||||
sliceass = Lexer::idPool("opSliceAssign");
|
||||
call = Lexer::idPool("opCall");
|
||||
cast = Lexer::idPool("opCast");
|
||||
match = Lexer::idPool("opMatch");
|
||||
next = Lexer::idPool("opNext");
|
||||
opIn = Lexer::idPool("opIn");
|
||||
opIn_r = Lexer::idPool("opIn_r");
|
||||
opStar = Lexer::idPool("opStar");
|
||||
opDot = Lexer::idPool("opDot");
|
||||
opImplicitCast = Lexer::idPool("opImplicitCast");
|
||||
classNew = Lexer::idPool("new");
|
||||
classDelete = Lexer::idPool("delete");
|
||||
apply = Lexer::idPool("opApply");
|
||||
applyReverse = Lexer::idPool("opApplyReverse");
|
||||
Fempty = Lexer::idPool("empty");
|
||||
Fhead = Lexer::idPool("front");
|
||||
Ftoe = Lexer::idPool("back");
|
||||
Fnext = Lexer::idPool("popFront");
|
||||
Fretreat = Lexer::idPool("popBack");
|
||||
adDup = Lexer::idPool("_adDupT");
|
||||
adReverse = Lexer::idPool("_adReverse");
|
||||
aaLen = Lexer::idPool("_aaLen");
|
||||
aaKeys = Lexer::idPool("_aaKeys");
|
||||
aaValues = Lexer::idPool("_aaValues");
|
||||
aaRehash = Lexer::idPool("_aaRehash");
|
||||
monitorenter = Lexer::idPool("_d_monitorenter");
|
||||
monitorexit = Lexer::idPool("_d_monitorexit");
|
||||
criticalenter = Lexer::idPool("_d_criticalenter");
|
||||
criticalexit = Lexer::idPool("_d_criticalexit");
|
||||
GNU_asm = Lexer::idPool("GNU_asm");
|
||||
lib = Lexer::idPool("lib");
|
||||
msg = Lexer::idPool("msg");
|
||||
startaddress = Lexer::idPool("startaddress");
|
||||
intrinsic = Lexer::idPool("intrinsic");
|
||||
va_intrinsic = Lexer::idPool("va_intrinsic");
|
||||
no_typeinfo = Lexer::idPool("no_typeinfo");
|
||||
no_moduleinfo = Lexer::idPool("no_moduleinfo");
|
||||
Alloca = Lexer::idPool("alloca");
|
||||
vastart = Lexer::idPool("va_start");
|
||||
vacopy = Lexer::idPool("va_copy");
|
||||
vaend = Lexer::idPool("va_end");
|
||||
vaarg = Lexer::idPool("va_arg");
|
||||
ldc = Lexer::idPool("ldc");
|
||||
allow_inline = Lexer::idPool("allow_inline");
|
||||
llvm_inline_asm = Lexer::idPool("llvm_inline_asm");
|
||||
tohash = Lexer::idPool("toHash");
|
||||
tostring = Lexer::idPool("toString");
|
||||
getmembers = Lexer::idPool("getMembers");
|
||||
main = Lexer::idPool("main");
|
||||
WinMain = Lexer::idPool("WinMain");
|
||||
DllMain = Lexer::idPool("DllMain");
|
||||
tls_get_addr = Lexer::idPool("___tls_get_addr");
|
||||
std = Lexer::idPool("std");
|
||||
math = Lexer::idPool("math");
|
||||
sin = Lexer::idPool("sin");
|
||||
cos = Lexer::idPool("cos");
|
||||
tan = Lexer::idPool("tan");
|
||||
_sqrt = Lexer::idPool("sqrt");
|
||||
fabs = Lexer::idPool("fabs");
|
||||
isAbstractClass = Lexer::idPool("isAbstractClass");
|
||||
isArithmetic = Lexer::idPool("isArithmetic");
|
||||
isAssociativeArray = Lexer::idPool("isAssociativeArray");
|
||||
isFinalClass = Lexer::idPool("isFinalClass");
|
||||
isFloating = Lexer::idPool("isFloating");
|
||||
isIntegral = Lexer::idPool("isIntegral");
|
||||
isScalar = Lexer::idPool("isScalar");
|
||||
isStaticArray = Lexer::idPool("isStaticArray");
|
||||
isUnsigned = Lexer::idPool("isUnsigned");
|
||||
isVirtualFunction = Lexer::idPool("isVirtualFunction");
|
||||
isAbstractFunction = Lexer::idPool("isAbstractFunction");
|
||||
isFinalFunction = Lexer::idPool("isFinalFunction");
|
||||
hasMember = Lexer::idPool("hasMember");
|
||||
getMember = Lexer::idPool("getMember");
|
||||
getVirtualFunctions = Lexer::idPool("getVirtualFunctions");
|
||||
classInstanceSize = Lexer::idPool("classInstanceSize");
|
||||
allMembers = Lexer::idPool("allMembers");
|
||||
derivedMembers = Lexer::idPool("derivedMembers");
|
||||
isSame = Lexer::idPool("isSame");
|
||||
compiles = Lexer::idPool("compiles");
|
||||
}
|
||||
242
dmd2/id.h
242
dmd2/id.h
@@ -1,242 +0,0 @@
|
||||
// File generated by idgen.c
|
||||
#ifndef DMD_ID_H
|
||||
#define DMD_ID_H 1
|
||||
struct Identifier;
|
||||
struct Id
|
||||
{
|
||||
static Identifier *IUnknown;
|
||||
static Identifier *Object;
|
||||
static Identifier *object;
|
||||
static Identifier *max;
|
||||
static Identifier *min;
|
||||
static Identifier *This;
|
||||
static Identifier *ctor;
|
||||
static Identifier *dtor;
|
||||
static Identifier *cpctor;
|
||||
static Identifier *_postblit;
|
||||
static Identifier *classInvariant;
|
||||
static Identifier *unitTest;
|
||||
static Identifier *init;
|
||||
static Identifier *size;
|
||||
static Identifier *__sizeof;
|
||||
static Identifier *alignof;
|
||||
static Identifier *mangleof;
|
||||
static Identifier *stringof;
|
||||
static Identifier *tupleof;
|
||||
static Identifier *length;
|
||||
static Identifier *remove;
|
||||
static Identifier *ptr;
|
||||
static Identifier *funcptr;
|
||||
static Identifier *dollar;
|
||||
static Identifier *offset;
|
||||
static Identifier *offsetof;
|
||||
static Identifier *ModuleInfo;
|
||||
static Identifier *ClassInfo;
|
||||
static Identifier *classinfo;
|
||||
static Identifier *typeinfo;
|
||||
static Identifier *outer;
|
||||
static Identifier *Exception;
|
||||
static Identifier *Throwable;
|
||||
static Identifier *withSym;
|
||||
static Identifier *result;
|
||||
static Identifier *returnLabel;
|
||||
static Identifier *delegate;
|
||||
static Identifier *line;
|
||||
static Identifier *empty;
|
||||
static Identifier *p;
|
||||
static Identifier *coverage;
|
||||
static Identifier *__vptr;
|
||||
static Identifier *__monitor;
|
||||
static Identifier *system;
|
||||
static Identifier *TypeInfo;
|
||||
static Identifier *TypeInfo_Class;
|
||||
static Identifier *TypeInfo_Interface;
|
||||
static Identifier *TypeInfo_Struct;
|
||||
static Identifier *TypeInfo_Enum;
|
||||
static Identifier *TypeInfo_Typedef;
|
||||
static Identifier *TypeInfo_Pointer;
|
||||
static Identifier *TypeInfo_Array;
|
||||
static Identifier *TypeInfo_StaticArray;
|
||||
static Identifier *TypeInfo_AssociativeArray;
|
||||
static Identifier *TypeInfo_Function;
|
||||
static Identifier *TypeInfo_Delegate;
|
||||
static Identifier *TypeInfo_Tuple;
|
||||
static Identifier *TypeInfo_Const;
|
||||
static Identifier *TypeInfo_Invariant;
|
||||
static Identifier *TypeInfo_Shared;
|
||||
static Identifier *elements;
|
||||
static Identifier *_arguments_typeinfo;
|
||||
static Identifier *_arguments;
|
||||
static Identifier *_argptr;
|
||||
static Identifier *_match;
|
||||
static Identifier *destroy;
|
||||
static Identifier *postblit;
|
||||
static Identifier *LINE;
|
||||
static Identifier *FILE;
|
||||
static Identifier *DATE;
|
||||
static Identifier *TIME;
|
||||
static Identifier *TIMESTAMP;
|
||||
static Identifier *VENDOR;
|
||||
static Identifier *VERSIONX;
|
||||
static Identifier *EOFX;
|
||||
static Identifier *nan;
|
||||
static Identifier *infinity;
|
||||
static Identifier *dig;
|
||||
static Identifier *epsilon;
|
||||
static Identifier *mant_dig;
|
||||
static Identifier *max_10_exp;
|
||||
static Identifier *max_exp;
|
||||
static Identifier *min_10_exp;
|
||||
static Identifier *min_exp;
|
||||
static Identifier *re;
|
||||
static Identifier *im;
|
||||
static Identifier *C;
|
||||
static Identifier *D;
|
||||
static Identifier *Windows;
|
||||
static Identifier *Pascal;
|
||||
static Identifier *System;
|
||||
static Identifier *exit;
|
||||
static Identifier *success;
|
||||
static Identifier *failure;
|
||||
static Identifier *keys;
|
||||
static Identifier *values;
|
||||
static Identifier *rehash;
|
||||
static Identifier *sort;
|
||||
static Identifier *reverse;
|
||||
static Identifier *dup;
|
||||
static Identifier *idup;
|
||||
static Identifier *property;
|
||||
static Identifier *___out;
|
||||
static Identifier *___in;
|
||||
static Identifier *__int;
|
||||
static Identifier *__dollar;
|
||||
static Identifier *__LOCAL_SIZE;
|
||||
static Identifier *uadd;
|
||||
static Identifier *neg;
|
||||
static Identifier *com;
|
||||
static Identifier *add;
|
||||
static Identifier *add_r;
|
||||
static Identifier *sub;
|
||||
static Identifier *sub_r;
|
||||
static Identifier *mul;
|
||||
static Identifier *mul_r;
|
||||
static Identifier *div;
|
||||
static Identifier *div_r;
|
||||
static Identifier *mod;
|
||||
static Identifier *mod_r;
|
||||
static Identifier *eq;
|
||||
static Identifier *cmp;
|
||||
static Identifier *iand;
|
||||
static Identifier *iand_r;
|
||||
static Identifier *ior;
|
||||
static Identifier *ior_r;
|
||||
static Identifier *ixor;
|
||||
static Identifier *ixor_r;
|
||||
static Identifier *shl;
|
||||
static Identifier *shl_r;
|
||||
static Identifier *shr;
|
||||
static Identifier *shr_r;
|
||||
static Identifier *ushr;
|
||||
static Identifier *ushr_r;
|
||||
static Identifier *cat;
|
||||
static Identifier *cat_r;
|
||||
static Identifier *assign;
|
||||
static Identifier *addass;
|
||||
static Identifier *subass;
|
||||
static Identifier *mulass;
|
||||
static Identifier *divass;
|
||||
static Identifier *modass;
|
||||
static Identifier *andass;
|
||||
static Identifier *orass;
|
||||
static Identifier *xorass;
|
||||
static Identifier *shlass;
|
||||
static Identifier *shrass;
|
||||
static Identifier *ushrass;
|
||||
static Identifier *catass;
|
||||
static Identifier *postinc;
|
||||
static Identifier *postdec;
|
||||
static Identifier *index;
|
||||
static Identifier *indexass;
|
||||
static Identifier *slice;
|
||||
static Identifier *sliceass;
|
||||
static Identifier *call;
|
||||
static Identifier *cast;
|
||||
static Identifier *match;
|
||||
static Identifier *next;
|
||||
static Identifier *opIn;
|
||||
static Identifier *opIn_r;
|
||||
static Identifier *opStar;
|
||||
static Identifier *opDot;
|
||||
static Identifier *opImplicitCast;
|
||||
static Identifier *classNew;
|
||||
static Identifier *classDelete;
|
||||
static Identifier *apply;
|
||||
static Identifier *applyReverse;
|
||||
static Identifier *Fempty;
|
||||
static Identifier *Fhead;
|
||||
static Identifier *Ftoe;
|
||||
static Identifier *Fnext;
|
||||
static Identifier *Fretreat;
|
||||
static Identifier *adDup;
|
||||
static Identifier *adReverse;
|
||||
static Identifier *aaLen;
|
||||
static Identifier *aaKeys;
|
||||
static Identifier *aaValues;
|
||||
static Identifier *aaRehash;
|
||||
static Identifier *monitorenter;
|
||||
static Identifier *monitorexit;
|
||||
static Identifier *criticalenter;
|
||||
static Identifier *criticalexit;
|
||||
static Identifier *GNU_asm;
|
||||
static Identifier *lib;
|
||||
static Identifier *msg;
|
||||
static Identifier *startaddress;
|
||||
static Identifier *intrinsic;
|
||||
static Identifier *va_intrinsic;
|
||||
static Identifier *no_typeinfo;
|
||||
static Identifier *no_moduleinfo;
|
||||
static Identifier *Alloca;
|
||||
static Identifier *vastart;
|
||||
static Identifier *vacopy;
|
||||
static Identifier *vaend;
|
||||
static Identifier *vaarg;
|
||||
static Identifier *ldc;
|
||||
static Identifier *allow_inline;
|
||||
static Identifier *llvm_inline_asm;
|
||||
static Identifier *tohash;
|
||||
static Identifier *tostring;
|
||||
static Identifier *getmembers;
|
||||
static Identifier *main;
|
||||
static Identifier *WinMain;
|
||||
static Identifier *DllMain;
|
||||
static Identifier *tls_get_addr;
|
||||
static Identifier *std;
|
||||
static Identifier *math;
|
||||
static Identifier *sin;
|
||||
static Identifier *cos;
|
||||
static Identifier *tan;
|
||||
static Identifier *_sqrt;
|
||||
static Identifier *fabs;
|
||||
static Identifier *isAbstractClass;
|
||||
static Identifier *isArithmetic;
|
||||
static Identifier *isAssociativeArray;
|
||||
static Identifier *isFinalClass;
|
||||
static Identifier *isFloating;
|
||||
static Identifier *isIntegral;
|
||||
static Identifier *isScalar;
|
||||
static Identifier *isStaticArray;
|
||||
static Identifier *isUnsigned;
|
||||
static Identifier *isVirtualFunction;
|
||||
static Identifier *isAbstractFunction;
|
||||
static Identifier *isFinalFunction;
|
||||
static Identifier *hasMember;
|
||||
static Identifier *getMember;
|
||||
static Identifier *getVirtualFunctions;
|
||||
static Identifier *classInstanceSize;
|
||||
static Identifier *allMembers;
|
||||
static Identifier *derivedMembers;
|
||||
static Identifier *isSame;
|
||||
static Identifier *compiles;
|
||||
static void initialize();
|
||||
};
|
||||
#endif
|
||||
@@ -1,102 +1,102 @@
|
||||
|
||||
// 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.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "identifier.h"
|
||||
#include "mars.h"
|
||||
#include "lexer.h"
|
||||
#include "id.h"
|
||||
|
||||
Identifier::Identifier(const char *string, int value)
|
||||
{
|
||||
//printf("Identifier('%s', %d)\n", string, value);
|
||||
this->string = string;
|
||||
this->value = value;
|
||||
this->len = strlen(string);
|
||||
}
|
||||
|
||||
hash_t Identifier::hashCode()
|
||||
{
|
||||
return String::calcHash(string);
|
||||
}
|
||||
|
||||
int Identifier::equals(Object *o)
|
||||
{
|
||||
return this == o || memcmp(string,o->toChars(),len+1) == 0;
|
||||
}
|
||||
|
||||
int Identifier::compare(Object *o)
|
||||
{
|
||||
return memcmp(string, o->toChars(), len + 1);
|
||||
}
|
||||
|
||||
char *Identifier::toChars()
|
||||
{
|
||||
return (char *)string;
|
||||
}
|
||||
|
||||
const char *Identifier::toHChars2()
|
||||
{
|
||||
const char *p = NULL;
|
||||
|
||||
if (this == Id::ctor) p = "this";
|
||||
else if (this == Id::dtor) p = "~this";
|
||||
else if (this == Id::classInvariant) p = "invariant";
|
||||
else if (this == Id::unitTest) p = "unittest";
|
||||
else if (this == Id::dollar) p = "$";
|
||||
else if (this == Id::withSym) p = "with";
|
||||
else if (this == Id::result) p = "result";
|
||||
else if (this == Id::returnLabel) p = "return";
|
||||
else
|
||||
{ p = toChars();
|
||||
if (*p == '_')
|
||||
{
|
||||
if (memcmp(p, "_staticCtor", 11) == 0)
|
||||
p = "static this";
|
||||
else if (memcmp(p, "_staticDtor", 11) == 0)
|
||||
p = "static ~this";
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void Identifier::print()
|
||||
{
|
||||
fprintf(stdmsg, "%s",string);
|
||||
}
|
||||
|
||||
int Identifier::dyncast()
|
||||
{
|
||||
return DYNCAST_IDENTIFIER;
|
||||
}
|
||||
|
||||
// BUG: these are redundant with Lexer::uniqueId()
|
||||
|
||||
Identifier *Identifier::generateId(const char *prefix)
|
||||
{
|
||||
static size_t i;
|
||||
|
||||
return generateId(prefix, ++i);
|
||||
}
|
||||
|
||||
Identifier *Identifier::generateId(const char *prefix, size_t i)
|
||||
{ OutBuffer buf;
|
||||
|
||||
buf.writestring(prefix);
|
||||
buf.printf("%zu", i);
|
||||
|
||||
char *id = buf.toChars();
|
||||
buf.data = NULL;
|
||||
return Lexer::idPool(id);
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "identifier.h"
|
||||
#include "mars.h"
|
||||
#include "lexer.h"
|
||||
#include "id.h"
|
||||
|
||||
Identifier::Identifier(const char *string, int value)
|
||||
{
|
||||
//printf("Identifier('%s', %d)\n", string, value);
|
||||
this->string = string;
|
||||
this->value = value;
|
||||
this->len = strlen(string);
|
||||
}
|
||||
|
||||
hash_t Identifier::hashCode()
|
||||
{
|
||||
return String::calcHash(string);
|
||||
}
|
||||
|
||||
int Identifier::equals(Object *o)
|
||||
{
|
||||
return this == o || memcmp(string,o->toChars(),len+1) == 0;
|
||||
}
|
||||
|
||||
int Identifier::compare(Object *o)
|
||||
{
|
||||
return memcmp(string, o->toChars(), len + 1);
|
||||
}
|
||||
|
||||
char *Identifier::toChars()
|
||||
{
|
||||
return (char *)string;
|
||||
}
|
||||
|
||||
const char *Identifier::toHChars2()
|
||||
{
|
||||
const char *p = NULL;
|
||||
|
||||
if (this == Id::ctor) p = "this";
|
||||
else if (this == Id::dtor) p = "~this";
|
||||
else if (this == Id::classInvariant) p = "invariant";
|
||||
else if (this == Id::unitTest) p = "unittest";
|
||||
else if (this == Id::dollar) p = "$";
|
||||
else if (this == Id::withSym) p = "with";
|
||||
else if (this == Id::result) p = "result";
|
||||
else if (this == Id::returnLabel) p = "return";
|
||||
else
|
||||
{ p = toChars();
|
||||
if (*p == '_')
|
||||
{
|
||||
if (memcmp(p, "_staticCtor", 11) == 0)
|
||||
p = "static this";
|
||||
else if (memcmp(p, "_staticDtor", 11) == 0)
|
||||
p = "static ~this";
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void Identifier::print()
|
||||
{
|
||||
fprintf(stdmsg, "%s",string);
|
||||
}
|
||||
|
||||
int Identifier::dyncast()
|
||||
{
|
||||
return DYNCAST_IDENTIFIER;
|
||||
}
|
||||
|
||||
// BUG: these are redundant with Lexer::uniqueId()
|
||||
|
||||
Identifier *Identifier::generateId(const char *prefix)
|
||||
{
|
||||
static size_t i;
|
||||
|
||||
return generateId(prefix, ++i);
|
||||
}
|
||||
|
||||
Identifier *Identifier::generateId(const char *prefix, size_t i)
|
||||
{ OutBuffer buf;
|
||||
|
||||
buf.writestring(prefix);
|
||||
buf.printf("%zu", i);
|
||||
|
||||
char *id = buf.toChars();
|
||||
buf.data = NULL;
|
||||
return Lexer::idPool(id);
|
||||
}
|
||||
|
||||
797
dmd2/idgen.c
797
dmd2/idgen.c
@@ -1,385 +1,412 @@
|
||||
|
||||
// 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.
|
||||
|
||||
// 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
|
||||
{
|
||||
const char *ident; // name to use in DMD source
|
||||
const char *name; // name in D executable
|
||||
};
|
||||
|
||||
Msgtable msgtable[] =
|
||||
{
|
||||
{ "IUnknown" },
|
||||
{ "Object" },
|
||||
{ "object" },
|
||||
{ "max" },
|
||||
{ "min" },
|
||||
{ "This", "this" },
|
||||
{ "ctor", "__ctor" },
|
||||
{ "dtor", "__dtor" },
|
||||
{ "cpctor", "__cpctor" },
|
||||
{ "_postblit", "__postblit" },
|
||||
{ "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" },
|
||||
{ "Throwable" },
|
||||
{ "withSym", "__withSym" },
|
||||
{ "result", "__result" },
|
||||
{ "returnLabel", "__returnLabel" },
|
||||
{ "delegate" },
|
||||
{ "line" },
|
||||
{ "empty", "" },
|
||||
{ "p" },
|
||||
{ "coverage", "__coverage" },
|
||||
{ "__vptr" },
|
||||
{ "__monitor" },
|
||||
{ "system" },
|
||||
|
||||
{ "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" },
|
||||
{ "TypeInfo_Shared" },
|
||||
{ "elements" },
|
||||
{ "_arguments_typeinfo" },
|
||||
{ "_arguments" },
|
||||
{ "_argptr" },
|
||||
{ "_match" },
|
||||
{ "destroy" },
|
||||
{ "postblit" },
|
||||
|
||||
{ "LINE", "__LINE__" },
|
||||
{ "FILE", "__FILE__" },
|
||||
{ "DATE", "__DATE__" },
|
||||
{ "TIME", "__TIME__" },
|
||||
{ "TIMESTAMP", "__TIMESTAMP__" },
|
||||
{ "VENDOR", "__VENDOR__" },
|
||||
{ "VERSIONX", "__VERSION__" },
|
||||
{ "EOFX", "__EOF__" },
|
||||
|
||||
{ "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" },
|
||||
|
||||
{ "property" },
|
||||
|
||||
// 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" },
|
||||
{ "opStar" },
|
||||
{ "opDot" },
|
||||
{ "opImplicitCast" },
|
||||
|
||||
{ "classNew", "new" },
|
||||
{ "classDelete", "delete" },
|
||||
|
||||
// For foreach
|
||||
{ "apply", "opApply" },
|
||||
{ "applyReverse", "opApplyReverse" },
|
||||
|
||||
#if 1
|
||||
{ "Fempty", "empty" },
|
||||
{ "Fhead", "front" },
|
||||
{ "Ftoe", "back" },
|
||||
{ "Fnext", "popFront" },
|
||||
{ "Fretreat", "popBack" },
|
||||
#else
|
||||
{ "Fempty", "empty" },
|
||||
{ "Fhead", "head" },
|
||||
{ "Ftoe", "toe" },
|
||||
{ "Fnext", "next" },
|
||||
{ "Fretreat", "retreat" },
|
||||
#endif
|
||||
|
||||
{ "adDup", "_adDupT" },
|
||||
{ "adReverse", "_adReverse" },
|
||||
|
||||
// For internal functions
|
||||
{ "aaLen", "_aaLen" },
|
||||
{ "aaKeys", "_aaKeys" },
|
||||
{ "aaValues", "_aaValues" },
|
||||
{ "aaRehash", "_aaRehash" },
|
||||
{ "monitorenter", "_d_monitorenter" },
|
||||
{ "monitorexit", "_d_monitorexit" },
|
||||
{ "criticalenter", "_d_criticalenter" },
|
||||
{ "criticalexit", "_d_criticalexit" },
|
||||
|
||||
// For pragma's
|
||||
{ "GNU_asm" },
|
||||
{ "lib" },
|
||||
{ "msg" },
|
||||
{ "startaddress" },
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC pragma's
|
||||
{ "intrinsic" },
|
||||
{ "va_intrinsic" },
|
||||
{ "no_typeinfo" },
|
||||
{ "no_moduleinfo" },
|
||||
{ "Alloca", "alloca" },
|
||||
{ "vastart", "va_start" },
|
||||
{ "vacopy", "va_copy" },
|
||||
{ "vaend", "va_end" },
|
||||
{ "vaarg", "va_arg" },
|
||||
{ "ldc" },
|
||||
{ "allow_inline" },
|
||||
{ "llvm_inline_asm" },
|
||||
#endif
|
||||
|
||||
// For special functions
|
||||
{ "tohash", "toHash" },
|
||||
{ "tostring", "toString" },
|
||||
{ "getmembers", "getMembers" },
|
||||
|
||||
// Special functions
|
||||
#if IN_DMD
|
||||
{ "alloca" },
|
||||
#endif
|
||||
{ "main" },
|
||||
{ "WinMain" },
|
||||
{ "DllMain" },
|
||||
{ "tls_get_addr", "___tls_get_addr" },
|
||||
|
||||
// Builtin functions
|
||||
{ "std" },
|
||||
{ "math" },
|
||||
{ "sin" },
|
||||
{ "cos" },
|
||||
{ "tan" },
|
||||
{ "_sqrt", "sqrt" },
|
||||
{ "fabs" },
|
||||
|
||||
// Traits
|
||||
{ "isAbstractClass" },
|
||||
{ "isArithmetic" },
|
||||
{ "isAssociativeArray" },
|
||||
{ "isFinalClass" },
|
||||
{ "isFloating" },
|
||||
{ "isIntegral" },
|
||||
{ "isScalar" },
|
||||
{ "isStaticArray" },
|
||||
{ "isUnsigned" },
|
||||
{ "isVirtualFunction" },
|
||||
{ "isAbstractFunction" },
|
||||
{ "isFinalFunction" },
|
||||
{ "hasMember" },
|
||||
{ "getMember" },
|
||||
{ "getVirtualFunctions" },
|
||||
{ "classInstanceSize" },
|
||||
{ "allMembers" },
|
||||
{ "derivedMembers" },
|
||||
{ "isSame" },
|
||||
{ "compiles" },
|
||||
};
|
||||
|
||||
|
||||
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++)
|
||||
{ const 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++)
|
||||
{ const char *id = msgtable[i].ident;
|
||||
const 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++)
|
||||
{ const char *id = msgtable[i].ident;
|
||||
const 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-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.
|
||||
|
||||
// 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 <assert.h>
|
||||
|
||||
struct Msgtable
|
||||
{
|
||||
const char *ident; // name to use in DMD source
|
||||
const char *name; // name in D executable
|
||||
};
|
||||
|
||||
Msgtable msgtable[] =
|
||||
{
|
||||
{ "IUnknown" },
|
||||
{ "Object" },
|
||||
{ "object" },
|
||||
{ "max" },
|
||||
{ "min" },
|
||||
{ "This", "this" },
|
||||
{ "ctor", "__ctor" },
|
||||
{ "dtor", "__dtor" },
|
||||
{ "cpctor", "__cpctor" },
|
||||
{ "_postblit", "__postblit" },
|
||||
{ "classInvariant", "__invariant" },
|
||||
{ "unitTest", "__unitTest" },
|
||||
{ "require", "__require" },
|
||||
{ "ensure", "__ensure" },
|
||||
{ "init" },
|
||||
{ "size" },
|
||||
{ "__sizeof", "sizeof" },
|
||||
{ "__xalignof", "alignof" },
|
||||
{ "mangleof" },
|
||||
{ "stringof" },
|
||||
{ "tupleof" },
|
||||
{ "length" },
|
||||
{ "remove" },
|
||||
{ "ptr" },
|
||||
{ "funcptr" },
|
||||
{ "dollar", "__dollar" },
|
||||
{ "ctfe", "__ctfe" },
|
||||
{ "offset" },
|
||||
{ "offsetof" },
|
||||
{ "ModuleInfo" },
|
||||
{ "ClassInfo" },
|
||||
{ "classinfo" },
|
||||
{ "typeinfo" },
|
||||
{ "outer" },
|
||||
{ "Exception" },
|
||||
{ "AssociativeArray" },
|
||||
{ "Throwable" },
|
||||
{ "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" },
|
||||
{ "TypeInfo_Shared" },
|
||||
{ "TypeInfo_Wild", "TypeInfo_Inout" },
|
||||
{ "elements" },
|
||||
{ "_arguments_typeinfo" },
|
||||
{ "_arguments" },
|
||||
{ "_argptr" },
|
||||
{ "_match" },
|
||||
{ "destroy" },
|
||||
{ "postblit" },
|
||||
|
||||
{ "LINE", "__LINE__" },
|
||||
{ "FILE", "__FILE__" },
|
||||
{ "DATE", "__DATE__" },
|
||||
{ "TIME", "__TIME__" },
|
||||
{ "TIMESTAMP", "__TIMESTAMP__" },
|
||||
{ "VENDOR", "__VENDOR__" },
|
||||
{ "VERSIONX", "__VERSION__" },
|
||||
{ "EOFX", "__EOF__" },
|
||||
|
||||
{ "nan" },
|
||||
{ "infinity" },
|
||||
{ "dig" },
|
||||
{ "epsilon" },
|
||||
{ "mant_dig" },
|
||||
{ "max_10_exp" },
|
||||
{ "max_exp" },
|
||||
{ "min_10_exp" },
|
||||
{ "min_exp" },
|
||||
{ "min_normal" },
|
||||
{ "re" },
|
||||
{ "im" },
|
||||
|
||||
{ "C" },
|
||||
{ "D" },
|
||||
{ "Windows" },
|
||||
{ "Pascal" },
|
||||
{ "System" },
|
||||
|
||||
{ "exit" },
|
||||
{ "success" },
|
||||
{ "failure" },
|
||||
|
||||
{ "keys" },
|
||||
{ "values" },
|
||||
{ "rehash" },
|
||||
|
||||
{ "sort" },
|
||||
{ "reverse" },
|
||||
{ "dup" },
|
||||
{ "idup" },
|
||||
|
||||
{ "property" },
|
||||
{ "safe" },
|
||||
{ "trusted" },
|
||||
{ "system" },
|
||||
{ "disable" },
|
||||
|
||||
// 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" },
|
||||
{ "opStar" },
|
||||
{ "opDot" },
|
||||
{ "opDispatch" },
|
||||
{ "opUnary" },
|
||||
{ "opIndexUnary" },
|
||||
{ "opSliceUnary" },
|
||||
{ "opBinary" },
|
||||
{ "opBinaryRight" },
|
||||
{ "opOpAssign" },
|
||||
{ "opIndexOpAssign" },
|
||||
{ "opSliceOpAssign" },
|
||||
{ "pow", "opPow" },
|
||||
{ "pow_r", "opPow_r" },
|
||||
{ "powass", "opPowAssign" },
|
||||
|
||||
{ "classNew", "new" },
|
||||
{ "classDelete", "delete" },
|
||||
|
||||
// For foreach
|
||||
{ "apply", "opApply" },
|
||||
{ "applyReverse", "opApplyReverse" },
|
||||
|
||||
#if 1
|
||||
{ "Fempty", "empty" },
|
||||
{ "Fhead", "front" },
|
||||
{ "Ftoe", "back" },
|
||||
{ "Fnext", "popFront" },
|
||||
{ "Fretreat", "popBack" },
|
||||
#else
|
||||
{ "Fempty", "empty" },
|
||||
{ "Fhead", "head" },
|
||||
{ "Ftoe", "toe" },
|
||||
{ "Fnext", "next" },
|
||||
{ "Fretreat", "retreat" },
|
||||
#endif
|
||||
|
||||
{ "adDup", "_adDupT" },
|
||||
{ "adReverse", "_adReverse" },
|
||||
|
||||
// For internal functions
|
||||
{ "aaLen", "_aaLen" },
|
||||
{ "aaKeys", "_aaKeys" },
|
||||
{ "aaValues", "_aaValues" },
|
||||
{ "aaRehash", "_aaRehash" },
|
||||
{ "monitorenter", "_d_monitorenter" },
|
||||
{ "monitorexit", "_d_monitorexit" },
|
||||
{ "criticalenter", "_d_criticalenter" },
|
||||
{ "criticalexit", "_d_criticalexit" },
|
||||
{ "_ArrayEq" },
|
||||
|
||||
// For pragma's
|
||||
{ "GNU_asm" },
|
||||
{ "lib" },
|
||||
{ "msg" },
|
||||
{ "startaddress" },
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC pragma's
|
||||
{ "intrinsic" },
|
||||
{ "va_intrinsic" },
|
||||
{ "no_typeinfo" },
|
||||
{ "no_moduleinfo" },
|
||||
{ "Alloca", "alloca" },
|
||||
{ "vastart", "va_start" },
|
||||
{ "vacopy", "va_copy" },
|
||||
{ "vaend", "va_end" },
|
||||
{ "vaarg", "va_arg" },
|
||||
{ "ldc" },
|
||||
{ "allow_inline" },
|
||||
{ "llvm_inline_asm" },
|
||||
#endif
|
||||
|
||||
// For special functions
|
||||
{ "tohash", "toHash" },
|
||||
{ "tostring", "toString" },
|
||||
{ "getmembers", "getMembers" },
|
||||
|
||||
// Special functions
|
||||
#if IN_DMD
|
||||
{ "alloca" },
|
||||
#endif
|
||||
{ "main" },
|
||||
{ "WinMain" },
|
||||
{ "DllMain" },
|
||||
{ "tls_get_addr", "___tls_get_addr" },
|
||||
|
||||
// Builtin functions
|
||||
{ "std" },
|
||||
{ "math" },
|
||||
{ "sin" },
|
||||
{ "cos" },
|
||||
{ "tan" },
|
||||
{ "_sqrt", "sqrt" },
|
||||
{ "_pow", "pow" },
|
||||
{ "fabs" },
|
||||
|
||||
// Traits
|
||||
{ "isAbstractClass" },
|
||||
{ "isArithmetic" },
|
||||
{ "isAssociativeArray" },
|
||||
{ "isFinalClass" },
|
||||
{ "isFloating" },
|
||||
{ "isIntegral" },
|
||||
{ "isScalar" },
|
||||
{ "isStaticArray" },
|
||||
{ "isUnsigned" },
|
||||
{ "isVirtualFunction" },
|
||||
{ "isAbstractFunction" },
|
||||
{ "isFinalFunction" },
|
||||
{ "isStaticFunction" },
|
||||
{ "isRef" },
|
||||
{ "isOut" },
|
||||
{ "isLazy" },
|
||||
{ "hasMember" },
|
||||
{ "identifier" },
|
||||
{ "getMember" },
|
||||
{ "getOverloads" },
|
||||
{ "getVirtualFunctions" },
|
||||
{ "classInstanceSize" },
|
||||
{ "allMembers" },
|
||||
{ "derivedMembers" },
|
||||
{ "isSame" },
|
||||
{ "compiles" },
|
||||
};
|
||||
|
||||
|
||||
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++)
|
||||
{ const 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++)
|
||||
{ const char *id = msgtable[i].ident;
|
||||
const 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++)
|
||||
{ const char *id = msgtable[i].ident;
|
||||
const 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;
|
||||
}
|
||||
|
||||
924
dmd2/impcnvgen.c
924
dmd2/impcnvgen.c
@@ -1,462 +1,462 @@
|
||||
|
||||
// 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 "mtype.h"
|
||||
|
||||
TY impcnvResult[TMAX][TMAX];
|
||||
TY impcnvType1[TMAX][TMAX];
|
||||
TY impcnvType2[TMAX][TMAX];
|
||||
int impcnvWarn[TMAX][TMAX];
|
||||
|
||||
int integral_promotion(int t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case Tchar:
|
||||
case Twchar:
|
||||
//case Tbit:
|
||||
case Tbool:
|
||||
case Tint8:
|
||||
case Tuns8:
|
||||
case Tint16:
|
||||
case Tuns16: return Tint32;
|
||||
case Tdchar: return Tuns32;
|
||||
default: return t;
|
||||
}
|
||||
}
|
||||
|
||||
void init()
|
||||
{ int i, j;
|
||||
|
||||
// Set conversion tables
|
||||
for (i = 0; i < TMAX; i++)
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{ impcnvResult[i][j] = Terror;
|
||||
impcnvType1[i][j] = Terror;
|
||||
impcnvType2[i][j] = Terror;
|
||||
impcnvWarn[i][j] = 0;
|
||||
}
|
||||
|
||||
#define X(t1,t2, nt1,nt2, rt) \
|
||||
impcnvResult[t1][t2] = rt; \
|
||||
impcnvType1[t1][t2] = nt1; \
|
||||
impcnvType2[t1][t2] = nt2;
|
||||
|
||||
/* ======================= */
|
||||
|
||||
#if 0
|
||||
X(Tbit,Tbit, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tint8, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tuns8, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tint16, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tbit,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tbit,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tbit,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tbit,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tbit,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tbit,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tbit,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tbit,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tbit,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tbit,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tbit,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
#endif
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tbool,Tbool, Tbool,Tbool, Tbool)
|
||||
X(Tbool,Tint8, Tint32,Tint32, Tint32)
|
||||
X(Tbool,Tuns8, Tint32,Tint32, Tint32)
|
||||
X(Tbool,Tint16, Tint32,Tint32, Tint32)
|
||||
X(Tbool,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tbool,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tbool,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tbool,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tbool,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tbool,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tbool,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tbool,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tbool,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tbool,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tbool,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tbool,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tbool,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tbool,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tint8,Tint8, Tint32,Tint32, Tint32)
|
||||
X(Tint8,Tuns8, Tint32,Tint32, Tint32)
|
||||
X(Tint8,Tint16, Tint32,Tint32, Tint32)
|
||||
X(Tint8,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tint8,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tint8,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tint8,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tint8,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tint8,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tint8,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tint8,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tint8,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tint8,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tint8,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tint8,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tint8,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tint8,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tuns8,Tuns8, Tint32,Tint32, Tint32)
|
||||
X(Tuns8,Tint16, Tint32,Tint32, Tint32)
|
||||
X(Tuns8,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tuns8,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tuns8,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tuns8,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tuns8,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tuns8,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tuns8,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tuns8,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tuns8,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tuns8,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tuns8,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tuns8,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tuns8,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tuns8,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tint16,Tint16, Tint32,Tint32, Tint32)
|
||||
X(Tint16,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tint16,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tint16,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tint16,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tint16,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tint16,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tint16,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tint16,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tint16,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tint16,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tint16,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tint16,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tint16,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tint16,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tuns16,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tuns16,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tuns16,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tuns16,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tuns16,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tuns16,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tuns16,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tuns16,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tuns16,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tuns16,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tuns16,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tuns16,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tuns16,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tuns16,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tint32,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tint32,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tint32,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tint32,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tint32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tint32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tint32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tint32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tint32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tint32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tint32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tint32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tint32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tuns32,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tuns32,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tuns32,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tuns32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tuns32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tuns32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tuns32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tuns32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tuns32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tuns32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tuns32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tuns32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tint64,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tint64,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tint64,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tint64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tint64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tint64,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tint64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tint64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tint64,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tint64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tint64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tuns64,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tuns64,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tuns64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tuns64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tuns64,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tuns64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tuns64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tuns64,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tuns64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tuns64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tfloat32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tfloat32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tfloat32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
|
||||
X(Tfloat32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tfloat32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tfloat32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
|
||||
X(Tfloat32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tfloat32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tfloat32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tfloat64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tfloat64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
|
||||
X(Tfloat64,Timaginary32, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tfloat64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tfloat64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
|
||||
X(Tfloat64,Tcomplex32, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tfloat64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tfloat64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tfloat80,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
|
||||
X(Tfloat80,Timaginary32, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tfloat80,Timaginary64, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tfloat80,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
|
||||
X(Tfloat80,Tcomplex32, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
X(Tfloat80,Tcomplex64, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
X(Tfloat80,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Timaginary32,Timaginary32, Timaginary32,Timaginary32, Timaginary32)
|
||||
X(Timaginary32,Timaginary64, Timaginary64,Timaginary64, Timaginary64)
|
||||
X(Timaginary32,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
|
||||
|
||||
X(Timaginary32,Tcomplex32, Timaginary32,Tcomplex32, Tcomplex32)
|
||||
X(Timaginary32,Tcomplex64, Timaginary64,Tcomplex64, Tcomplex64)
|
||||
X(Timaginary32,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Timaginary64,Timaginary64, Timaginary64,Timaginary64, Timaginary64)
|
||||
X(Timaginary64,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
|
||||
|
||||
X(Timaginary64,Tcomplex32, Timaginary64,Tcomplex64, Tcomplex64)
|
||||
X(Timaginary64,Tcomplex64, Timaginary64,Tcomplex64, Tcomplex64)
|
||||
X(Timaginary64,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Timaginary80,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
|
||||
|
||||
X(Timaginary80,Tcomplex32, Timaginary80,Tcomplex80, Tcomplex80)
|
||||
X(Timaginary80,Tcomplex64, Timaginary80,Tcomplex80, Tcomplex80)
|
||||
X(Timaginary80,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tcomplex32,Tcomplex32, Tcomplex32,Tcomplex32, Tcomplex32)
|
||||
X(Tcomplex32,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64)
|
||||
X(Tcomplex32,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tcomplex64,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64)
|
||||
X(Tcomplex64,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tcomplex80,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
|
||||
|
||||
#undef X
|
||||
|
||||
#define Y(t1,t2) impcnvWarn[t1][t2] = 1;
|
||||
|
||||
#if 0
|
||||
Y(Tint8, Tbit)
|
||||
Y(Tuns8, Tbit)
|
||||
Y(Tint16, Tbit)
|
||||
Y(Tuns16, Tbit)
|
||||
Y(Tint32, Tbit)
|
||||
Y(Tuns32, Tbit)
|
||||
Y(Tint64, Tbit)
|
||||
Y(Tuns64, Tbit)
|
||||
#endif
|
||||
|
||||
Y(Tuns8, Tint8)
|
||||
Y(Tint16, Tint8)
|
||||
Y(Tuns16, Tint8)
|
||||
Y(Tint32, Tint8)
|
||||
Y(Tuns32, Tint8)
|
||||
Y(Tint64, Tint8)
|
||||
Y(Tuns64, Tint8)
|
||||
|
||||
Y(Tint8, Tuns8)
|
||||
Y(Tint16, Tuns8)
|
||||
Y(Tuns16, Tuns8)
|
||||
Y(Tint32, Tuns8)
|
||||
Y(Tuns32, Tuns8)
|
||||
Y(Tint64, Tuns8)
|
||||
Y(Tuns64, Tuns8)
|
||||
|
||||
Y(Tint8, Tchar)
|
||||
Y(Tint16, Tchar)
|
||||
Y(Tuns16, Tchar)
|
||||
Y(Tint32, Tchar)
|
||||
Y(Tuns32, Tchar)
|
||||
Y(Tint64, Tchar)
|
||||
Y(Tuns64, Tchar)
|
||||
|
||||
Y(Tuns16, Tint16)
|
||||
Y(Tint32, Tint16)
|
||||
Y(Tuns32, Tint16)
|
||||
Y(Tint64, Tint16)
|
||||
Y(Tuns64, Tint16)
|
||||
|
||||
Y(Tint16, Tuns16)
|
||||
Y(Tint32, Tuns16)
|
||||
Y(Tuns32, Tuns16)
|
||||
Y(Tint64, Tuns16)
|
||||
Y(Tuns64, Tuns16)
|
||||
|
||||
Y(Tint16, Twchar)
|
||||
Y(Tint32, Twchar)
|
||||
Y(Tuns32, Twchar)
|
||||
Y(Tint64, Twchar)
|
||||
Y(Tuns64, Twchar)
|
||||
|
||||
// Y(Tuns32, Tint32)
|
||||
Y(Tint64, Tint32)
|
||||
Y(Tuns64, Tint32)
|
||||
|
||||
// Y(Tint32, Tuns32)
|
||||
Y(Tint64, Tuns32)
|
||||
Y(Tuns64, Tuns32)
|
||||
|
||||
Y(Tint64, Tdchar)
|
||||
Y(Tuns64, Tdchar)
|
||||
|
||||
Y(Tint64, Tuns64)
|
||||
Y(Tuns64, Tint64)
|
||||
|
||||
for (i = 0; i < TMAX; i++)
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{
|
||||
if (impcnvResult[i][j] == Terror)
|
||||
{
|
||||
impcnvResult[i][j] = impcnvResult[j][i];
|
||||
impcnvType1[i][j] = impcnvType2[j][i];
|
||||
impcnvType2[i][j] = impcnvType1[j][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{ FILE *fp;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
init();
|
||||
|
||||
fp = fopen("impcnvtab.c","w");
|
||||
|
||||
fprintf(fp,"// This file is generated by impcnvgen.c\n");
|
||||
fprintf(fp,"#include \"mtype.h\"\n");
|
||||
|
||||
fprintf(fp,"unsigned char Type::impcnvResult[TMAX][TMAX] =\n{\n");
|
||||
for (i = 0; i < TMAX; i++)
|
||||
{
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{
|
||||
fprintf(fp, "%d,",impcnvResult[i][j]);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
fprintf(fp,"};\n");
|
||||
|
||||
fprintf(fp,"unsigned char Type::impcnvType1[TMAX][TMAX] =\n{\n");
|
||||
for (i = 0; i < TMAX; i++)
|
||||
{
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{
|
||||
fprintf(fp, "%d,",impcnvType1[i][j]);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
fprintf(fp,"};\n");
|
||||
|
||||
fprintf(fp,"unsigned char Type::impcnvType2[TMAX][TMAX] =\n{\n");
|
||||
for (i = 0; i < TMAX; i++)
|
||||
{
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{
|
||||
fprintf(fp, "%d,",impcnvType2[i][j]);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
fprintf(fp,"};\n");
|
||||
|
||||
fprintf(fp,"unsigned char Type::impcnvWarn[TMAX][TMAX] =\n{\n");
|
||||
for (i = 0; i < TMAX; i++)
|
||||
{
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{
|
||||
fprintf(fp, "%d,",impcnvWarn[i][j]);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
fprintf(fp,"};\n");
|
||||
|
||||
fclose(fp);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
// 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 "mtype.h"
|
||||
|
||||
TY impcnvResult[TMAX][TMAX];
|
||||
TY impcnvType1[TMAX][TMAX];
|
||||
TY impcnvType2[TMAX][TMAX];
|
||||
int impcnvWarn[TMAX][TMAX];
|
||||
|
||||
int integral_promotion(int t)
|
||||
{
|
||||
switch (t)
|
||||
{
|
||||
case Tchar:
|
||||
case Twchar:
|
||||
//case Tbit:
|
||||
case Tbool:
|
||||
case Tint8:
|
||||
case Tuns8:
|
||||
case Tint16:
|
||||
case Tuns16: return Tint32;
|
||||
case Tdchar: return Tuns32;
|
||||
default: return t;
|
||||
}
|
||||
}
|
||||
|
||||
void init()
|
||||
{ int i, j;
|
||||
|
||||
// Set conversion tables
|
||||
for (i = 0; i < TMAX; i++)
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{ impcnvResult[i][j] = Terror;
|
||||
impcnvType1[i][j] = Terror;
|
||||
impcnvType2[i][j] = Terror;
|
||||
impcnvWarn[i][j] = 0;
|
||||
}
|
||||
|
||||
#define X(t1,t2, nt1,nt2, rt) \
|
||||
impcnvResult[t1][t2] = rt; \
|
||||
impcnvType1[t1][t2] = nt1; \
|
||||
impcnvType2[t1][t2] = nt2;
|
||||
|
||||
/* ======================= */
|
||||
|
||||
#if 0
|
||||
X(Tbit,Tbit, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tint8, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tuns8, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tint16, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tbit,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tbit,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tbit,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tbit,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tbit,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tbit,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tbit,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tbit,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tbit,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tbit,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tbit,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tbit,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
#endif
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tbool,Tbool, Tbool,Tbool, Tbool)
|
||||
X(Tbool,Tint8, Tint32,Tint32, Tint32)
|
||||
X(Tbool,Tuns8, Tint32,Tint32, Tint32)
|
||||
X(Tbool,Tint16, Tint32,Tint32, Tint32)
|
||||
X(Tbool,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tbool,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tbool,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tbool,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tbool,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tbool,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tbool,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tbool,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tbool,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tbool,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tbool,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tbool,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tbool,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tbool,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tint8,Tint8, Tint32,Tint32, Tint32)
|
||||
X(Tint8,Tuns8, Tint32,Tint32, Tint32)
|
||||
X(Tint8,Tint16, Tint32,Tint32, Tint32)
|
||||
X(Tint8,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tint8,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tint8,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tint8,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tint8,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tint8,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tint8,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tint8,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tint8,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tint8,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tint8,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tint8,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tint8,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tint8,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tuns8,Tuns8, Tint32,Tint32, Tint32)
|
||||
X(Tuns8,Tint16, Tint32,Tint32, Tint32)
|
||||
X(Tuns8,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tuns8,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tuns8,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tuns8,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tuns8,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tuns8,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tuns8,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tuns8,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tuns8,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tuns8,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tuns8,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tuns8,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tuns8,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tuns8,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tint16,Tint16, Tint32,Tint32, Tint32)
|
||||
X(Tint16,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tint16,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tint16,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tint16,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tint16,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tint16,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tint16,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tint16,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tint16,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tint16,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tint16,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tint16,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tint16,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tint16,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tuns16,Tuns16, Tint32,Tint32, Tint32)
|
||||
X(Tuns16,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tuns16,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tuns16,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tuns16,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tuns16,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tuns16,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tuns16,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tuns16,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tuns16,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tuns16,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tuns16,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tuns16,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tuns16,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tint32,Tint32, Tint32,Tint32, Tint32)
|
||||
X(Tint32,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tint32,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tint32,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tint32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tint32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tint32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tint32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tint32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tint32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tint32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tint32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tint32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tuns32,Tuns32, Tuns32,Tuns32, Tuns32)
|
||||
X(Tuns32,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tuns32,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tuns32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tuns32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tuns32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tuns32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tuns32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tuns32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tuns32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tuns32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tuns32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tint64,Tint64, Tint64,Tint64, Tint64)
|
||||
X(Tint64,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tint64,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tint64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tint64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tint64,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tint64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tint64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tint64,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tint64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tint64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tuns64,Tuns64, Tuns64,Tuns64, Tuns64)
|
||||
|
||||
X(Tuns64,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tuns64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tuns64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
X(Tuns64,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tuns64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tuns64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tuns64,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tuns64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tuns64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tfloat32,Tfloat32, Tfloat32,Tfloat32, Tfloat32)
|
||||
X(Tfloat32,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tfloat32,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
|
||||
X(Tfloat32,Timaginary32, Tfloat32,Timaginary32, Tfloat32)
|
||||
X(Tfloat32,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tfloat32,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
|
||||
X(Tfloat32,Tcomplex32, Tfloat32,Tcomplex32, Tcomplex32)
|
||||
X(Tfloat32,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tfloat32,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tfloat64,Tfloat64, Tfloat64,Tfloat64, Tfloat64)
|
||||
X(Tfloat64,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
|
||||
X(Tfloat64,Timaginary32, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tfloat64,Timaginary64, Tfloat64,Timaginary64, Tfloat64)
|
||||
X(Tfloat64,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
|
||||
X(Tfloat64,Tcomplex32, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tfloat64,Tcomplex64, Tfloat64,Tcomplex64, Tcomplex64)
|
||||
X(Tfloat64,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tfloat80,Tfloat80, Tfloat80,Tfloat80, Tfloat80)
|
||||
|
||||
X(Tfloat80,Timaginary32, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tfloat80,Timaginary64, Tfloat80,Timaginary80, Tfloat80)
|
||||
X(Tfloat80,Timaginary80, Tfloat80,Timaginary80, Tfloat80)
|
||||
|
||||
X(Tfloat80,Tcomplex32, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
X(Tfloat80,Tcomplex64, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
X(Tfloat80,Tcomplex80, Tfloat80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Timaginary32,Timaginary32, Timaginary32,Timaginary32, Timaginary32)
|
||||
X(Timaginary32,Timaginary64, Timaginary64,Timaginary64, Timaginary64)
|
||||
X(Timaginary32,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
|
||||
|
||||
X(Timaginary32,Tcomplex32, Timaginary32,Tcomplex32, Tcomplex32)
|
||||
X(Timaginary32,Tcomplex64, Timaginary64,Tcomplex64, Tcomplex64)
|
||||
X(Timaginary32,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Timaginary64,Timaginary64, Timaginary64,Timaginary64, Timaginary64)
|
||||
X(Timaginary64,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
|
||||
|
||||
X(Timaginary64,Tcomplex32, Timaginary64,Tcomplex64, Tcomplex64)
|
||||
X(Timaginary64,Tcomplex64, Timaginary64,Tcomplex64, Tcomplex64)
|
||||
X(Timaginary64,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Timaginary80,Timaginary80, Timaginary80,Timaginary80, Timaginary80)
|
||||
|
||||
X(Timaginary80,Tcomplex32, Timaginary80,Tcomplex80, Tcomplex80)
|
||||
X(Timaginary80,Tcomplex64, Timaginary80,Tcomplex80, Tcomplex80)
|
||||
X(Timaginary80,Tcomplex80, Timaginary80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tcomplex32,Tcomplex32, Tcomplex32,Tcomplex32, Tcomplex32)
|
||||
X(Tcomplex32,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64)
|
||||
X(Tcomplex32,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tcomplex64,Tcomplex64, Tcomplex64,Tcomplex64, Tcomplex64)
|
||||
X(Tcomplex64,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
|
||||
|
||||
/* ======================= */
|
||||
|
||||
X(Tcomplex80,Tcomplex80, Tcomplex80,Tcomplex80, Tcomplex80)
|
||||
|
||||
#undef X
|
||||
|
||||
#define Y(t1,t2) impcnvWarn[t1][t2] = 1;
|
||||
|
||||
#if 0
|
||||
Y(Tint8, Tbit)
|
||||
Y(Tuns8, Tbit)
|
||||
Y(Tint16, Tbit)
|
||||
Y(Tuns16, Tbit)
|
||||
Y(Tint32, Tbit)
|
||||
Y(Tuns32, Tbit)
|
||||
Y(Tint64, Tbit)
|
||||
Y(Tuns64, Tbit)
|
||||
#endif
|
||||
|
||||
Y(Tuns8, Tint8)
|
||||
Y(Tint16, Tint8)
|
||||
Y(Tuns16, Tint8)
|
||||
Y(Tint32, Tint8)
|
||||
Y(Tuns32, Tint8)
|
||||
Y(Tint64, Tint8)
|
||||
Y(Tuns64, Tint8)
|
||||
|
||||
Y(Tint8, Tuns8)
|
||||
Y(Tint16, Tuns8)
|
||||
Y(Tuns16, Tuns8)
|
||||
Y(Tint32, Tuns8)
|
||||
Y(Tuns32, Tuns8)
|
||||
Y(Tint64, Tuns8)
|
||||
Y(Tuns64, Tuns8)
|
||||
|
||||
Y(Tint8, Tchar)
|
||||
Y(Tint16, Tchar)
|
||||
Y(Tuns16, Tchar)
|
||||
Y(Tint32, Tchar)
|
||||
Y(Tuns32, Tchar)
|
||||
Y(Tint64, Tchar)
|
||||
Y(Tuns64, Tchar)
|
||||
|
||||
Y(Tuns16, Tint16)
|
||||
Y(Tint32, Tint16)
|
||||
Y(Tuns32, Tint16)
|
||||
Y(Tint64, Tint16)
|
||||
Y(Tuns64, Tint16)
|
||||
|
||||
Y(Tint16, Tuns16)
|
||||
Y(Tint32, Tuns16)
|
||||
Y(Tuns32, Tuns16)
|
||||
Y(Tint64, Tuns16)
|
||||
Y(Tuns64, Tuns16)
|
||||
|
||||
Y(Tint16, Twchar)
|
||||
Y(Tint32, Twchar)
|
||||
Y(Tuns32, Twchar)
|
||||
Y(Tint64, Twchar)
|
||||
Y(Tuns64, Twchar)
|
||||
|
||||
// Y(Tuns32, Tint32)
|
||||
Y(Tint64, Tint32)
|
||||
Y(Tuns64, Tint32)
|
||||
|
||||
// Y(Tint32, Tuns32)
|
||||
Y(Tint64, Tuns32)
|
||||
Y(Tuns64, Tuns32)
|
||||
|
||||
Y(Tint64, Tdchar)
|
||||
Y(Tuns64, Tdchar)
|
||||
|
||||
// Y(Tint64, Tuns64)
|
||||
// Y(Tuns64, Tint64)
|
||||
|
||||
for (i = 0; i < TMAX; i++)
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{
|
||||
if (impcnvResult[i][j] == Terror)
|
||||
{
|
||||
impcnvResult[i][j] = impcnvResult[j][i];
|
||||
impcnvType1[i][j] = impcnvType2[j][i];
|
||||
impcnvType2[i][j] = impcnvType1[j][i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main()
|
||||
{ FILE *fp;
|
||||
int i;
|
||||
int j;
|
||||
|
||||
init();
|
||||
|
||||
fp = fopen("impcnvtab.c","w");
|
||||
|
||||
fprintf(fp,"// This file is generated by impcnvgen.c\n");
|
||||
fprintf(fp,"#include \"mtype.h\"\n");
|
||||
|
||||
fprintf(fp,"unsigned char Type::impcnvResult[TMAX][TMAX] =\n{\n");
|
||||
for (i = 0; i < TMAX; i++)
|
||||
{
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{
|
||||
fprintf(fp, "%d,",impcnvResult[i][j]);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
fprintf(fp,"};\n");
|
||||
|
||||
fprintf(fp,"unsigned char Type::impcnvType1[TMAX][TMAX] =\n{\n");
|
||||
for (i = 0; i < TMAX; i++)
|
||||
{
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{
|
||||
fprintf(fp, "%d,",impcnvType1[i][j]);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
fprintf(fp,"};\n");
|
||||
|
||||
fprintf(fp,"unsigned char Type::impcnvType2[TMAX][TMAX] =\n{\n");
|
||||
for (i = 0; i < TMAX; i++)
|
||||
{
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{
|
||||
fprintf(fp, "%d,",impcnvType2[i][j]);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
fprintf(fp,"};\n");
|
||||
|
||||
fprintf(fp,"unsigned char Type::impcnvWarn[TMAX][TMAX] =\n{\n");
|
||||
for (i = 0; i < TMAX; i++)
|
||||
{
|
||||
for (j = 0; j < TMAX; j++)
|
||||
{
|
||||
fprintf(fp, "%d,",impcnvWarn[i][j]);
|
||||
}
|
||||
fprintf(fp, "\n");
|
||||
}
|
||||
fprintf(fp,"};\n");
|
||||
|
||||
fclose(fp);
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
82
dmd2/imphint.c
Normal file
82
dmd2/imphint.c
Normal file
@@ -0,0 +1,82 @@
|
||||
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 2010 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 <ctype.h>
|
||||
#include <assert.h>
|
||||
#include <string.h>
|
||||
|
||||
/******************************************
|
||||
* Looks for undefined identifier s to see
|
||||
* if it might be undefined because an import
|
||||
* was not specified.
|
||||
* Not meant to be a comprehensive list of names in each module,
|
||||
* just the most common ones.
|
||||
*/
|
||||
|
||||
const char *importHint(const char *s)
|
||||
{
|
||||
#if DMDV1
|
||||
static const char *modules[] =
|
||||
{ "std.c.stdio",
|
||||
"std.stdio",
|
||||
"std.math",
|
||||
};
|
||||
static const char *names[] =
|
||||
{
|
||||
"printf", NULL,
|
||||
"writefln", NULL,
|
||||
"sin", "cos", "sqrt", "fabs", NULL,
|
||||
};
|
||||
#else
|
||||
static const char *modules[] =
|
||||
{ "core.stdc.stdio",
|
||||
"std.stdio",
|
||||
"std.math",
|
||||
};
|
||||
static const char *names[] =
|
||||
{
|
||||
"printf", NULL,
|
||||
"writeln", NULL,
|
||||
"sin", "cos", "sqrt", "fabs", NULL,
|
||||
};
|
||||
#endif
|
||||
int m = 0;
|
||||
for (int n = 0; n < sizeof(names)/sizeof(names[0]); n++)
|
||||
{
|
||||
const char *p = names[n];
|
||||
if (p == NULL)
|
||||
{ m++;
|
||||
continue;
|
||||
}
|
||||
assert(m < sizeof(modules)/sizeof(modules[0]));
|
||||
if (strcmp(s, p) == 0)
|
||||
return modules[m];
|
||||
}
|
||||
return NULL; // didn't find it
|
||||
}
|
||||
|
||||
#if UNITTEST
|
||||
|
||||
void unittest_importHint()
|
||||
{
|
||||
const char *p;
|
||||
|
||||
p = importHint("printf");
|
||||
assert(p);
|
||||
p = importHint("fabs");
|
||||
assert(p);
|
||||
p = importHint("xxxxx");
|
||||
assert(!p);
|
||||
}
|
||||
|
||||
#endif
|
||||
752
dmd2/import.c
752
dmd2/import.c
@@ -1,364 +1,388 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "dsymbol.h"
|
||||
#include "import.h"
|
||||
#include "identifier.h"
|
||||
#include "module.h"
|
||||
#include "scope.h"
|
||||
#include "hdrgen.h"
|
||||
#include "mtype.h"
|
||||
#include "declaration.h"
|
||||
#include "id.h"
|
||||
#include "attrib.h"
|
||||
|
||||
/********************************* Import ****************************/
|
||||
|
||||
Import::Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
|
||||
int isstatic)
|
||||
: Dsymbol(id)
|
||||
{
|
||||
assert(id);
|
||||
this->loc = loc;
|
||||
this->packages = packages;
|
||||
this->id = id;
|
||||
this->aliasId = aliasId;
|
||||
this->isstatic = isstatic;
|
||||
#if IN_LLVM
|
||||
protection = PROTundefined;
|
||||
#endif
|
||||
pkg = NULL;
|
||||
mod = NULL;
|
||||
|
||||
if (aliasId)
|
||||
this->ident = aliasId;
|
||||
// Kludge to change Import identifier to first package
|
||||
else if (packages && packages->dim)
|
||||
this->ident = (Identifier *)packages->data[0];
|
||||
}
|
||||
|
||||
void Import::addAlias(Identifier *name, Identifier *alias)
|
||||
{
|
||||
if (isstatic)
|
||||
error("cannot have an import bind list");
|
||||
|
||||
if (!aliasId)
|
||||
this->ident = NULL; // make it an anonymous import
|
||||
|
||||
names.push(name);
|
||||
aliases.push(alias);
|
||||
}
|
||||
|
||||
const char *Import::kind()
|
||||
{
|
||||
return isstatic ? (char *)"static import" : (char *)"import";
|
||||
}
|
||||
|
||||
#if IN_LLVM
|
||||
enum PROT Import::prot()
|
||||
{
|
||||
return protection;
|
||||
}
|
||||
#endif
|
||||
|
||||
Dsymbol *Import::syntaxCopy(Dsymbol *s)
|
||||
{
|
||||
assert(!s);
|
||||
|
||||
Import *si;
|
||||
|
||||
si = new Import(loc, packages, id, aliasId, isstatic);
|
||||
|
||||
for (size_t i = 0; i < names.dim; i++)
|
||||
{
|
||||
si->addAlias((Identifier *)names.data[i], (Identifier *)aliases.data[i]);
|
||||
}
|
||||
|
||||
return si;
|
||||
}
|
||||
|
||||
void Import::load(Scope *sc)
|
||||
{
|
||||
DsymbolTable *dst;
|
||||
Dsymbol *s;
|
||||
|
||||
//printf("Import::load('%s')\n", toChars());
|
||||
|
||||
// See if existing module
|
||||
dst = Package::resolve(packages, NULL, &pkg);
|
||||
|
||||
s = dst->lookup(id);
|
||||
if (s)
|
||||
{
|
||||
#if TARGET_NET
|
||||
mod = (Module *)s;
|
||||
#else
|
||||
if (s->isModule())
|
||||
mod = (Module *)s;
|
||||
else
|
||||
error("package and module have the same name");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!mod)
|
||||
{
|
||||
// Load module
|
||||
mod = Module::load(loc, packages, id);
|
||||
dst->insert(id, mod); // id may be different from mod->ident,
|
||||
// if so then insert alias
|
||||
if (!mod->importedFrom)
|
||||
mod->importedFrom = sc ? sc->module->importedFrom : Module::rootModule;
|
||||
}
|
||||
if (!pkg)
|
||||
pkg = mod;
|
||||
|
||||
//printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
|
||||
}
|
||||
|
||||
void escapePath(OutBuffer *buf, const char *fname)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
switch (*fname)
|
||||
{
|
||||
case 0:
|
||||
return;
|
||||
case '(':
|
||||
case ')':
|
||||
case '\\':
|
||||
buf->writebyte('\\');
|
||||
default:
|
||||
buf->writebyte(*fname);
|
||||
break;
|
||||
}
|
||||
fname++;
|
||||
}
|
||||
}
|
||||
|
||||
void Import::semantic(Scope *sc)
|
||||
{
|
||||
//printf("Import::semantic('%s')\n", toChars());
|
||||
|
||||
load(sc);
|
||||
|
||||
if (mod)
|
||||
{
|
||||
#if 0
|
||||
if (mod->loc.linnum != 0)
|
||||
{ /* If the line number is not 0, then this is not
|
||||
* a 'root' module, i.e. it was not specified on the command line.
|
||||
*/
|
||||
mod->importedFrom = sc->module->importedFrom;
|
||||
assert(mod->importedFrom);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Modules need a list of each imported module
|
||||
//printf("%s imports %s\n", sc->module->toChars(), mod->toChars());
|
||||
sc->module->aimports.push(mod);
|
||||
|
||||
if (!isstatic && !aliasId && !names.dim)
|
||||
{
|
||||
/* Default to private importing
|
||||
*/
|
||||
enum PROT prot = sc->protection;
|
||||
if (!sc->explicitProtection)
|
||||
prot = PROTprivate;
|
||||
sc->scopesym->importScope(mod, prot);
|
||||
}
|
||||
|
||||
mod->semantic();
|
||||
|
||||
if (mod->needmoduleinfo)
|
||||
sc->module->needmoduleinfo = 1;
|
||||
|
||||
sc = sc->push(mod);
|
||||
for (size_t i = 0; i < aliasdecls.dim; i++)
|
||||
{ AliasDeclaration *ad = (AliasDeclaration *)aliasdecls.data[i];
|
||||
|
||||
//printf("\tImport alias semantic('%s')\n", s->toChars());
|
||||
if (!mod->search(loc, (Identifier *)names.data[i], 0))
|
||||
error("%s not found", ((Identifier *)names.data[i])->toChars());
|
||||
|
||||
ad->importprot = protection;
|
||||
ad->semantic(sc);
|
||||
}
|
||||
sc = sc->pop();
|
||||
}
|
||||
|
||||
if (global.params.moduleDeps != NULL)
|
||||
{
|
||||
/* The grammar of the file is:
|
||||
* ImportDeclaration
|
||||
* ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> "
|
||||
* ModuleAliasIdentifier ] "\n"
|
||||
*
|
||||
* BasicImportDeclaration
|
||||
* ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection
|
||||
* " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
|
||||
*
|
||||
* FilePath
|
||||
* - any string with '(', ')' and '\' escaped with the '\' character
|
||||
*/
|
||||
|
||||
OutBuffer *ob = global.params.moduleDeps;
|
||||
|
||||
ob->writestring(sc->module->toPrettyChars());
|
||||
ob->writestring(" (");
|
||||
escapePath(ob, sc->module->srcfile->toChars());
|
||||
ob->writestring(") : ");
|
||||
|
||||
ProtDeclaration::protectionToCBuffer(ob, sc->protection);
|
||||
if (isstatic)
|
||||
StorageClassDeclaration::stcToCBuffer(ob, STCstatic);
|
||||
ob->writestring(": ");
|
||||
|
||||
if (packages)
|
||||
{
|
||||
for (size_t i = 0; i < packages->dim; i++)
|
||||
{
|
||||
Identifier *pid = (Identifier *)packages->data[i];
|
||||
ob->printf("%s.", pid->toChars());
|
||||
}
|
||||
}
|
||||
|
||||
ob->writestring(id->toChars());
|
||||
ob->writestring(" (");
|
||||
if (mod)
|
||||
escapePath(ob, mod->srcfile->toChars());
|
||||
else
|
||||
ob->writestring("???");
|
||||
ob->writebyte(')');
|
||||
|
||||
for (size_t i = 0; i < names.dim; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
ob->writebyte(':');
|
||||
else
|
||||
ob->writebyte(',');
|
||||
|
||||
Identifier *name = (Identifier *)names.data[i];
|
||||
Identifier *alias = (Identifier *)aliases.data[i];
|
||||
|
||||
if (!alias)
|
||||
{
|
||||
ob->printf("%s", name->toChars());
|
||||
alias = name;
|
||||
}
|
||||
else
|
||||
ob->printf("%s=%s", alias->toChars(), name->toChars());
|
||||
}
|
||||
|
||||
if (aliasId)
|
||||
ob->printf(" -> %s", aliasId->toChars());
|
||||
|
||||
ob->writenl();
|
||||
}
|
||||
|
||||
//printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
|
||||
}
|
||||
|
||||
void Import::semantic2(Scope *sc)
|
||||
{
|
||||
//printf("Import::semantic2('%s')\n", toChars());
|
||||
mod->semantic2();
|
||||
if (mod->needmoduleinfo)
|
||||
sc->module->needmoduleinfo = 1;
|
||||
}
|
||||
|
||||
Dsymbol *Import::toAlias()
|
||||
{
|
||||
if (aliasId)
|
||||
return mod;
|
||||
return this;
|
||||
}
|
||||
|
||||
/*****************************
|
||||
* Add import to sd's symbol table.
|
||||
*/
|
||||
|
||||
int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (names.dim == 0)
|
||||
return Dsymbol::addMember(sc, sd, memnum);
|
||||
|
||||
if (aliasId)
|
||||
result = Dsymbol::addMember(sc, sd, memnum);
|
||||
|
||||
/* Instead of adding the import to sd's symbol table,
|
||||
* add each of the alias=name pairs
|
||||
*/
|
||||
for (size_t i = 0; i < names.dim; i++)
|
||||
{
|
||||
Identifier *name = (Identifier *)names.data[i];
|
||||
Identifier *alias = (Identifier *)aliases.data[i];
|
||||
|
||||
if (!alias)
|
||||
alias = name;
|
||||
|
||||
TypeIdentifier *tname = new TypeIdentifier(loc, name);
|
||||
AliasDeclaration *ad = new AliasDeclaration(loc, alias, tname);
|
||||
result |= ad->addMember(sc, sd, memnum);
|
||||
|
||||
aliasdecls.push(ad);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Dsymbol *Import::search(Loc loc, Identifier *ident, int flags)
|
||||
{
|
||||
//printf("%s.Import::search(ident = '%s', flags = x%x)\n", toChars(), ident->toChars(), flags);
|
||||
|
||||
if (!pkg)
|
||||
{ load(NULL);
|
||||
mod->semantic();
|
||||
}
|
||||
|
||||
// Forward it to the package/module
|
||||
return pkg->search(loc, ident, flags);
|
||||
}
|
||||
|
||||
int Import::overloadInsert(Dsymbol *s)
|
||||
{
|
||||
// Allow multiple imports of the same name
|
||||
return s->isImport() != NULL;
|
||||
}
|
||||
|
||||
void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (hgs->hdrgen && id == Id::object)
|
||||
return; // object is imported by default
|
||||
|
||||
if (isstatic)
|
||||
buf->writestring("static ");
|
||||
buf->writestring("import ");
|
||||
if (aliasId)
|
||||
{
|
||||
buf->printf("%s = ", aliasId->toChars());
|
||||
}
|
||||
if (packages && packages->dim)
|
||||
{
|
||||
for (size_t i = 0; i < packages->dim; i++)
|
||||
{ Identifier *pid = (Identifier *)packages->data[i];
|
||||
|
||||
buf->printf("%s.", pid->toChars());
|
||||
}
|
||||
}
|
||||
buf->printf("%s;", id->toChars());
|
||||
buf->writenl();
|
||||
}
|
||||
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "dsymbol.h"
|
||||
#include "import.h"
|
||||
#include "identifier.h"
|
||||
#include "module.h"
|
||||
#include "scope.h"
|
||||
#include "hdrgen.h"
|
||||
#include "mtype.h"
|
||||
#include "declaration.h"
|
||||
#include "id.h"
|
||||
#include "attrib.h"
|
||||
|
||||
/********************************* Import ****************************/
|
||||
|
||||
Import::Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
|
||||
int isstatic)
|
||||
: Dsymbol(id)
|
||||
{
|
||||
assert(id);
|
||||
this->loc = loc;
|
||||
this->packages = packages;
|
||||
this->id = id;
|
||||
this->aliasId = aliasId;
|
||||
this->isstatic = isstatic;
|
||||
#if IN_LLVM
|
||||
protection = PROTundefined;
|
||||
#endif
|
||||
pkg = NULL;
|
||||
mod = NULL;
|
||||
|
||||
if (aliasId)
|
||||
this->ident = aliasId;
|
||||
// Kludge to change Import identifier to first package
|
||||
else if (packages && packages->dim)
|
||||
this->ident = (Identifier *)packages->data[0];
|
||||
}
|
||||
|
||||
void Import::addAlias(Identifier *name, Identifier *alias)
|
||||
{
|
||||
if (isstatic)
|
||||
error("cannot have an import bind list");
|
||||
|
||||
if (!aliasId)
|
||||
this->ident = NULL; // make it an anonymous import
|
||||
|
||||
names.push(name);
|
||||
aliases.push(alias);
|
||||
}
|
||||
|
||||
const char *Import::kind()
|
||||
{
|
||||
return isstatic ? (char *)"static import" : (char *)"import";
|
||||
}
|
||||
|
||||
#if IN_LLVM
|
||||
enum PROT Import::prot()
|
||||
{
|
||||
return protection;
|
||||
}
|
||||
#endif
|
||||
|
||||
Dsymbol *Import::syntaxCopy(Dsymbol *s)
|
||||
{
|
||||
assert(!s);
|
||||
|
||||
Import *si;
|
||||
|
||||
si = new Import(loc, packages, id, aliasId, isstatic);
|
||||
|
||||
for (size_t i = 0; i < names.dim; i++)
|
||||
{
|
||||
si->addAlias((Identifier *)names.data[i], (Identifier *)aliases.data[i]);
|
||||
}
|
||||
|
||||
return si;
|
||||
}
|
||||
|
||||
void Import::load(Scope *sc)
|
||||
{
|
||||
//printf("Import::load('%s')\n", toChars());
|
||||
|
||||
// See if existing module
|
||||
DsymbolTable *dst = Package::resolve(packages, NULL, &pkg);
|
||||
|
||||
Dsymbol *s = dst->lookup(id);
|
||||
if (s)
|
||||
{
|
||||
#if TARGET_NET
|
||||
mod = (Module *)s;
|
||||
#else
|
||||
if (s->isModule())
|
||||
mod = (Module *)s;
|
||||
else
|
||||
error("package and module have the same name");
|
||||
#endif
|
||||
}
|
||||
|
||||
if (!mod)
|
||||
{
|
||||
// Load module
|
||||
mod = Module::load(loc, packages, id);
|
||||
dst->insert(id, mod); // id may be different from mod->ident,
|
||||
// if so then insert alias
|
||||
if (!mod->importedFrom)
|
||||
mod->importedFrom = sc ? sc->module->importedFrom : Module::rootModule;
|
||||
}
|
||||
if (!pkg)
|
||||
pkg = mod;
|
||||
|
||||
//printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
|
||||
}
|
||||
|
||||
void escapePath(OutBuffer *buf, const char *fname)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
switch (*fname)
|
||||
{
|
||||
case 0:
|
||||
return;
|
||||
case '(':
|
||||
case ')':
|
||||
case '\\':
|
||||
buf->writebyte('\\');
|
||||
default:
|
||||
buf->writebyte(*fname);
|
||||
break;
|
||||
}
|
||||
fname++;
|
||||
}
|
||||
}
|
||||
|
||||
void Import::importAll(Scope *sc)
|
||||
{
|
||||
if (!mod)
|
||||
{
|
||||
load(sc);
|
||||
mod->importAll(0);
|
||||
|
||||
if (!isstatic && !aliasId && !names.dim)
|
||||
{
|
||||
/* Default to private importing
|
||||
*/
|
||||
enum PROT prot = sc->protection;
|
||||
if (!sc->explicitProtection)
|
||||
prot = PROTprivate;
|
||||
sc->scopesym->importScope(mod, prot);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Import::semantic(Scope *sc)
|
||||
{
|
||||
//printf("Import::semantic('%s')\n", toChars());
|
||||
|
||||
// Load if not already done so
|
||||
if (!mod)
|
||||
{ load(sc);
|
||||
mod->importAll(0);
|
||||
}
|
||||
|
||||
if (mod)
|
||||
{
|
||||
#if 0
|
||||
if (mod->loc.linnum != 0)
|
||||
{ /* If the line number is not 0, then this is not
|
||||
* a 'root' module, i.e. it was not specified on the command line.
|
||||
*/
|
||||
mod->importedFrom = sc->module->importedFrom;
|
||||
assert(mod->importedFrom);
|
||||
}
|
||||
#endif
|
||||
|
||||
// Modules need a list of each imported module
|
||||
//printf("%s imports %s\n", sc->module->toChars(), mod->toChars());
|
||||
sc->module->aimports.push(mod);
|
||||
|
||||
if (!isstatic && !aliasId && !names.dim)
|
||||
{
|
||||
/* Default to private importing
|
||||
*/
|
||||
enum PROT prot = sc->protection;
|
||||
if (!sc->explicitProtection)
|
||||
prot = PROTprivate;
|
||||
sc->scopesym->importScope(mod, prot);
|
||||
}
|
||||
|
||||
mod->semantic();
|
||||
|
||||
if (mod->needmoduleinfo)
|
||||
{ //printf("module4 %s because of %s\n", sc->module->toChars(), mod->toChars());
|
||||
sc->module->needmoduleinfo = 1;
|
||||
}
|
||||
|
||||
sc = sc->push(mod);
|
||||
for (size_t i = 0; i < aliasdecls.dim; i++)
|
||||
{ AliasDeclaration *ad = (AliasDeclaration *)aliasdecls.data[i];
|
||||
|
||||
//printf("\tImport alias semantic('%s')\n", s->toChars());
|
||||
if (!mod->search(loc, (Identifier *)names.data[i], 0))
|
||||
error("%s not found", ((Identifier *)names.data[i])->toChars());
|
||||
|
||||
ad->importprot = protection;
|
||||
ad->semantic(sc);
|
||||
}
|
||||
sc = sc->pop();
|
||||
}
|
||||
|
||||
if (global.params.moduleDeps != NULL)
|
||||
{
|
||||
/* The grammar of the file is:
|
||||
* ImportDeclaration
|
||||
* ::= BasicImportDeclaration [ " : " ImportBindList ] [ " -> "
|
||||
* ModuleAliasIdentifier ] "\n"
|
||||
*
|
||||
* BasicImportDeclaration
|
||||
* ::= ModuleFullyQualifiedName " (" FilePath ") : " Protection
|
||||
* " [ " static" ] : " ModuleFullyQualifiedName " (" FilePath ")"
|
||||
*
|
||||
* FilePath
|
||||
* - any string with '(', ')' and '\' escaped with the '\' character
|
||||
*/
|
||||
|
||||
OutBuffer *ob = global.params.moduleDeps;
|
||||
|
||||
ob->writestring(sc->module->toPrettyChars());
|
||||
ob->writestring(" (");
|
||||
escapePath(ob, sc->module->srcfile->toChars());
|
||||
ob->writestring(") : ");
|
||||
|
||||
ProtDeclaration::protectionToCBuffer(ob, sc->protection);
|
||||
if (isstatic)
|
||||
StorageClassDeclaration::stcToCBuffer(ob, STCstatic);
|
||||
ob->writestring(": ");
|
||||
|
||||
if (packages)
|
||||
{
|
||||
for (size_t i = 0; i < packages->dim; i++)
|
||||
{
|
||||
Identifier *pid = (Identifier *)packages->data[i];
|
||||
ob->printf("%s.", pid->toChars());
|
||||
}
|
||||
}
|
||||
|
||||
ob->writestring(id->toChars());
|
||||
ob->writestring(" (");
|
||||
if (mod)
|
||||
escapePath(ob, mod->srcfile->toChars());
|
||||
else
|
||||
ob->writestring("???");
|
||||
ob->writebyte(')');
|
||||
|
||||
for (size_t i = 0; i < names.dim; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
ob->writebyte(':');
|
||||
else
|
||||
ob->writebyte(',');
|
||||
|
||||
Identifier *name = (Identifier *)names.data[i];
|
||||
Identifier *alias = (Identifier *)aliases.data[i];
|
||||
|
||||
if (!alias)
|
||||
{
|
||||
ob->printf("%s", name->toChars());
|
||||
alias = name;
|
||||
}
|
||||
else
|
||||
ob->printf("%s=%s", alias->toChars(), name->toChars());
|
||||
}
|
||||
|
||||
if (aliasId)
|
||||
ob->printf(" -> %s", aliasId->toChars());
|
||||
|
||||
ob->writenl();
|
||||
}
|
||||
|
||||
//printf("-Import::semantic('%s'), pkg = %p\n", toChars(), pkg);
|
||||
}
|
||||
|
||||
void Import::semantic2(Scope *sc)
|
||||
{
|
||||
//printf("Import::semantic2('%s')\n", toChars());
|
||||
mod->semantic2();
|
||||
if (mod->needmoduleinfo)
|
||||
{ //printf("module5 %s because of %s\n", sc->module->toChars(), mod->toChars());
|
||||
sc->module->needmoduleinfo = 1;
|
||||
}
|
||||
}
|
||||
|
||||
Dsymbol *Import::toAlias()
|
||||
{
|
||||
if (aliasId)
|
||||
return mod;
|
||||
return this;
|
||||
}
|
||||
|
||||
/*****************************
|
||||
* Add import to sd's symbol table.
|
||||
*/
|
||||
|
||||
int Import::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
|
||||
{
|
||||
int result = 0;
|
||||
|
||||
if (names.dim == 0)
|
||||
return Dsymbol::addMember(sc, sd, memnum);
|
||||
|
||||
if (aliasId)
|
||||
result = Dsymbol::addMember(sc, sd, memnum);
|
||||
|
||||
/* Instead of adding the import to sd's symbol table,
|
||||
* add each of the alias=name pairs
|
||||
*/
|
||||
for (size_t i = 0; i < names.dim; i++)
|
||||
{
|
||||
Identifier *name = (Identifier *)names.data[i];
|
||||
Identifier *alias = (Identifier *)aliases.data[i];
|
||||
|
||||
if (!alias)
|
||||
alias = name;
|
||||
|
||||
TypeIdentifier *tname = new TypeIdentifier(loc, name);
|
||||
AliasDeclaration *ad = new AliasDeclaration(loc, alias, tname);
|
||||
result |= ad->addMember(sc, sd, memnum);
|
||||
|
||||
aliasdecls.push(ad);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
Dsymbol *Import::search(Loc loc, Identifier *ident, int flags)
|
||||
{
|
||||
//printf("%s.Import::search(ident = '%s', flags = x%x)\n", toChars(), ident->toChars(), flags);
|
||||
|
||||
if (!pkg)
|
||||
{ load(NULL);
|
||||
mod->semantic();
|
||||
}
|
||||
|
||||
// Forward it to the package/module
|
||||
return pkg->search(loc, ident, flags);
|
||||
}
|
||||
|
||||
int Import::overloadInsert(Dsymbol *s)
|
||||
{
|
||||
// Allow multiple imports of the same name
|
||||
return s->isImport() != NULL;
|
||||
}
|
||||
|
||||
void Import::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
if (hgs->hdrgen && id == Id::object)
|
||||
return; // object is imported by default
|
||||
|
||||
if (isstatic)
|
||||
buf->writestring("static ");
|
||||
buf->writestring("import ");
|
||||
if (aliasId)
|
||||
{
|
||||
buf->printf("%s = ", aliasId->toChars());
|
||||
}
|
||||
if (packages && packages->dim)
|
||||
{
|
||||
for (size_t i = 0; i < packages->dim; i++)
|
||||
{ Identifier *pid = (Identifier *)packages->data[i];
|
||||
|
||||
buf->printf("%s.", pid->toChars());
|
||||
}
|
||||
}
|
||||
buf->printf("%s;", id->toChars());
|
||||
buf->writenl();
|
||||
}
|
||||
|
||||
|
||||
143
dmd2/import.h
143
dmd2/import.h
@@ -1,71 +1,72 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 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_IMPORT_H
|
||||
#define DMD_IMPORT_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "dsymbol.h"
|
||||
|
||||
|
||||
struct Identifier;
|
||||
struct Scope;
|
||||
struct OutBuffer;
|
||||
struct Module;
|
||||
struct Package;
|
||||
struct AliasDeclaration;
|
||||
#ifdef _DH
|
||||
struct HdrGenState;
|
||||
#endif
|
||||
|
||||
struct Import : Dsymbol
|
||||
{
|
||||
Array *packages; // array of Identifier's representing packages
|
||||
Identifier *id; // module Identifier
|
||||
Identifier *aliasId;
|
||||
int isstatic; // !=0 if static import
|
||||
#if IN_LLVM
|
||||
enum PROT protection;
|
||||
#endif
|
||||
|
||||
// Pairs of alias=name to bind into current namespace
|
||||
Array names;
|
||||
Array aliases;
|
||||
|
||||
Array aliasdecls; // AliasDeclarations for names/aliases
|
||||
|
||||
Module *mod;
|
||||
Package *pkg; // leftmost package/module
|
||||
|
||||
Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
|
||||
int isstatic);
|
||||
void addAlias(Identifier *name, Identifier *alias);
|
||||
|
||||
const char *kind();
|
||||
#if IN_LLVM
|
||||
enum PROT prot();
|
||||
#endif
|
||||
Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
|
||||
void load(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
Dsymbol *toAlias();
|
||||
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
int overloadInsert(Dsymbol *s);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
Import *isImport() { return this; }
|
||||
};
|
||||
|
||||
#endif /* DMD_IMPORT_H */
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 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_IMPORT_H
|
||||
#define DMD_IMPORT_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "dsymbol.h"
|
||||
|
||||
|
||||
struct Identifier;
|
||||
struct Scope;
|
||||
struct OutBuffer;
|
||||
struct Module;
|
||||
struct Package;
|
||||
struct AliasDeclaration;
|
||||
#ifdef _DH
|
||||
struct HdrGenState;
|
||||
#endif
|
||||
|
||||
struct Import : Dsymbol
|
||||
{
|
||||
Array *packages; // array of Identifier's representing packages
|
||||
Identifier *id; // module Identifier
|
||||
Identifier *aliasId;
|
||||
int isstatic; // !=0 if static import
|
||||
#if IN_LLVM
|
||||
enum PROT protection;
|
||||
#endif
|
||||
|
||||
// Pairs of alias=name to bind into current namespace
|
||||
Array names;
|
||||
Array aliases;
|
||||
|
||||
Array aliasdecls; // AliasDeclarations for names/aliases
|
||||
|
||||
Module *mod;
|
||||
Package *pkg; // leftmost package/module
|
||||
|
||||
Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
|
||||
int isstatic);
|
||||
void addAlias(Identifier *name, Identifier *alias);
|
||||
|
||||
const char *kind();
|
||||
#if IN_LLVM
|
||||
enum PROT prot();
|
||||
#endif
|
||||
Dsymbol *syntaxCopy(Dsymbol *s); // copy only syntax trees
|
||||
void load(Scope *sc);
|
||||
void importAll(Scope *sc);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
Dsymbol *toAlias();
|
||||
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
|
||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
int overloadInsert(Dsymbol *s);
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
Import *isImport() { return this; }
|
||||
};
|
||||
|
||||
#endif /* DMD_IMPORT_H */
|
||||
|
||||
662
dmd2/inifile.c
662
dmd2/inifile.c
@@ -1,329 +1,333 @@
|
||||
/*
|
||||
* Some portions copyright (c) 1994-1995 by Symantec
|
||||
* Copyright (c) 1999-2009 by Digital Mars
|
||||
* All Rights Reserved
|
||||
* http://www.digitalmars.com
|
||||
* Written by Walter Bright
|
||||
*
|
||||
* This source file is made available for personal use
|
||||
* only. The license is in /dmd/src/dmd/backendlicense.txt
|
||||
* For any other uses, please contact Digital Mars.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if __APPLE__
|
||||
#include <sys/syslimits.h>
|
||||
#endif
|
||||
#if __FreeBSD__ || __sun&&__SVR4
|
||||
// for PATH_MAX
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#if __sun&&__SVR4
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include "root.h"
|
||||
#include "rmem.h"
|
||||
|
||||
#define LOG 0
|
||||
|
||||
char *skipspace(const char *p);
|
||||
|
||||
#if __GNUC__
|
||||
char *strupr(char *s)
|
||||
{
|
||||
char *t = s;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
*s = toupper(*s);
|
||||
s++;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
#endif /* unix */
|
||||
|
||||
/*****************************
|
||||
* Read and analyze .ini file.
|
||||
* Input:
|
||||
* argv0 program name (argv[0])
|
||||
* inifile .ini file name
|
||||
*/
|
||||
|
||||
void inifile(const char *argv0x, const char *inifilex)
|
||||
{
|
||||
char *argv0 = (char *)argv0x;
|
||||
char *inifile = (char *)inifilex; // do const-correct later
|
||||
char *path; // need path for @P macro
|
||||
char *filename;
|
||||
OutBuffer buf;
|
||||
int i;
|
||||
int k;
|
||||
int envsection = 0;
|
||||
|
||||
#if LOG
|
||||
printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile);
|
||||
#endif
|
||||
if (FileName::absolute(inifile))
|
||||
{
|
||||
filename = inifile;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Look for inifile in the following sequence of places:
|
||||
* o current directory
|
||||
* o home directory
|
||||
* o directory off of argv0
|
||||
* o /etc/
|
||||
*/
|
||||
if (FileName::exists(inifile))
|
||||
{
|
||||
filename = inifile;
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = FileName::combine(getenv("HOME"), inifile);
|
||||
if (!FileName::exists(filename))
|
||||
{
|
||||
#if _WIN32 // This fix by Tim Matthews
|
||||
char resolved_name[MAX_PATH + 1];
|
||||
if(GetModuleFileName(NULL, resolved_name, MAX_PATH + 1) && FileName::exists(resolved_name))
|
||||
{
|
||||
filename = (char *)FileName::replaceName(resolved_name, inifile);
|
||||
if(FileName::exists(filename))
|
||||
goto Ldone;
|
||||
}
|
||||
#endif
|
||||
filename = (char *)FileName::replaceName(argv0, inifile);
|
||||
if (!FileName::exists(filename))
|
||||
{
|
||||
#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
|
||||
#if __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 // This fix by Thomas Kuehne
|
||||
/* argv0 might be a symbolic link,
|
||||
* so try again looking past it to the real path
|
||||
*/
|
||||
#if __APPLE__ || __FreeBSD__ || __sun&&__SVR4
|
||||
char resolved_name[PATH_MAX + 1];
|
||||
char* real_argv0 = realpath(argv0, resolved_name);
|
||||
#else
|
||||
char* real_argv0 = realpath(argv0, NULL);
|
||||
#endif
|
||||
//printf("argv0 = %s, real_argv0 = %p\n", argv0, real_argv0);
|
||||
if (real_argv0)
|
||||
{
|
||||
filename = (char *)FileName::replaceName(real_argv0, inifile);
|
||||
#if !(__APPLE__ || __FreeBSD__ || __sun&&__SVR4)
|
||||
free(real_argv0);
|
||||
#endif
|
||||
if (FileName::exists(filename))
|
||||
goto Ldone;
|
||||
}
|
||||
#else
|
||||
#error use of glibc non-standard extension realpath(char*, NULL)
|
||||
#endif
|
||||
if (1){
|
||||
// Search PATH for argv0
|
||||
const char *p = getenv("PATH");
|
||||
Array *paths = FileName::splitPath(p);
|
||||
filename = FileName::searchPath(paths, argv0, 0);
|
||||
if (!filename)
|
||||
goto Letc; // argv0 not found on path
|
||||
filename = (char *)FileName::replaceName(filename, inifile);
|
||||
if (FileName::exists(filename))
|
||||
goto Ldone;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Search /etc/ for inifile
|
||||
Letc:
|
||||
filename = FileName::combine((char *)"/etc/", inifile);
|
||||
|
||||
Ldone:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
path = FileName::path(filename);
|
||||
#if LOG
|
||||
printf("\tpath = '%s', filename = '%s'\n", path, filename);
|
||||
#endif
|
||||
|
||||
File file(filename);
|
||||
|
||||
if (file.read())
|
||||
return; // error reading file
|
||||
|
||||
// Parse into lines
|
||||
int eof = 0;
|
||||
for (i = 0; i < file.len && !eof; i++)
|
||||
{
|
||||
int linestart = i;
|
||||
|
||||
for (; i < file.len; i++)
|
||||
{
|
||||
switch (file.buffer[i])
|
||||
{
|
||||
case '\r':
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
// Skip if it was preceded by '\r'
|
||||
if (i && file.buffer[i - 1] == '\r')
|
||||
goto Lskip;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
case 0x1A:
|
||||
eof = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// The line is file.buffer[linestart..i]
|
||||
char *line;
|
||||
int len;
|
||||
char *p;
|
||||
char *pn;
|
||||
|
||||
line = (char *)&file.buffer[linestart];
|
||||
len = i - linestart;
|
||||
|
||||
buf.reset();
|
||||
|
||||
// First, expand the macros.
|
||||
// Macros are bracketed by % characters.
|
||||
|
||||
for (k = 0; k < len; k++)
|
||||
{
|
||||
if (line[k] == '%')
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = k + 1; j < len; j++)
|
||||
{
|
||||
if (line[j] == '%')
|
||||
{
|
||||
if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0)
|
||||
{
|
||||
// %@P% is special meaning the path to the .ini file
|
||||
p = path;
|
||||
if (!*p)
|
||||
p = (char *)".";
|
||||
}
|
||||
else
|
||||
{ int len = j - k;
|
||||
char tmp[10]; // big enough most of the time
|
||||
|
||||
if (len <= sizeof(tmp))
|
||||
p = tmp;
|
||||
else
|
||||
p = (char *)alloca(len);
|
||||
len--;
|
||||
memcpy(p, &line[k + 1], len);
|
||||
p[len] = 0;
|
||||
strupr(p);
|
||||
p = getenv(p);
|
||||
if (!p)
|
||||
p = (char *)"";
|
||||
}
|
||||
buf.writestring(p);
|
||||
k = j;
|
||||
goto L1;
|
||||
}
|
||||
}
|
||||
}
|
||||
buf.writeByte(line[k]);
|
||||
L1:
|
||||
;
|
||||
}
|
||||
|
||||
// Remove trailing spaces
|
||||
while (buf.offset && isspace(buf.data[buf.offset - 1]))
|
||||
buf.offset--;
|
||||
|
||||
p = buf.toChars();
|
||||
|
||||
// The expanded line is in p.
|
||||
// Now parse it for meaning.
|
||||
|
||||
p = skipspace(p);
|
||||
switch (*p)
|
||||
{
|
||||
case ';': // comment
|
||||
case 0: // blank
|
||||
break;
|
||||
|
||||
case '[': // look for [Environment]
|
||||
p = skipspace(p + 1);
|
||||
for (pn = p; isalnum(*pn); pn++)
|
||||
;
|
||||
if (pn - p == 11 &&
|
||||
memicmp(p, "Environment", 11) == 0 &&
|
||||
*skipspace(pn) == ']'
|
||||
)
|
||||
envsection = 1;
|
||||
else
|
||||
envsection = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (envsection)
|
||||
{
|
||||
pn = p;
|
||||
|
||||
// Convert name to upper case;
|
||||
// remove spaces bracketing =
|
||||
for (p = pn; *p; p++)
|
||||
{ if (islower(*p))
|
||||
*p &= ~0x20;
|
||||
else if (isspace(*p))
|
||||
memmove(p, p + 1, strlen(p));
|
||||
else if (*p == '=')
|
||||
{
|
||||
p++;
|
||||
while (isspace(*p))
|
||||
memmove(p, p + 1, strlen(p));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
putenv(strdup(pn));
|
||||
#if LOG
|
||||
printf("\tputenv('%s')\n", pn);
|
||||
//printf("getenv(\"TEST\") = '%s'\n",getenv("TEST"));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Lskip:
|
||||
;
|
||||
}
|
||||
}
|
||||
|
||||
/********************
|
||||
* Skip spaces.
|
||||
*/
|
||||
|
||||
char *skipspace(const char *p)
|
||||
{
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
return (char *)p;
|
||||
}
|
||||
|
||||
/*
|
||||
* Some portions copyright (c) 1994-1995 by Symantec
|
||||
* Copyright (c) 1999-2009 by Digital Mars
|
||||
* All Rights Reserved
|
||||
* http://www.digitalmars.com
|
||||
* Written by Walter Bright
|
||||
*
|
||||
* This source file is made available for personal use
|
||||
* only. The license is in /dmd/src/dmd/backendlicense.txt
|
||||
* For any other uses, please contact Digital Mars.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#if __APPLE__
|
||||
#include <sys/syslimits.h>
|
||||
#endif
|
||||
#if __FreeBSD__ || __sun&&__SVR4
|
||||
// for PATH_MAX
|
||||
#include <limits.h>
|
||||
#endif
|
||||
|
||||
#if __sun&&__SVR4
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#include "root.h"
|
||||
#include "rmem.h"
|
||||
|
||||
#define LOG 0
|
||||
|
||||
char *skipspace(const char *p);
|
||||
|
||||
#if __GNUC__
|
||||
char *strupr(char *s)
|
||||
{
|
||||
char *t = s;
|
||||
|
||||
while (*s)
|
||||
{
|
||||
*s = toupper(*s);
|
||||
s++;
|
||||
}
|
||||
|
||||
return t;
|
||||
}
|
||||
#endif /* unix */
|
||||
|
||||
/*****************************
|
||||
* Read and analyze .ini file.
|
||||
* Input:
|
||||
* argv0 program name (argv[0])
|
||||
* inifile .ini file name
|
||||
* Returns:
|
||||
* file name of ini file
|
||||
* Note: this is a memory leak
|
||||
*/
|
||||
|
||||
const char *inifile(const char *argv0x, const char *inifilex)
|
||||
{
|
||||
char *argv0 = (char *)argv0x;
|
||||
char *inifile = (char *)inifilex; // do const-correct later
|
||||
char *path; // need path for @P macro
|
||||
char *filename;
|
||||
OutBuffer buf;
|
||||
int i;
|
||||
int k;
|
||||
int envsection = 0;
|
||||
|
||||
#if LOG
|
||||
printf("inifile(argv0 = '%s', inifile = '%s')\n", argv0, inifile);
|
||||
#endif
|
||||
if (FileName::absolute(inifile))
|
||||
{
|
||||
filename = inifile;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Look for inifile in the following sequence of places:
|
||||
* o current directory
|
||||
* o home directory
|
||||
* o directory off of argv0
|
||||
* o /etc/
|
||||
*/
|
||||
if (FileName::exists(inifile))
|
||||
{
|
||||
filename = inifile;
|
||||
}
|
||||
else
|
||||
{
|
||||
filename = FileName::combine(getenv("HOME"), inifile);
|
||||
if (!FileName::exists(filename))
|
||||
{
|
||||
#if _WIN32 // This fix by Tim Matthews
|
||||
char resolved_name[MAX_PATH + 1];
|
||||
if(GetModuleFileName(NULL, resolved_name, MAX_PATH + 1) && FileName::exists(resolved_name))
|
||||
{
|
||||
filename = (char *)FileName::replaceName(resolved_name, inifile);
|
||||
if(FileName::exists(filename))
|
||||
goto Ldone;
|
||||
}
|
||||
#endif
|
||||
filename = (char *)FileName::replaceName(argv0, inifile);
|
||||
if (!FileName::exists(filename))
|
||||
{
|
||||
#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
|
||||
#if __GLIBC__ || __APPLE__ || __FreeBSD__ || __sun&&__SVR4 // This fix by Thomas Kuehne
|
||||
/* argv0 might be a symbolic link,
|
||||
* so try again looking past it to the real path
|
||||
*/
|
||||
#if __APPLE__ || __FreeBSD__ || __sun&&__SVR4
|
||||
char resolved_name[PATH_MAX + 1];
|
||||
char* real_argv0 = realpath(argv0, resolved_name);
|
||||
#else
|
||||
char* real_argv0 = realpath(argv0, NULL);
|
||||
#endif
|
||||
//printf("argv0 = %s, real_argv0 = %p\n", argv0, real_argv0);
|
||||
if (real_argv0)
|
||||
{
|
||||
filename = (char *)FileName::replaceName(real_argv0, inifile);
|
||||
#if !(__APPLE__ || __FreeBSD__ || __sun&&__SVR4)
|
||||
free(real_argv0);
|
||||
#endif
|
||||
if (FileName::exists(filename))
|
||||
goto Ldone;
|
||||
}
|
||||
#else
|
||||
#error use of glibc non-standard extension realpath(char*, NULL)
|
||||
#endif
|
||||
if (1){
|
||||
// Search PATH for argv0
|
||||
const char *p = getenv("PATH");
|
||||
Array *paths = FileName::splitPath(p);
|
||||
filename = FileName::searchPath(paths, argv0, 0);
|
||||
if (!filename)
|
||||
goto Letc; // argv0 not found on path
|
||||
filename = (char *)FileName::replaceName(filename, inifile);
|
||||
if (FileName::exists(filename))
|
||||
goto Ldone;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Search /etc/ for inifile
|
||||
Letc:
|
||||
filename = FileName::combine((char *)"/etc/", inifile);
|
||||
|
||||
Ldone:
|
||||
;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
path = FileName::path(filename);
|
||||
#if LOG
|
||||
printf("\tpath = '%s', filename = '%s'\n", path, filename);
|
||||
#endif
|
||||
|
||||
File file(filename);
|
||||
|
||||
if (file.read())
|
||||
return filename; // error reading file
|
||||
|
||||
// Parse into lines
|
||||
int eof = 0;
|
||||
for (i = 0; i < file.len && !eof; i++)
|
||||
{
|
||||
int linestart = i;
|
||||
|
||||
for (; i < file.len; i++)
|
||||
{
|
||||
switch (file.buffer[i])
|
||||
{
|
||||
case '\r':
|
||||
break;
|
||||
|
||||
case '\n':
|
||||
// Skip if it was preceded by '\r'
|
||||
if (i && file.buffer[i - 1] == '\r')
|
||||
goto Lskip;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
case 0x1A:
|
||||
eof = 1;
|
||||
break;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
// The line is file.buffer[linestart..i]
|
||||
char *line;
|
||||
int len;
|
||||
char *p;
|
||||
char *pn;
|
||||
|
||||
line = (char *)&file.buffer[linestart];
|
||||
len = i - linestart;
|
||||
|
||||
buf.reset();
|
||||
|
||||
// First, expand the macros.
|
||||
// Macros are bracketed by % characters.
|
||||
|
||||
for (k = 0; k < len; k++)
|
||||
{
|
||||
if (line[k] == '%')
|
||||
{
|
||||
int j;
|
||||
|
||||
for (j = k + 1; j < len; j++)
|
||||
{
|
||||
if (line[j] == '%')
|
||||
{
|
||||
if (j - k == 3 && memicmp(&line[k + 1], "@P", 2) == 0)
|
||||
{
|
||||
// %@P% is special meaning the path to the .ini file
|
||||
p = path;
|
||||
if (!*p)
|
||||
p = (char *)".";
|
||||
}
|
||||
else
|
||||
{ int len = j - k;
|
||||
char tmp[10]; // big enough most of the time
|
||||
|
||||
if (len <= sizeof(tmp))
|
||||
p = tmp;
|
||||
else
|
||||
p = (char *)alloca(len);
|
||||
len--;
|
||||
memcpy(p, &line[k + 1], len);
|
||||
p[len] = 0;
|
||||
strupr(p);
|
||||
p = getenv(p);
|
||||
if (!p)
|
||||
p = (char *)"";
|
||||
}
|
||||
buf.writestring(p);
|
||||
k = j;
|
||||
goto L1;
|
||||
}
|
||||
}
|
||||
}
|
||||
buf.writeByte(line[k]);
|
||||
L1:
|
||||
;
|
||||
}
|
||||
|
||||
// Remove trailing spaces
|
||||
while (buf.offset && isspace(buf.data[buf.offset - 1]))
|
||||
buf.offset--;
|
||||
|
||||
p = buf.toChars();
|
||||
|
||||
// The expanded line is in p.
|
||||
// Now parse it for meaning.
|
||||
|
||||
p = skipspace(p);
|
||||
switch (*p)
|
||||
{
|
||||
case ';': // comment
|
||||
case 0: // blank
|
||||
break;
|
||||
|
||||
case '[': // look for [Environment]
|
||||
p = skipspace(p + 1);
|
||||
for (pn = p; isalnum(*pn); pn++)
|
||||
;
|
||||
if (pn - p == 11 &&
|
||||
memicmp(p, "Environment", 11) == 0 &&
|
||||
*skipspace(pn) == ']'
|
||||
)
|
||||
envsection = 1;
|
||||
else
|
||||
envsection = 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
if (envsection)
|
||||
{
|
||||
pn = p;
|
||||
|
||||
// Convert name to upper case;
|
||||
// remove spaces bracketing =
|
||||
for (p = pn; *p; p++)
|
||||
{ if (islower(*p))
|
||||
*p &= ~0x20;
|
||||
else if (isspace(*p))
|
||||
memmove(p, p + 1, strlen(p));
|
||||
else if (*p == '=')
|
||||
{
|
||||
p++;
|
||||
while (isspace(*p))
|
||||
memmove(p, p + 1, strlen(p));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
putenv(strdup(pn));
|
||||
#if LOG
|
||||
printf("\tputenv('%s')\n", pn);
|
||||
//printf("getenv(\"TEST\") = '%s'\n",getenv("TEST"));
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
Lskip:
|
||||
;
|
||||
}
|
||||
return filename;
|
||||
}
|
||||
|
||||
/********************
|
||||
* Skip spaces.
|
||||
*/
|
||||
|
||||
char *skipspace(const char *p)
|
||||
{
|
||||
while (isspace(*p))
|
||||
p++;
|
||||
return (char *)p;
|
||||
}
|
||||
|
||||
|
||||
1375
dmd2/init.c
1375
dmd2/init.c
File diff suppressed because it is too large
Load Diff
279
dmd2/init.h
279
dmd2/init.h
@@ -1,139 +1,140 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 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 INIT_H
|
||||
#define INIT_H
|
||||
|
||||
#include "root.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "arraytypes.h"
|
||||
|
||||
struct Identifier;
|
||||
struct Expression;
|
||||
struct Scope;
|
||||
struct Type;
|
||||
struct dt_t;
|
||||
struct AggregateDeclaration;
|
||||
struct VoidInitializer;
|
||||
struct StructInitializer;
|
||||
struct ArrayInitializer;
|
||||
struct ExpInitializer;
|
||||
#ifdef _DH
|
||||
struct HdrGenState;
|
||||
#endif
|
||||
|
||||
struct Initializer : Object
|
||||
{
|
||||
Loc loc;
|
||||
|
||||
Initializer(Loc loc);
|
||||
virtual Initializer *syntaxCopy();
|
||||
virtual Initializer *semantic(Scope *sc, Type *t);
|
||||
virtual Type *inferType(Scope *sc);
|
||||
virtual Expression *toExpression() = 0;
|
||||
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
|
||||
char *toChars();
|
||||
|
||||
static Initializers *arraySyntaxCopy(Initializers *ai);
|
||||
|
||||
#if IN_DMD
|
||||
virtual dt_t *toDt();
|
||||
#endif
|
||||
|
||||
virtual VoidInitializer *isVoidInitializer() { return NULL; }
|
||||
virtual StructInitializer *isStructInitializer() { return NULL; }
|
||||
virtual ArrayInitializer *isArrayInitializer() { return NULL; }
|
||||
virtual ExpInitializer *isExpInitializer() { return NULL; }
|
||||
};
|
||||
|
||||
struct VoidInitializer : Initializer
|
||||
{
|
||||
Type *type; // type that this will initialize to
|
||||
|
||||
VoidInitializer(Loc loc);
|
||||
Initializer *syntaxCopy();
|
||||
Initializer *semantic(Scope *sc, Type *t);
|
||||
Expression *toExpression();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
#if IN_DMD
|
||||
dt_t *toDt();
|
||||
#endif
|
||||
|
||||
virtual VoidInitializer *isVoidInitializer() { return this; }
|
||||
};
|
||||
|
||||
struct StructInitializer : Initializer
|
||||
{
|
||||
Identifiers field; // of Identifier *'s
|
||||
Initializers value; // parallel array of Initializer *'s
|
||||
|
||||
Array vars; // parallel array of VarDeclaration *'s
|
||||
AggregateDeclaration *ad; // which aggregate this is for
|
||||
|
||||
StructInitializer(Loc loc);
|
||||
Initializer *syntaxCopy();
|
||||
void addInit(Identifier *field, Initializer *value);
|
||||
Initializer *semantic(Scope *sc, Type *t);
|
||||
Expression *toExpression();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
#if IN_DMD
|
||||
dt_t *toDt();
|
||||
#endif
|
||||
|
||||
StructInitializer *isStructInitializer() { return this; }
|
||||
};
|
||||
|
||||
struct ArrayInitializer : Initializer
|
||||
{
|
||||
Expressions index; // indices
|
||||
Initializers value; // of Initializer *'s
|
||||
unsigned dim; // length of array being initialized
|
||||
Type *type; // type that array will be used to initialize
|
||||
int sem; // !=0 if semantic() is run
|
||||
|
||||
ArrayInitializer(Loc loc);
|
||||
Initializer *syntaxCopy();
|
||||
void addInit(Expression *index, Initializer *value);
|
||||
Initializer *semantic(Scope *sc, Type *t);
|
||||
Type *inferType(Scope *sc);
|
||||
Expression *toExpression();
|
||||
Initializer *toAssocArrayInitializer();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
#if IN_DMD
|
||||
dt_t *toDt();
|
||||
dt_t *toDtBit(); // for bit arrays
|
||||
#endif
|
||||
|
||||
ArrayInitializer *isArrayInitializer() { return this; }
|
||||
};
|
||||
|
||||
struct ExpInitializer : Initializer
|
||||
{
|
||||
Expression *exp;
|
||||
|
||||
ExpInitializer(Loc loc, Expression *exp);
|
||||
Initializer *syntaxCopy();
|
||||
Initializer *semantic(Scope *sc, Type *t);
|
||||
Type *inferType(Scope *sc);
|
||||
Expression *toExpression();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
#if IN_DMD
|
||||
dt_t *toDt();
|
||||
#endif
|
||||
|
||||
virtual ExpInitializer *isExpInitializer() { return this; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2007 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 INIT_H
|
||||
#define INIT_H
|
||||
|
||||
#include "root.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "arraytypes.h"
|
||||
|
||||
struct Identifier;
|
||||
struct Expression;
|
||||
struct Scope;
|
||||
struct Type;
|
||||
struct dt_t;
|
||||
struct AggregateDeclaration;
|
||||
struct VoidInitializer;
|
||||
struct StructInitializer;
|
||||
struct ArrayInitializer;
|
||||
struct ExpInitializer;
|
||||
#ifdef _DH
|
||||
struct HdrGenState;
|
||||
#endif
|
||||
|
||||
struct Initializer : Object
|
||||
{
|
||||
Loc loc;
|
||||
|
||||
Initializer(Loc loc);
|
||||
virtual Initializer *syntaxCopy();
|
||||
virtual Initializer *semantic(Scope *sc, Type *t);
|
||||
virtual Type *inferType(Scope *sc);
|
||||
virtual Expression *toExpression() = 0;
|
||||
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
|
||||
char *toChars();
|
||||
|
||||
static Initializers *arraySyntaxCopy(Initializers *ai);
|
||||
|
||||
#if IN_DMD
|
||||
virtual dt_t *toDt();
|
||||
#endif
|
||||
|
||||
virtual VoidInitializer *isVoidInitializer() { return NULL; }
|
||||
virtual StructInitializer *isStructInitializer() { return NULL; }
|
||||
virtual ArrayInitializer *isArrayInitializer() { return NULL; }
|
||||
virtual ExpInitializer *isExpInitializer() { return NULL; }
|
||||
};
|
||||
|
||||
struct VoidInitializer : Initializer
|
||||
{
|
||||
Type *type; // type that this will initialize to
|
||||
|
||||
VoidInitializer(Loc loc);
|
||||
Initializer *syntaxCopy();
|
||||
Initializer *semantic(Scope *sc, Type *t);
|
||||
Expression *toExpression();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
#if IN_DMD
|
||||
dt_t *toDt();
|
||||
#endif
|
||||
|
||||
virtual VoidInitializer *isVoidInitializer() { return this; }
|
||||
};
|
||||
|
||||
struct StructInitializer : Initializer
|
||||
{
|
||||
Identifiers field; // of Identifier *'s
|
||||
Initializers value; // parallel array of Initializer *'s
|
||||
|
||||
Array vars; // parallel array of VarDeclaration *'s
|
||||
AggregateDeclaration *ad; // which aggregate this is for
|
||||
|
||||
StructInitializer(Loc loc);
|
||||
Initializer *syntaxCopy();
|
||||
void addInit(Identifier *field, Initializer *value);
|
||||
Initializer *semantic(Scope *sc, Type *t);
|
||||
Expression *toExpression();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
#if IN_DMD
|
||||
dt_t *toDt();
|
||||
#endif
|
||||
|
||||
StructInitializer *isStructInitializer() { return this; }
|
||||
};
|
||||
|
||||
struct ArrayInitializer : Initializer
|
||||
{
|
||||
Expressions index; // indices
|
||||
Initializers value; // of Initializer *'s
|
||||
unsigned dim; // length of array being initialized
|
||||
Type *type; // type that array will be used to initialize
|
||||
int sem; // !=0 if semantic() is run
|
||||
|
||||
ArrayInitializer(Loc loc);
|
||||
Initializer *syntaxCopy();
|
||||
void addInit(Expression *index, Initializer *value);
|
||||
Initializer *semantic(Scope *sc, Type *t);
|
||||
int isAssociativeArray();
|
||||
Type *inferType(Scope *sc);
|
||||
Expression *toExpression();
|
||||
Expression *toAssocArrayLiteral();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
#if IN_DMD
|
||||
dt_t *toDt();
|
||||
dt_t *toDtBit(); // for bit arrays
|
||||
#endif
|
||||
|
||||
ArrayInitializer *isArrayInitializer() { return this; }
|
||||
};
|
||||
|
||||
struct ExpInitializer : Initializer
|
||||
{
|
||||
Expression *exp;
|
||||
|
||||
ExpInitializer(Loc loc, Expression *exp);
|
||||
Initializer *syntaxCopy();
|
||||
Initializer *semantic(Scope *sc, Type *t);
|
||||
Type *inferType(Scope *sc);
|
||||
Expression *toExpression();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
|
||||
#if IN_DMD
|
||||
dt_t *toDt();
|
||||
#endif
|
||||
|
||||
virtual ExpInitializer *isExpInitializer() { return this; }
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
3157
dmd2/inline.c
3157
dmd2/inline.c
File diff suppressed because it is too large
Load Diff
6060
dmd2/interpret.c
6060
dmd2/interpret.c
File diff suppressed because it is too large
Load Diff
350
dmd2/irstate.c
350
dmd2/irstate.c
@@ -1,164 +1,186 @@
|
||||
|
||||
// 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
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "irstate.h"
|
||||
|
||||
IRState::IRState(IRState *irs, Statement *s)
|
||||
{
|
||||
prev = irs;
|
||||
statement = s;
|
||||
symbol = NULL;
|
||||
breakBlock = NULL;
|
||||
contBlock = NULL;
|
||||
switchBlock = NULL;
|
||||
defaultBlock = NULL;
|
||||
ident = NULL;
|
||||
ehidden = NULL;
|
||||
startaddress = NULL;
|
||||
if (irs)
|
||||
{
|
||||
m = irs->m;
|
||||
shidden = irs->shidden;
|
||||
sclosure = irs->sclosure;
|
||||
sthis = irs->sthis;
|
||||
blx = irs->blx;
|
||||
deferToObj = irs->deferToObj;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = NULL;
|
||||
shidden = NULL;
|
||||
sclosure = NULL;
|
||||
sthis = NULL;
|
||||
blx = NULL;
|
||||
deferToObj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IRState::IRState(IRState *irs, Dsymbol *s)
|
||||
{
|
||||
prev = irs;
|
||||
statement = NULL;
|
||||
symbol = s;
|
||||
breakBlock = NULL;
|
||||
contBlock = NULL;
|
||||
switchBlock = NULL;
|
||||
defaultBlock = NULL;
|
||||
ident = NULL;
|
||||
ehidden = NULL;
|
||||
startaddress = NULL;
|
||||
if (irs)
|
||||
{
|
||||
m = irs->m;
|
||||
shidden = irs->shidden;
|
||||
sclosure = irs->sclosure;
|
||||
sthis = irs->sthis;
|
||||
blx = irs->blx;
|
||||
deferToObj = irs->deferToObj;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = NULL;
|
||||
shidden = NULL;
|
||||
sclosure = NULL;
|
||||
sthis = NULL;
|
||||
blx = NULL;
|
||||
deferToObj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IRState::IRState(Module *m, Dsymbol *s)
|
||||
{
|
||||
prev = NULL;
|
||||
statement = NULL;
|
||||
this->m = m;
|
||||
symbol = s;
|
||||
breakBlock = NULL;
|
||||
contBlock = NULL;
|
||||
switchBlock = NULL;
|
||||
defaultBlock = NULL;
|
||||
ident = NULL;
|
||||
ehidden = NULL;
|
||||
shidden = NULL;
|
||||
sclosure = NULL;
|
||||
sthis = NULL;
|
||||
blx = NULL;
|
||||
deferToObj = NULL;
|
||||
startaddress = NULL;
|
||||
}
|
||||
|
||||
block *IRState::getBreakBlock(Identifier *ident)
|
||||
{
|
||||
IRState *bc;
|
||||
|
||||
for (bc = this; bc; bc = bc->prev)
|
||||
{
|
||||
if (ident)
|
||||
{
|
||||
if (bc->prev && bc->prev->ident == ident)
|
||||
return bc->breakBlock;
|
||||
}
|
||||
else if (bc->breakBlock)
|
||||
return bc->breakBlock;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block *IRState::getContBlock(Identifier *ident)
|
||||
{
|
||||
IRState *bc;
|
||||
|
||||
for (bc = this; bc; bc = bc->prev)
|
||||
{
|
||||
if (ident)
|
||||
{
|
||||
if (bc->prev && bc->prev->ident == ident)
|
||||
return bc->contBlock;
|
||||
}
|
||||
else if (bc->contBlock)
|
||||
return bc->contBlock;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block *IRState::getSwitchBlock()
|
||||
{
|
||||
IRState *bc;
|
||||
|
||||
for (bc = this; bc; bc = bc->prev)
|
||||
{
|
||||
if (bc->switchBlock)
|
||||
return bc->switchBlock;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block *IRState::getDefaultBlock()
|
||||
{
|
||||
IRState *bc;
|
||||
|
||||
for (bc = this; bc; bc = bc->prev)
|
||||
{
|
||||
if (bc->defaultBlock)
|
||||
return bc->defaultBlock;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FuncDeclaration *IRState::getFunc()
|
||||
{
|
||||
IRState *bc;
|
||||
|
||||
for (bc = this; bc->prev; bc = bc->prev)
|
||||
{
|
||||
}
|
||||
return (FuncDeclaration *)(bc->symbol);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "mars.h"
|
||||
#include "mtype.h"
|
||||
#include "declaration.h"
|
||||
#include "irstate.h"
|
||||
|
||||
IRState::IRState(IRState *irs, Statement *s)
|
||||
{
|
||||
prev = irs;
|
||||
statement = s;
|
||||
symbol = NULL;
|
||||
breakBlock = NULL;
|
||||
contBlock = NULL;
|
||||
switchBlock = NULL;
|
||||
defaultBlock = NULL;
|
||||
ident = NULL;
|
||||
ehidden = NULL;
|
||||
startaddress = NULL;
|
||||
if (irs)
|
||||
{
|
||||
m = irs->m;
|
||||
shidden = irs->shidden;
|
||||
sclosure = irs->sclosure;
|
||||
sthis = irs->sthis;
|
||||
blx = irs->blx;
|
||||
deferToObj = irs->deferToObj;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = NULL;
|
||||
shidden = NULL;
|
||||
sclosure = NULL;
|
||||
sthis = NULL;
|
||||
blx = NULL;
|
||||
deferToObj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IRState::IRState(IRState *irs, Dsymbol *s)
|
||||
{
|
||||
prev = irs;
|
||||
statement = NULL;
|
||||
symbol = s;
|
||||
breakBlock = NULL;
|
||||
contBlock = NULL;
|
||||
switchBlock = NULL;
|
||||
defaultBlock = NULL;
|
||||
ident = NULL;
|
||||
ehidden = NULL;
|
||||
startaddress = NULL;
|
||||
if (irs)
|
||||
{
|
||||
m = irs->m;
|
||||
shidden = irs->shidden;
|
||||
sclosure = irs->sclosure;
|
||||
sthis = irs->sthis;
|
||||
blx = irs->blx;
|
||||
deferToObj = irs->deferToObj;
|
||||
}
|
||||
else
|
||||
{
|
||||
m = NULL;
|
||||
shidden = NULL;
|
||||
sclosure = NULL;
|
||||
sthis = NULL;
|
||||
blx = NULL;
|
||||
deferToObj = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
IRState::IRState(Module *m, Dsymbol *s)
|
||||
{
|
||||
prev = NULL;
|
||||
statement = NULL;
|
||||
this->m = m;
|
||||
symbol = s;
|
||||
breakBlock = NULL;
|
||||
contBlock = NULL;
|
||||
switchBlock = NULL;
|
||||
defaultBlock = NULL;
|
||||
ident = NULL;
|
||||
ehidden = NULL;
|
||||
shidden = NULL;
|
||||
sclosure = NULL;
|
||||
sthis = NULL;
|
||||
blx = NULL;
|
||||
deferToObj = NULL;
|
||||
startaddress = NULL;
|
||||
}
|
||||
|
||||
block *IRState::getBreakBlock(Identifier *ident)
|
||||
{
|
||||
IRState *bc;
|
||||
|
||||
for (bc = this; bc; bc = bc->prev)
|
||||
{
|
||||
if (ident)
|
||||
{
|
||||
if (bc->prev && bc->prev->ident == ident)
|
||||
return bc->breakBlock;
|
||||
}
|
||||
else if (bc->breakBlock)
|
||||
return bc->breakBlock;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block *IRState::getContBlock(Identifier *ident)
|
||||
{
|
||||
IRState *bc;
|
||||
|
||||
for (bc = this; bc; bc = bc->prev)
|
||||
{
|
||||
if (ident)
|
||||
{
|
||||
if (bc->prev && bc->prev->ident == ident)
|
||||
return bc->contBlock;
|
||||
}
|
||||
else if (bc->contBlock)
|
||||
return bc->contBlock;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block *IRState::getSwitchBlock()
|
||||
{
|
||||
IRState *bc;
|
||||
|
||||
for (bc = this; bc; bc = bc->prev)
|
||||
{
|
||||
if (bc->switchBlock)
|
||||
return bc->switchBlock;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
block *IRState::getDefaultBlock()
|
||||
{
|
||||
IRState *bc;
|
||||
|
||||
for (bc = this; bc; bc = bc->prev)
|
||||
{
|
||||
if (bc->defaultBlock)
|
||||
return bc->defaultBlock;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
FuncDeclaration *IRState::getFunc()
|
||||
{
|
||||
IRState *bc;
|
||||
|
||||
for (bc = this; bc->prev; bc = bc->prev)
|
||||
{
|
||||
}
|
||||
return (FuncDeclaration *)(bc->symbol);
|
||||
}
|
||||
|
||||
|
||||
/**********************
|
||||
* Return !=0 if do array bounds checking
|
||||
*/
|
||||
int IRState::arrayBoundsCheck()
|
||||
{
|
||||
int result = global.params.useArrayBounds;
|
||||
|
||||
if (result == 1)
|
||||
{ // For safe functions only
|
||||
result = 0;
|
||||
FuncDeclaration *fd = getFunc();
|
||||
if (fd)
|
||||
{ Type *t = fd->type;
|
||||
if (t->ty == Tfunction && ((TypeFunction *)t)->trust == TRUSTsafe)
|
||||
result = 1;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
115
dmd2/irstate.h
115
dmd2/irstate.h
@@ -1,57 +1,58 @@
|
||||
|
||||
// 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
|
||||
|
||||
#ifndef DMD_CONTEXT_H
|
||||
#define DMD_CONTEXT_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
struct Module;
|
||||
struct Statement;
|
||||
struct block;
|
||||
struct Dsymbol;
|
||||
struct Identifier;
|
||||
struct Symbol;
|
||||
struct FuncDeclaration;
|
||||
struct Blockx;
|
||||
struct Array;
|
||||
struct elem;
|
||||
|
||||
struct IRState
|
||||
{
|
||||
IRState *prev;
|
||||
Statement *statement;
|
||||
Module *m; // module
|
||||
Dsymbol *symbol;
|
||||
Identifier *ident;
|
||||
Symbol *shidden; // hidden parameter to function
|
||||
Symbol *sthis; // 'this' parameter to function (member and nested)
|
||||
Symbol *sclosure; // pointer to closure instance
|
||||
Blockx *blx;
|
||||
Array *deferToObj; // array of Dsymbol's to run toObjFile(int multiobj) on later
|
||||
elem *ehidden; // transmit hidden pointer to CallExp::toElem()
|
||||
Symbol *startaddress;
|
||||
|
||||
block *breakBlock;
|
||||
block *contBlock;
|
||||
block *switchBlock;
|
||||
block *defaultBlock;
|
||||
|
||||
IRState(IRState *irs, Statement *s);
|
||||
IRState(IRState *irs, Dsymbol *s);
|
||||
IRState(Module *m, Dsymbol *s);
|
||||
|
||||
block *getBreakBlock(Identifier *ident);
|
||||
block *getContBlock(Identifier *ident);
|
||||
block *getSwitchBlock();
|
||||
block *getDefaultBlock();
|
||||
FuncDeclaration *getFunc();
|
||||
};
|
||||
|
||||
#endif /* DMD_CONTEXT_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
|
||||
|
||||
#ifndef DMD_CONTEXT_H
|
||||
#define DMD_CONTEXT_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
struct Module;
|
||||
struct Statement;
|
||||
struct block;
|
||||
struct Dsymbol;
|
||||
struct Identifier;
|
||||
struct Symbol;
|
||||
struct FuncDeclaration;
|
||||
struct Blockx;
|
||||
struct Array;
|
||||
struct elem;
|
||||
|
||||
struct IRState
|
||||
{
|
||||
IRState *prev;
|
||||
Statement *statement;
|
||||
Module *m; // module
|
||||
Dsymbol *symbol;
|
||||
Identifier *ident;
|
||||
Symbol *shidden; // hidden parameter to function
|
||||
Symbol *sthis; // 'this' parameter to function (member and nested)
|
||||
Symbol *sclosure; // pointer to closure instance
|
||||
Blockx *blx;
|
||||
Array *deferToObj; // array of Dsymbol's to run toObjFile(int multiobj) on later
|
||||
elem *ehidden; // transmit hidden pointer to CallExp::toElem()
|
||||
Symbol *startaddress;
|
||||
|
||||
block *breakBlock;
|
||||
block *contBlock;
|
||||
block *switchBlock;
|
||||
block *defaultBlock;
|
||||
|
||||
IRState(IRState *irs, Statement *s);
|
||||
IRState(IRState *irs, Dsymbol *s);
|
||||
IRState(Module *m, Dsymbol *s);
|
||||
|
||||
block *getBreakBlock(Identifier *ident);
|
||||
block *getContBlock(Identifier *ident);
|
||||
block *getSwitchBlock();
|
||||
block *getDefaultBlock();
|
||||
FuncDeclaration *getFunc();
|
||||
int arrayBoundsCheck();
|
||||
};
|
||||
|
||||
#endif /* DMD_CONTEXT_H */
|
||||
|
||||
440
dmd2/json.c
Normal file
440
dmd2/json.c
Normal file
@@ -0,0 +1,440 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
// This implements the JSON capability.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "rmem.h"
|
||||
#include "root.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "dsymbol.h"
|
||||
#include "macro.h"
|
||||
#include "template.h"
|
||||
#include "lexer.h"
|
||||
#include "aggregate.h"
|
||||
#include "declaration.h"
|
||||
#include "enum.h"
|
||||
#include "id.h"
|
||||
#include "module.h"
|
||||
#include "scope.h"
|
||||
#include "hdrgen.h"
|
||||
#include "json.h"
|
||||
#include "mtype.h"
|
||||
#include "attrib.h"
|
||||
#include "cond.h"
|
||||
|
||||
const char Pname[] = "name";
|
||||
const char Pkind[] = "kind";
|
||||
const char Pfile[] = "file";
|
||||
const char Pline[] = "line";
|
||||
const char Ptype[] = "type";
|
||||
const char Pcomment[] = "comment";
|
||||
const char Pmembers[] = "members";
|
||||
|
||||
void JsonRemoveComma(OutBuffer *buf);
|
||||
|
||||
void json_generate(Array *modules)
|
||||
{ OutBuffer buf;
|
||||
|
||||
buf.writestring("[\n");
|
||||
for (int i = 0; i < modules->dim; i++)
|
||||
{ Module *m = (Module *)modules->data[i];
|
||||
if (global.params.verbose)
|
||||
printf("json gen %s\n", m->toChars());
|
||||
m->toJsonBuffer(&buf);
|
||||
buf.writestring(",\n");
|
||||
}
|
||||
JsonRemoveComma(&buf);
|
||||
buf.writestring("]\n");
|
||||
|
||||
// Write buf to file
|
||||
char *arg = global.params.xfilename;
|
||||
if (!arg || !*arg)
|
||||
{ // Generate lib file name from first obj name
|
||||
char *n = (char *)global.params.objfiles->data[0];
|
||||
|
||||
n = FileName::name(n);
|
||||
FileName *fn = FileName::forceExt(n, global.json_ext);
|
||||
arg = fn->toChars();
|
||||
}
|
||||
else if (arg[0] == '-' && arg[1] == 0)
|
||||
{ // Write to stdout; assume it succeeds
|
||||
int n = fwrite(buf.data, 1, buf.offset, stdout);
|
||||
assert(n == buf.offset); // keep gcc happy about return values
|
||||
return;
|
||||
}
|
||||
// if (!FileName::absolute(arg))
|
||||
// arg = FileName::combine(dir, arg);
|
||||
FileName *jsonfilename = FileName::defaultExt(arg, global.json_ext);
|
||||
File *jsonfile = new File(jsonfilename);
|
||||
assert(jsonfile);
|
||||
jsonfile->setbuffer(buf.data, buf.offset);
|
||||
jsonfile->ref = 1;
|
||||
char *pt = FileName::path(jsonfile->toChars());
|
||||
if (*pt)
|
||||
FileName::ensurePathExists(pt);
|
||||
mem.free(pt);
|
||||
jsonfile->writev();
|
||||
}
|
||||
|
||||
|
||||
/*********************************
|
||||
* Encode string into buf, and wrap it in double quotes.
|
||||
*/
|
||||
void JsonString(OutBuffer *buf, const char *s)
|
||||
{
|
||||
buf->writeByte('\"');
|
||||
for (; *s; s++)
|
||||
{
|
||||
unsigned char c = (unsigned char) *s;
|
||||
switch (c)
|
||||
{
|
||||
case '\n':
|
||||
buf->writestring("\\n");
|
||||
break;
|
||||
|
||||
case '\r':
|
||||
buf->writestring("\\r");
|
||||
break;
|
||||
|
||||
case '\t':
|
||||
buf->writestring("\\t");
|
||||
break;
|
||||
|
||||
case '\"':
|
||||
buf->writestring("\\\"");
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
buf->writestring("\\\\");
|
||||
break;
|
||||
|
||||
case '/':
|
||||
buf->writestring("\\/");
|
||||
break;
|
||||
|
||||
case '\b':
|
||||
buf->writestring("\\b");
|
||||
break;
|
||||
|
||||
case '\f':
|
||||
buf->writestring("\\f");
|
||||
break;
|
||||
|
||||
default:
|
||||
if (c < 0x20)
|
||||
buf->printf("\\u%04x", c);
|
||||
else
|
||||
// Note that UTF-8 chars pass through here just fine
|
||||
buf->writeByte(c);
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf->writeByte('\"');
|
||||
}
|
||||
|
||||
void JsonProperty(OutBuffer *buf, const char *name, const char *value)
|
||||
{
|
||||
JsonString(buf, name);
|
||||
buf->writestring(" : ");
|
||||
JsonString(buf, value);
|
||||
buf->writestring(",\n");
|
||||
}
|
||||
|
||||
void JsonProperty(OutBuffer *buf, const char *name, int value)
|
||||
{
|
||||
JsonString(buf, name);
|
||||
buf->writestring(" : ");
|
||||
buf->printf("%d", value);
|
||||
buf->writestring(",\n");
|
||||
}
|
||||
|
||||
void JsonRemoveComma(OutBuffer *buf)
|
||||
{
|
||||
if (buf->offset >= 2 &&
|
||||
buf->data[buf->offset - 2] == ',' &&
|
||||
buf->data[buf->offset - 1] == '\n')
|
||||
buf->offset -= 2;
|
||||
}
|
||||
|
||||
void Dsymbol::toJsonBuffer(OutBuffer *buf)
|
||||
{
|
||||
}
|
||||
|
||||
void Module::toJsonBuffer(OutBuffer *buf)
|
||||
{
|
||||
buf->writestring("{\n");
|
||||
|
||||
if (md)
|
||||
JsonProperty(buf, Pname, md->toChars());
|
||||
|
||||
JsonProperty(buf, Pkind, kind());
|
||||
|
||||
JsonProperty(buf, Pfile, srcfile->toChars());
|
||||
|
||||
if (comment)
|
||||
JsonProperty(buf, Pcomment, (const char *)comment);
|
||||
|
||||
JsonString(buf, Pmembers);
|
||||
buf->writestring(" : [\n");
|
||||
|
||||
size_t offset = buf->offset;
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
if (offset != buf->offset)
|
||||
{ buf->writestring(",\n");
|
||||
offset = buf->offset;
|
||||
}
|
||||
s->toJsonBuffer(buf);
|
||||
}
|
||||
|
||||
JsonRemoveComma(buf);
|
||||
buf->writestring("]\n");
|
||||
|
||||
buf->writestring("}\n");
|
||||
}
|
||||
|
||||
void AttribDeclaration::toJsonBuffer(OutBuffer *buf)
|
||||
{
|
||||
//printf("AttribDeclaration::toJsonBuffer()\n");
|
||||
|
||||
Array *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
{
|
||||
size_t offset = buf->offset;
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)d->data[i];
|
||||
//printf("AttribDeclaration::toJsonBuffer %s\n", s->toChars());
|
||||
if (offset != buf->offset)
|
||||
{ buf->writestring(",\n");
|
||||
offset = buf->offset;
|
||||
}
|
||||
s->toJsonBuffer(buf);
|
||||
}
|
||||
JsonRemoveComma(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void ConditionalDeclaration::toJsonBuffer(OutBuffer *buf)
|
||||
{
|
||||
//printf("ConditionalDeclaration::toJsonBuffer()\n");
|
||||
if (condition->inc)
|
||||
{
|
||||
AttribDeclaration::toJsonBuffer(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void InvariantDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
void DtorDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
void StaticCtorDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
void StaticDtorDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
void ClassInfoDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
void ModuleInfoDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
void TypeInfoDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
void UnitTestDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
#if DMDV2
|
||||
void PostBlitDeclaration::toJsonBuffer(OutBuffer *buf) { }
|
||||
#endif
|
||||
|
||||
void Declaration::toJsonBuffer(OutBuffer *buf)
|
||||
{
|
||||
//printf("Declaration::toJsonBuffer()\n");
|
||||
buf->writestring("{\n");
|
||||
|
||||
JsonProperty(buf, Pname, toChars());
|
||||
JsonProperty(buf, Pkind, kind());
|
||||
if (type)
|
||||
JsonProperty(buf, Ptype, type->toChars());
|
||||
|
||||
if (comment)
|
||||
JsonProperty(buf, Pcomment, (const char *)comment);
|
||||
|
||||
if (loc.linnum)
|
||||
JsonProperty(buf, Pline, loc.linnum);
|
||||
|
||||
TypedefDeclaration *td = isTypedefDeclaration();
|
||||
if (td)
|
||||
{
|
||||
JsonProperty(buf, "base", td->basetype->toChars());
|
||||
}
|
||||
|
||||
JsonRemoveComma(buf);
|
||||
buf->writestring("}\n");
|
||||
}
|
||||
|
||||
void AggregateDeclaration::toJsonBuffer(OutBuffer *buf)
|
||||
{
|
||||
//printf("AggregateDeclaration::toJsonBuffer()\n");
|
||||
buf->writestring("{\n");
|
||||
|
||||
JsonProperty(buf, Pname, toChars());
|
||||
JsonProperty(buf, Pkind, kind());
|
||||
if (comment)
|
||||
JsonProperty(buf, Pcomment, (const char *)comment);
|
||||
if (loc.linnum)
|
||||
JsonProperty(buf, Pline, loc.linnum);
|
||||
|
||||
ClassDeclaration *cd = isClassDeclaration();
|
||||
if (cd)
|
||||
{
|
||||
if (cd->baseClass)
|
||||
{
|
||||
JsonProperty(buf, "base", cd->baseClass->toChars());
|
||||
}
|
||||
if (cd->interfaces_dim)
|
||||
{
|
||||
JsonString(buf, "interfaces");
|
||||
buf->writestring(" : [\n");
|
||||
size_t offset = buf->offset;
|
||||
for (int i = 0; i < cd->interfaces_dim; i++)
|
||||
{ BaseClass *b = cd->interfaces[i];
|
||||
if (offset != buf->offset)
|
||||
{ buf->writestring(",\n");
|
||||
offset = buf->offset;
|
||||
}
|
||||
JsonString(buf, b->base->toChars());
|
||||
}
|
||||
JsonRemoveComma(buf);
|
||||
buf->writestring("],\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (members)
|
||||
{
|
||||
JsonString(buf, Pmembers);
|
||||
buf->writestring(" : [\n");
|
||||
size_t offset = buf->offset;
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
if (offset != buf->offset)
|
||||
{ buf->writestring(",\n");
|
||||
offset = buf->offset;
|
||||
}
|
||||
s->toJsonBuffer(buf);
|
||||
}
|
||||
JsonRemoveComma(buf);
|
||||
buf->writestring("]\n");
|
||||
}
|
||||
JsonRemoveComma(buf);
|
||||
|
||||
buf->writestring("}\n");
|
||||
}
|
||||
|
||||
void TemplateDeclaration::toJsonBuffer(OutBuffer *buf)
|
||||
{
|
||||
//printf("TemplateDeclaration::toJsonBuffer()\n");
|
||||
|
||||
buf->writestring("{\n");
|
||||
|
||||
JsonProperty(buf, Pname, toChars());
|
||||
JsonProperty(buf, Pkind, kind());
|
||||
if (comment)
|
||||
JsonProperty(buf, Pcomment, (const char *)comment);
|
||||
|
||||
if (loc.linnum)
|
||||
JsonProperty(buf, Pline, loc.linnum);
|
||||
|
||||
JsonString(buf, Pmembers);
|
||||
buf->writestring(" : [\n");
|
||||
size_t offset = buf->offset;
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
if (offset != buf->offset)
|
||||
{ buf->writestring(",\n");
|
||||
offset = buf->offset;
|
||||
}
|
||||
s->toJsonBuffer(buf);
|
||||
}
|
||||
JsonRemoveComma(buf);
|
||||
buf->writestring("]\n");
|
||||
|
||||
buf->writestring("}\n");
|
||||
}
|
||||
|
||||
void EnumDeclaration::toJsonBuffer(OutBuffer *buf)
|
||||
{
|
||||
//printf("EnumDeclaration::toJsonBuffer()\n");
|
||||
if (isAnonymous())
|
||||
{
|
||||
if (members)
|
||||
{
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{
|
||||
Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
s->toJsonBuffer(buf);
|
||||
buf->writestring(",\n");
|
||||
}
|
||||
JsonRemoveComma(buf);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
buf->writestring("{\n");
|
||||
|
||||
JsonProperty(buf, Pname, toChars());
|
||||
JsonProperty(buf, Pkind, kind());
|
||||
if (comment)
|
||||
JsonProperty(buf, Pcomment, (const char *)comment);
|
||||
|
||||
if (loc.linnum)
|
||||
JsonProperty(buf, Pline, loc.linnum);
|
||||
|
||||
if (memtype)
|
||||
JsonProperty(buf, "base", memtype->toChars());
|
||||
|
||||
if (members)
|
||||
{
|
||||
JsonString(buf, Pmembers);
|
||||
buf->writestring(" : [\n");
|
||||
size_t offset = buf->offset;
|
||||
for (int i = 0; i < members->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)members->data[i];
|
||||
if (offset != buf->offset)
|
||||
{ buf->writestring(",\n");
|
||||
offset = buf->offset;
|
||||
}
|
||||
s->toJsonBuffer(buf);
|
||||
}
|
||||
JsonRemoveComma(buf);
|
||||
buf->writestring("]\n");
|
||||
}
|
||||
JsonRemoveComma(buf);
|
||||
|
||||
buf->writestring("}\n");
|
||||
}
|
||||
|
||||
void EnumMember::toJsonBuffer(OutBuffer *buf)
|
||||
{
|
||||
//printf("EnumMember::toJsonBuffer()\n");
|
||||
buf->writestring("{\n");
|
||||
|
||||
JsonProperty(buf, Pname, toChars());
|
||||
JsonProperty(buf, Pkind, kind());
|
||||
|
||||
if (comment)
|
||||
JsonProperty(buf, Pcomment, (const char *)comment);
|
||||
|
||||
if (loc.linnum)
|
||||
JsonProperty(buf, Pline, loc.linnum);
|
||||
|
||||
JsonRemoveComma(buf);
|
||||
buf->writestring("}\n");
|
||||
}
|
||||
|
||||
|
||||
24
dmd2/json.h
Normal file
24
dmd2/json.h
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
|
||||
// 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_JSON_H
|
||||
#define DMD_JSON_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
struct Array;
|
||||
|
||||
void json_generate(Array *);
|
||||
|
||||
#endif /* DMD_JSON_H */
|
||||
|
||||
6303
dmd2/lexer.c
6303
dmd2/lexer.c
File diff suppressed because it is too large
Load Diff
628
dmd2/lexer.h
628
dmd2/lexer.h
@@ -1,310 +1,318 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2008 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_LEXER_H
|
||||
#define DMD_LEXER_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
#include "mars.h"
|
||||
|
||||
struct StringTable;
|
||||
struct Identifier;
|
||||
struct Module;
|
||||
|
||||
/* Tokens:
|
||||
( )
|
||||
[ ]
|
||||
{ }
|
||||
< > <= >= == != === !==
|
||||
<< >> <<= >>= >>> >>>=
|
||||
+ - += -=
|
||||
* / % *= /= %=
|
||||
& | ^ &= |= ^=
|
||||
= ! ~ @
|
||||
++ --
|
||||
. -> : ,
|
||||
? && ||
|
||||
*/
|
||||
|
||||
enum TOK
|
||||
{
|
||||
TOKreserved,
|
||||
|
||||
// Other
|
||||
TOKlparen, TOKrparen,
|
||||
TOKlbracket, TOKrbracket,
|
||||
TOKlcurly, TOKrcurly,
|
||||
TOKcolon, TOKneg,
|
||||
TOKsemicolon, TOKdotdotdot,
|
||||
TOKeof, TOKcast,
|
||||
TOKnull, TOKassert,
|
||||
TOKtrue, TOKfalse,
|
||||
TOKarray, TOKcall,
|
||||
TOKaddress,
|
||||
TOKtype, TOKthrow,
|
||||
TOKnew, TOKdelete,
|
||||
TOKstar, TOKsymoff,
|
||||
TOKvar, TOKdotvar,
|
||||
TOKdotti, TOKdotexp,
|
||||
TOKdottype, TOKslice,
|
||||
TOKarraylength, TOKversion,
|
||||
TOKmodule, TOKdollar,
|
||||
TOKtemplate, TOKdottd,
|
||||
TOKdeclaration, TOKtypeof,
|
||||
TOKpragma, TOKdsymbol,
|
||||
TOKtypeid, TOKuadd,
|
||||
TOKremove,
|
||||
TOKnewanonclass, TOKcomment,
|
||||
TOKarrayliteral, TOKassocarrayliteral,
|
||||
TOKstructliteral,
|
||||
|
||||
// Operators
|
||||
TOKlt, TOKgt,
|
||||
TOKle, TOKge,
|
||||
TOKequal, TOKnotequal,
|
||||
TOKidentity, TOKnotidentity,
|
||||
TOKindex, TOKis,
|
||||
TOKtobool,
|
||||
|
||||
// 60
|
||||
// NCEG floating point compares
|
||||
// !<>= <> <>= !> !>= !< !<= !<>
|
||||
TOKunord,TOKlg,TOKleg,TOKule,TOKul,TOKuge,TOKug,TOKue,
|
||||
|
||||
TOKshl, TOKshr,
|
||||
TOKshlass, TOKshrass,
|
||||
TOKushr, TOKushrass,
|
||||
TOKcat, TOKcatass, // ~ ~=
|
||||
TOKadd, TOKmin, TOKaddass, TOKminass,
|
||||
TOKmul, TOKdiv, TOKmod,
|
||||
TOKmulass, TOKdivass, TOKmodass,
|
||||
TOKand, TOKor, TOKxor,
|
||||
TOKandass, TOKorass, TOKxorass,
|
||||
TOKassign, TOKnot, TOKtilde,
|
||||
TOKplusplus, TOKminusminus, TOKconstruct, TOKblit,
|
||||
TOKdot, TOKarrow, TOKcomma,
|
||||
TOKquestion, TOKandand, TOKoror,
|
||||
|
||||
// 104
|
||||
// Numeric literals
|
||||
TOKint32v, TOKuns32v,
|
||||
TOKint64v, TOKuns64v,
|
||||
TOKfloat32v, TOKfloat64v, TOKfloat80v,
|
||||
TOKimaginary32v, TOKimaginary64v, TOKimaginary80v,
|
||||
|
||||
// Char constants
|
||||
TOKcharv, TOKwcharv, TOKdcharv,
|
||||
|
||||
// Leaf operators
|
||||
TOKidentifier, TOKstring,
|
||||
TOKthis, TOKsuper,
|
||||
TOKhalt, TOKtuple,
|
||||
|
||||
// Basic types
|
||||
TOKvoid,
|
||||
TOKint8, TOKuns8,
|
||||
TOKint16, TOKuns16,
|
||||
TOKint32, TOKuns32,
|
||||
TOKint64, TOKuns64,
|
||||
TOKfloat32, TOKfloat64, TOKfloat80,
|
||||
TOKimaginary32, TOKimaginary64, TOKimaginary80,
|
||||
TOKcomplex32, TOKcomplex64, TOKcomplex80,
|
||||
TOKchar, TOKwchar, TOKdchar, TOKbit, TOKbool,
|
||||
TOKcent, TOKucent,
|
||||
|
||||
// Aggregates
|
||||
TOKstruct, TOKclass, TOKinterface, TOKunion, TOKenum, TOKimport,
|
||||
TOKtypedef, TOKalias, TOKoverride, TOKdelegate, TOKfunction,
|
||||
TOKmixin,
|
||||
|
||||
TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
|
||||
TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile,
|
||||
TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
|
||||
TOKauto, TOKpackage, TOKmanifest, TOKimmutable,
|
||||
|
||||
// Statements
|
||||
TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,
|
||||
TOKcase, TOKdefault, TOKbreak, TOKcontinue, TOKwith,
|
||||
TOKsynchronized, TOKreturn, TOKgoto, TOKtry, TOKcatch, TOKfinally,
|
||||
TOKasm, TOKforeach, TOKforeach_reverse,
|
||||
TOKscope,
|
||||
TOKon_scope_exit, TOKon_scope_failure, TOKon_scope_success,
|
||||
|
||||
// Contracts
|
||||
TOKbody, TOKinvariant,
|
||||
|
||||
// Testing
|
||||
TOKunittest,
|
||||
|
||||
// Added after 1.0
|
||||
TOKref,
|
||||
TOKmacro,
|
||||
#if DMDV2
|
||||
TOKtraits,
|
||||
TOKoverloadset,
|
||||
TOKpure,
|
||||
TOKnothrow,
|
||||
TOKtls,
|
||||
TOKgshared,
|
||||
TOKline,
|
||||
TOKfile,
|
||||
TOKshared,
|
||||
TOKat,
|
||||
#endif
|
||||
|
||||
// LDC specific
|
||||
#if IN_LLVM
|
||||
TOKgep,
|
||||
#endif
|
||||
|
||||
TOKMAX
|
||||
};
|
||||
|
||||
#define CASE_BASIC_TYPES \
|
||||
case TOKwchar: case TOKdchar: \
|
||||
case TOKbit: case TOKbool: case TOKchar: \
|
||||
case TOKint8: case TOKuns8: \
|
||||
case TOKint16: case TOKuns16: \
|
||||
case TOKint32: case TOKuns32: \
|
||||
case TOKint64: case TOKuns64: \
|
||||
case TOKfloat32: case TOKfloat64: case TOKfloat80: \
|
||||
case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: \
|
||||
case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: \
|
||||
case TOKvoid
|
||||
|
||||
#define CASE_BASIC_TYPES_X(t) \
|
||||
case TOKvoid: t = Type::tvoid; goto LabelX; \
|
||||
case TOKint8: t = Type::tint8; goto LabelX; \
|
||||
case TOKuns8: t = Type::tuns8; goto LabelX; \
|
||||
case TOKint16: t = Type::tint16; goto LabelX; \
|
||||
case TOKuns16: t = Type::tuns16; goto LabelX; \
|
||||
case TOKint32: t = Type::tint32; goto LabelX; \
|
||||
case TOKuns32: t = Type::tuns32; goto LabelX; \
|
||||
case TOKint64: t = Type::tint64; goto LabelX; \
|
||||
case TOKuns64: t = Type::tuns64; goto LabelX; \
|
||||
case TOKfloat32: t = Type::tfloat32; goto LabelX; \
|
||||
case TOKfloat64: t = Type::tfloat64; goto LabelX; \
|
||||
case TOKfloat80: t = Type::tfloat80; goto LabelX; \
|
||||
case TOKimaginary32: t = Type::timaginary32; goto LabelX; \
|
||||
case TOKimaginary64: t = Type::timaginary64; goto LabelX; \
|
||||
case TOKimaginary80: t = Type::timaginary80; goto LabelX; \
|
||||
case TOKcomplex32: t = Type::tcomplex32; goto LabelX; \
|
||||
case TOKcomplex64: t = Type::tcomplex64; goto LabelX; \
|
||||
case TOKcomplex80: t = Type::tcomplex80; goto LabelX; \
|
||||
case TOKbit: t = Type::tbit; goto LabelX; \
|
||||
case TOKbool: t = Type::tbool; goto LabelX; \
|
||||
case TOKchar: t = Type::tchar; goto LabelX; \
|
||||
case TOKwchar: t = Type::twchar; goto LabelX; \
|
||||
case TOKdchar: t = Type::tdchar; goto LabelX; \
|
||||
LabelX
|
||||
|
||||
struct Token
|
||||
{
|
||||
Token *next;
|
||||
unsigned char *ptr; // pointer to first character of this token within buffer
|
||||
enum TOK value;
|
||||
unsigned char *blockComment; // doc comment string prior to this token
|
||||
unsigned char *lineComment; // doc comment for previous token
|
||||
union
|
||||
{
|
||||
// Integers
|
||||
d_int32 int32value;
|
||||
d_uns32 uns32value;
|
||||
d_int64 int64value;
|
||||
d_uns64 uns64value;
|
||||
|
||||
// Floats
|
||||
#ifdef IN_GCC
|
||||
// real_t float80value; // can't use this in a union!
|
||||
#else
|
||||
d_float80 float80value;
|
||||
#endif
|
||||
|
||||
struct
|
||||
{ unsigned char *ustring; // UTF8 string
|
||||
unsigned len;
|
||||
unsigned char postfix; // 'c', 'w', 'd'
|
||||
};
|
||||
|
||||
Identifier *ident;
|
||||
};
|
||||
#ifdef IN_GCC
|
||||
real_t float80value; // can't use this in a union!
|
||||
#endif
|
||||
|
||||
static const char *tochars[TOKMAX];
|
||||
static void *operator new(size_t sz);
|
||||
|
||||
int isKeyword();
|
||||
void print();
|
||||
const char *toChars();
|
||||
static const char *toChars(enum TOK);
|
||||
};
|
||||
|
||||
struct Lexer
|
||||
{
|
||||
static StringTable stringtable;
|
||||
static OutBuffer stringbuffer;
|
||||
static Token *freelist;
|
||||
|
||||
Loc loc; // for error messages
|
||||
|
||||
unsigned char *base; // pointer to start of buffer
|
||||
unsigned char *end; // past end of buffer
|
||||
unsigned char *p; // current character
|
||||
Token token;
|
||||
Module *mod;
|
||||
int doDocComment; // collect doc comment information
|
||||
int anyToken; // !=0 means seen at least one token
|
||||
int commentToken; // !=0 means comments are TOKcomment's
|
||||
|
||||
Lexer(Module *mod,
|
||||
unsigned char *base, unsigned begoffset, unsigned endoffset,
|
||||
int doDocComment, int commentToken);
|
||||
|
||||
static void initKeywords();
|
||||
static Identifier *idPool(const char *s);
|
||||
static Identifier *uniqueId(const char *s);
|
||||
static Identifier *uniqueId(const char *s, int num);
|
||||
|
||||
TOK nextToken();
|
||||
TOK peekNext();
|
||||
TOK peekNext2();
|
||||
void scan(Token *t);
|
||||
Token *peek(Token *t);
|
||||
Token *peekPastParen(Token *t);
|
||||
unsigned escapeSequence();
|
||||
TOK wysiwygStringConstant(Token *t, int tc);
|
||||
TOK hexStringConstant(Token *t);
|
||||
#if DMDV2
|
||||
TOK delimitedStringConstant(Token *t);
|
||||
TOK tokenStringConstant(Token *t);
|
||||
#endif
|
||||
TOK escapeStringConstant(Token *t, int wide);
|
||||
TOK charConstant(Token *t, int wide);
|
||||
void stringPostfix(Token *t);
|
||||
unsigned wchar(unsigned u);
|
||||
TOK number(Token *t);
|
||||
TOK inreal(Token *t);
|
||||
void error(const char *format, ...) IS_PRINTF(2);
|
||||
void error(Loc loc, const char *format, ...) IS_PRINTF(3);
|
||||
void pragma();
|
||||
unsigned decodeUTF();
|
||||
void getDocComment(Token *t, unsigned lineComment);
|
||||
|
||||
static int isValidIdentifier(char *p);
|
||||
static unsigned char *combineComments(unsigned char *c1, unsigned char *c2);
|
||||
};
|
||||
|
||||
#endif /* DMD_LEXER_H */
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2010 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_LEXER_H
|
||||
#define DMD_LEXER_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "root.h"
|
||||
#include "mars.h"
|
||||
|
||||
struct StringTable;
|
||||
struct Identifier;
|
||||
struct Module;
|
||||
|
||||
/* Tokens:
|
||||
( )
|
||||
[ ]
|
||||
{ }
|
||||
< > <= >= == != === !==
|
||||
<< >> <<= >>= >>> >>>=
|
||||
+ - += -=
|
||||
* / % *= /= %=
|
||||
& | ^ &= |= ^=
|
||||
= ! ~ @
|
||||
^^ ^^=
|
||||
++ --
|
||||
. -> : ,
|
||||
? && ||
|
||||
*/
|
||||
|
||||
enum TOK
|
||||
{
|
||||
TOKreserved,
|
||||
|
||||
// Other
|
||||
TOKlparen, TOKrparen,
|
||||
TOKlbracket, TOKrbracket,
|
||||
TOKlcurly, TOKrcurly,
|
||||
TOKcolon, TOKneg,
|
||||
TOKsemicolon, TOKdotdotdot,
|
||||
TOKeof, TOKcast,
|
||||
TOKnull, TOKassert,
|
||||
TOKtrue, TOKfalse,
|
||||
TOKarray, TOKcall,
|
||||
TOKaddress,
|
||||
TOKtype, TOKthrow,
|
||||
TOKnew, TOKdelete,
|
||||
TOKstar, TOKsymoff,
|
||||
TOKvar, TOKdotvar,
|
||||
TOKdotti, TOKdotexp,
|
||||
TOKdottype, TOKslice,
|
||||
TOKarraylength, TOKversion,
|
||||
TOKmodule, TOKdollar,
|
||||
TOKtemplate, TOKdottd,
|
||||
TOKdeclaration, TOKtypeof,
|
||||
TOKpragma, TOKdsymbol,
|
||||
TOKtypeid, TOKuadd,
|
||||
TOKremove,
|
||||
TOKnewanonclass, TOKcomment,
|
||||
TOKarrayliteral, TOKassocarrayliteral,
|
||||
TOKstructliteral,
|
||||
|
||||
// Operators
|
||||
TOKlt, TOKgt,
|
||||
TOKle, TOKge,
|
||||
TOKequal, TOKnotequal,
|
||||
TOKidentity, TOKnotidentity,
|
||||
TOKindex, TOKis,
|
||||
TOKtobool,
|
||||
|
||||
// 60
|
||||
// NCEG floating point compares
|
||||
// !<>= <> <>= !> !>= !< !<= !<>
|
||||
TOKunord,TOKlg,TOKleg,TOKule,TOKul,TOKuge,TOKug,TOKue,
|
||||
|
||||
TOKshl, TOKshr,
|
||||
TOKshlass, TOKshrass,
|
||||
TOKushr, TOKushrass,
|
||||
TOKcat, TOKcatass, // ~ ~=
|
||||
TOKadd, TOKmin, TOKaddass, TOKminass,
|
||||
TOKmul, TOKdiv, TOKmod,
|
||||
TOKmulass, TOKdivass, TOKmodass,
|
||||
TOKand, TOKor, TOKxor,
|
||||
TOKandass, TOKorass, TOKxorass,
|
||||
TOKassign, TOKnot, TOKtilde,
|
||||
TOKplusplus, TOKminusminus, TOKconstruct, TOKblit,
|
||||
TOKdot, TOKarrow, TOKcomma,
|
||||
TOKquestion, TOKandand, TOKoror,
|
||||
TOKpreplusplus, TOKpreminusminus,
|
||||
|
||||
// 106
|
||||
// Numeric literals
|
||||
TOKint32v, TOKuns32v,
|
||||
TOKint64v, TOKuns64v,
|
||||
TOKfloat32v, TOKfloat64v, TOKfloat80v,
|
||||
TOKimaginary32v, TOKimaginary64v, TOKimaginary80v,
|
||||
|
||||
// Char constants
|
||||
TOKcharv, TOKwcharv, TOKdcharv,
|
||||
|
||||
// Leaf operators
|
||||
TOKidentifier, TOKstring,
|
||||
TOKthis, TOKsuper,
|
||||
TOKhalt, TOKtuple,
|
||||
TOKerror,
|
||||
|
||||
// Basic types
|
||||
TOKvoid,
|
||||
TOKint8, TOKuns8,
|
||||
TOKint16, TOKuns16,
|
||||
TOKint32, TOKuns32,
|
||||
TOKint64, TOKuns64,
|
||||
TOKfloat32, TOKfloat64, TOKfloat80,
|
||||
TOKimaginary32, TOKimaginary64, TOKimaginary80,
|
||||
TOKcomplex32, TOKcomplex64, TOKcomplex80,
|
||||
TOKchar, TOKwchar, TOKdchar, TOKbit, TOKbool,
|
||||
TOKcent, TOKucent,
|
||||
|
||||
// 152
|
||||
// Aggregates
|
||||
TOKstruct, TOKclass, TOKinterface, TOKunion, TOKenum, TOKimport,
|
||||
TOKtypedef, TOKalias, TOKoverride, TOKdelegate, TOKfunction,
|
||||
TOKmixin,
|
||||
|
||||
TOKalign, TOKextern, TOKprivate, TOKprotected, TOKpublic, TOKexport,
|
||||
TOKstatic, /*TOKvirtual,*/ TOKfinal, TOKconst, TOKabstract, TOKvolatile,
|
||||
TOKdebug, TOKdeprecated, TOKin, TOKout, TOKinout, TOKlazy,
|
||||
TOKauto, TOKpackage, TOKmanifest, TOKimmutable,
|
||||
|
||||
// Statements
|
||||
TOKif, TOKelse, TOKwhile, TOKfor, TOKdo, TOKswitch,
|
||||
TOKcase, TOKdefault, TOKbreak, TOKcontinue, TOKwith,
|
||||
TOKsynchronized, TOKreturn, TOKgoto, TOKtry, TOKcatch, TOKfinally,
|
||||
TOKasm, TOKforeach, TOKforeach_reverse,
|
||||
TOKscope,
|
||||
TOKon_scope_exit, TOKon_scope_failure, TOKon_scope_success,
|
||||
|
||||
// Contracts
|
||||
TOKbody, TOKinvariant,
|
||||
|
||||
// Testing
|
||||
TOKunittest,
|
||||
|
||||
// Added after 1.0
|
||||
TOKref,
|
||||
TOKmacro,
|
||||
#if DMDV2
|
||||
TOKtraits,
|
||||
TOKoverloadset,
|
||||
TOKpure,
|
||||
TOKnothrow,
|
||||
TOKtls,
|
||||
TOKgshared,
|
||||
TOKline,
|
||||
TOKfile,
|
||||
TOKshared,
|
||||
TOKat,
|
||||
TOKpow,
|
||||
TOKpowass,
|
||||
#endif
|
||||
|
||||
// LDC specific
|
||||
#if IN_LLVM
|
||||
TOKgep,
|
||||
#endif
|
||||
|
||||
TOKMAX
|
||||
};
|
||||
|
||||
#define TOKwild TOKinout
|
||||
|
||||
#define BASIC_TYPES \
|
||||
TOKwchar: case TOKdchar: \
|
||||
case TOKbit: case TOKbool: case TOKchar: \
|
||||
case TOKint8: case TOKuns8: \
|
||||
case TOKint16: case TOKuns16: \
|
||||
case TOKint32: case TOKuns32: \
|
||||
case TOKint64: case TOKuns64: \
|
||||
case TOKfloat32: case TOKfloat64: case TOKfloat80: \
|
||||
case TOKimaginary32: case TOKimaginary64: case TOKimaginary80: \
|
||||
case TOKcomplex32: case TOKcomplex64: case TOKcomplex80: \
|
||||
case TOKvoid
|
||||
|
||||
#define BASIC_TYPES_X(t) \
|
||||
TOKvoid: t = Type::tvoid; goto LabelX; \
|
||||
case TOKint8: t = Type::tint8; goto LabelX; \
|
||||
case TOKuns8: t = Type::tuns8; goto LabelX; \
|
||||
case TOKint16: t = Type::tint16; goto LabelX; \
|
||||
case TOKuns16: t = Type::tuns16; goto LabelX; \
|
||||
case TOKint32: t = Type::tint32; goto LabelX; \
|
||||
case TOKuns32: t = Type::tuns32; goto LabelX; \
|
||||
case TOKint64: t = Type::tint64; goto LabelX; \
|
||||
case TOKuns64: t = Type::tuns64; goto LabelX; \
|
||||
case TOKfloat32: t = Type::tfloat32; goto LabelX; \
|
||||
case TOKfloat64: t = Type::tfloat64; goto LabelX; \
|
||||
case TOKfloat80: t = Type::tfloat80; goto LabelX; \
|
||||
case TOKimaginary32: t = Type::timaginary32; goto LabelX; \
|
||||
case TOKimaginary64: t = Type::timaginary64; goto LabelX; \
|
||||
case TOKimaginary80: t = Type::timaginary80; goto LabelX; \
|
||||
case TOKcomplex32: t = Type::tcomplex32; goto LabelX; \
|
||||
case TOKcomplex64: t = Type::tcomplex64; goto LabelX; \
|
||||
case TOKcomplex80: t = Type::tcomplex80; goto LabelX; \
|
||||
case TOKbit: t = Type::tbit; goto LabelX; \
|
||||
case TOKbool: t = Type::tbool; goto LabelX; \
|
||||
case TOKchar: t = Type::tchar; goto LabelX; \
|
||||
case TOKwchar: t = Type::twchar; goto LabelX; \
|
||||
case TOKdchar: t = Type::tdchar; goto LabelX; \
|
||||
LabelX
|
||||
|
||||
struct Token
|
||||
{
|
||||
Token *next;
|
||||
unsigned char *ptr; // pointer to first character of this token within buffer
|
||||
enum TOK value;
|
||||
unsigned char *blockComment; // doc comment string prior to this token
|
||||
unsigned char *lineComment; // doc comment for previous token
|
||||
union
|
||||
{
|
||||
// Integers
|
||||
d_int32 int32value;
|
||||
d_uns32 uns32value;
|
||||
d_int64 int64value;
|
||||
d_uns64 uns64value;
|
||||
|
||||
// Floats
|
||||
#ifdef IN_GCC
|
||||
// real_t float80value; // can't use this in a union!
|
||||
#else
|
||||
d_float80 float80value;
|
||||
#endif
|
||||
|
||||
struct
|
||||
{ unsigned char *ustring; // UTF8 string
|
||||
unsigned len;
|
||||
unsigned char postfix; // 'c', 'w', 'd'
|
||||
};
|
||||
|
||||
Identifier *ident;
|
||||
};
|
||||
#ifdef IN_GCC
|
||||
real_t float80value; // can't use this in a union!
|
||||
#endif
|
||||
|
||||
static const char *tochars[TOKMAX];
|
||||
static void *operator new(size_t sz);
|
||||
|
||||
int isKeyword();
|
||||
void print();
|
||||
const char *toChars();
|
||||
static const char *toChars(enum TOK);
|
||||
};
|
||||
|
||||
struct Lexer
|
||||
{
|
||||
static StringTable stringtable;
|
||||
static OutBuffer stringbuffer;
|
||||
static Token *freelist;
|
||||
|
||||
Loc loc; // for error messages
|
||||
|
||||
unsigned char *base; // pointer to start of buffer
|
||||
unsigned char *end; // past end of buffer
|
||||
unsigned char *p; // current character
|
||||
Token token;
|
||||
Module *mod;
|
||||
int doDocComment; // collect doc comment information
|
||||
int anyToken; // !=0 means seen at least one token
|
||||
int commentToken; // !=0 means comments are TOKcomment's
|
||||
|
||||
Lexer(Module *mod,
|
||||
unsigned char *base, unsigned begoffset, unsigned endoffset,
|
||||
int doDocComment, int commentToken);
|
||||
|
||||
static void initKeywords();
|
||||
static Identifier *idPool(const char *s);
|
||||
static Identifier *uniqueId(const char *s);
|
||||
static Identifier *uniqueId(const char *s, int num);
|
||||
|
||||
TOK nextToken();
|
||||
TOK peekNext();
|
||||
TOK peekNext2();
|
||||
void scan(Token *t);
|
||||
Token *peek(Token *t);
|
||||
Token *peekPastParen(Token *t);
|
||||
unsigned escapeSequence();
|
||||
TOK wysiwygStringConstant(Token *t, int tc);
|
||||
TOK hexStringConstant(Token *t);
|
||||
#if DMDV2
|
||||
TOK delimitedStringConstant(Token *t);
|
||||
TOK tokenStringConstant(Token *t);
|
||||
#endif
|
||||
TOK escapeStringConstant(Token *t, int wide);
|
||||
TOK charConstant(Token *t, int wide);
|
||||
void stringPostfix(Token *t);
|
||||
unsigned wchar(unsigned u);
|
||||
TOK number(Token *t);
|
||||
TOK inreal(Token *t);
|
||||
void error(const char *format, ...) IS_PRINTF(2);
|
||||
void error(Loc loc, const char *format, ...) IS_PRINTF(3);
|
||||
void pragma();
|
||||
unsigned decodeUTF();
|
||||
void getDocComment(Token *t, unsigned lineComment);
|
||||
|
||||
static int isValidIdentifier(char *p);
|
||||
static unsigned char *combineComments(unsigned char *c1, unsigned char *c2);
|
||||
};
|
||||
|
||||
#endif /* DMD_LEXER_H */
|
||||
|
||||
98
dmd2/lib.h
98
dmd2/lib.h
@@ -1,49 +1,49 @@
|
||||
|
||||
// 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_LIB_H
|
||||
#define DMD_LIB_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
struct ObjModule;
|
||||
|
||||
struct ObjSymbol
|
||||
{
|
||||
char *name;
|
||||
ObjModule *om;
|
||||
};
|
||||
|
||||
struct Library
|
||||
{
|
||||
File *libfile;
|
||||
Array objmodules; // ObjModule[]
|
||||
Array objsymbols; // ObjSymbol[]
|
||||
|
||||
StringTable tab;
|
||||
|
||||
Library();
|
||||
void setFilename(char *dir, char *filename);
|
||||
void addObject(const char *module_name, void *buf, size_t buflen);
|
||||
void addLibrary(void *buf, size_t buflen);
|
||||
void write();
|
||||
|
||||
private:
|
||||
void addSymbol(ObjModule *om, char *name, int pickAny = 0);
|
||||
void scanObjModule(ObjModule *om);
|
||||
unsigned short numDictPages(unsigned padding);
|
||||
int FillDict(unsigned char *bucketsP, unsigned short uNumPages);
|
||||
void WriteLibToBuffer(OutBuffer *libbuf);
|
||||
};
|
||||
|
||||
#endif /* DMD_LIB_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_LIB_H
|
||||
#define DMD_LIB_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
struct ObjModule;
|
||||
|
||||
struct ObjSymbol
|
||||
{
|
||||
char *name;
|
||||
ObjModule *om;
|
||||
};
|
||||
|
||||
struct Library
|
||||
{
|
||||
File *libfile;
|
||||
Array objmodules; // ObjModule[]
|
||||
Array objsymbols; // ObjSymbol[]
|
||||
|
||||
StringTable tab;
|
||||
|
||||
Library();
|
||||
void setFilename(char *dir, char *filename);
|
||||
void addObject(const char *module_name, void *buf, size_t buflen);
|
||||
void addLibrary(void *buf, size_t buflen);
|
||||
void write();
|
||||
|
||||
private:
|
||||
void addSymbol(ObjModule *om, char *name, int pickAny = 0);
|
||||
void scanObjModule(ObjModule *om);
|
||||
unsigned short numDictPages(unsigned padding);
|
||||
int FillDict(unsigned char *bucketsP, unsigned short uNumPages);
|
||||
void WriteLibToBuffer(OutBuffer *libbuf);
|
||||
};
|
||||
|
||||
#endif /* DMD_LIB_H */
|
||||
|
||||
|
||||
898
dmd2/macro.c
898
dmd2/macro.c
@@ -1,449 +1,449 @@
|
||||
|
||||
// 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.
|
||||
|
||||
/* Simple macro text processor.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "rmem.h"
|
||||
#include "root.h"
|
||||
|
||||
#include "macro.h"
|
||||
|
||||
#define isidstart(c) (isalpha(c) || (c) == '_')
|
||||
#define isidchar(c) (isalnum(c) || (c) == '_')
|
||||
|
||||
unsigned char *memdup(unsigned char *p, size_t len)
|
||||
{
|
||||
return (unsigned char *)memcpy(mem.malloc(len), p, len);
|
||||
}
|
||||
|
||||
Macro::Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen)
|
||||
{
|
||||
next = NULL;
|
||||
|
||||
#if 1
|
||||
this->name = name;
|
||||
this->namelen = namelen;
|
||||
|
||||
this->text = text;
|
||||
this->textlen = textlen;
|
||||
#else
|
||||
this->name = name;
|
||||
this->namelen = namelen;
|
||||
|
||||
this->text = text;
|
||||
this->textlen = textlen;
|
||||
#endif
|
||||
inuse = 0;
|
||||
}
|
||||
|
||||
|
||||
Macro *Macro::search(unsigned char *name, size_t namelen)
|
||||
{ Macro *table;
|
||||
|
||||
//printf("Macro::search(%.*s)\n", namelen, name);
|
||||
for (table = this; table; table = table->next)
|
||||
{
|
||||
if (table->namelen == namelen &&
|
||||
memcmp(table->name, name, namelen) == 0)
|
||||
{
|
||||
//printf("\tfound %d\n", table->textlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
Macro *Macro::define(Macro **ptable, unsigned char *name, size_t namelen, unsigned char *text, size_t textlen)
|
||||
{
|
||||
//printf("Macro::define('%.*s' = '%.*s')\n", namelen, name, textlen, text);
|
||||
|
||||
Macro *table;
|
||||
|
||||
//assert(ptable);
|
||||
for (table = *ptable; table; table = table->next)
|
||||
{
|
||||
if (table->namelen == namelen &&
|
||||
memcmp(table->name, name, namelen) == 0)
|
||||
{
|
||||
table->text = text;
|
||||
table->textlen = textlen;
|
||||
return table;
|
||||
}
|
||||
}
|
||||
table = new Macro(name, namelen, text, textlen);
|
||||
table->next = *ptable;
|
||||
*ptable = table;
|
||||
return table;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
* Given buffer p[0..end], extract argument marg[0..marglen].
|
||||
* Params:
|
||||
* n 0: get entire argument
|
||||
* 1..9: get nth argument
|
||||
* -1: get 2nd through end
|
||||
*/
|
||||
|
||||
unsigned extractArgN(unsigned char *p, unsigned end, unsigned char **pmarg, unsigned *pmarglen, int n)
|
||||
{
|
||||
/* Scan forward for matching right parenthesis.
|
||||
* Nest parentheses.
|
||||
* Skip over $( and $)
|
||||
* Skip over "..." and '...' strings inside HTML tags.
|
||||
* Skip over <!-- ... --> comments.
|
||||
* Skip over previous macro insertions
|
||||
* Set marglen.
|
||||
*/
|
||||
unsigned parens = 1;
|
||||
unsigned char instring = 0;
|
||||
unsigned incomment = 0;
|
||||
unsigned intag = 0;
|
||||
unsigned inexp = 0;
|
||||
unsigned argn = 0;
|
||||
|
||||
unsigned v = 0;
|
||||
|
||||
Largstart:
|
||||
#if 1
|
||||
// Skip first space, if any, to find the start of the macro argument
|
||||
if (v < end && isspace(p[v]))
|
||||
v++;
|
||||
#else
|
||||
// Skip past spaces to find the start of the macro argument
|
||||
for (; v < end && isspace(p[v]); v++)
|
||||
;
|
||||
#endif
|
||||
*pmarg = p + v;
|
||||
|
||||
for (; v < end; v++)
|
||||
{ unsigned char c = p[v];
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case ',':
|
||||
if (!inexp && !instring && !incomment && parens == 1)
|
||||
{
|
||||
argn++;
|
||||
if (argn == 1 && n == -1)
|
||||
{ v++;
|
||||
goto Largstart;
|
||||
}
|
||||
if (argn == n)
|
||||
break;
|
||||
if (argn + 1 == n)
|
||||
{ v++;
|
||||
goto Largstart;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case '(':
|
||||
if (!inexp && !instring && !incomment)
|
||||
parens++;
|
||||
continue;
|
||||
|
||||
case ')':
|
||||
if (!inexp && !instring && !incomment && --parens == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
if (!inexp && !incomment && intag)
|
||||
{
|
||||
if (c == instring)
|
||||
instring = 0;
|
||||
else if (!instring)
|
||||
instring = c;
|
||||
}
|
||||
continue;
|
||||
|
||||
case '<':
|
||||
if (!inexp && !instring && !incomment)
|
||||
{
|
||||
if (v + 6 < end &&
|
||||
p[v + 1] == '!' &&
|
||||
p[v + 2] == '-' &&
|
||||
p[v + 3] == '-')
|
||||
{
|
||||
incomment = 1;
|
||||
v += 3;
|
||||
}
|
||||
else if (v + 2 < end &&
|
||||
isalpha(p[v + 1]))
|
||||
intag = 1;
|
||||
}
|
||||
continue;
|
||||
|
||||
case '>':
|
||||
if (!inexp)
|
||||
intag = 0;
|
||||
continue;
|
||||
|
||||
case '-':
|
||||
if (!inexp &&
|
||||
!instring &&
|
||||
incomment &&
|
||||
v + 2 < end &&
|
||||
p[v + 1] == '-' &&
|
||||
p[v + 2] == '>')
|
||||
{
|
||||
incomment = 0;
|
||||
v += 2;
|
||||
}
|
||||
continue;
|
||||
|
||||
case 0xFF:
|
||||
if (v + 1 < end)
|
||||
{
|
||||
if (p[v + 1] == '{')
|
||||
inexp++;
|
||||
else if (p[v + 1] == '}')
|
||||
inexp--;
|
||||
}
|
||||
continue;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (argn == 0 && n == -1)
|
||||
*pmarg = p + v;
|
||||
*pmarglen = p + v - *pmarg;
|
||||
//printf("extractArg%d('%.*s') = '%.*s'\n", n, end, p, *pmarglen, *pmarg);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* Expand macro in place in buf.
|
||||
* Only look at the text in buf from start to end.
|
||||
*/
|
||||
|
||||
void Macro::expand(OutBuffer *buf, unsigned start, unsigned *pend,
|
||||
unsigned char *arg, unsigned arglen)
|
||||
{
|
||||
#if 0
|
||||
printf("Macro::expand(buf[%d..%d], arg = '%.*s')\n", start, *pend, arglen, arg);
|
||||
printf("Buf is: '%.*s'\n", *pend - start, buf->data + start);
|
||||
#endif
|
||||
|
||||
static int nest;
|
||||
if (nest > 100) // limit recursive expansion
|
||||
return;
|
||||
nest++;
|
||||
|
||||
unsigned end = *pend;
|
||||
assert(start <= end);
|
||||
assert(end <= buf->offset);
|
||||
|
||||
/* First pass - replace $0
|
||||
*/
|
||||
arg = memdup(arg, arglen);
|
||||
for (unsigned u = start; u + 1 < end; )
|
||||
{
|
||||
unsigned char *p = buf->data; // buf->data is not loop invariant
|
||||
|
||||
/* Look for $0, but not $$0, and replace it with arg.
|
||||
*/
|
||||
if (p[u] == '$' && (isdigit(p[u + 1]) || p[u + 1] == '+'))
|
||||
{
|
||||
if (u > start && p[u - 1] == '$')
|
||||
{ // Don't expand $$0, but replace it with $0
|
||||
buf->remove(u - 1, 1);
|
||||
end--;
|
||||
u += 1; // now u is one past the closing '1'
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned char c = p[u + 1];
|
||||
int n = (c == '+') ? -1 : c - '0';
|
||||
|
||||
unsigned char *marg;
|
||||
unsigned marglen;
|
||||
extractArgN(arg, arglen, &marg, &marglen, n);
|
||||
if (marglen == 0)
|
||||
{ // Just remove macro invocation
|
||||
//printf("Replacing '$%c' with '%.*s'\n", p[u + 1], marglen, marg);
|
||||
buf->remove(u, 2);
|
||||
end -= 2;
|
||||
}
|
||||
else if (c == '+')
|
||||
{
|
||||
// Replace '$+' with 'arg'
|
||||
//printf("Replacing '$%c' with '%.*s'\n", p[u + 1], marglen, marg);
|
||||
buf->remove(u, 2);
|
||||
buf->insert(u, marg, marglen);
|
||||
end += marglen - 2;
|
||||
|
||||
// Scan replaced text for further expansion
|
||||
unsigned mend = u + marglen;
|
||||
expand(buf, u, &mend, NULL, 0);
|
||||
end += mend - (u + marglen);
|
||||
u = mend;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Replace '$1' with '\xFF{arg\xFF}'
|
||||
//printf("Replacing '$%c' with '\xFF{%.*s\xFF}'\n", p[u + 1], marglen, marg);
|
||||
buf->data[u] = 0xFF;
|
||||
buf->data[u + 1] = '{';
|
||||
buf->insert(u + 2, marg, marglen);
|
||||
buf->insert(u + 2 + marglen, "\xFF}", 2);
|
||||
end += -2 + 2 + marglen + 2;
|
||||
|
||||
// Scan replaced text for further expansion
|
||||
unsigned mend = u + 2 + marglen;
|
||||
expand(buf, u + 2, &mend, NULL, 0);
|
||||
end += mend - (u + 2 + marglen);
|
||||
u = mend;
|
||||
}
|
||||
//printf("u = %d, end = %d\n", u, end);
|
||||
//printf("#%.*s#\n", end, &buf->data[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
u++;
|
||||
}
|
||||
|
||||
/* Second pass - replace other macros
|
||||
*/
|
||||
for (unsigned u = start; u + 4 < end; )
|
||||
{
|
||||
unsigned char *p = buf->data; // buf->data is not loop invariant
|
||||
|
||||
/* A valid start of macro expansion is $(c, where c is
|
||||
* an id start character, and not $$(c.
|
||||
*/
|
||||
if (p[u] == '$' && p[u + 1] == '(' && isidstart(p[u + 2]))
|
||||
{
|
||||
//printf("\tfound macro start '%c'\n", p[u + 2]);
|
||||
unsigned char *name = p + u + 2;
|
||||
unsigned namelen = 0;
|
||||
|
||||
unsigned char *marg;
|
||||
unsigned marglen;
|
||||
|
||||
unsigned v;
|
||||
/* Scan forward to find end of macro name and
|
||||
* beginning of macro argument (marg).
|
||||
*/
|
||||
for (v = u + 2; v < end; v++)
|
||||
{ unsigned char c = p[v];
|
||||
|
||||
if (!isidchar(c))
|
||||
{ // We've gone past the end of the macro name.
|
||||
namelen = v - (u + 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
v += extractArgN(p + v, end - v, &marg, &marglen, 0);
|
||||
assert(v <= end);
|
||||
|
||||
if (v < end)
|
||||
{ // v is on the closing ')'
|
||||
if (u > start && p[u - 1] == '$')
|
||||
{ // Don't expand $$(NAME), but replace it with $(NAME)
|
||||
buf->remove(u - 1, 1);
|
||||
end--;
|
||||
u = v; // now u is one past the closing ')'
|
||||
continue;
|
||||
}
|
||||
|
||||
Macro *m = search(name, namelen);
|
||||
if (m)
|
||||
{
|
||||
#if 0
|
||||
if (m->textlen && m->text[0] == ' ')
|
||||
{ m->text++;
|
||||
m->textlen--;
|
||||
}
|
||||
#endif
|
||||
if (m->inuse && marglen == 0)
|
||||
{ // Remove macro invocation
|
||||
buf->remove(u, v + 1 - u);
|
||||
end -= v + 1 - u;
|
||||
}
|
||||
else if (m->inuse && arglen == marglen && memcmp(arg, marg, arglen) == 0)
|
||||
{ // Recursive expansion; just leave in place
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("\tmacro '%.*s'(%.*s) = '%.*s'\n", m->namelen, m->name, marglen, marg, m->textlen, m->text);
|
||||
#if 1
|
||||
marg = memdup(marg, marglen);
|
||||
// Insert replacement text
|
||||
buf->spread(v + 1, 2 + m->textlen + 2);
|
||||
buf->data[v + 1] = 0xFF;
|
||||
buf->data[v + 2] = '{';
|
||||
memcpy(buf->data + v + 3, m->text, m->textlen);
|
||||
buf->data[v + 3 + m->textlen] = 0xFF;
|
||||
buf->data[v + 3 + m->textlen + 1] = '}';
|
||||
|
||||
end += 2 + m->textlen + 2;
|
||||
|
||||
// Scan replaced text for further expansion
|
||||
m->inuse++;
|
||||
unsigned mend = v + 1 + 2+m->textlen+2;
|
||||
expand(buf, v + 1, &mend, marg, marglen);
|
||||
end += mend - (v + 1 + 2+m->textlen+2);
|
||||
m->inuse--;
|
||||
|
||||
buf->remove(u, v + 1 - u);
|
||||
end -= v + 1 - u;
|
||||
u += mend - (v + 1);
|
||||
#else
|
||||
// Insert replacement text
|
||||
buf->insert(v + 1, m->text, m->textlen);
|
||||
end += m->textlen;
|
||||
|
||||
// Scan replaced text for further expansion
|
||||
m->inuse++;
|
||||
unsigned mend = v + 1 + m->textlen;
|
||||
expand(buf, v + 1, &mend, marg, marglen);
|
||||
end += mend - (v + 1 + m->textlen);
|
||||
m->inuse--;
|
||||
|
||||
buf->remove(u, v + 1 - u);
|
||||
end -= v + 1 - u;
|
||||
u += mend - (v + 1);
|
||||
#endif
|
||||
mem.free(marg);
|
||||
//printf("u = %d, end = %d\n", u, end);
|
||||
//printf("#%.*s#\n", end - u, &buf->data[u]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Replace $(NAME) with nothing
|
||||
buf->remove(u, v + 1 - u);
|
||||
end -= (v + 1 - u);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
u++;
|
||||
}
|
||||
mem.free(arg);
|
||||
*pend = end;
|
||||
nest--;
|
||||
}
|
||||
|
||||
// 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.
|
||||
|
||||
/* Simple macro text processor.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "rmem.h"
|
||||
#include "root.h"
|
||||
|
||||
#include "macro.h"
|
||||
|
||||
#define isidstart(c) (isalpha(c) || (c) == '_')
|
||||
#define isidchar(c) (isalnum(c) || (c) == '_')
|
||||
|
||||
unsigned char *memdup(unsigned char *p, size_t len)
|
||||
{
|
||||
return (unsigned char *)memcpy(mem.malloc(len), p, len);
|
||||
}
|
||||
|
||||
Macro::Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen)
|
||||
{
|
||||
next = NULL;
|
||||
|
||||
#if 1
|
||||
this->name = name;
|
||||
this->namelen = namelen;
|
||||
|
||||
this->text = text;
|
||||
this->textlen = textlen;
|
||||
#else
|
||||
this->name = name;
|
||||
this->namelen = namelen;
|
||||
|
||||
this->text = text;
|
||||
this->textlen = textlen;
|
||||
#endif
|
||||
inuse = 0;
|
||||
}
|
||||
|
||||
|
||||
Macro *Macro::search(unsigned char *name, size_t namelen)
|
||||
{ Macro *table;
|
||||
|
||||
//printf("Macro::search(%.*s)\n", namelen, name);
|
||||
for (table = this; table; table = table->next)
|
||||
{
|
||||
if (table->namelen == namelen &&
|
||||
memcmp(table->name, name, namelen) == 0)
|
||||
{
|
||||
//printf("\tfound %d\n", table->textlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return table;
|
||||
}
|
||||
|
||||
Macro *Macro::define(Macro **ptable, unsigned char *name, size_t namelen, unsigned char *text, size_t textlen)
|
||||
{
|
||||
//printf("Macro::define('%.*s' = '%.*s')\n", namelen, name, textlen, text);
|
||||
|
||||
Macro *table;
|
||||
|
||||
//assert(ptable);
|
||||
for (table = *ptable; table; table = table->next)
|
||||
{
|
||||
if (table->namelen == namelen &&
|
||||
memcmp(table->name, name, namelen) == 0)
|
||||
{
|
||||
table->text = text;
|
||||
table->textlen = textlen;
|
||||
return table;
|
||||
}
|
||||
}
|
||||
table = new Macro(name, namelen, text, textlen);
|
||||
table->next = *ptable;
|
||||
*ptable = table;
|
||||
return table;
|
||||
}
|
||||
|
||||
/**********************************************************
|
||||
* Given buffer p[0..end], extract argument marg[0..marglen].
|
||||
* Params:
|
||||
* n 0: get entire argument
|
||||
* 1..9: get nth argument
|
||||
* -1: get 2nd through end
|
||||
*/
|
||||
|
||||
unsigned extractArgN(unsigned char *p, unsigned end, unsigned char **pmarg, unsigned *pmarglen, int n)
|
||||
{
|
||||
/* Scan forward for matching right parenthesis.
|
||||
* Nest parentheses.
|
||||
* Skip over $( and $)
|
||||
* Skip over "..." and '...' strings inside HTML tags.
|
||||
* Skip over <!-- ... --> comments.
|
||||
* Skip over previous macro insertions
|
||||
* Set marglen.
|
||||
*/
|
||||
unsigned parens = 1;
|
||||
unsigned char instring = 0;
|
||||
unsigned incomment = 0;
|
||||
unsigned intag = 0;
|
||||
unsigned inexp = 0;
|
||||
unsigned argn = 0;
|
||||
|
||||
unsigned v = 0;
|
||||
|
||||
Largstart:
|
||||
#if 1
|
||||
// Skip first space, if any, to find the start of the macro argument
|
||||
if (v < end && isspace(p[v]))
|
||||
v++;
|
||||
#else
|
||||
// Skip past spaces to find the start of the macro argument
|
||||
for (; v < end && isspace(p[v]); v++)
|
||||
;
|
||||
#endif
|
||||
*pmarg = p + v;
|
||||
|
||||
for (; v < end; v++)
|
||||
{ unsigned char c = p[v];
|
||||
|
||||
switch (c)
|
||||
{
|
||||
case ',':
|
||||
if (!inexp && !instring && !incomment && parens == 1)
|
||||
{
|
||||
argn++;
|
||||
if (argn == 1 && n == -1)
|
||||
{ v++;
|
||||
goto Largstart;
|
||||
}
|
||||
if (argn == n)
|
||||
break;
|
||||
if (argn + 1 == n)
|
||||
{ v++;
|
||||
goto Largstart;
|
||||
}
|
||||
}
|
||||
continue;
|
||||
|
||||
case '(':
|
||||
if (!inexp && !instring && !incomment)
|
||||
parens++;
|
||||
continue;
|
||||
|
||||
case ')':
|
||||
if (!inexp && !instring && !incomment && --parens == 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
continue;
|
||||
|
||||
case '"':
|
||||
case '\'':
|
||||
if (!inexp && !incomment && intag)
|
||||
{
|
||||
if (c == instring)
|
||||
instring = 0;
|
||||
else if (!instring)
|
||||
instring = c;
|
||||
}
|
||||
continue;
|
||||
|
||||
case '<':
|
||||
if (!inexp && !instring && !incomment)
|
||||
{
|
||||
if (v + 6 < end &&
|
||||
p[v + 1] == '!' &&
|
||||
p[v + 2] == '-' &&
|
||||
p[v + 3] == '-')
|
||||
{
|
||||
incomment = 1;
|
||||
v += 3;
|
||||
}
|
||||
else if (v + 2 < end &&
|
||||
isalpha(p[v + 1]))
|
||||
intag = 1;
|
||||
}
|
||||
continue;
|
||||
|
||||
case '>':
|
||||
if (!inexp)
|
||||
intag = 0;
|
||||
continue;
|
||||
|
||||
case '-':
|
||||
if (!inexp &&
|
||||
!instring &&
|
||||
incomment &&
|
||||
v + 2 < end &&
|
||||
p[v + 1] == '-' &&
|
||||
p[v + 2] == '>')
|
||||
{
|
||||
incomment = 0;
|
||||
v += 2;
|
||||
}
|
||||
continue;
|
||||
|
||||
case 0xFF:
|
||||
if (v + 1 < end)
|
||||
{
|
||||
if (p[v + 1] == '{')
|
||||
inexp++;
|
||||
else if (p[v + 1] == '}')
|
||||
inexp--;
|
||||
}
|
||||
continue;
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (argn == 0 && n == -1)
|
||||
*pmarg = p + v;
|
||||
*pmarglen = p + v - *pmarg;
|
||||
//printf("extractArg%d('%.*s') = '%.*s'\n", n, end, p, *pmarglen, *pmarg);
|
||||
return v;
|
||||
}
|
||||
|
||||
|
||||
/*****************************************************
|
||||
* Expand macro in place in buf.
|
||||
* Only look at the text in buf from start to end.
|
||||
*/
|
||||
|
||||
void Macro::expand(OutBuffer *buf, unsigned start, unsigned *pend,
|
||||
unsigned char *arg, unsigned arglen)
|
||||
{
|
||||
#if 0
|
||||
printf("Macro::expand(buf[%d..%d], arg = '%.*s')\n", start, *pend, arglen, arg);
|
||||
printf("Buf is: '%.*s'\n", *pend - start, buf->data + start);
|
||||
#endif
|
||||
|
||||
static int nest;
|
||||
if (nest > 100) // limit recursive expansion
|
||||
return;
|
||||
nest++;
|
||||
|
||||
unsigned end = *pend;
|
||||
assert(start <= end);
|
||||
assert(end <= buf->offset);
|
||||
|
||||
/* First pass - replace $0
|
||||
*/
|
||||
arg = memdup(arg, arglen);
|
||||
for (unsigned u = start; u + 1 < end; )
|
||||
{
|
||||
unsigned char *p = buf->data; // buf->data is not loop invariant
|
||||
|
||||
/* Look for $0, but not $$0, and replace it with arg.
|
||||
*/
|
||||
if (p[u] == '$' && (isdigit(p[u + 1]) || p[u + 1] == '+'))
|
||||
{
|
||||
if (u > start && p[u - 1] == '$')
|
||||
{ // Don't expand $$0, but replace it with $0
|
||||
buf->remove(u - 1, 1);
|
||||
end--;
|
||||
u += 1; // now u is one past the closing '1'
|
||||
continue;
|
||||
}
|
||||
|
||||
unsigned char c = p[u + 1];
|
||||
int n = (c == '+') ? -1 : c - '0';
|
||||
|
||||
unsigned char *marg;
|
||||
unsigned marglen;
|
||||
extractArgN(arg, arglen, &marg, &marglen, n);
|
||||
if (marglen == 0)
|
||||
{ // Just remove macro invocation
|
||||
//printf("Replacing '$%c' with '%.*s'\n", p[u + 1], marglen, marg);
|
||||
buf->remove(u, 2);
|
||||
end -= 2;
|
||||
}
|
||||
else if (c == '+')
|
||||
{
|
||||
// Replace '$+' with 'arg'
|
||||
//printf("Replacing '$%c' with '%.*s'\n", p[u + 1], marglen, marg);
|
||||
buf->remove(u, 2);
|
||||
buf->insert(u, marg, marglen);
|
||||
end += marglen - 2;
|
||||
|
||||
// Scan replaced text for further expansion
|
||||
unsigned mend = u + marglen;
|
||||
expand(buf, u, &mend, NULL, 0);
|
||||
end += mend - (u + marglen);
|
||||
u = mend;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Replace '$1' with '\xFF{arg\xFF}'
|
||||
//printf("Replacing '$%c' with '\xFF{%.*s\xFF}'\n", p[u + 1], marglen, marg);
|
||||
buf->data[u] = 0xFF;
|
||||
buf->data[u + 1] = '{';
|
||||
buf->insert(u + 2, marg, marglen);
|
||||
buf->insert(u + 2 + marglen, "\xFF}", 2);
|
||||
end += -2 + 2 + marglen + 2;
|
||||
|
||||
// Scan replaced text for further expansion
|
||||
unsigned mend = u + 2 + marglen;
|
||||
expand(buf, u + 2, &mend, NULL, 0);
|
||||
end += mend - (u + 2 + marglen);
|
||||
u = mend;
|
||||
}
|
||||
//printf("u = %d, end = %d\n", u, end);
|
||||
//printf("#%.*s#\n", end, &buf->data[0]);
|
||||
continue;
|
||||
}
|
||||
|
||||
u++;
|
||||
}
|
||||
|
||||
/* Second pass - replace other macros
|
||||
*/
|
||||
for (unsigned u = start; u + 4 < end; )
|
||||
{
|
||||
unsigned char *p = buf->data; // buf->data is not loop invariant
|
||||
|
||||
/* A valid start of macro expansion is $(c, where c is
|
||||
* an id start character, and not $$(c.
|
||||
*/
|
||||
if (p[u] == '$' && p[u + 1] == '(' && isidstart(p[u + 2]))
|
||||
{
|
||||
//printf("\tfound macro start '%c'\n", p[u + 2]);
|
||||
unsigned char *name = p + u + 2;
|
||||
unsigned namelen = 0;
|
||||
|
||||
unsigned char *marg;
|
||||
unsigned marglen;
|
||||
|
||||
unsigned v;
|
||||
/* Scan forward to find end of macro name and
|
||||
* beginning of macro argument (marg).
|
||||
*/
|
||||
for (v = u + 2; v < end; v++)
|
||||
{ unsigned char c = p[v];
|
||||
|
||||
if (!isidchar(c))
|
||||
{ // We've gone past the end of the macro name.
|
||||
namelen = v - (u + 2);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
v += extractArgN(p + v, end - v, &marg, &marglen, 0);
|
||||
assert(v <= end);
|
||||
|
||||
if (v < end)
|
||||
{ // v is on the closing ')'
|
||||
if (u > start && p[u - 1] == '$')
|
||||
{ // Don't expand $$(NAME), but replace it with $(NAME)
|
||||
buf->remove(u - 1, 1);
|
||||
end--;
|
||||
u = v; // now u is one past the closing ')'
|
||||
continue;
|
||||
}
|
||||
|
||||
Macro *m = search(name, namelen);
|
||||
if (m)
|
||||
{
|
||||
#if 0
|
||||
if (m->textlen && m->text[0] == ' ')
|
||||
{ m->text++;
|
||||
m->textlen--;
|
||||
}
|
||||
#endif
|
||||
if (m->inuse && marglen == 0)
|
||||
{ // Remove macro invocation
|
||||
buf->remove(u, v + 1 - u);
|
||||
end -= v + 1 - u;
|
||||
}
|
||||
else if (m->inuse && arglen == marglen && memcmp(arg, marg, arglen) == 0)
|
||||
{ // Recursive expansion; just leave in place
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
//printf("\tmacro '%.*s'(%.*s) = '%.*s'\n", m->namelen, m->name, marglen, marg, m->textlen, m->text);
|
||||
#if 1
|
||||
marg = memdup(marg, marglen);
|
||||
// Insert replacement text
|
||||
buf->spread(v + 1, 2 + m->textlen + 2);
|
||||
buf->data[v + 1] = 0xFF;
|
||||
buf->data[v + 2] = '{';
|
||||
memcpy(buf->data + v + 3, m->text, m->textlen);
|
||||
buf->data[v + 3 + m->textlen] = 0xFF;
|
||||
buf->data[v + 3 + m->textlen + 1] = '}';
|
||||
|
||||
end += 2 + m->textlen + 2;
|
||||
|
||||
// Scan replaced text for further expansion
|
||||
m->inuse++;
|
||||
unsigned mend = v + 1 + 2+m->textlen+2;
|
||||
expand(buf, v + 1, &mend, marg, marglen);
|
||||
end += mend - (v + 1 + 2+m->textlen+2);
|
||||
m->inuse--;
|
||||
|
||||
buf->remove(u, v + 1 - u);
|
||||
end -= v + 1 - u;
|
||||
u += mend - (v + 1);
|
||||
#else
|
||||
// Insert replacement text
|
||||
buf->insert(v + 1, m->text, m->textlen);
|
||||
end += m->textlen;
|
||||
|
||||
// Scan replaced text for further expansion
|
||||
m->inuse++;
|
||||
unsigned mend = v + 1 + m->textlen;
|
||||
expand(buf, v + 1, &mend, marg, marglen);
|
||||
end += mend - (v + 1 + m->textlen);
|
||||
m->inuse--;
|
||||
|
||||
buf->remove(u, v + 1 - u);
|
||||
end -= v + 1 - u;
|
||||
u += mend - (v + 1);
|
||||
#endif
|
||||
mem.free(marg);
|
||||
//printf("u = %d, end = %d\n", u, end);
|
||||
//printf("#%.*s#\n", end - u, &buf->data[u]);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// Replace $(NAME) with nothing
|
||||
buf->remove(u, v + 1 - u);
|
||||
end -= (v + 1 - u);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
u++;
|
||||
}
|
||||
mem.free(arg);
|
||||
*pend = end;
|
||||
nest--;
|
||||
}
|
||||
|
||||
88
dmd2/macro.h
88
dmd2/macro.h
@@ -1,44 +1,44 @@
|
||||
|
||||
// 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.
|
||||
|
||||
#ifndef DMD_MACRO_H
|
||||
#define DMD_MACRO_H 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "root.h"
|
||||
|
||||
|
||||
class Macro
|
||||
{
|
||||
Macro *next; // next in list
|
||||
|
||||
unsigned char *name; // macro name
|
||||
size_t namelen; // length of macro name
|
||||
|
||||
unsigned char *text; // macro replacement text
|
||||
size_t textlen; // length of replacement text
|
||||
|
||||
int inuse; // macro is in use (don't expand)
|
||||
|
||||
Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen);
|
||||
Macro *search(unsigned char *name, size_t namelen);
|
||||
|
||||
public:
|
||||
static Macro *define(Macro **ptable, unsigned char *name, size_t namelen, unsigned char *text, size_t textlen);
|
||||
|
||||
void expand(OutBuffer *buf, unsigned start, unsigned *pend,
|
||||
unsigned char *arg, unsigned arglen);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// 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.
|
||||
|
||||
#ifndef DMD_MACRO_H
|
||||
#define DMD_MACRO_H 1
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "root.h"
|
||||
|
||||
|
||||
class Macro
|
||||
{
|
||||
Macro *next; // next in list
|
||||
|
||||
unsigned char *name; // macro name
|
||||
size_t namelen; // length of macro name
|
||||
|
||||
unsigned char *text; // macro replacement text
|
||||
size_t textlen; // length of replacement text
|
||||
|
||||
int inuse; // macro is in use (don't expand)
|
||||
|
||||
Macro(unsigned char *name, size_t namelen, unsigned char *text, size_t textlen);
|
||||
Macro *search(unsigned char *name, size_t namelen);
|
||||
|
||||
public:
|
||||
static Macro *define(Macro **ptable, unsigned char *name, size_t namelen, unsigned char *text, size_t textlen);
|
||||
|
||||
void expand(OutBuffer *buf, unsigned start, unsigned *pend,
|
||||
unsigned char *arg, unsigned arglen);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
596
dmd2/mangle.c
596
dmd2/mangle.c
@@ -1,298 +1,298 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "root.h"
|
||||
|
||||
#include "init.h"
|
||||
#include "declaration.h"
|
||||
#include "aggregate.h"
|
||||
#include "mtype.h"
|
||||
#include "attrib.h"
|
||||
#include "template.h"
|
||||
#include "id.h"
|
||||
#include "module.h"
|
||||
|
||||
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
|
||||
char *cpp_mangle(Dsymbol *s);
|
||||
#endif
|
||||
|
||||
char *mangle(Declaration *sthis)
|
||||
{
|
||||
OutBuffer buf;
|
||||
char *id;
|
||||
Dsymbol *s;
|
||||
|
||||
//printf("::mangle(%s)\n", sthis->toChars());
|
||||
s = sthis;
|
||||
do
|
||||
{
|
||||
//printf("mangle: s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent);
|
||||
if (s->ident)
|
||||
{
|
||||
FuncDeclaration *fd = s->isFuncDeclaration();
|
||||
if (s != sthis && fd)
|
||||
{
|
||||
id = mangle(fd);
|
||||
buf.prependstring(id);
|
||||
goto L1;
|
||||
}
|
||||
else
|
||||
{
|
||||
id = s->ident->toChars();
|
||||
int len = strlen(id);
|
||||
char tmp[sizeof(len) * 3 + 1];
|
||||
buf.prependstring(id);
|
||||
sprintf(tmp, "%d", len);
|
||||
buf.prependstring(tmp);
|
||||
}
|
||||
}
|
||||
else
|
||||
buf.prependstring("0");
|
||||
s = s->parent;
|
||||
} while (s);
|
||||
|
||||
// buf.prependstring("_D");
|
||||
L1:
|
||||
//printf("deco = '%s'\n", sthis->type->deco ? sthis->type->deco : "null");
|
||||
//printf("sthis->type = %s\n", sthis->type->toChars());
|
||||
FuncDeclaration *fd = sthis->isFuncDeclaration();
|
||||
if (fd && (fd->needThis() || fd->isNested()))
|
||||
buf.writeByte(Type::needThisPrefix());
|
||||
if (sthis->type->deco)
|
||||
buf.writestring(sthis->type->deco);
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!fd->inferRetType)
|
||||
printf("%s\n", fd->toChars());
|
||||
#endif
|
||||
assert(fd->inferRetType);
|
||||
}
|
||||
|
||||
id = buf.toChars();
|
||||
buf.data = NULL;
|
||||
return id;
|
||||
}
|
||||
|
||||
char *Declaration::mangle()
|
||||
#if __DMC__
|
||||
__out(result)
|
||||
{
|
||||
int len = strlen(result);
|
||||
|
||||
assert(len > 0);
|
||||
//printf("mangle: '%s' => '%s'\n", toChars(), result);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
assert(result[i] == '_' ||
|
||||
result[i] == '@' ||
|
||||
isalnum(result[i]) || result[i] & 0x80);
|
||||
}
|
||||
}
|
||||
__body
|
||||
#endif
|
||||
{
|
||||
//printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n", this, toChars(), parent ? parent->toChars() : "null", linkage);
|
||||
if (!parent || parent->isModule() || linkage == LINKcpp) // if at global scope
|
||||
{
|
||||
// If it's not a D declaration, no mangling
|
||||
switch (linkage)
|
||||
{
|
||||
case LINKd:
|
||||
break;
|
||||
|
||||
#if IN_LLVM
|
||||
case LINKintrinsic:
|
||||
#endif
|
||||
case LINKc:
|
||||
case LINKwindows:
|
||||
case LINKpascal:
|
||||
return ident->toChars();
|
||||
|
||||
case LINKcpp:
|
||||
#if CPP_MANGLE
|
||||
return cpp_mangle(this);
|
||||
#else
|
||||
// Windows C++ mangling is done by C++ back end
|
||||
return ident->toChars();
|
||||
#endif
|
||||
|
||||
case LINKdefault:
|
||||
error("forward declaration");
|
||||
return ident->toChars();
|
||||
|
||||
default:
|
||||
fprintf(stdmsg, "'%s', linkage = %d\n", toChars(), linkage);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
char *p = ::mangle(this);
|
||||
OutBuffer buf;
|
||||
buf.writestring("_D");
|
||||
buf.writestring(p);
|
||||
p = buf.toChars();
|
||||
buf.data = NULL;
|
||||
//printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d) = %s\n", this, toChars(), parent ? parent->toChars() : "null", linkage, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
char *FuncDeclaration::mangle()
|
||||
#if __DMC__
|
||||
__out(result)
|
||||
{
|
||||
assert(strlen(result) > 0);
|
||||
}
|
||||
__body
|
||||
#endif
|
||||
{
|
||||
if (isMain())
|
||||
return (char *)"_Dmain";
|
||||
|
||||
if (isWinMain() || isDllMain() || ident == Id::tls_get_addr)
|
||||
return ident->toChars();
|
||||
|
||||
assert(this);
|
||||
return Declaration::mangle();
|
||||
}
|
||||
|
||||
char *StructDeclaration::mangle()
|
||||
{
|
||||
//printf("StructDeclaration::mangle() '%s'\n", toChars());
|
||||
return Dsymbol::mangle();
|
||||
}
|
||||
|
||||
|
||||
char *TypedefDeclaration::mangle()
|
||||
{
|
||||
//printf("TypedefDeclaration::mangle() '%s'\n", toChars());
|
||||
return Dsymbol::mangle();
|
||||
}
|
||||
|
||||
|
||||
char *ClassDeclaration::mangle()
|
||||
{
|
||||
Dsymbol *parentsave = parent;
|
||||
|
||||
//printf("ClassDeclaration::mangle() %s.%s\n", parent->toChars(), toChars());
|
||||
|
||||
/* These are reserved to the compiler, so keep simple
|
||||
* names for them.
|
||||
*/
|
||||
if (ident == Id::Exception)
|
||||
{ if (parent->ident == Id::object)
|
||||
parent = NULL;
|
||||
}
|
||||
else if (ident == Id::TypeInfo ||
|
||||
// ident == Id::Exception ||
|
||||
ident == Id::TypeInfo_Struct ||
|
||||
ident == Id::TypeInfo_Class ||
|
||||
ident == Id::TypeInfo_Typedef ||
|
||||
ident == Id::TypeInfo_Tuple ||
|
||||
this == object ||
|
||||
this == classinfo ||
|
||||
this == Module::moduleinfo ||
|
||||
memcmp(ident->toChars(), "TypeInfo_", 9) == 0
|
||||
)
|
||||
parent = NULL;
|
||||
|
||||
char *id = Dsymbol::mangle();
|
||||
parent = parentsave;
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
char *TemplateInstance::mangle()
|
||||
{
|
||||
OutBuffer buf;
|
||||
char *id;
|
||||
|
||||
#if 0
|
||||
printf("TemplateInstance::mangle() %s", toChars());
|
||||
if (parent)
|
||||
printf(" parent = %s %s", parent->kind(), parent->toChars());
|
||||
printf("\n");
|
||||
#endif
|
||||
id = ident ? ident->toChars() : toChars();
|
||||
if (!tempdecl)
|
||||
error("is not defined");
|
||||
else if (tempdecl->parent)
|
||||
{
|
||||
char *p = tempdecl->parent->mangle();
|
||||
if (p[0] == '_' && p[1] == 'D')
|
||||
p += 2;
|
||||
buf.writestring(p);
|
||||
}
|
||||
buf.printf("%zu%s", strlen(id), id);
|
||||
id = buf.toChars();
|
||||
buf.data = NULL;
|
||||
//printf("TemplateInstance::mangle() %s = %s\n", toChars(), id);
|
||||
return id;
|
||||
}
|
||||
|
||||
#if IN_LLVM
|
||||
char *TemplateMixin::mangle()
|
||||
{
|
||||
OutBuffer buf;
|
||||
char *id;
|
||||
|
||||
#if 0
|
||||
printf("TemplateMixin::mangle() %s", toChars());
|
||||
if (parent)
|
||||
printf(" parent = %s %s", parent->kind(), parent->toChars());
|
||||
printf("\n");
|
||||
#endif
|
||||
id = ident ? ident->toChars() : toChars();
|
||||
if (parent)
|
||||
{
|
||||
char *p = parent->mangle();
|
||||
if (p[0] == '_' && p[1] == 'D')
|
||||
p += 2;
|
||||
buf.writestring(p);
|
||||
}
|
||||
buf.printf("%zu%s", strlen(id), id);
|
||||
id = buf.toChars();
|
||||
buf.data = NULL;
|
||||
//printf("TemplateMixin::mangle() %s = %s\n", toChars(), id);
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *Dsymbol::mangle()
|
||||
{
|
||||
OutBuffer buf;
|
||||
char *id;
|
||||
|
||||
#if 0
|
||||
printf("Dsymbol::mangle() '%s'", toChars());
|
||||
if (parent)
|
||||
printf(" parent = %s %s", parent->kind(), parent->toChars());
|
||||
printf("\n");
|
||||
#endif
|
||||
id = ident ? ident->toChars() : toChars();
|
||||
if (parent)
|
||||
{
|
||||
char *p = parent->mangle();
|
||||
if (p[0] == '_' && p[1] == 'D')
|
||||
p += 2;
|
||||
buf.writestring(p);
|
||||
}
|
||||
buf.printf("%zu%s", strlen(id), id);
|
||||
id = buf.toChars();
|
||||
buf.data = NULL;
|
||||
//printf("Dsymbol::mangle() %s = %s\n", toChars(), id);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "root.h"
|
||||
|
||||
#include "init.h"
|
||||
#include "declaration.h"
|
||||
#include "aggregate.h"
|
||||
#include "mtype.h"
|
||||
#include "attrib.h"
|
||||
#include "template.h"
|
||||
#include "id.h"
|
||||
#include "module.h"
|
||||
|
||||
#if TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS
|
||||
char *cpp_mangle(Dsymbol *s);
|
||||
#endif
|
||||
|
||||
char *mangle(Declaration *sthis)
|
||||
{
|
||||
OutBuffer buf;
|
||||
char *id;
|
||||
Dsymbol *s;
|
||||
|
||||
//printf("::mangle(%s)\n", sthis->toChars());
|
||||
s = sthis;
|
||||
do
|
||||
{
|
||||
//printf("mangle: s = %p, '%s', parent = %p\n", s, s->toChars(), s->parent);
|
||||
if (s->ident)
|
||||
{
|
||||
FuncDeclaration *fd = s->isFuncDeclaration();
|
||||
if (s != sthis && fd)
|
||||
{
|
||||
id = mangle(fd);
|
||||
buf.prependstring(id);
|
||||
goto L1;
|
||||
}
|
||||
else
|
||||
{
|
||||
id = s->ident->toChars();
|
||||
int len = strlen(id);
|
||||
char tmp[sizeof(len) * 3 + 1];
|
||||
buf.prependstring(id);
|
||||
sprintf(tmp, "%d", len);
|
||||
buf.prependstring(tmp);
|
||||
}
|
||||
}
|
||||
else
|
||||
buf.prependstring("0");
|
||||
s = s->parent;
|
||||
} while (s);
|
||||
|
||||
// buf.prependstring("_D");
|
||||
L1:
|
||||
//printf("deco = '%s'\n", sthis->type->deco ? sthis->type->deco : "null");
|
||||
//printf("sthis->type = %s\n", sthis->type->toChars());
|
||||
FuncDeclaration *fd = sthis->isFuncDeclaration();
|
||||
if (fd && (fd->needThis() || fd->isNested()))
|
||||
buf.writeByte(Type::needThisPrefix());
|
||||
if (sthis->type->deco)
|
||||
buf.writestring(sthis->type->deco);
|
||||
else
|
||||
{
|
||||
#ifdef DEBUG
|
||||
if (!fd->inferRetType)
|
||||
printf("%s\n", fd->toChars());
|
||||
#endif
|
||||
assert(fd && fd->inferRetType);
|
||||
}
|
||||
|
||||
id = buf.toChars();
|
||||
buf.data = NULL;
|
||||
return id;
|
||||
}
|
||||
|
||||
char *Declaration::mangle()
|
||||
#if __DMC__
|
||||
__out(result)
|
||||
{
|
||||
int len = strlen(result);
|
||||
|
||||
assert(len > 0);
|
||||
//printf("mangle: '%s' => '%s'\n", toChars(), result);
|
||||
for (int i = 0; i < len; i++)
|
||||
{
|
||||
assert(result[i] == '_' ||
|
||||
result[i] == '@' ||
|
||||
isalnum(result[i]) || result[i] & 0x80);
|
||||
}
|
||||
}
|
||||
__body
|
||||
#endif
|
||||
{
|
||||
//printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d)\n", this, toChars(), parent ? parent->toChars() : "null", linkage);
|
||||
if (!parent || parent->isModule() || linkage == LINKcpp) // if at global scope
|
||||
{
|
||||
// If it's not a D declaration, no mangling
|
||||
switch (linkage)
|
||||
{
|
||||
case LINKd:
|
||||
break;
|
||||
|
||||
#if IN_LLVM
|
||||
case LINKintrinsic:
|
||||
#endif
|
||||
case LINKc:
|
||||
case LINKwindows:
|
||||
case LINKpascal:
|
||||
return ident->toChars();
|
||||
|
||||
case LINKcpp:
|
||||
#if CPP_MANGLE
|
||||
return cpp_mangle(this);
|
||||
#else
|
||||
// Windows C++ mangling is done by C++ back end
|
||||
return ident->toChars();
|
||||
#endif
|
||||
|
||||
case LINKdefault:
|
||||
error("forward declaration");
|
||||
return ident->toChars();
|
||||
|
||||
default:
|
||||
fprintf(stdmsg, "'%s', linkage = %d\n", toChars(), linkage);
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
char *p = ::mangle(this);
|
||||
OutBuffer buf;
|
||||
buf.writestring("_D");
|
||||
buf.writestring(p);
|
||||
p = buf.toChars();
|
||||
buf.data = NULL;
|
||||
//printf("Declaration::mangle(this = %p, '%s', parent = '%s', linkage = %d) = %s\n", this, toChars(), parent ? parent->toChars() : "null", linkage, p);
|
||||
return p;
|
||||
}
|
||||
|
||||
char *FuncDeclaration::mangle()
|
||||
#if __DMC__
|
||||
__out(result)
|
||||
{
|
||||
assert(strlen(result) > 0);
|
||||
}
|
||||
__body
|
||||
#endif
|
||||
{
|
||||
if (isMain())
|
||||
return (char *)"_Dmain";
|
||||
|
||||
if (isWinMain() || isDllMain() || ident == Id::tls_get_addr)
|
||||
return ident->toChars();
|
||||
|
||||
assert(this);
|
||||
return Declaration::mangle();
|
||||
}
|
||||
|
||||
char *StructDeclaration::mangle()
|
||||
{
|
||||
//printf("StructDeclaration::mangle() '%s'\n", toChars());
|
||||
return Dsymbol::mangle();
|
||||
}
|
||||
|
||||
|
||||
char *TypedefDeclaration::mangle()
|
||||
{
|
||||
//printf("TypedefDeclaration::mangle() '%s'\n", toChars());
|
||||
return Dsymbol::mangle();
|
||||
}
|
||||
|
||||
|
||||
char *ClassDeclaration::mangle()
|
||||
{
|
||||
Dsymbol *parentsave = parent;
|
||||
|
||||
//printf("ClassDeclaration::mangle() %s.%s\n", parent->toChars(), toChars());
|
||||
|
||||
/* These are reserved to the compiler, so keep simple
|
||||
* names for them.
|
||||
*/
|
||||
if (ident == Id::Exception)
|
||||
{ if (parent->ident == Id::object)
|
||||
parent = NULL;
|
||||
}
|
||||
else if (ident == Id::TypeInfo ||
|
||||
// ident == Id::Exception ||
|
||||
ident == Id::TypeInfo_Struct ||
|
||||
ident == Id::TypeInfo_Class ||
|
||||
ident == Id::TypeInfo_Typedef ||
|
||||
ident == Id::TypeInfo_Tuple ||
|
||||
this == object ||
|
||||
this == classinfo ||
|
||||
this == Module::moduleinfo ||
|
||||
memcmp(ident->toChars(), "TypeInfo_", 9) == 0
|
||||
)
|
||||
parent = NULL;
|
||||
|
||||
char *id = Dsymbol::mangle();
|
||||
parent = parentsave;
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
char *TemplateInstance::mangle()
|
||||
{
|
||||
OutBuffer buf;
|
||||
char *id;
|
||||
|
||||
#if 0
|
||||
printf("TemplateInstance::mangle() %s", toChars());
|
||||
if (parent)
|
||||
printf(" parent = %s %s", parent->kind(), parent->toChars());
|
||||
printf("\n");
|
||||
#endif
|
||||
id = ident ? ident->toChars() : toChars();
|
||||
if (!tempdecl)
|
||||
error("is not defined");
|
||||
else if (tempdecl->parent)
|
||||
{
|
||||
char *p = tempdecl->parent->mangle();
|
||||
if (p[0] == '_' && p[1] == 'D')
|
||||
p += 2;
|
||||
buf.writestring(p);
|
||||
}
|
||||
buf.printf("%zu%s", strlen(id), id);
|
||||
id = buf.toChars();
|
||||
buf.data = NULL;
|
||||
//printf("TemplateInstance::mangle() %s = %s\n", toChars(), id);
|
||||
return id;
|
||||
}
|
||||
|
||||
#if IN_LLVM
|
||||
char *TemplateMixin::mangle()
|
||||
{
|
||||
OutBuffer buf;
|
||||
char *id;
|
||||
|
||||
#if 0
|
||||
printf("TemplateMixin::mangle() %s", toChars());
|
||||
if (parent)
|
||||
printf(" parent = %s %s", parent->kind(), parent->toChars());
|
||||
printf("\n");
|
||||
#endif
|
||||
id = ident ? ident->toChars() : toChars();
|
||||
if (parent)
|
||||
{
|
||||
char *p = parent->mangle();
|
||||
if (p[0] == '_' && p[1] == 'D')
|
||||
p += 2;
|
||||
buf.writestring(p);
|
||||
}
|
||||
buf.printf("%zu%s", strlen(id), id);
|
||||
id = buf.toChars();
|
||||
buf.data = NULL;
|
||||
//printf("TemplateMixin::mangle() %s = %s\n", toChars(), id);
|
||||
return id;
|
||||
}
|
||||
#endif
|
||||
|
||||
char *Dsymbol::mangle()
|
||||
{
|
||||
OutBuffer buf;
|
||||
char *id;
|
||||
|
||||
#if 0
|
||||
printf("Dsymbol::mangle() '%s'", toChars());
|
||||
if (parent)
|
||||
printf(" parent = %s %s", parent->kind(), parent->toChars());
|
||||
printf("\n");
|
||||
#endif
|
||||
id = ident ? ident->toChars() : toChars();
|
||||
if (parent)
|
||||
{
|
||||
char *p = parent->mangle();
|
||||
if (p[0] == '_' && p[1] == 'D')
|
||||
p += 2;
|
||||
buf.writestring(p);
|
||||
}
|
||||
buf.printf("%zu%s", strlen(id), id);
|
||||
id = buf.toChars();
|
||||
buf.data = NULL;
|
||||
//printf("Dsymbol::mangle() %s = %s\n", toChars(), id);
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
|
||||
197
dmd2/mars.c
197
dmd2/mars.c
@@ -1,6 +1,6 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// Copyright (c) 1999-2010 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
@@ -36,6 +36,7 @@
|
||||
#include "expression.h"
|
||||
#include "lexer.h"
|
||||
#include "lib.h"
|
||||
#include "json.h"
|
||||
|
||||
#if WINDOWS_SEH
|
||||
#include <windows.h>
|
||||
@@ -60,6 +61,8 @@ Global::Global()
|
||||
hdr_ext = "di";
|
||||
doc_ext = "html";
|
||||
ddoc_ext = "ddoc";
|
||||
json_ext = "json";
|
||||
map_ext = "map";
|
||||
|
||||
#if IN_LLVM
|
||||
ll_ext = "ll";
|
||||
@@ -89,13 +92,13 @@ Global::Global()
|
||||
#endif
|
||||
#endif
|
||||
|
||||
copyright = "Copyright (c) 1999-2009 by Digital Mars";
|
||||
copyright = "Copyright (c) 1999-2010 by Digital Mars";
|
||||
written = "written by Walter Bright"
|
||||
#if TARGET_NET
|
||||
"\nMSIL back-end (alpha release) by Cristian L. Vlasceanu and associates.";
|
||||
#endif
|
||||
;
|
||||
version = "v2.032";
|
||||
version = "v2.049";
|
||||
#if IN_LLVM
|
||||
ldc_version = "LDC trunk";
|
||||
llvm_version = "LLVM 2.8";
|
||||
@@ -116,11 +119,11 @@ char *Loc::toChars()
|
||||
|
||||
if (filename)
|
||||
{
|
||||
buf.printf("%s", filename);
|
||||
buf.printf("%s", filename);
|
||||
}
|
||||
|
||||
if (linnum)
|
||||
buf.printf("(%d)", linnum);
|
||||
buf.printf("(%d)", linnum);
|
||||
buf.writeByte(0);
|
||||
return (char *)buf.extractData();
|
||||
}
|
||||
@@ -150,29 +153,34 @@ void error(Loc loc, const char *format, ...)
|
||||
|
||||
void warning(Loc loc, const char *format, ...)
|
||||
{
|
||||
if (global.params.warnings && !global.gag)
|
||||
{
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vwarning(loc, format, ap);
|
||||
va_end( ap );
|
||||
}
|
||||
va_list ap;
|
||||
va_start(ap, format);
|
||||
vwarning(loc, format, ap);
|
||||
va_end( ap );
|
||||
}
|
||||
|
||||
void verror(Loc loc, const char *format, va_list ap)
|
||||
{
|
||||
if (!global.gag)
|
||||
{
|
||||
char *p = loc.toChars();
|
||||
char *p = loc.toChars();
|
||||
|
||||
if (*p)
|
||||
fprintf(stdmsg, "%s: ", p);
|
||||
mem.free(p);
|
||||
if (*p)
|
||||
fprintf(stdmsg, "%s: ", p);
|
||||
mem.free(p);
|
||||
|
||||
fprintf(stdmsg, "Error: ");
|
||||
vfprintf(stdmsg, format, ap);
|
||||
fprintf(stdmsg, "\n");
|
||||
fflush(stdmsg);
|
||||
fprintf(stdmsg, "Error: ");
|
||||
// MS doesn't recognize %zu format
|
||||
OutBuffer tmp;
|
||||
tmp.vprintf(format, ap);
|
||||
#if _MSC_VER
|
||||
fprintf(stdmsg, "%s", tmp.toChars());
|
||||
#else
|
||||
vfprintf(stdmsg, format, ap);
|
||||
#endif
|
||||
fprintf(stdmsg, "\n");
|
||||
fflush(stdmsg);
|
||||
//halt();
|
||||
}
|
||||
global.errors++;
|
||||
}
|
||||
@@ -188,9 +196,19 @@ void vwarning(Loc loc, const char *format, va_list ap)
|
||||
mem.free(p);
|
||||
|
||||
fprintf(stdmsg, "Warning: ");
|
||||
#if _MSC_VER
|
||||
// MS doesn't recognize %zu format
|
||||
OutBuffer tmp;
|
||||
tmp.vprintf(format, ap);
|
||||
fprintf(stdmsg, "%s", tmp.toChars());
|
||||
#else
|
||||
vfprintf(stdmsg, format, ap);
|
||||
#endif
|
||||
fprintf(stdmsg, "\n");
|
||||
fflush(stdmsg);
|
||||
//halt();
|
||||
if (global.params.warnings == 1)
|
||||
global.warnings++; // warnings don't count if gagged
|
||||
}
|
||||
}
|
||||
|
||||
@@ -226,25 +244,20 @@ void halt()
|
||||
|
||||
void getenv_setargv(const char *envvar, int *pargc, char** *pargv)
|
||||
{
|
||||
char *env;
|
||||
char *p;
|
||||
Array *argv;
|
||||
int argc;
|
||||
|
||||
int wildcard; // do wildcard expansion
|
||||
int instring;
|
||||
int slash;
|
||||
char c;
|
||||
int j;
|
||||
|
||||
env = getenv(envvar);
|
||||
char *env = getenv(envvar);
|
||||
if (!env)
|
||||
return;
|
||||
return;
|
||||
|
||||
env = mem.strdup(env); // create our own writable copy
|
||||
env = mem.strdup(env); // create our own writable copy
|
||||
|
||||
argc = *pargc;
|
||||
argv = new Array();
|
||||
int argc = *pargc;
|
||||
Array *argv = new Array();
|
||||
argv->setDim(argc);
|
||||
|
||||
int argc_left = 0;
|
||||
@@ -259,83 +272,83 @@ void getenv_setargv(const char *envvar, int *pargc, char** *pargv)
|
||||
argv->setDim(i);
|
||||
break;
|
||||
} else {
|
||||
argv->data[i] = (void *)(*pargv)[i];
|
||||
argv->data[i] = (void *)(*pargv)[i];
|
||||
}
|
||||
}
|
||||
// HACK to stop required values from command line being drawn from DFLAGS
|
||||
argv->push((char*)"");
|
||||
argc++;
|
||||
|
||||
j = 1; // leave argv[0] alone
|
||||
int j = 1; // leave argv[0] alone
|
||||
while (1)
|
||||
{
|
||||
wildcard = 1;
|
||||
switch (*env)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
env++;
|
||||
break;
|
||||
int wildcard = 1; // do wildcard expansion
|
||||
switch (*env)
|
||||
{
|
||||
case ' ':
|
||||
case '\t':
|
||||
env++;
|
||||
break;
|
||||
|
||||
case 0:
|
||||
goto Ldone;
|
||||
case 0:
|
||||
goto Ldone;
|
||||
|
||||
case '"':
|
||||
wildcard = 0;
|
||||
default:
|
||||
argv->push(env); // append
|
||||
//argv->insert(j, env); // insert at position j
|
||||
j++;
|
||||
argc++;
|
||||
p = env;
|
||||
slash = 0;
|
||||
instring = 0;
|
||||
c = 0;
|
||||
case '"':
|
||||
wildcard = 0;
|
||||
default:
|
||||
argv->push(env); // append
|
||||
//argv->insert(j, env); // insert at position j
|
||||
j++;
|
||||
argc++;
|
||||
p = env;
|
||||
slash = 0;
|
||||
instring = 0;
|
||||
c = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
c = *env++;
|
||||
switch (c)
|
||||
{
|
||||
case '"':
|
||||
p -= (slash >> 1);
|
||||
if (slash & 1)
|
||||
{ p--;
|
||||
goto Laddc;
|
||||
}
|
||||
instring ^= 1;
|
||||
slash = 0;
|
||||
continue;
|
||||
while (1)
|
||||
{
|
||||
c = *env++;
|
||||
switch (c)
|
||||
{
|
||||
case '"':
|
||||
p -= (slash >> 1);
|
||||
if (slash & 1)
|
||||
{ p--;
|
||||
goto Laddc;
|
||||
}
|
||||
instring ^= 1;
|
||||
slash = 0;
|
||||
continue;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
if (instring)
|
||||
goto Laddc;
|
||||
*p = 0;
|
||||
//if (wildcard)
|
||||
//wildcardexpand(); // not implemented
|
||||
break;
|
||||
case ' ':
|
||||
case '\t':
|
||||
if (instring)
|
||||
goto Laddc;
|
||||
*p = 0;
|
||||
//if (wildcard)
|
||||
//wildcardexpand(); // not implemented
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
slash++;
|
||||
*p++ = c;
|
||||
continue;
|
||||
case '\\':
|
||||
slash++;
|
||||
*p++ = c;
|
||||
continue;
|
||||
|
||||
case 0:
|
||||
*p = 0;
|
||||
//if (wildcard)
|
||||
//wildcardexpand(); // not implemented
|
||||
goto Ldone;
|
||||
case 0:
|
||||
*p = 0;
|
||||
//if (wildcard)
|
||||
//wildcardexpand(); // not implemented
|
||||
goto Ldone;
|
||||
|
||||
default:
|
||||
Laddc:
|
||||
slash = 0;
|
||||
*p++ = c;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
default:
|
||||
Laddc:
|
||||
slash = 0;
|
||||
*p++ = c;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ldone:
|
||||
|
||||
941
dmd2/mars.h
941
dmd2/mars.h
@@ -1,462 +1,479 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_MARS_H
|
||||
#define DMD_MARS_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/*
|
||||
It is very important to use version control macros correctly - the
|
||||
idea is that host and target are independent. If these are done
|
||||
correctly, cross compilers can be built.
|
||||
The host compiler and host operating system are also different,
|
||||
and are predefined by the host compiler. The ones used in
|
||||
dmd are:
|
||||
|
||||
Macros defined by the compiler, not the code:
|
||||
|
||||
Compiler:
|
||||
__DMC__ Digital Mars compiler
|
||||
_MSC_VER Microsoft compiler
|
||||
__GNUC__ Gnu compiler
|
||||
|
||||
Host operating system:
|
||||
_WIN32 Microsoft NT, Windows 95, Windows 98, Win32s,
|
||||
Windows 2000, Win XP, Vista
|
||||
_WIN64 Windows for AMD64
|
||||
linux Linux
|
||||
__APPLE__ Mac OSX
|
||||
__FreeBSD__ FreeBSD
|
||||
__sun&&__SVR4 Solaris, OpenSolaris (yes, both macros are necessary)
|
||||
|
||||
For the target systems, there are the target operating system and
|
||||
the target object file format:
|
||||
|
||||
Target operating system:
|
||||
TARGET_WINDOS Covers 32 bit windows and 64 bit windows
|
||||
TARGET_LINUX Covers 32 and 64 bit linux
|
||||
TARGET_OSX Covers 32 and 64 bit Mac OSX
|
||||
TARGET_FREEBSD Covers 32 and 64 bit FreeBSD
|
||||
TARGET_SOLARIS Covers 32 and 64 bit Solaris
|
||||
TARGET_NET Covers .Net
|
||||
|
||||
It is expected that the compiler for each platform will be able
|
||||
to generate 32 and 64 bit code from the same compiler binary.
|
||||
|
||||
Target object module format:
|
||||
OMFOBJ Intel Object Module Format, used on Windows
|
||||
ELFOBJ Elf Object Module Format, used on linux, FreeBSD and Solaris
|
||||
MACHOBJ Mach-O Object Module Format, used on Mac OSX
|
||||
|
||||
There are currently no macros for byte endianness order.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#define __STDC_FORMAT_MACROS 1
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __DMC__
|
||||
#ifdef DEBUG
|
||||
#undef assert
|
||||
#define assert(e) (static_cast<void>((e) || (printf("assert %s(%d) %s\n", __FILE__, __LINE__, #e), halt())))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifndef IS_PRINTF
|
||||
# ifdef __GNUC__
|
||||
# define IS_PRINTF(FMTARG) __attribute((__format__ (__printf__, (FMTARG), (FMTARG)+1) ))
|
||||
# else
|
||||
# define IS_PRINTF(FMTARG)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef IN_GCC
|
||||
/* Changes for the GDC compiler by David Friedman */
|
||||
#endif
|
||||
|
||||
#define DMDV1 0
|
||||
#define DMDV2 1 // Version 2.0 features
|
||||
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
|
||||
#define STRUCTTHISREF DMDV2 // if 'this' for struct is a reference, not a pointer
|
||||
#define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN
|
||||
|
||||
// Set if C++ mangling is done by the front end
|
||||
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS))
|
||||
|
||||
/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and
|
||||
* TARGET_SOLARIS, which are
|
||||
* set on the command line via the compiler makefile.
|
||||
*/
|
||||
|
||||
#if _WIN32
|
||||
#define TARGET_WINDOS 1 // Windows dmd generates Windows targets
|
||||
#define OMFOBJ 1
|
||||
#endif
|
||||
|
||||
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
|
||||
#ifndef ELFOBJ
|
||||
#define ELFOBJ 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if TARGET_OSX
|
||||
#ifndef MACHOBJ
|
||||
#define MACHOBJ 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
struct Array;
|
||||
struct OutBuffer;
|
||||
|
||||
#if IN_LLVM
|
||||
enum ARCH
|
||||
{
|
||||
ARCHinvalid,
|
||||
ARCHx86,
|
||||
ARCHx86_64,
|
||||
ARCHppc,
|
||||
ARCHppc_64,
|
||||
ARCHarm,
|
||||
ARCHthumb
|
||||
};
|
||||
enum OUTPUTFLAG
|
||||
{
|
||||
OUTPUTFLAGno,
|
||||
OUTPUTFLAGdefault, // for the .o default
|
||||
OUTPUTFLAGset // for -output
|
||||
};
|
||||
|
||||
enum OS
|
||||
{
|
||||
OSinvalid,
|
||||
OSLinux,
|
||||
OSWindows,
|
||||
OSMacOSX,
|
||||
OSFreeBSD,
|
||||
OSSolaris,
|
||||
};
|
||||
|
||||
typedef unsigned char ubyte;
|
||||
#endif
|
||||
|
||||
// Put command line switches in here
|
||||
struct Param
|
||||
{
|
||||
bool obj; // write object file
|
||||
bool link; // perform link
|
||||
bool verbose; // verbose compile
|
||||
bool vtls; // identify thread local variables
|
||||
ubyte symdebug; // insert debug symbolic information
|
||||
#if !IN_LLVM
|
||||
// LDC uses a different mechanism
|
||||
bool optimize; // run optimizer
|
||||
char optimizeLevel; // optimization level
|
||||
#endif
|
||||
ARCH cpu; // target CPU
|
||||
OS os;
|
||||
bool is64bit; // generate X86_64 bit code
|
||||
bool isLE; // generate little endian code
|
||||
bool useDeprecated; // allow use of deprecated features
|
||||
bool useAssert; // generate runtime code for assert()'s
|
||||
bool useInvariants; // generate class invariant checks
|
||||
bool useIn; // generate precondition checks
|
||||
bool useOut; // generate postcondition checks
|
||||
bool useArrayBounds; // generate array bounds checks
|
||||
bool useSwitchError; // check for switches without a default
|
||||
bool useUnitTests; // generate unittest code
|
||||
bool useInline; // inline expand functions
|
||||
bool warnings; // enable warnings
|
||||
ubyte Dversion; // D version number
|
||||
char safe; // enforce safe memory model
|
||||
|
||||
char *argv0; // program name
|
||||
Array *imppath; // array of char*'s of where to look for import modules
|
||||
Array *fileImppath; // array of char*'s of where to look for file import modules
|
||||
char *objdir; // .obj file output directory
|
||||
char *objname; // .obj file output name
|
||||
|
||||
bool doDocComments; // process embedded documentation comments
|
||||
char *docdir; // write documentation file to docdir directory
|
||||
char *docname; // write documentation file to docname
|
||||
Array *ddocfiles; // macro include files for Ddoc
|
||||
|
||||
bool doHdrGeneration; // process embedded documentation comments
|
||||
char *hdrdir; // write 'header' file to docdir directory
|
||||
char *hdrname; // write 'header' file to docname
|
||||
|
||||
unsigned debuglevel; // debug level
|
||||
Array *debugids; // debug identifiers
|
||||
|
||||
unsigned versionlevel; // version level
|
||||
Array *versionids; // version identifiers
|
||||
|
||||
bool dump_source;
|
||||
|
||||
Array *defaultlibnames; // default libraries for non-debug builds
|
||||
Array *debuglibnames; // default libraries for debug builds
|
||||
|
||||
const char *xmlname; // filename for XML output
|
||||
|
||||
char *moduleDepsFile; // filename for deps output
|
||||
OutBuffer *moduleDeps; // contents to be written to deps file
|
||||
|
||||
// Hidden debug switches
|
||||
bool debuga;
|
||||
bool debugb;
|
||||
bool debugc;
|
||||
bool debugf;
|
||||
bool debugr;
|
||||
bool debugw;
|
||||
bool debugx;
|
||||
bool debugy;
|
||||
|
||||
bool run; // run resulting executable
|
||||
|
||||
// Linker stuff
|
||||
Array *objfiles;
|
||||
Array *linkswitches;
|
||||
Array *libfiles;
|
||||
char *deffile;
|
||||
char *resfile;
|
||||
char *exefile;
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC stuff
|
||||
OUTPUTFLAG output_ll;
|
||||
OUTPUTFLAG output_bc;
|
||||
OUTPUTFLAG output_s;
|
||||
OUTPUTFLAG output_o;
|
||||
bool llvmAnnotate;
|
||||
bool useInlineAsm;
|
||||
bool verbose_cg;
|
||||
bool useAvailableExternally;
|
||||
|
||||
// target stuff
|
||||
const char* llvmArch;
|
||||
const char *targetTriple;
|
||||
const char *dataLayout;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct Global
|
||||
{
|
||||
const char *mars_ext;
|
||||
const char *sym_ext;
|
||||
const char *obj_ext;
|
||||
#if IN_LLVM
|
||||
#if _WIN32
|
||||
char *obj_ext_alt;
|
||||
#endif
|
||||
char *ll_ext;
|
||||
char *bc_ext;
|
||||
char *s_ext;
|
||||
#endif
|
||||
const char *lib_ext;
|
||||
const char *doc_ext; // for Ddoc generated files
|
||||
const char *ddoc_ext; // for Ddoc macro include files
|
||||
const char *hdr_ext; // for D 'header' import files
|
||||
const char *copyright;
|
||||
const char *written;
|
||||
Array *path; // Array of char*'s which form the import lookup path
|
||||
Array *filePath; // Array of char*'s which form the file import lookup path
|
||||
int structalign;
|
||||
const char *version;
|
||||
#if IN_LLVM
|
||||
char *ldc_version;
|
||||
char *llvm_version;
|
||||
#endif
|
||||
|
||||
Param params;
|
||||
unsigned errors; // number of errors reported so far
|
||||
unsigned gag; // !=0 means gag reporting of errors
|
||||
|
||||
Global();
|
||||
};
|
||||
|
||||
extern Global global;
|
||||
|
||||
/* Set if Windows Structured Exception Handling C extensions are supported.
|
||||
* Apparently, VC has dropped support for these?
|
||||
*/
|
||||
#define WINDOWS_SEH (_WIN32 && __DMC__)
|
||||
|
||||
|
||||
#ifdef __DMC__
|
||||
typedef _Complex long double complex_t;
|
||||
#else
|
||||
#ifndef IN_GCC
|
||||
#include "complex_t.h"
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
//#include "complex.h"//This causes problems with include the c++ <complex> and not the C "complex.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Be careful not to care about sign when using dinteger_t
|
||||
//typedef uint64_t integer_t;
|
||||
typedef uint64_t dinteger_t; // use this instead of integer_t to
|
||||
// avoid conflicts with system #include's
|
||||
|
||||
// Signed and unsigned variants
|
||||
typedef int64_t sinteger_t;
|
||||
typedef uint64_t uinteger_t;
|
||||
|
||||
typedef int8_t d_int8;
|
||||
typedef uint8_t d_uns8;
|
||||
typedef int16_t d_int16;
|
||||
typedef uint16_t d_uns16;
|
||||
typedef int32_t d_int32;
|
||||
typedef uint32_t d_uns32;
|
||||
typedef int64_t d_int64;
|
||||
typedef uint64_t d_uns64;
|
||||
|
||||
typedef float d_float32;
|
||||
typedef double d_float64;
|
||||
typedef long double d_float80;
|
||||
|
||||
typedef d_uns8 d_char;
|
||||
typedef d_uns16 d_wchar;
|
||||
typedef d_uns32 d_dchar;
|
||||
|
||||
#ifdef IN_GCC
|
||||
#include "d-gcc-real.h"
|
||||
#else
|
||||
typedef long double real_t;
|
||||
#endif
|
||||
|
||||
// Modify OutBuffer::writewchar to write the correct size of wchar
|
||||
#if _WIN32
|
||||
#define writewchar writeword
|
||||
#else
|
||||
// This needs a configuration test...
|
||||
#define writewchar write4
|
||||
#endif
|
||||
|
||||
#ifdef IN_GCC
|
||||
#include "d-gcc-complex_t.h"
|
||||
#endif
|
||||
|
||||
struct Module;
|
||||
|
||||
//typedef unsigned Loc; // file location
|
||||
struct Loc
|
||||
{
|
||||
const char *filename;
|
||||
unsigned linnum;
|
||||
|
||||
Loc()
|
||||
{
|
||||
linnum = 0;
|
||||
filename = NULL;
|
||||
}
|
||||
|
||||
Loc(int x)
|
||||
{
|
||||
linnum = x;
|
||||
filename = NULL;
|
||||
}
|
||||
|
||||
Loc(Module *mod, unsigned linnum);
|
||||
|
||||
char *toChars();
|
||||
bool equals(const Loc& loc);
|
||||
};
|
||||
|
||||
#ifndef GCC_SAFE_DMD
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry
|
||||
// in interface vtbl[]'s
|
||||
#define INTERFACE_VIRTUAL 0 // 1 means if an interface appears
|
||||
// in the inheritance graph multiple
|
||||
// times, only one is used
|
||||
|
||||
enum LINK
|
||||
{
|
||||
LINKdefault,
|
||||
LINKd,
|
||||
LINKc,
|
||||
LINKcpp,
|
||||
LINKwindows,
|
||||
LINKpascal,
|
||||
|
||||
#if IN_LLVM
|
||||
LINKintrinsic,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum DYNCAST
|
||||
{
|
||||
DYNCAST_OBJECT,
|
||||
DYNCAST_EXPRESSION,
|
||||
DYNCAST_DSYMBOL,
|
||||
DYNCAST_TYPE,
|
||||
DYNCAST_IDENTIFIER,
|
||||
DYNCAST_TUPLE,
|
||||
};
|
||||
|
||||
enum MATCH
|
||||
{
|
||||
MATCHnomatch, // no match
|
||||
MATCHconvert, // match with conversions
|
||||
#if DMDV2
|
||||
MATCHconst, // match with conversion to const
|
||||
#endif
|
||||
MATCHexact // exact match
|
||||
};
|
||||
|
||||
void warning(Loc loc, const char *format, ...) IS_PRINTF(2);
|
||||
void vwarning(Loc loc, const char *format, va_list);
|
||||
void error(Loc loc, const char *format, ...) IS_PRINTF(2);
|
||||
void verror(Loc loc, const char *format, va_list);
|
||||
void fatal();
|
||||
void err_nomem();
|
||||
#if IN_LLVM
|
||||
void inifile(char *argv0, const char *inifile);
|
||||
#else
|
||||
int runLINK();
|
||||
void deleteExeFile();
|
||||
int runProgram();
|
||||
void inifile(const char *argv0, const char *inifile);
|
||||
#endif
|
||||
void halt();
|
||||
#if !IN_LLVM
|
||||
void util_progress();
|
||||
#endif
|
||||
|
||||
/*** Where to send error messages ***/
|
||||
#if IN_GCC || IN_LLVM
|
||||
#define stdmsg stderr
|
||||
#else
|
||||
#define stdmsg stderr
|
||||
#endif
|
||||
|
||||
#if !IN_LLVM
|
||||
struct Dsymbol;
|
||||
struct Library;
|
||||
struct File;
|
||||
void obj_start(char *srcfile);
|
||||
void obj_end(Library *library, File *objfile);
|
||||
void obj_append(Dsymbol *s);
|
||||
void obj_write_deferred(Library *library);
|
||||
#endif
|
||||
|
||||
#endif /* DMD_MARS_H */
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2010 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_MARS_H
|
||||
#define DMD_MARS_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
/*
|
||||
It is very important to use version control macros correctly - the
|
||||
idea is that host and target are independent. If these are done
|
||||
correctly, cross compilers can be built.
|
||||
The host compiler and host operating system are also different,
|
||||
and are predefined by the host compiler. The ones used in
|
||||
dmd are:
|
||||
|
||||
Macros defined by the compiler, not the code:
|
||||
|
||||
Compiler:
|
||||
__DMC__ Digital Mars compiler
|
||||
_MSC_VER Microsoft compiler
|
||||
__GNUC__ Gnu compiler
|
||||
|
||||
Host operating system:
|
||||
_WIN32 Microsoft NT, Windows 95, Windows 98, Win32s,
|
||||
Windows 2000, Win XP, Vista
|
||||
_WIN64 Windows for AMD64
|
||||
linux Linux
|
||||
__APPLE__ Mac OSX
|
||||
__FreeBSD__ FreeBSD
|
||||
__sun&&__SVR4 Solaris, OpenSolaris (yes, both macros are necessary)
|
||||
|
||||
For the target systems, there are the target operating system and
|
||||
the target object file format:
|
||||
|
||||
Target operating system:
|
||||
TARGET_WINDOS Covers 32 bit windows and 64 bit windows
|
||||
TARGET_LINUX Covers 32 and 64 bit linux
|
||||
TARGET_OSX Covers 32 and 64 bit Mac OSX
|
||||
TARGET_FREEBSD Covers 32 and 64 bit FreeBSD
|
||||
TARGET_SOLARIS Covers 32 and 64 bit Solaris
|
||||
TARGET_NET Covers .Net
|
||||
|
||||
It is expected that the compiler for each platform will be able
|
||||
to generate 32 and 64 bit code from the same compiler binary.
|
||||
|
||||
Target object module format:
|
||||
OMFOBJ Intel Object Module Format, used on Windows
|
||||
ELFOBJ Elf Object Module Format, used on linux, FreeBSD and Solaris
|
||||
MACHOBJ Mach-O Object Module Format, used on Mac OSX
|
||||
|
||||
There are currently no macros for byte endianness order.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdarg.h>
|
||||
#include <stddef.h>
|
||||
#define __STDC_FORMAT_MACROS 1
|
||||
#include <inttypes.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#ifdef __DMC__
|
||||
#ifdef DEBUG
|
||||
#undef assert
|
||||
#define assert(e) (static_cast<void>((e) || (printf("assert %s(%d) %s\n", __FILE__, __LINE__, #e), halt())))
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG
|
||||
#define UNITTEST 1
|
||||
#endif
|
||||
void unittests();
|
||||
|
||||
#ifndef IS_PRINTF
|
||||
# ifdef __GNUC__
|
||||
# define IS_PRINTF(FMTARG) __attribute((__format__ (__printf__, (FMTARG), (FMTARG)+1) ))
|
||||
# else
|
||||
# define IS_PRINTF(FMTARG)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef IN_GCC
|
||||
/* Changes for the GDC compiler by David Friedman */
|
||||
#endif
|
||||
|
||||
#define DMDV1 0
|
||||
#define DMDV2 1 // Version 2.0 features
|
||||
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
|
||||
#define STRUCTTHISREF DMDV2 // if 'this' for struct is a reference, not a pointer
|
||||
#define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN
|
||||
#define SARRAYVALUE DMDV2 // static arrays are value types
|
||||
#define MODULEINFO_IS_STRUCT DMDV2 // if ModuleInfo is a struct rather than a class
|
||||
|
||||
// Set if C++ mangling is done by the front end
|
||||
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS))
|
||||
|
||||
/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and
|
||||
* TARGET_SOLARIS, which are
|
||||
* set on the command line via the compiler makefile.
|
||||
*/
|
||||
|
||||
#if _WIN32
|
||||
#define TARGET_WINDOS 1 // Windows dmd generates Windows targets
|
||||
#define OMFOBJ 1
|
||||
#endif
|
||||
|
||||
#if TARGET_LINUX || TARGET_FREEBSD || TARGET_SOLARIS
|
||||
#ifndef ELFOBJ
|
||||
#define ELFOBJ 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if TARGET_OSX
|
||||
#ifndef MACHOBJ
|
||||
#define MACHOBJ 1
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
struct Array;
|
||||
struct OutBuffer;
|
||||
|
||||
#if IN_LLVM
|
||||
enum ARCH
|
||||
{
|
||||
ARCHinvalid,
|
||||
ARCHx86,
|
||||
ARCHx86_64,
|
||||
ARCHppc,
|
||||
ARCHppc_64,
|
||||
ARCHarm,
|
||||
ARCHthumb
|
||||
};
|
||||
enum OUTPUTFLAG
|
||||
{
|
||||
OUTPUTFLAGno,
|
||||
OUTPUTFLAGdefault, // for the .o default
|
||||
OUTPUTFLAGset // for -output
|
||||
};
|
||||
|
||||
enum OS
|
||||
{
|
||||
OSinvalid,
|
||||
OSLinux,
|
||||
OSWindows,
|
||||
OSMacOSX,
|
||||
OSFreeBSD,
|
||||
OSSolaris,
|
||||
};
|
||||
|
||||
typedef unsigned char ubyte;
|
||||
#endif
|
||||
|
||||
// Put command line switches in here
|
||||
struct Param
|
||||
{
|
||||
bool obj; // write object file
|
||||
bool link; // perform link
|
||||
bool verbose; // verbose compile
|
||||
bool vtls; // identify thread local variables
|
||||
ubyte symdebug; // insert debug symbolic information
|
||||
#if !IN_LLVM
|
||||
// LDC uses a different mechanism
|
||||
bool optimize; // run optimizer
|
||||
char optimizeLevel; // optimization level
|
||||
#endif
|
||||
ARCH cpu; // target CPU
|
||||
OS os;
|
||||
bool is64bit; // generate X86_64 bit code
|
||||
char map; // generate linker .map file
|
||||
bool isLE; // generate little endian code
|
||||
bool useDeprecated; // allow use of deprecated features
|
||||
bool useAssert; // generate runtime code for assert()'s
|
||||
bool useInvariants; // generate class invariant checks
|
||||
bool useIn; // generate precondition checks
|
||||
bool useOut; // generate postcondition checks
|
||||
bool useArrayBounds; // generate array bounds checks
|
||||
bool useSwitchError; // check for switches without a default
|
||||
bool useUnitTests; // generate unittest code
|
||||
bool useInline; // inline expand functions
|
||||
bool warnings; // enable warnings
|
||||
ubyte Dversion; // D version number
|
||||
|
||||
char *argv0; // program name
|
||||
Array *imppath; // array of char*'s of where to look for import modules
|
||||
Array *fileImppath; // array of char*'s of where to look for file import modules
|
||||
char *objdir; // .obj file output directory
|
||||
char *objname; // .obj file output name
|
||||
|
||||
bool doDocComments; // process embedded documentation comments
|
||||
char *docdir; // write documentation file to docdir directory
|
||||
char *docname; // write documentation file to docname
|
||||
Array *ddocfiles; // macro include files for Ddoc
|
||||
|
||||
bool doHdrGeneration; // process embedded documentation comments
|
||||
char *hdrdir; // write 'header' file to docdir directory
|
||||
char *hdrname; // write 'header' file to docname
|
||||
|
||||
char doXGeneration; // write JSON file
|
||||
char *xfilename; // write JSON file to xfilename
|
||||
|
||||
unsigned debuglevel; // debug level
|
||||
Array *debugids; // debug identifiers
|
||||
|
||||
unsigned versionlevel; // version level
|
||||
Array *versionids; // version identifiers
|
||||
|
||||
bool dump_source;
|
||||
|
||||
Array *defaultlibnames; // default libraries for non-debug builds
|
||||
Array *debuglibnames; // default libraries for debug builds
|
||||
|
||||
char *moduleDepsFile; // filename for deps output
|
||||
OutBuffer *moduleDeps; // contents to be written to deps file
|
||||
|
||||
// Hidden debug switches
|
||||
bool debuga;
|
||||
bool debugb;
|
||||
bool debugc;
|
||||
bool debugf;
|
||||
bool debugr;
|
||||
bool debugw;
|
||||
bool debugx;
|
||||
bool debugy;
|
||||
|
||||
bool run; // run resulting executable
|
||||
|
||||
// Linker stuff
|
||||
Array *objfiles;
|
||||
Array *linkswitches;
|
||||
Array *libfiles;
|
||||
char *deffile;
|
||||
char *resfile;
|
||||
char *exefile;
|
||||
char *mapfile;
|
||||
#if IN_LLVM
|
||||
// LDC stuff
|
||||
OUTPUTFLAG output_ll;
|
||||
OUTPUTFLAG output_bc;
|
||||
OUTPUTFLAG output_s;
|
||||
OUTPUTFLAG output_o;
|
||||
bool llvmAnnotate;
|
||||
bool useInlineAsm;
|
||||
bool verbose_cg;
|
||||
bool useAvailableExternally;
|
||||
|
||||
// target stuff
|
||||
const char* llvmArch;
|
||||
const char *targetTriple;
|
||||
const char *dataLayout;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct Global
|
||||
{
|
||||
const char *mars_ext;
|
||||
const char *sym_ext;
|
||||
const char *obj_ext;
|
||||
#if IN_LLVM
|
||||
#if _WIN32
|
||||
char *obj_ext_alt;
|
||||
#endif
|
||||
char *ll_ext;
|
||||
char *bc_ext;
|
||||
char *s_ext;
|
||||
#endif
|
||||
const char *lib_ext;
|
||||
const char *dll_ext;
|
||||
const char *doc_ext; // for Ddoc generated files
|
||||
const char *ddoc_ext; // for Ddoc macro include files
|
||||
const char *hdr_ext; // for D 'header' import files
|
||||
const char *json_ext; // for JSON files
|
||||
const char *map_ext; // for .map files
|
||||
const char *copyright;
|
||||
const char *written;
|
||||
Array *path; // Array of char*'s which form the import lookup path
|
||||
Array *filePath; // Array of char*'s which form the file import lookup path
|
||||
int structalign;
|
||||
const char *version;
|
||||
#if IN_LLVM
|
||||
char *ldc_version;
|
||||
char *llvm_version;
|
||||
#endif
|
||||
|
||||
Param params;
|
||||
unsigned errors; // number of errors reported so far
|
||||
unsigned warnings; // number of warnings reported so far
|
||||
unsigned gag; // !=0 means gag reporting of errors & warnings
|
||||
|
||||
Global();
|
||||
};
|
||||
|
||||
extern Global global;
|
||||
|
||||
/* Set if Windows Structured Exception Handling C extensions are supported.
|
||||
* Apparently, VC has dropped support for these?
|
||||
*/
|
||||
#define WINDOWS_SEH (_WIN32 && __DMC__)
|
||||
|
||||
|
||||
#ifdef __DMC__
|
||||
typedef _Complex long double complex_t;
|
||||
#else
|
||||
#ifndef IN_GCC
|
||||
#include "complex_t.h"
|
||||
#endif
|
||||
#ifdef __APPLE__
|
||||
//#include "complex.h"//This causes problems with include the c++ <complex> and not the C "complex.h"
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Be careful not to care about sign when using dinteger_t
|
||||
//typedef uint64_t integer_t;
|
||||
typedef uint64_t dinteger_t; // use this instead of integer_t to
|
||||
// avoid conflicts with system #include's
|
||||
|
||||
// Signed and unsigned variants
|
||||
typedef int64_t sinteger_t;
|
||||
typedef uint64_t uinteger_t;
|
||||
|
||||
typedef int8_t d_int8;
|
||||
typedef uint8_t d_uns8;
|
||||
typedef int16_t d_int16;
|
||||
typedef uint16_t d_uns16;
|
||||
typedef int32_t d_int32;
|
||||
typedef uint32_t d_uns32;
|
||||
typedef int64_t d_int64;
|
||||
typedef uint64_t d_uns64;
|
||||
|
||||
typedef float d_float32;
|
||||
typedef double d_float64;
|
||||
typedef long double d_float80;
|
||||
|
||||
typedef d_uns8 d_char;
|
||||
typedef d_uns16 d_wchar;
|
||||
typedef d_uns32 d_dchar;
|
||||
|
||||
#ifdef IN_GCC
|
||||
#include "d-gcc-real.h"
|
||||
#else
|
||||
typedef long double real_t;
|
||||
#endif
|
||||
|
||||
// Modify OutBuffer::writewchar to write the correct size of wchar
|
||||
#if _WIN32
|
||||
#define writewchar writeword
|
||||
#else
|
||||
// This needs a configuration test...
|
||||
#define writewchar write4
|
||||
#endif
|
||||
|
||||
#ifdef IN_GCC
|
||||
#include "d-gcc-complex_t.h"
|
||||
#endif
|
||||
|
||||
struct Module;
|
||||
|
||||
//typedef unsigned Loc; // file location
|
||||
struct Loc
|
||||
{
|
||||
const char *filename;
|
||||
unsigned linnum;
|
||||
|
||||
Loc()
|
||||
{
|
||||
linnum = 0;
|
||||
filename = NULL;
|
||||
}
|
||||
|
||||
Loc(int x)
|
||||
{
|
||||
linnum = x;
|
||||
filename = NULL;
|
||||
}
|
||||
|
||||
Loc(Module *mod, unsigned linnum);
|
||||
|
||||
char *toChars();
|
||||
bool equals(const Loc& loc);
|
||||
};
|
||||
|
||||
#ifndef GCC_SAFE_DMD
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#endif
|
||||
|
||||
#define INTERFACE_OFFSET 0 // if 1, put classinfo as first entry
|
||||
// in interface vtbl[]'s
|
||||
#define INTERFACE_VIRTUAL 0 // 1 means if an interface appears
|
||||
// in the inheritance graph multiple
|
||||
// times, only one is used
|
||||
|
||||
enum LINK
|
||||
{
|
||||
LINKdefault,
|
||||
LINKd,
|
||||
LINKc,
|
||||
LINKcpp,
|
||||
LINKwindows,
|
||||
LINKpascal,
|
||||
|
||||
#if IN_LLVM
|
||||
LINKintrinsic,
|
||||
#endif
|
||||
};
|
||||
|
||||
enum DYNCAST
|
||||
{
|
||||
DYNCAST_OBJECT,
|
||||
DYNCAST_EXPRESSION,
|
||||
DYNCAST_DSYMBOL,
|
||||
DYNCAST_TYPE,
|
||||
DYNCAST_IDENTIFIER,
|
||||
DYNCAST_TUPLE,
|
||||
};
|
||||
|
||||
enum MATCH
|
||||
{
|
||||
MATCHnomatch, // no match
|
||||
MATCHconvert, // match with conversions
|
||||
#if DMDV2
|
||||
MATCHconst, // match with conversion to const
|
||||
#endif
|
||||
MATCHexact // exact match
|
||||
};
|
||||
|
||||
typedef uint64_t StorageClass;
|
||||
|
||||
|
||||
void warning(Loc loc, const char *format, ...) IS_PRINTF(2);
|
||||
void error(Loc loc, const char *format, ...) IS_PRINTF(2);
|
||||
void verror(Loc loc, const char *format, va_list);
|
||||
void vwarning(Loc loc, const char *format, va_list);
|
||||
void fatal();
|
||||
void err_nomem();
|
||||
#if IN_LLVM
|
||||
void inifile(char *argv0, const char *inifile);
|
||||
#else
|
||||
int runLINK();
|
||||
void deleteExeFile();
|
||||
int runProgram();
|
||||
const char *inifile(const char *argv0, const char *inifile);
|
||||
#endif
|
||||
void halt();
|
||||
#if !IN_LLVM
|
||||
void util_progress();
|
||||
#endif
|
||||
|
||||
/*** Where to send error messages ***/
|
||||
#if IN_GCC || IN_LLVM
|
||||
#define stdmsg stderr
|
||||
#else
|
||||
#define stdmsg stderr
|
||||
#endif
|
||||
|
||||
#if !IN_LLVM
|
||||
struct Dsymbol;
|
||||
struct Library;
|
||||
struct File;
|
||||
void obj_start(char *srcfile);
|
||||
void obj_end(Library *library, File *objfile);
|
||||
void obj_append(Dsymbol *s);
|
||||
void obj_write_deferred(Library *library);
|
||||
#endif
|
||||
|
||||
const char *importHint(const char *s);
|
||||
|
||||
#endif /* DMD_MARS_H */
|
||||
|
||||
2557
dmd2/module.c
2557
dmd2/module.c
File diff suppressed because it is too large
Load Diff
441
dmd2/module.h
441
dmd2/module.h
@@ -1,215 +1,226 @@
|
||||
|
||||
// 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
|
||||
class Ir;
|
||||
struct DValue;
|
||||
typedef DValue elem;
|
||||
namespace llvm {
|
||||
class LLVMContext;
|
||||
class Module;
|
||||
}
|
||||
#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 object file
|
||||
File *docfile; // output doc file
|
||||
File *hdrfile; // output hdr 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 selfimports; // 0: don't know, 1: does not, 2: does
|
||||
int selfImports(); // returns !=0 if module imports itself
|
||||
|
||||
int insearch;
|
||||
Identifier *searchCacheIdent;
|
||||
Dsymbol *searchCacheSymbol; // cached value of search
|
||||
int searchCacheFlags; // cached flags
|
||||
|
||||
int semanticstarted; // has semantic() been started?
|
||||
int semanticRun; // 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
|
||||
bool safe; // TRUE if module is marked as 'safe'
|
||||
|
||||
int doDocComment; // enable generating doc comments for this module
|
||||
int doHdrGen; // enable generating header file for this module
|
||||
|
||||
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();
|
||||
#if !IN_LLVM
|
||||
void setDocfile(); // set docfile member
|
||||
#endif
|
||||
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(Scope* unused_sc = NULL); // semantic analysis
|
||||
void semantic2(Scope* unused_sc = NULL); // pass 2 semantic analysis
|
||||
void semantic3(Scope* unused_sc = NULL); // pass 3 semantic analysis
|
||||
void inlineScan(); // scan for functions to inline
|
||||
#if !IN_LLVM
|
||||
void setHdrfile(); // set hdrfile member
|
||||
#endif
|
||||
#ifdef _DH
|
||||
void genhdrfile(); // generate D import file
|
||||
#endif
|
||||
// void gensymfile();
|
||||
void gendocfile();
|
||||
int needModuleInfo();
|
||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
void deleteObjFile();
|
||||
void addDeferredSemantic(Dsymbol *s);
|
||||
void runDeferredSemantic();
|
||||
int imports(Module *m);
|
||||
|
||||
// Back end
|
||||
#if IN_DMD
|
||||
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();
|
||||
#endif
|
||||
void genmoduleinfo();
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
llvm::Module* genLLVMModule(llvm::LLVMContext& context, Ir* sir);
|
||||
void buildTargetFiles(bool singleObj);
|
||||
File* buildFilePath(const char* forcename, const char* path, const char* ext);
|
||||
Module *isModule() { return this; }
|
||||
|
||||
bool llvmForceLogging;
|
||||
|
||||
// array ops emitted in this module already
|
||||
StringTable arrayfuncs;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct ModuleDeclaration
|
||||
{
|
||||
Identifier *id;
|
||||
Array *packages; // array of Identifier's representing packages
|
||||
bool safe;
|
||||
|
||||
ModuleDeclaration(Array *packages, Identifier *id, bool safe);
|
||||
|
||||
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
|
||||
class Ir;
|
||||
struct DValue;
|
||||
typedef DValue elem;
|
||||
namespace llvm {
|
||||
class LLVMContext;
|
||||
class Module;
|
||||
}
|
||||
#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 *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 selfimports; // 0: don't know, 1: does not, 2: does
|
||||
int selfImports(); // returns !=0 if module imports itself
|
||||
|
||||
int insearch;
|
||||
Identifier *searchCacheIdent;
|
||||
Dsymbol *searchCacheSymbol; // cached value of search
|
||||
int searchCacheFlags; // cached flags
|
||||
|
||||
int semanticstarted; // has semantic() been started?
|
||||
int semanticRun; // 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
|
||||
bool safe; // TRUE if module is marked as 'safe'
|
||||
|
||||
size_t nameoffset; // offset of module name from start of ModuleInfo
|
||||
size_t namelen; // length of module name in characters
|
||||
|
||||
int doDocComment; // enable generating doc comments for this module
|
||||
int doHdrGen; // enable generating header file for this module
|
||||
|
||||
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);
|
||||
void toJsonBuffer(OutBuffer *buf);
|
||||
const char *kind();
|
||||
#if !IN_LLVM
|
||||
void setDocfile(); // set docfile member
|
||||
#endif
|
||||
void read(Loc loc); // read file
|
||||
#if IN_GCC
|
||||
void parse(bool dump_source = false); // syntactic parse
|
||||
#else
|
||||
void parse(); // syntactic parse
|
||||
#endif
|
||||
void importAll(Scope *sc);
|
||||
void semantic(Scope* unused_sc = NULL); // semantic analysis
|
||||
void semantic2(Scope* unused_sc = NULL); // pass 2 semantic analysis
|
||||
void semantic3(Scope* unused_sc = NULL); // pass 3 semantic analysis
|
||||
void inlineScan(); // scan for functions to inline
|
||||
#if !IN_LLVM
|
||||
void setHdrfile(); // set hdrfile member
|
||||
#endif
|
||||
#ifdef _DH
|
||||
void genhdrfile(); // generate D import file
|
||||
#endif
|
||||
// void gensymfile();
|
||||
void gendocfile();
|
||||
int needModuleInfo();
|
||||
Dsymbol *search(Loc loc, Identifier *ident, int flags);
|
||||
Dsymbol *symtabInsert(Dsymbol *s);
|
||||
void deleteObjFile();
|
||||
void addDeferredSemantic(Dsymbol *s);
|
||||
static void runDeferredSemantic();
|
||||
static void clearCache();
|
||||
int imports(Module *m);
|
||||
|
||||
// Back end
|
||||
#if IN_DMD
|
||||
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 *ssharedctor; // module shared constructor
|
||||
Symbol *sshareddtor; // module shared destructor
|
||||
Symbol *stest; // module unit test
|
||||
|
||||
Symbol *sfilename; // symbol for filename
|
||||
|
||||
Symbol *massert; // module assert function
|
||||
Symbol *toModuleAssert(); // get module assert function
|
||||
|
||||
Symbol *munittest; // module unittest failure function
|
||||
Symbol *toModuleUnittest(); // get module unittest failure function
|
||||
|
||||
Symbol *marray; // module array bounds function
|
||||
Symbol *toModuleArray(); // get module array bounds function
|
||||
|
||||
|
||||
static Symbol *gencritsec();
|
||||
elem *toEfilename();
|
||||
|
||||
Symbol *toSymbol();
|
||||
#endif
|
||||
void genmoduleinfo();
|
||||
|
||||
#if IN_LLVM
|
||||
// LDC
|
||||
llvm::Module* genLLVMModule(llvm::LLVMContext& context, Ir* sir);
|
||||
void buildTargetFiles(bool singleObj);
|
||||
File* buildFilePath(const char* forcename, const char* path, const char* ext);
|
||||
Module *isModule() { return this; }
|
||||
|
||||
bool llvmForceLogging;
|
||||
|
||||
// array ops emitted in this module already
|
||||
StringTable arrayfuncs;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
struct ModuleDeclaration
|
||||
{
|
||||
Identifier *id;
|
||||
Array *packages; // array of Identifier's representing packages
|
||||
bool safe;
|
||||
|
||||
ModuleDeclaration(Array *packages, Identifier *id, bool safe);
|
||||
|
||||
char *toChars();
|
||||
};
|
||||
|
||||
#endif /* DMD_MODULE_H */
|
||||
|
||||
6972
dmd2/mtype.c
6972
dmd2/mtype.c
File diff suppressed because it is too large
Load Diff
1883
dmd2/mtype.h
1883
dmd2/mtype.h
File diff suppressed because it is too large
Load Diff
122
dmd2/objfile.h
122
dmd2/objfile.h
@@ -1,61 +1,61 @@
|
||||
|
||||
|
||||
#ifndef OBJFILE_H
|
||||
#define OBJFILE_H
|
||||
|
||||
#include "root.h"
|
||||
|
||||
typedef void *SymHandle;
|
||||
typedef unsigned SegOffset;
|
||||
|
||||
enum ObjFormat
|
||||
{
|
||||
NTCOFF,
|
||||
ELF
|
||||
};
|
||||
|
||||
struct ObjFile : File
|
||||
{
|
||||
ObjFile(FileName *);
|
||||
~ObjFile();
|
||||
|
||||
ObjFile *init(ObjFormat);
|
||||
|
||||
void comment(const char *); // insert comment into object file
|
||||
void modulename(const char *); // set module name
|
||||
void library(const char *); // add default library
|
||||
void startaddress(SegHandle seg, SegOffset offset); // set start address
|
||||
|
||||
// Segments
|
||||
enum SegHandle
|
||||
{ code = 1,
|
||||
data, bss
|
||||
};
|
||||
|
||||
SymHandle defineSym(const char *name, SegHandle seg, SegOffset offset);
|
||||
SymHandle externSym(const char *name);
|
||||
|
||||
SegOffset write(SegHandle seg, const void *data, unsigned nbytes);
|
||||
SegOffset writestring(SegHandle seg, char *string);
|
||||
SegOffset write8(SegHandle seg, unsigned b);
|
||||
SegOffset write16(SegHandle seg, unsigned w);
|
||||
SegOffset write32(SegHandle seg, unsigned long v);
|
||||
SegOffset write64(SegHandle seg, unsigned long long v);
|
||||
SegOffset fill0(SegHandle seg, unsigned nbytes);
|
||||
SegOffset align(SegHandle seg, unsigned size);
|
||||
SegOffset writefixup(SegHandle seg, SymHandle sym, unsigned value, int selfrelative);
|
||||
|
||||
// Non-binding hint as to how big seg will grow
|
||||
void reserve(SegHandle seg, SegOffset size);
|
||||
|
||||
// Set actual size
|
||||
void setSize(SegHandle seg, SegOffset size);
|
||||
|
||||
// Get/set offset for subsequent writes
|
||||
void setOffset(SegHandle seg, SegOffset offset);
|
||||
SegOffset getOffset(SegHandle seg);
|
||||
|
||||
SegHandle createSeg(const char *name);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef OBJFILE_H
|
||||
#define OBJFILE_H
|
||||
|
||||
#include "root.h"
|
||||
|
||||
typedef void *SymHandle;
|
||||
typedef unsigned SegOffset;
|
||||
|
||||
enum ObjFormat
|
||||
{
|
||||
NTCOFF,
|
||||
ELF
|
||||
};
|
||||
|
||||
struct ObjFile : File
|
||||
{
|
||||
ObjFile(FileName *);
|
||||
~ObjFile();
|
||||
|
||||
ObjFile *init(ObjFormat);
|
||||
|
||||
void comment(const char *); // insert comment into object file
|
||||
void modulename(const char *); // set module name
|
||||
void library(const char *); // add default library
|
||||
void startaddress(SegHandle seg, SegOffset offset); // set start address
|
||||
|
||||
// Segments
|
||||
enum SegHandle
|
||||
{ code = 1,
|
||||
data, bss
|
||||
};
|
||||
|
||||
SymHandle defineSym(const char *name, SegHandle seg, SegOffset offset);
|
||||
SymHandle externSym(const char *name);
|
||||
|
||||
SegOffset write(SegHandle seg, const void *data, unsigned nbytes);
|
||||
SegOffset writestring(SegHandle seg, char *string);
|
||||
SegOffset write8(SegHandle seg, unsigned b);
|
||||
SegOffset write16(SegHandle seg, unsigned w);
|
||||
SegOffset write32(SegHandle seg, unsigned long v);
|
||||
SegOffset write64(SegHandle seg, unsigned long long v);
|
||||
SegOffset fill0(SegHandle seg, unsigned nbytes);
|
||||
SegOffset align(SegHandle seg, unsigned size);
|
||||
SegOffset writefixup(SegHandle seg, SymHandle sym, unsigned value, int selfrelative);
|
||||
|
||||
// Non-binding hint as to how big seg will grow
|
||||
void reserve(SegHandle seg, SegOffset size);
|
||||
|
||||
// Set actual size
|
||||
void setSize(SegHandle seg, SegOffset size);
|
||||
|
||||
// Get/set offset for subsequent writes
|
||||
void setOffset(SegHandle seg, SegOffset offset);
|
||||
SegOffset getOffset(SegHandle seg);
|
||||
|
||||
SegHandle createSeg(const char *name);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
2233
dmd2/opover.c
2233
dmd2/opover.c
File diff suppressed because it is too large
Load Diff
2039
dmd2/optimize.c
2039
dmd2/optimize.c
File diff suppressed because it is too large
Load Diff
12403
dmd2/parse.c
12403
dmd2/parse.c
File diff suppressed because it is too large
Load Diff
328
dmd2/parse.h
328
dmd2/parse.h
@@ -1,146 +1,182 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_PARSE_H
|
||||
#define DMD_PARSE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "arraytypes.h"
|
||||
#include "lexer.h"
|
||||
#include "enum.h"
|
||||
|
||||
struct Type;
|
||||
struct TypeQualified;
|
||||
struct Expression;
|
||||
struct Declaration;
|
||||
struct Statement;
|
||||
struct Import;
|
||||
struct Initializer;
|
||||
struct FuncDeclaration;
|
||||
struct CtorDeclaration;
|
||||
struct PostBlitDeclaration;
|
||||
struct DtorDeclaration;
|
||||
struct StaticCtorDeclaration;
|
||||
struct StaticDtorDeclaration;
|
||||
struct ConditionalDeclaration;
|
||||
struct InvariantDeclaration;
|
||||
struct UnitTestDeclaration;
|
||||
struct NewDeclaration;
|
||||
struct DeleteDeclaration;
|
||||
struct Condition;
|
||||
struct Module;
|
||||
struct ModuleDeclaration;
|
||||
struct TemplateDeclaration;
|
||||
struct TemplateInstance;
|
||||
struct StaticAssert;
|
||||
|
||||
/************************************
|
||||
* These control how parseStatement() works.
|
||||
*/
|
||||
|
||||
enum ParseStatementFlags
|
||||
{
|
||||
PSsemi = 1, // empty ';' statements are allowed
|
||||
PSscope = 2, // start a new scope
|
||||
PScurly = 4, // { } statement is required
|
||||
PScurlyscope = 8, // { } starts a new scope
|
||||
};
|
||||
|
||||
|
||||
struct Parser : Lexer
|
||||
{
|
||||
ModuleDeclaration *md;
|
||||
enum LINK linkage;
|
||||
Loc endloc; // set to location of last right curly
|
||||
int inBrackets; // inside [] of array index or slice
|
||||
|
||||
Parser(Module *module, unsigned char *base, unsigned length, int doDocComment);
|
||||
|
||||
Array *parseModule();
|
||||
Array *parseDeclDefs(int once);
|
||||
Array *parseAutoDeclarations(unsigned storageClass, unsigned char *comment);
|
||||
Array *parseBlock();
|
||||
void composeStorageClass(unsigned stc);
|
||||
Expression *parseConstraint();
|
||||
TemplateDeclaration *parseTemplateDeclaration();
|
||||
TemplateParameters *parseTemplateParameterList(int flag = 0);
|
||||
Dsymbol *parseMixin();
|
||||
Objects *parseTemplateArgumentList();
|
||||
Objects *parseTemplateArgumentList2();
|
||||
Objects *parseTemplateArgument();
|
||||
StaticAssert *parseStaticAssert();
|
||||
TypeQualified *parseTypeof();
|
||||
enum LINK parseLinkage();
|
||||
Condition *parseDebugCondition();
|
||||
Condition *parseVersionCondition();
|
||||
Condition *parseStaticIfCondition();
|
||||
Dsymbol *parseCtor();
|
||||
PostBlitDeclaration *parsePostBlit();
|
||||
DtorDeclaration *parseDtor();
|
||||
StaticCtorDeclaration *parseStaticCtor();
|
||||
StaticDtorDeclaration *parseStaticDtor();
|
||||
InvariantDeclaration *parseInvariant();
|
||||
UnitTestDeclaration *parseUnitTest();
|
||||
NewDeclaration *parseNew();
|
||||
DeleteDeclaration *parseDelete();
|
||||
Arguments *parseParameters(int *pvarargs);
|
||||
EnumDeclaration *parseEnum();
|
||||
Dsymbol *parseAggregate();
|
||||
BaseClasses *parseBaseClasses();
|
||||
Import *parseImport(Array *decldefs, int isstatic);
|
||||
Type *parseType(Identifier **pident = NULL, TemplateParameters **tpl = NULL);
|
||||
Type *parseBasicType();
|
||||
Type *parseBasicType2(Type *t);
|
||||
Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL);
|
||||
Array *parseDeclarations(unsigned storage_class);
|
||||
void parseContracts(FuncDeclaration *f);
|
||||
Statement *parseStatement(int flags);
|
||||
Initializer *parseInitializer();
|
||||
Expression *parseDefaultInitExp();
|
||||
void check(Loc loc, enum TOK value);
|
||||
void check(enum TOK value);
|
||||
void check(enum TOK value, const char *string);
|
||||
int isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt);
|
||||
int isBasicType(Token **pt);
|
||||
int isDeclarator(Token **pt, int *haveId, enum TOK endtok);
|
||||
int isParameters(Token **pt);
|
||||
int isExpression(Token **pt);
|
||||
int isTemplateInstance(Token *t, Token **pt);
|
||||
int skipParens(Token *t, Token **pt);
|
||||
|
||||
Expression *parseExpression();
|
||||
Expression *parsePrimaryExp();
|
||||
Expression *parseUnaryExp();
|
||||
Expression *parsePostExp(Expression *e);
|
||||
Expression *parseMulExp();
|
||||
Expression *parseAddExp();
|
||||
Expression *parseShiftExp();
|
||||
Expression *parseRelExp();
|
||||
Expression *parseEqualExp();
|
||||
Expression *parseCmpExp();
|
||||
Expression *parseAndExp();
|
||||
Expression *parseXorExp();
|
||||
Expression *parseOrExp();
|
||||
Expression *parseAndAndExp();
|
||||
Expression *parseOrOrExp();
|
||||
Expression *parseCondExp();
|
||||
Expression *parseAssignExp();
|
||||
|
||||
Expressions *parseArguments();
|
||||
|
||||
Expression *parseNewExp(Expression *thisexp);
|
||||
|
||||
void addComment(Dsymbol *s, unsigned char *blockComment);
|
||||
};
|
||||
|
||||
#endif /* DMD_PARSE_H */
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_PARSE_H
|
||||
#define DMD_PARSE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "arraytypes.h"
|
||||
#include "lexer.h"
|
||||
#include "enum.h"
|
||||
|
||||
struct Type;
|
||||
struct TypeQualified;
|
||||
struct Expression;
|
||||
struct Declaration;
|
||||
struct Statement;
|
||||
struct Import;
|
||||
struct Initializer;
|
||||
struct FuncDeclaration;
|
||||
struct CtorDeclaration;
|
||||
struct PostBlitDeclaration;
|
||||
struct DtorDeclaration;
|
||||
struct StaticCtorDeclaration;
|
||||
struct StaticDtorDeclaration;
|
||||
struct SharedStaticCtorDeclaration;
|
||||
struct SharedStaticDtorDeclaration;
|
||||
struct ConditionalDeclaration;
|
||||
struct InvariantDeclaration;
|
||||
struct UnitTestDeclaration;
|
||||
struct NewDeclaration;
|
||||
struct DeleteDeclaration;
|
||||
struct Condition;
|
||||
struct Module;
|
||||
struct ModuleDeclaration;
|
||||
struct TemplateDeclaration;
|
||||
struct TemplateInstance;
|
||||
struct StaticAssert;
|
||||
|
||||
/************************************
|
||||
* These control how parseStatement() works.
|
||||
*/
|
||||
|
||||
enum ParseStatementFlags
|
||||
{
|
||||
PSsemi = 1, // empty ';' statements are allowed
|
||||
PSscope = 2, // start a new scope
|
||||
PScurly = 4, // { } statement is required
|
||||
PScurlyscope = 8, // { } starts a new scope
|
||||
};
|
||||
|
||||
|
||||
struct Parser : Lexer
|
||||
{
|
||||
ModuleDeclaration *md;
|
||||
enum LINK linkage;
|
||||
Loc endloc; // set to location of last right curly
|
||||
int inBrackets; // inside [] of array index or slice
|
||||
|
||||
Parser(Module *module, unsigned char *base, unsigned length, int doDocComment);
|
||||
|
||||
Dsymbols *parseModule();
|
||||
Dsymbols *parseDeclDefs(int once);
|
||||
Dsymbols *parseAutoDeclarations(StorageClass storageClass, unsigned char *comment);
|
||||
Dsymbols *parseBlock();
|
||||
void composeStorageClass(StorageClass stc);
|
||||
StorageClass parseAttribute();
|
||||
StorageClass parsePostfix();
|
||||
Expression *parseConstraint();
|
||||
TemplateDeclaration *parseTemplateDeclaration(int ismixin);
|
||||
TemplateParameters *parseTemplateParameterList(int flag = 0);
|
||||
Dsymbol *parseMixin();
|
||||
Objects *parseTemplateArgumentList();
|
||||
Objects *parseTemplateArgumentList2();
|
||||
Objects *parseTemplateArgument();
|
||||
StaticAssert *parseStaticAssert();
|
||||
TypeQualified *parseTypeof();
|
||||
enum LINK parseLinkage();
|
||||
Condition *parseDebugCondition();
|
||||
Condition *parseVersionCondition();
|
||||
Condition *parseStaticIfCondition();
|
||||
Dsymbol *parseCtor();
|
||||
PostBlitDeclaration *parsePostBlit();
|
||||
DtorDeclaration *parseDtor();
|
||||
StaticCtorDeclaration *parseStaticCtor();
|
||||
StaticDtorDeclaration *parseStaticDtor();
|
||||
SharedStaticCtorDeclaration *parseSharedStaticCtor();
|
||||
SharedStaticDtorDeclaration *parseSharedStaticDtor();
|
||||
InvariantDeclaration *parseInvariant();
|
||||
UnitTestDeclaration *parseUnitTest();
|
||||
NewDeclaration *parseNew();
|
||||
DeleteDeclaration *parseDelete();
|
||||
Parameters *parseParameters(int *pvarargs);
|
||||
EnumDeclaration *parseEnum();
|
||||
Dsymbol *parseAggregate();
|
||||
BaseClasses *parseBaseClasses();
|
||||
Import *parseImport(Dsymbols *decldefs, int isstatic);
|
||||
Type *parseType(Identifier **pident = NULL, TemplateParameters **tpl = NULL);
|
||||
Type *parseBasicType();
|
||||
Type *parseBasicType2(Type *t);
|
||||
Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL);
|
||||
Dsymbols *parseDeclarations(StorageClass storage_class);
|
||||
void parseContracts(FuncDeclaration *f);
|
||||
Statement *parseStatement(int flags);
|
||||
Initializer *parseInitializer();
|
||||
Expression *parseDefaultInitExp();
|
||||
void check(Loc loc, enum TOK value);
|
||||
void check(enum TOK value);
|
||||
void check(enum TOK value, const char *string);
|
||||
void checkParens(enum TOK value, Expression *e);
|
||||
int isDeclaration(Token *t, int needId, enum TOK endtok, Token **pt);
|
||||
int isBasicType(Token **pt);
|
||||
int isDeclarator(Token **pt, int *haveId, enum TOK endtok);
|
||||
int isParameters(Token **pt);
|
||||
int isExpression(Token **pt);
|
||||
int isTemplateInstance(Token *t, Token **pt);
|
||||
int skipParens(Token *t, Token **pt);
|
||||
|
||||
Expression *parseExpression();
|
||||
Expression *parsePrimaryExp();
|
||||
Expression *parseUnaryExp();
|
||||
Expression *parsePostExp(Expression *e);
|
||||
Expression *parseMulExp();
|
||||
Expression *parseAddExp();
|
||||
Expression *parseShiftExp();
|
||||
#if DMDV1
|
||||
Expression *parseRelExp();
|
||||
Expression *parseEqualExp();
|
||||
#endif
|
||||
Expression *parseCmpExp();
|
||||
Expression *parseAndExp();
|
||||
Expression *parseXorExp();
|
||||
Expression *parseOrExp();
|
||||
Expression *parseAndAndExp();
|
||||
Expression *parseOrOrExp();
|
||||
Expression *parseCondExp();
|
||||
Expression *parseAssignExp();
|
||||
|
||||
Expressions *parseArguments();
|
||||
|
||||
Expression *parseNewExp(Expression *thisexp);
|
||||
|
||||
void addComment(Dsymbol *s, unsigned char *blockComment);
|
||||
};
|
||||
|
||||
// Operator precedence - greater values are higher precedence
|
||||
|
||||
enum PREC
|
||||
{
|
||||
PREC_zero,
|
||||
PREC_expr,
|
||||
PREC_assign,
|
||||
PREC_cond,
|
||||
PREC_oror,
|
||||
PREC_andand,
|
||||
PREC_or,
|
||||
PREC_xor,
|
||||
PREC_and,
|
||||
PREC_equal,
|
||||
PREC_rel,
|
||||
PREC_shift,
|
||||
PREC_add,
|
||||
PREC_mul,
|
||||
PREC_pow,
|
||||
PREC_unary,
|
||||
PREC_primary,
|
||||
};
|
||||
|
||||
extern enum PREC precedence[TOKMAX];
|
||||
|
||||
void initPrecedence();
|
||||
|
||||
#endif /* DMD_PARSE_H */
|
||||
|
||||
188
dmd2/root/aav.c
Normal file
188
dmd2/root/aav.c
Normal file
@@ -0,0 +1,188 @@
|
||||
/**
|
||||
* Implementation of associative arrays.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "aav.h"
|
||||
|
||||
static const size_t prime_list[] = {
|
||||
31UL,
|
||||
97UL, 389UL,
|
||||
1543UL, 6151UL,
|
||||
24593UL, 98317UL,
|
||||
393241UL, 1572869UL,
|
||||
6291469UL, 25165843UL,
|
||||
100663319UL, 402653189UL,
|
||||
1610612741UL, 4294967291UL,
|
||||
};
|
||||
|
||||
struct aaA
|
||||
{
|
||||
aaA *next;
|
||||
Key key;
|
||||
Value value;
|
||||
};
|
||||
|
||||
struct AA
|
||||
{
|
||||
aaA* *b;
|
||||
size_t b_length;
|
||||
size_t nodes; // total number of aaA nodes
|
||||
aaA* binit[4]; // initial value of b[]
|
||||
};
|
||||
|
||||
static const AA bbinit = { NULL, };
|
||||
|
||||
/****************************************************
|
||||
* Determine number of entries in associative array.
|
||||
*/
|
||||
|
||||
size_t _aaLen(AA* aa)
|
||||
{
|
||||
return aa ? aa->nodes : 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Get pointer to value in associative array indexed by key.
|
||||
* Add entry for key if it is not already there.
|
||||
*/
|
||||
|
||||
Value* _aaGet(AA** paa, Key key)
|
||||
{
|
||||
//printf("paa = %p\n", paa);
|
||||
|
||||
if (!*paa)
|
||||
{ AA *a = new AA();
|
||||
*a = bbinit;
|
||||
a->b = a->binit;
|
||||
a->b_length = sizeof(a->binit) / sizeof(a->binit[0]);
|
||||
*paa = a;
|
||||
assert((*paa)->b_length == 4);
|
||||
}
|
||||
//printf("paa = %p, *paa = %p\n", paa, *paa);
|
||||
|
||||
assert((*paa)->b_length);
|
||||
size_t i = (size_t)key % (*paa)->b_length;
|
||||
aaA** pe = &(*paa)->b[i];
|
||||
aaA *e;
|
||||
while ((e = *pe) != NULL)
|
||||
{
|
||||
if (key == e->key)
|
||||
return &e->value;
|
||||
pe = &e->next;
|
||||
}
|
||||
|
||||
// Not found, create new elem
|
||||
//printf("create new one\n");
|
||||
e = new aaA();
|
||||
e->next = NULL;
|
||||
e->key = key;
|
||||
e->value = NULL;
|
||||
*pe = e;
|
||||
|
||||
size_t nodes = ++(*paa)->nodes;
|
||||
//printf("length = %d, nodes = %d\n", paa.a.b.length, nodes);
|
||||
if (nodes > (*paa)->b_length * 4)
|
||||
{
|
||||
//printf("rehash\n");
|
||||
_aaRehash(paa);
|
||||
}
|
||||
|
||||
return &e->value;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************
|
||||
* Get value in associative array indexed by key.
|
||||
* Returns NULL if it is not already there.
|
||||
*/
|
||||
|
||||
Value _aaGetRvalue(AA* aa, Key key)
|
||||
{
|
||||
//printf("_aaGetRvalue(key = %p)\n", key);
|
||||
if (!aa)
|
||||
return NULL;
|
||||
|
||||
size_t len = aa->b_length;
|
||||
|
||||
if (len)
|
||||
{
|
||||
size_t i = (size_t)key % len;
|
||||
aaA* e = aa->b[i];
|
||||
while (e)
|
||||
{
|
||||
if (key == e->key)
|
||||
return e->value;
|
||||
e = e->next;
|
||||
}
|
||||
}
|
||||
return NULL; // not found
|
||||
}
|
||||
|
||||
|
||||
/********************************************
|
||||
* Rehash an array.
|
||||
*/
|
||||
|
||||
void _aaRehash(AA** paa)
|
||||
{
|
||||
//printf("Rehash\n");
|
||||
if (*paa)
|
||||
{
|
||||
AA newb = bbinit;
|
||||
AA *aa = *paa;
|
||||
size_t len = _aaLen(*paa);
|
||||
if (len)
|
||||
{ size_t i;
|
||||
|
||||
for (i = 0; i < sizeof(prime_list)/sizeof(prime_list[0]) - 1; i++)
|
||||
{
|
||||
if (len <= prime_list[i])
|
||||
break;
|
||||
}
|
||||
len = prime_list[i];
|
||||
newb.b = new aaA*[len];
|
||||
memset(newb.b, 0, len * sizeof(aaA*));
|
||||
newb.b_length = len;
|
||||
|
||||
for (size_t k = 0; k < aa->b_length; k++)
|
||||
{ aaA *e = aa->b[k];
|
||||
while (e)
|
||||
{ aaA* enext = e->next;
|
||||
size_t j = (size_t)e->key % len;
|
||||
e->next = newb.b[j];
|
||||
newb.b[j] = e;
|
||||
e = enext;
|
||||
}
|
||||
}
|
||||
if (aa->b != aa->binit)
|
||||
delete aa->b;
|
||||
|
||||
newb.nodes = aa->nodes;
|
||||
}
|
||||
|
||||
**paa = newb;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if UNITTEST
|
||||
|
||||
void unittest_aa()
|
||||
{
|
||||
AA* aa = NULL;
|
||||
Value v = _aaGetRvalue(aa, NULL);
|
||||
assert(!v);
|
||||
Value *pv = _aaGet(&aa, NULL);
|
||||
assert(pv);
|
||||
*pv = (void *)3;
|
||||
v = _aaGetRvalue(aa, NULL);
|
||||
assert(v == (void *)3);
|
||||
}
|
||||
|
||||
#endif
|
||||
11
dmd2/root/aav.h
Normal file
11
dmd2/root/aav.h
Normal file
@@ -0,0 +1,11 @@
|
||||
|
||||
typedef void* Value;
|
||||
typedef void* Key;
|
||||
|
||||
struct AA;
|
||||
|
||||
size_t _aaLen(AA* aa);
|
||||
Value* _aaGet(AA** aa, Key key);
|
||||
Value _aaGetRvalue(AA* aa, Key key);
|
||||
void _aaRehash(AA** paa);
|
||||
|
||||
@@ -1,224 +1,254 @@
|
||||
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if (defined (__SVR4) && defined (__sun))
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#if _MSC_VER || __MINGW32__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#if IN_GCC
|
||||
#include "gdc_alloca.h"
|
||||
#endif
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#endif
|
||||
|
||||
#include "port.h"
|
||||
#include "root.h"
|
||||
#include "dchar.h"
|
||||
#include "rmem.h"
|
||||
|
||||
|
||||
/********************************* Array ****************************/
|
||||
|
||||
Array::Array()
|
||||
{
|
||||
data = NULL;
|
||||
dim = 0;
|
||||
allocdim = 0;
|
||||
}
|
||||
|
||||
Array::~Array()
|
||||
{
|
||||
mem.free(data);
|
||||
}
|
||||
|
||||
void Array::mark()
|
||||
{ unsigned u;
|
||||
|
||||
mem.mark(data);
|
||||
for (u = 0; u < dim; u++)
|
||||
mem.mark(data[u]); // BUG: what if arrays of Object's?
|
||||
}
|
||||
|
||||
void Array::reserve(unsigned nentries)
|
||||
{
|
||||
//printf("Array::reserve: size = %d, offset = %d, nbytes = %d\n", size, offset, nbytes);
|
||||
if (allocdim - dim < nentries)
|
||||
{
|
||||
allocdim = dim + nentries;
|
||||
data = (void **)mem.realloc(data, allocdim * sizeof(*data));
|
||||
}
|
||||
}
|
||||
|
||||
void Array::setDim(unsigned newdim)
|
||||
{
|
||||
if (dim < newdim)
|
||||
{
|
||||
reserve(newdim - dim);
|
||||
}
|
||||
dim = newdim;
|
||||
}
|
||||
|
||||
void Array::fixDim()
|
||||
{
|
||||
if (dim != allocdim)
|
||||
{ data = (void **)mem.realloc(data, dim * sizeof(*data));
|
||||
allocdim = dim;
|
||||
}
|
||||
}
|
||||
|
||||
void Array::push(void *ptr)
|
||||
{
|
||||
reserve(1);
|
||||
data[dim++] = ptr;
|
||||
}
|
||||
|
||||
void *Array::pop()
|
||||
{
|
||||
return data[--dim];
|
||||
}
|
||||
|
||||
void Array::shift(void *ptr)
|
||||
{
|
||||
reserve(1);
|
||||
memmove(data + 1, data, dim * sizeof(*data));
|
||||
data[0] = ptr;
|
||||
dim++;
|
||||
}
|
||||
|
||||
void Array::insert(unsigned index, void *ptr)
|
||||
{
|
||||
reserve(1);
|
||||
memmove(data + index + 1, data + index, (dim - index) * sizeof(*data));
|
||||
data[index] = ptr;
|
||||
dim++;
|
||||
}
|
||||
|
||||
|
||||
void Array::insert(unsigned index, Array *a)
|
||||
{
|
||||
if (a)
|
||||
{ unsigned d;
|
||||
|
||||
d = a->dim;
|
||||
reserve(d);
|
||||
if (dim != index)
|
||||
memmove(data + index + d, data + index, (dim - index) * sizeof(*data));
|
||||
memcpy(data + index, a->data, d * sizeof(*data));
|
||||
dim += d;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************
|
||||
* Append array a to this array.
|
||||
*/
|
||||
|
||||
void Array::append(Array *a)
|
||||
{
|
||||
insert(dim, a);
|
||||
}
|
||||
|
||||
void Array::remove(unsigned i)
|
||||
{
|
||||
memmove(data + i, data + i + 1, (dim - i - 1) * sizeof(data[0]));
|
||||
dim--;
|
||||
}
|
||||
|
||||
char *Array::toChars()
|
||||
{
|
||||
unsigned len;
|
||||
unsigned u;
|
||||
char **buf;
|
||||
char *str;
|
||||
char *p;
|
||||
|
||||
buf = (char **)alloca(dim * sizeof(char *));
|
||||
len = 2;
|
||||
for (u = 0; u < dim; u++)
|
||||
{
|
||||
buf[u] = ((Object *)data[u])->toChars();
|
||||
len += strlen(buf[u]) + 1;
|
||||
}
|
||||
str = (char *)mem.malloc(len);
|
||||
|
||||
str[0] = '[';
|
||||
p = str + 1;
|
||||
for (u = 0; u < dim; u++)
|
||||
{
|
||||
if (u)
|
||||
*p++ = ',';
|
||||
len = strlen(buf[u]);
|
||||
memcpy(p,buf[u],len);
|
||||
p += len;
|
||||
}
|
||||
*p++ = ']';
|
||||
*p = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
void Array::zero()
|
||||
{
|
||||
memset(data,0,dim * sizeof(data[0]));
|
||||
}
|
||||
|
||||
void *Array::tos()
|
||||
{
|
||||
return dim ? data[dim - 1] : NULL;
|
||||
}
|
||||
|
||||
int
|
||||
#if _WIN32
|
||||
__cdecl
|
||||
#endif
|
||||
Array_sort_compare(const void *x, const void *y)
|
||||
{
|
||||
Object *ox = *(Object **)x;
|
||||
Object *oy = *(Object **)y;
|
||||
|
||||
return ox->compare(oy);
|
||||
}
|
||||
|
||||
void Array::sort()
|
||||
{
|
||||
if (dim)
|
||||
{
|
||||
qsort(data, dim, sizeof(Object *), Array_sort_compare);
|
||||
}
|
||||
}
|
||||
|
||||
Array *Array::copy()
|
||||
{
|
||||
Array *a = new Array();
|
||||
|
||||
a->setDim(dim);
|
||||
memcpy(a->data, data, dim * sizeof(void *));
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
// Copyright (c) 1999-2010 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 <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if (defined (__SVR4) && defined (__sun))
|
||||
#include <alloca.h>
|
||||
#endif
|
||||
|
||||
#if _MSC_VER || __MINGW32__
|
||||
#include <malloc.h>
|
||||
#endif
|
||||
|
||||
#if IN_GCC
|
||||
#include "gdc_alloca.h"
|
||||
#endif
|
||||
|
||||
#if _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
#ifndef _WIN32
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#endif
|
||||
|
||||
#include "port.h"
|
||||
#include "root.h"
|
||||
#include "dchar.h"
|
||||
#include "rmem.h"
|
||||
|
||||
|
||||
/********************************* Array ****************************/
|
||||
|
||||
Array::Array()
|
||||
{
|
||||
data = SMALLARRAYCAP ? &smallarray[0] : NULL;
|
||||
dim = 0;
|
||||
allocdim = SMALLARRAYCAP;
|
||||
}
|
||||
|
||||
Array::~Array()
|
||||
{
|
||||
if (data != &smallarray[0])
|
||||
mem.free(data);
|
||||
}
|
||||
|
||||
void Array::mark()
|
||||
{ unsigned u;
|
||||
|
||||
mem.mark(data);
|
||||
for (u = 0; u < dim; u++)
|
||||
mem.mark(data[u]); // BUG: what if arrays of Object's?
|
||||
}
|
||||
|
||||
void Array::reserve(unsigned nentries)
|
||||
{
|
||||
//printf("Array::reserve: dim = %d, allocdim = %d, nentries = %d\n", dim, allocdim, nentries);
|
||||
if (allocdim - dim < nentries)
|
||||
{
|
||||
if (allocdim == 0)
|
||||
{ // Not properly initialized, someone memset it to zero
|
||||
if (nentries <= SMALLARRAYCAP)
|
||||
{ allocdim = SMALLARRAYCAP;
|
||||
data = SMALLARRAYCAP ? &smallarray[0] : NULL;
|
||||
}
|
||||
else
|
||||
{ allocdim = nentries;
|
||||
data = (void **)mem.malloc(allocdim * sizeof(*data));
|
||||
}
|
||||
}
|
||||
else if (allocdim == SMALLARRAYCAP)
|
||||
{
|
||||
allocdim = dim + nentries;
|
||||
data = (void **)mem.malloc(allocdim * sizeof(*data));
|
||||
memcpy(data, &smallarray[0], dim * sizeof(*data));
|
||||
}
|
||||
else
|
||||
{ allocdim = dim + nentries;
|
||||
data = (void **)mem.realloc(data, allocdim * sizeof(*data));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Array::setDim(unsigned newdim)
|
||||
{
|
||||
if (dim < newdim)
|
||||
{
|
||||
reserve(newdim - dim);
|
||||
}
|
||||
dim = newdim;
|
||||
}
|
||||
|
||||
void Array::fixDim()
|
||||
{
|
||||
if (dim != allocdim)
|
||||
{
|
||||
if (allocdim >= SMALLARRAYCAP)
|
||||
{
|
||||
if (dim <= SMALLARRAYCAP)
|
||||
{
|
||||
memcpy(&smallarray[0], data, dim * sizeof(*data));
|
||||
mem.free(data);
|
||||
}
|
||||
else
|
||||
data = (void **)mem.realloc(data, dim * sizeof(*data));
|
||||
}
|
||||
allocdim = dim;
|
||||
}
|
||||
}
|
||||
|
||||
void Array::push(void *ptr)
|
||||
{
|
||||
reserve(1);
|
||||
data[dim++] = ptr;
|
||||
}
|
||||
|
||||
void *Array::pop()
|
||||
{
|
||||
return data[--dim];
|
||||
}
|
||||
|
||||
void Array::shift(void *ptr)
|
||||
{
|
||||
reserve(1);
|
||||
memmove(data + 1, data, dim * sizeof(*data));
|
||||
data[0] = ptr;
|
||||
dim++;
|
||||
}
|
||||
|
||||
void Array::insert(unsigned index, void *ptr)
|
||||
{
|
||||
reserve(1);
|
||||
memmove(data + index + 1, data + index, (dim - index) * sizeof(*data));
|
||||
data[index] = ptr;
|
||||
dim++;
|
||||
}
|
||||
|
||||
|
||||
void Array::insert(unsigned index, Array *a)
|
||||
{
|
||||
if (a)
|
||||
{ unsigned d;
|
||||
|
||||
d = a->dim;
|
||||
reserve(d);
|
||||
if (dim != index)
|
||||
memmove(data + index + d, data + index, (dim - index) * sizeof(*data));
|
||||
memcpy(data + index, a->data, d * sizeof(*data));
|
||||
dim += d;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/***********************************
|
||||
* Append array a to this array.
|
||||
*/
|
||||
|
||||
void Array::append(Array *a)
|
||||
{
|
||||
insert(dim, a);
|
||||
}
|
||||
|
||||
void Array::remove(unsigned i)
|
||||
{
|
||||
memmove(data + i, data + i + 1, (dim - i - 1) * sizeof(data[0]));
|
||||
dim--;
|
||||
}
|
||||
|
||||
char *Array::toChars()
|
||||
{
|
||||
unsigned len;
|
||||
unsigned u;
|
||||
char **buf;
|
||||
char *str;
|
||||
char *p;
|
||||
|
||||
buf = (char **)alloca(dim * sizeof(char *));
|
||||
len = 2;
|
||||
for (u = 0; u < dim; u++)
|
||||
{
|
||||
buf[u] = ((Object *)data[u])->toChars();
|
||||
len += strlen(buf[u]) + 1;
|
||||
}
|
||||
str = (char *)mem.malloc(len);
|
||||
|
||||
str[0] = '[';
|
||||
p = str + 1;
|
||||
for (u = 0; u < dim; u++)
|
||||
{
|
||||
if (u)
|
||||
*p++ = ',';
|
||||
len = strlen(buf[u]);
|
||||
memcpy(p,buf[u],len);
|
||||
p += len;
|
||||
}
|
||||
*p++ = ']';
|
||||
*p = 0;
|
||||
return str;
|
||||
}
|
||||
|
||||
void Array::zero()
|
||||
{
|
||||
memset(data,0,dim * sizeof(data[0]));
|
||||
}
|
||||
|
||||
void *Array::tos()
|
||||
{
|
||||
return dim ? data[dim - 1] : NULL;
|
||||
}
|
||||
|
||||
int
|
||||
#if _WIN32
|
||||
__cdecl
|
||||
#endif
|
||||
Array_sort_compare(const void *x, const void *y)
|
||||
{
|
||||
Object *ox = *(Object **)x;
|
||||
Object *oy = *(Object **)y;
|
||||
|
||||
return ox->compare(oy);
|
||||
}
|
||||
|
||||
void Array::sort()
|
||||
{
|
||||
if (dim)
|
||||
{
|
||||
qsort(data, dim, sizeof(Object *), Array_sort_compare);
|
||||
}
|
||||
}
|
||||
|
||||
Array *Array::copy()
|
||||
{
|
||||
Array *a = new Array();
|
||||
|
||||
a->setDim(dim);
|
||||
memcpy(a->data, data, dim * sizeof(void *));
|
||||
return a;
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#if _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <process.h>
|
||||
|
||||
@@ -43,7 +42,7 @@ struct AsyncRead
|
||||
AsyncRead *AsyncRead::create(size_t nfiles)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
|
||||
(nfiles - 1) * sizeof(FileData));
|
||||
(nfiles - 1) * sizeof(FileData));
|
||||
aw->filesmax = nfiles;
|
||||
return aw;
|
||||
}
|
||||
@@ -64,22 +63,22 @@ void AsyncRead::start()
|
||||
//printf("aw->filesdim = %p %d\n", this, filesdim);
|
||||
if (filesdim)
|
||||
{
|
||||
unsigned threadaddr;
|
||||
hThread = (HANDLE) _beginthreadex(NULL,
|
||||
0,
|
||||
&startthread,
|
||||
this,
|
||||
0,
|
||||
(unsigned *)&threadaddr);
|
||||
unsigned threadaddr;
|
||||
hThread = (HANDLE) _beginthreadex(NULL,
|
||||
0,
|
||||
&startthread,
|
||||
this,
|
||||
0,
|
||||
(unsigned *)&threadaddr);
|
||||
|
||||
if (hThread)
|
||||
{
|
||||
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
if (hThread)
|
||||
{
|
||||
SetThreadPriority(hThread, THREAD_PRIORITY_HIGHEST);
|
||||
}
|
||||
else
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -87,7 +86,7 @@ int AsyncRead::read(size_t i)
|
||||
{
|
||||
FileData *f = &files[i];
|
||||
WaitForSingleObject(f->event, INFINITE);
|
||||
Sleep(0); // give up time slice
|
||||
Sleep(0); // give up time slice
|
||||
return f->result;
|
||||
}
|
||||
|
||||
@@ -104,13 +103,160 @@ unsigned __stdcall startthread(void *p)
|
||||
|
||||
//printf("aw->filesdim = %p %d\n", aw, aw->filesdim);
|
||||
for (size_t i = 0; i < aw->filesdim; i++)
|
||||
{ FileData *f = &aw->files[i];
|
||||
{ FileData *f = &aw->files[i];
|
||||
|
||||
f->result = f->file->read();
|
||||
SetEvent(f->event);
|
||||
f->result = f->file->read();
|
||||
SetEvent(f->event);
|
||||
}
|
||||
_endthreadex(EXIT_SUCCESS);
|
||||
return EXIT_SUCCESS; // if skidding
|
||||
return EXIT_SUCCESS; // if skidding
|
||||
}
|
||||
|
||||
#elif linux // Posix
|
||||
|
||||
#include <errno.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "rmem.h"
|
||||
|
||||
void *startthread(void *arg);
|
||||
|
||||
void err_abort(int status, const char *msg)
|
||||
{
|
||||
fprintf(stderr, "fatal error = %d, %s\n", status, msg);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
struct FileData
|
||||
{
|
||||
File *file;
|
||||
int result;
|
||||
|
||||
pthread_mutex_t mutex;
|
||||
pthread_cond_t cond;
|
||||
int value;
|
||||
};
|
||||
|
||||
struct AsyncRead
|
||||
{
|
||||
static AsyncRead *create(size_t nfiles);
|
||||
void addFile(File *file);
|
||||
void start();
|
||||
int read(size_t i);
|
||||
static void dispose(AsyncRead *);
|
||||
|
||||
size_t filesdim;
|
||||
size_t filesmax;
|
||||
FileData files[1];
|
||||
};
|
||||
|
||||
|
||||
AsyncRead *AsyncRead::create(size_t nfiles)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
|
||||
(nfiles - 1) * sizeof(FileData));
|
||||
aw->filesmax = nfiles;
|
||||
return aw;
|
||||
}
|
||||
|
||||
void AsyncRead::addFile(File *file)
|
||||
{
|
||||
//printf("addFile(file = %p)\n", file);
|
||||
//printf("filesdim = %d, filesmax = %d\n", filesdim, filesmax);
|
||||
assert(filesdim < filesmax);
|
||||
FileData *f = &files[filesdim];
|
||||
f->file = file;
|
||||
|
||||
int status = pthread_mutex_init(&f->mutex, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "init mutex");
|
||||
status = pthread_cond_init(&f->cond, NULL);
|
||||
if (status != 0)
|
||||
err_abort(status, "init cond");
|
||||
|
||||
filesdim++;
|
||||
}
|
||||
|
||||
void AsyncRead::start()
|
||||
{
|
||||
//printf("aw->filesdim = %p %d\n", this, filesdim);
|
||||
if (filesdim)
|
||||
{
|
||||
pthread_t thread_id;
|
||||
int status = pthread_create(&thread_id,
|
||||
NULL,
|
||||
&startthread,
|
||||
this);
|
||||
if (status != 0)
|
||||
err_abort(status, "create thread");
|
||||
}
|
||||
}
|
||||
|
||||
int AsyncRead::read(size_t i)
|
||||
{
|
||||
FileData *f = &files[i];
|
||||
|
||||
// Wait for the event
|
||||
int status = pthread_mutex_lock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "lock mutex");
|
||||
while (f->value == 0)
|
||||
{
|
||||
status = pthread_cond_wait(&f->cond, &f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "wait on condition");
|
||||
}
|
||||
status = pthread_mutex_unlock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "unlock mutex");
|
||||
|
||||
return f->result;
|
||||
}
|
||||
|
||||
void AsyncRead::dispose(AsyncRead *aw)
|
||||
{
|
||||
//printf("AsyncRead::dispose()\n");
|
||||
for (int i = 0; i < aw->filesdim; i++)
|
||||
{
|
||||
FileData *f = &aw->files[i];
|
||||
int status = pthread_cond_destroy(&f->cond);
|
||||
if (status != 0)
|
||||
err_abort(status, "cond destroy");
|
||||
status = pthread_mutex_destroy(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "mutex destroy");
|
||||
}
|
||||
delete aw;
|
||||
}
|
||||
|
||||
|
||||
void *startthread(void *p)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)p;
|
||||
|
||||
//printf("startthread: aw->filesdim = %p %d\n", aw, aw->filesdim);
|
||||
size_t dim = aw->filesdim;
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ FileData *f = &aw->files[i];
|
||||
|
||||
f->result = f->file->read();
|
||||
|
||||
// Set event
|
||||
int status = pthread_mutex_lock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "lock mutex");
|
||||
f->value = 1;
|
||||
status = pthread_cond_signal(&f->cond);
|
||||
if (status != 0)
|
||||
err_abort(status, "signal condition");
|
||||
status = pthread_mutex_unlock(&f->mutex);
|
||||
if (status != 0)
|
||||
err_abort(status, "unlock mutex");
|
||||
}
|
||||
|
||||
return NULL; // end thread
|
||||
}
|
||||
|
||||
#else
|
||||
@@ -147,7 +293,7 @@ struct AsyncRead
|
||||
AsyncRead *AsyncRead::create(size_t nfiles)
|
||||
{
|
||||
AsyncRead *aw = (AsyncRead *)mem.calloc(1, sizeof(AsyncRead) +
|
||||
(nfiles - 1) * sizeof(FileData));
|
||||
(nfiles - 1) * sizeof(FileData));
|
||||
aw->filesmax = nfiles;
|
||||
return aw;
|
||||
}
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
|
||||
// Copyright (c) 2009-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef ASYNC_H
|
||||
#define ASYNC_H
|
||||
|
||||
#if __DMC__
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
/*******************
|
||||
* Simple interface to read files asynchronously in another
|
||||
* thread.
|
||||
*/
|
||||
|
||||
struct AsyncRead
|
||||
{
|
||||
static AsyncRead *create(size_t nfiles);
|
||||
void addFile(File *file);
|
||||
void start();
|
||||
int read(size_t i);
|
||||
static void dispose(AsyncRead *);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
// Copyright (c) 2009-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef ASYNC_H
|
||||
#define ASYNC_H
|
||||
|
||||
#if __DMC__
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
|
||||
/*******************
|
||||
* Simple interface to read files asynchronously in another
|
||||
* thread.
|
||||
*/
|
||||
|
||||
struct AsyncRead
|
||||
{
|
||||
static AsyncRead *create(size_t nfiles);
|
||||
void addFile(File *file);
|
||||
void start();
|
||||
int read(size_t i);
|
||||
static void dispose(AsyncRead *);
|
||||
};
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,482 +1,482 @@
|
||||
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "dchar.h"
|
||||
#include "rmem.h"
|
||||
|
||||
#if M_UNICODE
|
||||
|
||||
// Converts a char string to Unicode
|
||||
|
||||
dchar *Dchar::dup(char *p)
|
||||
{
|
||||
dchar *s;
|
||||
size_t len;
|
||||
|
||||
if (!p)
|
||||
return NULL;
|
||||
len = strlen(p);
|
||||
s = (dchar *)mem.malloc((len + 1) * sizeof(dchar));
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
{
|
||||
s[i] = (dchar)(p[i] & 0xFF);
|
||||
}
|
||||
s[len] = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
dchar *Dchar::memchr(dchar *p, int c, int count)
|
||||
{
|
||||
int u;
|
||||
|
||||
for (u = 0; u < count; u++)
|
||||
{
|
||||
if (p[u] == c)
|
||||
return p + u;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if _WIN32 && __DMC__
|
||||
__declspec(naked)
|
||||
unsigned Dchar::calcHash(const dchar *str, unsigned len)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov ECX,4[ESP]
|
||||
mov EDX,8[ESP]
|
||||
xor EAX,EAX
|
||||
test EDX,EDX
|
||||
je L92
|
||||
|
||||
LC8: cmp EDX,1
|
||||
je L98
|
||||
cmp EDX,2
|
||||
je LAE
|
||||
|
||||
add EAX,[ECX]
|
||||
// imul EAX,EAX,025h
|
||||
lea EAX,[EAX][EAX*8]
|
||||
add ECX,4
|
||||
sub EDX,2
|
||||
jmp LC8
|
||||
|
||||
L98: mov DX,[ECX]
|
||||
and EDX,0FFFFh
|
||||
add EAX,EDX
|
||||
ret
|
||||
|
||||
LAE: add EAX,[ECX]
|
||||
L92: ret
|
||||
}
|
||||
}
|
||||
#else
|
||||
hash_t Dchar::calcHash(const dchar *str, size_t len)
|
||||
{
|
||||
unsigned hash = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash += *(const uint16_t *)str;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash += *(const uint32_t *)str;
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash += *(const uint32_t *)str;
|
||||
hash *= 37;
|
||||
str += 2;
|
||||
len -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
hash_t Dchar::icalcHash(const dchar *str, size_t len)
|
||||
{
|
||||
hash_t hash = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash += *(const uint16_t *)str | 0x20;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash += *(const uint32_t *)str | 0x200020;
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash += *(const uint32_t *)str | 0x200020;
|
||||
hash *= 37;
|
||||
str += 2;
|
||||
len -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif MCBS
|
||||
|
||||
hash_t Dchar::calcHash(const dchar *str, size_t len)
|
||||
{
|
||||
hash_t hash = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 37;
|
||||
hash += *(const uint8_t *)str;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash *= 37;
|
||||
hash += *(const uint16_t *)str;
|
||||
return hash;
|
||||
|
||||
case 3:
|
||||
hash *= 37;
|
||||
hash += (*(const uint16_t *)str << 8) +
|
||||
((const uint8_t *)str)[2];
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 37;
|
||||
hash += *(const uint32_t *)str;
|
||||
str += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif UTF8
|
||||
|
||||
// Specification is: http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335
|
||||
|
||||
char Dchar::mblen[256] =
|
||||
{
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1,
|
||||
};
|
||||
|
||||
dchar *Dchar::dec(dchar *pstart, dchar *p)
|
||||
{
|
||||
while ((p[-1] & 0xC0) == 0x80)
|
||||
p--;
|
||||
return p;
|
||||
}
|
||||
|
||||
int Dchar::get(dchar *p)
|
||||
{
|
||||
unsigned c;
|
||||
unsigned char *q = (unsigned char *)p;
|
||||
|
||||
c = q[0];
|
||||
switch (mblen[c])
|
||||
{
|
||||
case 2:
|
||||
c = ((c - 0xC0) << 6) |
|
||||
(q[1] - 0x80);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
c = ((c - 0xE0) << 12) |
|
||||
((q[1] - 0x80) << 6) |
|
||||
(q[2] - 0x80);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
c = ((c - 0xF0) << 18) |
|
||||
((q[1] - 0x80) << 12) |
|
||||
((q[2] - 0x80) << 6) |
|
||||
(q[3] - 0x80);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
c = ((c - 0xF8) << 24) |
|
||||
((q[1] - 0x80) << 18) |
|
||||
((q[2] - 0x80) << 12) |
|
||||
((q[3] - 0x80) << 6) |
|
||||
(q[4] - 0x80);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
c = ((c - 0xFC) << 30) |
|
||||
((q[1] - 0x80) << 24) |
|
||||
((q[2] - 0x80) << 18) |
|
||||
((q[3] - 0x80) << 12) |
|
||||
((q[4] - 0x80) << 6) |
|
||||
(q[5] - 0x80);
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
dchar *Dchar::put(dchar *p, unsigned c)
|
||||
{
|
||||
if (c <= 0x7F)
|
||||
{
|
||||
*p++ = c;
|
||||
}
|
||||
else if (c <= 0x7FF)
|
||||
{
|
||||
p[0] = 0xC0 + (c >> 6);
|
||||
p[1] = 0x80 + (c & 0x3F);
|
||||
p += 2;
|
||||
}
|
||||
else if (c <= 0xFFFF)
|
||||
{
|
||||
p[0] = 0xE0 + (c >> 12);
|
||||
p[1] = 0x80 + ((c >> 6) & 0x3F);
|
||||
p[2] = 0x80 + (c & 0x3F);
|
||||
p += 3;
|
||||
}
|
||||
else if (c <= 0x1FFFFF)
|
||||
{
|
||||
p[0] = 0xF0 + (c >> 18);
|
||||
p[1] = 0x80 + ((c >> 12) & 0x3F);
|
||||
p[2] = 0x80 + ((c >> 6) & 0x3F);
|
||||
p[3] = 0x80 + (c & 0x3F);
|
||||
p += 4;
|
||||
}
|
||||
else if (c <= 0x3FFFFFF)
|
||||
{
|
||||
p[0] = 0xF8 + (c >> 24);
|
||||
p[1] = 0x80 + ((c >> 18) & 0x3F);
|
||||
p[2] = 0x80 + ((c >> 12) & 0x3F);
|
||||
p[3] = 0x80 + ((c >> 6) & 0x3F);
|
||||
p[4] = 0x80 + (c & 0x3F);
|
||||
p += 5;
|
||||
}
|
||||
else if (c <= 0x7FFFFFFF)
|
||||
{
|
||||
p[0] = 0xFC + (c >> 30);
|
||||
p[1] = 0x80 + ((c >> 24) & 0x3F);
|
||||
p[2] = 0x80 + ((c >> 18) & 0x3F);
|
||||
p[3] = 0x80 + ((c >> 12) & 0x3F);
|
||||
p[4] = 0x80 + ((c >> 6) & 0x3F);
|
||||
p[5] = 0x80 + (c & 0x3F);
|
||||
p += 6;
|
||||
}
|
||||
else
|
||||
assert(0); // not a UCS-4 character
|
||||
return p;
|
||||
}
|
||||
|
||||
hash_t Dchar::calcHash(const dchar *str, size_t len)
|
||||
{
|
||||
hash_t hash = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 37;
|
||||
hash += *(const uint8_t *)str;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += *(const uint16_t *)str;
|
||||
#else
|
||||
hash += str[0] * 256 + str[1];
|
||||
#endif
|
||||
return hash;
|
||||
|
||||
case 3:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += (*(const uint16_t *)str << 8) +
|
||||
((const uint8_t *)str)[2];
|
||||
#else
|
||||
hash += (str[0] * 256 + str[1]) * 256 + str[2];
|
||||
#endif
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += *(const uint32_t *)str;
|
||||
#else
|
||||
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
|
||||
#endif
|
||||
|
||||
str += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else // ascii
|
||||
|
||||
hash_t Dchar::calcHash(const dchar *str, size_t len)
|
||||
{
|
||||
hash_t hash = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 37;
|
||||
hash += *(const uint8_t *)str;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += *(const uint16_t *)str;
|
||||
#else
|
||||
hash += str[0] * 256 + str[1];
|
||||
#endif
|
||||
return hash;
|
||||
|
||||
case 3:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += (*(const uint16_t *)str << 8) +
|
||||
((const uint8_t *)str)[2];
|
||||
#else
|
||||
hash += (str[0] * 256 + str[1]) * 256 + str[2];
|
||||
#endif
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += *(const uint32_t *)str;
|
||||
#else
|
||||
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
|
||||
#endif
|
||||
str += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hash_t Dchar::icalcHash(const dchar *str, size_t len)
|
||||
{
|
||||
hash_t hash = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 37;
|
||||
hash += *(const uint8_t *)str | 0x20;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash *= 37;
|
||||
hash += *(const uint16_t *)str | 0x2020;
|
||||
return hash;
|
||||
|
||||
case 3:
|
||||
hash *= 37;
|
||||
hash += ((*(const uint16_t *)str << 8) +
|
||||
((const uint8_t *)str)[2]) | 0x202020;
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 37;
|
||||
hash += *(const uint32_t *)str | 0x20202020;
|
||||
str += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
|
||||
void main()
|
||||
{
|
||||
// Print out values to hardcode into Dchar::mblen[]
|
||||
int c;
|
||||
int s;
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
{
|
||||
s = 1;
|
||||
if (c >= 0xC0 && c <= 0xDF)
|
||||
s = 2;
|
||||
if (c >= 0xE0 && c <= 0xEF)
|
||||
s = 3;
|
||||
if (c >= 0xF0 && c <= 0xF7)
|
||||
s = 4;
|
||||
if (c >= 0xF8 && c <= 0xFB)
|
||||
s = 5;
|
||||
if (c >= 0xFC && c <= 0xFD)
|
||||
s = 6;
|
||||
|
||||
printf("%d", s);
|
||||
if ((c & 15) == 15)
|
||||
printf(",\n");
|
||||
else
|
||||
printf(",");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "dchar.h"
|
||||
#include "rmem.h"
|
||||
|
||||
#if M_UNICODE
|
||||
|
||||
// Converts a char string to Unicode
|
||||
|
||||
dchar *Dchar::dup(char *p)
|
||||
{
|
||||
dchar *s;
|
||||
size_t len;
|
||||
|
||||
if (!p)
|
||||
return NULL;
|
||||
len = strlen(p);
|
||||
s = (dchar *)mem.malloc((len + 1) * sizeof(dchar));
|
||||
for (unsigned i = 0; i < len; i++)
|
||||
{
|
||||
s[i] = (dchar)(p[i] & 0xFF);
|
||||
}
|
||||
s[len] = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
dchar *Dchar::memchr(dchar *p, int c, int count)
|
||||
{
|
||||
int u;
|
||||
|
||||
for (u = 0; u < count; u++)
|
||||
{
|
||||
if (p[u] == c)
|
||||
return p + u;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#if _WIN32 && __DMC__
|
||||
__declspec(naked)
|
||||
unsigned Dchar::calcHash(const dchar *str, unsigned len)
|
||||
{
|
||||
__asm
|
||||
{
|
||||
mov ECX,4[ESP]
|
||||
mov EDX,8[ESP]
|
||||
xor EAX,EAX
|
||||
test EDX,EDX
|
||||
je L92
|
||||
|
||||
LC8: cmp EDX,1
|
||||
je L98
|
||||
cmp EDX,2
|
||||
je LAE
|
||||
|
||||
add EAX,[ECX]
|
||||
// imul EAX,EAX,025h
|
||||
lea EAX,[EAX][EAX*8]
|
||||
add ECX,4
|
||||
sub EDX,2
|
||||
jmp LC8
|
||||
|
||||
L98: mov DX,[ECX]
|
||||
and EDX,0FFFFh
|
||||
add EAX,EDX
|
||||
ret
|
||||
|
||||
LAE: add EAX,[ECX]
|
||||
L92: ret
|
||||
}
|
||||
}
|
||||
#else
|
||||
hash_t Dchar::calcHash(const dchar *str, size_t len)
|
||||
{
|
||||
unsigned hash = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash += *(const uint16_t *)str;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash += *(const uint32_t *)str;
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash += *(const uint32_t *)str;
|
||||
hash *= 37;
|
||||
str += 2;
|
||||
len -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
hash_t Dchar::icalcHash(const dchar *str, size_t len)
|
||||
{
|
||||
hash_t hash = 0;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash += *(const uint16_t *)str | 0x20;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash += *(const uint32_t *)str | 0x200020;
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash += *(const uint32_t *)str | 0x200020;
|
||||
hash *= 37;
|
||||
str += 2;
|
||||
len -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif MCBS
|
||||
|
||||
hash_t Dchar::calcHash(const dchar *str, size_t len)
|
||||
{
|
||||
hash_t hash = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 37;
|
||||
hash += *(const uint8_t *)str;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash *= 37;
|
||||
hash += *(const uint16_t *)str;
|
||||
return hash;
|
||||
|
||||
case 3:
|
||||
hash *= 37;
|
||||
hash += (*(const uint16_t *)str << 8) +
|
||||
((const uint8_t *)str)[2];
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 37;
|
||||
hash += *(const uint32_t *)str;
|
||||
str += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#elif UTF8
|
||||
|
||||
// Specification is: http://anubis.dkuug.dk/JTC1/SC2/WG2/docs/n1335
|
||||
|
||||
char Dchar::mblen[256] =
|
||||
{
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
|
||||
3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,
|
||||
4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1,
|
||||
};
|
||||
|
||||
dchar *Dchar::dec(dchar *pstart, dchar *p)
|
||||
{
|
||||
while ((p[-1] & 0xC0) == 0x80)
|
||||
p--;
|
||||
return p;
|
||||
}
|
||||
|
||||
int Dchar::get(dchar *p)
|
||||
{
|
||||
unsigned c;
|
||||
unsigned char *q = (unsigned char *)p;
|
||||
|
||||
c = q[0];
|
||||
switch (mblen[c])
|
||||
{
|
||||
case 2:
|
||||
c = ((c - 0xC0) << 6) |
|
||||
(q[1] - 0x80);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
c = ((c - 0xE0) << 12) |
|
||||
((q[1] - 0x80) << 6) |
|
||||
(q[2] - 0x80);
|
||||
break;
|
||||
|
||||
case 4:
|
||||
c = ((c - 0xF0) << 18) |
|
||||
((q[1] - 0x80) << 12) |
|
||||
((q[2] - 0x80) << 6) |
|
||||
(q[3] - 0x80);
|
||||
break;
|
||||
|
||||
case 5:
|
||||
c = ((c - 0xF8) << 24) |
|
||||
((q[1] - 0x80) << 18) |
|
||||
((q[2] - 0x80) << 12) |
|
||||
((q[3] - 0x80) << 6) |
|
||||
(q[4] - 0x80);
|
||||
break;
|
||||
|
||||
case 6:
|
||||
c = ((c - 0xFC) << 30) |
|
||||
((q[1] - 0x80) << 24) |
|
||||
((q[2] - 0x80) << 18) |
|
||||
((q[3] - 0x80) << 12) |
|
||||
((q[4] - 0x80) << 6) |
|
||||
(q[5] - 0x80);
|
||||
break;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
dchar *Dchar::put(dchar *p, unsigned c)
|
||||
{
|
||||
if (c <= 0x7F)
|
||||
{
|
||||
*p++ = c;
|
||||
}
|
||||
else if (c <= 0x7FF)
|
||||
{
|
||||
p[0] = 0xC0 + (c >> 6);
|
||||
p[1] = 0x80 + (c & 0x3F);
|
||||
p += 2;
|
||||
}
|
||||
else if (c <= 0xFFFF)
|
||||
{
|
||||
p[0] = 0xE0 + (c >> 12);
|
||||
p[1] = 0x80 + ((c >> 6) & 0x3F);
|
||||
p[2] = 0x80 + (c & 0x3F);
|
||||
p += 3;
|
||||
}
|
||||
else if (c <= 0x1FFFFF)
|
||||
{
|
||||
p[0] = 0xF0 + (c >> 18);
|
||||
p[1] = 0x80 + ((c >> 12) & 0x3F);
|
||||
p[2] = 0x80 + ((c >> 6) & 0x3F);
|
||||
p[3] = 0x80 + (c & 0x3F);
|
||||
p += 4;
|
||||
}
|
||||
else if (c <= 0x3FFFFFF)
|
||||
{
|
||||
p[0] = 0xF8 + (c >> 24);
|
||||
p[1] = 0x80 + ((c >> 18) & 0x3F);
|
||||
p[2] = 0x80 + ((c >> 12) & 0x3F);
|
||||
p[3] = 0x80 + ((c >> 6) & 0x3F);
|
||||
p[4] = 0x80 + (c & 0x3F);
|
||||
p += 5;
|
||||
}
|
||||
else if (c <= 0x7FFFFFFF)
|
||||
{
|
||||
p[0] = 0xFC + (c >> 30);
|
||||
p[1] = 0x80 + ((c >> 24) & 0x3F);
|
||||
p[2] = 0x80 + ((c >> 18) & 0x3F);
|
||||
p[3] = 0x80 + ((c >> 12) & 0x3F);
|
||||
p[4] = 0x80 + ((c >> 6) & 0x3F);
|
||||
p[5] = 0x80 + (c & 0x3F);
|
||||
p += 6;
|
||||
}
|
||||
else
|
||||
assert(0); // not a UCS-4 character
|
||||
return p;
|
||||
}
|
||||
|
||||
hash_t Dchar::calcHash(const dchar *str, size_t len)
|
||||
{
|
||||
hash_t hash = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 37;
|
||||
hash += *(const uint8_t *)str;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += *(const uint16_t *)str;
|
||||
#else
|
||||
hash += str[0] * 256 + str[1];
|
||||
#endif
|
||||
return hash;
|
||||
|
||||
case 3:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += (*(const uint16_t *)str << 8) +
|
||||
((const uint8_t *)str)[2];
|
||||
#else
|
||||
hash += (str[0] * 256 + str[1]) * 256 + str[2];
|
||||
#endif
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += *(const uint32_t *)str;
|
||||
#else
|
||||
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
|
||||
#endif
|
||||
|
||||
str += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#else // ascii
|
||||
|
||||
hash_t Dchar::calcHash(const dchar *str, size_t len)
|
||||
{
|
||||
hash_t hash = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 37;
|
||||
hash += *(const uint8_t *)str;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += *(const uint16_t *)str;
|
||||
#else
|
||||
hash += str[0] * 256 + str[1];
|
||||
#endif
|
||||
return hash;
|
||||
|
||||
case 3:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += (*(const uint16_t *)str << 8) +
|
||||
((const uint8_t *)str)[2];
|
||||
#else
|
||||
hash += (str[0] * 256 + str[1]) * 256 + str[2];
|
||||
#endif
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 37;
|
||||
#if __I86__
|
||||
hash += *(const uint32_t *)str;
|
||||
#else
|
||||
hash += ((str[0] * 256 + str[1]) * 256 + str[2]) * 256 + str[3];
|
||||
#endif
|
||||
str += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
hash_t Dchar::icalcHash(const dchar *str, size_t len)
|
||||
{
|
||||
hash_t hash = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 37;
|
||||
hash += *(const uint8_t *)str | 0x20;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash *= 37;
|
||||
hash += *(const uint16_t *)str | 0x2020;
|
||||
return hash;
|
||||
|
||||
case 3:
|
||||
hash *= 37;
|
||||
hash += ((*(const uint16_t *)str << 8) +
|
||||
((const uint8_t *)str)[2]) | 0x202020;
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 37;
|
||||
hash += *(const uint32_t *)str | 0x20202020;
|
||||
str += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
#include <stdio.h>
|
||||
|
||||
void main()
|
||||
{
|
||||
// Print out values to hardcode into Dchar::mblen[]
|
||||
int c;
|
||||
int s;
|
||||
|
||||
for (c = 0; c < 256; c++)
|
||||
{
|
||||
s = 1;
|
||||
if (c >= 0xC0 && c <= 0xDF)
|
||||
s = 2;
|
||||
if (c >= 0xE0 && c <= 0xEF)
|
||||
s = 3;
|
||||
if (c >= 0xF0 && c <= 0xF7)
|
||||
s = 4;
|
||||
if (c >= 0xF8 && c <= 0xFB)
|
||||
s = 5;
|
||||
if (c >= 0xFC && c <= 0xFD)
|
||||
s = 6;
|
||||
|
||||
printf("%d", s);
|
||||
if ((c & 15) == 15)
|
||||
printf(",\n");
|
||||
else
|
||||
printf(",");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -1,194 +1,194 @@
|
||||
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
|
||||
#ifndef DCHAR_H
|
||||
#define DCHAR_H
|
||||
|
||||
#if __GNUC__ && !_WIN32
|
||||
#include "gnuc.h"
|
||||
#endif
|
||||
|
||||
#if _MSC_VER
|
||||
// Disable useless warnings about unreferenced functions
|
||||
#pragma warning (disable : 4514)
|
||||
#endif
|
||||
|
||||
//#include "root.h"
|
||||
typedef size_t hash_t;
|
||||
|
||||
#undef TEXT
|
||||
|
||||
// NOTE: All functions accepting pointer arguments must not be NULL
|
||||
|
||||
#if M_UNICODE
|
||||
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
typedef wchar_t dchar;
|
||||
#define TEXT(x) L##x
|
||||
|
||||
#define Dchar_mbmax 1
|
||||
|
||||
struct Dchar
|
||||
{
|
||||
static dchar *inc(dchar *p) { return p + 1; }
|
||||
static dchar *dec(dchar *pstart, dchar *p) { (void)pstart; return p - 1; }
|
||||
static int len(const dchar *p) { return wcslen(p); }
|
||||
static dchar get(dchar *p) { return *p; }
|
||||
static dchar getprev(dchar *pstart, dchar *p) { (void)pstart; return p[-1]; }
|
||||
static dchar *put(dchar *p, dchar c) { *p = c; return p + 1; }
|
||||
static int cmp(dchar *s1, dchar *s2)
|
||||
{
|
||||
#if __DMC__
|
||||
if (!*s1 && !*s2) // wcscmp is broken
|
||||
return 0;
|
||||
#endif
|
||||
return wcscmp(s1, s2);
|
||||
#if 0
|
||||
return (*s1 == *s2)
|
||||
? wcscmp(s1, s2)
|
||||
: ((int)*s1 - (int)*s2);
|
||||
#endif
|
||||
}
|
||||
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars * sizeof(dchar)); }
|
||||
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
|
||||
static int isAlpha(dchar c) { return iswalpha(c); }
|
||||
static int isUpper(dchar c) { return iswupper(c); }
|
||||
static int isLower(dchar c) { return iswlower(c); }
|
||||
static int isLocaleUpper(dchar c) { return isUpper(c); }
|
||||
static int isLocaleLower(dchar c) { return isLower(c); }
|
||||
static int toLower(dchar c) { return isUpper(c) ? towlower(c) : c; }
|
||||
static int toLower(dchar *p) { return toLower(*p); }
|
||||
static int toUpper(dchar c) { return isLower(c) ? towupper(c) : c; }
|
||||
static dchar *dup(dchar *p) { return ::_wcsdup(p); } // BUG: out of memory?
|
||||
static dchar *dup(char *p);
|
||||
static dchar *chr(dchar *p, unsigned c) { return wcschr(p, (dchar)c); }
|
||||
static dchar *rchr(dchar *p, unsigned c) { return wcsrchr(p, (dchar)c); }
|
||||
static dchar *memchr(dchar *p, int c, int count);
|
||||
static dchar *cpy(dchar *s1, dchar *s2) { return wcscpy(s1, s2); }
|
||||
static dchar *str(dchar *s1, dchar *s2) { return wcsstr(s1, s2); }
|
||||
static hash_t calcHash(const dchar *str, size_t len);
|
||||
|
||||
// Case insensitive versions
|
||||
static int icmp(dchar *s1, dchar *s2) { return wcsicmp(s1, s2); }
|
||||
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::wcsnicmp(s1, s2, nchars); }
|
||||
static hash_t icalcHash(const dchar *str, size_t len);
|
||||
};
|
||||
|
||||
#elif MCBS
|
||||
|
||||
#include <limits.h>
|
||||
#include <mbstring.h>
|
||||
|
||||
typedef char dchar;
|
||||
#define TEXT(x) x
|
||||
|
||||
#define Dchar_mbmax MB_LEN_MAX
|
||||
|
||||
#elif UTF8
|
||||
|
||||
typedef char dchar;
|
||||
#define TEXT(x) x
|
||||
|
||||
#define Dchar_mbmax 6
|
||||
|
||||
struct Dchar
|
||||
{
|
||||
static char mblen[256];
|
||||
|
||||
static dchar *inc(dchar *p) { return p + mblen[*p & 0xFF]; }
|
||||
static dchar *dec(dchar *pstart, dchar *p);
|
||||
static int len(const dchar *p) { return strlen(p); }
|
||||
static int get(dchar *p);
|
||||
static int getprev(dchar *pstart, dchar *p)
|
||||
{ return *dec(pstart, p) & 0xFF; }
|
||||
static dchar *put(dchar *p, unsigned c);
|
||||
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
|
||||
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
|
||||
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
|
||||
static int isAlpha(dchar c) { return c <= 0x7F ? isalpha(c) : 0; }
|
||||
static int isUpper(dchar c) { return c <= 0x7F ? isupper(c) : 0; }
|
||||
static int isLower(dchar c) { return c <= 0x7F ? islower(c) : 0; }
|
||||
static int isLocaleUpper(dchar c) { return isUpper(c); }
|
||||
static int isLocaleLower(dchar c) { return isLower(c); }
|
||||
static int toLower(dchar c) { return isUpper(c) ? tolower(c) : c; }
|
||||
static int toLower(dchar *p) { return toLower(*p); }
|
||||
static int toUpper(dchar c) { return isLower(c) ? toupper(c) : c; }
|
||||
static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory?
|
||||
static dchar *chr(dchar *p, int c) { return strchr(p, c); }
|
||||
static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
|
||||
static dchar *memchr(dchar *p, int c, int count)
|
||||
{ return (dchar *)::memchr(p, c, count); }
|
||||
static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
|
||||
static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
|
||||
static hash_t calcHash(const dchar *str, size_t len);
|
||||
|
||||
// Case insensitive versions
|
||||
static int icmp(dchar *s1, dchar *s2) { return _mbsicmp(s1, s2); }
|
||||
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::_mbsnicmp(s1, s2, nchars); }
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef GCC_SAFE_DMD
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
typedef char dchar;
|
||||
#define TEXT(x) x
|
||||
|
||||
#define Dchar_mbmax 1
|
||||
|
||||
struct Dchar
|
||||
{
|
||||
static dchar *inc(dchar *p) { return p + 1; }
|
||||
static dchar *dec(dchar *pstart, dchar *p) { return p - 1; }
|
||||
static int len(const dchar *p) { return strlen(p); }
|
||||
static int get(dchar *p) { return *p & 0xFF; }
|
||||
static int getprev(dchar *pstart, dchar *p) { return p[-1] & 0xFF; }
|
||||
static dchar *put(dchar *p, unsigned c) { *p = c; return p + 1; }
|
||||
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
|
||||
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
|
||||
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
|
||||
#ifndef GCC_SAFE_DMD
|
||||
static int isAlpha(dchar c) { return isalpha(c); }
|
||||
static int isUpper(dchar c) { return isupper(c); }
|
||||
static int isLower(dchar c) { return islower(c); }
|
||||
static int isLocaleUpper(dchar c) { return isupper(c); }
|
||||
static int isLocaleLower(dchar c) { return islower(c); }
|
||||
static int toLower(dchar c) { return isupper(c) ? tolower(c) : c; }
|
||||
static int toLower(dchar *p) { return toLower(*p); }
|
||||
static int toUpper(dchar c) { return islower(c) ? toupper(c) : c; }
|
||||
static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory?
|
||||
#endif
|
||||
static dchar *chr(dchar *p, int c) { return strchr(p, c); }
|
||||
static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
|
||||
static dchar *memchr(dchar *p, int c, int count)
|
||||
{ return (dchar *)::memchr(p, c, count); }
|
||||
static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
|
||||
static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
|
||||
static hash_t calcHash(const dchar *str, size_t len);
|
||||
|
||||
// Case insensitive versions
|
||||
#ifdef __GNUC__
|
||||
static int icmp(dchar *s1, dchar *s2) { return strcasecmp(s1, s2); }
|
||||
#else
|
||||
static int icmp(dchar *s1, dchar *s2) { return stricmp(s1, s2); }
|
||||
#endif
|
||||
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::memicmp(s1, s2, nchars); }
|
||||
static hash_t icalcHash(const dchar *str, size_t len);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
|
||||
#ifndef DCHAR_H
|
||||
#define DCHAR_H
|
||||
|
||||
#if __GNUC__ && !_WIN32
|
||||
#include "gnuc.h"
|
||||
#endif
|
||||
|
||||
#if _MSC_VER
|
||||
// Disable useless warnings about unreferenced functions
|
||||
#pragma warning (disable : 4514)
|
||||
#endif
|
||||
|
||||
//#include "root.h"
|
||||
typedef size_t hash_t;
|
||||
|
||||
#undef TEXT
|
||||
|
||||
// NOTE: All functions accepting pointer arguments must not be NULL
|
||||
|
||||
#if M_UNICODE
|
||||
|
||||
#include <string.h>
|
||||
#include <wchar.h>
|
||||
|
||||
typedef wchar_t dchar;
|
||||
#define TEXT(x) L##x
|
||||
|
||||
#define Dchar_mbmax 1
|
||||
|
||||
struct Dchar
|
||||
{
|
||||
static dchar *inc(dchar *p) { return p + 1; }
|
||||
static dchar *dec(dchar *pstart, dchar *p) { (void)pstart; return p - 1; }
|
||||
static int len(const dchar *p) { return wcslen(p); }
|
||||
static dchar get(dchar *p) { return *p; }
|
||||
static dchar getprev(dchar *pstart, dchar *p) { (void)pstart; return p[-1]; }
|
||||
static dchar *put(dchar *p, dchar c) { *p = c; return p + 1; }
|
||||
static int cmp(dchar *s1, dchar *s2)
|
||||
{
|
||||
#if __DMC__
|
||||
if (!*s1 && !*s2) // wcscmp is broken
|
||||
return 0;
|
||||
#endif
|
||||
return wcscmp(s1, s2);
|
||||
#if 0
|
||||
return (*s1 == *s2)
|
||||
? wcscmp(s1, s2)
|
||||
: ((int)*s1 - (int)*s2);
|
||||
#endif
|
||||
}
|
||||
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars * sizeof(dchar)); }
|
||||
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
|
||||
static int isAlpha(dchar c) { return iswalpha(c); }
|
||||
static int isUpper(dchar c) { return iswupper(c); }
|
||||
static int isLower(dchar c) { return iswlower(c); }
|
||||
static int isLocaleUpper(dchar c) { return isUpper(c); }
|
||||
static int isLocaleLower(dchar c) { return isLower(c); }
|
||||
static int toLower(dchar c) { return isUpper(c) ? towlower(c) : c; }
|
||||
static int toLower(dchar *p) { return toLower(*p); }
|
||||
static int toUpper(dchar c) { return isLower(c) ? towupper(c) : c; }
|
||||
static dchar *dup(dchar *p) { return ::_wcsdup(p); } // BUG: out of memory?
|
||||
static dchar *dup(char *p);
|
||||
static dchar *chr(dchar *p, unsigned c) { return wcschr(p, (dchar)c); }
|
||||
static dchar *rchr(dchar *p, unsigned c) { return wcsrchr(p, (dchar)c); }
|
||||
static dchar *memchr(dchar *p, int c, int count);
|
||||
static dchar *cpy(dchar *s1, dchar *s2) { return wcscpy(s1, s2); }
|
||||
static dchar *str(dchar *s1, dchar *s2) { return wcsstr(s1, s2); }
|
||||
static hash_t calcHash(const dchar *str, size_t len);
|
||||
|
||||
// Case insensitive versions
|
||||
static int icmp(dchar *s1, dchar *s2) { return wcsicmp(s1, s2); }
|
||||
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::wcsnicmp(s1, s2, nchars); }
|
||||
static hash_t icalcHash(const dchar *str, size_t len);
|
||||
};
|
||||
|
||||
#elif MCBS
|
||||
|
||||
#include <limits.h>
|
||||
#include <mbstring.h>
|
||||
|
||||
typedef char dchar;
|
||||
#define TEXT(x) x
|
||||
|
||||
#define Dchar_mbmax MB_LEN_MAX
|
||||
|
||||
#elif UTF8
|
||||
|
||||
typedef char dchar;
|
||||
#define TEXT(x) x
|
||||
|
||||
#define Dchar_mbmax 6
|
||||
|
||||
struct Dchar
|
||||
{
|
||||
static char mblen[256];
|
||||
|
||||
static dchar *inc(dchar *p) { return p + mblen[*p & 0xFF]; }
|
||||
static dchar *dec(dchar *pstart, dchar *p);
|
||||
static int len(const dchar *p) { return strlen(p); }
|
||||
static int get(dchar *p);
|
||||
static int getprev(dchar *pstart, dchar *p)
|
||||
{ return *dec(pstart, p) & 0xFF; }
|
||||
static dchar *put(dchar *p, unsigned c);
|
||||
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
|
||||
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
|
||||
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
|
||||
static int isAlpha(dchar c) { return c <= 0x7F ? isalpha(c) : 0; }
|
||||
static int isUpper(dchar c) { return c <= 0x7F ? isupper(c) : 0; }
|
||||
static int isLower(dchar c) { return c <= 0x7F ? islower(c) : 0; }
|
||||
static int isLocaleUpper(dchar c) { return isUpper(c); }
|
||||
static int isLocaleLower(dchar c) { return isLower(c); }
|
||||
static int toLower(dchar c) { return isUpper(c) ? tolower(c) : c; }
|
||||
static int toLower(dchar *p) { return toLower(*p); }
|
||||
static int toUpper(dchar c) { return isLower(c) ? toupper(c) : c; }
|
||||
static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory?
|
||||
static dchar *chr(dchar *p, int c) { return strchr(p, c); }
|
||||
static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
|
||||
static dchar *memchr(dchar *p, int c, int count)
|
||||
{ return (dchar *)::memchr(p, c, count); }
|
||||
static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
|
||||
static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
|
||||
static hash_t calcHash(const dchar *str, size_t len);
|
||||
|
||||
// Case insensitive versions
|
||||
static int icmp(dchar *s1, dchar *s2) { return _mbsicmp(s1, s2); }
|
||||
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::_mbsnicmp(s1, s2, nchars); }
|
||||
};
|
||||
|
||||
#else
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#ifndef GCC_SAFE_DMD
|
||||
#include <ctype.h>
|
||||
#endif
|
||||
|
||||
typedef char dchar;
|
||||
#define TEXT(x) x
|
||||
|
||||
#define Dchar_mbmax 1
|
||||
|
||||
struct Dchar
|
||||
{
|
||||
static dchar *inc(dchar *p) { return p + 1; }
|
||||
static dchar *dec(dchar *pstart, dchar *p) { return p - 1; }
|
||||
static int len(const dchar *p) { return strlen(p); }
|
||||
static int get(dchar *p) { return *p & 0xFF; }
|
||||
static int getprev(dchar *pstart, dchar *p) { return p[-1] & 0xFF; }
|
||||
static dchar *put(dchar *p, unsigned c) { *p = c; return p + 1; }
|
||||
static int cmp(dchar *s1, dchar *s2) { return strcmp(s1, s2); }
|
||||
static int memcmp(const dchar *s1, const dchar *s2, int nchars) { return ::memcmp(s1, s2, nchars); }
|
||||
static int isDigit(dchar c) { return '0' <= c && c <= '9'; }
|
||||
#ifndef GCC_SAFE_DMD
|
||||
static int isAlpha(dchar c) { return isalpha(c); }
|
||||
static int isUpper(dchar c) { return isupper(c); }
|
||||
static int isLower(dchar c) { return islower(c); }
|
||||
static int isLocaleUpper(dchar c) { return isupper(c); }
|
||||
static int isLocaleLower(dchar c) { return islower(c); }
|
||||
static int toLower(dchar c) { return isupper(c) ? tolower(c) : c; }
|
||||
static int toLower(dchar *p) { return toLower(*p); }
|
||||
static int toUpper(dchar c) { return islower(c) ? toupper(c) : c; }
|
||||
static dchar *dup(dchar *p) { return ::strdup(p); } // BUG: out of memory?
|
||||
#endif
|
||||
static dchar *chr(dchar *p, int c) { return strchr(p, c); }
|
||||
static dchar *rchr(dchar *p, int c) { return strrchr(p, c); }
|
||||
static dchar *memchr(dchar *p, int c, int count)
|
||||
{ return (dchar *)::memchr(p, c, count); }
|
||||
static dchar *cpy(dchar *s1, dchar *s2) { return strcpy(s1, s2); }
|
||||
static dchar *str(dchar *s1, dchar *s2) { return strstr(s1, s2); }
|
||||
static hash_t calcHash(const dchar *str, size_t len);
|
||||
|
||||
// Case insensitive versions
|
||||
#ifdef __GNUC__
|
||||
static int icmp(dchar *s1, dchar *s2) { return strcasecmp(s1, s2); }
|
||||
#else
|
||||
static int icmp(dchar *s1, dchar *s2) { return stricmp(s1, s2); }
|
||||
#endif
|
||||
static int memicmp(const dchar *s1, const dchar *s2, int nchars) { return ::memicmp(s1, s2, nchars); }
|
||||
static hash_t icalcHash(const dchar *str, size_t len);
|
||||
};
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -8,20 +8,20 @@ int memicmp(const char *s1, const char *s2, int n)
|
||||
int result = 0;
|
||||
|
||||
for (int i = 0; i < n; i++)
|
||||
{ char c1 = s1[i];
|
||||
char c2 = s2[i];
|
||||
{ char c1 = s1[i];
|
||||
char c2 = s2[i];
|
||||
|
||||
result = c1 - c2;
|
||||
if (result)
|
||||
{
|
||||
if ('A' <= c1 && c1 <= 'Z')
|
||||
c1 += 'a' - 'A';
|
||||
if ('A' <= c2 && c2 <= 'Z')
|
||||
c2 += 'a' - 'A';
|
||||
result = c1 - c2;
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
result = c1 - c2;
|
||||
if (result)
|
||||
{
|
||||
if ('A' <= c1 && c1 <= 'Z')
|
||||
c1 += 'a' - 'A';
|
||||
if ('A' <= c2 && c2 <= 'Z')
|
||||
c2 += 'a' - 'A';
|
||||
result = c1 - c2;
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@@ -31,24 +31,24 @@ int stricmp(const char *s1, const char *s2)
|
||||
int result = 0;
|
||||
|
||||
for (;;)
|
||||
{ char c1 = *s1;
|
||||
char c2 = *s2;
|
||||
{ char c1 = *s1;
|
||||
char c2 = *s2;
|
||||
|
||||
result = c1 - c2;
|
||||
if (result)
|
||||
{
|
||||
if ('A' <= c1 && c1 <= 'Z')
|
||||
c1 += 'a' - 'A';
|
||||
if ('A' <= c2 && c2 <= 'Z')
|
||||
c2 += 'a' - 'A';
|
||||
result = c1 - c2;
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
if (!c1)
|
||||
break;
|
||||
s1++;
|
||||
s2++;
|
||||
result = c1 - c2;
|
||||
if (result)
|
||||
{
|
||||
if ('A' <= c1 && c1 <= 'Z')
|
||||
c1 += 'a' - 'A';
|
||||
if ('A' <= c2 && c2 <= 'Z')
|
||||
c2 += 'a' - 'A';
|
||||
result = c1 - c2;
|
||||
if (result)
|
||||
break;
|
||||
}
|
||||
if (!c1)
|
||||
break;
|
||||
s1++;
|
||||
s2++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -1,63 +1,63 @@
|
||||
// lstring.c
|
||||
|
||||
// Copyright (c) 1999-2002 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "dchar.h"
|
||||
#include "rmem.h"
|
||||
#include "lstring.h"
|
||||
|
||||
#ifdef _MSC_VER // prevent compiler internal crash
|
||||
Lstring Lstring::zero;
|
||||
#else
|
||||
Lstring Lstring::zero = LSTRING_EMPTY();
|
||||
#endif
|
||||
|
||||
Lstring *Lstring::ctor(const dchar *p, unsigned length)
|
||||
{
|
||||
Lstring *s;
|
||||
|
||||
s = alloc(length);
|
||||
memcpy(s->string, p, length * sizeof(dchar));
|
||||
return s;
|
||||
}
|
||||
|
||||
Lstring *Lstring::alloc(unsigned length)
|
||||
{
|
||||
Lstring *s;
|
||||
|
||||
s = (Lstring *)mem.malloc(size(length));
|
||||
s->length = length;
|
||||
s->string[length] = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
Lstring *Lstring::append(const Lstring *s)
|
||||
{
|
||||
Lstring *t;
|
||||
|
||||
if (!s->length)
|
||||
return this;
|
||||
t = alloc(length + s->length);
|
||||
memcpy(t->string, string, length * sizeof(dchar));
|
||||
memcpy(t->string + length, s->string, s->length * sizeof(dchar));
|
||||
return t;
|
||||
}
|
||||
|
||||
Lstring *Lstring::substring(int start, int end)
|
||||
{
|
||||
Lstring *t;
|
||||
|
||||
if (start == end)
|
||||
return &zero;
|
||||
t = alloc(end - start);
|
||||
memcpy(t->string, string + start, (end - start) * sizeof(dchar));
|
||||
return t;
|
||||
}
|
||||
// lstring.c
|
||||
|
||||
// Copyright (c) 1999-2002 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "dchar.h"
|
||||
#include "rmem.h"
|
||||
#include "lstring.h"
|
||||
|
||||
#ifdef _MSC_VER // prevent compiler internal crash
|
||||
Lstring Lstring::zero;
|
||||
#else
|
||||
Lstring Lstring::zero = LSTRING_EMPTY();
|
||||
#endif
|
||||
|
||||
Lstring *Lstring::ctor(const dchar *p, unsigned length)
|
||||
{
|
||||
Lstring *s;
|
||||
|
||||
s = alloc(length);
|
||||
memcpy(s->string, p, length * sizeof(dchar));
|
||||
return s;
|
||||
}
|
||||
|
||||
Lstring *Lstring::alloc(unsigned length)
|
||||
{
|
||||
Lstring *s;
|
||||
|
||||
s = (Lstring *)mem.malloc(size(length));
|
||||
s->length = length;
|
||||
s->string[length] = 0;
|
||||
return s;
|
||||
}
|
||||
|
||||
Lstring *Lstring::append(const Lstring *s)
|
||||
{
|
||||
Lstring *t;
|
||||
|
||||
if (!s->length)
|
||||
return this;
|
||||
t = alloc(length + s->length);
|
||||
memcpy(t->string, string, length * sizeof(dchar));
|
||||
memcpy(t->string + length, s->string, s->length * sizeof(dchar));
|
||||
return t;
|
||||
}
|
||||
|
||||
Lstring *Lstring::substring(int start, int end)
|
||||
{
|
||||
Lstring *t;
|
||||
|
||||
if (start == end)
|
||||
return &zero;
|
||||
t = alloc(end - start);
|
||||
memcpy(t->string, string + start, (end - start) * sizeof(dchar));
|
||||
return t;
|
||||
}
|
||||
|
||||
@@ -1,72 +1,72 @@
|
||||
|
||||
// lstring.h
|
||||
// length-prefixed strings
|
||||
|
||||
// Copyright (c) 1999-2002 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef LSTRING_H
|
||||
#define LSTRING_H 1
|
||||
|
||||
#include "dchar.h"
|
||||
|
||||
struct Lstring
|
||||
{
|
||||
unsigned length;
|
||||
|
||||
// Disable warning about nonstandard extension
|
||||
#pragma warning (disable : 4200)
|
||||
dchar string[];
|
||||
|
||||
static Lstring zero; // 0 length string
|
||||
|
||||
// No constructors because we want to be able to statically
|
||||
// initialize Lstring's, and Lstrings are of variable size.
|
||||
|
||||
#if M_UNICODE
|
||||
#define LSTRING(p,length) { length, L##p }
|
||||
#else
|
||||
#define LSTRING(p,length) { length, p }
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#define LSTRING_EMPTY() { 0 }
|
||||
#else
|
||||
#define LSTRING_EMPTY() LSTRING("", 0)
|
||||
#endif
|
||||
|
||||
static Lstring *ctor(const dchar *p) { return ctor(p, Dchar::len(p)); }
|
||||
static Lstring *ctor(const dchar *p, unsigned length);
|
||||
static unsigned size(unsigned length) { return sizeof(Lstring) + (length + 1) * sizeof(dchar); }
|
||||
static Lstring *alloc(unsigned length);
|
||||
Lstring *clone();
|
||||
|
||||
unsigned len() { return length; }
|
||||
|
||||
dchar *toDchars() { return string; }
|
||||
|
||||
hash_t hash() { return Dchar::calcHash(string, length); }
|
||||
hash_t ihash() { return Dchar::icalcHash(string, length); }
|
||||
|
||||
static int cmp(const Lstring *s1, const Lstring *s2)
|
||||
{
|
||||
int c = s2->length - s1->length;
|
||||
return c ? c : Dchar::memcmp(s1->string, s2->string, s1->length);
|
||||
}
|
||||
|
||||
static int icmp(const Lstring *s1, const Lstring *s2)
|
||||
{
|
||||
int c = s2->length - s1->length;
|
||||
return c ? c : Dchar::memicmp(s1->string, s2->string, s1->length);
|
||||
}
|
||||
|
||||
Lstring *append(const Lstring *s);
|
||||
Lstring *substring(int start, int end);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// lstring.h
|
||||
// length-prefixed strings
|
||||
|
||||
// Copyright (c) 1999-2002 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef LSTRING_H
|
||||
#define LSTRING_H 1
|
||||
|
||||
#include "dchar.h"
|
||||
|
||||
struct Lstring
|
||||
{
|
||||
unsigned length;
|
||||
|
||||
// Disable warning about nonstandard extension
|
||||
#pragma warning (disable : 4200)
|
||||
dchar string[];
|
||||
|
||||
static Lstring zero; // 0 length string
|
||||
|
||||
// No constructors because we want to be able to statically
|
||||
// initialize Lstring's, and Lstrings are of variable size.
|
||||
|
||||
#if M_UNICODE
|
||||
#define LSTRING(p,length) { length, L##p }
|
||||
#else
|
||||
#define LSTRING(p,length) { length, p }
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
#define LSTRING_EMPTY() { 0 }
|
||||
#else
|
||||
#define LSTRING_EMPTY() LSTRING("", 0)
|
||||
#endif
|
||||
|
||||
static Lstring *ctor(const dchar *p) { return ctor(p, Dchar::len(p)); }
|
||||
static Lstring *ctor(const dchar *p, unsigned length);
|
||||
static unsigned size(unsigned length) { return sizeof(Lstring) + (length + 1) * sizeof(dchar); }
|
||||
static Lstring *alloc(unsigned length);
|
||||
Lstring *clone();
|
||||
|
||||
unsigned len() { return length; }
|
||||
|
||||
dchar *toDchars() { return string; }
|
||||
|
||||
hash_t hash() { return Dchar::calcHash(string, length); }
|
||||
hash_t ihash() { return Dchar::icalcHash(string, length); }
|
||||
|
||||
static int cmp(const Lstring *s1, const Lstring *s2)
|
||||
{
|
||||
int c = s2->length - s1->length;
|
||||
return c ? c : Dchar::memcmp(s1->string, s2->string, s1->length);
|
||||
}
|
||||
|
||||
static int icmp(const Lstring *s1, const Lstring *s2)
|
||||
{
|
||||
int c = s2->length - s1->length;
|
||||
return c ? c : Dchar::memicmp(s1->string, s2->string, s1->length);
|
||||
}
|
||||
|
||||
Lstring *append(const Lstring *s);
|
||||
Lstring *substring(int start, int end);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
200
dmd2/root/man.c
200
dmd2/root/man.c
@@ -1,100 +1,100 @@
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 2008-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#pragma comment(lib,"shell32.lib")
|
||||
|
||||
void browse(const char *url)
|
||||
{
|
||||
ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if linux || __FreeBSD__ || __sun&&__SVR4
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void browse(const char *url)
|
||||
{
|
||||
pid_t childpid;
|
||||
const char *args[3];
|
||||
|
||||
char *browser = getenv("BROWSER");
|
||||
if (browser)
|
||||
browser = strdup(browser);
|
||||
else
|
||||
browser = "x-www-browser";
|
||||
|
||||
args[0] = browser;
|
||||
args[1] = url;
|
||||
args[2] = NULL;
|
||||
|
||||
childpid = fork();
|
||||
if (childpid == 0)
|
||||
{
|
||||
execvp(args[0], (char**)args);
|
||||
perror(args[0]); // failed to execute
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if __APPLE__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void browse(const char *url)
|
||||
{
|
||||
pid_t childpid;
|
||||
const char *args[5];
|
||||
|
||||
char *browser = getenv("BROWSER");
|
||||
if (browser)
|
||||
{ browser = strdup(browser);
|
||||
args[0] = browser;
|
||||
args[1] = url;
|
||||
args[2] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
//browser = "/Applications/Safari.app/Contents/MacOS/Safari";
|
||||
args[0] = "open";
|
||||
args[1] = "-a";
|
||||
args[2] = "/Applications/Safari.app";
|
||||
args[3] = url;
|
||||
args[4] = NULL;
|
||||
}
|
||||
|
||||
childpid = fork();
|
||||
if (childpid == 0)
|
||||
{
|
||||
execvp(args[0], (char**)args);
|
||||
perror(args[0]); // failed to execute
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// Compiler implementation of the D programming language
|
||||
// Copyright (c) 2008-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#if _WIN32
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
#pragma comment(lib,"shell32.lib")
|
||||
|
||||
void browse(const char *url)
|
||||
{
|
||||
ShellExecute(NULL, "open", url, NULL, NULL, SW_SHOWNORMAL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if linux || __FreeBSD__ || __sun&&__SVR4
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void browse(const char *url)
|
||||
{
|
||||
pid_t childpid;
|
||||
const char *args[3];
|
||||
|
||||
const char *browser = getenv("BROWSER");
|
||||
if (browser)
|
||||
browser = strdup(browser);
|
||||
else
|
||||
browser = "x-www-browser";
|
||||
|
||||
args[0] = browser;
|
||||
args[1] = url;
|
||||
args[2] = NULL;
|
||||
|
||||
childpid = fork();
|
||||
if (childpid == 0)
|
||||
{
|
||||
execvp(args[0], (char**)args);
|
||||
perror(args[0]); // failed to execute
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if __APPLE__
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/wait.h>
|
||||
#include <unistd.h>
|
||||
|
||||
void browse(const char *url)
|
||||
{
|
||||
pid_t childpid;
|
||||
const char *args[5];
|
||||
|
||||
char *browser = getenv("BROWSER");
|
||||
if (browser)
|
||||
{ browser = strdup(browser);
|
||||
args[0] = browser;
|
||||
args[1] = url;
|
||||
args[2] = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
//browser = "/Applications/Safari.app/Contents/MacOS/Safari";
|
||||
args[0] = "open";
|
||||
args[1] = "-a";
|
||||
args[2] = "/Applications/Safari.app";
|
||||
args[3] = url;
|
||||
args[4] = NULL;
|
||||
}
|
||||
|
||||
childpid = fork();
|
||||
if (childpid == 0)
|
||||
{
|
||||
execvp(args[0], (char**)args);
|
||||
perror(args[0]); // failed to execute
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
1525
dmd2/root/port.c
1525
dmd2/root/port.c
File diff suppressed because it is too large
Load Diff
156
dmd2/root/port.h
156
dmd2/root/port.h
@@ -1,78 +1,78 @@
|
||||
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
// Portable wrapper around compiler/system specific things.
|
||||
// The idea is to minimize #ifdef's in the app code.
|
||||
|
||||
#ifndef TYPEDEFS
|
||||
#define TYPEDEFS
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#if _MSC_VER
|
||||
typedef __int64 longlong;
|
||||
typedef unsigned __int64 ulonglong;
|
||||
|
||||
// According to VC 8.0 docs, long double is the same as double
|
||||
#define strtold strtod
|
||||
#define strtof strtod
|
||||
|
||||
#else
|
||||
typedef long long longlong;
|
||||
typedef unsigned long long ulonglong;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
typedef double d_time;
|
||||
|
||||
struct Port
|
||||
{
|
||||
static double nan;
|
||||
static double infinity;
|
||||
static double dbl_max;
|
||||
static double dbl_min;
|
||||
static long double ldbl_max;
|
||||
|
||||
#if __GNUC__
|
||||
// These conflict with macros in math.h, should rename them
|
||||
#undef isnan
|
||||
#undef isfinite
|
||||
#undef isinfinity
|
||||
#undef signbit
|
||||
#endif
|
||||
static int isNan(double);
|
||||
static int isNan(long double);
|
||||
|
||||
static int isSignallingNan(double);
|
||||
static int isSignallingNan(long double);
|
||||
|
||||
static int isFinite(double);
|
||||
static int isInfinity(double);
|
||||
static int Signbit(double);
|
||||
|
||||
static double floor(double);
|
||||
static double pow(double x, double y);
|
||||
|
||||
static ulonglong strtoull(const char *p, char **pend, int base);
|
||||
|
||||
static char *ull_to_string(char *buffer, ulonglong ull);
|
||||
static wchar_t *ull_to_string(wchar_t *buffer, ulonglong ull);
|
||||
|
||||
// Convert ulonglong to double
|
||||
static double ull_to_double(ulonglong ull);
|
||||
|
||||
// Get locale-dependent list separator
|
||||
static const char *list_separator();
|
||||
static const wchar_t *wlist_separator();
|
||||
|
||||
static char *strupr(char *);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
|
||||
#ifndef PORT_H
|
||||
#define PORT_H
|
||||
|
||||
// Portable wrapper around compiler/system specific things.
|
||||
// The idea is to minimize #ifdef's in the app code.
|
||||
|
||||
#ifndef TYPEDEFS
|
||||
#define TYPEDEFS
|
||||
|
||||
#include <wchar.h>
|
||||
|
||||
#if _MSC_VER
|
||||
typedef __int64 longlong;
|
||||
typedef unsigned __int64 ulonglong;
|
||||
|
||||
// According to VC 8.0 docs, long double is the same as double
|
||||
#define strtold strtod
|
||||
#define strtof strtod
|
||||
|
||||
#else
|
||||
typedef long long longlong;
|
||||
typedef unsigned long long ulonglong;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
typedef double d_time;
|
||||
|
||||
struct Port
|
||||
{
|
||||
static double nan;
|
||||
static double infinity;
|
||||
static double dbl_max;
|
||||
static double dbl_min;
|
||||
static long double ldbl_max;
|
||||
|
||||
#if __GNUC__
|
||||
// These conflict with macros in math.h, should rename them
|
||||
#undef isnan
|
||||
#undef isfinite
|
||||
#undef isinfinity
|
||||
#undef signbit
|
||||
#endif
|
||||
static int isNan(double);
|
||||
static int isNan(long double);
|
||||
|
||||
static int isSignallingNan(double);
|
||||
static int isSignallingNan(long double);
|
||||
|
||||
static int isFinite(double);
|
||||
static int isInfinity(double);
|
||||
static int Signbit(double);
|
||||
|
||||
static double floor(double);
|
||||
static double pow(double x, double y);
|
||||
|
||||
static ulonglong strtoull(const char *p, char **pend, int base);
|
||||
|
||||
static char *ull_to_string(char *buffer, ulonglong ull);
|
||||
static wchar_t *ull_to_string(wchar_t *buffer, ulonglong ull);
|
||||
|
||||
// Convert ulonglong to double
|
||||
static double ull_to_double(ulonglong ull);
|
||||
|
||||
// Get locale-dependent list separator
|
||||
static const char *list_separator();
|
||||
static const wchar_t *wlist_separator();
|
||||
|
||||
static char *strupr(char *);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
@@ -1,275 +1,275 @@
|
||||
// Copyright (C) 1990-1998 by Symantec
|
||||
// Copyright (C) 2000-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// http://www.digitalmars.com
|
||||
// Written by Walter Bright
|
||||
/*
|
||||
* This source file is made available for personal use
|
||||
* only. The license is in /dmd/src/dmd/backendlicense.txt
|
||||
* For any other uses, please contact Digital Mars.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if _WIN32
|
||||
#include <tchar.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#endif
|
||||
|
||||
/*********************************
|
||||
* #include <stdlib.h>
|
||||
* int response_expand(int *pargc,char ***pargv);
|
||||
*
|
||||
* Expand any response files in command line.
|
||||
* Response files are arguments that look like:
|
||||
* @NAME
|
||||
* The name is first searched for in the environment. If it is not
|
||||
* there, it is searched for as a file name.
|
||||
* Arguments are separated by spaces, tabs, or newlines. These can be
|
||||
* imbedded within arguments by enclosing the argument in '' or "".
|
||||
* Recursively expands nested response files.
|
||||
*
|
||||
* To use, put the line:
|
||||
* response_expand(&argc,&argv);
|
||||
* as the first executable statement in main(int argc, char **argv).
|
||||
* argc and argv are adjusted to be the new command line arguments
|
||||
* after response file expansion.
|
||||
*
|
||||
* Digital Mars's MAKE program can be notified that a program can accept
|
||||
* long command lines via environment variables by preceding the rule
|
||||
* line for the program with a *.
|
||||
*
|
||||
* Returns:
|
||||
* 0 success
|
||||
* !=0 failure (argc, argv unchanged)
|
||||
*/
|
||||
|
||||
struct Narg
|
||||
{
|
||||
int argc; /* arg count */
|
||||
int argvmax; /* dimension of nargv[] */
|
||||
char **argv;
|
||||
};
|
||||
|
||||
static int addargp(struct Narg *n, char *p)
|
||||
{
|
||||
/* The 2 is to always allow room for a NULL argp at the end */
|
||||
if (n->argc + 2 >= n->argvmax)
|
||||
{
|
||||
n->argvmax = n->argc + 2;
|
||||
n->argv = (char **) realloc(n->argv,n->argvmax * sizeof(char *));
|
||||
if (!n->argv)
|
||||
return 1;
|
||||
}
|
||||
n->argv[n->argc++] = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int response_expand(int *pargc, char ***pargv)
|
||||
{
|
||||
struct Narg n;
|
||||
int i;
|
||||
char *cp;
|
||||
int recurse = 0;
|
||||
|
||||
n.argc = 0;
|
||||
n.argvmax = 0; /* dimension of n.argv[] */
|
||||
n.argv = NULL;
|
||||
for(i=0; i<*pargc; ++i)
|
||||
{
|
||||
cp = (*pargv)[i];
|
||||
if (*cp == '@')
|
||||
{
|
||||
char *buffer;
|
||||
char *bufend;
|
||||
char *p;
|
||||
|
||||
cp++;
|
||||
p = getenv(cp);
|
||||
if (p)
|
||||
{
|
||||
buffer = strdup(p);
|
||||
if (!buffer)
|
||||
goto noexpand;
|
||||
bufend = buffer + strlen(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
long length;
|
||||
int fd;
|
||||
int nread;
|
||||
size_t len;
|
||||
|
||||
#if __DMC__
|
||||
length = filesize(cp);
|
||||
#else
|
||||
struct stat statbuf;
|
||||
if (stat(cp, &statbuf))
|
||||
goto noexpand;
|
||||
length = statbuf.st_size;
|
||||
#endif
|
||||
if (length & 0xF0000000) /* error or file too big */
|
||||
goto noexpand;
|
||||
len = length;
|
||||
buffer = (char *)malloc(len + 1);
|
||||
if (!buffer)
|
||||
goto noexpand;
|
||||
bufend = &buffer[len];
|
||||
/* Read file into buffer */
|
||||
#if _WIN32
|
||||
fd = open(cp,O_RDONLY|O_BINARY);
|
||||
#else
|
||||
fd = open(cp,O_RDONLY);
|
||||
#endif
|
||||
if (fd == -1)
|
||||
goto noexpand;
|
||||
nread = read(fd,buffer,len);
|
||||
close(fd);
|
||||
|
||||
if (nread != len)
|
||||
goto noexpand;
|
||||
}
|
||||
|
||||
// The logic of this should match that in setargv()
|
||||
|
||||
for (p = buffer; p < bufend; p++)
|
||||
{
|
||||
char *d;
|
||||
char c,lastc;
|
||||
unsigned char instring;
|
||||
int num_slashes,non_slashes;
|
||||
|
||||
switch (*p)
|
||||
{
|
||||
case 26: /* ^Z marks end of file */
|
||||
goto L2;
|
||||
|
||||
case 0xD:
|
||||
case 0:
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
continue; // scan to start of argument
|
||||
|
||||
case '@':
|
||||
recurse = 1;
|
||||
default: /* start of new argument */
|
||||
if (addargp(&n,p))
|
||||
goto noexpand;
|
||||
instring = 0;
|
||||
c = 0;
|
||||
num_slashes = 0;
|
||||
for (d = p; 1; p++)
|
||||
{
|
||||
lastc = c;
|
||||
if (p >= bufend)
|
||||
goto Lend;
|
||||
c = *p;
|
||||
switch (c)
|
||||
{
|
||||
case '"':
|
||||
/*
|
||||
Yes this looks strange,but this is so that we are
|
||||
MS Compatible, tests have shown that:
|
||||
\\\\"foo bar" gets passed as \\foo bar
|
||||
\\\\foo gets passed as \\\\foo
|
||||
\\\"foo gets passed as \"foo
|
||||
and \"foo gets passed as "foo in VC!
|
||||
*/
|
||||
non_slashes = num_slashes % 2;
|
||||
num_slashes = num_slashes / 2;
|
||||
for (; num_slashes > 0; num_slashes--)
|
||||
{
|
||||
d--;
|
||||
*d = '\0';
|
||||
}
|
||||
|
||||
if (non_slashes)
|
||||
{
|
||||
*(d-1) = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
instring ^= 1;
|
||||
}
|
||||
break;
|
||||
case 26:
|
||||
Lend:
|
||||
*d = 0; // terminate argument
|
||||
goto L2;
|
||||
|
||||
case 0xD: // CR
|
||||
c = lastc;
|
||||
continue; // ignore
|
||||
|
||||
case '@':
|
||||
recurse = 1;
|
||||
goto Ladd;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
if (!instring)
|
||||
{
|
||||
case '\n':
|
||||
case 0:
|
||||
*d = 0; // terminate argument
|
||||
goto Lnextarg;
|
||||
}
|
||||
default:
|
||||
Ladd:
|
||||
if (c == '\\')
|
||||
num_slashes++;
|
||||
else
|
||||
num_slashes = 0;
|
||||
*d++ = c;
|
||||
break;
|
||||
}
|
||||
#ifdef _MBCS
|
||||
if (_istlead (c)) {
|
||||
*d++ = *++p;
|
||||
if (*(d - 1) == '\0') {
|
||||
d--;
|
||||
goto Lnextarg;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
Lnextarg:
|
||||
;
|
||||
}
|
||||
L2:
|
||||
;
|
||||
}
|
||||
else if (addargp(&n,(*pargv)[i]))
|
||||
goto noexpand;
|
||||
}
|
||||
n.argv[n.argc] = NULL;
|
||||
if (recurse)
|
||||
{
|
||||
/* Recursively expand @filename */
|
||||
if (response_expand(&n.argc,&n.argv))
|
||||
goto noexpand;
|
||||
}
|
||||
*pargc = n.argc;
|
||||
*pargv = n.argv;
|
||||
return 0; /* success */
|
||||
|
||||
noexpand: /* error */
|
||||
free(n.argv);
|
||||
/* BUG: any file buffers are not free'd */
|
||||
return 1;
|
||||
}
|
||||
// Copyright (C) 1990-1998 by Symantec
|
||||
// Copyright (C) 2000-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// http://www.digitalmars.com
|
||||
// Written by Walter Bright
|
||||
/*
|
||||
* This source file is made available for personal use
|
||||
* only. The license is in /dmd/src/dmd/backendlicense.txt
|
||||
* For any other uses, please contact Digital Mars.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#if _WIN32
|
||||
#include <tchar.h>
|
||||
#include <io.h>
|
||||
#endif
|
||||
|
||||
#if linux || __APPLE__ || __FreeBSD__ || __sun&&__SVR4
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#include <fcntl.h>
|
||||
#include <errno.h>
|
||||
#include <unistd.h>
|
||||
#include <utime.h>
|
||||
#endif
|
||||
|
||||
/*********************************
|
||||
* #include <stdlib.h>
|
||||
* int response_expand(int *pargc,char ***pargv);
|
||||
*
|
||||
* Expand any response files in command line.
|
||||
* Response files are arguments that look like:
|
||||
* @NAME
|
||||
* The name is first searched for in the environment. If it is not
|
||||
* there, it is searched for as a file name.
|
||||
* Arguments are separated by spaces, tabs, or newlines. These can be
|
||||
* imbedded within arguments by enclosing the argument in '' or "".
|
||||
* Recursively expands nested response files.
|
||||
*
|
||||
* To use, put the line:
|
||||
* response_expand(&argc,&argv);
|
||||
* as the first executable statement in main(int argc, char **argv).
|
||||
* argc and argv are adjusted to be the new command line arguments
|
||||
* after response file expansion.
|
||||
*
|
||||
* Digital Mars's MAKE program can be notified that a program can accept
|
||||
* long command lines via environment variables by preceding the rule
|
||||
* line for the program with a *.
|
||||
*
|
||||
* Returns:
|
||||
* 0 success
|
||||
* !=0 failure (argc, argv unchanged)
|
||||
*/
|
||||
|
||||
struct Narg
|
||||
{
|
||||
int argc; /* arg count */
|
||||
int argvmax; /* dimension of nargv[] */
|
||||
char **argv;
|
||||
};
|
||||
|
||||
static int addargp(struct Narg *n, char *p)
|
||||
{
|
||||
/* The 2 is to always allow room for a NULL argp at the end */
|
||||
if (n->argc + 2 >= n->argvmax)
|
||||
{
|
||||
n->argvmax = n->argc + 2;
|
||||
n->argv = (char **) realloc(n->argv,n->argvmax * sizeof(char *));
|
||||
if (!n->argv)
|
||||
return 1;
|
||||
}
|
||||
n->argv[n->argc++] = p;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int response_expand(int *pargc, char ***pargv)
|
||||
{
|
||||
struct Narg n;
|
||||
int i;
|
||||
char *cp;
|
||||
int recurse = 0;
|
||||
|
||||
n.argc = 0;
|
||||
n.argvmax = 0; /* dimension of n.argv[] */
|
||||
n.argv = NULL;
|
||||
for(i=0; i<*pargc; ++i)
|
||||
{
|
||||
cp = (*pargv)[i];
|
||||
if (*cp == '@')
|
||||
{
|
||||
char *buffer;
|
||||
char *bufend;
|
||||
char *p;
|
||||
|
||||
cp++;
|
||||
p = getenv(cp);
|
||||
if (p)
|
||||
{
|
||||
buffer = strdup(p);
|
||||
if (!buffer)
|
||||
goto noexpand;
|
||||
bufend = buffer + strlen(buffer);
|
||||
}
|
||||
else
|
||||
{
|
||||
long length;
|
||||
int fd;
|
||||
int nread;
|
||||
size_t len;
|
||||
|
||||
#if __DMC__
|
||||
length = filesize(cp);
|
||||
#else
|
||||
struct stat statbuf;
|
||||
if (stat(cp, &statbuf))
|
||||
goto noexpand;
|
||||
length = statbuf.st_size;
|
||||
#endif
|
||||
if (length & 0xF0000000) /* error or file too big */
|
||||
goto noexpand;
|
||||
len = length;
|
||||
buffer = (char *)malloc(len + 1);
|
||||
if (!buffer)
|
||||
goto noexpand;
|
||||
bufend = &buffer[len];
|
||||
/* Read file into buffer */
|
||||
#if _WIN32
|
||||
fd = open(cp,O_RDONLY|O_BINARY);
|
||||
#else
|
||||
fd = open(cp,O_RDONLY);
|
||||
#endif
|
||||
if (fd == -1)
|
||||
goto noexpand;
|
||||
nread = read(fd,buffer,len);
|
||||
close(fd);
|
||||
|
||||
if (nread != len)
|
||||
goto noexpand;
|
||||
}
|
||||
|
||||
// The logic of this should match that in setargv()
|
||||
|
||||
for (p = buffer; p < bufend; p++)
|
||||
{
|
||||
char *d;
|
||||
char c,lastc;
|
||||
unsigned char instring;
|
||||
int num_slashes,non_slashes;
|
||||
|
||||
switch (*p)
|
||||
{
|
||||
case 26: /* ^Z marks end of file */
|
||||
goto L2;
|
||||
|
||||
case 0xD:
|
||||
case 0:
|
||||
case ' ':
|
||||
case '\t':
|
||||
case '\n':
|
||||
continue; // scan to start of argument
|
||||
|
||||
case '@':
|
||||
recurse = 1;
|
||||
default: /* start of new argument */
|
||||
if (addargp(&n,p))
|
||||
goto noexpand;
|
||||
instring = 0;
|
||||
c = 0;
|
||||
num_slashes = 0;
|
||||
for (d = p; 1; p++)
|
||||
{
|
||||
lastc = c;
|
||||
if (p >= bufend)
|
||||
goto Lend;
|
||||
c = *p;
|
||||
switch (c)
|
||||
{
|
||||
case '"':
|
||||
/*
|
||||
Yes this looks strange,but this is so that we are
|
||||
MS Compatible, tests have shown that:
|
||||
\\\\"foo bar" gets passed as \\foo bar
|
||||
\\\\foo gets passed as \\\\foo
|
||||
\\\"foo gets passed as \"foo
|
||||
and \"foo gets passed as "foo in VC!
|
||||
*/
|
||||
non_slashes = num_slashes % 2;
|
||||
num_slashes = num_slashes / 2;
|
||||
for (; num_slashes > 0; num_slashes--)
|
||||
{
|
||||
d--;
|
||||
*d = '\0';
|
||||
}
|
||||
|
||||
if (non_slashes)
|
||||
{
|
||||
*(d-1) = c;
|
||||
}
|
||||
else
|
||||
{
|
||||
instring ^= 1;
|
||||
}
|
||||
break;
|
||||
case 26:
|
||||
Lend:
|
||||
*d = 0; // terminate argument
|
||||
goto L2;
|
||||
|
||||
case 0xD: // CR
|
||||
c = lastc;
|
||||
continue; // ignore
|
||||
|
||||
case '@':
|
||||
recurse = 1;
|
||||
goto Ladd;
|
||||
|
||||
case ' ':
|
||||
case '\t':
|
||||
if (!instring)
|
||||
{
|
||||
case '\n':
|
||||
case 0:
|
||||
*d = 0; // terminate argument
|
||||
goto Lnextarg;
|
||||
}
|
||||
default:
|
||||
Ladd:
|
||||
if (c == '\\')
|
||||
num_slashes++;
|
||||
else
|
||||
num_slashes = 0;
|
||||
*d++ = c;
|
||||
break;
|
||||
}
|
||||
#ifdef _MBCS
|
||||
if (_istlead (c)) {
|
||||
*d++ = *++p;
|
||||
if (*(d - 1) == '\0') {
|
||||
d--;
|
||||
goto Lnextarg;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
}
|
||||
Lnextarg:
|
||||
;
|
||||
}
|
||||
L2:
|
||||
;
|
||||
}
|
||||
else if (addargp(&n,(*pargv)[i]))
|
||||
goto noexpand;
|
||||
}
|
||||
n.argv[n.argc] = NULL;
|
||||
if (recurse)
|
||||
{
|
||||
/* Recursively expand @filename */
|
||||
if (response_expand(&n.argc,&n.argv))
|
||||
goto noexpand;
|
||||
}
|
||||
*pargc = n.argc;
|
||||
*pargv = n.argv;
|
||||
return 0; /* success */
|
||||
|
||||
noexpand: /* error */
|
||||
free(n.argv);
|
||||
/* BUG: any file buffers are not free'd */
|
||||
return 1;
|
||||
}
|
||||
|
||||
102
dmd2/root/rmem.h
102
dmd2/root/rmem.h
@@ -1,51 +1,51 @@
|
||||
// Copyright (C) 2000-2001 by Chromium Communications
|
||||
// All Rights Reserved
|
||||
|
||||
#ifndef ROOT_MEM_H
|
||||
#define ROOT_MEM_H
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
|
||||
typedef void (*FINALIZERPROC)(void* pObj, void* pClientData);
|
||||
|
||||
struct GC; // thread specific allocator
|
||||
|
||||
struct Mem
|
||||
{
|
||||
GC *gc; // pointer to our thread specific allocator
|
||||
Mem() { gc = NULL; }
|
||||
|
||||
void init();
|
||||
|
||||
// Derive from Mem to get these storage allocators instead of global new/delete
|
||||
void * operator new(size_t m_size);
|
||||
void * operator new(size_t m_size, Mem *mem);
|
||||
void * operator new(size_t m_size, GC *gc);
|
||||
void operator delete(void *p);
|
||||
|
||||
void * operator new[](size_t m_size);
|
||||
void operator delete[](void *p);
|
||||
|
||||
char *strdup(const char *s);
|
||||
void *malloc(size_t size);
|
||||
void *malloc_uncollectable(size_t size);
|
||||
void *calloc(size_t size, size_t n);
|
||||
void *realloc(void *p, size_t size);
|
||||
void free(void *p);
|
||||
void free_uncollectable(void *p);
|
||||
void *mallocdup(void *o, size_t size);
|
||||
void error();
|
||||
void check(void *p); // validate pointer
|
||||
void fullcollect(); // do full garbage collection
|
||||
void fullcollectNoStack(); // do full garbage collection, no scan stack
|
||||
void mark(void *pointer);
|
||||
void addroots(char* pStart, char* pEnd);
|
||||
void removeroots(char* pStart);
|
||||
void setFinalizer(void* pObj, FINALIZERPROC pFn, void* pClientData);
|
||||
void setStackBottom(void *bottom);
|
||||
GC *getThreadGC(); // get apartment allocator for this thread
|
||||
};
|
||||
|
||||
extern Mem mem;
|
||||
|
||||
#endif /* ROOT_MEM_H */
|
||||
// Copyright (C) 2000-2001 by Chromium Communications
|
||||
// All Rights Reserved
|
||||
|
||||
#ifndef ROOT_MEM_H
|
||||
#define ROOT_MEM_H
|
||||
|
||||
#include <stddef.h> // for size_t
|
||||
|
||||
typedef void (*FINALIZERPROC)(void* pObj, void* pClientData);
|
||||
|
||||
struct GC; // thread specific allocator
|
||||
|
||||
struct Mem
|
||||
{
|
||||
GC *gc; // pointer to our thread specific allocator
|
||||
Mem() { gc = NULL; }
|
||||
|
||||
void init();
|
||||
|
||||
// Derive from Mem to get these storage allocators instead of global new/delete
|
||||
void * operator new(size_t m_size);
|
||||
void * operator new(size_t m_size, Mem *mem);
|
||||
void * operator new(size_t m_size, GC *gc);
|
||||
void operator delete(void *p);
|
||||
|
||||
void * operator new[](size_t m_size);
|
||||
void operator delete[](void *p);
|
||||
|
||||
char *strdup(const char *s);
|
||||
void *malloc(size_t size);
|
||||
void *malloc_uncollectable(size_t size);
|
||||
void *calloc(size_t size, size_t n);
|
||||
void *realloc(void *p, size_t size);
|
||||
void free(void *p);
|
||||
void free_uncollectable(void *p);
|
||||
void *mallocdup(void *o, size_t size);
|
||||
void error();
|
||||
void check(void *p); // validate pointer
|
||||
void fullcollect(); // do full garbage collection
|
||||
void fullcollectNoStack(); // do full garbage collection, no scan stack
|
||||
void mark(void *pointer);
|
||||
void addroots(char* pStart, char* pEnd);
|
||||
void removeroots(char* pStart);
|
||||
void setFinalizer(void* pObj, FINALIZERPROC pFn, void* pClientData);
|
||||
void setStackBottom(void *bottom);
|
||||
GC *getThreadGC(); // get apartment allocator for this thread
|
||||
};
|
||||
|
||||
extern Mem mem;
|
||||
|
||||
#endif /* ROOT_MEM_H */
|
||||
|
||||
4043
dmd2/root/root.c
4043
dmd2/root/root.c
File diff suppressed because it is too large
Load Diff
726
dmd2/root/root.h
726
dmd2/root/root.h
@@ -1,359 +1,367 @@
|
||||
|
||||
|
||||
// Copyright (c) 1999-2006 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef ROOT_H
|
||||
#define ROOT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if __DMC__
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
typedef size_t hash_t;
|
||||
|
||||
#include "dchar.h"
|
||||
|
||||
char *wchar2ascii(wchar_t *);
|
||||
int wcharIsAscii(wchar_t *);
|
||||
char *wchar2ascii(wchar_t *, unsigned len);
|
||||
int wcharIsAscii(wchar_t *, unsigned len);
|
||||
|
||||
int bstrcmp(unsigned char *s1, unsigned char *s2);
|
||||
char *bstr2str(unsigned char *b);
|
||||
void error(const char *format, ...);
|
||||
void error(const wchar_t *format, ...);
|
||||
void warning(const char *format, ...);
|
||||
|
||||
#ifndef TYPEDEFS
|
||||
#define TYPEDEFS
|
||||
|
||||
#if _MSC_VER
|
||||
#include <float.h> // for _isnan
|
||||
#include <malloc.h> // for alloca
|
||||
// According to VC 8.0 docs, long double is the same as double
|
||||
#define strtold strtod
|
||||
#define strtof strtod
|
||||
#define isnan _isnan
|
||||
|
||||
typedef __int64 longlong;
|
||||
typedef unsigned __int64 ulonglong;
|
||||
#else
|
||||
typedef long long longlong;
|
||||
typedef unsigned long long ulonglong;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
longlong randomx();
|
||||
|
||||
/*
|
||||
* Root of our class library.
|
||||
*/
|
||||
|
||||
struct OutBuffer;
|
||||
struct Array;
|
||||
|
||||
struct Object
|
||||
{
|
||||
Object() { }
|
||||
virtual ~Object() { }
|
||||
|
||||
virtual int equals(Object *o);
|
||||
|
||||
/**
|
||||
* Returns a hash code, useful for things like building hash tables of Objects.
|
||||
*/
|
||||
virtual hash_t hashCode();
|
||||
|
||||
/**
|
||||
* Return <0, ==0, or >0 if this is less than, equal to, or greater than obj.
|
||||
* Useful for sorting Objects.
|
||||
*/
|
||||
virtual int compare(Object *obj);
|
||||
|
||||
/**
|
||||
* Pretty-print an Object. Useful for debugging the old-fashioned way.
|
||||
*/
|
||||
virtual void print();
|
||||
|
||||
virtual char *toChars();
|
||||
virtual dchar *toDchars();
|
||||
virtual void toBuffer(OutBuffer *buf);
|
||||
|
||||
/**
|
||||
* Used as a replacement for dynamic_cast. Returns a unique number
|
||||
* defined by the library user. For Object, the return value is 0.
|
||||
*/
|
||||
virtual int dyncast();
|
||||
|
||||
/**
|
||||
* Marks pointers for garbage collector by calling mem.mark() for all pointers into heap.
|
||||
*/
|
||||
/*virtual*/ // not used, disable for now
|
||||
void mark();
|
||||
};
|
||||
|
||||
struct String : Object
|
||||
{
|
||||
int ref; // != 0 if this is a reference to someone else's string
|
||||
char *str; // the string itself
|
||||
|
||||
String(char *str, int ref = 1);
|
||||
|
||||
~String();
|
||||
|
||||
static hash_t calcHash(const char *str, size_t len);
|
||||
static hash_t calcHash(const char *str);
|
||||
hash_t hashCode();
|
||||
unsigned len();
|
||||
int equals(Object *obj);
|
||||
int compare(Object *obj);
|
||||
char *toChars();
|
||||
void print();
|
||||
void mark();
|
||||
};
|
||||
|
||||
struct FileName : String
|
||||
{
|
||||
FileName(char *str, int ref);
|
||||
FileName(char *path, char *name);
|
||||
hash_t hashCode();
|
||||
int equals(Object *obj);
|
||||
static int equals(const char *name1, const char *name2);
|
||||
int compare(Object *obj);
|
||||
static int compare(const char *name1, const char *name2);
|
||||
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 *);
|
||||
static const char *replaceName(const char *path, const char *name);
|
||||
|
||||
static char *combine(const char *path, const char *name);
|
||||
static Array *splitPath(const char *path);
|
||||
static FileName *defaultExt(const char *name, const char *ext);
|
||||
static FileName *forceExt(const char *name, const char *ext);
|
||||
int equalsExt(const char *ext);
|
||||
|
||||
void CopyTo(FileName *to);
|
||||
static char *searchPath(Array *path, const char *name, int cwd);
|
||||
static int exists(const char *name);
|
||||
static void ensurePathExists(const char *path);
|
||||
};
|
||||
|
||||
struct File : Object
|
||||
{
|
||||
int ref; // != 0 if this is a reference to someone else's buffer
|
||||
unsigned char *buffer; // data for our file
|
||||
unsigned len; // amount of data in buffer[]
|
||||
void *touchtime; // system time to use for file
|
||||
|
||||
FileName *name; // name of our file
|
||||
|
||||
File(char *);
|
||||
File(FileName *);
|
||||
~File();
|
||||
|
||||
void mark();
|
||||
|
||||
char *toChars();
|
||||
|
||||
/* Read file, return !=0 if error
|
||||
*/
|
||||
|
||||
int read();
|
||||
|
||||
/* Write file, either succeed or fail
|
||||
* with error message & exit.
|
||||
*/
|
||||
|
||||
void readv();
|
||||
|
||||
/* Read file, return !=0 if error
|
||||
*/
|
||||
|
||||
int mmread();
|
||||
|
||||
/* Write file, either succeed or fail
|
||||
* with error message & exit.
|
||||
*/
|
||||
|
||||
void mmreadv();
|
||||
|
||||
/* Write file, return !=0 if error
|
||||
*/
|
||||
|
||||
int write();
|
||||
|
||||
/* Write file, either succeed or fail
|
||||
* with error message & exit.
|
||||
*/
|
||||
|
||||
void writev();
|
||||
|
||||
/* Return !=0 if file exists.
|
||||
* 0: file doesn't exist
|
||||
* 1: normal file
|
||||
* 2: directory
|
||||
*/
|
||||
|
||||
/* Append to file, return !=0 if error
|
||||
*/
|
||||
|
||||
int append();
|
||||
|
||||
/* Append to file, either succeed or fail
|
||||
* with error message & exit.
|
||||
*/
|
||||
|
||||
void appendv();
|
||||
|
||||
/* Return !=0 if file exists.
|
||||
* 0: file doesn't exist
|
||||
* 1: normal file
|
||||
* 2: directory
|
||||
*/
|
||||
|
||||
int exists();
|
||||
|
||||
/* Given wildcard filespec, return an array of
|
||||
* matching File's.
|
||||
*/
|
||||
|
||||
static Array *match(char *);
|
||||
static Array *match(FileName *);
|
||||
|
||||
// Compare file times.
|
||||
// Return <0 this < f
|
||||
// =0 this == f
|
||||
// >0 this > f
|
||||
int compareTime(File *f);
|
||||
|
||||
// Read system file statistics
|
||||
void stat();
|
||||
|
||||
/* Set buffer
|
||||
*/
|
||||
|
||||
void setbuffer(void *buffer, unsigned len)
|
||||
{
|
||||
this->buffer = (unsigned char *)buffer;
|
||||
this->len = len;
|
||||
}
|
||||
|
||||
void checkoffset(size_t offset, size_t nbytes);
|
||||
|
||||
void remove(); // delete file
|
||||
};
|
||||
|
||||
struct OutBuffer : Object
|
||||
{
|
||||
unsigned char *data;
|
||||
unsigned offset;
|
||||
unsigned size;
|
||||
|
||||
OutBuffer();
|
||||
~OutBuffer();
|
||||
void *extractData();
|
||||
void mark();
|
||||
|
||||
void reserve(unsigned nbytes);
|
||||
void setsize(unsigned size);
|
||||
void reset();
|
||||
void write(const void *data, unsigned nbytes);
|
||||
void writebstring(unsigned char *string);
|
||||
void writestring(const char *string);
|
||||
void writedstring(const char *string);
|
||||
void writedstring(const wchar_t *string);
|
||||
void prependstring(const char *string);
|
||||
void writenl(); // write newline
|
||||
void writeByte(unsigned b);
|
||||
void writebyte(unsigned b) { writeByte(b); }
|
||||
void writeUTF8(unsigned b);
|
||||
void writedchar(unsigned b);
|
||||
void prependbyte(unsigned b);
|
||||
void writeword(unsigned w);
|
||||
void writeUTF16(unsigned w);
|
||||
void write4(unsigned w);
|
||||
void write(OutBuffer *buf);
|
||||
void write(Object *obj);
|
||||
void fill0(unsigned nbytes);
|
||||
void align(unsigned size);
|
||||
void vprintf(const char *format, va_list args);
|
||||
void printf(const char *format, ...);
|
||||
#if M_UNICODE
|
||||
void vprintf(const unsigned short *format, va_list args);
|
||||
void printf(const unsigned short *format, ...);
|
||||
#endif
|
||||
void bracket(char left, char right);
|
||||
unsigned bracket(unsigned i, const char *left, unsigned j, const char *right);
|
||||
void spread(unsigned offset, unsigned nbytes);
|
||||
unsigned insert(unsigned offset, const void *data, unsigned nbytes);
|
||||
void remove(unsigned offset, unsigned nbytes);
|
||||
char *toChars();
|
||||
char *extractString();
|
||||
};
|
||||
|
||||
struct Array : Object
|
||||
{
|
||||
unsigned dim;
|
||||
unsigned allocdim;
|
||||
void **data;
|
||||
|
||||
Array();
|
||||
~Array();
|
||||
void mark();
|
||||
char *toChars();
|
||||
|
||||
void reserve(unsigned nentries);
|
||||
void setDim(unsigned newdim);
|
||||
void fixDim();
|
||||
void push(void *ptr);
|
||||
void *pop();
|
||||
void shift(void *ptr);
|
||||
void insert(unsigned index, void *ptr);
|
||||
void insert(unsigned index, Array *a);
|
||||
void append(Array *a);
|
||||
void remove(unsigned i);
|
||||
void zero();
|
||||
void *tos();
|
||||
void sort();
|
||||
Array *copy();
|
||||
};
|
||||
|
||||
struct Bits : Object
|
||||
{
|
||||
unsigned bitdim;
|
||||
unsigned allocdim;
|
||||
unsigned *data;
|
||||
|
||||
Bits();
|
||||
~Bits();
|
||||
void mark();
|
||||
|
||||
void resize(unsigned bitdim);
|
||||
|
||||
void set(unsigned bitnum);
|
||||
void clear(unsigned bitnum);
|
||||
int test(unsigned bitnum);
|
||||
|
||||
void set();
|
||||
void clear();
|
||||
void copy(Bits *from);
|
||||
Bits *clone();
|
||||
|
||||
void sub(Bits *b);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
// Copyright (c) 1999-2010 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 ROOT_H
|
||||
#define ROOT_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdarg.h>
|
||||
|
||||
#if __DMC__
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
typedef size_t hash_t;
|
||||
|
||||
#include "dchar.h"
|
||||
|
||||
char *wchar2ascii(wchar_t *);
|
||||
int wcharIsAscii(wchar_t *);
|
||||
char *wchar2ascii(wchar_t *, unsigned len);
|
||||
int wcharIsAscii(wchar_t *, unsigned len);
|
||||
|
||||
int bstrcmp(unsigned char *s1, unsigned char *s2);
|
||||
char *bstr2str(unsigned char *b);
|
||||
void error(const char *format, ...);
|
||||
void error(const wchar_t *format, ...);
|
||||
void warning(const char *format, ...);
|
||||
|
||||
#ifndef TYPEDEFS
|
||||
#define TYPEDEFS
|
||||
|
||||
#if _MSC_VER
|
||||
#include <float.h> // for _isnan
|
||||
#include <malloc.h> // for alloca
|
||||
// According to VC 8.0 docs, long double is the same as double
|
||||
#define strtold strtod
|
||||
#define strtof strtod
|
||||
#define isnan _isnan
|
||||
|
||||
typedef __int64 longlong;
|
||||
typedef unsigned __int64 ulonglong;
|
||||
#else
|
||||
typedef long long longlong;
|
||||
typedef unsigned long long ulonglong;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
longlong randomx();
|
||||
|
||||
/*
|
||||
* Root of our class library.
|
||||
*/
|
||||
|
||||
struct OutBuffer;
|
||||
struct Array;
|
||||
|
||||
struct Object
|
||||
{
|
||||
Object() { }
|
||||
virtual ~Object() { }
|
||||
|
||||
virtual int equals(Object *o);
|
||||
|
||||
/**
|
||||
* Returns a hash code, useful for things like building hash tables of Objects.
|
||||
*/
|
||||
virtual hash_t hashCode();
|
||||
|
||||
/**
|
||||
* Return <0, ==0, or >0 if this is less than, equal to, or greater than obj.
|
||||
* Useful for sorting Objects.
|
||||
*/
|
||||
virtual int compare(Object *obj);
|
||||
|
||||
/**
|
||||
* Pretty-print an Object. Useful for debugging the old-fashioned way.
|
||||
*/
|
||||
virtual void print();
|
||||
|
||||
virtual char *toChars();
|
||||
virtual dchar *toDchars();
|
||||
virtual void toBuffer(OutBuffer *buf);
|
||||
|
||||
/**
|
||||
* Used as a replacement for dynamic_cast. Returns a unique number
|
||||
* defined by the library user. For Object, the return value is 0.
|
||||
*/
|
||||
virtual int dyncast();
|
||||
|
||||
/**
|
||||
* Marks pointers for garbage collector by calling mem.mark() for all pointers into heap.
|
||||
*/
|
||||
/*virtual*/ // not used, disable for now
|
||||
void mark();
|
||||
};
|
||||
|
||||
struct String : Object
|
||||
{
|
||||
int ref; // != 0 if this is a reference to someone else's string
|
||||
char *str; // the string itself
|
||||
|
||||
String(char *str, int ref = 1);
|
||||
|
||||
~String();
|
||||
|
||||
static hash_t calcHash(const char *str, size_t len);
|
||||
static hash_t calcHash(const char *str);
|
||||
hash_t hashCode();
|
||||
unsigned len();
|
||||
int equals(Object *obj);
|
||||
int compare(Object *obj);
|
||||
char *toChars();
|
||||
void print();
|
||||
void mark();
|
||||
};
|
||||
|
||||
struct FileName : String
|
||||
{
|
||||
FileName(char *str, int ref);
|
||||
FileName(char *path, char *name);
|
||||
hash_t hashCode();
|
||||
int equals(Object *obj);
|
||||
static int equals(const char *name1, const char *name2);
|
||||
int compare(Object *obj);
|
||||
static int compare(const char *name1, const char *name2);
|
||||
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 *);
|
||||
static const char *replaceName(const char *path, const char *name);
|
||||
|
||||
static char *combine(const char *path, const char *name);
|
||||
static Array *splitPath(const char *path);
|
||||
static FileName *defaultExt(const char *name, const char *ext);
|
||||
static FileName *forceExt(const char *name, const char *ext);
|
||||
int equalsExt(const char *ext);
|
||||
|
||||
void CopyTo(FileName *to);
|
||||
static char *searchPath(Array *path, const char *name, int cwd);
|
||||
static char *safeSearchPath(Array *path, const char *name);
|
||||
static int exists(const char *name);
|
||||
static void ensurePathExists(const char *path);
|
||||
static char *canonicalName(const char *name);
|
||||
};
|
||||
|
||||
struct File : Object
|
||||
{
|
||||
int ref; // != 0 if this is a reference to someone else's buffer
|
||||
unsigned char *buffer; // data for our file
|
||||
unsigned len; // amount of data in buffer[]
|
||||
void *touchtime; // system time to use for file
|
||||
|
||||
FileName *name; // name of our file
|
||||
|
||||
File(char *);
|
||||
File(FileName *);
|
||||
~File();
|
||||
|
||||
void mark();
|
||||
|
||||
char *toChars();
|
||||
|
||||
/* Read file, return !=0 if error
|
||||
*/
|
||||
|
||||
int read();
|
||||
|
||||
/* Write file, either succeed or fail
|
||||
* with error message & exit.
|
||||
*/
|
||||
|
||||
void readv();
|
||||
|
||||
/* Read file, return !=0 if error
|
||||
*/
|
||||
|
||||
int mmread();
|
||||
|
||||
/* Write file, either succeed or fail
|
||||
* with error message & exit.
|
||||
*/
|
||||
|
||||
void mmreadv();
|
||||
|
||||
/* Write file, return !=0 if error
|
||||
*/
|
||||
|
||||
int write();
|
||||
|
||||
/* Write file, either succeed or fail
|
||||
* with error message & exit.
|
||||
*/
|
||||
|
||||
void writev();
|
||||
|
||||
/* Return !=0 if file exists.
|
||||
* 0: file doesn't exist
|
||||
* 1: normal file
|
||||
* 2: directory
|
||||
*/
|
||||
|
||||
/* Append to file, return !=0 if error
|
||||
*/
|
||||
|
||||
int append();
|
||||
|
||||
/* Append to file, either succeed or fail
|
||||
* with error message & exit.
|
||||
*/
|
||||
|
||||
void appendv();
|
||||
|
||||
/* Return !=0 if file exists.
|
||||
* 0: file doesn't exist
|
||||
* 1: normal file
|
||||
* 2: directory
|
||||
*/
|
||||
|
||||
int exists();
|
||||
|
||||
/* Given wildcard filespec, return an array of
|
||||
* matching File's.
|
||||
*/
|
||||
|
||||
static Array *match(char *);
|
||||
static Array *match(FileName *);
|
||||
|
||||
// Compare file times.
|
||||
// Return <0 this < f
|
||||
// =0 this == f
|
||||
// >0 this > f
|
||||
int compareTime(File *f);
|
||||
|
||||
// Read system file statistics
|
||||
void stat();
|
||||
|
||||
/* Set buffer
|
||||
*/
|
||||
|
||||
void setbuffer(void *buffer, unsigned len)
|
||||
{
|
||||
this->buffer = (unsigned char *)buffer;
|
||||
this->len = len;
|
||||
}
|
||||
|
||||
void checkoffset(size_t offset, size_t nbytes);
|
||||
|
||||
void remove(); // delete file
|
||||
};
|
||||
|
||||
struct OutBuffer : Object
|
||||
{
|
||||
unsigned char *data;
|
||||
unsigned offset;
|
||||
unsigned size;
|
||||
|
||||
OutBuffer();
|
||||
~OutBuffer();
|
||||
void *extractData();
|
||||
void mark();
|
||||
|
||||
void reserve(unsigned nbytes);
|
||||
void setsize(unsigned size);
|
||||
void reset();
|
||||
void write(const void *data, unsigned nbytes);
|
||||
void writebstring(unsigned char *string);
|
||||
void writestring(const char *string);
|
||||
void writedstring(const char *string);
|
||||
void writedstring(const wchar_t *string);
|
||||
void prependstring(const char *string);
|
||||
void writenl(); // write newline
|
||||
void writeByte(unsigned b);
|
||||
void writebyte(unsigned b) { writeByte(b); }
|
||||
void writeUTF8(unsigned b);
|
||||
void writedchar(unsigned b);
|
||||
void prependbyte(unsigned b);
|
||||
void writeword(unsigned w);
|
||||
void writeUTF16(unsigned w);
|
||||
void write4(unsigned w);
|
||||
void write(OutBuffer *buf);
|
||||
void write(Object *obj);
|
||||
void fill0(unsigned nbytes);
|
||||
void align(unsigned size);
|
||||
void vprintf(const char *format, va_list args);
|
||||
void printf(const char *format, ...);
|
||||
#if M_UNICODE
|
||||
void vprintf(const unsigned short *format, va_list args);
|
||||
void printf(const unsigned short *format, ...);
|
||||
#endif
|
||||
void bracket(char left, char right);
|
||||
unsigned bracket(unsigned i, const char *left, unsigned j, const char *right);
|
||||
void spread(unsigned offset, unsigned nbytes);
|
||||
unsigned insert(unsigned offset, const void *data, unsigned nbytes);
|
||||
void remove(unsigned offset, unsigned nbytes);
|
||||
char *toChars();
|
||||
char *extractString();
|
||||
};
|
||||
|
||||
struct Array : Object
|
||||
{
|
||||
unsigned dim;
|
||||
void **data;
|
||||
|
||||
private:
|
||||
unsigned allocdim;
|
||||
#define SMALLARRAYCAP 1
|
||||
void *smallarray[SMALLARRAYCAP]; // inline storage for small arrays
|
||||
|
||||
public:
|
||||
Array();
|
||||
~Array();
|
||||
//Array(const Array&);
|
||||
void mark();
|
||||
char *toChars();
|
||||
|
||||
void reserve(unsigned nentries);
|
||||
void setDim(unsigned newdim);
|
||||
void fixDim();
|
||||
void push(void *ptr);
|
||||
void *pop();
|
||||
void shift(void *ptr);
|
||||
void insert(unsigned index, void *ptr);
|
||||
void insert(unsigned index, Array *a);
|
||||
void append(Array *a);
|
||||
void remove(unsigned i);
|
||||
void zero();
|
||||
void *tos();
|
||||
void sort();
|
||||
Array *copy();
|
||||
};
|
||||
|
||||
struct Bits : Object
|
||||
{
|
||||
unsigned bitdim;
|
||||
unsigned allocdim;
|
||||
unsigned *data;
|
||||
|
||||
Bits();
|
||||
~Bits();
|
||||
void mark();
|
||||
|
||||
void resize(unsigned bitdim);
|
||||
|
||||
void set(unsigned bitnum);
|
||||
void clear(unsigned bitnum);
|
||||
int test(unsigned bitnum);
|
||||
|
||||
void set();
|
||||
void clear();
|
||||
void copy(Bits *from);
|
||||
Bits *clone();
|
||||
|
||||
void sub(Bits *b);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
253
dmd2/root/speller.c
Normal file
253
dmd2/root/speller.c
Normal file
@@ -0,0 +1,253 @@
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "speller.h"
|
||||
|
||||
const char idchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_";
|
||||
|
||||
/**************************************************
|
||||
* Looks for correct spelling.
|
||||
* Currently only looks a 'distance' of one from the seed[].
|
||||
* This does an exhaustive search, so can potentially be very slow.
|
||||
* Input:
|
||||
* seed wrongly spelled word
|
||||
* fp search function
|
||||
* fparg argument to search function
|
||||
* charset character set
|
||||
* Returns:
|
||||
* NULL no correct spellings found
|
||||
* void* value returned by fp() for first possible correct spelling
|
||||
*/
|
||||
|
||||
void *spellerY(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg,
|
||||
const char *charset, size_t index)
|
||||
{
|
||||
if (!seedlen)
|
||||
return NULL;
|
||||
assert(seed[seedlen] == 0);
|
||||
|
||||
char tmp[30];
|
||||
char *buf;
|
||||
if (seedlen <= sizeof(tmp) - 2)
|
||||
buf = tmp;
|
||||
else
|
||||
{
|
||||
buf = (char *)alloca(seedlen + 2); // leave space for extra char
|
||||
if (!buf)
|
||||
return NULL; // no matches
|
||||
}
|
||||
|
||||
memcpy(buf, seed, index);
|
||||
|
||||
/* Delete at seed[index] */
|
||||
if (index < seedlen)
|
||||
{
|
||||
memcpy(buf + index, seed + index + 1, seedlen - index);
|
||||
assert(buf[seedlen - 1] == 0);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
|
||||
if (charset && *charset)
|
||||
{
|
||||
/* Substitutions */
|
||||
if (index < seedlen)
|
||||
{
|
||||
memcpy(buf, seed, seedlen + 1);
|
||||
for (const char *s = charset; *s; s++)
|
||||
{
|
||||
buf[index] = *s;
|
||||
|
||||
//printf("sub buf = '%s'\n", buf);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
assert(buf[seedlen] == 0);
|
||||
}
|
||||
|
||||
/* Insertions */
|
||||
memcpy (buf + index + 1, seed + index, seedlen + 1 - index);
|
||||
|
||||
for (const char *s = charset; *s; s++)
|
||||
{
|
||||
buf[index] = *s;
|
||||
|
||||
//printf("ins buf = '%s'\n", buf);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
assert(buf[seedlen + 1] == 0);
|
||||
}
|
||||
|
||||
return NULL; // didn't find any corrections
|
||||
}
|
||||
|
||||
void *spellerX(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg,
|
||||
const char *charset, int flag)
|
||||
{
|
||||
if (!seedlen)
|
||||
return NULL;
|
||||
|
||||
char tmp[30];
|
||||
char *buf;
|
||||
if (seedlen <= sizeof(tmp) - 2)
|
||||
buf = tmp;
|
||||
else
|
||||
{
|
||||
buf = (char *)alloca(seedlen + 2); // leave space for extra char
|
||||
if (!buf)
|
||||
return NULL; // no matches
|
||||
}
|
||||
|
||||
/* Deletions */
|
||||
memcpy(buf, seed + 1, seedlen);
|
||||
for (int i = 0; i < seedlen; i++)
|
||||
{
|
||||
//printf("del buf = '%s'\n", buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerY(buf, seedlen - 1, fp, fparg, charset, i);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
|
||||
buf[i] = seed[i];
|
||||
}
|
||||
|
||||
/* Transpositions */
|
||||
if (!flag)
|
||||
{
|
||||
memcpy(buf, seed, seedlen + 1);
|
||||
for (int i = 0; i + 1 < seedlen; i++)
|
||||
{
|
||||
// swap [i] and [i + 1]
|
||||
buf[i] = seed[i + 1];
|
||||
buf[i + 1] = seed[i];
|
||||
|
||||
//printf("tra buf = '%s'\n", buf);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
|
||||
buf[i] = seed[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (charset && *charset)
|
||||
{
|
||||
/* Substitutions */
|
||||
memcpy(buf, seed, seedlen + 1);
|
||||
for (int i = 0; i < seedlen; i++)
|
||||
{
|
||||
for (const char *s = charset; *s; s++)
|
||||
{
|
||||
buf[i] = *s;
|
||||
|
||||
//printf("sub buf = '%s'\n", buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerY(buf, seedlen, fp, fparg, charset, i + 1);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
buf[i] = seed[i];
|
||||
}
|
||||
|
||||
/* Insertions */
|
||||
memcpy(buf + 1, seed, seedlen + 1);
|
||||
for (int i = 0; i <= seedlen; i++) // yes, do seedlen+1 iterations
|
||||
{
|
||||
for (const char *s = charset; *s; s++)
|
||||
{
|
||||
buf[i] = *s;
|
||||
|
||||
//printf("ins buf = '%s'\n", buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerY(buf, seedlen + 1, fp, fparg, charset, i + 1);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
buf[i] = seed[i]; // going past end of seed[] is ok, as we hit the 0
|
||||
}
|
||||
}
|
||||
|
||||
return NULL; // didn't find any corrections
|
||||
}
|
||||
|
||||
void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charset)
|
||||
{
|
||||
size_t seedlen = strlen(seed);
|
||||
for (int distance = 0; distance < 2; distance++)
|
||||
{ void *p = spellerX(seed, seedlen, fp, fparg, charset, distance);
|
||||
if (p)
|
||||
return p;
|
||||
// if (seedlen > 10)
|
||||
// break;
|
||||
}
|
||||
return NULL; // didn't find it
|
||||
}
|
||||
|
||||
|
||||
#if UNITTEST
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
void *speller_test(void *fparg, const char *s)
|
||||
{
|
||||
//printf("speller_test(%s, %s)\n", fparg, s);
|
||||
if (strcmp((char *)fparg, s) == 0)
|
||||
return fparg;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void unittest_speller()
|
||||
{
|
||||
static const char *cases[][3] =
|
||||
{
|
||||
{ "hello", "hell", "y" },
|
||||
{ "hello", "hel", "y" },
|
||||
{ "hello", "ello", "y" },
|
||||
{ "hello", "llo", "y" },
|
||||
{ "hello", "hellox", "y" },
|
||||
{ "hello", "helloxy", "y" },
|
||||
{ "hello", "xhello", "y" },
|
||||
{ "hello", "xyhello", "y" },
|
||||
{ "hello", "ehllo", "y" },
|
||||
{ "hello", "helol", "y" },
|
||||
{ "hello", "abcd", "n" },
|
||||
//{ "ehllo", "helol", "y" },
|
||||
{ "hello", "helxxlo", "y" },
|
||||
{ "hello", "ehlxxlo", "n" },
|
||||
{ "hello", "heaao", "y" },
|
||||
{ "_123456789_123456789_123456789_123456789", "_123456789_123456789_123456789_12345678", "y" },
|
||||
};
|
||||
//printf("unittest_speller()\n");
|
||||
const void *p = speller("hello", &speller_test, (void *)"hell", idchars);
|
||||
assert(p != NULL);
|
||||
for (int i = 0; i < sizeof(cases)/sizeof(cases[0]); i++)
|
||||
{
|
||||
//printf("case [%d]\n", i);
|
||||
void *p = speller(cases[i][0], &speller_test, (void *)cases[i][1], idchars);
|
||||
if (p)
|
||||
assert(cases[i][2][0] == 'y');
|
||||
else
|
||||
assert(cases[i][2][0] == 'n');
|
||||
}
|
||||
//printf("unittest_speller() success\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
7
dmd2/root/speller.h
Normal file
7
dmd2/root/speller.h
Normal file
@@ -0,0 +1,7 @@
|
||||
|
||||
typedef void *(fp_speller_t)(void *, const char *);
|
||||
|
||||
extern const char idchars[];
|
||||
|
||||
void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charset);
|
||||
|
||||
@@ -1,139 +1,139 @@
|
||||
|
||||
// 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.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "rmem.h"
|
||||
#include "dchar.h"
|
||||
#include "lstring.h"
|
||||
#include "stringtable.h"
|
||||
|
||||
StringTable::StringTable(unsigned size)
|
||||
{
|
||||
table = (void **)mem.calloc(size, sizeof(void *));
|
||||
tabledim = size;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
StringTable::~StringTable()
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
// Zero out dangling pointers to help garbage collector.
|
||||
// Should zero out StringEntry's too.
|
||||
for (i = 0; i < count; i++)
|
||||
table[i] = NULL;
|
||||
|
||||
mem.free(table);
|
||||
table = NULL;
|
||||
}
|
||||
|
||||
struct StringEntry
|
||||
{
|
||||
StringEntry *left;
|
||||
StringEntry *right;
|
||||
hash_t hash;
|
||||
|
||||
StringValue value;
|
||||
|
||||
static StringEntry *alloc(const dchar *s, unsigned len);
|
||||
};
|
||||
|
||||
StringEntry *StringEntry::alloc(const dchar *s, unsigned len)
|
||||
{
|
||||
StringEntry *se;
|
||||
|
||||
se = (StringEntry *) mem.calloc(1,sizeof(StringEntry) - sizeof(Lstring) + Lstring::size(len));
|
||||
se->value.lstring.length = len;
|
||||
se->hash = Dchar::calcHash(s,len);
|
||||
memcpy(se->value.lstring.string, s, len * sizeof(dchar));
|
||||
return se;
|
||||
}
|
||||
|
||||
void **StringTable::search(const dchar *s, unsigned len)
|
||||
{
|
||||
hash_t hash;
|
||||
unsigned u;
|
||||
int cmp;
|
||||
StringEntry **se;
|
||||
|
||||
//printf("StringTable::search(%p,%d)\n",s,len);
|
||||
hash = Dchar::calcHash(s,len);
|
||||
u = hash % tabledim;
|
||||
se = (StringEntry **)&table[u];
|
||||
//printf("\thash = %d, u = %d\n",hash,u);
|
||||
while (*se)
|
||||
{
|
||||
cmp = (*se)->hash - hash;
|
||||
if (cmp == 0)
|
||||
{
|
||||
cmp = (*se)->value.lstring.len() - len;
|
||||
if (cmp == 0)
|
||||
{
|
||||
cmp = Dchar::memcmp(s,(*se)->value.lstring.toDchars(),len);
|
||||
if (cmp == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cmp < 0)
|
||||
se = &(*se)->left;
|
||||
else
|
||||
se = &(*se)->right;
|
||||
}
|
||||
//printf("\treturn %p, %p\n",se, (*se));
|
||||
return (void **)se;
|
||||
}
|
||||
|
||||
StringValue *StringTable::lookup(const dchar *s, unsigned len)
|
||||
{ StringEntry *se;
|
||||
|
||||
se = *(StringEntry **)search(s,len);
|
||||
if (se)
|
||||
return &se->value;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
StringValue *StringTable::update(const dchar *s, unsigned len)
|
||||
{ StringEntry **pse;
|
||||
StringEntry *se;
|
||||
|
||||
pse = (StringEntry **)search(s,len);
|
||||
se = *pse;
|
||||
if (!se) // not in table: so create new entry
|
||||
{
|
||||
se = StringEntry::alloc(s, len);
|
||||
*pse = se;
|
||||
}
|
||||
return &se->value;
|
||||
}
|
||||
|
||||
StringValue *StringTable::insert(const dchar *s, unsigned len)
|
||||
{ StringEntry **pse;
|
||||
StringEntry *se;
|
||||
|
||||
pse = (StringEntry **)search(s,len);
|
||||
se = *pse;
|
||||
if (se)
|
||||
return NULL; // error: already in table
|
||||
else
|
||||
{
|
||||
se = StringEntry::alloc(s, len);
|
||||
*pse = se;
|
||||
}
|
||||
return &se->value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// 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.
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "rmem.h"
|
||||
#include "dchar.h"
|
||||
#include "lstring.h"
|
||||
#include "stringtable.h"
|
||||
|
||||
StringTable::StringTable(unsigned size)
|
||||
{
|
||||
table = (void **)mem.calloc(size, sizeof(void *));
|
||||
tabledim = size;
|
||||
count = 0;
|
||||
}
|
||||
|
||||
StringTable::~StringTable()
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
// Zero out dangling pointers to help garbage collector.
|
||||
// Should zero out StringEntry's too.
|
||||
for (i = 0; i < count; i++)
|
||||
table[i] = NULL;
|
||||
|
||||
mem.free(table);
|
||||
table = NULL;
|
||||
}
|
||||
|
||||
struct StringEntry
|
||||
{
|
||||
StringEntry *left;
|
||||
StringEntry *right;
|
||||
hash_t hash;
|
||||
|
||||
StringValue value;
|
||||
|
||||
static StringEntry *alloc(const dchar *s, unsigned len);
|
||||
};
|
||||
|
||||
StringEntry *StringEntry::alloc(const dchar *s, unsigned len)
|
||||
{
|
||||
StringEntry *se;
|
||||
|
||||
se = (StringEntry *) mem.calloc(1,sizeof(StringEntry) - sizeof(Lstring) + Lstring::size(len));
|
||||
se->value.lstring.length = len;
|
||||
se->hash = Dchar::calcHash(s,len);
|
||||
memcpy(se->value.lstring.string, s, len * sizeof(dchar));
|
||||
return se;
|
||||
}
|
||||
|
||||
void **StringTable::search(const dchar *s, unsigned len)
|
||||
{
|
||||
hash_t hash;
|
||||
unsigned u;
|
||||
int cmp;
|
||||
StringEntry **se;
|
||||
|
||||
//printf("StringTable::search(%p,%d)\n",s,len);
|
||||
hash = Dchar::calcHash(s,len);
|
||||
u = hash % tabledim;
|
||||
se = (StringEntry **)&table[u];
|
||||
//printf("\thash = %d, u = %d\n",hash,u);
|
||||
while (*se)
|
||||
{
|
||||
cmp = (*se)->hash - hash;
|
||||
if (cmp == 0)
|
||||
{
|
||||
cmp = (*se)->value.lstring.len() - len;
|
||||
if (cmp == 0)
|
||||
{
|
||||
cmp = Dchar::memcmp(s,(*se)->value.lstring.toDchars(),len);
|
||||
if (cmp == 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (cmp < 0)
|
||||
se = &(*se)->left;
|
||||
else
|
||||
se = &(*se)->right;
|
||||
}
|
||||
//printf("\treturn %p, %p\n",se, (*se));
|
||||
return (void **)se;
|
||||
}
|
||||
|
||||
StringValue *StringTable::lookup(const dchar *s, unsigned len)
|
||||
{ StringEntry *se;
|
||||
|
||||
se = *(StringEntry **)search(s,len);
|
||||
if (se)
|
||||
return &se->value;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
StringValue *StringTable::update(const dchar *s, unsigned len)
|
||||
{ StringEntry **pse;
|
||||
StringEntry *se;
|
||||
|
||||
pse = (StringEntry **)search(s,len);
|
||||
se = *pse;
|
||||
if (!se) // not in table: so create new entry
|
||||
{
|
||||
se = StringEntry::alloc(s, len);
|
||||
*pse = se;
|
||||
}
|
||||
return &se->value;
|
||||
}
|
||||
|
||||
StringValue *StringTable::insert(const dchar *s, unsigned len)
|
||||
{ StringEntry **pse;
|
||||
StringEntry *se;
|
||||
|
||||
pse = (StringEntry **)search(s,len);
|
||||
se = *pse;
|
||||
if (se)
|
||||
return NULL; // error: already in table
|
||||
else
|
||||
{
|
||||
se = StringEntry::alloc(s, len);
|
||||
*pse = se;
|
||||
}
|
||||
return &se->value;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -1,48 +1,48 @@
|
||||
// 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 STRINGTABLE_H
|
||||
#define STRINGTABLE_H
|
||||
|
||||
#if __SC__
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "root.h"
|
||||
#include "dchar.h"
|
||||
#include "lstring.h"
|
||||
|
||||
struct StringValue
|
||||
{
|
||||
union
|
||||
{ int intvalue;
|
||||
void *ptrvalue;
|
||||
dchar *string;
|
||||
};
|
||||
Lstring lstring;
|
||||
};
|
||||
|
||||
struct StringTable : Object
|
||||
{
|
||||
void **table;
|
||||
unsigned count;
|
||||
unsigned tabledim;
|
||||
|
||||
StringTable(unsigned size = 37);
|
||||
~StringTable();
|
||||
|
||||
StringValue *lookup(const dchar *s, unsigned len);
|
||||
StringValue *insert(const dchar *s, unsigned len);
|
||||
StringValue *update(const dchar *s, unsigned len);
|
||||
|
||||
private:
|
||||
void **search(const dchar *s, unsigned len);
|
||||
};
|
||||
|
||||
#endif
|
||||
// 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 STRINGTABLE_H
|
||||
#define STRINGTABLE_H
|
||||
|
||||
#if __SC__
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
#include "root.h"
|
||||
#include "dchar.h"
|
||||
#include "lstring.h"
|
||||
|
||||
struct StringValue
|
||||
{
|
||||
union
|
||||
{ int intvalue;
|
||||
void *ptrvalue;
|
||||
dchar *string;
|
||||
};
|
||||
Lstring lstring;
|
||||
};
|
||||
|
||||
struct StringTable : Object
|
||||
{
|
||||
void **table;
|
||||
unsigned count;
|
||||
unsigned tabledim;
|
||||
|
||||
StringTable(unsigned size = 37);
|
||||
~StringTable();
|
||||
|
||||
StringValue *lookup(const dchar *s, unsigned len);
|
||||
StringValue *insert(const dchar *s, unsigned len);
|
||||
StringValue *update(const dchar *s, unsigned len);
|
||||
|
||||
private:
|
||||
void **search(const dchar *s, unsigned len);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
764
dmd2/scope.c
764
dmd2/scope.c
@@ -1,363 +1,401 @@
|
||||
|
||||
// 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.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "root.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "init.h"
|
||||
#include "identifier.h"
|
||||
#include "attrib.h"
|
||||
#include "dsymbol.h"
|
||||
#include "scope.h"
|
||||
#include "declaration.h"
|
||||
#include "aggregate.h"
|
||||
#include "module.h"
|
||||
#include "id.h"
|
||||
|
||||
Scope *Scope::freelist = NULL;
|
||||
|
||||
void *Scope::operator new(size_t size)
|
||||
{
|
||||
if (freelist)
|
||||
{
|
||||
Scope *s = freelist;
|
||||
freelist = s->enclosing;
|
||||
//printf("freelist %p\n", s);
|
||||
assert(s->flags & SCOPEfree);
|
||||
s->flags &= ~SCOPEfree;
|
||||
return s;
|
||||
}
|
||||
|
||||
void *p = ::operator new(size);
|
||||
//printf("new %p\n", p);
|
||||
return p;
|
||||
}
|
||||
|
||||
Scope::Scope()
|
||||
{ // Create root scope
|
||||
|
||||
//printf("Scope::Scope() %p\n", this);
|
||||
this->module = NULL;
|
||||
this->scopesym = NULL;
|
||||
this->sd = NULL;
|
||||
this->enclosing = NULL;
|
||||
this->parent = NULL;
|
||||
this->sw = NULL;
|
||||
this->enclosingFinally = NULL;
|
||||
this->enclosingScopeExit = NULL;
|
||||
this->tinst = NULL;
|
||||
this->sbreak = NULL;
|
||||
this->scontinue = NULL;
|
||||
this->fes = NULL;
|
||||
this->structalign = global.structalign;
|
||||
this->func = NULL;
|
||||
this->slabel = NULL;
|
||||
this->linkage = LINKd;
|
||||
this->protection = PROTpublic;
|
||||
this->explicitProtection = 0;
|
||||
this->stc = 0;
|
||||
this->offset = 0;
|
||||
this->inunion = 0;
|
||||
this->incontract = 0;
|
||||
this->nofree = 0;
|
||||
this->noctor = 0;
|
||||
this->noaccesscheck = 0;
|
||||
this->mustsemantic = 0;
|
||||
this->intypeof = 0;
|
||||
this->parameterSpecialization = 0;
|
||||
this->callSuper = 0;
|
||||
this->flags = 0;
|
||||
this->anonAgg = NULL;
|
||||
this->lastdc = NULL;
|
||||
this->lastoffset = 0;
|
||||
this->docbuf = NULL;
|
||||
}
|
||||
|
||||
Scope::Scope(Scope *enclosing)
|
||||
{
|
||||
//printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
|
||||
assert(!(enclosing->flags & SCOPEfree));
|
||||
this->module = enclosing->module;
|
||||
this->func = enclosing->func;
|
||||
this->parent = enclosing->parent;
|
||||
this->scopesym = NULL;
|
||||
this->sd = NULL;
|
||||
this->sw = enclosing->sw;
|
||||
this->enclosingFinally = enclosing->enclosingFinally;
|
||||
this->enclosingScopeExit = enclosing->enclosingScopeExit;
|
||||
this->tinst = enclosing->tinst;
|
||||
this->sbreak = enclosing->sbreak;
|
||||
this->scontinue = enclosing->scontinue;
|
||||
this->fes = enclosing->fes;
|
||||
this->structalign = enclosing->structalign;
|
||||
this->enclosing = enclosing;
|
||||
#ifdef DEBUG
|
||||
if (enclosing->enclosing)
|
||||
assert(!(enclosing->enclosing->flags & SCOPEfree));
|
||||
if (this == enclosing->enclosing)
|
||||
{
|
||||
printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing);
|
||||
}
|
||||
assert(this != enclosing->enclosing);
|
||||
#endif
|
||||
this->slabel = NULL;
|
||||
this->linkage = enclosing->linkage;
|
||||
this->protection = enclosing->protection;
|
||||
this->explicitProtection = enclosing->explicitProtection;
|
||||
this->stc = enclosing->stc;
|
||||
this->offset = 0;
|
||||
this->inunion = enclosing->inunion;
|
||||
this->incontract = enclosing->incontract;
|
||||
this->nofree = 0;
|
||||
this->noctor = enclosing->noctor;
|
||||
this->noaccesscheck = enclosing->noaccesscheck;
|
||||
this->mustsemantic = enclosing->mustsemantic;
|
||||
this->intypeof = enclosing->intypeof;
|
||||
this->parameterSpecialization = enclosing->parameterSpecialization;
|
||||
this->callSuper = enclosing->callSuper;
|
||||
this->flags = 0;
|
||||
this->anonAgg = NULL;
|
||||
this->lastdc = NULL;
|
||||
this->lastoffset = 0;
|
||||
this->docbuf = enclosing->docbuf;
|
||||
assert(this != enclosing);
|
||||
}
|
||||
|
||||
Scope *Scope::createGlobal(Module *module)
|
||||
{
|
||||
Scope *sc;
|
||||
|
||||
sc = new Scope();
|
||||
sc->module = module;
|
||||
sc->scopesym = new ScopeDsymbol();
|
||||
sc->scopesym->symtab = new DsymbolTable();
|
||||
|
||||
// Add top level package as member of this global scope
|
||||
Dsymbol *m = module;
|
||||
while (m->parent)
|
||||
m = m->parent;
|
||||
m->addMember(NULL, sc->scopesym, 1);
|
||||
m->parent = NULL; // got changed by addMember()
|
||||
|
||||
// Create the module scope underneath the global scope
|
||||
sc = sc->push(module);
|
||||
sc->parent = module;
|
||||
return sc;
|
||||
}
|
||||
|
||||
Scope *Scope::push()
|
||||
{
|
||||
//printf("Scope::push()\n");
|
||||
Scope *s = new Scope(this);
|
||||
assert(this != s);
|
||||
return s;
|
||||
}
|
||||
|
||||
Scope *Scope::push(ScopeDsymbol *ss)
|
||||
{
|
||||
//printf("Scope::push(%s)\n", ss->toChars());
|
||||
Scope *s = push();
|
||||
s->scopesym = ss;
|
||||
return s;
|
||||
}
|
||||
|
||||
Scope *Scope::pop()
|
||||
{
|
||||
//printf("Scope::pop() %p nofree = %d\n", this, nofree);
|
||||
Scope *enc = enclosing;
|
||||
|
||||
if (enclosing)
|
||||
enclosing->callSuper |= callSuper;
|
||||
|
||||
if (!nofree)
|
||||
{ enclosing = freelist;
|
||||
freelist = this;
|
||||
flags |= SCOPEfree;
|
||||
}
|
||||
|
||||
return enc;
|
||||
}
|
||||
|
||||
void Scope::mergeCallSuper(Loc loc, unsigned cs)
|
||||
{
|
||||
// This does a primitive flow analysis to support the restrictions
|
||||
// regarding when and how constructors can appear.
|
||||
// It merges the results of two paths.
|
||||
// The two paths are callSuper and cs; the result is merged into callSuper.
|
||||
|
||||
if (cs != callSuper)
|
||||
{ int a;
|
||||
int b;
|
||||
|
||||
callSuper |= cs & (CSXany_ctor | CSXlabel);
|
||||
if (cs & CSXreturn)
|
||||
{
|
||||
}
|
||||
else if (callSuper & CSXreturn)
|
||||
{
|
||||
callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
|
||||
}
|
||||
else
|
||||
{
|
||||
a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0;
|
||||
b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
|
||||
if (a != b)
|
||||
error(loc, "one path skips constructor");
|
||||
callSuper |= cs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
|
||||
{ Dsymbol *s;
|
||||
Scope *sc;
|
||||
|
||||
//printf("Scope::search(%p, '%s')\n", this, ident->toChars());
|
||||
if (ident == Id::empty)
|
||||
{
|
||||
// Look for module scope
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
assert(sc != sc->enclosing);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
s = sc->scopesym->isModule();
|
||||
if (s)
|
||||
{
|
||||
//printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
|
||||
if (pscopesym)
|
||||
*pscopesym = sc->scopesym;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
assert(sc != sc->enclosing);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
//printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
|
||||
s = sc->scopesym->search(loc, ident, 0);
|
||||
if (s)
|
||||
{
|
||||
if ((global.params.warnings ||
|
||||
global.params.Dversion > 1) &&
|
||||
ident == Id::length &&
|
||||
sc->scopesym->isArrayScopeSymbol() &&
|
||||
sc->enclosing &&
|
||||
sc->enclosing->search(loc, ident, NULL))
|
||||
{
|
||||
warning(s->loc, "array 'length' hides other 'length' name in outer scope");
|
||||
}
|
||||
|
||||
//printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
|
||||
if (pscopesym)
|
||||
*pscopesym = sc->scopesym;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Dsymbol *Scope::insert(Dsymbol *s)
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
//printf("\tsc = %p\n", sc);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
//printf("\t\tsc->scopesym = %p\n", sc->scopesym);
|
||||
if (!sc->scopesym->symtab)
|
||||
sc->scopesym->symtab = new DsymbolTable();
|
||||
return sc->scopesym->symtab->insert(s);
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Search enclosing scopes for ClassDeclaration.
|
||||
*/
|
||||
|
||||
ClassDeclaration *Scope::getClassScope()
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
ClassDeclaration *cd;
|
||||
|
||||
if (sc->scopesym)
|
||||
{
|
||||
cd = sc->scopesym->isClassDeclaration();
|
||||
if (cd)
|
||||
return cd;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Search enclosing scopes for ClassDeclaration.
|
||||
*/
|
||||
|
||||
AggregateDeclaration *Scope::getStructClassScope()
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
AggregateDeclaration *ad;
|
||||
|
||||
if (sc->scopesym)
|
||||
{
|
||||
ad = sc->scopesym->isClassDeclaration();
|
||||
if (ad)
|
||||
return ad;
|
||||
else
|
||||
{ ad = sc->scopesym->isStructDeclaration();
|
||||
if (ad)
|
||||
return ad;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* For TemplateDeclarations, we need to remember the Scope
|
||||
* where it was declared. So mark the Scope as not
|
||||
* to be free'd.
|
||||
*/
|
||||
|
||||
void Scope::setNoFree()
|
||||
{ Scope *sc;
|
||||
//int i = 0;
|
||||
|
||||
//printf("Scope::setNoFree(this = %p)\n", this);
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
//printf("\tsc = %p\n", sc);
|
||||
sc->nofree = 1;
|
||||
|
||||
assert(!(flags & SCOPEfree));
|
||||
//assert(sc != sc->enclosing);
|
||||
//assert(!sc->enclosing || sc != sc->enclosing->enclosing);
|
||||
//if (++i == 10)
|
||||
//assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
// Copyright (c) 1999-2010 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 <assert.h>
|
||||
|
||||
#include "root.h"
|
||||
#include "speller.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "init.h"
|
||||
#include "identifier.h"
|
||||
#include "attrib.h"
|
||||
#include "dsymbol.h"
|
||||
#include "scope.h"
|
||||
#include "declaration.h"
|
||||
#include "aggregate.h"
|
||||
#include "module.h"
|
||||
#include "id.h"
|
||||
#include "lexer.h"
|
||||
|
||||
Scope *Scope::freelist = NULL;
|
||||
|
||||
void *Scope::operator new(size_t size)
|
||||
{
|
||||
if (freelist)
|
||||
{
|
||||
Scope *s = freelist;
|
||||
freelist = s->enclosing;
|
||||
//printf("freelist %p\n", s);
|
||||
assert(s->flags & SCOPEfree);
|
||||
s->flags &= ~SCOPEfree;
|
||||
return s;
|
||||
}
|
||||
|
||||
void *p = ::operator new(size);
|
||||
//printf("new %p\n", p);
|
||||
return p;
|
||||
}
|
||||
|
||||
Scope::Scope()
|
||||
{ // Create root scope
|
||||
|
||||
//printf("Scope::Scope() %p\n", this);
|
||||
this->module = NULL;
|
||||
this->scopesym = NULL;
|
||||
this->sd = NULL;
|
||||
this->enclosing = NULL;
|
||||
this->parent = NULL;
|
||||
this->sw = NULL;
|
||||
this->enclosingFinally = NULL;
|
||||
this->enclosingScopeExit = NULL;
|
||||
this->tinst = NULL;
|
||||
this->sbreak = NULL;
|
||||
this->scontinue = NULL;
|
||||
this->fes = NULL;
|
||||
this->structalign = global.structalign;
|
||||
this->func = NULL;
|
||||
this->slabel = NULL;
|
||||
this->linkage = LINKd;
|
||||
this->protection = PROTpublic;
|
||||
this->explicitProtection = 0;
|
||||
this->stc = 0;
|
||||
this->offset = 0;
|
||||
this->inunion = 0;
|
||||
this->incontract = 0;
|
||||
this->nofree = 0;
|
||||
this->noctor = 0;
|
||||
this->noaccesscheck = 0;
|
||||
this->mustsemantic = 0;
|
||||
this->intypeof = 0;
|
||||
this->parameterSpecialization = 0;
|
||||
this->callSuper = 0;
|
||||
this->flags = 0;
|
||||
this->anonAgg = NULL;
|
||||
this->lastdc = NULL;
|
||||
this->lastoffset = 0;
|
||||
this->docbuf = NULL;
|
||||
}
|
||||
|
||||
Scope::Scope(Scope *enclosing)
|
||||
{
|
||||
//printf("Scope::Scope(enclosing = %p) %p\n", enclosing, this);
|
||||
assert(!(enclosing->flags & SCOPEfree));
|
||||
this->module = enclosing->module;
|
||||
this->func = enclosing->func;
|
||||
this->parent = enclosing->parent;
|
||||
this->scopesym = NULL;
|
||||
this->sd = NULL;
|
||||
this->sw = enclosing->sw;
|
||||
this->enclosingFinally = enclosing->enclosingFinally;
|
||||
this->enclosingScopeExit = enclosing->enclosingScopeExit;
|
||||
this->tinst = enclosing->tinst;
|
||||
this->sbreak = enclosing->sbreak;
|
||||
this->scontinue = enclosing->scontinue;
|
||||
this->fes = enclosing->fes;
|
||||
this->structalign = enclosing->structalign;
|
||||
this->enclosing = enclosing;
|
||||
#ifdef DEBUG
|
||||
if (enclosing->enclosing)
|
||||
assert(!(enclosing->enclosing->flags & SCOPEfree));
|
||||
if (this == enclosing->enclosing)
|
||||
{
|
||||
printf("this = %p, enclosing = %p, enclosing->enclosing = %p\n", this, enclosing, enclosing->enclosing);
|
||||
}
|
||||
assert(this != enclosing->enclosing);
|
||||
#endif
|
||||
this->slabel = NULL;
|
||||
this->linkage = enclosing->linkage;
|
||||
this->protection = enclosing->protection;
|
||||
this->explicitProtection = enclosing->explicitProtection;
|
||||
this->stc = enclosing->stc;
|
||||
this->offset = 0;
|
||||
this->inunion = enclosing->inunion;
|
||||
this->incontract = enclosing->incontract;
|
||||
this->nofree = 0;
|
||||
this->noctor = enclosing->noctor;
|
||||
this->noaccesscheck = enclosing->noaccesscheck;
|
||||
this->mustsemantic = enclosing->mustsemantic;
|
||||
this->intypeof = enclosing->intypeof;
|
||||
this->parameterSpecialization = enclosing->parameterSpecialization;
|
||||
this->callSuper = enclosing->callSuper;
|
||||
this->flags = 0;
|
||||
this->anonAgg = NULL;
|
||||
this->lastdc = NULL;
|
||||
this->lastoffset = 0;
|
||||
this->docbuf = enclosing->docbuf;
|
||||
assert(this != enclosing);
|
||||
}
|
||||
|
||||
Scope *Scope::createGlobal(Module *module)
|
||||
{
|
||||
Scope *sc;
|
||||
|
||||
sc = new Scope();
|
||||
sc->module = module;
|
||||
sc->scopesym = new ScopeDsymbol();
|
||||
sc->scopesym->symtab = new DsymbolTable();
|
||||
|
||||
// Add top level package as member of this global scope
|
||||
Dsymbol *m = module;
|
||||
while (m->parent)
|
||||
m = m->parent;
|
||||
m->addMember(NULL, sc->scopesym, 1);
|
||||
m->parent = NULL; // got changed by addMember()
|
||||
|
||||
// Create the module scope underneath the global scope
|
||||
sc = sc->push(module);
|
||||
sc->parent = module;
|
||||
return sc;
|
||||
}
|
||||
|
||||
Scope *Scope::push()
|
||||
{
|
||||
//printf("Scope::push()\n");
|
||||
Scope *s = new Scope(this);
|
||||
assert(this != s);
|
||||
return s;
|
||||
}
|
||||
|
||||
Scope *Scope::push(ScopeDsymbol *ss)
|
||||
{
|
||||
//printf("Scope::push(%s)\n", ss->toChars());
|
||||
Scope *s = push();
|
||||
s->scopesym = ss;
|
||||
return s;
|
||||
}
|
||||
|
||||
Scope *Scope::pop()
|
||||
{
|
||||
//printf("Scope::pop() %p nofree = %d\n", this, nofree);
|
||||
Scope *enc = enclosing;
|
||||
|
||||
if (enclosing)
|
||||
enclosing->callSuper |= callSuper;
|
||||
|
||||
if (!nofree)
|
||||
{ enclosing = freelist;
|
||||
freelist = this;
|
||||
flags |= SCOPEfree;
|
||||
}
|
||||
|
||||
return enc;
|
||||
}
|
||||
|
||||
void Scope::mergeCallSuper(Loc loc, unsigned cs)
|
||||
{
|
||||
// This does a primitive flow analysis to support the restrictions
|
||||
// regarding when and how constructors can appear.
|
||||
// It merges the results of two paths.
|
||||
// The two paths are callSuper and cs; the result is merged into callSuper.
|
||||
|
||||
if (cs != callSuper)
|
||||
{ int a;
|
||||
int b;
|
||||
|
||||
callSuper |= cs & (CSXany_ctor | CSXlabel);
|
||||
if (cs & CSXreturn)
|
||||
{
|
||||
}
|
||||
else if (callSuper & CSXreturn)
|
||||
{
|
||||
callSuper = cs | (callSuper & (CSXany_ctor | CSXlabel));
|
||||
}
|
||||
else
|
||||
{
|
||||
a = (cs & (CSXthis_ctor | CSXsuper_ctor)) != 0;
|
||||
b = (callSuper & (CSXthis_ctor | CSXsuper_ctor)) != 0;
|
||||
if (a != b)
|
||||
error(loc, "one path skips constructor");
|
||||
callSuper |= cs;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Dsymbol *Scope::search(Loc loc, Identifier *ident, Dsymbol **pscopesym)
|
||||
{ Dsymbol *s;
|
||||
Scope *sc;
|
||||
|
||||
//printf("Scope::search(%p, '%s')\n", this, ident->toChars());
|
||||
if (ident == Id::empty)
|
||||
{
|
||||
// Look for module scope
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
assert(sc != sc->enclosing);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
s = sc->scopesym->isModule();
|
||||
if (s)
|
||||
{
|
||||
//printf("\tfound %s.%s\n", s->parent ? s->parent->toChars() : "", s->toChars());
|
||||
if (pscopesym)
|
||||
*pscopesym = sc->scopesym;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
assert(sc != sc->enclosing);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
//printf("\tlooking in scopesym '%s', kind = '%s'\n", sc->scopesym->toChars(), sc->scopesym->kind());
|
||||
s = sc->scopesym->search(loc, ident, 0);
|
||||
if (s)
|
||||
{
|
||||
if ((global.params.warnings ||
|
||||
global.params.Dversion > 1) &&
|
||||
ident == Id::length &&
|
||||
sc->scopesym->isArrayScopeSymbol() &&
|
||||
sc->enclosing &&
|
||||
sc->enclosing->search(loc, ident, NULL))
|
||||
{
|
||||
warning(s->loc, "array 'length' hides other 'length' name in outer scope");
|
||||
}
|
||||
|
||||
//printf("\tfound %s.%s, kind = '%s'\n", s->parent ? s->parent->toChars() : "", s->toChars(), s->kind());
|
||||
if (pscopesym)
|
||||
*pscopesym = sc->scopesym;
|
||||
return s;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Dsymbol *Scope::insert(Dsymbol *s)
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
//printf("\tsc = %p\n", sc);
|
||||
if (sc->scopesym)
|
||||
{
|
||||
//printf("\t\tsc->scopesym = %p\n", sc->scopesym);
|
||||
if (!sc->scopesym->symtab)
|
||||
sc->scopesym->symtab = new DsymbolTable();
|
||||
return sc->scopesym->symtabInsert(s);
|
||||
}
|
||||
}
|
||||
assert(0);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Search enclosing scopes for ClassDeclaration.
|
||||
*/
|
||||
|
||||
ClassDeclaration *Scope::getClassScope()
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
ClassDeclaration *cd;
|
||||
|
||||
if (sc->scopesym)
|
||||
{
|
||||
cd = sc->scopesym->isClassDeclaration();
|
||||
if (cd)
|
||||
return cd;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Search enclosing scopes for ClassDeclaration.
|
||||
*/
|
||||
|
||||
AggregateDeclaration *Scope::getStructClassScope()
|
||||
{ Scope *sc;
|
||||
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
AggregateDeclaration *ad;
|
||||
|
||||
if (sc->scopesym)
|
||||
{
|
||||
ad = sc->scopesym->isClassDeclaration();
|
||||
if (ad)
|
||||
return ad;
|
||||
else
|
||||
{ ad = sc->scopesym->isStructDeclaration();
|
||||
if (ad)
|
||||
return ad;
|
||||
}
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*******************************************
|
||||
* For TemplateDeclarations, we need to remember the Scope
|
||||
* where it was declared. So mark the Scope as not
|
||||
* to be free'd.
|
||||
*/
|
||||
|
||||
void Scope::setNoFree()
|
||||
{ Scope *sc;
|
||||
//int i = 0;
|
||||
|
||||
//printf("Scope::setNoFree(this = %p)\n", this);
|
||||
for (sc = this; sc; sc = sc->enclosing)
|
||||
{
|
||||
//printf("\tsc = %p\n", sc);
|
||||
sc->nofree = 1;
|
||||
|
||||
assert(!(flags & SCOPEfree));
|
||||
//assert(sc != sc->enclosing);
|
||||
//assert(!sc->enclosing || sc != sc->enclosing->enclosing);
|
||||
//if (++i == 10)
|
||||
//assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/************************************************
|
||||
* Given the failed search attempt, try to find
|
||||
* one with a close spelling.
|
||||
*/
|
||||
|
||||
void *scope_search_fp(void *arg, const char *seed)
|
||||
{
|
||||
//printf("scope_search_fp('%s')\n", seed);
|
||||
|
||||
/* If not in the lexer's string table, it certainly isn't in the symbol table.
|
||||
* Doing this first is a lot faster.
|
||||
*/
|
||||
size_t len = strlen(seed);
|
||||
if (!len)
|
||||
return NULL;
|
||||
StringValue *sv = Lexer::stringtable.lookup(seed, len);
|
||||
if (!sv)
|
||||
return NULL;
|
||||
Identifier *id = (Identifier *)sv->ptrvalue;
|
||||
assert(id);
|
||||
|
||||
Scope *sc = (Scope *)arg;
|
||||
Module::clearCache();
|
||||
Dsymbol *s = sc->search(0, id, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
Dsymbol *Scope::search_correct(Identifier *ident)
|
||||
{
|
||||
if (global.gag)
|
||||
return NULL; // don't do it for speculative compiles; too time consuming
|
||||
|
||||
return (Dsymbol *)speller(ident->toChars(), &scope_search_fp, this, idchars);
|
||||
}
|
||||
|
||||
253
dmd2/scope.h
253
dmd2/scope.h
@@ -1,126 +1,127 @@
|
||||
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_SCOPE_H
|
||||
#define DMD_SCOPE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
struct Dsymbol;
|
||||
struct ScopeDsymbol;
|
||||
struct Array;
|
||||
struct Identifier;
|
||||
struct Module;
|
||||
struct Statement;
|
||||
struct SwitchStatement;
|
||||
struct TryFinallyStatement;
|
||||
struct LabelStatement;
|
||||
struct ForeachStatement;
|
||||
struct ClassDeclaration;
|
||||
struct AggregateDeclaration;
|
||||
struct AnonymousAggregateDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct DocComment;
|
||||
struct TemplateInstance;
|
||||
|
||||
#if IN_LLVM
|
||||
struct EnclosingHandler;
|
||||
struct AnonDeclaration;
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
// Requires a full definition for PROT and LINK
|
||||
#include "dsymbol.h" // PROT
|
||||
#include "mars.h" // LINK
|
||||
#else
|
||||
enum LINK;
|
||||
enum PROT;
|
||||
#endif
|
||||
|
||||
struct Scope
|
||||
{
|
||||
Scope *enclosing; // enclosing Scope
|
||||
|
||||
Module *module; // Root module
|
||||
ScopeDsymbol *scopesym; // current symbol
|
||||
ScopeDsymbol *sd; // if in static if, and declaring new symbols,
|
||||
// sd gets the addMember()
|
||||
FuncDeclaration *func; // function we are in
|
||||
Dsymbol *parent; // parent to use
|
||||
LabelStatement *slabel; // enclosing labelled statement
|
||||
SwitchStatement *sw; // enclosing switch statement
|
||||
TryFinallyStatement *enclosingFinally; // enclosing try finally statement; set inside its finally block
|
||||
TemplateInstance *tinst; // enclosing template instance
|
||||
Statement *enclosingScopeExit; // enclosing statement that wants to do something on scope exit
|
||||
Statement *sbreak; // enclosing statement that supports "break"
|
||||
Statement *scontinue; // enclosing statement that supports "continue"
|
||||
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
|
||||
unsigned offset; // next offset to use in aggregate
|
||||
int inunion; // we're processing members of a union
|
||||
int incontract; // we're inside contract code
|
||||
int nofree; // set if shouldn't free it
|
||||
int noctor; // set if constructor calls aren't allowed
|
||||
int intypeof; // in typeof(exp)
|
||||
int parameterSpecialization; // if in template parameter specialization
|
||||
int noaccesscheck; // don't do access checks
|
||||
int mustsemantic; // cannot defer semantic()
|
||||
|
||||
unsigned callSuper; // primitive flow analysis for constructors
|
||||
#define CSXthis_ctor 1 // called this()
|
||||
#define CSXsuper_ctor 2 // called super()
|
||||
#define CSXthis 4 // referenced this
|
||||
#define CSXsuper 8 // referenced super
|
||||
#define CSXlabel 0x10 // seen a label
|
||||
#define CSXreturn 0x20 // seen a return statement
|
||||
#define CSXany_ctor 0x40 // either this() or super() was called
|
||||
|
||||
unsigned structalign; // alignment for struct members
|
||||
enum LINK linkage; // linkage for external functions
|
||||
|
||||
enum PROT protection; // protection for class members
|
||||
int explicitProtection; // set if in an explicit protection attribute
|
||||
|
||||
unsigned stc; // storage class
|
||||
|
||||
unsigned flags;
|
||||
#define SCOPEctor 1 // constructor type
|
||||
#define SCOPEstaticif 2 // inside static if
|
||||
#define SCOPEfree 4 // is on free list
|
||||
|
||||
AnonymousAggregateDeclaration *anonAgg; // for temporary analysis
|
||||
|
||||
DocComment *lastdc; // documentation comment for last symbol at this scope
|
||||
unsigned lastoffset; // offset in docbuf of where to insert next dec
|
||||
OutBuffer *docbuf; // buffer for documentation output
|
||||
|
||||
static Scope *freelist;
|
||||
static void *operator new(size_t sz);
|
||||
static Scope *createGlobal(Module *module);
|
||||
|
||||
Scope();
|
||||
Scope(Module *module);
|
||||
Scope(Scope *enclosing);
|
||||
|
||||
Scope *push();
|
||||
Scope *push(ScopeDsymbol *ss);
|
||||
Scope *pop();
|
||||
|
||||
void mergeCallSuper(Loc loc, unsigned cs);
|
||||
|
||||
Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym);
|
||||
Dsymbol *insert(Dsymbol *s);
|
||||
|
||||
ClassDeclaration *getClassScope();
|
||||
AggregateDeclaration *getStructClassScope();
|
||||
void setNoFree();
|
||||
};
|
||||
|
||||
#endif /* DMD_SCOPE_H */
|
||||
|
||||
// Copyright (c) 1999-2009 by Digital Mars
|
||||
// All Rights Reserved
|
||||
// written by Walter Bright
|
||||
// http://www.digitalmars.com
|
||||
// License for redistribution is by either the Artistic License
|
||||
// in artistic.txt, or the GNU General Public License in gnu.txt.
|
||||
// See the included readme.txt for details.
|
||||
|
||||
#ifndef DMD_SCOPE_H
|
||||
#define DMD_SCOPE_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif
|
||||
|
||||
struct Dsymbol;
|
||||
struct ScopeDsymbol;
|
||||
struct Array;
|
||||
struct Identifier;
|
||||
struct Module;
|
||||
struct Statement;
|
||||
struct SwitchStatement;
|
||||
struct TryFinallyStatement;
|
||||
struct LabelStatement;
|
||||
struct ForeachStatement;
|
||||
struct ClassDeclaration;
|
||||
struct AggregateDeclaration;
|
||||
struct AnonymousAggregateDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct DocComment;
|
||||
struct TemplateInstance;
|
||||
|
||||
#if IN_LLVM
|
||||
struct EnclosingHandler;
|
||||
struct AnonDeclaration;
|
||||
#endif
|
||||
|
||||
#if __GNUC__
|
||||
// Requires a full definition for PROT and LINK
|
||||
#include "dsymbol.h" // PROT
|
||||
#include "mars.h" // LINK
|
||||
#else
|
||||
enum LINK;
|
||||
enum PROT;
|
||||
#endif
|
||||
|
||||
struct Scope
|
||||
{
|
||||
Scope *enclosing; // enclosing Scope
|
||||
|
||||
Module *module; // Root module
|
||||
ScopeDsymbol *scopesym; // current symbol
|
||||
ScopeDsymbol *sd; // if in static if, and declaring new symbols,
|
||||
// sd gets the addMember()
|
||||
FuncDeclaration *func; // function we are in
|
||||
Dsymbol *parent; // parent to use
|
||||
LabelStatement *slabel; // enclosing labelled statement
|
||||
SwitchStatement *sw; // enclosing switch statement
|
||||
TryFinallyStatement *enclosingFinally; // enclosing try finally statement; set inside its finally block
|
||||
TemplateInstance *tinst; // enclosing template instance
|
||||
Statement *enclosingScopeExit; // enclosing statement that wants to do something on scope exit
|
||||
Statement *sbreak; // enclosing statement that supports "break"
|
||||
Statement *scontinue; // enclosing statement that supports "continue"
|
||||
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
|
||||
unsigned offset; // next offset to use in aggregate
|
||||
int inunion; // we're processing members of a union
|
||||
int incontract; // we're inside contract code
|
||||
int nofree; // set if shouldn't free it
|
||||
int noctor; // set if constructor calls aren't allowed
|
||||
int intypeof; // in typeof(exp)
|
||||
int parameterSpecialization; // if in template parameter specialization
|
||||
int noaccesscheck; // don't do access checks
|
||||
int mustsemantic; // cannot defer semantic()
|
||||
|
||||
unsigned callSuper; // primitive flow analysis for constructors
|
||||
#define CSXthis_ctor 1 // called this()
|
||||
#define CSXsuper_ctor 2 // called super()
|
||||
#define CSXthis 4 // referenced this
|
||||
#define CSXsuper 8 // referenced super
|
||||
#define CSXlabel 0x10 // seen a label
|
||||
#define CSXreturn 0x20 // seen a return statement
|
||||
#define CSXany_ctor 0x40 // either this() or super() was called
|
||||
|
||||
unsigned structalign; // alignment for struct members
|
||||
enum LINK linkage; // linkage for external functions
|
||||
|
||||
enum PROT protection; // protection for class members
|
||||
int explicitProtection; // set if in an explicit protection attribute
|
||||
|
||||
StorageClass stc; // storage class
|
||||
|
||||
unsigned flags;
|
||||
#define SCOPEctor 1 // constructor type
|
||||
#define SCOPEstaticif 2 // inside static if
|
||||
#define SCOPEfree 4 // is on free list
|
||||
|
||||
AnonymousAggregateDeclaration *anonAgg; // for temporary analysis
|
||||
|
||||
DocComment *lastdc; // documentation comment for last symbol at this scope
|
||||
unsigned lastoffset; // offset in docbuf of where to insert next dec
|
||||
OutBuffer *docbuf; // buffer for documentation output
|
||||
|
||||
static Scope *freelist;
|
||||
static void *operator new(size_t sz);
|
||||
static Scope *createGlobal(Module *module);
|
||||
|
||||
Scope();
|
||||
Scope(Module *module);
|
||||
Scope(Scope *enclosing);
|
||||
|
||||
Scope *push();
|
||||
Scope *push(ScopeDsymbol *ss);
|
||||
Scope *pop();
|
||||
|
||||
void mergeCallSuper(Loc loc, unsigned cs);
|
||||
|
||||
Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym);
|
||||
Dsymbol *search_correct(Identifier *ident);
|
||||
Dsymbol *insert(Dsymbol *s);
|
||||
|
||||
ClassDeclaration *getClassScope();
|
||||
AggregateDeclaration *getStructClassScope();
|
||||
void setNoFree();
|
||||
};
|
||||
|
||||
#endif /* DMD_SCOPE_H */
|
||||
|
||||
9554
dmd2/statement.c
9554
dmd2/statement.c
File diff suppressed because it is too large
Load Diff
1915
dmd2/statement.h
1915
dmd2/statement.h
File diff suppressed because it is too large
Load Diff
@@ -1,120 +1,116 @@
|
||||
|
||||
// Copyright (c) 1999-2007 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 <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "dsymbol.h"
|
||||
#include "staticassert.h"
|
||||
#include "expression.h"
|
||||
#include "id.h"
|
||||
#include "hdrgen.h"
|
||||
#include "scope.h"
|
||||
#include "template.h"
|
||||
|
||||
|
||||
/********************************* AttribDeclaration ****************************/
|
||||
|
||||
StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg)
|
||||
: Dsymbol(Id::empty)
|
||||
{
|
||||
this->loc = loc;
|
||||
this->exp = exp;
|
||||
this->msg = msg;
|
||||
}
|
||||
|
||||
Dsymbol *StaticAssert::syntaxCopy(Dsymbol *s)
|
||||
{
|
||||
StaticAssert *sa;
|
||||
|
||||
assert(!s);
|
||||
sa = new StaticAssert(loc, exp->syntaxCopy(), msg ? msg->syntaxCopy() : NULL);
|
||||
return sa;
|
||||
}
|
||||
|
||||
int StaticAssert::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
|
||||
{
|
||||
return 0; // we didn't add anything
|
||||
}
|
||||
|
||||
void StaticAssert::semantic(Scope *sc)
|
||||
{
|
||||
}
|
||||
|
||||
#include "scope.h"
|
||||
#include "template.h"
|
||||
#include "declaration.h"
|
||||
|
||||
void StaticAssert::semantic2(Scope *sc)
|
||||
{
|
||||
Expression *e;
|
||||
|
||||
//printf("StaticAssert::semantic2() %s\n", toChars());
|
||||
e = exp->semantic(sc);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (e->isBool(FALSE))
|
||||
{
|
||||
if (msg)
|
||||
{ HdrGenState hgs;
|
||||
OutBuffer buf;
|
||||
|
||||
msg = msg->semantic(sc);
|
||||
msg = msg->optimize(WANTvalue | WANTinterpret);
|
||||
hgs.console = 1;
|
||||
msg->toCBuffer(&buf, &hgs);
|
||||
error("%s", buf.toChars());
|
||||
}
|
||||
else
|
||||
error("(%s) is false", exp->toChars());
|
||||
if(sc->tinst)
|
||||
sc->tinst->printInstantiationTrace();
|
||||
if (!global.gag) {
|
||||
fatal();
|
||||
}
|
||||
}
|
||||
else if (!e->isBool(TRUE))
|
||||
{
|
||||
error("(%s) is not evaluatable at compile time", exp->toChars());
|
||||
}
|
||||
}
|
||||
|
||||
int StaticAssert::oneMember(Dsymbol **ps)
|
||||
{
|
||||
//printf("StaticAssert::oneMember())\n");
|
||||
*ps = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void StaticAssert::inlineScan()
|
||||
{
|
||||
}
|
||||
|
||||
void StaticAssert::toObjFile(int multiobj)
|
||||
{
|
||||
}
|
||||
|
||||
const char *StaticAssert::kind()
|
||||
{
|
||||
return "static assert";
|
||||
}
|
||||
|
||||
void StaticAssert::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
buf->writestring(kind());
|
||||
buf->writeByte('(');
|
||||
exp->toCBuffer(buf, hgs);
|
||||
if (msg)
|
||||
{
|
||||
buf->writeByte(',');
|
||||
msg->toCBuffer(buf, hgs);
|
||||
}
|
||||
buf->writestring(");");
|
||||
buf->writenl();
|
||||
}
|
||||
|
||||
// Copyright (c) 1999-2007 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 <string.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "dsymbol.h"
|
||||
#include "staticassert.h"
|
||||
#include "expression.h"
|
||||
#include "id.h"
|
||||
#include "hdrgen.h"
|
||||
#include "scope.h"
|
||||
#include "template.h"
|
||||
#include "declaration.h"
|
||||
|
||||
|
||||
/********************************* AttribDeclaration ****************************/
|
||||
|
||||
StaticAssert::StaticAssert(Loc loc, Expression *exp, Expression *msg)
|
||||
: Dsymbol(Id::empty)
|
||||
{
|
||||
this->loc = loc;
|
||||
this->exp = exp;
|
||||
this->msg = msg;
|
||||
}
|
||||
|
||||
Dsymbol *StaticAssert::syntaxCopy(Dsymbol *s)
|
||||
{
|
||||
StaticAssert *sa;
|
||||
|
||||
assert(!s);
|
||||
sa = new StaticAssert(loc, exp->syntaxCopy(), msg ? msg->syntaxCopy() : NULL);
|
||||
return sa;
|
||||
}
|
||||
|
||||
int StaticAssert::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
|
||||
{
|
||||
return 0; // we didn't add anything
|
||||
}
|
||||
|
||||
void StaticAssert::semantic(Scope *sc)
|
||||
{
|
||||
}
|
||||
|
||||
void StaticAssert::semantic2(Scope *sc)
|
||||
{
|
||||
Expression *e;
|
||||
|
||||
//printf("StaticAssert::semantic2() %s\n", toChars());
|
||||
e = exp->semantic(sc);
|
||||
e = e->optimize(WANTvalue | WANTinterpret);
|
||||
if (e->isBool(FALSE))
|
||||
{
|
||||
if (msg)
|
||||
{ HdrGenState hgs;
|
||||
OutBuffer buf;
|
||||
|
||||
msg = msg->semantic(sc);
|
||||
msg = msg->optimize(WANTvalue | WANTinterpret);
|
||||
hgs.console = 1;
|
||||
msg->toCBuffer(&buf, &hgs);
|
||||
error("%s", buf.toChars());
|
||||
}
|
||||
else
|
||||
error("(%s) is false", exp->toChars());
|
||||
if (sc->tinst)
|
||||
sc->tinst->printInstantiationTrace();
|
||||
if (!global.gag)
|
||||
fatal();
|
||||
}
|
||||
else if (!e->isBool(TRUE))
|
||||
{
|
||||
error("(%s) is not evaluatable at compile time", exp->toChars());
|
||||
}
|
||||
}
|
||||
|
||||
int StaticAssert::oneMember(Dsymbol **ps)
|
||||
{
|
||||
//printf("StaticAssert::oneMember())\n");
|
||||
*ps = NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void StaticAssert::inlineScan()
|
||||
{
|
||||
}
|
||||
|
||||
void StaticAssert::toObjFile(int multiobj)
|
||||
{
|
||||
}
|
||||
|
||||
const char *StaticAssert::kind()
|
||||
{
|
||||
return "static assert";
|
||||
}
|
||||
|
||||
void StaticAssert::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
|
||||
{
|
||||
buf->writestring(kind());
|
||||
buf->writeByte('(');
|
||||
exp->toCBuffer(buf, hgs);
|
||||
if (msg)
|
||||
{
|
||||
buf->writeByte(',');
|
||||
msg->toCBuffer(buf, hgs);
|
||||
}
|
||||
buf->writestring(");");
|
||||
buf->writenl();
|
||||
}
|
||||
|
||||
@@ -1,43 +1,43 @@
|
||||
|
||||
// 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.
|
||||
|
||||
#ifndef DMD_STATICASSERT_H
|
||||
#define DMD_STATICASSERT_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "dsymbol.h"
|
||||
|
||||
struct Expression;
|
||||
#ifdef _DH
|
||||
struct HdrGenState;
|
||||
#endif
|
||||
|
||||
struct StaticAssert : Dsymbol
|
||||
{
|
||||
Expression *exp;
|
||||
Expression *msg;
|
||||
|
||||
StaticAssert(Loc loc, Expression *exp, Expression *msg);
|
||||
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
int addMember(Scope *sc, ScopeDsymbol *sd, int memnum);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
void inlineScan();
|
||||
int oneMember(Dsymbol **ps);
|
||||
void toObjFile(int multiobj);
|
||||
const char *kind();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
// 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.
|
||||
|
||||
#ifndef DMD_STATICASSERT_H
|
||||
#define DMD_STATICASSERT_H
|
||||
|
||||
#ifdef __DMC__
|
||||
#pragma once
|
||||
#endif /* __DMC__ */
|
||||
|
||||
#include "dsymbol.h"
|
||||
|
||||
struct Expression;
|
||||
#ifdef _DH
|
||||
struct HdrGenState;
|
||||
#endif
|
||||
|
||||
struct StaticAssert : Dsymbol
|
||||
{
|
||||
Expression *exp;
|
||||
Expression *msg;
|
||||
|
||||
StaticAssert(Loc loc, Expression *exp, Expression *msg);
|
||||
|
||||
Dsymbol *syntaxCopy(Dsymbol *s);
|
||||
int addMember(Scope *sc, ScopeDsymbol *sd, int memnum);
|
||||
void semantic(Scope *sc);
|
||||
void semantic2(Scope *sc);
|
||||
void inlineScan();
|
||||
int oneMember(Dsymbol **ps);
|
||||
void toObjFile(int multiobj);
|
||||
const char *kind();
|
||||
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
1274
dmd2/struct.c
1274
dmd2/struct.c
File diff suppressed because it is too large
Load Diff
5186
dmd2/template.c
5186
dmd2/template.c
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user