mirror of
https://github.com/xomboverlord/ldc.git
synced 2026-01-11 18:33:14 +01:00
[svn r56] Initial support for TypeInfo.
Enums not work. Several other bugfixes.
This commit is contained in:
19
dmd/mars.c
19
dmd/mars.c
@@ -38,8 +38,8 @@ long __cdecl __ehfilter(LPEXCEPTION_POINTERS ep);
|
||||
#include "id.h"
|
||||
#include "cond.h"
|
||||
#include "expression.h"
|
||||
#include "lexer.h"
|
||||
|
||||
#include "lexer.h"
|
||||
|
||||
#include "gen/logger.h"
|
||||
|
||||
void getenv_setargv(const char *envvar, int *pargc, char** *pargv);
|
||||
@@ -177,6 +177,7 @@ Usage:\n\
|
||||
-debug=ident compile in debug code identified by ident\n\
|
||||
-debuglib=name set symbolic debug library to name\n\
|
||||
-defaultlib=name set default library to name\n\
|
||||
-dis disassemble module after compiling\n\
|
||||
-g add symbolic debug info\n\
|
||||
-gc add symbolic debug info, pretend to be C\n\
|
||||
-H generate 'header' file\n\
|
||||
@@ -204,7 +205,7 @@ Usage:\n\
|
||||
-release compile release version\n\
|
||||
-run srcfile args... run resulting program, passing args\n\
|
||||
-unittest compile in unit tests\n\
|
||||
-v verbose\n\
|
||||
-v verbose\n\
|
||||
-vv very verbose (does not include -v)\n\
|
||||
-v1 D language version 1\n\
|
||||
-version=level compile in version code >= level\n\
|
||||
@@ -229,7 +230,7 @@ int main(int argc, char *argv[])
|
||||
int argcstart = argc;
|
||||
char* tt_arch = 0;
|
||||
char* tt_os = 0;
|
||||
char* data_layout = 0;
|
||||
char* data_layout = 0;
|
||||
bool very_verbose = false;
|
||||
|
||||
// Check for malformed input
|
||||
@@ -355,10 +356,10 @@ int main(int argc, char *argv[])
|
||||
else if (strcmp(p + 1, "profile") == 0)
|
||||
global.params.trace = 1;
|
||||
else if (strcmp(p + 1, "v") == 0)
|
||||
global.params.verbose = 1;
|
||||
global.params.verbose = 1;
|
||||
else if (strcmp(p + 1, "vv") == 0) {
|
||||
Logger::enable();
|
||||
very_verbose = true;
|
||||
Logger::enable();
|
||||
very_verbose = true;
|
||||
}
|
||||
else if (strcmp(p + 1, "v1") == 0)
|
||||
global.params.Dversion = 1;
|
||||
@@ -384,6 +385,8 @@ int main(int argc, char *argv[])
|
||||
global.params.noruntime = 1;
|
||||
else if (strcmp(p + 1, "noverify") == 0)
|
||||
global.params.novalidate = 1;
|
||||
else if (strcmp(p + 1, "dis") == 0)
|
||||
global.params.disassemble = 1;
|
||||
else if (p[1] == 'o')
|
||||
{
|
||||
switch (p[2])
|
||||
@@ -661,7 +664,7 @@ int main(int argc, char *argv[])
|
||||
fatal();
|
||||
}
|
||||
else {
|
||||
global.params.llvmArch = const_cast<char*>(e->Name);
|
||||
global.params.llvmArch = const_cast<char*>(e->Name);
|
||||
if (global.params.verbose || very_verbose)
|
||||
printf("Default target found: %s\n", global.params.llvmArch);
|
||||
}
|
||||
|
||||
@@ -128,6 +128,7 @@ struct Param
|
||||
char *tt_arch;
|
||||
char *tt_os;
|
||||
char *data_layout;
|
||||
char disassemble;
|
||||
};
|
||||
|
||||
struct Global
|
||||
|
||||
@@ -157,6 +157,7 @@ Module::Module(char *filename, Identifier *ident, int doDocComment, int doHdrGen
|
||||
|
||||
objfile = new File(objfilename);
|
||||
bcfile = new File(bcfilename);
|
||||
llfile = new File(llfilename);
|
||||
symfile = new File(symfilename);
|
||||
}
|
||||
|
||||
|
||||
@@ -61,6 +61,7 @@ struct Module : Package
|
||||
File *srcfile; // input source file
|
||||
File *objfile; // output .obj file
|
||||
File *bcfile; // output .bc file
|
||||
File *llfile; // output .ll file
|
||||
File *hdrfile; // 'header' file
|
||||
File *symfile; // output symbol file
|
||||
File *docfile; // output documentation file
|
||||
|
||||
71
gen/arrays.c
71
gen/arrays.c
@@ -480,3 +480,74 @@ llvm::Value* LLVM_DtoStaticArrayCompare(TOK op, llvm::Value* l, llvm::Value* r)
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Value* LLVM_DtoDynArrayCompare(TOK op, llvm::Value* l, llvm::Value* r)
|
||||
{
|
||||
const char* fname;
|
||||
if (op == TOKequal)
|
||||
fname = "_d_dyn_array_eq";
|
||||
else if (op == TOKnotequal)
|
||||
fname = "_d_dyn_array_neq";
|
||||
else
|
||||
assert(0);
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, fname);
|
||||
assert(fn);
|
||||
|
||||
Logger::cout() << "lhsType:" << *l->getType() << "\nrhsType:" << *r->getType() << '\n';
|
||||
assert(l->getType() == r->getType());
|
||||
assert(llvm::isa<llvm::PointerType>(l->getType()));
|
||||
const llvm::Type* arrty = l->getType()->getContainedType(0);
|
||||
assert(llvm::isa<llvm::StructType>(arrty));
|
||||
const llvm::StructType* structType = llvm::cast<llvm::StructType>(arrty);
|
||||
const llvm::Type* elemType = structType->getElementType(1)->getContainedType(0);
|
||||
|
||||
std::vector<const llvm::Type*> arrTypes;
|
||||
arrTypes.push_back(LLVM_DtoSize_t());
|
||||
arrTypes.push_back(llvm::PointerType::get(llvm::Type::Int8Ty));
|
||||
const llvm::StructType* arrType = llvm::StructType::get(arrTypes);
|
||||
|
||||
llvm::Value* llmem = l;
|
||||
llvm::Value* rrmem = r;
|
||||
|
||||
if (arrty != arrType) {
|
||||
llmem= new llvm::AllocaInst(arrType,"tmparr",gIR->topallocapoint());
|
||||
|
||||
llvm::Value* ll = gIR->ir->CreateLoad(LLVM_DtoGEPi(l, 0,0, "tmp"),"tmp");
|
||||
ll = LLVM_DtoArrayCastLength(ll, elemType, llvm::Type::Int8Ty);
|
||||
llvm::Value* lllen = LLVM_DtoGEPi(llmem, 0,0, "tmp");
|
||||
gIR->ir->CreateStore(ll,lllen);
|
||||
|
||||
ll = gIR->ir->CreateLoad(LLVM_DtoGEPi(l, 0,1, "tmp"),"tmp");
|
||||
ll = new llvm::BitCastInst(ll, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp", gIR->scopebb());
|
||||
llvm::Value* llptr = LLVM_DtoGEPi(llmem, 0,1, "tmp");
|
||||
gIR->ir->CreateStore(ll,llptr);
|
||||
|
||||
rrmem = new llvm::AllocaInst(arrType,"tmparr",gIR->topallocapoint());
|
||||
|
||||
llvm::Value* rr = gIR->ir->CreateLoad(LLVM_DtoGEPi(r, 0,0, "tmp"),"tmp");
|
||||
rr = LLVM_DtoArrayCastLength(rr, elemType, llvm::Type::Int8Ty);
|
||||
llvm::Value* rrlen = LLVM_DtoGEPi(rrmem, 0,0, "tmp");
|
||||
gIR->ir->CreateStore(rr,rrlen);
|
||||
|
||||
rr = gIR->ir->CreateLoad(LLVM_DtoGEPi(r, 0,1, "tmp"),"tmp");
|
||||
rr = new llvm::BitCastInst(rr, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp", gIR->scopebb());
|
||||
llvm::Value* rrptr = LLVM_DtoGEPi(rrmem, 0,1, "tmp");
|
||||
gIR->ir->CreateStore(rr,rrptr);
|
||||
}
|
||||
|
||||
std::vector<llvm::Value*> args;
|
||||
args.push_back(llmem);
|
||||
args.push_back(rrmem);
|
||||
return new llvm::CallInst(fn, args.begin(), args.end(), "tmp", gIR->scopebb());
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////
|
||||
llvm::Value* LLVM_DtoArrayCastLength(llvm::Value* len, const llvm::Type* elemty, const llvm::Type* newelemty)
|
||||
{
|
||||
llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_array_cast_len");
|
||||
assert(fn);
|
||||
std::vector<llvm::Value*> args;
|
||||
args.push_back(len);
|
||||
args.push_back(llvm::ConstantInt::get(LLVM_DtoSize_t(), gTargetData->getTypeSize(elemty), false));
|
||||
args.push_back(llvm::ConstantInt::get(LLVM_DtoSize_t(), gTargetData->getTypeSize(newelemty), false));
|
||||
return new llvm::CallInst(fn, args.begin(), args.end(), "tmp", gIR->scopebb());
|
||||
}
|
||||
|
||||
@@ -20,6 +20,10 @@ void LLVM_DtoResizeDynArray(llvm::Value* arr, llvm::Value* sz);
|
||||
void LLVM_DtoCatArrayElement(llvm::Value* arr, Expression* exp);
|
||||
|
||||
void LLVM_DtoStaticArrayCopy(llvm::Value* dst, llvm::Value* src);
|
||||
|
||||
llvm::Value* LLVM_DtoStaticArrayCompare(TOK op, llvm::Value* l, llvm::Value* r);
|
||||
llvm::Value* LLVM_DtoDynArrayCompare(TOK op, llvm::Value* l, llvm::Value* r);
|
||||
|
||||
llvm::Value* LLVM_DtoArrayCastLength(llvm::Value* len, const llvm::Type* elemty, const llvm::Type* newelemty);
|
||||
|
||||
#endif // LLVMC_GEN_ARRAYS_H
|
||||
|
||||
@@ -19,6 +19,7 @@ elem::elem()
|
||||
field = false;
|
||||
callconv = (unsigned)-1;
|
||||
isthis = false;
|
||||
istypeinfo = false;
|
||||
|
||||
vardecl = 0;
|
||||
funcdecl = 0;
|
||||
|
||||
@@ -32,6 +32,7 @@ public:
|
||||
bool field;
|
||||
unsigned callconv;
|
||||
bool isthis;
|
||||
bool istypeinfo;
|
||||
|
||||
VarDeclaration* vardecl;
|
||||
FuncDeclaration* funcdecl;
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include <cassert>
|
||||
|
||||
#include "gen/llvm.h"
|
||||
#include "llvm/Module.h"
|
||||
#include "llvm/Bitcode/ReaderWriter.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
@@ -13,6 +14,8 @@
|
||||
static llvm::Module* M = NULL;
|
||||
static bool runtime_failed = false;
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool LLVM_D_InitRuntime()
|
||||
{
|
||||
Logger::println("*** Loading D runtime ***");
|
||||
@@ -41,7 +44,7 @@ bool LLVM_D_InitRuntime()
|
||||
Logger::println("Failed to load runtime: %s", errstr.c_str());
|
||||
runtime_failed = true;
|
||||
}
|
||||
|
||||
|
||||
delete buffer;
|
||||
return retval;
|
||||
}
|
||||
@@ -54,6 +57,8 @@ void LLVM_D_FreeRuntime()
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name)
|
||||
{
|
||||
// TODO maybe check the target module first, to allow overriding the runtime on a pre module basis?
|
||||
@@ -63,20 +68,47 @@ llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name
|
||||
error("No implicit runtime calls allowed with -noruntime option enabled");
|
||||
fatal();
|
||||
}
|
||||
|
||||
|
||||
if (!M) {
|
||||
assert(!runtime_failed);
|
||||
LLVM_D_InitRuntime();
|
||||
}
|
||||
|
||||
|
||||
llvm::Function* fn = M->getFunction(name);
|
||||
if (!fn) {
|
||||
error("Runtime function '%s' was not found", name);
|
||||
fatal();
|
||||
//return NULL;
|
||||
}
|
||||
|
||||
|
||||
const llvm::FunctionType* fnty = fn->getFunctionType();
|
||||
return llvm::cast<llvm::Function>(target->getOrInsertFunction(name, fnty));
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char* name)
|
||||
{
|
||||
// TODO maybe check the target module first, to allow overriding the runtime on a pre module basis?
|
||||
// could be done and seems like it could be neat too :)
|
||||
|
||||
if (global.params.noruntime) {
|
||||
error("No implicit runtime calls allowed with -noruntime option enabled");
|
||||
fatal();
|
||||
}
|
||||
|
||||
if (!M) {
|
||||
assert(!runtime_failed);
|
||||
LLVM_D_InitRuntime();
|
||||
}
|
||||
|
||||
llvm::GlobalVariable* g = M->getNamedGlobal(name);
|
||||
if (!g) {
|
||||
error("Runtime global '%s' was not found", name);
|
||||
fatal();
|
||||
//return NULL;
|
||||
}
|
||||
|
||||
const llvm::PointerType* t = g->getType();
|
||||
return new llvm::GlobalVariable(t->getElementType(),g->isConstant(),g->getLinkage(),NULL,g->getName(),target);
|
||||
}
|
||||
|
||||
@@ -4,3 +4,5 @@ bool LLVM_D_InitRuntime();
|
||||
void LLVM_D_FreeRuntime();
|
||||
|
||||
llvm::Function* LLVM_D_GetRuntimeFunction(llvm::Module* target, const char* name);
|
||||
|
||||
llvm::GlobalVariable* LLVM_D_GetRuntimeGlobal(llvm::Module* target, const char* name);
|
||||
|
||||
30
gen/todt.c
30
gen/todt.c
@@ -116,36 +116,6 @@ void StructDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
void TypeInfoFunctionDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
void TypeInfoDelegateDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
void TypeInfoInterfaceDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
void TypeInfoTupleDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
dt_t **Type::toDt(dt_t **pdt)
|
||||
{
|
||||
return 0;
|
||||
|
||||
86
gen/toir.c
86
gen/toir.c
@@ -83,12 +83,17 @@ elem* DeclarationExp::toElem(IRState* p)
|
||||
else if (AliasDeclaration* a = declaration->isAliasDeclaration())
|
||||
{
|
||||
Logger::println("AliasDeclaration");
|
||||
assert(0);
|
||||
}
|
||||
else if (EnumDeclaration* e = declaration->isEnumDeclaration())
|
||||
{
|
||||
// do nothing
|
||||
}
|
||||
// unsupported declaration
|
||||
else
|
||||
{
|
||||
error("Only Var/Struct-Declaration is supported for DeclarationExp");
|
||||
fatal();
|
||||
assert(0);
|
||||
}
|
||||
return e;
|
||||
}
|
||||
@@ -138,9 +143,7 @@ elem* VarExp::toElem(IRState* p)
|
||||
// typeinfo
|
||||
else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
|
||||
{
|
||||
tid->toObjFile();
|
||||
e->mem = tid->llvmValue;
|
||||
e->type = elem::VAR;
|
||||
assert(0);
|
||||
}
|
||||
// global forward ref
|
||||
else {
|
||||
@@ -181,28 +184,24 @@ elem* VarExp::toElem(IRState* p)
|
||||
else {
|
||||
// nested variable
|
||||
if (vd->nestedref) {
|
||||
/*
|
||||
FuncDeclaration* fd = vd->toParent()->isFuncDeclaration();
|
||||
assert(fd != NULL);
|
||||
llvm::Value* ptr = NULL;
|
||||
// inside nested function
|
||||
if (fd != p->func().decl) {
|
||||
ptr = p->func().decl->llvmThisVar;
|
||||
Logger::cout() << "nested var reference:" << '\n' << *ptr << *vd->llvmValue->getType() << '\n';
|
||||
ptr = p->ir->CreateBitCast(ptr, vd->llvmValue->getType(), "tmp");
|
||||
}
|
||||
// inside the actual parent function
|
||||
else {
|
||||
ptr = vd->llvmValue;
|
||||
}
|
||||
assert(ptr);
|
||||
e->mem = LLVM_DtoGEPi(ptr,0,unsigned(vd->llvmNestedIndex),"tmp",p->scopebb());
|
||||
*/
|
||||
e->mem = LLVM_DtoNestedVariable(vd);
|
||||
}
|
||||
// normal local variable
|
||||
else {
|
||||
e->mem = vd->llvmValue;
|
||||
if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) {
|
||||
Logger::println("typeinfo varexp");
|
||||
const llvm::Type* vartype = LLVM_DtoType(type);
|
||||
if (tid->llvmValue->getType() != llvm::PointerType::get(vartype)) {
|
||||
e->mem = p->ir->CreateBitCast(tid->llvmValue, vartype, "tmp");
|
||||
}
|
||||
else {
|
||||
e->mem = tid->llvmValue;
|
||||
}
|
||||
Logger::cout() << "got:" << '\n' << *tid->llvmValue << "returned:" << '\n' << *e->mem << '\n';
|
||||
}
|
||||
else {
|
||||
e->mem = vd->llvmValue;
|
||||
}
|
||||
}
|
||||
e->vardecl = vd;
|
||||
e->type = elem::VAR;
|
||||
@@ -350,7 +349,7 @@ llvm::Constant* NullExp::toConstElem(IRState* p)
|
||||
|
||||
elem* StringExp::toElem(IRState* p)
|
||||
{
|
||||
Logger::print("StringExp::toElem: %s | \n", toChars(), type->toChars());
|
||||
Logger::print("StringExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
Type* dtype = LLVM_DtoDType(type);
|
||||
@@ -379,10 +378,9 @@ elem* StringExp::toElem(IRState* p)
|
||||
if (dtype->ty == Tarray) {
|
||||
llvm::Constant* clen = llvm::ConstantInt::get(LLVM_DtoSize_t(),len,false);
|
||||
if (p->lvals.empty() || !p->toplval()) {
|
||||
e->type = elem::SLICE;
|
||||
e->arg = clen;
|
||||
e->mem = arrptr;
|
||||
return e;
|
||||
llvm::Value* tmpmem = new llvm::AllocaInst(LLVM_DtoType(dtype),"tmp",p->topallocapoint());
|
||||
LLVM_DtoSetArray(tmpmem, clen, arrptr);
|
||||
e->mem = tmpmem;
|
||||
}
|
||||
else if (llvm::Value* arr = p->toplval()) {
|
||||
if (llvm::isa<llvm::GlobalVariable>(arr)) {
|
||||
@@ -1247,15 +1245,21 @@ elem* CastExp::toElem(IRState* p)
|
||||
}
|
||||
else if (totype->ty == Tarray) {
|
||||
Logger::cout() << "to array" << '\n';
|
||||
assert(fromtype->next->size() == totype->next->size());
|
||||
const llvm::Type* ptrty = LLVM_DtoType(totype->next);
|
||||
if (ptrty == llvm::Type::VoidTy)
|
||||
ptrty = llvm::Type::Int8Ty;
|
||||
ptrty = llvm::PointerType::get(ptrty);
|
||||
|
||||
const llvm::Type* ety = LLVM_DtoType(fromtype->next);
|
||||
if (ety == llvm::Type::VoidTy)
|
||||
ety = llvm::Type::Int8Ty;
|
||||
|
||||
if (u->type == elem::SLICE) {
|
||||
e->mem = new llvm::BitCastInst(u->mem, ptrty, "tmp", p->scopebb());
|
||||
e->arg = u->arg;
|
||||
if (fromtype->next->size() == totype->next->size())
|
||||
e->arg = u->arg;
|
||||
else
|
||||
e->arg = LLVM_DtoArrayCastLength(u->arg, ety, ptrty->getContainedType(0));
|
||||
}
|
||||
else {
|
||||
llvm::Value* uval = u->getValue();
|
||||
@@ -1264,6 +1268,7 @@ elem* CastExp::toElem(IRState* p)
|
||||
assert(llvm::isa<llvm::PointerType>(uval->getType()));
|
||||
const llvm::ArrayType* arrty = llvm::cast<llvm::ArrayType>(uval->getType()->getContainedType(0));
|
||||
e->arg = llvm::ConstantInt::get(LLVM_DtoSize_t(), arrty->getNumElements(), false);
|
||||
e->arg = LLVM_DtoArrayCastLength(e->arg, ety, ptrty->getContainedType(0));
|
||||
e->mem = new llvm::BitCastInst(uval, ptrty, "tmp", p->scopebb());
|
||||
}
|
||||
else {
|
||||
@@ -1271,6 +1276,7 @@ elem* CastExp::toElem(IRState* p)
|
||||
llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false);
|
||||
e->arg = LLVM_DtoGEP(uval,zero,zero,"tmp",p->scopebb());
|
||||
e->arg = new llvm::LoadInst(e->arg, "tmp", p->scopebb());
|
||||
e->arg = LLVM_DtoArrayCastLength(e->arg, ety, ptrty->getContainedType(0));
|
||||
|
||||
e->mem = LLVM_DtoGEP(uval,zero,one,"tmp",p->scopebb());
|
||||
e->mem = new llvm::LoadInst(e->mem, "tmp", p->scopebb());
|
||||
@@ -1318,6 +1324,13 @@ elem* SymOffExp::toElem(IRState* p)
|
||||
if (VarDeclaration* vd = var->isVarDeclaration())
|
||||
{
|
||||
Logger::println("VarDeclaration");
|
||||
if (!vd->llvmTouched && vd->isDataseg())
|
||||
vd->toObjFile();
|
||||
|
||||
if (vd->isTypedefDeclaration()) {
|
||||
e->istypeinfo = true;
|
||||
}
|
||||
|
||||
assert(vd->llvmValue);
|
||||
Type* t = LLVM_DtoDType(type);
|
||||
Type* vdtype = LLVM_DtoDType(vd->type);
|
||||
@@ -1634,6 +1647,9 @@ elem* SliceExp::toElem(IRState* p)
|
||||
Logger::print("SliceExp::toElem: %s | %s\n", toChars(), type->toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
Type* t = LLVM_DtoDType(type);
|
||||
assert(t->ty == Tarray);
|
||||
|
||||
elem* v = e1->toElem(p);
|
||||
Type* e1type = LLVM_DtoDType(e1->type);
|
||||
|
||||
@@ -1722,6 +1738,16 @@ elem* SliceExp::toElem(IRState* p)
|
||||
|
||||
delete lo;
|
||||
delete up;
|
||||
|
||||
/*
|
||||
llvm::Value* tmpmem = new llvm::AllocaInst(LLVM_DtoType(t),"tmp",p->topallocapoint());
|
||||
llvm::Value* ptr = LLVM_DtoGEPi(tmpmem,0,0,"tmp");
|
||||
p->ir->CreateStore(e->arg, ptr);
|
||||
ptr = LLVM_DtoGEPi(tmpmem,0,1,"tmp");
|
||||
p->ir->CreateStore(e->mem, ptr);
|
||||
e->arg = NULL;
|
||||
e->mem = tmpmem;
|
||||
*/
|
||||
}
|
||||
// full slice
|
||||
else
|
||||
@@ -1897,7 +1923,7 @@ elem* EqualExp::toElem(IRState* p)
|
||||
}
|
||||
else if (t->ty == Tarray)
|
||||
{
|
||||
assert(0 && "array comparison invokes the typeinfo runtime");
|
||||
e->val = LLVM_DtoDynArrayCompare(op,l->mem,r->mem);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -161,7 +161,9 @@ const llvm::Type* LLVM_DtoType(Type* t)
|
||||
}
|
||||
|
||||
// typedefs
|
||||
// enum
|
||||
case Ttypedef:
|
||||
case Tenum:
|
||||
{
|
||||
Type* bt = t->toBasetype();
|
||||
assert(bt);
|
||||
|
||||
131
gen/toobj.c
131
gen/toobj.c
@@ -98,19 +98,19 @@ Module::genobjfile()
|
||||
// run passes
|
||||
// TODO
|
||||
|
||||
/*if (global.params.llvmLL) {
|
||||
//assert(0);
|
||||
std::ofstream os(llfile->name->toChars());
|
||||
//llvm::WriteAssemblyToFile(ir.module, os);
|
||||
ir.module->print(os);
|
||||
}*/
|
||||
|
||||
// write bytecode
|
||||
//if (global.params.llvmBC) {
|
||||
{
|
||||
Logger::println("Writing LLVM bitcode\n");
|
||||
std::ofstream os(bcfile->name->toChars(), std::ios::binary);
|
||||
llvm::WriteBitcodeToFile(ir.module, os);
|
||||
//}
|
||||
std::ofstream bos(bcfile->name->toChars(), std::ios::binary);
|
||||
llvm::WriteBitcodeToFile(ir.module, bos);
|
||||
}
|
||||
|
||||
// disassemble ?
|
||||
if (global.params.disassemble) {
|
||||
Logger::println("Writing LLVM asm to: %s\n", llfile->name->toChars());
|
||||
std::ofstream aos(llfile->name->toChars());
|
||||
ir.module->print(aos);
|
||||
}
|
||||
|
||||
delete ir.module;
|
||||
gIR = NULL;
|
||||
@@ -295,7 +295,7 @@ void StructDeclaration::toObjFile()
|
||||
gIR->structs.pop_back();
|
||||
|
||||
// generate typeinfo
|
||||
type->getTypeInfo(NULL); // generate TypeInfo
|
||||
//type->getTypeInfo(NULL);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
@@ -407,8 +407,10 @@ void ClassDeclaration::toObjFile()
|
||||
{
|
||||
llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::ExternalLinkage;
|
||||
|
||||
std::string varname(mangle());
|
||||
varname.append("__vtblZ");
|
||||
std::string varname("_D");
|
||||
varname.append(mangle());
|
||||
varname.append("6__vtblZ");
|
||||
|
||||
std::string styname(mangle());
|
||||
styname.append("__vtblTy");
|
||||
|
||||
@@ -441,8 +443,10 @@ void ClassDeclaration::toObjFile()
|
||||
|
||||
_init = llvm::ConstantStruct::get(structtype,gIR->topstruct().inits);
|
||||
assert(_init);
|
||||
std::string initname(mangle());
|
||||
initname.append("__initZ");
|
||||
|
||||
std::string initname("_D");
|
||||
initname.append(mangle());
|
||||
initname.append("6__initZ");
|
||||
//Logger::cout() << *_init << '\n';
|
||||
llvm::GlobalVariable* initvar = new llvm::GlobalVariable(ts->llvmType, true, _linkage, 0, initname, gIR->module);
|
||||
ts->llvmInit = initvar;
|
||||
@@ -499,7 +503,7 @@ void VarDeclaration::toObjFile()
|
||||
bool _isconst = isConst();
|
||||
|
||||
llvm::GlobalValue::LinkageTypes _linkage;
|
||||
if (parent->isFuncDeclaration())
|
||||
if (parent && parent->isFuncDeclaration())
|
||||
_linkage = llvm::GlobalValue::InternalLinkage;
|
||||
else
|
||||
_linkage = LLVM_DtoLinkage(protection, storage_class);
|
||||
@@ -514,46 +518,51 @@ void VarDeclaration::toObjFile()
|
||||
|
||||
Logger::println("Creating global variable");
|
||||
std::string _name(mangle());
|
||||
|
||||
llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_type,_isconst,_linkage,0,_name,M);
|
||||
llvmValue = gvar;
|
||||
|
||||
gIR->lvals.push_back(gvar);
|
||||
_init = LLVM_DtoConstInitializer(t, init);
|
||||
gIR->lvals.pop_back();
|
||||
// if extern don't emit initializer
|
||||
if (!(storage_class & STCextern))
|
||||
{
|
||||
gIR->lvals.push_back(gvar);
|
||||
_init = LLVM_DtoConstInitializer(t, init);
|
||||
gIR->lvals.pop_back();
|
||||
|
||||
//Logger::cout() << "initializer: " << *_init << '\n';
|
||||
if (_type != _init->getType()) {
|
||||
Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n";
|
||||
// zero initalizer
|
||||
if (_init->isNullValue())
|
||||
_init = llvm::Constant::getNullValue(_type);
|
||||
// pointer to global constant (struct.init)
|
||||
else if (llvm::isa<llvm::GlobalVariable>(_init))
|
||||
{
|
||||
assert(_init->getType()->getContainedType(0) == _type);
|
||||
llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init);
|
||||
assert(t->ty == Tstruct);
|
||||
TypeStruct* ts = (TypeStruct*)t;
|
||||
assert(ts->sym->llvmInitZ);
|
||||
_init = ts->sym->llvmInitZ;
|
||||
}
|
||||
// array single value init
|
||||
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);
|
||||
}
|
||||
else {
|
||||
Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
|
||||
//assert(0);
|
||||
//Logger::cout() << "initializer: " << *_init << '\n';
|
||||
if (_type != _init->getType()) {
|
||||
Logger::cout() << "got type '" << *_init->getType() << "' expected '" << *_type << "'\n";
|
||||
// zero initalizer
|
||||
if (_init->isNullValue())
|
||||
_init = llvm::Constant::getNullValue(_type);
|
||||
// pointer to global constant (struct.init)
|
||||
else if (llvm::isa<llvm::GlobalVariable>(_init))
|
||||
{
|
||||
assert(_init->getType()->getContainedType(0) == _type);
|
||||
llvm::GlobalVariable* gv = llvm::cast<llvm::GlobalVariable>(_init);
|
||||
assert(t->ty == Tstruct);
|
||||
TypeStruct* ts = (TypeStruct*)t;
|
||||
assert(ts->sym->llvmInitZ);
|
||||
_init = ts->sym->llvmInitZ;
|
||||
}
|
||||
// array single value init
|
||||
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);
|
||||
}
|
||||
else {
|
||||
Logger::cout() << "Unexpected initializer type: " << *_type << '\n';
|
||||
//assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
gvar->setInitializer(_init);
|
||||
}
|
||||
|
||||
gvar->setInitializer(_init);
|
||||
|
||||
llvmDModule = gIR->dmodule;
|
||||
|
||||
//if (storage_class & STCprivate)
|
||||
@@ -618,7 +627,8 @@ void TypedefDeclaration::toObjFile()
|
||||
Logger::print("TypedefDeclaration::toObjFile(%d): %s\n", tdi++, toChars());
|
||||
LOG_SCOPE;
|
||||
|
||||
// TODO
|
||||
// generate typeinfo
|
||||
type->getTypeInfo(NULL);
|
||||
}
|
||||
|
||||
/* ================================================================== */
|
||||
@@ -695,7 +705,7 @@ void FuncDeclaration::toObjFile()
|
||||
// first make absolutely sure the type is up to date
|
||||
f->llvmType = llvmValue->getType()->getContainedType(0);
|
||||
|
||||
Logger::cout() << "func type: " << *f->llvmType << '\n';
|
||||
//Logger::cout() << "func type: " << *f->llvmType << '\n';
|
||||
|
||||
// this handling
|
||||
if (f->llvmUsesThis) {
|
||||
@@ -754,12 +764,15 @@ void FuncDeclaration::toObjFile()
|
||||
// llvm requires all basic blocks to end with a TerminatorInst but DMD does not put a return statement
|
||||
// in automatically, so we do it here.
|
||||
if (!isMain()) {
|
||||
if (gIR->scopebb()->empty() || !llvm::isa<llvm::TerminatorInst>(gIR->scopebb()->back())) {
|
||||
if (!gIR->scopereturned()) {
|
||||
// pass the previous block into this block
|
||||
//new llvm::BranchInst(irs.end, irs.begin);
|
||||
if (func->getReturnType() == llvm::Type::VoidTy) {
|
||||
new llvm::ReturnInst(gIR->scopebb());
|
||||
}
|
||||
else {
|
||||
new llvm::ReturnInst(llvm::UndefValue::get(func->getReturnType()), gIR->scopebb());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -778,7 +791,17 @@ void FuncDeclaration::toObjFile()
|
||||
// would be nice to figure out how to assert that this is correct
|
||||
llvm::BasicBlock* lastbb = &func->getBasicBlockList().back();
|
||||
if (lastbb->empty()) {
|
||||
lastbb->eraseFromParent();
|
||||
if (lastbb->getNumUses() == 0)
|
||||
lastbb->eraseFromParent();
|
||||
else {
|
||||
new llvm::UnreachableInst(lastbb);
|
||||
/*if (func->getReturnType() == llvm::Type::VoidTy) {
|
||||
new llvm::ReturnInst(lastbb);
|
||||
}
|
||||
else {
|
||||
new llvm::ReturnInst(llvm::UndefValue::get(func->getReturnType()), lastbb);
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
gIR->functions.pop_back();
|
||||
|
||||
702
gen/typinf.c
702
gen/typinf.c
@@ -11,6 +11,8 @@
|
||||
#include <cstdio>
|
||||
#include <cassert>
|
||||
|
||||
#include "gen/llvm.h"
|
||||
|
||||
#include "mars.h"
|
||||
#include "module.h"
|
||||
#include "mtype.h"
|
||||
@@ -25,347 +27,171 @@
|
||||
#include "import.h"
|
||||
#include "aggregate.h"
|
||||
|
||||
#include "gen/irstate.h"
|
||||
#include "gen/logger.h"
|
||||
#include "gen/runtime.h"
|
||||
|
||||
/*******************************************
|
||||
|
||||
* Get a canonicalized form of the TypeInfo for use with the internal
|
||||
|
||||
* runtime library routines. Canonicalized in that static arrays are
|
||||
|
||||
* represented as dynamic arrays, enums are represented by their
|
||||
|
||||
* underlying type, etc. This reduces the number of TypeInfo's needed,
|
||||
|
||||
* so we can use the custom internal ones more.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
Expression *Type::getInternalTypeInfo(Scope *sc)
|
||||
|
||||
{ TypeInfoDeclaration *tid;
|
||||
|
||||
Expression *e;
|
||||
|
||||
Type *t;
|
||||
|
||||
static TypeInfoDeclaration *internalTI[TMAX];
|
||||
|
||||
|
||||
|
||||
//printf("Type::getInternalTypeInfo() %s\n", toChars());
|
||||
|
||||
t = toBasetype();
|
||||
|
||||
switch (t->ty)
|
||||
|
||||
{
|
||||
|
||||
case Tsarray:
|
||||
|
||||
t = t->next->arrayOf(); // convert to corresponding dynamic array type
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
case Tclass:
|
||||
|
||||
if (((TypeClass *)t)->sym->isInterfaceDeclaration())
|
||||
|
||||
break;
|
||||
|
||||
goto Linternal;
|
||||
|
||||
|
||||
|
||||
case Tarray:
|
||||
|
||||
if (t->next->ty != Tclass)
|
||||
|
||||
break;
|
||||
|
||||
goto Linternal;
|
||||
|
||||
|
||||
|
||||
case Tfunction:
|
||||
|
||||
case Tdelegate:
|
||||
|
||||
case Tpointer:
|
||||
|
||||
Linternal:
|
||||
|
||||
tid = internalTI[t->ty];
|
||||
|
||||
if (!tid)
|
||||
|
||||
{ tid = new TypeInfoDeclaration(t, 1);
|
||||
|
||||
internalTI[t->ty] = tid;
|
||||
|
||||
}
|
||||
|
||||
e = new VarExp(0, tid);
|
||||
|
||||
e = e->addressOf(sc);
|
||||
|
||||
//e = e->addressOf(sc);
|
||||
e->type = tid->type; // do this so we don't get redundant dereference
|
||||
|
||||
return e;
|
||||
|
||||
|
||||
|
||||
default:
|
||||
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
//printf("\tcalling getTypeInfo() %s\n", t->toChars());
|
||||
|
||||
return t->getTypeInfo(sc);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/****************************************************
|
||||
|
||||
* Get the exact TypeInfo.
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
Expression *Type::getTypeInfo(Scope *sc)
|
||||
|
||||
{
|
||||
|
||||
Expression *e;
|
||||
|
||||
Type *t;
|
||||
|
||||
|
||||
|
||||
//printf("Type::getTypeInfo() %p, %s\n", this, toChars());
|
||||
|
||||
t = merge(); // do this since not all Type's are merge'd
|
||||
|
||||
if (!t->vtinfo)
|
||||
|
||||
{ t->vtinfo = t->getTypeInfoDeclaration();
|
||||
|
||||
assert(t->vtinfo);
|
||||
|
||||
|
||||
|
||||
/* If this has a custom implementation in std/typeinfo, then
|
||||
|
||||
* do not generate a COMDAT for it.
|
||||
|
||||
*/
|
||||
|
||||
if (!t->builtinTypeInfo())
|
||||
|
||||
{ // Generate COMDAT
|
||||
|
||||
if (sc) // if in semantic() pass
|
||||
|
||||
{ // Find module that will go all the way to an object file
|
||||
|
||||
Module *m = sc->module->importedFrom;
|
||||
|
||||
m->members->push(t->vtinfo);
|
||||
|
||||
}
|
||||
|
||||
else // if in obj generation pass
|
||||
|
||||
{
|
||||
|
||||
t->vtinfo->toObjFile();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
e = new VarExp(0, t->vtinfo);
|
||||
|
||||
//e = e->addressOf(sc);
|
||||
e->type = t->vtinfo->type; // do this so we don't get redundant dereference
|
||||
|
||||
return e;
|
||||
|
||||
}
|
||||
|
||||
|
||||
enum RET TypeFunction::retStyle()
|
||||
{
|
||||
return RETstack;
|
||||
}
|
||||
|
||||
TypeInfoDeclaration *Type::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
//printf("Type::getTypeInfoDeclaration() %s\n", toChars());
|
||||
|
||||
return new TypeInfoDeclaration(this, 0);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeTypedef::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoTypedefDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypePointer::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoPointerDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeDArray::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoArrayDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeSArray::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoStaticArrayDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeAArray::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoAssociativeArrayDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeStruct::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoStructDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeClass::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
if (sym->isInterfaceDeclaration())
|
||||
|
||||
return new TypeInfoInterfaceDeclaration(this);
|
||||
|
||||
else
|
||||
|
||||
return new TypeInfoClassDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeEnum::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoEnumDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeFunction::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoFunctionDeclaration(this);
|
||||
|
||||
}
|
||||
enum RET TypeFunction::retStyle()
|
||||
|
||||
{
|
||||
|
||||
return RETstack;
|
||||
|
||||
}
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeDelegate::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoDelegateDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
TypeInfoDeclaration *TypeTuple::getTypeInfoDeclaration()
|
||||
|
||||
{
|
||||
|
||||
return new TypeInfoTupleDeclaration(this);
|
||||
|
||||
}
|
||||
|
||||
|
||||
void TypeInfoDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
|
||||
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
|
||||
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
|
||||
void TypeInfoClassDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
}
|
||||
|
||||
void TypeInfoDeclaration::toObjFile()
|
||||
{
|
||||
Logger::println("TypeInfoDeclaration::toObjFile()");
|
||||
LOG_SCOPE;
|
||||
Logger::println("type = '%s'", tinfo->toChars());
|
||||
|
||||
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
/* These decide if there's an instance for them already in std.typeinfo,
|
||||
@@ -384,7 +210,7 @@ int TypeBasic::builtinTypeInfo()
|
||||
|
||||
int TypeDArray::builtinTypeInfo()
|
||||
{
|
||||
return 0;
|
||||
return next->isTypeBasic() != NULL;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
@@ -401,3 +227,511 @@ Expression *createTypeInfoArray(Scope *sc, Expression *args[], int dim)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
// MAGIC PLACE
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void TypeInfoDeclaration::toObjFile()
|
||||
{
|
||||
Logger::println("TypeInfoDeclaration::toObjFile()");
|
||||
LOG_SCOPE;
|
||||
Logger::println("type = '%s'", tinfo->toChars());
|
||||
|
||||
if (llvmTouched) return;
|
||||
else llvmTouched = true;
|
||||
|
||||
Logger::println("Getting typeinfo var: %s", mangle());
|
||||
llvmValue = LLVM_D_GetRuntimeGlobal(gIR->module, mangle());
|
||||
assert(llvmValue);
|
||||
Logger::cout() << "Got:" << '\n' << *llvmValue << '\n';
|
||||
}
|
||||
|
||||
/* ========================================================================= */
|
||||
|
||||
void TypeInfoDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoTypedefDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoTypedefDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoEnumDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoEnumDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoPointerDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoPointerDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoArrayDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoStaticArrayDeclaration");
|
||||
}
|
||||
|
||||
void TypeInfoAssociativeArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
assert(0 && "TypeInfoAssociativeArrayDeclaration");
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
char *name = sd->toPrettyChars();
|
||||
size_t namelen = strlen(name);
|
||||
dtdword(pdt, namelen);
|
||||
dtabytes(pdt, TYnptr, 0, namelen + 1, name);
|
||||
|
||||
// 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 TypeInfoEnumDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoEnumDeclaration::toDt()\n");
|
||||
dtxoff(pdt, Type::typeinfoenum->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Enum
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tenum);
|
||||
|
||||
TypeEnum *tc = (TypeEnum *)tinfo;
|
||||
EnumDeclaration *sd = tc->sym;
|
||||
|
||||
/* 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
|
||||
|
||||
char *name = sd->toPrettyChars();
|
||||
size_t namelen = strlen(name);
|
||||
dtdword(pdt, namelen);
|
||||
dtabytes(pdt, TYnptr, 0, namelen + 1, name);
|
||||
|
||||
// void[] init;
|
||||
if (tinfo->isZeroInit() || !sd->defaultval)
|
||||
{ // 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 TypeInfoPointerDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoPointerDeclaration::toDt()\n");
|
||||
dtxoff(pdt, Type::typeinfopointer->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Pointer
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
void TypeInfoStaticArrayDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoStaticArrayDeclaration::toDt()\n");
|
||||
dtxoff(pdt, Type::typeinfostaticarray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_StaticArray
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tsarray);
|
||||
|
||||
TypeSArray *tc = (TypeSArray *)tinfo;
|
||||
|
||||
tc->next->getTypeInfo(NULL);
|
||||
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)
|
||||
{
|
||||
//printf("TypeInfoAssociativeArrayDeclaration::toDt()\n");
|
||||
dtxoff(pdt, Type::typeinfoassociativearray->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_AssociativeArray
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Taarray);
|
||||
|
||||
TypeAArray *tc = (TypeAArray *)tinfo;
|
||||
|
||||
tc->next->getTypeInfo(NULL);
|
||||
dtxoff(pdt, tc->next->vtinfo->toSymbol(), 0, TYnptr); // TypeInfo for array of type
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
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
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
void TypeInfoStructDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoStructDeclaration::toDt() '%s'\n", toChars());
|
||||
|
||||
unsigned offset = Type::typeinfostruct->structsize;
|
||||
|
||||
dtxoff(pdt, Type::typeinfostruct->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfo_Struct
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tstruct);
|
||||
|
||||
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[]
|
||||
*/
|
||||
|
||||
char *name = sd->toPrettyChars();
|
||||
size_t namelen = strlen(name);
|
||||
dtdword(pdt, namelen);
|
||||
//dtabytes(pdt, TYnptr, 0, namelen + 1, name);
|
||||
dtxoff(pdt, toSymbol(), offset, TYnptr);
|
||||
offset += namelen + 1;
|
||||
|
||||
// void[] init;
|
||||
dtdword(pdt, sd->structsize); // init.length
|
||||
if (sd->zeroInit)
|
||||
dtdword(pdt, 0); // NULL for 0 initialization
|
||||
else
|
||||
dtxoff(pdt, sd->toInitializer(), 0, TYnptr); // init.ptr
|
||||
|
||||
FuncDeclaration *fd;
|
||||
FuncDeclaration *fdx;
|
||||
TypeFunction *tf;
|
||||
Type *ta;
|
||||
Dsymbol *s;
|
||||
|
||||
static TypeFunction *tftohash;
|
||||
static TypeFunction *tftostring;
|
||||
|
||||
if (!tftohash)
|
||||
{
|
||||
Scope sc;
|
||||
|
||||
tftohash = new TypeFunction(NULL, Type::thash_t, 0, LINKd);
|
||||
tftohash = (TypeFunction *)tftohash->semantic(0, &sc);
|
||||
|
||||
tftostring = new TypeFunction(NULL, Type::tchar->arrayOf(), 0, LINKd);
|
||||
tftostring = (TypeFunction *)tftostring->semantic(0, &sc);
|
||||
}
|
||||
|
||||
TypeFunction *tfeqptr;
|
||||
{
|
||||
Scope sc;
|
||||
Arguments *arguments = new Arguments;
|
||||
Argument *arg = new Argument(STCin, tc->pointerTo(), NULL, NULL);
|
||||
|
||||
arguments->push(arg);
|
||||
tfeqptr = new TypeFunction(arguments, Type::tint32, 0, LINKd);
|
||||
tfeqptr = (TypeFunction *)tfeqptr->semantic(0, &sc);
|
||||
}
|
||||
|
||||
#if 0
|
||||
TypeFunction *tfeq;
|
||||
{
|
||||
Scope sc;
|
||||
Array *arguments = new Array;
|
||||
Argument *arg = new Argument(In, tc, NULL, NULL);
|
||||
|
||||
arguments->push(arg);
|
||||
tfeq = new TypeFunction(arguments, Type::tint32, 0, LINKd);
|
||||
tfeq = (TypeFunction *)tfeq->semantic(0, &sc);
|
||||
}
|
||||
#endif
|
||||
|
||||
s = search_function(sd, Id::tohash);
|
||||
fdx = s ? s->isFuncDeclaration() : NULL;
|
||||
if (fdx)
|
||||
{ fd = fdx->overloadExactMatch(tftohash);
|
||||
if (fd)
|
||||
dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
|
||||
else
|
||||
//fdx->error("must be declared as extern (D) uint toHash()");
|
||||
dtdword(pdt, 0);
|
||||
}
|
||||
else
|
||||
dtdword(pdt, 0);
|
||||
|
||||
s = search_function(sd, Id::eq);
|
||||
fdx = s ? s->isFuncDeclaration() : NULL;
|
||||
for (int i = 0; i < 2; i++)
|
||||
{
|
||||
if (fdx)
|
||||
{ fd = fdx->overloadExactMatch(tfeqptr);
|
||||
if (fd)
|
||||
dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
|
||||
else
|
||||
//fdx->error("must be declared as extern (D) int %s(%s*)", fdx->toChars(), sd->toChars());
|
||||
dtdword(pdt, 0);
|
||||
}
|
||||
else
|
||||
dtdword(pdt, 0);
|
||||
|
||||
s = search_function(sd, Id::cmp);
|
||||
fdx = s ? s->isFuncDeclaration() : NULL;
|
||||
}
|
||||
|
||||
s = search_function(sd, Id::tostring);
|
||||
fdx = s ? s->isFuncDeclaration() : NULL;
|
||||
if (fdx)
|
||||
{ fd = fdx->overloadExactMatch(tftostring);
|
||||
if (fd)
|
||||
dtxoff(pdt, fd->toSymbol(), 0, TYnptr);
|
||||
else
|
||||
//fdx->error("must be declared as extern (D) char[] toString()");
|
||||
dtdword(pdt, 0);
|
||||
}
|
||||
else
|
||||
dtdword(pdt, 0);
|
||||
|
||||
// uint m_flags;
|
||||
dtdword(pdt, tc->hasPointers());
|
||||
|
||||
// name[]
|
||||
dtnbytes(pdt, namelen + 1, name);
|
||||
}
|
||||
|
||||
void TypeInfoClassDeclaration::toDt(dt_t **pdt)
|
||||
{
|
||||
//printf("TypeInfoClassDeclaration::toDt() %s\n", tinfo->toChars());
|
||||
dtxoff(pdt, Type::typeinfoclass->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoClass
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tclass);
|
||||
|
||||
TypeClass *tc = (TypeClass *)tinfo;
|
||||
Symbol *s;
|
||||
|
||||
if (!tc->sym->vclassinfo)
|
||||
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)
|
||||
{
|
||||
//printf("TypeInfoInterfaceDeclaration::toDt() %s\n", tinfo->toChars());
|
||||
dtxoff(pdt, Type::typeinfointerface->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Tclass);
|
||||
|
||||
TypeClass *tc = (TypeClass *)tinfo;
|
||||
Symbol *s;
|
||||
|
||||
if (!tc->sym->vclassinfo)
|
||||
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)
|
||||
{
|
||||
//printf("TypeInfoTupleDeclaration::toDt() %s\n", tinfo->toChars());
|
||||
dtxoff(pdt, Type::typeinfotypelist->toVtblSymbol(), 0, TYnptr); // vtbl for TypeInfoInterface
|
||||
dtdword(pdt, 0); // monitor
|
||||
|
||||
assert(tinfo->ty == Ttuple);
|
||||
|
||||
TypeTuple *tu = (TypeTuple *)tinfo;
|
||||
|
||||
size_t dim = tu->arguments->dim;
|
||||
dtdword(pdt, dim); // elements.length
|
||||
|
||||
dt_t *d = NULL;
|
||||
for (size_t i = 0; i < dim; i++)
|
||||
{ Argument *arg = (Argument *)tu->arguments->data[i];
|
||||
Expression *e = arg->type->getTypeInfo(NULL);
|
||||
e = e->optimize(WANTvalue);
|
||||
e->toDt(&d);
|
||||
}
|
||||
|
||||
Symbol *s;
|
||||
s = static_sym();
|
||||
s->Sdt = d;
|
||||
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
|
||||
|
||||
@@ -1,32 +1,37 @@
|
||||
#!/bin/bash
|
||||
|
||||
if [ "$1" = "gdb" ]; then
|
||||
dc_cmd="gdb --args llvmdc"
|
||||
else
|
||||
dc_cmd="llvmdc"
|
||||
fi
|
||||
echo "removing old objects"
|
||||
rm -f obj/*.bc
|
||||
rm -f ../lib/*.bc
|
||||
|
||||
# build runtime
|
||||
$dc_cmd internal/contract.d \
|
||||
internal/arrays.d \
|
||||
echo "compiling contract runtime"
|
||||
llvmdc internal/contract.d -c -of../lib/llvmdcore.bc -noruntime || exit 1
|
||||
|
||||
echo "compiling common runtime"
|
||||
rebuild internal/arrays.d \
|
||||
internal/mem.d \
|
||||
internal/moduleinit.d \
|
||||
-c -noruntime -odobj || exit 1
|
||||
-c -oqobj -dc=llvmdc-posix || exit 1
|
||||
|
||||
echo "compiling module init backend"
|
||||
llvm-as -f -o=obj/moduleinit_backend.bc internal/moduleinit_backend.ll || exit 1
|
||||
llvm-link -f -o=../lib/llvmdcore.bc obj/contract.bc obj/arrays.bc obj/mem.bc obj/moduleinit.bc obj/moduleinit_backend.bc || exit 1
|
||||
llvm-link -f -o=../lib/llvmdcore.bc `ls obj/internal.*.bc` ../lib/llvmdcore.bc obj/moduleinit_backend.bc || exit 1
|
||||
|
||||
$dc_cmd internal/objectimpl.d -c -odobj || exit 1
|
||||
llvm-link -f -o=obj/all.bc obj/contract.bc obj/arrays.bc obj/mem.bc obj/moduleinit.bc obj/objectimpl.bc obj/moduleinit_backend.bc || exit 1
|
||||
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
|
||||
|
||||
opt -f -std-compile-opts -o=../lib/llvmdcore.bc obj/all.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 "optimizing"
|
||||
opt -f -std-compile-opts -o=../lib/llvmdcore.bc ../lib/llvmdcore.bc || exit 1
|
||||
|
||||
# build phobos
|
||||
$dc_cmd std/stdio.d -c -odobj || exit 1
|
||||
llvm-link -f -o=../lib/lphobos.bc obj/stdio.bc || exit 1
|
||||
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
|
||||
opt -f -std-compile-opts -o=../lib/lphobos.bc ../lib/lphobos.bc || exit 1
|
||||
|
||||
if [ "$1" = "ll" ]; then
|
||||
llvm-dis -f -o=all.ll ../lib/llvmdcore.bc || exit 1
|
||||
fi
|
||||
|
||||
echo SUCCESS
|
||||
echo "SUCCESS"
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
rm *.bc *.s *.o
|
||||
rm ../lib/llvmdcore.bc
|
||||
@@ -1,2 +0,0 @@
|
||||
[std/typeinfo]
|
||||
type=library
|
||||
@@ -85,3 +85,32 @@ bool _d_static_array_neq(void* lhs, void* rhs, size_t bytesize)
|
||||
return memcmp(lhs,rhs,bytesize) != 0;
|
||||
}
|
||||
|
||||
bool _d_dyn_array_eq(void[] lhs, void[] rhs)
|
||||
{
|
||||
if (lhs.length != rhs.length)
|
||||
return false;
|
||||
else if (lhs is rhs)
|
||||
return true;
|
||||
return memcmp(lhs.ptr,rhs.ptr,lhs.length) == 0;
|
||||
}
|
||||
|
||||
bool _d_dyn_array_neq(void[] lhs, void[] rhs)
|
||||
{
|
||||
if (lhs.length != rhs.length)
|
||||
return true;
|
||||
else if (lhs is rhs)
|
||||
return false;
|
||||
return memcmp(lhs.ptr,rhs.ptr,lhs.length) != 0;
|
||||
}
|
||||
|
||||
// for array cast
|
||||
size_t _d_array_cast_len(size_t len, size_t elemsz, size_t newelemsz)
|
||||
{
|
||||
if (newelemsz == 1) {
|
||||
return len*elemsz;
|
||||
}
|
||||
else if (len % newelemsz) {
|
||||
throw new Exception("Bad array cast");
|
||||
}
|
||||
return (len*elemsz)/newelemsz;
|
||||
}
|
||||
|
||||
@@ -37,9 +37,28 @@ module object;
|
||||
|
||||
//import std.outofmemory;
|
||||
|
||||
/**
|
||||
* An unsigned integral type large enough to span the memory space. Use for
|
||||
* array indices and pointer offsets for maximal portability to
|
||||
* architectures that have different memory address ranges. This is
|
||||
* analogous to C's size_t.
|
||||
*/
|
||||
alias typeof(int.sizeof) size_t;
|
||||
|
||||
/**
|
||||
* A signed integral type large enough to span the memory space. Use for
|
||||
* pointer differences and for size_t differences for maximal portability to
|
||||
* architectures that have different memory address ranges. This is
|
||||
* analogous to C's ptrdiff_t.
|
||||
*/
|
||||
alias typeof(cast(void*)0 - cast(void*)0) ptrdiff_t;
|
||||
|
||||
alias size_t hash_t;
|
||||
|
||||
extern (C)
|
||||
{ /// C's printf function.
|
||||
int printf(char *, ...);
|
||||
void trace_term();
|
||||
|
||||
int memcmp(void *, void *, size_t);
|
||||
void* memcpy(void *, void *, size_t);
|
||||
@@ -53,34 +72,12 @@ extern (C)
|
||||
/// Standard boolean type.
|
||||
alias bool bit;
|
||||
|
||||
version (LLVM64)
|
||||
{
|
||||
/**
|
||||
* An unsigned integral type large enough to span the memory space. Use for
|
||||
* array indices and pointer offsets for maximal portability to
|
||||
* architectures that have different memory address ranges. This is
|
||||
* analogous to C's size_t.
|
||||
*/
|
||||
alias ulong size_t;
|
||||
|
||||
/**
|
||||
* A signed integral type large enough to span the memory space. Use for
|
||||
* pointer differences and for size_t differences for maximal portability to
|
||||
* architectures that have different memory address ranges. This is
|
||||
* analogous to C's ptrdiff_t.
|
||||
*/
|
||||
alias long ptrdiff_t;
|
||||
|
||||
alias ulong hash_t;
|
||||
}
|
||||
else
|
||||
{
|
||||
alias uint size_t;
|
||||
alias int ptrdiff_t;
|
||||
alias uint hash_t;
|
||||
}
|
||||
alias char[] string;
|
||||
alias wchar[] wstring;
|
||||
alias dchar[] dstring;
|
||||
|
||||
/+
|
||||
|
||||
/* *************************
|
||||
* Internal struct pointed to by the hidden .monitor member.
|
||||
*/
|
||||
@@ -90,6 +87,7 @@ struct Monitor
|
||||
|
||||
/* More stuff goes here defined by internal/monitor.c */
|
||||
}
|
||||
|
||||
+/
|
||||
|
||||
/******************
|
||||
@@ -109,7 +107,7 @@ class Object
|
||||
char[] toString()
|
||||
{
|
||||
//return this.classinfo.name;
|
||||
return "Object.toString: classinfo not yet implemented";
|
||||
return "object.Object (no classinfo yet)";
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -118,7 +116,7 @@ class Object
|
||||
hash_t toHash()
|
||||
{
|
||||
// BUG: this prevents a compacting GC from working, needs to be fixed
|
||||
return cast(uint)cast(void *)this;
|
||||
return cast(hash_t)cast(void *)this;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -135,8 +133,8 @@ class Object
|
||||
// BUG: this prevents a compacting GC from working, needs to be fixed
|
||||
//return cast(int)cast(void *)this - cast(int)cast(void *)o;
|
||||
|
||||
assert(0, "need opCmp for class <no classinfo yet>");
|
||||
//throw new Error("need opCmp for class " ~ this.classinfo.name);
|
||||
throw new Error("need opCmp for class unknown object.Object (no classinfo yet)");
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -158,8 +156,9 @@ class Object
|
||||
*/
|
||||
final void notifyRegister(void delegate(Object) dg)
|
||||
{
|
||||
/+
|
||||
//printf("notifyRegister(dg = %llx, o = %p)\n", dg, this);
|
||||
/+synchronized (this)
|
||||
synchronized (this)
|
||||
{
|
||||
Monitor* m = cast(Monitor*)(cast(void**)this)[1];
|
||||
foreach (inout x; m.delegates)
|
||||
@@ -191,7 +190,8 @@ class Object
|
||||
m.delegates[startlen .. len] = null;
|
||||
}
|
||||
m.delegates[startlen] = dg;
|
||||
}+/
|
||||
}
|
||||
+/
|
||||
}
|
||||
|
||||
/* **
|
||||
@@ -201,7 +201,8 @@ class Object
|
||||
*/
|
||||
final void notifyUnRegister(void delegate(Object) dg)
|
||||
{
|
||||
/+synchronized (this)
|
||||
/+
|
||||
synchronized (this)
|
||||
{
|
||||
Monitor* m = cast(Monitor*)(cast(void**)this)[1];
|
||||
foreach (inout x; m.delegates)
|
||||
@@ -209,7 +210,8 @@ class Object
|
||||
if (x == dg)
|
||||
x = null;
|
||||
}
|
||||
}+/
|
||||
}
|
||||
+/
|
||||
}
|
||||
|
||||
/******
|
||||
@@ -219,15 +221,17 @@ class Object
|
||||
* Returns:
|
||||
* null if failed
|
||||
*/
|
||||
/+static Object factory(char[] classname)
|
||||
static Object factory(char[] classname)
|
||||
{
|
||||
/+
|
||||
auto ci = ClassInfo.find(classname);
|
||||
if (ci)
|
||||
{
|
||||
return ci.create();
|
||||
}
|
||||
+/
|
||||
return null;
|
||||
}+/
|
||||
}
|
||||
}
|
||||
|
||||
/+
|
||||
@@ -330,6 +334,8 @@ class ClassInfo : Object
|
||||
|
||||
private import std.string;
|
||||
|
||||
+/
|
||||
|
||||
/**
|
||||
* Array of pairs giving the offset and type information for each
|
||||
* member in an aggregate.
|
||||
@@ -340,6 +346,17 @@ struct OffsetTypeInfo
|
||||
TypeInfo ti; /// TypeInfo for this member
|
||||
}
|
||||
|
||||
private int string_cmp(char[] s1, char[] s2)
|
||||
{
|
||||
auto len = s1.length;
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
int result = memcmp(s1.ptr, s2.ptr, len);
|
||||
if (result == 0)
|
||||
result = cast(int)(cast(ptrdiff_t)s1.length - cast(ptrdiff_t)s2.length);
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runtime type information about a type.
|
||||
* Can be retrieved for any type using a
|
||||
@@ -362,7 +379,7 @@ class TypeInfo
|
||||
TypeInfo ti = cast(TypeInfo)o;
|
||||
if (ti is null)
|
||||
return 1;
|
||||
return std.string.cmp(this.toString(), ti.toString());
|
||||
return string_cmp(this.toString(), ti.toString());
|
||||
}
|
||||
|
||||
int opEquals(Object o)
|
||||
@@ -416,6 +433,8 @@ class TypeInfo
|
||||
OffsetTypeInfo[] offTi() { return null; }
|
||||
}
|
||||
|
||||
/+
|
||||
|
||||
class TypeInfo_Typedef : TypeInfo
|
||||
{
|
||||
char[] toString() { return name; }
|
||||
@@ -1021,6 +1040,30 @@ class TypeInfo_Tuple : TypeInfo
|
||||
assert(0);
|
||||
}
|
||||
}
|
||||
|
||||
class TypeInfo_Const : TypeInfo
|
||||
{
|
||||
char[] toString() { return "const " ~ base.toString(); }
|
||||
|
||||
int opEquals(Object o) { return base.opEquals(o); }
|
||||
hash_t getHash(void *p) { return base.getHash(p); }
|
||||
int equals(void *p1, void *p2) { return base.equals(p1, p2); }
|
||||
int compare(void *p1, void *p2) { return base.compare(p1, p2); }
|
||||
size_t tsize() { return base.tsize(); }
|
||||
void swap(void *p1, void *p2) { return base.swap(p1, p2); }
|
||||
|
||||
TypeInfo next() { return base.next(); }
|
||||
uint flags() { return base.flags(); }
|
||||
void[] init() { return base.init(); }
|
||||
|
||||
TypeInfo base;
|
||||
}
|
||||
|
||||
class TypeInfo_Invariant : TypeInfo_Const
|
||||
{
|
||||
char[] toString() { return "invariant " ~ base.toString(); }
|
||||
}
|
||||
|
||||
+/
|
||||
|
||||
/**
|
||||
@@ -1038,12 +1081,6 @@ class Exception : Object
|
||||
this.msg = msg;
|
||||
}
|
||||
|
||||
void print()
|
||||
{
|
||||
auto str = toString();
|
||||
printf("%.*s\n", str.length, str.ptr);
|
||||
}
|
||||
|
||||
char[] toString() { return msg; }
|
||||
}
|
||||
|
||||
@@ -1070,3 +1107,4 @@ class Error : Exception
|
||||
}
|
||||
|
||||
//extern (C) int nullext = 0;
|
||||
|
||||
|
||||
4
lphobos/phobos.d
Normal file
4
lphobos/phobos.d
Normal file
@@ -0,0 +1,4 @@
|
||||
module phobos;
|
||||
|
||||
import
|
||||
std.stdio;
|
||||
@@ -1,111 +0,0 @@
|
||||
|
||||
module std.typeinfo.ti_Aint;
|
||||
|
||||
private import std.c.string;
|
||||
|
||||
// int[]
|
||||
|
||||
class TypeInfo_Ai : TypeInfo
|
||||
{
|
||||
char[] toString() { return "int[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ int[] s = *cast(int[]*)p;
|
||||
auto len = s.length;
|
||||
auto str = s.ptr;
|
||||
hash_t hash = 0;
|
||||
|
||||
while (len)
|
||||
{
|
||||
hash *= 9;
|
||||
hash += *cast(uint *)str;
|
||||
str++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
int[] s1 = *cast(int[]*)p1;
|
||||
int[] s2 = *cast(int[]*)p2;
|
||||
|
||||
return s1.length == s2.length &&
|
||||
memcmp(cast(void *)s1, cast(void *)s2, s1.length * int.sizeof) == 0;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
int[] s1 = *cast(int[]*)p1;
|
||||
int[] s2 = *cast(int[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int result = s1[u] - s2[u];
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (int[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(int);
|
||||
}
|
||||
}
|
||||
|
||||
// uint[]
|
||||
|
||||
class TypeInfo_Ak : TypeInfo_Ai
|
||||
{
|
||||
char[] toString() { return "uint[]"; }
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
uint[] s1 = *cast(uint[]*)p1;
|
||||
uint[] s2 = *cast(uint[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int result = s1[u] - s2[u];
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(uint);
|
||||
}
|
||||
}
|
||||
|
||||
// dchar[]
|
||||
|
||||
class TypeInfo_Aw : TypeInfo_Ak
|
||||
{
|
||||
char[] toString() { return "dchar[]"; }
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(dchar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
// byte
|
||||
|
||||
module std.typeinfo.ti_byte;
|
||||
|
||||
class TypeInfo_g : TypeInfo
|
||||
{
|
||||
char[] toString() { return "byte"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(byte *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(byte *)p1 == *cast(byte *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *cast(byte *)p1 - *cast(byte *)p2;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return byte.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
byte t;
|
||||
|
||||
t = *cast(byte *)p1;
|
||||
*cast(byte *)p1 = *cast(byte *)p2;
|
||||
*cast(byte *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,42 +0,0 @@
|
||||
|
||||
// pointer
|
||||
|
||||
module std.typeinfo.ti_ptr;
|
||||
|
||||
class TypeInfo_P : TypeInfo
|
||||
{
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return cast(uint)*cast(void* *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(void* *)p1 == *cast(void* *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *cast(void* *)p1 - *cast(void* *)p2;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (void*).sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
void* t;
|
||||
|
||||
t = *cast(void* *)p1;
|
||||
*cast(void* *)p1 = *cast(void* *)p2;
|
||||
*cast(void* *)p2 = t;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
// ushort
|
||||
|
||||
module std.typeinfo.ti_ushort;
|
||||
|
||||
class TypeInfo_t : TypeInfo
|
||||
{
|
||||
char[] toString() { return "ushort"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(ushort *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(ushort *)p1 == *cast(ushort *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *cast(ushort *)p1 - *cast(ushort *)p2;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return ushort.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
ushort t;
|
||||
|
||||
t = *cast(ushort *)p1;
|
||||
*cast(ushort *)p1 = *cast(ushort *)p2;
|
||||
*cast(ushort *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,92 +0,0 @@
|
||||
module std.typeinfo.ti_AC;
|
||||
|
||||
// Object[]
|
||||
|
||||
class TypeInfo_AC : TypeInfo
|
||||
{
|
||||
hash_t getHash(void *p)
|
||||
{ Object[] s = *cast(Object[]*)p;
|
||||
hash_t hash = 0;
|
||||
|
||||
foreach (Object o; s)
|
||||
{
|
||||
if (o)
|
||||
hash += o.toHash();
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
Object[] s1 = *cast(Object[]*)p1;
|
||||
Object[] s2 = *cast(Object[]*)p2;
|
||||
|
||||
if (s1.length == s2.length)
|
||||
{
|
||||
for (size_t u = 0; u < s1.length; u++)
|
||||
{ Object o1 = s1[u];
|
||||
Object o2 = s2[u];
|
||||
|
||||
// Do not pass null's to Object.opEquals()
|
||||
if (o1 is o2 ||
|
||||
(!(o1 is null) && !(o2 is null) && o1.opEquals(o2)))
|
||||
continue;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
Object[] s1 = *cast(Object[]*)p1;
|
||||
Object[] s2 = *cast(Object[]*)p2;
|
||||
int c;
|
||||
|
||||
c = cast(int)s1.length - cast(int)s2.length;
|
||||
if (c == 0)
|
||||
{
|
||||
for (size_t u = 0; u < s1.length; u++)
|
||||
{ Object o1 = s1[u];
|
||||
Object o2 = s2[u];
|
||||
|
||||
if (o1 is o2)
|
||||
continue;
|
||||
|
||||
// Regard null references as always being "less than"
|
||||
if (o1)
|
||||
{
|
||||
if (!o2)
|
||||
{ c = 1;
|
||||
break;
|
||||
}
|
||||
c = o1.opCmp(o2);
|
||||
if (c)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{ c = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (Object[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(Object);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
|
||||
* Written by Walter Bright
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, in both source and binary form, subject to the following
|
||||
* restrictions:
|
||||
*
|
||||
* o The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* o Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
* o This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
|
||||
module std.typeinfo.ti_Acdouble;
|
||||
|
||||
private import std.typeinfo.ti_cdouble;
|
||||
|
||||
// cdouble[]
|
||||
|
||||
class TypeInfo_Ar : TypeInfo
|
||||
{
|
||||
char[] toString() { return "cdouble[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ cdouble[] s = *cast(cdouble[]*)p;
|
||||
size_t len = s.length;
|
||||
cdouble *str = s.ptr;
|
||||
hash_t hash = 0;
|
||||
|
||||
while (len)
|
||||
{
|
||||
hash *= 9;
|
||||
hash += (cast(uint *)str)[0];
|
||||
hash += (cast(uint *)str)[1];
|
||||
hash += (cast(uint *)str)[2];
|
||||
hash += (cast(uint *)str)[3];
|
||||
str++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
cdouble[] s1 = *cast(cdouble[]*)p1;
|
||||
cdouble[] s2 = *cast(cdouble[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (len != s2.length)
|
||||
return 0;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_r._equals(s1[u], s2[u]);
|
||||
if (c == 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
cdouble[] s1 = *cast(cdouble[]*)p1;
|
||||
cdouble[] s2 = *cast(cdouble[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_r._compare(s1[u], s2[u]);
|
||||
if (c)
|
||||
return c;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (cdouble[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(cdouble);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
|
||||
* Written by Walter Bright
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, in both source and binary form, subject to the following
|
||||
* restrictions:
|
||||
*
|
||||
* o The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* o Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
* o This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
|
||||
module std.typeinfo.ti_Acfloat;
|
||||
|
||||
private import std.typeinfo.ti_cfloat;
|
||||
|
||||
// cfloat[]
|
||||
|
||||
class TypeInfo_Aq : TypeInfo
|
||||
{
|
||||
char[] toString() { return "cfloat[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ cfloat[] s = *cast(cfloat[]*)p;
|
||||
size_t len = s.length;
|
||||
cfloat *str = s.ptr;
|
||||
hash_t hash = 0;
|
||||
|
||||
while (len)
|
||||
{
|
||||
hash *= 9;
|
||||
hash += (cast(uint *)str)[0];
|
||||
hash += (cast(uint *)str)[1];
|
||||
str++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
cfloat[] s1 = *cast(cfloat[]*)p1;
|
||||
cfloat[] s2 = *cast(cfloat[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (len != s2.length)
|
||||
return 0;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_q._equals(s1[u], s2[u]);
|
||||
if (c == 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
cfloat[] s1 = *cast(cfloat[]*)p1;
|
||||
cfloat[] s2 = *cast(cfloat[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_q._compare(s1[u], s2[u]);
|
||||
if (c)
|
||||
return c;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (cfloat[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(cfloat);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
|
||||
* Written by Walter Bright
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, in both source and binary form, subject to the following
|
||||
* restrictions:
|
||||
*
|
||||
* o The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* o Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
* o This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
|
||||
module std.typeinfo.ti_Acreal;
|
||||
|
||||
private import std.typeinfo.ti_creal;
|
||||
|
||||
// creal[]
|
||||
|
||||
class TypeInfo_Ac : TypeInfo
|
||||
{
|
||||
char[] toString() { return "creal[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ creal[] s = *cast(creal[]*)p;
|
||||
size_t len = s.length;
|
||||
creal *str = s.ptr;
|
||||
hash_t hash = 0;
|
||||
|
||||
while (len)
|
||||
{
|
||||
hash *= 9;
|
||||
hash += (cast(uint *)str)[0];
|
||||
hash += (cast(uint *)str)[1];
|
||||
hash += (cast(uint *)str)[2];
|
||||
hash += (cast(uint *)str)[3];
|
||||
hash += (cast(uint *)str)[4];
|
||||
str++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
creal[] s1 = *cast(creal[]*)p1;
|
||||
creal[] s2 = *cast(creal[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (len != s2.length)
|
||||
return 0;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_c._equals(s1[u], s2[u]);
|
||||
if (c == 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
creal[] s1 = *cast(creal[]*)p1;
|
||||
creal[] s2 = *cast(creal[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_c._compare(s1[u], s2[u]);
|
||||
if (c)
|
||||
return c;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (creal[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(creal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,112 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
|
||||
* Written by Walter Bright
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, in both source and binary form, subject to the following
|
||||
* restrictions:
|
||||
*
|
||||
* o The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* o Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
* o This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
|
||||
module std.typeinfo.ti_Adouble;
|
||||
|
||||
private import std.typeinfo.ti_double;
|
||||
|
||||
// double[]
|
||||
|
||||
class TypeInfo_Ad : TypeInfo
|
||||
{
|
||||
char[] toString() { return "double[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ double[] s = *cast(double[]*)p;
|
||||
size_t len = s.length;
|
||||
auto str = s.ptr;
|
||||
hash_t hash = 0;
|
||||
|
||||
while (len)
|
||||
{
|
||||
hash *= 9;
|
||||
hash += (cast(uint *)str)[0];
|
||||
hash += (cast(uint *)str)[1];
|
||||
str++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
double[] s1 = *cast(double[]*)p1;
|
||||
double[] s2 = *cast(double[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (len != s2.length)
|
||||
return 0;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_d._equals(s1[u], s2[u]);
|
||||
if (c == 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
double[] s1 = *cast(double[]*)p1;
|
||||
double[] s2 = *cast(double[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_d._compare(s1[u], s2[u]);
|
||||
if (c)
|
||||
return c;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (double[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(double);
|
||||
}
|
||||
}
|
||||
|
||||
// idouble[]
|
||||
|
||||
class TypeInfo_Ap : TypeInfo_Ad
|
||||
{
|
||||
char[] toString() { return "idouble[]"; }
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(idouble);
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
|
||||
* Written by Walter Bright
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, in both source and binary form, subject to the following
|
||||
* restrictions:
|
||||
*
|
||||
* o The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* o Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
* o This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
|
||||
module std.typeinfo.ti_Afloat;
|
||||
|
||||
private import std.typeinfo.ti_float;
|
||||
|
||||
// float[]
|
||||
|
||||
class TypeInfo_Af : TypeInfo
|
||||
{
|
||||
char[] toString() { return "float[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ float[] s = *cast(float[]*)p;
|
||||
size_t len = s.length;
|
||||
auto str = s.ptr;
|
||||
hash_t hash = 0;
|
||||
|
||||
while (len)
|
||||
{
|
||||
hash *= 9;
|
||||
hash += *cast(uint *)str;
|
||||
str++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
float[] s1 = *cast(float[]*)p1;
|
||||
float[] s2 = *cast(float[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (len != s2.length)
|
||||
return 0;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_f._equals(s1[u], s2[u]);
|
||||
if (c == 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
float[] s1 = *cast(float[]*)p1;
|
||||
float[] s2 = *cast(float[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_f._compare(s1[u], s2[u]);
|
||||
if (c)
|
||||
return c;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (float[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(float);
|
||||
}
|
||||
}
|
||||
|
||||
// ifloat[]
|
||||
|
||||
class TypeInfo_Ao : TypeInfo_Af
|
||||
{
|
||||
char[] toString() { return "ifloat[]"; }
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(ifloat);
|
||||
}
|
||||
}
|
||||
@@ -1,202 +0,0 @@
|
||||
|
||||
module std.typeinfo.ti_Ag;
|
||||
|
||||
private import std.string;
|
||||
private import std.c.string;
|
||||
|
||||
// byte[]
|
||||
|
||||
class TypeInfo_Ag : TypeInfo
|
||||
{
|
||||
char[] toString() { return "byte[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ byte[] s = *cast(byte[]*)p;
|
||||
size_t len = s.length;
|
||||
byte *str = s.ptr;
|
||||
hash_t hash = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 9;
|
||||
hash += *cast(ubyte *)str;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash *= 9;
|
||||
hash += *cast(ushort *)str;
|
||||
return hash;
|
||||
|
||||
case 3:
|
||||
hash *= 9;
|
||||
hash += (*cast(ushort *)str << 8) +
|
||||
(cast(ubyte *)str)[2];
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 9;
|
||||
hash += *cast(uint *)str;
|
||||
str += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
byte[] s1 = *cast(byte[]*)p1;
|
||||
byte[] s2 = *cast(byte[]*)p2;
|
||||
|
||||
return s1.length == s2.length &&
|
||||
memcmp(cast(byte *)s1, cast(byte *)s2, s1.length) == 0;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
byte[] s1 = *cast(byte[]*)p1;
|
||||
byte[] s2 = *cast(byte[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int result = s1[u] - s2[u];
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (byte[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(byte);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ubyte[]
|
||||
|
||||
class TypeInfo_Ah : TypeInfo_Ag
|
||||
{
|
||||
char[] toString() { return "ubyte[]"; }
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
char[] s1 = *cast(char[]*)p1;
|
||||
char[] s2 = *cast(char[]*)p2;
|
||||
|
||||
return std.string.cmp(s1, s2);
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(ubyte);
|
||||
}
|
||||
}
|
||||
|
||||
// void[]
|
||||
|
||||
class TypeInfo_Av : TypeInfo_Ah
|
||||
{
|
||||
char[] toString() { return "void[]"; }
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(void);
|
||||
}
|
||||
}
|
||||
|
||||
// bool[]
|
||||
|
||||
class TypeInfo_Ab : TypeInfo_Ah
|
||||
{
|
||||
char[] toString() { return "bool[]"; }
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(bool);
|
||||
}
|
||||
}
|
||||
|
||||
// char[]
|
||||
|
||||
class TypeInfo_Aa : TypeInfo_Ag
|
||||
{
|
||||
char[] toString() { return "char[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ char[] s = *cast(char[]*)p;
|
||||
hash_t hash = 0;
|
||||
|
||||
version (all)
|
||||
{
|
||||
foreach (char c; s)
|
||||
hash = hash * 11 + c;
|
||||
}
|
||||
else
|
||||
{
|
||||
size_t len = s.length;
|
||||
char *str = s;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 9;
|
||||
hash += *cast(ubyte *)str;
|
||||
return hash;
|
||||
|
||||
case 2:
|
||||
hash *= 9;
|
||||
hash += *cast(ushort *)str;
|
||||
return hash;
|
||||
|
||||
case 3:
|
||||
hash *= 9;
|
||||
hash += (*cast(ushort *)str << 8) +
|
||||
(cast(ubyte *)str)[2];
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 9;
|
||||
hash += *cast(uint *)str;
|
||||
str += 4;
|
||||
len -= 4;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return hash;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(char);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,111 +0,0 @@
|
||||
|
||||
module std.typeinfo.ti_Aint;
|
||||
|
||||
private import std.c.string;
|
||||
|
||||
// int[]
|
||||
|
||||
class TypeInfo_Ai : TypeInfo
|
||||
{
|
||||
char[] toString() { return "int[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ int[] s = *cast(int[]*)p;
|
||||
auto len = s.length;
|
||||
auto str = s.ptr;
|
||||
hash_t hash = 0;
|
||||
|
||||
while (len)
|
||||
{
|
||||
hash *= 9;
|
||||
hash += *cast(uint *)str;
|
||||
str++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
int[] s1 = *cast(int[]*)p1;
|
||||
int[] s2 = *cast(int[]*)p2;
|
||||
|
||||
return s1.length == s2.length &&
|
||||
memcmp(cast(void *)s1, cast(void *)s2, s1.length * int.sizeof) == 0;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
int[] s1 = *cast(int[]*)p1;
|
||||
int[] s2 = *cast(int[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int result = s1[u] - s2[u];
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (int[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(int);
|
||||
}
|
||||
}
|
||||
|
||||
// uint[]
|
||||
|
||||
class TypeInfo_Ak : TypeInfo_Ai
|
||||
{
|
||||
char[] toString() { return "uint[]"; }
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
uint[] s1 = *cast(uint[]*)p1;
|
||||
uint[] s2 = *cast(uint[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int result = s1[u] - s2[u];
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(uint);
|
||||
}
|
||||
}
|
||||
|
||||
// dchar[]
|
||||
|
||||
class TypeInfo_Aw : TypeInfo_Ak
|
||||
{
|
||||
char[] toString() { return "dchar[]"; }
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(dchar);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,103 +0,0 @@
|
||||
|
||||
module std.typeinfo.ti_Along;
|
||||
|
||||
private import std.c.string;
|
||||
|
||||
// long[]
|
||||
|
||||
class TypeInfo_Al : TypeInfo
|
||||
{
|
||||
char[] toString() { return "long[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ long[] s = *cast(long[]*)p;
|
||||
size_t len = s.length;
|
||||
auto str = s.ptr;
|
||||
hash_t hash = 0;
|
||||
|
||||
while (len)
|
||||
{
|
||||
hash *= 9;
|
||||
hash += *cast(uint *)str + *(cast(uint *)str + 1);
|
||||
str++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
long[] s1 = *cast(long[]*)p1;
|
||||
long[] s2 = *cast(long[]*)p2;
|
||||
|
||||
return s1.length == s2.length &&
|
||||
memcmp(cast(void *)s1, cast(void *)s2, s1.length * long.sizeof) == 0;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
long[] s1 = *cast(long[]*)p1;
|
||||
long[] s2 = *cast(long[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
if (s1[u] < s2[u])
|
||||
return -1;
|
||||
else if (s1[u] > s2[u])
|
||||
return 1;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (long[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(long);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ulong[]
|
||||
|
||||
class TypeInfo_Am : TypeInfo_Al
|
||||
{
|
||||
char[] toString() { return "ulong[]"; }
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
ulong[] s1 = *cast(ulong[]*)p1;
|
||||
ulong[] s2 = *cast(ulong[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
if (s1[u] < s2[u])
|
||||
return -1;
|
||||
else if (s1[u] > s2[u])
|
||||
return 1;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(ulong);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,113 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2006 by Digital Mars, www.digitalmars.com
|
||||
* Written by Walter Bright
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, in both source and binary form, subject to the following
|
||||
* restrictions:
|
||||
*
|
||||
* o The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* o Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
* o This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
|
||||
module std.typeinfo.ti_Areal;
|
||||
|
||||
private import std.typeinfo.ti_real;
|
||||
|
||||
// real[]
|
||||
|
||||
class TypeInfo_Ae : TypeInfo
|
||||
{
|
||||
char[] toString() { return "real[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ real[] s = *cast(real[]*)p;
|
||||
size_t len = s.length;
|
||||
auto str = s.ptr;
|
||||
hash_t hash = 0;
|
||||
|
||||
while (len)
|
||||
{
|
||||
hash *= 9;
|
||||
hash += (cast(uint *)str)[0];
|
||||
hash += (cast(uint *)str)[1];
|
||||
hash += (cast(ushort *)str)[4];
|
||||
str++;
|
||||
len--;
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
real[] s1 = *cast(real[]*)p1;
|
||||
real[] s2 = *cast(real[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (len != s2.length)
|
||||
return 0;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_e._equals(s1[u], s2[u]);
|
||||
if (c == 0)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
real[] s1 = *cast(real[]*)p1;
|
||||
real[] s2 = *cast(real[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int c = TypeInfo_e._compare(s1[u], s2[u]);
|
||||
if (c)
|
||||
return c;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (real[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(real);
|
||||
}
|
||||
}
|
||||
|
||||
// ireal[]
|
||||
|
||||
class TypeInfo_Aj : TypeInfo_Ae
|
||||
{
|
||||
char[] toString() { return "ireal[]"; }
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(ireal);
|
||||
}
|
||||
}
|
||||
@@ -1,126 +0,0 @@
|
||||
|
||||
module std.typeinfo.ti_Ashort;
|
||||
|
||||
private import std.c.string;
|
||||
|
||||
// short[]
|
||||
|
||||
class TypeInfo_As : TypeInfo
|
||||
{
|
||||
char[] toString() { return "short[]"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{ short[] s = *cast(short[]*)p;
|
||||
size_t len = s.length;
|
||||
short *str = s.ptr;
|
||||
hash_t hash = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
switch (len)
|
||||
{
|
||||
case 0:
|
||||
return hash;
|
||||
|
||||
case 1:
|
||||
hash *= 9;
|
||||
hash += *cast(ushort *)str;
|
||||
return hash;
|
||||
|
||||
default:
|
||||
hash *= 9;
|
||||
hash += *cast(uint *)str;
|
||||
str += 2;
|
||||
len -= 2;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
short[] s1 = *cast(short[]*)p1;
|
||||
short[] s2 = *cast(short[]*)p2;
|
||||
|
||||
return s1.length == s2.length &&
|
||||
memcmp(cast(void *)s1, cast(void *)s2, s1.length * short.sizeof) == 0;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
short[] s1 = *cast(short[]*)p1;
|
||||
short[] s2 = *cast(short[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int result = s1[u] - s2[u];
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return (short[]).sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(short);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ushort[]
|
||||
|
||||
class TypeInfo_At : TypeInfo_As
|
||||
{
|
||||
char[] toString() { return "ushort[]"; }
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
ushort[] s1 = *cast(ushort[]*)p1;
|
||||
ushort[] s2 = *cast(ushort[]*)p2;
|
||||
size_t len = s1.length;
|
||||
|
||||
if (s2.length < len)
|
||||
len = s2.length;
|
||||
for (size_t u = 0; u < len; u++)
|
||||
{
|
||||
int result = s1[u] - s2[u];
|
||||
if (result)
|
||||
return result;
|
||||
}
|
||||
return cast(int)s1.length - cast(int)s2.length;
|
||||
}
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(ushort);
|
||||
}
|
||||
}
|
||||
|
||||
// wchar[]
|
||||
|
||||
class TypeInfo_Au : TypeInfo_At
|
||||
{
|
||||
char[] toString() { return "wchar[]"; }
|
||||
|
||||
TypeInfo next()
|
||||
{
|
||||
return typeid(wchar);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2005 by Digital Mars, www.digitalmars.com
|
||||
* Written by Walter Bright
|
||||
*
|
||||
* This software is provided 'as-is', without any express or implied
|
||||
* warranty. In no event will the authors be held liable for any damages
|
||||
* arising from the use of this software.
|
||||
*
|
||||
* Permission is granted to anyone to use this software for any purpose,
|
||||
* including commercial applications, and to alter it and redistribute it
|
||||
* freely, in both source and binary form, subject to the following
|
||||
* restrictions:
|
||||
*
|
||||
* o The origin of this software must not be misrepresented; you must not
|
||||
* claim that you wrote the original software. If you use this software
|
||||
* in a product, an acknowledgment in the product documentation would be
|
||||
* appreciated but is not required.
|
||||
* o Altered source versions must be plainly marked as such, and must not
|
||||
* be misrepresented as being the original software.
|
||||
* o This notice may not be removed or altered from any source
|
||||
* distribution.
|
||||
*/
|
||||
|
||||
module std.typeinfo.ti_C;
|
||||
|
||||
// Object
|
||||
|
||||
class TypeInfo_C : TypeInfo
|
||||
{
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
Object o = *cast(Object*)p;
|
||||
assert(o);
|
||||
return o.toHash();
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
Object o1 = *cast(Object*)p1;
|
||||
Object o2 = *cast(Object*)p2;
|
||||
|
||||
return o1 == o2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
Object o1 = *cast(Object*)p1;
|
||||
Object o2 = *cast(Object*)p2;
|
||||
int c = 0;
|
||||
|
||||
// Regard null references as always being "less than"
|
||||
if (!(o1 is o2))
|
||||
{
|
||||
if (o1)
|
||||
{ if (!o2)
|
||||
c = 1;
|
||||
else
|
||||
c = o1.opCmp(o2);
|
||||
}
|
||||
else
|
||||
c = -1;
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return Object.sizeof;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
|
||||
// cdouble
|
||||
|
||||
module std.typeinfo.ti_cdouble;
|
||||
|
||||
class TypeInfo_r : TypeInfo
|
||||
{
|
||||
char[] toString() { return "cdouble"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
|
||||
(cast(uint *)p)[2] + (cast(uint *)p)[3];
|
||||
}
|
||||
|
||||
static int _equals(cdouble f1, cdouble f2)
|
||||
{
|
||||
return f1 == f2;
|
||||
}
|
||||
|
||||
static int _compare(cdouble f1, cdouble f2)
|
||||
{ int result;
|
||||
|
||||
if (f1.re < f2.re)
|
||||
result = -1;
|
||||
else if (f1.re > f2.re)
|
||||
result = 1;
|
||||
else if (f1.im < f2.im)
|
||||
result = -1;
|
||||
else if (f1.im > f2.im)
|
||||
result = 1;
|
||||
else
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return _equals(*cast(cdouble *)p1, *cast(cdouble *)p2);
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return _compare(*cast(cdouble *)p1, *cast(cdouble *)p2);
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return cdouble.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
cdouble t;
|
||||
|
||||
t = *cast(cdouble *)p1;
|
||||
*cast(cdouble *)p1 = *cast(cdouble *)p2;
|
||||
*cast(cdouble *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static cdouble r;
|
||||
|
||||
return (cast(cdouble *)&r)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
|
||||
// cfloat
|
||||
|
||||
module std.typeinfo.ti_cfloat;
|
||||
|
||||
class TypeInfo_q : TypeInfo
|
||||
{
|
||||
char[] toString() { return "cfloat"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return (cast(uint *)p)[0] + (cast(uint *)p)[1];
|
||||
}
|
||||
|
||||
static int _equals(cfloat f1, cfloat f2)
|
||||
{
|
||||
return f1 == f2;
|
||||
}
|
||||
|
||||
static int _compare(cfloat f1, cfloat f2)
|
||||
{ int result;
|
||||
|
||||
if (f1.re < f2.re)
|
||||
result = -1;
|
||||
else if (f1.re > f2.re)
|
||||
result = 1;
|
||||
else if (f1.im < f2.im)
|
||||
result = -1;
|
||||
else if (f1.im > f2.im)
|
||||
result = 1;
|
||||
else
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return _equals(*cast(cfloat *)p1, *cast(cfloat *)p2);
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return _compare(*cast(cfloat *)p1, *cast(cfloat *)p2);
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return cfloat.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
cfloat t;
|
||||
|
||||
t = *cast(cfloat *)p1;
|
||||
*cast(cfloat *)p1 = *cast(cfloat *)p2;
|
||||
*cast(cfloat *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static cfloat r;
|
||||
|
||||
return (cast(cfloat *)&r)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
module std.typeinfo.ti_char;
|
||||
|
||||
class TypeInfo_a : TypeInfo
|
||||
{
|
||||
char[] toString() { return "char"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(char *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(char *)p1 == *cast(char *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *cast(char *)p1 - *cast(char *)p2;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return char.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
char t;
|
||||
|
||||
t = *cast(char *)p1;
|
||||
*cast(char *)p1 = *cast(char *)p2;
|
||||
*cast(char *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static char c;
|
||||
|
||||
return (cast(char *)&c)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
|
||||
// creal
|
||||
|
||||
module std.typeinfo.ti_creal;
|
||||
|
||||
class TypeInfo_c : TypeInfo
|
||||
{
|
||||
char[] toString() { return "creal"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return (cast(uint *)p)[0] + (cast(uint *)p)[1] +
|
||||
(cast(uint *)p)[2] + (cast(uint *)p)[3] +
|
||||
(cast(uint *)p)[4];
|
||||
}
|
||||
|
||||
static int _equals(creal f1, creal f2)
|
||||
{
|
||||
return f1 == f2;
|
||||
}
|
||||
|
||||
static int _compare(creal f1, creal f2)
|
||||
{ int result;
|
||||
|
||||
if (f1.re < f2.re)
|
||||
result = -1;
|
||||
else if (f1.re > f2.re)
|
||||
result = 1;
|
||||
else if (f1.im < f2.im)
|
||||
result = -1;
|
||||
else if (f1.im > f2.im)
|
||||
result = 1;
|
||||
else
|
||||
result = 0;
|
||||
return result;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return _equals(*cast(creal *)p1, *cast(creal *)p2);
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return _compare(*cast(creal *)p1, *cast(creal *)p2);
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return creal.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
creal t;
|
||||
|
||||
t = *cast(creal *)p1;
|
||||
*cast(creal *)p1 = *cast(creal *)p2;
|
||||
*cast(creal *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static creal r;
|
||||
|
||||
return (cast(creal *)&r)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
|
||||
// dchar
|
||||
|
||||
module std.typeinfo.ti_dchar;
|
||||
|
||||
class TypeInfo_w : TypeInfo
|
||||
{
|
||||
char[] toString() { return "dchar"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(dchar *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(dchar *)p1 == *cast(dchar *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *cast(dchar *)p1 - *cast(dchar *)p2;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return dchar.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
dchar t;
|
||||
|
||||
t = *cast(dchar *)p1;
|
||||
*cast(dchar *)p1 = *cast(dchar *)p2;
|
||||
*cast(dchar *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static dchar c;
|
||||
|
||||
return (cast(dchar *)&c)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
|
||||
// delegate
|
||||
|
||||
module std.typeinfo.ti_delegate;
|
||||
|
||||
alias void delegate(int) dg;
|
||||
|
||||
class TypeInfo_D : TypeInfo
|
||||
{
|
||||
hash_t getHash(void *p)
|
||||
{ long l = *cast(long *)p;
|
||||
|
||||
return cast(uint)(l + (l >> 32));
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(dg *)p1 == *cast(dg *)p2;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return dg.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
dg t;
|
||||
|
||||
t = *cast(dg *)p1;
|
||||
*cast(dg *)p1 = *cast(dg *)p2;
|
||||
*cast(dg *)p2 = t;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
|
||||
// double
|
||||
|
||||
module std.typeinfo.ti_double;
|
||||
|
||||
private import std.math;
|
||||
|
||||
class TypeInfo_d : TypeInfo
|
||||
{
|
||||
char[] toString() { return "double"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return (cast(uint *)p)[0] + (cast(uint *)p)[1];
|
||||
}
|
||||
|
||||
static int _equals(double f1, double f2)
|
||||
{
|
||||
return f1 == f2 ||
|
||||
(isnan(f1) && isnan(f2));
|
||||
}
|
||||
|
||||
static int _compare(double d1, double d2)
|
||||
{
|
||||
if (d1 !<>= d2) // if either are NaN
|
||||
{
|
||||
if (isnan(d1))
|
||||
{ if (isnan(d2))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return _equals(*cast(double *)p1, *cast(double *)p2);
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return _compare(*cast(double *)p1, *cast(double *)p2);
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return double.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
double t;
|
||||
|
||||
t = *cast(double *)p1;
|
||||
*cast(double *)p1 = *cast(double *)p2;
|
||||
*cast(double *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static double r;
|
||||
|
||||
return (cast(double *)&r)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
|
||||
// float
|
||||
|
||||
module std.typeinfo.ti_float;
|
||||
|
||||
private import std.math;
|
||||
|
||||
class TypeInfo_f : TypeInfo
|
||||
{
|
||||
char[] toString() { return "float"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(uint *)p;
|
||||
}
|
||||
|
||||
static int _equals(float f1, float f2)
|
||||
{
|
||||
return f1 == f2 ||
|
||||
(isnan(f1) && isnan(f2));
|
||||
}
|
||||
|
||||
static int _compare(float d1, float d2)
|
||||
{
|
||||
if (d1 !<>= d2) // if either are NaN
|
||||
{
|
||||
if (isnan(d1))
|
||||
{ if (isnan(d2))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return _equals(*cast(float *)p1, *cast(float *)p2);
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return _compare(*cast(float *)p1, *cast(float *)p2);
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return float.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
float t;
|
||||
|
||||
t = *cast(float *)p1;
|
||||
*cast(float *)p1 = *cast(float *)p2;
|
||||
*cast(float *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static float r;
|
||||
|
||||
return (cast(float *)&r)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
// idouble
|
||||
|
||||
module std.typeinfo.ti_idouble;
|
||||
|
||||
private import std.typeinfo.ti_double;
|
||||
|
||||
class TypeInfo_p : TypeInfo_d
|
||||
{
|
||||
char[] toString() { return "idouble"; }
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
// ifloat
|
||||
|
||||
module std.typeinfo.ti_ifloat;
|
||||
|
||||
private import std.typeinfo.ti_float;
|
||||
|
||||
class TypeInfo_o : TypeInfo_f
|
||||
{
|
||||
char[] toString() { return "ifloat"; }
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
// int
|
||||
|
||||
module std.typeinfo.ti_int;
|
||||
|
||||
class TypeInfo_i : TypeInfo
|
||||
{
|
||||
char[] toString() { return "int"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(uint *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(uint *)p1 == *cast(uint *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
if (*cast(int*) p1 < *cast(int*) p2)
|
||||
return -1;
|
||||
else if (*cast(int*) p1 > *cast(int*) p2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return int.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
int t;
|
||||
|
||||
t = *cast(int *)p1;
|
||||
*cast(int *)p1 = *cast(int *)p2;
|
||||
*cast(int *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
|
||||
// ireal
|
||||
|
||||
module std.typeinfo.ti_ireal;
|
||||
|
||||
private import std.typeinfo.ti_real;
|
||||
|
||||
class TypeInfo_j : TypeInfo_e
|
||||
{
|
||||
char[] toString() { return "ireal"; }
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
// long
|
||||
|
||||
module std.typeinfo.ti_long;
|
||||
|
||||
class TypeInfo_l : TypeInfo
|
||||
{
|
||||
char[] toString() { return "long"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(uint *)p + (cast(uint *)p)[1];
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(long *)p1 == *cast(long *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
if (*cast(long *)p1 < *cast(long *)p2)
|
||||
return -1;
|
||||
else if (*cast(long *)p1 > *cast(long *)p2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return long.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
long t;
|
||||
|
||||
t = *cast(long *)p1;
|
||||
*cast(long *)p1 = *cast(long *)p2;
|
||||
*cast(long *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
|
||||
// real
|
||||
|
||||
module std.typeinfo.ti_real;
|
||||
|
||||
private import std.math;
|
||||
|
||||
class TypeInfo_e : TypeInfo
|
||||
{
|
||||
char[] toString() { return "real"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return (cast(uint *)p)[0] + (cast(uint *)p)[1] + (cast(ushort *)p)[4];
|
||||
}
|
||||
|
||||
static int _equals(real f1, real f2)
|
||||
{
|
||||
return f1 == f2 ||
|
||||
(isnan(f1) && isnan(f2));
|
||||
}
|
||||
|
||||
static int _compare(real d1, real d2)
|
||||
{
|
||||
if (d1 !<>= d2) // if either are NaN
|
||||
{
|
||||
if (isnan(d1))
|
||||
{ if (isnan(d2))
|
||||
return 0;
|
||||
return -1;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
return (d1 == d2) ? 0 : ((d1 < d2) ? -1 : 1);
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return _equals(*cast(real *)p1, *cast(real *)p2);
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return _compare(*cast(real *)p1, *cast(real *)p2);
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return real.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
real t;
|
||||
|
||||
t = *cast(real *)p1;
|
||||
*cast(real *)p1 = *cast(real *)p2;
|
||||
*cast(real *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static real r;
|
||||
|
||||
return (cast(real *)&r)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
|
||||
// short
|
||||
|
||||
module std.typeinfo.ti_short;
|
||||
|
||||
class TypeInfo_s : TypeInfo
|
||||
{
|
||||
char[] toString() { return "short"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(short *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(short *)p1 == *cast(short *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *cast(short *)p1 - *cast(short *)p2;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return short.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
short t;
|
||||
|
||||
t = *cast(short *)p1;
|
||||
*cast(short *)p1 = *cast(short *)p2;
|
||||
*cast(short *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
// ubyte
|
||||
|
||||
module std.typeinfo.ti_ubyte;
|
||||
|
||||
class TypeInfo_h : TypeInfo
|
||||
{
|
||||
char[] toString() { return "ubyte"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(ubyte *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(ubyte *)p1 == *cast(ubyte *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *cast(ubyte *)p1 - *cast(ubyte *)p2;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return ubyte.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
ubyte t;
|
||||
|
||||
t = *cast(ubyte *)p1;
|
||||
*cast(ubyte *)p1 = *cast(ubyte *)p2;
|
||||
*cast(ubyte *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
||||
class TypeInfo_b : TypeInfo_h
|
||||
{
|
||||
char[] toString() { return "bool"; }
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
// uint
|
||||
|
||||
module std.typeinfo.ti_uint;
|
||||
|
||||
class TypeInfo_k : TypeInfo
|
||||
{
|
||||
char[] toString() { return "uint"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(uint *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(uint *)p1 == *cast(uint *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
if (*cast(uint*) p1 < *cast(uint*) p2)
|
||||
return -1;
|
||||
else if (*cast(uint*) p1 > *cast(uint*) p2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return uint.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
int t;
|
||||
|
||||
t = *cast(uint *)p1;
|
||||
*cast(uint *)p1 = *cast(uint *)p2;
|
||||
*cast(uint *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
|
||||
// ulong
|
||||
|
||||
module std.typeinfo.ti_ulong;
|
||||
|
||||
class TypeInfo_m : TypeInfo
|
||||
{
|
||||
char[] toString() { return "ulong"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(uint *)p + (cast(uint *)p)[1];
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(ulong *)p1 == *cast(ulong *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
if (*cast(ulong *)p1 < *cast(ulong *)p2)
|
||||
return -1;
|
||||
else if (*cast(ulong *)p1 > *cast(ulong *)p2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return ulong.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
ulong t;
|
||||
|
||||
t = *cast(ulong *)p1;
|
||||
*cast(ulong *)p1 = *cast(ulong *)p2;
|
||||
*cast(ulong *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
// void
|
||||
|
||||
module std.typeinfo.ti_void;
|
||||
|
||||
class TypeInfo_v : TypeInfo
|
||||
{
|
||||
char[] toString() { return "void"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
assert(0);
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(byte *)p1 == *cast(byte *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *cast(byte *)p1 - *cast(byte *)p2;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return void.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
byte t;
|
||||
|
||||
t = *cast(byte *)p1;
|
||||
*cast(byte *)p1 = *cast(byte *)p2;
|
||||
*cast(byte *)p2 = t;
|
||||
}
|
||||
|
||||
uint flags()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
|
||||
module std.typeinfo.ti_wchar;
|
||||
|
||||
|
||||
class TypeInfo_u : TypeInfo
|
||||
{
|
||||
char[] toString() { return "wchar"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(wchar *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(wchar *)p1 == *cast(wchar *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
return *cast(wchar *)p1 - *cast(wchar *)p2;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return wchar.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
wchar t;
|
||||
|
||||
t = *cast(wchar *)p1;
|
||||
*cast(wchar *)p1 = *cast(wchar *)p2;
|
||||
*cast(wchar *)p2 = t;
|
||||
}
|
||||
|
||||
void[] init()
|
||||
{ static wchar c;
|
||||
|
||||
return (cast(wchar *)&c)[0 .. 1];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// byte
|
||||
|
||||
module std.typeinfo.ti_byte;
|
||||
module typeinfo.ti_byte;
|
||||
|
||||
class TypeInfo_g : TypeInfo
|
||||
{
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
module std.typeinfo.ti_char;
|
||||
module typeinfo.ti_char;
|
||||
|
||||
class TypeInfo_a : TypeInfo
|
||||
{
|
||||
@@ -1,43 +1,43 @@
|
||||
|
||||
// int
|
||||
|
||||
module std.typeinfo.ti_int;
|
||||
|
||||
class TypeInfo_i : TypeInfo
|
||||
{
|
||||
char[] toString() { return "int"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(uint *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(uint *)p1 == *cast(uint *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
if (*cast(int*) p1 < *cast(int*) p2)
|
||||
return -1;
|
||||
else if (*cast(int*) p1 > *cast(int*) p2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return int.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
int t;
|
||||
|
||||
t = *cast(int *)p1;
|
||||
*cast(int *)p1 = *cast(int *)p2;
|
||||
*cast(int *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// int
|
||||
|
||||
module typeinfo.ti_int;
|
||||
|
||||
class TypeInfo_i : TypeInfo
|
||||
{
|
||||
char[] toString() { return "int"; }
|
||||
|
||||
hash_t getHash(void *p)
|
||||
{
|
||||
return *cast(uint *)p;
|
||||
}
|
||||
|
||||
int equals(void *p1, void *p2)
|
||||
{
|
||||
return *cast(uint *)p1 == *cast(uint *)p2;
|
||||
}
|
||||
|
||||
int compare(void *p1, void *p2)
|
||||
{
|
||||
if (*cast(int*) p1 < *cast(int*) p2)
|
||||
return -1;
|
||||
else if (*cast(int*) p1 > *cast(int*) p2)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t tsize()
|
||||
{
|
||||
return int.sizeof;
|
||||
}
|
||||
|
||||
void swap(void *p1, void *p2)
|
||||
{
|
||||
int t;
|
||||
|
||||
t = *cast(int *)p1;
|
||||
*cast(int *)p1 = *cast(int *)p2;
|
||||
*cast(int *)p2 = t;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// pointer
|
||||
|
||||
module std.typeinfo.ti_ptr;
|
||||
module typeinfo.ti_ptr;
|
||||
|
||||
class TypeInfo_P : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// short
|
||||
|
||||
module std.typeinfo.ti_short;
|
||||
module typeinfo.ti_short;
|
||||
|
||||
class TypeInfo_s : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// ubyte
|
||||
|
||||
module std.typeinfo.ti_ubyte;
|
||||
module typeinfo.ti_ubyte;
|
||||
|
||||
class TypeInfo_h : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// uint
|
||||
|
||||
module std.typeinfo.ti_uint;
|
||||
module typeinfo.ti_uint;
|
||||
|
||||
class TypeInfo_k : TypeInfo
|
||||
{
|
||||
@@ -1,7 +1,7 @@
|
||||
|
||||
// ushort
|
||||
|
||||
module std.typeinfo.ti_ushort;
|
||||
module typeinfo.ti_ushort;
|
||||
|
||||
class TypeInfo_t : TypeInfo
|
||||
{
|
||||
8
test/bug26.d
Normal file
8
test/bug26.d
Normal file
@@ -0,0 +1,8 @@
|
||||
module bug26;
|
||||
|
||||
extern int i;
|
||||
|
||||
void main()
|
||||
{
|
||||
int j = i;
|
||||
}
|
||||
17
test/bug27.d
Normal file
17
test/bug27.d
Normal file
@@ -0,0 +1,17 @@
|
||||
module bug27;
|
||||
|
||||
int func(int a, int b)
|
||||
{
|
||||
if (a == b)
|
||||
return 0;
|
||||
else if (a < b)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
int i = func(3,4);
|
||||
assert(i == -1);
|
||||
}
|
||||
17
test/bug28.d
Normal file
17
test/bug28.d
Normal file
@@ -0,0 +1,17 @@
|
||||
module bug28;
|
||||
|
||||
void main()
|
||||
{
|
||||
char[] a = "hello";
|
||||
char[] b = "hello";
|
||||
char[] c = "world";
|
||||
char[] d = "somethingelse";
|
||||
assert(a == a);
|
||||
assert(a == b);
|
||||
assert(a != c);
|
||||
assert(b != c);
|
||||
assert(a != d);
|
||||
assert(b != d);
|
||||
assert(c != d);
|
||||
assert(d == d);
|
||||
}
|
||||
15
test/bug29.d
Normal file
15
test/bug29.d
Normal file
@@ -0,0 +1,15 @@
|
||||
module bug29;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[] arr16 = new int[4];
|
||||
{
|
||||
void[] arr = arr16;
|
||||
{
|
||||
printf("%lu\n", arr.length);
|
||||
{
|
||||
assert(arr.length == 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
22
test/bug30.d
Normal file
22
test/bug30.d
Normal file
@@ -0,0 +1,22 @@
|
||||
module bug30;
|
||||
|
||||
void main()
|
||||
{
|
||||
int[] a = new int[4];
|
||||
{a[0] = 1;
|
||||
a[1] = 2;
|
||||
a[2] = 3;
|
||||
a[3] = 4;}
|
||||
int[] b = new int[4];
|
||||
{b[0] = 1;
|
||||
b[1] = 2;
|
||||
b[2] = 3;
|
||||
b[3] = 4;}
|
||||
int[] c = new int[4];
|
||||
{c[0] = 1;
|
||||
c[1] = 2;
|
||||
c[2] = 4;
|
||||
c[3] = 3;}
|
||||
{assert(a == b);}
|
||||
{assert(a != c);}
|
||||
}
|
||||
12
test/enum1.d
Normal file
12
test/enum1.d
Normal file
@@ -0,0 +1,12 @@
|
||||
module enum1;
|
||||
|
||||
void main()
|
||||
{
|
||||
enum {
|
||||
HELLO,
|
||||
WORLD
|
||||
}
|
||||
|
||||
assert(HELLO == 0);
|
||||
assert(WORLD == 1);
|
||||
}
|
||||
10
test/enum2.d
Normal file
10
test/enum2.d
Normal file
@@ -0,0 +1,10 @@
|
||||
module enum2;
|
||||
|
||||
void main()
|
||||
{
|
||||
enum E {
|
||||
A,B
|
||||
}
|
||||
E e = E.B;
|
||||
assert(e == E.B);
|
||||
}
|
||||
15
test/enum3.d
Normal file
15
test/enum3.d
Normal file
@@ -0,0 +1,15 @@
|
||||
module enum3;
|
||||
|
||||
enum GE : ushort
|
||||
{
|
||||
A,B,C
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
GE e = GE.B;
|
||||
size_t s = GE.sizeof;
|
||||
assert(e == 1);
|
||||
assert(e.sizeof == s);
|
||||
assert(s == 2);
|
||||
}
|
||||
@@ -8,8 +8,8 @@ struct S
|
||||
|
||||
void main()
|
||||
{
|
||||
S[4] arr;
|
||||
S[4] arr = void;
|
||||
foreach(i,v;arr) {
|
||||
v = S(i,i*2.5);
|
||||
v = S(i, i*2.5);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,4 +3,7 @@ module typeinfo;
|
||||
void main()
|
||||
{
|
||||
auto ti = typeid(int);
|
||||
char[] str = ti.toString();
|
||||
printf("%.*s\n", str.length, str.ptr);
|
||||
assert(str == "int");
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user