Mercurial > projects > ldc
comparison gen/toir.c @ 58:2c3cd3596187 trunk
[svn r62] Added support for TypeInfo _Array, _Function, _Pointer, _Delegate, _Enum
Added initial support for CatExp aka 'a ~ b'
Fixed global constant static arrays initialized with string literals
Fixed casting any dynamic array to void*
Fixed new expression with temporary storage
Fixed alias declarations in function scope
Fixed relational comparisons of pointers
author | lindquist |
---|---|
date | Thu, 25 Oct 2007 09:02:55 +0200 |
parents | a9d29e9f1fed |
children | b86e00b938a5 |
comparison
equal
deleted
inserted
replaced
57:a9d29e9f1fed | 58:2c3cd3596187 |
---|---|
80 f->toObjFile(); | 80 f->toObjFile(); |
81 } | 81 } |
82 // alias declaration | 82 // alias declaration |
83 else if (AliasDeclaration* a = declaration->isAliasDeclaration()) | 83 else if (AliasDeclaration* a = declaration->isAliasDeclaration()) |
84 { | 84 { |
85 Logger::println("AliasDeclaration"); | 85 Logger::println("AliasDeclaration - no work"); |
86 assert(0); | 86 // do nothing |
87 } | 87 } |
88 else if (EnumDeclaration* e = declaration->isEnumDeclaration()) | 88 else if (EnumDeclaration* e = declaration->isEnumDeclaration()) |
89 { | 89 { |
90 Logger::println("EnumDeclaration - no work"); | |
90 // do nothing | 91 // do nothing |
91 } | 92 } |
92 // unsupported declaration | 93 // unsupported declaration |
93 else | 94 else |
94 { | 95 { |
160 e->type = elem::VAL; | 161 e->type = elem::VAL; |
161 } | 162 } |
162 // typeinfo | 163 // typeinfo |
163 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) | 164 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration()) |
164 { | 165 { |
165 assert(0); | 166 tid->toObjFile(); |
167 assert(tid->llvmValue); | |
168 e->val = tid->llvmValue; | |
169 e->type = elem::VAR; | |
166 } | 170 } |
167 // global forward ref | 171 // global forward ref |
168 else { | 172 else { |
169 Logger::println("unsupported magic: %s\n", vd->toChars()); | 173 Logger::println("unsupported magic: %s\n", vd->toChars()); |
170 assert(0 && "only magic supported is $, _arguments, _argptr"); | 174 assert(0 && "only magic supported is $, _arguments, _argptr"); |
436 uint8_t* str = (uint8_t*)string; | 440 uint8_t* str = (uint8_t*)string; |
437 std::string cont((char*)str, len); | 441 std::string cont((char*)str, len); |
438 | 442 |
439 Type* t = LLVM_DtoDType(type); | 443 Type* t = LLVM_DtoDType(type); |
440 | 444 |
445 if (t->ty == Tsarray) { | |
446 return llvm::ConstantArray::get(cont,false); | |
447 } | |
441 llvm::Constant* _init = llvm::ConstantArray::get(cont,true); | 448 llvm::Constant* _init = llvm::ConstantArray::get(cont,true); |
442 if (t->ty == Tsarray) { | 449 |
443 return _init; | |
444 } | |
445 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; | 450 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; |
446 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,"stringliteral",gIR->module); | 451 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,"stringliteral",gIR->module); |
447 | 452 |
448 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 453 llvm::ConstantInt* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
449 llvm::Constant* idxs[2] = { zero, zero }; | 454 llvm::Constant* idxs[2] = { zero, zero }; |
1340 } | 1345 } |
1341 else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) { | 1346 else if (fromtype->ty == Tarray || fromtype->ty == Tsarray) { |
1342 Logger::cout() << "from array or sarray" << '\n'; | 1347 Logger::cout() << "from array or sarray" << '\n'; |
1343 if (totype->ty == Tpointer) { | 1348 if (totype->ty == Tpointer) { |
1344 Logger::cout() << "to pointer" << '\n'; | 1349 Logger::cout() << "to pointer" << '\n'; |
1345 assert(fromtype->next == totype->next); | 1350 assert(fromtype->next == totype->next || totype->next->ty == Tvoid); |
1346 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); | 1351 llvm::Value* zero = llvm::ConstantInt::get(llvm::Type::Int32Ty, 0, false); |
1347 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); | 1352 llvm::Value* one = llvm::ConstantInt::get(llvm::Type::Int32Ty, 1, false); |
1348 llvm::Value* ptr = LLVM_DtoGEP(u->getValue(),zero,one,"tmp",p->scopebb()); | 1353 llvm::Value* ptr = LLVM_DtoGEP(u->getValue(),zero,one,"tmp",p->scopebb()); |
1349 e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb()); | 1354 e->val = new llvm::LoadInst(ptr, "tmp", p->scopebb()); |
1355 if (fromtype->next != totype->next) | |
1356 e->val = p->ir->CreateBitCast(e->val, llvm::PointerType::get(llvm::Type::Int8Ty), "tmp"); | |
1350 e->type = elem::VAL; | 1357 e->type = elem::VAL; |
1351 } | 1358 } |
1352 else if (totype->ty == Tarray) { | 1359 else if (totype->ty == Tarray) { |
1353 Logger::cout() << "to array" << '\n'; | 1360 Logger::cout() << "to array" << '\n'; |
1354 const llvm::Type* ptrty = LLVM_DtoType(totype->next); | 1361 const llvm::Type* ptrty = LLVM_DtoType(totype->next); |
1888 | 1895 |
1889 Type* t = LLVM_DtoDType(e1->type); | 1896 Type* t = LLVM_DtoDType(e1->type); |
1890 Type* e2t = LLVM_DtoDType(e2->type); | 1897 Type* e2t = LLVM_DtoDType(e2->type); |
1891 assert(t == e2t); | 1898 assert(t == e2t); |
1892 | 1899 |
1893 if (t->isintegral()) | 1900 if (t->isintegral() || t->ty == Tpointer) |
1894 { | 1901 { |
1895 llvm::ICmpInst::Predicate cmpop; | 1902 llvm::ICmpInst::Predicate cmpop; |
1896 bool skip = false; | 1903 bool skip = false; |
1897 switch(op) | 1904 switch(op) |
1898 { | 1905 { |
2130 assert(!newargs); | 2137 assert(!newargs); |
2131 assert(newtype); | 2138 assert(newtype); |
2132 assert(!allocator); | 2139 assert(!allocator); |
2133 | 2140 |
2134 elem* e = new elem; | 2141 elem* e = new elem; |
2142 e->inplace = true; | |
2135 | 2143 |
2136 Type* ntype = LLVM_DtoDType(newtype); | 2144 Type* ntype = LLVM_DtoDType(newtype); |
2137 | 2145 |
2138 const llvm::Type* t = LLVM_DtoType(ntype); | 2146 const llvm::Type* t = LLVM_DtoType(ntype); |
2139 | 2147 |
2148 else if (ntype->ty == Tarray) { | 2156 else if (ntype->ty == Tarray) { |
2149 assert(arguments); | 2157 assert(arguments); |
2150 if (arguments->dim == 1) { | 2158 if (arguments->dim == 1) { |
2151 elem* sz = ((Expression*)arguments->data[0])->toElem(p); | 2159 elem* sz = ((Expression*)arguments->data[0])->toElem(p); |
2152 llvm::Value* dimval = sz->getValue(); | 2160 llvm::Value* dimval = sz->getValue(); |
2153 assert(p->topexp() && p->topexp()->e2 == this && p->topexp()->v); | 2161 Type* nnt = LLVM_DtoDType(ntype->next); |
2154 LLVM_DtoNewDynArray(p->topexp()->v, dimval, ntype->next); | 2162 if (nnt->ty == Tvoid) |
2163 nnt = Type::tint8; | |
2164 if (!p->topexp() || p->topexp()->e2 != this) { | |
2165 const llvm::Type* restype = LLVM_DtoType(type); | |
2166 Logger::cout() << "restype = " << *restype << '\n'; | |
2167 e->mem = new llvm::AllocaInst(restype,"tmp",p->topallocapoint()); | |
2168 LLVM_DtoNewDynArray(e->mem, dimval, nnt); | |
2169 e->inplace = false; | |
2170 } | |
2171 else if (p->topexp() || p->topexp()->e2 != this) { | |
2172 assert(p->topexp()->v); | |
2173 e->mem = p->topexp()->v; | |
2174 LLVM_DtoNewDynArray(e->mem, dimval, nnt); | |
2175 } | |
2176 else | |
2177 assert(0); | |
2155 delete sz; | 2178 delete sz; |
2156 } | 2179 } |
2157 else { | 2180 else { |
2158 assert(0); | 2181 assert(0); |
2159 } | 2182 } |
2195 else { | 2218 else { |
2196 LLVM_DtoStructCopy(e->mem,ts->llvmInit); | 2219 LLVM_DtoStructCopy(e->mem,ts->llvmInit); |
2197 } | 2220 } |
2198 } | 2221 } |
2199 | 2222 |
2200 e->inplace = true; | |
2201 e->type = elem::VAR; | 2223 e->type = elem::VAR; |
2202 | 2224 |
2203 return e; | 2225 return e; |
2204 } | 2226 } |
2205 | 2227 |
2659 elem* CatExp::toElem(IRState* p) | 2681 elem* CatExp::toElem(IRState* p) |
2660 { | 2682 { |
2661 Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars()); | 2683 Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars()); |
2662 LOG_SCOPE; | 2684 LOG_SCOPE; |
2663 | 2685 |
2664 assert(0 && "array cat is not yet implemented"); | 2686 Type* t = LLVM_DtoDType(type); |
2665 | 2687 |
2666 elem* lhs = e1->toElem(p); | 2688 bool inplace = false; |
2667 elem* rhs = e2->toElem(p); | 2689 llvm::Value* dst = 0; |
2668 | 2690 IRExp* ex = p->topexp(); |
2669 // determine new size | 2691 if (ex && ex->e2 == this) { |
2670 | 2692 assert(ex->v); |
2671 delete lhs; | 2693 dst = ex->v; |
2672 delete rhs; | 2694 inplace = true; |
2673 | 2695 } |
2674 return 0; | 2696 else { |
2697 assert(t->ty == Tarray); | |
2698 const llvm::Type* arrty = LLVM_DtoType(t); | |
2699 dst = new llvm::AllocaInst(arrty, "tmpmem", p->topallocapoint()); | |
2700 } | |
2701 | |
2702 LLVM_DtoCatArrays(dst,e1,e2); | |
2703 | |
2704 elem* e = new elem; | |
2705 e->mem = dst; | |
2706 e->type = elem::VAR; | |
2707 e->inplace = inplace; | |
2708 | |
2709 return e; | |
2675 } | 2710 } |
2676 | 2711 |
2677 ////////////////////////////////////////////////////////////////////////////////////////// | 2712 ////////////////////////////////////////////////////////////////////////////////////////// |
2678 | 2713 |
2679 elem* CatAssignExp::toElem(IRState* p) | 2714 elem* CatAssignExp::toElem(IRState* p) |
2687 Type* e1type = LLVM_DtoDType(e1->type); | 2722 Type* e1type = LLVM_DtoDType(e1->type); |
2688 Type* elemtype = LLVM_DtoDType(e1type->next); | 2723 Type* elemtype = LLVM_DtoDType(e1type->next); |
2689 Type* e2type = LLVM_DtoDType(e2->type); | 2724 Type* e2type = LLVM_DtoDType(e2->type); |
2690 | 2725 |
2691 if (e2type == elemtype) { | 2726 if (e2type == elemtype) { |
2692 LLVM_DtoCatArrayElement(l->mem,e2); | 2727 LLVM_DtoCatAssignElement(l->mem,e2); |
2693 } | 2728 } |
2694 else | 2729 else |
2695 assert(0 && "only one element at a time right now"); | 2730 assert(0 && "only one element at a time right now"); |
2696 | 2731 |
2697 return 0; | 2732 return 0; |