Add methods to merge an AttrBuilder into another builder.
authorBill Wendling <isanbard@gmail.com>
Wed, 6 Feb 2013 01:16:00 +0000 (01:16 +0000)
committerBill Wendling <isanbard@gmail.com>
Wed, 6 Feb 2013 01:16:00 +0000 (01:16 +0000)
This is useful when parsing an object that references multiple attribute groups.

N.B. If both builders have alignments specified, then they should match!

llvm-svn: 174480

llvm/include/llvm/IR/Attributes.h
llvm/lib/IR/Attributes.cpp

index 83396e1..d0fe2e1 100644 (file)
@@ -373,6 +373,10 @@ public:
     addAttribute(A);
   }
   AttrBuilder(AttributeSet AS, unsigned Idx);
+  AttrBuilder(const AttrBuilder &B)
+    : Attrs(B.Attrs),
+      TargetDepAttrs(B.TargetDepAttrs.begin(), B.TargetDepAttrs.end()),
+      Alignment(B.Alignment), StackAlignment(B.StackAlignment) {}
 
   void clear();
 
@@ -394,6 +398,9 @@ public:
   /// \brief Remove the target-dependent attribute to the builder.
   AttrBuilder &removeAttribute(StringRef A);
 
+  /// \brief Add the attributes from the builder.
+  AttrBuilder &merge(const AttrBuilder &B);
+
   /// \brief Return true if the builder has the specified attribute.
   bool contains(Attribute::AttrKind A) const;
 
index dc1a657..67ab4ea 100644 (file)
@@ -956,6 +956,23 @@ AttrBuilder &AttrBuilder::addStackAlignmentAttr(unsigned Align) {
   return *this;
 }
 
+AttrBuilder &AttrBuilder::merge(const AttrBuilder &B) {
+  // FIXME: What if both have alignments, but they don't match?!
+  if (!Alignment)
+    Alignment = B.Alignment;
+
+  if (!StackAlignment)
+    StackAlignment = B.StackAlignment;
+
+  Attrs.insert(B.Attrs.begin(), B.Attrs.end());
+
+  for (td_const_iterator I = B.TargetDepAttrs.begin(),
+         E = B.TargetDepAttrs.end(); I != E; ++I)
+    TargetDepAttrs[I->first] = I->second;
+
+  return *this;
+}
+
 bool AttrBuilder::contains(Attribute::AttrKind A) const {
   return Attrs.count(A);
 }