First merge of 2.064 beta.

This corresponds to DMD commit a913ce4bc59a94a022a27e390fc841f4aededffb.

Doesn't build Phobos yet.
This commit is contained in:
David Nadlinger
2013-10-29 19:21:15 +01:00
committed by Kai Nacke
parent c400d180d2
commit cb341586e3
130 changed files with 13566 additions and 9190 deletions
+242 -233
View File
@@ -1,6 +1,6 @@
// Compiler implementation of the D programming language
// Copyright (c) 1999-2012 by Digital Mars
// Copyright (c) 1999-2013 by Digital Mars
// All Rights Reserved
// written by Walter Bright
// http://www.digitalmars.com
@@ -32,16 +32,15 @@
/********************************* ClassDeclaration ****************************/
ClassDeclaration *ClassDeclaration::classinfo;
ClassDeclaration *ClassDeclaration::object;
ClassDeclaration *ClassDeclaration::throwable;
ClassDeclaration *ClassDeclaration::exception;
ClassDeclaration *ClassDeclaration::errorException;
ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses)
ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses, bool inObject)
: AggregateDeclaration(loc, id)
{
static char msg[] = "only object.d can define this reserved class name";
static const char msg[] = "only object.d can define this reserved class name";
if (baseclasses)
// Actually, this is a transfer
@@ -79,147 +78,140 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
if (id->toChars()[0] == 'T')
{
if (id == Id::TypeInfo)
{ if (Type::typeinfo)
Type::typeinfo->error("%s", msg);
Type::typeinfo = this;
{ if (!inObject)
error("%s", msg);
Type::dtypeinfo = this;
}
if (id == Id::TypeInfo_Class)
{ if (Type::typeinfoclass)
Type::typeinfoclass->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfoclass = this;
}
if (id == Id::TypeInfo_Interface)
{ if (Type::typeinfointerface)
Type::typeinfointerface->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfointerface = this;
}
if (id == Id::TypeInfo_Struct)
{ if (Type::typeinfostruct)
Type::typeinfostruct->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfostruct = this;
}
if (id == Id::TypeInfo_Typedef)
{ if (Type::typeinfotypedef)
Type::typeinfotypedef->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfotypedef = this;
}
if (id == Id::TypeInfo_Pointer)
{ if (Type::typeinfopointer)
Type::typeinfopointer->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfopointer = this;
}
if (id == Id::TypeInfo_Array)
{ if (Type::typeinfoarray)
Type::typeinfoarray->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfoarray = this;
}
if (id == Id::TypeInfo_StaticArray)
{ //if (Type::typeinfostaticarray)
{ //if (!inObject)
//Type::typeinfostaticarray->error("%s", msg);
Type::typeinfostaticarray = this;
}
if (id == Id::TypeInfo_AssociativeArray)
{ if (Type::typeinfoassociativearray)
Type::typeinfoassociativearray->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfoassociativearray = this;
}
if (id == Id::TypeInfo_Enum)
{ if (Type::typeinfoenum)
Type::typeinfoenum->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfoenum = this;
}
if (id == Id::TypeInfo_Function)
{ if (Type::typeinfofunction)
Type::typeinfofunction->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfofunction = this;
}
if (id == Id::TypeInfo_Delegate)
{ if (Type::typeinfodelegate)
Type::typeinfodelegate->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfodelegate = this;
}
if (id == Id::TypeInfo_Tuple)
{ if (Type::typeinfotypelist)
Type::typeinfotypelist->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfotypelist = this;
}
#if DMDV2
if (id == Id::TypeInfo_Const)
{ if (Type::typeinfoconst)
Type::typeinfoconst->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfoconst = this;
}
if (id == Id::TypeInfo_Invariant)
{ if (Type::typeinfoinvariant)
Type::typeinfoinvariant->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfoinvariant = this;
}
if (id == Id::TypeInfo_Shared)
{ if (Type::typeinfoshared)
Type::typeinfoshared->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfoshared = this;
}
if (id == Id::TypeInfo_Wild)
{ if (Type::typeinfowild)
Type::typeinfowild->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfowild = this;
}
if (id == Id::TypeInfo_Vector)
{ if (Type::typeinfovector)
Type::typeinfovector->error("%s", msg);
{ if (!inObject)
error("%s", msg);
Type::typeinfovector = this;
}
#endif
}
if (id == Id::Object)
{ if (object)
object->error("%s", msg);
{ if (!inObject)
error("%s", msg);
object = this;
}
if (id == Id::Throwable)
{ if (throwable)
throwable->error("%s", msg);
{ if (!inObject)
error("%s", msg);
throwable = this;
}
if (id == Id::Exception)
{ if (exception)
exception->error("%s", msg);
{ if (!inObject)
error("%s", msg);
exception = this;
}
if (id == Id::Error)
{ if (errorException)
errorException->error("%s", msg);
{ if (!inObject)
error("%s", msg);
errorException = this;
}
//if (id == Id::ClassInfo)
if (id == Id::TypeInfo_Class)
{ if (classinfo)
classinfo->error("%s", msg);
classinfo = this;
}
#if !MODULEINFO_IS_STRUCT
#ifdef DMDV2
if (id == Id::ModuleInfo && !Module::moduleinfo)
@@ -227,7 +219,7 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
#else
if (id == Id::ModuleInfo)
{ if (Module::moduleinfo)
Module::moduleinfo->error("%s", msg);
error("%s", msg);
Module::moduleinfo = this;
}
#endif
@@ -235,6 +227,7 @@ ClassDeclaration::ClassDeclaration(Loc loc, Identifier *id, BaseClasses *basecla
}
com = 0;
cpp = 0;
isscope = 0;
isabstract = 0;
inuse = 0;
@@ -302,7 +295,8 @@ void ClassDeclaration::semantic(Scope *sc)
Scope *scx = NULL;
if (scope)
{ sc = scope;
{
sc = scope;
scx = scope; // save so we don't make redundant copies
scope = NULL;
}
@@ -316,17 +310,21 @@ void ClassDeclaration::semantic(Scope *sc)
userAttributes = sc->userAttributes;
if (sc->linkage == LINKcpp)
error("cannot create C++ classes");
cpp = 1;
// Expand any tuples in baseclasses[]
for (size_t i = 0; i < baseclasses->dim; )
{ BaseClass *b = (*baseclasses)[i];
b->type = b->type->semantic(loc, sc);
Type *tb = b->type->toBasetype();
{
// Ungag errors when not speculative
Ungag ungag = ungagSpeculative();
BaseClass *b = (*baseclasses)[i];
b->type = b->type->semantic(loc, sc);
Type *tb = b->type->toBasetype();
if (tb->ty == Ttuple)
{ TypeTuple *tup = (TypeTuple *)tb;
enum PROT protection = b->protection;
PROT protection = b->protection;
baseclasses->remove(i);
size_t dim = Parameter::dim(tup->arguments);
for (size_t j = 0; j < dim; j++)
@@ -341,21 +339,23 @@ void ClassDeclaration::semantic(Scope *sc)
// See if there's a base class as first in baseclasses[]
if (baseclasses->dim)
{ TypeClass *tc;
BaseClass *b;
Type *tb;
{
// Ungag errors when not speculative
Ungag ungag = ungagSpeculative();
b = (*baseclasses)[0];
BaseClass *b = (*baseclasses)[0];
//b->type = b->type->semantic(loc, sc);
tb = b->type->toBasetype();
Type *tb = b->type->toBasetype();
if (tb->ty != Tclass)
{ if (b->type != Type::terror)
{
if (b->type != Type::terror)
error("base type must be class or interface, not %s", b->type->toChars());
baseclasses->remove(0);
}
else
{
tc = (TypeClass *)(tb);
TypeClass *tc = (TypeClass *)(tb);
if (tc->sym->isDeprecated())
{
@@ -411,19 +411,18 @@ void ClassDeclaration::semantic(Scope *sc)
// Treat the remaining entries in baseclasses as interfaces
// Check for errors, handle forward references
for (size_t i = (baseClass ? 1 : 0); i < baseclasses->dim; )
{ TypeClass *tc;
BaseClass *b;
Type *tb;
{
// Ungag errors when not speculative
Ungag ungag = ungagSpeculative();
b = (*baseclasses)[i];
BaseClass *b = (*baseclasses)[i];
b->type = b->type->semantic(loc, sc);
tb = b->type->toBasetype();
if (tb->ty == Tclass)
tc = (TypeClass *)tb;
else
tc = NULL;
Type *tb = b->type->toBasetype();
TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL;
if (!tc || !tc->sym->isInterfaceDeclaration())
{ if (b->type != Type::terror)
{
if (b->type != Type::terror)
error("base type must be interface, not %s", b->type->toChars());
baseclasses->remove(i);
continue;
@@ -475,63 +474,65 @@ void ClassDeclaration::semantic(Scope *sc)
doAncestorsSemantic = SemanticDone;
// If no base class, and this is not an Object, use Object as base class
if (!baseClass && ident != Id::Object)
{
if (!object)
{
error("missing or corrupt object.d");
fatal();
}
Type *t = object->type;
t = t->semantic(loc, sc)->toBasetype();
assert(t->ty == Tclass);
TypeClass *tc = (TypeClass *)t;
BaseClass *b = new BaseClass(tc, PROTpublic);
baseclasses->shift(b);
baseClass = tc->sym;
assert(!baseClass->isInterfaceDeclaration());
b->base = baseClass;
}
interfaces_dim = baseclasses->dim;
interfaces = baseclasses->tdata();
if (baseClass)
{
if (baseClass->storage_class & STCfinal)
error("cannot inherit from final class %s", baseClass->toChars());
interfaces_dim--;
interfaces++;
// Copy vtbl[] from base class
vtbl.setDim(baseClass->vtbl.dim);
memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.dim);
// Inherit properties from base class
com = baseClass->isCOMclass();
isscope = baseClass->isscope;
vthis = baseClass->vthis;
enclosing = baseClass->enclosing;
storage_class |= baseClass->storage_class & STC_TYPECTOR;
}
else
{
// No base class, so this is the root of the class hierarchy
vtbl.setDim(0);
vtbl.push(this); // leave room for classinfo as first member
}
protection = sc->protection;
storage_class |= sc->stc;
if (sizeok == SIZEOKnone)
{
// If no base class, and this is not an Object, use Object as base class
if (!baseClass && ident != Id::Object && !cpp)
{
if (!object)
{
error("missing or corrupt object.d");
fatal();
}
Type *t = object->type;
t = t->semantic(loc, sc)->toBasetype();
assert(t->ty == Tclass);
TypeClass *tc = (TypeClass *)t;
BaseClass *b = new BaseClass(tc, PROTpublic);
baseclasses->shift(b);
baseClass = tc->sym;
assert(!baseClass->isInterfaceDeclaration());
b->base = baseClass;
}
interfaces_dim = baseclasses->dim;
interfaces = baseclasses->tdata();
if (baseClass)
{
if (baseClass->storage_class & STCfinal)
error("cannot inherit from final class %s", baseClass->toChars());
interfaces_dim--;
interfaces++;
// Copy vtbl[] from base class
vtbl.setDim(baseClass->vtbl.dim);
memcpy(vtbl.tdata(), baseClass->vtbl.tdata(), sizeof(void *) * vtbl.dim);
// Inherit properties from base class
com = baseClass->isCOMclass();
if (baseClass->isCPPclass())
cpp = 1;
isscope = baseClass->isscope;
vthis = baseClass->vthis;
enclosing = baseClass->enclosing;
storage_class |= baseClass->storage_class & STC_TYPECTOR;
}
else
{
// No base class, so this is the root of the class hierarchy
vtbl.setDim(0);
if (vtblOffset())
vtbl.push(this); // leave room for classinfo as first member
}
protection = sc->protection;
storage_class |= sc->stc;
interfaceSemantic(sc);
for (size_t i = 0; i < members->dim; i++)
@@ -544,7 +545,8 @@ void ClassDeclaration::semantic(Scope *sc)
* member which is a pointer to the enclosing scope.
*/
if (vthis) // if inheriting from nested class
{ // Use the base class's 'this' member
{
// Use the base class's 'this' member
if (storage_class & STCstatic)
error("static class cannot inherit from nested class %s", baseClass->toChars());
if (toParent2() != baseClass->toParent2() &&
@@ -570,14 +572,14 @@ void ClassDeclaration::semantic(Scope *sc)
}
else
makeNested();
}
if (storage_class & STCauto)
error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?");
if (storage_class & STCscope)
isscope = 1;
if (storage_class & STCabstract)
isabstract = 1;
if (storage_class & STCauto)
error("storage class 'auto' is invalid when declaring a class, did you mean to use 'scope'?");
if (storage_class & STCscope)
isscope = 1;
if (storage_class & STCabstract)
isabstract = 1;
}
sc = sc->push(this);
//sc->stc &= ~(STCfinal | STCauto | STCscope | STCstatic | STCabstract | STCdeprecated | STC_TYPECTOR | STCtls | STCgshared);
@@ -585,7 +587,6 @@ void ClassDeclaration::semantic(Scope *sc)
sc->stc &= STCsafe | STCtrusted | STCsystem;
sc->parent = this;
sc->inunion = 0;
if (isCOMclass())
{
if (global.params.isWindows)
@@ -600,13 +601,19 @@ void ClassDeclaration::semantic(Scope *sc)
sc->explicitProtection = 0;
sc->structalign = STRUCTALIGN_DEFAULT;
if (baseClass)
{ sc->offset = baseClass->structsize;
{
sc->offset = baseClass->structsize;
alignsize = baseClass->alignsize;
sc->offset = (sc->offset + alignsize - 1) & ~(alignsize - 1);
// if (enclosing)
// sc->offset += Target::ptrsize; // room for uplevel context pointer
}
else
{ sc->offset = Target::ptrsize * 2; // allow room for __vptr and __monitor
{
if (cpp)
sc->offset = Target::ptrsize; // allow room for __vptr
else
sc->offset = Target::ptrsize * 2; // allow room for __vptr and __monitor
alignsize = Target::ptrsize;
}
sc->userAttributes = NULL;
@@ -619,50 +626,45 @@ void ClassDeclaration::semantic(Scope *sc)
* resolve individual members like enums.
*/
for (size_t i = 0; i < members_dim; i++)
{ Dsymbol *s = (*members)[i];
/* There are problems doing this in the general case because
* Scope keeps track of things like 'offset'
*/
if (s->isEnumDeclaration() ||
(s->isAggregateDeclaration() && s->ident) ||
s->isTemplateMixin() ||
s->isAttribDeclaration() ||
s->isAliasDeclaration())
{
//printf("[%d] setScope %s %s, sc = %p\n", i, s->kind(), s->toChars(), sc);
s->setScope(sc);
}
{
Dsymbol *s = (*members)[i];
//printf("[%d] setScope %s %s, sc = %p\n", i, s->kind(), s->toChars(), sc);
s->setScope(sc);
}
for (size_t i = 0; i < members_dim; i++)
{ Dsymbol *s = (*members)[i];
{
Dsymbol *s = (*members)[i];
// Ungag errors when not speculative
Ungag ungag = ungagSpeculative();
s->semantic(sc);
}
// Set the offsets of the fields and determine the size of the class
unsigned offset = structsize;
bool isunion = isUnionDeclaration() != NULL;
for (size_t i = 0; i < members->dim; i++)
{ Dsymbol *s = (*members)[i];
{
Dsymbol *s = (*members)[i];
s->setFieldOffset(this, &offset, false);
}
sc->offset = structsize;
if (global.errors != errors)
{ // The type is no good.
{
// The type is no good.
type = Type::terror;
}
if (sizeok == SIZEOKfwd) // failed due to forward references
{ // semantic() failed due to forward references
{
// semantic() failed due to forward references
// Unwind what we did, and defer it for later
for (size_t i = 0; i < fields.dim; i++)
{ Dsymbol *s = fields[i];
VarDeclaration *vd = s->isVarDeclaration();
if (vd)
vd->offset = 0;
{
if (VarDeclaration *v = fields[i])
v->offset = 0;
}
fields.setDim(0);
structsize = 0;
@@ -688,11 +690,7 @@ void ClassDeclaration::semantic(Scope *sc)
/* Look for special member functions.
* They must be in this class, not in a base class.
*/
ctor = search(Loc(), Id::ctor, 0);
#if DMDV1
if (ctor && (ctor->toParent() != this || !ctor->isCtorDeclaration()))
ctor = NULL;
#else
searchCtor();
if (ctor && (ctor->toParent() != this || !(ctor->isCtorDeclaration() || ctor->isTemplateDeclaration())))
ctor = NULL; // search() looks through ancestor classes
if (!ctor && noDefaultCtor)
@@ -705,11 +703,6 @@ void ClassDeclaration::semantic(Scope *sc)
::error(v->loc, "field %s must be initialized in constructor", v->toChars());
}
}
#endif
// dtor = (DtorDeclaration *)search(Id::dtor, 0);
// if (dtor && dtor->toParent() != this)
// dtor = NULL;
inv = buildInv(sc);
@@ -722,10 +715,14 @@ void ClassDeclaration::semantic(Scope *sc)
// this() { }
if (!ctor && baseClass && baseClass->ctor)
{
if (resolveFuncCall(loc, sc, baseClass->ctor, NULL, NULL, NULL, 1))
if (FuncDeclaration *fd = resolveFuncCall(loc, sc, baseClass->ctor, NULL, NULL, NULL, 1))
{
//printf("Creating default this(){} for class %s\n", toChars());
Type *tf = new TypeFunction(NULL, NULL, 0, LINKd, 0);
TypeFunction *btf = (TypeFunction *)fd->type;
TypeFunction *tf = new TypeFunction(NULL, NULL, 0, LINKd, fd->storage_class);
tf->purity = btf->purity;
tf->isnothrow = btf->isnothrow;
tf->trust = btf->trust;
CtorDeclaration *ctor = new CtorDeclaration(loc, Loc(), 0, tf);
ctor->fbody = new CompoundStatement(Loc(), new Statements());
members->push(ctor);
@@ -787,7 +784,7 @@ void ClassDeclaration::semantic(Scope *sc)
if (FuncDeclaration *f = hasIdentityOpAssign(sc))
{
if (!(f->storage_class & STCdisable))
error("identity assignment operator overload is illegal");
error(f->loc, "identity assignment operator overload is illegal");
}
sc->pop();
@@ -808,14 +805,12 @@ void ClassDeclaration::semantic(Scope *sc)
deferred->semantic3(sc);
}
#if 0
if (type->ty == Tclass && ((TypeClass *)type)->sym != this)
{
printf("this = %p %s\n", this, this->toChars());
printf("type = %d sym = %p\n", type->ty, ((TypeClass *)type)->sym);
error("failed semantic analysis");
this->errors = true;
type = Type::terror;
}
#endif
assert(type->ty != Tclass || ((TypeClass *)type)->sym == this);
}
void ClassDeclaration::toCBuffer(OutBuffer *buf, HdrGenState *hgs)
@@ -899,10 +894,10 @@ int ClassDeclaration::isBaseOf(ClassDeclaration *cd, int *poffset)
{
/* cd->baseClass might not be set if cd is forward referenced.
*/
if (!cd->baseClass && cd->baseclasses->dim && !cd->isInterfaceDeclaration())
if (!cd->baseClass && cd->scope && !cd->isInterfaceDeclaration())
{
cd->semantic(NULL);
if (!cd->baseClass)
if (!cd->baseClass && cd->scope)
cd->error("base class is forward referenced by %s", toChars());
}
@@ -941,14 +936,7 @@ Dsymbol *ClassDeclaration::search(Loc loc, Identifier *ident, int flags)
{
// must semantic on base class/interfaces
doAncestorsSemantic = SemanticIn;
// If speculatively gagged, ungag now.
unsigned oldgag = global.gag;
if (global.isSpeculativeGagging())
global.gag = 0;
semantic(scope);
global.gag = oldgag;
if (doAncestorsSemantic != SemanticDone)
doAncestorsSemantic = SemanticStart;
}
@@ -995,6 +983,8 @@ ClassDeclaration *ClassDeclaration::searchBase(Loc loc, Identifier *ident)
{
BaseClass *b = (*baseclasses)[i];
ClassDeclaration *cdb = b->type->isClassHandle();
if (!cdb) // Bugzilla 10616
return NULL;
if (cdb->ident->equals(ident))
return cdb;
cdb = cdb->searchBase(loc, ident);
@@ -1010,10 +1000,13 @@ ClassDeclaration *ClassDeclaration::searchBase(Loc loc, Identifier *ident)
*/
#if DMDV2
int isf(void *param, FuncDeclaration *fd)
int isf(void *param, Dsymbol *s)
{
FuncDeclaration *fd = s->isFuncDeclaration();
if (!fd)
return 0;
//printf("param = %p, fd = %p %s\n", param, fd, fd->toChars());
return param == fd;
return (RootObject *)param == fd;
}
int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
@@ -1021,7 +1014,8 @@ int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
//printf("ClassDeclaration::isFuncHidden(class = %s, fd = %s)\n", toChars(), fd->toChars());
Dsymbol *s = search(Loc(), fd->ident, 4|2);
if (!s)
{ //printf("not found\n");
{
//printf("not found\n");
/* Because, due to a hack, if there are multiple definitions
* of fd->ident, NULL is returned.
*/
@@ -1032,9 +1026,10 @@ int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
if (os)
{
for (size_t i = 0; i < os->a.dim; i++)
{ Dsymbol *s2 = os->a[i];
{
Dsymbol *s2 = os->a[i];
FuncDeclaration *f2 = s2->isFuncDeclaration();
if (f2 && overloadApply(f2, &isf, fd))
if (f2 && overloadApply(f2, (void *)fd, &isf))
return 0;
}
return 1;
@@ -1043,7 +1038,7 @@ int ClassDeclaration::isFuncHidden(FuncDeclaration *fd)
{
FuncDeclaration *fdstart = s->isFuncDeclaration();
//printf("%s fdstart = %p\n", s->kind(), fdstart);
if (overloadApply(fdstart, &isf, fd))
if (overloadApply(fdstart, (void *)fd, &isf))
return 0;
return !fd->parent->isTemplateMixin();
@@ -1152,9 +1147,13 @@ void ClassDeclaration::interfaceSemantic(Scope *sc)
if (b->base->isCOMinterface())
com = 1;
#if 1
if (b->base->isCPPinterface() && id)
id->cpp = 1;
#else
if (b->base->isCPPinterface())
cpp = 1;
#endif
vtblInterfaces->push(b);
b->copyBaseInterfaces(vtblInterfaces);
}
@@ -1174,6 +1173,11 @@ int ClassDeclaration::isCOMinterface()
}
#if DMDV2
int ClassDeclaration::isCPPclass()
{
return cpp;
}
int ClassDeclaration::isCPPinterface()
{
return 0;
@@ -1184,10 +1188,10 @@ int ClassDeclaration::isCPPinterface()
/****************************************
*/
int ClassDeclaration::isAbstract()
bool ClassDeclaration::isAbstract()
{
if (isabstract)
return TRUE;
return true;
for (size_t i = 1; i < vtbl.dim; i++)
{
FuncDeclaration *fd = vtbl[i]->isFuncDeclaration();
@@ -1196,10 +1200,10 @@ int ClassDeclaration::isAbstract()
if (!fd || fd->isAbstract())
{
isabstract |= 1;
return TRUE;
return true;
}
}
return FALSE;
return false;
}
@@ -1208,11 +1212,14 @@ int ClassDeclaration::isAbstract()
* For class objects, yes, this is where the classinfo ptr goes.
* For COM interfaces, no.
* For non-COM interfaces, yes, this is where the Interface ptr goes.
* Returns:
* 0 vtbl[0] is first virtual function pointer
* 1 vtbl[0] is classinfo/interfaceinfo pointer
*/
int ClassDeclaration::vtblOffset()
{
return 1;
return cpp ? 0 : 1;
}
/****************************************
@@ -1236,8 +1243,6 @@ void ClassDeclaration::addLocalClass(ClassDeclarations *aclasses)
InterfaceDeclaration::InterfaceDeclaration(Loc loc, Identifier *id, BaseClasses *baseclasses)
: ClassDeclaration(loc, id, baseclasses)
{
com = 0;
cpp = 0;
if (id == Id::IUnknown) // IUnknown is the root of all COM interfaces
{ com = 1;
cpp = 1; // IUnknown is also a C++ interface
@@ -1284,7 +1289,8 @@ void InterfaceDeclaration::semantic(Scope *sc)
Scope *scx = NULL;
if (scope)
{ sc = scope;
{
sc = scope;
scx = scope; // save so we don't make redundant copies
scope = NULL;
}
@@ -1299,13 +1305,17 @@ void InterfaceDeclaration::semantic(Scope *sc)
// Expand any tuples in baseclasses[]
for (size_t i = 0; i < baseclasses->dim; )
{ BaseClass *b = (*baseclasses)[i];
b->type = b->type->semantic(loc, sc);
Type *tb = b->type->toBasetype();
{
// Ungag errors when not speculative
Ungag ungag = ungagSpeculative();
BaseClass *b = (*baseclasses)[i];
b->type = b->type->semantic(loc, sc);
Type *tb = b->type->toBasetype();
if (tb->ty == Ttuple)
{ TypeTuple *tup = (TypeTuple *)tb;
enum PROT protection = b->protection;
PROT protection = b->protection;
baseclasses->remove(i);
size_t dim = Parameter::dim(tup->arguments);
for (size_t j = 0; j < dim; j++)
@@ -1323,19 +1333,18 @@ void InterfaceDeclaration::semantic(Scope *sc)
// Check for errors, handle forward references
for (size_t i = 0; i < baseclasses->dim; )
{ TypeClass *tc;
BaseClass *b;
Type *tb;
{
// Ungag errors when not speculative
Ungag ungag = ungagSpeculative();
b = (*baseclasses)[i];
BaseClass *b = (*baseclasses)[i];
b->type = b->type->semantic(loc, sc);
tb = b->type->toBasetype();
if (tb->ty == Tclass)
tc = (TypeClass *)tb;
else
tc = NULL;
Type *tb = b->type->toBasetype();
TypeClass *tc = (tb->ty == Tclass) ? (TypeClass *)tb : NULL;
if (!tc || !tc->sym->isInterfaceDeclaration())
{ if (b->type != Type::terror)
{
if (b->type != Type::terror)
error("base type must be interface, not %s", b->type->toChars());
baseclasses->remove(i);
continue;
@@ -1432,9 +1441,9 @@ void InterfaceDeclaration::semantic(Scope *sc)
sc = sc->push(this);
sc->stc &= STCsafe | STCtrusted | STCsystem;
sc->parent = this;
if (isCOMinterface())
if (com)
sc->linkage = LINKwindows;
else if (isCPPinterface())
else if (cpp)
sc->linkage = LINKcpp;
sc->structalign = STRUCTALIGN_DEFAULT;
sc->protection = PROTpublic;
@@ -1463,6 +1472,9 @@ void InterfaceDeclaration::semantic(Scope *sc)
for (size_t i = 0; i < members->dim; i++)
{
Dsymbol *s = (*members)[i];
// Ungag errors when not speculative
Ungag ungag = ungagSpeculative();
s->semantic(sc);
}
@@ -1476,14 +1488,12 @@ void InterfaceDeclaration::semantic(Scope *sc)
sc->pop();
//printf("-InterfaceDeclaration::semantic(%s), type = %p\n", toChars(), type);
#if 0
if (type->ty == Tclass && ((TypeClass *)type)->sym != this)
{
printf("this = %p %s\n", this, this->toChars());
printf("type = %d sym = %p\n", type->ty, ((TypeClass *)type)->sym);
error("failed semantic analysis");
this->errors = true;
type = Type::terror;
}
#endif
assert(type->ty != Tclass || ((TypeClass *)type)->sym == this);
}
@@ -1618,7 +1628,7 @@ BaseClass::BaseClass()
memset(this, 0, sizeof(BaseClass));
}
BaseClass::BaseClass(Type *type, enum PROT protection)
BaseClass::BaseClass(Type *type, PROT protection)
{
//printf("BaseClass(this = %p, '%s')\n", this, type->toChars());
this->type = type;
@@ -1643,7 +1653,6 @@ BaseClass::BaseClass(Type *type, enum PROT protection)
int BaseClass::fillVtbl(ClassDeclaration *cd, FuncDeclarations *vtbl, int newinstance)
{
ClassDeclaration *id = base;
int result = 0;
//printf("BaseClass::fillVtbl(this='%s', cd='%s')\n", base->toChars(), cd->toChars());