comparison gen/llvmhelpers.cpp @ 502:837af2a63564

Fixed problems constant multidimensional static array initializers.
author Tomas Lindquist Olsen <tomas.l.olsen@gmail.com>
date Wed, 13 Aug 2008 15:43:13 +0200
parents a34078905d01
children 7148a3f2b44b
comparison
equal deleted inserted replaced
501:ba7f06832d1c 502:837af2a63564
959 assert(!_type->isAbstract()); 959 assert(!_type->isAbstract());
960 960
961 llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->ir.irGlobal->value); 961 llvm::GlobalVariable* gvar = llvm::cast<llvm::GlobalVariable>(vd->ir.irGlobal->value);
962 if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl)) 962 if (!(vd->storage_class & STCextern) && (vd->getModule() == gIR->dmodule || istempl))
963 { 963 {
964 Logger::println("setting initializer");
965 Logger::cout() << "global: " << *gvar << '\n';
966 Logger::cout() << "init: " << *_init << '\n';
964 gvar->setInitializer(_init); 967 gvar->setInitializer(_init);
965 // do debug info 968 // do debug info
966 if (global.params.symdebug) 969 if (global.params.symdebug)
967 { 970 {
968 LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd); 971 LLGlobalVariable* gv = DtoDwarfGlobalVariable(gvar, vd);
1256 { 1259 {
1257 LLConstant* _init = 0; // may return zero 1260 LLConstant* _init = 0; // may return zero
1258 if (!init) 1261 if (!init)
1259 { 1262 {
1260 Logger::println("const default initializer for %s", type->toChars()); 1263 Logger::println("const default initializer for %s", type->toChars());
1261 1264 _init = DtoDefaultInit(type);
1262 if(type->ty == Tsarray)
1263 {
1264 Logger::println("type is a static array, building constant array initializer");
1265 TypeSArray* arrtype = (TypeSArray*)type;
1266 Type* elemtype = type->next;
1267
1268 integer_t arraydim;
1269 arraydim = arrtype->dim->toInteger();
1270
1271 std::vector<LLConstant*> inits(arraydim, elemtype->defaultInit()->toConstElem(gIR));
1272 const LLArrayType* arrty = LLArrayType::get(DtoType(elemtype),arraydim);
1273 _init = LLConstantArray::get(arrty, inits);
1274 }
1275 else
1276 _init = type->defaultInit()->toConstElem(gIR);
1277 } 1265 }
1278 else if (ExpInitializer* ex = init->isExpInitializer()) 1266 else if (ExpInitializer* ex = init->isExpInitializer())
1279 { 1267 {
1280 Logger::println("const expression initializer"); 1268 Logger::println("const expression initializer");
1281 _init = ex->exp->toConstElem(gIR); 1269 _init = ex->exp->toConstElem(gIR);
1392 else { 1380 else {
1393 Logger::println("unsupported initializer: %s", init->toChars()); 1381 Logger::println("unsupported initializer: %s", init->toChars());
1394 assert(0); 1382 assert(0);
1395 } 1383 }
1396 return 0; 1384 return 0;
1385 }
1386
1387 //////////////////////////////////////////////////////////////////////////////////////////
1388
1389 static LLConstant* expand_to_sarray(Type *base, Expression* exp)
1390 {
1391 Logger::println("building type %s from expression (%s) of type %s", base->toChars(), exp->toChars(), exp->type->toChars());
1392 const LLType* dstTy = DtoType(base);
1393 Logger::cout() << "final llvm type requested: " << *dstTy << '\n';
1394
1395 LLConstant* val = exp->toConstElem(gIR);
1396
1397 Type* expbase = exp->type->toBasetype();
1398 Type* t = base;
1399
1400 LLSmallVector<size_t, 4> dims;
1401
1402 while(1)
1403 {
1404 if (t->equals(expbase))
1405 break;
1406 assert(t->ty == Tsarray);
1407 TypeSArray* tsa = (TypeSArray*)t;
1408 dims.push_back(tsa->dim->toInteger());
1409 assert(t->next);
1410 t = t->next->toBasetype();
1411 }
1412
1413 size_t i = dims.size();
1414 assert(i);
1415
1416 std::vector<LLConstant*> inits;
1417 while (i--)
1418 {
1419 const LLArrayType* arrty = LLArrayType::get(val->getType(), dims[i]);
1420 inits.clear();
1421 inits.insert(inits.end(), dims[i], val);
1422 val = LLConstantArray::get(arrty, inits);
1423 }
1424
1425 return val;
1426 }
1427
1428 LLConstant* DtoDefaultInit(Type* type)
1429 {
1430 Expression* exp = type->defaultInit();
1431
1432 Type* expbase = exp->type->toBasetype();
1433 Type* base = type->toBasetype();
1434
1435 // if not the same basetypes, we won't get the same llvm types either
1436 if (!expbase->equals(base))
1437 {
1438 if (base->ty == Tsarray)
1439 {
1440 Logger::println("type is a static array, building constant array initializer from single value");
1441 return expand_to_sarray(base, exp);
1442 }
1443 else
1444 {
1445 error("cannot yet convert default initializer %s from type %s to %s", exp->toChars(), exp->type->toChars(), type->toChars());
1446 fatal();
1447 }
1448 assert(0);
1449
1450 }
1451
1452 return exp->toConstElem(gIR);
1397 } 1453 }
1398 1454
1399 1455
1400 ////////////////////////////////////////////////////////////////////////////////////////// 1456 //////////////////////////////////////////////////////////////////////////////////////////
1401 1457