private:
// Important things that make up a function!
- BasicBlockListType BasicBlocks; ///< The basic blocks
- ArgumentListType ArgumentList; ///< The formal arguments
- ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
- ParamAttrsList *ParamAttrs; ///< Parameter attributes
- unsigned CallingConvention; ///< Calling convention to use
+ BasicBlockListType BasicBlocks; ///< The basic blocks
+ mutable ArgumentListType ArgumentList; ///< The formal arguments
+ ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
+ ParamAttrsList *ParamAttrs; ///< Parameter attributes
+
+ // The Calling Convention is stored in Value::SubclassData.
+ /*unsigned CallingConvention;*/
friend class SymbolTableListTraits<Function, Module>;
void setNext(Function *N) { Next = N; }
void setPrev(Function *N) { Prev = N; }
+ // getNext/Prev - Return the next or previous function in the list. These
+ // methods should never be used directly, and are only used to implement the
+ // function list as part of the module.
+ //
+ Function *getNext() { return Next; }
+ const Function *getNext() const { return Next; }
+ Function *getPrev() { return Prev; }
+ const Function *getPrev() const { return Prev; }
+
+ /// hasLazyArguments/CheckLazyArguments - The argument list of a function is
+ /// built on demand, so that the list isn't allocated until the first client
+ /// needs it. The hasLazyArguments predicate returns true if the arg list
+ /// hasn't been set up yet.
+ bool hasLazyArguments() const {
+ return SubclassData & 1;
+ }
+ void CheckLazyArguments() const {
+ if (hasLazyArguments())
+ BuildLazyArguments();
+ }
+ void BuildLazyArguments() const;
public:
/// Function ctor - If the (optional) Module argument is specified, the
/// function is automatically inserted into the end of the function list for
/// getCallingConv()/setCallingConv(uint) - These method get and set the
/// calling convention of this function. The enum values for the known
/// calling conventions are defined in CallingConv.h.
- unsigned getCallingConv() const { return CallingConvention; }
- void setCallingConv(unsigned CC) { CallingConvention = CC; }
-
+ unsigned getCallingConv() const { return SubclassData >> 1; }
+ void setCallingConv(unsigned CC) {
+ SubclassData = (SubclassData & 1) | (CC << 1);
+ }
+
/// Obtains a constant pointer to the ParamAttrsList object which holds the
/// parameter attributes information, if any.
/// @returns 0 if no parameter attributes have been set.
/// Sets the parameter attributes for this Function. To construct a
/// ParamAttrsList, see ParameterAttributes.h
/// @brief Set the parameter attributes.
- void setParamAttrs(ParamAttrsList *attrs) { ParamAttrs = attrs; }
+ void setParamAttrs(ParamAttrsList *attrs);
/// deleteBody - This method deletes the body of the function, and converts
/// the linkage to external.
void eraseFromParent();
- // getNext/Prev - Return the next or previous function in the list. These
- // methods should never be used directly, and are only used to implement the
- // function list as part of the module.
- //
- Function *getNext() { return Next; }
- const Function *getNext() const { return Next; }
- Function *getPrev() { return Prev; }
- const Function *getPrev() const { return Prev; }
-
/// Get the underlying elements of the Function... the basic block list is
/// empty for external functions.
///
- const ArgumentListType &getArgumentList() const { return ArgumentList; }
- ArgumentListType &getArgumentList() { return ArgumentList; }
+ const ArgumentListType &getArgumentList() const {
+ CheckLazyArguments();
+ return ArgumentList;
+ }
+ ArgumentListType &getArgumentList() {
+ CheckLazyArguments();
+ return ArgumentList;
+ }
const BasicBlockListType &getBasicBlockList() const { return BasicBlocks; }
BasicBlockListType &getBasicBlockList() { return BasicBlocks; }
//===--------------------------------------------------------------------===//
// Argument iterator forwarding functions
//
- arg_iterator arg_begin() { return ArgumentList.begin(); }
- const_arg_iterator arg_begin() const { return ArgumentList.begin(); }
- arg_iterator arg_end () { return ArgumentList.end(); }
- const_arg_iterator arg_end () const { return ArgumentList.end(); }
+ arg_iterator arg_begin() {
+ CheckLazyArguments();
+ return ArgumentList.begin();
+ }
+ const_arg_iterator arg_begin() const {
+ CheckLazyArguments();
+ return ArgumentList.begin();
+ }
+ arg_iterator arg_end() {
+ CheckLazyArguments();
+ return ArgumentList.end();
+ }
+ const_arg_iterator arg_end() const {
+ CheckLazyArguments();
+ return ArgumentList.end();
+ }
- size_t arg_size () const { return ArgumentList.size(); }
- bool arg_empty() const { return ArgumentList.empty(); }
+ size_t arg_size() const;
+ bool arg_empty() const;
virtual void print(std::ostream &OS) const { print(OS, 0); }
void print(std::ostream *OS) const { if (OS) print(*OS); }
static unsigned getBasicBlockListOffset() {
Function *Obj = 0;
- return reinterpret_cast<unsigned>(&Obj->BasicBlocks);
+ return unsigned(reinterpret_cast<uintptr_t>(&Obj->BasicBlocks));
}
static unsigned getArgumentListOffset() {
Function *Obj = 0;
- return reinterpret_cast<unsigned>(&Obj->ArgumentList);
+ return unsigned(reinterpret_cast<uintptr_t>(&Obj->ArgumentList));
}
};