/// \brief Add the specified attribute at the specified index to this
/// attribute list. Since attribute lists are immutable, this returns the new
/// list.
- AttributeSet addAttr(LLVMContext &C, unsigned Idx, Attribute Attrs) const;
+ AttributeSet addAttr(LLVMContext &C, unsigned Idx, AttributeSet Attrs) const;
/// \brief Remove the specified attribute at the specified index from this
/// attribute list. Since attribute lists are immutable, this returns the new
AttributeSet Attrs) const;
//===--------------------------------------------------------------------===//
- // Attribute List Accessors
+ // Attribute Set Accessors
//===--------------------------------------------------------------------===//
/// \brief The attributes for the specified index are returned.
/// \brief The function attributes are returned.
AttributeSet getFnAttributes() const;
- /// \brief Return the alignment for the specified function parameter.
- unsigned getParamAlignment(unsigned Idx) const;
-
/// \brief Return true if the attribute exists at the given index.
- bool hasAttribute(unsigned Index, Attribute::AttrKind Kind) const;
+ bool hasAttribute(uint64_t Index, Attribute::AttrKind Kind) const;
/// \brief Return true if attribute exists at the given index.
- bool hasAttributes(unsigned Index) const;
+ bool hasAttributes(uint64_t Index) const;
- /// \brief Returns the alignment field of an attribute as a byte alignment
- /// value.
- unsigned getAlignment(unsigned Index) const;
+ /// \brief Return the alignment for the specified function parameter.
+ unsigned getParamAlignment(uint64_t Idx) const;
/// \brief Get the stack alignment.
- unsigned getStackAlignment(unsigned Index) const;
+ unsigned getStackAlignment(uint64_t Index) const;
/// \brief Return the attributes at the index as a string.
- std::string getAsString(unsigned Index) const;
+ std::string getAsString(uint64_t Index) const;
uint64_t Raw(unsigned Index) const;
/// \brief Remove an attribute from the builder.
AttrBuilder &removeAttribute(Attribute::AttrKind Val);
- /// \brief Add the attributes from A to the builder.
- AttrBuilder &addAttributes(const Attribute &A);
+ /// \brief Add the attributes to the builder.
+ AttrBuilder &addAttributes(Attribute A);
+
+ /// \brief Remove the attributes from the builder.
+ AttrBuilder &removeAttributes(Attribute A);
- /// \brief Remove the attributes from A from the builder.
- AttrBuilder &removeAttributes(const Attribute &A);
+ /// \brief Add the attributes to the builder.
+ AttrBuilder &addAttributes(AttributeSet A);
/// \brief Return true if the builder has the specified attribute.
bool contains(Attribute::AttrKind A) const;
return *this;
}
+AttrBuilder &AttrBuilder::addAttributes(Attribute Attr) {
+ uint64_t Mask = Attr.Raw();
+
+ for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
+ I = Attribute::AttrKind(I + 1))
+ if ((Mask & AttributeImpl::getAttrMask(I)) != 0)
+ Attrs.insert(I);
+
+ if (Attr.getAlignment())
+ Alignment = Attr.getAlignment();
+ if (Attr.getStackAlignment())
+ StackAlignment = Attr.getStackAlignment();
+ return *this;
+}
+
+AttrBuilder &AttrBuilder::removeAttributes(Attribute A) {
+ uint64_t Mask = A.Raw();
+
+ for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
+ I = Attribute::AttrKind(I + 1)) {
+ if (Mask & AttributeImpl::getAttrMask(I)) {
+ Attrs.erase(I);
+
+ if (I == Attribute::Alignment)
+ Alignment = 0;
+ else if (I == Attribute::StackAlignment)
+ StackAlignment = 0;
+ }
+ }
+
+ return *this;
+}
+
AttrBuilder &AttrBuilder::addAlignmentAttr(unsigned Align) {
if (Align == 0) return *this;
return *this;
}
-AttrBuilder &AttrBuilder::addAttributes(const Attribute &Attr) {
- uint64_t Mask = Attr.Raw();
-
- for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
- I = Attribute::AttrKind(I + 1))
- if ((Mask & AttributeImpl::getAttrMask(I)) != 0)
- Attrs.insert(I);
-
- if (Attr.getAlignment())
- Alignment = Attr.getAlignment();
- if (Attr.getStackAlignment())
- StackAlignment = Attr.getStackAlignment();
- return *this;
-}
-
-AttrBuilder &AttrBuilder::removeAttributes(const Attribute &A){
- uint64_t Mask = A.Raw();
-
- for (Attribute::AttrKind I = Attribute::None; I != Attribute::EndAttrKinds;
- I = Attribute::AttrKind(I + 1)) {
- if (Mask & AttributeImpl::getAttrMask(I)) {
- Attrs.erase(I);
-
- if (I == Attribute::Alignment)
- Alignment = 0;
- else if (I == Attribute::StackAlignment)
- StackAlignment = 0;
- }
- }
-
- return *this;
-}
-
bool AttrBuilder::contains(Attribute::AttrKind A) const {
return Attrs.count(A);
}
return pImpl->getSlotAttributes(Slot);
}
-bool AttributeSet::hasAttribute(unsigned Index, Attribute::AttrKind Kind) const{
+bool AttributeSet::hasAttribute(uint64_t Index, Attribute::AttrKind Kind) const{
return getAttributes(Index).hasAttribute(Kind);
}
-bool AttributeSet::hasAttributes(unsigned Index) const {
+bool AttributeSet::hasAttributes(uint64_t Index) const {
return getAttributes(Index).hasAttributes();
}
-std::string AttributeSet::getAsString(unsigned Index) const {
+std::string AttributeSet::getAsString(uint64_t Index) const {
return getAttributes(Index).getAsString();
}
-unsigned AttributeSet::getParamAlignment(unsigned Idx) const {
+unsigned AttributeSet::getParamAlignment(uint64_t Idx) const {
return getAttributes(Idx).getAlignment();
}
-unsigned AttributeSet::getStackAlignment(unsigned Index) const {
+unsigned AttributeSet::getStackAlignment(uint64_t Index) const {
return getAttributes(Index).getStackAlignment();
}
AttributeSet AttributeSet::addAttribute(LLVMContext &C, unsigned Idx,
Attribute::AttrKind Attr) const {
- return addAttr(C, Idx, Attribute::get(C, Attr));
+ return addAttr(C, Idx, AttributeSet::get(C, Idx, Attr));
}
AttributeSet AttributeSet::addAttributes(LLVMContext &C, unsigned Idx,
AttributeSet Attrs) const {
- return addAttr(C, Idx, Attrs.getAttributes(Idx));
+ return addAttr(C, Idx, Attrs);
}
AttributeSet AttributeSet::addAttr(LLVMContext &C, unsigned Idx,
- Attribute Attrs) const {
- Attribute OldAttrs = getAttributes(Idx);
+ AttributeSet Attrs) const {
+ if (!pImpl) return Attrs;
+ if (!Attrs.pImpl) return *this;
+
#ifndef NDEBUG
- // FIXME it is not obvious how this should work for alignment.
- // For now, say we can't change a known alignment.
- unsigned OldAlign = OldAttrs.getAlignment();
- unsigned NewAlign = Attrs.getAlignment();
+ // FIXME it is not obvious how this should work for alignment. For now, say
+ // we can't change a known alignment.
+ unsigned OldAlign = getParamAlignment(Idx);
+ unsigned NewAlign = Attrs.getParamAlignment(Idx);
assert((!OldAlign || !NewAlign || OldAlign == NewAlign) &&
"Attempt to change alignment!");
#endif
- AttrBuilder NewAttrs =
- AttrBuilder(OldAttrs).addAttributes(Attrs);
- if (NewAttrs == AttrBuilder(OldAttrs))
- return *this;
+ // Add the attribute slots before the one we're trying to add.
+ SmallVector<AttributeSet, 4> AttrSet;
+ uint64_t NumAttrs = pImpl->getNumAttributes();
+ AttributeSet AS;
+ uint64_t LastIndex = 0;
+ for (unsigned I = 0, E = NumAttrs; I != E; ++I) {
+ if (getSlotIndex(I) >= Idx) {
+ if (getSlotIndex(I) == Idx) AS = getSlotAttributes(LastIndex++);
+ break;
+ }
+ LastIndex = I + 1;
+ AttrSet.push_back(getSlotAttributes(I));
+ }
- SmallVector<AttributeWithIndex, 8> NewAttrList;
- if (pImpl == 0) {
- NewAttrList.push_back(AttributeWithIndex::get(Idx, Attrs));
- } else {
- ArrayRef<AttributeWithIndex> OldAttrList = pImpl->getAttributes();
- unsigned i = 0, e = OldAttrList.size();
-
- // Copy attributes for arguments before this one.
- for (; i != e && OldAttrList[i].Index < Idx; ++i)
- NewAttrList.push_back(OldAttrList[i]);
-
- // If there are attributes already at this index, merge them in.
- if (i != e && OldAttrList[i].Index == Idx) {
- Attrs =
- Attribute::get(C, AttrBuilder(Attrs).
- addAttributes(OldAttrList[i].Attrs));
- ++i;
+ // Now add the attribute into the correct slot. There may already be an
+ // AttributeSet there.
+ AttrBuilder B(AS, Idx);
+
+ for (unsigned I = 0, E = Attrs.pImpl->getNumAttributes(); I != E; ++I)
+ if (Attrs.getSlotIndex(I) == Idx) {
+ for (AttributeSetImpl::const_iterator II = Attrs.pImpl->begin(I),
+ IE = Attrs.pImpl->end(I); II != IE; ++II)
+ B.addAttributes(*II);
+ break;
}
- NewAttrList.push_back(AttributeWithIndex::get(Idx, Attrs));
+ AttrSet.push_back(AttributeSet::get(C, Idx, B));
- // Copy attributes for arguments after this one.
- NewAttrList.insert(NewAttrList.end(),
- OldAttrList.begin()+i, OldAttrList.end());
- }
+ // Add the remaining attribute slots.
+ for (unsigned I = LastIndex, E = NumAttrs; I < E; ++I)
+ AttrSet.push_back(getSlotAttributes(I));
- return get(C, NewAttrList);
+ return get(C, AttrSet);
}
AttributeSet AttributeSet::removeAttribute(LLVMContext &C, unsigned Idx,