diff --git a/include/llvm/Function.h b/include/llvm/Function.h index 4cfb6761cce..101de8ac3c2 100644 --- a/include/llvm/Function.h +++ b/include/llvm/Function.h @@ -26,6 +26,7 @@ namespace llvm { class FunctionType; +class ParamAttrsList; // Traits for intrusive list of instructions... template<> struct ilist_traits @@ -60,11 +61,11 @@ public: private: // Important things that make up a function! - BasicBlockListType BasicBlocks; // The basic blocks - ArgumentListType ArgumentList; // The formal arguments - - ValueSymbolTable *SymTab; - unsigned CallingConvention; + 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 friend class SymbolTableListTraits; @@ -111,6 +112,17 @@ public: unsigned getCallingConv() const { return CallingConvention; } void setCallingConv(unsigned CC) { CallingConvention = CC; } + /// 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. + /// @brief Get the parameter attributes. + const ParamAttrsList *getParamAttrs() const { return ParamAttrs; } + + /// 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; } + /// deleteBody - This method deletes the body of the function, and converts /// the linkage to external. /// diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 337ae2a463b..a25dd128ef2 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -26,6 +26,7 @@ class PointerType; class VectorType; class ConstantRange; class APInt; +class ParamAttrsList; //===----------------------------------------------------------------------===// // AllocationInst Class @@ -694,6 +695,7 @@ public: /// hold the calling convention of the call. /// class CallInst : public Instruction { + ParamAttrsList *ParamAttrs; ///< parameter attributes for call CallInst(const CallInst &CI); void init(Value *Func, Value* const *Params, unsigned NumParams); void init(Value *Func, Value *Actual1, Value *Actual2); @@ -735,6 +737,16 @@ public: SubclassData = (SubclassData & 1) | (CC << 1); } + /// Obtains a constant pointer to the ParamAttrsList object which holds the + /// parameter attributes information, if any. + /// @brief Get the parameter attributes. + const ParamAttrsList *getParamAttrs() const { return ParamAttrs; } + + /// Sets the parameter attributes for this CallInst. To construct a + /// ParamAttrsList, see ParameterAttributes.h + /// @brief Set the parameter attributes. + void setParamAttrs(ParamAttrsList *attrs) { ParamAttrs = attrs; } + /// getCalledFunction - Return the function being called by this instruction /// if it is a direct call. If it is a call through a function pointer, /// return null. diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 5da3cebb069..c6bf331ccb2 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -71,6 +71,69 @@ void Argument::setParent(Function *parent) { LeakDetector::removeGarbageObject(this); } +//===----------------------------------------------------------------------===// +// ParamAttrsList Implementation +//===----------------------------------------------------------------------===// + +uint16_t +ParamAttrsList::getParamAttrs(uint16_t Index) const { + unsigned limit = attrs.size(); + for (unsigned i = 0; i < limit; ++i) + if (attrs[i].index == Index) + return attrs[i].attrs; + return NoAttributeSet; +} + + +std::string +ParamAttrsList::getParamAttrsText(uint16_t Attrs) { + std::string Result; + if (Attrs & ZExtAttribute) + Result += "zext "; + if (Attrs & SExtAttribute) + Result += "sext "; + if (Attrs & NoReturnAttribute) + Result += "noreturn "; + if (Attrs & NoUnwindAttribute) + Result += "nounwind "; + if (Attrs & InRegAttribute) + Result += "inreg "; + if (Attrs & StructRetAttribute) + Result += "sret "; + return Result; +} + +void +ParamAttrsList::addAttributes(uint16_t Index, uint16_t Attrs) { + // First, try to replace an existing one + for (unsigned i = 0; i < attrs.size(); ++i) + if (attrs[i].index == Index) { + attrs[i].attrs |= Attrs; + return; + } + + // If not found, add a new one + ParamAttrsWithIndex Val; + Val.attrs = Attrs; + Val.index = Index; + attrs.push_back(Val); +} + +void +ParamAttrsList::removeAttributes(uint16_t Index, uint16_t Attrs) { + // Find the index from which to remove the attributes + for (unsigned i = 0; i < attrs.size(); ++i) + if (attrs[i].index == Index) { + attrs[i].attrs &= ~Attrs; + if (attrs[i].attrs == NoAttributeSet) + attrs.erase(&attrs[i]); + return; + } + + // The index wasn't found above + assert(0 && "Index not found for removeAttributes"); +} + //===----------------------------------------------------------------------===// // Function Implementation //===----------------------------------------------------------------------===// @@ -78,6 +141,7 @@ void Argument::setParent(Function *parent) { Function::Function(const FunctionType *Ty, LinkageTypes Linkage, const std::string &name, Module *ParentModule) : GlobalValue(PointerType::get(Ty), Value::FunctionVal, 0, 0, Linkage, name) { + ParamAttrs = 0; CallingConvention = 0; BasicBlocks.setItemParent(this); BasicBlocks.setParent(this); diff --git a/lib/VMCore/Instructions.cpp b/lib/VMCore/Instructions.cpp index c7da56b96ff..c09ec3ce217 100644 --- a/lib/VMCore/Instructions.cpp +++ b/lib/VMCore/Instructions.cpp @@ -188,6 +188,7 @@ CallInst::~CallInst() { } void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) { + ParamAttrs = 0; NumOperands = NumParams+1; Use *OL = OperandList = new Use[NumParams+1]; OL[0].init(Func, this); @@ -208,6 +209,7 @@ void CallInst::init(Value *Func, Value* const *Params, unsigned NumParams) { } void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) { + ParamAttrs = 0; NumOperands = 3; Use *OL = OperandList = new Use[3]; OL[0].init(Func, this); @@ -230,6 +232,7 @@ void CallInst::init(Value *Func, Value *Actual1, Value *Actual2) { } void CallInst::init(Value *Func, Value *Actual) { + ParamAttrs = 0; NumOperands = 2; Use *OL = OperandList = new Use[2]; OL[0].init(Func, this); @@ -248,6 +251,7 @@ void CallInst::init(Value *Func, Value *Actual) { } void CallInst::init(Value *Func) { + ParamAttrs = 0; NumOperands = 1; Use *OL = OperandList = new Use[1]; OL[0].init(Func, this); diff --git a/lib/VMCore/Type.cpp b/lib/VMCore/Type.cpp index 40bcdb2adc0..0e74f2e4f89 100644 --- a/lib/VMCore/Type.cpp +++ b/lib/VMCore/Type.cpp @@ -1121,65 +1121,6 @@ bool FunctionType::isStructReturn() const { return false; } -uint16_t -ParamAttrsList::getParamAttrs(uint16_t Index) const { - unsigned limit = attrs.size(); - for (unsigned i = 0; i < limit; ++i) - if (attrs[i].index == Index) - return attrs[i].attrs; - return NoAttributeSet; -} - - -std::string -ParamAttrsList::getParamAttrsText(uint16_t Attrs) { - std::string Result; - if (Attrs & ZExtAttribute) - Result += "zext "; - if (Attrs & SExtAttribute) - Result += "sext "; - if (Attrs & NoReturnAttribute) - Result += "noreturn "; - if (Attrs & NoUnwindAttribute) - Result += "nounwind "; - if (Attrs & InRegAttribute) - Result += "inreg "; - if (Attrs & StructRetAttribute) - Result += "sret "; - return Result; -} - -void -ParamAttrsList::addAttributes(uint16_t Index, uint16_t Attrs) { - // First, try to replace an existing one - for (unsigned i = 0; i < attrs.size(); ++i) - if (attrs[i].index == Index) { - attrs[i].attrs |= Attrs; - return; - } - - // If not found, add a new one - ParamAttrsWithIndex Val; - Val.attrs = Attrs; - Val.index = Index; - attrs.push_back(Val); -} - -void -ParamAttrsList::removeAttributes(uint16_t Index, uint16_t Attrs) { - // Find the index from which to remove the attributes - for (unsigned i = 0; i < attrs.size(); ++i) - if (attrs[i].index == Index) { - attrs[i].attrs &= ~Attrs; - if (attrs[i].attrs == NoAttributeSet) - attrs.erase(&attrs[i]); - return; - } - - // The index wasn't found above - assert(0 && "Index not found for removeAttributes"); -} - //===----------------------------------------------------------------------===// // Array Type Factory... //