Convert comments to Doxygen style

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@3507 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2002-08-25 22:54:55 +00:00
parent 969c4ad65d
commit 2619905926
12 changed files with 366 additions and 359 deletions

View File

@@ -25,7 +25,7 @@ public:
Parent = 0; Parent = 0;
} }
// Specialize setName to handle symbol table majik... /// setName - Specialize setName to handle symbol table majik...
virtual void setName(const std::string &name, SymbolTable *ST = 0); virtual void setName(const std::string &name, SymbolTable *ST = 0);
inline const Function *getParent() const { return Parent; } inline const Function *getParent() const { return Parent; }
@@ -39,7 +39,9 @@ public:
virtual void print(std::ostream &OS) const; virtual void print(std::ostream &OS) const;
// Methods for support type inquiry through isa, cast, and dyn_cast: /// classof - Methods for support type inquiry through isa, cast, and
/// dyn_cast:
///
static inline bool classof(const Argument *) { return true; } static inline bool classof(const Argument *) { return true; }
static inline bool classof(const Value *V) { static inline bool classof(const Value *V) {
return V->getValueType() == ArgumentVal; return V->getValueType() == ArgumentVal;

View File

@@ -1,20 +1,22 @@
//===-- llvm/BasicBlock.h - Represent a basic block in the VM ----*- C++ -*--=// //===-- llvm/BasicBlock.h - Represent a basic block in the VM ----*- C++ -*--=//
// ///
// This file contains the declaration of the BasicBlock class, which represents /// \class BasicBlock
// a single basic block in the VM. ///
// /// This file contains the declaration of the BasicBlock class, which represents
// Note that basic blocks themselves are Value's, because they are referenced /// a single basic block in the VM.
// by instructions like branches and can go in switch tables and stuff... ///
// /// Note that basic blocks themselves are Value's, because they are referenced
//===----------------------------------------------------------------------===// /// by instructions like branches and can go in switch tables and stuff...
// ///
// Note that well formed basic blocks are formed of a list of instructions ///===---------------------------------------------------------------------===//
// followed by a single TerminatorInst instruction. TerminatorInst's may not ///
// occur in the middle of basic blocks, and must terminate the blocks. /// Note that well formed basic blocks are formed of a list of instructions
// /// followed by a single TerminatorInst instruction. TerminatorInst's may not
// This code allows malformed basic blocks to occur, because it may be useful /// occur in the middle of basic blocks, and must terminate the blocks.
// in the intermediate stage of analysis or modification of a program. ///
// /// This code allows malformed basic blocks to occur, because it may be useful
/// in the intermediate stage modification to a program.
///
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_BASICBLOCK_H #ifndef LLVM_BASICBLOCK_H
@@ -74,10 +76,10 @@ public:
BasicBlock *getPrev() { return Prev; } BasicBlock *getPrev() { return Prev; }
const BasicBlock *getPrev() const { return Prev; } const BasicBlock *getPrev() const { return Prev; }
// getTerminator() - If this is a well formed basic block, then this returns /// getTerminator() - If this is a well formed basic block, then this returns
// a pointer to the terminator instruction. If it is not, then you get a null /// a pointer to the terminator instruction. If it is not, then you get a
// pointer back. /// null pointer back.
// ///
TerminatorInst *getTerminator(); TerminatorInst *getTerminator();
const TerminatorInst *const getTerminator() const; const TerminatorInst *const getTerminator() const;
@@ -111,57 +113,57 @@ public:
inline const Instruction &back() const { return InstList.back(); } inline const Instruction &back() const { return InstList.back(); }
inline Instruction &back() { return InstList.back(); } inline Instruction &back() { return InstList.back(); }
// getInstList() - Return the underlying instruction list container. You need /// getInstList() - Return the underlying instruction list container. You
// to access it directly if you want to modify it currently. /// need to access it directly if you want to modify it currently.
// ///
const InstListType &getInstList() const { return InstList; } const InstListType &getInstList() const { return InstList; }
InstListType &getInstList() { return InstList; } InstListType &getInstList() { return InstList; }
virtual void print(std::ostream &OS) const; virtual void print(std::ostream &OS) const;
// Methods for support type inquiry through isa, cast, and dyn_cast: /// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const BasicBlock *BB) { return true; } static inline bool classof(const BasicBlock *BB) { return true; }
static inline bool classof(const Value *V) { static inline bool classof(const Value *V) {
return V->getValueType() == Value::BasicBlockVal; return V->getValueType() == Value::BasicBlockVal;
} }
// hasConstantReferences() - This predicate is true if there is a /// hasConstantReferences() - This predicate is true if there is a
// reference to this basic block in the constant pool for this method. For /// reference to this basic block in the constant pool for this method. For
// example, if a block is reached through a switch table, that table resides /// example, if a block is reached through a switch table, that table resides
// in the constant pool, and the basic block is reference from it. /// in the constant pool, and the basic block is reference from it.
// ///
bool hasConstantReferences() const; bool hasConstantReferences() const;
// dropAllReferences() - This function causes all the subinstructions to "let /// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining. This allows one to /// go" of all references that they are maintaining. This allows one to
// 'delete' a whole class at a time, even though there may be circular /// 'delete' a whole class at a time, even though there may be circular
// references... first all references are dropped, and all use counts go to /// references... first all references are dropped, and all use counts go to
// zero. Then everything is delete'd for real. Note that no operations are /// zero. Then everything is delete'd for real. Note that no operations are
// valid on an object that has "dropped all references", except operator /// valid on an object that has "dropped all references", except operator
// delete. /// delete.
// ///
void dropAllReferences(); void dropAllReferences();
// removePredecessor - This method is used to notify a BasicBlock that the /// removePredecessor - This method is used to notify a BasicBlock that the
// specified Predecessor of the block is no longer able to reach it. This is /// specified Predecessor of the block is no longer able to reach it. This is
// actually not used to update the Predecessor list, but is actually used to /// actually not used to update the Predecessor list, but is actually used to
// update the PHI nodes that reside in the block. Note that this should be /// update the PHI nodes that reside in the block. Note that this should be
// called while the predecessor still refers to this block. /// called while the predecessor still refers to this block.
// ///
void removePredecessor(BasicBlock *Pred); void removePredecessor(BasicBlock *Pred);
// splitBasicBlock - This splits a basic block into two at the specified /// splitBasicBlock - This splits a basic block into two at the specified
// instruction. Note that all instructions BEFORE the specified iterator stay /// instruction. Note that all instructions BEFORE the specified iterator
// as part of the original basic block, an unconditional branch is added to /// stay as part of the original basic block, an unconditional branch is added
// the new BB, and the rest of the instructions in the BB are moved to the new /// to the new BB, and the rest of the instructions in the BB are moved to the
// BB, including the old terminator. The newly formed BasicBlock is returned. /// new BB, including the old terminator. The newly formed BasicBlock is
// This function invalidates the specified iterator. /// returned. This function invalidates the specified iterator.
// ///
// Note that this only works on well formed basic blocks (must have a /// Note that this only works on well formed basic blocks (must have a
// terminator), and 'I' must not be the end of instruction list (which would /// terminator), and 'I' must not be the end of instruction list (which would
// cause a degenerate basic block to be formed, having a terminator inside of /// cause a degenerate basic block to be formed, having a terminator inside of
// the basic block). /// the basic block).
// ///
BasicBlock *splitBasicBlock(iterator I); BasicBlock *splitBasicBlock(iterator I);
}; };

