Mercurial > projects > ldc
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 |