diff options
author | Duncan Sands <baldrick@free.fr> | 2007-11-30 18:19:18 +0000 |
---|---|---|
committer | Duncan Sands <baldrick@free.fr> | 2007-11-30 18:19:18 +0000 |
commit | 757d243167a52fef433146be11fa1462f6468270 (patch) | |
tree | aa3c16399f7b2fdb1556a69aef681da2ff8d4678 /lib/VMCore/Function.cpp | |
parent | a8b974648f9d8bacc43280653dc654c9120d05ca (diff) | |
download | external_llvm-757d243167a52fef433146be11fa1462f6468270.zip external_llvm-757d243167a52fef433146be11fa1462f6468270.tar.gz external_llvm-757d243167a52fef433146be11fa1462f6468270.tar.bz2 |
Add a convenience method for modifying parameter
attributes. While there, I noticed that not all
attribute methods returned a pointer-to-constant,
so I fixed that.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@44457 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/VMCore/Function.cpp')
-rw-r--r-- | lib/VMCore/Function.cpp | 60 |
1 files changed, 59 insertions, 1 deletions
diff --git a/lib/VMCore/Function.cpp b/lib/VMCore/Function.cpp index 92853e3..16728f6 100644 --- a/lib/VMCore/Function.cpp +++ b/lib/VMCore/Function.cpp @@ -167,7 +167,7 @@ ParamAttrsList::Profile(FoldingSetNodeID &ID) const { 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()) @@ -200,6 +200,64 @@ ParamAttrsList::get(const ParamAttrsVector &attrVec) { 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); } |