[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum

Added initial support for CatExp aka 'a ~ b'
Fixed global constant static arrays initialized with string literals
Fixed casting any dynamic array to void*
Fixed new expression with temporary storage
Fixed alias declarations in function scope
Fixed relational comparisons of pointers
This commit is contained in:
Tomas Lindquist Olsen
2007-10-25 09:02:55 +02:00
parent 5478de7147
commit be330878c2
39 changed files with 551 additions and 263 deletions

View File

@@ -192,6 +192,7 @@ void LLVM_DtoArrayInit(llvm::Value* ptr, llvm::Value* dim, llvm::Value* val)
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, funcname);
assert(fn);
Logger::cout() << "calling array init function: " << *fn <<'\n';
llvm::CallInst* call = new llvm::CallInst(fn, args.begin(), args.end(), "", gIR->scopebb());
call->setCallingConv(llvm::CallingConv::C);
}
@@ -391,17 +392,18 @@ llvm::Constant* LLVM_DtoConstantSlice(llvm::Constant* dim, llvm::Constant* ptr)
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit)
llvm::Value* LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit)
{
const llvm::Type* ty = LLVM_DtoType(dty);
assert(ty != llvm::Type::VoidTy);
size_t sz = gTargetData->getTypeSize(ty);
llvm::ConstantInt* n = llvm::ConstantInt::get(LLVM_DtoSize_t(), sz, false);
llvm::Value* bytesize = llvm::BinaryOperator::createMul(n,dim,"tmp",gIR->scopebb());
llvm::Value* bytesize = (sz == 1) ? dim : llvm::BinaryOperator::createMul(n,dim,"tmp",gIR->scopebb());
llvm::Value* nullptr = llvm::ConstantPointerNull::get(llvm::PointerType::get(ty));
llvm::Value* newptr = LLVM_DtoRealloc(nullptr, bytesize);
if (doinit) {
elem* e = dty->defaultInit()->toElem(gIR);
LLVM_DtoArrayInit(newptr,dim,e->getValue());
@@ -412,6 +414,8 @@ void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doi
new llvm::StoreInst(dim,lenptr,gIR->scopebb());
llvm::Value* ptrptr = LLVM_DtoGEPi(dst,0,1,"tmp",gIR->scopebb());
new llvm::StoreInst(newptr,ptrptr,gIR->scopebb());
return newptr;
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -422,7 +426,7 @@ void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz)
size_t isz = gTargetData->getTypeSize(ptrld->getType()->getContainedType(0));
llvm::ConstantInt* n = llvm::ConstantInt::get(LLVM_DtoSize_t(), isz, false);
llvm::Value* bytesz = llvm::BinaryOperator::createMul(n,sz,"tmp",gIR->scopebb());
llvm::Value* bytesz = (isz == 1) ? sz : llvm::BinaryOperator::createMul(n,sz,"tmp",gIR->scopebb());
llvm::Value* newptr = LLVM_DtoRealloc(ptrld, bytesz);
new llvm::StoreInst(newptr,ptr,gIR->scopebb());
@@ -432,7 +436,7 @@ void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz)
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLVM_DtoCatArrayElement(llvm::Value* arr, Expression* exp)
void LLVM_DtoCatAssignElement(llvm::Value* arr, Expression* exp)
{
llvm::Value* ptr = LLVM_DtoGEPi(arr, 0, 0, "tmp", gIR->scopebb());
llvm::Value* idx = new llvm::LoadInst(ptr, "tmp", gIR->scopebb());
@@ -450,6 +454,38 @@ void LLVM_DtoCatArrayElement(llvm::Value* arr, Expression* exp)
delete e;
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLVM_DtoCatArrays(llvm::Value* arr, Expression* exp1, Expression* exp2)
{
Type* t1 = LLVM_DtoDType(exp1->type);
Type* t2 = LLVM_DtoDType(exp2->type);
assert(t1->ty == Tarray);
assert(t1->ty == t2->ty);
elem* e1 = exp1->toElem(gIR);
llvm::Value* a = e1->getValue();
delete e1;
elem* e2 = exp2->toElem(gIR);
llvm::Value* b = e2->getValue();
delete e2;
llvm::Value *len1, *len2, *src1, *src2, *res;
len1 = gIR->ir->CreateLoad(LLVM_DtoGEPi(a,0,0,"tmp"),"tmp");
len2 = gIR->ir->CreateLoad(LLVM_DtoGEPi(b,0,0,"tmp"),"tmp");
res = gIR->ir->CreateAdd(len1,len2,"tmp");
llvm::Value* mem = LLVM_DtoNewDynArray(arr, res, LLVM_DtoDType(t1->next), false);
src1 = gIR->ir->CreateLoad(LLVM_DtoGEPi(a,0,1,"tmp"),"tmp");
src2 = gIR->ir->CreateLoad(LLVM_DtoGEPi(b,0,1,"tmp"),"tmp");
LLVM_DtoMemCpy(mem,src1,len1);
mem = gIR->ir->CreateGEP(mem,len1,"tmp");
LLVM_DtoMemCpy(mem,src2,len2);
}
//////////////////////////////////////////////////////////////////////////////////////////
llvm::Value* LLVM_DtoStaticArrayCompare(TOK op, llvm::Value* l, llvm::Value* r)
{
@@ -569,8 +605,5 @@ llvm::Value* LLVM_DtoDynArrayIs(TOK op, llvm::Value* l, llvm::Value* r)
llvm::Value* b2 = gIR->ir->CreateICmp(pred,lp,rp,"tmp");
llvm::Value* b = gIR->ir->CreateAnd(b1,b2,"tmp");
if (op == TOKnotidentity)
return gIR->ir->CreateNot(b,"tmp");
else
return b;
return b;
}

View File

@@ -14,10 +14,11 @@ void LLVM_DtoArrayAssign(llvm::Value* l, llvm::Value* r);
void LLVM_DtoSetArray(llvm::Value* arr, llvm::Value* dim, llvm::Value* ptr);
void LLVM_DtoNullArray(llvm::Value* v);
void LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit=true);
llvm::Value* LLVM_DtoNewDynArray(llvm::Value* dst, llvm::Value* dim, Type* dty, bool doinit=true);
void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz);
void LLVM_DtoCatArrayElement(llvm::Value* arr, Expression* exp);
void LLVM_DtoCatAssignElement(llvm::Value* arr, Expression* exp);
void LLVM_DtoCatArrays(llvm::Value* arr, Expression* e1, Expression* e2);
void LLVM_DtoStaticArrayCopy(llvm::Value* dst, llvm::Value* src);

