: attrs(attrVec), refCount(0) {}
public:
- /// This method ensures the uniqueness of ParamAttrsList instances. The
+ /// This method ensures the uniqueness of ParamAttrsList instances. The
/// argument is a vector of attribute/index pairs as represented by the
- /// ParamAttrsWithIndex structure. The vector is used in the construction of
- /// the ParamAttrsList instance. If an instance with identical vector pairs
- /// exists, it will be returned instead of creating a new instance.
+ /// ParamAttrsWithIndex structure. The index values must be in strictly
+ /// increasing order and ParamAttr::None is not allowed. The vector is
+ /// used to construct the ParamAttrsList instance. If an instance with
+ /// identical vector pairs exists, it will be returned instead of creating
+ /// a new instance.
/// @brief Get a ParamAttrsList instance.
- static ParamAttrsList *get(const ParamAttrsVector &attrVec);
+ static const ParamAttrsList *get(const ParamAttrsVector &attrVec);
+
+ /// Returns the ParamAttrsList obtained by modifying PAL using the supplied
+ /// list of attribute/index pairs. Any existing attributes for the given
+ /// index are replaced by the given attributes. If there were no attributes
+ /// then the new ones are inserted. Attributes can be deleted by replacing
+ /// them with ParamAttr::None. Index values must be strictly increasing.
+ /// @brief Get a new ParamAttrsList instance by modifying an existing one.
+ static const ParamAttrsList *getModified(const ParamAttrsList *PAL,
+ const ParamAttrsVector &modVec);
/// Returns whether each of the specified lists of attributes can be safely
/// replaced with the other in a function or a function call.
bool isVarArg = ParamTypeList.size() && ParamTypeList.back() == Type::VoidTy;
if (isVarArg) ParamTypeList.pop_back();
- ParamAttrsList *PAL = 0;
+ const ParamAttrsList *PAL = 0;
if (!Attrs.empty())
PAL = ParamAttrsList::get(Attrs);
GEN_ERROR("Invalid number of parameters detected");
}
- ParamAttrsList *PAL = 0;
+ const ParamAttrsList *PAL = 0;
if (!Attrs.empty())
PAL = ParamAttrsList::get(Attrs);
}
// Finish off the ParamAttrs and check them
- ParamAttrsList *PAL = 0;
+ const ParamAttrsList *PAL = 0;
if (!Attrs.empty())
PAL = ParamAttrsList::get(Attrs);
static ManagedStatic<FoldingSet<ParamAttrsList> > ParamAttrsLists;
-ParamAttrsList *
+const ParamAttrsList *
ParamAttrsList::get(const ParamAttrsVector &attrVec) {
// If there are no attributes then return a null ParamAttrsList pointer.
if (attrVec.empty())
return PAL;
}
+const ParamAttrsList *
+ParamAttrsList::getModified(const ParamAttrsList *PAL,
+ const ParamAttrsVector &modVec) {
+ if (modVec.empty())
+ return PAL;
+
+#ifndef NDEBUG
+ for (unsigned i = 0, e = modVec.size(); i < e; ++i)
+ assert((!i || modVec[i-1].index < modVec[i].index)
+ && "Misordered ParamAttrsList!");
+#endif
+
+ if (!PAL) {
+ // Strip any instances of ParamAttr::None from modVec before calling 'get'.
+ ParamAttrsVector newVec;
+ for (unsigned i = 0, e = modVec.size(); i < e; ++i)
+ if (modVec[i].attrs != ParamAttr::None)
+ newVec.push_back(modVec[i]);
+ return get(newVec);
+ }
+
+ const ParamAttrsVector &oldVec = PAL->attrs;
+
+ ParamAttrsVector newVec;
+ unsigned oldI = 0;
+ unsigned modI = 0;
+ unsigned oldE = oldVec.size();
+ unsigned modE = modVec.size();
+
+ while (oldI < oldE && modI < modE) {
+ uint16_t oldIndex = oldVec[oldI].index;
+ uint16_t modIndex = modVec[modI].index;
+
+ if (oldIndex < modIndex) {
+ newVec.push_back(oldVec[oldI]);
+ ++oldI;
+ } else if (modIndex < oldIndex) {
+ if (modVec[modI].attrs != ParamAttr::None)
+ newVec.push_back(modVec[modI]);
+ ++modI;
+ } else {
+ // Same index - overwrite or delete existing attributes.
+ if (modVec[modI].attrs != ParamAttr::None)
+ newVec.push_back(modVec[modI]);
+ ++oldI;
+ ++modI;
+ }
+ }
+
+ for (; oldI < oldE; ++oldI)
+ newVec.push_back(oldVec[oldI]);
+ for (; modI < modE; ++modI)
+ if (modVec[modI].attrs != ParamAttr::None)
+ newVec.push_back(modVec[modI]);
+
+ return get(newVec);
+}
+
ParamAttrsList::~ParamAttrsList() {
ParamAttrsLists->RemoveNode(this);
}
bool isVarArg = Params.size() && Params.back() == Type::VoidTy;
if (isVarArg) Params.pop_back();
- ParamAttrsList *PAL = 0;
+ const ParamAttrsList *PAL = 0;
if (lastCallingConv == OldCallingConv::CSRet) {
ParamAttrsVector Attrs;
ParamAttrsWithIndex PAWI;