annotate gen/toir.cpp @ 825:a70ddd449e7d

Commented some logging that could be '''very''' long, cuts -vv output size of a gtkd gl sample down 1.2GB by 3/4. Fixed wrong pointer type for multidimension "deep" slicing.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Thu, 04 Dec 2008 16:11:09 +0100
parents 794c8af186ce
children f466f475b654
rev   line source
lindquist@1 1 // Backend stubs
lindquist@1 2
lindquist@1 3 /* DMDFE backend stubs
lindquist@1 4 * This file contains the implementations of the backend routines.
lindquist@1 5 * For dmdfe these do nothing but print a message saying the module
lindquist@1 6 * has been parsed. Substitute your own behaviors for these routimes.
lindquist@1 7 */
lindquist@1 8
lindquist@1 9 #include <stdio.h>
lindquist@1 10 #include <math.h>
lindquist@1 11 #include <sstream>
lindquist@1 12 #include <fstream>
lindquist@1 13 #include <iostream>
lindquist@1 14
lindquist@40 15 #include "gen/llvm.h"
lindquist@1 16
lindquist@132 17 #include "attrib.h"
lindquist@1 18 #include "total.h"
lindquist@1 19 #include "init.h"
lindquist@1 20 #include "mtype.h"
ChristianK@321 21 #include "template.h"
lindquist@1 22 #include "hdrgen.h"
lindquist@1 23 #include "port.h"
kamm@594 24 #include "mem.h"
lindquist@4 25
lindquist@4 26 #include "gen/irstate.h"
lindquist@4 27 #include "gen/logger.h"
lindquist@4 28 #include "gen/tollvm.h"
lindquist@244 29 #include "gen/llvmhelpers.h"
lindquist@4 30 #include "gen/runtime.h"
lindquist@4 31 #include "gen/arrays.h"
lindquist@88 32 #include "gen/structs.h"
lindquist@100 33 #include "gen/classes.h"
lindquist@102 34 #include "gen/typeinf.h"
lindquist@104 35 #include "gen/complex.h"
lindquist@86 36 #include "gen/dvalue.h"
lindquist@109 37 #include "gen/aa.h"
lindquist@131 38 #include "gen/functions.h"
lindquist@244 39 #include "gen/todebug.h"
lindquist@86 40
lindquist@1 41 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 42
lindquist@86 43 DValue* DeclarationExp::toElem(IRState* p)
lindquist@1 44 {
lindquist@1 45 Logger::print("DeclarationExp::toElem: %s | T=%s\n", toChars(), type->toChars());
lindquist@1 46 LOG_SCOPE;
lindquist@1 47
kamm@433 48 return DtoDeclarationExp(declaration);
lindquist@1 49 }
lindquist@1 50
lindquist@1 51 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 52
lindquist@86 53 DValue* VarExp::toElem(IRState* p)
lindquist@1 54 {
lindquist@1 55 Logger::print("VarExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 56 LOG_SCOPE;
lindquist@1 57
lindquist@1 58 assert(var);
lindquist@1 59 if (VarDeclaration* vd = var->isVarDeclaration())
lindquist@1 60 {
tomas@763 61 Logger::println("VarDeclaration ' %s ' of type ' %s '", vd->toChars(), vd->type->toChars());
lindquist@50 62
lindquist@57 63 // _arguments
tomas@464 64 if (vd->ident == Id::_arguments && p->func()->_arguments)
lindquist@57 65 {
lindquist@72 66 Logger::println("Id::_arguments");
lindquist@363 67 LLValue* v = p->func()->_arguments;
tomas@585 68 return new DVarValue(type, vd, v);
lindquist@57 69 }
lindquist@57 70 // _argptr
tomas@464 71 else if (vd->ident == Id::_argptr && p->func()->_argptr)
lindquist@57 72 {
lindquist@72 73 Logger::println("Id::_argptr");
lindquist@363 74 LLValue* v = p->func()->_argptr;
tomas@585 75 return new DVarValue(type, vd, v);
lindquist@57 76 }
lindquist@67 77 // _dollar
lindquist@67 78 else if (vd->ident == Id::dollar)
lindquist@67 79 {
lindquist@72 80 Logger::println("Id::dollar");
lindquist@67 81 assert(!p->arrays.empty());
lindquist@213 82 LLValue* tmp = DtoArrayLen(p->arrays.back());
tomas@585 83 return new DImValue(type, tmp);
lindquist@67 84 }
lindquist@67 85 // typeinfo
lindquist@67 86 else if (TypeInfoDeclaration* tid = vd->isTypeInfoDeclaration())
lindquist@1 87 {
lindquist@1 88 Logger::println("TypeInfoDeclaration");
lindquist@102 89 DtoForceDeclareDsymbol(tid);
ChristianK@173 90 assert(tid->ir.getIrValue());
lindquist@213 91 const LLType* vartype = DtoType(type);
tomas@585 92 LLValue* m = tid->ir.getIrValue();
tomas@585 93 if (m->getType() != getPtrToType(vartype))
tomas@585 94 m = p->ir->CreateBitCast(m, vartype, "tmp");
tomas@585 95 return new DImValue(type, m);
lindquist@1 96 }
lindquist@100 97 // classinfo
lindquist@100 98 else if (ClassInfoDeclaration* cid = vd->isClassInfoDeclaration())
lindquist@100 99 {
lindquist@100 100 Logger::println("ClassInfoDeclaration: %s", cid->cd->toChars());
ChristianK@367 101 DtoForceDeclareDsymbol(cid->cd);
ChristianK@173 102 assert(cid->cd->ir.irStruct->classInfo);
tomas@585 103 return new DVarValue(type, vd, cid->cd->ir.irStruct->classInfo);
lindquist@100 104 }
lindquist@67 105 // nested variable
tomas@758 106 #if DMDV2
tomas@758 107 else if (vd->nestedrefs.dim) {
tomas@758 108 #else
lindquist@67 109 else if (vd->nestedref) {
tomas@758 110 #endif
lindquist@72 111 Logger::println("nested variable");
tomas@486 112 return DtoNestedVariable(loc, type, vd);
lindquist@1 113 }
lindquist@1 114 // function parameter
lindquist@67 115 else if (vd->isParameter()) {
lindquist@1 116 Logger::println("function param");
tomas@719 117 Logger::println("type: %s", vd->type->toChars());
lindquist@339 118 FuncDeclaration* fd = vd->toParent2()->isFuncDeclaration();
lindquist@339 119 if (fd && fd != p->func()->decl) {
lindquist@339 120 Logger::println("nested parameter");
tomas@486 121 return DtoNestedVariable(loc, type, vd);
lindquist@339 122 }
tomas@719 123 else if (vd->storage_class & STClazy) {
tomas@719 124 Logger::println("lazy parameter");
tomas@719 125 assert(type->ty == Tdelegate);
tomas@719 126 return new DVarValue(type, vd->ir.getIrValue());
tomas@719 127 }
lindquist@339 128 else if (vd->isRef() || vd->isOut() || DtoIsPassedByRef(vd->type) || llvm::isa<llvm::AllocaInst>(vd->ir.getIrValue())) {
tomas@585 129 return new DVarValue(type, vd, vd->ir.getIrValue());
lindquist@1 130 }
ChristianK@173 131 else if (llvm::isa<llvm::Argument>(vd->ir.getIrValue())) {
ChristianK@173 132 return new DImValue(type, vd->ir.getIrValue());
lindquist@1 133 }
lindquist@82 134 else assert(0);
lindquist@1 135 }
lindquist@1 136 else {
tomas@585 137 Logger::println("a normal variable");
tomas@797 138
lindquist@67 139 // take care of forward references of global variables
lindquist@100 140 if (vd->isDataseg() || (vd->storage_class & STCextern)) {
lindquist@336 141 vd->toObjFile(0); // TODO: multiobj
lindquist@100 142 }
tomas@797 143
tomas@797 144 LLValue* val;
tomas@797 145
tomas@797 146 if (!vd->ir.isSet() || !(val = vd->ir.getIrValue())) {
tomas@656 147 error("variable %s not resolved", vd->toChars());
tomas@622 148 if (Logger::enabled())
tomas@656 149 Logger::cout() << "unresolved variable had type: " << *DtoType(vd->type) << '\n';
kamm@397 150 fatal();
lindquist@88 151 }
tomas@797 152
kamm@628 153 if (vd->isDataseg() || (vd->storage_class & STCextern)) {
kamm@628 154 DtoConstInitGlobal(vd);
tomas@797 155 val = DtoBitCast(val, DtoType(type->pointerTo()));
kamm@628 156 }
tomas@797 157
tomas@797 158 return new DVarValue(type, vd, val);
lindquist@1 159 }
lindquist@1 160 }
lindquist@1 161 else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
lindquist@1 162 {
lindquist@1 163 Logger::println("FuncDeclaration");
tomas@384 164 LLValue* func = 0;
tomas@384 165 if (fdecl->llvmInternal != LLVMva_arg) {
lindquist@102 166 DtoForceDeclareDsymbol(fdecl);
tomas@384 167 func = fdecl->ir.irFunc->func;
lindquist@102 168 }
tomas@384 169 return new DFuncValue(fdecl, func);
lindquist@1 170 }
lindquist@1 171 else if (SymbolDeclaration* sdecl = var->isSymbolDeclaration())
lindquist@1 172 {
lindquist@1 173 // this seems to be the static initialiser for structs
tomas@486 174 Type* sdecltype = sdecl->type->toBasetype();
lindquist@40 175 Logger::print("Sym: type=%s\n", sdecltype->toChars());
lindquist@40 176 assert(sdecltype->ty == Tstruct);
lindquist@40 177 TypeStruct* ts = (TypeStruct*)sdecltype;
lindquist@121 178 assert(ts->sym);
lindquist@162 179 DtoForceConstInitDsymbol(ts->sym);
ChristianK@173 180 assert(ts->sym->ir.irStruct->init);
tomas@585 181 return new DVarValue(type, ts->sym->ir.irStruct->init);
lindquist@1 182 }
lindquist@1 183 else
lindquist@1 184 {
lindquist@1 185 assert(0 && "Unimplemented VarExp type");
lindquist@1 186 }
lindquist@1 187
lindquist@86 188 return 0;
lindquist@1 189 }
lindquist@1 190
lindquist@1 191 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 192
lindquist@213 193 LLConstant* VarExp::toConstElem(IRState* p)
lindquist@40 194 {
lindquist@40 195 Logger::print("VarExp::toConstElem: %s | %s\n", toChars(), type->toChars());
lindquist@40 196 LOG_SCOPE;
lindquist@40 197 if (SymbolDeclaration* sdecl = var->isSymbolDeclaration())
lindquist@40 198 {
lindquist@40 199 // this seems to be the static initialiser for structs
tomas@486 200 Type* sdecltype = sdecl->type->toBasetype();
lindquist@40 201 Logger::print("Sym: type=%s\n", sdecltype->toChars());
lindquist@40 202 assert(sdecltype->ty == Tstruct);
lindquist@40 203 TypeStruct* ts = (TypeStruct*)sdecltype;
lindquist@102 204 DtoForceConstInitDsymbol(ts->sym);
ChristianK@173 205 assert(ts->sym->ir.irStruct->constInit);
ChristianK@173 206 return ts->sym->ir.irStruct->constInit;
lindquist@40 207 }
lindquist@132 208 else if (TypeInfoDeclaration* ti = var->isTypeInfoDeclaration())
lindquist@132 209 {
lindquist@213 210 const LLType* vartype = DtoType(type);
lindquist@275 211 LLConstant* m = DtoTypeInfoOf(ti->tinfo, false);
lindquist@275 212 if (m->getType() != getPtrToType(vartype))
lindquist@132 213 m = llvm::ConstantExpr::getBitCast(m, vartype);
lindquist@132 214 return m;
lindquist@132 215 }
lindquist@132 216 assert(0 && "Unsupported const VarExp kind");
lindquist@40 217 return NULL;
lindquist@40 218 }
lindquist@40 219
lindquist@40 220 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@40 221
lindquist@86 222 DValue* IntegerExp::toElem(IRState* p)
lindquist@1 223 {
lindquist@1 224 Logger::print("IntegerExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 225 LOG_SCOPE;
lindquist@213 226 LLConstant* c = toConstElem(p);
lindquist@86 227 return new DConstValue(type, c);
lindquist@40 228 }
lindquist@40 229
lindquist@40 230 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@40 231
lindquist@213 232 LLConstant* IntegerExp::toConstElem(IRState* p)
lindquist@40 233 {
lindquist@40 234 Logger::print("IntegerExp::toConstElem: %s | %s\n", toChars(), type->toChars());
lindquist@40 235 LOG_SCOPE;
lindquist@213 236 const LLType* t = DtoType(type);
lindquist@96 237 if (isaPointer(t)) {
lindquist@88 238 Logger::println("pointer");
lindquist@213 239 LLConstant* i = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)value,false);
lindquist@40 240 return llvm::ConstantExpr::getIntToPtr(i, t);
lindquist@1 241 }
lindquist@244 242 assert(llvm::isa<LLIntegerType>(t));
lindquist@213 243 LLConstant* c = llvm::ConstantInt::get(t,(uint64_t)value,!type->isunsigned());
lindquist@88 244 assert(c);
tomas@622 245 if (Logger::enabled())
tomas@622 246 Logger::cout() << "value = " << *c << '\n';
lindquist@88 247 return c;
lindquist@1 248 }
lindquist@1 249
lindquist@1 250 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 251
lindquist@86 252 DValue* RealExp::toElem(IRState* p)
lindquist@1 253 {
lindquist@1 254 Logger::print("RealExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 255 LOG_SCOPE;
lindquist@213 256 LLConstant* c = toConstElem(p);
lindquist@86 257 return new DConstValue(type, c);
lindquist@40 258 }
lindquist@40 259
lindquist@40 260 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@40 261
lindquist@213 262 LLConstant* RealExp::toConstElem(IRState* p)
lindquist@40 263 {
kamm@643 264 Logger::print("RealExp::toConstElem: %s | %s | %LX\n", toChars(), type->toChars(), value);
lindquist@40 265 LOG_SCOPE;
tomas@486 266 Type* t = type->toBasetype();
lindquist@104 267 return DtoConstFP(t, value);
lindquist@1 268 }
lindquist@1 269
lindquist@1 270 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 271
lindquist@86 272 DValue* NullExp::toElem(IRState* p)
lindquist@1 273 {
lindquist@1 274 Logger::print("NullExp::toElem(type=%s): %s\n", type->toChars(),toChars());
lindquist@1 275 LOG_SCOPE;
lindquist@213 276 LLConstant* c = toConstElem(p);
lindquist@86 277 return new DNullValue(type, c);
lindquist@40 278 }
lindquist@40 279
lindquist@40 280 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@40 281
lindquist@213 282 LLConstant* NullExp::toConstElem(IRState* p)
lindquist@40 283 {
lindquist@40 284 Logger::print("NullExp::toConstElem(type=%s): %s\n", type->toChars(),toChars());
lindquist@40 285 LOG_SCOPE;
lindquist@213 286 const LLType* t = DtoType(type);
lindquist@28 287 if (type->ty == Tarray) {
lindquist@96 288 assert(isaStruct(t));
lindquist@40 289 return llvm::ConstantAggregateZero::get(t);
lindquist@28 290 }
lindquist@40 291 else {
lindquist@40 292 return llvm::Constant::getNullValue(t);
lindquist@40 293 }
lindquist@40 294 assert(0);
lindquist@40 295 return NULL;
lindquist@1 296 }
lindquist@1 297
lindquist@1 298 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 299
lindquist@90 300 DValue* ComplexExp::toElem(IRState* p)
lindquist@90 301 {
lindquist@90 302 Logger::print("ComplexExp::toElem(): %s | %s\n", toChars(), type->toChars());
lindquist@90 303 LOG_SCOPE;
lindquist@213 304 LLConstant* c = toConstElem(p);
tomas@585 305 LLValue* res;
lindquist@104 306
lindquist@104 307 if (c->isNullValue()) {
tomas@486 308 Type* t = type->toBasetype();
lindquist@104 309 if (t->ty == Tcomplex32)
lindquist@104 310 c = DtoConstFP(Type::tfloat32, 0);
tomas@445 311 else if (t->ty == Tcomplex64)
tomas@445 312 c = DtoConstFP(Type::tfloat64, 0);
tomas@445 313 else if (t->ty == Tcomplex80)
tomas@445 314 c = DtoConstFP(Type::tfloat80, 0);
lindquist@104 315 else
tomas@445 316 assert(0);
tomas@585 317 res = DtoAggrPair(DtoType(type), c, c);
lindquist@104 318 }
tomas@585 319 else {
tomas@585 320 res = DtoAggrPair(DtoType(type), c->getOperand(0), c->getOperand(1));
tomas@585 321 }
tomas@585 322
tomas@585 323 return new DImValue(type, res);
lindquist@90 324 }
lindquist@90 325
lindquist@90 326 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@90 327
lindquist@213 328 LLConstant* ComplexExp::toConstElem(IRState* p)
lindquist@90 329 {
lindquist@90 330 Logger::print("ComplexExp::toConstElem(): %s | %s\n", toChars(), type->toChars());
lindquist@90 331 LOG_SCOPE;
lindquist@104 332 return DtoConstComplex(type, value.re, value.im);
lindquist@90 333 }
lindquist@90 334
lindquist@90 335 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@90 336
lindquist@86 337 DValue* StringExp::toElem(IRState* p)
lindquist@1 338 {
lindquist@52 339 Logger::print("StringExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 340 LOG_SCOPE;
lindquist@1 341
tomas@486 342 Type* dtype = type->toBasetype();
tomas@758 343 Type* cty = dtype->nextOf()->toBasetype();
lindquist@1 344
lindquist@328 345 const LLType* ct = DtoTypeNotVoid(cty);
tomas@758 346 //printf("ct = %s\n", type->nextOf()->toChars());
lindquist@244 347 const LLArrayType* at = LLArrayType::get(ct,len+1);
lindquist@1 348
lindquist@213 349 LLConstant* _init;
lindquist@183 350 if (cty->size() == 1) {
lindquist@86 351 uint8_t* str = (uint8_t*)string;
lindquist@86 352 std::string cont((char*)str, len);
lindquist@86 353 _init = llvm::ConstantArray::get(cont,true);
lindquist@86 354 }
lindquist@183 355 else if (cty->size() == 2) {
lindquist@86 356 uint16_t* str = (uint16_t*)string;
lindquist@213 357 std::vector<LLConstant*> vals;
lindquist@86 358 for(size_t i=0; i<len; ++i) {
lindquist@86 359 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));;
lindquist@86 360 }
lindquist@86 361 vals.push_back(llvm::ConstantInt::get(ct, 0, false));
lindquist@86 362 _init = llvm::ConstantArray::get(at,vals);
lindquist@86 363 }
lindquist@183 364 else if (cty->size() == 4) {
lindquist@86 365 uint32_t* str = (uint32_t*)string;
lindquist@213 366 std::vector<LLConstant*> vals;
lindquist@86 367 for(size_t i=0; i<len; ++i) {
lindquist@86 368 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));;
lindquist@86 369 }
lindquist@86 370 vals.push_back(llvm::ConstantInt::get(ct, 0, false));
lindquist@86 371 _init = llvm::ConstantArray::get(at,vals);
lindquist@86 372 }
lindquist@86 373 else
lindquist@86 374 assert(0);
lindquist@1 375
lindquist@1 376 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
tomas@622 377 if (Logger::enabled())
tomas@622 378 Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n';
tomas@797 379 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".str",gIR->module);
lindquist@1 380
lindquist@244 381 llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
lindquist@213 382 LLConstant* idxs[2] = { zero, zero };
lindquist@213 383 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
lindquist@1 384
lindquist@40 385 if (dtype->ty == Tarray) {
lindquist@213 386 LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false);
tomas@720 387 return new DImValue(type, DtoConstSlice(clen, arrptr));
lindquist@1 388 }
lindquist@40 389 else if (dtype->ty == Tsarray) {
lindquist@244 390 const LLType* dstType = getPtrToType(LLArrayType::get(ct, len));
lindquist@213 391 LLValue* emem = (gvar->getType() == dstType) ? gvar : DtoBitCast(gvar, dstType);
tomas@585 392 return new DVarValue(type, emem);
lindquist@21 393 }
lindquist@40 394 else if (dtype->ty == Tpointer) {
lindquist@86 395 return new DImValue(type, arrptr);
lindquist@1 396 }
lindquist@86 397
lindquist@86 398 assert(0);
lindquist@86 399 return 0;
lindquist@1 400 }
lindquist@1 401
lindquist@1 402 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 403
lindquist@213 404 LLConstant* StringExp::toConstElem(IRState* p)
lindquist@40 405 {
lindquist@40 406 Logger::print("StringExp::toConstElem: %s | %s\n", toChars(), type->toChars());
lindquist@40 407 LOG_SCOPE;
lindquist@40 408
tomas@486 409 Type* t = type->toBasetype();
tomas@758 410 Type* cty = t->nextOf()->toBasetype();
lindquist@176 411
lindquist@176 412 bool nullterm = (t->ty != Tsarray);
lindquist@176 413 size_t endlen = nullterm ? len+1 : len;
lindquist@176 414
lindquist@213 415 const LLType* ct = DtoType(cty);
lindquist@244 416 const LLArrayType* at = LLArrayType::get(ct,endlen);
lindquist@176 417
lindquist@213 418 LLConstant* _init;
lindquist@183 419 if (cty->size() == 1) {
lindquist@176 420 uint8_t* str = (uint8_t*)string;
lindquist@176 421 std::string cont((char*)str, len);
lindquist@176 422 _init = llvm::ConstantArray::get(cont, nullterm);
lindquist@58 423 }
lindquist@183 424 else if (cty->size() == 2) {
lindquist@176 425 uint16_t* str = (uint16_t*)string;
lindquist@213 426 std::vector<LLConstant*> vals;
lindquist@176 427 for(size_t i=0; i<len; ++i) {
lindquist@176 428 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));;
lindquist@176 429 }
lindquist@176 430 if (nullterm)
lindquist@176 431 vals.push_back(llvm::ConstantInt::get(ct, 0, false));
lindquist@176 432 _init = llvm::ConstantArray::get(at,vals);
lindquist@176 433 }
lindquist@183 434 else if (cty->size() == 4) {
lindquist@176 435 uint32_t* str = (uint32_t*)string;
lindquist@213 436 std::vector<LLConstant*> vals;
lindquist@176 437 for(size_t i=0; i<len; ++i) {
lindquist@176 438 vals.push_back(llvm::ConstantInt::get(ct, str[i], false));;
lindquist@176 439 }
lindquist@176 440 if (nullterm)
lindquist@176 441 vals.push_back(llvm::ConstantInt::get(ct, 0, false));
lindquist@176 442 _init = llvm::ConstantArray::get(at,vals);
lindquist@176 443 }
lindquist@176 444 else
lindquist@176 445 assert(0);
lindquist@58 446
lindquist@178 447 if (t->ty == Tsarray)
lindquist@178 448 {
lindquist@178 449 return _init;
lindquist@178 450 }
lindquist@178 451
lindquist@40 452 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
tomas@797 453 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".str",gIR->module);
lindquist@40 454
lindquist@244 455 llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
lindquist@213 456 LLConstant* idxs[2] = { zero, zero };
lindquist@213 457 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
lindquist@40 458
lindquist@40 459 if (t->ty == Tpointer) {
lindquist@40 460 return arrptr;
lindquist@40 461 }
lindquist@178 462 else if (t->ty == Tarray) {
lindquist@213 463 LLConstant* clen = llvm::ConstantInt::get(DtoSize_t(),len,false);
lindquist@81 464 return DtoConstSlice(clen, arrptr);
lindquist@40 465 }
lindquist@40 466
lindquist@40 467 assert(0);
lindquist@40 468 return NULL;
lindquist@40 469 }
lindquist@40 470
lindquist@40 471 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@40 472
lindquist@86 473 DValue* AssignExp::toElem(IRState* p)
lindquist@1 474 {
tomas@467 475 Logger::print("AssignExp::toElem: %s | (%s)(%s = %s)\n", toChars(), type->toChars(), e1->type->toChars(), e2->type ? e2->type->toChars() : 0);
lindquist@1 476 LOG_SCOPE;
lindquist@1 477
lindquist@335 478 if (e1->op == TOKarraylength)
lindquist@335 479 {
lindquist@335 480 Logger::println("performing array.length assignment");
lindquist@335 481 ArrayLengthExp *ale = (ArrayLengthExp *)e1;
lindquist@335 482 DValue* arr = ale->e1->toElem(p);
tomas@585 483 DVarValue arrval(ale->e1->type, arr->getLVal());
lindquist@335 484 DValue* newlen = e2->toElem(p);
lindquist@335 485 DSliceValue* slice = DtoResizeDynArray(arrval.getType(), &arrval, newlen);
kamm@399 486 DtoAssign(loc, &arrval, slice);
lindquist@335 487 return newlen;
lindquist@335 488 }
lindquist@335 489
lindquist@335 490 Logger::println("performing normal assignment");
lindquist@335 491
lindquist@86 492 DValue* l = e1->toElem(p);
lindquist@86 493 DValue* r = e2->toElem(p);
kamm@399 494 DtoAssign(loc, l, r);
lindquist@92 495
tomas@585 496 if (l->isSlice())
lindquist@108 497 return l;
lindquist@109 498
tomas@468 499 return r;
lindquist@1 500 }
lindquist@1 501
lindquist@1 502 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 503
lindquist@86 504 DValue* AddExp::toElem(IRState* p)
lindquist@1 505 {
lindquist@23 506 Logger::print("AddExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 507 LOG_SCOPE;
lindquist@86 508
lindquist@86 509 DValue* l = e1->toElem(p);
lindquist@86 510 DValue* r = e2->toElem(p);
lindquist@1 511
tomas@486 512 Type* t = type->toBasetype();
tomas@486 513 Type* e1type = e1->type->toBasetype();
tomas@758 514 Type* e1next = e1type->nextOf() ? e1type->nextOf()->toBasetype() : NULL;
tomas@486 515 Type* e2type = e2->type->toBasetype();
lindquist@40 516
lindquist@40 517 if (e1type != e2type) {
tomas@705 518 if (e1type->ty == Tpointer) {
lindquist@94 519 Logger::println("add to pointer");
lindquist@94 520 if (r->isConst()) {
lindquist@94 521 llvm::ConstantInt* cofs = llvm::cast<llvm::ConstantInt>(r->isConst()->c);
lindquist@94 522 if (cofs->isZero()) {
lindquist@94 523 Logger::println("is zero");
lindquist@94 524 return new DImValue(type, l->getRVal());
lindquist@94 525 }
lindquist@94 526 }
lindquist@213 527 LLValue* v = llvm::GetElementPtrInst::Create(l->getRVal(), r->getRVal(), "tmp", p->scopebb());
lindquist@86 528 return new DImValue(type, v);
lindquist@1 529 }
lindquist@104 530 else if (t->iscomplex()) {
kamm@399 531 return DtoComplexAdd(loc, type, l, r);
lindquist@104 532 }
lindquist@86 533 assert(0);
lindquist@1 534 }
lindquist@104 535 else if (t->iscomplex()) {
kamm@399 536 return DtoComplexAdd(loc, type, l, r);
lindquist@104 537 }
lindquist@1 538 else {
lindquist@86 539 return DtoBinAdd(l,r);
lindquist@1 540 }
lindquist@1 541 }
lindquist@1 542
lindquist@1 543 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 544
lindquist@86 545 DValue* AddAssignExp::toElem(IRState* p)
lindquist@1 546 {
kamm@770 547 Logger::print("AddAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 548 LOG_SCOPE;
lindquist@1 549
lindquist@86 550 DValue* l = e1->toElem(p);
lindquist@86 551 DValue* r = e2->toElem(p);
lindquist@86 552
tomas@486 553 Type* t = type->toBasetype();
lindquist@104 554
lindquist@86 555 DValue* res;
tomas@486 556 if (e1->type->toBasetype()->ty == Tpointer) {
lindquist@213 557 LLValue* gep = llvm::GetElementPtrInst::Create(l->getRVal(),r->getRVal(),"tmp",p->scopebb());
lindquist@86 558 res = new DImValue(type, gep);
lindquist@86 559 }
lindquist@104 560 else if (t->iscomplex()) {
kamm@399 561 res = DtoComplexAdd(loc, e1->type, l, r);
lindquist@104 562 }
lindquist@86 563 else {
lindquist@86 564 res = DtoBinAdd(l,r);
lindquist@86 565 }
kamm@399 566 DtoAssign(loc, l, res);
lindquist@86 567
kamm@770 568 if (res->getType() != type)
kamm@770 569 res = DtoCast(loc, res, type);
kamm@770 570
ChristianK@334 571 return res;
lindquist@1 572 }
lindquist@1 573
lindquist@1 574 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 575
lindquist@86 576 DValue* MinExp::toElem(IRState* p)
lindquist@1 577 {
lindquist@1 578 Logger::print("MinExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 579 LOG_SCOPE;
lindquist@86 580
lindquist@86 581 DValue* l = e1->toElem(p);
lindquist@86 582 DValue* r = e2->toElem(p);
lindquist@86 583
tomas@486 584 Type* t = type->toBasetype();
tomas@486 585 Type* t1 = e1->type->toBasetype();
tomas@486 586 Type* t2 = e2->type->toBasetype();
lindquist@167 587
lindquist@167 588 if (t1->ty == Tpointer && t2->ty == Tpointer) {
lindquist@213 589 LLValue* lv = l->getRVal();
lindquist@213 590 LLValue* rv = r->getRVal();
tomas@622 591 if (Logger::enabled())
tomas@622 592 Logger::cout() << "lv: " << *lv << " rv: " << *rv << '\n';
lindquist@167 593 lv = p->ir->CreatePtrToInt(lv, DtoSize_t(), "tmp");
lindquist@167 594 rv = p->ir->CreatePtrToInt(rv, DtoSize_t(), "tmp");
lindquist@213 595 LLValue* diff = p->ir->CreateSub(lv,rv,"tmp");
lindquist@86 596 if (diff->getType() != DtoType(type))
lindquist@167 597 diff = p->ir->CreateIntToPtr(diff, DtoType(type), "tmp");
lindquist@86 598 return new DImValue(type, diff);
lindquist@86 599 }
lindquist@167 600 else if (t1->ty == Tpointer) {
lindquist@213 601 LLValue* idx = p->ir->CreateNeg(r->getRVal(), "tmp");
lindquist@213 602 LLValue* v = llvm::GetElementPtrInst::Create(l->getRVal(), idx, "tmp", p->scopebb());
lindquist@167 603 return new DImValue(type, v);
lindquist@167 604 }
lindquist@104 605 else if (t->iscomplex()) {
kamm@399 606 return DtoComplexSub(loc, type, l, r);
lindquist@104 607 }
lindquist@86 608 else {
lindquist@86 609 return DtoBinSub(l,r);
lindquist@86 610 }
lindquist@1 611 }
lindquist@1 612
lindquist@1 613 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 614
lindquist@86 615 DValue* MinAssignExp::toElem(IRState* p)
lindquist@1 616 {
lindquist@86 617 Logger::print("MinAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 618 LOG_SCOPE;
lindquist@1 619
lindquist@86 620 DValue* l = e1->toElem(p);
lindquist@86 621 DValue* r = e2->toElem(p);
lindquist@86 622
tomas@486 623 Type* t = type->toBasetype();
lindquist@104 624
lindquist@86 625 DValue* res;
tomas@486 626 if (e1->type->toBasetype()->ty == Tpointer) {
lindquist@131 627 Logger::println("ptr");
lindquist@213 628 LLValue* tmp = r->getRVal();
lindquist@213 629 LLValue* zero = llvm::ConstantInt::get(tmp->getType(),0,false);
tomas@704 630 tmp = llvm::BinaryOperator::CreateSub(zero,tmp,"tmp",p->scopebb());
lindquist@205 631 tmp = llvm::GetElementPtrInst::Create(l->getRVal(),tmp,"tmp",p->scopebb());
lindquist@86 632 res = new DImValue(type, tmp);
lindquist@86 633 }
lindquist@104 634 else if (t->iscomplex()) {
lindquist@131 635 Logger::println("complex");
kamm@399 636 res = DtoComplexSub(loc, type, l, r);
lindquist@104 637 }
lindquist@86 638 else {
lindquist@131 639 Logger::println("basic");
lindquist@86 640 res = DtoBinSub(l,r);
lindquist@86 641 }
kamm@399 642 DtoAssign(loc, l, res);
lindquist@86 643
kamm@770 644 if (res->getType() != type)
kamm@770 645 res = DtoCast(loc, res, type);
kamm@770 646
ChristianK@364 647 return res;
lindquist@104 648 }
lindquist@104 649
lindquist@104 650 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@104 651
lindquist@104 652 DValue* MulExp::toElem(IRState* p)
lindquist@104 653 {
lindquist@104 654 Logger::print("MulExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@104 655 LOG_SCOPE;
lindquist@104 656
lindquist@104 657 DValue* l = e1->toElem(p);
lindquist@104 658 DValue* r = e2->toElem(p);
lindquist@104 659
lindquist@104 660 if (type->iscomplex()) {
kamm@399 661 return DtoComplexMul(loc, type, l, r);
lindquist@104 662 }
lindquist@104 663
kamm@524 664 return DtoBinMul(type, l, r);
lindquist@104 665 }
lindquist@104 666
lindquist@104 667 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@104 668
lindquist@104 669 DValue* MulAssignExp::toElem(IRState* p)
lindquist@104 670 {
lindquist@104 671 Logger::print("MulAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@104 672 LOG_SCOPE;
lindquist@104 673
lindquist@104 674 DValue* l = e1->toElem(p);
lindquist@104 675 DValue* r = e2->toElem(p);
lindquist@104 676
lindquist@104 677 DValue* res;
lindquist@104 678 if (type->iscomplex()) {
kamm@399 679 res = DtoComplexMul(loc, type, l, r);
lindquist@1 680 }
lindquist@1 681 else {
kamm@525 682 res = DtoBinMul(l->getType(), l, r);
lindquist@1 683 }
kamm@399 684 DtoAssign(loc, l, res);
lindquist@104 685
kamm@770 686 if (res->getType() != type)
kamm@770 687 res = DtoCast(loc, res, type);
kamm@770 688
ChristianK@364 689 return res;
lindquist@1 690 }
lindquist@1 691
lindquist@1 692 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 693
lindquist@104 694 DValue* DivExp::toElem(IRState* p)
lindquist@1 695 {
lindquist@104 696 Logger::print("DivExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 697 LOG_SCOPE;
lindquist@86 698
lindquist@86 699 DValue* l = e1->toElem(p);
lindquist@86 700 DValue* r = e2->toElem(p);
lindquist@86 701
lindquist@104 702 if (type->iscomplex()) {
kamm@399 703 return DtoComplexDiv(loc, type, l, r);
lindquist@104 704 }
lindquist@104 705
kamm@524 706 return DtoBinDiv(type, l, r);
lindquist@104 707 }
lindquist@104 708
lindquist@104 709 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@104 710
lindquist@104 711 DValue* DivAssignExp::toElem(IRState* p)
lindquist@104 712 {
lindquist@104 713 Logger::print("DivAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@104 714 LOG_SCOPE;
lindquist@104 715
lindquist@104 716 DValue* l = e1->toElem(p);
lindquist@104 717 DValue* r = e2->toElem(p);
lindquist@104 718
lindquist@104 719 DValue* res;
lindquist@104 720 if (type->iscomplex()) {
kamm@399 721 res = DtoComplexDiv(loc, type, l, r);
lindquist@86 722 }
lindquist@86 723 else {
kamm@525 724 res = DtoBinDiv(l->getType(), l, r);
lindquist@86 725 }
kamm@399 726 DtoAssign(loc, l, res);
lindquist@104 727
kamm@770 728 if (res->getType() != type)
kamm@770 729 res = DtoCast(loc, res, type);
kamm@770 730
ChristianK@364 731 return res;
lindquist@1 732 }
lindquist@1 733
lindquist@1 734 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 735
lindquist@104 736 DValue* ModExp::toElem(IRState* p)
lindquist@1 737 {
lindquist@104 738 Logger::print("ModExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 739 LOG_SCOPE;
lindquist@1 740
lindquist@86 741 DValue* l = e1->toElem(p);
lindquist@86 742 DValue* r = e2->toElem(p);
lindquist@86 743
kamm@524 744 return DtoBinRem(type, l, r);
lindquist@1 745 }
lindquist@1 746
lindquist@1 747 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 748
lindquist@104 749 DValue* ModAssignExp::toElem(IRState* p)
lindquist@1 750 {
lindquist@104 751 Logger::print("ModAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 752 LOG_SCOPE;
lindquist@86 753
lindquist@86 754 DValue* l = e1->toElem(p);
lindquist@86 755 DValue* r = e2->toElem(p);
lindquist@86 756
kamm@525 757 DValue* res = DtoBinRem(l->getType(), l, r);
kamm@399 758 DtoAssign(loc, l, res);
lindquist@86 759
kamm@770 760 if (res->getType() != type)
kamm@770 761 res = DtoCast(loc, res, type);
kamm@770 762
ChristianK@364 763 return res;
lindquist@1 764 }
lindquist@1 765
lindquist@1 766 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 767
lindquist@86 768 DValue* CallExp::toElem(IRState* p)
lindquist@1 769 {
lindquist@104 770 Logger::print("CallExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 771 LOG_SCOPE;
lindquist@55 772
tomas@414 773 // get the callee value
tomas@414 774 DValue* fnval = e1->toElem(p);
tomas@414 775
tomas@414 776 // get func value if any
tomas@414 777 DFuncValue* dfnval = fnval->isFunc();
tomas@414 778
tomas@414 779 // handle magic intrinsics (mapping to instructions)
lindquist@55 780 bool va_intrinsic = false;
tomas@414 781 if (dfnval && dfnval->func)
tomas@414 782 {
tomas@414 783 FuncDeclaration* fndecl = dfnval->func;
lindquist@215 784 // va_start instruction
tomas@414 785 if (fndecl->llvmInternal == LLVMva_start) {
tomas@443 786 // llvm doesn't need the second param hence the override
tomas@443 787 Expression* exp = (Expression*)arguments->data[0];
tomas@443 788 DValue* expv = exp->toElem(p);
tomas@443 789 LLValue* arg = DtoBitCast(expv->getLVal(), getVoidPtrType());
tomas@443 790 return new DImValue(type, gIR->ir->CreateCall(GET_INTRINSIC_DECL(vastart), arg, ""));
lindquist@55 791 }
lindquist@215 792 // va_arg instruction
lindquist@86 793 else if (fndecl->llvmInternal == LLVMva_arg) {
tomas@414 794 return DtoVaArg(loc, type, (Expression*)arguments->data[0]);
lindquist@55 795 }
tomas@414 796 // C alloca
lindquist@94 797 else if (fndecl->llvmInternal == LLVMalloca) {
lindquist@94 798 Expression* exp = (Expression*)arguments->data[0];
lindquist@94 799 DValue* expv = exp->toElem(p);
lindquist@132 800 if (expv->getType()->toBasetype()->ty != Tint32)
kamm@399 801 expv = DtoCast(loc, expv, Type::tint32);
tomas@486 802 return new DImValue(type, p->ir->CreateAlloca(LLType::Int8Ty, expv->getRVal(), ".alloca"));
lindquist@94 803 }
lindquist@55 804 }
lindquist@55 805
kamm@422 806 return DtoCallFunction(loc, type, fnval, arguments);
lindquist@1 807 }
lindquist@1 808
lindquist@1 809 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 810
lindquist@86 811 DValue* CastExp::toElem(IRState* p)
lindquist@1 812 {
lindquist@53 813 Logger::print("CastExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 814 LOG_SCOPE;
lindquist@86 815
tomas@715 816 // get the value to cast
lindquist@86 817 DValue* u = e1->toElem(p);
tomas@715 818
tomas@715 819 // cast it to the 'to' type, if necessary
tomas@715 820 DValue* v = u;
tomas@715 821 if (!to->equals(e1->type))
tomas@715 822 v = DtoCast(loc, u, to);
tomas@715 823
tomas@715 824 // paint the type, if necessary
tomas@715 825 if (!type->equals(to))
tomas@715 826 v = DtoPaintType(loc, v, type);
tomas@715 827
tomas@715 828 // slices are not valid lvalues
tomas@715 829 if (v->isSlice())
lindquist@97 830 return v;
tomas@715 831 // if we're casting a lvalue, keep it around, we might be in a lvalue cast.
ChristianK@334 832 else if(u->isLVal())
ChristianK@359 833 return new DLRValue(u, v);
tomas@715 834 // otherwise just return the new value
tomas@715 835 return v;
lindquist@1 836 }
lindquist@1 837
lindquist@1 838 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 839
tomas@619 840 LLConstant* CastExp::toConstElem(IRState* p)
tomas@619 841 {
tomas@619 842 Logger::print("CastExp::toConstElem: %s | %s\n", toChars(), type->toChars());
tomas@619 843 LOG_SCOPE;
tomas@619 844
tomas@619 845 LLConstant* c = e1->toConstElem(p);
tomas@619 846 const LLType* lltype = DtoType(type);
kamm@624 847
kamm@624 848 if(!isaPointer(c->getType()) || !isaPointer(lltype)) {
tomas@715 849 error("can only cast pointers to pointers at code generation time, not %s to %s", type->toChars(), e1->type->toChars());
kamm@624 850 fatal();
kamm@624 851 }
tomas@619 852
tomas@619 853 return llvm::ConstantExpr::getBitCast(c, lltype);
tomas@619 854 }
tomas@619 855
tomas@619 856 //////////////////////////////////////////////////////////////////////////////////////////
tomas@619 857
lindquist@86 858 DValue* SymOffExp::toElem(IRState* p)
lindquist@1 859 {
lindquist@1 860 Logger::print("SymOffExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 861 LOG_SCOPE;
lindquist@86 862
lindquist@98 863 assert(0 && "SymOffExp::toElem should no longer be called :/");
lindquist@94 864 return 0;
lindquist@94 865 }
lindquist@94 866
lindquist@94 867 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@94 868
lindquist@94 869 DValue* AddrExp::toElem(IRState* p)
lindquist@94 870 {
lindquist@108 871 Logger::println("AddrExp::toElem: %s | %s", toChars(), type->toChars());
lindquist@94 872 LOG_SCOPE;
lindquist@94 873 DValue* v = e1->toElem(p);
lindquist@108 874 if (v->isField()) {
lindquist@108 875 Logger::println("is field");
lindquist@94 876 return v;
lindquist@108 877 }
lindquist@100 878 else if (DFuncValue* fv = v->isFunc()) {
lindquist@108 879 Logger::println("is func");
lindquist@100 880 //Logger::println("FuncDeclaration");
lindquist@94 881 FuncDeclaration* fd = fv->func;
lindquist@94 882 assert(fd);
lindquist@136 883 DtoForceDeclareDsymbol(fd);
ChristianK@173 884 return new DFuncValue(fd, fd->ir.irFunc->func);
lindquist@1 885 }
lindquist@101 886 else if (DImValue* im = v->isIm()) {
lindquist@108 887 Logger::println("is immediate");
lindquist@101 888 return v;
lindquist@101 889 }
lindquist@108 890 Logger::println("is nothing special");
tomas@820 891
tomas@820 892 // we special case here, since apparently taking the address of a slice is ok
tomas@820 893 LLValue* lval;
tomas@820 894 if (v->isLVal())
tomas@820 895 lval = v->getLVal();
tomas@820 896 else
tomas@820 897 {
tomas@820 898 assert(v->isSlice());
tomas@820 899 LLValue* rval = v->getRVal();
tomas@820 900 lval = DtoAlloca(rval->getType(), ".tmp_slice_storage");
tomas@820 901 DtoStore(rval, lval);
tomas@820 902 }
tomas@820 903
tomas@622 904 if (Logger::enabled())
tomas@622 905 Logger::cout() << "lval: " << *lval << '\n';
tomas@820 906
tomas@820 907 return new DImValue(type, DtoBitCast(lval, DtoType(type)));
lindquist@1 908 }
lindquist@1 909
kamm@459 910 LLConstant* AddrExp::toConstElem(IRState* p)
kamm@459 911 {
tomas@819 912 // FIXME: this should probably be generalized more so we don't
tomas@819 913 // need to have a case for each thing we can take the address of
tomas@819 914
tomas@819 915 // address of global variable
tomas@819 916 if (e1->op == TOKvar)
tomas@486 917 {
tomas@819 918 VarExp* vexp = (VarExp*)e1;
tomas@819 919
tomas@819 920 // make sure 'this' isn't needed
tomas@819 921 if (vexp->var->needThis())
tomas@819 922 {
tomas@819 923 error("need 'this' to access %s", vexp->var->toChars());
tomas@819 924 fatal();
tomas@819 925 }
tomas@819 926
tomas@819 927 // global variable
tomas@819 928 if (VarDeclaration* vd = vexp->var->isVarDeclaration())
tomas@819 929 {
tomas@819 930 LLConstant* llc = llvm::dyn_cast<LLConstant>(vd->ir.getIrValue());
tomas@819 931 assert(llc);
tomas@819 932 return llc;
tomas@819 933 }
tomas@819 934 // static function
tomas@819 935 else if (FuncDeclaration* fd = vexp->var->isFuncDeclaration())
tomas@819 936 {
tomas@819 937 IrFunction* irfunc = fd->ir.irFunc;
tomas@819 938 assert(irfunc);
tomas@819 939 return irfunc->func;
tomas@819 940 }
tomas@819 941 // something else
tomas@819 942 else
tomas@819 943 {
tomas@819 944 // fail
tomas@819 945 goto Lerr;
tomas@819 946 }
tomas@486 947 }
tomas@819 948 // address of indexExp
tomas@819 949 else if (e1->op == TOKindex)
tomas@469 950 {
tomas@819 951 IndexExp* iexp = (IndexExp*)e1;
tomas@819 952
tomas@819 953 // indexee must be global static array var
tomas@819 954 assert(iexp->e1->op == TOKvar);
tomas@819 955 VarExp* vexp = (VarExp*)iexp->e1;
tomas@819 956 VarDeclaration* vd = vexp->var->isVarDeclaration();
tomas@819 957 assert(vd);
tomas@819 958 assert(vd->type->toBasetype()->ty == Tsarray);
tomas@819 959 assert(vd->ir.irGlobal);
tomas@819 960
tomas@819 961 // get index
tomas@819 962 LLConstant* index = iexp->e2->toConstElem(p);
tomas@819 963 assert(index->getType() == DtoSize_t());
tomas@819 964
tomas@819 965 // gep
tomas@819 966 LLConstant* idxs[2] = { DtoConstSize_t(0), index };
tomas@819 967 LLConstant* gep = llvm::ConstantExpr::getGetElementPtr(isaConstant(vd->ir.irGlobal->value), idxs, 2);
tomas@819 968
tomas@819 969 // bitcast to requested type
tomas@819 970 assert(type->toBasetype()->ty == Tpointer);
tomas@819 971 return DtoBitCast(gep, DtoType(type));
tomas@469 972 }
tomas@469 973 // not yet supported
tomas@469 974 else
tomas@469 975 {
tomas@819 976 Lerr:
tomas@469 977 error("constant expression '%s' not yet implemented", toChars());
tomas@469 978 fatal();
tomas@469 979 }
kamm@459 980 }
kamm@459 981
lindquist@1 982 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 983
lindquist@86 984 DValue* PtrExp::toElem(IRState* p)
lindquist@1 985 {
lindquist@108 986 Logger::println("PtrExp::toElem: %s | %s", toChars(), type->toChars());
lindquist@1 987 LOG_SCOPE;
lindquist@86 988
lindquist@86 989 DValue* a = e1->toElem(p);
lindquist@86 990
tomas@585 991 // this is *so* ugly.. I'd really like to figure out some way to avoid this badness...
lindquist@213 992 LLValue* lv = a->getRVal();
lindquist@213 993 LLValue* v = lv;
tomas@585 994
tomas@585 995 Type* bt = type->toBasetype();
tomas@585 996
tomas@585 997 // we can't load function pointers, but they aren't passed by reference either
tomas@585 998 // FIXME: maybe a MayLoad function isn't a bad idea after all ...
tomas@585 999 if (!DtoIsPassedByRef(bt) && bt->ty != Tfunction)
lindquist@86 1000 v = DtoLoad(v);
tomas@585 1001
tomas@585 1002 return new DLRValue(new DVarValue(type, lv), new DImValue(type, v));
lindquist@1 1003 }
lindquist@1 1004
lindquist@1 1005 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1006
lindquist@86 1007 DValue* DotVarExp::toElem(IRState* p)
lindquist@1 1008 {
lindquist@1 1009 Logger::print("DotVarExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1010 LOG_SCOPE;
lindquist@86 1011
lindquist@86 1012 DValue* l = e1->toElem(p);
lindquist@1 1013
tomas@486 1014 Type* t = type->toBasetype();
tomas@486 1015 Type* e1type = e1->type->toBasetype();
lindquist@40 1016
lindquist@172 1017 //Logger::println("e1type=%s", e1type->toChars());
lindquist@172 1018 //Logger::cout() << *DtoType(e1type) << '\n';
lindquist@1 1019
lindquist@1 1020 if (VarDeclaration* vd = var->isVarDeclaration()) {
lindquist@213 1021 LLValue* arrptr;
tomas@705 1022 // indexing struct pointer
lindquist@40 1023 if (e1type->ty == Tpointer) {
tomas@758 1024 assert(e1type->nextOf()->ty == Tstruct);
tomas@758 1025 TypeStruct* ts = (TypeStruct*)e1type->nextOf();
tomas@705 1026 arrptr = DtoIndexStruct(l->getRVal(), ts->sym, vd);
lindquist@1 1027 }
tomas@705 1028 // indexing normal struct
tomas@486 1029 else if (e1type->ty == Tstruct) {
tomas@486 1030 TypeStruct* ts = (TypeStruct*)e1type;
tomas@705 1031 arrptr = DtoIndexStruct(l->getRVal(), ts->sym, vd);
tomas@486 1032 }
tomas@705 1033 // indexing class
lindquist@113 1034 else if (e1type->ty == Tclass) {
lindquist@40 1035 TypeClass* tc = (TypeClass*)e1type;
tomas@705 1036 arrptr = DtoIndexClass(l->getRVal(), tc->sym, vd);
lindquist@1 1037 }
lindquist@77 1038 else
lindquist@77 1039 assert(0);
lindquist@86 1040
lindquist@123 1041 //Logger::cout() << "mem: " << *arrptr << '\n';
tomas@585 1042 return new DVarValue(type, vd, arrptr);
lindquist@1 1043 }
lindquist@1 1044 else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
lindquist@1 1045 {
lindquist@113 1046 DtoResolveDsymbol(fdecl);
lindquist@113 1047
lindquist@213 1048 LLValue* funcval;
lindquist@213 1049 LLValue* vthis2 = 0;
lindquist@113 1050 if (e1type->ty == Tclass) {
lindquist@113 1051 TypeClass* tc = (TypeClass*)e1type;
lindquist@113 1052 if (tc->sym->isInterfaceDeclaration()) {
lindquist@114 1053 vthis2 = DtoCastInterfaceToObject(l, NULL)->getRVal();
lindquist@113 1054 }
lindquist@1 1055 }
lindquist@213 1056 LLValue* vthis = l->getRVal();
lindquist@113 1057 if (!vthis2) vthis2 = vthis;
lindquist@1 1058
lindquist@133 1059 // super call
lindquist@133 1060 if (e1->op == TOKsuper) {
lindquist@133 1061 DtoForceDeclareDsymbol(fdecl);
ChristianK@173 1062 funcval = fdecl->ir.irFunc->func;
lindquist@133 1063 assert(funcval);
lindquist@133 1064 }
lindquist@133 1065 // normal virtual call
lindquist@133 1066 else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) {
lindquist@1 1067 assert(fdecl->vtblIndex > 0);
lindquist@40 1068 assert(e1type->ty == Tclass);
lindquist@1 1069
tomas@797 1070 LLValue* zero = DtoConstUint(0);
tomas@797 1071 size_t vtblidx = fdecl->vtblIndex;
tomas@622 1072 if (Logger::enabled())
tomas@622 1073 Logger::cout() << "vthis: " << *vthis << '\n';
tomas@797 1074 funcval = vthis;
tomas@797 1075 if (!fdecl->isMember2()->isInterfaceDeclaration())
tomas@797 1076 funcval = DtoGEP(funcval, zero, zero);
lindquist@244 1077 funcval = DtoLoad(funcval);
tomas@797 1078 Logger::println("vtblidx = %lu", vtblidx);
tomas@797 1079 funcval = DtoGEP(funcval, zero, DtoConstUint(vtblidx), toChars());
lindquist@244 1080 funcval = DtoLoad(funcval);
tomas@797 1081
lindquist@193 1082 funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
tomas@622 1083 if (Logger::enabled())
tomas@622 1084 Logger::cout() << "funcval casted: " << *funcval << '\n';
lindquist@1 1085 }
lindquist@113 1086 // static call
lindquist@113 1087 else {
lindquist@113 1088 DtoForceDeclareDsymbol(fdecl);
ChristianK@173 1089 funcval = fdecl->ir.irFunc->func;
lindquist@113 1090 assert(funcval);
lindquist@113 1091 }
lindquist@113 1092 return new DFuncValue(fdecl, funcval, vthis2);
lindquist@1 1093 }
lindquist@1 1094 else {
lindquist@123 1095 printf("unsupported dotvarexp: %s\n", var->toChars());
lindquist@1 1096 }
lindquist@1 1097
lindquist@86 1098 assert(0);
lindquist@86 1099 return 0;
lindquist@1 1100 }
lindquist@1 1101
lindquist@1 1102 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1103
lindquist@86 1104 DValue* ThisExp::toElem(IRState* p)
lindquist@1 1105 {
lindquist@1 1106 Logger::print("ThisExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1107 LOG_SCOPE;
lindquist@1 1108
lindquist@328 1109 // this seems to happen for dmd generated assert statements like:
lindquist@328 1110 // assert(this, "null this");
tomas@452 1111 // FIXME: check for TOKthis in AssertExp instead
lindquist@328 1112 if (!var)
lindquist@328 1113 {
tomas@486 1114 LLValue* v = p->func()->thisArg;
lindquist@328 1115 assert(v);
tomas@585 1116 return new DVarValue(type, v);
lindquist@328 1117 }
lindquist@328 1118 // regular this expr
lindquist@328 1119 else if (VarDeclaration* vd = var->isVarDeclaration()) {
lindquist@213 1120 LLValue* v;
tomas@452 1121 if (vd->toParent2() != p->func()->decl) {
tomas@452 1122 Logger::println("nested this exp");
tomas@486 1123 return DtoNestedVariable(loc, type, vd);
tomas@452 1124 }
tomas@452 1125 else {
tomas@452 1126 Logger::println("normal this exp");
tomas@486 1127 v = p->func()->thisArg;
tomas@452 1128 }
tomas@585 1129 return new DVarValue(type, vd, v);
lindquist@1 1130 }
lindquist@86 1131
lindquist@328 1132 // anything we're not yet handling ?
lindquist@86 1133 assert(0);
lindquist@86 1134 return 0;
lindquist@1 1135 }
lindquist@1 1136
lindquist@1 1137 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1138
lindquist@86 1139 DValue* IndexExp::toElem(IRState* p)
lindquist@1 1140 {
lindquist@1 1141 Logger::print("IndexExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1142 LOG_SCOPE;
lindquist@1 1143
lindquist@86 1144 DValue* l = e1->toElem(p);
lindquist@1 1145
tomas@486 1146 Type* e1type = e1->type->toBasetype();
lindquist@40 1147
lindquist@86 1148 p->arrays.push_back(l); // if $ is used it must be an array so this is fine.
lindquist@86 1149 DValue* r = e2->toElem(p);
lindquist@1 1150 p->arrays.pop_back();
lindquist@1 1151
lindquist@244 1152 LLValue* zero = DtoConstUint(0);
lindquist@244 1153 LLValue* one = DtoConstUint(1);
lindquist@213 1154
lindquist@213 1155 LLValue* arrptr = 0;
lindquist@40 1156 if (e1type->ty == Tpointer) {
lindquist@244 1157 arrptr = DtoGEP1(l->getRVal(),r->getRVal());
lindquist@1 1158 }
lindquist@40 1159 else if (e1type->ty == Tsarray) {
kamm@439 1160 if(global.params.useArrayBounds)
kamm@440 1161 DtoArrayBoundsCheck(loc, l, r, false);
lindquist@244 1162 arrptr = DtoGEP(l->getRVal(), zero, r->getRVal());
lindquist@1 1163 }
lindquist@40 1164 else if (e1type->ty == Tarray) {
kamm@439 1165 if(global.params.useArrayBounds)
kamm@440 1166 DtoArrayBoundsCheck(loc, l, r, false);
lindquist@275 1167 arrptr = DtoArrayPtr(l);
lindquist@244 1168 arrptr = DtoGEP1(arrptr,r->getRVal());
lindquist@1 1169 }
lindquist@109 1170 else if (e1type->ty == Taarray) {
tomas@458 1171 return DtoAAIndex(loc, type, l, r, modifiable);
lindquist@109 1172 }
lindquist@109 1173 else {
lindquist@109 1174 Logger::println("invalid index exp! e1type: %s", e1type->toChars());
lindquist@109 1175 assert(0);
lindquist@109 1176 }
tomas@585 1177 return new DVarValue(type, arrptr);
lindquist@1 1178 }
lindquist@1 1179
lindquist@1 1180 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1181
lindquist@86 1182 DValue* SliceExp::toElem(IRState* p)
lindquist@1 1183 {
lindquist@1 1184 Logger::print("SliceExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1185 LOG_SCOPE;
lindquist@1 1186
lindquist@308 1187 // this is the new slicing code, it's different in that a full slice will no longer retain the original pointer.
lindquist@308 1188 // but this was broken if there *was* no original pointer, ie. a slice of a slice...
lindquist@308 1189 // now all slices have *both* the 'len' and 'ptr' fields set to != null.
lindquist@308 1190
lindquist@308 1191 // value being sliced
lindquist@308 1192 LLValue* elen;
lindquist@308 1193 LLValue* eptr;
lindquist@308 1194 DValue* e = e1->toElem(p);
lindquist@308 1195
lindquist@308 1196 // handle pointer slicing
lindquist@308 1197 Type* etype = e1->type->toBasetype();
lindquist@308 1198 if (etype->ty == Tpointer)
lindquist@308 1199 {
lindquist@308 1200 assert(lwr);
lindquist@308 1201 eptr = e->getRVal();
lindquist@308 1202 }
lindquist@308 1203 // array slice
lindquist@308 1204 else
lindquist@308 1205 {
lindquist@308 1206 eptr = DtoArrayPtr(e);
lindquist@308 1207 }
lindquist@308 1208
lindquist@308 1209 // has lower bound, pointer needs adjustment
lindquist@1 1210 if (lwr)
lindquist@1 1211 {
lindquist@308 1212 // must have upper bound too then
lindquist@1 1213 assert(upr);
lindquist@308 1214
lindquist@308 1215 // get bounds (make sure $ works)
lindquist@308 1216 p->arrays.push_back(e);
lindquist@86 1217 DValue* lo = lwr->toElem(p);
lindquist@86 1218 DValue* up = upr->toElem(p);
lindquist@1 1219 p->arrays.pop_back();
lindquist@308 1220 LLValue* vlo = lo->getRVal();
lindquist@308 1221 LLValue* vup = up->getRVal();
lindquist@308 1222
kamm@440 1223 if(global.params.useArrayBounds && (etype->ty == Tsarray || etype->ty == Tarray))
kamm@440 1224 DtoArrayBoundsCheck(loc, e, up, true);
kamm@440 1225
lindquist@308 1226 // offset by lower
lindquist@308 1227 eptr = DtoGEP1(eptr, vlo);
lindquist@308 1228
lindquist@308 1229 // adjust length
lindquist@308 1230 elen = p->ir->CreateSub(vup, vlo, "tmp");
lindquist@1 1231 }
lindquist@308 1232 // no bounds or full slice -> just convert to slice
lindquist@1 1233 else
lindquist@1 1234 {
lindquist@308 1235 assert(e1->type->toBasetype()->ty != Tpointer);
lindquist@339 1236 // if the sliceee is a static array, we use the length of that as DMD seems
lindquist@339 1237 // to give contrary inconsistent sizesin some multidimensional static array cases.
lindquist@339 1238 // (namely default initialization, int[16][16] arr; -> int[256] arr = 0;)
lindquist@339 1239 if (etype->ty == Tsarray)
lindquist@339 1240 {
lindquist@339 1241 TypeSArray* tsa = (TypeSArray*)etype;
lindquist@339 1242 elen = DtoConstSize_t(tsa->dim->toUInteger());
tomas@825 1243
tomas@825 1244 // in this case, we also need to make sure the pointer is cast to the innermost element type
tomas@825 1245 eptr = DtoBitCast(eptr, DtoType(tsa->nextOf()->pointerTo()));
lindquist@339 1246 }
lindquist@339 1247 // for normal code the actual array length is what we want!
lindquist@339 1248 else
lindquist@339 1249 {
lindquist@339 1250 elen = DtoArrayLen(e);
lindquist@339 1251 }
lindquist@1 1252 }
lindquist@1 1253
lindquist@308 1254 return new DSliceValue(type, elen, eptr);
lindquist@1 1255 }
lindquist@1 1256
lindquist@1 1257 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1258
lindquist@86 1259 DValue* CmpExp::toElem(IRState* p)
lindquist@1 1260 {
lindquist@1 1261 Logger::print("CmpExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1262 LOG_SCOPE;
lindquist@1 1263
lindquist@86 1264 DValue* l = e1->toElem(p);
lindquist@86 1265 DValue* r = e2->toElem(p);
lindquist@1 1266
tomas@486 1267 Type* t = e1->type->toBasetype();
tomas@486 1268 Type* e2t = e2->type->toBasetype();
lindquist@1 1269
lindquist@213 1270 LLValue* eval = 0;
lindquist@86 1271
lindquist@58 1272 if (t->isintegral() || t->ty == Tpointer)
lindquist@1 1273 {
lindquist@1 1274 llvm::ICmpInst::Predicate cmpop;
lindquist@40 1275 bool skip = false;
tomas@575 1276 // pointers don't report as being unsigned
tomas@575 1277 bool uns = (t->isunsigned() || t->ty == Tpointer);
lindquist@1 1278 switch(op)
lindquist@1 1279 {
lindquist@1 1280 case TOKlt:
lindquist@40 1281 case TOKul:
tomas@575 1282 cmpop = uns ? llvm::ICmpInst::ICMP_ULT : llvm::ICmpInst::ICMP_SLT;
lindquist@1 1283 break;
lindquist@1 1284 case TOKle:
lindquist@40 1285 case TOKule:
tomas@575 1286 cmpop = uns ? llvm::ICmpInst::ICMP_ULE : llvm::ICmpInst::ICMP_SLE;
lindquist@1 1287 break;
lindquist@1 1288 case TOKgt:
lindquist@40 1289 case TOKug:
tomas@575 1290 cmpop = uns ? llvm::ICmpInst::ICMP_UGT : llvm::ICmpInst::ICMP_SGT;
lindquist@1 1291 break;
lindquist@1 1292 case TOKge:
lindquist@40 1293 case TOKuge:
tomas@575 1294 cmpop = uns ? llvm::ICmpInst::ICMP_UGE : llvm::ICmpInst::ICMP_SGE;
lindquist@1 1295 break;
lindquist@40 1296 case TOKue:
lindquist@40 1297 cmpop = llvm::ICmpInst::ICMP_EQ;
lindquist@40 1298 break;
lindquist@40 1299 case TOKlg:
lindquist@40 1300 cmpop = llvm::ICmpInst::ICMP_NE;
lindquist@40 1301 break;
lindquist@40 1302 case TOKleg:
lindquist@40 1303 skip = true;
lindquist@86 1304 eval = llvm::ConstantInt::getTrue();
lindquist@40 1305 break;
lindquist@40 1306 case TOKunord:
lindquist@40 1307 skip = true;
lindquist@86 1308 eval = llvm::ConstantInt::getFalse();
lindquist@40 1309 break;
lindquist@40 1310
lindquist@1 1311 default:
lindquist@1 1312 assert(0);
lindquist@1 1313 }
lindquist@40 1314 if (!skip)
lindquist@40 1315 {
lindquist@213 1316 LLValue* a = l->getRVal();
lindquist@213 1317 LLValue* b = r->getRVal();
tomas@622 1318 if (Logger::enabled())
tomas@622 1319 {
tomas@622 1320 Logger::cout() << "type 1: " << *a << '\n';
tomas@622 1321 Logger::cout() << "type 2: " << *b << '\n';
tomas@622 1322 }
tomas@574 1323 if (a->getType() != b->getType())
tomas@574 1324 b = DtoBitCast(b, a->getType());
lindquist@365 1325 eval = p->ir->CreateICmp(cmpop, a, b, "tmp");
lindquist@40 1326 }
lindquist@1 1327 }
lindquist@1 1328 else if (t->isfloating())
lindquist@1 1329 {
lindquist@1 1330 llvm::FCmpInst::Predicate cmpop;
lindquist@1 1331 switch(op)
lindquist@1 1332 {
lindquist@1 1333 case TOKlt:
lindquist@1 1334 cmpop = llvm::FCmpInst::FCMP_OLT;break;
lindquist@1 1335 case TOKle:
lindquist@1 1336 cmpop = llvm::FCmpInst::FCMP_OLE;break;
lindquist@1 1337 case TOKgt:
lindquist@1 1338 cmpop = llvm::FCmpInst::FCMP_OGT;break;
lindquist@1 1339 case TOKge:
lindquist@1 1340 cmpop = llvm::FCmpInst::FCMP_OGE;break;
lindquist@1 1341 case TOKunord:
lindquist@1 1342 cmpop = llvm::FCmpInst::FCMP_UNO;break;
lindquist@1 1343 case TOKule:
lindquist@1 1344 cmpop = llvm::FCmpInst::FCMP_ULE;break;
lindquist@1 1345 case TOKul:
lindquist@1 1346 cmpop = llvm::FCmpInst::FCMP_ULT;break;
lindquist@1 1347 case TOKuge:
lindquist@1 1348 cmpop = llvm::FCmpInst::FCMP_UGE;break;
lindquist@1 1349 case TOKug:
lindquist@1 1350 cmpop = llvm::FCmpInst::FCMP_UGT;break;
lindquist@1 1351 case TOKue:
lindquist@1 1352 cmpop = llvm::FCmpInst::FCMP_UEQ;break;
lindquist@1 1353 case TOKlg:
lindquist@1 1354 cmpop = llvm::FCmpInst::FCMP_ONE;break;
lindquist@1 1355 case TOKleg:
lindquist@1 1356 cmpop = llvm::FCmpInst::FCMP_ORD;break;
lindquist@1 1357
lindquist@1 1358 default:
lindquist@1 1359 assert(0);
lindquist@1 1360 }
lindquist@365 1361 eval = p->ir->CreateFCmp(cmpop, l->getRVal(), r->getRVal(), "tmp");
lindquist@1 1362 }
lindquist@99 1363 else if (t->ty == Tsarray || t->ty == Tarray)
lindquist@99 1364 {
lindquist@99 1365 Logger::println("static or dynamic array");
kamm@424 1366 eval = DtoArrayCompare(loc,op,l,r);
lindquist@99 1367 }
lindquist@1 1368 else
lindquist@1 1369 {
lindquist@1 1370 assert(0 && "Unsupported CmpExp type");
lindquist@1 1371 }
lindquist@1 1372
lindquist@86 1373 return new DImValue(type, eval);
lindquist@1 1374 }
lindquist@1 1375
lindquist@1 1376 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1377
lindquist@86 1378 DValue* EqualExp::toElem(IRState* p)
lindquist@1 1379 {
lindquist@1 1380 Logger::print("EqualExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1381 LOG_SCOPE;
lindquist@1 1382
lindquist@86 1383 DValue* l = e1->toElem(p);
lindquist@86 1384 DValue* r = e2->toElem(p);
lindquist@1 1385
tomas@486 1386 Type* t = e1->type->toBasetype();
tomas@486 1387 Type* e2t = e2->type->toBasetype();
lindquist@108 1388 //assert(t == e2t);
lindquist@1 1389
lindquist@213 1390 LLValue* eval = 0;
lindquist@86 1391
kamm@512 1392 // the Tclass catches interface comparisons, regular
kamm@512 1393 // class equality should be rewritten as a.opEquals(b) by this time
kamm@512 1394 if (t->isintegral() || t->ty == Tpointer || t->ty == Tclass)
lindquist@1 1395 {
kamm@512 1396 Logger::println("integral or pointer or interface");
lindquist@1 1397 llvm::ICmpInst::Predicate cmpop;
lindquist@1 1398 switch(op)
lindquist@1 1399 {
lindquist@1 1400 case TOKequal:
lindquist@1 1401 cmpop = llvm::ICmpInst::ICMP_EQ;
lindquist@1 1402 break;
lindquist@1 1403 case TOKnotequal:
lindquist@1 1404 cmpop = llvm::ICmpInst::ICMP_NE;
lindquist@1 1405 break;
lindquist@1 1406 default:
lindquist@1 1407 assert(0);
lindquist@1 1408 }
lindquist@213 1409 LLValue* lv = l->getRVal();
lindquist@213 1410 LLValue* rv = r->getRVal();
lindquist@108 1411 if (rv->getType() != lv->getType()) {
lindquist@108 1412 rv = DtoBitCast(rv, lv->getType());
lindquist@108 1413 }
tomas@705 1414 if (Logger::enabled())
tomas@705 1415 {
tomas@705 1416 Logger::cout() << "lv: " << *lv << '\n';
tomas@705 1417 Logger::cout() << "rv: " << *rv << '\n';
tomas@705 1418 }
lindquist@365 1419 eval = p->ir->CreateICmp(cmpop, lv, rv, "tmp");
lindquist@1 1420 }
lindquist@104 1421 else if (t->iscomplex())
lindquist@104 1422 {
lindquist@104 1423 Logger::println("complex");
kamm@399 1424 eval = DtoComplexEquals(loc, op, l, r);
lindquist@104 1425 }
lindquist@1 1426 else if (t->isfloating())
lindquist@1 1427 {
lindquist@64 1428 Logger::println("floating");
lindquist@1 1429 llvm::FCmpInst::Predicate cmpop;
lindquist@1 1430 switch(op)
lindquist@1 1431 {
lindquist@1 1432 case TOKequal:
lindquist@1 1433 cmpop = llvm::FCmpInst::FCMP_OEQ;
lindquist@1 1434 break;
lindquist@1 1435 case TOKnotequal:
lindquist@1 1436 cmpop = llvm::FCmpInst::FCMP_UNE;
lindquist@1 1437 break;
lindquist@1 1438 default:
lindquist@1 1439 assert(0);
lindquist@1 1440 }
lindquist@365 1441 eval = p->ir->CreateFCmp(cmpop, l->getRVal(), r->getRVal(), "tmp");
lindquist@1 1442 }
lindquist@98 1443 else if (t->ty == Tsarray || t->ty == Tarray)
lindquist@40 1444 {
lindquist@98 1445 Logger::println("static or dynamic array");
kamm@424 1446 eval = DtoArrayEquals(loc,op,l,r);
lindquist@1 1447 }
lindquist@53 1448 else if (t->ty == Tdelegate)
lindquist@53 1449 {
lindquist@64 1450 Logger::println("delegate");
lindquist@344 1451 eval = DtoDelegateEquals(op,l->getRVal(),r->getRVal());
lindquist@344 1452 }
lindquist@344 1453 else if (t->ty == Tstruct)
lindquist@344 1454 {
lindquist@344 1455 Logger::println("struct");
lindquist@344 1456 // when this is reached it means there is no opEquals overload.
lindquist@344 1457 eval = DtoStructEquals(op,l,r);
lindquist@53 1458 }
lindquist@1 1459 else
lindquist@1 1460 {
lindquist@1 1461 assert(0 && "Unsupported EqualExp type");
lindquist@1 1462 }
lindquist@1 1463
lindquist@86 1464 return new DImValue(type, eval);
lindquist@1 1465 }
lindquist@1 1466
lindquist@1 1467 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1468
lindquist@86 1469 DValue* PostExp::toElem(IRState* p)
lindquist@1 1470 {
lindquist@1 1471 Logger::print("PostExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1472 LOG_SCOPE;
lindquist@1 1473
lindquist@86 1474 DValue* l = e1->toElem(p);
lindquist@86 1475 DValue* r = e2->toElem(p);
lindquist@86 1476
lindquist@213 1477 LLValue* val = l->getRVal();
lindquist@213 1478 LLValue* post = 0;
lindquist@1 1479
tomas@486 1480 Type* e1type = e1->type->toBasetype();
tomas@486 1481 Type* e2type = e2->type->toBasetype();
lindquist@40 1482
lindquist@40 1483 if (e1type->isintegral())
lindquist@1 1484 {
lindquist@40 1485 assert(e2type->isintegral());
lindquist@213 1486 LLValue* one = llvm::ConstantInt::get(val->getType(), 1, !e2type->isunsigned());
lindquist@1 1487 if (op == TOKplusplus) {
tomas@704 1488 post = llvm::BinaryOperator::CreateAdd(val,one,"tmp",p->scopebb());
lindquist@1 1489 }
lindquist@1 1490 else if (op == TOKminusminus) {
tomas@704 1491 post = llvm::BinaryOperator::CreateSub(val,one,"tmp",p->scopebb());
lindquist@1 1492 }
lindquist@1 1493 }
lindquist@40 1494 else if (e1type->ty == Tpointer)
lindquist@1 1495 {
lindquist@40 1496 assert(e2type->isintegral());
lindquist@213 1497 LLConstant* minusone = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)-1,true);
lindquist@213 1498 LLConstant* plusone = llvm::ConstantInt::get(DtoSize_t(),(uint64_t)1,false);
lindquist@213 1499 LLConstant* whichone = (op == TOKplusplus) ? plusone : minusone;
lindquist@205 1500 post = llvm::GetElementPtrInst::Create(val, whichone, "tmp", p->scopebb());
lindquist@1 1501 }
lindquist@40 1502 else if (e1type->isfloating())
lindquist@1 1503 {
lindquist@40 1504 assert(e2type->isfloating());
lindquist@213 1505 LLValue* one = DtoConstFP(e1type, 1.0);
lindquist@1 1506 if (op == TOKplusplus) {
tomas@704 1507 post = llvm::BinaryOperator::CreateAdd(val,one,"tmp",p->scopebb());
lindquist@1 1508 }
lindquist@1 1509 else if (op == TOKminusminus) {
tomas@704 1510 post = llvm::BinaryOperator::CreateSub(val,one,"tmp",p->scopebb());
lindquist@1 1511 }
lindquist@1 1512 }
lindquist@1 1513 else
lindquist@1 1514 assert(post);
lindquist@1 1515
lindquist@86 1516 DtoStore(post,l->getLVal());
lindquist@86 1517
tomas@486 1518 return new DImValue(type,val);
lindquist@1 1519 }
lindquist@1 1520
lindquist@1 1521 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1522
lindquist@86 1523 DValue* NewExp::toElem(IRState* p)
lindquist@1 1524 {
lindquist@1 1525 Logger::print("NewExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1526 LOG_SCOPE;
lindquist@1 1527
lindquist@1 1528 assert(newtype);
tomas@486 1529 Type* ntype = newtype->toBasetype();
lindquist@81 1530
lindquist@203 1531 // new class
lindquist@133 1532 if (ntype->ty == Tclass) {
lindquist@169 1533 Logger::println("new class");
tomas@486 1534 return DtoNewClass(loc, (TypeClass*)ntype, this);
lindquist@133 1535 }
lindquist@203 1536 // new dynamic array
lindquist@203 1537 else if (ntype->ty == Tarray)
lindquist@203 1538 {
lindquist@203 1539 Logger::println("new dynamic array: %s", newtype->toChars());
lindquist@203 1540 // get dim
lindquist@203 1541 assert(arguments);
lindquist@286 1542 assert(arguments->dim >= 1);
lindquist@286 1543 if (arguments->dim == 1)
lindquist@286 1544 {
lindquist@286 1545 DValue* sz = ((Expression*)arguments->data[0])->toElem(p);
lindquist@286 1546 // allocate & init
kamm@591 1547 return DtoNewDynArray(loc, newtype, sz, true);
lindquist@286 1548 }
lindquist@286 1549 else
lindquist@286 1550 {
lindquist@286 1551 size_t ndims = arguments->dim;
lindquist@286 1552 std::vector<DValue*> dims(ndims);
lindquist@286 1553 for (size_t i=0; i<ndims; ++i)
lindquist@286 1554 dims[i] = ((Expression*)arguments->data[i])->toElem(p);
kamm@591 1555 return DtoNewMulDimDynArray(loc, newtype, &dims[0], ndims, true);
lindquist@286 1556 }
lindquist@203 1557 }
lindquist@203 1558 // new static array
lindquist@203 1559 else if (ntype->ty == Tsarray)
lindquist@203 1560 {
lindquist@203 1561 assert(0);
lindquist@203 1562 }
lindquist@203 1563 // new struct
lindquist@203 1564 else if (ntype->ty == Tstruct)
lindquist@203 1565 {
lindquist@213 1566 Logger::println("new struct on heap: %s\n", newtype->toChars());
lindquist@203 1567 // allocate
lindquist@213 1568 LLValue* mem = DtoNew(newtype);
lindquist@203 1569 // init
lindquist@203 1570 TypeStruct* ts = (TypeStruct*)ntype;
lindquist@203 1571 if (ts->isZeroInit()) {
lindquist@244 1572 DtoAggrZeroInit(mem);
lindquist@203 1573 }
lindquist@203 1574 else {
lindquist@203 1575 assert(ts->sym);
kamm@671 1576 DtoForceConstInitDsymbol(ts->sym);
lindquist@244 1577 DtoAggrCopy(mem,ts->sym->ir.irStruct->init);
lindquist@203 1578 }
tomas@486 1579 return new DImValue(type, mem);
lindquist@203 1580 }
lindquist@203 1581 // new basic type
lindquist@203 1582 else
lindquist@203 1583 {
lindquist@203 1584 // allocate
lindquist@213 1585 LLValue* mem = DtoNew(newtype);
tomas@585 1586 DVarValue tmpvar(newtype, mem);
lindquist@212 1587
lindquist@212 1588 // default initialize
lindquist@212 1589 Expression* exp = newtype->defaultInit(loc);
lindquist@212 1590 DValue* iv = exp->toElem(gIR);
kamm@399 1591 DtoAssign(loc, &tmpvar, iv);
lindquist@212 1592
lindquist@212 1593 // return as pointer-to
tomas@486 1594 return new DImValue(type, mem);
lindquist@203 1595 }
lindquist@203 1596
lindquist@203 1597 assert(0);
lindquist@1 1598 }
lindquist@1 1599
lindquist@1 1600 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1601
lindquist@86 1602 DValue* DeleteExp::toElem(IRState* p)
lindquist@1 1603 {
lindquist@1 1604 Logger::print("DeleteExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1605 LOG_SCOPE;
lindquist@1 1606
lindquist@209 1607 DValue* dval = e1->toElem(p);
tomas@486 1608 Type* et = e1->type->toBasetype();
lindquist@209 1609
lindquist@209 1610 // simple pointer
lindquist@209 1611 if (et->ty == Tpointer)
lindquist@209 1612 {
lindquist@213 1613 LLValue* rval = dval->getRVal();
lindquist@209 1614 DtoDeleteMemory(rval);
tomas@585 1615 if (dval->isVar())
lindquist@209 1616 DtoStore(llvm::Constant::getNullValue(rval->getType()), dval->getLVal());
lindquist@1 1617 }
lindquist@209 1618 // class
lindquist@209 1619 else if (et->ty == Tclass)
lindquist@209 1620 {
lindquist@209 1621 bool onstack = false;
lindquist@210 1622 TypeClass* tc = (TypeClass*)et;
lindquist@210 1623 if (tc->sym->isInterfaceDeclaration())
lindquist@210 1624 {
lindquist@210 1625 DtoDeleteInterface(dval->getRVal());
lindquist@210 1626 onstack = true;
lindquist@210 1627 }
lindquist@210 1628 else if (DVarValue* vv = dval->isVar()) {
lindquist@209 1629 if (vv->var && vv->var->onstack) {
kamm@554 1630 DtoFinalizeClass(dval->getRVal());
lindquist@275 1631 onstack = true;
lindquist@113 1632 }
lindquist@1 1633 }
lindquist@209 1634 if (!onstack) {
lindquist@213 1635 LLValue* rval = dval->getRVal();
lindquist@209 1636 DtoDeleteClass(rval);
lindquist@209 1637 }
tomas@585 1638 if (dval->isVar()) {
lindquist@213 1639 LLValue* lval = dval->getLVal();
lindquist@209 1640 DtoStore(llvm::Constant::getNullValue(lval->getType()->getContainedType(0)), lval);
lindquist@209 1641 }
lindquist@1 1642 }
lindquist@209 1643 // dyn array
lindquist@209 1644 else if (et->ty == Tarray)
lindquist@209 1645 {
lindquist@209 1646 DtoDeleteArray(dval);
tomas@715 1647 if (dval->isLVal())
tomas@715 1648 DtoSetArrayToNull(dval->getLVal());
lindquist@1 1649 }
lindquist@209 1650 // unknown/invalid
lindquist@209 1651 else
lindquist@209 1652 {
lindquist@209 1653 assert(0 && "invalid delete");
lindquist@1 1654 }
lindquist@1 1655
lindquist@209 1656 // no value to return
lindquist@209 1657 return NULL;
lindquist@1 1658 }
lindquist@1 1659
lindquist@1 1660 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1661
lindquist@86 1662 DValue* ArrayLengthExp::toElem(IRState* p)
lindquist@1 1663 {
lindquist@1 1664 Logger::print("ArrayLengthExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1665 LOG_SCOPE;
lindquist@1 1666
lindquist@86 1667 DValue* u = e1->toElem(p);
lindquist@335 1668 return new DImValue(type, DtoArrayLen(u));
lindquist@1 1669 }
lindquist@1 1670
lindquist@1 1671 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1672
lindquist@86 1673 DValue* AssertExp::toElem(IRState* p)
lindquist@1 1674 {
lindquist@328 1675 Logger::print("AssertExp::toElem: %s\n", toChars());
lindquist@1 1676 LOG_SCOPE;
lindquist@1 1677
kamm@530 1678 if(!global.params.useAssert)
kamm@530 1679 return NULL;
kamm@530 1680
lindquist@133 1681 // condition
lindquist@133 1682 DValue* cond = e1->toElem(p);
kamm@530 1683 Type* condty = e1->type->toBasetype();
kamm@530 1684
kamm@530 1685 InvariantDeclaration* invdecl;
kamm@530 1686
kamm@530 1687 // class invariants
kamm@530 1688 if(
kamm@530 1689 global.params.useInvariants &&
kamm@530 1690 condty->ty == Tclass &&
kamm@530 1691 !((TypeClass*)condty)->sym->isInterfaceDeclaration())
kamm@530 1692 {
kamm@530 1693 Logger::print("calling class invariant");
kamm@530 1694 llvm::Function* fn = LLVM_D_GetRuntimeFunction(gIR->module, "_d_invariant");
kamm@530 1695 LLValue* arg = DtoBitCast(cond->getRVal(), fn->getFunctionType()->getParamType(0));
kamm@530 1696 gIR->CreateCallOrInvoke(fn, arg);
kamm@530 1697 }
kamm@530 1698 // struct invariants
kamm@530 1699 else if(
kamm@530 1700 global.params.useInvariants &&
tomas@758 1701 condty->ty == Tpointer && condty->nextOf()->ty == Tstruct &&
tomas@758 1702 (invdecl = ((TypeStruct*)condty->nextOf())->sym->inv) != NULL)
kamm@530 1703 {
kamm@530 1704 Logger::print("calling struct invariant");
kamm@530 1705 DFuncValue invfunc(invdecl, invdecl->ir.irFunc->func, cond->getRVal());
kamm@530 1706 DtoCallFunction(loc, NULL, &invfunc, NULL);
kamm@530 1707 }
kamm@530 1708 else
kamm@530 1709 {
kamm@530 1710 // create basic blocks
kamm@530 1711 llvm::BasicBlock* oldend = p->scopeend();
kamm@530 1712 llvm::BasicBlock* assertbb = llvm::BasicBlock::Create("assert", p->topfunc(), oldend);
kamm@530 1713 llvm::BasicBlock* endbb = llvm::BasicBlock::Create("noassert", p->topfunc(), oldend);
kamm@530 1714
kamm@530 1715 // test condition
kamm@778 1716 LLValue* condval = DtoCast(loc, cond, Type::tbool)->getRVal();
kamm@530 1717
kamm@530 1718 // branch
kamm@530 1719 llvm::BranchInst::Create(endbb, assertbb, condval, p->scopebb());
kamm@530 1720
kamm@530 1721 // call assert runtime functions
kamm@530 1722 p->scope() = IRScope(assertbb,endbb);
kamm@530 1723 DtoAssert(&loc, msg ? msg->toElem(p) : NULL);
kamm@530 1724
kamm@530 1725 // rewrite the scope
kamm@530 1726 p->scope() = IRScope(endbb,oldend);
kamm@530 1727 }
lindquist@133 1728
lindquist@133 1729 // no meaningful return value
lindquist@133 1730 return NULL;
lindquist@1 1731 }
lindquist@1 1732
lindquist@1 1733 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1734
lindquist@86 1735 DValue* NotExp::toElem(IRState* p)
lindquist@1 1736 {
lindquist@1 1737 Logger::print("NotExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1738 LOG_SCOPE;
lindquist@1 1739
lindquist@86 1740 DValue* u = e1->toElem(p);
lindquist@86 1741
kamm@778 1742 LLValue* b = DtoCast(loc, u, Type::tbool)->getRVal();
lindquist@213 1743
kamm@611 1744 LLConstant* zero = DtoConstBool(false);
lindquist@86 1745 b = p->ir->CreateICmpEQ(b,zero);
lindquist@86 1746
lindquist@86 1747 return new DImValue(type, b);
lindquist@1 1748 }
lindquist@1 1749
lindquist@1 1750 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1751
lindquist@86 1752 DValue* AndAndExp::toElem(IRState* p)
lindquist@1 1753 {
lindquist@1 1754 Logger::print("AndAndExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1755 LOG_SCOPE;
lindquist@1 1756
lindquist@1 1757 // allocate a temporary for the final result. failed to come up with a better way :/
lindquist@213 1758 LLValue* resval = 0;
lindquist@1 1759 llvm::BasicBlock* entryblock = &p->topfunc()->front();
kamm@479 1760 resval = DtoAlloca(LLType::Int1Ty,"andandtmp");
lindquist@86 1761
lindquist@86 1762 DValue* u = e1->toElem(p);
lindquist@1 1763
lindquist@1 1764 llvm::BasicBlock* oldend = p->scopeend();
lindquist@205 1765 llvm::BasicBlock* andand = llvm::BasicBlock::Create("andand", gIR->topfunc(), oldend);
lindquist@205 1766 llvm::BasicBlock* andandend = llvm::BasicBlock::Create("andandend", gIR->topfunc(), oldend);
lindquist@86 1767
kamm@778 1768 LLValue* ubool = DtoCast(loc, u, Type::tbool)->getRVal();
lindquist@244 1769 DtoStore(ubool,resval);
lindquist@205 1770 llvm::BranchInst::Create(andand,andandend,ubool,p->scopebb());
lindquist@86 1771
lindquist@1 1772 p->scope() = IRScope(andand, andandend);
lindquist@86 1773 DValue* v = e2->toElem(p);
lindquist@86 1774
kamm@778 1775 LLValue* vbool = DtoCast(loc, v, Type::tbool)->getRVal();
tomas@704 1776 LLValue* uandvbool = llvm::BinaryOperator::Create(llvm::BinaryOperator::And, ubool, vbool,"tmp",p->scopebb());
lindquist@244 1777 DtoStore(uandvbool,resval);
lindquist@205 1778 llvm::BranchInst::Create(andandend,p->scopebb());
lindquist@1 1779
lindquist@1 1780 p->scope() = IRScope(andandend, oldend);
lindquist@86 1781
lindquist@244 1782 resval = DtoLoad(resval);
lindquist@86 1783 return new DImValue(type, resval);
lindquist@1 1784 }
lindquist@1 1785
lindquist@1 1786 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1787
lindquist@86 1788 DValue* OrOrExp::toElem(IRState* p)
lindquist@1 1789 {
lindquist@1 1790 Logger::print("OrOrExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1791 LOG_SCOPE;
lindquist@1 1792
lindquist@1 1793 // allocate a temporary for the final result. failed to come up with a better way :/
lindquist@213 1794 LLValue* resval = 0;
lindquist@1 1795 llvm::BasicBlock* entryblock = &p->topfunc()->front();
kamm@479 1796 resval = DtoAlloca(LLType::Int1Ty,"orortmp");
lindquist@86 1797
lindquist@86 1798 DValue* u = e1->toElem(p);
lindquist@1 1799
lindquist@1 1800 llvm::BasicBlock* oldend = p->scopeend();
lindquist@205 1801 llvm::BasicBlock* oror = llvm::BasicBlock::Create("oror", gIR->topfunc(), oldend);
lindquist@205 1802 llvm::BasicBlock* ororend = llvm::BasicBlock::Create("ororend", gIR->topfunc(), oldend);
lindquist@86 1803
kamm@778 1804 LLValue* ubool = DtoCast(loc, u, Type::tbool)->getRVal();
lindquist@244 1805 DtoStore(ubool,resval);
lindquist@205 1806 llvm::BranchInst::Create(ororend,oror,ubool,p->scopebb());
lindquist@86 1807
lindquist@1 1808 p->scope() = IRScope(oror, ororend);
lindquist@86 1809 DValue* v = e2->toElem(p);
lindquist@86 1810
kamm@778 1811 LLValue* vbool = DtoCast(loc, v, Type::tbool)->getRVal();
lindquist@244 1812 DtoStore(vbool,resval);
lindquist@205 1813 llvm::BranchInst::Create(ororend,p->scopebb());
lindquist@1 1814
lindquist@1 1815 p->scope() = IRScope(ororend, oldend);
lindquist@86 1816
lindquist@86 1817 resval = new llvm::LoadInst(resval,"tmp",p->scopebb());
lindquist@86 1818 return new DImValue(type, resval);
lindquist@1 1819 }
lindquist@1 1820
lindquist@1 1821 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1822
lindquist@1 1823 #define BinBitExp(X,Y) \
lindquist@86 1824 DValue* X##Exp::toElem(IRState* p) \
lindquist@1 1825 { \
lindquist@1 1826 Logger::print("%sExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \
lindquist@1 1827 LOG_SCOPE; \
lindquist@86 1828 DValue* u = e1->toElem(p); \
lindquist@86 1829 DValue* v = e2->toElem(p); \
tomas@704 1830 LLValue* x = llvm::BinaryOperator::Create(llvm::Instruction::Y, u->getRVal(), v->getRVal(), "tmp", p->scopebb()); \
lindquist@86 1831 return new DImValue(type, x); \
lindquist@1 1832 } \
lindquist@1 1833 \
lindquist@86 1834 DValue* X##AssignExp::toElem(IRState* p) \
lindquist@1 1835 { \
lindquist@1 1836 Logger::print("%sAssignExp::toElem: %s | %s\n", #X, toChars(), type->toChars()); \
lindquist@1 1837 LOG_SCOPE; \
lindquist@86 1838 DValue* u = e1->toElem(p); \
lindquist@86 1839 DValue* v = e2->toElem(p); \
lindquist@213 1840 LLValue* uval = u->getRVal(); \
lindquist@213 1841 LLValue* vval = v->getRVal(); \
tomas@704 1842 LLValue* tmp = llvm::BinaryOperator::Create(llvm::Instruction::Y, uval, vval, "tmp", p->scopebb()); \
lindquist@244 1843 DtoStore(DtoPointedType(u->getLVal(), tmp), u->getLVal()); \
lindquist@86 1844 return u; \
lindquist@1 1845 }
lindquist@1 1846
lindquist@1 1847 BinBitExp(And,And);
lindquist@1 1848 BinBitExp(Or,Or);
lindquist@1 1849 BinBitExp(Xor,Xor);
lindquist@1 1850 BinBitExp(Shl,Shl);
lindquist@1 1851 BinBitExp(Ushr,LShr);
lindquist@1 1852
lindquist@268 1853 DValue* ShrExp::toElem(IRState* p)
lindquist@268 1854 {
lindquist@268 1855 Logger::print("ShrExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@268 1856 LOG_SCOPE;
lindquist@268 1857 DValue* u = e1->toElem(p);
lindquist@268 1858 DValue* v = e2->toElem(p);
lindquist@268 1859 LLValue* x;
lindquist@268 1860 if (e1->type->isunsigned())
lindquist@268 1861 x = p->ir->CreateLShr(u->getRVal(), v->getRVal(), "tmp");
lindquist@268 1862 else
lindquist@268 1863 x = p->ir->CreateAShr(u->getRVal(), v->getRVal(), "tmp");
lindquist@268 1864 return new DImValue(type, x);
lindquist@268 1865 }
lindquist@268 1866
lindquist@268 1867 DValue* ShrAssignExp::toElem(IRState* p)
lindquist@268 1868 {
lindquist@268 1869 Logger::print("ShrAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@268 1870 LOG_SCOPE;
lindquist@268 1871 DValue* u = e1->toElem(p);
lindquist@268 1872 DValue* v = e2->toElem(p);
lindquist@268 1873 LLValue* uval = u->getRVal();
lindquist@268 1874 LLValue* vval = v->getRVal();
lindquist@268 1875 LLValue* tmp;
lindquist@268 1876 if (e1->type->isunsigned())
lindquist@268 1877 tmp = p->ir->CreateLShr(uval, vval, "tmp");
lindquist@268 1878 else
lindquist@268 1879 tmp = p->ir->CreateAShr(uval, vval, "tmp");
lindquist@268 1880 DtoStore(DtoPointedType(u->getLVal(), tmp), u->getLVal());
lindquist@268 1881 return u;
lindquist@268 1882 }
lindquist@268 1883
lindquist@1 1884 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1885
lindquist@86 1886 DValue* HaltExp::toElem(IRState* p)
lindquist@1 1887 {
lindquist@262 1888 Logger::print("HaltExp::toElem: %s\n", toChars());
lindquist@1 1889 LOG_SCOPE;
lindquist@1 1890
lindquist@363 1891 // FIXME: DMD inserts a trap here... we probably should as well !?!
lindquist@363 1892
ChristianK@281 1893 #if 1
lindquist@258 1894 DtoAssert(&loc, NULL);
lindquist@258 1895 #else
lindquist@217 1896 // call the new (?) trap intrinsic
lindquist@217 1897 p->ir->CreateCall(GET_INTRINSIC_DECL(trap),"");
lindquist@291 1898 new llvm::UnreachableInst(p->scopebb());
lindquist@258 1899 #endif
lindquist@36 1900
ChristianK@282 1901 // this terminated the basicblock, start a new one
ChristianK@282 1902 // this is sensible, since someone might goto behind the assert
ChristianK@282 1903 // and prevents compiler errors if a terminator follows the assert
ChristianK@282 1904 llvm::BasicBlock* oldend = gIR->scopeend();
ChristianK@282 1905 llvm::BasicBlock* bb = llvm::BasicBlock::Create("afterhalt", p->topfunc(), oldend);
ChristianK@282 1906 p->scope() = IRScope(bb,oldend);
ChristianK@282 1907
lindquist@1 1908 return 0;
lindquist@1 1909 }
lindquist@1 1910
lindquist@1 1911 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1912
lindquist@86 1913 DValue* DelegateExp::toElem(IRState* p)
lindquist@1 1914 {
lindquist@1 1915 Logger::print("DelegateExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1916 LOG_SCOPE;
lindquist@1 1917
kamm@426 1918 if(func->isStatic())
kamm@426 1919 error("can't take delegate of static function %s, it does not require a context ptr", func->toChars());
kamm@426 1920
lindquist@244 1921 const LLPointerType* int8ptrty = getPtrToType(LLType::Int8Ty);
lindquist@1 1922
tomas@719 1923 assert(type->toBasetype()->ty == Tdelegate);
tomas@719 1924 const LLType* dgty = DtoType(type);
lindquist@1 1925
lindquist@143 1926 DValue* u = e1->toElem(p);
lindquist@213 1927 LLValue* uval;
lindquist@119 1928 if (DFuncValue* f = u->isFunc()) {
tomas@634 1929 assert(f->func);
tomas@634 1930 LLValue* contextptr = DtoNestedContext(loc, f->func);
tomas@486 1931 uval = DtoBitCast(contextptr, getVoidPtrType());
lindquist@119 1932 }
lindquist@119 1933 else {
lindquist@143 1934 DValue* src = u;
lindquist@143 1935 if (ClassDeclaration* cd = u->getType()->isClassHandle())
lindquist@143 1936 {
lindquist@143 1937 Logger::println("context type is class handle");
lindquist@143 1938 if (cd->isInterfaceDeclaration())
lindquist@143 1939 {
lindquist@143 1940 Logger::println("context type is interface");
lindquist@143 1941 src = DtoCastInterfaceToObject(u, ClassDeclaration::object->type);
lindquist@143 1942 }
lindquist@143 1943 }
lindquist@143 1944 uval = src->getRVal();
lindquist@119 1945 }
lindquist@119 1946
tomas@622 1947 if (Logger::enabled())
tomas@622 1948 Logger::cout() << "context = " << *uval << '\n';
lindquist@143 1949
lindquist@213 1950 LLValue* castcontext = DtoBitCast(uval, int8ptrty);
lindquist@133 1951
lindquist@133 1952 Logger::println("func: '%s'", func->toPrettyChars());
lindquist@133 1953
lindquist@213 1954 LLValue* castfptr;
lindquist@133 1955 if (func->isVirtual())
lindquist@133 1956 castfptr = DtoVirtualFunctionPointer(u, func);
lindquist@133 1957 else if (func->isAbstract())
lindquist@133 1958 assert(0 && "TODO delegate to abstract method");
lindquist@133 1959 else if (func->toParent()->isInterfaceDeclaration())
lindquist@133 1960 assert(0 && "TODO delegate to interface method");
lindquist@133 1961 else
lindquist@150 1962 {
lindquist@150 1963 DtoForceDeclareDsymbol(func);
ChristianK@173 1964 castfptr = func->ir.irFunc->func;
lindquist@150 1965 }
lindquist@133 1966
tomas@719 1967 castfptr = DtoBitCast(castfptr, dgty->getContainedType(1));
tomas@719 1968
tomas@719 1969 return new DImValue(type, DtoAggrPair(castcontext, castfptr, ".dg"));
lindquist@1 1970 }
lindquist@1 1971
lindquist@1 1972 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 1973
lindquist@86 1974 DValue* IdentityExp::toElem(IRState* p)
lindquist@1 1975 {
lindquist@1 1976 Logger::print("IdentityExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 1977 LOG_SCOPE;
lindquist@1 1978
lindquist@86 1979 DValue* u = e1->toElem(p);
lindquist@86 1980 DValue* v = e2->toElem(p);
lindquist@86 1981
lindquist@308 1982 Type* t1 = e1->type->toBasetype();
lindquist@308 1983
lindquist@308 1984 // handle dynarray specially
lindquist@308 1985 if (t1->ty == Tarray)
lindquist@308 1986 return new DImValue(type, DtoDynArrayIs(op,u,v));
lindquist@345 1987 // also structs
lindquist@345 1988 else if (t1->ty == Tstruct)
lindquist@345 1989 return new DImValue(type, DtoStructEquals(op,u,v));
lindquist@345 1990
lindquist@345 1991 // FIXME this stuff isn't pretty
lindquist@213 1992 LLValue* l = u->getRVal();
lindquist@213 1993 LLValue* r = v->getRVal();
lindquist@213 1994 LLValue* eval = 0;
lindquist@86 1995
lindquist@308 1996 if (t1->ty == Tdelegate) {
lindquist@162 1997 if (v->isNull()) {
lindquist@162 1998 r = NULL;
lindquist@162 1999 }
lindquist@162 2000 else {
lindquist@162 2001 assert(l->getType() == r->getType());
lindquist@162 2002 }
lindquist@344 2003 eval = DtoDelegateEquals(op,l,r);
lindquist@162 2004 }
lindquist@144 2005 else if (t1->isfloating())
lindquist@144 2006 {
lindquist@365 2007 eval = (op == TOKidentity)
lindquist@365 2008 ? p->ir->CreateFCmpOEQ(l,r,"tmp")
lindquist@365 2009 : p->ir->CreateFCmpONE(l,r,"tmp");
lindquist@144 2010 }
tomas@629 2011 else if (t1->ty == Tpointer || t1->ty == Tclass)
lindquist@167 2012 {
lindquist@167 2013 if (l->getType() != r->getType()) {
lindquist@167 2014 if (v->isNull())
lindquist@167 2015 r = llvm::ConstantPointerNull::get(isaPointer(l->getType()));
lindquist@167 2016 else
lindquist@244 2017 r = DtoBitCast(r, l->getType());
lindquist@167 2018 }
lindquist@365 2019 eval = (op == TOKidentity)
lindquist@365 2020 ? p->ir->CreateICmpEQ(l,r,"tmp")
lindquist@365 2021 : p->ir->CreateICmpNE(l,r,"tmp");
lindquist@167 2022 }
lindquist@54 2023 else {
tomas@629 2024 assert(l->getType() == r->getType());
lindquist@365 2025 eval = (op == TOKidentity)
lindquist@365 2026 ? p->ir->CreateICmpEQ(l,r,"tmp")
lindquist@365 2027 : p->ir->CreateICmpNE(l,r,"tmp");
lindquist@54 2028 }
lindquist@86 2029 return new DImValue(type, eval);
lindquist@1 2030 }
lindquist@1 2031
lindquist@1 2032 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 2033
lindquist@86 2034 DValue* CommaExp::toElem(IRState* p)
lindquist@1 2035 {
lindquist@1 2036 Logger::print("CommaExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 2037 LOG_SCOPE;
lindquist@1 2038
lindquist@86 2039 DValue* u = e1->toElem(p);
lindquist@86 2040 DValue* v = e2->toElem(p);
lindquist@144 2041 assert(e2->type == type);
lindquist@1 2042 return v;
lindquist@1 2043 }
lindquist@1 2044
lindquist@1 2045 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 2046
lindquist@86 2047 DValue* CondExp::toElem(IRState* p)
lindquist@1 2048 {
lindquist@1 2049 Logger::print("CondExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 2050 LOG_SCOPE;
lindquist@1 2051
tomas@486 2052 Type* dtype = type->toBasetype();
lindquist@213 2053 const LLType* resty = DtoType(dtype);
lindquist@1 2054
lindquist@1 2055 // allocate a temporary for the final result. failed to come up with a better way :/
lindquist@1 2056 llvm::BasicBlock* entryblock = &p->topfunc()->front();
kamm@479 2057 LLValue* resval = DtoAlloca(resty,"condtmp");
tomas@585 2058 DVarValue* dvv = new DVarValue(type, resval);
lindquist@1 2059
lindquist@1 2060 llvm::BasicBlock* oldend = p->scopeend();
lindquist@205 2061 llvm::BasicBlock* condtrue = llvm::BasicBlock::Create("condtrue", gIR->topfunc(), oldend);
lindquist@205 2062 llvm::BasicBlock* condfalse = llvm::BasicBlock::Create("condfalse", gIR->topfunc(), oldend);
lindquist@205 2063 llvm::BasicBlock* condend = llvm::BasicBlock::Create("condend", gIR->topfunc(), oldend);
lindquist@1 2064
lindquist@86 2065 DValue* c = econd->toElem(p);
kamm@778 2066 LLValue* cond_val = DtoCast(loc, c, Type::tbool)->getRVal();
lindquist@205 2067 llvm::BranchInst::Create(condtrue,condfalse,cond_val,p->scopebb());
lindquist@1 2068
lindquist@1 2069 p->scope() = IRScope(condtrue, condfalse);
lindquist@86 2070 DValue* u = e1->toElem(p);
kamm@399 2071 DtoAssign(loc, dvv, u);
lindquist@205 2072 llvm::BranchInst::Create(condend,p->scopebb());
lindquist@1 2073
lindquist@1 2074 p->scope() = IRScope(condfalse, condend);
lindquist@86 2075 DValue* v = e2->toElem(p);
kamm@399 2076 DtoAssign(loc, dvv, v);
lindquist@205 2077 llvm::BranchInst::Create(condend,p->scopebb());
lindquist@1 2078
lindquist@1 2079 p->scope() = IRScope(condend, oldend);
lindquist@86 2080 return dvv;
lindquist@1 2081 }
lindquist@1 2082
lindquist@1 2083 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 2084
lindquist@86 2085 DValue* ComExp::toElem(IRState* p)
lindquist@1 2086 {
lindquist@1 2087 Logger::print("ComExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@1 2088 LOG_SCOPE;
lindquist@1 2089
lindquist@86 2090 DValue* u = e1->toElem(p);
lindquist@86 2091
lindquist@213 2092 LLValue* value = u->getRVal();
tomas@809 2093 LLValue* minusone = llvm::ConstantInt::get(value->getType(), (uint64_t)-1, true);
tomas@704 2094 value = llvm::BinaryOperator::Create(llvm::Instruction::Xor, value, minusone, "tmp", p->scopebb());
lindquist@86 2095
lindquist@86 2096 return new DImValue(type, value);
lindquist@1 2097 }
lindquist@1 2098
lindquist@1 2099 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@1 2100
lindquist@86 2101 DValue* NegExp::toElem(IRState* p)
lindquist@23 2102 {
lindquist@23 2103 Logger::print("NegExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@23 2104 LOG_SCOPE;
lindquist@86 2105
lindquist@86 2106 DValue* l = e1->toElem(p);
lindquist@164 2107
lindquist@164 2108 if (type->iscomplex()) {
kamm@399 2109 return DtoComplexNeg(loc, type, l);
lindquist@164 2110 }
lindquist@164 2111
lindquist@213 2112 LLValue* val = l->getRVal();
kamm@616 2113
kamm@616 2114 val = gIR->ir->CreateNeg(val,"negval");
lindquist@86 2115 return new DImValue(type, val);
lindquist@23 2116 }
lindquist@23 2117
lindquist@23 2118 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@23 2119
lindquist@86 2120 DValue* CatExp::toElem(IRState* p)
lindquist@36 2121 {
lindquist@36 2122 Logger::print("CatExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@36 2123 LOG_SCOPE;
lindquist@36 2124
tomas@486 2125 Type* t = type->toBasetype();
tomas@486 2126
tomas@486 2127 bool arrNarr = e1->type->toBasetype() == e2->type->toBasetype();
lindquist@132 2128
lindquist@203 2129 // array ~ array
lindquist@203 2130 if (arrNarr)
lindquist@203 2131 {
lindquist@203 2132 return DtoCatArrays(type, e1, e2);
lindquist@203 2133 }
lindquist@203 2134 // array ~ element
lindquist@203 2135 // element ~ array
lindquist@203 2136 else
lindquist@203 2137 {
lindquist@203 2138 return DtoCatArrayElement(type, e1, e2);
lindquist@203 2139 }
lindquist@36 2140 }
lindquist@36 2141
lindquist@36 2142 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@36 2143
lindquist@86 2144 DValue* CatAssignExp::toElem(IRState* p)
lindquist@40 2145 {
lindquist@40 2146 Logger::print("CatAssignExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@40 2147 LOG_SCOPE;
lindquist@40 2148
lindquist@86 2149 DValue* l = e1->toElem(p);
lindquist@40 2150
tomas@486 2151 Type* e1type = e1->type->toBasetype();
tomas@758 2152 Type* elemtype = e1type->nextOf()->toBasetype();
tomas@486 2153 Type* e2type = e2->type->toBasetype();
lindquist@40 2154
lindquist@40 2155 if (e2type == elemtype) {
lindquist@203 2156 DSliceValue* slice = DtoCatAssignElement(l,e2);
kamm@399 2157 DtoAssign(loc, l, slice);
lindquist@86 2158 }
lindquist@86 2159 else if (e1type == e2type) {
lindquist@203 2160 DSliceValue* slice = DtoCatAssignArray(l,e2);
kamm@399 2161 DtoAssign(loc, l, slice);
lindquist@40 2162 }
lindquist@40 2163 else
lindquist@40 2164 assert(0 && "only one element at a time right now");
lindquist@40 2165
lindquist@203 2166 return l;
lindquist@40 2167 }
lindquist@40 2168
lindquist@40 2169 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@40 2170
lindquist@86 2171 DValue* FuncExp::toElem(IRState* p)
lindquist@49 2172 {
lindquist@49 2173 Logger::print("FuncExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@49 2174 LOG_SCOPE;
lindquist@49 2175
lindquist@49 2176 assert(fd);
lindquist@49 2177
lindquist@49 2178 if (fd->isNested()) Logger::println("nested");
lindquist@49 2179 Logger::println("kind = %s\n", fd->kind());
lindquist@49 2180
lindquist@108 2181 DtoForceDefineDsymbol(fd);
kamm@521 2182 assert(fd->ir.irFunc->func);
lindquist@49 2183
kamm@520 2184 if(fd->tok == TOKdelegate) {
kamm@520 2185 const LLType* dgty = DtoType(type);
tomas@719 2186
kamm@520 2187 LLValue* cval;
kamm@520 2188 IrFunction* irfn = p->func();
kamm@520 2189 if (irfn->nestedVar)
kamm@520 2190 cval = irfn->nestedVar;
kamm@520 2191 else if (irfn->nestArg)
kamm@520 2192 cval = irfn->nestArg;
kamm@520 2193 else
kamm@520 2194 cval = getNullPtr(getVoidPtrType());
tomas@719 2195 cval = DtoBitCast(cval, dgty->getContainedType(0));
tomas@719 2196
tomas@719 2197 LLValue* castfptr = DtoBitCast(fd->ir.irFunc->func, dgty->getContainedType(1));
tomas@719 2198
tomas@719 2199 return new DImValue(type, DtoAggrPair(cval, castfptr, ".func"));
kamm@521 2200
kamm@520 2201 } else if(fd->tok == TOKfunction) {
tomas@585 2202 return new DImValue(type, fd->ir.irFunc->func);
kamm@520 2203 }
kamm@521 2204
kamm@521 2205 assert(0 && "fd->tok must be TOKfunction or TOKdelegate");
lindquist@49 2206 }
lindquist@49 2207
lindquist@49 2208 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@49 2209
tomas@797 2210 LLConstant* FuncExp::toConstElem(IRState* p)
tomas@797 2211 {
tomas@797 2212 Logger::print("FuncExp::toConstElem: %s | %s\n", toChars(), type->toChars());
tomas@797 2213 LOG_SCOPE;
tomas@797 2214
tomas@797 2215 assert(fd);
tomas@797 2216 assert(fd->tok == TOKfunction);
tomas@797 2217
tomas@797 2218 DtoForceDefineDsymbol(fd);
tomas@797 2219 assert(fd->ir.irFunc->func);
tomas@797 2220
tomas@797 2221 return fd->ir.irFunc->func;
tomas@797 2222 }
tomas@797 2223
tomas@797 2224 //////////////////////////////////////////////////////////////////////////////////////////
tomas@797 2225
lindquist@86 2226 DValue* ArrayLiteralExp::toElem(IRState* p)
lindquist@86 2227 {
lindquist@86 2228 Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@86 2229 LOG_SCOPE;
lindquist@86 2230
lindquist@175 2231 // D types
lindquist@175 2232 Type* arrayType = type->toBasetype();
lindquist@175 2233 Type* elemType = arrayType->nextOf()->toBasetype();
lindquist@175 2234
lindquist@175 2235 // is dynamic ?
lindquist@175 2236 bool dyn = (arrayType->ty == Tarray);
lindquist@175 2237 // length
lindquist@175 2238 size_t len = elements->dim;
lindquist@175 2239
lindquist@175 2240 // llvm target type
lindquist@213 2241 const LLType* llType = DtoType(arrayType);
tomas@622 2242 if (Logger::enabled())
tomas@622 2243 Logger::cout() << (dyn?"dynamic":"static") << " array literal with length " << len << " of D type: '" << arrayType->toChars() << "' has llvm type: '" << *llType << "'\n";
lindquist@175 2244
lindquist@175 2245 // llvm storage type
tomas@587 2246 const LLType* llElemType = DtoTypeNotVoid(elemType);
tomas@587 2247 const LLType* llStoType = LLArrayType::get(llElemType, len);
tomas@622 2248 if (Logger::enabled())
tomas@622 2249 Logger::cout() << "llvm storage type: '" << *llStoType << "'\n";
lindquist@175 2250
tomas@587 2251 // don't allocate storage for zero length dynamic array literals
tomas@587 2252 if (dyn && len == 0)
tomas@587 2253 {
tomas@587 2254 // dmd seems to just make them null...
tomas@587 2255 return new DSliceValue(type, DtoConstSize_t(0), getNullPtr(getPtrToType(llElemType)));
tomas@587 2256 }
tomas@587 2257
lindquist@175 2258 // dst pointer
kamm@592 2259 LLValue* dstMem;
kamm@592 2260 DSliceValue* dynSlice = NULL;
kamm@592 2261 if(dyn)
kamm@592 2262 {
kamm@592 2263 dynSlice = DtoNewDynArray(loc, arrayType, new DConstValue(Type::tsize_t, DtoConstSize_t(len)), false);
kamm@592 2264 dstMem = dynSlice->ptr;
kamm@592 2265 }
kamm@592 2266 else
kamm@592 2267 dstMem = DtoAlloca(llStoType, "arrayliteral");
lindquist@175 2268
lindquist@175 2269 // store elements
lindquist@175 2270 for (size_t i=0; i<len; ++i)
lindquist@86 2271 {
lindquist@86 2272 Expression* expr = (Expression*)elements->data[i];
kamm@592 2273 LLValue* elemAddr;
kamm@592 2274 if(dyn)
kamm@592 2275 elemAddr = DtoGEPi1(dstMem, i, "tmp", p->scopebb());
kamm@592 2276 else
kamm@592 2277 elemAddr = DtoGEPi(dstMem,0,i,"tmp",p->scopebb());
lindquist@175 2278
lindquist@175 2279 // emulate assignment
tomas@585 2280 DVarValue* vv = new DVarValue(expr->type, elemAddr);
lindquist@86 2281 DValue* e = expr->toElem(p);
tomas@486 2282 DtoAssign(loc, vv, e);
lindquist@86 2283 }
lindquist@86 2284
lindquist@175 2285 // return storage directly ?
tomas@486 2286 if (!dyn)
tomas@486 2287 return new DImValue(type, dstMem);
tomas@486 2288
kamm@592 2289 // return slice
kamm@592 2290 return dynSlice;
lindquist@86 2291 }
lindquist@86 2292
lindquist@86 2293 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@86 2294
lindquist@213 2295 LLConstant* ArrayLiteralExp::toConstElem(IRState* p)
lindquist@86 2296 {
lindquist@86 2297 Logger::print("ArrayLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars());
lindquist@86 2298 LOG_SCOPE;
lindquist@86 2299
tomas@602 2300 // extract D types
tomas@602 2301 Type* bt = type->toBasetype();
tomas@758 2302 Type* elemt = bt->nextOf();
tomas@602 2303
tomas@602 2304 // build llvm array type
tomas@602 2305 const LLArrayType* arrtype = LLArrayType::get(DtoType(elemt), elements->dim);
tomas@602 2306
tomas@602 2307 // dynamic arrays can occur here as well ...
kamm@603 2308 bool dyn = (bt->ty == Tarray);
tomas@602 2309
tomas@602 2310 // build the initializer
lindquist@213 2311 std::vector<LLConstant*> vals(elements->dim, NULL);
lindquist@86 2312 for (unsigned i=0; i<elements->dim; ++i)
lindquist@86 2313 {
lindquist@86 2314 Expression* expr = (Expression*)elements->data[i];
lindquist@86 2315 vals[i] = expr->toConstElem(p);
lindquist@86 2316 }
lindquist@86 2317
tomas@602 2318 // build the constant array initializer
tomas@602 2319 LLConstant* initval = llvm::ConstantArray::get(arrtype, vals);
tomas@602 2320
tomas@602 2321 // if static array, we're done
tomas@602 2322 if (!dyn)
tomas@602 2323 return initval;
tomas@602 2324
tomas@602 2325 // for dynamic arrays we need to put the initializer in a global, and build a constant dynamic array reference with the .ptr field pointing into this global
tomas@602 2326 LLConstant* globalstore = new LLGlobalVariable(arrtype, true, LLGlobalValue::InternalLinkage, initval, ".dynarrayStorage", p->module);
tomas@602 2327 LLConstant* idxs[2] = { DtoConstUint(0), DtoConstUint(0) };
tomas@602 2328 LLConstant* globalstorePtr = llvm::ConstantExpr::getGetElementPtr(globalstore, idxs, 2);
tomas@602 2329
tomas@602 2330 return DtoConstSlice(DtoConstSize_t(elements->dim), globalstorePtr);
lindquist@86 2331 }
lindquist@86 2332
lindquist@86 2333 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@86 2334
lindquist@86 2335 DValue* StructLiteralExp::toElem(IRState* p)
lindquist@86 2336 {
lindquist@86 2337 Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@86 2338 LOG_SCOPE;
lindquist@86 2339
tomas@797 2340 // get arrays
tomas@823 2341 size_t nexprs = elements->dim;;
tomas@797 2342 Expression** exprs = (Expression**)elements->data;
tomas@797 2343
tomas@823 2344 size_t nvars = sd->fields.dim;
tomas@797 2345 VarDeclaration** vars = (VarDeclaration**)sd->fields.data;
tomas@797 2346
tomas@823 2347 assert(nexprs <= nvars);
tomas@823 2348
tomas@823 2349 // first locate all explicit initializers
tomas@823 2350 std::vector<VarDeclaration*> explicitInits;
tomas@823 2351 for (size_t i=0; i < nexprs; i++)
tomas@823 2352 {
tomas@823 2353 if (exprs[i])
tomas@823 2354 {
tomas@823 2355 explicitInits.push_back(vars[i]);
tomas@823 2356 }
tomas@823 2357 }
tomas@823 2358
tomas@797 2359 // vector of values to build aggregate from
tomas@797 2360 std::vector<llvm::Value*> values;
tomas@797 2361
tomas@823 2362 // offset trackers
tomas@797 2363 size_t lastoffset = 0;
tomas@797 2364 size_t lastsize = 0;
tomas@797 2365
tomas@823 2366 // index of next explicit init
tomas@823 2367 size_t exidx = 0;
tomas@823 2368 // number of explicit inits
tomas@823 2369 size_t nex = explicitInits.size();
tomas@823 2370
tomas@797 2371 // for through each field and build up the struct, padding with zeros
tomas@823 2372 size_t i;
tomas@823 2373 for (i=0; i<nvars; i++)
tomas@797 2374 {
tomas@823 2375 Expression* e = (nexprs > i) ? exprs[i] : NULL;
tomas@797 2376 VarDeclaration* var = vars[i];
tomas@797 2377
tomas@823 2378 // get var info
tomas@823 2379 size_t os = var->offset;
tomas@823 2380 size_t sz = var->type->size();
tomas@823 2381
tomas@823 2382 // get next explicit
tomas@823 2383 VarDeclaration* nextVar = NULL;
tomas@823 2384 size_t nextOs = 0;
tomas@823 2385 if (exidx < nex)
tomas@823 2386 {
tomas@823 2387 nextVar = explicitInits[exidx];
tomas@823 2388 nextOs = nextVar->offset;
tomas@823 2389 }
tomas@823 2390 // none, rest is defaults
tomas@823 2391 else
tomas@823 2392 {
tomas@823 2393 break;
tomas@823 2394 }
tomas@823 2395
tomas@823 2396 // not explicit initializer, default initialize if there is room, otherwise skip
tomas@797 2397 if (!e)
tomas@823 2398 {
tomas@823 2399 // default init if there is room
tomas@823 2400 // (past current offset) and (small enough to fit before next explicit)
tomas@823 2401 if ((os >= lastoffset + lastsize) && (os+sz <= nextOs))
tomas@823 2402 {
tomas@823 2403 // add any 0 padding needed before this field
tomas@823 2404 if (os > lastoffset + lastsize)
tomas@823 2405 {
tomas@823 2406 //printf("1added %lu zeros\n", os - lastoffset - lastsize);
tomas@823 2407 addZeros(values, lastoffset + lastsize, os);
tomas@823 2408 }
tomas@823 2409
tomas@823 2410 // get field default init
tomas@823 2411 IrField* f = var->ir.irField;
tomas@823 2412 assert(f);
tomas@823 2413 if (!f->constInit)
tomas@823 2414 f->constInit = DtoConstInitializer(var->loc, var->type, var->init);
tomas@823 2415
tomas@823 2416 values.push_back(f->constInit);
tomas@823 2417
tomas@823 2418 lastoffset = os;
tomas@823 2419 lastsize = sz;
tomas@823 2420 //printf("added default: %s : %lu (%lu)\n", var->toChars(), os, sz);
tomas@823 2421 }
tomas@823 2422 // skip
tomas@797 2423 continue;
tomas@823 2424 }
tomas@823 2425
tomas@823 2426 assert(nextVar == var);
tomas@797 2427
tomas@797 2428 // add any 0 padding needed before this field
tomas@823 2429 if (os > lastoffset + lastsize)
tomas@797 2430 {
tomas@823 2431 //printf("added %lu zeros\n", os - lastoffset - lastsize);
tomas@823 2432 addZeros(values, lastoffset + lastsize, os);
lindquist@86 2433 }
tomas@797 2434
tomas@797 2435 // add the expression value
tomas@797 2436 DValue* v = e->toElem(p);
tomas@797 2437 values.push_back(v->getRVal());
tomas@797 2438
tomas@797 2439 // update offsets
tomas@823 2440 lastoffset = os;
tomas@823 2441 lastsize = sz;
tomas@823 2442
tomas@823 2443 // go to next explicit init
tomas@823 2444 exidx++;
tomas@823 2445
tomas@823 2446 //printf("added field: %s : %lu (%lu)\n", var->toChars(), os, sz);
lindquist@86 2447 }
lindquist@86 2448
tomas@823 2449 // fill out rest with default initializers
tomas@797 2450 const LLType* structtype = DtoType(sd->type);
tomas@797 2451 size_t structsize = getABITypeSize(structtype);
tomas@797 2452
tomas@823 2453 // FIXME: this could probably share some code with the above
tomas@797 2454 if (structsize > lastoffset+lastsize)
lindquist@86 2455 {
tomas@823 2456 for (/*continue from first loop*/; i < nvars; i++)
tomas@823 2457 {
tomas@823 2458 VarDeclaration* var = vars[i];
tomas@823 2459
tomas@823 2460 // get var info
tomas@823 2461 size_t os = var->offset;
tomas@823 2462 size_t sz = var->type->size();
tomas@823 2463
tomas@823 2464 // skip?
tomas@823 2465 if (os < lastoffset + lastsize)
tomas@823 2466 continue;
tomas@823 2467
tomas@823 2468 // add any 0 padding needed before this field
tomas@823 2469 if (os > lastoffset + lastsize)
tomas@823 2470 {
tomas@823 2471 //printf("2added %lu zeros\n", os - lastoffset - lastsize);
tomas@823 2472 addZeros(values, lastoffset + lastsize, os);
tomas@823 2473 }
tomas@823 2474
tomas@823 2475 // get field default init
tomas@823 2476 IrField* f = var->ir.irField;
tomas@823 2477 assert(f);
tomas@823 2478 if (!f->constInit)
tomas@823 2479 f->constInit = DtoConstInitializer(var->loc, var->type, var->init);
tomas@823 2480
tomas@823 2481 values.push_back(f->constInit);
tomas@823 2482
tomas@823 2483 lastoffset = os;
tomas@823 2484 lastsize = sz;
tomas@823 2485 //printf("2added default: %s : %lu (%lu)\n", var->toChars(), os, sz);
tomas@823 2486 }
tomas@823 2487 }
tomas@823 2488
tomas@823 2489 // add any 0 padding needed at the end of the literal
tomas@823 2490 if (structsize > lastoffset+lastsize)
tomas@823 2491 {
tomas@823 2492 //printf("3added %lu zeros\n", structsize - lastoffset - lastsize);
tomas@797 2493 addZeros(values, lastoffset + lastsize, structsize);
lindquist@86 2494 }
lindquist@86 2495
tomas@797 2496 // get the struct type from the values
tomas@823 2497 size_t n = values.size();
tomas@797 2498 std::vector<const LLType*> types(n, NULL);
tomas@797 2499
tomas@797 2500 for (size_t i=0; i<n; i++)
tomas@797 2501 {
tomas@797 2502 types[i] = values[i]->getType();
tomas@797 2503 }
tomas@797 2504
tomas@797 2505 const LLStructType* sty = LLStructType::get(types, sd->ir.irStruct->packed);
tomas@797 2506
tomas@797 2507 // allocate storage for the struct literal on the stack
tomas@797 2508 LLValue* mem = DtoAlloca(sty, "tmpstructliteral");
tomas@797 2509
tomas@797 2510 // put all the values into the storage
tomas@797 2511 for (size_t i=0; i<n; i++)
tomas@797 2512 {
tomas@797 2513 LLValue* ptr = DtoGEPi(mem, 0, i);
tomas@797 2514 DtoStore(values[i], ptr);
tomas@797 2515 }
tomas@797 2516
tomas@797 2517 // cast the alloca pointer to the "formal" struct type
tomas@797 2518 mem = DtoBitCast(mem, getPtrToType(structtype));
tomas@797 2519
tomas@797 2520 // return as a var
tomas@797 2521 return new DVarValue(type, mem);
lindquist@86 2522 }
lindquist@86 2523
lindquist@86 2524 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@86 2525
lindquist@213 2526 LLConstant* StructLiteralExp::toConstElem(IRState* p)
lindquist@86 2527 {
lindquist@86 2528 Logger::print("StructLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars());
lindquist@86 2529 LOG_SCOPE;
lindquist@86 2530
tomas@797 2531 // get arrays
tomas@797 2532 size_t n = elements->dim;
tomas@797 2533 Expression** exprs = (Expression**)elements->data;
tomas@797 2534
tomas@797 2535 assert(sd->fields.dim == n);
tomas@797 2536 VarDeclaration** vars = (VarDeclaration**)sd->fields.data;
tomas@797 2537
tomas@797 2538 // vector of values to build aggregate from
tomas@797 2539 std::vector<llvm::Constant*> values;
tomas@797 2540
tomas@797 2541 // trackers
tomas@797 2542 size_t lastoffset = 0;
tomas@797 2543 size_t lastsize = 0;
tomas@797 2544
tomas@797 2545 // for through each field and build up the struct, padding with zeros
tomas@797 2546 for (size_t i=0; i<n; i++)
lindquist@86 2547 {
tomas@797 2548 Expression* e = exprs[i];
tomas@797 2549 VarDeclaration* var = vars[i];
tomas@797 2550
tomas@797 2551 // field is skipped
tomas@797 2552 if (!e)
tomas@797 2553 continue;
tomas@797 2554
tomas@797 2555 // add any 0 padding needed before this field
tomas@797 2556 if (var->offset > lastoffset + lastsize)
tomas@797 2557 {
tomas@797 2558 addZeros(values, lastoffset + lastsize, var->offset);
tomas@797 2559 }
tomas@797 2560
tomas@797 2561 // add the expression value
tomas@797 2562 values.push_back(e->toConstElem(p));
tomas@797 2563
tomas@797 2564 // update offsets
tomas@797 2565 lastoffset = var->offset;
tomas@797 2566 lastsize = var->type->size();
lindquist@86 2567 }
lindquist@86 2568
tomas@797 2569 // add any 0 padding needed at the end of the literal
tomas@797 2570 const LLType* structtype = DtoType(sd->type);
tomas@797 2571 size_t structsize = getABITypeSize(structtype);
tomas@797 2572
tomas@797 2573 if (structsize > lastoffset+lastsize)
tomas@797 2574 {
tomas@797 2575 addZeros(values, lastoffset + lastsize, structsize);
tomas@797 2576 }
tomas@797 2577
tomas@797 2578 // return constant struct
tomas@797 2579 return LLConstantStruct::get(values, sd->ir.irStruct->packed);
lindquist@86 2580 }
lindquist@86 2581
lindquist@86 2582 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@86 2583
lindquist@109 2584 DValue* InExp::toElem(IRState* p)
lindquist@109 2585 {
lindquist@109 2586 Logger::print("InExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@109 2587 LOG_SCOPE;
lindquist@109 2588
lindquist@109 2589 DValue* key = e1->toElem(p);
lindquist@109 2590 DValue* aa = e2->toElem(p);
lindquist@109 2591
kamm@399 2592 return DtoAAIn(loc, type, aa, key);
lindquist@109 2593 }
lindquist@109 2594
lindquist@127 2595 DValue* RemoveExp::toElem(IRState* p)
lindquist@127 2596 {
lindquist@127 2597 Logger::print("RemoveExp::toElem: %s\n", toChars());
lindquist@127 2598 LOG_SCOPE;
lindquist@127 2599
lindquist@127 2600 DValue* aa = e1->toElem(p);
lindquist@127 2601 DValue* key = e2->toElem(p);
lindquist@127 2602
kamm@399 2603 DtoAARemove(loc, aa, key);
lindquist@127 2604
lindquist@127 2605 return NULL; // does not produce anything useful
lindquist@127 2606 }
lindquist@127 2607
lindquist@109 2608 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@109 2609
lindquist@125 2610 DValue* AssocArrayLiteralExp::toElem(IRState* p)
lindquist@125 2611 {
lindquist@125 2612 Logger::print("AssocArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars());
lindquist@125 2613 LOG_SCOPE;
lindquist@125 2614
lindquist@125 2615 assert(keys);
lindquist@125 2616 assert(values);
lindquist@125 2617 assert(keys->dim == values->dim);
lindquist@125 2618
tomas@486 2619 Type* aatype = type->toBasetype();
tomas@758 2620 Type* vtype = aatype->nextOf();
ChristianK@283 2621 const LLType* aalltype = DtoType(type);
ChristianK@283 2622
ChristianK@283 2623 // it should be possible to avoid the temporary in some cases
kamm@479 2624 LLValue* tmp = DtoAlloca(aalltype,"aaliteral");
tomas@585 2625 DValue* aa = new DVarValue(type, tmp);
ChristianK@283 2626 DtoStore(LLConstant::getNullValue(aalltype), tmp);
lindquist@127 2627
lindquist@125 2628 const size_t n = keys->dim;
lindquist@125 2629 for (size_t i=0; i<n; ++i)
lindquist@125 2630 {
lindquist@125 2631 Expression* ekey = (Expression*)keys->data[i];
lindquist@125 2632 Expression* eval = (Expression*)values->data[i];
lindquist@125 2633
lindquist@125 2634 Logger::println("(%u) aa[%s] = %s", i, ekey->toChars(), eval->toChars());
lindquist@127 2635
lindquist@127 2636 // index
lindquist@127 2637 DValue* key = ekey->toElem(p);
tomas@458 2638 DValue* mem = DtoAAIndex(loc, vtype, aa, key, true);
lindquist@127 2639
lindquist@127 2640 // store
lindquist@127 2641 DValue* val = eval->toElem(p);
kamm@399 2642 DtoAssign(loc, mem, val);
lindquist@125 2643 }
lindquist@125 2644
lindquist@127 2645 return aa;
lindquist@125 2646 }
lindquist@125 2647
lindquist@125 2648 //////////////////////////////////////////////////////////////////////////////////////////
lindquist@125 2649
tomas@599 2650 DValue* GEPExp::toElem(IRState* p)
tomas@599 2651 {
tomas@599 2652 // this should be good enough for now!
tomas@599 2653 DValue* val = e1->toElem(p);
tomas@599 2654 assert(val->isLVal());
tomas@599 2655 LLValue* v = DtoGEPi(val->getLVal(), 0, index);
tomas@599 2656 return new DVarValue(type, DtoBitCast(v, getPtrToType(DtoType(type))));
tomas@599 2657 }
tomas@599 2658
tomas@599 2659 //////////////////////////////////////////////////////////////////////////////////////////
tomas@599 2660
kamm@666 2661 DValue* BoolExp::toElem(IRState* p)
kamm@666 2662 {
kamm@778 2663 return new DImValue(type, DtoCast(loc, e1->toElem(p), Type::tbool)->getRVal());
kamm@666 2664 }
kamm@666 2665
kamm@666 2666 //////////////////////////////////////////////////////////////////////////////////////////
kamm@666 2667
kamm@667 2668 DValue* DotTypeExp::toElem(IRState* p)
kamm@667 2669 {
kamm@667 2670 Type* t = sym->getType();
kamm@667 2671 assert(t);
kamm@667 2672 return e1->toElem(p);
kamm@667 2673 }
kamm@667 2674
kamm@667 2675 //////////////////////////////////////////////////////////////////////////////////////////
kamm@667 2676
lindquist@86 2677 #define STUB(x) DValue *x::toElem(IRState * p) {error("Exp type "#x" not implemented: %s", toChars()); fatal(); return 0; }
lindquist@1 2678 STUB(Expression);
lindquist@1 2679 STUB(TypeDotIdExp);
lindquist@1 2680 STUB(ScopeExp);
lindquist@1 2681 STUB(TypeExp);
lindquist@92 2682 STUB(TupleExp);
lindquist@1 2683
tomas@758 2684 #if DMDV2
tomas@758 2685 STUB(SymbolExp);
tomas@758 2686 #endif
tomas@758 2687
lindquist@213 2688 #define CONSTSTUB(x) LLConstant* x::toConstElem(IRState * p) {error("const Exp type "#x" not implemented: '%s' type: '%s'", toChars(), type->toChars()); fatal(); return NULL; }
lindquist@40 2689 CONSTSTUB(Expression);
lindquist@40 2690 CONSTSTUB(AssocArrayLiteralExp);
lindquist@40 2691
lindquist@1 2692 unsigned Type::totym() { return 0; }
lindquist@1 2693
lindquist@37 2694 type * Type::toCtype()
lindquist@37 2695 {
lindquist@37 2696 assert(0);
lindquist@1 2697 return 0;
lindquist@1 2698 }
lindquist@1 2699
lindquist@1 2700 type * Type::toCParamtype()
lindquist@1 2701 {
lindquist@37 2702 assert(0);
lindquist@1 2703 return 0;
lindquist@1 2704 }
lindquist@1 2705 Symbol * Type::toSymbol()
lindquist@1 2706 {
lindquist@37 2707 assert(0);
lindquist@1 2708 return 0;
lindquist@1 2709 }
lindquist@1 2710
lindquist@1 2711 type *
lindquist@1 2712 TypeTypedef::toCtype()
lindquist@1 2713 {
lindquist@37 2714 assert(0);
lindquist@1 2715 return 0;
lindquist@1 2716 }
lindquist@1 2717
lindquist@1 2718 type *
lindquist@1 2719 TypeTypedef::toCParamtype()
lindquist@1 2720 {
lindquist@37 2721 assert(0);
lindquist@1 2722 return 0;
lindquist@1 2723 }
lindquist@1 2724
lindquist@1 2725 void
lindquist@1 2726 TypedefDeclaration::toDebug()
lindquist@1 2727 {
lindquist@37 2728 assert(0);
lindquist@1 2729 }
lindquist@1 2730
lindquist@1 2731
lindquist@1 2732 type *
lindquist@1 2733 TypeEnum::toCtype()
lindquist@1 2734 {
lindquist@37 2735 assert(0);
lindquist@1 2736 return 0;
lindquist@1 2737 }
lindquist@1 2738
lindquist@1 2739 type *
lindquist@1 2740 TypeStruct::toCtype()
lindquist@1 2741 {
lindquist@37 2742 assert(0);
lindquist@1 2743 return 0;
lindquist@1 2744 }
lindquist@1 2745
lindquist@1 2746 void
lindquist@1 2747 StructDeclaration::toDebug()
lindquist@1 2748 {
lindquist@37 2749 assert(0);
lindquist@1 2750 }
lindquist@1 2751
lindquist@1 2752 Symbol * TypeClass::toSymbol()
lindquist@1 2753 {
lindquist@37 2754 assert(0);
lindquist@1 2755 return 0;
lindquist@1 2756 }
lindquist@1 2757
lindquist@1 2758 unsigned TypeFunction::totym()
lindquist@1 2759 {
lindquist@37 2760 assert(0);
lindquist@1 2761 return 0;
lindquist@1 2762 }
lindquist@1 2763
lindquist@37 2764 type * TypeFunction::toCtype()
lindquist@1 2765 {
lindquist@37 2766 assert(0);
lindquist@1 2767 return 0;
lindquist@1 2768 }
lindquist@1 2769
lindquist@37 2770 type * TypeSArray::toCtype()
lindquist@1 2771 {
lindquist@37 2772 assert(0);
lindquist@1 2773 return 0;
lindquist@1 2774 }
lindquist@1 2775
lindquist@37 2776 type *TypeSArray::toCParamtype()
lindquist@1 2777 {
lindquist@37 2778 assert(0);
lindquist@1 2779 return 0;
lindquist@1 2780 }
lindquist@1 2781
lindquist@37 2782 type * TypeDArray::toCtype()
lindquist@1 2783 {
lindquist@37 2784 assert(0);
lindquist@1 2785 return 0;
lindquist@1 2786 }
lindquist@1 2787
lindquist@37 2788 type * TypeAArray::toCtype()
lindquist@1 2789 {
lindquist@37 2790 assert(0);
lindquist@1 2791 return 0;
lindquist@1 2792 }
lindquist@1 2793
lindquist@37 2794 type * TypePointer::toCtype()
lindquist@1 2795 {
lindquist@37 2796 assert(0);
lindquist@1 2797 return 0;
lindquist@1 2798 }
lindquist@1 2799
lindquist@37 2800 type * TypeDelegate::toCtype()
lindquist@1 2801 {
lindquist@37 2802 assert(0);
lindquist@1 2803 return 0;
lindquist@1 2804 }
lindquist@1 2805
lindquist@37 2806 type * TypeClass::toCtype()
lindquist@1 2807 {
lindquist@37 2808 assert(0);
lindquist@37 2809 return 0;
lindquist@37 2810 }
lindquist@37 2811
lindquist@37 2812 void ClassDeclaration::toDebug()
lindquist@37 2813 {
lindquist@37 2814 assert(0);
lindquist@1 2815 }
lindquist@1 2816
lindquist@14 2817 //////////////////////////////////////////////////////////////////////////////
lindquist@1 2818
lindquist@1 2819 void
lindquist@1 2820 EnumDeclaration::toDebug()
lindquist@1 2821 {
lindquist@37 2822 assert(0);
lindquist@1 2823 }
lindquist@1 2824
lindquist@37 2825 int Dsymbol::cvMember(unsigned char*)
lindquist@1 2826 {
lindquist@37 2827 assert(0);
lindquist@1 2828 return 0;
lindquist@1 2829 }
lindquist@37 2830 int EnumDeclaration::cvMember(unsigned char*)
lindquist@1 2831 {
lindquist@37 2832 assert(0);
lindquist@1 2833 return 0;
lindquist@1 2834 }
lindquist@37 2835 int FuncDeclaration::cvMember(unsigned char*)
lindquist@1 2836 {
lindquist@37 2837 assert(0);
lindquist@1 2838 return 0;
lindquist@1 2839 }
lindquist@37 2840 int VarDeclaration::cvMember(unsigned char*)
lindquist@1 2841 {
lindquist@37 2842 assert(0);
lindquist@1 2843 return 0;
lindquist@1 2844 }
lindquist@37 2845 int TypedefDeclaration::cvMember(unsigned char*)
lindquist@1 2846 {
lindquist@37 2847 assert(0);
lindquist@1 2848 return 0;
lindquist@1 2849 }
lindquist@1 2850
tomas@659 2851 void obj_includelib(const char* lib)
lindquist@340 2852 {
kamm@594 2853 char *arg = (char *)mem.malloc(64);
kamm@594 2854 strcpy(arg, "-l");
kamm@594 2855 strncat(arg, lib, 64);
kamm@594 2856 global.params.linkswitches->push(arg);
lindquist@340 2857 }
lindquist@340 2858
lindquist@340 2859 void backend_init()
lindquist@1 2860 {
lindquist@37 2861 // now lazily loaded
lindquist@1 2862 //LLVM_D_InitRuntime();
lindquist@1 2863 }
lindquist@1 2864
lindquist@340 2865 void backend_term()
lindquist@1 2866 {
lindquist@1 2867 LLVM_D_FreeRuntime();
lindquist@1 2868 }