From e4c3179d43c81c4bb864fd00aff865023318802d Mon Sep 17 00:00:00 2001 From: Alexey Prokhin Date: Thu, 28 Oct 2010 14:53:01 +0400 Subject: [PATCH] Different fixes: phobos compiles now --- dmd2/interpret.c | 4 ++++ dmd2/mtype.c | 24 ++++++++++++---------- gen/arrays.cpp | 28 +++++++++++++++++++------ gen/arrays.h | 3 ++- gen/declarations.cpp | 2 +- gen/llvmhelpers.cpp | 11 +++++++--- gen/nested.cpp | 9 +++++++- gen/runtime.cpp | 49 ++++++++++++++++++++++++++++++-------------- gen/tocall.cpp | 10 +++++++++ gen/toir.cpp | 8 +++++++- gen/tollvm.cpp | 7 +++++++ 11 files changed, 116 insertions(+), 39 deletions(-) diff --git a/dmd2/interpret.c b/dmd2/interpret.c index ec2a5c73..41ae5335 100644 --- a/dmd2/interpret.c +++ b/dmd2/interpret.c @@ -965,6 +965,10 @@ Expression *SwitchStatement::interpret(InterState *istate) s = sdefault; } +#if IN_LLVM + if (!s) + return EXP_CANT_INTERPRET; +#endif assert(s); istate->start = s; e = body ? body->interpret(istate) : NULL; diff --git a/dmd2/mtype.c b/dmd2/mtype.c index 6c67f127..7c9abf6b 100644 --- a/dmd2/mtype.c +++ b/dmd2/mtype.c @@ -1753,11 +1753,7 @@ Expression *Type::getProperty(Loc loc, Identifier *ident) { if (ty == Tvoid) error(loc, "void does not have an initializer"); -#if IN_LLVM - e = defaultInit(loc); -#else e = defaultInitLiteral(loc); -#endif } else if (ident == Id::mangleof) { const char *s; @@ -4303,7 +4299,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident) void TypeAArray::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) { Type::toDecoBuffer(buf, flag, mangle); - index->toDecoBuffer(buf, mangle); + index->toDecoBuffer(buf, 0, mangle); next->toDecoBuffer(buf, (flag & 0x100) ? 0 : mod, mangle); } @@ -4597,6 +4593,8 @@ TypeFunction::TypeFunction(Parameters *parameters, Type *treturn, int varargs, e #if IN_LLVM this->funcdecl = NULL; #endif + if (stc & STCpure) + this->ispure = true; if (stc & STCnothrow) this->isnothrow = true; if (stc & STCproperty) @@ -4797,8 +4795,8 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) case LINKpascal: mc = 'V'; break; case LINKcpp: mc = 'R'; break; - // LDC - case LINKintrinsic: mc = 'Q'; break; + // LDC + case LINKintrinsic: mc = 'Q'; break; default: assert(0); @@ -4833,7 +4831,7 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) { AggregateDeclaration* ad = funcdecl->isMember2(); buf->writeByte('M'); - ad->type->toDecoBuffer(buf, false); + ad->type->toDecoBuffer(buf, 0, false); } /* BUG This causes problems with delegate types On the other hand, the llvm type for nested functions *is* different @@ -4845,7 +4843,7 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) if (funcdecl->toParent2() && funcdecl->toParent2()->isFuncDeclaration()) { FuncDeclaration* fd = funcdecl->toParent2()->isFuncDeclaration(); - fd->type->toDecoBuffer(buf, false); + fd->type->toDecoBuffer(buf, 0, false); } }*/ } @@ -4855,7 +4853,7 @@ void TypeFunction::toDecoBuffer(OutBuffer *buf, int flag, bool mangle) //if (buf->data[buf->offset - 1] == '@') halt(); buf->writeByte('Z' - varargs); // mark end of arg list assert(next); - next->toDecoBuffer(buf, mangle); + next->toDecoBuffer(buf, 0, mangle); inuse--; } @@ -7152,6 +7150,9 @@ Expression *TypeStruct::defaultInitLiteral(Loc loc) #if LOGDEFAULTINIT printf("TypeStruct::defaultInitLiteral() '%s'\n", toChars()); #endif +#if IN_LLVM + return defaultInit(loc); +#else if (sym->isNested()) return defaultInit(loc); Expressions *structelems = new Expressions(); @@ -7171,6 +7172,7 @@ Expression *TypeStruct::defaultInitLiteral(Loc loc) // sym->type != NULL ? structinit->type = sym->type; return structinit; +#endif } @@ -8237,7 +8239,7 @@ void Parameter::argsToDecoBuffer(OutBuffer *buf, Parameters *arguments, bool man for (size_t i = 0; i < dim; i++) { Parameter *arg = Parameter::getNth(arguments, i); - arg->toDecoBuffer(buf, mangle); + arg->toDecoBuffer(buf, mangle); } } } diff --git a/gen/arrays.cpp b/gen/arrays.cpp index 4289f894..75d3fb7a 100644 --- a/gen/arrays.cpp +++ b/gen/arrays.cpp @@ -806,27 +806,43 @@ DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2) ////////////////////////////////////////////////////////////////////////////////////////// -DSliceValue* DtoAppendDChar(DValue* arr, Expression* exp) +DSliceValue* DtoAppendDChar(DValue* arr, Expression* exp, const char *func) { - Logger::println("DtoCatAssignArray"); - LOG_SCOPE; Type *arrayType = arr->getType(); DValue* valueToAppend = exp->toElem(gIR); // Prepare arguments - LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_arrayappendcd"); + LLFunction* fn = LLVM_D_GetRuntimeFunction(gIR->module, func); LLSmallVector args; - // ref char[] x + // ref string x args.push_back(DtoBitCast(arr->getLVal(), fn->getFunctionType()->getParamType(0))); // dchar c args.push_back(DtoBitCast(valueToAppend->getRVal(), fn->getFunctionType()->getParamType(1))); - // Call _d_arrayappendcd + // Call function LLValue* newArray = gIR->CreateCallOrInvoke(fn, args.begin(), args.end(), ".appendedArray").getInstruction(); return getSlice(arrayType, newArray); } +////////////////////////////////////////////////////////////////////////////////////////// + +DSliceValue* DtoAppendDCharToString(DValue* arr, Expression* exp) +{ + Logger::println("DtoAppendDCharToString"); + LOG_SCOPE; + return DtoAppendDChar(arr, exp, "_d_arrayappendcd"); +} + +////////////////////////////////////////////////////////////////////////////////////////// + +DSliceValue* DtoAppendDCharToUnicodeString(DValue* arr, Expression* exp) +{ + Logger::println("DtoAppendDCharToUnicodeString"); + LOG_SCOPE; + return DtoAppendDChar(arr, exp, "_d_arrayappendwd"); +} + ////////////////////////////////////////////////////////////////////////////////////////// // helper for eq and cmp static LLValue* DtoArrayEqCmp_impl(Loc& loc, const char* func, DValue* l, DValue* r, bool useti) diff --git a/gen/arrays.h b/gen/arrays.h index b7e2a0ed..8ea34eab 100644 --- a/gen/arrays.h +++ b/gen/arrays.h @@ -28,7 +28,8 @@ void DtoCatAssignElement(Loc& loc, Type* type, DValue* arr, Expression* exp); DSliceValue* DtoCatAssignArray(DValue* arr, Expression* exp); DSliceValue* DtoCatArrays(Type* type, Expression* e1, Expression* e2); DSliceValue* DtoCatArrayElement(Type* type, Expression* exp1, Expression* exp2); -DSliceValue* DtoAppendDChar(DValue* arr, Expression* exp); +DSliceValue* DtoAppendDCharToString(DValue* arr, Expression* exp); +DSliceValue* DtoAppendDCharToUnicodeString(DValue* arr, Expression* exp); void DtoStaticArrayCopy(LLValue* dst, LLValue* src); diff --git a/gen/declarations.cpp b/gen/declarations.cpp index ab425297..7e25739f 100644 --- a/gen/declarations.cpp +++ b/gen/declarations.cpp @@ -103,7 +103,7 @@ void VarDeclaration::codegen(Ir* p) { Logger::println("data segment"); - #if DMDV2 + #if DMDV2 && 0 // TODO: if (storage_class & STCmanifest) { assert(0 && "manifest constant being codegened!!!"); diff --git a/gen/llvmhelpers.cpp b/gen/llvmhelpers.cpp index 1c57f036..d833fc04 100644 --- a/gen/llvmhelpers.cpp +++ b/gen/llvmhelpers.cpp @@ -444,7 +444,12 @@ void DtoAssign(Loc& loc, DValue* lhs, DValue* rhs) r = DtoCast(loc, rhs, lhs->getType())->getRVal(); if (Logger::enabled()) Logger::cout() << "really assign\nlhs: " << *l << "rhs: " << *r << '\n'; - assert(r->getType() == l->getType()->getContainedType(0)); +#if 1 + if(r->getType() != lit) // It's wierd but it happens. TODO: try to remove this hack + r = DtoBitCast(r, lit); +#else + assert(r->getType() == lit); +#endif } gIR->ir->CreateStore(r, l); } @@ -1525,8 +1530,8 @@ size_t realignOffset(size_t offset, Type* type) Type * stripModifiers( Type * type ) { #if DMDV2 - if (type->ty == Tfunction) - return type; + if (type->ty == Tfunction) + return type; Type *t = type; while (t->mod) { diff --git a/gen/nested.cpp b/gen/nested.cpp index a2ba52c6..9b493e3f 100644 --- a/gen/nested.cpp +++ b/gen/nested.cpp @@ -92,8 +92,15 @@ DValue* DtoNestedVariable(Loc loc, Type* astype, VarDeclaration* vd) LLValue* ctx = 0; if (irfunc->decl->isMember2()) { + #if DMDV2 + AggregateDeclaration* cd = irfunc->decl->isMember2(); + LLValue* val = irfunc->thisArg; + if (cd->isClassDeclaration()) + val = DtoLoad(val); + #else ClassDeclaration* cd = irfunc->decl->isMember2()->isClassDeclaration(); LLValue* val = DtoLoad(irfunc->thisArg); + #endif ctx = DtoLoad(DtoGEPi(val, 0,cd->vthis->ir.irField->index, ".vthis")); } else if (irfunc->nestedVar) @@ -267,7 +274,7 @@ LLValue* DtoNestedContext(Loc loc, Dsymbol* sym) Logger::cout() << "Context depth: " << ctxDepth << '\n'; if (neededDepth >= ctxDepth) { - assert(neededDepth <= ctxDepth + 1 && "How are we going more than one nesting level up?"); + // assert(neededDepth <= ctxDepth + 1 && "How are we going more than one nesting level up?"); // fd needs the same context as we do, so all is well Logger::println("Calling sibling function or directly nested function"); } else { diff --git a/gen/runtime.cpp b/gen/runtime.cpp index 009388cc..6edb4d5a 100644 --- a/gen/runtime.cpp +++ b/gen/runtime.cpp @@ -292,6 +292,25 @@ static void LLVM_D_BuildRuntimeModule() llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M) ->setAttributes(Attr_NoAlias); } + // void* _d_newarraymT(TypeInfo ti, size_t length, size_t* dims) + // void* _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims) + // void* _d_newarraymvT(TypeInfo ti, size_t length, size_t* dims) + { + llvm::StringRef fname("_d_newarraymT"); + llvm::StringRef fname2("_d_newarraymiT"); + llvm::StringRef fname3("_d_newarraymvT"); + std::vector types; + types.push_back(typeInfoTy); + types.push_back(sizeTy); + types.push_back(rt_ptr(sizeTy)); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) + ->setAttributes(Attr_NoAlias_3_NoCapture); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M) + ->setAttributes(Attr_NoAlias_3_NoCapture); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M) + ->setAttributes(Attr_NoAlias_3_NoCapture); + } #else // void[] _d_newarrayT(TypeInfo ti, size_t length) // void[] _d_newarrayiT(TypeInfo ti, size_t length) @@ -305,11 +324,8 @@ static void LLVM_D_BuildRuntimeModule() llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); } -#endif - - // void* _d_newarraymT(TypeInfo ti, size_t length, size_t* dims) - // void* _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims) - // D1: void* _d_newarraymvT(TypeInfo ti, size_t length, size_t* dims) + // void[] _d_newarraymT(TypeInfo ti, size_t length, size_t* dims) + // void[] _d_newarraymiT(TypeInfo ti, size_t length, size_t* dims) { llvm::StringRef fname("_d_newarraymT"); llvm::StringRef fname2("_d_newarraymiT"); @@ -317,17 +333,11 @@ static void LLVM_D_BuildRuntimeModule() types.push_back(typeInfoTy); types.push_back(sizeTy); types.push_back(rt_ptr(sizeTy)); - const llvm::FunctionType* fty = llvm::FunctionType::get(voidPtrTy, types, false); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M) - ->setAttributes(Attr_NoAlias_3_NoCapture); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M) - ->setAttributes(Attr_NoAlias_3_NoCapture); -#if DMDV1 - llvm::StringRef fname3("_d_newarraymvT"); - llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname3, M) - ->setAttributes(Attr_NoAlias_3_NoCapture); -#endif + const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname2, M); } +#endif // D1: // void* _d_arraysetlengthT(TypeInfo ti, size_t newlength, size_t plength, void* pdata) @@ -390,6 +400,15 @@ static void LLVM_D_BuildRuntimeModule() const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); } + // void[] _d_arrayappendwd(ref wchar[] x, dchar c) + { + llvm::StringRef fname("_d_arrayappendwd"); + std::vector types; + types.push_back(getPtrToType(wstringTy)); + types.push_back(intTy); + const llvm::FunctionType* fty = llvm::FunctionType::get(voidArrayTy, types, false); + llvm::Function::Create(fty, llvm::GlobalValue::ExternalLinkage, fname, M); + } // byte[] _d_arraycatT(TypeInfo ti, byte[] x, byte[] y) { llvm::StringRef fname("_d_arraycatT"); diff --git a/gen/tocall.cpp b/gen/tocall.cpp index 44a37187..33be5ef8 100644 --- a/gen/tocall.cpp +++ b/gen/tocall.cpp @@ -583,12 +583,22 @@ DValue* DtoCallFunction(Loc& loc, Type* resulttype, DValue* fnval, Expressions* switch(rbase->ty) { case Tarray: + #if DMDV2 + if (tf->isref) + retllval = DtoBitCast(retllval, DtoType(rbase->pointerTo())); + else + #endif retllval = DtoAggrPaint(retllval, DtoType(rbase)); break; case Tclass: case Taarray: case Tpointer: + #if DMDV2 + if (tf->isref) + retllval = DtoBitCast(retllval, DtoType(rbase->pointerTo())); + else + #endif retllval = DtoBitCast(retllval, DtoType(rbase)); break; diff --git a/gen/toir.cpp b/gen/toir.cpp index 9c3b34f3..4be17174 100644 --- a/gen/toir.cpp +++ b/gen/toir.cpp @@ -2263,10 +2263,16 @@ DValue* CatAssignExp::toElem(IRState* p) } else if (elemtype->ty == Tchar) { if (e2type->ty == Tdchar) - DtoAppendDChar(l, e2); + DtoAppendDCharToString(l, e2); else assert(0 && "cannot append the element to a string"); } + else if (elemtype->ty == Twchar) { + if (e2type->ty == Tdchar) + DtoAppendDCharToUnicodeString(l, e2); + else + assert(0 && "cannot append the element to an unicode string"); + } else { assert(0 && "only one element at a time right now"); } diff --git a/gen/tollvm.cpp b/gen/tollvm.cpp index d18bd29a..4fe8cfd5 100644 --- a/gen/tollvm.cpp +++ b/gen/tollvm.cpp @@ -272,6 +272,13 @@ LLGlobalValue::LinkageTypes DtoLinkage(Dsymbol* sym) // extern(C) functions are always external else if (ft->linkage == LINKc) return llvm::GlobalValue::ExternalLinkage; + // If a function without a body is nested in another + // function, we cannot use internal linkage for that + // function (see below about nested functions) + // FIXME: maybe there is a better way without emission + // of needless symbols? + if (!fdecl->fbody) + return llvm::GlobalValue::ExternalLinkage; } // class else if (ClassDeclaration* cd = sym->isClassDeclaration())