+ if (hasAttribute(Index, Attr)) return *this;
+ return addAttributes(C, Index, AttributeSet::get(C, Index, Attr));
+}
+
+AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index,
+ StringRef Kind) const {
+ llvm::AttrBuilder B;
+ B.addAttribute(Kind);
+ return addAttributes(C, Index, AttributeSet::get(C, Index, B));
+}
+
+AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Index,
+ StringRef Kind, StringRef Value) const {
+ llvm::AttrBuilder B;
+ B.addAttribute(Kind, Value);
+ return addAttributes(C, Index, AttributeSet::get(C, Index, B));
+}
+
+AttributeSet AttributeSet::addAttribute(LLVMContext &C,
+ ArrayRef<unsigned> Indices,
+ Attribute A) const {
+ unsigned I = 0, E = pImpl ? pImpl->getNumAttributes() : 0;
+ auto IdxI = Indices.begin(), IdxE = Indices.end();
+ SmallVector<AttributeSet, 4> AttrSet;
+
+ while (I != E && IdxI != IdxE) {
+ if (getSlotIndex(I) < *IdxI)
+ AttrSet.emplace_back(getSlotAttributes(I++));
+ else if (getSlotIndex(I) > *IdxI)
+ AttrSet.emplace_back(AttributeSet::get(C, std::make_pair(*IdxI++, A)));
+ else {
+ AttrBuilder B(getSlotAttributes(I), *IdxI);
+ B.addAttribute(A);
+ AttrSet.emplace_back(AttributeSet::get(C, *IdxI, B));
+ ++I;
+ ++IdxI;
+ }
+ }
+
+ while (I != E)
+ AttrSet.emplace_back(getSlotAttributes(I++));
+
+ while (IdxI != IdxE)
+ AttrSet.emplace_back(AttributeSet::get(C, std::make_pair(*IdxI++, A)));
+
+ return get(C, AttrSet);