void Mapper::mapAppendingVariable(GlobalVariable &GV, Constant *InitPrefix, bool IsOldCtorDtor, ArrayRef<Constant *> NewMembers) { SmallVector<Constant *, 16> Elements; if (InitPrefix) { unsigned NumElements = cast<ArrayType>(InitPrefix->getType())->getNumElements(); for (unsigned I = 0; I != NumElements; ++I) Elements.push_back(InitPrefix->getAggregateElement(I)); } PointerType *VoidPtrTy; Type *EltTy; if (IsOldCtorDtor) { // FIXME: This upgrade is done during linking to support the C API. See // also IRLinker::linkAppendingVarProto() in IRMover.cpp. VoidPtrTy = Type::getInt8Ty(GV.getContext())->getPointerTo(); auto &ST = *cast<StructType>(NewMembers.front()->getType()); Type *Tys[3] = {ST.getElementType(0), ST.getElementType(1), VoidPtrTy}; EltTy = StructType::get(GV.getContext(), Tys, false); } for (auto *V : NewMembers) { Constant *NewV; if (IsOldCtorDtor) { auto *S = cast<ConstantStruct>(V); auto *E1 = cast<Constant>(mapValue(S->getOperand(0))); auto *E2 = cast<Constant>(mapValue(S->getOperand(1))); Constant *Null = Constant::getNullValue(VoidPtrTy); NewV = ConstantStruct::get(cast<StructType>(EltTy), E1, E2, Null); } else { NewV = cast_or_null<Constant>(mapValue(V)); } Elements.push_back(NewV); } GV.setInitializer(ConstantArray::get( cast<ArrayType>(GV.getType()->getElementType()), Elements)); }