1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2025-01-31 12:41:49 +01:00

* Both Method & GlobalVariable now subclass GlobalValue

* ConstPoolPointerReference now represents a pointer to a GlobalValue
* Methods name references are now explicit pointers to methods
* Rename Value::GlobalVal to Value::GlobalVariableVal to avoid confusion

llvm-svn: 703
This commit is contained in:
Chris Lattner 2001-10-03 14:53:21 +00:00
parent fee01c0591
commit a01eda3091
21 changed files with 145 additions and 71 deletions

View File

@ -97,7 +97,8 @@ inline ostream &operator<<(ostream &o, const Value *I) {
case Value::InstructionVal:WriteToAssembly(cast<Instruction>(I) , o); break;
case Value::BasicBlockVal: WriteToAssembly(cast<BasicBlock>(I) , o); break;
case Value::MethodVal: WriteToAssembly(cast<Method>(I) , o); break;
case Value::GlobalVal: WriteToAssembly(cast<GlobalVariable>(I), o); break;
case Value::GlobalVariableVal:
WriteToAssembly(cast<GlobalVariable>(I), o); break;
case Value::ModuleVal: WriteToAssembly(cast<Module>(I) , o); break;
default: return o << "<unknown value type: " << I->getValueType() << ">";
}

View File

@ -227,26 +227,26 @@ public:
// ConstPoolPointerReference - a constant pointer value that is initialized to
// point to a global value, which is a constant.
// point to a global value, which lies at a constant, fixed address.
//
class ConstPoolPointerReference : public ConstPoolPointer {
ConstPoolPointerReference(const ConstPoolPointerReference &); // DNI!
protected:
ConstPoolPointerReference(GlobalVariable *GV);
ConstPoolPointerReference(GlobalValue *GV);
~ConstPoolPointerReference() {}
public:
static ConstPoolPointerReference *get(GlobalVariable *GV) {
static ConstPoolPointerReference *get(GlobalValue *GV) {
// FIXME: These should all be shared!
return new ConstPoolPointerReference(GV);
}
virtual string getStrValue() const;
const GlobalVariable *getValue() const {
return cast<GlobalVariable>(Operands[0].get());
const GlobalValue *getValue() const {
return cast<GlobalValue>(Operands[0].get());
}
GlobalVariable *getValue() {
return cast<GlobalVariable>(Operands[0].get());
GlobalValue *getValue() {
return cast<GlobalValue>(Operands[0].get());
}
};

View File

@ -13,6 +13,7 @@
#include "llvm/SymTabValue.h"
#include "llvm/BasicBlock.h"
#include "llvm/GlobalValue.h"
class Instruction;
class BasicBlock;
@ -20,7 +21,7 @@ class MethodArgument;
class MethodType;
class Module;
class Method : public Value, public SymTabValue {
class Method : public GlobalValue, public SymTabValue {
public:
typedef ValueHolder<MethodArgument, Method, Method> ArgumentListType;
typedef ValueHolder<BasicBlock , Method, Method> BasicBlocksType;
@ -49,10 +50,8 @@ public:
// Specialize setName to handle symbol table majik...
virtual void setName(const string &name, SymbolTable *ST = 0);
const Type *getReturnType() const;
const MethodType *getType() const {
return (const MethodType*)Value::getType();
}
const Type *getReturnType() const; // Return the return type of method
const MethodType *getMethodType() const; // Return the MethodType for me
// Is the body of this method unknown? (the basic block list is empty if so)
// this is true for external methods, defined as forward "declare"ations

View File

@ -0,0 +1,36 @@
//===-- llvm/GlobalValue.h - Class to represent a global value ---*- C++ -*--=//
//
// This file is a common base class of all globally definable objects. As such,
// it is subclassed by GlobalVariable and by Method. This is used because you
// can do certain things with these global objects that you can't do to anything
// else. For example, use the address of one as a constant.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_GLOBALVALUE_H
#define LLVM_GLOBALVALUE_H
#include "llvm/User.h"
class PointerType;
class GlobalValue : public User {
GlobalValue(const GlobalValue &); // do not implement
protected:
GlobalValue(const Type *Ty, ValueTy vty, const string &name = "")
: User(Ty, vty, name) {}
public:
// getType - Global values are always pointers (FIXME, methods should be ptrs too!)
inline const PointerType *getType() const {
return (const PointerType*)User::getType();
}
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const GlobalValue *T) { return true; }
static inline bool classof(const Value *V) {
return V->getValueType() == Value::MethodVal ||
V->getValueType() == Value::GlobalVariableVal;
}
};
#endif

View File

@ -13,12 +13,12 @@
#ifndef LLVM_GLOBAL_VARIABLE_H
#define LLVM_GLOBAL_VARIABLE_H
#include "llvm/User.h"
#include "llvm/GlobalValue.h"
class Module;
class ConstPoolVal;
class PointerType;
class GlobalVariable : public User {
class GlobalVariable : public GlobalValue {
Module *Parent; // The module that contains this method
friend class ValueHolder<GlobalVariable, Module, Module>;
@ -30,11 +30,6 @@ public:
const string &Name = "");
~GlobalVariable() {}
// getType - Global variables are always pointers
inline const PointerType *getType() const {
return (const PointerType*)User::getType();
}
// Specialize setName to handle symbol table majik...
virtual void setName(const string &name, SymbolTable *ST = 0);
@ -63,7 +58,7 @@ public:
// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const GlobalVariable *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueType() == Value::GlobalVal;
return V->getValueType() == Value::GlobalVariableVal;
}
};

View File

@ -22,6 +22,7 @@ class ConstPoolVal;
class MethodArgument;
class Instruction;
class BasicBlock;
class GlobalValue;
class Method;
class GlobalVariable;
class Module;
@ -43,7 +44,7 @@ public:
InstructionVal, // This is an instance of Instruction
BasicBlockVal, // This is an instance of BasicBlock
MethodVal, // This is an instance of Method
GlobalVal, // This is an instance of GlobalVariable
GlobalVariableVal, // This is an instance of GlobalVariable
ModuleVal, // This is an instance of Module
};
@ -256,10 +257,16 @@ template <> inline bool isa<Method, Value*>(Value *Val) {
return Val->getValueType() == Value::MethodVal;
}
template <> inline bool isa<GlobalVariable, const Value*>(const Value *Val) {
return Val->getValueType() == Value::GlobalVal;
return Val->getValueType() == Value::GlobalVariableVal;
}
template <> inline bool isa<GlobalVariable, Value*>(Value *Val) {
return Val->getValueType() == Value::GlobalVal;
return Val->getValueType() == Value::GlobalVariableVal;
}
template <> inline bool isa<GlobalValue, const Value*>(const Value *Val) {
return isa<GlobalVariable>(Val) || isa<Method>(Val);
}
template <> inline bool isa<GlobalValue, Value*>(Value *Val) {
return isa<GlobalVariable>(Val) || isa<Method>(Val);
}
template <> inline bool isa<Module, const Value*>(const Value *Val) {
return Val->getValueType() == Value::ModuleVal;

View File

@ -150,7 +150,7 @@ public:
return cast<Method>(Operands[0]);
}
Method *getCalledMethod() {
return cast<Method>(Operands[0]);
return cast<Method>(Operands[0]);
}
// Methods for support type inquiry through isa, cast, and dyn_cast:

View File

@ -224,7 +224,7 @@ ExprType analysis::ClassifyExpression(Value *Expr) {
case Value::TypeVal: case Value::BasicBlockVal:
case Value::MethodVal: case Value::ModuleVal: default:
assert(0 && "Unexpected expression type to classify!");
case Value::GlobalVal: // Global Variable & Method argument:
case Value::GlobalVariableVal: // Global Variable & Method argument:
case Value::MethodArgumentVal: // nothing known, return variable itself
return Expr;
case Value::ConstantVal: // Constant value, just return constant

View File

@ -176,7 +176,12 @@ typedef PlaceholderValue<BBPlaceHolderHelper> BBPlaceHolder;
typedef PlaceholderValue<MethPlaceHolderHelper> MethPlaceHolder;
static inline ValID &getValIDFromPlaceHolder(const Value *Val) {
switch (Val->getType()->getPrimitiveID()) {
const Type *Ty = Val->getType();
if (isa<PointerType>(Ty) &&
isa<MethodType>(cast<PointerType>(Ty)->getValueType()))
Ty = cast<PointerType>(Ty)->getValueType();
switch (Ty->getPrimitiveID()) {
case Type::TypeTyID: return ((TypePlaceHolder*)Val)->getDef();
case Type::LabelTyID: return ((BBPlaceHolder*)Val)->getDef();
case Type::MethodTyID: return ((MethPlaceHolder*)Val)->getDef();
@ -185,7 +190,12 @@ static inline ValID &getValIDFromPlaceHolder(const Value *Val) {
}
static inline int getLineNumFromPlaceHolder(const Value *Val) {
switch (Val->getType()->getPrimitiveID()) {
const Type *Ty = Val->getType();
if (isa<PointerType>(Ty) &&
isa<MethodType>(cast<PointerType>(Ty)->getValueType()))
Ty = cast<PointerType>(Ty)->getValueType();
switch (Ty->getPrimitiveID()) {
case Type::TypeTyID: return ((TypePlaceHolder*)Val)->getLineNum();
case Type::LabelTyID: return ((BBPlaceHolder*)Val)->getLineNum();
case Type::MethodTyID: return ((MethPlaceHolder*)Val)->getLineNum();

View File

@ -295,6 +295,10 @@ static Value *getVal(const Type *Ty, const ValID &D,
vector<ValueList> *LateResolver = (CurMeth.CurrentMethod) ?
&CurMeth.LateResolveValues : &CurModule.LateResolveValues;
if (const PointerType *PTy = dyn_cast<PointerType>(Ty))
if (const MethodType *MTy = dyn_cast<MethodType>(PTy->getValueType()))
Ty = MTy; // Convert pointer to method to method type
switch (Ty->getPrimitiveID()) {
case Type::LabelTyID: d = new BBPlaceHolder(Ty, D); break;
case Type::MethodTyID: d = new MethPlaceHolder(Ty, D);
@ -938,8 +942,7 @@ ConstPool : ConstPool OptAssign CONST ConstVal {
if (Initializer == 0)
ThrowException("Global value initializer is not a constant!");
GlobalVariable *GV = new GlobalVariable(PointerType::get(Ty), $3,
Initializer);
GlobalVariable *GV = new GlobalVariable(Ty, $3, Initializer);
setValueName(GV, $2);
CurModule.CurrentModule->getGlobalList().push_back(GV);
@ -953,7 +956,7 @@ ConstPool : ConstPool OptAssign CONST ConstVal {
"' is not a sized type!");
}
GlobalVariable *GV = new GlobalVariable(PointerType::get(Ty), $4);
GlobalVariable *GV = new GlobalVariable(Ty, $4);
setValueName(GV, $2);
CurModule.CurrentModule->getGlobalList().push_back(GV);
@ -1031,13 +1034,14 @@ MethodHeaderH : TypesV STRINGCONSTANT '(' ArgList ')' {
for (list<MethodArgument*>::iterator I = $4->begin(); I != $4->end(); ++I)
ParamTypeList.push_back((*I)->getType());
const MethodType *MT = MethodType::get(*$1, ParamTypeList);
const MethodType *MT = MethodType::get(*$1, ParamTypeList);
const PointerType *PMT = PointerType::get(MT);
delete $1;
Method *M = 0;
if (SymbolTable *ST = CurModule.CurrentModule->getSymbolTable()) {
if (Value *V = ST->lookup(MT, $2)) { // Method already in symtab?
M = cast<Method>(V);
if (Value *V = ST->lookup(PMT, $2)) { // Method already in symtab?
M = cast<Method>(V);
// Yes it is. If this is the case, either we need to be a forward decl,
// or it needs to be.
@ -1274,18 +1278,23 @@ InstVal : BinaryOps Types ValueRef ',' ValueRef {
delete $2; // Free the list...
}
| CALL TypesV ValueRef '(' ValueRefListE ')' {
const PointerType *PMTy;
const MethodType *Ty;
if (!(Ty = dyn_cast<MethodType>($2->get()))) {
if (!(PMTy = dyn_cast<PointerType>($2->get())) ||
!(Ty = dyn_cast<MethodType>(PMTy->getValueType()))) {
// Pull out the types of all of the arguments...
vector<const Type*> ParamTypes;
for (list<Value*>::iterator I = $5->begin(), E = $5->end(); I != E; ++I)
ParamTypes.push_back((*I)->getType());
Ty = MethodType::get(*$2, ParamTypes);
if ($5) {
for (list<Value*>::iterator I = $5->begin(), E = $5->end(); I != E; ++I)
ParamTypes.push_back((*I)->getType());
}
Ty = MethodType::get($2->get(), ParamTypes);
PMTy = PointerType::get(Ty);
}
delete $2;
Value *V = getVal(Ty, $3); // Get the method we're calling...
Value *V = getVal(PMTy, $3); // Get the method we're calling...
// Create the call node...
if (!$5) { // Has no arguments?

View File

@ -158,7 +158,7 @@ bool BytecodeParser::parseTypeConstants(const uchar *&Buf, const uchar *EndBuf,
BCR_TRACE(5, "Resulting types:\n");
for (unsigned i = 0; i < NumEntries; i++) {
BCR_TRACE(5, cast<Type>(Tab[i+BaseLevel]) << "\n");
BCR_TRACE(5, cast<const Type>(Tab[i+BaseLevel]) << "\n");
}
return false;
}

View File

@ -197,9 +197,9 @@ bool BytecodeParser::ParseInstruction(const uchar *&Buf, const uchar *EndBuf,
if (M == 0) return failure(true);
vector<Value *> Params;
const MethodType::ParamTypes &PL = M->getType()->getParamTypes();
const MethodType::ParamTypes &PL = M->getMethodType()->getParamTypes();
if (!M->getType()->isVarArg()) {
if (!M->getMethodType()->isVarArg()) {
MethodType::ParamTypes::const_iterator It = PL.begin();
switch (Raw.NumOperands) {

View File

@ -223,7 +223,10 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
Values.clear();
if (MethodSignatureList.empty()) return failure(true); // Unexpected method!
const MethodType *MTy = MethodSignatureList.front().first;
const PointerType *PMTy = MethodSignatureList.front().first; // PtrMeth
const MethodType *MTy = dyn_cast<const MethodType>(PMTy->getValueType());
if (MTy == 0) return failure(true); // Not ptr to method!
unsigned MethSlot = MethodSignatureList.front().second;
MethodSignatureList.pop_front();
Method *M = new Method(MTy);
@ -289,13 +292,13 @@ bool BytecodeParser::ParseMethod(const uchar *&Buf, const uchar *EndBuf,
delete M; return failure(true); // Unresolvable references!
}
Value *MethPHolder = getValue(MTy, MethSlot, false);
Value *MethPHolder = getValue(PMTy, MethSlot, false);
assert(MethPHolder && "Something is broken no placeholder found!");
assert(isa<Method>(MethPHolder) && "Not a method?");
unsigned type; // Type slot
assert(!getTypeSlot(MTy, type) && "How can meth type not exist?");
getTypeSlot(MTy, type);
getTypeSlot(PMTy, type);
C->getMethodList().push_back(M);
@ -330,6 +333,9 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
return failure(true);
}
const PointerType *PTy = cast<const PointerType>(Ty);
Ty = PTy->getValueType();
ConstPoolVal *Initializer = 0;
if (VarType & 2) { // Does it have an initalizer?
// Do not improvise... values must have been stored in the constant pool,
@ -338,8 +344,7 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
unsigned InitSlot;
if (read_vbr(Buf, End, InitSlot)) return failure(true);
Value *V = getValue(cast<const PointerType>(Ty)->getValueType(),
InitSlot, false);
Value *V = getValue(Ty, InitSlot, false);
if (V == 0) return failure(true);
Initializer = cast<ConstPoolVal>(V);
}
@ -350,7 +355,7 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
C->getGlobalList().push_back(GV);
if (read_vbr(Buf, End, VarType)) return failure(true);
BCR_TRACE(2, "Global Variable of type: " << Ty->getDescription() << endl);
BCR_TRACE(2, "Global Variable of type: " << PTy->getDescription() << endl);
}
// Read the method signatures for all of the methods that are coming, and
@ -359,10 +364,14 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
if (read_vbr(Buf, End, MethSignature)) return failure(true);
while (MethSignature != Type::VoidTyID) { // List is terminated by Void
const Type *Ty = getType(MethSignature);
if (!Ty || !isa<MethodType>(Ty)) {
cerr << "Method not meth type! Ty = " << Ty << endl;
if (!Ty || !isa<PointerType>(Ty) ||
!isa<MethodType>(cast<PointerType>(Ty)->getValueType())) {
cerr << "Method not ptr to meth type! Ty = " << Ty << endl;
return failure(true);
}
// We create methods by passing the underlying MethodType to create...
Ty = cast<PointerType>(Ty)->getValueType();
// When the ModuleGlobalInfo section is read, we load the type of each
// method and the 'ModuleValues' slot that it lands in. We then load a
@ -370,19 +379,20 @@ bool BytecodeParser::ParseModuleGlobalInfo(const uchar *&Buf, const uchar *End,
// placeholder is replaced.
// Insert the placeholder...
Value *Def = new MethPHolder(Ty, 0);
insertValue(Def, ModuleValues);
Value *Val = new MethPHolder(Ty, 0);
insertValue(Val, ModuleValues);
// Figure out which entry of its typeslot it went into...
unsigned TypeSlot;
if (getTypeSlot(Def->getType(), TypeSlot)) return failure(true);
if (getTypeSlot(Val->getType(), TypeSlot)) return failure(true);
unsigned SlotNo = ModuleValues[TypeSlot].size()-1;
// Keep track of this information in a linked list that is emptied as
// methods are loaded...
//
MethodSignatureList.push_back(make_pair(cast<const MethodType>(Ty),SlotNo));
MethodSignatureList.push_back(
make_pair(cast<const PointerType>(Val->getType()), SlotNo));
if (read_vbr(Buf, End, MethSignature)) return failure(true);
BCR_TRACE(2, "Method of type: " << Ty << endl);
}

View File

@ -72,7 +72,7 @@ private: // All of this data is transient across calls to ParseBytecode
// into its slot to reserve it. When the method is loaded, this placeholder
// is replaced.
//
list<pair<const MethodType *, unsigned> > MethodSignatureList;
list<pair<const PointerType *, unsigned> > MethodSignatureList;
private:
bool ParseModule (const uchar * Buf, const uchar *End, Module *&);

View File

@ -15,6 +15,7 @@
#include "llvm/BasicBlock.h"
#include "llvm/Instruction.h"
#include "llvm/DerivedTypes.h"
#include "llvm/iOther.h"
#include <algorithm>
typedef unsigned char uchar;
@ -214,10 +215,11 @@ void BytecodeWriter::processInstruction(const Instruction *I) {
assert(Slots[1] != -1 && "Cast return type unknown?");
if (Slots[1] > MaxOpSlot) MaxOpSlot = Slots[1];
NumOperands++;
} else if (I->getOpcode() == Instruction::Call && // Handle VarArg calls
cast<MethodType>(I->getOperand(0)->getType())->isVarArg()) {
outputInstrVarArgsCall(I, Table, Type, Out);
return;
} else if (const CallInst *CI = dyn_cast<CallInst>(I)) {// Handle VarArg calls
if (CI->getCalledMethod()->getMethodType()->isVarArg()) {
outputInstrVarArgsCall(I, Table, Type, Out);
return;
}
}
// Decide which instruction encoding to use. This is determined primarily by

View File

@ -45,7 +45,7 @@ static ExFunc lookupMethod(const Method *M) {
// Function not found, look it up... start by figuring out what the
// composite function name should be.
string ExtName = "lle_";
const MethodType *MT = M->getType();
const MethodType *MT = M->getMethodType();
for (unsigned i = 0; const Type *Ty = MT->getContainedType(i); ++i)
ExtName += getTypeID(Ty);
ExtName += "_" + M->getName();
@ -72,7 +72,7 @@ void Interpreter::callExternalMethod(Method *M,
}
// TODO: FIXME when types are not const!
GenericValue Result = Fn(const_cast<MethodType*>(M->getType()), ArgVals);
GenericValue Result = Fn(const_cast<MethodType*>(M->getMethodType()),ArgVals);
// Copy the result back into the result variable if we are not returning void.
if (M->getReturnType() != Type::VoidTy) {

View File

@ -696,7 +696,7 @@ MachineInstr * UltraSparcRegInfo::cpValue2RegMI(Value * Val,
switch( Val->getValueType() ) {
case Value::ConstantVal:
case Value::GlobalVal:
case Value::GlobalVariableVal:
MOType = MachineOperand:: MO_UnextendedImmed; // TODO**** correct???
break;

View File

@ -192,7 +192,7 @@ void AssemblyWriter::processMethod(const Method *M) {
// Finish printing arguments...
const MethodType *MT = cast<const MethodType>(M->getType());
const MethodType *MT = cast<const MethodType>(M->getMethodType());
if (MT->isVarArg()) {
if (MT->getParamTypes().size()) Out << ", ";
Out << "..."; // Output varargs portion of signature!
@ -300,6 +300,7 @@ void AssemblyWriter::processInstruction(const Instruction *I) {
} else if (I->getOpcode() == Instruction::Ret && !Operand) {
Out << " void";
} else if (I->getOpcode() == Instruction::Call) {
// TODO: Should try to print out short form of the Call instruction
writeOperand(Operand, true);
Out << "(";
if (I->getNumOperands() > 1) writeOperand(I->getOperand(1), true);

View File

@ -106,7 +106,7 @@ ConstPoolStruct::ConstPoolStruct(const StructType *T,
ConstPoolPointer::ConstPoolPointer(const PointerType *T) : ConstPoolVal(T) {}
ConstPoolPointerReference::ConstPoolPointerReference(GlobalVariable *GV)
ConstPoolPointerReference::ConstPoolPointerReference(GlobalValue *GV)
: ConstPoolPointer(GV->getType()) {
Operands.push_back(Use(GV, this));
}

View File

@ -26,8 +26,8 @@ template class ValueHolder<MethodArgument, Method, Method>;
template class ValueHolder<BasicBlock , Method, Method>;
Method::Method(const MethodType *Ty, const string &name)
: Value(Ty, Value::MethodVal, name), SymTabValue(this), BasicBlocks(this),
ArgumentList(this, this) {
: GlobalValue(PointerType::get(Ty), Value::MethodVal, name),
SymTabValue(this), BasicBlocks(this), ArgumentList(this, this) {
assert(::isa<MethodType>(Ty) && "Method signature must be of method type!");
Parent = 0;
}
@ -62,8 +62,12 @@ void Method::setParent(Module *parent) {
setParentSymTab(Parent ? Parent->getSymbolTableSure() : 0);
}
const MethodType *Method::getMethodType() const {
return cast<MethodType>(cast<PointerType>(getType())->getValueType());
}
const Type *Method::getReturnType() const {
return ((const MethodType *)getType())->getReturnType();
return getMethodType()->getReturnType();
}
// dropAllReferences() - This function causes all the subinstructions to "let
@ -85,8 +89,8 @@ void Method::dropAllReferences() {
GlobalVariable::GlobalVariable(const Type *Ty, bool isConstant,
ConstPoolVal *Initializer = 0,
const string &Name = "")
: User(Ty, Value::GlobalVal, Name), Parent(0), Constant(isConstant) {
assert(Ty->isPointerType() && "Global Variables must be pointers!");
: GlobalValue(PointerType::get(Ty), Value::GlobalVariableVal, Name),
Parent(0), Constant(isConstant) {
if (Initializer) Operands.push_back(Use((Value*)Initializer, this));
assert(!isConstant || hasInitializer() &&

View File

@ -15,9 +15,9 @@ CallInst::CallInst(Method *M, const vector<Value*> &params,
Operands.reserve(1+params.size());
Operands.push_back(Use(M, this));
const MethodType::ParamTypes &PL = M->getType()->getParamTypes();
const MethodType::ParamTypes &PL = M->getMethodType()->getParamTypes();
assert((params.size() == PL.size()) ||
(M->getType()->isVarArg() && params.size() > PL.size()) &&
(M->getMethodType()->isVarArg() && params.size() > PL.size()) &&
"Calling a function with bad signature");
#ifndef NDEBUG
MethodType::ParamTypes::const_iterator It = PL.begin();