comparison gen/toir.cpp @ 797:340acf1535d0

Removed KDevelop3 project files, CMake can generate them just fine! Fixed function literals in static initializers. Changed alignment of delegates from 2*PTRSIZE to just PTRSIZE. Changed errors to go to stderr instead of stdout. Fairly major rewriting of struct/union/class handling, STILL A BIT BUGGY !!!
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Sat, 29 Nov 2008 21:25:43 +0100
parents 4adf0f742896
children 28ce72c60a21
comparison
equal deleted inserted replaced
796:6e7a4c3b64d2 797:340acf1535d0
133 } 133 }
134 else assert(0); 134 else assert(0);
135 } 135 }
136 else { 136 else {
137 Logger::println("a normal variable"); 137 Logger::println("a normal variable");
138
138 // take care of forward references of global variables 139 // take care of forward references of global variables
139 if (vd->isDataseg() || (vd->storage_class & STCextern)) { 140 if (vd->isDataseg() || (vd->storage_class & STCextern)) {
140 vd->toObjFile(0); // TODO: multiobj 141 vd->toObjFile(0); // TODO: multiobj
141 } 142 }
142 if (!vd->ir.isSet() || !vd->ir.getIrValue()) { 143
144 LLValue* val;
145
146 if (!vd->ir.isSet() || !(val = vd->ir.getIrValue())) {
143 error("variable %s not resolved", vd->toChars()); 147 error("variable %s not resolved", vd->toChars());
144 if (Logger::enabled()) 148 if (Logger::enabled())
145 Logger::cout() << "unresolved variable had type: " << *DtoType(vd->type) << '\n'; 149 Logger::cout() << "unresolved variable had type: " << *DtoType(vd->type) << '\n';
146 fatal(); 150 fatal();
147 } 151 }
152
148 if (vd->isDataseg() || (vd->storage_class & STCextern)) { 153 if (vd->isDataseg() || (vd->storage_class & STCextern)) {
149 DtoConstInitGlobal(vd); 154 DtoConstInitGlobal(vd);
155 val = DtoBitCast(val, DtoType(type->pointerTo()));
150 } 156 }
151 return new DVarValue(type, vd, vd->ir.getIrValue()); 157
158 return new DVarValue(type, vd, val);
152 } 159 }
153 } 160 }
154 else if (FuncDeclaration* fdecl = var->isFuncDeclaration()) 161 else if (FuncDeclaration* fdecl = var->isFuncDeclaration())
155 { 162 {
156 Logger::println("FuncDeclaration"); 163 Logger::println("FuncDeclaration");
367 assert(0); 374 assert(0);
368 375
369 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; 376 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
370 if (Logger::enabled()) 377 if (Logger::enabled())
371 Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n'; 378 Logger::cout() << "type: " << *at << "\ninit: " << *_init << '\n';
372 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".stringliteral",gIR->module); 379 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(at,true,_linkage,_init,".str",gIR->module);
373 380
374 llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); 381 llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
375 LLConstant* idxs[2] = { zero, zero }; 382 LLConstant* idxs[2] = { zero, zero };
376 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); 383 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
377 384
441 { 448 {
442 return _init; 449 return _init;
443 } 450 }
444 451
445 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage; 452 llvm::GlobalValue::LinkageTypes _linkage = llvm::GlobalValue::InternalLinkage;//WeakLinkage;
446 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".stringliteral",gIR->module); 453 llvm::GlobalVariable* gvar = new llvm::GlobalVariable(_init->getType(),true,_linkage,_init,".str",gIR->module);
447 454
448 llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); 455 llvm::ConstantInt* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false);
449 LLConstant* idxs[2] = { zero, zero }; 456 LLConstant* idxs[2] = { zero, zero };
450 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2); 457 LLConstant* arrptr = llvm::ConstantExpr::getGetElementPtr(gvar,idxs,2);
451 458
1006 // normal virtual call 1013 // normal virtual call
1007 else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) { 1014 else if (fdecl->isAbstract() || (!fdecl->isFinal() && fdecl->isVirtual())) {
1008 assert(fdecl->vtblIndex > 0); 1015 assert(fdecl->vtblIndex > 0);
1009 assert(e1type->ty == Tclass); 1016 assert(e1type->ty == Tclass);
1010 1017
1011 LLValue* zero = llvm::ConstantInt::get(LLType::Int32Ty, 0, false); 1018 LLValue* zero = DtoConstUint(0);
1012 LLValue* vtblidx = llvm::ConstantInt::get(LLType::Int32Ty, (size_t)fdecl->vtblIndex, false); 1019 size_t vtblidx = fdecl->vtblIndex;
1013 if (Logger::enabled()) 1020 if (Logger::enabled())
1014 Logger::cout() << "vthis: " << *vthis << '\n'; 1021 Logger::cout() << "vthis: " << *vthis << '\n';
1015 funcval = DtoGEP(vthis, zero, zero); 1022 funcval = vthis;
1023 if (!fdecl->isMember2()->isInterfaceDeclaration())
1024 funcval = DtoGEP(funcval, zero, zero);
1016 funcval = DtoLoad(funcval); 1025 funcval = DtoLoad(funcval);
1017 funcval = DtoGEP(funcval, zero, vtblidx, toChars()); 1026 Logger::println("vtblidx = %lu", vtblidx);
1027 funcval = DtoGEP(funcval, zero, DtoConstUint(vtblidx), toChars());
1018 funcval = DtoLoad(funcval); 1028 funcval = DtoLoad(funcval);
1019 #if OPAQUE_VTBLS 1029
1020 funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type))); 1030 funcval = DtoBitCast(funcval, getPtrToType(DtoType(fdecl->type)));
1021 if (Logger::enabled()) 1031 if (Logger::enabled())
1022 Logger::cout() << "funcval casted: " << *funcval << '\n'; 1032 Logger::cout() << "funcval casted: " << *funcval << '\n';
1023 #endif
1024 } 1033 }
1025 // static call 1034 // static call
1026 else { 1035 else {
1027 DtoForceDeclareDsymbol(fdecl); 1036 DtoForceDeclareDsymbol(fdecl);
1028 funcval = fdecl->ir.irFunc->func; 1037 funcval = fdecl->ir.irFunc->func;
2141 assert(0 && "fd->tok must be TOKfunction or TOKdelegate"); 2150 assert(0 && "fd->tok must be TOKfunction or TOKdelegate");
2142 } 2151 }
2143 2152
2144 ////////////////////////////////////////////////////////////////////////////////////////// 2153 //////////////////////////////////////////////////////////////////////////////////////////
2145 2154
2155 LLConstant* FuncExp::toConstElem(IRState* p)
2156 {
2157 Logger::print("FuncExp::toConstElem: %s | %s\n", toChars(), type->toChars());
2158 LOG_SCOPE;
2159
2160 assert(fd);
2161 assert(fd->tok == TOKfunction);
2162
2163 DtoForceDefineDsymbol(fd);
2164 assert(fd->ir.irFunc->func);
2165
2166 return fd->ir.irFunc->func;
2167 }
2168
2169 //////////////////////////////////////////////////////////////////////////////////////////
2170
2146 DValue* ArrayLiteralExp::toElem(IRState* p) 2171 DValue* ArrayLiteralExp::toElem(IRState* p)
2147 { 2172 {
2148 Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); 2173 Logger::print("ArrayLiteralExp::toElem: %s | %s\n", toChars(), type->toChars());
2149 LOG_SCOPE; 2174 LOG_SCOPE;
2150 2175
2250 return DtoConstSlice(DtoConstSize_t(elements->dim), globalstorePtr); 2275 return DtoConstSlice(DtoConstSize_t(elements->dim), globalstorePtr);
2251 } 2276 }
2252 2277
2253 ////////////////////////////////////////////////////////////////////////////////////////// 2278 //////////////////////////////////////////////////////////////////////////////////////////
2254 2279
2280 void addZeros(std::vector<llvm::Value*>& inits, unsigned pos, unsigned offset);
2281
2255 DValue* StructLiteralExp::toElem(IRState* p) 2282 DValue* StructLiteralExp::toElem(IRState* p)
2256 { 2283 {
2257 Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars()); 2284 Logger::print("StructLiteralExp::toElem: %s | %s\n", toChars(), type->toChars());
2258 LOG_SCOPE; 2285 LOG_SCOPE;
2259 2286
2260 const LLType* llt = DtoType(type); 2287 // get arrays
2261 2288 size_t n = elements->dim;
2262 LLValue* mem = 0; 2289 Expression** exprs = (Expression**)elements->data;
2263 2290
2264 LLValue* sptr = DtoAlloca(llt,"tmpstructliteral"); 2291 assert(sd->fields.dim == n);
2265 2292 VarDeclaration** vars = (VarDeclaration**)sd->fields.data;
2266 // default init the struct to take care of padding 2293
2267 // and unspecified members 2294 // vector of values to build aggregate from
2268 TypeStruct* ts = (TypeStruct*)type->toBasetype(); 2295 std::vector<llvm::Value*> values;
2269 assert(ts->sym); 2296
2270 DtoForceConstInitDsymbol(ts->sym); 2297 // trackers
2271 assert(ts->sym->ir.irStruct->init); 2298 size_t lastoffset = 0;
2272 DtoAggrCopy(sptr, ts->sym->ir.irStruct->init); 2299 size_t lastsize = 0;
2273 2300
2274 // num elements in literal 2301 // for through each field and build up the struct, padding with zeros
2275 unsigned n = elements->dim; 2302 for (size_t i=0; i<n; i++)
2276 2303 {
2277 // unions might have different types for each literal 2304 Expression* e = exprs[i];
2278 if (sd->ir.irStruct->hasUnions) { 2305 VarDeclaration* var = vars[i];
2279 // build the type of the literal 2306
2280 std::vector<const LLType*> tys; 2307 // field is skipped
2281 for (unsigned i=0; i<n; ++i) { 2308 if (!e)
2282 Expression* vx = (Expression*)elements->data[i]; 2309 continue;
2283 if (!vx) continue; 2310
2284 tys.push_back(DtoType(vx->type)); 2311 // add any 0 padding needed before this field
2285 } 2312 if (var->offset > lastoffset + lastsize)
2286 const LLStructType* t = LLStructType::get(tys, sd->ir.irStruct->packed); 2313 {
2287 if (t != llt) { 2314 addZeros(values, lastoffset + lastsize, var->offset);
2288 if (getABITypeSize(t) != getABITypeSize(llt)) { 2315 }
2289 if (Logger::enabled()) 2316
2290 Logger::cout() << "got size " << getABITypeSize(t) << ", expected " << getABITypeSize(llt) << '\n'; 2317 // add the expression value
2291 assert(0 && "type size mismatch"); 2318 DValue* v = e->toElem(p);
2292 } 2319 values.push_back(v->getRVal());
2293 sptr = DtoBitCast(sptr, getPtrToType(t)); 2320
2294 if (Logger::enabled()) 2321 // update offsets
2295 Logger::cout() << "sptr type is now: " << *t << '\n'; 2322 lastoffset = var->offset;
2296 } 2323 lastsize = var->type->size();
2297 } 2324 }
2298 2325
2299 // build 2326 // add any 0 padding needed at the end of the literal
2300 unsigned j = 0; 2327 const LLType* structtype = DtoType(sd->type);
2301 for (unsigned i=0; i<n; ++i) 2328 size_t structsize = getABITypeSize(structtype);
2302 { 2329
2303 Expression* vx = (Expression*)elements->data[i]; 2330 if (structsize > lastoffset+lastsize)
2304 if (!vx) continue; 2331 {
2305 2332 addZeros(values, lastoffset + lastsize, structsize);
2306 if (Logger::enabled()) 2333 }
2307 Logger::cout() << "getting index " << j << " of " << *sptr << '\n'; 2334
2308 LLValue* arrptr = DtoGEPi(sptr,0,j); 2335 // get the struct type from the values
2309 DValue* darrptr = new DVarValue(vx->type, arrptr); 2336 n = values.size();
2310 2337 std::vector<const LLType*> types(n, NULL);
2311 DValue* ve = vx->toElem(p); 2338
2312 DtoAssign(loc, darrptr, ve); 2339 for (size_t i=0; i<n; i++)
2313 2340 {
2314 j++; 2341 types[i] = values[i]->getType();
2315 } 2342 }
2316 2343
2317 return new DImValue(type, sptr); 2344 const LLStructType* sty = LLStructType::get(types, sd->ir.irStruct->packed);
2318 } 2345
2319 2346 // allocate storage for the struct literal on the stack
2320 ////////////////////////////////////////////////////////////////////////////////////////// 2347 LLValue* mem = DtoAlloca(sty, "tmpstructliteral");
2348
2349 // put all the values into the storage
2350 for (size_t i=0; i<n; i++)
2351 {
2352 LLValue* ptr = DtoGEPi(mem, 0, i);
2353 DtoStore(values[i], ptr);
2354 }
2355
2356 // cast the alloca pointer to the "formal" struct type
2357 mem = DtoBitCast(mem, getPtrToType(structtype));
2358
2359 // return as a var
2360 return new DVarValue(type, mem);
2361 }
2362
2363 //////////////////////////////////////////////////////////////////////////////////////////
2364
2365 void addZeros(std::vector<llvm::Constant*>& inits, unsigned pos, unsigned offset);
2321 2366
2322 LLConstant* StructLiteralExp::toConstElem(IRState* p) 2367 LLConstant* StructLiteralExp::toConstElem(IRState* p)
2323 { 2368 {
2324 Logger::print("StructLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars()); 2369 Logger::print("StructLiteralExp::toConstElem: %s | %s\n", toChars(), type->toChars());
2325 LOG_SCOPE; 2370 LOG_SCOPE;
2326 2371
2327 unsigned n = elements->dim; 2372 // get arrays
2328 std::vector<LLConstant*> vals(n, NULL); 2373 size_t n = elements->dim;
2329 2374 Expression** exprs = (Expression**)elements->data;
2330 for (unsigned i=0; i<n; ++i) 2375
2331 { 2376 assert(sd->fields.dim == n);
2332 Expression* vx = (Expression*)elements->data[i]; 2377 VarDeclaration** vars = (VarDeclaration**)sd->fields.data;
2333 vals[i] = vx->toConstElem(p); 2378
2334 } 2379 // vector of values to build aggregate from
2335 2380 std::vector<llvm::Constant*> values;
2336 assert(type->toBasetype()->ty == Tstruct); 2381
2337 const LLType* t = DtoType(type); 2382 // trackers
2338 const LLStructType* st = isaStruct(t); 2383 size_t lastoffset = 0;
2339 return llvm::ConstantStruct::get(st,vals); 2384 size_t lastsize = 0;
2385
2386 // for through each field and build up the struct, padding with zeros
2387 for (size_t i=0; i<n; i++)
2388 {
2389 Expression* e = exprs[i];
2390 VarDeclaration* var = vars[i];
2391
2392 // field is skipped
2393 if (!e)
2394 continue;
2395
2396 // add any 0 padding needed before this field
2397 if (var->offset > lastoffset + lastsize)
2398 {
2399 addZeros(values, lastoffset + lastsize, var->offset);
2400 }
2401
2402 // add the expression value
2403 values.push_back(e->toConstElem(p));
2404
2405 // update offsets
2406 lastoffset = var->offset;
2407 lastsize = var->type->size();
2408 }
2409
2410 // add any 0 padding needed at the end of the literal
2411 const LLType* structtype = DtoType(sd->type);
2412 size_t structsize = getABITypeSize(structtype);
2413
2414 if (structsize > lastoffset+lastsize)
2415 {
2416 addZeros(values, lastoffset + lastsize, structsize);
2417 }
2418
2419 // return constant struct
2420 return LLConstantStruct::get(values, sd->ir.irStruct->packed);
2340 } 2421 }
2341 2422
2342 ////////////////////////////////////////////////////////////////////////////////////////// 2423 //////////////////////////////////////////////////////////////////////////////////////////
2343 2424
2344 DValue* InExp::toElem(IRState* p) 2425 DValue* InExp::toElem(IRState* p)