View File

@@ -82,11 +82,12 @@ elem* DeclarationExp::toElem(IRState* p)
// alias declaration
else if (AliasDeclaration* a = declaration->isAliasDeclaration())
{
Logger::println("AliasDeclaration");
assert(0);
Logger::println("AliasDeclaration - no work");
// do nothing
}
else if (EnumDeclaration* e = declaration->isEnumDeclaration())
{
Logger::println("EnumDeclaration - no work");
// do nothing
}
// unsupported declaration
@@ -162,7 +163,10 @@ elem* VarExp::toElem(IRState* p)
// typeinfo
else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
{
assert(0);
tid->toObjFile();
assert(tid->llvmValue);
e->val = tid->llvmValue;
e->type = elem::VAR;
}
// global forward ref
else {
@@ -438,10 +442,11 @@ llvm::Constant* StringExp::toConstElem(IRState* p)
Type* t = LLVM_DtoDType(type);
llvm::Constant* _init = llvm::ConstantArray::get(cont,true);
if (t->ty == Tsarray) {
return _init;
return llvm::ConstantArray::get(cont,false);
}
llvm::Constant* _init = llvm::ConstantArray::get(cont,true);
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,"stringliteral",gIR->module);
@@ -1342,11 +1347,13 @@ elem* CastExp::toElem(IRState* p)
Logger::cout() << "from array or sarray" << '\n';
if (totype->ty == Tpointer) {
Logger::cout() << "to pointer" << '\n';
assert(fromtype->next == totype->next);
assert(fromtype->next == totype->next || totype->next->ty == Tvoid);
llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
llvm::Value* ptr = LLVM_DtoGEP(u->getValue(),zero,one,"tmp",p->scopebb());
e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb());
if (fromtype->next != totype->next)
e->val = p->ir->CreateBitCast(e->val, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp");
e->type = elem::VAL;
}
else if (totype->ty == Tarray) {
@@ -1890,7 +1897,7 @@ elem* CmpExp::toElem(IRState* p)
Type* e2t = LLVM_DtoDType(e2->type);
assert(t == e2t);
if (t->isintegral())
if (t->isintegral() || t->ty == Tpointer)
{
llvm::ICmpInst::Predicate cmpop;
bool skip = false;
@@ -2132,6 +2139,7 @@ elem* NewExp::toElem(IRState* p)
assert(!allocator);
elem* e = new elem;
e->inplace = true;
Type* ntype = LLVM_DtoDType(newtype);
@@ -2150,8 +2158,23 @@ elem* NewExp::toElem(IRState* p)
if (arguments->dim == 1) {
elem* sz = ((Expression*)arguments->data[0])->toElem(p);
llvm::Value* dimval = sz->getValue();
assert(p->topexp() && p->topexp()->e2 == this && p->topexp()->v);
LLVM_DtoNewDynArray(p->topexp()->v, dimval, ntype->next);
Type* nnt = LLVM_DtoDType(ntype->next);
if (nnt->ty == Tvoid)
nnt = Type::tint8;
if (!p->topexp() || p->topexp()->e2 != this) {
const llvm::Type* restype = LLVM_DtoType(type);
Logger::cout() << "restype = " << *restype << '\n';
e->mem = new llvm::AllocaInst(restype,"tmp",p->topallocapoint());
LLVM_DtoNewDynArray(e->mem, dimval, nnt);
e->inplace = false;
}
else if (p->topexp() || p->topexp()->e2 != this) {
assert(p->topexp()->v);
e->mem = p->topexp()->v;
LLVM_DtoNewDynArray(e->mem, dimval, nnt);
}
else
assert(0);
delete sz;
}
else {
@@ -2197,7 +2220,6 @@ elem* NewExp::toElem(IRState* p)
}
}
e->inplace = true;
e->type = elem::VAR;
return e;
@@ -2661,17 +2683,30 @@ elem* CatExp::toElem(IRState* p)
Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars());
LOG_SCOPE;
assert(0 && "array cat is not yet implemented");
Type* t = LLVM_DtoDType(type);
elem* lhs = e1->toElem(p);
elem* rhs = e2->toElem(p);
bool inplace = false;
llvm::Value* dst = 0;
IRExp* ex = p->topexp();
if (ex && ex->e2 == this) {
assert(ex->v);
dst = ex->v;
inplace = true;
}
else {
assert(t->ty == Tarray);
const llvm::Type* arrty = LLVM_DtoType(t);
dst = new llvm::AllocaInst(arrty, "tmpmem", p->topallocapoint());
}
// determine new size
LLVM_DtoCatArrays(dst,e1,e2);
delete lhs;
delete rhs;
elem* e = new elem;
e->mem = dst;
e->type = elem::VAR;
e->inplace = inplace;
return 0;
return e;
}
//////////////////////////////////////////////////////////////////////////////////////////
@@ -2689,7 +2724,7 @@ elem* CatAssignExp::toElem(IRState* p)
Type* e2type = LLVM_DtoDType(e2->type);
if (e2type == elemtype) {
LLVM_DtoCatArrayElement(l->mem,e2);
LLVM_DtoCatAssignElement(l->mem,e2);
}
else
assert(0 && "only one element at a time right now");

