================ @@ -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