View File

@@ -16,40 +16,40 @@ protected:
void destroyConstantImpl(); void destroyConstantImpl();
public: public:
// Specialize setName to handle symbol table majik... /// setName - Specialize setName to handle symbol table majik...
virtual void setName(const std::string &name, SymbolTable *ST = 0); virtual void setName(const std::string &name, SymbolTable *ST = 0);
// Static constructor to get a '0' constant of arbitrary type... /// Static constructor to get a '0' constant of arbitrary type...
static Constant *getNullValue(const Type *Ty); static Constant *getNullValue(const Type *Ty);
// isNullValue - Return true if this is the value that would be returned by /// isNullValue - Return true if this is the value that would be returned by
// getNullValue. /// getNullValue.
virtual bool isNullValue() const = 0; virtual bool isNullValue() const = 0;
virtual void print(std::ostream &O) const; virtual void print(std::ostream &O) const;
// isConstantExpr - Return true if this is a ConstantExpr /// isConstantExpr - Return true if this is a ConstantExpr
virtual bool isConstantExpr() const { return false; } virtual bool isConstantExpr() const { return false; }
// destroyConstant - Called if some element of this constant is no longer /// destroyConstant - Called if some element of this constant is no longer
// valid. At this point only other constants may be on the use_list for this /// valid. At this point only other constants may be on the use_list for this
// constant. Any constants on our Use list must also be destroy'd. The /// constant. Any constants on our Use list must also be destroy'd. The
// implementation must be sure to remove the constant from the list of /// implementation must be sure to remove the constant from the list of
// available cached constants. Implementations should call /// available cached constants. Implementations should call
// destroyConstantImpl as the last thing they do, to destroy all users and /// destroyConstantImpl as the last thing they do, to destroy all users and
// delete this. /// delete this.
// ///
// Note that this call is only valid on non-primitive constants: You cannot /// Note that this call is only valid on non-primitive constants: You cannot
// destroy an integer constant for example. This API is used to delete /// destroy an integer constant for example. This API is used to delete
// constants that have ConstantPointerRef's embeded in them when the module is /// constants that have ConstantPointerRef's embeded in them when the module
// deleted, and it is used by GlobalDCE to remove ConstantPointerRefs that are /// is deleted, and it is used by GlobalDCE to remove ConstantPointerRefs that
// unneeded, allowing globals to be DCE'd. /// are unneeded, allowing globals to be DCE'd.
// ///
virtual void destroyConstant() { assert(0 && "Not reached!"); } virtual void destroyConstant() { assert(0 && "Not reached!"); }
// Methods for support type inquiry through isa, cast, and dyn_cast: /// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Constant *) { return true; } static inline bool classof(const Constant *) { return true; }
static inline bool classof(const Value *V) { static inline bool classof(const Value *V) {
return V->getValueType() == Value::ConstantVal; return V->getValueType() == Value::ConstantVal;

View File

@@ -77,8 +77,10 @@ public:
const Type *getReturnType() const; // Return the type of the ret val const Type *getReturnType() const; // Return the type of the ret val
const FunctionType *getFunctionType() const; // Return the FunctionType for me const FunctionType *getFunctionType() const; // Return the FunctionType for me
// Is the body of this function unknown? (the basic block list is empty if so) /// isExternal - Is the body of this function unknown? (the basic block list
// this is true for external functions, defined as forward "declare"ations /// is empty if so) this is true for external functions, defined as forward
/// "declare"ations
///
bool isExternal() const { return BasicBlocks.empty(); } bool isExternal() const { return BasicBlocks.empty(); }
// getNext/Prev - Return the next or previous instruction in the list. The // getNext/Prev - Return the next or previous instruction in the list. The
@@ -88,9 +90,9 @@ public:
Function *getPrev() { return Prev; } Function *getPrev() { return Prev; }
const Function *getPrev() const { return Prev; } const Function *getPrev() const { return Prev; }
// Get the underlying elements of the Function... both the argument list and /// Get the underlying elements of the Function... both the argument list and
// basic block list are empty for external functions. /// basic block list are empty for external functions.
// ///
const ArgumentListType &getArgumentList() const { return ArgumentList; } const ArgumentListType &getArgumentList() const { return ArgumentList; }
ArgumentListType &getArgumentList() { return ArgumentList; } ArgumentListType &getArgumentList() { return ArgumentList; }
@@ -103,21 +105,21 @@ public:
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Symbol Table Accessing functions... // Symbol Table Accessing functions...
// hasSymbolTable() - Returns true if there is a symbol table allocated to /// hasSymbolTable() - Returns true if there is a symbol table allocated to
// this object AND if there is at least one name in it! /// this object AND if there is at least one name in it!
// ///
bool hasSymbolTable() const; bool hasSymbolTable() const;
// CAUTION: The current symbol table may be null if there are no names (ie, /// getSymbolTable() - CAUTION: The current symbol table may be null if there
// the symbol table is empty) /// are no names (ie, the symbol table is empty)
// ///
inline SymbolTable *getSymbolTable() { return SymTab; } inline SymbolTable *getSymbolTable() { return SymTab; }
inline const SymbolTable *getSymbolTable() const { return SymTab; } inline const SymbolTable *getSymbolTable() const { return SymTab; }
// getSymbolTableSure is guaranteed to not return a null pointer, because if /// getSymbolTableSure is guaranteed to not return a null pointer, because if
// the function does not already have a symtab, one is created. Use this if /// the function does not already have a symtab, one is created. Use this if
// you intend to put something into the symbol table for the function. /// you intend to put something into the symbol table for the function.
// ///
SymbolTable *getSymbolTableSure(); // Implemented in Value.cpp SymbolTable *getSymbolTableSure(); // Implemented in Value.cpp
@@ -163,20 +165,20 @@ public:
virtual void print(std::ostream &OS) const; virtual void print(std::ostream &OS) const;
// Methods for support type inquiry through isa, cast, and dyn_cast: /// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Function *) { return true; } static inline bool classof(const Function *) { return true; }
static inline bool classof(const Value *V) { static inline bool classof(const Value *V) {
return V->getValueType() == Value::FunctionVal; return V->getValueType() == Value::FunctionVal;
} }
// dropAllReferences() - This function causes all the subinstructions to "let /// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining. This allows one to /// go" of all references that they are maintaining. This allows one to
// 'delete' a whole class at a time, even though there may be circular /// 'delete' a whole class at a time, even though there may be circular
// references... first all references are dropped, and all use counts go to /// references... first all references are dropped, and all use counts go to
// zero. Then everything is delete'd for real. Note that no operations are /// zero. Then everything is delete'd for real. Note that no operations are
// valid on an object that has "dropped all references", except operator /// valid on an object that has "dropped all references", except operator
// delete. /// delete.
// ///
void dropAllReferences(); void dropAllReferences();
}; };