View File

@@ -1382,3 +1382,33 @@ llvm::Constant* LLVM_DtoConstString(const char* str)
llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2)
);
}
//////////////////////////////////////////////////////////////////////////////////////////
void LLVM_DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes)
{
assert(dst->getType() == src->getType());
llvm::Type* arrty = llvm::PointerType::get(llvm::Type::Int8Ty);
llvm::Value *dstarr, *srcarr;
if (dst->getType() == arrty)
{
dstarr = dst;
srcarr = src;
}
else
{
dstarr = new llvm::BitCastInst(dst,arrty,"tmp",gIR->scopebb());
srcarr = new llvm::BitCastInst(src,arrty,"tmp",gIR->scopebb());
}
llvm::Function* fn = (global.params.is64bit) ? LLVM_DeclareMemCpy64() : LLVM_DeclareMemCpy32();
std::vector<llvm::Value*> llargs;
llargs.resize(4);
llargs[0] = dstarr;
llargs[1] = srcarr;
llargs[2] = nbytes;
llargs[3] = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false);
new llvm::CallInst(fn, llargs.begin(), llargs.end(), "", gIR->scopebb());
}

View File

@@ -63,4 +63,6 @@ llvm::ConstantInt* LLVM_DtoConstSize_t(size_t);
llvm::ConstantInt* LLVM_DtoConstUint(unsigned i);
llvm::Constant* LLVM_DtoConstString(const char*);
void LLVM_DtoMemCpy(llvm::Value* dst, llvm::Value* src, llvm::Value* nbytes);
#include "enums.h"

View File

