-static void insertInitializationCall(Function *MainFn, const char *FnName,
- GlobalValue *Array) {
- const Type *ArgVTy = PointerType::get(PointerType::get(Type::SByteTy));
- const Type *UIntPtr = PointerType::get(Type::UIntTy);
- Module &M = *MainFn->getParent();
- Function *InitFn = M.getOrInsertFunction(FnName, Type::VoidTy, Type::IntTy,
- ArgVTy, UIntPtr, Type::UIntTy, 0);
-
- // This could force argc and argv into programs that wouldn't otherwise have
- // them, but instead we just pass null values in.
- std::vector<Value*> Args(4);
- Args[0] = Constant::getNullValue(Type::IntTy);
- Args[1] = Constant::getNullValue(ArgVTy);
-
- // Skip over any allocas in the entry block.
- BasicBlock *Entry = MainFn->begin();
- BasicBlock::iterator InsertPos = Entry->begin();
- while (isa<AllocaInst>(InsertPos)) ++InsertPos;
-
- Function::aiterator AI;
- switch (MainFn->asize()) {
- default:
- case 2:
- AI = MainFn->abegin(); ++AI;
- if (AI->getType() != ArgVTy) {
- Args[1] = new CastInst(AI, ArgVTy, "argv.cast", InsertPos);
- } else {
- Args[1] = AI;
- }
-
- case 1:
- AI = MainFn->abegin();
- if (AI->getType() != Type::IntTy) {
- Args[0] = new CastInst(AI, Type::IntTy, "argc.cast", InsertPos);
- } else {
- Args[0] = AI;
- }
-
- case 0:
- break;
- }
-
- ConstantPointerRef *ArrayCPR = ConstantPointerRef::get(Array);
- std::vector<Constant*> GEPIndices(2, Constant::getNullValue(Type::LongTy));
- Args[2] = ConstantExpr::getGetElementPtr(ArrayCPR, GEPIndices);
-
- unsigned NumElements =
- cast<ArrayType>(Array->getType()->getElementType())->getNumElements();
- Args[3] = ConstantUInt::get(Type::UIntTy, NumElements);
-
- new CallInst(InitFn, Args, "", InsertPos);