================ @@ -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 ---------------- cor3ntin wrote:
Agreed. I also have design concerns. N3037 is silent on attributes. Should we maybe conservatively not allow redeclarations of entities relying on compiler extensions and such? The whole feature seems extremely brittle to maintain in the long run - and to test - so maybe an approach of limiting structural equivalence to things the standard mandates or are motivated by user request is preferable 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