+void Verifier::VerifyAttributeTypes(AttributeSet Attrs, unsigned Idx,
+ bool isFunction, const Value* V) {
+ unsigned Slot = ~0U;
+ for (unsigned I = 0, E = Attrs.getNumSlots(); I != E; ++I)
+ if (Attrs.getSlotIndex(I) == Idx) {
+ Slot = I;
+ break;
+ }
+
+ assert(Slot != ~0U && "Attribute set inconsistency!");
+
+ for (AttributeSet::iterator I = Attrs.begin(Slot), E = Attrs.end(Slot);
+ I != E; ++I) {
+ if (I->isStringAttribute())
+ continue;
+
+ if (I->getKindAsEnum() == Attribute::NoReturn ||
+ I->getKindAsEnum() == Attribute::NoUnwind ||
+ I->getKindAsEnum() == Attribute::ReadNone ||
+ I->getKindAsEnum() == Attribute::ReadOnly ||
+ I->getKindAsEnum() == Attribute::NoInline ||
+ I->getKindAsEnum() == Attribute::AlwaysInline ||
+ I->getKindAsEnum() == Attribute::OptimizeForSize ||
+ I->getKindAsEnum() == Attribute::StackProtect ||
+ I->getKindAsEnum() == Attribute::StackProtectReq ||
+ I->getKindAsEnum() == Attribute::StackProtectStrong ||
+ I->getKindAsEnum() == Attribute::NoRedZone ||
+ I->getKindAsEnum() == Attribute::NoImplicitFloat ||
+ I->getKindAsEnum() == Attribute::Naked ||
+ I->getKindAsEnum() == Attribute::InlineHint ||
+ I->getKindAsEnum() == Attribute::StackAlignment ||
+ I->getKindAsEnum() == Attribute::UWTable ||
+ I->getKindAsEnum() == Attribute::NonLazyBind ||
+ I->getKindAsEnum() == Attribute::ReturnsTwice ||
+ I->getKindAsEnum() == Attribute::SanitizeAddress ||
+ I->getKindAsEnum() == Attribute::SanitizeThread ||
+ I->getKindAsEnum() == Attribute::SanitizeMemory ||
+ I->getKindAsEnum() == Attribute::MinSize ||
+ I->getKindAsEnum() == Attribute::NoDuplicate ||
+ I->getKindAsEnum() == Attribute::NoBuiltin ||
+ I->getKindAsEnum() == Attribute::Cold) {
+ if (!isFunction)
+ CheckFailed("Attribute '" + I->getAsString() +
+ "' only applies to functions!", V);
+ return;
+ } else if (isFunction) {
+ CheckFailed("Attribute '" + I->getAsString() +
+ "' does not apply to functions!", V);
+ return;
+ }
+ }
+}
+