@@ -547,10 +547,14 @@ void VarDeclaration::toObjFile()
else if (llvm::isa<llvm::ArrayType>(_type))
{
const llvm::ArrayType* at = llvm::cast<llvm::ArrayType>(_type);
assert(_type->getContainedType(0) == _init->getType());
std::vector<llvm::Constant*> initvals;
initvals.resize(at->getNumElements(), _init);
_init = llvm::ConstantArray::get(at, initvals);
if (at->getElementType() == _init->getType()) {
std::vector<llvm::Constant*> initvals;
initvals.resize(at->getNumElements(), _init);
_init = llvm::ConstantArray::get(at, initvals);
}
else {
assert(0);
}
}
else {
Logger::cout() << "Unexpected initializer type: " << *_type << '\n';

View File

@@ -246,12 +246,13 @@ void TypeInfoDeclaration::toObjFile()
Logger::println("typeinfo mangle: %s", mangle());
// this is a declaration of a builtin __initZ var
if (tinfo->builtinTypeInfo()) {
// this is a declaration of a builtin __initZ var
llvmValue = LLVM_D_GetRuntimeGlobal(gIR->module, mangle());
assert(llvmValue);
Logger::cout() << "Got typeinfo var:" << '\n' << *llvmValue << '\n';
}
// custom typedef
else {
toDt(NULL);
// this is a specialized typeinfo
@@ -265,8 +266,16 @@ void TypeInfoDeclaration::toObjFile()
void TypeInfoDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoDeclaration");
/*
//printf("TypeInfoDeclaration::toDt() %s\n", toChars());
dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
dtdword(pdt, 0); // monitor
*/
}
/* ========================================================================= */
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
{
Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars());
@@ -354,116 +363,59 @@ void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
*/
}
/* ========================================================================= */
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoEnumDeclaration");
}
Logger::println("TypeInfoTypedefDeclaration::toDt() %s", toChars());
LOG_SCOPE;
void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoPointerDeclaration");
}
ClassDeclaration* base = Type::typeinfoenum;
base->toObjFile();
void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoArrayDeclaration");
}
llvm::Constant* initZ = base->llvmInitZ;
assert(initZ);
const llvm::StructType* stype = llvm::cast<llvm::StructType>(initZ->getType());
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoStaticArrayDeclaration");
}
std::vector<llvm::Constant*> sinits;
sinits.push_back(initZ->getOperand(0));
void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoAssociativeArrayDeclaration");
}
assert(tinfo->ty == Tenum);
TypeEnum *tc = (TypeEnum *)tinfo;
EnumDeclaration *sd = tc->sym;
void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoFunctionDeclaration");
}
void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoDelegateDeclaration");
}
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoStructDeclaration");
}
void TypeInfoClassDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoClassDeclaration");
}
void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoInterfaceDeclaration");
}
void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoTupleDeclaration");
}
// original dmdfe toDt code for reference
#if 0
void TypeInfoDeclaration::toDt(dt_t **pdt)
{
//printf("TypeInfoDeclaration::toDt() %s\n", toChars());
dtxoff(pdt, Type::typeinfo->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo
dtdword(pdt, 0); // monitor
}
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
{
//printf("TypeInfoTypedefDeclaration::toDt() %s\n", toChars());
dtxoff(pdt, Type::typeinfotypedef->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Typedef
dtdword(pdt, 0); // monitor
assert(tinfo->ty == Ttypedef);
TypeTypedef *tc = (TypeTypedef *)tinfo;
TypedefDeclaration *sd = tc->sym;
//printf("basetype = %s\n", sd->basetype->toChars());
/* Put out:
* TypeInfo base;
* char[] name;
* void[] m_init;
*/
sd->basetype = sd->basetype->merge();
sd->basetype->getTypeInfo(NULL); // generate vtinfo
assert(sd->basetype->vtinfo);
dtxoff(pdt, sd->basetype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for basetype
// TypeInfo base
//const llvm::PointerType* basept = llvm::cast<llvm::PointerType>(initZ->getOperand(1)->getType());
//sinits.push_back(llvm::ConstantPointerNull::get(basept));
Logger::println("generating base typeinfo");
//sd->basetype = sd->basetype->merge();
sd->memtype->getTypeInfo(NULL); // generate vtinfo
assert(sd->memtype->vtinfo);
if (!sd->memtype->vtinfo->llvmValue)
sd->memtype->vtinfo->toObjFile();
assert(llvm::isa<llvm::Constant>(sd->memtype->vtinfo->llvmValue));
llvm::Constant* castbase = llvm::cast<llvm::Constant>(sd->memtype->vtinfo->llvmValue);
castbase = llvm::ConstantExpr::getBitCast(castbase, initZ->getOperand(1)->getType());
sinits.push_back(castbase);
// char[] name
char *name = sd->toPrettyChars();
size_t namelen = strlen(name);
dtdword(pdt, namelen);
dtabytes(pdt, TYnptr, 0, namelen + 1, name);
sinits.push_back(LLVM_DtoConstString(name));
assert(sinits.back()->getType() == initZ->getOperand(2)->getType());
// void[] init;
if (tinfo->isZeroInit() || !sd->init)
{ // 0 initializer, or the same as the base type
dtdword(pdt, 0); // init.length
dtdword(pdt, 0); // init.ptr
}
else
{
dtdword(pdt, sd->type->size()); // init.length
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
}
}
// void[] init
//const llvm::PointerType* initpt = llvm::PointerType::get(llvm::Type::Int8Ty);
//sinits.push_back(LLVM_DtoConstantSlice(LLVM_DtoConstSize_t(0), llvm::ConstantPointerNull::get(initpt)));
sinits.push_back(initZ->getOperand(3));
// create the symbol
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,toChars(),gIR->module);
llvmValue = gvar;
/*
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
{
//printf("TypeInfoEnumDeclaration::toDt()\n");
dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
dtdword(pdt, 0); // monitor
@@ -473,11 +425,10 @@ void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
TypeEnum *tc = (TypeEnum *)tinfo;
EnumDeclaration *sd = tc->sym;
/* Put out:
* TypeInfo base;
* char[] name;
* void[] m_init;
*/
// Put out:
// TypeInfo base;
// char[] name;
// void[] m_init;
sd->memtype->getTypeInfo(NULL);
dtxoff(pdt, sd->memtype->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for enum members
@@ -498,38 +449,75 @@ void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
dtdword(pdt, sd->type->size()); // init.length
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
}
*/
}
/* ========================================================================= */
static llvm::Constant* LLVM_D_Create_TypeInfoBase(Type* basetype, TypeInfoDeclaration* tid, ClassDeclaration* cd)
{
ClassDeclaration* base = cd;
base->toObjFile();
llvm::Constant* initZ = base->llvmInitZ;
assert(initZ);
const llvm::StructType* stype = llvm::cast<llvm::StructType>(initZ->getType());
std::vector<llvm::Constant*> sinits;
sinits.push_back(initZ->getOperand(0));
// TypeInfo base
Logger::println("generating base typeinfo");
basetype->getTypeInfo(NULL);
assert(basetype->vtinfo);
if (!basetype->vtinfo->llvmValue)
basetype->vtinfo->toObjFile();
assert(llvm::isa<llvm::Constant>(basetype->vtinfo->llvmValue));
llvm::Constant* castbase = llvm::cast<llvm::Constant>(basetype->vtinfo->llvmValue);
castbase = llvm::ConstantExpr::getBitCast(castbase, initZ->getOperand(1)->getType());
sinits.push_back(castbase);
// create the symbol
llvm::Constant* tiInit = llvm::ConstantStruct::get(stype, sinits);
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(stype,true,llvm::GlobalValue::InternalLinkage,tiInit,tid->toChars(),gIR->module);
tid->llvmValue = gvar;
}
/* ========================================================================= */
void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
{
//printf("TypeInfoPointerDeclaration::toDt()\n");
dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer
dtdword(pdt, 0); // monitor
Logger::println("TypeInfoPointerDeclaration::toDt() %s", toChars());
LOG_SCOPE;
assert(tinfo->ty == Tpointer);
TypePointer *tc = (TypePointer *)tinfo;
tc->next->getTypeInfo(NULL);
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for type being pointed to
LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfopointer);
}
/* ========================================================================= */
void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
{
//printf("TypeInfoArrayDeclaration::toDt()\n");
dtxoff(pdt, Type::typeinfoarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Array
dtdword(pdt, 0); // monitor
Logger::println("TypeInfoArrayDeclaration::toDt() %s", toChars());
LOG_SCOPE;
assert(tinfo->ty == Tarray);
TypeDArray *tc = (TypeDArray *)tinfo;
tc->next->getTypeInfo(NULL);
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfoarray);
}
/* ========================================================================= */
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoStaticArrayDeclaration");
/*
//printf("TypeInfoStaticArrayDeclaration::toDt()\n");
dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
dtdword(pdt, 0); // monitor
@@ -542,10 +530,16 @@ void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
dtdword(pdt, tc->dim->toInteger()); // length
*/
}
/* ========================================================================= */
void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoAssociativeArrayDeclaration");
/*
//printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray
dtdword(pdt, 0); // monitor
@@ -559,38 +553,42 @@ void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
tc->index->getTypeInfo(NULL);
dtxoff(pdt, tc->index->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
*/
}
/* ========================================================================= */
void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
{
//printf("TypeInfoFunctionDeclaration::toDt()\n");
dtxoff(pdt, Type::typeinfofunction->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Function
dtdword(pdt, 0); // monitor
Logger::println("TypeInfoFunctionDeclaration::toDt() %s", toChars());
LOG_SCOPE;
assert(tinfo->ty == Tfunction);
TypeFunction *tc = (TypeFunction *)tinfo;
tc->next->getTypeInfo(NULL);
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for function return value
LLVM_D_Create_TypeInfoBase(tc->next, this, Type::typeinfofunction);
}
/* ========================================================================= */
void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
{
//printf("TypeInfoDelegateDeclaration::toDt()\n");
dtxoff(pdt, Type::typeinfodelegate->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Delegate
dtdword(pdt, 0); // monitor
Logger::println("TypeInfoDelegateDeclaration::toDt() %s", toChars());
LOG_SCOPE;
assert(tinfo->ty == Tdelegate);
TypeDelegate *tc = (TypeDelegate *)tinfo;
tc->next->next->getTypeInfo(NULL);
dtxoff(pdt, tc->next->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for delegate return value
LLVM_D_Create_TypeInfoBase(tc->next->next, this, Type::typeinfodelegate);
}
/* ========================================================================= */
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoStructDeclaration");
/*
//printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
unsigned offset = Type::typeinfostruct->structsize;
@@ -603,17 +601,17 @@ void TypeInfoStructDeclaration::toDt(dt_t **pdt)
TypeStruct *tc = (TypeStruct *)tinfo;
StructDeclaration *sd = tc->sym;
/* Put out:
* char[] name;
* void[] init;
* hash_t function(void*) xtoHash;
* int function(void*,void*) xopEquals;
* int function(void*,void*) xopCmp;
* char[] function(void*) xtoString;
* uint m_flags;
*
* name[]
*/
// Put out:
// char[] name;
// void[] init;
// hash_t function(void*) xtoHash;
// int function(void*,void*) xopEquals;
// int function(void*,void*) xopCmp;
// char[] function(void*) xtoString;
// uint m_flags;
//
// name[]
//
char *name = sd->toPrettyChars();
size_t namelen = strlen(name);
@@ -723,10 +721,16 @@ void TypeInfoStructDeclaration::toDt(dt_t **pdt)
// name[]
dtnbytes(pdt, namelen + 1, name);
*/
}
/* ========================================================================= */
void TypeInfoClassDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoClassDeclaration");
/*
//printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
dtdword(pdt, 0); // monitor
@@ -740,10 +744,16 @@ void TypeInfoClassDeclaration::toDt(dt_t **pdt)
tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
s = tc->sym->vclassinfo->toSymbol();
dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
*/
}
/* ========================================================================= */
void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoInterfaceDeclaration");
/*
//printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
dtdword(pdt, 0); // monitor
@@ -757,10 +767,16 @@ void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
tc->sym->vclassinfo = new ClassInfoDeclaration(tc->sym);
s = tc->sym->vclassinfo->toSymbol();
dtxoff(pdt, s, 0, TYnptr); // ClassInfo for tinfo
*/
}
/* ========================================================================= */
void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
{
assert(0 && "TypeInfoTupleDeclaration");
/*
//printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
dtdword(pdt, 0); // monitor
@@ -786,46 +802,5 @@ void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
outdata(s);
dtxoff(pdt, s, 0, TYnptr); // elements.ptr
*/
}
void TypeInfoDeclaration::toObjFile()
{
Symbol *s;
unsigned sz;
Dsymbol *parent;
//printf("TypeInfoDeclaration::toObjFile(%p '%s') protection %d\n", this, toChars(), protection);
s = toSymbol();
sz = type->size();
parent = this->toParent();
s->Sclass = SCcomdat;
s->Sfl = FLdata;
toDt(&s->Sdt);
dt_optimize(s->Sdt);
// See if we can convert a comdat to a comdef,
// which saves on exe file space.
if (s->Sclass == SCcomdat &&
s->Sdt->dt == DT_azeros &&
s->Sdt->DTnext == NULL)
{
s->Sclass = SCglobal;
s->Sdt->dt = DT_common;
}
#if ELFOBJ // Burton
if (s->Sdt && s->Sdt->dt == DT_azeros && s->Sdt->DTnext == NULL)
s->Sseg = UDATA;
else
s->Sseg = DATA;
#endif /* ELFOBJ */
outdata(s);
if (isExport())
obj_export(s,0);
}
#endif

