This commit is contained in:
Christian Kamm
2008-12-12 08:18:30 +01:00
10 changed files with 101 additions and 54 deletions

View File

@@ -3761,10 +3761,6 @@ Expression *VarExp::semantic(Scope *sc)
#endif
}
// LDC: Fixes bug 1161, http://d.puremagic.com/issues/show_bug.cgi?id=1161
// check access to VarDeclaration
accessCheck(loc, sc, NULL, var);
VarDeclaration *v = var->isVarDeclaration();
if (v)
{

View File

@@ -3829,10 +3829,6 @@ Expression *VarExp::semantic(Scope *sc)
#endif
}
// LDC: Fixes bug 1161, http://d.puremagic.com/issues/show_bug.cgi?id=1161
// check access to VarDeclaration
accessCheck(loc, sc, NULL, var);
VarDeclaration *v = var->isVarDeclaration();
if (v)
{

View File

@@ -22,7 +22,7 @@
//////////////////////////////////////////////////////////////////////////////////////////
// adds the base interfaces of b and the given iri to IrStruct's interfaceMap
void add_base_interfaces(IrStruct* to, IrInterface* iri, BaseClass* b)
static void add_base_interfaces(IrStruct* to, IrInterface* iri, BaseClass* b)
{
for (unsigned j = 0; j < b->baseInterfaces_dim; j++)
{
@@ -39,7 +39,7 @@ void add_base_interfaces(IrStruct* to, IrInterface* iri, BaseClass* b)
// adds interface b to target, if newinstance != 0, then target must provide all
// functions required to implement b (it reimplements b)
void add_interface(ClassDeclaration* target, BaseClass* b, int newinstance)
static void add_interface(ClassDeclaration* target, BaseClass* b, int newinstance)
{
Logger::println("adding interface: %s", b->base->toChars());
LOG_SCOPE;
@@ -90,7 +90,7 @@ void add_interface(ClassDeclaration* target, BaseClass* b, int newinstance)
//////////////////////////////////////////////////////////////////////////////////////////
void add_class_data(ClassDeclaration* target, ClassDeclaration* cd)
static void add_class_data(ClassDeclaration* target, ClassDeclaration* cd)
{
Logger::println("Adding data from class: %s", cd->toChars());
LOG_SCOPE;
@@ -125,7 +125,7 @@ void add_class_data(ClassDeclaration* target, ClassDeclaration* cd)
//////////////////////////////////////////////////////////////////////////////////////////
void DtoResolveInterface(InterfaceDeclaration* cd)
static void DtoResolveInterface(InterfaceDeclaration* cd)
{
if (cd->ir.resolved) return;
cd->ir.resolved = true;
@@ -275,7 +275,7 @@ void DtoResolveClass(ClassDeclaration* cd)
//////////////////////////////////////////////////////////////////////////////////////////
void DtoDeclareInterface(InterfaceDeclaration* cd)
static void DtoDeclareInterface(InterfaceDeclaration* cd)
{
if (cd->ir.declared) return;
cd->ir.declared = true;
@@ -440,7 +440,7 @@ void DtoDeclareClass(ClassDeclaration* cd)
//////////////////////////////////////////////////////////////////////////////
// adds data fields and interface vtables to the constant initializer of class cd
size_t init_class_initializer(std::vector<LLConstant*>& inits, ClassDeclaration* target, ClassDeclaration* cd, size_t offsetbegin)
static size_t init_class_initializer(std::vector<LLConstant*>& inits, ClassDeclaration* target, ClassDeclaration* cd, size_t offsetbegin)
{
// first do baseclasses
if (cd->baseClass)
@@ -543,7 +543,7 @@ size_t init_class_initializer(std::vector<LLConstant*>& inits, ClassDeclaration*
//////////////////////////////////////////////////////////////////////////////
// build the vtable initializer for class cd
void init_class_vtbl_initializer(ClassDeclaration* cd)
static void init_class_vtbl_initializer(ClassDeclaration* cd)
{
// generate vtable initializer
std::vector<LLConstant*> sinits(cd->vtbl.dim, NULL);
@@ -596,7 +596,7 @@ void init_class_vtbl_initializer(ClassDeclaration* cd)
//////////////////////////////////////////////////////////////////////////////
void init_class_interface_vtbl_initializers(ClassDeclaration* cd)
static void init_class_interface_vtbl_initializers(ClassDeclaration* cd)
{
IrStruct* irstruct = cd->ir.irStruct;
@@ -697,7 +697,7 @@ void init_class_interface_vtbl_initializers(ClassDeclaration* cd)
//////////////////////////////////////////////////////////////////////////////
void DtoConstInitInterface(InterfaceDeclaration* cd)
static void DtoConstInitInterface(InterfaceDeclaration* cd)
{
if (cd->ir.initialized) return;
cd->ir.initialized = true;
@@ -780,7 +780,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
//////////////////////////////////////////////////////////////////////////////////////////
void DefineInterfaceInfos(IrStruct* irstruct)
static void DefineInterfaceInfos(IrStruct* irstruct)
{
// always do interface info array when possible
std::vector<LLConstant*> infoInits;
@@ -810,7 +810,7 @@ void DefineInterfaceInfos(IrStruct* irstruct)
//////////////////////////////////////////////////////////////////////////////////////////
void DtoDefineInterface(InterfaceDeclaration* cd)
static void DtoDefineInterface(InterfaceDeclaration* cd)
{
if (cd->ir.defined) return;
cd->ir.defined = true;
@@ -1059,6 +1059,7 @@ DValue* DtoCastClass(DValue* val, Type* _to)
Logger::println("static down cast");
// get the from class
ClassDeclaration* cd = fc->sym->isClassDeclaration();
DtoResolveClass(cd); // add this
IrStruct* irstruct = cd->ir.irStruct;
// find interface impl
IrStruct::InterfaceMapIter iriter = irstruct->interfaceMap.find(it);
@@ -1218,6 +1219,9 @@ LLValue* DtoIndexClass(LLValue* src, ClassDeclaration* cd, VarDeclaration* vd)
if (Logger::enabled())
Logger::cout() << "src: " << *src << '\n';
// make sure class is resolved
DtoResolveClass(cd);
// vd must be a field
IrField* field = vd->ir.irField;
assert(field);
@@ -1260,6 +1264,7 @@ LLValue* DtoVirtualFunctionPointer(DValue* inst, FuncDeclaration* fdecl)
{
// sanity checks
assert(fdecl->isVirtual());
assert(!fdecl->isFinal());
assert(fdecl->vtblIndex > 0); // 0 is always ClassInfo/Interface*
assert(inst->getType()->toBasetype()->ty == Tclass);
@@ -1323,7 +1328,7 @@ void DtoDeclareClassInfo(ClassDeclaration* cd)
#if GENERATE_OFFTI
// build a single element for the OffsetInfo[] of ClassInfo
LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd)
static LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd)
{
std::vector<LLConstant*> inits(2);
@@ -1348,7 +1353,7 @@ LLConstant* build_offti_entry(ClassDeclaration* cd, VarDeclaration* vd)
return llvm::ConstantStruct::get(inits);
}
LLConstant* build_offti_array(ClassDeclaration* cd, const LLType* arrayT)
static LLConstant* build_offti_array(ClassDeclaration* cd, const LLType* arrayT)
{
IrStruct* irstruct = cd->ir.irStruct;
@@ -1383,7 +1388,7 @@ LLConstant* build_offti_array(ClassDeclaration* cd, const LLType* arrayT)
#endif // GENERATE_OFFTI
LLConstant* build_class_dtor(ClassDeclaration* cd)
static LLConstant* build_class_dtor(ClassDeclaration* cd)
{
FuncDeclaration* dtor = cd->dtor;
@@ -1395,7 +1400,7 @@ LLConstant* build_class_dtor(ClassDeclaration* cd)
return llvm::ConstantExpr::getBitCast(dtor->ir.irFunc->func, getPtrToType(LLType::Int8Ty));
}
unsigned build_classinfo_flags(ClassDeclaration* cd)
static unsigned build_classinfo_flags(ClassDeclaration* cd)
{
// adapted from original dmd code
unsigned flags = 0;

View File

@@ -628,13 +628,6 @@ void DtoDefineFunc(FuncDeclaration* fd)
Logger::println("DtoDefineFunc(%s): %s", fd->toPrettyChars(), fd->loc.toChars());
LOG_SCOPE;
// error on naked
if (fd->naked)
{
fd->error("naked is not supported");
fatal();
}
// debug info
if (global.params.symdebug) {
Module* mo = fd->getModule();
@@ -778,24 +771,31 @@ void DtoDefineFunc(FuncDeclaration* fd)
if (!fd->nestedVars.empty())
{
Logger::println("has nested frame");
// start with add all enclosing parent frames
// start with adding all enclosing parent frames until a static parent is reached
int nparelems = 0;
Dsymbol* par = fd->toParent2();
while (par)
if (!fd->isStatic())
{
if (FuncDeclaration* parfd = par->isFuncDeclaration())
Dsymbol* par = fd->toParent2();
while (par)
{
nparelems += parfd->nestedVars.size();
if (FuncDeclaration* parfd = par->isFuncDeclaration())
{
nparelems += parfd->nestedVars.size();
// stop at first static
if (parfd->isStatic())
break;
}
else if (ClassDeclaration* parcd = par->isClassDeclaration())
{
// nothing needed
}
else
{
break;
}
par = par->toParent2();
}
else if (ClassDeclaration* parcd = par->isClassDeclaration())
{
// nothing needed
}
else
{
break;
}
par = par->toParent2();
}
int nelems = fd->nestedVars.size() + nparelems;

View File

@@ -303,6 +303,8 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd)
Logger::println("indexing struct field %s:", vd->toPrettyChars());
LOG_SCOPE;
DtoResolveStruct(sd);
// vd must be a field
IrField* field = vd->ir.irField;
assert(field);

View File

@@ -242,10 +242,8 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions*
const LLFunctionType* callableTy = DtoExtractFunctionType(callable->getType());
assert(callableTy);
if (Logger::enabled())
{
Logger::cout() << "callable: " << *callable << '\n';
}
// if (Logger::enabled())
// Logger::cout() << "callable: " << *callable << '\n';
// get n arguments
size_t n_arguments = arguments ? arguments->dim : 0;

View File

@@ -56,10 +56,18 @@ DValue* VarExp::toElem(IRState* p)
LOG_SCOPE;
assert(var);
if (VarDeclaration* vd = var->isVarDeclaration())
{
Logger::println("VarDeclaration ' %s ' of type ' %s '", vd->toChars(), vd->type->toChars());
// this is an error! must be accessed with DotVarExp
if (var->needThis())
{
error("need 'this' to access member %s", toChars());
fatal();
}
// _arguments
if (vd->ident == Id::_arguments && p->func()->_arguments)
{
@@ -144,6 +152,9 @@ DValue* VarExp::toElem(IRState* p)
LLValue* val;
if (!vd->ir.isSet() || !(val = vd->ir.getIrValue())) {
// FIXME: this error is bad!
// We should be VERY careful about adding errors in general, as they have
// a tendency to "mask" out the underlying problems ...
error("variable %s not resolved", vd->toChars());
if (Logger::enabled())
Logger::cout() << "unresolved variable had type: " << *DtoType(vd->type) << '\n';
@@ -213,6 +224,13 @@ LLConstant* VarExp::toConstElem(IRState* p)
m = llvm::ConstantExpr::getBitCast(m, vartype);
return m;
}
else if (VarDeclaration* vd = var->isVarDeclaration())
{
// return the initializer
assert(vd->init);
return DtoConstInitializer(loc, type, vd->init);
}
// fail
assert(0 && "Unsupported const VarExp kind");
return NULL;
}
@@ -1952,7 +1970,7 @@ DValue* DelegateExp::toElem(IRState* p)
Logger::println("func: '%s'", func->toPrettyChars());
LLValue* castfptr;
if (func->isVirtual())
if (func->isVirtual() && !func->isFinal())
castfptr = DtoVirtualFunctionPointer(u, func);
else if (func->isAbstract())
assert(0 && "TODO delegate to abstract method");

View File

@@ -1060,7 +1060,7 @@ extern (C) void _moduleCtor()
_moduleinfo_dtors = new ModuleInfo[_moduleinfo_array.length];
debug(PRINTF) printf("_moduleinfo_dtors = x%x\n", cast(void *)_moduleinfo_dtors);
_moduleIndependentCtors();
_moduleCtor2(_moduleinfo_array, 0);
_moduleCtor2(null, _moduleinfo_array, 0);
}
extern (C) void _moduleIndependentCtors()
@@ -1076,7 +1076,7 @@ extern (C) void _moduleIndependentCtors()
debug(PRINTF) printf("_moduleIndependentCtors() DONE\n");
}
void _moduleCtor2(ModuleInfo[] mi, int skip)
void _moduleCtor2(ModuleInfo from, ModuleInfo[] mi, int skip)
{
debug(PRINTF) printf("_moduleCtor2(): %d modules\n", mi.length);
for (uint i = 0; i < mi.length; i++)
@@ -1096,11 +1096,12 @@ void _moduleCtor2(ModuleInfo[] mi, int skip)
if (m.flags & MIctorstart)
{ if (skip || m.flags & MIstandalone)
continue;
throw new Exception( "Cyclic dependency in module " ~ m.name );
assert(from !is null);
throw new Exception( "Cyclic dependency in module " ~ from.name ~ " for import " ~ m.name);
}
m.flags |= MIctorstart;
_moduleCtor2(m.importedModules, 0);
_moduleCtor2(m, m.importedModules, 0);
if (m.ctor)
(*m.ctor)();
m.flags &= ~MIctorstart;
@@ -1114,7 +1115,7 @@ void _moduleCtor2(ModuleInfo[] mi, int skip)
else
{
m.flags |= MIctordone;
_moduleCtor2(m.importedModules, 1);
_moduleCtor2(m, m.importedModules, 1);
}
}
debug(PRINTF) printf("_moduleCtor2() DONE\n");

View File

@@ -0,0 +1,13 @@
void test(void delegate() spam)
{
static void foo() // static is the problem
{
uint x;
void peek() { x = 0; }
}
void bar()
{
spam();
}
}

18
tests/mini/delegate3.d Normal file
View File

@@ -0,0 +1,18 @@
module bar;
class S
{
int i;
final int foo()
{
return i;
}
}
void main()
{
auto s = new S;
s.i = 42;
auto dg = &s.foo;
assert(dg() == 42);
}