mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
[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:
51
gen/arrays.c
51
gen/arrays.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
71
gen/toir.c
71
gen/toir.c
@@ -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");
|
||||
|
||||
30
gen/tollvm.c
30
gen/tollvm.c
@@ -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());
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
|
||||
12
gen/toobj.c
12
gen/toobj.c
@@ -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';
|
||||
|
||||
339
gen/typinf.c
339
gen/typinf.c
@@ -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
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -23,4 +23,3 @@ void writef(T...)(T t) {
|
||||
void writefln(T...)(T t) {
|
||||
writef(t, "\n");
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// byte
|
||||
|
||||
module typeinfo.ti_byte;
|
||||
module typeinfo1.ti_byte;
|
||||
|
||||
class TypeInfo_g : TypeInfo
|
||||
{
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
module typeinfo.ti_char;
|
||||
module typeinfo1.ti_char;
|
||||
|
||||
class TypeInfo_a : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// dchar
|
||||
|
||||
module typeinfo.ti_dchar;
|
||||
module typeinfo1.ti_dchar;
|
||||
|
||||
class TypeInfo_w : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// delegate
|
||||
|
||||
module typeinfo.ti_delegate;
|
||||
module typeinfo1.ti_delegate;
|
||||
|
||||
alias void delegate(int) dg;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// double
|
||||
|
||||
module typeinfo.ti_double;
|
||||
module typeinfo1.ti_double;
|
||||
|
||||
class TypeInfo_d : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// float
|
||||
|
||||
module typeinfo.ti_float;
|
||||
module typeinfo1.ti_float;
|
||||
|
||||
class TypeInfo_f : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// int
|
||||
|
||||
module typeinfo.ti_int;
|
||||
module typeinfo1.ti_int;
|
||||
|
||||
class TypeInfo_i : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// long
|
||||
|
||||
module typeinfo.ti_long;
|
||||
module typeinfo1.ti_long;
|
||||
|
||||
class TypeInfo_l : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// pointer
|
||||
|
||||
module typeinfo.ti_ptr;
|
||||
module typeinfo1.ti_ptr;
|
||||
|
||||
class TypeInfo_P : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// real
|
||||
|
||||
module typeinfo.ti_real;
|
||||
module typeinfo1.ti_real;
|
||||
|
||||
class TypeInfo_e : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// short
|
||||
|
||||
module typeinfo.ti_short;
|
||||
module typeinfo1.ti_short;
|
||||
|
||||
class TypeInfo_s : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// ubyte
|
||||
|
||||
module typeinfo.ti_ubyte;
|
||||
module typeinfo1.ti_ubyte;
|
||||
|
||||
class TypeInfo_h : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// uint
|
||||
|
||||
module typeinfo.ti_uint;
|
||||
module typeinfo1.ti_uint;
|
||||
|
||||
class TypeInfo_k : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// ulong
|
||||
|
||||
module typeinfo.ti_ulong;
|
||||
module typeinfo1.ti_ulong;
|
||||
|
||||
class TypeInfo_m : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// ushort
|
||||
|
||||
module typeinfo.ti_ushort;
|
||||
module typeinfo1.ti_ushort;
|
||||
|
||||
class TypeInfo_t : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// void
|
||||
|
||||
module typeinfo.ti_void;
|
||||
module typeinfo1.ti_void;
|
||||
|
||||
class TypeInfo_v : TypeInfo
|
||||
{
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
module typeinfo.ti_wchar;
|
||||
module typeinfo1.ti_wchar;
|
||||
|
||||
|
||||
class TypeInfo_u : TypeInfo
|
||||
@@ -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
20
lphobos/typeinfos1.d
Normal 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
7
lphobos/typeinfos2.d
Normal 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
17
test/arrays8.d
Normal 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
55
test/bug34.d
Normal 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
7
test/bug35.d
Normal file
@@ -0,0 +1,7 @@
|
||||
module bug35;
|
||||
|
||||
private const char[10] digits = "0123456789"; /// 0..9
|
||||
|
||||
void main()
|
||||
{
|
||||
}
|
||||
8
test/bug36.d
Normal file
8
test/bug36.d
Normal file
@@ -0,0 +1,8 @@
|
||||
module bug36;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[] a;
|
||||
void* cp = cast(void*)a;
|
||||
|
||||
}
|
||||
11
test/typeinfo4.d
Normal file
11
test/typeinfo4.d
Normal 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
10
test/typeinfo5.d
Normal 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
8
test/typeinfo6.d
Normal 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
14
test/typeinfo7.d
Normal 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
17
test/typeinfo8.d
Normal 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()");
|
||||
}
|
||||
Reference in New Issue
Block a user