View File

@@ -21,9 +21,14 @@ echo "compiling object implementation"
llvmdc internal/objectimpl.d -c -odobj || exit 1
llvm-link -f -o=../lib/llvmdcore.bc obj/objectimpl.bc ../lib/llvmdcore.bc || exit 1
echo "compiling typeinfos"
rebuild typeinfos.d -c -oqobj -dc=llvmdc-posix || exit 1
llvm-link -f -o=../lib/llvmdcore.bc `ls obj/typeinfo.*.bc` ../lib/llvmdcore.bc || exit 1
echo "compiling typeinfo 1"
rebuild typeinfos1.d -c -oqobj -dc=llvmdc-posix || exit 1
llvm-link -f -o=../lib/llvmdcore.bc `ls obj/typeinfo1.*.bc` ../lib/llvmdcore.bc || exit 1
echo "compiling typeinfo 2"
rebuild typeinfos2.d -c -oqobj -dc=llvmdc-posix || exit 1
llvm-link -f -o=../lib/llvmdcore.bc `ls obj/typeinfo2.*.bc` ../lib/llvmdcore.bc || exit 1
echo "compiling llvm runtime support"
rebuild llvmsupport.d -c -oqobj -dc=llvmdc-posix || exit
@@ -35,7 +40,7 @@ opt -f -std-compile-opts -o=../lib/llvmdcore.bc ../lib/llvmdcore.bc || exit 1
# build phobos
echo "compiling phobos"
rebuild phobos.d -c -oqobj -dc=llvmdc-posix || exit 1
llvm-link -f -o=../lib/lphobos.bc `ls phobos_obj/*.bc` || exit 1
llvm-link -f -o=../lib/lphobos.bc `ls obj/std.*.bc` || exit 1
opt -f -std-compile-opts -o=../lib/lphobos.bc ../lib/lphobos.bc || exit 1
echo "SUCCESS"

