================
@@ -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
----------------
uecker wrote:

The standard defines when things are compatible and it explicitly does not 
require attributes to match for types to be compatible (in general, this has 
not much to do with this proposal except that this general rule now also 
applies here).  In general, this proposal does not raise any new questions  
here (but extends the scope of such questions) and the answer to the question 
should be the same as elsewhere (e.g. as in typedef redefinitions, 
compatibility of function types). I would recommend to warn on redefinitions 
that add or remove standard attributes. For compatibility those should *not* 
matter.  For vendor attributes this up to you, of course and some attributes 
will certainly make types incompatible (e.g. "packed", here one can take a look 
at what you do for LTO because these things should already matter there).  For 
vendors attributes, the safe choice is to reject redefinitions. For 
compatibility, one has make a choice for each case, but it should be mostly 
obvious (does it change the representation?) 

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