================
@@ -451,6 +452,119 @@ class StmtComparer {
};
} // namespace
+namespace {
+enum class AttrComparisonKind { Equal, NotEqual };
+
+/// Represents the result of comparing the attribute sets on two decls. If the
+/// sets are incompatible, A1/A2 point to the offending attributes.
+struct AttrComparisonResult {
+ AttrComparisonKind Kind = AttrComparisonKind::Equal;
+ const Attr *A1 = nullptr, *A2 = nullptr;
+};
+} // namespace
+
+static AttrComparisonResult
+areAvailabilityAttrsEqual(const AvailabilityAttr *A1,
+ const AvailabilityAttr *A2) {
+ if (A1->getPlatform() == A2->getPlatform() &&
+ A1->getIntroduced() == A2->getIntroduced() &&
+ A1->getDeprecated() == A2->getDeprecated() &&
+ A1->getObsoleted() == A2->getObsoleted() &&
+ A1->getUnavailable() == A2->getUnavailable() &&
+ A1->getMessage() == A2->getMessage() &&
+ A1->getReplacement() == A2->getReplacement() &&
+ A1->getStrict() == A2->getStrict() &&
+ A1->getPriority() == A2->getPriority() &&
+ A1->getEnvironment() == A2->getEnvironment())
+ return {AttrComparisonKind::Equal};
+ return {AttrComparisonKind::NotEqual, A1, A2};
+}
+
+static AttrComparisonResult
+areEnumExtensibilityAttrsEqual(const EnumExtensibilityAttr *A1,
+ const EnumExtensibilityAttr *A2) {
+ if (A1->getExtensibility() == A2->getExtensibility())
+ return {AttrComparisonKind::Equal};
+ return {AttrComparisonKind::NotEqual, A1, A2};
+}
+
+static AttrComparisonResult areAttrsEqual(const Attr *A1, const Attr *A2) {
+ auto Kind1 = A1->getKind(), Kind2 = A2->getKind();
+ if (Kind1 != Kind2)
+ return {AttrComparisonKind::NotEqual, A1, A2};
+
+ switch (Kind1) {
+ case attr::Availability:
+ return areAvailabilityAttrsEqual(cast<AvailabilityAttr>(A1),
+ cast<AvailabilityAttr>(A2));
+ case attr::EnumExtensibility:
+ return areEnumExtensibilityAttrsEqual(cast<EnumExtensibilityAttr>(A1),
+ cast<EnumExtensibilityAttr>(A2));
+ case attr::Unused:
+ return {AttrComparisonKind::Equal};
+ default:
+ llvm_unreachable("unexpected attr kind");
+ }
+}
+
+static bool compareAttrKind(const Attr *A1, const Attr *A2) {
+ return A1->getKind() < A2->getKind();
+}
+
+namespace {
+using AttrSet = std::multiset<const Attr *, decltype(&compareAttrKind)>;
----------------
AaronBallman wrote:
Would a `SmallPtrSet` make more sense?
https://github.com/llvm/llvm-project/pull/168769
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits