unsigned NumAttrSets; ///< Number of entries in this set.
/// Available enum function attributes.
AttributeBitSet AvailableFunctionAttrs;
+ /// Union of enum attributes available at any index.
+ AttributeBitSet AvailableSomewhereAttrs;
// Helper fn for TrailingObjects class.
size_t numTrailingObjects(OverloadToken<AttributeSet>) { return NumAttrSets; }
return AvailableFunctionAttrs.hasAttribute(Kind);
}
+ /// Return true if the specified attribute is set for at least one
+ /// parameter or for the return value. If Index is not nullptr, the index
+ /// of a parameter with the specified attribute is provided.
+ bool hasAttrSomewhere(Attribute::AttrKind Kind,
+ unsigned *Index = nullptr) const;
+
using iterator = const AttributeSet *;
iterator begin() const { return getTrailingObjects<AttributeSet>(); }
// There's memory after the node where we can store the entries in.
llvm::copy(Sets, getTrailingObjects<AttributeSet>());
- // Initialize AvailableFunctionAttrs summary bitset.
+ // Initialize AvailableFunctionAttrs and AvailableSomewhereAttrs
+ // summary bitsets.
static_assert(attrIdxToArrayIdx(AttributeList::FunctionIndex) == 0U,
"function should be stored in slot 0");
- for (const auto &I : Sets[0]) {
+ for (const auto &I : Sets[0])
if (!I.isStringAttribute())
AvailableFunctionAttrs.addAttribute(I.getKindAsEnum());
- }
+
+ for (const auto &Set : Sets)
+ for (const auto &I : Set)
+ if (!I.isStringAttribute())
+ AvailableSomewhereAttrs.addAttribute(I.getKindAsEnum());
}
void AttributeListImpl::Profile(FoldingSetNodeID &ID) const {
ID.AddPointer(Set.SetNode);
}
+bool AttributeListImpl::hasAttrSomewhere(Attribute::AttrKind Kind,
+ unsigned *Index) const {
+ if (!AvailableSomewhereAttrs.hasAttribute(Kind))
+ return false;
+
+ if (Index) {
+ for (unsigned I = 0, E = NumAttrSets; I != E; ++I) {
+ if (begin()[I].hasAttribute(Kind)) {
+ *Index = I - 1;
+ break;
+ }
+ }
+ }
+
+ return true;
+}
+
+
#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
LLVM_DUMP_METHOD void AttributeListImpl::dump() const {
AttributeList(const_cast<AttributeListImpl *>(this)).dump();
bool AttributeList::hasAttrSomewhere(Attribute::AttrKind Attr,
unsigned *Index) const {
- if (!pImpl) return false;
-
- for (unsigned I = index_begin(), E = index_end(); I != E; ++I) {
- if (hasAttribute(I, Attr)) {
- if (Index)
- *Index = I;
- return true;
- }
- }
-
- return false;
+ return pImpl && pImpl->hasAttrSomewhere(Attr, Index);
}
Attribute AttributeList::getAttribute(unsigned Index,