View File

@@ -466,8 +466,6 @@ class TypeInfo_Enum : TypeInfo_Typedef
{
}
/+
class TypeInfo_Pointer : TypeInfo
{
char[] toString() { return m_next.toString() ~ "*"; }
@@ -595,11 +593,57 @@ class TypeInfo_Array : TypeInfo
uint flags() { return 1; }
}
private const char[10] digits = "0123456789"; /// 0..9
private char[] lengthToString(uint u)
{ char[uint.sizeof * 3] buffer = void;
int ndigits;
char[] result;
ndigits = 0;
if (u < 10)
// Avoid storage allocation for simple stuff
result = digits[u .. u + 1];
else
{
while (u)
{
uint c = (u % 10) + '0';
u /= 10;
ndigits++;
buffer[buffer.length - ndigits] = cast(char)c;
}
result = new char[ndigits];
result[] = buffer[buffer.length - ndigits .. buffer.length];
}
return result;
}
private char[] lengthToString(ulong u)
{ char[ulong.sizeof * 3] buffer;
int ndigits;
char[] result;
if (u < 0x1_0000_0000)
return lengthToString(cast(uint)u);
ndigits = 0;
while (u)
{
char c = cast(char)((u % 10) + '0');
u /= 10;
ndigits++;
buffer[buffer.length - ndigits] = c;
}
result = new char[ndigits];
result[] = buffer[buffer.length - ndigits .. buffer.length];
return result;
}
class TypeInfo_StaticArray : TypeInfo
{
char[] toString()
{
return value.toString() ~ "[" ~ std.string.toString(len) ~ "]";
return value.toString() ~ "[" ~ lengthToString(len) ~ "]";
}
int opEquals(Object o)
@@ -658,8 +702,12 @@ class TypeInfo_StaticArray : TypeInfo
if (sz < buffer.sizeof)
tmp = buffer.ptr;
else
else {
if (value.flags() & 1)
tmp = pbuffer = (new void[sz]).ptr;
else
tmp = pbuffer = (new byte[sz]).ptr;
}
for (size_t u = 0; u < len; u += sz)
{ size_t o = u * sz;
@@ -761,6 +809,8 @@ class TypeInfo_Delegate : TypeInfo
TypeInfo next;
}
/+
class TypeInfo_Class : TypeInfo
{
char[] toString() { return info.name; }
@@ -1041,6 +1091,8 @@ class TypeInfo_Tuple : TypeInfo
}
}
+/
class TypeInfo_Const : TypeInfo
{
char[] toString() { return "const " ~ base.toString(); }
@@ -1064,8 +1116,6 @@ class TypeInfo_Invariant : TypeInfo_Const
char[] toString() { return "invariant " ~ base.toString(); }
}
+/
/**
* All recoverable exceptions should be derived from class Exception.
*/