View File

@@ -15,9 +15,9 @@
// TerminatorInst Class // TerminatorInst Class
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// TerminatorInst - Subclasses of this class are all able to terminate a basic /// TerminatorInst - Subclasses of this class are all able to terminate a basic
// block. Thus, these are all the flow control type of operations. /// block. Thus, these are all the flow control type of operations.
// ///
class TerminatorInst : public Instruction { class TerminatorInst : public Instruction {
protected: protected:
TerminatorInst(Instruction::TermOps iType); TerminatorInst(Instruction::TermOps iType);
@@ -25,17 +25,17 @@ protected:
const std::string &Name = ""); const std::string &Name = "");
public: public:
// Terminators must implement the methods required by Instruction... /// Terminators must implement the methods required by Instruction...
virtual Instruction *clone() const = 0; virtual Instruction *clone() const = 0;
// Additionally, they must provide a method to get at the successors of this /// Additionally, they must provide a method to get at the successors of this
// terminator instruction. 'idx' may not be >= the number of successors /// terminator instruction. 'idx' may not be >= the number of successors
// returned by getNumSuccessors()! /// returned by getNumSuccessors()!
// ///
virtual const BasicBlock *getSuccessor(unsigned idx) const = 0; virtual const BasicBlock *getSuccessor(unsigned idx) const = 0;
virtual unsigned getNumSuccessors() const = 0; virtual unsigned getNumSuccessors() const = 0;
// Set a successor at a given index /// Set a successor at a given index
virtual void setSuccessor(unsigned idx, BasicBlock *B) = 0; virtual void setSuccessor(unsigned idx, BasicBlock *B) = 0;
inline BasicBlock *getSuccessor(unsigned idx) { inline BasicBlock *getSuccessor(unsigned idx) {
@@ -71,29 +71,29 @@ protected:
public: public:
// create() - Construct a binary instruction, given the opcode /// create() - Construct a binary instruction, given the opcode
// and the two operands. /// and the two operands.
// ///
static BinaryOperator *create(BinaryOps Op, Value *S1, Value *S2, static BinaryOperator *create(BinaryOps Op, Value *S1, Value *S2,
const std::string &Name = ""); const std::string &Name = "");
// Helper functions to construct and inspect unary operations (NEG and NOT) /// Helper functions to construct and inspect unary operations (NEG and NOT)
// via binary operators SUB and XOR: /// via binary operators SUB and XOR:
// ///
// createNeg, createNot - Create the NEG and NOT /// createNeg, createNot - Create the NEG and NOT
// instructions out of SUB and XOR instructions. /// instructions out of SUB and XOR instructions.
// ///
// isNeg, isNot - Check if the given Value is a NEG or NOT instruction.
//
// getNegArgument, getNotArgument - Helper functions to extract the
// unary argument of a NEG or NOT operation implemented via Sub or Xor.
//
static BinaryOperator *createNeg(Value *Op, const std::string &Name = ""); static BinaryOperator *createNeg(Value *Op, const std::string &Name = "");
static BinaryOperator *createNot(Value *Op, const std::string &Name = ""); static BinaryOperator *createNot(Value *Op, const std::string &Name = "");
/// isNeg, isNot - Check if the given Value is a NEG or NOT instruction.
///
static bool isNeg(const Value *V); static bool isNeg(const Value *V);
static bool isNot(const Value *V); static bool isNot(const Value *V);
/// getNegArgument, getNotArgument - Helper functions to extract the
/// unary argument of a NEG or NOT operation implemented via Sub or Xor.
///
static const Value* getNegArgument(const BinaryOperator* Bop); static const Value* getNegArgument(const BinaryOperator* Bop);
static Value* getNegArgument( BinaryOperator* Bop); static Value* getNegArgument( BinaryOperator* Bop);
static const Value* getNotArgument(const BinaryOperator* Bop); static const Value* getNotArgument(const BinaryOperator* Bop);
@@ -107,13 +107,13 @@ public:
return create(getOpcode(), Operands[0], Operands[1]); return create(getOpcode(), Operands[0], Operands[1]);
} }
// swapOperands - Exchange the two operands to this instruction. /// swapOperands - Exchange the two operands to this instruction.
// This instruction is safe to use on any binary instruction and /// This instruction is safe to use on any binary instruction and
// does not modify the semantics of the instruction. If the /// does not modify the semantics of the instruction. If the
// instruction is order dependant (SetLT f.e.) the opcode is /// instruction is order dependant (SetLT f.e.) the opcode is
// changed. If the instruction cannot be reversed (ie, it's a Div), /// changed. If the instruction cannot be reversed (ie, it's a Div),
// then return true. /// then return true.
// ///
bool swapOperands(); bool swapOperands();
// Methods for support type inquiry through isa, cast, and dyn_cast: // Methods for support type inquiry through isa, cast, and dyn_cast:

