mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-16 04:43:14 +01:00
Merged DMD 1.037 frontend
This commit is contained in:
@@ -615,6 +615,7 @@ void AnonDeclaration::semantic(Scope *sc)
|
||||
sc->flags = 0;
|
||||
aad.structalign = sc->structalign;
|
||||
aad.parent = ad;
|
||||
|
||||
for (unsigned i = 0; i < decl->dim; i++)
|
||||
{
|
||||
Dsymbol *s = (Dsymbol *)decl->data[i];
|
||||
|
||||
25
dmd/cast.c
25
dmd/cast.c
@@ -33,9 +33,10 @@ Expression *Expression::implicitCastTo(Scope *sc, Type *t)
|
||||
{
|
||||
//printf("implicitCastTo(%s) => %s\n", type->toChars(), t->toChars());
|
||||
if (implicitConvTo(t))
|
||||
{
|
||||
{ TY tyfrom = type->toBasetype()->ty;
|
||||
TY tyto = t->toBasetype()->ty;
|
||||
if (global.params.warnings &&
|
||||
Type::impcnvWarn[type->toBasetype()->ty][t->toBasetype()->ty] &&
|
||||
Type::impcnvWarn[tyfrom][tyto] &&
|
||||
op != TOKint64)
|
||||
{
|
||||
Expression *e = optimize(WANTflags | WANTvalue);
|
||||
@@ -43,8 +44,24 @@ Expression *Expression::implicitCastTo(Scope *sc, Type *t)
|
||||
if (e->op == TOKint64)
|
||||
return e->implicitCastTo(sc, t);
|
||||
|
||||
warning("%s: implicit conversion of expression (%s) of type %s to %s can cause loss of data",
|
||||
loc.toChars(), toChars(), type->toChars(), t->toChars());
|
||||
if (tyfrom == Tint32 &&
|
||||
(op == TOKadd || op == TOKmin ||
|
||||
op == TOKand || op == TOKor || op == TOKxor)
|
||||
)
|
||||
{
|
||||
/* This is really only a semi-kludge fix,
|
||||
* we really should look at the operands of op
|
||||
* and see if they are narrower types.
|
||||
* For example, b=b|b and b=b|7 and s=b+b should be allowed,
|
||||
* but b=b|i should be an error.
|
||||
*/
|
||||
;
|
||||
}
|
||||
else
|
||||
{
|
||||
warning("%s: implicit conversion of expression (%s) of type %s to %s can cause loss of data",
|
||||
loc.toChars(), toChars(), type->toChars(), t->toChars());
|
||||
}
|
||||
}
|
||||
#if DMDV2
|
||||
if (match == MATCHconst && t == type->constOf())
|
||||
|
||||
@@ -623,6 +623,7 @@ struct FuncDeclaration : Declaration
|
||||
virtual int isNested();
|
||||
int needThis();
|
||||
virtual int isVirtual();
|
||||
virtual int isFinal();
|
||||
virtual int addPreInvariant();
|
||||
virtual int addPostInvariant();
|
||||
Expression *interpret(InterState *istate, Expressions *arguments);
|
||||
|
||||
@@ -5067,10 +5067,14 @@ Expression *DotIdExp::semantic(Scope *sc)
|
||||
|
||||
if (eright->op == TOKimport) // also used for template alias's
|
||||
{
|
||||
Dsymbol *s;
|
||||
ScopeExp *ie = (ScopeExp *)eright;
|
||||
|
||||
s = ie->sds->search(loc, ident, 0);
|
||||
/* Disable access to another module's private imports.
|
||||
* The check for 'is sds our current module' is because
|
||||
* the current module should have access to its own imports.
|
||||
*/
|
||||
Dsymbol *s = ie->sds->search(loc, ident,
|
||||
(ie->sds->isModule() && ie->sds != sc->module) ? 1 : 0);
|
||||
if (s)
|
||||
{
|
||||
s = s->toAlias();
|
||||
|
||||
24
dmd/func.c
24
dmd/func.c
@@ -1965,6 +1965,23 @@ int FuncDeclaration::isVirtual()
|
||||
toParent()->isClassDeclaration();
|
||||
}
|
||||
|
||||
int FuncDeclaration::isFinal()
|
||||
{
|
||||
ClassDeclaration *cd;
|
||||
#if 0
|
||||
printf("FuncDeclaration::isFinal(%s)\n", toChars());
|
||||
printf("%p %d %d %d %d\n", isMember(), isStatic(), protection == PROTprivate, isCtorDeclaration(), linkage != LINKd);
|
||||
printf("result is %d\n",
|
||||
isMember() &&
|
||||
!(isStatic() || protection == PROTprivate || protection == PROTpackage) &&
|
||||
(cd = toParent()->isClassDeclaration()) != NULL &&
|
||||
cd->storage_class & STCfinal);
|
||||
#endif
|
||||
return isMember() &&
|
||||
(Declaration::isFinal() ||
|
||||
((cd = toParent()->isClassDeclaration()) != NULL && cd->storage_class & STCfinal));
|
||||
}
|
||||
|
||||
int FuncDeclaration::isAbstract()
|
||||
{
|
||||
return storage_class & STCabstract;
|
||||
@@ -2708,10 +2725,11 @@ void UnitTestDeclaration::semantic(Scope *sc)
|
||||
{
|
||||
if (global.params.useUnitTests)
|
||||
{
|
||||
Type *tret;
|
||||
|
||||
type = new TypeFunction(NULL, Type::tvoid, FALSE, LINKd);
|
||||
FuncDeclaration::semantic(sc);
|
||||
Scope *sc2 = sc->push();
|
||||
sc2->linkage = LINKd;
|
||||
FuncDeclaration::semantic(sc2);
|
||||
sc2->pop();
|
||||
}
|
||||
|
||||
// We're going to need ModuleInfo even if the unit tests are not
|
||||
|
||||
537
dmd/import.c
537
dmd/import.c
@@ -1,275 +1,262 @@
|
||||
|
||||
// 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 <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"
|
||||
|
||||
/********************************* Import ****************************/
|
||||
|
||||
Import::Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
|
||||
int isstatic)
|
||||
: Dsymbol(id)
|
||||
{
|
||||
this->loc = loc;
|
||||
this->packages = packages;
|
||||
this->id = id;
|
||||
this->aliasId = aliasId;
|
||||
this->isstatic = isstatic;
|
||||
protection = PROTundefined;
|
||||
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";
|
||||
}
|
||||
|
||||
enum PROT Import::prot()
|
||||
{
|
||||
return protection;
|
||||
}
|
||||
|
||||
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 (s->isModule())
|
||||
mod = (Module *)s;
|
||||
else
|
||||
error("package and module have the same name");
|
||||
}
|
||||
|
||||
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;
|
||||
mod->semantic();
|
||||
|
||||
//printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
/* Default to private importing
|
||||
*/
|
||||
protection = sc->protection;
|
||||
if (!sc->explicitProtection)
|
||||
protection = PROTprivate;
|
||||
|
||||
if (!isstatic && !aliasId && !names.dim)
|
||||
{
|
||||
sc->scopesym->importScope(mod, protection);
|
||||
}
|
||||
|
||||
// Modules need a list of each imported module
|
||||
sc->module->aimports.push(mod);
|
||||
|
||||
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->semantic(sc);
|
||||
ad->protection = protection;
|
||||
}
|
||||
sc = sc->pop();
|
||||
}
|
||||
//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;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
#if 1
|
||||
TypeIdentifier *tname = new TypeIdentifier(loc, name);
|
||||
#else
|
||||
TypeIdentifier *tname = new TypeIdentifier(loc, NULL);
|
||||
if (packages)
|
||||
{
|
||||
for (size_t j = 0; j < packages->dim; j++)
|
||||
{ Identifier *pid = (Identifier *)packages->data[j];
|
||||
|
||||
if (!tname->ident)
|
||||
tname->ident = pid;
|
||||
else
|
||||
tname->addIdent(pid);
|
||||
}
|
||||
}
|
||||
if (!tname->ident)
|
||||
tname->ident = id;
|
||||
else
|
||||
tname->addIdent(id);
|
||||
tname->addIdent(name);
|
||||
#endif
|
||||
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);
|
||||
|
||||
// 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-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 <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"
|
||||
|
||||
/********************************* Import ****************************/
|
||||
|
||||
Import::Import(Loc loc, Array *packages, Identifier *id, Identifier *aliasId,
|
||||
int isstatic)
|
||||
: Dsymbol(id)
|
||||
{
|
||||
this->loc = loc;
|
||||
this->packages = packages;
|
||||
this->id = id;
|
||||
this->aliasId = aliasId;
|
||||
this->isstatic = isstatic;
|
||||
protection = PROTundefined;
|
||||
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";
|
||||
}
|
||||
|
||||
enum PROT Import::prot()
|
||||
{
|
||||
return protection;
|
||||
}
|
||||
|
||||
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 (s->isModule())
|
||||
mod = (Module *)s;
|
||||
else
|
||||
error("package and module have the same name");
|
||||
}
|
||||
|
||||
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;
|
||||
mod->semantic();
|
||||
|
||||
//printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
|
||||
}
|
||||
|
||||
|
||||
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
|
||||
|
||||
/* Default to private importing
|
||||
*/
|
||||
protection = sc->protection;
|
||||
if (!sc->explicitProtection)
|
||||
protection = PROTprivate;
|
||||
|
||||
if (!isstatic && !aliasId && !names.dim)
|
||||
{
|
||||
sc->scopesym->importScope(mod, protection);
|
||||
}
|
||||
|
||||
// Modules need a list of each imported module
|
||||
sc->module->aimports.push(mod);
|
||||
|
||||
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->semantic(sc);
|
||||
ad->protection = protection;
|
||||
}
|
||||
sc = sc->pop();
|
||||
}
|
||||
//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);
|
||||
|
||||
// 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();
|
||||
}
|
||||
|
||||
|
||||
28
dmd/lexer.c
28
dmd/lexer.c
@@ -2656,10 +2656,13 @@ unsigned Lexer::decodeUTF()
|
||||
|
||||
void Lexer::getDocComment(Token *t, unsigned lineComment)
|
||||
{
|
||||
OutBuffer buf;
|
||||
/* ct tells us which kind of comment it is: '/', '*', or '+'
|
||||
*/
|
||||
unsigned char ct = t->ptr[2];
|
||||
|
||||
/* Start of comment text skips over / * *, / + +, or / / /
|
||||
*/
|
||||
unsigned char *q = t->ptr + 3; // start of comment text
|
||||
int linestart = 0;
|
||||
|
||||
unsigned char *qend = p;
|
||||
if (ct == '*' || ct == '+')
|
||||
@@ -2684,6 +2687,12 @@ void Lexer::getDocComment(Token *t, unsigned lineComment)
|
||||
}
|
||||
}
|
||||
|
||||
/* Comment is now [q .. qend].
|
||||
* Canonicalize it into buf[].
|
||||
*/
|
||||
OutBuffer buf;
|
||||
int linestart = 0;
|
||||
|
||||
for (; q < qend; q++)
|
||||
{
|
||||
unsigned char c = *q;
|
||||
@@ -2760,11 +2769,14 @@ void Lexer::getDocComment(Token *t, unsigned lineComment)
|
||||
}
|
||||
|
||||
/********************************************
|
||||
* Combine two document comments into one.
|
||||
* Combine two document comments into one,
|
||||
* separated by a newline.
|
||||
*/
|
||||
|
||||
unsigned char *Lexer::combineComments(unsigned char *c1, unsigned char *c2)
|
||||
{
|
||||
//printf("Lexer::combineComments('%s', '%s')\n", c1, c2);
|
||||
|
||||
unsigned char *c = c2;
|
||||
|
||||
if (c1)
|
||||
@@ -2775,9 +2787,12 @@ unsigned char *Lexer::combineComments(unsigned char *c1, unsigned char *c2)
|
||||
|
||||
c = (unsigned char *)mem.malloc(len1 + 1 + len2 + 1);
|
||||
memcpy(c, c1, len1);
|
||||
c[len1] = '\n';
|
||||
memcpy(c + len1 + 1, c2, len2);
|
||||
c[len1 + 1 + len2] = 0;
|
||||
if (len1 && c1[len1 - 1] != '\n')
|
||||
{ c[len1] = '\n';
|
||||
len1++;
|
||||
}
|
||||
memcpy(c + len1, c2, len2);
|
||||
c[len1 + len2] = 0;
|
||||
}
|
||||
}
|
||||
return c;
|
||||
@@ -2951,6 +2966,7 @@ static Keyword keywords[] =
|
||||
{ "__FILE__", TOKfile },
|
||||
{ "__LINE__", TOKline },
|
||||
{ "shared", TOKshared },
|
||||
{ "immutable", TOKimmutable },
|
||||
#endif
|
||||
};
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ Global::Global()
|
||||
|
||||
copyright = "Copyright (c) 1999-2008 by Digital Mars and Tomas Lindquist Olsen";
|
||||
written = "written by Walter Bright and Tomas Lindquist Olsen";
|
||||
version = "v1.036";
|
||||
version = "v1.037";
|
||||
ldc_version = "0.1";
|
||||
global.structalign = 8;
|
||||
|
||||
|
||||
@@ -2485,7 +2485,7 @@ Expression *TypeAArray::defaultInit(Loc loc)
|
||||
|
||||
int TypeAArray::isZeroInit()
|
||||
{
|
||||
return 1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
int TypeAArray::checkBoolean()
|
||||
@@ -3994,6 +3994,12 @@ Expression *TypeEnum::getProperty(Loc loc, Identifier *ident)
|
||||
goto Lfwd;
|
||||
e = defaultInit(loc);
|
||||
}
|
||||
else if (ident == Id::stringof)
|
||||
{ char *s = toChars();
|
||||
e = new StringExp(loc, s, strlen(s), 'c');
|
||||
Scope sc;
|
||||
e = e->semantic(&sc);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!sym->memtype)
|
||||
|
||||
@@ -386,7 +386,7 @@ Array *Parser::parseDeclDefs(int once)
|
||||
}
|
||||
ident = token.ident;
|
||||
nextToken();
|
||||
if (token.value == TOKcomma)
|
||||
if (token.value == TOKcomma && peekNext() != TOKrparen)
|
||||
args = parseArguments(); // pragma(identifier, args...)
|
||||
else
|
||||
check(TOKrparen); // pragma(identifier)
|
||||
@@ -3068,7 +3068,7 @@ Statement *Parser::parseStatement(int flags)
|
||||
}
|
||||
ident = token.ident;
|
||||
nextToken();
|
||||
if (token.value == TOKcomma)
|
||||
if (token.value == TOKcomma && peekNext() != TOKrparen)
|
||||
args = parseArguments(); // pragma(identifier, args...);
|
||||
else
|
||||
check(TOKrparen); // pragma(identifier);
|
||||
|
||||
60
dmd/root.c
60
dmd/root.c
@@ -16,6 +16,7 @@
|
||||
|
||||
#if _MSC_VER ||__MINGW32__
|
||||
#include <malloc.h>
|
||||
#include <string>
|
||||
#endif
|
||||
|
||||
#if _WIN32
|
||||
@@ -47,6 +48,7 @@ extern "C" void __cdecl _assert(void *e, void *f, unsigned line)
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/*************************************
|
||||
* Convert wchar string to ascii string.
|
||||
*/
|
||||
@@ -1606,6 +1608,36 @@ void OutBuffer::align(unsigned size)
|
||||
fill0(nbytes);
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////
|
||||
// The compiler shipped with Visual Studio 2005 (and possible
|
||||
// other versions) does not support C99 printf format specfiers
|
||||
// such as %z and %j
|
||||
#if _MSC_VER
|
||||
using std::string;
|
||||
using std::wstring;
|
||||
|
||||
template<typename S>
|
||||
inline void
|
||||
search_and_replace(S& str, const S& what, const S& replacement)
|
||||
{
|
||||
assert(!what.empty());
|
||||
size_t pos = str.find(what);
|
||||
while (pos != S::npos)
|
||||
{
|
||||
str.replace(pos, what.size(), replacement);
|
||||
pos = str.find(what, pos + replacement.size());
|
||||
}
|
||||
}
|
||||
#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f) \
|
||||
S tmp = f; \
|
||||
search_and_replace(fmt, S("%z"), S("%l")); \
|
||||
search_and_replace(fmt, S("%j"), S("%i")); \
|
||||
f = tmp.c_str();
|
||||
#else
|
||||
#define WORKAROUND_C99_SPECIFIERS_BUG(S,tmp,f)
|
||||
#endif
|
||||
|
||||
void OutBuffer::vprintf(const char *format, va_list args)
|
||||
{
|
||||
char buffer[128];
|
||||
@@ -1613,10 +1645,7 @@ void OutBuffer::vprintf(const char *format, va_list args)
|
||||
unsigned psize;
|
||||
int count;
|
||||
|
||||
// On some platforms (i.e. x86_64) va_list is an array and thus passed by
|
||||
// reference. Copy the input list so we can copy it back before retrying.
|
||||
va_list orig_args;
|
||||
va_copy(orig_args, args);
|
||||
WORKAROUND_C99_SPECIFIERS_BUG(string, fmt, format);
|
||||
|
||||
p = buffer;
|
||||
psize = sizeof(buffer);
|
||||
@@ -1628,7 +1657,19 @@ void OutBuffer::vprintf(const char *format, va_list args)
|
||||
break;
|
||||
psize *= 2;
|
||||
#elif POSIX
|
||||
count = vsnprintf(p,psize,format,args);
|
||||
va_list va;
|
||||
va_copy(va, args);
|
||||
/*
|
||||
The functions vprintf(), vfprintf(), vsprintf(), vsnprintf()
|
||||
are equivalent to the functions printf(), fprintf(), sprintf(),
|
||||
snprintf(), respectively, except that they are called with a
|
||||
va_list instead of a variable number of arguments. These
|
||||
functions do not call the va_end macro. Consequently, the value
|
||||
of ap is undefined after the call. The application should call
|
||||
va_end(ap) itself afterwards.
|
||||
*/
|
||||
count = vsnprintf(p,psize,format,va);
|
||||
va_end(va);
|
||||
if (count == -1)
|
||||
psize *= 2;
|
||||
else if (count >= psize)
|
||||
@@ -1636,7 +1677,6 @@ void OutBuffer::vprintf(const char *format, va_list args)
|
||||
else
|
||||
break;
|
||||
#endif
|
||||
va_copy(args, orig_args);
|
||||
p = (char *) alloca(psize); // buffer too small, try again with larger size
|
||||
}
|
||||
write(p,count);
|
||||
@@ -1650,6 +1690,8 @@ void OutBuffer::vprintf(const wchar_t *format, va_list args)
|
||||
unsigned psize;
|
||||
int count;
|
||||
|
||||
WORKAROUND_C99_SPECIFIERS_BUG(wstring, fmt, format);
|
||||
|
||||
p = buffer;
|
||||
psize = sizeof(buffer) / sizeof(buffer[0]);
|
||||
for (;;)
|
||||
@@ -1661,7 +1703,11 @@ void OutBuffer::vprintf(const wchar_t *format, va_list args)
|
||||
psize *= 2;
|
||||
#endif
|
||||
#if POSIX
|
||||
count = vsnwprintf(p,psize,format,args);
|
||||
va_list va;
|
||||
va_copy(va, args);
|
||||
count = vsnwprintf(p,psize,format,va);
|
||||
va_end(va);
|
||||
|
||||
if (count == -1)
|
||||
psize *= 2;
|
||||
else if (count >= psize)
|
||||
|
||||
158
dmd/statement.c
158
dmd/statement.c
@@ -26,6 +26,7 @@
|
||||
#include "id.h"
|
||||
#include "hdrgen.h"
|
||||
#include "parse.h"
|
||||
#include "template.h"
|
||||
|
||||
/******************************** Statement ***************************/
|
||||
|
||||
@@ -451,10 +452,7 @@ Statement *CompoundStatement::semantic(Scope *sc)
|
||||
body = new CompoundStatement(0, a);
|
||||
body = new ScopeStatement(0, body);
|
||||
|
||||
static int num;
|
||||
char name[3 + sizeof(num) * 3 + 1];
|
||||
sprintf(name, "__o%d", ++num);
|
||||
Identifier *id = Lexer::idPool(name);
|
||||
Identifier *id = Lexer::uniqueId("__o");
|
||||
|
||||
Statement *handler = new ThrowStatement(0, new IdentifierExp(0, id));
|
||||
handler = new CompoundStatement(0, sexception, handler);
|
||||
@@ -1107,12 +1105,17 @@ Statement *ForStatement::semantic(Scope *sc)
|
||||
// Use a default value
|
||||
condition = new IntegerExp(loc, 1, Type::tboolean);
|
||||
sc->noctor++;
|
||||
condition = condition->semantic(sc);
|
||||
condition = resolveProperties(sc, condition);
|
||||
condition = condition->optimize(WANTvalue);
|
||||
condition = condition->checkToBoolean();
|
||||
if (condition)
|
||||
{
|
||||
condition = condition->semantic(sc);
|
||||
condition = resolveProperties(sc, condition);
|
||||
condition = condition->optimize(WANTvalue);
|
||||
condition = condition->checkToBoolean();
|
||||
}
|
||||
if (increment)
|
||||
increment = increment->semantic(sc);
|
||||
{ increment = increment->semantic(sc);
|
||||
increment = resolveProperties(sc, increment);
|
||||
}
|
||||
|
||||
sc->sbreak = this;
|
||||
sc->scontinue = this;
|
||||
@@ -1257,8 +1260,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
//printf("ForeachStatement::semantic() %p\n", this);
|
||||
ScopeDsymbol *sym;
|
||||
Statement *s = this;
|
||||
int dim = arguments->dim;
|
||||
int i;
|
||||
size_t dim = arguments->dim;
|
||||
TypeAArray *taa = NULL;
|
||||
|
||||
Type *tn = NULL;
|
||||
@@ -1272,6 +1274,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
|
||||
aggr = aggr->semantic(sc);
|
||||
aggr = resolveProperties(sc, aggr);
|
||||
aggr = aggr->optimize(WANTvalue);
|
||||
if (!aggr->type)
|
||||
{
|
||||
error("invalid foreach aggregate %s", aggr->toChars());
|
||||
@@ -1387,7 +1390,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
return s;
|
||||
}
|
||||
|
||||
for (i = 0; i < dim; i++)
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ Argument *arg = (Argument *)arguments->data[i];
|
||||
if (!arg->type)
|
||||
{
|
||||
@@ -1419,7 +1422,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
if (tn->ty == Tchar || tn->ty == Twchar || tn->ty == Tdchar)
|
||||
{ Argument *arg;
|
||||
|
||||
i = (dim == 1) ? 0 : 1; // index of value
|
||||
int i = (dim == 1) ? 0 : 1; // index of value
|
||||
arg = (Argument *)arguments->data[i];
|
||||
arg->type = arg->type->semantic(loc, sc);
|
||||
tnv = arg->type->toBasetype();
|
||||
@@ -1437,7 +1440,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < dim; i++)
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ // Declare args
|
||||
Argument *arg = (Argument *)arguments->data[i];
|
||||
VarDeclaration *var;
|
||||
@@ -1468,7 +1471,8 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
if (aggr->op == TOKstring)
|
||||
aggr = aggr->implicitCastTo(sc, value->type->arrayOf());
|
||||
else
|
||||
error("foreach: %s is not an array of %s", tab->toChars(), value->type->toChars());
|
||||
error("foreach: %s is not an array of %s",
|
||||
tab->toChars(), value->type->toChars());
|
||||
}
|
||||
|
||||
if (key)
|
||||
@@ -1505,6 +1509,72 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
|
||||
case Tclass:
|
||||
case Tstruct:
|
||||
#if DMDV2
|
||||
{ /* Look for range iteration, i.e. the properties
|
||||
* .empty, .next, .retreat, .head and .rear
|
||||
* foreach (e; range) { ... }
|
||||
* translates to:
|
||||
* for (auto __r = range; !__r.empty; __r.next)
|
||||
* { auto e = __r.head;
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
if (dim != 1) // only one argument allowed with ranges
|
||||
goto Lapply;
|
||||
AggregateDeclaration *ad = (tab->ty == Tclass)
|
||||
? (AggregateDeclaration *)((TypeClass *)tab)->sym
|
||||
: (AggregateDeclaration *)((TypeStruct *)tab)->sym;
|
||||
Identifier *idhead;
|
||||
Identifier *idnext;
|
||||
if (op == TOKforeach)
|
||||
{ idhead = Id::Fhead;
|
||||
idnext = Id::Fnext;
|
||||
}
|
||||
else
|
||||
{ idhead = Id::Frear;
|
||||
idnext = Id::Fretreat;
|
||||
}
|
||||
Dsymbol *shead = search_function(ad, idhead);
|
||||
if (!shead)
|
||||
goto Lapply;
|
||||
|
||||
/* Generate a temporary __r and initialize it with the aggregate.
|
||||
*/
|
||||
Identifier *id = Identifier::generateId("__r");
|
||||
VarDeclaration *r = new VarDeclaration(loc, NULL, id, new ExpInitializer(loc, aggr));
|
||||
r->semantic(sc);
|
||||
Statement *init = new DeclarationStatement(loc, r);
|
||||
|
||||
// !__r.empty
|
||||
Expression *e = new VarExp(loc, r);
|
||||
e = new DotIdExp(loc, e, Id::Fempty);
|
||||
Expression *condition = new NotExp(loc, e);
|
||||
|
||||
// __r.next
|
||||
e = new VarExp(loc, r);
|
||||
Expression *increment = new DotIdExp(loc, e, idnext);
|
||||
|
||||
/* Declaration statement for e:
|
||||
* auto e = __r.idhead;
|
||||
*/
|
||||
e = new VarExp(loc, r);
|
||||
Expression *einit = new DotIdExp(loc, e, idhead);
|
||||
einit = einit->semantic(sc);
|
||||
Argument *arg = (Argument *)arguments->data[0];
|
||||
VarDeclaration *ve = new VarDeclaration(loc, arg->type, arg->ident, new ExpInitializer(loc, einit));
|
||||
ve->storage_class |= STCforeach;
|
||||
ve->storage_class |= arg->storageClass & (STCin | STCout | STCref | STCconst | STCinvariant);
|
||||
|
||||
DeclarationExp *de = new DeclarationExp(loc, ve);
|
||||
|
||||
Statement *body = new CompoundStatement(loc,
|
||||
new DeclarationStatement(loc, de), this->body);
|
||||
|
||||
s = new ForStatement(loc, init, condition, increment, body);
|
||||
s = s->semantic(sc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case Tdelegate:
|
||||
Lapply:
|
||||
{ FuncDeclaration *fdapply;
|
||||
@@ -1540,7 +1610,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
* int delegate(ref T arg) { body }
|
||||
*/
|
||||
args = new Arguments();
|
||||
for (i = 0; i < dim; i++)
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ Argument *arg = (Argument *)arguments->data[i];
|
||||
|
||||
arg->type = arg->type->semantic(loc, sc);
|
||||
@@ -1551,10 +1621,8 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
// a reference.
|
||||
VarDeclaration *v;
|
||||
Initializer *ie;
|
||||
char applyArg[10 + sizeof(i)*3 + 1];
|
||||
|
||||
sprintf(applyArg, "__applyArg%d", i);
|
||||
id = Lexer::idPool(applyArg);
|
||||
id = Lexer::uniqueId("__applyArg", i);
|
||||
|
||||
ie = new ExpInitializer(0, new IdentifierExp(0, id));
|
||||
v = new VarDeclaration(0, arg->type, arg->ident, ie);
|
||||
@@ -2145,6 +2213,11 @@ Statement *PragmaStatement::semantic(Scope *sc)
|
||||
}
|
||||
else if (ident == Id::lib)
|
||||
{
|
||||
#if 1
|
||||
/* Should this be allowed?
|
||||
*/
|
||||
error("pragma(lib) not allowed as statement");
|
||||
#else
|
||||
if (!args || args->dim != 1)
|
||||
error("string expected for library name");
|
||||
else
|
||||
@@ -2166,6 +2239,7 @@ Statement *PragmaStatement::semantic(Scope *sc)
|
||||
mem.free(name);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
error("unrecognized pragma(%s)", ident->toChars());
|
||||
@@ -2454,8 +2528,7 @@ Statement *CaseStatement::semantic(Scope *sc)
|
||||
//printf("CaseStatement::semantic() %s\n", toChars());
|
||||
exp = exp->semantic(sc);
|
||||
if (sw)
|
||||
{ int i;
|
||||
|
||||
{
|
||||
exp = exp->implicitCastTo(sc, sw->condition->type);
|
||||
exp = exp->optimize(WANTvalue | WANTinterpret);
|
||||
if (exp->op != TOKstring && exp->op != TOKint64)
|
||||
@@ -2464,7 +2537,7 @@ Statement *CaseStatement::semantic(Scope *sc)
|
||||
exp = new IntegerExp(0);
|
||||
}
|
||||
|
||||
for (i = 0; i < sw->cases->dim; i++)
|
||||
for (int i = 0; i < sw->cases->dim; i++)
|
||||
{
|
||||
CaseStatement *cs = (CaseStatement *)sw->cases->data[i];
|
||||
|
||||
@@ -2478,7 +2551,7 @@ Statement *CaseStatement::semantic(Scope *sc)
|
||||
sw->cases->push(this);
|
||||
|
||||
// Resolve any goto case's with no exp to this case statement
|
||||
for (i = 0; i < sw->gotoCases.dim; i++)
|
||||
for (size_t i = 0; i < sw->gotoCases.dim; i++)
|
||||
{
|
||||
GotoCaseStatement *gcs = (GotoCaseStatement *)sw->gotoCases.data[i];
|
||||
|
||||
@@ -2875,32 +2948,25 @@ Statement *ReturnStatement::semantic(Scope *sc)
|
||||
exp->op == TOKstring)
|
||||
{
|
||||
sc->fes->cases.push(this);
|
||||
// Construct: return cases.dim+1;
|
||||
s = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
|
||||
}
|
||||
else if (fd->type->nextOf()->toBasetype() == Type::tvoid)
|
||||
{
|
||||
Statement *s1;
|
||||
Statement *s2;
|
||||
|
||||
s = new ReturnStatement(0, NULL);
|
||||
sc->fes->cases.push(s);
|
||||
|
||||
// Construct: { exp; return cases.dim + 1; }
|
||||
s1 = new ExpStatement(loc, exp);
|
||||
s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
|
||||
Statement *s1 = new ExpStatement(loc, exp);
|
||||
Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
|
||||
s = new CompoundStatement(loc, s1, s2);
|
||||
}
|
||||
else
|
||||
{
|
||||
VarExp *v;
|
||||
Statement *s1;
|
||||
Statement *s2;
|
||||
|
||||
// Construct: return vresult;
|
||||
if (!fd->vresult)
|
||||
{ VarDeclaration *v;
|
||||
|
||||
v = new VarDeclaration(loc, tret, Id::result, NULL);
|
||||
{ // Declare vresult
|
||||
VarDeclaration *v = new VarDeclaration(loc, tret, Id::result, NULL);
|
||||
v->noauto = 1;
|
||||
v->semantic(scx);
|
||||
if (!scx->insert(v))
|
||||
@@ -2909,16 +2975,14 @@ Statement *ReturnStatement::semantic(Scope *sc)
|
||||
fd->vresult = v;
|
||||
}
|
||||
|
||||
v = new VarExp(0, fd->vresult);
|
||||
s = new ReturnStatement(0, v);
|
||||
s = new ReturnStatement(0, new VarExp(0, fd->vresult));
|
||||
sc->fes->cases.push(s);
|
||||
|
||||
// Construct: { vresult = exp; return cases.dim + 1; }
|
||||
v = new VarExp(0, fd->vresult);
|
||||
exp = new AssignExp(loc, v, exp);
|
||||
exp = new AssignExp(loc, new VarExp(0, fd->vresult), exp);
|
||||
exp = exp->semantic(sc);
|
||||
s1 = new ExpStatement(loc, exp);
|
||||
s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
|
||||
Statement *s1 = new ExpStatement(loc, exp);
|
||||
Statement *s2 = new ReturnStatement(0, new IntegerExp(sc->fes->cases.dim + 1));
|
||||
s = new CompoundStatement(loc, s1, s2);
|
||||
}
|
||||
return s;
|
||||
@@ -2959,9 +3023,10 @@ Statement *ReturnStatement::semantic(Scope *sc)
|
||||
|
||||
gs->label = fd->returnLabel;
|
||||
if (exp)
|
||||
{ Statement *s;
|
||||
|
||||
s = new ExpStatement(0, exp);
|
||||
{ /* Replace: return exp;
|
||||
* with: exp; goto returnLabel;
|
||||
*/
|
||||
Statement *s = new ExpStatement(0, exp);
|
||||
return new CompoundStatement(loc, s, gs);
|
||||
}
|
||||
return gs;
|
||||
@@ -3739,10 +3804,7 @@ void OnScopeStatement::scopeCode(Statement **sentry, Statement **sexception, Sta
|
||||
* sexception: x = 1;
|
||||
* sfinally: if (!x) statement;
|
||||
*/
|
||||
static int num;
|
||||
char name[5 + sizeof(num) * 3 + 1];
|
||||
sprintf(name, "__osf%d", ++num);
|
||||
Identifier *id = Lexer::idPool(name);
|
||||
Identifier *id = Lexer::uniqueId("__os");
|
||||
|
||||
ExpInitializer *ie = new ExpInitializer(loc, new IntegerExp(0));
|
||||
VarDeclaration *v = new VarDeclaration(loc, Type::tint32, id, ie);
|
||||
|
||||
Reference in New Issue
Block a user