- if(ObsoleteVarArgs) {
- if(Function* F = Result->getNamedFunction("llvm.va_start")) {
- assert(F->arg_size() == 0 && "Obsolete va_start takes 0 argument!");
-
- //foo = va_start()
- // ->
- //bar = alloca typeof(foo)
- //va_start(bar)
- //foo = load bar
-
- const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
- const Type* ArgTy = F->getFunctionType()->getReturnType();
- const Type* ArgTyPtr = PointerType::get(ArgTy);
- Function* NF = Result->getOrInsertFunction("llvm.va_start",
- RetTy, ArgTyPtr, 0);
-
- while (!F->use_empty()) {
- CallInst* CI = cast<CallInst>(F->use_back());
- AllocaInst* bar = new AllocaInst(ArgTy, 0, "vastart.fix.1", CI);
- new CallInst(NF, bar, "", CI);
- Value* foo = new LoadInst(bar, "vastart.fix.2", CI);
- CI->replaceAllUsesWith(foo);
- CI->getParent()->getInstList().erase(CI);
- }
- Result->getFunctionList().erase(F);
- }
-
- if(Function* F = Result->getNamedFunction("llvm.va_end")) {
- assert(F->arg_size() == 1 && "Obsolete va_end takes 1 argument!");
- //vaend foo
- // ->
- //bar = alloca 1 of typeof(foo)
- //vaend bar
- const Type* RetTy = Type::getPrimitiveType(Type::VoidTyID);
- const Type* ArgTy = F->getFunctionType()->getParamType(0);
- const Type* ArgTyPtr = PointerType::get(ArgTy);
- Function* NF = Result->getOrInsertFunction("llvm.va_end",
- RetTy, ArgTyPtr, 0);
-
- while (!F->use_empty()) {
- CallInst* CI = cast<CallInst>(F->use_back());
- AllocaInst* bar = new AllocaInst(ArgTy, 0, "vaend.fix.1", CI);
- new CallInst(NF, bar, "", CI);
- CI->getParent()->getInstList().erase(CI);
- }
- Result->getFunctionList().erase(F);
- }