Fix big bug introduced with symbol table changes
[oota-llvm.git] / lib / Transforms / ExprTypeConvert.cpp
index aa183d24ebf5facf5467a8df2a2ee1d421677f66..85f9bb0714cf09b8d657fbe17f80c73bcf329fb6 100644 (file)
@@ -285,6 +285,24 @@ bool ExpressionConvertableToType(Value *V, const Type *Ty,
     return false;   // No match, maybe next time.
   }
 
+  case Instruction::Call: {
+    if (isa<Function>(I->getOperand(0)))
+      return false;  // Don't even try to change direct calls.
+
+    // If this is a function pointer, we can convert the return type if we can
+    // convert the source function pointer.
+    //
+    const PointerType *PT = cast<PointerType>(I->getOperand(0)->getType());
+    const FunctionType *FT = cast<FunctionType>(PT->getElementType());
+    std::vector<const Type *> ArgTys(FT->getParamTypes().begin(),
+                                     FT->getParamTypes().end());
+    const FunctionType *NewTy =
+      FunctionType::get(Ty, ArgTys, FT->isVarArg());
+    if (!ExpressionConvertableToType(I->getOperand(0),
+                                     PointerType::get(NewTy), CTMap))
+      return false;
+    break;
+  }
   default:
     return false;
   }
@@ -320,7 +338,7 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) {
 
   Instruction *I = dyn_cast<Instruction>(V);
   if (I == 0) {
-    Constant *CPV = cast<Constant>(V)) {
+    Constant *CPV = cast<Constant>(V);
     // Constants are converted by constant folding the cast that is required.
     // We assume here that all casts are implemented for constant prop.
     Value *Result = ConstantFoldCastInstruction(CPV, Ty);
@@ -477,9 +495,30 @@ Value *ConvertExpressionToType(Value *V, const Type *Ty, ValueMapCache &VMC) {
 
 
     assert(Res && "Didn't find match!");
-    break;   // No match, maybe next time.
+    break;
   }
 
+  case Instruction::Call: {
+    assert(!isa<Function>(I->getOperand(0)));
+
+    // If this is a function pointer, we can convert the return type if we can
+    // convert the source function pointer.
+    //
+    const PointerType *PT = cast<PointerType>(I->getOperand(0)->getType());
+    const FunctionType *FT = cast<FunctionType>(PT->getElementType());
+    std::vector<const Type *> ArgTys(FT->getParamTypes().begin(),
+                                     FT->getParamTypes().end());
+    const FunctionType *NewTy =
+      FunctionType::get(Ty, ArgTys, FT->isVarArg());
+    const PointerType *NewPTy = PointerType::get(NewTy);
+
+    Res = new CallInst(Constant::getNullValue(NewPTy),
+                       std::vector<Value*>(I->op_begin()+1, I->op_end()),
+                       Name);
+    VMC.ExprMap[I] = Res;
+    Res->setOperand(0, ConvertExpressionToType(I->getOperand(0), NewPTy, VMC));
+    break;
+  }
   default:
     assert(0 && "Expression convertable, but don't know how to convert?");
     return 0;