Merge DMD r243: some harmonization with D2 dmd

---
 dmd/aggregate.h   |   24 ++++-
 dmd/attrib.c      |   63 ++++++----
 dmd/attrib.h      |   10 +-
 dmd/declaration.h |    5 +-
 dmd/func.c        |  337 ++++++++++++++++++++++-------------------------------
 dmd/mars.c        |    2 +-
 dmd/mars.h        |    7 +
 dmd/mtype.h       |   13 ++-
 dmd/parse.c       |   32 ++++-
 dmd/parse.h       |   14 ++-
 dmd/scope.h       |    2 +-
 11 files changed, 263 insertions(+), 246 deletions(-)
This commit is contained in:
Leandro Lucarella
2010-01-06 15:18:19 -03:00
parent 7192b16ef9
commit 7d2c329195
11 changed files with 263 additions and 246 deletions

View File

@@ -16,6 +16,7 @@
#endif /* __DMC__ */
#include "root.h"
#include "dsymbol.h"
#include <vector>
@@ -49,7 +50,7 @@ namespace llvm
struct AggregateDeclaration : ScopeDsymbol
{
Type *type;
unsigned storage_class;
StorageClass storage_class;
enum PROT protection;
Type *handle; // 'this' type
unsigned structsize; // size of struct
@@ -63,6 +64,10 @@ struct AggregateDeclaration : ScopeDsymbol
// 2: cannot determine size; fwd referenced
int isdeprecated; // !=0 if deprecated
#if DMDV2
int isnested; // !=0 if is nested
VarDeclaration *vthis; // 'this' parameter if this aggregate is nested
#endif
// Special member functions
InvariantDeclaration *inv; // invariant
NewDeclaration *aggNew; // allocator
@@ -92,6 +97,7 @@ struct AggregateDeclaration : ScopeDsymbol
void addField(Scope *sc, VarDeclaration *v);
int isDeprecated(); // is aggregate deprecated?
FuncDeclaration *buildDtor(Scope *sc);
int isNested();
void emitComment(Scope *sc);
void toJsonBuffer(OutBuffer *buf);
@@ -147,7 +153,15 @@ struct StructDeclaration : AggregateDeclaration
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
char *mangle();
const char *kind();
#if DMDV1
Expression *cloneMembers();
#endif
#if DMDV2
int needOpAssign();
FuncDeclaration *buildOpAssign(Scope *sc);
FuncDeclaration *buildPostBlit(Scope *sc);
FuncDeclaration *buildCpCtor(Scope *sc);
#endif
void toDocBuffer(OutBuffer *buf);
PROT getAccess(Dsymbol *smember); // determine access to smember
@@ -209,8 +223,10 @@ struct ClassDeclaration : AggregateDeclaration
static ClassDeclaration *classinfo;
ClassDeclaration *baseClass; // NULL only if this is Object
#if DMDV1
CtorDeclaration *ctor;
CtorDeclaration *defaultCtor; // default constructor
#endif
FuncDeclaration *staticCtor;
FuncDeclaration *staticDtor;
Array vtbl; // Array of FuncDeclaration's making up the vtbl[]
@@ -231,10 +247,10 @@ struct ClassDeclaration : AggregateDeclaration
// it derives from IUnknown)
int isscope; // !=0 if this is a scope class
int isabstract; // !=0 if abstract class
#if DMDV1
int isnested; // !=0 if is nested
VarDeclaration *vthis; // 'this' parameter if this class is nested
#endif
int inuse; // to prevent recursive attempts
ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses);
@@ -252,7 +268,9 @@ struct ClassDeclaration : AggregateDeclaration
#endif
FuncDeclaration *findFunc(Identifier *ident, TypeFunction *tf);
void interfaceSemantic(Scope *sc);
#if DMDV1
int isNested();
#endif
int isCOMclass();
virtual int isCOMinterface();
#if DMDV2

View File

