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() << ">";
}
// 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());
}
};
#include "llvm/SymTabValue.h"
#include "llvm/BasicBlock.h"
+#include "llvm/GlobalValue.h"
class Instruction;
class BasicBlock;
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;
// 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
--- /dev/null
+//===-- 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
#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>;
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);
// 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;
}
};
class MethodArgument;
class Instruction;
class BasicBlock;
+class GlobalValue;
class Method;
class GlobalVariable;
class Module;
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
};
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;
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:
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
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();
}
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();
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);
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);
"' 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);
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.
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?
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;
}
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) {
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);
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);
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,
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);
}
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
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
// 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);
}
// 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 *&);
#include "llvm/BasicBlock.h"
#include "llvm/Instruction.h"
#include "llvm/DerivedTypes.h"
+#include "llvm/iOther.h"
#include <algorithm>
typedef unsigned char uchar;
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
// 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();
}
// 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) {
switch( Val->getValueType() ) {
case Value::ConstantVal:
- case Value::GlobalVal:
+ case Value::GlobalVariableVal:
MOType = MachineOperand:: MO_UnextendedImmed; // TODO**** correct???
break;
// 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!
} 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);
ConstPoolPointer::ConstPoolPointer(const PointerType *T) : ConstPoolVal(T) {}
-ConstPoolPointerReference::ConstPoolPointerReference(GlobalVariable *GV)
+ConstPoolPointerReference::ConstPoolPointerReference(GlobalValue *GV)
: ConstPoolPointer(GV->getType()) {
Operands.push_back(Use(GV, this));
}
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;
}
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
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() &&
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();