AaronBallman wrote: > I’m pretty sure our stance on this was that we very much _don’t_ want to > retain unrecognised attributes, but I don’t remember the exact reason. Iirc > @AaronBallman knows
I still have to give this more review, but this probably warrants an RFC. There's a *lot* of attributes in the wild we don't support and so I have no idea what this will do to memory overhead issues in Clang, particularly for attributes showing up in system headers. There are two scenarios, both with different amounts of concern: 1) No idea about this attribute, never seen it before. 2) I know about this attribute, you're using it wrong (or on the wrong target, etc) #2 is actually the significantly more problematic situation. We have a ton of code in the compiler that does things like `D->hasAttr<FooAttr>()` and presumes that if the semantic attribute is associated with the declaration, all is fine. We'd have to update *all* of those to do something more like `const auto *A = D->getAttr<FooAttr>(); A && A->isIgnoredButRetainedInTheAST()`, any uses through AST matchers would have to be updated, etc. So my stance is that we should never, ever support #2 by adding `FooAttr` into the AST, but it's fine to add an `UnknownAttr` into the AST in this case. For both cases, I would expect we'd add some sort of `ThisIsntReallyAnAttrAttr` AST node which wraps the thing we want to ignore. There's still a problem that we need to audit everywhere we do `D->hasAttrs()` and presume that means there are attributes applied, but I think that's a much more tractable problem. There are some open questions though: * Is this going to retain attributes we know about but are used incorrectly? e.g., `int x [[gnu::packed]]`; if yes, will this also happen for things which are implemented as attributes but spelled another way? e.g., `alignas` or `constinit`? * Are these to be treated as "real" attributes? e.g., if I write something on a primary template, does the instantiation get the unknown attribute as well? Are all unknown attributes on declarations inherited on redeclaration too? * Is an unknown type attribute a real type attribute? e.g., `_Generic(int, int [[unknown]] : 1, int : 2, default : 0)` is this ambiguous because `int` is effectively specified twice or is this well-defined and returns `2`? * What should happen for things like reflection? Does the declaration "have" the attribute if it's not one we support? * Does this include retaining invalid attributes? e.g., `[[12]]` * I assume this also handles things like `[[using unknown: whatever]]`, but how much information do we want to retain about the form the user spelled in source? e.g., do we want to distinguish between that and `[[unknown::whatever]]`? https://github.com/llvm/llvm-project/pull/209224 _______________________________________________ cfe-commits mailing list [email protected] https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits
