This can be used to display Fix-Its.
We only add this to GNU attributes. Since it now has two optional arguments, and the common parsing does not handle "replacement = ", we use custom parsing for DeprecatedAttr.
Details
Diff Detail
- Repository
- rL LLVM
Event Timeline
I like the idea of a potential fixit being provided by the attribute, but I do not agree with the way the feature is surfaced in this patch.
For the GNU-style attribute, the named argument functionality is sufficiently novel syntax that I would strongly like to avoid it, especially since attribute((deprecated)) is supported by multiple compilers.
We should not be adding this functionality to the C++-style attribute in the gnu namespace; that's not our vendor namespace to modify. I wouldn't be opposed to adding a clang namespace where we support this feature, however.
We definitely need to make sure we are not modifying the functionality for the C++ standards-based attribute, or the __declspec based attribute (for pretty printing, as well as parsing, etc).
So this change is missing a lot of tests to make sure we do not support this feature in places where it doesn't belong.
include/clang/Basic/Attr.td | ||
---|---|---|
716 ↗ | (On Diff #49768) | Would you mind adding some documentation to the attribute since we're changing it? |
lib/Parse/ParseDecl.cpp | ||
1048 ↗ | (On Diff #49768) | This also gets called for attributes parsed in the gnu:: namespace, which means that you are modifying the behavior of gnu::deprecated(), which we should not do unless GCC also supports this feature. |
1068 ↗ | (On Diff #49768) | I assume this was meant to do something useful? |
1070 ↗ | (On Diff #49768) | This now makes the attribute behave differently than __attribute__((deprecated)) because you can have this odd named-argument behavior. I would strongly prefer this be an actual optional parameter instead of using this approach. e.g., __attribute__((deprecated("", "fixit"))). |
lib/Sema/SemaDeclAttr.cpp | ||
5074 ↗ | (On Diff #49768) | This check should be moved above the extension warning above -- we only want to diagnose the extension if the attribute is actually applied. |
test/SemaCXX/cxx11-attr-print.cpp | ||
16 ↗ | (On Diff #49768) | This is a bug; we should not be hijacking the gnu attribute space. |
18 ↗ | (On Diff #49768) | I would like a test that verifies we don't print an empty fixit literal when using the C++14 [[deprecated]] attribute. Same for __declspec(deprecated). |
Hi Aaron,
Thanks for the review!
I like the idea of a potential fixit being provided by the attribute, but I do not agree with the way the feature is surfaced in this patch.
For the GNU-style attribute, the named argument functionality is sufficiently novel syntax that I would strongly like to avoid it, especially since attribute((deprecated)) is supported by multiple compilers.
I suggested replacement = "" mostly for its explicitness, especially when we already have an optional message argument "".
If a user only want to specify replacement without a message, we can say deprecated(replacement = "xxx")
With 'replacement =`, the user will need to specify an empty message.
But your concern makes sense too. We can support the following:
deprecated("xxx") --> a message
deprecated("xxx, "fixit") --> a message and a fixit
We should not be adding this functionality to the C++-style attribute in the gnu namespace; that's not our vendor namespace to modify.
I believe the patch currently does not change the C++-style attribute. Of course, I should add testing cases to verify.
I wouldn't be opposed to adding a clang namespace where we support this feature, however.
We definitely need to make sure we are not modifying the functionality for the C++ standards-based attribute
Is this ("the C++ standards-based attribute") the same as "the C++-style attribute" you mentioned above?
, or the declspec based attribute (for pretty printing, as well as parsing, etc).
Yes, I should add testing cases to make sure declspec is not changed at all with this patch.
So this change is missing a lot of tests to make sure we do not support this feature in places where it doesn't belong.
include/clang/Basic/Attr.td | ||
---|---|---|
716 ↗ | (On Diff #49768) | Yes, I should. |
lib/Parse/ParseDecl.cpp | ||
1048 ↗ | (On Diff #49768) | Yes, I will fix this. |
1068 ↗ | (On Diff #49768) | Yes, I should emit a diagnostic. |
lib/Sema/SemaDeclAttr.cpp | ||
5074 ↗ | (On Diff #49768) | Agree. |
test/SemaCXX/cxx11-attr-print.cpp | ||
16 ↗ | (On Diff #49768) | Yes, I will fix this. |
18 ↗ | (On Diff #49768) | Will do. |
I do like the explicit nature of this approach, but I'm worried about it being too novel. For instance, would this compel GCC to implement a similar parsing feature since they also support the deprecated attribute, that sort of thing. Also, it feels like a bit of an odd design in C and C++ since nothing else in the language supports argument passing by name like that (and I would really hate to see us use = blah only to find out that C++ someday standardizes on something different).
But your concern makes sense too. We can support the following:
deprecated("xxx") --> a message
deprecated("xxx, "fixit") --> a message and a fixit
I think this is the correct approach, even with multiple optional arguments.
We should not be adding this functionality to the C++-style attribute in the gnu namespace; that's not our vendor namespace to modify.
I believe the patch currently does not change the C++-style attribute. Of course, I should add testing cases to verify.
I believe the patch does change the C++-style attribute in the gnu namespace, as best I can tell. e.g., it would now allow: `[[gnu::deprecated("something", "a fixit")]]`. We need to be careful not to allow this unless GCC allows the same syntax, otherwise we are hijacking their vendor attribute namespace with something incompatible.
I wouldn't be opposed to adding a clang namespace where we support this feature, however.
We definitely need to make sure we are not modifying the functionality for the C++ standards-based attribute
Is this ("the C++ standards-based attribute") the same as "the C++-style attribute" you mentioned above?
This is talking about the C++14 [[deprecated]] attribute. We want to make sure we don't allow [[deprecated("foo", "fixit")]], which I don't think your patch does (but we should have tests ensuring it).
, or the declspec based attribute (for pretty printing, as well as parsing, etc).
Yes, I should add testing cases to make sure declspec is not changed at all with this patch.So this change is missing a lot of tests to make sure we do not support this feature in places where it doesn't belong.
I do like the explicit nature of this approach, but I'm worried about it being too novel. For instance, would this compel GCC to implement a similar parsing feature since they also support the deprecated attribute, that sort of thing. Also, it feels like a bit of an odd design in C and C++ since nothing else in the language supports argument passing by name like that (and I would really hate to see us use = blah only to find out that C++ someday standardizes on something different).
This makes sense to me. We also want to add this to the "availability" attribute, and since that already uses named arguments, I think we should use the "replacement=" syntax there.
Uploading a new patch addressing Aaron's comments:
1> Add an optional string argument for fix-it, instead of the original proposal of named argument Replacement = "xxx"
This actually simplifies the patch a lot
2> Add testing cases to make sure we don't accept a fix-it argument for declspec, c++11 attribute, gnu namespace attribute
3> Change AST printing to make sure we only dump the fix-it argument for gnu style attribute
Cheers,
Manman
utils/TableGen/ClangAttrEmitter.cpp | ||
---|---|---|
1234 ↗ | (On Diff #50374) | This does not look pretty. Maybe we can implement a function writeDeprecatedValue that can skip the second argument if it is empty? |
include/clang/Basic/Attr.td | ||
---|---|---|
726 ↗ | (On Diff #50374) | The formatting here is a bit strange. |
lib/Sema/SemaDeclAttr.cpp | ||
5143 ↗ | (On Diff #50374) | This should move back down below the extension warning (the effect is the same, but logically we want to warn before attaching). |
utils/TableGen/ClangAttrEmitter.cpp | ||
1234 ↗ | (On Diff #50374) | I wouldn't be opposed to that approach; we already do it for writeAvailabilityValue(), so another one for deprecated wouldn't be that horrible. |
Hi Aaron,
Which document are you referring to? "include/clang/Basic/AttrDocs.td"?
We don't have a section for DeprecatedAttr, should I start one?
Cheers,
Manman
Yes, AttrDocs.td that you then reference in to Attr.td.
We don't have a section for DeprecatedAttr, should I start one?
Yes, please! We used to get away with relying on GCC to document the attribute, so now that we're adding Clang-specific behavior, we should bite the bullet and document the attribute properly. :-)
Thanks!
One small documentation nit, but I'm fine with you fixing it then committing (no need for another round of review). Thanks!
include/clang/Basic/AttrDocs.td | ||
---|---|---|
2189 ↗ | (On Diff #50682) | "When spelled as `__attribute__((deprecated))`, the deprecated attribute can..." "Otherwise, when spelled as `[[gnu::deprecated]] or [[deprecated]]`, the attribute can have one optional string argument which is the message to display when emitting the warning." |