mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
[svn r140] did a lot of the work towards being able to pass multiple modules on the command line. not complete yet though
This commit is contained in:
@@ -45,7 +45,7 @@ namespace llvm
|
||||
class ConstantStruct;
|
||||
class GlobalVariable;
|
||||
}
|
||||
struct IRStruct;
|
||||
struct IrStruct;
|
||||
struct DUnion;
|
||||
|
||||
struct AggregateDeclaration : ScopeDsymbol
|
||||
@@ -110,7 +110,7 @@ struct AggregateDeclaration : ScopeDsymbol
|
||||
llvm::Constant* llvmConstClass;
|
||||
bool llvmHasUnions;
|
||||
DUnion* llvmUnion;
|
||||
IRStruct* llvmIRStruct;
|
||||
IrStruct* llvmIrStruct;
|
||||
bool llvmClassDeclared;
|
||||
bool llvmClassDefined;
|
||||
|
||||
|
||||
@@ -549,12 +549,10 @@ VarDeclaration::VarDeclaration(Loc loc, Type *type, Identifier *id, Initializer
|
||||
onstack = 0;
|
||||
canassign = 0;
|
||||
value = NULL;
|
||||
llvmNestedIndex = -1;
|
||||
llvmFieldIndex = -1;
|
||||
llvmFieldIndexOffset = 0;
|
||||
llvmNeedsStorage = false;
|
||||
llvmConstInit = NULL;
|
||||
llvmIRGlobal = NULL;
|
||||
irGlobal = NULL;
|
||||
irLocal = NULL;
|
||||
irField = NULL;
|
||||
needsStorage = false;
|
||||
}
|
||||
|
||||
Dsymbol *VarDeclaration::syntaxCopy(Dsymbol *s)
|
||||
@@ -1060,7 +1058,7 @@ void VarDeclaration::checkNestedReference(Scope *sc, Loc loc)
|
||||
fdthis->getLevel(loc, fdv);
|
||||
nestedref = 1;
|
||||
fdv->nestedFrameRef = 1;
|
||||
fdv->llvmNestedVars.insert(this);
|
||||
fdv->nestedVars.insert(this);
|
||||
//printf("var %s in function %s is nested ref\n", toChars(), fdv->toChars());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,8 +24,11 @@
|
||||
namespace llvm {
|
||||
class Value;
|
||||
}
|
||||
struct IRFunction;
|
||||
struct IRGlobal;
|
||||
struct IrFunction;
|
||||
struct IrVar;
|
||||
struct IrGlobal;
|
||||
struct IrLocal;
|
||||
struct IrField;
|
||||
|
||||
struct Expression;
|
||||
struct Statement;
|
||||
@@ -261,12 +264,13 @@ struct VarDeclaration : Declaration
|
||||
VarDeclaration *isVarDeclaration() { return (VarDeclaration *)this; }
|
||||
|
||||
// LLVMDC
|
||||
int llvmNestedIndex;
|
||||
int llvmFieldIndex;
|
||||
size_t llvmFieldIndexOffset;
|
||||
bool llvmNeedsStorage;
|
||||
llvm::Constant* llvmConstInit;
|
||||
IRGlobal* llvmIRGlobal;
|
||||
IrGlobal* irGlobal;
|
||||
IrLocal* irLocal;
|
||||
IrField* irField;
|
||||
bool needsStorage;
|
||||
|
||||
IrVar* getIrVar();
|
||||
llvm::Value*& getIrValue();
|
||||
};
|
||||
|
||||
/**************************************************************/
|
||||
@@ -609,16 +613,9 @@ struct FuncDeclaration : Declaration
|
||||
FuncDeclaration *isFuncDeclaration() { return this; }
|
||||
|
||||
// llvmdc stuff
|
||||
bool llvmQueued;
|
||||
llvm::Value* llvmThisVar;
|
||||
std::set<VarDeclaration*> llvmNestedVars;
|
||||
llvm::Value* llvmNested;
|
||||
llvm::Value* llvmArguments;
|
||||
llvm::Value* llvmArgPtr;
|
||||
llvm::Constant* llvmDwarfSubProgram;
|
||||
bool llvmRunTimeHack;
|
||||
IRFunction* llvmIRFunc;
|
||||
llvm::Value* llvmRetArg;
|
||||
bool runTimeHack;
|
||||
IrFunction* irFunc;
|
||||
std::set<VarDeclaration*> nestedVars;
|
||||
};
|
||||
|
||||
struct FuncAliasDeclaration : FuncDeclaration
|
||||
|
||||
@@ -43,10 +43,12 @@ Dsymbol::Dsymbol()
|
||||
this->isym = NULL;
|
||||
this->loc = 0;
|
||||
this->comment = NULL;
|
||||
|
||||
this->llvmInternal = LLVMnone;
|
||||
this->llvmInternal1 = NULL;
|
||||
this->llvmInternal2 = NULL;
|
||||
this->llvmValue = NULL;
|
||||
|
||||
//this->llvmValue = NULL;
|
||||
this->llvmDModule = NULL;
|
||||
|
||||
this->llvmResolved = false;
|
||||
@@ -65,10 +67,12 @@ Dsymbol::Dsymbol(Identifier *ident)
|
||||
this->isym = NULL;
|
||||
this->loc = 0;
|
||||
this->comment = NULL;
|
||||
|
||||
this->llvmInternal = LLVMnone;
|
||||
this->llvmInternal1 = NULL;
|
||||
this->llvmInternal2 = NULL;
|
||||
this->llvmValue = NULL;
|
||||
|
||||
//this->llvmValue = NULL;
|
||||
this->llvmDModule = NULL;
|
||||
|
||||
this->llvmResolved = false;
|
||||
|
||||
@@ -220,7 +220,7 @@ struct Dsymbol : Object
|
||||
char* llvmInternal1;
|
||||
char* llvmInternal2;
|
||||
|
||||
llvm::Value* llvmValue;
|
||||
//llvm::Value* llvmValue;
|
||||
Module* llvmDModule;
|
||||
|
||||
bool llvmResolved;
|
||||
|
||||
@@ -3456,7 +3456,7 @@ Expression *SymOffExp::semantic(Scope *sc)
|
||||
if (v)
|
||||
{
|
||||
v->checkNestedReference(sc, loc);
|
||||
v->llvmNeedsStorage = true;
|
||||
v->needsStorage = true;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
@@ -3601,7 +3601,7 @@ Expression *VarExp::modifiableLvalue(Scope *sc, Expression *e)
|
||||
if (v && v->canassign == 0 &&
|
||||
(var->isConst() || (global.params.Dversion > 1 && var->isFinal())))
|
||||
error("cannot modify final variable '%s'", var->toChars());
|
||||
v->llvmNeedsStorage = true;
|
||||
v->needsStorage = true;
|
||||
|
||||
if (var->isCtorinit())
|
||||
{ // It's only modifiable if inside the right constructor
|
||||
@@ -5887,7 +5887,7 @@ Expression *AddrExp::semantic(Scope *sc)
|
||||
}
|
||||
else if (v)
|
||||
{
|
||||
v->llvmNeedsStorage = true;
|
||||
v->needsStorage = true;
|
||||
}
|
||||
}
|
||||
else if (e1->op == TOKarray)
|
||||
|
||||
12
dmd/func.c
12
dmd/func.c
@@ -73,15 +73,9 @@ FuncDeclaration::FuncDeclaration(Loc loc, Loc endloc, Identifier *id, enum STC s
|
||||
nrvo_can = 1;
|
||||
nrvo_var = NULL;
|
||||
shidden = NULL;
|
||||
llvmQueued = false;
|
||||
llvmThisVar = NULL;
|
||||
llvmNested = NULL;
|
||||
llvmArguments = NULL;
|
||||
llvmArgPtr = NULL;
|
||||
llvmDwarfSubProgram = NULL;
|
||||
llvmRunTimeHack = false;
|
||||
llvmIRFunc = NULL;
|
||||
llvmRetArg = NULL;
|
||||
// llvmdc
|
||||
runTimeHack = false;
|
||||
irFunc = NULL;
|
||||
}
|
||||
|
||||
Dsymbol *FuncDeclaration::syntaxCopy(Dsymbol *s)
|
||||
|
||||
16
dmd/mtype.c
16
dmd/mtype.c
@@ -1514,7 +1514,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
|
||||
nm = name[n->ty == Twchar];
|
||||
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm);
|
||||
fd->llvmRunTimeHack = true;
|
||||
fd->runTimeHack = true;
|
||||
ec = new VarExp(0, fd);
|
||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||
arguments = new Expressions();
|
||||
@@ -1532,7 +1532,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
|
||||
nm = name[n->ty == Twchar];
|
||||
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), nm);
|
||||
fd->llvmRunTimeHack = true;
|
||||
fd->runTimeHack = true;
|
||||
ec = new VarExp(0, fd);
|
||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||
arguments = new Expressions();
|
||||
@@ -1551,7 +1551,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
assert(size);
|
||||
dup = (ident == Id::dup);
|
||||
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), dup ? Id::adDup : Id::adReverse);
|
||||
fd->llvmRunTimeHack = true;
|
||||
fd->runTimeHack = true;
|
||||
ec = new VarExp(0, fd);
|
||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||
arguments = new Expressions();
|
||||
@@ -1571,7 +1571,7 @@ Expression *TypeArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
|
||||
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(),
|
||||
(char*)(n->ty == Tbit ? "_adSortBit" : "_adSort"));
|
||||
fd->llvmRunTimeHack = true;
|
||||
fd->runTimeHack = true;
|
||||
ec = new VarExp(0, fd);
|
||||
e = e->castTo(sc, n->arrayOf()); // convert to dynamic array
|
||||
arguments = new Expressions();
|
||||
@@ -2273,7 +2273,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
Expressions *arguments;
|
||||
|
||||
fd = FuncDeclaration::genCfunc(Type::tsize_t, Id::aaLen);
|
||||
fd->llvmRunTimeHack = true;
|
||||
fd->runTimeHack = true;
|
||||
ec = new VarExp(0, fd);
|
||||
arguments = new Expressions();
|
||||
arguments->push(e);
|
||||
@@ -2289,7 +2289,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
|
||||
assert(size);
|
||||
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaKeys);
|
||||
fd->llvmRunTimeHack = true;
|
||||
fd->runTimeHack = true;
|
||||
ec = new VarExp(0, fd);
|
||||
arguments = new Expressions();
|
||||
arguments->push(e);
|
||||
@@ -2304,7 +2304,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
Expressions *arguments;
|
||||
|
||||
fd = FuncDeclaration::genCfunc(Type::tvoid->arrayOf(), Id::aaValues);
|
||||
fd->llvmRunTimeHack = true;
|
||||
fd->runTimeHack = true;
|
||||
ec = new VarExp(0, fd);
|
||||
arguments = new Expressions();
|
||||
arguments->push(e);
|
||||
@@ -2322,7 +2322,7 @@ Expression *TypeAArray::dotExp(Scope *sc, Expression *e, Identifier *ident)
|
||||
Expressions *arguments;
|
||||
|
||||
fd = FuncDeclaration::genCfunc(Type::tvoid->pointerTo(), Id::aaRehash);
|
||||
fd->llvmRunTimeHack = true;
|
||||
fd->runTimeHack = true;
|
||||
ec = new VarExp(0, fd);
|
||||
arguments = new Expressions();
|
||||
arguments->push(e->addressOf(sc));
|
||||
|
||||
@@ -1431,7 +1431,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply2");
|
||||
else
|
||||
fdapply = FuncDeclaration::genCfunc(Type::tindex, "_aaApply");
|
||||
fdapply->llvmRunTimeHack = true;
|
||||
fdapply->runTimeHack = true;
|
||||
ec = new VarExp(0, fdapply);
|
||||
Expressions *exps = new Expressions();
|
||||
exps->push(aggr);
|
||||
@@ -1473,7 +1473,7 @@ Statement *ForeachStatement::semantic(Scope *sc)
|
||||
int j = sprintf(fdname, "_aApply%s%.*s%d", r, 2, fntab[flag], dim);
|
||||
assert(j < sizeof(fdname));
|
||||
fdapply = FuncDeclaration::genCfunc(Type::tindex, fdname);
|
||||
fdapply->llvmRunTimeHack = true;
|
||||
fdapply->runTimeHack = true;
|
||||
|
||||
ec = new VarExp(0, fdapply);
|
||||
Expressions *exps = new Expressions();
|
||||
|
||||
@@ -54,7 +54,7 @@ AggregateDeclaration::AggregateDeclaration(Loc loc, Identifier *id)
|
||||
llvmInProgress = false;
|
||||
llvmHasUnions = false;
|
||||
llvmUnion = NULL;
|
||||
llvmIRStruct = NULL;
|
||||
llvmIrStruct = NULL;
|
||||
llvmClassDeclared = false;
|
||||
llvmClassDefined = false;
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ static llvm::Value* to_keyti(DValue* key)
|
||||
assert(tid);
|
||||
DtoResolveDsymbol(Type::typeinfo);
|
||||
DtoForceDeclareDsymbol(tid);
|
||||
assert(tid->llvmValue);
|
||||
return tid->llvmValue;
|
||||
assert(tid->irGlobal->value);
|
||||
return tid->irGlobal->value;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -671,13 +671,11 @@ static llvm::Value* DtoArrayEqCmp_impl(const char* func, DValue* l, DValue* r, b
|
||||
// pass element typeinfo ?
|
||||
if (useti) {
|
||||
TypeInfoDeclaration* ti = DtoDType(l->getType())->next->getTypeInfoDeclaration();
|
||||
if (!ti->llvmValue) {
|
||||
DtoForceConstInitDsymbol(ti);
|
||||
}
|
||||
Logger::cout() << "typeinfo decl: " << *ti->llvmValue << '\n';
|
||||
DtoForceConstInitDsymbol(ti);
|
||||
Logger::cout() << "typeinfo decl: " << *ti->getIrValue() << '\n';
|
||||
|
||||
pt = fn->getFunctionType()->getParamType(2);
|
||||
args.push_back(DtoBitCast(ti->llvmValue, pt));
|
||||
args.push_back(DtoBitCast(ti->getIrValue(), pt));
|
||||
}
|
||||
|
||||
return gIR->ir->CreateCall(fn, args.begin(), args.end(), "tmp");
|
||||
|
||||
224
gen/classes.cpp
224
gen/classes.cpp
@@ -16,6 +16,8 @@
|
||||
#include "gen/runtime.h"
|
||||
#include "gen/dvalue.h"
|
||||
|
||||
#include "ir/irstruct.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void LLVM_AddBaseClassData(BaseClasses* bcs)
|
||||
@@ -24,9 +26,8 @@ static void LLVM_AddBaseClassData(BaseClasses* bcs)
|
||||
for (int j=0; j<bcs->dim; j++)
|
||||
{
|
||||
BaseClass* bc = (BaseClass*)(bcs->data[j]);
|
||||
assert(bc);
|
||||
if (bc->base->isInterfaceDeclaration())
|
||||
continue; // interfaces only has methods
|
||||
continue; // interfaces only have methods
|
||||
|
||||
LLVM_AddBaseClassData(&bc->base->baseclasses);
|
||||
|
||||
@@ -38,14 +39,6 @@ static void LLVM_AddBaseClassData(BaseClasses* bcs)
|
||||
VarDeclaration* v = (VarDeclaration*)(arr->data[k]);
|
||||
v->toObjFile();
|
||||
}
|
||||
|
||||
/*for (int k=0; k < bc->base->members->dim; k++) {
|
||||
Dsymbol* dsym = (Dsymbol*)(bc->base->members->data[k]);
|
||||
if (dsym->isVarDeclaration())
|
||||
{
|
||||
dsym->toObjFile();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
@@ -63,11 +56,11 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||
assert(cd->type->ty == Tclass);
|
||||
TypeClass* ts = (TypeClass*)cd->type;
|
||||
|
||||
// make sure the IRStruct is created
|
||||
IRStruct* irstruct = cd->llvmIRStruct;
|
||||
// make sure the IrStruct is created
|
||||
IrStruct* irstruct = cd->llvmIrStruct;
|
||||
if (!irstruct) {
|
||||
irstruct = new IRStruct(ts);
|
||||
cd->llvmIRStruct = irstruct;
|
||||
irstruct = new IrStruct(ts);
|
||||
cd->llvmIrStruct = irstruct;
|
||||
}
|
||||
|
||||
// resolve the base class
|
||||
@@ -75,7 +68,7 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||
DtoResolveClass(cd->baseClass);
|
||||
}
|
||||
|
||||
// resolve interfaces
|
||||
// resolve interface vtables
|
||||
if (cd->vtblInterfaces) {
|
||||
for (int i=0; i < cd->vtblInterfaces->dim; i++) {
|
||||
BaseClass *b = (BaseClass *)cd->vtblInterfaces->data[i];
|
||||
@@ -111,7 +104,7 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||
fieldtypes.push_back(ivtblTy);
|
||||
|
||||
// add this interface to the map
|
||||
IRInterface* iri = new IRInterface(b, isaStruct(itc->llvmVtblType->get()));
|
||||
IrInterface* iri = new IrInterface(b, isaStruct(itc->llvmVtblType->get()));
|
||||
irstruct->interfaces.insert(std::make_pair(id, iri));
|
||||
}
|
||||
|
||||
@@ -140,14 +133,14 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||
VarDeclaration* fieldinit = NULL;
|
||||
size_t fieldpad = 0;
|
||||
int idx = 0;
|
||||
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
|
||||
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
|
||||
// first iteration
|
||||
if (lastoffset == (unsigned)-1) {
|
||||
lastoffset = i->first;
|
||||
fieldtype = i->second.type;
|
||||
fieldinit = i->second.var;
|
||||
prevsize = getABITypeSize(fieldtype);
|
||||
i->second.var->llvmFieldIndex = idx;
|
||||
i->second.var->irField->index = idx;
|
||||
}
|
||||
// colliding offset?
|
||||
else if (lastoffset == i->first) {
|
||||
@@ -157,15 +150,15 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||
prevsize = s;
|
||||
}
|
||||
cd->llvmHasUnions = true;
|
||||
i->second.var->llvmFieldIndex = idx;
|
||||
i->second.var->irField->index = idx;
|
||||
}
|
||||
// intersecting offset?
|
||||
else if (i->first < (lastoffset + prevsize)) {
|
||||
size_t s = getABITypeSize(i->second.type);
|
||||
assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
|
||||
cd->llvmHasUnions = true;
|
||||
i->second.var->llvmFieldIndex = idx;
|
||||
i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s;
|
||||
i->second.var->irField->index = idx;
|
||||
i->second.var->irField->indexOffset = (i->first - lastoffset) / s;
|
||||
}
|
||||
// fresh offset
|
||||
else {
|
||||
@@ -185,7 +178,7 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||
fieldtype = i->second.type;
|
||||
fieldinit = i->second.var;
|
||||
prevsize = getABITypeSize(fieldtype);
|
||||
i->second.var->llvmFieldIndex = idx;
|
||||
i->second.var->irField->index = idx;
|
||||
fieldpad = 0;
|
||||
}
|
||||
}
|
||||
@@ -199,7 +192,7 @@ void DtoResolveClass(ClassDeclaration* cd)
|
||||
|
||||
/*
|
||||
// add field types
|
||||
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
|
||||
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
|
||||
fieldtypes.push_back(i->second.type);
|
||||
}
|
||||
*/
|
||||
@@ -307,8 +300,8 @@ void DtoDeclareClass(ClassDeclaration* cd)
|
||||
assert(cd->type->ty == Tclass);
|
||||
TypeClass* ts = (TypeClass*)cd->type;
|
||||
|
||||
assert(cd->llvmIRStruct);
|
||||
IRStruct* irstruct = cd->llvmIRStruct;
|
||||
assert(cd->llvmIrStruct);
|
||||
IrStruct* irstruct = cd->llvmIrStruct;
|
||||
|
||||
gIR->structs.push_back(irstruct);
|
||||
gIR->classes.push_back(cd);
|
||||
@@ -318,56 +311,45 @@ void DtoDeclareClass(ClassDeclaration* cd)
|
||||
needs_definition = true;
|
||||
}
|
||||
|
||||
// interface vtables are emitted by the class implementing them
|
||||
// also, interfaces have no static initializer
|
||||
// also, abstract classes have no vtable
|
||||
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
|
||||
|
||||
// interfaces have no static initializer
|
||||
// same goes for abstract classes
|
||||
if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
|
||||
// vtable
|
||||
std::string varname("_D");
|
||||
varname.append(cd->mangle());
|
||||
varname.append("6__vtblZ");
|
||||
|
||||
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
|
||||
|
||||
const llvm::StructType* svtbl_ty = isaStruct(ts->llvmVtblType->get());
|
||||
cd->llvmVtbl = new llvm::GlobalVariable(svtbl_ty, true, _linkage, 0, varname, gIR->module);
|
||||
}
|
||||
|
||||
// build interface info type
|
||||
std::vector<const llvm::Type*> types;
|
||||
// ClassInfo classinfo
|
||||
ClassDeclaration* cd2 = ClassDeclaration::classinfo;
|
||||
DtoResolveClass(cd2);
|
||||
types.push_back(getPtrToType(cd2->type->llvmType->get()));
|
||||
// void*[] vtbl
|
||||
std::vector<const llvm::Type*> vtbltypes;
|
||||
vtbltypes.push_back(DtoSize_t());
|
||||
const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
|
||||
vtbltypes.push_back(byteptrptrty);
|
||||
types.push_back(llvm::StructType::get(vtbltypes));
|
||||
// int offset
|
||||
types.push_back(llvm::Type::Int32Ty);
|
||||
// create type
|
||||
const llvm::StructType* infoTy = llvm::StructType::get(types);
|
||||
// get interface info type
|
||||
const llvm::StructType* infoTy = DtoInterfaceInfoType();
|
||||
|
||||
// interface info array
|
||||
if (cd->vtblInterfaces->dim > 0) {
|
||||
// symbol name
|
||||
std::string nam = "_D";
|
||||
nam.append(cd->mangle());
|
||||
nam.append("16__interfaceInfosZ");
|
||||
// resolve array type
|
||||
const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim);
|
||||
// declare global
|
||||
irstruct->interfaceInfosTy = arrTy;
|
||||
irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
|
||||
}
|
||||
// interface info array
|
||||
if (cd->vtblInterfaces->dim > 0) {
|
||||
// symbol name
|
||||
std::string nam = "_D";
|
||||
nam.append(cd->mangle());
|
||||
nam.append("16__interfaceInfosZ");
|
||||
// resolve array type
|
||||
const llvm::ArrayType* arrTy = llvm::ArrayType::get(infoTy, cd->vtblInterfaces->dim);
|
||||
// declare global
|
||||
irstruct->interfaceInfosTy = arrTy;
|
||||
irstruct->interfaceInfos = new llvm::GlobalVariable(arrTy, true, _linkage, NULL, nam, gIR->module);
|
||||
}
|
||||
|
||||
// interfaces have no static initializer
|
||||
// same goes for abstract classes
|
||||
if (!cd->isInterfaceDeclaration() && !cd->isAbstract()) {
|
||||
// interface vtables
|
||||
unsigned idx = 0;
|
||||
for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
|
||||
for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
|
||||
{
|
||||
ClassDeclaration* id = i->first;
|
||||
IRInterface* iri = i->second;
|
||||
IrInterface* iri = i->second;
|
||||
|
||||
std::string nam("_D");
|
||||
nam.append(cd->mangle());
|
||||
@@ -377,7 +359,6 @@ void DtoDeclareClass(ClassDeclaration* cd)
|
||||
|
||||
assert(iri->vtblTy);
|
||||
iri->vtbl = new llvm::GlobalVariable(iri->vtblTy, true, _linkage, 0, nam, gIR->module);
|
||||
iri->infoTy = infoTy;
|
||||
llvm::Constant* idxs[2] = {DtoConstUint(0), DtoConstUint(idx)};
|
||||
iri->info = llvm::ConstantExpr::getGetElementPtr(irstruct->interfaceInfos, idxs, 2);
|
||||
idx++;
|
||||
@@ -420,7 +401,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||
Logger::println("DtoConstInitClass(%s): %s", cd->toPrettyChars(), cd->loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
IRStruct* irstruct = cd->llvmIRStruct;
|
||||
IrStruct* irstruct = cd->llvmIrStruct;
|
||||
gIR->structs.push_back(irstruct);
|
||||
gIR->classes.push_back(cd);
|
||||
|
||||
@@ -431,12 +412,12 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||
const llvm::StructType* vtbltype = isaStruct(ts->llvmVtblType->get());
|
||||
|
||||
// make sure each offset knows its default initializer
|
||||
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
|
||||
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
|
||||
{
|
||||
IRStruct::Offset* so = &i->second;
|
||||
IrStruct::Offset* so = &i->second;
|
||||
llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
|
||||
so->init = finit;
|
||||
so->var->llvmConstInit = finit;
|
||||
so->var->irField->constInit = finit;
|
||||
}
|
||||
|
||||
// fill out fieldtypes/inits
|
||||
@@ -465,9 +446,11 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||
size_t dataoffset = 2;
|
||||
|
||||
// next comes interface vtables
|
||||
for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
|
||||
const llvm::StructType* infoTy = DtoInterfaceInfoType();
|
||||
for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
|
||||
{
|
||||
IRInterface* iri = i->second;
|
||||
IrInterface* iri = i->second;
|
||||
iri->infoTy = infoTy;
|
||||
if (cd->isAbstract())
|
||||
{
|
||||
fieldinits.push_back(llvm::Constant::getNullValue(iri->vtblTy));
|
||||
@@ -482,7 +465,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||
|
||||
/*
|
||||
// rest
|
||||
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
|
||||
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
|
||||
Logger::println("adding fieldinit for: %s", i->second.var->toChars());
|
||||
fieldinits.push_back(i->second.init);
|
||||
}
|
||||
@@ -493,7 +476,7 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||
for (size_t i=0; i<nfi; ++i) {
|
||||
llvm::Constant* c;
|
||||
if (irstruct->defaultFields[i] != NULL) {
|
||||
c = irstruct->defaultFields[i]->llvmConstInit;
|
||||
c = irstruct->defaultFields[i]->irField->constInit;
|
||||
assert(c);
|
||||
}
|
||||
else {
|
||||
@@ -535,8 +518,8 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||
|
||||
if (FuncDeclaration* fd = dsym->isFuncDeclaration()) {
|
||||
DtoForceDeclareDsymbol(fd);
|
||||
assert(fd->llvmValue);
|
||||
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
|
||||
assert(fd->irFunc->func);
|
||||
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->irFunc->func);
|
||||
// cast if necessary (overridden method)
|
||||
if (c->getType() != vtbltype->getElementType(k))
|
||||
c = llvm::ConstantExpr::getBitCast(c, vtbltype->getElementType(k));
|
||||
@@ -568,30 +551,34 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||
// create interface vtable const initalizers
|
||||
int idx = 2;
|
||||
int idxScale = PTRSIZE;
|
||||
for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
|
||||
for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
|
||||
{
|
||||
ClassDeclaration* id = i->first;
|
||||
assert(id->type->ty == Tclass);
|
||||
TypeClass* its = (TypeClass*)id->type;
|
||||
|
||||
IRInterface* iri = i->second;
|
||||
IrInterface* iri = i->second;
|
||||
BaseClass* b = iri->base;
|
||||
|
||||
const llvm::StructType* ivtbl_ty = isaStruct(its->llvmVtblType->get());
|
||||
|
||||
// generate interface info initializer
|
||||
std::vector<llvm::Constant*> infoInits;
|
||||
|
||||
// classinfo
|
||||
assert(id->llvmClass);
|
||||
llvm::Constant* c = id->llvmClass;
|
||||
infoInits.push_back(c);
|
||||
|
||||
// vtbl
|
||||
const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
|
||||
c = llvm::ConstantExpr::getBitCast(iri->vtbl, byteptrptrty);
|
||||
c = DtoConstSlice(DtoConstSize_t(b->vtbl.dim), c);
|
||||
infoInits.push_back(c);
|
||||
|
||||
// offset
|
||||
infoInits.push_back(DtoConstInt(idx*idxScale));
|
||||
|
||||
// create interface info initializer constant
|
||||
iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
|
||||
|
||||
@@ -608,8 +595,9 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||
FuncDeclaration* fd = dsym->isFuncDeclaration();
|
||||
assert(fd);
|
||||
DtoForceDeclareDsymbol(fd);
|
||||
assert(fd->llvmValue);
|
||||
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->llvmValue);
|
||||
assert(fd->irFunc->func);
|
||||
llvm::Constant* c = llvm::cast<llvm::Constant>(fd->irFunc->func);
|
||||
|
||||
// we have to bitcast, as the type created in ResolveClass expects a different this type
|
||||
c = llvm::ConstantExpr::getBitCast(c, iri->vtblTy->getContainedType(k));
|
||||
iinits.push_back(c);
|
||||
@@ -629,7 +617,39 @@ void DtoConstInitClass(ClassDeclaration* cd)
|
||||
|
||||
idx++;
|
||||
}
|
||||
} // !abstract
|
||||
}
|
||||
// we always generate interfaceinfos as best we can
|
||||
else
|
||||
{
|
||||
for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
|
||||
{
|
||||
ClassDeclaration* id = i->first;
|
||||
assert(id->type->ty == Tclass);
|
||||
TypeClass* its = (TypeClass*)id->type;
|
||||
|
||||
IrInterface* iri = i->second;
|
||||
BaseClass* b = iri->base;
|
||||
|
||||
// generate interface info initializer
|
||||
std::vector<llvm::Constant*> infoInits;
|
||||
|
||||
// classinfo
|
||||
assert(id->llvmClass);
|
||||
llvm::Constant* c = id->llvmClass;
|
||||
infoInits.push_back(c);
|
||||
|
||||
// vtbl
|
||||
const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
|
||||
c = DtoConstSlice(DtoConstSize_t(0), getNullPtr(byteptrptrty));
|
||||
infoInits.push_back(c);
|
||||
|
||||
// offset
|
||||
infoInits.push_back(DtoConstInt(0));
|
||||
|
||||
// create interface info initializer constant
|
||||
iri->infoInit = llvm::cast<llvm::ConstantStruct>(llvm::ConstantStruct::get(iri->infoTy, infoInits));
|
||||
}
|
||||
}
|
||||
|
||||
gIR->classes.pop_back();
|
||||
gIR->structs.pop_back();
|
||||
@@ -658,11 +678,11 @@ void DtoDefineClass(ClassDeclaration* cd)
|
||||
cd->llvmVtbl->setInitializer(cd->llvmConstVtbl);
|
||||
|
||||
// initialize interface vtables
|
||||
IRStruct* irstruct = cd->llvmIRStruct;
|
||||
IrStruct* irstruct = cd->llvmIrStruct;
|
||||
std::vector<llvm::Constant*> infoInits;
|
||||
for (IRStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
|
||||
for (IrStruct::InterfaceIter i=irstruct->interfaces.begin(); i!=irstruct->interfaces.end(); ++i)
|
||||
{
|
||||
IRInterface* iri = i->second;
|
||||
IrInterface* iri = i->second;
|
||||
iri->vtbl->setInitializer(iri->vtblInit);
|
||||
infoInits.push_back(iri->infoInit);
|
||||
}
|
||||
@@ -711,7 +731,7 @@ DValue* DtoNewClass(TypeClass* tc, NewExp* newexp)
|
||||
LOG_SCOPE;
|
||||
DValue* thisval = newexp->thisexp->toElem(gIR);
|
||||
size_t idx = 2;
|
||||
idx += tc->sym->llvmIRStruct->interfaces.size();
|
||||
idx += tc->sym->llvmIrStruct->interfaces.size();
|
||||
llvm::Value* dst = thisval->getRVal();
|
||||
llvm::Value* src = DtoGEPi(mem,0,idx,"tmp");
|
||||
Logger::cout() << "dst: " << *dst << "\nsrc: " << *src << '\n';
|
||||
@@ -723,10 +743,10 @@ DValue* DtoNewClass(TypeClass* tc, NewExp* newexp)
|
||||
Logger::println("Resolving nested context");
|
||||
LOG_SCOPE;
|
||||
size_t idx = 2;
|
||||
idx += tc->sym->llvmIRStruct->interfaces.size();
|
||||
llvm::Value* nest = gIR->func()->decl->llvmNested;
|
||||
idx += tc->sym->llvmIrStruct->interfaces.size();
|
||||
llvm::Value* nest = gIR->func()->decl->irFunc->nestedVar;
|
||||
if (!nest)
|
||||
nest = gIR->func()->decl->llvmThisVar;
|
||||
nest = gIR->func()->decl->irFunc->thisVar;
|
||||
assert(nest);
|
||||
llvm::Value* gep = DtoGEPi(mem,0,idx,"tmp");
|
||||
nest = DtoBitCast(nest, gep->getType()->getContainedType(0));
|
||||
@@ -792,7 +812,7 @@ DValue* DtoCallClassCtor(TypeClass* type, CtorDeclaration* ctor, Array* argument
|
||||
|
||||
assert(ctor);
|
||||
DtoForceDeclareDsymbol(ctor);
|
||||
llvm::Function* fn = llvm::cast<llvm::Function>(ctor->llvmValue);
|
||||
llvm::Function* fn = ctor->irFunc->func;
|
||||
TypeFunction* tf = (TypeFunction*)DtoDType(ctor->type);
|
||||
|
||||
std::vector<llvm::Value*> ctorargs;
|
||||
@@ -822,8 +842,8 @@ void DtoCallClassDtors(TypeClass* tc, llvm::Value* instance)
|
||||
for (size_t i=0; i<arr->dim; i++)
|
||||
{
|
||||
FuncDeclaration* fd = (FuncDeclaration*)arr->data[i];
|
||||
assert(fd->llvmValue);
|
||||
new llvm::CallInst(fd->llvmValue, instance, "", gIR->scopebb());
|
||||
assert(fd->irFunc->func);
|
||||
new llvm::CallInst(fd->irFunc->func, instance, "", gIR->scopebb());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1031,37 +1051,37 @@ llvm::Value* DtoIndexClass(llvm::Value* ptr, ClassDeclaration* cd, Type* t, unsi
|
||||
|
||||
unsigned dataoffset = 2 + cd->vtblInterfaces->dim;
|
||||
|
||||
IRStruct* irstruct = cd->llvmIRStruct;
|
||||
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
|
||||
IrStruct* irstruct = cd->llvmIrStruct;
|
||||
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
|
||||
//for (unsigned i=0; i<cd->fields.dim; ++i) {
|
||||
//VarDeclaration* vd = (VarDeclaration*)cd->fields.data[i];
|
||||
VarDeclaration* vd = i->second.var;
|
||||
assert(vd);
|
||||
Type* vdtype = DtoDType(vd->type);
|
||||
Logger::println("found %u type %s", vd->offset, vdtype->toChars());
|
||||
assert(vd->llvmFieldIndex >= 0);
|
||||
assert(vd->irField->index >= 0);
|
||||
if (os == vd->offset && vdtype == t) {
|
||||
idxs.push_back(vd->llvmFieldIndex + dataoffset);
|
||||
idxs.push_back(vd->irField->index + dataoffset);
|
||||
Logger::cout() << "indexing: " << *ptr << '\n';
|
||||
ptr = DtoGEP(ptr, idxs, "tmp");
|
||||
if (ptr->getType() != llt)
|
||||
ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
|
||||
Logger::cout() << "indexing: " << *ptr << '\n';
|
||||
if (vd->llvmFieldIndexOffset)
|
||||
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
|
||||
if (vd->irField->indexOffset)
|
||||
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
|
||||
Logger::cout() << "indexing: " << *ptr << '\n';
|
||||
return ptr;
|
||||
}
|
||||
else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
|
||||
TypeStruct* ts = (TypeStruct*)vdtype;
|
||||
StructDeclaration* ssd = ts->sym;
|
||||
idxs.push_back(vd->llvmFieldIndex + dataoffset);
|
||||
if (vd->llvmFieldIndexOffset) {
|
||||
idxs.push_back(vd->irField->index + dataoffset);
|
||||
if (vd->irField->indexOffset) {
|
||||
Logger::println("has union field offset");
|
||||
ptr = DtoGEP(ptr, idxs, "tmp");
|
||||
if (ptr->getType() != llt)
|
||||
ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
|
||||
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
|
||||
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
|
||||
std::vector<unsigned> tmp;
|
||||
return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
|
||||
}
|
||||
@@ -1153,7 +1173,7 @@ static llvm::Constant* build_offti_entry(VarDeclaration* vd)
|
||||
vd->type->getTypeInfo(NULL);
|
||||
assert(vd->type->vtinfo);
|
||||
DtoForceDeclareDsymbol(vd->type->vtinfo);
|
||||
llvm::Constant* c = isaConstant(vd->type->vtinfo->llvmValue);
|
||||
llvm::Constant* c = isaConstant(vd->type->vtinfo->getIrValue());
|
||||
|
||||
const llvm::Type* tiTy = getPtrToType(Type::typeinfo->type->llvmType->get());
|
||||
//Logger::cout() << "tiTy = " << *tiTy << '\n';
|
||||
@@ -1230,8 +1250,8 @@ static llvm::Constant* build_class_dtor(ClassDeclaration* cd)
|
||||
else if (cd->dtors.dim == 1) {
|
||||
DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[0];
|
||||
DtoForceDeclareDsymbol(d);
|
||||
assert(d->llvmValue);
|
||||
return llvm::ConstantExpr::getBitCast(isaConstant(d->llvmValue), getPtrToType(llvm::Type::Int8Ty));
|
||||
assert(d->irFunc->func);
|
||||
return llvm::ConstantExpr::getBitCast(isaConstant(d->irFunc->func), getPtrToType(llvm::Type::Int8Ty));
|
||||
}
|
||||
|
||||
std::string gname("_D");
|
||||
@@ -1249,8 +1269,8 @@ static llvm::Constant* build_class_dtor(ClassDeclaration* cd)
|
||||
{
|
||||
DtorDeclaration *d = (DtorDeclaration *)cd->dtors.data[i];
|
||||
DtoForceDeclareDsymbol(d);
|
||||
assert(d->llvmValue);
|
||||
builder.CreateCall(d->llvmValue, thisptr);
|
||||
assert(d->irFunc->func);
|
||||
builder.CreateCall(d->irFunc->func, thisptr);
|
||||
}
|
||||
builder.CreateRetVoid();
|
||||
|
||||
@@ -1380,7 +1400,7 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
|
||||
inits.push_back(c);
|
||||
|
||||
// interfaces array
|
||||
IRStruct* irstruct = cd->llvmIRStruct;
|
||||
IrStruct* irstruct = cd->llvmIrStruct;
|
||||
if (cd->isInterfaceDeclaration() || !irstruct->interfaceInfos || cd->isAbstract()) {
|
||||
c = cinfo->llvmConstInit->getOperand(5);
|
||||
}
|
||||
@@ -1446,7 +1466,7 @@ void DtoDefineClassInfo(ClassDeclaration* cd)
|
||||
// default constructor
|
||||
if (cd->defaultCtor && !cd->isInterfaceDeclaration() && !cd->isAbstract()) {
|
||||
DtoForceDeclareDsymbol(cd->defaultCtor);
|
||||
c = isaConstant(cd->defaultCtor->llvmValue);
|
||||
c = isaConstant(cd->defaultCtor->irFunc->func);
|
||||
const llvm::Type* toTy = cinfo->llvmConstInit->getOperand(12)->getType();
|
||||
c = llvm::ConstantExpr::getBitCast(c, toTy);
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ static llvm::Function* DtoDeclareVaFunction(FuncDeclaration* fdecl)
|
||||
llvm::Function* func = llvm::dyn_cast<llvm::Function>(fn);
|
||||
assert(func);
|
||||
assert(func->isIntrinsic());
|
||||
fdecl->llvmValue = func;
|
||||
fdecl->irFunc->func = func;
|
||||
return func;
|
||||
}
|
||||
|
||||
@@ -257,7 +257,7 @@ void DtoResolveFunction(FuncDeclaration* fdecl)
|
||||
Logger::println("DtoResolveFunction(%s): %s", fdecl->toPrettyChars(), fdecl->loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
if (fdecl->llvmRunTimeHack) {
|
||||
if (fdecl->runTimeHack) {
|
||||
gIR->declareList.push_back(fdecl);
|
||||
TypeFunction* tf = (TypeFunction*)fdecl->type;
|
||||
tf->llvmRetInPtr = DtoIsPassedByRef(tf->next);
|
||||
@@ -309,10 +309,12 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
fatal();
|
||||
}
|
||||
|
||||
if (fdecl->llvmRunTimeHack) {
|
||||
if (fdecl->runTimeHack) {
|
||||
Logger::println("runtime hack func chars: %s", fdecl->toChars());
|
||||
if (!fdecl->llvmValue)
|
||||
fdecl->llvmValue = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars());
|
||||
if (!fdecl->irFunc) {
|
||||
fdecl->irFunc = new IrFunction(fdecl);
|
||||
fdecl->irFunc->func = LLVM_D_GetRuntimeFunction(gIR->module, fdecl->toChars());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -323,8 +325,8 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
else if (fdecl->llvmInternal == LLVMva_start)
|
||||
declareOnly = true;
|
||||
|
||||
if (!fdecl->llvmIRFunc) {
|
||||
fdecl->llvmIRFunc = new IRFunction(fdecl);
|
||||
if (!fdecl->irFunc) {
|
||||
fdecl->irFunc = new IrFunction(fdecl);
|
||||
}
|
||||
|
||||
// mangled name
|
||||
@@ -351,7 +353,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
assert(func->getFunctionType() == functype);
|
||||
|
||||
// add func to IRFunc
|
||||
fdecl->llvmIRFunc->func = func;
|
||||
fdecl->irFunc->func = func;
|
||||
|
||||
// calling convention
|
||||
if (!vafunc && fdecl->llvmInternal != LLVMintrinsic)
|
||||
@@ -372,7 +374,7 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
func->setCallingConv(llvm::CallingConv::C);
|
||||
}
|
||||
|
||||
fdecl->llvmValue = func;
|
||||
fdecl->irFunc->func = func;
|
||||
assert(llvm::isa<llvm::FunctionType>(f->llvmType->get()));
|
||||
|
||||
// main
|
||||
@@ -394,22 +396,22 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
int k = 0;
|
||||
if (f->llvmRetInPtr) {
|
||||
iarg->setName("retval");
|
||||
fdecl->llvmRetArg = iarg;
|
||||
fdecl->irFunc->retArg = iarg;
|
||||
++iarg;
|
||||
}
|
||||
if (f->llvmUsesThis) {
|
||||
iarg->setName("this");
|
||||
fdecl->llvmThisVar = iarg;
|
||||
assert(fdecl->llvmThisVar);
|
||||
fdecl->irFunc->thisVar = iarg;
|
||||
assert(fdecl->irFunc->thisVar);
|
||||
++iarg;
|
||||
}
|
||||
|
||||
if (f->linkage == LINKd && f->varargs == 1) {
|
||||
iarg->setName("_arguments");
|
||||
fdecl->llvmArguments = iarg;
|
||||
fdecl->irFunc->_arguments = iarg;
|
||||
++iarg;
|
||||
iarg->setName("_argptr");
|
||||
fdecl->llvmArgPtr = iarg;
|
||||
fdecl->irFunc->_argptr = iarg;
|
||||
++iarg;
|
||||
}
|
||||
|
||||
@@ -420,7 +422,9 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
//Logger::println("identifier: '%s' %p\n", arg->ident->toChars(), arg->ident);
|
||||
if (arg && arg->ident != 0) {
|
||||
if (arg->vardecl) {
|
||||
arg->vardecl->llvmValue = iarg;
|
||||
assert(!arg->vardecl->irLocal);
|
||||
arg->vardecl->irLocal = new IrLocal(arg->vardecl);
|
||||
arg->vardecl->irLocal->value = iarg;
|
||||
}
|
||||
iarg->setName(arg->ident->toChars());
|
||||
}
|
||||
@@ -458,14 +462,14 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
||||
if (!mo->llvmCompileUnit) {
|
||||
mo->llvmCompileUnit = DtoDwarfCompileUnit(mo,false);
|
||||
}
|
||||
fd->llvmDwarfSubProgram = DtoDwarfSubProgram(fd, mo->llvmCompileUnit);
|
||||
fd->irFunc->dwarfSubProg = DtoDwarfSubProgram(fd, mo->llvmCompileUnit);
|
||||
}
|
||||
|
||||
Type* t = DtoDType(fd->type);
|
||||
TypeFunction* f = (TypeFunction*)t;
|
||||
assert(f->llvmType);
|
||||
|
||||
llvm::Function* func = fd->llvmIRFunc->func;
|
||||
llvm::Function* func = fd->irFunc->func;
|
||||
const llvm::FunctionType* functype = func->getFunctionType();
|
||||
|
||||
// only members of the current module or template instances maybe be defined
|
||||
@@ -477,8 +481,8 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
||||
if (fd->fbody != 0)
|
||||
{
|
||||
Logger::println("Doing function body for: %s", fd->toChars());
|
||||
assert(fd->llvmIRFunc);
|
||||
gIR->functions.push_back(fd->llvmIRFunc);
|
||||
assert(fd->irFunc);
|
||||
gIR->functions.push_back(fd->irFunc);
|
||||
|
||||
if (fd->isMain())
|
||||
gIR->emitMain = true;
|
||||
@@ -496,7 +500,8 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
||||
// need result variable? (not nested)
|
||||
if (fd->vresult && !fd->vresult->nestedref) {
|
||||
Logger::println("non-nested vresult value");
|
||||
fd->vresult->llvmValue = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
|
||||
fd->vresult->irLocal = new IrLocal(fd->vresult);
|
||||
fd->vresult->irLocal->value = new llvm::AllocaInst(DtoType(fd->vresult->type),"function_vresult",allocaPoint);
|
||||
}
|
||||
|
||||
// give arguments storage
|
||||
@@ -505,16 +510,16 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
||||
Argument* arg = Argument::getNth(f->parameters, i);
|
||||
if (arg && arg->vardecl) {
|
||||
VarDeclaration* vd = arg->vardecl;
|
||||
if (!vd->llvmNeedsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
|
||||
if (!vd->needsStorage || vd->nestedref || vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type))
|
||||
continue;
|
||||
llvm::Value* a = vd->llvmValue;
|
||||
llvm::Value* a = vd->irLocal->value;
|
||||
assert(a);
|
||||
std::string s(a->getName());
|
||||
Logger::println("giving argument '%s' storage", s.c_str());
|
||||
s.append("_storage");
|
||||
llvm::Value* v = new llvm::AllocaInst(a->getType(),s,allocaPoint);
|
||||
gIR->ir->CreateStore(a,v);
|
||||
vd->llvmValue = v;
|
||||
vd->irLocal->value = v;
|
||||
}
|
||||
else {
|
||||
Logger::attention(fd->loc, "some unknown argument: %s", arg ? arg->toChars() : 0);
|
||||
@@ -527,29 +532,32 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
||||
llvm::Value* parentNested = NULL;
|
||||
if (FuncDeclaration* fd2 = fd->toParent2()->isFuncDeclaration()) {
|
||||
if (!fd->isStatic()) // huh?
|
||||
parentNested = fd2->llvmNested;
|
||||
parentNested = fd2->irFunc->nestedVar;
|
||||
}
|
||||
|
||||
// need result variable? (nested)
|
||||
if (fd->vresult && fd->vresult->nestedref) {
|
||||
Logger::println("nested vresult value: %s", fd->vresult->toChars());
|
||||
fd->llvmNestedVars.insert(fd->vresult);
|
||||
fd->nestedVars.insert(fd->vresult);
|
||||
}
|
||||
|
||||
// construct nested variables struct
|
||||
if (!fd->llvmNestedVars.empty() || parentNested) {
|
||||
if (!fd->nestedVars.empty() || parentNested) {
|
||||
std::vector<const llvm::Type*> nestTypes;
|
||||
int j = 0;
|
||||
if (parentNested) {
|
||||
nestTypes.push_back(parentNested->getType());
|
||||
j++;
|
||||
}
|
||||
for (std::set<VarDeclaration*>::iterator i=fd->llvmNestedVars.begin(); i!=fd->llvmNestedVars.end(); ++i) {
|
||||
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
|
||||
VarDeclaration* vd = *i;
|
||||
vd->llvmNestedIndex = j++;
|
||||
if (!vd->irLocal)
|
||||
vd->irLocal = new IrLocal(vd);
|
||||
vd->irLocal->nestedIndex = j++;
|
||||
if (vd->isParameter()) {
|
||||
assert(vd->llvmValue);
|
||||
nestTypes.push_back(vd->llvmValue->getType());
|
||||
|
||||
assert(vd->irLocal->value);
|
||||
nestTypes.push_back(vd->irLocal->value->getType());
|
||||
}
|
||||
else {
|
||||
nestTypes.push_back(DtoType(vd->type));
|
||||
@@ -557,17 +565,18 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
||||
}
|
||||
const llvm::StructType* nestSType = llvm::StructType::get(nestTypes);
|
||||
Logger::cout() << "nested var struct has type:" << *nestSType << '\n';
|
||||
fd->llvmNested = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
|
||||
fd->irFunc->nestedVar = new llvm::AllocaInst(nestSType,"nestedvars",allocaPoint);
|
||||
if (parentNested) {
|
||||
assert(fd->llvmThisVar);
|
||||
llvm::Value* ptr = gIR->ir->CreateBitCast(fd->llvmThisVar, parentNested->getType(), "tmp");
|
||||
gIR->ir->CreateStore(ptr, DtoGEPi(fd->llvmNested, 0,0, "tmp"));
|
||||
assert(fd->irFunc->thisVar);
|
||||
llvm::Value* ptr = gIR->ir->CreateBitCast(fd->irFunc->thisVar, parentNested->getType(), "tmp");
|
||||
gIR->ir->CreateStore(ptr, DtoGEPi(fd->irFunc->nestedVar, 0,0, "tmp"));
|
||||
}
|
||||
for (std::set<VarDeclaration*>::iterator i=fd->llvmNestedVars.begin(); i!=fd->llvmNestedVars.end(); ++i) {
|
||||
for (std::set<VarDeclaration*>::iterator i=fd->nestedVars.begin(); i!=fd->nestedVars.end(); ++i) {
|
||||
VarDeclaration* vd = *i;
|
||||
if (vd->isParameter()) {
|
||||
gIR->ir->CreateStore(vd->llvmValue, DtoGEPi(fd->llvmNested, 0, vd->llvmNestedIndex, "tmp"));
|
||||
vd->llvmValue = fd->llvmNested;
|
||||
assert(vd->irLocal);
|
||||
gIR->ir->CreateStore(vd->irLocal->value, DtoGEPi(fd->irFunc->nestedVar, 0, vd->irLocal->nestedIndex, "tmp"));
|
||||
vd->irLocal->value = fd->irFunc->nestedVar;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -575,9 +584,9 @@ void DtoDefineFunc(FuncDeclaration* fd)
|
||||
// copy _argptr to a memory location
|
||||
if (f->linkage == LINKd && f->varargs == 1)
|
||||
{
|
||||
llvm::Value* argptrmem = new llvm::AllocaInst(fd->llvmArgPtr->getType(), "_argptrmem", gIR->topallocapoint());
|
||||
new llvm::StoreInst(fd->llvmArgPtr, argptrmem, gIR->scopebb());
|
||||
fd->llvmArgPtr = argptrmem;
|
||||
llvm::Value* argptrmem = new llvm::AllocaInst(fd->irFunc->_argptr->getType(), "_argptrmem", gIR->topallocapoint());
|
||||
new llvm::StoreInst(fd->irFunc->_argptr, argptrmem, gIR->scopebb());
|
||||
fd->irFunc->_argptr = argptrmem;
|
||||
}
|
||||
|
||||
// output function body
|
||||
|
||||
@@ -40,7 +40,7 @@ IRState::IRState()
|
||||
ir.state = this;
|
||||
}
|
||||
|
||||
IRFunction* IRState::func()
|
||||
IrFunction* IRState::func()
|
||||
{
|
||||
assert(!functions.empty() && "Function stack is empty!");
|
||||
return functions.back();
|
||||
@@ -64,7 +64,7 @@ llvm::Instruction* IRState::topallocapoint()
|
||||
return functions.back()->allocapoint;
|
||||
}
|
||||
|
||||
IRStruct* IRState::topstruct()
|
||||
IrStruct* IRState::topstruct()
|
||||
{
|
||||
assert(!structs.empty() && "Struct vector is empty!");
|
||||
return structs.back();
|
||||
@@ -101,32 +101,6 @@ bool IRState::scopereturned()
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IRStruct::IRStruct(Type* t)
|
||||
: recty((t->llvmType != NULL) ? *t->llvmType : llvm::OpaqueType::get())
|
||||
{
|
||||
type = t;
|
||||
defined = false;
|
||||
constinited = false;
|
||||
interfaceInfosTy = NULL;
|
||||
interfaceInfos = NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IRFinally::IRFinally()
|
||||
{
|
||||
bb = 0;
|
||||
retbb = 0;
|
||||
}
|
||||
|
||||
IRFinally::IRFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb)
|
||||
{
|
||||
bb = b;
|
||||
retbb = rb;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
LLVMBuilder* IRBuilderHelper::operator->()
|
||||
{
|
||||
LLVMBuilder& b = state->scope().builder;
|
||||
@@ -136,20 +110,6 @@ LLVMBuilder* IRBuilderHelper::operator->()
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IRFunction::IRFunction(FuncDeclaration* fd)
|
||||
{
|
||||
decl = fd;
|
||||
Type* t = DtoDType(fd->type);
|
||||
assert(t->ty == Tfunction);
|
||||
type = (TypeFunction*)t;
|
||||
func = NULL;
|
||||
allocapoint = NULL;
|
||||
finallyretval = NULL;
|
||||
defined = false;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IRExp::IRExp()
|
||||
{
|
||||
e1 = e2 = NULL;
|
||||
@@ -162,11 +122,3 @@ IRExp::IRExp(Expression* l, Expression* r, DValue* val)
|
||||
e2 = r;
|
||||
v = val;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IRGlobal::IRGlobal(VarDeclaration* v) :
|
||||
type(llvm::OpaqueType::get())
|
||||
{
|
||||
var = v;
|
||||
}
|
||||
|
||||
119
gen/irstate.h
119
gen/irstate.h
@@ -1,15 +1,16 @@
|
||||
#ifndef LLVMDC_GEN_IRSTATE_H
|
||||
#define LLVMDC_GEN_IRSTATE_H
|
||||
|
||||
#include <stack>
|
||||
#include <vector>
|
||||
#include <deque>
|
||||
#include <map>
|
||||
#include <list>
|
||||
|
||||
#include "root.h"
|
||||
#include "aggregate.h"
|
||||
|
||||
#include "ir/irfunction.h"
|
||||
#include "ir/irstruct.h"
|
||||
#include "ir/irvar.h"
|
||||
|
||||
// global ir state for current module
|
||||
struct IRState;
|
||||
extern IRState* gIR;
|
||||
@@ -23,13 +24,6 @@ struct Module;
|
||||
struct TypeStruct;
|
||||
struct BaseClass;
|
||||
|
||||
/*
|
||||
struct LLVMValue
|
||||
{
|
||||
std::vector<llvm::Value*> vals;
|
||||
};
|
||||
*/
|
||||
|
||||
// represents a scope
|
||||
struct IRScope
|
||||
{
|
||||
@@ -41,94 +35,6 @@ struct IRScope
|
||||
IRScope(llvm::BasicBlock* b, llvm::BasicBlock* e);
|
||||
};
|
||||
|
||||
struct IRInterface : Object
|
||||
{
|
||||
BaseClass* base;
|
||||
ClassDeclaration* decl;
|
||||
|
||||
const llvm::StructType* vtblTy;
|
||||
llvm::ConstantStruct* vtblInit;
|
||||
llvm::GlobalVariable* vtbl;
|
||||
|
||||
const llvm::StructType* infoTy;
|
||||
llvm::ConstantStruct* infoInit;
|
||||
llvm::Constant* info;
|
||||
|
||||
IRInterface(BaseClass* b, const llvm::StructType* vt)
|
||||
{
|
||||
base = b;
|
||||
decl = b->base;
|
||||
vtblTy = vt;
|
||||
vtblInit = NULL;
|
||||
vtbl = NULL;
|
||||
infoTy = NULL;
|
||||
infoInit = NULL;
|
||||
info = NULL;
|
||||
}
|
||||
};
|
||||
|
||||
// represents a struct or class
|
||||
struct IRStruct : Object
|
||||
{
|
||||
struct Offset
|
||||
{
|
||||
VarDeclaration* var;
|
||||
const llvm::Type* type;
|
||||
llvm::Constant* init;
|
||||
|
||||
Offset(VarDeclaration* v, const llvm::Type* ty)
|
||||
: var(v), type(ty), init(NULL) {}
|
||||
};
|
||||
|
||||
typedef std::multimap<unsigned, Offset> OffsetMap;
|
||||
typedef std::vector<VarDeclaration*> VarDeclVector;
|
||||
typedef std::map<ClassDeclaration*, IRInterface*> InterfaceMap;
|
||||
typedef InterfaceMap::iterator InterfaceIter;
|
||||
|
||||
public:
|
||||
IRStruct(Type*);
|
||||
|
||||
Type* type;
|
||||
llvm::PATypeHolder recty;
|
||||
OffsetMap offsets;
|
||||
VarDeclVector defaultFields;
|
||||
|
||||
InterfaceMap interfaces;
|
||||
const llvm::ArrayType* interfaceInfosTy;
|
||||
llvm::GlobalVariable* interfaceInfos;
|
||||
|
||||
bool defined;
|
||||
bool constinited;
|
||||
};
|
||||
|
||||
// represents a finally block
|
||||
struct IRFinally
|
||||
{
|
||||
llvm::BasicBlock* bb;
|
||||
llvm::BasicBlock* retbb;
|
||||
|
||||
IRFinally();
|
||||
IRFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb);
|
||||
};
|
||||
|
||||
// represents a function
|
||||
struct IRFunction : Object
|
||||
{
|
||||
llvm::Function* func;
|
||||
llvm::Instruction* allocapoint;
|
||||
FuncDeclaration* decl;
|
||||
TypeFunction* type;
|
||||
|
||||
// finally blocks
|
||||
typedef std::vector<IRFinally> FinallyVec;
|
||||
FinallyVec finallys;
|
||||
llvm::Value* finallyretval;
|
||||
|
||||
bool defined;
|
||||
|
||||
IRFunction(FuncDeclaration*);
|
||||
};
|
||||
|
||||
struct IRBuilderHelper
|
||||
{
|
||||
IRState* state;
|
||||
@@ -144,15 +50,6 @@ struct IRExp
|
||||
IRExp(Expression* l, Expression* r, DValue* val);
|
||||
};
|
||||
|
||||
// represents a global variable
|
||||
struct IRGlobal : Object
|
||||
{
|
||||
VarDeclaration* var;
|
||||
llvm::PATypeHolder type;
|
||||
|
||||
IRGlobal(VarDeclaration* v);
|
||||
};
|
||||
|
||||
// represents the module
|
||||
struct IRState
|
||||
{
|
||||
@@ -163,18 +60,18 @@ struct IRState
|
||||
llvm::Module* module;
|
||||
|
||||
// functions
|
||||
typedef std::vector<IRFunction*> FunctionVector;
|
||||
typedef std::vector<IrFunction*> FunctionVector;
|
||||
FunctionVector functions;
|
||||
IRFunction* func();
|
||||
IrFunction* func();
|
||||
|
||||
llvm::Function* topfunc();
|
||||
TypeFunction* topfunctype();
|
||||
llvm::Instruction* topallocapoint();
|
||||
|
||||
// structs
|
||||
typedef std::vector<IRStruct*> StructVector;
|
||||
typedef std::vector<IrStruct*> StructVector;
|
||||
StructVector structs;
|
||||
IRStruct* topstruct();
|
||||
IrStruct* topstruct();
|
||||
|
||||
// classes TODO move into IRClass
|
||||
typedef std::vector<ClassDeclaration*> ClassDeclVec;
|
||||
|
||||
@@ -25,6 +25,8 @@
|
||||
#include "gen/todebug.h"
|
||||
#include "gen/dvalue.h"
|
||||
|
||||
#include "ir/irfunction.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void CompoundStatement::toIR(IRState* p)
|
||||
@@ -57,13 +59,13 @@ void ReturnStatement::toIR(IRState* p)
|
||||
if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
|
||||
assert(DtoIsPassedByRef(exptype));
|
||||
|
||||
IRFunction* f = p->func();
|
||||
IrFunction* f = p->func();
|
||||
assert(f->type->llvmRetInPtr);
|
||||
assert(f->decl->llvmRetArg);
|
||||
assert(f->decl->irFunc->retArg);
|
||||
|
||||
if (global.params.symdebug) DtoDwarfStopPoint(loc.linnum);
|
||||
|
||||
DValue* rvar = new DVarValue(f->type->next, f->decl->llvmRetArg, true);
|
||||
DValue* rvar = new DVarValue(f->type->next, f->decl->irFunc->retArg, true);
|
||||
|
||||
p->exps.push_back(IRExp(NULL,exp,rvar));
|
||||
DValue* e = exp->toElem(p);
|
||||
@@ -72,7 +74,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||
if (!e->inPlace())
|
||||
DtoAssign(rvar, e);
|
||||
|
||||
IRFunction::FinallyVec& fin = f->finallys;
|
||||
IrFunction::FinallyVec& fin = f->finallys;
|
||||
if (fin.empty()) {
|
||||
if (global.params.symdebug) DtoDwarfFuncEnd(f->decl);
|
||||
new llvm::ReturnInst(p->scopebb());
|
||||
@@ -88,7 +90,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||
delete e;
|
||||
Logger::cout() << "return value is '" <<*v << "'\n";
|
||||
|
||||
IRFunction::FinallyVec& fin = p->func()->finallys;
|
||||
IrFunction::FinallyVec& fin = p->func()->finallys;
|
||||
if (fin.empty()) {
|
||||
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
|
||||
new llvm::ReturnInst(v, p->scopebb());
|
||||
@@ -105,7 +107,7 @@ void ReturnStatement::toIR(IRState* p)
|
||||
else
|
||||
{
|
||||
if (p->topfunc()->getReturnType() == llvm::Type::VoidTy) {
|
||||
IRFunction::FinallyVec& fin = p->func()->finallys;
|
||||
IrFunction::FinallyVec& fin = p->func()->finallys;
|
||||
if (fin.empty()) {
|
||||
if (global.params.symdebug) DtoDwarfFuncEnd(p->func()->decl);
|
||||
new llvm::ReturnInst(p->scopebb());
|
||||
@@ -425,8 +427,8 @@ void TryFinallyStatement::toIR(IRState* p)
|
||||
|
||||
// do the try block
|
||||
p->scope() = IRScope(trybb,finallybb);
|
||||
gIR->func()->finallys.push_back(IRFinally(finallybb,finallyretbb));
|
||||
IRFinally& fin = p->func()->finallys.back();
|
||||
gIR->func()->finallys.push_back(IrFinally(finallybb,finallyretbb));
|
||||
IrFinally& fin = p->func()->finallys.back();
|
||||
|
||||
assert(body);
|
||||
body->toIR(p);
|
||||
@@ -453,7 +455,7 @@ void TryFinallyStatement::toIR(IRState* p)
|
||||
// terminate finally (return path)
|
||||
size_t nfin = p->func()->finallys.size();
|
||||
if (nfin > 1) {
|
||||
IRFinally& ofin = p->func()->finallys[nfin-2];
|
||||
IrFinally& ofin = p->func()->finallys[nfin-2];
|
||||
p->ir->CreateBr(ofin.retbb);
|
||||
}
|
||||
// no outer
|
||||
@@ -793,7 +795,13 @@ void ForeachStatement::toIR(IRState* p)
|
||||
// key
|
||||
const llvm::Type* keytype = key ? DtoType(key->type) : DtoSize_t();
|
||||
llvm::Value* keyvar = new llvm::AllocaInst(keytype, "foreachkey", p->topallocapoint());
|
||||
if (key) key->llvmValue = keyvar;
|
||||
if (key)
|
||||
{
|
||||
//key->llvmValue = keyvar;
|
||||
assert(!key->irLocal);
|
||||
key->irLocal = new IrLocal(key);
|
||||
key->irLocal->value = keyvar;
|
||||
}
|
||||
llvm::Value* zerokey = llvm::ConstantInt::get(keytype,0,false);
|
||||
|
||||
// value
|
||||
@@ -801,6 +809,8 @@ void ForeachStatement::toIR(IRState* p)
|
||||
llvm::Value* valvar = NULL;
|
||||
if (!value->isRef() && !value->isOut())
|
||||
valvar = new llvm::AllocaInst(valtype, "foreachval", p->topallocapoint());
|
||||
assert(!value->irLocal);
|
||||
value->irLocal = new IrLocal(value);
|
||||
|
||||
// what to iterate
|
||||
DValue* aggrval = aggr->toElem(p);
|
||||
@@ -896,15 +906,15 @@ void ForeachStatement::toIR(IRState* p)
|
||||
llvm::Constant* zero = llvm::ConstantInt::get(keytype,0,false);
|
||||
llvm::Value* loadedKey = p->ir->CreateLoad(keyvar,"tmp");
|
||||
if (aggrtype->ty == Tsarray)
|
||||
value->llvmValue = DtoGEP(val,zero,loadedKey,"tmp");
|
||||
value->irLocal->value = DtoGEP(val,zero,loadedKey,"tmp");
|
||||
else if (aggrtype->ty == Tarray)
|
||||
value->llvmValue = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb());
|
||||
value->irLocal->value = new llvm::GetElementPtrInst(val,loadedKey,"tmp",p->scopebb());
|
||||
|
||||
if (!value->isRef() && !value->isOut()) {
|
||||
DValue* dst = new DVarValue(value->type, valvar, true);
|
||||
DValue* src = new DVarValue(value->type, value->llvmValue, true);
|
||||
DValue* src = new DVarValue(value->type, value->irLocal->value, true);
|
||||
DtoAssign(dst, src);
|
||||
value->llvmValue = valvar;
|
||||
value->irLocal->value = valvar;
|
||||
}
|
||||
|
||||
// emit body
|
||||
@@ -982,7 +992,7 @@ void WithStatement::toIR(IRState* p)
|
||||
assert(body);
|
||||
|
||||
DValue* e = exp->toElem(p);
|
||||
wthis->llvmValue = e->getRVal();
|
||||
wthis->irLocal->value = e->getRVal();
|
||||
delete e;
|
||||
|
||||
body->toIR(p);
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
#include "gen/logger.h"
|
||||
#include "gen/structs.h"
|
||||
|
||||
#include "ir/irstruct.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
const llvm::Type* DtoStructType(Type* t)
|
||||
@@ -93,7 +95,7 @@ llvm::Constant* DtoConstStructInitializer(StructInitializer* si)
|
||||
VarDeclaration* vd = (VarDeclaration*)si->vars.data[i];
|
||||
assert(vd);
|
||||
llvm::Constant* v = DtoConstInitializer(vd->type, ini);
|
||||
inits.push_back(DUnionIdx(vd->llvmFieldIndex, vd->llvmFieldIndexOffset, v));
|
||||
inits.push_back(DUnionIdx(vd->irField->index, vd->irField->indexOffset, v));
|
||||
}
|
||||
|
||||
DtoConstInitStruct((StructDeclaration*)si->ad);
|
||||
@@ -121,26 +123,26 @@ llvm::Value* DtoIndexStruct(llvm::Value* ptr, StructDeclaration* sd, Type* t, un
|
||||
VarDeclaration* vd = (VarDeclaration*)sd->fields.data[i];
|
||||
Type* vdtype = DtoDType(vd->type);
|
||||
Logger::println("found %u type %s", vd->offset, vdtype->toChars());
|
||||
assert(vd->llvmFieldIndex >= 0);
|
||||
assert(vd->irField->index >= 0);
|
||||
if (os == vd->offset && vdtype == t) {
|
||||
idxs.push_back(vd->llvmFieldIndex);
|
||||
idxs.push_back(vd->irField->index);
|
||||
ptr = DtoGEP(ptr, idxs, "tmp");
|
||||
if (ptr->getType() != llt)
|
||||
ptr = gIR->ir->CreateBitCast(ptr, llt, "tmp");
|
||||
if (vd->llvmFieldIndexOffset)
|
||||
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
|
||||
if (vd->irField->indexOffset)
|
||||
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
|
||||
return ptr;
|
||||
}
|
||||
else if (vdtype->ty == Tstruct && (vd->offset + vdtype->size()) > os) {
|
||||
TypeStruct* ts = (TypeStruct*)vdtype;
|
||||
StructDeclaration* ssd = ts->sym;
|
||||
idxs.push_back(vd->llvmFieldIndex);
|
||||
if (vd->llvmFieldIndexOffset) {
|
||||
idxs.push_back(vd->irField->index);
|
||||
if (vd->irField->indexOffset) {
|
||||
Logger::println("has union field offset");
|
||||
ptr = DtoGEP(ptr, idxs, "tmp");
|
||||
if (ptr->getType() != llt)
|
||||
ptr = DtoBitCast(ptr, llt);
|
||||
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->llvmFieldIndexOffset), "tmp", gIR->scopebb());
|
||||
ptr = new llvm::GetElementPtrInst(ptr, DtoConstUint(vd->irField->indexOffset), "tmp", gIR->scopebb());
|
||||
std::vector<unsigned> tmp;
|
||||
return DtoIndexStruct(ptr, ssd, t, os-vd->offset, tmp);
|
||||
}
|
||||
@@ -176,8 +178,8 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||
|
||||
TypeStruct* ts = (TypeStruct*)DtoDType(sd->type);
|
||||
|
||||
IRStruct* irstruct = new IRStruct(ts);
|
||||
sd->llvmIRStruct = irstruct;
|
||||
IrStruct* irstruct = new IrStruct(ts);
|
||||
sd->llvmIrStruct = irstruct;
|
||||
gIR->structs.push_back(irstruct);
|
||||
|
||||
// fields
|
||||
@@ -233,7 +235,7 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||
VarDeclaration* fieldinit = NULL;
|
||||
size_t fieldpad = 0;
|
||||
int idx = 0;
|
||||
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
|
||||
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i) {
|
||||
// first iteration
|
||||
if (lastoffset == (unsigned)-1) {
|
||||
lastoffset = i->first;
|
||||
@@ -241,7 +243,7 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||
fieldtype = i->second.type;
|
||||
fieldinit = i->second.var;
|
||||
prevsize = getABITypeSize(fieldtype);
|
||||
i->second.var->llvmFieldIndex = idx;
|
||||
i->second.var->irField->index = idx;
|
||||
}
|
||||
// colliding offset?
|
||||
else if (lastoffset == i->first) {
|
||||
@@ -251,15 +253,15 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||
prevsize = s;
|
||||
}
|
||||
sd->llvmHasUnions = true;
|
||||
i->second.var->llvmFieldIndex = idx;
|
||||
i->second.var->irField->index = idx;
|
||||
}
|
||||
// intersecting offset?
|
||||
else if (i->first < (lastoffset + prevsize)) {
|
||||
size_t s = getABITypeSize(i->second.type);
|
||||
assert((i->first + s) <= (lastoffset + prevsize)); // this holds because all types are aligned to their size
|
||||
sd->llvmHasUnions = true;
|
||||
i->second.var->llvmFieldIndex = idx;
|
||||
i->second.var->llvmFieldIndexOffset = (i->first - lastoffset) / s;
|
||||
i->second.var->irField->index = idx;
|
||||
i->second.var->irField->indexOffset = (i->first - lastoffset) / s;
|
||||
}
|
||||
// fresh offset
|
||||
else {
|
||||
@@ -279,7 +281,7 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||
fieldtype = i->second.type;
|
||||
fieldinit = i->second.var;
|
||||
prevsize = getABITypeSize(fieldtype);
|
||||
i->second.var->llvmFieldIndex = idx;
|
||||
i->second.var->irField->index = idx;
|
||||
fieldpad = 0;
|
||||
}
|
||||
}
|
||||
@@ -349,16 +351,16 @@ void DtoConstInitStruct(StructDeclaration* sd)
|
||||
Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
IRStruct* irstruct = sd->llvmIRStruct;
|
||||
IrStruct* irstruct = sd->llvmIrStruct;
|
||||
gIR->structs.push_back(irstruct);
|
||||
|
||||
// make sure each offset knows its default initializer
|
||||
for (IRStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
|
||||
for (IrStruct::OffsetMap::iterator i=irstruct->offsets.begin(); i!=irstruct->offsets.end(); ++i)
|
||||
{
|
||||
IRStruct::Offset* so = &i->second;
|
||||
IrStruct::Offset* so = &i->second;
|
||||
llvm::Constant* finit = DtoConstFieldInitializer(so->var->type, so->var->init);
|
||||
so->init = finit;
|
||||
so->var->llvmConstInit = finit;
|
||||
so->var->irField->constInit = finit;
|
||||
}
|
||||
|
||||
const llvm::StructType* structtype = isaStruct(sd->type->llvmType->get());
|
||||
@@ -369,7 +371,7 @@ void DtoConstInitStruct(StructDeclaration* sd)
|
||||
for (size_t i=0; i<nfi; ++i) {
|
||||
llvm::Constant* c;
|
||||
if (irstruct->defaultFields[i] != NULL) {
|
||||
c = irstruct->defaultFields[i]->llvmConstInit;
|
||||
c = irstruct->defaultFields[i]->irField->constInit;
|
||||
assert(c);
|
||||
}
|
||||
else {
|
||||
@@ -435,12 +437,12 @@ void DtoDefineStruct(StructDeclaration* sd)
|
||||
DUnion::DUnion()
|
||||
{
|
||||
DUnionField* f = NULL;
|
||||
IRStruct* topstruct = gIR->topstruct();
|
||||
IrStruct* topstruct = gIR->topstruct();
|
||||
bool unions = false;
|
||||
for (IRStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i)
|
||||
for (IrStruct::OffsetMap::iterator i=topstruct->offsets.begin(); i!=topstruct->offsets.end(); ++i)
|
||||
{
|
||||
unsigned o = i->first;
|
||||
IRStruct::Offset* so = &i->second;
|
||||
IrStruct::Offset* so = &i->second;
|
||||
const llvm::Type* ft = so->init->getType();
|
||||
size_t sz = getABITypeSize(ft);
|
||||
if (f == NULL) { // new field
|
||||
|
||||
@@ -164,14 +164,14 @@ llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariab
|
||||
|
||||
void DtoDwarfFuncStart(FuncDeclaration* fd)
|
||||
{
|
||||
assert(fd->llvmDwarfSubProgram);
|
||||
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), dbgToArrTy(fd->llvmDwarfSubProgram));
|
||||
assert(fd->irFunc->dwarfSubProg);
|
||||
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), dbgToArrTy(fd->irFunc->dwarfSubProg));
|
||||
}
|
||||
|
||||
void DtoDwarfFuncEnd(FuncDeclaration* fd)
|
||||
{
|
||||
assert(fd->llvmDwarfSubProgram);
|
||||
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), dbgToArrTy(fd->llvmDwarfSubProgram));
|
||||
assert(fd->irFunc->dwarfSubProg);
|
||||
gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), dbgToArrTy(fd->irFunc->dwarfSubProg));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
99
gen/toir.cpp
99
gen/toir.cpp
@@ -57,12 +57,14 @@ DValue* DeclarationExp::toElem(IRState* p)
|
||||
DtoAnnotation(toChars());
|
||||
|
||||
Logger::println("vdtype = %s", vd->type->toChars());
|
||||
|
||||
// referenced by nested delegate?
|
||||
if (vd->nestedref) {
|
||||
Logger::println("has nestedref set");
|
||||
vd->llvmValue = p->func()->decl->llvmNested;
|
||||
assert(vd->llvmValue);
|
||||
assert(vd->llvmNestedIndex >= 0);
|
||||
assert(vd->irLocal);
|
||||
vd->irLocal->value = p->func()->decl->irFunc->nestedVar;
|
||||
assert(vd->irLocal->value);
|
||||
assert(vd->irLocal->nestedIndex >= 0);
|
||||
}
|
||||
// normal stack variable
|
||||
else {
|
||||
@@ -70,14 +72,16 @@ DValue* DeclarationExp::toElem(IRState* p)
|
||||
const llvm::Type* lltype = DtoType(vd->type);
|
||||
llvm::AllocaInst* allocainst = new llvm::AllocaInst(lltype, vd->toChars(), p->topallocapoint());
|
||||
//allocainst->setAlignment(vd->type->alignsize()); // TODO
|
||||
vd->llvmValue = allocainst;
|
||||
assert(!vd->irLocal);
|
||||
vd->irLocal = new IrLocal(vd);
|
||||
vd->irLocal->value = allocainst;
|
||||
}
|
||||
|
||||
Logger::cout() << "llvm value for decl: " << *vd->llvmValue << '\n';
|
||||
Logger::cout() << "llvm value for decl: " << *vd->irLocal->value << '\n';
|
||||
DValue* ie = DtoInitializer(vd->init);
|
||||
}
|
||||
|
||||
return new DVarValue(vd, vd->llvmValue, true);
|
||||
return new DVarValue(vd, vd->getIrValue(), true);
|
||||
}
|
||||
// struct declaration
|
||||
else if (StructDeclaration* s = declaration->isStructDeclaration())
|
||||
@@ -149,19 +153,19 @@ DValue* VarExp::toElem(IRState* p)
|
||||
if (vd->ident == Id::_arguments)
|
||||
{
|
||||
Logger::println("Id::_arguments");
|
||||
if (!vd->llvmValue)
|
||||
vd->llvmValue = p->func()->decl->llvmArguments;
|
||||
assert(vd->llvmValue);
|
||||
return new DVarValue(vd, vd->llvmValue, true);
|
||||
if (!vd->getIrValue())
|
||||
vd->getIrValue() = p->func()->decl->irFunc->_arguments;
|
||||
assert(vd->getIrValue());
|
||||
return new DVarValue(vd, vd->getIrValue(), true);
|
||||
}
|
||||
// _argptr
|
||||
else if (vd->ident == Id::_argptr)
|
||||
{
|
||||
Logger::println("Id::_argptr");
|
||||
if (!vd->llvmValue)
|
||||
vd->llvmValue = p->func()->decl->llvmArgPtr;
|
||||
assert(vd->llvmValue);
|
||||
return new DVarValue(vd, vd->llvmValue, true);
|
||||
if (!vd->getIrValue())
|
||||
vd->getIrValue() = p->func()->decl->irFunc->_argptr;
|
||||
assert(vd->getIrValue());
|
||||
return new DVarValue(vd, vd->getIrValue(), true);
|
||||
}
|
||||
// _dollar
|
||||
else if (vd->ident == Id::dollar)
|
||||
@@ -176,13 +180,13 @@ DValue* VarExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::println("TypeInfoDeclaration");
|
||||
DtoForceDeclareDsymbol(tid);
|
||||
assert(tid->llvmValue);
|
||||
assert(tid->getIrValue());
|
||||
const llvm::Type* vartype = DtoType(type);
|
||||
llvm::Value* m;
|
||||
if (tid->llvmValue->getType() != getPtrToType(vartype))
|
||||
m = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp");
|
||||
if (tid->getIrValue()->getType() != getPtrToType(vartype))
|
||||
m = p->ir->CreateBitCast(tid->getIrValue(), vartype, "tmp");
|
||||
else
|
||||
m = tid->llvmValue;
|
||||
m = tid->getIrValue();
|
||||
return new DVarValue(vd, m, true);
|
||||
}
|
||||
// classinfo
|
||||
@@ -201,16 +205,16 @@ DValue* VarExp::toElem(IRState* p)
|
||||
// function parameter
|
||||
else if (vd->isParameter()) {
|
||||
Logger::println("function param");
|
||||
if (!vd->llvmValue) {
|
||||
if (!vd->getIrValue()) {
|
||||
// TODO: determine this properly
|
||||
// this happens when the DMD frontend generates by pointer wrappers for struct opEquals(S) and opCmp(S)
|
||||
vd->llvmValue = &p->func()->func->getArgumentList().back();
|
||||
vd->getIrValue() = &p->func()->func->getArgumentList().back();
|
||||
}
|
||||
if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->llvmValue)) {
|
||||
return new DVarValue(vd, vd->llvmValue, true);
|
||||
if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->getIrValue())) {
|
||||
return new DVarValue(vd, vd->getIrValue(), true);
|
||||
}
|
||||
else if (llvm::isa<llvm::Argument>(vd->llvmValue)) {
|
||||
return new DImValue(type, vd->llvmValue);
|
||||
else if (llvm::isa<llvm::Argument>(vd->getIrValue())) {
|
||||
return new DImValue(type, vd->getIrValue());
|
||||
}
|
||||
else assert(0);
|
||||
}
|
||||
@@ -220,11 +224,11 @@ DValue* VarExp::toElem(IRState* p)
|
||||
vd->toObjFile();
|
||||
DtoConstInitGlobal(vd);
|
||||
}
|
||||
if (!vd->llvmValue || vd->llvmValue->getType()->isAbstract()) {
|
||||
if (!vd->getIrValue() || vd->getIrValue()->getType()->isAbstract()) {
|
||||
Logger::println("global variable not resolved :/ %s", vd->toChars());
|
||||
assert(0);
|
||||
}
|
||||
return new DVarValue(vd, vd->llvmValue, true);
|
||||
return new DVarValue(vd, vd->getIrValue(), true);
|
||||
}
|
||||
}
|
||||
else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
|
||||
@@ -233,7 +237,7 @@ DValue* VarExp::toElem(IRState* p)
|
||||
if (fdecl->llvmInternal != LLVMva_arg) {// && fdecl->llvmValue == 0)
|
||||
DtoForceDeclareDsymbol(fdecl);
|
||||
}
|
||||
return new DFuncValue(fdecl, fdecl->llvmValue);
|
||||
return new DFuncValue(fdecl, fdecl->irFunc->func);
|
||||
}
|
||||
else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration())
|
||||
{
|
||||
@@ -274,11 +278,11 @@ llvm::Constant* VarExp::toConstElem(IRState* p)
|
||||
else if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
|
||||
{
|
||||
DtoForceDeclareDsymbol(ti);
|
||||
assert(ti->llvmValue);
|
||||
assert(ti->getIrValue());
|
||||
const llvm::Type* vartype = DtoType(type);
|
||||
llvm::Constant* m = isaConstant(ti->llvmValue);
|
||||
llvm::Constant* m = isaConstant(ti->getIrValue());
|
||||
assert(m);
|
||||
if (ti->llvmValue->getType() != getPtrToType(vartype))
|
||||
if (ti->getIrValue()->getType() != getPtrToType(vartype))
|
||||
m = llvm::ConstantExpr::getBitCast(m, vartype);
|
||||
return m;
|
||||
}
|
||||
@@ -974,7 +978,7 @@ DValue* CallExp::toElem(IRState* p)
|
||||
llargs[j] = new llvm::AllocaInst(argiter->get()->getContainedType(0),"rettmp",p->topallocapoint());
|
||||
}
|
||||
|
||||
if (dfn && dfn->func && dfn->func->llvmRunTimeHack) {
|
||||
if (dfn && dfn->func && dfn->func->runTimeHack) {
|
||||
const llvm::Type* rettype = getPtrToType(DtoType(type));
|
||||
if (llargs[j]->getType() != llfnty->getParamType(j)) {
|
||||
Logger::println("llvmRunTimeHack==true - force casting return value param");
|
||||
@@ -1075,8 +1079,8 @@ DValue* CallExp::toElem(IRState* p)
|
||||
Expression* argexp = (Expression*)arguments->data[i];
|
||||
TypeInfoDeclaration* tidecl = argexp->type->getTypeInfoDeclaration();
|
||||
DtoForceDeclareDsymbol(tidecl);
|
||||
assert(tidecl->llvmValue);
|
||||
vtypeinfos.push_back(tidecl->llvmValue);
|
||||
assert(tidecl->getIrValue());
|
||||
vtypeinfos.push_back(tidecl->getIrValue());
|
||||
llvm::Value* v = p->ir->CreateBitCast(vtypeinfos[i], typeinfotype, "tmp");
|
||||
p->ir->CreateStore(v, DtoGEPi(typeinfomem,0,i,"tmp"));
|
||||
}
|
||||
@@ -1108,7 +1112,7 @@ DValue* CallExp::toElem(IRState* p)
|
||||
}
|
||||
|
||||
// this hack is necessary :/
|
||||
if (dfn && dfn->func && dfn->func->llvmRunTimeHack) {
|
||||
if (dfn && dfn->func && dfn->func->runTimeHack) {
|
||||
if (llfnty->getParamType(j) != NULL) {
|
||||
if (llargs[j]->getType() != llfnty->getParamType(j)) {
|
||||
Logger::println("llvmRunTimeHack==true - force casting argument");
|
||||
@@ -1137,7 +1141,7 @@ DValue* CallExp::toElem(IRState* p)
|
||||
llvm::CallInst* call = new llvm::CallInst(funcval, llargs.begin(), llargs.end(), varname, p->scopebb());
|
||||
llvm::Value* retllval = (retinptr) ? llargs[0] : call;
|
||||
|
||||
if (retinptr && dfn && dfn->func && dfn->func->llvmRunTimeHack) {
|
||||
if (retinptr && dfn && dfn->func && dfn->func->runTimeHack) {
|
||||
const llvm::Type* rettype = getPtrToType(DtoType(type));
|
||||
if (retllval->getType() != rettype) {
|
||||
Logger::println("llvmRunTimeHack==true - force casting return value");
|
||||
@@ -1208,12 +1212,12 @@ DValue* SymOffExp::toElem(IRState* p)
|
||||
vd->toObjFile(); // TODO
|
||||
}
|
||||
|
||||
assert(vd->llvmValue);
|
||||
assert(vd->getIrValue());
|
||||
Type* t = DtoDType(type);
|
||||
Type* tnext = DtoDType(t->next);
|
||||
Type* vdtype = DtoDType(vd->type);
|
||||
|
||||
llvm::Value* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->llvmValue;
|
||||
llvm::Value* llvalue = vd->nestedref ? DtoNestedVariable(vd) : vd->getIrValue();
|
||||
llvm::Value* varmem = 0;
|
||||
|
||||
if (vdtype->ty == Tstruct && !(t->ty == Tpointer && t->next == vdtype)) {
|
||||
@@ -1287,9 +1291,8 @@ DValue* AddrExp::toElem(IRState* p)
|
||||
//Logger::println("FuncDeclaration");
|
||||
FuncDeclaration* fd = fv->func;
|
||||
assert(fd);
|
||||
if (fd->llvmValue == 0)
|
||||
DtoForceDeclareDsymbol(fd);
|
||||
return new DFuncValue(fd, fd->llvmValue);
|
||||
DtoForceDeclareDsymbol(fd);
|
||||
return new DFuncValue(fd, fd->irFunc->func);
|
||||
}
|
||||
else if (DImValue* im = v->isIm()) {
|
||||
Logger::println("is immediate");
|
||||
@@ -1394,7 +1397,7 @@ DValue* DotVarExp::toElem(IRState* p)
|
||||
// super call
|
||||
if (e1->op == TOKsuper) {
|
||||
DtoForceDeclareDsymbol(fdecl);
|
||||
funcval = fdecl->llvmValue;
|
||||
funcval = fdecl->irFunc->func;
|
||||
assert(funcval);
|
||||
}
|
||||
// normal virtual call
|
||||
@@ -1415,7 +1418,7 @@ DValue* DotVarExp::toElem(IRState* p)
|
||||
// static call
|
||||
else {
|
||||
DtoForceDeclareDsymbol(fdecl);
|
||||
funcval = fdecl->llvmValue;
|
||||
funcval = fdecl->irFunc->func;
|
||||
assert(funcval);
|
||||
//assert(funcval->getType() == DtoType(fdecl->type));
|
||||
}
|
||||
@@ -1438,7 +1441,7 @@ DValue* ThisExp::toElem(IRState* p)
|
||||
|
||||
if (VarDeclaration* vd = var->isVarDeclaration()) {
|
||||
llvm::Value* v;
|
||||
v = p->func()->decl->llvmThisVar;
|
||||
v = p->func()->decl->irFunc->thisVar;
|
||||
if (llvm::isa<llvm::AllocaInst>(v))
|
||||
v = new llvm::LoadInst(v, "tmp", p->scopebb());
|
||||
return new DThisValue(vd, v);
|
||||
@@ -2187,7 +2190,7 @@ DValue* DelegateExp::toElem(IRState* p)
|
||||
if (DFuncValue* f = u->isFunc()) {
|
||||
//assert(f->vthis);
|
||||
//uval = f->vthis;
|
||||
llvm::Value* nestvar = p->func()->decl->llvmNested;
|
||||
llvm::Value* nestvar = p->func()->decl->irFunc->nestedVar;
|
||||
if (nestvar)
|
||||
uval = nestvar;
|
||||
else
|
||||
@@ -2213,7 +2216,7 @@ DValue* DelegateExp::toElem(IRState* p)
|
||||
else if (func->toParent()->isInterfaceDeclaration())
|
||||
assert(0 && "TODO delegate to interface method");
|
||||
else
|
||||
castfptr = func->llvmValue;
|
||||
castfptr = func->irFunc->func;
|
||||
|
||||
castfptr = DtoBitCast(castfptr, fptr->getType()->getContainedType(0));
|
||||
DtoStore(castfptr, fptr);
|
||||
@@ -2440,7 +2443,7 @@ DValue* FuncExp::toElem(IRState* p)
|
||||
|
||||
llvm::Value* context = DtoGEPi(lval,0,0,"tmp",p->scopebb());
|
||||
const llvm::PointerType* pty = isaPointer(context->getType()->getContainedType(0));
|
||||
llvm::Value* llvmNested = p->func()->decl->llvmNested;
|
||||
llvm::Value* llvmNested = p->func()->decl->irFunc->nestedVar;
|
||||
if (llvmNested == NULL) {
|
||||
llvm::Value* nullcontext = llvm::ConstantPointerNull::get(pty);
|
||||
p->ir->CreateStore(nullcontext, context);
|
||||
@@ -2452,8 +2455,8 @@ DValue* FuncExp::toElem(IRState* p)
|
||||
|
||||
llvm::Value* fptr = DtoGEPi(lval,0,1,"tmp",p->scopebb());
|
||||
|
||||
assert(fd->llvmValue);
|
||||
llvm::Value* castfptr = new llvm::BitCastInst(fd->llvmValue,fptr->getType()->getContainedType(0),"tmp",p->scopebb());
|
||||
assert(fd->irFunc->func);
|
||||
llvm::Value* castfptr = new llvm::BitCastInst(fd->irFunc->func,fptr->getType()->getContainedType(0),"tmp",p->scopebb());
|
||||
new llvm::StoreInst(castfptr, fptr, p->scopebb());
|
||||
|
||||
if (temp)
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
|
||||
#include "gen/llvm.h"
|
||||
|
||||
#include "mtype.h"
|
||||
#include "dsymbol.h"
|
||||
#include "aggregate.h"
|
||||
#include "declaration.h"
|
||||
@@ -103,7 +102,7 @@ const llvm::Type* DtoType(Type* t)
|
||||
// recursive or cyclic declaration
|
||||
if (!gIR->structs.empty())
|
||||
{
|
||||
IRStruct* found = 0;
|
||||
IrStruct* found = 0;
|
||||
for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
|
||||
{
|
||||
if (t == (*i)->type)
|
||||
@@ -117,7 +116,7 @@ const llvm::Type* DtoType(Type* t)
|
||||
TypeStruct* ts = (TypeStruct*)t;
|
||||
assert(ts->sym);
|
||||
DtoResolveDsymbol(ts->sym);
|
||||
return ts->sym->llvmIRStruct->recty.get();//t->llvmType->get();
|
||||
return ts->sym->llvmIrStruct->recty.get();//t->llvmType->get();
|
||||
}
|
||||
|
||||
case Tclass: {
|
||||
@@ -125,7 +124,7 @@ const llvm::Type* DtoType(Type* t)
|
||||
// recursive or cyclic declaration
|
||||
if (!gIR->structs.empty())
|
||||
{
|
||||
IRStruct* found = 0;
|
||||
IrStruct* found = 0;
|
||||
for (IRState::StructVector::iterator i=gIR->structs.begin(); i!=gIR->structs.end(); ++i)
|
||||
{
|
||||
if (t == (*i)->type)
|
||||
@@ -140,7 +139,7 @@ const llvm::Type* DtoType(Type* t)
|
||||
TypeClass* tc = (TypeClass*)t;
|
||||
assert(tc->sym);
|
||||
DtoResolveDsymbol(tc->sym);
|
||||
return getPtrToType(tc->sym->llvmIRStruct->recty.get());//t->llvmType->get());
|
||||
return getPtrToType(tc->sym->llvmIrStruct->recty.get());//t->llvmType->get());
|
||||
}
|
||||
|
||||
// functions
|
||||
@@ -687,7 +686,7 @@ static const llvm::Type* get_next_frame_ptr_type(Dsymbol* sc)
|
||||
assert(p->isFuncDeclaration() || p->isClassDeclaration());
|
||||
if (FuncDeclaration* fd = p->isFuncDeclaration())
|
||||
{
|
||||
llvm::Value* v = fd->llvmNested;
|
||||
llvm::Value* v = fd->irFunc->nestedVar;
|
||||
assert(v);
|
||||
return v->getType();
|
||||
}
|
||||
@@ -717,9 +716,9 @@ static llvm::Value* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, llvm:
|
||||
|
||||
if (fd->toParent2() == func)
|
||||
{
|
||||
if (!func->llvmNested)
|
||||
if (!func->irFunc->nestedVar)
|
||||
return NULL;
|
||||
return DtoBitCast(v, func->llvmNested->getType());
|
||||
return DtoBitCast(v, func->irFunc->nestedVar->getType());
|
||||
}
|
||||
|
||||
v = DtoBitCast(v, get_next_frame_ptr_type(fd));
|
||||
@@ -733,7 +732,7 @@ static llvm::Value* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, llvm:
|
||||
else if (ClassDeclaration* cd = fd->toParent2()->isClassDeclaration())
|
||||
{
|
||||
size_t idx = 2;
|
||||
idx += cd->llvmIRStruct->interfaces.size();
|
||||
idx += cd->llvmIrStruct->interfaces.size();
|
||||
v = DtoGEPi(v,0,idx,"tmp");
|
||||
v = DtoLoad(v);
|
||||
}
|
||||
@@ -747,7 +746,7 @@ static llvm::Value* get_frame_ptr_impl(FuncDeclaration* func, Dsymbol* sc, llvm:
|
||||
{
|
||||
Logger::println("scope is class: %s", cd->toChars());
|
||||
/*size_t idx = 2;
|
||||
idx += cd->llvmIRStruct->interfaces.size();
|
||||
idx += cd->llvmIrStruct->interfaces.size();
|
||||
v = DtoGEPi(v,0,idx,"tmp");
|
||||
Logger::cout() << "gep = " << *v << '\n';
|
||||
v = DtoLoad(v);*/
|
||||
@@ -766,14 +765,14 @@ static llvm::Value* get_frame_ptr(FuncDeclaration* func)
|
||||
{
|
||||
Logger::println("Resolving context pointer for nested function: '%s'", func->toPrettyChars());
|
||||
LOG_SCOPE;
|
||||
IRFunction* irfunc = gIR->func();
|
||||
IrFunction* irfunc = gIR->func();
|
||||
|
||||
// in the right scope already
|
||||
if (func == irfunc->decl)
|
||||
return irfunc->decl->llvmNested;
|
||||
return irfunc->decl->irFunc->nestedVar;
|
||||
|
||||
// use the 'this' pointer
|
||||
llvm::Value* ptr = irfunc->decl->llvmThisVar;
|
||||
llvm::Value* ptr = irfunc->decl->irFunc->thisVar;
|
||||
assert(ptr);
|
||||
|
||||
// return the fully resolved frame pointer
|
||||
@@ -830,7 +829,7 @@ static void print_nested_frame_list(VarDeclaration* vd, Dsymbol* par)
|
||||
llvm::Value* DtoNestedVariable(VarDeclaration* vd)
|
||||
{
|
||||
// log the frame list
|
||||
IRFunction* irfunc = gIR->func();
|
||||
IrFunction* irfunc = gIR->func();
|
||||
if (Logger::enabled())
|
||||
print_nested_frame_list(vd, irfunc->decl);
|
||||
|
||||
@@ -841,10 +840,10 @@ llvm::Value* DtoNestedVariable(VarDeclaration* vd)
|
||||
assert(ptr && "nested var, but no context");
|
||||
|
||||
// we must cast here to be sure. nested classes just have a void*
|
||||
ptr = DtoBitCast(ptr, func->llvmNested->getType());
|
||||
ptr = DtoBitCast(ptr, func->irFunc->nestedVar->getType());
|
||||
|
||||
// index nested var and load (if necessary)
|
||||
llvm::Value* v = DtoGEPi(ptr, 0, vd->llvmNestedIndex, "tmp");
|
||||
llvm::Value* v = DtoGEPi(ptr, 0, vd->irLocal->nestedIndex, "tmp");
|
||||
// references must be loaded, for normal variables this IS already the variable storage!!!
|
||||
if (vd->isParameter() && (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type)))
|
||||
v = DtoLoad(v);
|
||||
@@ -922,9 +921,9 @@ void DtoAssign(DValue* lhs, DValue* rhs)
|
||||
llvm::Value* tmp = rhs->getRVal();
|
||||
FuncDeclaration* fdecl = gIR->func()->decl;
|
||||
// respecify the this param
|
||||
if (!llvm::isa<llvm::AllocaInst>(fdecl->llvmThisVar))
|
||||
fdecl->llvmThisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint());
|
||||
DtoStore(tmp, fdecl->llvmThisVar);
|
||||
if (!llvm::isa<llvm::AllocaInst>(fdecl->irFunc->thisVar))
|
||||
fdecl->irFunc->thisVar = new llvm::AllocaInst(tmp->getType(), "newthis", gIR->topallocapoint());
|
||||
DtoStore(tmp, fdecl->irFunc->thisVar);
|
||||
}
|
||||
// regular class ref -> class ref assignment
|
||||
else {
|
||||
@@ -1584,11 +1583,11 @@ void DtoConstInitGlobal(VarDeclaration* vd)
|
||||
|
||||
if (_init && _init->getType() != _type)
|
||||
_type = _init->getType();
|
||||
llvm::cast<llvm::OpaqueType>(vd->llvmIRGlobal->type.get())->refineAbstractTypeTo(_type);
|
||||
_type = vd->llvmIRGlobal->type.get();
|
||||
llvm::cast<llvm::OpaqueType>(vd->irGlobal->type.get())->refineAbstractTypeTo(_type);
|
||||
_type = vd->irGlobal->type.get();
|
||||
assert(!_type->isAbstract());
|
||||
|
||||
llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->llvmValue);
|
||||
llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->irGlobal->value);
|
||||
if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl))
|
||||
{
|
||||
gvar->setInitializer(_init);
|
||||
@@ -1743,3 +1742,29 @@ void DtoAnnotation(const char* str)
|
||||
// create a noop with the code as the result name!
|
||||
gIR->ir->CreateAnd(DtoConstSize_t(0),DtoConstSize_t(0),s.c_str());
|
||||
}
|
||||
|
||||
const llvm::StructType* DtoInterfaceInfoType()
|
||||
{
|
||||
static const llvm::StructType* t = NULL;
|
||||
if (t)
|
||||
return t;
|
||||
|
||||
// build interface info type
|
||||
std::vector<const llvm::Type*> types;
|
||||
// ClassInfo classinfo
|
||||
ClassDeclaration* cd2 = ClassDeclaration::classinfo;
|
||||
DtoResolveClass(cd2);
|
||||
types.push_back(getPtrToType(cd2->type->llvmType->get()));
|
||||
// void*[] vtbl
|
||||
std::vector<const llvm::Type*> vtbltypes;
|
||||
vtbltypes.push_back(DtoSize_t());
|
||||
const llvm::Type* byteptrptrty = getPtrToType(getPtrToType(llvm::Type::Int8Ty));
|
||||
vtbltypes.push_back(byteptrptrty);
|
||||
types.push_back(llvm::StructType::get(vtbltypes));
|
||||
// int offset
|
||||
types.push_back(llvm::Type::Int32Ty);
|
||||
// create type
|
||||
t = llvm::StructType::get(types);
|
||||
|
||||
return t;
|
||||
}
|
||||
|
||||
34
gen/tollvm.h
34
gen/tollvm.h
@@ -1,51 +1,74 @@
|
||||
#ifndef LLVMDC_GEN_TOLLVM_H
|
||||
#define LLVMDC_GEN_TOLLVM_H
|
||||
|
||||
// D -> LLVM helpers
|
||||
|
||||
struct DValue;
|
||||
#include "gen/llvm.h"
|
||||
#include "lexer.h"
|
||||
#include "mtype.h"
|
||||
#include "attrib.h"
|
||||
#include "declaration.h"
|
||||
|
||||
// D->LLVM type handling stuff
|
||||
const llvm::Type* DtoType(Type* t);
|
||||
bool DtoIsPassedByRef(Type* type);
|
||||
|
||||
// resolve typedefs to their real type.
|
||||
// TODO should probably be removed in favor of DMD's Type::toBasetype
|
||||
Type* DtoDType(Type* t);
|
||||
|
||||
// delegate helpers
|
||||
const llvm::StructType* DtoDelegateType(Type* t);
|
||||
llvm::Value* DtoNullDelegate(llvm::Value* v);
|
||||
llvm::Value* DtoDelegateCopy(llvm::Value* dst, llvm::Value* src);
|
||||
llvm::Value* DtoCompareDelegate(TOK op, llvm::Value* lhs, llvm::Value* rhs);
|
||||
|
||||
// return linkage types for general cases
|
||||
llvm::GlobalValue::LinkageTypes DtoLinkage(PROT prot, uint stc);
|
||||
|
||||
// convert DMD calling conv to LLVM
|
||||
unsigned DtoCallingConv(LINK l);
|
||||
|
||||
// TODO: this one should be removed!!!
|
||||
llvm::Value* DtoPointedType(llvm::Value* ptr, llvm::Value* val);
|
||||
|
||||
// casts any value to a boolean
|
||||
llvm::Value* DtoBoolean(llvm::Value* val);
|
||||
|
||||
// some types
|
||||
const llvm::Type* DtoSize_t();
|
||||
const llvm::StructType* DtoInterfaceInfoType();
|
||||
|
||||
// initializer helpers
|
||||
llvm::Constant* DtoConstInitializer(Type* type, Initializer* init);
|
||||
llvm::Constant* DtoConstFieldInitializer(Type* type, Initializer* init);
|
||||
DValue* DtoInitializer(Initializer* init);
|
||||
|
||||
// declaration of memset/cpy intrinsics
|
||||
llvm::Function* LLVM_DeclareMemSet32();
|
||||
llvm::Function* LLVM_DeclareMemSet64();
|
||||
llvm::Function* LLVM_DeclareMemCpy32();
|
||||
llvm::Function* LLVM_DeclareMemCpy64();
|
||||
|
||||
// getelementptr helpers
|
||||
llvm::Value* DtoGEP(llvm::Value* ptr, llvm::Value* i0, llvm::Value* i1, const std::string& var, llvm::BasicBlock* bb=NULL);
|
||||
llvm::Value* DtoGEP(llvm::Value* ptr, const std::vector<unsigned>& src, const std::string& var, llvm::BasicBlock* bb=NULL);
|
||||
llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, const std::string& var, llvm::BasicBlock* bb=NULL);
|
||||
llvm::Value* DtoGEPi(llvm::Value* ptr, unsigned i0, unsigned i1, const std::string& var, llvm::BasicBlock* bb=NULL);
|
||||
|
||||
// dynamic memory helpers
|
||||
llvm::Value* DtoRealloc(llvm::Value* ptr, const llvm::Type* ty);
|
||||
llvm::Value* DtoRealloc(llvm::Value* ptr, llvm::Value* len);
|
||||
|
||||
// assertion generator
|
||||
void DtoAssert(Loc* loc, DValue* msg);
|
||||
|
||||
// nested variable/class helpers
|
||||
llvm::Value* DtoNestedContext(FuncDeclaration* func);
|
||||
llvm::Value* DtoNestedVariable(VarDeclaration* vd);
|
||||
|
||||
// annotation generator
|
||||
void DtoAnnotation(const char* str);
|
||||
|
||||
// to constant helpers
|
||||
llvm::ConstantInt* DtoConstSize_t(size_t);
|
||||
llvm::ConstantInt* DtoConstUint(unsigned i);
|
||||
llvm::ConstantInt* DtoConstInt(int i);
|
||||
@@ -56,17 +79,18 @@ llvm::Constant* DtoConstStringPtr(const char* str, const char* section = 0);
|
||||
llvm::Constant* DtoConstBool(bool);
|
||||
llvm::Constant* DtoConstNullPtr(const llvm::Type* t);
|
||||
|
||||
// is template instance check
|
||||
bool DtoIsTemplateInstance(Dsymbol* s);
|
||||
|
||||
// generates lazy static initialization code for a global variable
|
||||
void DtoLazyStaticInit(bool istempl, llvm::Value* gvar, Initializer* init, Type* t);
|
||||
|
||||
// these are all basically drivers for the codegeneration called by the main loop
|
||||
void DtoResolveDsymbol(Dsymbol* dsym);
|
||||
void DtoDeclareDsymbol(Dsymbol* dsym);
|
||||
void DtoDefineDsymbol(Dsymbol* dsym);
|
||||
void DtoConstInitDsymbol(Dsymbol* dsym);
|
||||
|
||||
void DtoConstInitGlobal(VarDeclaration* vd);
|
||||
|
||||
void DtoEmptyResolveList();
|
||||
void DtoEmptyDeclareList();
|
||||
void DtoEmptyConstInitList();
|
||||
|
||||
@@ -41,6 +41,8 @@
|
||||
#include "gen/todebug.h"
|
||||
#include "gen/runtime.h"
|
||||
|
||||
#include "ir/irvar.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// in gen/optimize.cpp
|
||||
@@ -169,7 +171,7 @@ static llvm::Function* build_module_ctor()
|
||||
|
||||
size_t n = gIR->ctors.size();
|
||||
if (n == 1)
|
||||
return llvm::cast<llvm::Function>(gIR->ctors[0]->llvmValue);
|
||||
return gIR->ctors[0]->irFunc->func;
|
||||
|
||||
std::string name("_D");
|
||||
name.append(gIR->dmodule->mangle());
|
||||
@@ -184,7 +186,7 @@ static llvm::Function* build_module_ctor()
|
||||
LLVMBuilder builder(bb);
|
||||
|
||||
for (size_t i=0; i<n; i++) {
|
||||
llvm::Function* f = llvm::cast<llvm::Function>(gIR->ctors[i]->llvmValue);
|
||||
llvm::Function* f = gIR->ctors[i]->irFunc->func;
|
||||
llvm::CallInst* call = builder.CreateCall(f,"");
|
||||
call->setCallingConv(llvm::CallingConv::Fast);
|
||||
}
|
||||
@@ -202,7 +204,7 @@ static llvm::Function* build_module_dtor()
|
||||
|
||||
size_t n = gIR->dtors.size();
|
||||
if (n == 1)
|
||||
return llvm::cast<llvm::Function>(gIR->dtors[0]->llvmValue);
|
||||
return gIR->dtors[0]->irFunc->func;
|
||||
|
||||
std::string name("_D");
|
||||
name.append(gIR->dmodule->mangle());
|
||||
@@ -217,7 +219,7 @@ static llvm::Function* build_module_dtor()
|
||||
LLVMBuilder builder(bb);
|
||||
|
||||
for (size_t i=0; i<n; i++) {
|
||||
llvm::Function* f = llvm::cast<llvm::Function>(gIR->dtors[i]->llvmValue);
|
||||
llvm::Function* f = gIR->dtors[i]->irFunc->func;
|
||||
llvm::CallInst* call = builder.CreateCall(f,"");
|
||||
call->setCallingConv(llvm::CallingConv::Fast);
|
||||
}
|
||||
@@ -235,7 +237,7 @@ static llvm::Function* build_module_unittest()
|
||||
|
||||
size_t n = gIR->unitTests.size();
|
||||
if (n == 1)
|
||||
return llvm::cast<llvm::Function>(gIR->unitTests[0]->llvmValue);
|
||||
return gIR->unitTests[0]->irFunc->func;
|
||||
|
||||
std::string name("_D");
|
||||
name.append(gIR->dmodule->mangle());
|
||||
@@ -250,7 +252,7 @@ static llvm::Function* build_module_unittest()
|
||||
LLVMBuilder builder(bb);
|
||||
|
||||
for (size_t i=0; i<n; i++) {
|
||||
llvm::Function* f = llvm::cast<llvm::Function>(gIR->unitTests[i]->llvmValue);
|
||||
llvm::Function* f = gIR->unitTests[i]->irFunc->func;
|
||||
llvm::CallInst* call = builder.CreateCall(f,"");
|
||||
call->setCallingConv(llvm::CallingConv::Fast);
|
||||
}
|
||||
@@ -354,7 +356,7 @@ void Module::genmoduleinfo()
|
||||
ClassDeclaration* cd = (ClassDeclaration*)aclasses.data[i];
|
||||
if (cd->isInterfaceDeclaration())
|
||||
{
|
||||
Logger::println("skipping interface '%s'", cd->toPrettyChars());
|
||||
Logger::println("skipping interface '%s' in moduleinfo", cd->toPrettyChars());
|
||||
continue;
|
||||
}
|
||||
Logger::println("class: %s", cd->toPrettyChars());
|
||||
@@ -507,7 +509,7 @@ void VarDeclaration::toObjFile()
|
||||
llvmResolved = true;
|
||||
llvmDeclared = true;
|
||||
|
||||
llvmIRGlobal = new IRGlobal(this);
|
||||
irGlobal = new IrGlobal(this);
|
||||
|
||||
Logger::println("parent: %s (%s)", parent->toChars(), parent->kind());
|
||||
|
||||
@@ -529,13 +531,13 @@ void VarDeclaration::toObjFile()
|
||||
else
|
||||
_linkage = DtoLinkage(protection, storage_class);
|
||||
|
||||
const llvm::Type* _type = llvmIRGlobal->type.get();
|
||||
const llvm::Type* _type = irGlobal->type.get();
|
||||
|
||||
Logger::println("Creating global variable");
|
||||
std::string _name(mangle());
|
||||
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,NULL,_name,gIR->module);
|
||||
llvmValue = gvar;
|
||||
irGlobal->value = gvar;
|
||||
|
||||
if (static_local)
|
||||
DtoConstInitGlobal(this);
|
||||
@@ -549,9 +551,10 @@ void VarDeclaration::toObjFile()
|
||||
Logger::println("Aggregate var declaration: '%s' offset=%d", toChars(), offset);
|
||||
|
||||
const llvm::Type* _type = DtoType(type);
|
||||
irField = new IrField(this);
|
||||
|
||||
// add the field in the IRStruct
|
||||
gIR->topstruct()->offsets.insert(std::make_pair(offset, IRStruct::Offset(this, _type)));
|
||||
gIR->topstruct()->offsets.insert(std::make_pair(offset, IrStruct::Offset(this, _type)));
|
||||
}
|
||||
|
||||
Logger::println("VarDeclaration::toObjFile is done");
|
||||
|
||||
@@ -39,6 +39,8 @@
|
||||
#include "gen/structs.h"
|
||||
#include "gen/classes.h"
|
||||
|
||||
#include "ir/irvar.h"
|
||||
|
||||
/*******************************************
|
||||
* Get a canonicalized form of the TypeInfo for use with the internal
|
||||
* runtime library routines. Canonicalized in that static arrays are
|
||||
@@ -254,7 +256,7 @@ void DtoResolveTypeInfo(TypeInfoDeclaration* tid)
|
||||
Logger::println("DtoResolveTypeInfo(%s)", tid->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
tid->llvmIRGlobal = new IRGlobal(tid);
|
||||
tid->irGlobal = new IrGlobal(tid);
|
||||
|
||||
gIR->declareList.push_back(tid);
|
||||
}
|
||||
@@ -280,15 +282,17 @@ void DtoDeclareTypeInfo(TypeInfoDeclaration* tid)
|
||||
const llvm::Type* t = llvm::OpaqueType::get();
|
||||
llvm::GlobalVariable* g = new llvm::GlobalVariable(t, true, llvm::GlobalValue::ExternalLinkage, NULL, mangled, gIR->module);
|
||||
assert(g);
|
||||
tid->llvmValue = g;
|
||||
/*if (!tid->irGlobal)
|
||||
tid->irGlobal = new IrGlobal(tid);*/
|
||||
tid->irGlobal->value = g;
|
||||
mangled.append("__TYPE");
|
||||
gIR->module->addTypeName(mangled, tid->llvmValue->getType()->getContainedType(0));
|
||||
Logger::println("Got typeinfo var: %s", tid->llvmValue->getName().c_str());
|
||||
gIR->module->addTypeName(mangled, tid->irGlobal->value->getType()->getContainedType(0));
|
||||
Logger::println("Got typeinfo var: %s", tid->irGlobal->value->getName().c_str());
|
||||
tid->llvmInitialized = true;
|
||||
tid->llvmDefined = true;
|
||||
}
|
||||
else if (!tid->llvmValue) {
|
||||
tid->llvmValue = found;
|
||||
else if (!tid->irGlobal->value) {
|
||||
tid->irGlobal->value = found;
|
||||
tid->llvmInitialized = true;
|
||||
tid->llvmDefined = true;
|
||||
}
|
||||
@@ -352,7 +356,7 @@ void TypeInfoTypedefDeclaration::llvmDeclare()
|
||||
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
||||
|
||||
// create the symbol
|
||||
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoTypedefDeclaration::llvmDefine()
|
||||
@@ -385,12 +389,11 @@ void TypeInfoTypedefDeclaration::llvmDefine()
|
||||
|
||||
sd->basetype->getTypeInfo(NULL); // generate vtinfo
|
||||
assert(sd->basetype->vtinfo);
|
||||
if (!sd->basetype->vtinfo->llvmValue)
|
||||
DtoForceDeclareDsymbol(sd->basetype->vtinfo);
|
||||
DtoForceDeclareDsymbol(sd->basetype->vtinfo);
|
||||
|
||||
assert(sd->basetype->vtinfo->llvmValue);
|
||||
assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->llvmValue));
|
||||
llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->basetype->vtinfo->llvmValue);
|
||||
assert(sd->basetype->vtinfo->irGlobal->value);
|
||||
assert(llvm::isa<llvm::Constant>(sd->basetype->vtinfo->irGlobal->value));
|
||||
llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->basetype->vtinfo->irGlobal->value);
|
||||
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
|
||||
sinits.push_back(castbase);
|
||||
|
||||
@@ -418,7 +421,7 @@ void TypeInfoTypedefDeclaration::llvmDefine()
|
||||
|
||||
// create the symbol
|
||||
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(llvmValue)->setInitializer(tiInit);
|
||||
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
|
||||
@@ -439,7 +442,7 @@ void TypeInfoEnumDeclaration::llvmDeclare()
|
||||
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
||||
|
||||
// create the symbol
|
||||
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoEnumDeclaration::llvmDefine()
|
||||
@@ -471,11 +474,10 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
||||
|
||||
sd->memtype->getTypeInfo(NULL); // generate vtinfo
|
||||
assert(sd->memtype->vtinfo);
|
||||
if (!sd->memtype->vtinfo->llvmValue)
|
||||
DtoForceDeclareDsymbol(sd->memtype->vtinfo);
|
||||
DtoForceDeclareDsymbol(sd->memtype->vtinfo);
|
||||
|
||||
assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->llvmValue));
|
||||
llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->llvmValue);
|
||||
assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->irGlobal->value));
|
||||
llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->irGlobal->value);
|
||||
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
|
||||
sinits.push_back(castbase);
|
||||
|
||||
@@ -504,7 +506,7 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
||||
|
||||
// create the symbol
|
||||
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(llvmValue)->setInitializer(tiInit);
|
||||
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
|
||||
@@ -522,7 +524,7 @@ static llvm::Constant* LLVM_D_Declare_TypeInfoBase(TypeInfoDeclaration* tid, Cla
|
||||
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
||||
|
||||
// create the symbol
|
||||
tid->llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
|
||||
tid->irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,tid->toChars(),gIR->module);
|
||||
}
|
||||
|
||||
static llvm::Constant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
|
||||
@@ -543,16 +545,15 @@ static llvm::Constant* LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclar
|
||||
Logger::println("generating base typeinfo");
|
||||
basetype->getTypeInfo(NULL);
|
||||
assert(basetype->vtinfo);
|
||||
if (!basetype->vtinfo->llvmValue)
|
||||
DtoForceDeclareDsymbol(basetype->vtinfo);
|
||||
assert(llvm::isa<llvm::Constant>(basetype->vtinfo->llvmValue));
|
||||
llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->llvmValue);
|
||||
DtoForceDeclareDsymbol(basetype->vtinfo);
|
||||
assert(llvm::isa<llvm::Constant>(basetype->vtinfo->irGlobal->value));
|
||||
llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->irGlobal->value);
|
||||
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
|
||||
sinits.push_back(castbase);
|
||||
|
||||
// create the symbol
|
||||
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(tid->llvmValue)->setInitializer(tiInit);
|
||||
isaGlobalVar(tid->irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
@@ -628,7 +629,7 @@ void TypeInfoStaticArrayDeclaration::llvmDeclare()
|
||||
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
||||
|
||||
// create the symbol
|
||||
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoStaticArrayDeclaration::llvmDefine()
|
||||
@@ -659,7 +660,7 @@ void TypeInfoStaticArrayDeclaration::llvmDefine()
|
||||
// get symbol
|
||||
assert(tc->next->vtinfo);
|
||||
DtoForceDeclareDsymbol(tc->next->vtinfo);
|
||||
llvm::Constant* castbase = isaConstant(tc->next->vtinfo->llvmValue);
|
||||
llvm::Constant* castbase = isaConstant(tc->next->vtinfo->irGlobal->value);
|
||||
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
|
||||
sinits.push_back(castbase);
|
||||
|
||||
@@ -668,7 +669,7 @@ void TypeInfoStaticArrayDeclaration::llvmDefine()
|
||||
|
||||
// create the symbol
|
||||
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(llvmValue)->setInitializer(tiInit);
|
||||
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
|
||||
@@ -691,7 +692,7 @@ void TypeInfoAssociativeArrayDeclaration::llvmDeclare()
|
||||
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
||||
|
||||
// create the symbol
|
||||
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
||||
@@ -724,7 +725,7 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
||||
// get symbol
|
||||
assert(tc->next->vtinfo);
|
||||
DtoForceDeclareDsymbol(tc->next->vtinfo);
|
||||
llvm::Constant* castbase = isaConstant(tc->next->vtinfo->llvmValue);
|
||||
llvm::Constant* castbase = isaConstant(tc->next->vtinfo->irGlobal->value);
|
||||
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(2));
|
||||
sinits.push_back(castbase);
|
||||
|
||||
@@ -734,13 +735,13 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
||||
// get symbol
|
||||
assert(tc->index->vtinfo);
|
||||
DtoForceDeclareDsymbol(tc->index->vtinfo);
|
||||
castbase = isaConstant(tc->index->vtinfo->llvmValue);
|
||||
castbase = isaConstant(tc->index->vtinfo->irGlobal->value);
|
||||
castbase = llvm::ConstantExpr::getBitCast(castbase, stype->getElementType(3));
|
||||
sinits.push_back(castbase);
|
||||
|
||||
// create the symbol
|
||||
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(llvmValue)->setInitializer(tiInit);
|
||||
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
|
||||
@@ -824,7 +825,7 @@ void TypeInfoStructDeclaration::llvmDeclare()
|
||||
const llvm::StructType* stype = isaStruct(((TypeClass*)base->type)->llvmType->get());
|
||||
|
||||
// create the symbol
|
||||
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoStructDeclaration::llvmDefine()
|
||||
@@ -924,8 +925,8 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||
fd = fdx->overloadExactMatch(tftohash);
|
||||
if (fd) {
|
||||
DtoForceDeclareDsymbol(fd);
|
||||
assert(fd->llvmValue != 0);
|
||||
llvm::Constant* c = isaConstant(fd->llvmValue);
|
||||
assert(fd->irFunc->func != 0);
|
||||
llvm::Constant* c = isaConstant(fd->irFunc->func);
|
||||
assert(c);
|
||||
c = llvm::ConstantExpr::getBitCast(c, ptty);
|
||||
sinits.push_back(c);
|
||||
@@ -950,8 +951,8 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||
fd = fdx->overloadExactMatch(tfeqptr);
|
||||
if (fd) {
|
||||
DtoForceDeclareDsymbol(fd);
|
||||
assert(fd->llvmValue != 0);
|
||||
llvm::Constant* c = isaConstant(fd->llvmValue);
|
||||
assert(fd->irFunc->func != 0);
|
||||
llvm::Constant* c = isaConstant(fd->irFunc->func);
|
||||
assert(c);
|
||||
c = llvm::ConstantExpr::getBitCast(c, ptty);
|
||||
sinits.push_back(c);
|
||||
@@ -978,8 +979,8 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||
fd = fdx->overloadExactMatch(tftostring);
|
||||
if (fd) {
|
||||
DtoForceDeclareDsymbol(fd);
|
||||
assert(fd->llvmValue != 0);
|
||||
llvm::Constant* c = isaConstant(fd->llvmValue);
|
||||
assert(fd->irFunc->func != 0);
|
||||
llvm::Constant* c = isaConstant(fd->irFunc->func);
|
||||
assert(c);
|
||||
c = llvm::ConstantExpr::getBitCast(c, ptty);
|
||||
sinits.push_back(c);
|
||||
@@ -1000,7 +1001,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,tiInit,toChars(),gIR->module);
|
||||
|
||||
isaGlobalVar(llvmValue)->setInitializer(tiInit);
|
||||
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
|
||||
@@ -1024,7 +1025,7 @@ void TypeInfoClassDeclaration::llvmDeclare()
|
||||
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
||||
|
||||
// create the symbol
|
||||
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoClassDeclaration::llvmDefine()
|
||||
@@ -1056,7 +1057,7 @@ void TypeInfoClassDeclaration::llvmDefine()
|
||||
|
||||
// create the symbol
|
||||
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(llvmValue)->setInitializer(tiInit);
|
||||
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoClassDeclaration::toDt(dt_t **pdt)
|
||||
@@ -1080,7 +1081,7 @@ void TypeInfoInterfaceDeclaration::llvmDeclare()
|
||||
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
||||
|
||||
// create the symbol
|
||||
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoInterfaceDeclaration::llvmDefine()
|
||||
@@ -1112,7 +1113,7 @@ void TypeInfoInterfaceDeclaration::llvmDefine()
|
||||
|
||||
// create the symbol
|
||||
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(llvmValue)->setInitializer(tiInit);
|
||||
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
|
||||
@@ -1136,7 +1137,7 @@ void TypeInfoTupleDeclaration::llvmDeclare()
|
||||
const llvm::StructType* stype = isaStruct(base->type->llvmType->get());
|
||||
|
||||
// create the symbol
|
||||
llvmValue = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
irGlobal->value = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::WeakLinkage,NULL,toChars(),gIR->module);
|
||||
}
|
||||
|
||||
void TypeInfoTupleDeclaration::llvmDefine()
|
||||
@@ -1175,8 +1176,8 @@ void TypeInfoTupleDeclaration::llvmDefine()
|
||||
Argument *arg = (Argument *)tu->arguments->data[i];
|
||||
arg->type->getTypeInfo(NULL);
|
||||
DtoForceDeclareDsymbol(arg->type->vtinfo);
|
||||
assert(arg->type->vtinfo->llvmValue);
|
||||
llvm::Constant* c = isaConstant(arg->type->vtinfo->llvmValue);
|
||||
assert(arg->type->vtinfo->irGlobal->value);
|
||||
llvm::Constant* c = isaConstant(arg->type->vtinfo->irGlobal->value);
|
||||
c = llvm::ConstantExpr::getBitCast(c, tiTy);
|
||||
arrInits.push_back(c);
|
||||
}
|
||||
@@ -1191,7 +1192,7 @@ void TypeInfoTupleDeclaration::llvmDefine()
|
||||
|
||||
// create the symbol
|
||||
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
|
||||
isaGlobalVar(llvmValue)->setInitializer(tiInit);
|
||||
isaGlobalVar(irGlobal->value)->setInitializer(tiInit);
|
||||
}
|
||||
|
||||
void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
|
||||
|
||||
14
ir/ir.h
Normal file
14
ir/ir.h
Normal file
@@ -0,0 +1,14 @@
|
||||
// this head contains stuff used by all the IR
|
||||
|
||||
#ifndef LLVMDC_IR_IR_H
|
||||
#define LLVMDC_IR_IR_H
|
||||
|
||||
#include "ir/irforw.h"
|
||||
#include "root.h"
|
||||
|
||||
struct IrBase : Object
|
||||
{
|
||||
virtual ~IrBase() {}
|
||||
};
|
||||
|
||||
#endif
|
||||
45
ir/irforw.h
Normal file
45
ir/irforw.h
Normal file
@@ -0,0 +1,45 @@
|
||||
#ifndef LLVMDC_IR_IRFORW_H
|
||||
#define LLVMDC_IR_IRFORW_H
|
||||
|
||||
// dmd forward declarations
|
||||
struct Module;
|
||||
struct Dsymbol;
|
||||
struct Declaration;
|
||||
struct VarDeclaration;
|
||||
struct FuncDeclaration;
|
||||
struct AggregateDeclaration;
|
||||
struct StructDeclaration;
|
||||
struct ClassDeclaration;
|
||||
struct InterfaceDeclaration;
|
||||
struct Expression;
|
||||
struct BaseClass;
|
||||
struct Array;
|
||||
struct Argument;
|
||||
|
||||
struct Type;
|
||||
struct TypeStruct;
|
||||
struct TypeClass;
|
||||
struct TypeEnum;
|
||||
struct TypeArray;
|
||||
struct TypeFunction;
|
||||
|
||||
// llvm forward declarations
|
||||
namespace llvm
|
||||
{
|
||||
class Value;
|
||||
class GlobalValue;
|
||||
class GlobalVariable;
|
||||
class Function;
|
||||
class Constant;
|
||||
class ConstantStruct;
|
||||
class ConstantArray;
|
||||
class TargetData;
|
||||
class Type;
|
||||
class StructType;
|
||||
class ArrayType;
|
||||
class PointerType;
|
||||
class BasicBlock;
|
||||
class Instruction;
|
||||
}
|
||||
|
||||
#endif
|
||||
44
ir/irfunction.cpp
Normal file
44
ir/irfunction.cpp
Normal file
@@ -0,0 +1,44 @@
|
||||
#include "gen/tollvm.h"
|
||||
#include "ir/irfunction.h"
|
||||
|
||||
IrFinally::IrFinally()
|
||||
{
|
||||
bb = 0;
|
||||
retbb = 0;
|
||||
}
|
||||
|
||||
IrFinally::IrFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb)
|
||||
{
|
||||
bb = b;
|
||||
retbb = rb;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrFunction::IrFunction(FuncDeclaration* fd)
|
||||
{
|
||||
decl = fd;
|
||||
|
||||
Type* t = DtoDType(fd->type);
|
||||
assert(t->ty == Tfunction);
|
||||
type = (TypeFunction*)t;
|
||||
func = NULL;
|
||||
allocapoint = NULL;
|
||||
finallyretval = NULL;
|
||||
|
||||
queued = false;
|
||||
defined = false;
|
||||
|
||||
retArg = NULL;
|
||||
thisVar = NULL;
|
||||
nestedVar = NULL;
|
||||
_arguments = NULL;
|
||||
_argptr = NULL;
|
||||
dwarfSubProg = NULL;
|
||||
}
|
||||
|
||||
IrFunction::~IrFunction()
|
||||
{
|
||||
}
|
||||
44
ir/irfunction.h
Normal file
44
ir/irfunction.h
Normal file
@@ -0,0 +1,44 @@
|
||||
#ifndef LLVMDC_IR_IRFUNCTION_H
|
||||
#define LLVMDC_IR_IRFUNCTION_H
|
||||
|
||||
#include "ir/ir.h"
|
||||
|
||||
#include <vector>
|
||||
|
||||
// represents a finally block
|
||||
struct IrFinally
|
||||
{
|
||||
llvm::BasicBlock* bb;
|
||||
llvm::BasicBlock* retbb;
|
||||
|
||||
IrFinally();
|
||||
IrFinally(llvm::BasicBlock* b, llvm::BasicBlock* rb);
|
||||
};
|
||||
|
||||
// represents a function
|
||||
struct IrFunction : IrBase
|
||||
{
|
||||
llvm::Function* func;
|
||||
llvm::Instruction* allocapoint;
|
||||
FuncDeclaration* decl;
|
||||
TypeFunction* type;
|
||||
|
||||
// finally blocks
|
||||
typedef std::vector<IrFinally> FinallyVec;
|
||||
FinallyVec finallys;
|
||||
llvm::Value* finallyretval;
|
||||
|
||||
bool queued;
|
||||
bool defined;
|
||||
llvm::Value* retArg;
|
||||
llvm::Value* thisVar;
|
||||
llvm::Value* nestedVar;
|
||||
llvm::Value* _arguments;
|
||||
llvm::Value* _argptr;
|
||||
llvm::Constant* dwarfSubProg;
|
||||
|
||||
IrFunction(FuncDeclaration* fd);
|
||||
virtual ~IrFunction();
|
||||
};
|
||||
|
||||
#endif
|
||||
10
ir/irmodule.cpp
Normal file
10
ir/irmodule.cpp
Normal file
@@ -0,0 +1,10 @@
|
||||
#include "ir/irmodule.h"
|
||||
|
||||
IrModule::IrModule(Module* module)
|
||||
{
|
||||
M = module;
|
||||
}
|
||||
|
||||
IrModule::~IrModule()
|
||||
{
|
||||
}
|
||||
16
ir/irmodule.h
Normal file
16
ir/irmodule.h
Normal file
@@ -0,0 +1,16 @@
|
||||
#ifndef LLVMDC_IR_IRMODULE_H
|
||||
#define LLVMDC_IR_IRMODULE_H
|
||||
|
||||
#include "ir/ir.h"
|
||||
|
||||
struct Module;
|
||||
|
||||
struct IrModule : IrBase
|
||||
{
|
||||
IrModule(Module* module);
|
||||
virtual ~IrModule();
|
||||
|
||||
Module* M;
|
||||
};
|
||||
|
||||
#endif
|
||||
38
ir/irstruct.cpp
Normal file
38
ir/irstruct.cpp
Normal file
@@ -0,0 +1,38 @@
|
||||
#include "gen/llvm.h"
|
||||
#include "mtype.h"
|
||||
#include "aggregate.h"
|
||||
#include "ir/irstruct.h"
|
||||
|
||||
IrInterface::IrInterface(BaseClass* b, const llvm::StructType* vt)
|
||||
{
|
||||
base = b;
|
||||
decl = b->base;
|
||||
vtblTy = vt;
|
||||
vtblInit = NULL;
|
||||
vtbl = NULL;
|
||||
infoTy = NULL;
|
||||
infoInit = NULL;
|
||||
info = NULL;
|
||||
}
|
||||
|
||||
IrInterface::~IrInterface()
|
||||
{
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrStruct::IrStruct(Type* t)
|
||||
: recty((t->llvmType != NULL) ? *t->llvmType : llvm::OpaqueType::get())
|
||||
{
|
||||
type = t;
|
||||
defined = false;
|
||||
constinited = false;
|
||||
interfaceInfosTy = NULL;
|
||||
interfaceInfos = NULL;
|
||||
}
|
||||
|
||||
IrStruct::~IrStruct()
|
||||
{
|
||||
}
|
||||
65
ir/irstruct.h
Normal file
65
ir/irstruct.h
Normal file
@@ -0,0 +1,65 @@
|
||||
#ifndef LLVMDC_IR_IRSTRUCT_H
|
||||
#define LLVMDC_IR_IRSTRUCT_H
|
||||
|
||||
#include "ir/ir.h"
|
||||
|
||||
#include <vector>
|
||||
#include <map>
|
||||
|
||||
struct IrInterface : IrBase
|
||||
{
|
||||
BaseClass* base;
|
||||
ClassDeclaration* decl;
|
||||
|
||||
const llvm::StructType* vtblTy;
|
||||
llvm::ConstantStruct* vtblInit;
|
||||
llvm::GlobalVariable* vtbl;
|
||||
|
||||
const llvm::StructType* infoTy;
|
||||
llvm::ConstantStruct* infoInit;
|
||||
llvm::Constant* info;
|
||||
|
||||
IrInterface(BaseClass* b, const llvm::StructType* vt);
|
||||
~IrInterface();
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// represents a struct or class
|
||||
struct IrStruct : IrBase
|
||||
{
|
||||
struct Offset
|
||||
{
|
||||
VarDeclaration* var;
|
||||
const llvm::Type* type;
|
||||
llvm::Constant* init;
|
||||
|
||||
Offset(VarDeclaration* v, const llvm::Type* ty)
|
||||
: var(v), type(ty), init(NULL) {}
|
||||
};
|
||||
|
||||
typedef std::multimap<unsigned, Offset> OffsetMap;
|
||||
typedef std::vector<VarDeclaration*> VarDeclVector;
|
||||
typedef std::map<ClassDeclaration*, IrInterface*> InterfaceMap;
|
||||
typedef InterfaceMap::iterator InterfaceIter;
|
||||
|
||||
public:
|
||||
IrStruct(Type*);
|
||||
virtual ~IrStruct();
|
||||
|
||||
Type* type;
|
||||
llvm::PATypeHolder recty;
|
||||
OffsetMap offsets;
|
||||
VarDeclVector defaultFields;
|
||||
|
||||
InterfaceMap interfaces;
|
||||
const llvm::ArrayType* interfaceInfosTy;
|
||||
llvm::GlobalVariable* interfaceInfos;
|
||||
|
||||
bool defined;
|
||||
bool constinited;
|
||||
};
|
||||
|
||||
#endif
|
||||
63
ir/irvar.cpp
Normal file
63
ir/irvar.cpp
Normal file
@@ -0,0 +1,63 @@
|
||||
#include "llvm/DerivedTypes.h"
|
||||
#include "declaration.h"
|
||||
#include "ir/irvar.h"
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrVar* VarDeclaration::getIrVar()
|
||||
{
|
||||
assert(irGlobal || irLocal || irField);
|
||||
return irGlobal ? (IrVar*)irGlobal : irLocal ? (IrVar*)irLocal : (IrVar*)irField;
|
||||
}
|
||||
|
||||
llvm::Value*& VarDeclaration::getIrValue()
|
||||
{
|
||||
return getIrVar()->value;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrVar::IrVar(VarDeclaration* var)
|
||||
{
|
||||
V = var;
|
||||
value = NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrGlobal::IrGlobal(VarDeclaration* v): IrVar(v),
|
||||
type(llvm::OpaqueType::get())
|
||||
{
|
||||
constInit = NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrLocal::IrLocal(VarDeclaration* v) : IrVar(v)
|
||||
{
|
||||
nestedIndex = -1;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
IrField::IrField(VarDeclaration* v) : IrVar(v)
|
||||
{
|
||||
index = -1;
|
||||
indexOffset = 0;
|
||||
constInit = NULL;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
42
ir/irvar.h
Normal file
42
ir/irvar.h
Normal file
@@ -0,0 +1,42 @@
|
||||
#ifndef LLVMDC_IR_IRVAR_H
|
||||
#define LLVMDC_IR_IRVAR_H
|
||||
|
||||
#include "ir/ir.h"
|
||||
#include "llvm/Type.h"
|
||||
|
||||
struct IrVar : IrBase
|
||||
{
|
||||
IrVar(VarDeclaration* var);
|
||||
|
||||
VarDeclaration* V;
|
||||
llvm::Value* value;
|
||||
};
|
||||
|
||||
// represents a global variable
|
||||
struct IrGlobal : IrVar
|
||||
{
|
||||
IrGlobal(VarDeclaration* v);
|
||||
|
||||
llvm::PATypeHolder type;
|
||||
llvm::Constant* constInit;
|
||||
};
|
||||
|
||||
// represents a local variable variable
|
||||
struct IrLocal : IrVar
|
||||
{
|
||||
IrLocal(VarDeclaration* v);
|
||||
|
||||
int nestedIndex;
|
||||
};
|
||||
|
||||
// represents an aggregate field variable
|
||||
struct IrField : IrVar
|
||||
{
|
||||
IrField(VarDeclaration* v);
|
||||
|
||||
int index;
|
||||
size_t indexOffset;
|
||||
llvm::Constant* constInit;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -120,7 +120,6 @@ gen/functions.h
|
||||
gen/irstate.cpp
|
||||
gen/irstate.h
|
||||
gen/llvm.h
|
||||
gen/llvmd.h
|
||||
gen/logger.cpp
|
||||
gen/logger.h
|
||||
gen/optimizer.cpp
|
||||
@@ -139,6 +138,19 @@ gen/tollvm.h
|
||||
gen/toobj.cpp
|
||||
gen/typeinf.h
|
||||
gen/typinf.cpp
|
||||
ir
|
||||
ir/forw.h
|
||||
ir/ir.h
|
||||
ir/irfunction.cpp
|
||||
ir/irfunction.h
|
||||
ir/irglobal.cpp
|
||||
ir/irglobal.h
|
||||
ir/irmodule.cpp
|
||||
ir/irmodule.h
|
||||
ir/irstruct.cpp
|
||||
ir/irstruct.h
|
||||
ir/irvar.cpp
|
||||
ir/irvar.h
|
||||
lphobos
|
||||
lphobos/build.sh
|
||||
lphobos/crc32.d
|
||||
@@ -263,7 +275,6 @@ tango/lib/compiler/llvmdc/aaA.d
|
||||
tango/lib/compiler/llvmdc/adi.d
|
||||
tango/lib/compiler/llvmdc/arrays.d
|
||||
tango/lib/compiler/llvmdc/cast.d
|
||||
tango/lib/compiler/llvmdc/contract.d
|
||||
tango/lib/compiler/llvmdc/critical.c
|
||||
tango/lib/compiler/llvmdc/dmain2.d
|
||||
tango/lib/compiler/llvmdc/eh.d
|
||||
@@ -749,6 +760,8 @@ tangotests/o.d
|
||||
tangotests/p.d
|
||||
tangotests/q.d
|
||||
tangotests/r.d
|
||||
tangotests/s.d
|
||||
tangotests/t.d
|
||||
test
|
||||
test/a.d
|
||||
test/aa1.d
|
||||
|
||||
@@ -21,7 +21,7 @@ package.bindir = "bin"
|
||||
package.name = "llvmdc"
|
||||
package.kind = "exe"
|
||||
package.language = "c++"
|
||||
package.files = { matchfiles("dmd/*.c"), matchfiles("gen/*.cpp") }
|
||||
package.files = { matchfiles("dmd/*.c"), matchfiles("gen/*.cpp"), matchfiles("ir/*.cpp") }
|
||||
package.excludes = { "dmd/idgen.c", "dmd/impcnvgen.c" }
|
||||
package.buildoptions = { "-x c++", "`llvm-config --cxxflags`" }
|
||||
package.linkoptions = {
|
||||
|
||||
@@ -27,6 +27,9 @@
|
||||
|
||||
extern (C):
|
||||
|
||||
debug = PRINTF;
|
||||
debug(PRINTF) int printf(char*, ...);
|
||||
|
||||
/******************************************
|
||||
* Given a pointer:
|
||||
* If it is an Object, return that Object.
|
||||
@@ -54,6 +57,7 @@ Object _d_toObject(void* p)
|
||||
o = cast(Object)(p - pi.offset);
|
||||
}
|
||||
}
|
||||
debug(PRINTF) printf("toObject = %p\n", o);
|
||||
return o;
|
||||
}
|
||||
|
||||
@@ -75,6 +79,7 @@ Object _d_interface_cast(void* p, ClassInfo c)
|
||||
o = cast(Object)(p - pi.offset);
|
||||
return _d_dynamic_cast(o, c);
|
||||
}
|
||||
debug(PRINTF) printf("_d_interface_cast = %p\n", o);
|
||||
return o;
|
||||
}
|
||||
|
||||
@@ -82,7 +87,7 @@ Object _d_dynamic_cast(Object o, ClassInfo c)
|
||||
{ ClassInfo oc;
|
||||
size_t offset = 0;
|
||||
|
||||
//printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name);
|
||||
debug(PRINTF) printf("_d_dynamic_cast(o = %p, c = '%.*s')\n", o, c.name.length, c.name.ptr);
|
||||
|
||||
if (o)
|
||||
{
|
||||
@@ -96,16 +101,20 @@ Object _d_dynamic_cast(Object o, ClassInfo c)
|
||||
o = null;
|
||||
}
|
||||
//printf("\tresult = %p\n", o);
|
||||
debug(PRINTF) printf("_d_dynamic_cast = %p\n", o);
|
||||
return o;
|
||||
}
|
||||
|
||||
int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset)
|
||||
{ int i;
|
||||
|
||||
debug(PRINTF) printf("_d_isbaseof2(%.*s, %.*s, %ul)\n", oc.name.length, oc.name.ptr, c.name.length, c.name.ptr, offset);
|
||||
|
||||
if (oc is c)
|
||||
return 1;
|
||||
do
|
||||
{
|
||||
debug(PRINTF) printf("oc.interfaces.length = %ul\n", oc.interfaces.length);
|
||||
if (oc.base is c)
|
||||
return 1;
|
||||
for (i = 0; i < oc.interfaces.length; i++)
|
||||
@@ -113,6 +122,7 @@ int _d_isbaseof2(ClassInfo oc, ClassInfo c, ref size_t offset)
|
||||
ClassInfo ic;
|
||||
|
||||
ic = oc.interfaces[i].classinfo;
|
||||
debug(PRINTF) printf("checking %.*s\n", ic.name.length, ic.name.ptr);
|
||||
if (ic is c)
|
||||
{ offset = cast(size_t)oc.interfaces[i].offset;
|
||||
return 1;
|
||||
|
||||
@@ -25,6 +25,7 @@ public import tango.io.model.IBuffer,
|
||||
extern (C)
|
||||
{
|
||||
protected void * memcpy (void *dst, void *src, uint);
|
||||
private int printf(char*, ...);
|
||||
}
|
||||
|
||||
/*******************************************************************************
|
||||
@@ -163,10 +164,14 @@ class Buffer : IBuffer
|
||||
|
||||
this (IConduit conduit)
|
||||
{
|
||||
printf("Buffer.this(%p)\n", conduit);
|
||||
assert (conduit !is null);
|
||||
assert (conduit);
|
||||
|
||||
this (conduit.bufferSize);
|
||||
setConduit (conduit);
|
||||
|
||||
assert(this !is null);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
@@ -221,7 +226,8 @@ class Buffer : IBuffer
|
||||
|
||||
this (uint capacity = 0)
|
||||
{
|
||||
setContent (new ubyte[capacity], 0);
|
||||
setContent (new ubyte[capacity], 0);
|
||||
assert(this !is null);
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
|
||||
@@ -23,6 +23,7 @@ private import tango.io.Buffer,
|
||||
version (Posix)
|
||||
private import tango.stdc.posix.unistd; // needed for isatty()
|
||||
|
||||
private extern(C) int printf(char*, ...);
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
@@ -69,6 +70,8 @@ struct Console
|
||||
|
||||
private this (Conduit conduit, bool redirected)
|
||||
{
|
||||
printf("Console.Input.this(%p, %d)\n", conduit, redirected);
|
||||
assert (conduit);
|
||||
redirect = redirected;
|
||||
buffer = new Buffer (conduit);
|
||||
}
|
||||
@@ -596,6 +599,7 @@ struct Console
|
||||
|
||||
private this (Handle handle)
|
||||
{
|
||||
printf("Console.Conduit.this(%d)\n", handle);
|
||||
reopen (handle);
|
||||
redirected = (isatty(handle) is 0);
|
||||
}
|
||||
@@ -621,14 +625,13 @@ static Console.Output Cout, /// the standard output stream
|
||||
|
||||
******************************************************************************/
|
||||
|
||||
extern(C) int printf(char*, ...);
|
||||
|
||||
static this ()
|
||||
{
|
||||
printf("STATIC INIT FOR CONSOLE\n");
|
||||
printf("Cin\n");
|
||||
printf("Cin conduit\n");
|
||||
auto conduit = new Console.Conduit (0);
|
||||
assert(conduit);
|
||||
printf("Cin input\n");
|
||||
Cin = new Console.Input (conduit, conduit.redirected);
|
||||
|
||||
printf("Cout\n");
|
||||
|
||||
@@ -18,6 +18,8 @@ public import tango.io.Conduit;
|
||||
|
||||
private import tango.core.Exception;
|
||||
|
||||
private extern(C) int printf(char*, ...);
|
||||
|
||||
/*******************************************************************************
|
||||
|
||||
Implements a means of reading and writing a file device. Conduits
|
||||
|
||||
Reference in New Issue
Block a user