#ifndef LLVM_FUNCTION_H
#define LLVM_FUNCTION_H
-#include "llvm/GlobalValue.h"
-#include "llvm/CallingConv.h"
-#include "llvm/BasicBlock.h"
#include "llvm/Argument.h"
#include "llvm/Attributes.h"
+#include "llvm/BasicBlock.h"
+#include "llvm/CallingConv.h"
+#include "llvm/GlobalValue.h"
#include "llvm/Support/Compiler.h"
namespace llvm {
BasicBlockListType BasicBlocks; ///< The basic blocks
mutable ArgumentListType ArgumentList; ///< The formal arguments
ValueSymbolTable *SymTab; ///< Symbol table of args/instructions
- AttrListPtr AttributeList; ///< Parameter attributes
+ AttributeSet AttributeList; ///< Parameter attributes
// HasLazyArguments is stored in Value::SubclassData.
/*bool HasLazyArguments;*/
-
+
// The Calling Convention is stored in Value::SubclassData.
/*CallingConv::ID CallingConvention;*/
BuildLazyArguments();
}
void BuildLazyArguments() const;
-
- Function(const Function&); // DO NOT IMPLEMENT
- void operator=(const Function&); // DO NOT IMPLEMENT
+
+ Function(const Function&) LLVM_DELETED_FUNCTION;
+ void operator=(const Function&) LLVM_DELETED_FUNCTION;
/// Function ctor - If the (optional) Module argument is specified, the
/// function is automatically inserted into the end of the function list for
/// the module.
///
- Function(const FunctionType *Ty, LinkageTypes Linkage,
+ Function(FunctionType *Ty, LinkageTypes Linkage,
const Twine &N = "", Module *M = 0);
public:
- static Function *Create(const FunctionType *Ty, LinkageTypes Linkage,
+ static Function *Create(FunctionType *Ty, LinkageTypes Linkage,
const Twine &N = "", Module *M = 0) {
return new(0) Function(Ty, Linkage, N, M);
}
~Function();
- const Type *getReturnType() const; // Return the type of the ret val
- const FunctionType *getFunctionType() const; // Return the FunctionType for me
+ Type *getReturnType() const; // Return the type of the ret val
+ FunctionType *getFunctionType() const; // Return the FunctionType for me
- /// getContext - Return a pointer to the LLVMContext associated with this
+ /// getContext - Return a pointer to the LLVMContext associated with this
/// function, or NULL if this function is not bound to a context yet.
LLVMContext &getContext() const;
/// arguments.
bool isVarArg() const;
- /// isDeclaration - Is the body of this function unknown? (The basic block
- /// list is empty if so.) This is true for function declarations, but not
- /// true for function definitions.
- ///
- virtual bool isDeclaration() const { return BasicBlocks.empty(); }
-
/// getIntrinsicID - This method returns the ID number of the specified
/// function, or Intrinsic::not_intrinsic if the function is not an
/// instrinsic, or if the pointer is null. This value is always defined to be
/// The particular intrinsic functions which correspond to this value are
/// defined in llvm/Intrinsics.h.
///
- unsigned getIntrinsicID() const LLVM_ATTRIBUTE_READONLY;
- bool isIntrinsic() const { return getIntrinsicID() != 0; }
+ unsigned getIntrinsicID() const LLVM_READONLY;
+ bool isIntrinsic() const { return getName().startswith("llvm."); }
/// getCallingConv()/setCallingConv(CC) - These method get and set the
/// calling convention of this function. The enum values for the known
setValueSubclassData((getSubclassDataFromValue() & 1) |
(static_cast<unsigned>(CC) << 1));
}
-
+
/// getAttributes - Return the attribute list for this Function.
///
- const AttrListPtr &getAttributes() const { return AttributeList; }
+ const AttributeSet &getAttributes() const { return AttributeList; }
/// setAttributes - Set the attribute list for this Function.
///
- void setAttributes(const AttrListPtr &attrs) { AttributeList = attrs; }
-
- /// hasFnAttr - Return true if this function has the given attribute.
- bool hasFnAttr(Attributes N) const {
- // Function Attributes are stored at ~0 index
- return AttributeList.paramHasAttr(~0U, N);
- }
+ void setAttributes(const AttributeSet &attrs) { AttributeList = attrs; }
/// addFnAttr - Add function attributes to this function.
///
- void addFnAttr(Attributes N) {
- // Function Attributes are stored at ~0 index
- addAttribute(~0U, N);
+ void addFnAttr(Attribute::AttrKind N) {
+ // Function Attribute are stored at ~0 index
+ addAttribute(AttributeSet::FunctionIndex, Attribute::get(getContext(), N));
}
/// removeFnAttr - Remove function attributes from this function.
///
- void removeFnAttr(Attributes N) {
- // Function Attributes are stored at ~0 index
+ void removeFnAttr(Attribute N) {
+ // Function Attribute are stored at ~0 index
removeAttribute(~0U, N);
}
void setGC(const char *Str);
void clearGC();
- /// @brief Determine whether the function has the given attribute.
- bool paramHasAttr(unsigned i, Attributes attr) const {
- return AttributeList.paramHasAttr(i, attr);
+
+ /// getRetAttributes - Return the return attributes for querying.
+ Attribute getRetAttributes() const {
+ return AttributeList.getRetAttributes();
+ }
+
+ /// getParamAttributes - Return the parameter attributes for querying.
+ Attribute getParamAttributes(unsigned Idx) const {
+ return AttributeList.getParamAttributes(Idx);
}
/// addAttribute - adds the attribute to the list of attributes.
- void addAttribute(unsigned i, Attributes attr);
-
+ void addAttribute(unsigned i, Attribute attr);
+
/// removeAttribute - removes the attribute from the list of attributes.
- void removeAttribute(unsigned i, Attributes attr);
+ void removeAttribute(unsigned i, Attribute attr);
/// @brief Extract the alignment for a call or parameter (0=unknown).
unsigned getParamAlignment(unsigned i) const {
/// @brief Determine if the function does not access memory.
bool doesNotAccessMemory() const {
- return hasFnAttr(Attribute::ReadNone);
+ return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::ReadNone);
}
- void setDoesNotAccessMemory(bool DoesNotAccessMemory = true) {
- if (DoesNotAccessMemory) addFnAttr(Attribute::ReadNone);
- else removeFnAttr(Attribute::ReadNone);
+ void setDoesNotAccessMemory() {
+ addFnAttr(Attribute::ReadNone);
}
/// @brief Determine if the function does not access or only reads memory.
bool onlyReadsMemory() const {
- return doesNotAccessMemory() || hasFnAttr(Attribute::ReadOnly);
+ return doesNotAccessMemory() ||
+ AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::ReadOnly);
}
- void setOnlyReadsMemory(bool OnlyReadsMemory = true) {
- if (OnlyReadsMemory) addFnAttr(Attribute::ReadOnly);
- else removeFnAttr(Attribute::ReadOnly | Attribute::ReadNone);
+ void setOnlyReadsMemory() {
+ addFnAttr(Attribute::ReadOnly);
}
/// @brief Determine if the function cannot return.
bool doesNotReturn() const {
- return hasFnAttr(Attribute::NoReturn);
+ return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::NoReturn);
}
- void setDoesNotReturn(bool DoesNotReturn = true) {
- if (DoesNotReturn) addFnAttr(Attribute::NoReturn);
- else removeFnAttr(Attribute::NoReturn);
+ void setDoesNotReturn() {
+ addFnAttr(Attribute::NoReturn);
}
/// @brief Determine if the function cannot unwind.
bool doesNotThrow() const {
- return hasFnAttr(Attribute::NoUnwind);
+ return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::NoUnwind);
}
- void setDoesNotThrow(bool DoesNotThrow = true) {
- if (DoesNotThrow) addFnAttr(Attribute::NoUnwind);
- else removeFnAttr(Attribute::NoUnwind);
+ void setDoesNotThrow() {
+ addFnAttr(Attribute::NoUnwind);
}
- /// @brief Determine if the function returns a structure through first
+ /// @brief Determine if the call cannot be duplicated.
+ bool cannotDuplicate() const {
+ return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::NoDuplicate);
+ }
+ void setCannotDuplicate() {
+ addFnAttr(Attribute::NoDuplicate);
+ }
+
+ /// @brief True if the ABI mandates (or the user requested) that this
+ /// function be in a unwind table.
+ bool hasUWTable() const {
+ return AttributeList.hasAttribute(AttributeSet::FunctionIndex,
+ Attribute::UWTable);
+ }
+ void setHasUWTable() {
+ addFnAttr(Attribute::UWTable);
+ }
+
+ /// @brief True if this function needs an unwind table.
+ bool needsUnwindTableEntry() const {
+ return hasUWTable() || !doesNotThrow();
+ }
+
+ /// @brief Determine if the function returns a structure through first
/// pointer argument.
bool hasStructRetAttr() const {
- return paramHasAttr(1, Attribute::StructRet);
+ return getParamAttributes(1).hasAttribute(Attribute::StructRet);
}
/// @brief Determine if the parameter does not alias other parameters.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool doesNotAlias(unsigned n) const {
- return paramHasAttr(n, Attribute::NoAlias);
+ return getParamAttributes(n).hasAttribute(Attribute::NoAlias);
}
- void setDoesNotAlias(unsigned n, bool DoesNotAlias = true) {
- if (DoesNotAlias) addAttribute(n, Attribute::NoAlias);
- else removeAttribute(n, Attribute::NoAlias);
+ void setDoesNotAlias(unsigned n) {
+ addAttribute(n, Attribute::get(getContext(), Attribute::NoAlias));
}
/// @brief Determine if the parameter can be captured.
/// @param n The parameter to check. 1 is the first parameter, 0 is the return
bool doesNotCapture(unsigned n) const {
- return paramHasAttr(n, Attribute::NoCapture);
+ return getParamAttributes(n).hasAttribute(Attribute::NoCapture);
}
- void setDoesNotCapture(unsigned n, bool DoesNotCapture = true) {
- if (DoesNotCapture) addAttribute(n, Attribute::NoCapture);
- else removeAttribute(n, Attribute::NoCapture);
+ void setDoesNotCapture(unsigned n) {
+ addAttribute(n, Attribute::get(getContext(), Attribute::NoCapture));
}
/// copyAttributesFrom - copy all additional attributes (those not needed to
void viewCFGOnly() const;
/// Methods for support type inquiry through isa, cast, and dyn_cast:
- static inline bool classof(const Function *) { return true; }
static inline bool classof(const Value *V) {
return V->getValueID() == Value::FunctionVal;
}
void dropAllReferences();
/// hasAddressTaken - returns true if there are any uses of this function
- /// other than direct calls or invokes to it. Optionally passes back the
- /// offending user for diagnostic purposes.
+ /// other than direct calls or invokes to it, or blockaddress expressions.
+ /// Optionally passes back an offending user for diagnostic purposes.
///
bool hasAddressTaken(const User** = 0) const;
+ /// isDefTriviallyDead - Return true if it is trivially safe to remove
+ /// this function definition from the module (because it isn't externally
+ /// visible, does not have its address taken, and has no callers). To make
+ /// this more accurate, call removeDeadConstantUsers first.
+ bool isDefTriviallyDead() const;
+
+ /// callsFunctionThatReturnsTwice - Return true if the function has a call to
+ /// setjmp or other function that gcc recognizes as "returning twice".
+ bool callsFunctionThatReturnsTwice() const;
+
private:
// Shadow Value::setValueSubclassData with a private forwarding method so that
// subclasses cannot accidentally use it.