Add a convenience method for modifying parameter
authorDuncan Sands <baldrick@free.fr>
Fri, 30 Nov 2007 18:19:18 +0000 (18:19 +0000)
committerDuncan Sands <baldrick@free.fr>
Fri, 30 Nov 2007 18:19:18 +0000 (18:19 +0000)
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

include/llvm/ParameterAttributes.h
lib/AsmParser/llvmAsmParser.y
lib/VMCore/Function.cpp
tools/llvm-upgrade/UpgradeParser.y

index 79b5d0c2a61bf6eb6f7acea291eec6bc35995b29..29bbd23abc172004d3f8ef92461a54ec884a0d9c 100644 (file)
@@ -130,13 +130,24 @@ class ParamAttrsList : public FoldingSetNode {
       : 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.
index 683b95b8fbaf553236104cf67af3833aa1652d08..31fd6190827d9530ee23ae3b27e0799c16225f88 100644 (file)
@@ -2243,7 +2243,7 @@ FunctionHeaderH : OptCallingConv ResultTypes GlobalName '(' ArgList ')'
   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);
 
@@ -2645,7 +2645,7 @@ BBTerminatorInst : RET ResolvedVal {              // Return with a result...
         GEN_ERROR("Invalid number of parameters detected");
     }
 
-    ParamAttrsList *PAL = 0;
+    const ParamAttrsList *PAL = 0;
     if (!Attrs.empty())
       PAL = ParamAttrsList::get(Attrs);
 
@@ -2977,7 +2977,7 @@ InstVal : ArithmeticOps Types ValueRef ',' ValueRef {
     }
 
     // Finish off the ParamAttrs and check them
-    ParamAttrsList *PAL = 0;
+    const ParamAttrsList *PAL = 0;
     if (!Attrs.empty())
       PAL = ParamAttrsList::get(Attrs);
 
index 92853e30f9b78dd17c21f466a2dd03b8f331de66..16728f6a0ca994628a2b345cd9a7e9744f6a2b37 100644 (file)
@@ -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);
 }
index b9a26cb95726ec043c2df2e79463df41bf2cbc41..7a6e3efc7b0b36056c379606343774c95c02a5b8 100644 (file)
@@ -2055,7 +2055,7 @@ UpRTypes
     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;