mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
fixes #428 :: apply DMDFE 1.061; thanks SiegeLord
This commit is contained in:
@@ -338,7 +338,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
||||
}
|
||||
if (!tc->sym->symtab || tc->sym->sizeok == 0)
|
||||
{ // Try to resolve forward reference
|
||||
if (sc->mustsemantic && tc->sym->scope)
|
||||
if (/*sc->mustsemantic &&*/ tc->sym->scope)
|
||||
tc->sym->semantic(NULL);
|
||||
}
|
||||
if (!tc->sym->symtab || tc->sym->scope || tc->sym->sizeok == 0)
|
||||
@@ -406,7 +406,7 @@ void ClassDeclaration::semantic(Scope *sc)
|
||||
|
||||
if (!tc->sym->symtab)
|
||||
{ // Try to resolve forward reference
|
||||
if (sc->mustsemantic && tc->sym->scope)
|
||||
if (/*sc->mustsemantic &&*/ tc->sym->scope)
|
||||
tc->sym->semantic(NULL);
|
||||
}
|
||||
|
||||
|
||||
@@ -523,7 +523,7 @@ void AliasDeclaration::semantic(Scope *sc)
|
||||
//printf("alias is a symbol %s %s\n", s->kind(), s->toChars());
|
||||
type = NULL;
|
||||
VarDeclaration *v = s->isVarDeclaration();
|
||||
if (v && v->linkage == LINKdefault)
|
||||
if (0 && v && v->linkage == LINKdefault)
|
||||
{
|
||||
error("forward reference of %s", v->toChars());
|
||||
s = NULL;
|
||||
@@ -831,8 +831,8 @@ void VarDeclaration::semantic(Scope *sc)
|
||||
OutBuffer buf;
|
||||
buf.printf("_%s_field_%zu", ident->toChars(), i);
|
||||
buf.writeByte(0);
|
||||
char *name = (char *)buf.extractData();
|
||||
Identifier *id = new Identifier(name, TOKidentifier);
|
||||
const char *name = (const char *)buf.extractData();
|
||||
Identifier *id = Lexer::idPool(name);
|
||||
|
||||
Expression *einit = ie;
|
||||
if (ie && ie->op == TOKtuple)
|
||||
|
||||
@@ -14,6 +14,7 @@
|
||||
|
||||
#include "rmem.h"
|
||||
#include "speller.h"
|
||||
#include "aav.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "dsymbol.h"
|
||||
@@ -1197,60 +1198,89 @@ Dsymbol *ArrayScopeSymbol::search(Loc loc, Identifier *ident, int flags)
|
||||
|
||||
DsymbolTable::DsymbolTable()
|
||||
{
|
||||
#if STRINGTABLE
|
||||
tab = new StringTable;
|
||||
#else
|
||||
tab = NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
DsymbolTable::~DsymbolTable()
|
||||
{
|
||||
#if STRINGTABLE
|
||||
delete tab;
|
||||
#endif
|
||||
}
|
||||
|
||||
Dsymbol *DsymbolTable::lookup(Identifier *ident)
|
||||
{
|
||||
#if STRINGTABLE
|
||||
#ifdef DEBUG
|
||||
assert(ident);
|
||||
assert(tab);
|
||||
#endif
|
||||
//printf("DsymbolTable::lookup(%s)\n", (char*)ident->string);
|
||||
StringValue *sv = tab->lookup((char*)ident->string, ident->len);
|
||||
return (Dsymbol *)(sv ? sv->ptrvalue : NULL);
|
||||
#else
|
||||
//printf("DsymbolTable::lookup(%s)\n", (char*)ident->string);
|
||||
return (Dsymbol *)_aaGetRvalue(tab, ident);
|
||||
#endif
|
||||
}
|
||||
|
||||
Dsymbol *DsymbolTable::insert(Dsymbol *s)
|
||||
{ StringValue *sv;
|
||||
Identifier *ident;
|
||||
|
||||
{
|
||||
//printf("DsymbolTable::insert(this = %p, '%s')\n", this, s->ident->toChars());
|
||||
ident = s->ident;
|
||||
Identifier *ident = s->ident;
|
||||
#if STRINGTABLE
|
||||
#ifdef DEBUG
|
||||
assert(ident);
|
||||
assert(tab);
|
||||
#endif
|
||||
sv = tab->insert(ident->toChars(), ident->len);
|
||||
StringValue *sv = tab->insert(ident->toChars(), ident->len);
|
||||
if (!sv)
|
||||
return NULL; // already in table
|
||||
sv->ptrvalue = s;
|
||||
return s;
|
||||
#else
|
||||
Dsymbol **ps = (Dsymbol **)_aaGet(&tab, ident);
|
||||
if (*ps)
|
||||
return NULL; // already in table
|
||||
*ps = s;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
Dsymbol *DsymbolTable::insert(Identifier *ident, Dsymbol *s)
|
||||
{ StringValue *sv;
|
||||
|
||||
{
|
||||
//printf("DsymbolTable::insert()\n");
|
||||
sv = tab->insert(ident->toChars(), ident->len);
|
||||
#if STRINGTABLE
|
||||
StringValue *sv = tab->insert(ident->toChars(), ident->len);
|
||||
if (!sv)
|
||||
return NULL; // already in table
|
||||
sv->ptrvalue = s;
|
||||
return s;
|
||||
#else
|
||||
Dsymbol **ps = (Dsymbol **)_aaGet(&tab, ident);
|
||||
if (*ps)
|
||||
return NULL; // already in table
|
||||
*ps = s;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
Dsymbol *DsymbolTable::update(Dsymbol *s)
|
||||
{ StringValue *sv;
|
||||
Identifier *ident;
|
||||
|
||||
ident = s->ident;
|
||||
sv = tab->update(ident->toChars(), ident->len);
|
||||
{
|
||||
Identifier *ident = s->ident;
|
||||
#if STRINGTABLE
|
||||
StringValue *sv = tab->update(ident->toChars(), ident->len);
|
||||
sv->ptrvalue = s;
|
||||
return s;
|
||||
#else
|
||||
Dsymbol **ps = (Dsymbol **)_aaGet(&tab, ident);
|
||||
*ps = s;
|
||||
return s;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -77,6 +77,7 @@ struct HdrGenState;
|
||||
struct TypeInfoDeclaration;
|
||||
struct ClassInfoDeclaration;
|
||||
struct OverloadSet;
|
||||
struct AA;
|
||||
#if TARGET_NET
|
||||
struct PragmaScope;
|
||||
#endif
|
||||
@@ -355,7 +356,11 @@ struct OverloadSet : Dsymbol
|
||||
|
||||
struct DsymbolTable : Object
|
||||
{
|
||||
#if STRINGTABLE
|
||||
StringTable *tab;
|
||||
#else
|
||||
AA *tab;
|
||||
#endif
|
||||
|
||||
DsymbolTable();
|
||||
~DsymbolTable();
|
||||
|
||||
@@ -2131,12 +2131,17 @@ Expression *IdentifierExp::semantic(Scope *sc)
|
||||
return e;
|
||||
}
|
||||
#endif
|
||||
|
||||
s = sc->search_correct(ident);
|
||||
if (s)
|
||||
error("undefined identifier %s, did you mean %s %s?", ident->toChars(), s->kind(), s->toChars());
|
||||
const char *n = importHint(ident->toChars());
|
||||
if (n)
|
||||
error("'%s' is not defined, perhaps you need to import %s; ?", ident->toChars(), n);
|
||||
else
|
||||
error("undefined identifier %s", ident->toChars());
|
||||
{
|
||||
s = sc->search_correct(ident);
|
||||
if (s)
|
||||
error("undefined identifier %s, did you mean %s %s?", ident->toChars(), s->kind(), s->toChars());
|
||||
else
|
||||
error("undefined identifier %s", ident->toChars());
|
||||
}
|
||||
return new ErrorExp();
|
||||
}
|
||||
|
||||
@@ -2251,7 +2256,9 @@ Lagain:
|
||||
{
|
||||
//printf("Identifier '%s' is a variable, type '%s'\n", toChars(), v->type->toChars());
|
||||
if (!type)
|
||||
{ type = v->type;
|
||||
{ if (!v->type && v->scope)
|
||||
v->semantic(v->scope);
|
||||
type = v->type;
|
||||
if (!v->type)
|
||||
{ error("forward reference of %s", v->toChars());
|
||||
type = Type::terror;
|
||||
@@ -2299,6 +2306,9 @@ Lagain:
|
||||
f = s->isFuncDeclaration();
|
||||
if (f)
|
||||
{ //printf("'%s' is a function\n", f->toChars());
|
||||
|
||||
if (!f->originalType && f->scope) // semantic not yet run
|
||||
f->semantic(f->scope);
|
||||
if (!f->type->deco)
|
||||
{
|
||||
error("forward reference to %s", toChars());
|
||||
@@ -3510,33 +3520,36 @@ Expression *ScopeExp::semantic(Scope *sc)
|
||||
Lagain:
|
||||
ti = sds->isTemplateInstance();
|
||||
if (ti && !global.errors)
|
||||
{ Dsymbol *s;
|
||||
{
|
||||
if (!ti->semanticRun)
|
||||
ti->semantic(sc);
|
||||
s = ti->inst->toAlias();
|
||||
sds2 = s->isScopeDsymbol();
|
||||
if (!sds2)
|
||||
{ Expression *e;
|
||||
|
||||
//printf("s = %s, '%s'\n", s->kind(), s->toChars());
|
||||
if (ti->withsym)
|
||||
{
|
||||
// Same as wthis.s
|
||||
e = new VarExp(loc, ti->withsym->withstate->wthis);
|
||||
e = new DotVarExp(loc, e, s->isDeclaration());
|
||||
}
|
||||
else
|
||||
e = new DsymbolExp(loc, s);
|
||||
e = e->semantic(sc);
|
||||
//printf("-1ScopeExp::semantic()\n");
|
||||
return e;
|
||||
}
|
||||
if (sds2 != sds)
|
||||
if (ti->inst)
|
||||
{
|
||||
sds = sds2;
|
||||
goto Lagain;
|
||||
Dsymbol *s = ti->inst->toAlias();
|
||||
sds2 = s->isScopeDsymbol();
|
||||
if (!sds2)
|
||||
{ Expression *e;
|
||||
|
||||
//printf("s = %s, '%s'\n", s->kind(), s->toChars());
|
||||
if (ti->withsym)
|
||||
{
|
||||
// Same as wthis.s
|
||||
e = new VarExp(loc, ti->withsym->withstate->wthis);
|
||||
e = new DotVarExp(loc, e, s->isDeclaration());
|
||||
}
|
||||
else
|
||||
e = new DsymbolExp(loc, s);
|
||||
e = e->semantic(sc);
|
||||
//printf("-1ScopeExp::semantic()\n");
|
||||
return e;
|
||||
}
|
||||
if (sds2 != sds)
|
||||
{
|
||||
sds = sds2;
|
||||
goto Lagain;
|
||||
}
|
||||
//printf("sds = %s, '%s'\n", sds->kind(), sds->toChars());
|
||||
}
|
||||
//printf("sds = %s, '%s'\n", sds->kind(), sds->toChars());
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -168,7 +168,7 @@ void FuncDeclaration::semantic(Scope *sc)
|
||||
parent = sc->parent;
|
||||
Dsymbol *parent = toParent();
|
||||
|
||||
if (semanticRun == PASSsemanticdone)
|
||||
if (semanticRun >= PASSsemanticdone)
|
||||
{
|
||||
if (!parent->isClassDeclaration())
|
||||
return;
|
||||
|
||||
@@ -63,7 +63,7 @@ Global::Global()
|
||||
|
||||
copyright = "Copyright (c) 1999-2010 by Digital Mars and Tomas Lindquist Olsen";
|
||||
written = "written by Walter Bright and Tomas Lindquist Olsen";
|
||||
version = "v1.060";
|
||||
version = "v1.061";
|
||||
ldc_version = LDC_REV;
|
||||
llvm_version = LLVM_REV_STR;
|
||||
global.structalign = 8;
|
||||
|
||||
@@ -442,6 +442,8 @@ void err_nomem();
|
||||
void inifile(char *argv0, const char *inifile);
|
||||
void halt();
|
||||
|
||||
const char *importHint(const char *s);
|
||||
|
||||
/*** Where to send error messages ***/
|
||||
#if IN_GCC || IN_LLVM
|
||||
#define stdmsg stderr
|
||||
|
||||
@@ -46,6 +46,8 @@ Expression *fromConstInitializer(Expression *e1)
|
||||
if (e1->op == TOKvar)
|
||||
{ VarExp *ve = (VarExp *)e1;
|
||||
VarDeclaration *v = ve->var->isVarDeclaration();
|
||||
if (v && !v->originalType && v->scope) // semantic() not yet run
|
||||
v->semantic (v->scope);
|
||||
if (v && v->isConst() && v->init)
|
||||
{ Expression *ei = v->init->toExpression();
|
||||
if (ei && ei->type)
|
||||
|
||||
14
dmd/scope.c
14
dmd/scope.c
@@ -23,6 +23,7 @@
|
||||
#include "aggregate.h"
|
||||
#include "module.h"
|
||||
#include "id.h"
|
||||
#include "lexer.h"
|
||||
|
||||
Scope *Scope::freelist = NULL;
|
||||
|
||||
@@ -372,10 +373,19 @@ void Scope::setNoFree()
|
||||
void *scope_search_fp(void *arg, const char *seed)
|
||||
{
|
||||
//printf("scope_search_fp('%s')\n", seed);
|
||||
|
||||
/* If not in the lexer's string table, it certainly isn't in the symbol table.
|
||||
* Doing this first is a lot faster.
|
||||
*/
|
||||
StringValue *sv = Lexer::stringtable.lookup(seed, strlen(seed));
|
||||
if (!sv)
|
||||
return NULL;
|
||||
Identifier *id = (Identifier *)sv->ptrvalue;
|
||||
assert(id);
|
||||
|
||||
Scope *sc = (Scope *)arg;
|
||||
Identifier id(seed, 0);
|
||||
Module::clearCache();
|
||||
Dsymbol *s = sc->search(0, &id, NULL);
|
||||
Dsymbol *s = sc->search(0, id, NULL);
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
216
dmd/speller.c
216
dmd/speller.c
@@ -2,6 +2,7 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
#include "speller.h"
|
||||
|
||||
@@ -12,112 +13,188 @@ const char idchars[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123
|
||||
* Currently only looks a 'distance' of one from the seed[].
|
||||
* This does an exhaustive search, so can potentially be very slow.
|
||||
* Input:
|
||||
*seedwrongly spelled word
|
||||
*fpsearch function
|
||||
*fpargargument to search function
|
||||
*charsetcharacter set
|
||||
* seed wrongly spelled word
|
||||
* fp search function
|
||||
* fparg argument to search function
|
||||
* charset character set
|
||||
* Returns:
|
||||
*NULLno correct spellings found
|
||||
*void*value returned by fp() for first possible correct spelling
|
||||
* NULL no correct spellings found
|
||||
* void* value returned by fp() for first possible correct spelling
|
||||
*/
|
||||
|
||||
void *spellerX(const char *seed, fp_speller_t fp, void *fparg, const char *charset, int flag)
|
||||
void *spellerY(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg,
|
||||
const char *charset, size_t index)
|
||||
{
|
||||
if (!seedlen)
|
||||
return NULL;
|
||||
assert(seed[seedlen] == 0);
|
||||
|
||||
char tmp[30];
|
||||
char *buf;
|
||||
if (seedlen <= sizeof(tmp) - 2)
|
||||
buf = tmp;
|
||||
else
|
||||
{
|
||||
buf = (char *)alloca(seedlen + 2); // leave space for extra char
|
||||
if (!buf)
|
||||
return NULL; // no matches
|
||||
}
|
||||
|
||||
memcpy(buf, seed, index);
|
||||
|
||||
/* Delete at seed[index] */
|
||||
if (index < seedlen)
|
||||
{
|
||||
memcpy(buf + index, seed + index + 1, seedlen - index);
|
||||
assert(buf[seedlen - 1] == 0);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
|
||||
if (charset && *charset)
|
||||
{
|
||||
/* Substitutions */
|
||||
if (index < seedlen)
|
||||
{
|
||||
memcpy(buf, seed, seedlen + 1);
|
||||
for (const char *s = charset; *s; s++)
|
||||
{
|
||||
buf[index] = *s;
|
||||
|
||||
//printf("sub buf = '%s'\n", buf);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
assert(buf[seedlen] == 0);
|
||||
}
|
||||
|
||||
/* Insertions */
|
||||
memcpy (buf + index + 1, seed + index, seedlen + 1 - index);
|
||||
|
||||
for (const char *s = charset; *s; s++)
|
||||
{
|
||||
buf[index] = *s;
|
||||
|
||||
//printf("ins buf = '%s'\n", buf);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
assert(buf[seedlen + 1] == 0);
|
||||
}
|
||||
|
||||
return NULL; // didn't find any corrections
|
||||
}
|
||||
|
||||
void *spellerX(const char *seed, size_t seedlen, fp_speller_t fp, void *fparg,
|
||||
const char *charset, int flag)
|
||||
{
|
||||
size_t seedlen = strlen(seed);
|
||||
if (!seedlen)
|
||||
return NULL;
|
||||
|
||||
char *buf = (char *)alloca(seedlen + 2);// leave space for extra char
|
||||
if (!buf)
|
||||
return NULL;// no matches
|
||||
char tmp[30];
|
||||
char *buf;
|
||||
if (seedlen <= sizeof(tmp) - 2)
|
||||
buf = tmp;
|
||||
else
|
||||
{
|
||||
buf = (char *)alloca(seedlen + 2); // leave space for extra char
|
||||
if (!buf)
|
||||
return NULL; // no matches
|
||||
}
|
||||
|
||||
/* Deletions */
|
||||
memcpy(buf, seed + 1, seedlen);
|
||||
for (int i = 0; i < seedlen; i++)
|
||||
{
|
||||
//printf("del buf = '%s'\n", buf);
|
||||
{
|
||||
//printf("del buf = '%s'\n", buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
||||
p = spellerY(buf, seedlen - 1, fp, fparg, charset, i);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
if (p)
|
||||
return p;
|
||||
|
||||
buf[i] = seed[i];
|
||||
}
|
||||
buf[i] = seed[i];
|
||||
}
|
||||
|
||||
/* Transpositions */
|
||||
memcpy(buf, seed, seedlen + 1);
|
||||
for (int i = 0; i + 1 < seedlen; i++)
|
||||
if (!flag)
|
||||
{
|
||||
memcpy(buf, seed, seedlen + 1);
|
||||
for (int i = 0; i + 1 < seedlen; i++)
|
||||
{
|
||||
// swap [i] and [i + 1]
|
||||
buf[i] = seed[i + 1];
|
||||
buf[i + 1] = seed[i];
|
||||
|
||||
//printf("tra buf = '%s'\n", buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
void *p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
|
||||
buf[i] = seed[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (charset && *charset)
|
||||
{
|
||||
/* Substitutions */
|
||||
memcpy(buf, seed, seedlen + 1);
|
||||
for (int i = 0; i < seedlen; i++)
|
||||
{
|
||||
/* Substitutions */
|
||||
memcpy(buf, seed, seedlen + 1);
|
||||
for (int i = 0; i < seedlen; i++)
|
||||
{
|
||||
for (const char *s = charset; *s; s++)
|
||||
{
|
||||
buf[i] = *s;
|
||||
for (const char *s = charset; *s; s++)
|
||||
{
|
||||
buf[i] = *s;
|
||||
|
||||
//printf("sub buf = '%s'\n", buf);
|
||||
//printf("sub buf = '%s'\n", buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
||||
p = spellerY(buf, seedlen, fp, fparg, charset, i + 1);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
buf[i] = seed[i];
|
||||
}
|
||||
|
||||
/* Insertions */
|
||||
memcpy(buf + 1, seed, seedlen + 1);
|
||||
for (int i = 0; i <= seedlen; i++)// yes, do seedlen+1 iterations
|
||||
{
|
||||
for (const char *s = charset; *s; s++)
|
||||
{
|
||||
buf[i] = *s;
|
||||
|
||||
//printf("ins buf = '%s'\n", buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerX(buf, fp, fparg, charset, flag - 1);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
buf[i] = seed[i];// going past end of seed[] is ok, as we hit the 0
|
||||
}
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
buf[i] = seed[i];
|
||||
}
|
||||
|
||||
return NULL;// didn't find any corrections
|
||||
/* Insertions */
|
||||
memcpy(buf + 1, seed, seedlen + 1);
|
||||
for (int i = 0; i <= seedlen; i++) // yes, do seedlen+1 iterations
|
||||
{
|
||||
for (const char *s = charset; *s; s++)
|
||||
{
|
||||
buf[i] = *s;
|
||||
|
||||
//printf("ins buf = '%s'\n", buf);
|
||||
void *p;
|
||||
if (flag)
|
||||
p = spellerY(buf, seedlen + 1, fp, fparg, charset, i + 1);
|
||||
else
|
||||
p = (*fp)(fparg, buf);
|
||||
if (p)
|
||||
return p;
|
||||
}
|
||||
buf[i] = seed[i]; // going past end of seed[] is ok, as we hit the 0
|
||||
}
|
||||
}
|
||||
|
||||
return NULL; // didn't find any corrections
|
||||
}
|
||||
|
||||
void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charset)
|
||||
{
|
||||
size_t seedlen = strlen(seed);
|
||||
for (int distance = 0; distance < 2; distance++)
|
||||
{ void *p = spellerX(seed, fp, fparg, charset, distance);
|
||||
{ void *p = spellerX(seed, seedlen, fp, fparg, charset, distance);
|
||||
if (p)
|
||||
return p;
|
||||
// if (seedlen > 10)
|
||||
// break;
|
||||
}
|
||||
return NULL; // didn't find it
|
||||
}
|
||||
@@ -131,6 +208,7 @@ void *speller(const char *seed, fp_speller_t fp, void *fparg, const char *charse
|
||||
|
||||
void *speller_test(void *fparg, const char *s)
|
||||
{
|
||||
//printf("speller_test(%s, %s)\n", fparg, s);
|
||||
if (strcmp((char *)fparg, s) == 0)
|
||||
return fparg;
|
||||
return NULL;
|
||||
@@ -141,18 +219,28 @@ void unittest_speller()
|
||||
static const char *cases[][3] =
|
||||
{
|
||||
{ "hello", "hell", "y" },
|
||||
{ "hello", "abcd", "n" },
|
||||
{ "hello", "hel", "y" },
|
||||
{ "ehllo", "helol", "y" },
|
||||
{ "hello", "ello", "y" },
|
||||
{ "hello", "llo", "y" },
|
||||
{ "hello", "hellox", "y" },
|
||||
{ "hello", "helloxy", "y" },
|
||||
{ "hello", "xhello", "y" },
|
||||
{ "hello", "xyhello", "y" },
|
||||
{ "hello", "ehllo", "y" },
|
||||
{ "hello", "helol", "y" },
|
||||
{ "hello", "abcd", "n" },
|
||||
//{ "ehllo", "helol", "y" },
|
||||
{ "hello", "helxxlo", "y" },
|
||||
{ "hello", "ehlxxlo", "n" },
|
||||
{ "hello", "heaao", "y" },
|
||||
{ "_123456789_123456789_123456789_123456789", "_123456789_123456789_123456789_12345678", "y" },
|
||||
};
|
||||
//printf("unittest_speller()\n");
|
||||
void *p = speller("hello", &speller_test, (void *)"hell", idchars);
|
||||
const void *p = speller("hello", &speller_test, (void *)"hell", idchars);
|
||||
assert(p != NULL);
|
||||
for (int i = 0; i < sizeof(cases)/sizeof(cases[0]); i++)
|
||||
{
|
||||
//printf("case [%d]\n", i);
|
||||
void *p = speller(cases[i][0], &speller_test, (void *)cases[i][1], idchars);
|
||||
if (p)
|
||||
assert(cases[i][2][0] == 'y');
|
||||
|
||||
@@ -122,6 +122,8 @@ unsigned AggregateDeclaration::size(Loc loc)
|
||||
//printf("AggregateDeclaration::size() = %d\n", structsize);
|
||||
if (!members)
|
||||
error(loc, "unknown size");
|
||||
if (sizeok != 1 && scope)
|
||||
semantic(NULL);
|
||||
if (sizeok != 1)
|
||||
{ error(loc, "no size yet for forward reference");
|
||||
//*(char*)0=0;
|
||||
@@ -181,6 +183,8 @@ void AggregateDeclaration::addField(Scope *sc, VarDeclaration *v)
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ts->sym->sizeok != 1 && ts->sym->scope)
|
||||
ts->sym->semantic(NULL);
|
||||
if (ts->sym->sizeok != 1)
|
||||
{
|
||||
sizeok = 2; // cannot finish; flag as forward referenced
|
||||
|
||||
@@ -3544,7 +3544,11 @@ void TemplateInstance::semantic(Scope *sc)
|
||||
}
|
||||
errors = 1;
|
||||
if (global.gag)
|
||||
{ // Try to reset things so we can try again later to instantiate it
|
||||
tempdecl->instances.remove(tempdecl_instance_idx);
|
||||
semanticRun = 0;
|
||||
inst = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#if LOG
|
||||
|
||||
Reference in New Issue
Block a user