View File

@@ -34,11 +34,11 @@ public:
// Specialize setName to handle symbol table majik... // Specialize setName to handle symbol table majik...
virtual void setName(const std::string &name, SymbolTable *ST = 0); virtual void setName(const std::string &name, SymbolTable *ST = 0);
// clone() - Create a copy of 'this' instruction that is identical in all ways /// clone() - Create a copy of 'this' instruction that is identical in all
// except the following: /// ways except the following:
// * The instruction has no parent /// * The instruction has no parent
// * The instruction has no name /// * The instruction has no name
// ///
virtual Instruction *clone() const = 0; virtual Instruction *clone() const = 0;
// Accessor methods... // Accessor methods...
@@ -56,9 +56,9 @@ public:
virtual bool hasSideEffects() const { return false; } // Memory & Call insts virtual bool hasSideEffects() const { return false; } // Memory & Call insts
// --------------------------------------------------------------------------- // ---------------------------------------------------------------------------
// Subclass classification... getOpcode() returns a member of /// Subclass classification... getOpcode() returns a member of
// one of the enums that is coming soon (down below)... /// one of the enums that is coming soon (down below)...
// ///
unsigned getOpcode() const { return iType; } unsigned getOpcode() const { return iType; }
virtual const char *getOpcodeName() const { virtual const char *getOpcodeName() const {
return getOpcodeName(getOpcode()); return getOpcodeName(getOpcode());
@@ -74,7 +74,7 @@ public:
virtual void print(std::ostream &OS) const; virtual void print(std::ostream &OS) const;
// Methods for support type inquiry through isa, cast, and dyn_cast: /// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Instruction *I) { return true; } static inline bool classof(const Instruction *I) { return true; }
static inline bool classof(const Value *V) { static inline bool classof(const Value *V) {
return V->getValueType() == Value::InstructionVal; return V->getValueType() == Value::InstructionVal;

View File

@@ -69,28 +69,28 @@ public:
Module(); Module();
~Module(); ~Module();
// getOrInsertFunction - Look up the specified function in the module symbol /// getOrInsertFunction - Look up the specified function in the module symbol
// table. If it does not exist, add a prototype for the function and return /// table. If it does not exist, add a prototype for the function and return
// it. /// it.
Function *getOrInsertFunction(const std::string &Name, const FunctionType *T); Function *getOrInsertFunction(const std::string &Name, const FunctionType *T);
// getFunction - Look up the specified function in the module symbol table. /// getFunction - Look up the specified function in the module symbol table.
// If it does not exist, return null. /// If it does not exist, return null.
// ///
Function *getFunction(const std::string &Name, const FunctionType *Ty); Function *getFunction(const std::string &Name, const FunctionType *Ty);
// addTypeName - Insert an entry in the symbol table mapping Str to Type. If /// addTypeName - Insert an entry in the symbol table mapping Str to Type. If
// there is already an entry for this name, true is returned and the symbol /// there is already an entry for this name, true is returned and the symbol
// table is not modified. /// table is not modified.
// ///
bool addTypeName(const std::string &Name, const Type *Ty); bool addTypeName(const std::string &Name, const Type *Ty);
// getTypeName - If there is at least one entry in the symbol table for the /// getTypeName - If there is at least one entry in the symbol table for the
// specified type, return it. /// specified type, return it.
// ///
std::string getTypeName(const Type *Ty); std::string getTypeName(const Type *Ty);
// Get the underlying elements of the Module... /// Get the underlying elements of the Module...
inline const GlobalListType &getGlobalList() const { return GlobalList; } inline const GlobalListType &getGlobalList() const { return GlobalList; }
inline GlobalListType &getGlobalList() { return GlobalList; } inline GlobalListType &getGlobalList() { return GlobalList; }
inline const FunctionListType &getFunctionList() const { return FunctionList;} inline const FunctionListType &getFunctionList() const { return FunctionList;}
@@ -100,21 +100,21 @@ public:
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Symbol table support functions... // Symbol table support functions...
// hasSymbolTable() - Returns true if there is a symbol table allocated to /// hasSymbolTable() - Returns true if there is a symbol table allocated to
// this object AND if there is at least one name in it! /// this object AND if there is at least one name in it!
// ///
bool hasSymbolTable() const; bool hasSymbolTable() const;
// CAUTION: The current symbol table may be null if there are no names (ie, /// getSymbolTable() - CAUTION: The current symbol table may be null if there
// the symbol table is empty) /// are no names (ie, the symbol table is empty)
// ///
inline SymbolTable *getSymbolTable() { return SymTab; } inline SymbolTable *getSymbolTable() { return SymTab; }
inline const SymbolTable *getSymbolTable() const { return SymTab; } inline const SymbolTable *getSymbolTable() const { return SymTab; }
// getSymbolTableSure is guaranteed to not return a null pointer, because if /// getSymbolTableSure is guaranteed to not return a null pointer, because if
// the method does not already have a symtab, one is created. Use this if /// the method does not already have a symtab, one is created. Use this if
// you intend to put something into the symbol table for the method. /// you intend to put something into the symbol table for the method.
// ///
SymbolTable *getSymbolTableSure(); SymbolTable *getSymbolTableSure();
@@ -160,14 +160,14 @@ public:
void print(std::ostream &OS) const; void print(std::ostream &OS) const;
void dump() const; void dump() const;
// dropAllReferences() - This function causes all the subinstructions to "let /// dropAllReferences() - This function causes all the subinstructions to "let
// go" of all references that they are maintaining. This allows one to /// go" of all references that they are maintaining. This allows one to
// 'delete' a whole class at a time, even though there may be circular /// 'delete' a whole class at a time, even though there may be circular
// references... first all references are dropped, and all use counts go to /// references... first all references are dropped, and all use counts go to
// zero. Then everything is delete'd for real. Note that no operations are /// zero. Then everything is delete'd for real. Note that no operations are
// valid on an object that has "dropped all references", except operator /// valid on an object that has "dropped all references", except operator
// delete. /// delete.
// ///
void dropAllReferences(); void dropAllReferences();
}; };

View File

@@ -39,10 +39,10 @@ struct AnalysisResolver;
typedef const PassInfo* AnalysisID; typedef const PassInfo* AnalysisID;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Pass interface - Implemented by all 'passes'. Subclass this if you are an /// Pass interface - Implemented by all 'passes'. Subclass this if you are an
// interprocedural optimization or you do not fit into any of the more /// interprocedural optimization or you do not fit into any of the more
// constrained passes described below. /// constrained passes described below.
// ///
class Pass { class Pass {
friend class AnalysisResolver; friend class AnalysisResolver;
AnalysisResolver *Resolver; // AnalysisResolver this pass is owned by... AnalysisResolver *Resolver; // AnalysisResolver this pass is owned by...
@@ -53,56 +53,56 @@ public:
Pass() : Resolver(0), PassInfoCache(0) {} Pass() : Resolver(0), PassInfoCache(0) {}
virtual ~Pass() {} // Destructor is virtual so we can be subclassed virtual ~Pass() {} // Destructor is virtual so we can be subclassed
// getPassName - Return a nice clean name for a pass. This usually /// getPassName - Return a nice clean name for a pass. This usually
// implemented in terms of the name that is registered by one of the /// implemented in terms of the name that is registered by one of the
// Registration templates, but can be overloaded directly, and if nothing else /// Registration templates, but can be overloaded directly, and if nothing
// is available, C++ RTTI will be consulted to get a SOMEWHAT intelligable /// else is available, C++ RTTI will be consulted to get a SOMEWHAT
// name for the pass. /// intelligable name for the pass.
// ///
virtual const char *getPassName() const; virtual const char *getPassName() const;
// getPassInfo - Return the PassInfo data structure that corresponds to this /// getPassInfo - Return the PassInfo data structure that corresponds to this
// pass... If the pass has not been registered, this will return null. /// pass... If the pass has not been registered, this will return null.
// ///
const PassInfo *getPassInfo() const; const PassInfo *getPassInfo() const;
// run - Run this pass, returning true if a modification was made to the /// run - Run this pass, returning true if a modification was made to the
// module argument. This should be implemented by all concrete subclasses. /// module argument. This should be implemented by all concrete subclasses.
// ///
virtual bool run(Module &M) = 0; virtual bool run(Module &M) = 0;
// print - Print out the internal state of the pass. This is called by /// print - Print out the internal state of the pass. This is called by
// Analyze to print out the contents of an analysis. Otherwise it is not /// Analyze to print out the contents of an analysis. Otherwise it is not
// neccesary to implement this method. Beware that the module pointer MAY be /// neccesary to implement this method. Beware that the module pointer MAY be
// null. This automatically forwards to a virtual function that does not /// null. This automatically forwards to a virtual function that does not
// provide the Module* in case the analysis doesn't need it it can just be /// provide the Module* in case the analysis doesn't need it it can just be
// ignored. /// ignored.
// ///
virtual void print(std::ostream &O, const Module *M) const { print(O); } virtual void print(std::ostream &O, const Module *M) const { print(O); }
virtual void print(std::ostream &O) const; virtual void print(std::ostream &O) const;
void dump() const; // dump - call print(std::cerr, 0); void dump() const; // dump - call print(std::cerr, 0);
// getAnalysisUsage - This function should be overriden by passes that need /// getAnalysisUsage - This function should be overriden by passes that need
// analysis information to do their job. If a pass specifies that it uses a /// analysis information to do their job. If a pass specifies that it uses a
// particular analysis result to this function, it can then use the /// particular analysis result to this function, it can then use the
// getAnalysis<AnalysisType>() function, below. /// getAnalysis<AnalysisType>() function, below.
// ///
virtual void getAnalysisUsage(AnalysisUsage &Info) const { virtual void getAnalysisUsage(AnalysisUsage &Info) const {
// By default, no analysis results are used, all are invalidated. // By default, no analysis results are used, all are invalidated.
} }
// releaseMemory() - This member can be implemented by a pass if it wants to /// releaseMemory() - This member can be implemented by a pass if it wants to
// be able to release its memory when it is no longer needed. The default /// be able to release its memory when it is no longer needed. The default
// behavior of passes is to hold onto memory for the entire duration of their /// behavior of passes is to hold onto memory for the entire duration of their
// lifetime (which is the entire compile time). For pipelined passes, this /// lifetime (which is the entire compile time). For pipelined passes, this
// is not a big deal because that memory gets recycled every time the pass is /// is not a big deal because that memory gets recycled every time the pass is
// invoked on another program unit. For IP passes, it is more important to /// invoked on another program unit. For IP passes, it is more important to
// free memory when it is unused. /// free memory when it is unused.
// ///
// Optionally implement this function to release pass memory when it is no /// Optionally implement this function to release pass memory when it is no
// longer used. /// longer used.
// ///
virtual void releaseMemory() {} virtual void releaseMemory() {}
// dumpPassStructure - Implement the -debug-passes=PassStructure option // dumpPassStructure - Implement the -debug-passes=PassStructure option
@@ -121,10 +121,10 @@ public:
protected: protected:
// getAnalysis<AnalysisType>() - This function is used by subclasses to get to /// getAnalysis<AnalysisType>() - This function is used by subclasses to get
// the analysis information that they claim to use by overriding the /// to the analysis information that they claim to use by overriding the
// getAnalysisUsage function. /// getAnalysisUsage function.
// ///
template<typename AnalysisType> template<typename AnalysisType>
AnalysisType &getAnalysis() { AnalysisType &getAnalysis() {
assert(Resolver && "Pass has not been inserted into a PassManager object!"); assert(Resolver && "Pass has not been inserted into a PassManager object!");
@@ -149,12 +149,12 @@ protected:
return *(AnalysisType*)Resolver->getAnalysis(PI); return *(AnalysisType*)Resolver->getAnalysis(PI);
} }
// getAnalysisToUpdate<AnalysisType>() - This function is used by subclasses /// getAnalysisToUpdate<AnalysisType>() - This function is used by subclasses
// to get to the analysis information that might be around that needs to be /// to get to the analysis information that might be around that needs to be
// updated. This is different than getAnalysis in that it can fail (ie the /// updated. This is different than getAnalysis in that it can fail (ie the
// analysis results haven't been computed), so should only be used if you /// analysis results haven't been computed), so should only be used if you
// provide the capability to update an analysis that exists. /// provide the capability to update an analysis that exists.
// ///
template<typename AnalysisType> template<typename AnalysisType>
AnalysisType *getAnalysisToUpdate() { AnalysisType *getAnalysisToUpdate() {
assert(Resolver && "Pass not resident in a PassManager object!"); assert(Resolver && "Pass not resident in a PassManager object!");
@@ -176,37 +176,38 @@ inline std::ostream &operator<<(std::ostream &OS, const Pass &P) {
} }
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// FunctionPass class - This class is used to implement most global /// FunctionPass class - This class is used to implement most global
// optimizations. Optimizations should subclass this class if they meet the /// optimizations. Optimizations should subclass this class if they meet the
// following constraints: /// following constraints:
// ///
// 1. Optimizations are organized globally, ie a function at a time /// 1. Optimizations are organized globally, ie a function at a time
// 2. Optimizing a function does not cause the addition or removal of any /// 2. Optimizing a function does not cause the addition or removal of any
// functions in the module /// functions in the module
// ///
struct FunctionPass : public Pass { struct FunctionPass : public Pass {
// doInitialization - Virtual method overridden by subclasses to do /// doInitialization - Virtual method overridden by subclasses to do
// any neccesary per-module initialization. /// any neccesary per-module initialization.
// ///
virtual bool doInitialization(Module &M) { return false; } virtual bool doInitialization(Module &M) { return false; }
// runOnFunction - Virtual method overriden by subclasses to do the /// runOnFunction - Virtual method overriden by subclasses to do the
// per-function processing of the pass. /// per-function processing of the pass.
// ///
virtual bool runOnFunction(Function &F) = 0; virtual bool runOnFunction(Function &F) = 0;
// doFinalization - Virtual method overriden by subclasses to do any post /// doFinalization - Virtual method overriden by subclasses to do any post
// processing needed after all passes have run. /// processing needed after all passes have run.
// ///
virtual bool doFinalization(Module &M) { return false; } virtual bool doFinalization(Module &M) { return false; }
// run - On a module, we run this pass by initializing, ronOnFunction'ing once /// run - On a module, we run this pass by initializing, ronOnFunction'ing
// for every function in the module, then by finalizing. /// once for every function in the module, then by finalizing.
// ///
virtual bool run(Module &M); virtual bool run(Module &M);
// run - On a function, we simply initialize, run the function, then finalize. /// run - On a function, we simply initialize, run the function, then
// /// finalize.
///
bool run(Function &F); bool run(Function &F);
private: private:
@@ -220,29 +221,29 @@ private:
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// BasicBlockPass class - This class is used to implement most local /// BasicBlockPass class - This class is used to implement most local
// optimizations. Optimizations should subclass this class if they /// optimizations. Optimizations should subclass this class if they
// meet the following constraints: /// meet the following constraints:
// 1. Optimizations are local, operating on either a basic block or /// 1. Optimizations are local, operating on either a basic block or
// instruction at a time. /// instruction at a time.
// 2. Optimizations do not modify the CFG of the contained function, or any /// 2. Optimizations do not modify the CFG of the contained function, or any
// other basic block in the function. /// other basic block in the function.
// 3. Optimizations conform to all of the contstraints of FunctionPass's. /// 3. Optimizations conform to all of the contstraints of FunctionPass's.
// ///
struct BasicBlockPass : public FunctionPass { struct BasicBlockPass : public FunctionPass {
// runOnBasicBlock - Virtual method overriden by subclasses to do the /// runOnBasicBlock - Virtual method overriden by subclasses to do the
// per-basicblock processing of the pass. /// per-basicblock processing of the pass.
// ///
virtual bool runOnBasicBlock(BasicBlock &BB) = 0; virtual bool runOnBasicBlock(BasicBlock &BB) = 0;
// To run this pass on a function, we simply call runOnBasicBlock once for /// To run this pass on a function, we simply call runOnBasicBlock once for
// each function. /// each function.
// ///
virtual bool runOnFunction(Function &F); virtual bool runOnFunction(Function &F);
// To run directly on the basic block, we initialize, runOnBasicBlock, then /// To run directly on the basic block, we initialize, runOnBasicBlock, then
// finalize. /// finalize.
// ///
bool run(BasicBlock &BB); bool run(BasicBlock &BB);
private: private:

View File

@@ -20,16 +20,16 @@ public:
PassManager(); PassManager();
~PassManager(); ~PassManager();
// add - Add a pass to the queue of passes to run. This passes ownership of /// add - Add a pass to the queue of passes to run. This passes ownership of
// the Pass to the PassManager. When the PassManager is destroyed, the pass /// the Pass to the PassManager. When the PassManager is destroyed, the pass
// will be destroyed as well, so there is no need to delete the pass. This /// will be destroyed as well, so there is no need to delete the pass. This
// implies that all passes MUST be allocated with 'new'. /// implies that all passes MUST be allocated with 'new'.
// ///
void add(Pass *P); void add(Pass *P);
// run - Execute all of the passes scheduled for execution. Keep track of /// run - Execute all of the passes scheduled for execution. Keep track of
// whether any of the functions modifies the program, and if so, return true. /// whether any of the functions modifies the program, and if so, return true.
// ///
bool run(Module &M); bool run(Module &M);
}; };

View File

@@ -39,12 +39,12 @@ class OpaqueType;
class Type : public Value { class Type : public Value {
public: public:
//===--------------------------------------------------------------------===// ///===-------------------------------------------------------------------===//
// Definitions of all of the base types for the Type system. Based on this /// Definitions of all of the base types for the Type system. Based on this
// value, you can cast to a "DerivedType" subclass (see DerivedTypes.h) /// value, you can cast to a "DerivedType" subclass (see DerivedTypes.h)
// Note: If you add an element to this, you need to add an element to the /// Note: If you add an element to this, you need to add an element to the
// Type::getPrimitiveType function, or else things will break! /// Type::getPrimitiveType function, or else things will break!
// ///
enum PrimitiveID { enum PrimitiveID {
VoidTyID = 0 , BoolTyID, // 0, 1: Basics... VoidTyID = 0 , BoolTyID, // 0, 1: Basics...
UByteTyID , SByteTyID, // 2, 3: 8 bit types... UByteTyID , SByteTyID, // 2, 3: 8 bit types...
@@ -77,106 +77,107 @@ private:
bool Recursive; // True if the type is recursive bool Recursive; // True if the type is recursive
protected: protected:
// ctor is protected, so only subclasses can create Type objects... /// ctor is protected, so only subclasses can create Type objects...
Type(const std::string &Name, PrimitiveID id); Type(const std::string &Name, PrimitiveID id);
virtual ~Type() {} virtual ~Type() {}
// When types are refined, they update their description to be more concrete. /// When types are refined, they update their description to be more concrete.
// ///
inline void setDescription(const std::string &D) { Desc = D; } inline void setDescription(const std::string &D) { Desc = D; }
// setName - Associate the name with this type in the symbol table, but don't /// setName - Associate the name with this type in the symbol table, but don't
// set the local name to be equal specified name. /// set the local name to be equal specified name.
// ///
virtual void setName(const std::string &Name, SymbolTable *ST = 0); virtual void setName(const std::string &Name, SymbolTable *ST = 0);
// Types can become nonabstract later, if they are refined. /// Types can become nonabstract later, if they are refined.
// ///
inline void setAbstract(bool Val) { Abstract = Val; } inline void setAbstract(bool Val) { Abstract = Val; }
// Types can become recursive later, if they are refined. /// Types can become recursive later, if they are refined.
// ///
inline void setRecursive(bool Val) { Recursive = Val; } inline void setRecursive(bool Val) { Recursive = Val; }
public: public:
virtual void print(std::ostream &O) const; virtual void print(std::ostream &O) const;
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
// Property accessors for dealing with types... // Property accessors for dealing with types... Some of these virtual methods
// are defined in private classes defined in Type.cpp for primitive types.
// //
// getPrimitiveID - Return the base type of the type. This will return one /// getPrimitiveID - Return the base type of the type. This will return one
// of the PrimitiveID enum elements defined above. /// of the PrimitiveID enum elements defined above.
// ///
inline PrimitiveID getPrimitiveID() const { return ID; } inline PrimitiveID getPrimitiveID() const { return ID; }
// getUniqueID - Returns the UID of the type. This can be thought of as a /// getUniqueID - Returns the UID of the type. This can be thought of as a
// small integer version of the pointer to the type class. Two types that are /// small integer version of the pointer to the type class. Two types that
// structurally different have different UIDs. This can be used for indexing /// are structurally different have different UIDs. This can be used for
// types into an array. /// indexing types into an array.
// ///
inline unsigned getUniqueID() const { return UID; } inline unsigned getUniqueID() const { return UID; }
// getDescription - Return the string representation of the type... /// getDescription - Return the string representation of the type...
inline const std::string &getDescription() const { return Desc; } inline const std::string &getDescription() const { return Desc; }
// isSigned - Return whether a numeric type is signed. /// isSigned - Return whether a numeric type is signed.
virtual bool isSigned() const { return 0; } virtual bool isSigned() const { return 0; }
// isUnsigned - Return whether a numeric type is unsigned. This is not /// isUnsigned - Return whether a numeric type is unsigned. This is not
// quite the complement of isSigned... nonnumeric types return false as they /// quite the complement of isSigned... nonnumeric types return false as they
// do with isSigned. /// do with isSigned.
// ///
virtual bool isUnsigned() const { return 0; } virtual bool isUnsigned() const { return 0; }
// isIntegral - Equilivent to isSigned() || isUnsigned, but with only a single /// isIntegral - Equilivent to isSigned() || isUnsigned, but with only a
// virtual function invocation. /// single virtual function invocation.
// ///
virtual bool isIntegral() const { return 0; } virtual bool isIntegral() const { return 0; }
// isFloatingPoint - Return true if this is one of the two floating point /// isFloatingPoint - Return true if this is one of the two floating point
// types /// types
bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID; } bool isFloatingPoint() const { return ID == FloatTyID || ID == DoubleTyID; }
// isAbstract - True if the type is either an Opaque type, or is a derived /// isAbstract - True if the type is either an Opaque type, or is a derived
// type that includes an opaque type somewhere in it. /// type that includes an opaque type somewhere in it.
// ///
inline bool isAbstract() const { return Abstract; } inline bool isAbstract() const { return Abstract; }
// isRecursive - True if the type graph contains a cycle. /// isRecursive - True if the type graph contains a cycle.
// ///
inline bool isRecursive() const { return Recursive; } inline bool isRecursive() const { return Recursive; }
// isLosslesslyConvertableTo - Return true if this type can be converted to /// isLosslesslyConvertableTo - Return true if this type can be converted to
// 'Ty' without any reinterpretation of bits. For example, uint to int. /// 'Ty' without any reinterpretation of bits. For example, uint to int.
// ///
bool isLosslesslyConvertableTo(const Type *Ty) const; bool isLosslesslyConvertableTo(const Type *Ty) const;
// Here are some useful little methods to query what type derived types are /// Here are some useful little methods to query what type derived types are
// Note that all other types can just compare to see if this == Type::xxxTy; /// Note that all other types can just compare to see if this == Type::xxxTy;
// ///
inline bool isPrimitiveType() const { return ID < FirstDerivedTyID; } inline bool isPrimitiveType() const { return ID < FirstDerivedTyID; }
inline bool isDerivedType() const { return ID >= FirstDerivedTyID; } inline bool isDerivedType() const { return ID >= FirstDerivedTyID; }
// isFirstClassType - Return true if the value is holdable in a register. /// isFirstClassType - Return true if the value is holdable in a register.
inline bool isFirstClassType() const { inline bool isFirstClassType() const {
return isPrimitiveType() || ID == PointerTyID; return isPrimitiveType() || ID == PointerTyID;
} }
// isSized - Return true if it makes sense to take the size of this type. To /// isSized - Return true if it makes sense to take the size of this type. To
// get the actual size for a particular target, it is reasonable to use the /// get the actual size for a particular target, it is reasonable to use the
// TargetData subsystem to do this. /// TargetData subsystem to do this.
// ///
bool isSized() const { bool isSized() const {
return ID != VoidTyID && ID != TypeTyID && return ID != VoidTyID && ID != TypeTyID &&
ID != FunctionTyID && ID != LabelTyID && ID != OpaqueTyID; ID != FunctionTyID && ID != LabelTyID && ID != OpaqueTyID;
} }
// getPrimitiveSize - Return the basic size of this type if it is a primative /// getPrimitiveSize - Return the basic size of this type if it is a primative
// type. These are fixed by LLVM and are not target dependant. This will /// type. These are fixed by LLVM and are not target dependant. This will
// return zero if the type does not have a size or is not a primitive type. /// return zero if the type does not have a size or is not a primitive type.
// ///
unsigned getPrimitiveSize() const; unsigned getPrimitiveSize() const;
@@ -188,15 +189,15 @@ public:
inline subtype_iterator subtype_begin() const; // DEFINED BELOW inline subtype_iterator subtype_begin() const; // DEFINED BELOW
inline subtype_iterator subtype_end() const; // DEFINED BELOW inline subtype_iterator subtype_end() const; // DEFINED BELOW
// getContainedType - This method is used to implement the type iterator /// getContainedType - This method is used to implement the type iterator
// (defined a the end of the file). For derived types, this returns the types /// (defined a the end of the file). For derived types, this returns the
// 'contained' in the derived type, returning 0 when 'i' becomes invalid. This /// types 'contained' in the derived type, returning 0 when 'i' becomes
// allows the user to iterate over the types in a struct, for example, really /// invalid. This allows the user to iterate over the types in a struct, for
// easily. /// example, really easily.
// ///
virtual const Type *getContainedType(unsigned i) const { return 0; } virtual const Type *getContainedType(unsigned i) const { return 0; }
// getNumContainedTypes - Return the number of types in the derived type /// getNumContainedTypes - Return the number of types in the derived type
virtual unsigned getNumContainedTypes() const { return 0; } virtual unsigned getNumContainedTypes() const { return 0; }
//===--------------------------------------------------------------------===// //===--------------------------------------------------------------------===//
@@ -204,7 +205,7 @@ public:
// instances of Type. // instances of Type.
// //
// getPrimitiveType/getUniqueIDType - Return a type based on an identifier. /// getPrimitiveType/getUniqueIDType - Return a type based on an identifier.
static const Type *getPrimitiveType(PrimitiveID IDNumber); static const Type *getPrimitiveType(PrimitiveID IDNumber);
static const Type *getUniqueIDType(unsigned UID); static const Type *getUniqueIDType(unsigned UID);
@@ -220,7 +221,7 @@ public:
static Type *TypeTy , *LabelTy; static Type *TypeTy , *LabelTy;
// Methods for support type inquiry through isa, cast, and dyn_cast: /// Methods for support type inquiry through isa, cast, and dyn_cast:
static inline bool classof(const Type *T) { return true; } static inline bool classof(const Type *T) { return true; }
static inline bool classof(const Value *V) { static inline bool classof(const Value *V) {
return V->getValueType() == Value::TypeVal; return V->getValueType() == Value::TypeVal;

View File

@@ -59,9 +59,9 @@ public:
Operands.clear(); Operands.clear();
} }
// replaceUsesOfWith - Replaces all references to the "From" definition with /// replaceUsesOfWith - Replaces all references to the "From" definition with
// references to the "To" definition. (defined in Value.cpp) /// references to the "To" definition.
// ///
void replaceUsesOfWith(Value *From, Value *To); void replaceUsesOfWith(Value *From, Value *To);
// Methods for support type inquiry through isa, cast, and dyn_cast: // Methods for support type inquiry through isa, cast, and dyn_cast:

View File

@@ -31,6 +31,9 @@ class SymbolTable;
// Value Class // Value Class
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
/// Value - The base class of all values computed by a program that may be used
/// as operands to other values.
///
class Value : public Annotable, // Values are annotable class Value : public Annotable, // Values are annotable
public AbstractTypeUser { // Values use potentially abstract types public AbstractTypeUser { // Values use potentially abstract types
public: public:
@@ -58,13 +61,16 @@ public:
Value(const Type *Ty, ValueTy vty, const std::string &name = ""); Value(const Type *Ty, ValueTy vty, const std::string &name = "");
virtual ~Value(); virtual ~Value();
// Support for debugging /// dump - Support for debugging, callable in GDB: V->dump()
//
void dump() const; void dump() const;
// Implement operator<< on Value... /// print - Implement operator<< on Value...
///
virtual void print(std::ostream &O) const = 0; virtual void print(std::ostream &O) const = 0;
// All values can potentially be typed /// All values are typed, get the type of this value.
///
inline const Type *getType() const { return Ty; } inline const Type *getType() const { return Ty; }
// All values can potentially be named... // All values can potentially be named...
@@ -75,27 +81,20 @@ public:
Name = name; Name = name;
} }
// Methods for determining the subtype of this Value. The getValueType() /// getValueType - Return the immediate subclass of this Value.
// method returns the type of the value directly. The cast*() methods are ///
// equivalent to using dynamic_cast<>... if the cast is successful, this is
// returned, otherwise you get a null pointer.
//
// The family of functions Val->cast<type>Asserting() is used in the same
// way as the Val->cast<type>() instructions, but they assert the expected
// type instead of checking it at runtime.
//
inline ValueTy getValueType() const { return VTy; } inline ValueTy getValueType() const { return VTy; }
// replaceAllUsesWith - Go through the uses list for this definition and make /// replaceAllUsesWith - Go through the uses list for this definition and make
// each use point to "D" instead of "this". After this completes, 'this's /// each use point to "V" instead of "this". After this completes, 'this's
// use list should be empty. /// use list is guaranteed to be empty.
// ///
void replaceAllUsesWith(Value *D); void replaceAllUsesWith(Value *V);
// refineAbstractType - This function is implemented because we use /// refineAbstractType - This function is implemented because we use
// potentially abstract types, and these types may be resolved to more /// potentially abstract types, and these types may be resolved to more
// concrete types after we are constructed. /// concrete types after we are constructed.
// ///
virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy); virtual void refineAbstractType(const DerivedType *OldTy, const Type *NewTy);
//---------------------------------------------------------------------- //----------------------------------------------------------------------