@@ -78,7 +78,7 @@ int AttribDeclaration::addMember(Scope *sc, ScopeDsymbol *sd, int memnum)
}
void AttribDeclaration::setScopeNewSc(Scope *sc,
unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection,
StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
unsigned structalign)
{
if (decl)
@@ -113,7 +113,7 @@ void AttribDeclaration::setScopeNewSc(Scope *sc,
}
void AttribDeclaration::semanticNewSc(Scope *sc,
unsigned stc, enum LINK linkage, enum PROT protection, int explicitProtection,
StorageClass stc, enum LINK linkage, enum PROT protection, int explicitProtection,
unsigned structalign)
{
if (decl)
@@ -360,7 +360,7 @@ void AttribDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
/************************* StorageClassDeclaration ****************************/
StorageClassDeclaration::StorageClassDeclaration(unsigned stc, Array *decl)
StorageClassDeclaration::StorageClassDeclaration(StorageClass stc, Array *decl)
: AttribDeclaration(decl)
{
this->stc = stc;
@@ -379,7 +379,7 @@ void StorageClassDeclaration::setScope(Scope *sc)
{
if (decl)
{
unsigned scstc = sc->stc;
StorageClass scstc = sc->stc;
/* These sets of storage classes are mutually exclusive,
* so choose the innermost or most recent one.
@@ -402,7 +402,7 @@ void StorageClassDeclaration::semantic(Scope *sc)
{
if (decl)
{
unsigned scstc = sc->stc;
StorageClass scstc = sc->stc;
/* These sets of storage classes are mutually exclusive,
* so choose the innermost or most recent one.
@@ -421,11 +421,11 @@ void StorageClassDeclaration::semantic(Scope *sc)
}
}
void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc)
void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, StorageClass stc)
{
struct SCstring
{
int stc;
StorageClass stc;
enum TOK tok;
};
@@ -441,6 +441,19 @@ void StorageClassDeclaration::stcToCBuffer(OutBuffer *buf, int stc)
{ STCsynchronized, TOKsynchronized },
{ STCdeprecated, TOKdeprecated },
{ STCoverride, TOKoverride },
{ STClazy, TOKlazy },
{ STCalias, TOKalias },
{ STCout, TOKout },
{ STCin, TOKin },
#if DMDV2
{ STCimmutable, TOKimmutable },
{ STCshared, TOKshared },
{ STCnothrow, TOKnothrow },
{ STCpure, TOKpure },
{ STCref, TOKref },
{ STCtls, TOKtls },
{ STCgshared, TOKgshared },
#endif
};
for (int i = 0; i < sizeof(table)/sizeof(table[0]); i++)
@@ -1006,25 +1019,27 @@ void PragmaDeclaration::semantic(Scope *sc)
goto Lnodecl;
}
#endif
#if DMDV2
else if (ident == Id::startaddress)
{
if (!args || args->dim != 1)
error("function name expected for start address");
else
{
Expression *e = (Expression *)args->data[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
args->data[0] = (void *)e;
Dsymbol *sa = getDsymbol(e);
if (!sa || !sa->isFuncDeclaration())
error("function name expected for start address, not '%s'", e->toChars());
}
goto Lnodecl;
}
#endif
#if TARGET_NET
else if (ident == Lexer::idPool("assembly"))
{
if (!args || args->dim != 1)
error("pragma has invalid number of arguments");
else
{
Expression *e = (Expression *)args->data[0];
e = e->semantic(sc);
e = e->optimize(WANTvalue | WANTinterpret);
args->data[0] = (void *)e;
if (e->op != TOKstring)
{
error("string expected, not '%s'", e->toChars());
}
PragmaScope* pragma = new PragmaScope(this, sc->parent, static_cast<StringExp*>(e));
decl = new Array;
decl->push(pragma);
}
}
#endif // TARGET_NET
@@ -1385,7 +1400,7 @@ void PragmaDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
e->toCBuffer(buf, hgs);
}
}
buf->writestring(")");
buf->writeByte(')');
AttribDeclaration::toCBuffer(buf, hgs);
}

View File

@@ -37,10 +37,10 @@ struct AttribDeclaration : Dsymbol
virtual Array *include(Scope *sc, ScopeDsymbol *s);
int addMember(Scope *sc, ScopeDsymbol *s, int memnum);
void setScopeNewSc(Scope *sc,
unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection,
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
unsigned structalign);
void semanticNewSc(Scope *sc,
unsigned newstc, enum LINK linkage, enum PROT protection, int explictProtection,
StorageClass newstc, enum LINK linkage, enum PROT protection, int explictProtection,
unsigned structalign);
void semantic(Scope *sc);
void semantic2(Scope *sc);
@@ -69,15 +69,15 @@ struct AttribDeclaration : Dsymbol
struct StorageClassDeclaration: AttribDeclaration
{
unsigned stc;
StorageClass stc;
StorageClassDeclaration(unsigned stc, Array *decl);
StorageClassDeclaration(StorageClass stc, Array *decl);
Dsymbol *syntaxCopy(Dsymbol *s);
void setScope(Scope *sc);
void semantic(Scope *sc);
void toCBuffer(OutBuffer *buf, HdrGenState *hgs);
static void stcToCBuffer(OutBuffer *buf, int stc);
static void stcToCBuffer(OutBuffer *buf, StorageClass stc);
};
struct LinkDeclaration : AttribDeclaration

View File

@@ -104,7 +104,7 @@ struct Declaration : Dsymbol
{
Type *type;
Type *originalType; // before semantic analysis
unsigned storage_class;
StorageClass storage_class;
enum PROT protection;
enum LINK linkage;
int inuse; // used to detect cycles
@@ -260,6 +260,7 @@ struct VarDeclaration : Declaration
int noscope; // no scope semantics
#if DMDV2
FuncDeclarations nestedrefs; // referenced by these lexically nested functions
bool isargptr; // if parameter that _argptr points to
#else
int nestedref; // referenced by a lexically nested function
#endif
@@ -712,7 +713,7 @@ struct FuncDeclaration : Declaration
int nestedFrameRef; // !=0 if nested variables referenced
#endif
FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type);
FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type);
Dsymbol *syntaxCopy(Dsymbol *);
void semantic(Scope *sc);
void semantic2(Scope *sc);

View File

@@ -31,7 +31,7 @@
/********************************* FuncDeclaration ****************************/
FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC storage_class, Type *type)
FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, StorageClass storage_class, Type *type)
: Declaration(id)
{
//printf("FuncDeclaration(id = '%s', type = %p)\n", id->toChars(), type);
@@ -124,7 +124,7 @@ Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
if (s)
f = (FuncDeclaration *)s;
else
f = new FuncDeclaration(loc, endloc, ident, (enum STC) storage_class, type->syntaxCopy());
f = new FuncDeclaration(loc, endloc, ident, storage_class, type->syntaxCopy());
f->outId = outId;
f->frequire = frequire ? frequire->syntaxCopy() : NULL;
f->fensure = fensure ? fensure->syntaxCopy() : NULL;
@@ -446,7 +446,6 @@ void FuncDeclaration::semantic(Scope *sc)
*/
for (int i = 0; i < cd->interfaces_dim; i++)
{
#if 1
BaseClass *b = cd->interfaces[i];
vi = findVtblIndex(&b->base->vtbl, b->base->vtbl.dim);
switch (vi)
@@ -499,68 +498,6 @@ void FuncDeclaration::semantic(Scope *sc)
goto L2;
}
}
#else
BaseClass *b = cd->interfaces[i];
for (vi = 0; vi < b->base->vtbl.dim; vi++)
{
Dsymbol *s = (Dsymbol *)b->base->vtbl.data[vi];
//printf("interface %d vtbl[%d] %p %s\n", i, vi, s, s->toChars());
FuncDeclaration *fdv = s->isFuncDeclaration();
if (fdv && fdv->ident == ident)
{
int cov = type->covariant(fdv->type);
//printf("\tcov = %d\n", cov);
if (cov == 2)
{
//type->print();
//fdv->type->print();
//printf("%s %s\n", type->deco, fdv->type->deco);
error("of type %s overrides but is not covariant with %s of type %s",
type->toChars(), fdv->toPrettyChars(), fdv->type->toChars());
}
if (cov == 1)
{ Type *ti = NULL;
if (fdv->tintro)
ti = fdv->tintro;
else if (!type->equals(fdv->type))
{
/* Only need to have a tintro if the vptr
* offsets differ
*/
int offset;
if (fdv->type->nextOf()->isBaseOf(type->nextOf(), &offset))
{
ti = fdv->type;
#if 0
if (offset)
ti = fdv->type;
else if (type->nextOf()->ty == Tclass)
{ ClassDeclaration *cdn = ((TypeClass *)type->nextOf())->sym;
if (cdn && cdn->sizeok != 1)
ti = fdv->type;
}
#endif
}
}
if (ti)
{
if (tintro && !tintro->equals(ti))
{
error("incompatible covariant types %s and %s", tintro->toChars(), ti->toChars());
}
tintro = ti;
}
goto L2;
}
if (cov == 3)
{
cd->sizeok = 2; // can't finish due to forward reference
return;
}
}
}
#endif
}
if (introducing && isOverride())
@@ -1312,13 +1249,11 @@ void FuncDeclaration::semantic3(Scope *sc)
v_argptr = argptr;
v_argptr->init = new VoidInitializer(loc);
#else
Expression *e1;
Expression *e;
Type *t = argptr->type;
VarDeclaration *p;
unsigned offset;
e1 = new VarExp(0, argptr);
Expression *e1 = new VarExp(0, argptr);
if (parameters && parameters->dim)
p = (VarDeclaration *)parameters->data[parameters->dim - 1];
else
@@ -1329,7 +1264,7 @@ void FuncDeclaration::semantic3(Scope *sc)
else
offset = p->type->size();
offset = (offset + 3) & ~3; // assume stack aligns on 4
e = new SymOffExp(0, p, offset);
Expression *e = new SymOffExp(0, p, offset);
e = new AssignExp(0, e1, e);
e->type = t;
a->push(new ExpStatement(0, e));
@@ -1918,48 +1853,6 @@ FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t, Module* from)
return p.f;
}
#if 0
FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t)
{
FuncDeclaration *f;
Declaration *d;
Declaration *next;
for (d = this; d; d = next)
{ FuncAliasDeclaration *fa = d->isFuncAliasDeclaration();
if (fa)
{
FuncDeclaration *f2 = fa->funcalias->overloadExactMatch(t);
if (f2)
return f2;
next = fa->overnext;
}
else
{
AliasDeclaration *a = d->isAliasDeclaration();
if (a)
{
Dsymbol *s = a->toAlias();
next = s->isDeclaration();
if (next == a)
break;
}
else
{
f = d->isFuncDeclaration();
if (!f)
break; // BUG: should print error message?
if (t->equals(d->type))
return f;
next = f->overnext;
}
}
}
return NULL;
}
#endif
/********************************************
* Decide which function matches the arguments best.
@@ -1968,6 +1861,9 @@ FuncDeclaration *FuncDeclaration::overloadExactMatch(Type *t)
struct Param2
{
Match *m;
#if DMDV2
Expression *ethis;
#endif
Expressions *arguments;
};
@@ -1998,6 +1894,22 @@ int fp2(void *param, FuncDeclaration *f)
else if (f->overrides(m->lastf))
goto LfIsBetter;
#if DMDV2
/* Try to disambiguate using template-style partial ordering rules.
* In essence, if f() and g() are ambiguous, if f() can call g(),
* but g() cannot call f(), then pick f().
* This is because f() is "more specialized."
*/
{
MATCH c1 = f->leastAsSpecialized(m->lastf);
MATCH c2 = m->lastf->leastAsSpecialized(f);
//printf("c1 = %d, c2 = %d\n", c1, c2);
if (c1 > c2)
goto LfIsBetter;
if (c1 < c2)
goto LlastIsBetter;
}
#endif
Lambiguous:
m->nextf = f;
m->count++;
@@ -2026,87 +1938,6 @@ void overloadResolveX(Match *m, FuncDeclaration *fstart,
overloadApply(from, fstart, &fp2, &p);
}
#if 0
// Recursive helper function
void overloadResolveX(Match *m, FuncDeclaration *fstart, Expressions *arguments)
{
MATCH match;
Declaration *d;
Declaration *next;
for (d = fstart; d; d = next)
{
FuncDeclaration *f;
FuncAliasDeclaration *fa;
AliasDeclaration *a;
fa = d->isFuncAliasDeclaration();
if (fa)
{
overloadResolveX(m, fa->funcalias, NULL, arguments);
next = fa->overnext;
}
else if ((f = d->isFuncDeclaration()) != NULL)
{
next = f->overnext;
if (f == m->lastf)
continue; // skip duplicates
else
{
TypeFunction *tf;
m->anyf = f;
tf = (TypeFunction *)f->type;
match = (MATCH) tf->callMatch(arguments);
//printf("2match = %d\n", match);
if (match != MATCHnomatch)
{
if (match > m->last)
goto LfIsBetter;
if (match < m->last)
goto LlastIsBetter;
/* See if one of the matches overrides the other.
*/
if (m->lastf->overrides(f))
goto LlastIsBetter;
else if (f->overrides(m->lastf))
goto LfIsBetter;
Lambiguous:
m->nextf = f;
m->count++;
continue;
LfIsBetter:
m->last = match;
m->lastf = f;
m->count = 1;
continue;
LlastIsBetter:
continue;
}
}
}
else if ((a = d->isAliasDeclaration()) != NULL)
{
Dsymbol *s = a->toAlias();
next = s->isDeclaration();
if (next == a)
break;
if (next == fstart)
break;
}
else
{ d->error("is aliased to a function");
break;
}
}
}
#endif
FuncDeclaration *FuncDeclaration::overloadResolve(Loc loc, Expression *ethis, Expressions *arguments, Module *from, int flags)
{
@@ -2179,6 +2010,118 @@ if (arguments)
}
}
/*************************************
* Determine partial specialization order of 'this' vs g.
* This is very similar to TemplateDeclaration::leastAsSpecialized().
* Returns:
* match 'this' is at least as specialized as g
* 0 g is more specialized than 'this'
*/
#if DMDV2
MATCH FuncDeclaration::leastAsSpecialized(FuncDeclaration *g)
{
#define LOG_LEASTAS 0
#if LOG_LEASTAS
printf("%s.leastAsSpecialized(%s)\n", toChars(), g->toChars());
#endif
/* This works by calling g() with f()'s parameters, and
* if that is possible, then f() is at least as specialized
* as g() is.
*/
TypeFunction *tf = (TypeFunction *)type;
TypeFunction *tg = (TypeFunction *)g->type;
size_t nfparams = Argument::dim(tf->parameters);
size_t ngparams = Argument::dim(tg->parameters);
MATCH match = MATCHexact;
/* If both functions have a 'this' pointer, and the mods are not
* the same and g's is not const, then this is less specialized.
*/
if (needThis() && g->needThis())
{
if (tf->mod != tg->mod)
{
if (tg->mod == MODconst)
match = MATCHconst;
else
return MATCHnomatch;
}
}
/* Create a dummy array of arguments out of the parameters to f()
*/
Expressions args;
args.setDim(nfparams);
for (int u = 0; u < nfparams; u++)
{
Argument *p = Argument::getNth(tf->parameters, u);
Expression *e;
if (p->storageClass & (STCref | STCout))
{
e = new IdentifierExp(0, p->ident);
e->type = p->type;
}
else
e = p->type->defaultInit();
args.data[u] = e;
}
MATCH m = (MATCH) tg->callMatch(NULL, &args);
if (m)
{
/* A variadic parameter list is less specialized than a
* non-variadic one.
*/
if (tf->varargs && !tg->varargs)
goto L1; // less specialized
#if LOG_LEASTAS
printf(" matches %d, so is least as specialized\n", m);
#endif
return m;
}
L1:
#if LOG_LEASTAS
printf(" doesn't match, so is not as specialized\n");
#endif
return MATCHnomatch;
}
/*******************************************
* Given a symbol that could be either a FuncDeclaration or
* a function template, resolve it to a function symbol.
* 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 *resolveFuncCall(Scope *sc, Loc loc, Dsymbol *s,
Objects *tiargs,
Expression *ethis,
Expressions *arguments,
int flags)
{
if (!s)
return NULL; // no match
FuncDeclaration *f = s->isFuncDeclaration();
if (f)
f = f->overloadResolve(loc, ethis, arguments);
else
{ TemplateDeclaration *td = s->isTemplateDeclaration();
assert(td);
f = td->deduceFunctionTemplate(sc, loc, tiargs, NULL, arguments, flags);
}
return f;
}
#endif
/********************************
* Labels are in a separate scope, one per function.
*/
@@ -2298,15 +2241,14 @@ void FuncDeclaration::appendExp(Expression *e)
}
void FuncDeclaration::appendState(Statement *s)
{ CompoundStatement *cs;
{
if (!fbody)
{ Statements *a;
a = new Statements();
fbody = new CompoundStatement(0, a);
}
cs = fbody->isCompoundStatement();
CompoundStatement *cs = fbody->isCompoundStatement();
cs->statements->push(s);
}
@@ -2362,7 +2304,7 @@ int FuncDeclaration::isVirtual()
{
#if 0
printf("FuncDeclaration::isVirtual(%s)\n", toChars());
printf("%p %d %d %d %d\n", isMember(), isStatic(), protection == PROTprivate, isCtorDeclaration(), linkage != LINKd);
printf("isMember:%p isStatic:%d private:%d ctor:%d !Dlinkage:%d\n", isMember(), isStatic(), protection == PROTprivate, isCtorDeclaration(), linkage != LINKd);
printf("result is %d\n",
isMember() &&
!(isStatic() || protection == PROTprivate || protection == PROTpackage) &&
@@ -2407,7 +2349,7 @@ int FuncDeclaration::isNested()
{
//if (!toParent())
//printf("FuncDeclaration::isNested('%s') parent=%p\n", toChars(), parent);
//printf("\ttoParent() = '%s'\n", toParent()->toChars());
//printf("\ttoParent2() = '%s'\n", toParent2()->toChars());
return ((storage_class & STCstatic) == 0) && toParent2() &&
(toParent2()->isFuncDeclaration() != NULL);
}
@@ -3078,6 +3020,7 @@ void StaticDtorDeclaration::semantic(Scope *sc)
m = sc->module;
if (m)
{ m->needmoduleinfo = 1;
//printf("module2 %s needs moduleinfo\n", m->toChars());
#ifdef IN_GCC
m->strictlyneedmoduleinfo = 1;
#endif

View File

@@ -58,7 +58,7 @@ Global::Global()
copyright = "Copyright (c) 1999-2009 by Digital Mars and Tomas Lindquist Olsen";
written = "written by Walter Bright and Tomas Lindquist Olsen";
version = "v1.051";
version = "v1.052";
ldc_version = LDC_REV;
llvm_version = LLVM_REV_STR;
global.structalign = 8;

View File

@@ -93,6 +93,10 @@ the target object file format:
#define BREAKABI 1 // 0 if not ready to break the ABI just yet
#define STRUCTTHISREF DMDV2 // if 'this' for struct is a reference, not a pointer
#define SNAN_DEFAULT_INIT DMDV2 // if floats are default initialized to signalling NaN
#define SARRAYVALUE DMDV2 // static arrays are value types
// Set if C++ mangling is done by the front end
#define CPP_MANGLE (DMDV2 && (TARGET_LINUX || TARGET_OSX || TARGET_FREEBSD || TARGET_SOLARIS))
/* Other targets are TARGET_LINUX, TARGET_OSX, TARGET_FREEBSD and
* TARGET_SOLARIS, which are
@@ -413,6 +417,9 @@ enum MATCH
MATCHexact // exact match
};
typedef unsigned StorageClass;
void warning(Loc loc, const char *format, ...) IS_PRINTF(2);
void vwarning(Loc loc, const char *format, va_list);
void error(Loc loc, const char *format, ...) IS_PRINTF(2);

View File

@@ -590,6 +590,9 @@ struct TypeStruct : Type
MATCH deduceType(Scope *sc, Type *tparam, TemplateParameters *parameters, Objects *dedtypes);
TypeInfoDeclaration *getTypeInfoDeclaration();
int hasPointers();
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif
#if IN_DMD
type *toCtype();
@@ -701,7 +704,7 @@ struct TypeClass : Type
#if DMDV2
Type *toHeadMutable();
MATCH constConv(Type *to);
#if TARGET_LINUX || TARGET_OSX
#if CPP_MANGLE
void toCppMangle(OutBuffer *buf, CppMangleState *cms);
#endif
#endif
@@ -748,19 +751,21 @@ struct TypeSlice : Type
struct Argument : Object
{
//enum InOut inout;
unsigned storageClass;
StorageClass storageClass;
Type *type;
Identifier *ident;
Expression *defaultArg;
Argument(unsigned storageClass, Type *type, Identifier *ident, Expression *defaultArg);
Argument(StorageClass storageClass, Type *type, Identifier *ident, Expression *defaultArg);
Argument *syntaxCopy();
Type *isLazyArray();
void toDecoBuffer(OutBuffer *buf, bool mangle);
static Arguments *arraySyntaxCopy(Arguments *args);
static char *argsTypesToChars(Arguments *args, int varargs);
static void argsCppMangle(OutBuffer *buf, CppMangleState *cms, Arguments *arguments, int varargs);
static void argsToCBuffer(OutBuffer *buf, HdrGenState *hgs, Arguments *arguments, int varargs);
static void argsToDecoBuffer(OutBuffer *buf, Arguments *arguments, bool mangle);
static int isTPL(Arguments *arguments);
static size_t dim(Arguments *arguments);
static Argument *getNth(Arguments *arguments, size_t nth, size_t *pn = NULL);
};
@@ -771,4 +776,6 @@ extern int REALPAD;
extern int Tsize_t;
extern int Tptrdiff_t;
int arrayTypeCompatible(Loc loc, Type *t1, Type *t2);
#endif /* DMD_MTYPE_H */

View File

@@ -149,7 +149,7 @@ Array *Parser::parseDeclDefs(int once)
Array *a;
Array *aelse;
enum PROT prot;
unsigned stc;
StorageClass stc;
Condition *condition;
unsigned char *comment;
@@ -286,6 +286,7 @@ Array *Parser::parseDeclDefs(int once)
case TOKpure: stc = STCpure; goto Lstc;
case TOKref: stc = STCref; goto Lstc;
case TOKtls: stc = STCtls; goto Lstc;
case TOKgshared: stc = STCgshared; goto Lstc;
//case TOKmanifest: stc = STCmanifest; goto Lstc;
#endif
@@ -514,6 +515,23 @@ Array *Parser::parseDeclDefs(int once)
return decldefs;
}
/*********************************************
* Give error on conflicting storage classes.
*/
#if DMDV2
void Parser::composeStorageClass(StorageClass stc)
{
StorageClass u = stc;
u &= STCconst | STCimmutable | STCmanifest;
if (u & (u - 1))
error("conflicting storage class %s", Token::toChars(token.value));
u = stc;
u &= STCgshared | STCshared | STCtls;
if (u & (u - 1))
error("conflicting storage class %s", Token::toChars(token.value));
}
#endif
/********************************************
* Parse declarations after an align, protection, or extern decl.
@@ -767,7 +785,7 @@ Condition *Parser::parseStaticIfCondition()
* Current token is 'this'.
*/
CtorDeclaration *Parser::parseCtor()
Dsymbol *Parser::parseCtor()
{
CtorDeclaration *f;
Arguments *arguments;
@@ -945,7 +963,7 @@ Arguments *Parser::parseParameters(int *pvarargs)
Identifier *ai = NULL;
Type *at;
Argument *a;
unsigned storageClass;
StorageClass storageClass = 0;
Expression *ae;
storageClass = STCin; // parameter is "in" by default
@@ -1323,7 +1341,7 @@ Lerr:
* Parse template parameter list.
*/
TemplateParameters *Parser::parseTemplateParameterList()
TemplateParameters *Parser::parseTemplateParameterList(int flag)
{
TemplateParameters *tpl = new TemplateParameters();
@@ -2082,8 +2100,8 @@ Type *Parser::parseDeclarator(Type *t, Identifier **pident, TemplateParameters *
Array *Parser::parseDeclarations()
{
enum STC storage_class;
enum STC stc;
StorageClass storage_class;
StorageClass stc;
Type *ts;
Type *t;
Type *tfirst;
@@ -2338,7 +2356,7 @@ Array *Parser::parseDeclarations()
*/
#if DMDV2
Array *Parser::parseAutoDeclarations(unsigned storageClass, unsigned char *comment)
Array *Parser::parseAutoDeclarations(StorageClass storageClass, unsigned char *comment)
{
Array *a = new Array;

View File

@@ -68,18 +68,24 @@ struct Parser : Lexer
Array *parseModule();
Array *parseDeclDefs(int once);
Array *parseAutoDeclarations(StorageClass storageClass, unsigned char *comment);
Array *parseBlock();
void composeStorageClass(unsigned stc);
void composeStorageClass(StorageClass stc);
Expression *parseConstraint();
TemplateDeclaration *parseTemplateDeclaration();
TemplateParameters *parseTemplateParameterList();
TemplateParameters *parseTemplateParameterList(int flag = 0);
Dsymbol *parseMixin();
Objects *parseTemplateArgumentList();
Objects *parseTemplateArgumentList2();
Objects *parseTemplateArgument();
StaticAssert *parseStaticAssert();
TypeQualified *parseTypeof();
enum LINK parseLinkage();
Condition *parseDebugCondition();
Condition *parseVersionCondition();
Condition *parseStaticIfCondition();
CtorDeclaration *parseCtor();
Dsymbol *parseCtor();
PostBlitDeclaration *parsePostBlit();
DtorDeclaration *parseDtor();
StaticCtorDeclaration *parseStaticCtor();
StaticDtorDeclaration *parseStaticDtor();
@@ -92,6 +98,7 @@ struct Parser : Lexer
Dsymbol *parseAggregate();
BaseClasses *parseBaseClasses();
Import *parseImport(Array *decldefs, int isstatic);
Type *parseType(Identifier **pident = NULL, TemplateParameters **tpl = NULL);
Type *parseBasicType();
Type *parseBasicType2(Type *t);
Type *parseDeclarator(Type *t, Identifier **pident, TemplateParameters **tpl = NULL);
@@ -99,6 +106,7 @@ struct Parser : Lexer
void parseContracts(FuncDeclaration *f);
Statement *parseStatement(int flags);
Initializer *parseInitializer();
Expression *parseDefaultInitExp();
void check(Loc loc, enum TOK value);
void check(enum TOK value);
void check(enum TOK value, const char *string);

View File

@@ -88,7 +88,7 @@ struct Scope
enum PROT protection; // protection for class members
int explicitProtection; // set if in an explicit protection attribute
unsigned stc; // storage class
StorageClass stc; // storage class
unsigned flags;
#define SCOPEctor 1 // constructor type