Merged DMD 1.038

This commit is contained in:
Tomas Lindquist Olsen
2009-01-06 16:33:51 +01:00
parent 306015f7fb
commit 16409a3367
22 changed files with 4315 additions and 3783 deletions

View File

@@ -406,7 +406,7 @@ void LinkDeclaration::semantic3(Scope *sc)
}
void LinkDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ char *p;
{ const char *p;
switch (linkage)
{
@@ -431,7 +431,7 @@ void LinkDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
char *LinkDeclaration::toChars()
{
return "extern ()";
return (char *)"extern ()";
}
/********************************* ProtDeclaration ****************************/
@@ -476,7 +476,7 @@ void ProtDeclaration::semantic(Scope *sc)
}
void ProtDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ char *p;
{ const char *p;
switch (protection)
{
@@ -721,7 +721,7 @@ void AnonDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
const char *AnonDeclaration::kind()
{
return (char *)(isunion ? "anonymous union" : "anonymous struct");
return (isunion ? "anonymous union" : "anonymous struct");
}
/********************************* PragmaDeclaration ****************************/
@@ -1363,6 +1363,7 @@ const char *StaticIfDeclaration::kind()
CompileDeclaration::CompileDeclaration(Loc loc, Expression *exp)
: AttribDeclaration(NULL)
{
//printf("CompileDeclaration(loc = %d)\n", loc.linnum);
this->loc = loc;
this->exp = exp;
this->sd = NULL;
@@ -1392,7 +1393,7 @@ int CompileDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
void CompileDeclaration::compileIt(Scope *sc)
{
//printf("CompileDeclaration::compileIt()\n");
//printf("CompileDeclaration::compileIt(loc = %d)\n", loc.linnum);
exp = exp->semantic(sc);
exp = resolveProperties(sc, exp);
exp = exp->optimize(WANTvalue | WANTinterpret);

View File

@@ -539,7 +539,16 @@ void ClassDeclaration::semantic(Scope *sc)
sc->inunion = 0;
if (isCOMclass())
{
#if _WIN32
sc->linkage = LINKwindows;
#else
/* This enables us to use COM objects under Linux and
* work with things like XPCOM
*/
sc->linkage = LINKc;
#endif
}
sc->protection = PROTpublic;
sc->explicitProtection = 0;
sc->structalign = 8;

View File

@@ -1,391 +1,391 @@
// 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 "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++)
{
char *id = (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(char *ident)
{
if (!global.params.debugids)
global.params.debugids = new Array();
global.params.debugids->push(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, char *ident)
{
static char* reserved[] =
{
"DigitalMars", "LLVM", "LDC", "LLVM64",
"X86", "X86_64", "PPC", "PPC64",
"Windows", "Win32", "Win64",
"linux", "darwin", "Posix",
"LittleEndian", "BigEndian",
"all",
"none",
};
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(char *ident)
{
checkPredefined(0, ident);
addPredefinedGlobalIdent(ident);
}
void VersionCondition::addPredefinedGlobalIdent(char *ident)
{
if (!global.params.versionids)
global.params.versionids = new Array();
global.params.versionids->push(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;
}
unsigned errors = global.errors;
global.gag++; // suppress printing of error messages
targ = targ->semantic(loc, sc);
global.gag--;
if (errors != global.errors) // if any errors happened
{ inc = 2; // then condition is false
global.errors = errors;
}
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, &parameters, &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-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 "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++)
{
char *id = (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(char *ident)
{
if (!global.params.debugids)
global.params.debugids = new Array();
global.params.debugids->push(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, char *ident)
{
static const char* reserved[] =
{
"DigitalMars", "LLVM", "LDC", "LLVM64",
"X86", "X86_64", "PPC", "PPC64",
"Windows", "Win32", "Win64",
"linux", "darwin", "Posix",
"LittleEndian", "BigEndian",
"all",
"none",
};
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(char *ident)
{
checkPredefined(0, ident);
addPredefinedGlobalIdent(ident);
}
void VersionCondition::addPredefinedGlobalIdent(char *ident)
{
if (!global.params.versionids)
global.params.versionids = new Array();
global.params.versionids->push(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;
}
unsigned errors = global.errors;
global.gag++; // suppress printing of error messages
targ = targ->semantic(loc, sc);
global.gag--;
if (errors != global.errors) // if any errors happened
{ inc = 2; // then condition is false
global.errors = errors;
}
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, &parameters, &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(')');
}

View File

@@ -47,9 +47,9 @@
struct Escape
{
char *strings[256];
const char *strings[256];
static char *escapeChar(unsigned c);
static const char *escapeChar(unsigned c);
};
struct Section
@@ -96,8 +96,8 @@ struct DocComment
};
int cmp(char *stringz, void *s, size_t slen);
int icmp(char *stringz, void *s, size_t slen);
int cmp(const char *stringz, void *s, size_t slen);
int icmp(const char *stringz, void *s, size_t slen);
int isDitto(unsigned char *comment);
unsigned char *skipwhitespace(unsigned char *p);
unsigned skiptoident(OutBuffer *buf, unsigned i);
@@ -404,7 +404,7 @@ void ScopeDsymbol::emitMemberComments(Scope *sc)
OutBuffer *buf = sc->docbuf;
if (members)
{ char *m = "$(DDOC_MEMBERS \n";
{ const char *m = "$(DDOC_MEMBERS \n";
if (isModule())
m = "$(DDOC_MODULE_MEMBERS \n";
@@ -441,7 +441,7 @@ void ScopeDsymbol::emitMemberComments(Scope *sc)
void emitProtection(OutBuffer *buf, PROT prot)
{
char *p;
const char *p;
switch (prot)
{
@@ -918,6 +918,7 @@ DocComment::DocComment()
DocComment *DocComment::parse(Scope *sc, Dsymbol *s, unsigned char *comment)
{ unsigned idlen;
//printf("parse(%s): '%s'\n", s->toChars(), comment);
if (sc->lastdc && isDitto(comment))
return NULL;
@@ -963,6 +964,7 @@ void DocComment::parseSections(unsigned char *comment)
unsigned char *name = NULL;
unsigned namelen = 0;
//printf("parseSections('%s')\n", comment);
p = comment;
while (*p)
{
@@ -1088,7 +1090,7 @@ void Section::write(DocComment *dc, Scope *sc, Dsymbol *s, OutBuffer *buf)
{
if (namelen)
{
static char *table[] =
static const char *table[] =
{ "AUTHORS", "BUGS", "COPYRIGHT", "DATE",
"DEPRECATED", "EXAMPLES", "HISTORY", "LICENSE",
"RETURNS", "SEE_ALSO", "STANDARDS", "THROWS",
@@ -1432,7 +1434,7 @@ void DocComment::parseEscapes(Escape **pescapetable, unsigned char *textstart, u
* Return < 0, ==0, > 0
*/
int cmp(char *stringz, void *s, size_t slen)
int cmp(const char *stringz, void *s, size_t slen)
{
size_t len1 = strlen(stringz);
@@ -1441,7 +1443,7 @@ int cmp(char *stringz, void *s, size_t slen)
return memcmp(stringz, s, slen);
}
int icmp(char *stringz, void *s, size_t slen)
int icmp(const char *stringz, void *s, size_t slen)
{
size_t len1 = strlen(stringz);
@@ -1578,7 +1580,7 @@ Lno:
int isKeyword(unsigned char *p, unsigned len)
{
static char *table[] = { "true", "false", "null" };
static const char *table[] = { "true", "false", "null" };
for (int i = 0; i < sizeof(table) / sizeof(table[0]); i++)
{
@@ -1629,10 +1631,10 @@ Argument *isFunctionParameter(Dsymbol *s, unsigned char *p, unsigned len)
void highlightText(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset)
{
//printf("highlightText()\n");
char *sid = s->ident->toChars();
const char *sid = s->ident->toChars();
FuncDeclaration *f = s->isFuncDeclaration();
unsigned char *p;
char *se;
const char *se;
int leadingBlank = 1;
int inCode = 0;
@@ -1878,7 +1880,7 @@ void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset)
//printf("highlightCode(s = '%s', kind = %s)\n", sid, s->kind());
for (unsigned i = offset; i < buf->offset; i++)
{ unsigned char c = buf->data[i];
char *se;
const char *se;
se = Escape::escapeChar(c);
if (se)
@@ -1920,7 +1922,7 @@ void highlightCode(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset)
void highlightCode3(OutBuffer *buf, unsigned char *p, unsigned char *pend)
{
for (; p < pend; p++)
{ char *s = Escape::escapeChar(*p);
{ const char *s = Escape::escapeChar(*p);
if (s)
buf->writestring(s);
else
@@ -1942,7 +1944,7 @@ void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset)
Token tok;
OutBuffer res;
unsigned char *lastp = buf->data;
char *highlight;
const char *highlight;
//printf("highlightCode2('%.*s')\n", buf->offset - 1, buf->data);
res.reserve(buf->offset);
@@ -2003,8 +2005,8 @@ void highlightCode2(Scope *sc, Dsymbol *s, OutBuffer *buf, unsigned offset)
* Find character string to replace c with.
*/
char *Escape::escapeChar(unsigned c)
{ char *s;
const char *Escape::escapeChar(unsigned c)
{ const char *s;
switch (c)
{

View File

@@ -12,7 +12,10 @@
#include <stdlib.h>
#include <ctype.h>
#include <assert.h>
#if _MSC_VER
#include <complex>
#else
#endif
#include <math.h>
#if _WIN32 && __DMC__
@@ -68,6 +71,7 @@ int isnan(double);
#include "parse.h"
Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim);
Expression *expandVar(int result, VarDeclaration *v);
#define LOGSEMANTIC 0
@@ -168,10 +172,20 @@ void initPrecedence()
precedence[TOKue] = PREC_rel;
precedence[TOKin] = PREC_rel;
#if 0
precedence[TOKequal] = PREC_equal;
precedence[TOKnotequal] = PREC_equal;
precedence[TOKidentity] = PREC_equal;
precedence[TOKnotidentity] = PREC_equal;
#else
/* Note that we changed precedence, so that < and != have the same
* precedence. This change is in the parser, too.
*/
precedence[TOKequal] = PREC_rel;
precedence[TOKnotequal] = PREC_rel;
precedence[TOKidentity] = PREC_rel;
precedence[TOKnotidentity] = PREC_rel;
#endif
precedence[TOKand] = PREC_and;
@@ -352,7 +366,7 @@ Expression *resolveProperties(Scope *sc, Expression *e)
{
Type *t = e->type->toBasetype();
if (t->ty == Tfunction)
if (t->ty == Tfunction /*|| e->op == TOKoverloadset*/)
{
e = new CallExp(e->loc, e);
e = e->semantic(sc);
@@ -539,8 +553,6 @@ Expression *callCpCtor(Loc loc, Scope *sc, Expression *e)
void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *arguments)
{
unsigned n;
int done;
Type *tb;
//printf("functionArguments()\n");
assert(arguments);
@@ -552,7 +564,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
n = (nargs > nparams) ? nargs : nparams; // n = max(nargs, nparams)
done = 0;
int done = 0;
for (size_t i = 0; i < n; i++)
{
Expression *arg;
@@ -561,6 +573,7 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
arg = (Expression *)arguments->data[i];
else
arg = NULL;
Type *tb;
if (i < nparams)
{
@@ -615,11 +628,8 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
break;
}
#endif
static int idn;
char name[10 + sizeof(idn)*3 + 1];
sprintf(name, "__arrayArg%d", ++idn);
Identifier *id = Lexer::idPool(name);
Type *t = new TypeSArray(tb->next, new IntegerExp(nargs - i));
Identifier *id = Lexer::uniqueId("__arrayArg");
Type *t = new TypeSArray(((TypeArray *)tb)->next, new IntegerExp(nargs - i));
t = t->semantic(loc, sc);
VarDeclaration *v = new VarDeclaration(loc, t, id, new VoidInitializer(loc));
v->semantic(sc);
@@ -631,16 +641,19 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
for (size_t u = i; u < nargs; u++)
{ Expression *a = (Expression *)arguments->data[u];
if (tret && !tb->next->equals(a->type))
if (tret && !((TypeArray *)tb)->next->equals(a->type))
a = a->toDelegate(sc, tret);
Expression *e = new VarExp(loc, v);
e = new IndexExp(loc, e, new IntegerExp(u + 1 - nparams));
e = new AssignExp(loc, e, a);
AssignExp *ae = new AssignExp(loc, e, a);
#if DMDV2
ae->op = TOKconstruct;
#endif
if (c)
c = new CommaExp(loc, c, e);
c = new CommaExp(loc, c, ae);
else
c = e;
c = ae;
}
arg = new VarExp(loc, v);
if (c)
@@ -694,12 +707,50 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
}
#endif
#if DMDV2
if (tb->ty == Tstruct && !(p->storageClass & (STCref | STCout)))
{
arg = callCpCtor(loc, sc, arg);
}
#endif
// Convert lazy argument to a delegate
if (p->storageClass & STClazy)
{
arg = arg->toDelegate(sc, p->type);
}
#if DMDV2
/* Look for arguments that cannot 'escape' from the called
* function.
*/
if (!tf->parameterEscapes(p))
{
/* Function literals can only appear once, so if this
* appearance was scoped, there cannot be any others.
*/
if (arg->op == TOKfunction)
{ FuncExp *fe = (FuncExp *)arg;
fe->fd->tookAddressOf = 0;
}
/* For passing a delegate to a scoped parameter,
* this doesn't count as taking the address of it.
* We only worry about 'escaping' references to the function.
*/
else if (arg->op == TOKdelegate)
{ DelegateExp *de = (DelegateExp *)arg;
if (de->e1->op == TOKvar)
{ VarExp *ve = (VarExp *)de->e1;
FuncDeclaration *f = ve->var->isFuncDeclaration();
if (f)
{ f->tookAddressOf--;
//printf("tookAddressOf = %d\n", f->tookAddressOf);
}
}
}
}
#endif
}
else
{
@@ -778,7 +829,11 @@ void functionArguments(Loc loc, Scope *sc, TypeFunction *tf, Expressions *argume
void expToCBuffer(OutBuffer *buf, HdrGenState *hgs, Expression *e, enum PREC pr)
{
//if (precedence[e->op] == 0) e->dump(0);
if (precedence[e->op] < pr)
if (precedence[e->op] < pr ||
/* Despite precedence, we don't allow a<b<c expressions.
* They must be parenthesized.
*/
(pr == PREC_rel && precedence[e->op] == pr))
{
buf->writeByte('(');
e->toCBuffer(buf, hgs);
@@ -982,6 +1037,16 @@ void Expression::toMangleBuffer(OutBuffer *buf)
error("expression %s is not a valid template value argument", toChars());
}
/***************************************
* Return !=0 if expression is an lvalue.
*/
#if DMDV2
int Expression::isLvalue()
{
return 0;
}
#endif
/*******************************
* Give error if we're not an lvalue.
* If we can, convert expression to be an lvalue.
@@ -1002,6 +1067,10 @@ Expression *Expression::modifiableLvalue(Scope *sc, Expression *e)
//printf("Expression::modifiableLvalue() %s, type = %s\n", toChars(), type->toChars());
// See if this expression is a modifiable lvalue (i.e. not const)
#if DMDV2
if (type && (!type->isMutable() || !type->isAssignable()))
error("%s is not mutable", e->toChars());
#endif
return toLvalue(sc, e);
}
@@ -1049,6 +1118,15 @@ void Expression::checkDeprecated(Scope *sc, Dsymbol *s)
s->checkDeprecated(loc, sc);
}
#if DMDV2
void Expression::checkPurity(Scope *sc, FuncDeclaration *f)
{
if (sc->func && sc->func->isPure() && !sc->intypeof && !f->isPure())
error("pure function '%s' cannot call impure function '%s'\n",
sc->func->toChars(), f->toChars());
}
#endif
/********************************
* Check for expressions that have no use.
* Input:
@@ -1175,7 +1253,11 @@ int Expression::isBit()
int Expression::canThrow()
{
#if DMDV2
return FALSE;
#else
return TRUE;
#endif
}
@@ -1849,7 +1931,9 @@ Expression *IdentifierExp::semantic(Scope *sc)
// ArrayScopeSymbol::search() doesn't have access to sc.
s->semantic(sc);
}
// Look to see if f is really a function template
/* If f is really a function template,
* then replace f with the function template declaration.
*/
FuncDeclaration *f = s->isFuncDeclaration();
if (f && f->parent)
{ TemplateInstance *ti = f->parent->isTemplateInstance();
@@ -1891,6 +1975,13 @@ void IdentifierExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring(ident->toChars());
}
#if DMDV2
int IdentifierExp::isLvalue()
{
return 1;
}
#endif
Expression *IdentifierExp::toLvalue(Scope *sc, Expression *e)
{
#if 0
@@ -1954,7 +2045,11 @@ Lagain:
// BUG: This should happen after overload resolution for functions, not before
if (s->needThis())
{
if (hasThis(sc) /*&& !s->isFuncDeclaration()*/)
if (hasThis(sc)
#if DMDV2
&& !s->isFuncDeclaration()
#endif
)
{
// Supply an implicit 'this', as in
// this.ident
@@ -2112,6 +2207,13 @@ void DsymbolExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring(s->toChars());
}
#if DMDV2
int DsymbolExp::isLvalue()
{
return 1;
}
#endif
Expression *DsymbolExp::toLvalue(Scope *sc, Expression *e)
{
#if 0
@@ -2214,6 +2316,13 @@ void ThisExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
buf->writestring("this");
}
#if DMDV2
int ThisExp::isLvalue()
{
return 1;
}
#endif
Expression *ThisExp::toLvalue(Scope *sc, Expression *e)
{
return this;
@@ -2431,7 +2540,7 @@ Expression *StringExp::semantic(Scope *sc)
if (!type)
{ OutBuffer buffer;
size_t newlen = 0;
char *p;
const char *p;
size_t u;
unsigned c;
@@ -2629,7 +2738,7 @@ void StringExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
void StringExp::toMangleBuffer(OutBuffer *buf)
{ char m;
OutBuffer tmp;
char *p;
const char *p;
unsigned c;
size_t u;
unsigned char *q;
@@ -2772,6 +2881,13 @@ int ArrayLiteralExp::isBool(int result)
return result ? (dim != 0) : (dim == 0);
}
#if DMDV2
int ArrayLiteralExp::canThrow()
{
return 1; // because it can fail allocating memory
}
#endif
void ArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writeByte('[');
@@ -2890,6 +3006,13 @@ int AssocArrayLiteralExp::isBool(int result)
return result ? (dim != 0) : (dim == 0);
}
#if DMDV2
int AssocArrayLiteralExp::canThrow()
{
return 1;
}
#endif
void AssocArrayLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writeByte('[');
@@ -3074,6 +3197,12 @@ int StructLiteralExp::getFieldIndex(Type *type, unsigned offset)
return -1;
}
#if DMDV2
int StructLiteralExp::isLvalue()
{
return 1;
}
#endif
Expression *StructLiteralExp::toLvalue(Scope *sc, Expression *e)
{
@@ -3096,6 +3225,13 @@ int StructLiteralExp::checkSideEffect(int flag)
return f;
}
#if DMDV2
int StructLiteralExp::canThrow()
{
return arrayExpressionCanThrow(elements);
}
#endif
void StructLiteralExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring(sd->toChars());
@@ -3287,6 +3423,8 @@ void TemplateExp::rvalue()
/********************** NewExp **************************************/
/* thisexp.new(newargs) newtype(arguments) */
NewExp::NewExp(Loc loc, Expression *thisexp, Expressions *newargs,
Type *newtype, Expressions *arguments)
: Expression(loc, TOKnew, sizeof(NewExp))
@@ -3472,17 +3610,14 @@ Lagain:
}
if (cd->aggNew)
{ Expression *e;
f = cd->aggNew;
{
// Prepend the uint size argument to newargs[]
e = new IntegerExp(loc, cd->size(loc), Type::tuns32);
Expression *e = new IntegerExp(loc, cd->size(loc), Type::tuns32);
if (!newargs)
newargs = new Expressions();
newargs->shift(e);
f = f->overloadResolve(loc, newargs);
f = cd->aggNew->overloadResolve(loc, newargs);
allocator = f->isNewDeclaration();
assert(allocator);
@@ -3494,7 +3629,6 @@ Lagain:
if (newargs && newargs->dim)
error("no allocator for %s", cd->toChars());
}
}
else if (tb->ty == Tstruct)
{
@@ -3575,6 +3709,13 @@ int NewExp::checkSideEffect(int flag)
return 1;
}
#if DMDV2
int NewExp::canThrow()
{
return 1;
}
#endif
void NewExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ int i;
@@ -3642,6 +3783,13 @@ int NewAnonClassExp::checkSideEffect(int flag)
return 1;
}
#if DMDV2
int NewAnonClassExp::canThrow()
{
return 1;
}
#endif
void NewAnonClassExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{ int i;
@@ -3670,6 +3818,18 @@ void NewAnonClassExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
}
}
/********************** SymbolExp **************************************/
#if DMDV2
SymbolExp::SymbolExp(Loc loc, enum TOK op, int size, Declaration *var, int hasOverloads)
: Expression(loc, op, size)
{
assert(var);
this->var = var;
this->hasOverloads = hasOverloads;
}
#endif
/********************** SymOffExp **************************************/
SymOffExp::SymOffExp(Loc loc, Declaration *var, unsigned offset)
@@ -3760,6 +3920,11 @@ Expression *VarExp::semantic(Scope *sc)
}
#endif
}
/* Fix for 1161 doesn't work because it causes protection
* problems when instantiating imported templates passing private
* variables as alias template parameters.
*/
//accessCheck(loc, sc, NULL, var);
VarDeclaration *v = var->isVarDeclaration();
if (v)
@@ -3774,6 +3939,13 @@ Expression *VarExp::semantic(Scope *sc)
}
}
v->checkNestedReference(sc, loc);
#if DMDV2
if (sc->func && sc->func->isPure() && !sc->intypeof)
{
if (v->isDataseg() && !v->isInvariant())
error("pure function '%s' cannot access mutable static data '%s'", sc->func->toChars(), v->toChars());
}
#endif
}
#if 0
else if ((fd = var->isFuncLiteralDeclaration()) != NULL)
@@ -3812,6 +3984,15 @@ void VarExp::checkEscape()
}
}
#if DMDV2
int VarExp::isLvalue()
{
if (var->storage_class & STClazy)
return 0;
return 1;
}
#endif
Expression *VarExp::toLvalue(Scope *sc, Expression *e)
{
#if 0
@@ -4026,6 +4207,13 @@ int TupleExp::checkSideEffect(int flag)
return f;
}
#if DMDV2
int TupleExp::canThrow()
{
return arrayExpressionCanThrow(exps);
}
#endif
void TupleExp::checkEscape()
{
for (size_t i = 0; i < exps->dim; i++)
@@ -4195,6 +4383,18 @@ int DeclarationExp::checkSideEffect(int flag)
return 1;
}
#if DMDV2
int DeclarationExp::canThrow()
{
VarDeclaration *v = declaration->isVarDeclaration();
if (v && v->init)
{ ExpInitializer *ie = v->init->isExpInitializer();
return ie && ie->exp->canThrow();
}
return 0;
}
#endif
void DeclarationExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
declaration->toCBuffer(buf, hgs);
@@ -4398,6 +4598,7 @@ Expression *IsExp::semantic(Scope *sc)
break;
case TOKinvariant:
case TOKimmutable:
if (!targ->isInvariant())
goto Lno;
tded = targ;
@@ -4604,6 +4805,13 @@ Expression *UnaExp::semantic(Scope *sc)
return this;
}
#if DMDV2
int UnaExp::canThrow()
{
return e1->canThrow();
}
#endif
void UnaExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring(Token::toChars(op));
@@ -4773,6 +4981,13 @@ int BinExp::isunsigned()
return e1->type->isunsigned() || e2->type->isunsigned();
}
#if DMDV2
int BinExp::canThrow()
{
return e1->canThrow() || e2->canThrow();
}
#endif
void BinExp::incompatibleTypes()
{
error("incompatible types for ((%s) %s (%s)): '%s' and '%s'",
@@ -4805,6 +5020,7 @@ Expression *CompileExp::semantic(Scope *sc)
Parser p(sc->module, (unsigned char *)se->string, se->len, 0);
p.loc = loc;
p.nextToken();
//printf("p.loc.linnum = %d\n", p.loc.linnum);
Expression *e = p.parseExpression();
if (p.token.value != TOKeof)
error("incomplete mixin expression (%s)", se->toChars());
@@ -4877,7 +5093,7 @@ Expression *FileExp::semantic(Scope *sc)
return se->semantic(sc);
Lerror:
se = new StringExp(loc, "");
se = new StringExp(loc, (char *)"");
goto Lret;
}
@@ -4940,6 +5156,13 @@ int AssertExp::checkSideEffect(int flag)
return 1;
}
#if DMDV2
int AssertExp::canThrow()
{
return (global.params.useAssert != 0);
}
#endif
void AssertExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("assert(");
@@ -5162,6 +5385,13 @@ Expression *DotIdExp::semantic(Scope *sc)
}
return e;
}
#if DMDV2
OverloadSet *o = s->isOverloadSet();
if (o)
{ //printf("'%s' is an overload set\n", o->toChars());
return new OverExp(o);
}
#endif
Type *t = s->getType();
if (t)
@@ -5224,6 +5454,29 @@ Expression *DotIdExp::semantic(Scope *sc)
e->type = ((TypePointer *)e1->type)->next;
return e->type->dotExp(sc, e, ident);
}
#if DMDV2
else if (t1b->ty == Tarray ||
t1b->ty == Tsarray ||
t1b->ty == Taarray)
{ /* If ident is not a valid property, rewrite:
* e1.ident
* as:
* .ident(e1)
*/
unsigned errors = global.errors;
global.gag++;
e = e1->type->dotExp(sc, e1, ident);
global.gag--;
if (errors != global.errors) // if failed to find the property
{
global.errors = errors;
e = new DotIdExp(loc, new IdentifierExp(loc, Id::empty), ident);
e = new CallExp(loc, e, e1);
}
e = e->semantic(sc);
return e;
}
#endif
else
{
e = e1->type->dotExp(sc, e1, ident);
@@ -5341,6 +5594,13 @@ Expression *DotVarExp::semantic(Scope *sc)
return this;
}
#if DMDV2
int DotVarExp::isLvalue()
{
return 1;
}
#endif
Expression *DotVarExp::toLvalue(Scope *sc, Expression *e)
{
//printf("DotVarExp::toLvalue(%s)\n", toChars());
@@ -5391,6 +5651,20 @@ Expression *DotVarExp::modifiableLvalue(Scope *sc, Expression *e)
break;
}
}
#if DMDV2
else
{
Type *t1 = e1->type->toBasetype();
if (!t1->isMutable() ||
(t1->ty == Tpointer && !t1->nextOf()->isMutable()) ||
!var->type->isMutable() ||
!var->type->isAssignable() ||
var->storage_class & STCmanifest
)
error("cannot modify const/invariant %s", toChars());
}
#endif
return this;
}
@@ -5713,12 +5987,16 @@ Expression *CallExp::semantic(Scope *sc)
if (!arguments)
arguments = new Expressions();
arguments->shift(dotid->e1);
#if DMDV2
e1 = new DotIdExp(dotid->loc, new IdentifierExp(dotid->loc, Id::empty), dotid->ident);
#else
e1 = new IdentifierExp(dotid->loc, dotid->ident);
#endif
}
}
}
#if DMDV2
#if 1
/* This recognizes:
* foo!(tiargs)(funcargs)
*/
@@ -5901,7 +6179,7 @@ Lagain:
if (!arguments)
// Should fix deduceFunctionTemplate() so it works on NULL argument
arguments = new Expressions();
f = td->deduceFunctionTemplate(sc, loc, NULL, arguments);
f = td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments);
if (!f)
{ type = Type::terror;
return this;
@@ -5925,6 +6203,9 @@ Lagain:
}
checkDeprecated(sc, f);
#if DMDV2
checkPurity(sc, f);
#endif
accessCheck(loc, sc, ue->e1, f);
if (!f->needThis())
{
@@ -5990,6 +6271,9 @@ Lagain:
f = f->overloadResolve(loc, arguments);
checkDeprecated(sc, f);
#if DMDV2
checkPurity(sc, f);
#endif
e1 = new DotVarExp(e1->loc, e1, f);
e1 = e1->semantic(sc);
t1 = e1->type;
@@ -6027,6 +6311,9 @@ Lagain:
f = cd->ctor;
f = f->overloadResolve(loc, arguments);
checkDeprecated(sc, f);
#if DMDV2
checkPurity(sc, f);
#endif
e1 = new DotVarExp(e1->loc, e1, f);
e1 = e1->semantic(sc);
t1 = e1->type;
@@ -6062,7 +6349,7 @@ Lagain:
else if (e1->op == TOKtemplate)
{
TemplateExp *te = (TemplateExp *)e1;
f = te->td->deduceFunctionTemplate(sc, loc, NULL, arguments);
f = te->td->deduceFunctionTemplate(sc, loc, targsi, NULL, arguments);
if (!f)
{ type = Type::terror;
return this;
@@ -6118,6 +6405,9 @@ Lagain:
f = f->overloadResolve(loc, arguments);
checkDeprecated(sc, f);
#if DMDV2
checkPurity(sc, f);
#endif
if (f->needThis() && hasThis(sc))
{
@@ -6165,9 +6455,75 @@ Lcheckargs:
int CallExp::checkSideEffect(int flag)
{
#if DMDV2
if (flag != 2)
return 1;
if (e1->checkSideEffect(2))
return 1;
/* If any of the arguments have side effects, this expression does
*/
for (size_t i = 0; i < arguments->dim; i++)
{ Expression *e = (Expression *)arguments->data[i];
if (e->checkSideEffect(2))
return 1;
}
/* If calling a function or delegate that is typed as pure,
* then this expression has no side effects.
*/
Type *t = e1->type->toBasetype();
if (t->ty == Tfunction && ((TypeFunction *)t)->ispure)
return 0;
if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->ispure)
return 0;
#endif
return 1;
}
#if DMDV2
int CallExp::canThrow()
{
if (e1->canThrow())
return 1;
/* If any of the arguments can throw, then this expression can throw
*/
for (size_t i = 0; i < arguments->dim; i++)
{ Expression *e = (Expression *)arguments->data[i];
if (e->canThrow())
return 1;
}
/* If calling a function or delegate that is typed as nothrow,
* then this expression cannot throw.
* Note that pure functions can throw.
*/
Type *t = e1->type->toBasetype();
if (t->ty == Tfunction && ((TypeFunction *)t)->isnothrow)
return 0;
if (t->ty == Tdelegate && ((TypeFunction *)((TypeDelegate *)t)->next)->isnothrow)
return 0;
return 1;
}
#endif
#if DMDV2
int CallExp::isLvalue()
{
if (type->toBasetype()->ty == Tstruct)
return 1;
Type *tb = e1->type->toBasetype();
if (tb->ty == Tfunction && ((TypeFunction *)tb)->isref)
return 1; // function returns a reference
return 0;
}
#endif
Expression *CallExp::toLvalue(Scope *sc, Expression *e)
{
if (type->toBasetype()->ty == Tstruct)
@@ -6309,6 +6665,13 @@ Expression *PtrExp::semantic(Scope *sc)
return this;
}
#if DMDV2
int PtrExp::isLvalue()
{
return 1;
}
#endif
Expression *PtrExp::toLvalue(Scope *sc, Expression *e)
{
#if 0
@@ -6321,6 +6684,21 @@ Expression *PtrExp::toLvalue(Scope *sc, Expression *e)
return this;
}
#if DMDV2
Expression *PtrExp::modifiableLvalue(Scope *sc, Expression *e)
{
//printf("PtrExp::modifiableLvalue() %s, type %s\n", toChars(), type->toChars());
if (e1->op == TOKsymoff)
{ SymOffExp *se = (SymOffExp *)e1;
se->var->checkModify(loc, sc, type);
//return toLvalue(sc, e);
}
return Expression::modifiableLvalue(sc, e);
}
#endif
void PtrExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writeByte('*');
@@ -6553,6 +6931,17 @@ CastExp::CastExp(Loc loc, Expression *e, Type *t)
to = t;
}
#if DMDV2
/* For cast(const) and cast(immutable)
*/
CastExp::CastExp(Loc loc, Expression *e, unsigned mod)
: UnaExp(loc, TOKcast, sizeof(CastExp), e)
{
to = NULL;
this->mod = mod;
}
#endif
Expression *CastExp::syntaxCopy()
{
return new CastExp(loc, e1->syntaxCopy(), to->syntaxCopy());
@@ -6637,7 +7026,35 @@ void CastExp::checkEscape()
void CastExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("cast(");
#if DMDV1
to->toCBuffer(buf, NULL, hgs);
#else
if (to)
to->toCBuffer(buf, NULL, hgs);
else
{
switch (mod)
{ case 0:
break;
case MODconst:
buf->writestring(Token::tochars[TOKconst]);
break;
case MODinvariant:
buf->writestring(Token::tochars[TOKimmutable]);
break;
case MODshared:
buf->writestring(Token::tochars[TOKshared]);
break;
case MODshared | MODconst:
buf->writestring(Token::tochars[TOKshared]);
buf->writeByte(' ');
buf->writestring(Token::tochars[TOKconst]);
break;
default:
assert(0);
}
}
#endif
buf->writeByte(')');
expToCBuffer(buf, hgs, e1, precedence[op]);
}
@@ -6831,6 +7248,13 @@ void SliceExp::checkEscape()
e1->checkEscape();
}
#if DMDV2
int SliceExp::isLvalue()
{
return 1;
}
#endif
Expression *SliceExp::toLvalue(Scope *sc, Expression *e)
{
return this;
@@ -6945,6 +7369,14 @@ Expression *ArrayExp::semantic(Scope *sc)
return e;
}
#if DMDV2
int ArrayExp::isLvalue()
{
if (type && type->toBasetype()->ty == Tvoid)
return 0;
return 1;
}
#endif
Expression *ArrayExp::toLvalue(Scope *sc, Expression *e)
{
@@ -7015,6 +7447,13 @@ void CommaExp::checkEscape()
e2->checkEscape();
}
#if DMDV2
int CommaExp::isLvalue()
{
return e2->isLvalue();
}
#endif
Expression *CommaExp::toLvalue(Scope *sc, Expression *e)
{
e2 = e2->toLvalue(sc, NULL);
@@ -7181,6 +7620,13 @@ Expression *IndexExp::semantic(Scope *sc)
return e;
}
#if DMDV2
int IndexExp::isLvalue()
{
return 1;
}
#endif
Expression *IndexExp::toLvalue(Scope *sc, Expression *e)
{
// if (type && type->toBasetype()->ty == Tvoid)
@@ -9034,9 +9480,21 @@ Expression *CondExp::semantic(Scope *sc)
break;
}
}
#if 0
printf("res: %s\n", type->toChars());
printf("e1 : %s\n", e1->type->toChars());
printf("e2 : %s\n", e2->type->toChars());
#endif
return this;
}
#if DMDV2
int CondExp::isLvalue()
{
return e1->isLvalue() && e2->isLvalue();
}
#endif
Expression *CondExp::toLvalue(Scope *sc, Expression *ex)
{
PtrExp *e;
@@ -9092,6 +9550,13 @@ int CondExp::checkSideEffect(int flag)
}
}
#if DMDV2
int CondExp::canThrow()
{
return econd->canThrow() || e1->canThrow() || e2->canThrow();
}
#endif
void CondExp::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
expToCBuffer(buf, hgs, econd, PREC_oror);

View File

@@ -825,14 +825,11 @@ struct DotVarExp : UnaExp
Expression *semantic(Scope *sc);
Expression *toLvalue(Scope *sc, Expression *e);
Expression *modifiableLvalue(Scope *sc, Expression *e);
Expression *optimize(int result);
Expression *interpret(InterState *istate);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void dump(int indent);
elem *toElem(IRState *irs);
//LDC: since we don't convert abc.def -> *(&abc + ABC.def.offsetof)
// these are needed
Expression *optimize(int result);
Expression *interpret(InterState *istate);
};
struct DotTemplateInstanceExp : UnaExp

View File

@@ -310,6 +310,8 @@ void FuncDeclaration::semantic(Scope *sc)
if (isFinal())
{
if (isOverride())
error("does not override any function");
cd->vtblFinal.push(this);
}
else
@@ -999,7 +1001,6 @@ void FuncDeclaration::semantic3(Scope *sc)
}
int offend = fbody ? fbody->blockExit() & BEfallthru : TRUE;
//int offend = fbody ? fbody->fallOffEnd() : TRUE;
if (isStaticCtorDeclaration())
{ /* It's a static constructor. Ensure that all

View File

@@ -112,7 +112,6 @@ void Import::load(Scope *sc)
}
if (!pkg)
pkg = mod;
mod->semantic();
//printf("-Import::load('%s'), pkg = %p\n", toChars(), pkg);
}
@@ -136,6 +135,12 @@ void Import::semantic(Scope *sc)
}
#endif
// Modules need a list of each imported module
//printf("%s imports %s\n", sc->module->toChars(), mod->toChars());
sc->module->aimports.push(mod);
mod->semantic();
/* Default to private importing
*/
protection = sc->protection;
@@ -147,9 +152,6 @@ void Import::semantic(Scope *sc)
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;
@@ -224,7 +226,9 @@ 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);
{ load(NULL);
mod->semantic();
}
// Forward it to the package/module
return pkg->search(loc, ident, flags);

File diff suppressed because it is too large Load Diff

120
dmd/man.c
View File

@@ -1,60 +1,60 @@
// Compiler implementation of the D programming language
// Copyright (c) 2008-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 <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 || __APPLE__
#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 = "firefox";
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
// Compiler implementation of the D programming language
// Copyright (c) 2008-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 <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 || __APPLE__
#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 = "firefox";
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

View File

@@ -63,7 +63,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.037";
version = "v1.038";
ldc_version = LDC_REV;
llvm_version = LLVM_REV;
global.structalign = 8;

View File

@@ -889,6 +889,38 @@ void Module::runDeferredSemantic()
//printf("-Module::runDeferredSemantic('%s'), len = %d\n", toChars(), deferred.dim);
}
/************************************
* Recursively look at every module this module imports,
* return TRUE if it imports m.
* Can be used to detect circular imports.
*/
int Module::imports(Module *m)
{
//printf("%s Module::imports(%s)\n", toChars(), m->toChars());
int aimports_dim = aimports.dim;
#if 0
for (int i = 0; i < aimports.dim; i++)
{ Module *mi = (Module *)aimports.data[i];
printf("\t[%d] %s\n", i, mi->toChars());
}
#endif
for (int i = 0; i < aimports.dim; i++)
{ Module *mi = (Module *)aimports.data[i];
if (mi == m)
return TRUE;
if (!mi->insearch)
{
mi->insearch = 1;
int r = mi->imports(m);
mi->insearch = 0;
if (r)
return r;
}
}
return FALSE;
}
/* =========================== ModuleDeclaration ===================== */
ModuleDeclaration::ModuleDeclaration(Array *packages, Identifier *id)

View File

@@ -141,6 +141,7 @@ struct Module : Package
void deleteObjFile();
void addDeferredSemantic(Dsymbol *s);
void runDeferredSemantic();
int imports(Module *m);
// Back end

View File

@@ -3721,6 +3721,34 @@ Type *TypeInstance::semantic(Loc loc, Scope *sc)
return t;
}
Dsymbol *TypeInstance::toDsymbol(Scope *sc)
{
Type *t;
Expression *e;
Dsymbol *s;
//printf("TypeInstance::semantic(%s)\n", toChars());
if (sc->parameterSpecialization)
{
unsigned errors = global.errors;
global.gag++;
resolve(loc, sc, &e, &t, &s);
global.gag--;
if (errors != global.errors)
{ if (global.gag == 0)
global.errors = errors;
return NULL;
}
}
else
resolve(loc, sc, &e, &t, &s);
return s;
}
/***************************** TypeTypeof *****************************/
@@ -4380,9 +4408,12 @@ Expression *TypeStruct::dotExp(Scope *sc, Expression *e, Identifier *ident)
return new IntegerExp(e->loc, 0, Type::tint32);
}
/* If e.tupleof
*/
if (ident == Id::tupleof)
{
/* Create a TupleExp
/* Create a TupleExp out of the fields of the struct e:
* (e.field0, e.field1, e.field2, ...)
*/
e = e->semantic(sc); // do this before turning on noaccesscheck
Expressions *exps = new Expressions;
@@ -4477,6 +4508,14 @@ L1:
return de;
}
Import *timp = s->isImport();
if (timp)
{
e = new DsymbolExp(e->loc, s);
e = e->semantic(sc);
return e;
}
d = s->isDeclaration();
#ifdef DEBUG
if (!d)
@@ -4521,9 +4560,7 @@ L1:
// *(&e + offset)
accessCheck(e->loc, sc, e, d);
// LDC we don't want dot exprs turned into pointer arithmetic. it complicates things for no apparent gain
#ifndef IN_LLVM
#if 0
b = new AddrExp(e->loc, e);
b->type = e->type->pointerTo();
b = new AddExp(e->loc, b, new IntegerExp(e->loc, v->offset, Type::tint32));

View File

@@ -507,6 +507,7 @@ struct TypeInstance : TypeQualified
void toCBuffer2(OutBuffer *buf, HdrGenState *hgs, int mod);
void resolve(Loc loc, Scope *sc, Expression **pe, Type **pt, Dsymbol **ps);
Type *semantic(Loc loc, Scope *sc);
Dsymbol *toDsymbol(Scope *sc);
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
};

File diff suppressed because it is too large Load Diff

View File

@@ -278,19 +278,35 @@ Expression *PtrExp::optimize(int result)
Expression *DotVarExp::optimize(int result)
{
//printf("DotVarExp::optimize(result = x%x) %s\n", result, toChars());
e1 = e1->optimize(result);
// Constant fold structliteral.member
#if DMDV2
if (e1->op == TOKvar)
{ VarExp *ve = (VarExp *)e1;
VarDeclaration *v = ve->var->isVarDeclaration();
Expression *e = expandVar(result, v);
if (e && e->op == TOKstructliteral)
{ StructLiteralExp *sle = (StructLiteralExp *)e;
VarDeclaration *vf = var->isVarDeclaration();
if (vf)
{
e = sle->getField(type, vf->offset);
if (e != EXP_CANT_INTERPRET)
return e;
}
}
}
else
#endif
if (e1->op == TOKstructliteral)
{ StructLiteralExp *se = (StructLiteralExp *)e1;
VarDeclaration* v;
if (v = var->isVarDeclaration())
{ StructLiteralExp *sle = (StructLiteralExp *)e1;
VarDeclaration *vf = var->isVarDeclaration();
if (vf)
{
Expression *e = se->getField(type, v->offset);
if (!e)
e = EXP_CANT_INTERPRET;
return e;
Expression *e = sle->getField(type, vf->offset);
if (e != EXP_CANT_INTERPRET)
return e;
}
}
@@ -322,6 +338,7 @@ Expression *CastExp::optimize(int result)
//printf("CastExp::optimize(result = %d) %s\n", result, toChars());
//printf("from %s to %s\n", type->toChars(), to->toChars());
//printf("from %s\n", type->toChars());
//printf("e1->type %s\n", e1->type->toChars());
//printf("type = %p\n", type);
assert(type);
enum TOK op1 = e1->op;

View File

@@ -124,13 +124,6 @@ int Statement::blockExit()
return BEany;
}
// TRUE if statement may fall off the end without a throw or return
int Statement::fallOffEnd()
{
return TRUE;
}
// TRUE if statement 'comes from' somewhere else, like a goto
int Statement::comeFrom()
@@ -227,21 +220,6 @@ int ExpStatement::blockExit()
return result;
}
int ExpStatement::fallOffEnd()
{
if (exp)
{
if (exp->op == TOKassert)
{ AssertExp *a = (AssertExp *)exp;
if (a->e1->isBool(FALSE)) // if it's an assert(0)
return FALSE;
}
else if (exp->op == TOKhalt)
return FALSE;
}
return TRUE;
}
/******************************** CompileStatement ***************************/
@@ -574,25 +552,6 @@ int CompoundStatement::blockExit()
return result;
}
int CompoundStatement::fallOffEnd()
{ int falloff = TRUE;
//printf("CompoundStatement::fallOffEnd() %s\n", toChars());
for (int i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *)statements->data[i];
if (!s)
continue;
if (!falloff && global.params.warnings && !s->comeFrom())
{
warning("%s: statement is not reachable", s->loc.toChars());
}
falloff = s->fallOffEnd();
}
return falloff;
}
int CompoundStatement::comeFrom()
{ int comefrom = FALSE;
@@ -710,18 +669,6 @@ int UnrolledLoopStatement::blockExit()
return result;
}
int UnrolledLoopStatement::fallOffEnd()
{
//printf("UnrolledLoopStatement::fallOffEnd()\n");
for (size_t i = 0; i < statements->dim; i++)
{ Statement *s = (Statement *)statements->data[i];
if (s)
s->fallOffEnd();
}
return TRUE;
}
int UnrolledLoopStatement::comeFrom()
{ int comefrom = FALSE;
@@ -815,11 +762,6 @@ int ScopeStatement::blockExit()
return statement ? statement->blockExit() : BEfallthru;
}
int ScopeStatement::fallOffEnd()
{
return statement ? statement->fallOffEnd() : TRUE;
}
int ScopeStatement::comeFrom()
{
//printf("ScopeStatement::comeFrom()\n");
@@ -945,13 +887,6 @@ int WhileStatement::blockExit()
return result;
}
int WhileStatement::fallOffEnd()
{
if (body)
body->fallOffEnd();
return TRUE;
}
int WhileStatement::comeFrom()
{
if (body)
@@ -1040,13 +975,6 @@ int DoStatement::blockExit()
return result;
}
int DoStatement::fallOffEnd()
{
if (body)
body->fallOffEnd();
return TRUE;
}
int DoStatement::comeFrom()
{
if (body)
@@ -1177,13 +1105,6 @@ int ForStatement::blockExit()
return result;
}
int ForStatement::fallOffEnd()
{
if (body)
body->fallOffEnd();
return TRUE;
}
int ForStatement::comeFrom()
{
//printf("ForStatement::comeFrom()\n");
@@ -1878,13 +1799,6 @@ int ForeachStatement::blockExit()
return result;
}
int ForeachStatement::fallOffEnd()
{
if (body)
body->fallOffEnd();
return TRUE;
}
int ForeachStatement::comeFrom()
{
if (body)
@@ -2042,15 +1956,6 @@ int IfStatement::blockExit()
return result;
}
int IfStatement::fallOffEnd()
{
if (!ifbody || ifbody->fallOffEnd() ||
!elsebody || elsebody->fallOffEnd())
return TRUE;
return FALSE;
}
void IfStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("if (");
@@ -2268,13 +2173,6 @@ int PragmaStatement::blockExit()
return result;
}
int PragmaStatement::fallOffEnd()
{
if (body)
return body->fallOffEnd();
return TRUE;
}
void PragmaStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("pragma (");
@@ -2475,13 +2373,6 @@ int SwitchStatement::blockExit()
return result;
}
int SwitchStatement::fallOffEnd()
{
if (body)
body->fallOffEnd();
return TRUE; // need to do this better
}
void SwitchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("switch (");
@@ -2586,11 +2477,6 @@ int CaseStatement::blockExit()
return statement->blockExit();
}
int CaseStatement::fallOffEnd()
{
return statement->fallOffEnd();
}
int CaseStatement::comeFrom()
{
return TRUE;
@@ -2650,11 +2536,6 @@ int DefaultStatement::blockExit()
return statement->blockExit();
}
int DefaultStatement::fallOffEnd()
{
return statement->fallOffEnd();
}
int DefaultStatement::comeFrom()
{
return TRUE;
@@ -2695,11 +2576,6 @@ int GotoDefaultStatement::blockExit()
return BEgoto;
}
int GotoDefaultStatement::fallOffEnd()
{
return FALSE;
}
void GotoDefaultStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("goto default;\n");
@@ -2749,11 +2625,6 @@ int GotoCaseStatement::blockExit()
return BEgoto;
}
int GotoCaseStatement::fallOffEnd()
{
return FALSE;
}
void GotoCaseStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("goto case");
@@ -2777,11 +2648,6 @@ int SwitchErrorStatement::blockExit()
return BEthrow;
}
int SwitchErrorStatement::fallOffEnd()
{
return FALSE;
}
void SwitchErrorStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("SwitchErrorStatement::toCBuffer()");
@@ -3056,11 +2922,6 @@ int ReturnStatement::blockExit()
return result;
}
int ReturnStatement::fallOffEnd()
{
return FALSE;
}
void ReturnStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->printf("return ");
@@ -3155,11 +3016,6 @@ int BreakStatement::blockExit()
return ident ? BEgoto : BEbreak;
}
int BreakStatement::fallOffEnd()
{
return FALSE;
}
void BreakStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("break");
@@ -3263,11 +3119,6 @@ int ContinueStatement::blockExit()
return ident ? BEgoto : BEcontinue;
}
int ContinueStatement::fallOffEnd()
{
return FALSE;
}
void ContinueStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("continue");
@@ -3358,11 +3209,6 @@ int SynchronizedStatement::blockExit()
return body ? body->blockExit() : BEfallthru;
}
int SynchronizedStatement::fallOffEnd()
{
return body ? body->fallOffEnd() : TRUE;
}
void SynchronizedStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("synchronized");
@@ -3480,11 +3326,6 @@ int WithStatement::blockExit()
return result;
}
int WithStatement::fallOffEnd()
{
return body ? body->fallOffEnd() : TRUE;
}
/******************************** TryCatchStatement ***************************/
TryCatchStatement::TryCatchStatement(Loc loc, Statement *body, Array *catches)
@@ -3556,22 +3397,6 @@ int TryCatchStatement::blockExit()
return result;
}
int TryCatchStatement::fallOffEnd()
{
int result = FALSE;
if (body)
result = body->fallOffEnd();
for (int i = 0; i < catches->dim; i++)
{ Catch *c;
c = (Catch *)catches->data[i];
if (c->handler)
result |= c->handler->fallOffEnd();
}
return result;
}
void TryCatchStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("try");
@@ -3728,18 +3553,11 @@ int TryFinallyStatement::usesEH()
int TryFinallyStatement::blockExit()
{
int result = body->blockExit();
return result;
if (body)
return body->blockExit();
return BEfallthru;
}
int TryFinallyStatement::fallOffEnd()
{ int result;
result = body ? body->fallOffEnd() : TRUE;
// if (finalbody)
// result = finalbody->fallOffEnd();
return result;
}
/****************************** OnScopeStatement ***************************/
@@ -3861,11 +3679,6 @@ int ThrowStatement::blockExit()
return BEthrow; // obviously
}
int ThrowStatement::fallOffEnd()
{
return FALSE;
}
void ThrowStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->printf("throw ");
@@ -3924,11 +3737,6 @@ int VolatileStatement::blockExit()
return statement ? statement->blockExit() : BEfallthru;
}
int VolatileStatement::fallOffEnd()
{
return statement ? statement->fallOffEnd() : TRUE;
}
void VolatileStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("volatile");
@@ -3993,11 +3801,6 @@ int GotoStatement::blockExit()
return BEgoto;
}
int GotoStatement::fallOffEnd()
{
return FALSE;
}
void GotoStatement::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
{
buf->writestring("goto ");
@@ -4087,11 +3890,6 @@ int LabelStatement::blockExit()
return statement ? statement->blockExit() : BEfallthru;
}
int LabelStatement::fallOffEnd()
{
return statement ? statement->fallOffEnd() : TRUE;
}
int LabelStatement::comeFrom()
{
//printf("LabelStatement::comeFrom()\n");

View File

@@ -148,7 +148,6 @@ struct Statement : Object
virtual int hasBreak();
virtual int hasContinue();
virtual int usesEH();
virtual int fallOffEnd();
virtual int blockExit();
virtual int comeFrom();
virtual void scopeCode(Statement **sentry, Statement **sexit, Statement **sfinally);
@@ -179,7 +178,6 @@ struct ExpStatement : Statement
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Statement *semantic(Scope *sc);
Expression *interpret(InterState *istate);
int fallOffEnd();
int blockExit();
int inlineCost(InlineCostState *ics);
@@ -225,7 +223,6 @@ struct CompoundStatement : Statement
virtual Statement *semantic(Scope *sc);
int usesEH();
int blockExit();
int fallOffEnd();
int comeFrom();
virtual Statements *flatten(Scope *sc);
ReturnStatement *isReturnStatement();
@@ -255,7 +252,6 @@ struct UnrolledLoopStatement : Statement
int hasContinue();
int usesEH();
int blockExit();
int fallOffEnd();
int comeFrom();
Expression *interpret(InterState *istate);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -280,7 +276,6 @@ struct ScopeStatement : Statement
int hasContinue();
int usesEH();
int blockExit();
int fallOffEnd();
int comeFrom();
Expression *interpret(InterState *istate);
@@ -302,7 +297,6 @@ struct WhileStatement : Statement
int hasContinue();
int usesEH();
int blockExit();
int fallOffEnd();
int comeFrom();
Expression *interpret(InterState *istate);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -325,7 +319,6 @@ struct DoStatement : Statement
int hasContinue();
int usesEH();
int blockExit();
int fallOffEnd();
int comeFrom();
Expression *interpret(InterState *istate);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -351,7 +344,6 @@ struct ForStatement : Statement
int hasContinue();
int usesEH();
int blockExit();
int fallOffEnd();
int comeFrom();
Expression *interpret(InterState *istate);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -384,7 +376,6 @@ struct ForeachStatement : Statement
int hasContinue();
int usesEH();
int blockExit();
int fallOffEnd();
int comeFrom();
Expression *interpret(InterState *istate);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -413,7 +404,6 @@ struct ForeachRangeStatement : Statement
int hasContinue();
int usesEH();
int blockExit();
int fallOffEnd();
int comeFrom();
Expression *interpret(InterState *istate);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -440,7 +430,6 @@ struct IfStatement : Statement
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
int usesEH();
int blockExit();
int fallOffEnd();
IfStatement *isIfStatement() { return this; }
int inlineCost(InlineCostState *ics);
@@ -477,7 +466,6 @@ struct PragmaStatement : Statement
Statement *semantic(Scope *sc);
int usesEH();
int blockExit();
int fallOffEnd();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
};
@@ -511,7 +499,6 @@ struct SwitchStatement : Statement
int hasBreak();
int usesEH();
int blockExit();
int fallOffEnd();
Expression *interpret(InterState *istate);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -533,7 +520,6 @@ struct CaseStatement : Statement
int compare(Object *obj);
int usesEH();
int blockExit();
int fallOffEnd();
int comeFrom();
Expression *interpret(InterState *istate);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -561,7 +547,6 @@ struct DefaultStatement : Statement
Statement *semantic(Scope *sc);
int usesEH();
int blockExit();
int fallOffEnd();
int comeFrom();
Expression *interpret(InterState *istate);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
@@ -584,7 +569,6 @@ struct GotoDefaultStatement : Statement
Statement *semantic(Scope *sc);
Expression *interpret(InterState *istate);
int blockExit();
int fallOffEnd();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void toIR(IRState *irs);
@@ -602,7 +586,6 @@ struct GotoCaseStatement : Statement
Statement *semantic(Scope *sc);
Expression *interpret(InterState *istate);
int blockExit();
int fallOffEnd();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void toIR(IRState *irs);
@@ -612,7 +595,6 @@ struct SwitchErrorStatement : Statement
{
SwitchErrorStatement(Loc loc);
int blockExit();
int fallOffEnd();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void toIR(IRState *irs);
@@ -628,7 +610,6 @@ struct ReturnStatement : Statement
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Statement *semantic(Scope *sc);
int blockExit();
int fallOffEnd();
Expression *interpret(InterState *istate);
int inlineCost(InlineCostState *ics);
@@ -650,7 +631,6 @@ struct BreakStatement : Statement
Statement *semantic(Scope *sc);
Expression *interpret(InterState *istate);
int blockExit();
int fallOffEnd();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void toIR(IRState *irs);
@@ -669,7 +649,6 @@ struct ContinueStatement : Statement
Statement *semantic(Scope *sc);
Expression *interpret(InterState *istate);
int blockExit();
int fallOffEnd();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
void toIR(IRState *irs);
@@ -691,7 +670,6 @@ struct SynchronizedStatement : Statement
int hasContinue();
int usesEH();
int blockExit();
int fallOffEnd();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Statement *inlineScan(InlineScanState *iss);
@@ -715,7 +693,6 @@ struct WithStatement : Statement
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
int usesEH();
int blockExit();
int fallOffEnd();
Statement *inlineScan(InlineScanState *iss);
@@ -733,7 +710,6 @@ struct TryCatchStatement : Statement
int hasBreak();
int usesEH();
int blockExit();
int fallOffEnd();
Statement *inlineScan(InlineScanState *iss);
@@ -771,7 +747,6 @@ struct TryFinallyStatement : Statement
int hasContinue();
int usesEH();
int blockExit();
int fallOffEnd();
Statement *inlineScan(InlineScanState *iss);
@@ -803,7 +778,6 @@ struct ThrowStatement : Statement
Statement *semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
int blockExit();
int fallOffEnd();
Statement *inlineScan(InlineScanState *iss);
@@ -820,7 +794,6 @@ struct VolatileStatement : Statement
Statement *semantic(Scope *sc);
Statements *flatten(Scope *sc);
int blockExit();
int fallOffEnd();
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Statement *inlineScan(InlineScanState *iss);
@@ -839,7 +812,6 @@ struct GotoStatement : Statement
Statement *syntaxCopy();
Statement *semantic(Scope *sc);
int blockExit();
int fallOffEnd();
Expression *interpret(InterState *istate);
void toIR(IRState *irs);
@@ -862,7 +834,6 @@ struct LabelStatement : Statement
Statements *flatten(Scope *sc);
int usesEH();
int blockExit();
int fallOffEnd();
int comeFrom();
Expression *interpret(InterState *istate);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);

