mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-12 02:43:14 +01:00
[svn r15] * Fixed a bunch problems with virtual calls. Seems I did some rather poor testing.
* Now 50/51 tests compile. * Added a simple runalltests.d scripts that should be run with 'gdmd -run runalltests.d' - LLVMDC will not compile it yet.
This commit is contained in:
@@ -509,6 +509,8 @@ struct FuncDeclaration : Declaration
|
||||
int cvMember(unsigned char *p);
|
||||
|
||||
FuncDeclaration *isFuncDeclaration() { return this; }
|
||||
|
||||
bool llvmQueued;
|
||||
};
|
||||
|
||||
struct FuncAliasDeclaration : FuncDeclaration
|
||||
|
||||
@@ -73,6 +73,7 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC s
|
||||
nrvo_can = 1;
|
||||
nrvo_var = NULL;
|
||||
shidden = NULL;
|
||||
llvmQueued = false;
|
||||
}
|
||||
|
||||
Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
|
||||
|
||||
@@ -349,7 +349,7 @@ int main(int argc, char *argv[])
|
||||
global.params.Dversion = 1;
|
||||
else if (strcmp(p + 1, "w") == 0)
|
||||
global.params.warnings = 1;
|
||||
else if (strcmp(p + 1, "O") == 0)
|
||||
else if (p[1] == 'O')
|
||||
{
|
||||
global.params.optimize = 1;
|
||||
if (p[2] != 0) {
|
||||
|
||||
@@ -114,7 +114,7 @@ Type::Type(TY ty, Type *next)
|
||||
this->arrayof = NULL;
|
||||
this->vtinfo = NULL;
|
||||
this->ctype = NULL;
|
||||
this->llvmType = 0;
|
||||
this->llvmType = NULL;
|
||||
}
|
||||
|
||||
Type *Type::syntaxCopy()
|
||||
|
||||
@@ -250,7 +250,7 @@ struct Type : Object
|
||||
virtual type *toCParamtype();
|
||||
virtual Symbol *toSymbol();
|
||||
|
||||
llvm::Type* llvmType;
|
||||
const llvm::Type* llvmType;
|
||||
|
||||
// For eliminating dynamic_cast
|
||||
virtual TypeBasic *isTypeBasic();
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::StructType* LLVM_DtoArrayType(Type* t)
|
||||
const llvm::StructType* LLVM_DtoArrayType(Type* t)
|
||||
{
|
||||
assert(t->next);
|
||||
const llvm::Type* at = LLVM_DtoType(t->next);
|
||||
@@ -51,7 +51,7 @@ llvm::StructType* LLVM_DtoArrayType(Type* t)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::ArrayType* LLVM_DtoStaticArrayType(Type* t)
|
||||
const llvm::ArrayType* LLVM_DtoStaticArrayType(Type* t)
|
||||
{
|
||||
if (t->llvmType)
|
||||
return llvm::cast<llvm::ArrayType>(t->llvmType);
|
||||
@@ -63,7 +63,7 @@ llvm::ArrayType* LLVM_DtoStaticArrayType(Type* t)
|
||||
|
||||
TypeSArray* tsa = (TypeSArray*)t;
|
||||
assert(tsa->dim->type->isintegral());
|
||||
llvm::ArrayType* arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
|
||||
const llvm::ArrayType* arrty = llvm::ArrayType::get(at,tsa->dim->toUInteger());
|
||||
|
||||
tsa->llvmType = arrty;
|
||||
return arrty;
|
||||
@@ -298,7 +298,7 @@ llvm::Constant* LLVM_DtoArrayInitializer(ArrayInitializer* arrinit)
|
||||
inits[i] = v;
|
||||
}
|
||||
|
||||
llvm::ArrayType* arrty = LLVM_DtoStaticArrayType(t);
|
||||
const llvm::ArrayType* arrty = LLVM_DtoStaticArrayType(t);
|
||||
return llvm::ConstantArray::get(arrty, inits);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#ifndef LLVMC_GEN_ARRAYS_H
|
||||
#define LLVMC_GEN_ARRAYS_H
|
||||
|
||||
llvm::StructType* LLVM_DtoArrayType(Type* t);
|
||||
const llvm::StructType* LLVM_DtoArrayType(Type* t);
|
||||
|
||||
llvm::ArrayType* LLVM_DtoStaticArrayType(Type* t);
|
||||
const llvm::ArrayType* LLVM_DtoStaticArrayType(Type* t);
|
||||
|
||||
llvm::Value* LLVM_DtoNullArray(llvm::Value* v);
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@ elem::elem()
|
||||
type = NONE;
|
||||
inplace = false;
|
||||
field = false;
|
||||
callconv = (unsigned)-1;
|
||||
|
||||
vardecl = 0;
|
||||
funcdecl = 0;
|
||||
|
||||
@@ -31,6 +31,7 @@ public:
|
||||
int type;
|
||||
bool inplace;
|
||||
bool field;
|
||||
unsigned callconv;
|
||||
|
||||
VarDeclaration* vardecl;
|
||||
FuncDeclaration* funcdecl;
|
||||
|
||||
@@ -954,6 +954,8 @@ elem* CallExp::toElem(IRState* p)
|
||||
// set calling convention
|
||||
if ((fn->funcdecl && (fn->funcdecl->llvmInternal != LLVMintrinsic)) || delegateCall)
|
||||
call->setCallingConv(LLVM_DtoCallingConv(dlink));
|
||||
else if (fn->callconv != (unsigned)-1)
|
||||
call->setCallingConv(fn->callconv);
|
||||
|
||||
delete fn;
|
||||
return e;
|
||||
@@ -1253,7 +1255,7 @@ elem* DotVarExp::toElem(IRState* p)
|
||||
funcval = LLVM_DtoGEP(funcval, zero, vtblidx, "tmp", p->scopebb());
|
||||
funcval = new llvm::LoadInst(funcval,"tmp",p->scopebb());
|
||||
assert(funcval->getType() == fdecl->llvmValue->getType());
|
||||
//funcval = new llvm::BitCastInst(funcval, fdecl->llvmValue->getType(), "tmp", p->scopebb());
|
||||
e->callconv = LLVM_DtoCallingConv(fdecl->linkage);
|
||||
}
|
||||
e->val = funcval;
|
||||
e->type = elem::VAL;
|
||||
|
||||
83
gen/tollvm.c
83
gen/tollvm.c
@@ -159,7 +159,7 @@ const llvm::Type* LLVM_DtoType(Type* t)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam)
|
||||
const llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam)
|
||||
{
|
||||
TypeFunction* f = (TypeFunction*)t;
|
||||
|
||||
@@ -203,7 +203,7 @@ llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl)
|
||||
const llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl)
|
||||
{
|
||||
TypeFunction* f = (TypeFunction*)fdecl->type;
|
||||
assert(f != 0);
|
||||
@@ -309,7 +309,7 @@ llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::StructType* LLVM_DtoDelegateType(Type* t)
|
||||
const llvm::StructType* LLVM_DtoDelegateType(Type* t)
|
||||
{
|
||||
const llvm::Type* i8ptr = llvm::PointerType::get(llvm::Type::Int8Ty);
|
||||
const llvm::Type* func = LLVM_DtoFunctionType(t->next, i8ptr);
|
||||
@@ -323,7 +323,7 @@ llvm::StructType* LLVM_DtoDelegateType(Type* t)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Type* LLVM_DtoStructType(Type* t)
|
||||
const llvm::Type* LLVM_DtoStructType(Type* t)
|
||||
{
|
||||
assert(0);
|
||||
std::vector<const llvm::Type*> types;
|
||||
@@ -763,26 +763,40 @@ void LLVM_DtoCallClassDtors(TypeClass* tc, llvm::Value* instance)
|
||||
|
||||
void LLVM_DtoInitClass(TypeClass* tc, llvm::Value* dst)
|
||||
{
|
||||
assert(tc->llvmInit);
|
||||
assert(dst->getType() == tc->llvmInit->getType());
|
||||
assert(gIR);
|
||||
|
||||
assert(tc->llvmType);
|
||||
uint64_t n = gTargetData->getTypeSize(tc->llvmType);
|
||||
llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
||||
uint64_t size_t_size = gTargetData->getTypeSize(LLVM_DtoSize_t());
|
||||
uint64_t n = gTargetData->getTypeSize(tc->llvmType) - size_t_size;
|
||||
|
||||
llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
|
||||
llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb());
|
||||
// set vtable field
|
||||
llvm::Value* vtblvar = LLVM_DtoGEPi(dst,0,0,"tmp",gIR->scopebb());
|
||||
assert(tc->sym->llvmVtbl);
|
||||
new llvm::StoreInst(tc->sym->llvmVtbl, vtblvar, gIR->scopebb());
|
||||
|
||||
llvm::Function* fn = LLVM_DeclareMemCpy32();
|
||||
std::vector<llvm::Value*> llargs;
|
||||
llargs.resize(4);
|
||||
llargs[0] = dstarr;
|
||||
llargs[1] = srcarr;
|
||||
llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
||||
llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
||||
// copy the static initializer
|
||||
if (n > 0) {
|
||||
assert(tc->llvmInit);
|
||||
assert(dst->getType() == tc->llvmInit->getType());
|
||||
|
||||
new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
||||
llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
|
||||
|
||||
llvm::Value* dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
|
||||
dstarr = LLVM_DtoGEPi(dstarr,size_t_size,"tmp",gIR->scopebb());
|
||||
|
||||
llvm::Value* srcarr = new llvm::BitCastInst(tc->llvmInit,arrty,"tmp",gIR->scopebb());
|
||||
srcarr = LLVM_DtoGEPi(srcarr,size_t_size,"tmp",gIR->scopebb());
|
||||
|
||||
llvm::Function* fn = LLVM_DeclareMemCpy32();
|
||||
std::vector<llvm::Value*> llargs;
|
||||
llargs.resize(4);
|
||||
llargs[0] = dstarr;
|
||||
llargs[1] = srcarr;
|
||||
llargs[2] = llvm::ConstantInt::get(llvm::Type::Int32Ty, n, false);
|
||||
llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
|
||||
|
||||
new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -825,14 +839,19 @@ llvm::Constant* LLVM_DtoInitializer(Type* type, Initializer* init)
|
||||
return _init;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb)
|
||||
{
|
||||
std::vector<llvm::Value*> v(2);
|
||||
v[0] = i0;
|
||||
v[1] = i1;
|
||||
Logger::cout() << "DtoGEP: " << *ptr << '\n';
|
||||
return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb)
|
||||
{
|
||||
size_t n = src.size();
|
||||
@@ -847,9 +866,32 @@ llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, con
|
||||
return new llvm::GetElementPtrInst(ptr, dst.begin(), dst.end(), var, bb);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* LLVM_DtoGEPi(llvm::Value* ptr, unsigned i, const std::string& var, llvm::BasicBlock* bb)
|
||||
{
|
||||
return new llvm::GetElementPtrInst(ptr, llvm::ConstantInt::get(llvm::Type::Int32Ty, i, false), var, bb);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* LLVM_DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb)
|
||||
{
|
||||
std::vector<llvm::Value*> v(2);
|
||||
v[0] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i0, false);
|
||||
v[1] = llvm::ConstantInt::get(llvm::Type::Int32Ty, i1, false);
|
||||
return new llvm::GetElementPtrInst(ptr, v.begin(), v.end(), var, bb);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Function* LLVM_DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
{
|
||||
TypeFunction* f = (TypeFunction*)fdecl->type;
|
||||
assert(f != 0);
|
||||
|
||||
if (fdecl->llvmValue != 0) {
|
||||
assert(llvm::isa<llvm::Function>(fdecl->llvmValue));
|
||||
return llvm::cast<llvm::Function>(fdecl->llvmValue);
|
||||
}
|
||||
|
||||
@@ -863,9 +905,7 @@ llvm::Function* LLVM_DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
}
|
||||
|
||||
// construct function
|
||||
TypeFunction* f = (TypeFunction*)fdecl->type;
|
||||
assert(f != 0);
|
||||
llvm::FunctionType* functype = (f->llvmType == 0) ? LLVM_DtoFunctionType(fdecl) : llvm::cast<llvm::FunctionType>(f->llvmType);
|
||||
const llvm::FunctionType* functype = (f->llvmType == 0) ? LLVM_DtoFunctionType(fdecl) : llvm::cast<llvm::FunctionType>(f->llvmType);
|
||||
|
||||
// mangled name
|
||||
char* mangled_name = (fdecl->llvmInternal == LLVMintrinsic) ? fdecl->llvmInternal1 : fdecl->mangle();
|
||||
@@ -881,6 +921,7 @@ llvm::Function* LLVM_DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
|
||||
fdecl->llvmValue = func;
|
||||
f->llvmType = functype;
|
||||
assert(llvm::isa<llvm::FunctionType>(f->llvmType));
|
||||
|
||||
if (fdecl->isMain()) {
|
||||
gIR->mainFunc = func;
|
||||
|
||||
10
gen/tollvm.h
10
gen/tollvm.h
@@ -4,16 +4,16 @@ struct StructInitializer;
|
||||
|
||||
const llvm::Type* LLVM_DtoType(Type* t);
|
||||
|
||||
llvm::Type* LLVM_DtoStructType(Type* t);
|
||||
const llvm::Type* LLVM_DtoStructType(Type* t);
|
||||
llvm::Value* LLVM_DtoStructZeroInit(TypeStruct* t, llvm::Value* v);
|
||||
llvm::Value* LLVM_DtoStructCopy(TypeStruct* t, llvm::Value* dst, llvm::Value* src);
|
||||
llvm::Constant* LLVM_DtoStructInitializer(StructInitializer* si);
|
||||
|
||||
llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam = 0);
|
||||
llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl);
|
||||
const llvm::FunctionType* LLVM_DtoFunctionType(Type* t, const llvm::Type* thisparam = 0);
|
||||
const llvm::FunctionType* LLVM_DtoFunctionType(FuncDeclaration* fdecl);
|
||||
llvm::Function* LLVM_DtoDeclareFunction(FuncDeclaration* fdecl);
|
||||
|
||||
llvm::StructType* LLVM_DtoDelegateType(Type* t);
|
||||
const llvm::StructType* LLVM_DtoDelegateType(Type* t);
|
||||
llvm::Value* LLVM_DtoNullDelegate(llvm::Value* v);
|
||||
llvm::Value* LLVM_DtoDelegateCopy(llvm::Value* dst, llvm::Value* src);
|
||||
|
||||
@@ -39,5 +39,7 @@ llvm::Function* LLVM_DeclareMemCpy64();
|
||||
|
||||
llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb);
|
||||
llvm::Value* LLVM_DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb);
|
||||
llvm::Value* LLVM_DtoGEPi(llvm::Value* ptr, unsigned i0, const std::string& var, llvm::BasicBlock* bb);
|
||||
llvm::Value* LLVM_DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb);
|
||||
|
||||
#include "enums.h"
|
||||
|
||||
58
gen/toobj.c
58
gen/toobj.c
@@ -80,18 +80,21 @@ Module::genobjfile()
|
||||
delete gTargetData;
|
||||
gTargetData = 0;
|
||||
|
||||
// emit the llvm main function if necessary
|
||||
if (ir.emitMain) {
|
||||
LLVM_DtoMain();
|
||||
}
|
||||
|
||||
// verify the llvm
|
||||
std::string verifyErr;
|
||||
Logger::println("Verifying module...");
|
||||
if (llvm::verifyModule(*ir.module,llvm::ReturnStatusAction,&verifyErr))
|
||||
{
|
||||
error("%s", verifyErr.c_str());
|
||||
fatal();
|
||||
}
|
||||
|
||||
// emit the llvm main function if necessary
|
||||
if (ir.emitMain) {
|
||||
LLVM_DtoMain();
|
||||
}
|
||||
else
|
||||
Logger::println("Verification passed!");
|
||||
|
||||
// run passes
|
||||
// TODO
|
||||
@@ -386,6 +389,7 @@ void ClassDeclaration::toObjFile()
|
||||
|
||||
if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
|
||||
fd->toObjFile();
|
||||
assert(fd->llvmValue);
|
||||
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
|
||||
sinits.push_back(c);
|
||||
sinits_ty.push_back(c->getType());
|
||||
@@ -437,17 +441,11 @@ void ClassDeclaration::toObjFile()
|
||||
assert(svtblVar != 0);
|
||||
gIR->topstruct().inits[0] = svtblVar;
|
||||
|
||||
//assert(tk == gIR->topstruct().size());
|
||||
#ifndef LLVMD_NO_LOGGER
|
||||
Logger::cout() << *structtype << '\n';
|
||||
//for (size_t k=0; k<gIR->topstruct().inits.size(); ++k)
|
||||
// Logger::cout() << *gIR->topstruct().inits[k] << '\n';
|
||||
#endif
|
||||
_init = llvm::ConstantStruct::get(structtype,gIR->topstruct().inits);
|
||||
assert(_init);
|
||||
std::string initname(mangle());
|
||||
initname.append("__initZ");
|
||||
Logger::cout() << *_init << '\n';
|
||||
//Logger::cout() << *_init << '\n';
|
||||
llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType, true, _linkage, 0, initname, gIR->module);
|
||||
ts->llvmInit = initvar;
|
||||
if (define_vtable) {
|
||||
@@ -616,27 +614,33 @@ void FuncDeclaration::toObjFile()
|
||||
llvm::Function* func = LLVM_DtoDeclareFunction(this);
|
||||
|
||||
if (!gIR->queueClassMethods.empty() && gIR->queueClassMethods.back()) {
|
||||
Logger::println("queueing %s", toChars());
|
||||
assert(!gIR->classmethods.empty());
|
||||
gIR->classmethods.back().push_back(this);
|
||||
if (!llvmQueued) {
|
||||
Logger::println("queueing %s", toChars());
|
||||
assert(!gIR->classmethods.empty());
|
||||
gIR->classmethods.back().push_back(this);
|
||||
llvmQueued = true;
|
||||
}
|
||||
return; // we wait with the definition as they might invoke a virtual method and the vtable is not yet complete
|
||||
}
|
||||
|
||||
TypeFunction* f = (TypeFunction*)type;
|
||||
llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(f->llvmType);
|
||||
assert(f->llvmType);
|
||||
const llvm::FunctionType* functype = llvm::cast<llvm::FunctionType>(llvmValue->getType()->getContainedType(0));
|
||||
|
||||
// only members of the current module maybe be defined
|
||||
if (getModule() == gIR->dmodule)
|
||||
{
|
||||
llvmDModule = gIR->dmodule;
|
||||
|
||||
bool allow_fbody = true;
|
||||
// handle static constructor / destructor
|
||||
if (isStaticCtorDeclaration() || isStaticDtorDeclaration()) {
|
||||
const llvm::ArrayType* sctor_type = llvm::ArrayType::get(llvm::PointerType::get(functype),1);
|
||||
//Logger::cout() << "static ctor type: " << *sctor_type << '\n';
|
||||
|
||||
|
||||
llvm::Constant* sctor_func = llvm::cast<llvm::Constant>(llvmValue);
|
||||
//Logger::cout() << "static ctor func: " << *sctor_func << '\n';
|
||||
|
||||
|
||||
llvm::Constant* sctor_init = 0;
|
||||
if (llvmInternal == LLVMnull)
|
||||
{
|
||||
@@ -648,10 +652,9 @@ void FuncDeclaration::toObjFile()
|
||||
{
|
||||
sctor_init = llvm::ConstantArray::get(sctor_type,&sctor_func,1);
|
||||
}
|
||||
|
||||
|
||||
//Logger::cout() << "static ctor init: " << *sctor_init << '\n';
|
||||
|
||||
|
||||
|
||||
// output the llvm.global_ctors array
|
||||
const char* varname = isStaticCtorDeclaration() ? "_d_module_ctor_array" : "_d_module_dtor_array";
|
||||
llvm::GlobalVariable* sctor_arr = new llvm::GlobalVariable(sctor_type, false, llvm::GlobalValue::AppendingLinkage, sctor_init, varname, gIR->module);
|
||||
@@ -660,6 +663,9 @@ void FuncDeclaration::toObjFile()
|
||||
// function definition
|
||||
if (allow_fbody && fbody != 0)
|
||||
{
|
||||
// first make absolutely sure the type is up to date
|
||||
f->llvmType = llvmValue->getType()->getContainedType(0);
|
||||
|
||||
if (isMain())
|
||||
gIR->emitMain = true;
|
||||
|
||||
@@ -672,10 +678,10 @@ void FuncDeclaration::toObjFile()
|
||||
|
||||
//assert(gIR->scopes.empty());
|
||||
gIR->scopes.push_back(irs);
|
||||
|
||||
|
||||
// create alloca point
|
||||
f->llvmAllocaPoint = new llvm::BitCastInst(llvm::ConstantInt::get(llvm::Type::Int32Ty,0,false),llvm::Type::Int32Ty,"alloca point",gIR->scopebb());
|
||||
|
||||
|
||||
// output function body
|
||||
fbody->toIR(gIR);
|
||||
|
||||
@@ -686,7 +692,7 @@ void FuncDeclaration::toObjFile()
|
||||
//new llvm::BranchInst(irs.end, irs.begin);
|
||||
new llvm::ReturnInst(gIR->scopebb());
|
||||
}
|
||||
|
||||
|
||||
// erase alloca point
|
||||
f->llvmAllocaPoint->eraseFromParent();
|
||||
f->llvmAllocaPoint = 0;
|
||||
@@ -710,8 +716,4 @@ void FuncDeclaration::toObjFile()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
llvmDModule = gIR->dmodule;
|
||||
|
||||
Logger::println("FuncDeclaration done\n");
|
||||
}
|
||||
|
||||
BIN
lib/llvmdcore.bc
BIN
lib/llvmdcore.bc
Binary file not shown.
@@ -29,10 +29,10 @@ pragma(LLVM_internal, "intrinsic", "llvm.pcmarker")
|
||||
|
||||
pragma(LLVM_internal, "intrinsic", "llvm.prefetch")
|
||||
void llvm_prefetch(void* ptr, uint rw, uint locality);
|
||||
*/
|
||||
|
||||
pragma(LLVM_internal, "intrinsic", "llvm.readcyclecounter")
|
||||
ulong llvm_readcyclecounter();
|
||||
*/
|
||||
ulong readcyclecounter();
|
||||
|
||||
// standard C intrinsics
|
||||
pragma(LLVM_internal, "intrinsic", "llvm.memcpy.i32")
|
||||
|
||||
33
runalltests.d
Normal file
33
runalltests.d
Normal file
@@ -0,0 +1,33 @@
|
||||
module runalltests;
|
||||
|
||||
import std.file;
|
||||
import std.path;
|
||||
import std.process;
|
||||
import std.stdio;
|
||||
|
||||
int main(string[] args) {
|
||||
string[] good;
|
||||
string[] bad;
|
||||
|
||||
auto contents = listdir("test", "*.d");
|
||||
foreach(c; contents) {
|
||||
if (system("./tester.sh "~getName(c)~" ll") != 0) {
|
||||
bad ~= c;
|
||||
}
|
||||
else {
|
||||
good ~= c;
|
||||
}
|
||||
}
|
||||
|
||||
int ret = 0;
|
||||
if (bad.length > 0) {
|
||||
writefln(bad.length, '/', contents.length, " tests failed:");
|
||||
foreach(b; bad) {
|
||||
writefln(" ",b);
|
||||
}
|
||||
ret = 1;
|
||||
}
|
||||
|
||||
writefln(good.length, '/', contents.length, " tests passed");
|
||||
return ret;
|
||||
}
|
||||
@@ -4,12 +4,34 @@ class C
|
||||
{
|
||||
void f()
|
||||
{
|
||||
printf("hello world\n");
|
||||
printf("world\n");
|
||||
}
|
||||
}
|
||||
|
||||
class D : C
|
||||
{
|
||||
void f()
|
||||
{
|
||||
printf("moon\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
extern(C)
|
||||
{
|
||||
void srand(uint seed);
|
||||
int rand();
|
||||
}
|
||||
|
||||
import llvm.intrinsic;
|
||||
|
||||
void main()
|
||||
{
|
||||
scope c = new C;
|
||||
C c;
|
||||
srand(readcyclecounter());
|
||||
if (rand() % 2)
|
||||
c = new C;
|
||||
else
|
||||
c = new D;
|
||||
c.f();
|
||||
}
|
||||
|
||||
21
test/classes7.d
Normal file
21
test/classes7.d
Normal file
@@ -0,0 +1,21 @@
|
||||
module classes7;
|
||||
|
||||
class C
|
||||
{
|
||||
int i=0;
|
||||
void f()
|
||||
{
|
||||
i=42;
|
||||
}
|
||||
void g()
|
||||
{
|
||||
f();
|
||||
}
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
scope c = new C;
|
||||
c.g();
|
||||
assert(c.i == 43);
|
||||
}
|
||||
14
tester.sh
14
tester.sh
@@ -6,24 +6,30 @@ if [ -z $1 ]; then
|
||||
fi
|
||||
|
||||
if [ "$2" = "ll" ]; then
|
||||
make &&
|
||||
llvmdc $1 -Itest -odtest -c &&
|
||||
llvm-dis -f $1.bc &&
|
||||
cat $1.ll
|
||||
exit $?
|
||||
elif [ "$2" = "llopt" ]; then
|
||||
llvmdc $1 -Itest -odtest -c &&
|
||||
opt -f -o=$1.bc -std-compile-opts $1.bc &&
|
||||
llvm-dis -f $1.bc &&
|
||||
cat $1.ll
|
||||
exit $?
|
||||
elif [ "$2" = "run" ]; then
|
||||
make &&
|
||||
llvmdc $1 -Itest -odtest -of$1 &&
|
||||
$1
|
||||
exit $?
|
||||
elif [ "$2" = "c" ]; then
|
||||
make &&
|
||||
llvmdc $1 -Itest -odtest -c
|
||||
exit $?
|
||||
elif [ "$2" = "gdb" ]; then
|
||||
make &&
|
||||
gdb --args llvmdc $1 -Itest -odtest '-c'
|
||||
exit $?
|
||||
elif [ "$2" = "gdbrun" ]; then
|
||||
llvmdc $1 -Itest -odtest '-c' &&
|
||||
gdb $1
|
||||
exit $?
|
||||
else
|
||||
echo "bad command or filename"
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user