================
@@ -450,6 +453,116 @@ class StmtComparer {
 };
 } // namespace
 
+static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
+                                     const Attr *Attr1, const Attr *Attr2) {
+  // Two attributes are structurally equivalent if they are the same kind
+  // of attribute, spelled with the same spelling kind, and have the same
+  // arguments. This means that [[noreturn]] and __attribute__((noreturn)) are
+  // not structurally equivalent, nor are [[nodiscard("foo")]] and
+  // [[nodiscard("bar")]].
+  if (Attr1->getKind() != Attr2->getKind())
+    return false;
+
+  if (Attr1->getSyntax() != Attr2->getSyntax())
+    return false;
+
+  if (Attr1->getSpellingListIndex() != Attr2->getSpellingListIndex())
+    return false;
+
+  auto GetAttrName = [](const Attr *A) {
+    if (const IdentifierInfo *II = A->getAttrName())
+      return II->getName();
+    return StringRef{};
+  };
+
+  if (GetAttrName(Attr1) != GetAttrName(Attr2))
+    return false;
+
+  // FIXME: check the attribute arguments. Attr does not track the arguments on
+  // the base class, which makes this awkward. We may want to tablegen a
+  // comparison function for attributes? In the meantime, we're doing this the
+  // cheap way by pretty printing the attributes and checking they produce
----------------
AaronBallman wrote:

> I am slightly uncomfortable using pretty printing, I mean theoretically we 
> usually don't consider pretty printing load bearing as such. This is probably 
> an ok short-term trade off but this feels potentially fragile.

Agreed, hence the FIXME. It's a temporary practical solution, but we don't have 
the underlying machinery to compare attribute arguments generically and that's 
far outside of the scope of this already large patch.

> Agreed. I also have design concerns. N3037 is silent on attributes.

Mismatched attributes are UB by omission, so I went with the most conservative 
model which is: all attributes have to be identical across objects to be 
structurally equivalent.

> ```
> struct S;
> struct [[deprecated]] S { // fine
>     int a;
> };
>```

Correct.

> ```
> struct S { // not fine?
>     [[deprecated]] int a; // not fine?
> };
> ```

Also correct.

https://github.com/llvm/llvm-project/pull/132939
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to