#include "llvm/GlobalValue.h"
#include "llvm/BasicBlock.h"
#include "llvm/Argument.h"
+#include "llvm/ParameterAttributes.h"
#include "llvm/Support/Annotation.h"
namespace llvm {
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
-
+ BasicBlockListType BasicBlocks; ///< The basic blocks
+ mutable ArgumentListType ArgumentList; ///< The formal arguments
+ ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
+ const ParamAttrsList *ParamAttrs; ///< Parameter attributes
// The Calling Convention is stored in Value::SubclassData.
/*unsigned CallingConvention;*/
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 SubclassData; }
- void setCallingConv(unsigned CC) { SubclassData = 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);
+ void setParamAttrs(const ParamAttrsList *attrs);
+
+ /// hasCollector/getCollector/setCollector/clearCollector - The name of the
+ /// garbage collection algorithm to use during code generation.
+ bool hasCollector() const;
+ const char *getCollector() const;
+ void setCollector(const char *Str);
+ void clearCollector();
+
+ /// @brief Determine whether the function has the given attribute.
+ bool paramHasAttr(uint16_t i, ParameterAttributes attr) const {
+ return ParamAttrs && ParamAttrs->paramHasAttr(i, attr);
+ }
+
+ /// @brief Determine if the function cannot return.
+ bool isNoReturn() const {
+ return paramHasAttr(0, ParamAttr::NoReturn);
+ }
+
+ /// @brief Determine if the function cannot unwind.
+ bool isNoUnwind() const {
+ return paramHasAttr(0, ParamAttr::NoUnwind);
+ }
+
+ /// @brief Determine if the function does not access memory.
+ bool doesNotAccessMemory() const {
+ return paramHasAttr(0, ParamAttr::ReadNone);
+ }
+
+ /// @brief Determine if the function does not access or only reads memory.
+ bool onlyReadsMemory() const {
+ return doesNotAccessMemory() || paramHasAttr(0, ParamAttr::ReadOnly);
+ }
+
+ /// @brief Determine if the function returns a structure.
+ bool isStructReturn() const {
+ return paramHasAttr(1, ParamAttr::StructRet);
+ }
/// deleteBody - This method deletes the body of the function, and converts
/// the linkage to external.
/// removeFromParent - This method unlinks 'this' from the containing module,
/// but does not delete it.
///
- virtual void removeFromParent();
+ void removeFromParent();
/// eraseFromParent - This method unlinks 'this' from the containing module
/// and deletes it.
///
- virtual void eraseFromParent();
+ void eraseFromParent();
/// 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); }
Function *Obj = 0;
return unsigned(reinterpret_cast<uintptr_t>(&Obj->ArgumentList));
}
-private:
- // 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; }
};
inline ValueSymbolTable *