From 1c79df38170c602fa9ddc8c50a48a4c07c654f85 Mon Sep 17 00:00:00 2001 From: Tomas Lindquist Olsen Date: Fri, 17 Apr 2009 14:38:29 +0200 Subject: [PATCH] Fixed all issues preventing Tango 0.99.8 to compile with `sh build-tango.sh --verbose ldc'. --- dmd/mtype.c | 22 +++++++++++++++++++--- dmd/mtype.h | 3 +++ gen/toir.cpp | 6 ++++++ gen/typinf.cpp | 19 +++++++++++-------- ir/irstruct.cpp | 2 ++ ir/irtypeclass.cpp | 23 ++++++++++++++++++++--- ir/irtypeclass.h | 4 ++++ ir/irtypestruct.cpp | 11 +++++++---- 8 files changed, 72 insertions(+), 18 deletions(-) diff --git a/dmd/mtype.c b/dmd/mtype.c index 308758fc..40bae88e 100644 --- a/dmd/mtype.c +++ b/dmd/mtype.c @@ -109,6 +109,10 @@ Type *Type::basic[TMAX]; unsigned char Type::mangleChar[TMAX]; StringTable Type::stringtable; +#if IN_LLVM +StringTable Type::deco_stringtable; +#endif + Type::Type(TY ty, Type *next) { @@ -444,11 +448,23 @@ Type *Type::merge() else { sv->ptrvalue = this; - + + // we still need deco strings to be unique + // or Type::equals fails, which breaks a bunch of stuff, + // like covariant member function overloads. OutBuffer mangle; toDecoBuffer(&mangle, true); - mangle.writeByte(0); - deco = mem.strdup((char *)mangle.data); + StringValue* sv2 = deco_stringtable.update((char *)mangle.data, mangle.offset); + if (sv2->ptrvalue) + { Type* t2 = (Type *) sv2->ptrvalue; + assert(t2->deco); + deco = t2->deco; + } + else + { + sv2->ptrvalue = this; + deco = (char *)sv2->lstring.string; + } //printf("new value, deco = '%s' %p\n", t->deco, t->deco); } } diff --git a/dmd/mtype.h b/dmd/mtype.h index 3de2caab..d1671b32 100644 --- a/dmd/mtype.h +++ b/dmd/mtype.h @@ -193,6 +193,9 @@ struct Type : Object static Type *basic[TMAX]; static unsigned char mangleChar[TMAX]; static StringTable stringtable; +#if IN_LLVM + static StringTable deco_stringtable; +#endif // These tables are for implicit conversion of binary ops; // the indices are the type of operand one, followed by operand two. diff --git a/gen/toir.cpp b/gen/toir.cpp index b85be628..1158d079 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2390,6 +2390,9 @@ DValue* StructLiteralExp::toElem(IRState* p) Logger::print("StructLiteralExp::toElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; + // make sure the struct is resolved + sd->codegen(Type::sir); + // get inits std::vector inits(sd->fields.dim, NULL); @@ -2448,6 +2451,9 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p) Logger::print("StructLiteralExp::toConstElem: %s @ %s\n", toChars(), type->toChars()); LOG_SCOPE; + // make sure the struct is resolved + sd->codegen(Type::sir); + // get inits std::vector inits(sd->fields.dim, NULL); diff --git a/gen/typinf.cpp b/gen/typinf.cpp index 89bd6162..8db4d85e 100644 --- a/gen/typinf.cpp +++ b/gen/typinf.cpp @@ -638,6 +638,7 @@ void TypeInfoStructDeclaration::llvmDefine() Logger::println("TypeInfoStructDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; + // make sure struct is resolved assert(tinfo->ty == Tstruct); TypeStruct *tc = (TypeStruct *)tinfo; StructDeclaration *sd = tc->sym; @@ -835,6 +836,11 @@ void TypeInfoClassDeclaration::llvmDefine() Logger::println("TypeInfoClassDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; + // make sure class is resolved + assert(tinfo->ty == Tclass); + TypeClass *tc = (TypeClass *)tinfo; + tc->sym->codegen(Type::sir); + // init typeinfo class ClassDeclaration* base = Type::typeinfoclass; assert(base); @@ -849,11 +855,6 @@ void TypeInfoClassDeclaration::llvmDefine() sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); // get classinfo - assert(tinfo->ty == Tclass); - TypeClass *tc = (TypeClass *)tinfo; - - tc->sym->codegen(Type::sir); - sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol()); // create the inititalizer @@ -873,6 +874,11 @@ void TypeInfoInterfaceDeclaration::llvmDefine() Logger::println("TypeInfoInterfaceDeclaration::llvmDefine() %s", toChars()); LOG_SCOPE; + // make sure interface is resolved + assert(tinfo->ty == Tclass); + TypeClass *tc = (TypeClass *)tinfo; + tc->sym->codegen(Type::sir); + // init typeinfo class ClassDeclaration* base = Type::typeinfointerface; assert(base); @@ -890,9 +896,6 @@ void TypeInfoInterfaceDeclaration::llvmDefine() sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty))); // get classinfo - assert(tinfo->ty == Tclass); - TypeClass *tc = (TypeClass *)tinfo; - sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol()); // create the inititalizer diff --git a/ir/irstruct.cpp b/ir/irstruct.cpp index 85199bca..701a55f1 100644 --- a/ir/irstruct.cpp +++ b/ir/irstruct.cpp @@ -191,7 +191,9 @@ LLConstant * IrStruct::createStructDefaultInitializer() // build constant struct llvm::Constant* definit = llvm::ConstantStruct::get(constants, packed); +#if 0 IF_LOG Logger::cout() << "final default initializer: " << *definit << std::endl; +#endif // sanity check if (definit->getType() != type->irtype->get()) diff --git a/ir/irtypeclass.cpp b/ir/irtypeclass.cpp index b8f24c84..58d2bd13 100644 --- a/ir/irtypeclass.cpp +++ b/ir/irtypeclass.cpp @@ -109,9 +109,7 @@ void IrTypeClass::addBaseClassData( offset += PTRSIZE; // add to the interface map - // FIXME: and all it's baseinterfaces - if (interfaceMap.find(b->base) == interfaceMap.end()) - interfaceMap.insert(std::make_pair(b->base, field_index)); + addInterfaceToMap(b->base, field_index); field_index++; // inc count @@ -252,3 +250,22 @@ size_t IrTypeClass::getInterfaceIndex(ClassDeclaration * inter) } ////////////////////////////////////////////////////////////////////////////// + +void IrTypeClass::addInterfaceToMap(ClassDeclaration * inter, size_t index) +{ + // don't duplicate work or overwrite indices + if (interfaceMap.find(inter) != interfaceMap.end()) + return; + + // add this interface + interfaceMap.insert(std::make_pair(inter, index)); + + // add all its base interfaces recursively + for (size_t i = 0; i < inter->interfaces_dim; i++) + { + BaseClass* b = inter->interfaces[i]; + addInterfaceToMap(b->base, index); + } +} + +////////////////////////////////////////////////////////////////////////////// diff --git a/ir/irtypeclass.h b/ir/irtypeclass.h index d82ec971..0edb30c8 100644 --- a/ir/irtypeclass.h +++ b/ir/irtypeclass.h @@ -68,6 +68,10 @@ protected: ClassDeclaration* base, size_t& offset, size_t& field_index); + + /// Adds the interface and all it's base interface to the interface + /// to index map. + void addInterfaceToMap(ClassDeclaration* inter, size_t index); }; #endif diff --git a/ir/irtypestruct.cpp b/ir/irtypestruct.cpp index e50507cf..82cf5312 100644 --- a/ir/irtypestruct.cpp +++ b/ir/irtypestruct.cpp @@ -86,14 +86,16 @@ const llvm::Type* IrTypeStruct::buildType() for (; !it.done(); it.next()) { VarDeclaration* vd = it.get(); + //Logger::println("vd: %s", vd->toPrettyChars()); - assert(vd->ir.irField == NULL && "struct inheritance is not allowed, how can this happen?"); + //assert(vd->ir.irField == NULL && "struct inheritance is not allowed, how can this happen?"); // skip if offset moved backwards if (vd->offset < offset) { IF_LOG Logger::println("Skipping field %s %s (+%u) for default", vd->type->toChars(), vd->toChars(), vd->offset); - new IrField(vd, 0, vd->offset); + if (vd->ir.irField == NULL) + new IrField(vd, 0, vd->offset); continue; } @@ -123,7 +125,8 @@ const llvm::Type* IrTypeStruct::buildType() // the IrField creation doesn't really belong here, but it's a trivial operation // and it save yet another of these loops. IF_LOG Logger::println("Field index: %zu", field_index); - new IrField(vd, field_index); + if (vd->ir.irField == NULL) + new IrField(vd, field_index); field_index++; } @@ -142,7 +145,7 @@ const llvm::Type* IrTypeStruct::buildType() // name types Type::sir->getState()->module->addTypeName(sd->toPrettyChars(), pa.get()); -#if 1 +#if 0 IF_LOG Logger::cout() << "final struct type: " << *pa.get() << std::endl; #endif