View File

@@ -201,8 +201,10 @@ int match(Object *o1, Object *o2, TemplateDeclaration *tempdecl, Scope *sc)
goto Lnomatch;
}
}
//printf("match\n");
return 1; // match
Lnomatch:
//printf("nomatch\n");
return 0; // nomatch;
}
@@ -320,7 +322,9 @@ void TemplateDeclaration::semantic(Scope *sc)
if (sc->func)
{
#if DMDV1
error("cannot declare template at function scope %s", sc->func->toChars());
#endif
}
if (/*global.params.useArrayBounds &&*/ sc->module)
@@ -551,7 +555,9 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
if (!flag)
{
// Any parameter left without a type gets the type of its corresponding arg
/* Any parameter left without a type gets the type of
* its corresponding arg
*/
for (int i = 0; i < dedtypes_dim; i++)
{
if (!dedtypes->data[i])
@@ -561,6 +567,25 @@ MATCH TemplateDeclaration::matchWithInstance(TemplateInstance *ti,
}
}
#if DMDV2
if (m && constraint && !(flag & 1))
{ /* Check to see if constraint is satisfied.
*/
Expression *e = constraint->syntaxCopy();
paramscope->flags |= SCOPEstaticif;
e = e->semantic(paramscope);
e = e->optimize(WANTvalue | WANTinterpret);
if (e->isBool(TRUE))
;
else if (e->isBool(FALSE))
goto Lnomatch;
else
{
e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars());
}
}
#endif
#if LOGM
// Print out the results
printf("--------------------------\n");
@@ -674,7 +699,9 @@ int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
/*************************************************
* Match function arguments against a specific template function.
* Input:
* loc instantiation location
* targsi Expression/Type initial list of template arguments
* ethis 'this' argument if !NULL
* fargs arguments to function
* Output:
* dedargs Expression/Type deduced template arguments
@@ -682,7 +709,8 @@ int TemplateDeclaration::leastAsSpecialized(TemplateDeclaration *td2)
* match level
*/
MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs,
MATCH TemplateDeclaration::deduceFunctionTemplateMatch(Loc loc, Objects *targsi,
Expression *ethis, Expressions *fargs,
Objects *dedargs)
{
size_t i;
@@ -824,6 +852,27 @@ L1:
}
L2:
#if DMDV2
// Match 'ethis' to any TemplateThisParameter's
if (ethis)
{
for (size_t i = 0; i < parameters->dim; i++)
{ TemplateParameter *tp = (TemplateParameter *)parameters->data[i];
TemplateThisParameter *ttp = tp->isTemplateThisParameter();
if (ttp)
{ MATCH m;
Type *t = new TypeIdentifier(0, ttp->ident);
m = ethis->type->deduceType(scope, t, parameters, &dedtypes);
if (!m)
goto Lnomatch;
if (m < match)
match = m; // pick worst match
}
}
}
#endif
// Loop through the function parameters
for (i = 0; i < nfparams; i++)
{
@@ -982,7 +1031,7 @@ Lmatch:
}
}
else
{ oded = tp->defaultArg(paramscope);
{ oded = tp->defaultArg(loc, paramscope);
if (!oded)
goto Lnomatch;
}
@@ -991,6 +1040,25 @@ Lmatch:
}
}
#if DMDV2
if (constraint)
{ /* Check to see if constraint is satisfied.
*/
Expression *e = constraint->syntaxCopy();
paramscope->flags |= SCOPEstaticif;
e = e->semantic(paramscope);
e = e->optimize(WANTvalue | WANTinterpret);
if (e->isBool(TRUE))
;
else if (e->isBool(FALSE))
goto Lnomatch;
else
{
e->error("constraint %s is not constant or does not evaluate to a bool", e->toChars());
}
}
#endif
#if 0
for (i = 0; i < dedargs->dim; i++)
{ Type *t = (Type *)dedargs->data[i];
@@ -1096,11 +1164,13 @@ int TemplateDeclaration::isOverloadable()
* sc instantiation scope
* loc instantiation location
* targsi initial list of template arguments
* ethis if !NULL, the 'this' pointer argument
* fargs arguments to function
* flags 1: do not issue error message on no match, just return NULL
*/
FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
Objects *targsi, Expressions *fargs)
Objects *targsi, Expression *ethis, Expressions *fargs, int flags)
{
MATCH m_best = MATCHnomatch;
TemplateDeclaration *td_ambig = NULL;
@@ -1142,7 +1212,7 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
MATCH m;
Objects dedargs;
m = td->deduceFunctionTemplateMatch(targsi, fargs, &dedargs);
m = td->deduceFunctionTemplateMatch(loc, targsi, ethis, fargs, &dedargs);
//printf("deduceFunctionTemplateMatch = %d\n", m);
if (!m) // if no match
continue;
@@ -1207,14 +1277,26 @@ FuncDeclaration *TemplateDeclaration::deduceFunctionTemplate(Scope *sc, Loc loc,
Lerror:
{
OutBuffer buf;
HdrGenState hgs;
OutBuffer bufa;
Objects *args = targsi;
if (args)
{ for (int i = 0; i < args->dim; i++)
{
if (i)
bufa.writeByte(',');
Object *oarg = (Object *)args->data[i];
ObjectToCBuffer(&bufa, &hgs, oarg);
}
}
OutBuffer buf;
argExpTypesToCBuffer(&buf, fargs, &hgs);
error(loc, "cannot deduce template function from argument types (%s)",
buf.toChars());
return NULL;
error(loc, "cannot deduce template function from argument types !(%s)(%s)",
bufa.toChars(), buf.toChars());
}
return NULL;
}
void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
@@ -1237,6 +1319,13 @@ void TemplateDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
tp->toCBuffer(buf, hgs);
}
buf->writeByte(')');
#if DMDV2
if (constraint)
{ buf->writestring(" if (");
constraint->toCBuffer(buf, hgs);
buf->writeByte(')');
}
#endif
if (hgs->hdrgen)
{
@@ -1271,6 +1360,13 @@ char *TemplateDeclaration::toChars()
tp->toCBuffer(&buf, &hgs);
}
buf.writeByte(')');
#if DMDV2
if (constraint)
{ buf.writestring(" if (");
constraint->toCBuffer(&buf, &hgs);
buf.writeByte(')');
}
#endif
buf.writeByte(0);
return (char *)buf.extractData();
}
@@ -1323,9 +1419,11 @@ int templateParameterLookup(Type *tparam, TemplateParameters *parameters)
MATCH Type::deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters,
Objects *dedtypes)
{
//printf("Type::deduceType()\n");
//printf("\tthis = %d, ", ty); print();
//printf("\ttparam = %d, ", tparam->ty); tparam->print();
#if 0
printf("Type::deduceType()\n");
printf("\tthis = %d, ", ty); print();
printf("\ttparam = %d, ", tparam->ty); tparam->print();
#endif
if (!tparam)
goto Lnomatch;
@@ -2027,7 +2125,7 @@ MATCH TemplateTypeParameter::matchArg(Scope *sc, Objects *tiargs,
oarg = (Object *)tiargs->data[i];
else
{ // Get default argument instead
oarg = defaultArg(sc);
oarg = defaultArg(loc, sc);
if (!oarg)
{ assert(i < dedtypes->dim);
// It might have already been deduced
@@ -2141,7 +2239,7 @@ Object *TemplateTypeParameter::specialization()
}
Object *TemplateTypeParameter::defaultArg(Scope *sc)
Object *TemplateTypeParameter::defaultArg(Loc loc, Scope *sc)
{
Type *t;
@@ -2271,7 +2369,7 @@ MATCH TemplateAliasParameter::matchArg(Scope *sc,
oarg = (Object *)tiargs->data[i];
else
{ // Get default argument instead
oarg = defaultArg(sc);
oarg = defaultArg(loc, sc);
if (!oarg)
{ assert(i < dedtypes->dim);
// It might have already been deduced
@@ -2357,7 +2455,7 @@ Object *TemplateAliasParameter::specialization()
}
Object *TemplateAliasParameter::defaultArg(Scope *sc)
Object *TemplateAliasParameter::defaultArg(Loc loc, Scope *sc)
{
Dsymbol *s = NULL;
@@ -2485,7 +2583,7 @@ MATCH TemplateValueParameter::matchArg(Scope *sc,
oarg = (Object *)tiargs->data[i];
else
{ // Get default argument instead
oarg = defaultArg(sc);
oarg = defaultArg(loc, sc);
if (!oarg)
{ assert(i < dedtypes->dim);
// It might have already been deduced
@@ -2602,7 +2700,7 @@ Object *TemplateValueParameter::specialization()
}
Object *TemplateValueParameter::defaultArg(Scope *sc)
Object *TemplateValueParameter::defaultArg(Loc loc, Scope *sc)
{
Expression *e = defaultValue;
if (e)
@@ -2748,7 +2846,7 @@ Object *TemplateTupleParameter::specialization()
}
Object *TemplateTupleParameter::defaultArg(Scope *sc)
Object *TemplateTupleParameter::defaultArg(Loc loc, Scope *sc)
{
return NULL;
}
@@ -2778,6 +2876,10 @@ TemplateInstance::TemplateInstance(Loc loc, Identifier *ident)
this->tinst = NULL;
}
/*****************
* This constructor is only called when we figured out which function
* template to instantiate.
*/
TemplateInstance::TemplateInstance(Loc loc, TemplateDeclaration *td, Objects *tiargs)
: ScopeDsymbol(NULL)
@@ -2830,7 +2932,6 @@ Objects *TemplateInstance::arraySyntaxCopy(Objects *objs)
Dsymbol *TemplateInstance::syntaxCopy(Dsymbol *s)
{
TemplateInstance *ti;
int i;
if (s)
ti = (TemplateInstance *)s;
@@ -2896,7 +2997,9 @@ void TemplateInstance::semantic(Scope *sc)
}
else
{
// Run semantic on each argument, place results in tiargs[]
/* Run semantic on each argument, place results in tiargs[]
* (if we havetempdecl, then tiargs is already evaluated)
*/
semanticTiargs(sc);
tempdecl = findTemplateDeclaration(sc);
@@ -2974,12 +3077,26 @@ void TemplateInstance::semantic(Scope *sc)
#if 1
int dosemantic3 = 0;
{ Array *a;
int i;
if (sc->scopesym && sc->scopesym->members && !sc->scopesym->isTemplateMixin())
Scope *scx = sc;
#if 0
for (scx = sc; scx; scx = scx->enclosing)
if (scx->scopesym)
break;
#endif
//if (scx && scx->scopesym) printf("3: scx is %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
if (scx && scx->scopesym &&
scx->scopesym->members && !scx->scopesym->isTemplateMixin() &&
/* The following test should really be if scx->module recursively
* imports itself. Because if it does, see bugzilla 2500.
*/
//scx->module == tempdecl->getModule()
!scx->module->imports(scx->module)
)
{
//printf("\t1: adding to %s %s\n", sc->scopesym->kind(), sc->scopesym->toChars());
a = sc->scopesym->members;
//printf("\t1: adding to %s %s\n", scx->scopesym->kind(), scx->scopesym->toChars());
a = scx->scopesym->members;
}
else
{ Module *m = sc->module->importedFrom;
@@ -3395,19 +3512,15 @@ TemplateDeclaration *TemplateInstance::findBestMatch(Scope *sc)
return NULL;
}
m = td->matchWithInstance(this, &dedtypes, 0);
//printf("m = %d\n", m);
//printf("matchWithInstance = %d\n", m);
if (!m) // no match at all
continue;
#if 1
if (m < m_best)
goto Ltd_best;
if (m > m_best)
goto Ltd;
#else
if (!m_best)
goto Ltd;
#endif
{
// Disambiguate by picking the most specialized TemplateDeclaration
int c1 = td->leastAsSpecialized(td_best);
@@ -3656,6 +3769,7 @@ Identifier *TemplateInstance::genIdent()
buf.writeByte('Z');
id = buf.toChars();
buf.data = NULL;
//printf("\tgenIdent = %s\n", id);
return new Identifier(id, TOKidentifier);
}
@@ -3672,7 +3786,7 @@ void TemplateInstance::declareParameters(Scope *scope)
{
TemplateParameter *tp = (TemplateParameter *)tempdecl->parameters->data[i];
//Object *o = (Object *)tiargs->data[i];
Object *o = (Object *)tdtypes.data[i];
Object *o = (Object *)tdtypes.data[i]; // initializer for tp
//printf("\ttdtypes[%d] = %p\n", i, o);
tempdecl->declareParameter(scope, tp, o);

View File

@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2006 by Digital Mars
// Copyright (c) 1999-2008 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -54,7 +54,9 @@ struct TemplateDeclaration : ScopeDsymbol
TemplateParameters *parameters; // array of TemplateParameter's
TemplateParameters *origParameters; // originals for Ddoc
#if DMDV2
Expression *constraint;
#endif
Array instances; // array of TemplateInstance's
TemplateDeclaration *overnext; // next overloaded TemplateDeclaration
@@ -63,7 +65,11 @@ struct TemplateDeclaration : ScopeDsymbol
Scope *scope;
Dsymbol *onemember; // if !=NULL then one member of this template
TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters, Array *decldefs);
TemplateDeclaration(Loc loc, Identifier *id, TemplateParameters *parameters,
#if DMDV2
Expression *constraint,
#endif
Array *decldefs);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
int overloadInsert(Dsymbol *s);
@@ -77,8 +83,8 @@ struct TemplateDeclaration : ScopeDsymbol
MATCH matchWithInstance(TemplateInstance *ti, Objects *atypes, int flag);
int leastAsSpecialized(TemplateDeclaration *td2);
MATCH deduceFunctionTemplateMatch(Objects *targsi, Expressions *fargs, Objects *dedargs);
FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expressions *fargs);
MATCH deduceFunctionTemplateMatch(Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, Objects *dedargs);
FuncDeclaration *deduceFunctionTemplate(Scope *sc, Loc loc, Objects *targsi, Expression *ethis, Expressions *fargs, int flags = 0);
void declareParameter(Scope *sc, TemplateParameter *tp, Object *o);
TemplateDeclaration *isTemplateDeclaration() { return this; }
@@ -112,6 +118,9 @@ struct TemplateParameter
virtual TemplateTypeParameter *isTemplateTypeParameter();
virtual TemplateValueParameter *isTemplateValueParameter();
virtual TemplateAliasParameter *isTemplateAliasParameter();
#if DMDV2
virtual TemplateThisParameter *isTemplateThisParameter();
#endif
virtual TemplateTupleParameter *isTemplateTupleParameter();
virtual TemplateParameter *syntaxCopy() = 0;
@@ -120,7 +129,7 @@ struct TemplateParameter
virtual void print(Object *oarg, Object *oded) = 0;
virtual void toCBuffer(OutBuffer *buf, HdrGenState *hgs) = 0;
virtual Object *specialization() = 0;
virtual Object *defaultArg(Scope *sc) = 0;
virtual Object *defaultArg(Loc loc, Scope *sc) = 0;
/* If TemplateParameter's match as far as overloading goes.
*/
@@ -152,7 +161,7 @@ struct TemplateTypeParameter : TemplateParameter
void print(Object *oarg, Object *oded);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Object *specialization();
Object *defaultArg(Scope *sc);
Object *defaultArg(Loc loc, Scope *sc);
int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
void *dummyArg();
@@ -196,7 +205,7 @@ struct TemplateValueParameter : TemplateParameter
void print(Object *oarg, Object *oded);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Object *specialization();
Object *defaultArg(Scope *sc);
Object *defaultArg(Loc loc, Scope *sc);
int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
void *dummyArg();
@@ -224,7 +233,7 @@ struct TemplateAliasParameter : TemplateParameter
void print(Object *oarg, Object *oded);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Object *specialization();
Object *defaultArg(Scope *sc);
Object *defaultArg(Loc loc, Scope *sc);
int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
void *dummyArg();
@@ -245,7 +254,7 @@ struct TemplateTupleParameter : TemplateParameter
void print(Object *oarg, Object *oded);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
Object *specialization();
Object *defaultArg(Scope *sc);
Object *defaultArg(Loc loc, Scope *sc);
int overloadMatch(TemplateParameter *);
MATCH matchArg(Scope *sc, Objects *tiargs, int i, TemplateParameters *parameters, Objects *dedtypes, Declaration **psparam);
void *dummyArg();

View File

@@ -1375,7 +1375,7 @@ void VolatileStatement::toIR(IRState* p)
statement->toIR(p);
// no point in a unreachable barrier, terminating statements must insert this themselves.
if (statement->fallOffEnd())
if (statement->blockExit() & BEfallthru)
{
// store-load
DtoMemoryBarrier(false, false, true, false);