void RTTIBuilder::push_void_array(llvm::Constant *CI, Type *valtype, Dsymbol *mangle_sym) { std::string initname(mangle(mangle_sym)); initname.append(".rtti.voidarr.data"); const LinkageWithCOMDAT lwc(TYPEINFO_LINKAGE_TYPE, supportsCOMDAT()); auto G = new LLGlobalVariable(gIR->module, CI->getType(), true, lwc.first, CI, initname); setLinkage(lwc, G); G->setAlignment(DtoAlignment(valtype)); push_void_array(getTypeAllocSize(CI->getType()), G); }
void DtoMemCpy(LLValue *dst, LLValue *src, bool withPadding, unsigned align) { LLType *pointee = dst->getType()->getContainedType(0); uint64_t n = withPadding ? getTypeAllocSize(pointee) : getTypeStoreSize(pointee); DtoMemCpy(dst, src, DtoConstSize_t(n), align); }
DLValue *DtoAAIndex(Loc &loc, Type *type, DValue *aa, DValue *key, bool lvalue) { // D2: // call: // extern(C) void* _aaGetY(AA* aa, TypeInfo aati, size_t valuesize, void* // pkey) // or // extern(C) void* _aaInX(AA aa*, TypeInfo keyti, void* pkey) // first get the runtime function llvm::Function *func = getRuntimeFunction(loc, gIR->module, lvalue ? "_aaGetY" : "_aaInX"); LLFunctionType *funcTy = func->getFunctionType(); // aa param LLValue *aaval = lvalue ? DtoLVal(aa) : DtoRVal(aa); aaval = DtoBitCast(aaval, funcTy->getParamType(0)); // pkey param LLValue *pkey = makeLValue(loc, key); pkey = DtoBitCast(pkey, funcTy->getParamType(lvalue ? 3 : 2)); // call runtime LLValue *ret; if (lvalue) { LLValue *rawAATI = DtoTypeInfoOf(aa->type->unSharedOf()->mutableOf(), false); LLValue *castedAATI = DtoBitCast(rawAATI, funcTy->getParamType(1)); LLValue *valsize = DtoConstSize_t(getTypeAllocSize(DtoType(type))); ret = gIR->CreateCallOrInvoke(func, aaval, castedAATI, valsize, pkey, "aa.index") .getInstruction(); } else { LLValue *keyti = DtoBitCast(to_keyti(aa), funcTy->getParamType(1)); ret = gIR->CreateCallOrInvoke(func, aaval, keyti, pkey, "aa.index") .getInstruction(); } // cast return value LLType *targettype = DtoPtrToType(type); if (ret->getType() != targettype) { ret = DtoBitCast(ret, targettype); } // Only check bounds for rvalues ('aa[key]'). // Lvalue use ('aa[key] = value') auto-adds an element. if (!lvalue && gIR->emitArrayBoundsChecks()) { llvm::BasicBlock *okbb = gIR->insertBB("aaboundsok"); llvm::BasicBlock *failbb = gIR->insertBBAfter(okbb, "aaboundscheckfail"); LLValue *nullaa = LLConstant::getNullValue(ret->getType()); LLValue *cond = gIR->ir->CreateICmpNE(nullaa, ret, "aaboundscheck"); gIR->ir->CreateCondBr(cond, okbb, failbb); // set up failbb to call the array bounds error runtime function gIR->scope() = IRScope(failbb); llvm::Function *errorfn = getRuntimeFunction(loc, gIR->module, "_d_arraybounds"); gIR->CreateCallOrInvoke( errorfn, DtoModuleFileName(gIR->func()->decl->getModule(), loc), DtoConstUint(loc.linnum)); // the function does not return gIR->ir->CreateUnreachable(); // if ok, proceed in okbb gIR->scope() = IRScope(okbb); } return new DLValue(type, ret); }