Constant pointer refs are causing these to fail unnecessarily, which is causing
[oota-llvm.git] / lib / VMCore / iCall.cpp
1 //===-- iCall.cpp - Implement the call & invoke instructions --------------===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the call and invoke instructions.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/iOther.h"
15 #include "llvm/iTerminators.h"
16 #include "llvm/Constants.h"
17 #include "llvm/DerivedTypes.h"
18 #include "llvm/Function.h"
19
20 //===----------------------------------------------------------------------===//
21 //                        CallInst Implementation
22 //===----------------------------------------------------------------------===//
23
24 CallInst::CallInst(Value *Func, const std::vector<Value*> &params, 
25                    const std::string &Name, Instruction *InsertBefore) 
26   : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
27                                  ->getElementType())->getReturnType(),
28                 Instruction::Call, Name, InsertBefore) {
29   Operands.reserve(1+params.size());
30   Operands.push_back(Use(Func, this));
31
32   const FunctionType *MTy = 
33     cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
34
35   const FunctionType::ParamTypes &PL = MTy->getParamTypes();
36   assert(params.size() == PL.size() || 
37          (MTy->isVarArg() && params.size() > PL.size()) &&
38          "Calling a function with bad signature");
39   for (unsigned i = 0; i < params.size(); i++)
40     Operands.push_back(Use(params[i], this));
41 }
42
43 CallInst::CallInst(Value *Func, const std::string &Name,
44                    Instruction *InsertBefore)
45   : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
46                                    ->getElementType())->getReturnType(),
47                 Instruction::Call, Name, InsertBefore) {
48   Operands.reserve(1);
49   Operands.push_back(Use(Func, this));
50   
51   const FunctionType *MTy = 
52     cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
53
54   const FunctionType::ParamTypes &PL = MTy->getParamTypes();
55   assert(PL.empty() && "Calling a function with bad signature");
56 }
57
58 CallInst::CallInst(Value *Func, Value* A, const std::string &Name,
59                    Instruction  *InsertBefore)
60   : Instruction(cast<FunctionType>(cast<PointerType>(Func->getType())
61                                    ->getElementType())->getReturnType(),
62                 Instruction::Call, Name, InsertBefore) {
63   Operands.reserve(2);
64   Operands.push_back(Use(Func, this));
65   
66   const FunctionType *MTy = 
67     cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
68
69   const FunctionType::ParamTypes &PL = MTy->getParamTypes();
70   assert(PL.size() == 1 || (MTy->isVarArg() && PL.empty()) &&
71          "Calling a function with bad signature");
72   Operands.push_back(Use(A, this));
73 }
74
75 CallInst::CallInst(const CallInst &CI) 
76   : Instruction(CI.getType(), Instruction::Call) {
77   Operands.reserve(CI.Operands.size());
78   for (unsigned i = 0; i < CI.Operands.size(); ++i)
79     Operands.push_back(Use(CI.Operands[i], this));
80 }
81
82 const Function *CallInst::getCalledFunction() const {
83   if (const Function *F = dyn_cast<Function>(Operands[0]))
84     return F;
85   if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Operands[0]))
86     return cast<Function>(CPR->getValue());
87   return 0;
88 }
89 Function *CallInst::getCalledFunction() {
90   if (Function *F = dyn_cast<Function>(Operands[0]))
91     return F;
92   if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Operands[0]))
93     return cast<Function>(CPR->getValue());
94   return 0;
95 }
96
97
98 //===----------------------------------------------------------------------===//
99 //                        InvokeInst Implementation
100 //===----------------------------------------------------------------------===//
101
102 InvokeInst::InvokeInst(Value *Func, BasicBlock *IfNormal,
103                        BasicBlock *IfException,
104                        const std::vector<Value*> &params,
105                        const std::string &Name, Instruction *InsertBefore)
106   : TerminatorInst(cast<FunctionType>(cast<PointerType>(Func->getType())
107                                     ->getElementType())->getReturnType(),
108                    Instruction::Invoke, Name, InsertBefore) {
109   Operands.reserve(3+params.size());
110   Operands.push_back(Use(Func, this));
111   Operands.push_back(Use((Value*)IfNormal, this));
112   Operands.push_back(Use((Value*)IfException, this));
113   const FunctionType *MTy = 
114     cast<FunctionType>(cast<PointerType>(Func->getType())->getElementType());
115   
116   const FunctionType::ParamTypes &PL = MTy->getParamTypes();
117   assert((params.size() == PL.size()) || 
118          (MTy->isVarArg() && params.size() > PL.size()) &&
119          "Calling a function with bad signature");
120   
121   for (unsigned i = 0; i < params.size(); i++)
122     Operands.push_back(Use(params[i], this));
123 }
124
125 InvokeInst::InvokeInst(const InvokeInst &CI) 
126   : TerminatorInst(CI.getType(), Instruction::Invoke) {
127   Operands.reserve(CI.Operands.size());
128   for (unsigned i = 0; i < CI.Operands.size(); ++i)
129     Operands.push_back(Use(CI.Operands[i], this));
130 }
131
132 const Function *InvokeInst::getCalledFunction() const {
133   if (const Function *F = dyn_cast<Function>(Operands[0]))
134     return F;
135   if (const ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Operands[0]))
136     return cast<Function>(CPR->getValue());
137   return 0;
138 }
139 Function *InvokeInst::getCalledFunction() {
140   if (Function *F = dyn_cast<Function>(Operands[0]))
141     return F;
142   if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(Operands[0]))
143     return cast<Function>(CPR->getValue());
144   return 0;
145 }