mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-10-22 02:37:26 +02:00
Added Doxygen file.
Completely seperated type and symbol generation. Should fix a lot of bugs, but is not yet 100% complete.
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
#ifndef LLVMC_GEN_ARRAYS_H
|
||||
#define LLVMC_GEN_ARRAYS_H
|
||||
|
||||
struct ArrayInitializer;
|
||||
|
||||
struct DSliceValue;
|
||||
|
||||
const llvm::StructType* DtoArrayType(Type* arrayTy);
|
||||
|
||||
+68
-950
File diff suppressed because it is too large
Load Diff
+7
-14
@@ -3,28 +3,21 @@
|
||||
|
||||
#include "gen/structs.h"
|
||||
|
||||
/**
|
||||
* Resolves the llvm type for a class declaration
|
||||
*/
|
||||
/// Resolves the llvm type for a class declaration
|
||||
void DtoResolveClass(ClassDeclaration* cd);
|
||||
|
||||
/**
|
||||
* Provides the llvm declaration for a class declaration
|
||||
*/
|
||||
/// Provides the llvm declaration for a class declaration
|
||||
void DtoDeclareClass(ClassDeclaration* cd);
|
||||
|
||||
/**
|
||||
* Constructs the constant initializer for a class declaration
|
||||
*/
|
||||
/// Constructs the constant initializer for a class declaration
|
||||
void DtoConstInitClass(ClassDeclaration* cd);
|
||||
|
||||
/**
|
||||
* Provides the llvm definition for a class declaration
|
||||
*/
|
||||
/// Provides the llvm definition for a class declaration
|
||||
void DtoDefineClass(ClassDeclaration* cd);
|
||||
|
||||
void DtoDeclareClassInfo(ClassDeclaration* cd);
|
||||
void DtoDefineClassInfo(ClassDeclaration* cd);
|
||||
/// Builds the initializer of cd's ClassInfo.
|
||||
/// FIXME: this should be put into IrStruct and eventually IrClass.
|
||||
LLConstant* DtoDefineClassInfo(ClassDeclaration* cd);
|
||||
|
||||
DValue* DtoNewClass(Loc loc, TypeClass* type, NewExp* newexp);
|
||||
void DtoInitClass(TypeClass* tc, LLValue* dst);
|
||||
|
||||
+14
-47
@@ -14,6 +14,8 @@
|
||||
|
||||
#include "ir/ir.h"
|
||||
#include "ir/irvar.h"
|
||||
#include "ir/irtype.h"
|
||||
#include "ir/irtypestruct.h"
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
@@ -72,11 +74,14 @@ void TupleDeclaration::codegen(Ir* p)
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
// FIXME: this is horrible!!!
|
||||
|
||||
void VarDeclaration::codegen(Ir* p)
|
||||
{
|
||||
Logger::print("VarDeclaration::toObjFile(): %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
// just forward aliases
|
||||
if (aliassym)
|
||||
{
|
||||
Logger::println("alias sym");
|
||||
@@ -84,10 +89,11 @@ void VarDeclaration::codegen(Ir* p)
|
||||
return;
|
||||
}
|
||||
|
||||
// output the parent aggregate first
|
||||
if (AggregateDeclaration* ad = isMember())
|
||||
ad->codegen(p);
|
||||
|
||||
// global variable or magic
|
||||
// global variable
|
||||
#if DMDV2
|
||||
// taken from dmd2/structs
|
||||
if (isDataseg() || (storage_class & (STCconst | STCinvariant) && init))
|
||||
@@ -138,25 +144,8 @@ void VarDeclaration::codegen(Ir* p)
|
||||
if (nakedUse)
|
||||
gIR->usedArray.push_back(DtoBitCast(gvar, getVoidPtrType()));
|
||||
|
||||
// don't initialize static struct members yet, they might be of the struct type
|
||||
// which doesn't have a static initializer yet.
|
||||
if (AggregateDeclaration* ad = isMember())
|
||||
ad->ir.irStruct->staticVars.push_back(this);
|
||||
else
|
||||
DtoConstInitGlobal(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
// might already have its irField, as classes derive each other without getting copies of the VarDeclaration
|
||||
if (!ir.irField)
|
||||
{
|
||||
assert(!ir.isSet());
|
||||
ir.irField = new IrField(this);
|
||||
}
|
||||
IrStruct* irstruct = gIR->topstruct();
|
||||
irstruct->addVar(this);
|
||||
|
||||
Logger::println("added offset %u", offset);
|
||||
// initialize
|
||||
DtoConstInitGlobal(this);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -164,8 +153,7 @@ void VarDeclaration::codegen(Ir* p)
|
||||
|
||||
void TypedefDeclaration::codegen(Ir*)
|
||||
{
|
||||
static int tdi = 0;
|
||||
Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars());
|
||||
Logger::print("TypedefDeclaration::toObjFile: %s\n", toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
// generate typeinfo
|
||||
@@ -181,33 +169,12 @@ void EnumDeclaration::codegen(Ir*)
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void FuncDeclaration::codegen(Ir*)
|
||||
void FuncDeclaration::codegen(Ir* p)
|
||||
{
|
||||
DtoResolveDsymbol(this);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
|
||||
void AnonDeclaration::codegen(Ir* p)
|
||||
{
|
||||
Array *d = include(NULL, NULL);
|
||||
|
||||
if (d)
|
||||
// don't touch function aliases, they don't contribute any new symbols
|
||||
if (!isFuncAliasDeclaration())
|
||||
{
|
||||
// get real aggregate parent
|
||||
IrStruct* irstruct = gIR->topstruct();
|
||||
|
||||
// push a block on the stack
|
||||
irstruct->pushAnon(isunion);
|
||||
|
||||
// go over children
|
||||
for (unsigned i = 0; i < d->dim; i++)
|
||||
{ Dsymbol *s = (Dsymbol *)d->data[i];
|
||||
s->codegen(p);
|
||||
}
|
||||
|
||||
// finish
|
||||
irstruct->popAnon();
|
||||
DtoResolveDsymbol(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+5
-11
@@ -201,7 +201,9 @@ const llvm::FunctionType* DtoFunctionType(Type* type, Type* thistype, Type* nest
|
||||
llvm::FunctionType* functype = llvm::FunctionType::get(f->fty.ret->ltype, argtypes, f->fty.c_vararg);
|
||||
f->ir.type = new llvm::PATypeHolder(functype);
|
||||
|
||||
#if 0
|
||||
Logger::cout() << "Final function type: " << *functype << "\n";
|
||||
#endif
|
||||
|
||||
return functype;
|
||||
}
|
||||
@@ -304,16 +306,6 @@ void DtoResolveFunction(FuncDeclaration* fdecl)
|
||||
return; // ignore declaration completely
|
||||
}
|
||||
|
||||
if (AggregateDeclaration* ad = fdecl->isMember())
|
||||
{
|
||||
ad->codegen(Type::sir);
|
||||
if (ad->isStructDeclaration() && llvm::isa<llvm::OpaqueType>(DtoType(ad->type)))
|
||||
{
|
||||
ad->ir.irStruct->structFuncs.push_back(fdecl);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
//printf("resolve function: %s\n", fdecl->toPrettyChars());
|
||||
|
||||
if (fdecl->parent)
|
||||
@@ -372,7 +364,6 @@ void DtoResolveFunction(FuncDeclaration* fdecl)
|
||||
// queue declaration unless the function is abstract without body
|
||||
if (!fdecl->isAbstract() || fdecl->fbody)
|
||||
{
|
||||
Logger::println("Ignoring declaration of abstract bodyless function %s", fdecl->toPrettyChars());
|
||||
DtoDeclareFunction(fdecl);
|
||||
}
|
||||
}
|
||||
@@ -465,6 +456,9 @@ void DtoDeclareFunction(FuncDeclaration* fdecl)
|
||||
Type* t = fdecl->type->toBasetype();
|
||||
TypeFunction* f = (TypeFunction*)t;
|
||||
|
||||
// sanity check
|
||||
assert(fdecl == f->funcdecl && "the function type does not point to this function");
|
||||
|
||||
bool declareOnly = !mustDefineSymbol(fdecl);
|
||||
|
||||
if (fdecl->llvmInternal == LLVMva_start)
|
||||
|
||||
+2
-1
@@ -1069,7 +1069,8 @@ LLConstant* DtoConstInitializer(Loc loc, Type* type, Initializer* init)
|
||||
else if (StructInitializer* si = init->isStructInitializer())
|
||||
{
|
||||
Logger::println("const struct initializer");
|
||||
_init = DtoConstStructInitializer(si);
|
||||
si->ad->codegen(Type::sir);
|
||||
return si->ad->ir.irStruct->createStructInitializer(si);
|
||||
}
|
||||
else if (ArrayInitializer* ai = init->isArrayInitializer())
|
||||
{
|
||||
|
||||
@@ -33,5 +33,7 @@ namespace Logger
|
||||
|
||||
#define LOG_SCOPE Logger::LoggerScope _logscope;
|
||||
|
||||
#define IF_LOG if (Logger::enabled())
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
+20
-599
@@ -15,438 +15,10 @@
|
||||
#include "gen/structs.h"
|
||||
#include "gen/dvalue.h"
|
||||
#include "gen/functions.h"
|
||||
#include "gen/utils.h"
|
||||
|
||||
#include "ir/irstruct.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// pair of var and its init
|
||||
typedef std::pair<VarDeclaration*,Initializer*> VarInitPair;
|
||||
|
||||
// comparison func for qsort
|
||||
static int varinit_offset_cmp_func(const void* p1, const void* p2)
|
||||
{
|
||||
VarDeclaration* v1 = ((VarInitPair*)p1)->first;
|
||||
VarDeclaration* v2 = ((VarInitPair*)p2)->first;
|
||||
if (v1->offset < v2->offset)
|
||||
return -1;
|
||||
else if (v1->offset > v2->offset)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
this uses a simple algorithm to build the correct constant
|
||||
|
||||
(1) first sort the explicit initializers by offset... well, DMD doesn't :)
|
||||
|
||||
(2) if there is NO space before the next explicit initializeer, goto (9)
|
||||
(3) find the next default initializer that fits before it, if NOT found goto (7)
|
||||
(4) insert zero padding up to the next default initializer
|
||||
(5) insert the next default initializer
|
||||
(6) goto (2)
|
||||
|
||||
(7) insert zero padding up to the next explicit initializer
|
||||
|
||||
(9) insert the next explicit initializer
|
||||
(10) goto (2)
|
||||
|
||||
(11) done
|
||||
|
||||
(next can be the end too)
|
||||
|
||||
*/
|
||||
|
||||
// return the next default initializer to use or null
|
||||
static VarDeclaration* nextDefault(IrStruct* irstruct, size_t& idx, size_t pos, size_t offset)
|
||||
{
|
||||
IrStruct::VarDeclVector& defaults = irstruct->defVars;
|
||||
size_t ndefaults = defaults.size();
|
||||
|
||||
// for each valid index
|
||||
while(idx < ndefaults)
|
||||
{
|
||||
VarDeclaration* v = defaults[idx];
|
||||
|
||||
// skip defaults before pos
|
||||
if (v->offset < pos)
|
||||
{
|
||||
idx++;
|
||||
continue;
|
||||
}
|
||||
|
||||
// this var default fits
|
||||
if (v->offset >= pos && v->offset + v->type->size() <= offset)
|
||||
return v;
|
||||
|
||||
// not usable
|
||||
break;
|
||||
}
|
||||
|
||||
// not usable
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LLConstant* DtoConstStructInitializer(StructInitializer* si)
|
||||
{
|
||||
Logger::println("DtoConstStructInitializer: %s", si->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
// get TypeStruct
|
||||
assert(si->ad);
|
||||
TypeStruct* ts = (TypeStruct*)si->ad->type;
|
||||
|
||||
// force constant initialization of the symbol
|
||||
si->ad->codegen(Type::sir);
|
||||
|
||||
// sanity check
|
||||
assert(si->value.dim > 0);
|
||||
assert(si->value.dim == si->vars.dim);
|
||||
|
||||
// vector of final initializer constants
|
||||
std::vector<LLConstant*> inits;
|
||||
|
||||
// get the ir struct
|
||||
IrStruct* irstruct = si->ad->ir.irStruct;
|
||||
|
||||
// get default fields
|
||||
IrStruct::VarDeclVector& defaults = irstruct->defVars;
|
||||
size_t ndefaults = defaults.size();
|
||||
|
||||
// make sure si->vars is sorted by offset
|
||||
std::vector<VarInitPair> vars;
|
||||
size_t nvars = si->vars.dim;
|
||||
vars.resize(nvars);
|
||||
|
||||
// fill pair vector
|
||||
for (size_t i = 0; i < nvars; i++)
|
||||
{
|
||||
VarDeclaration* var = (VarDeclaration*)si->vars.data[i];
|
||||
Initializer* ini = (Initializer*)si->value.data[i];
|
||||
assert(var);
|
||||
assert(ini);
|
||||
vars[i] = std::make_pair(var, ini);
|
||||
}
|
||||
// sort it
|
||||
qsort(&vars[0], nvars, sizeof(VarInitPair), &varinit_offset_cmp_func);
|
||||
|
||||
// check integrity
|
||||
// and do error checking, since the frontend does not verify static struct initializers
|
||||
size_t lastoffset = 0;
|
||||
size_t lastsize = 0;
|
||||
bool overlap = false;
|
||||
for (size_t i=0; i < nvars; i++)
|
||||
{
|
||||
// next explicit init var
|
||||
VarDeclaration* var = vars[i].first;
|
||||
Logger::println("var = %s : +%u", var->toChars(), var->offset);
|
||||
|
||||
// I would have thought this to be a frontend check
|
||||
for (size_t j=i+1; j<nvars; j++)
|
||||
{
|
||||
if (j == i)
|
||||
continue;
|
||||
VarDeclaration* var2 = vars[j].first;
|
||||
if (var2->offset >= var->offset && var2->offset < var->offset + var->type->size())
|
||||
{
|
||||
fprintf(stdmsg, "Error: %s: initializer '%s' overlaps with '%s'\n", si->loc.toChars(), var->toChars(), var2->toChars());
|
||||
overlap = true;
|
||||
}
|
||||
}
|
||||
|
||||
// update offsets
|
||||
lastoffset = var->offset;
|
||||
lastsize = var->type->size();
|
||||
}
|
||||
|
||||
// error handling, report all overlaps before aborting
|
||||
if (overlap)
|
||||
{
|
||||
error("%s: overlapping union initializers", si->loc.toChars());
|
||||
}
|
||||
|
||||
// go through each explicit initalizer, falling back to defaults or zeros when necessary
|
||||
lastoffset = 0;
|
||||
lastsize = 0;
|
||||
|
||||
size_t j=0; // defaults
|
||||
|
||||
for (size_t i=0; i < nvars; i++)
|
||||
{
|
||||
// get var and init
|
||||
VarDeclaration* var = vars[i].first;
|
||||
Initializer* ini = vars[i].second;
|
||||
|
||||
size_t offset = var->offset;
|
||||
size_t size = var->type->size();
|
||||
|
||||
// if there is space before the next explicit initializer
|
||||
Lpadding:
|
||||
size_t pos = lastoffset+lastsize;
|
||||
if (offset > pos)
|
||||
{
|
||||
// find the the next default initializer that fits in this space
|
||||
VarDeclaration* nextdef = nextDefault(irstruct, j, lastoffset+lastsize, offset);
|
||||
|
||||
// found
|
||||
if (nextdef)
|
||||
{
|
||||
// need zeros before the default
|
||||
if (nextdef->offset > pos)
|
||||
{
|
||||
Logger::println("inserting %lu byte padding at %lu", nextdef->offset - pos, pos);
|
||||
addZeros(inits, pos, nextdef->offset);
|
||||
}
|
||||
|
||||
// do the default
|
||||
Logger::println("adding default field: %s : +%u", nextdef->toChars(), nextdef->offset);
|
||||
if (!nextdef->ir.irField->constInit)
|
||||
nextdef->ir.irField->constInit = DtoConstInitializer(nextdef->loc, nextdef->type, nextdef->init);
|
||||
LLConstant* c = nextdef->ir.irField->constInit;
|
||||
inits.push_back(c);
|
||||
|
||||
// update offsets
|
||||
lastoffset = nextdef->offset;
|
||||
lastsize = nextdef->type->size();
|
||||
|
||||
// check if more defaults would fit
|
||||
goto Lpadding;
|
||||
}
|
||||
// not found, pad with zeros
|
||||
else
|
||||
{
|
||||
Logger::println("inserting %lu byte padding at %lu", offset - pos, pos);
|
||||
addZeros(inits, pos, offset);
|
||||
// offsets are updated by the explicit initializer
|
||||
}
|
||||
}
|
||||
|
||||
// insert next explicit
|
||||
Logger::println("adding explicit field: %s : +%lu", var->toChars(), offset);
|
||||
LOG_SCOPE;
|
||||
LLConstant* c = DtoConstInitializer(var->loc, var->type, ini);
|
||||
inits.push_back(c);
|
||||
|
||||
lastoffset = offset;
|
||||
lastsize = size;
|
||||
}
|
||||
|
||||
// there might still be padding after the last one, make sure that is defaulted/zeroed as well
|
||||
size_t structsize = si->ad->structsize;
|
||||
|
||||
// if there is space before the next explicit initializer
|
||||
// FIXME: this should be handled in the loop above as well
|
||||
Lpadding2:
|
||||
size_t pos = lastoffset+lastsize;
|
||||
if (structsize > pos)
|
||||
{
|
||||
// find the the next default initializer that fits in this space
|
||||
VarDeclaration* nextdef = nextDefault(irstruct, j, lastoffset+lastsize, structsize);
|
||||
|
||||
// found
|
||||
if (nextdef)
|
||||
{
|
||||
// need zeros before the default
|
||||
if (nextdef->offset > pos)
|
||||
{
|
||||
Logger::println("inserting %lu byte padding at %lu", nextdef->offset - pos, pos);
|
||||
addZeros(inits, pos, nextdef->offset);
|
||||
}
|
||||
|
||||
// do the default
|
||||
Logger::println("adding default field: %s : +%u", nextdef->toChars(), nextdef->offset);
|
||||
if (!nextdef->ir.irField->constInit)
|
||||
nextdef->ir.irField->constInit = DtoConstInitializer(nextdef->loc, nextdef->type, nextdef->init);
|
||||
LLConstant* c = nextdef->ir.irField->constInit;
|
||||
inits.push_back(c);
|
||||
|
||||
// update offsets
|
||||
lastoffset = nextdef->offset;
|
||||
lastsize = nextdef->type->size();
|
||||
|
||||
// check if more defaults would fit
|
||||
goto Lpadding2;
|
||||
}
|
||||
// not found, pad with zeros
|
||||
else
|
||||
{
|
||||
Logger::println("inserting %lu byte padding at %lu", structsize - pos, pos);
|
||||
addZeros(inits, pos, structsize);
|
||||
lastoffset = pos;
|
||||
lastsize = structsize - pos;
|
||||
}
|
||||
}
|
||||
|
||||
assert(lastoffset+lastsize == structsize);
|
||||
|
||||
// make the constant struct
|
||||
LLConstant* c = LLConstantStruct::get(inits, si->ad->ir.irStruct->packed);
|
||||
if (Logger::enabled())
|
||||
{
|
||||
Logger::cout() << "constant struct initializer: " << *c << '\n';
|
||||
}
|
||||
assert(getTypePaddedSize(c->getType()) == structsize);
|
||||
return c;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<llvm::Value*> DtoStructLiteralValues(const StructDeclaration* sd, const std::vector<llvm::Value*>& inits)
|
||||
{
|
||||
// get arrays
|
||||
size_t nvars = sd->fields.dim;
|
||||
VarDeclaration** vars = (VarDeclaration**)sd->fields.data;
|
||||
|
||||
assert(inits.size() == nvars);
|
||||
|
||||
// first locate all explicit initializers
|
||||
std::vector<VarDeclaration*> explicitInits;
|
||||
for (size_t i=0; i < nvars; i++)
|
||||
{
|
||||
if (inits[i])
|
||||
{
|
||||
explicitInits.push_back(vars[i]);
|
||||
}
|
||||
}
|
||||
|
||||
// vector of values to build aggregate from
|
||||
std::vector<llvm::Value*> values;
|
||||
|
||||
// offset trackers
|
||||
size_t lastoffset = 0;
|
||||
size_t lastsize = 0;
|
||||
|
||||
// index of next explicit init
|
||||
size_t exidx = 0;
|
||||
// number of explicit inits
|
||||
size_t nex = explicitInits.size();
|
||||
|
||||
// for through each field and build up the struct, padding with zeros
|
||||
size_t i;
|
||||
for (i=0; i<nvars; i++)
|
||||
{
|
||||
VarDeclaration* var = vars[i];
|
||||
|
||||
// get var info
|
||||
size_t os = var->offset;
|
||||
size_t sz = var->type->size();
|
||||
|
||||
// get next explicit
|
||||
VarDeclaration* nextVar = NULL;
|
||||
size_t nextOs = 0;
|
||||
if (exidx < nex)
|
||||
{
|
||||
nextVar = explicitInits[exidx];
|
||||
nextOs = nextVar->offset;
|
||||
}
|
||||
// none, rest is defaults
|
||||
else
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
// not explicit initializer, default initialize if there is room, otherwise skip
|
||||
if (!inits[i])
|
||||
{
|
||||
// default init if there is room
|
||||
// (past current offset) and (small enough to fit before next explicit)
|
||||
if ((os >= lastoffset + lastsize) && (os+sz <= nextOs))
|
||||
{
|
||||
// add any 0 padding needed before this field
|
||||
if (os > lastoffset + lastsize)
|
||||
{
|
||||
//printf("1added %lu zeros\n", os - lastoffset - lastsize);
|
||||
addZeros(values, lastoffset + lastsize, os);
|
||||
}
|
||||
|
||||
// get field default init
|
||||
IrField* f = var->ir.irField;
|
||||
assert(f);
|
||||
if (!f->constInit)
|
||||
f->constInit = DtoConstInitializer(var->loc, var->type, var->init);
|
||||
|
||||
values.push_back(f->constInit);
|
||||
|
||||
lastoffset = os;
|
||||
lastsize = sz;
|
||||
//printf("added default: %s : %lu (%lu)\n", var->toChars(), os, sz);
|
||||
}
|
||||
// skip
|
||||
continue;
|
||||
}
|
||||
|
||||
assert(nextVar == var);
|
||||
|
||||
// add any 0 padding needed before this field
|
||||
if (os > lastoffset + lastsize)
|
||||
{
|
||||
//printf("added %lu zeros\n", os - lastoffset - lastsize);
|
||||
addZeros(values, lastoffset + lastsize, os);
|
||||
}
|
||||
|
||||
// add the expression value
|
||||
values.push_back(inits[i]);
|
||||
|
||||
// update offsets
|
||||
lastoffset = os;
|
||||
lastsize = sz;
|
||||
|
||||
// go to next explicit init
|
||||
exidx++;
|
||||
|
||||
//printf("added field: %s : %lu (%lu)\n", var->toChars(), os, sz);
|
||||
}
|
||||
|
||||
// fill out rest with default initializers
|
||||
const LLType* structtype = DtoType(sd->type);
|
||||
size_t structsize = getTypePaddedSize(structtype);
|
||||
|
||||
// FIXME: this could probably share some code with the above
|
||||
if (structsize > lastoffset+lastsize)
|
||||
{
|
||||
for (/*continue from first loop*/; i < nvars; i++)
|
||||
{
|
||||
VarDeclaration* var = vars[i];
|
||||
|
||||
// get var info
|
||||
size_t os = var->offset;
|
||||
size_t sz = var->type->size();
|
||||
|
||||
// skip?
|
||||
if (os < lastoffset + lastsize)
|
||||
continue;
|
||||
|
||||
// add any 0 padding needed before this field
|
||||
if (os > lastoffset + lastsize)
|
||||
{
|
||||
//printf("2added %lu zeros\n", os - lastoffset - lastsize);
|
||||
addZeros(values, lastoffset + lastsize, os);
|
||||
}
|
||||
|
||||
// get field default init
|
||||
IrField* f = var->ir.irField;
|
||||
assert(f);
|
||||
if (!f->constInit)
|
||||
f->constInit = DtoConstInitializer(var->loc, var->type, var->init);
|
||||
|
||||
values.push_back(f->constInit);
|
||||
|
||||
lastoffset = os;
|
||||
lastsize = sz;
|
||||
//printf("2added default: %s : %lu (%lu)\n", var->toChars(), os, sz);
|
||||
}
|
||||
}
|
||||
|
||||
// add any 0 padding needed at the end of the literal
|
||||
if (structsize > lastoffset+lastsize)
|
||||
{
|
||||
//printf("3added %lu zeros\n", structsize - lastoffset - lastsize);
|
||||
addZeros(values, lastoffset + lastsize, structsize);
|
||||
}
|
||||
|
||||
return values;
|
||||
}
|
||||
#include "ir/irtypestruct.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
@@ -490,10 +62,6 @@ LLValue* DtoIndexStruct(LLValue* src, StructDeclaration* sd, VarDeclaration* vd)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void DtoDeclareStruct(StructDeclaration* sd);
|
||||
static void DtoConstInitStruct(StructDeclaration* sd);
|
||||
static void DtoDefineStruct(StructDeclaration* sd);
|
||||
|
||||
void DtoResolveStruct(StructDeclaration* sd)
|
||||
{
|
||||
// don't do anything if already been here
|
||||
@@ -505,185 +73,38 @@ void DtoResolveStruct(StructDeclaration* sd)
|
||||
Logger::println("Resolving struct type: %s (%s)", sd->toChars(), sd->locToChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
// get the DMD TypeStruct
|
||||
TypeStruct* ts = (TypeStruct*)sd->type;
|
||||
// make sure type exists
|
||||
DtoType(sd->type);
|
||||
|
||||
// create the IrStruct
|
||||
IrStruct* irstruct = new IrStruct(sd);
|
||||
sd->ir.irStruct = irstruct;
|
||||
|
||||
// create the type
|
||||
ts->ir.type = new LLPATypeHolder(llvm::OpaqueType::get());
|
||||
// emit the initZ symbol
|
||||
LLGlobalVariable* initZ = irstruct->getInitSymbol();
|
||||
|
||||
// create symbols we're going to need
|
||||
// avoids chicken egg problems
|
||||
std::string initname("_D");
|
||||
initname.append(sd->mangle());
|
||||
initname.append("6__initZ");
|
||||
|
||||
llvm::GlobalValue::LinkageTypes _linkage = DtoExternalLinkage(sd);
|
||||
sd->ir.irStruct->init = new llvm::GlobalVariable(sd->ir.irStruct->initOpaque.get(), true, _linkage, NULL, initname, gIR->module);
|
||||
|
||||
// handle forward declaration structs (opaques)
|
||||
// didn't even know D had those ...
|
||||
if (sd->sizeok != 1)
|
||||
{
|
||||
// nothing more to do
|
||||
return;
|
||||
}
|
||||
|
||||
// make this struct current
|
||||
gIR->structs.push_back(irstruct);
|
||||
|
||||
// get some info
|
||||
bool ispacked = (ts->alignsize() == 1);
|
||||
|
||||
// set irstruct info
|
||||
irstruct->packed = ispacked;
|
||||
|
||||
// methods, fields
|
||||
Array* arr = sd->members;
|
||||
for (int k=0; k < arr->dim; k++) {
|
||||
Dsymbol* s = (Dsymbol*)arr->data[k];
|
||||
s->codegen(Type::sir);
|
||||
}
|
||||
|
||||
const LLType* ST = irstruct->build();
|
||||
|
||||
#if 0
|
||||
std::cout << sd->kind() << ' ' << sd->toPrettyChars() << " type: " << *ST << '\n';
|
||||
|
||||
// add fields
|
||||
for (int k=0; k < fields->dim; k++)
|
||||
{
|
||||
VarDeclaration* v = (VarDeclaration*)fields->data[k];
|
||||
printf(" field: %s %s\n", v->type->toChars(), v->toChars());
|
||||
printf(" index: %u offset: %u\n", v->ir.irField->index, v->ir.irField->unionOffset);
|
||||
}
|
||||
|
||||
unsigned llvmSize = (unsigned)getTypePaddedSize(ST);
|
||||
unsigned dmdSize = (unsigned)sd->type->size();
|
||||
printf(" llvm size: %u dmd size: %u\n", llvmSize, dmdSize);
|
||||
assert(llvmSize == dmdSize);
|
||||
|
||||
#endif
|
||||
|
||||
/*for (int k=0; k < sd->members->dim; k++) {
|
||||
Dsymbol* dsym = (Dsymbol*)(sd->members->data[k]);
|
||||
dsym->toObjFile();
|
||||
}*/
|
||||
|
||||
Logger::println("doing struct fields");
|
||||
|
||||
// refine abstract types for stuff like: struct S{S* next;}
|
||||
llvm::cast<llvm::OpaqueType>(ts->ir.type->get())->refineAbstractTypeTo(ST);
|
||||
ST = ts->ir.type->get();
|
||||
|
||||
// name type
|
||||
if (sd->parent->isModule()) {
|
||||
gIR->module->addTypeName(sd->mangle(),ST);
|
||||
}
|
||||
|
||||
// emit functions
|
||||
size_t n = irstruct->structFuncs.size();
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
{
|
||||
DtoResolveFunction(irstruct->structFuncs[i]);
|
||||
}
|
||||
irstruct->structFuncs.clear();
|
||||
|
||||
gIR->structs.pop_back();
|
||||
|
||||
DtoDeclareStruct(sd);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void DtoDeclareStruct(StructDeclaration* sd)
|
||||
{
|
||||
DtoResolveStruct(sd);
|
||||
|
||||
if (sd->ir.declared) return;
|
||||
sd->ir.declared = true;
|
||||
|
||||
Logger::println("DtoDeclareStruct(%s): %s", sd->toChars(), sd->loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
TypeStruct* ts = (TypeStruct*)sd->type->toBasetype();
|
||||
|
||||
DtoConstInitStruct(sd);
|
||||
// perform definition
|
||||
if (mustDefineSymbol(sd))
|
||||
DtoDefineStruct(sd);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void DtoConstInitStruct(StructDeclaration* sd)
|
||||
{
|
||||
DtoDeclareStruct(sd);
|
||||
|
||||
if (sd->ir.initialized) return;
|
||||
sd->ir.initialized = true;
|
||||
|
||||
Logger::println("DtoConstInitStruct(%s): %s", sd->toChars(), sd->loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
IrStruct* irstruct = sd->ir.irStruct;
|
||||
gIR->structs.push_back(irstruct);
|
||||
|
||||
const llvm::StructType* structtype = isaStruct(sd->type->ir.type->get());
|
||||
|
||||
// always generate the constant initalizer
|
||||
assert(!irstruct->constInit);
|
||||
if (sd->zeroInit)
|
||||
{
|
||||
Logger::println("Zero initialized");
|
||||
irstruct->constInit = llvm::ConstantAggregateZero::get(structtype);
|
||||
}
|
||||
else
|
||||
{
|
||||
Logger::println("Not zero initialized");
|
||||
|
||||
LLConstant* c = irstruct->buildDefaultConstInit();
|
||||
irstruct->constInit = c;
|
||||
// set initZ initializer
|
||||
initZ->setInitializer(irstruct->getDefaultInit());
|
||||
}
|
||||
|
||||
// refine __initZ global type to the one of the initializer
|
||||
llvm::cast<llvm::OpaqueType>(irstruct->initOpaque.get())->refineAbstractTypeTo(irstruct->constInit->getType());
|
||||
|
||||
// build initializers for static member variables
|
||||
size_t n = irstruct->staticVars.size();
|
||||
for (size_t i = 0; i < n; ++i)
|
||||
// emit members
|
||||
if (sd->members)
|
||||
{
|
||||
DtoConstInitGlobal(irstruct->staticVars[i]);
|
||||
ArrayIter<Dsymbol> it(*sd->members);
|
||||
while (!it.done())
|
||||
{
|
||||
Dsymbol* member = it.get();
|
||||
if (member)
|
||||
member->codegen(Type::sir);
|
||||
it.next();
|
||||
}
|
||||
}
|
||||
// This is all we use it for. Clear the memory!
|
||||
irstruct->staticVars.clear();
|
||||
|
||||
gIR->structs.pop_back();
|
||||
|
||||
// emit typeinfo
|
||||
if (sd->getModule() == gIR->dmodule && sd->llvmInternal != LLVMno_typeinfo)
|
||||
DtoTypeInfoOf(sd->type, false);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void DtoDefineStruct(StructDeclaration* sd)
|
||||
{
|
||||
DtoConstInitStruct(sd);
|
||||
|
||||
if (sd->ir.defined) return;
|
||||
sd->ir.defined = true;
|
||||
|
||||
Logger::println("DtoDefineStruct(%s): %s", sd->toChars(), sd->loc.toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
assert(sd->type->ty == Tstruct);
|
||||
TypeStruct* ts = (TypeStruct*)sd->type;
|
||||
sd->ir.irStruct->init->setInitializer(sd->ir.irStruct->constInit);
|
||||
|
||||
sd->ir.DModule = gIR->dmodule;
|
||||
DtoTypeInfoOf(sd->type);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
+5
-6
@@ -13,6 +13,7 @@
|
||||
#include "gen/logger.h"
|
||||
#include "gen/llvmhelpers.h"
|
||||
#include "gen/linkage.h"
|
||||
#include "gen/utils.h"
|
||||
|
||||
#include "ir/irmodule.h"
|
||||
|
||||
@@ -288,14 +289,12 @@ static llvm::DICompositeType dwarfCompositeType(Type* type, llvm::DICompileUnit
|
||||
std::vector<LLConstant*> elems;
|
||||
if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one
|
||||
{
|
||||
std::vector<VarDeclaration*>& arr = ir->varDecls;
|
||||
size_t narr = arr.size();
|
||||
ArrayIter<VarDeclaration> it(sd->fields);
|
||||
size_t narr = sd->fields.dim;
|
||||
elems.reserve(narr);
|
||||
for (int k=0; k<narr; k++)
|
||||
for (; !it.done(); it.next())
|
||||
{
|
||||
VarDeclaration* vd = arr[k];
|
||||
assert(vd);
|
||||
|
||||
VarDeclaration* vd = it.get();
|
||||
LLGlobalVariable* ptr = dwarfMemberType(vd->loc.linnum, vd->type, compileUnit, definedCU, vd->toChars(), vd->offset).getGV();
|
||||
elems.push_back(DBG_CAST(ptr));
|
||||
}
|
||||
|
||||
+12
-14
@@ -131,8 +131,7 @@ DValue* VarExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
|
||||
cid->cd->codegen(Type::sir);;
|
||||
assert(cid->cd->ir.irStruct->classInfo);
|
||||
return new DVarValue(type, vd, cid->cd->ir.irStruct->classInfo);
|
||||
return new DVarValue(type, vd, cid->cd->ir.irStruct->getClassInfoSymbol());
|
||||
}
|
||||
// nested variable
|
||||
#if DMDV2
|
||||
@@ -216,8 +215,8 @@ DValue* VarExp::toElem(IRState* p)
|
||||
TypeStruct* ts = (TypeStruct*)sdecltype;
|
||||
assert(ts->sym);
|
||||
ts->sym->codegen(Type::sir);
|
||||
assert(ts->sym->ir.irStruct->init);
|
||||
return new DVarValue(type, ts->sym->ir.irStruct->init);
|
||||
|
||||
return new DVarValue(type, ts->sym->ir.irStruct->getInitSymbol());
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -242,8 +241,8 @@ LLConstant* VarExp::toConstElem(IRState* p)
|
||||
assert(sdecltype->ty == Tstruct);
|
||||
TypeStruct* ts = (TypeStruct*)sdecltype;
|
||||
ts->sym->codegen(Type::sir);
|
||||
assert(ts->sym->ir.irStruct->constInit);
|
||||
return ts->sym->ir.irStruct->constInit;
|
||||
|
||||
return ts->sym->ir.irStruct->getDefaultInit();
|
||||
}
|
||||
|
||||
if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
|
||||
@@ -1134,9 +1133,7 @@ DValue* DotVarExp::toElem(IRState* p)
|
||||
size_t vtblidx = fdecl->vtblIndex;
|
||||
if (Logger::enabled())
|
||||
Logger::cout() << "vthis: " << *vthis << '\n';
|
||||
funcval = vthis;
|
||||
if (!fdecl->isMember2()->isInterfaceDeclaration())
|
||||
funcval = DtoGEP(funcval, zero, zero);
|
||||
funcval = DtoGEP(vthis, zero, zero);
|
||||
funcval = DtoLoad(funcval);
|
||||
Logger::println("vtblidx = %lu", vtblidx);
|
||||
funcval = DtoGEP(funcval, zero, DtoConstUint(vtblidx), toChars());
|
||||
@@ -1646,7 +1643,7 @@ DValue* NewExp::toElem(IRState* p)
|
||||
else {
|
||||
assert(ts->sym);
|
||||
ts->sym->codegen(Type::sir);
|
||||
DtoAggrCopy(mem,ts->sym->ir.irStruct->init);
|
||||
DtoAggrCopy(mem,ts->sym->ir.irStruct->getInitSymbol());
|
||||
}
|
||||
return new DImValue(type, mem);
|
||||
}
|
||||
@@ -1658,8 +1655,7 @@ DValue* NewExp::toElem(IRState* p)
|
||||
DVarValue tmpvar(newtype, mem);
|
||||
|
||||
// default initialize
|
||||
// FIXME: should this use DtoConstExpInit instead ?
|
||||
// or is static arrays the only troublemaker?
|
||||
// static arrays never appear here, so using the defaultInit is ok!
|
||||
Expression* exp = newtype->defaultInit(loc);
|
||||
DValue* iv = exp->toElem(gIR);
|
||||
DtoAssign(loc, &tmpvar, iv);
|
||||
@@ -2413,7 +2409,8 @@ DValue* StructLiteralExp::toElem(IRState* p)
|
||||
}
|
||||
|
||||
// vector of values to build aggregate from
|
||||
std::vector<LLValue*> values = DtoStructLiteralValues(sd, inits);
|
||||
std::vector<LLValue*> values;// = DtoStructLiteralValues(sd, inits);
|
||||
assert(0 && "struct literal exp todo");
|
||||
|
||||
// get the struct type from the values
|
||||
size_t n = values.size();
|
||||
@@ -2462,7 +2459,8 @@ LLConstant* StructLiteralExp::toConstElem(IRState* p)
|
||||
inits[i] = exprs[i]->toConstElem(p);
|
||||
|
||||
// vector of values to build aggregate from
|
||||
std::vector<LLValue*> values = DtoStructLiteralValues(sd, inits);
|
||||
std::vector<LLValue*> values;// = DtoStructLiteralValues(sd, inits);
|
||||
assert(0 && "struct literal const exp todo");
|
||||
|
||||
// we know those values are constants.. cast them
|
||||
std::vector<LLConstant*> constvals(values.size(), NULL);
|
||||
|
||||
+22
-28
@@ -23,6 +23,7 @@
|
||||
#include "gen/llvm-version.h"
|
||||
|
||||
#include "ir/irtype.h"
|
||||
#include "ir/irtypeclass.h"
|
||||
|
||||
bool DtoIsPassedByRef(Type* type)
|
||||
{
|
||||
@@ -52,11 +53,17 @@ unsigned DtoShouldExtend(Type* type)
|
||||
|
||||
const LLType* DtoType(Type* t)
|
||||
{
|
||||
#if DMDV2
|
||||
t = t->mutableOf();
|
||||
#endif
|
||||
|
||||
if (t->irtype)
|
||||
{
|
||||
return t->irtype->get();
|
||||
}
|
||||
|
||||
IF_LOG Logger::println("Building type: %s", t->toChars());
|
||||
|
||||
assert(t);
|
||||
switch (t->ty)
|
||||
{
|
||||
@@ -86,57 +93,50 @@ const LLType* DtoType(Type* t)
|
||||
case Tdchar:
|
||||
{
|
||||
t->irtype = new IrTypeBasic(t);
|
||||
return t->irtype->get();
|
||||
return t->irtype->buildType();
|
||||
}
|
||||
|
||||
// pointers
|
||||
case Tpointer:
|
||||
{
|
||||
t->irtype = new IrTypePointer(t);
|
||||
return t->irtype->get();
|
||||
return t->irtype->buildType();
|
||||
}
|
||||
|
||||
// arrays
|
||||
case Tarray:
|
||||
{
|
||||
t->irtype = new IrTypeArray(t);
|
||||
return t->irtype->get();
|
||||
return t->irtype->buildType();
|
||||
}
|
||||
|
||||
case Tsarray:
|
||||
{
|
||||
t->irtype = new IrTypeSArray(t);
|
||||
return t->irtype->get();
|
||||
return t->irtype->buildType();
|
||||
}
|
||||
|
||||
// aggregates
|
||||
case Tstruct: {
|
||||
#if DMDV2
|
||||
TypeStruct* ts = (TypeStruct*)t->mutableOf();
|
||||
#else
|
||||
TypeStruct* ts = (TypeStruct*)t;
|
||||
#endif
|
||||
assert(ts->sym);
|
||||
DtoResolveDsymbol(ts->sym);
|
||||
return ts->ir.type->get();
|
||||
t->irtype = new IrTypeStruct(ts->sym);
|
||||
return t->irtype->buildType();
|
||||
}
|
||||
|
||||
case Tclass: {
|
||||
#if DMDV2
|
||||
TypeClass* tc = (TypeClass*)t->mutableOf();
|
||||
#else
|
||||
TypeClass* tc = (TypeClass*)t;
|
||||
#endif
|
||||
assert(tc->sym);
|
||||
DtoResolveDsymbol(tc->sym);
|
||||
return getPtrToType(tc->ir.type->get());
|
||||
t->irtype = new IrTypeClass(tc->sym);
|
||||
return t->irtype->buildType();
|
||||
}
|
||||
|
||||
// functions
|
||||
case Tfunction:
|
||||
{
|
||||
if (!t->ir.type || *t->ir.type == NULL) {
|
||||
return DtoFunctionType(t,NULL,NULL);
|
||||
TypeFunction* tf = (TypeFunction*)t;
|
||||
if (tf->funcdecl)
|
||||
return DtoFunctionType(tf->funcdecl);
|
||||
else
|
||||
return DtoFunctionType(tf,NULL,NULL);
|
||||
}
|
||||
else {
|
||||
return t->ir.type->get();
|
||||
@@ -156,6 +156,8 @@ const LLType* DtoType(Type* t)
|
||||
|
||||
// typedefs
|
||||
// enum
|
||||
|
||||
// FIXME: maybe just call toBasetype first ?
|
||||
case Ttypedef:
|
||||
case Tenum:
|
||||
{
|
||||
@@ -166,15 +168,7 @@ const LLType* DtoType(Type* t)
|
||||
|
||||
// associative arrays
|
||||
case Taarray:
|
||||
#if 1
|
||||
return getVoidPtrType();
|
||||
#else
|
||||
{
|
||||
TypeAArray* taa = (TypeAArray*)t;
|
||||
// aa key/val can't be void
|
||||
return getPtrToType(LLStructType::get(DtoType(taa->key), DtoType(taa->next), 0));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
Not needed atm as VarDecls for tuples are rewritten as a string of
|
||||
|
||||
+3
-4
@@ -146,7 +146,7 @@ llvm::Module* Module::genLLVMModule(Ir* sir)
|
||||
sir->emitFunctionBodies();
|
||||
|
||||
// generate ModuleInfo
|
||||
genmoduleinfo();
|
||||
//genmoduleinfo();
|
||||
|
||||
// emit usedArray
|
||||
if (!ir.usedArray.empty())
|
||||
@@ -621,7 +621,7 @@ void Module::genmoduleinfo()
|
||||
LLConstant* c = 0;
|
||||
|
||||
// vtable
|
||||
c = moduleinfo->ir.irStruct->vtbl;
|
||||
c = moduleinfo->ir.irStruct->getVtblSymbol();
|
||||
initVec.push_back(c);
|
||||
|
||||
// monitor
|
||||
@@ -696,8 +696,7 @@ void Module::genmoduleinfo()
|
||||
continue;
|
||||
}
|
||||
Logger::println("class: %s", cd->toPrettyChars());
|
||||
assert(cd->ir.irStruct->classInfo);
|
||||
c = DtoBitCast(cd->ir.irStruct->classInfo, getPtrToType(classinfoTy));
|
||||
c = DtoBitCast(cd->ir.irStruct->getClassInfoSymbol(), getPtrToType(classinfoTy));
|
||||
classInits.push_back(c);
|
||||
}
|
||||
// has class array?
|
||||
|
||||
+16
-29
@@ -253,20 +253,6 @@ int TypeDArray::builtinTypeInfo()
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
/***************************************
|
||||
* Create a static array of TypeInfo references
|
||||
* corresponding to an array of Expression's.
|
||||
* Used to supply hidden _arguments[] value for variadic D functions.
|
||||
*/
|
||||
|
||||
Expression *createTypeInfoArray(Scope *sc, Expression *exps[], int dim)
|
||||
{
|
||||
assert(0); // done elsewhere in LDC
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// MAGIC PLACE
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
@@ -376,7 +362,7 @@ void TypeInfoTypedefDeclaration::llvmDefine()
|
||||
|
||||
// vtbl
|
||||
std::vector<LLConstant*> sinits;
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
||||
|
||||
// monitor
|
||||
sinits.push_back(getNullPtr(getPtrToType(LLType::Int8Ty)));
|
||||
@@ -433,7 +419,7 @@ void TypeInfoEnumDeclaration::llvmDefine()
|
||||
|
||||
// vtbl
|
||||
std::vector<LLConstant*> sinits;
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
||||
|
||||
// monitor
|
||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||
@@ -491,7 +477,7 @@ static void LLVM_D_Define_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid,
|
||||
|
||||
// vtbl
|
||||
std::vector<LLConstant*> sinits;
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
||||
|
||||
// monitor
|
||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||
@@ -553,7 +539,7 @@ void TypeInfoStaticArrayDeclaration::llvmDefine()
|
||||
// initializer vector
|
||||
std::vector<LLConstant*> sinits;
|
||||
// first is always the vtable
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
||||
|
||||
// monitor
|
||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||
@@ -592,7 +578,7 @@ void TypeInfoAssociativeArrayDeclaration::llvmDefine()
|
||||
// initializer vector
|
||||
std::vector<LLConstant*> sinits;
|
||||
// first is always the vtable
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
||||
|
||||
// monitor
|
||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||
@@ -664,7 +650,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||
|
||||
// vtbl
|
||||
std::vector<LLConstant*> sinits;
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
||||
|
||||
// monitor
|
||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||
@@ -687,7 +673,7 @@ void TypeInfoStructDeclaration::llvmDefine()
|
||||
#endif
|
||||
{
|
||||
size_t cisize = getTypeStoreSize(tc->ir.type->get());
|
||||
LLConstant* cicast = llvm::ConstantExpr::getBitCast(sd->ir.irStruct->init, initpt);
|
||||
LLConstant* cicast = llvm::ConstantExpr::getBitCast(sd->ir.irStruct->getInitSymbol(), initpt);
|
||||
sinits.push_back(DtoConstSlice(DtoConstSize_t(cisize), cicast));
|
||||
}
|
||||
|
||||
@@ -857,7 +843,7 @@ void TypeInfoClassDeclaration::llvmDefine()
|
||||
// initializer vector
|
||||
std::vector<LLConstant*> sinits;
|
||||
// first is always the vtable
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
||||
|
||||
// monitor
|
||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||
@@ -865,9 +851,10 @@ void TypeInfoClassDeclaration::llvmDefine()
|
||||
// get classinfo
|
||||
assert(tinfo->ty == Tclass);
|
||||
TypeClass *tc = (TypeClass *)tinfo;
|
||||
tc->sym->codegen(Type::sir);;
|
||||
assert(tc->sym->ir.irStruct->classInfo);
|
||||
sinits.push_back(tc->sym->ir.irStruct->classInfo);
|
||||
|
||||
tc->sym->codegen(Type::sir);
|
||||
|
||||
sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol());
|
||||
|
||||
// create the inititalizer
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
||||
@@ -897,7 +884,7 @@ void TypeInfoInterfaceDeclaration::llvmDefine()
|
||||
// initializer vector
|
||||
std::vector<LLConstant*> sinits;
|
||||
// first is always the vtable
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
||||
|
||||
// monitor
|
||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||
@@ -905,8 +892,8 @@ void TypeInfoInterfaceDeclaration::llvmDefine()
|
||||
// get classinfo
|
||||
assert(tinfo->ty == Tclass);
|
||||
TypeClass *tc = (TypeClass *)tinfo;
|
||||
assert(tc->sym->ir.irStruct->classInfo);
|
||||
sinits.push_back(tc->sym->ir.irStruct->classInfo);
|
||||
|
||||
sinits.push_back(tc->sym->ir.irStruct->getClassInfoSymbol());
|
||||
|
||||
// create the inititalizer
|
||||
LLConstant* tiInit = llvm::ConstantStruct::get(sinits);
|
||||
@@ -936,7 +923,7 @@ void TypeInfoTupleDeclaration::llvmDefine()
|
||||
// initializer vector
|
||||
std::vector<LLConstant*> sinits;
|
||||
// first is always the vtable
|
||||
sinits.push_back(base->ir.irStruct->vtbl);
|
||||
sinits.push_back(base->ir.irStruct->getVtblSymbol());
|
||||
|
||||
// monitor
|
||||
sinits.push_back(llvm::ConstantPointerNull::get(getPtrToType(LLType::Int8Ty)));
|
||||
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
#ifndef __LDC_GEN_UTILS_H__
|
||||
#define __LDC_GEN_UTILS_H__
|
||||
|
||||
#include "root.h"
|
||||
|
||||
/// Very simple templated iterator for DMD ArrayS.
|
||||
template<class C>
|
||||
struct ArrayIter
|
||||
{
|
||||
Array& array;
|
||||
size_t index;
|
||||
|
||||
ArrayIter(Array& arr, size_t idx = 0)
|
||||
: array(arr), index(idx)
|
||||
{ }
|
||||
|
||||
bool done()
|
||||
{
|
||||
return index >= array.dim;
|
||||
}
|
||||
bool more()
|
||||
{
|
||||
return index < array.dim;
|
||||
}
|
||||
|
||||
C* get()
|
||||
{
|
||||
return static_cast<C*>(array.data[index]);
|
||||
}
|
||||
C* operator->()
|
||||
{
|
||||
return static_cast<C*>(array.data[index]);
|
||||
}
|
||||
|
||||
void next()
|
||||
{
|
||||
++index;
|
||||
}
|
||||
};
|
||||
|
||||
// some aliases
|
||||
typedef ArrayIter<Dsymbol> DsymbolIter;
|
||||
typedef ArrayIter<FuncDeclaration> FuncDeclarationIter;
|
||||
typedef ArrayIter<VarDeclaration> VarDeclarationIter;
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user