This is an archive of the discontinued LLVM Phabricator instance.

Add `#pragma clang deprecated`, used to deprecate macros
Needs ReviewPublic

Authored by erik.pilkington on Sep 23 2019, 2:39 PM.

Details

Summary

This patch adds support for #pragma clang deprecated, which emits a deprecated warning whenever it is encountered. This is intended to be used to deprecate macros, but it seems like it could be useful for deprecating include files as well (rather than #warning). This is similar to #pragma GCC warning, but that can't emit a diagnostic under -Wdeprecated, so these warnings wouldn't be controlled by traditional deprecation disabling methods. (-Wno-deprecated, #pragma clang diagnostic ignored).

rdar://problem/50356322 clang should provide a pragma to allow us to deprecate macros

Diff Detail

Event Timeline

Herald added a project: Restricted Project. · View Herald TranscriptSep 23 2019, 2:39 PM
erik.pilkington planned changes to this revision.Sep 24 2019, 12:10 PM

Marking as "planned changes" to get this out of review queues. Aaron Ballman wants to add "macro attributes", which would be a better way of solving this problem, and is going to ask the C and C++ committees if there is an appetite for such an idea. This is blocked on getting that answer.

erik.pilkington requested review of this revision.Sep 1 2020, 5:33 PM

@aaron.ballman: Did you happen to get any feedback on macro attributes? There are a growing number of macros that we'd like to be able to deprecate, and having a workable solution would be useful for us.

@aaron.ballman: Did you happen to get any feedback on macro attributes? There are a growing number of macros that we'd like to be able to deprecate, and having a workable solution would be useful for us.

Thank you for bringing this back up! I've worked on a patch to add preprocessor attributes to clang but have set it aside because it feels like it may be an awkward fit because of attribute arguments -- for instance, the preprocessor has no type system or AST, so we track values for things with APValue objects and there is no string APValue type, so it would be a fair amount of work to support # [[deprecated("don't use baz")]] define BAZ, let alone the more esoteric situations for arbitrary attributes. Another issue is that the preprocessor is sometimes shared between C/C++ frontends and, say, a FORTRAN frontend, which could suddenly introduce a new feature into a FORTRAN compiler without extra work.

Based on all of that, I think we should go with your approach of using a #pragma as it does solve a problem and isn't quite as novel. However, I am wondering about the design a bit -- why are you using a string literal to supply the macro name? It's my understanding that all preprocessing directives are executed at the same phase of translation (so you don't have to worry about #define changing the behavior of #pragma or _Pragma), so I would have expected a design more like:

#define FOOBAR(x) whatever(x)
#pragma clang deprecated(FOOBAR, "don't use FOOBAR, it will do bad things")

This feels like a more approachable way to expose the feature, to me, but I wonder if I'm missing something.

Other feedback is: should we diagnose if the pp-token for the macro identifier doesn't actually match the name of a macro? Or are we allowing constructs like:

#pragma clang deprecated(FOOBAR, "don't use FOOBAR, twelve is a terrible number")
#define FOOBAR 12
clang/lib/Lex/Pragma.cpp
1544

Do we want to allow arbitrary string literals, or only narrow character string literals? e.g., should we disallow something like: #pragma clang deprecated(L"oops", U"hahahaha") ?

clang/test/Lexer/pragma-deprecated.c
17–20

What is the utility of unconditionally emitting a diagnostic like this? We've already got #warning.

marksl added a subscriber: marksl.Mar 23 2021, 9:42 AM