View File

@@ -23,4 +23,3 @@ void writef(T...)(T t) {
void writefln(T...)(T t) {
writef(t, "\n");
}

View File

@@ -1,7 +1,7 @@
// byte
module typeinfo.ti_byte;
module typeinfo1.ti_byte;
class TypeInfo_g : TypeInfo
{

View File

@@ -1,5 +1,5 @@
module typeinfo.ti_char;
module typeinfo1.ti_char;
class TypeInfo_a : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// dchar
module typeinfo.ti_dchar;
module typeinfo1.ti_dchar;
class TypeInfo_w : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// delegate
module typeinfo.ti_delegate;
module typeinfo1.ti_delegate;
alias void delegate(int) dg;

View File

@@ -1,7 +1,7 @@
// double
module typeinfo.ti_double;
module typeinfo1.ti_double;
class TypeInfo_d : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// float
module typeinfo.ti_float;
module typeinfo1.ti_float;
class TypeInfo_f : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// int
module typeinfo.ti_int;
module typeinfo1.ti_int;
class TypeInfo_i : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// long
module typeinfo.ti_long;
module typeinfo1.ti_long;
class TypeInfo_l : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// pointer
module typeinfo.ti_ptr;
module typeinfo1.ti_ptr;
class TypeInfo_P : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// real
module typeinfo.ti_real;
module typeinfo1.ti_real;
class TypeInfo_e : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// short
module typeinfo.ti_short;
module typeinfo1.ti_short;
class TypeInfo_s : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// ubyte
module typeinfo.ti_ubyte;
module typeinfo1.ti_ubyte;
class TypeInfo_h : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// uint
module typeinfo.ti_uint;
module typeinfo1.ti_uint;
class TypeInfo_k : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// ulong
module typeinfo.ti_ulong;
module typeinfo1.ti_ulong;
class TypeInfo_m : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// ushort
module typeinfo.ti_ushort;
module typeinfo1.ti_ushort;
class TypeInfo_t : TypeInfo
{

View File

@@ -1,7 +1,7 @@
// void
module typeinfo.ti_void;
module typeinfo1.ti_void;
class TypeInfo_v : TypeInfo
{

View File

@@ -1,5 +1,5 @@
module typeinfo.ti_wchar;
module typeinfo1.ti_wchar;
class TypeInfo_u : TypeInfo

View File

@@ -1,20 +0,0 @@
module typeinfos;
import
typeinfo.ti_byte,
typeinfo.ti_char,
typeinfo.ti_delegate,
typeinfo.ti_dchar,
typeinfo.ti_double,
typeinfo.ti_float,
typeinfo.ti_int,
typeinfo.ti_long,
typeinfo.ti_ptr,
typeinfo.ti_real,
typeinfo.ti_short,
typeinfo.ti_ubyte,
typeinfo.ti_uint,
typeinfo.ti_ulong,
typeinfo.ti_ushort,
typeinfo.ti_void,
typeinfo.ti_wchar;

20
lphobos/typeinfos1.d Normal file
View File

@@ -0,0 +1,20 @@
module typeinfos1;
import
typeinfo1.ti_byte,
typeinfo1.ti_char,
typeinfo1.ti_delegate,
typeinfo1.ti_dchar,
typeinfo1.ti_double,
typeinfo1.ti_float,
typeinfo1.ti_int,
typeinfo1.ti_long,
typeinfo1.ti_ptr,
typeinfo1.ti_real,
typeinfo1.ti_short,
typeinfo1.ti_ubyte,
typeinfo1.ti_uint,
typeinfo1.ti_ulong,
typeinfo1.ti_ushort,
typeinfo1.ti_void,
typeinfo1.ti_wchar;

7
lphobos/typeinfos2.d Normal file
View File

@@ -0,0 +1,7 @@
module typeinfos2;
import
typeinfo2.ti_Ag,
typeinfo2.ti_Aint,
typeinfo2.ti_Along,
typeinfo2.ti_Ashort;

17
test/arrays8.d Normal file
View File

@@ -0,0 +1,17 @@
module arrays8;
void main()
{
char[] a = "hello ";
printf(" \"%s\".length = %u\n", a.ptr, a.length);
char[] b = "world";
printf(" \"%s\".length = %u\n", b.ptr, b.length);
char[] c = a ~ b;
printf("After 'a ~ b':\n");
printf(" \"%.*s\".length = %u\n", a.length, a.ptr, a.length);
printf(" \"%.*s\".length = %u\n", b.length, b.ptr, b.length);
printf(" \"%.*s\".length = %u\n", c.length, c.ptr, c.length);
assert(c.length == a.length + b.length);
assert(c !is a);
assert(c !is b);
}

55
test/bug34.d Normal file
View File

@@ -0,0 +1,55 @@
module bug34;
class MyTypeInfo_Pointer
{
char[] toString() { return m_next.toString() ~ "*"; }
int opEquals(Object o)
{ TypeInfo_Pointer c;
return this is o ||
((c = cast(TypeInfo_Pointer)o) !is null &&
this.m_next == c.m_next);
}
hash_t getHash(void *p)
{
return cast(uint)*cast(void* *)p;
}
int equals(void *p1, void *p2)
{
return cast(int)(*cast(void* *)p1 == *cast(void* *)p2);
}
int compare(void *p1, void *p2)
{
if (*cast(void* *)p1 < *cast(void* *)p2)
return -1;
else if (*cast(void* *)p1 > *cast(void* *)p2)
return 1;
else
return 0;
}
size_t tsize()
{
return (void*).sizeof;
}
void swap(void *p1, void *p2)
{ void* tmp;
tmp = *cast(void**)p1;
*cast(void**)p1 = *cast(void**)p2;
*cast(void**)p2 = tmp;
}
TypeInfo next() { return m_next; }
uint flags() { return 1; }
TypeInfo m_next;
}
void main()
{
}

7
test/bug35.d Normal file
View File

@@ -0,0 +1,7 @@
module bug35;
private const char[10] digits = "0123456789"; /// 0..9
void main()
{
}

8
test/bug36.d Normal file
View File

@@ -0,0 +1,8 @@
module bug36;
void main()
{
int[] a;
void* cp = cast(void*)a;
}

11
test/typeinfo4.d Normal file
View File

@@ -0,0 +1,11 @@
module typeinfo4;
void main()
{
auto ti = typeid(void*);
assert(ti.toString() == "void*");
assert(ti.tsize() == size_t.sizeof);
void* a = null;
void* b = a + 1;
assert(ti.compare(&a,&b) < 0);
}

10
test/typeinfo5.d Normal file
View File

@@ -0,0 +1,10 @@
module typeinfo5;
void main()
{
enum E : uint {
A,B,C
}
auto ti = typeid(E);
assert(ti.next() is typeid(uint));
}

8
test/typeinfo6.d Normal file
View File

@@ -0,0 +1,8 @@
module typeinfo6;
void main()
{
auto ti = typeid(int[]);
assert(ti.toString() == "int[]");
assert(ti.next() is typeid(int));
}

14
test/typeinfo7.d Normal file
View File

@@ -0,0 +1,14 @@
module typeinfo7;
int func(long)
{
return 0;
}
void main()
{
auto ti = typeid(typeof(func));
auto s = ti.toString;
printf("%.*s\n", s.length, s.ptr);
assert(s == "int()");
}

17
test/typeinfo8.d Normal file
View File

@@ -0,0 +1,17 @@
module typeinfo8;
struct S
{
void func()
{
}
}
void main()
{
S a;
auto ti = typeid(typeof(&a.func));
auto s = ti.toString;
printf("%.*s\n", s.length, s.ptr);
assert(s == "void delegate()");
}