Skip to content

Commit

Permalink
[Wdocumentation] Use C2x/C++14 deprecated attribute
Browse files Browse the repository at this point in the history
This replaces the non-standard __attribute__((deprecated)) with the
standard [[deprecated]] when compiling in C2x/C++14 mode.

Discovered while looking at https://bugs.llvm.org/show_bug.cgi?id=43753

Differential Revision: https://reviews.llvm.org/D71141
  • Loading branch information
mordante committed Dec 10, 2019
1 parent b972f2d commit b6d386f
Show file tree
Hide file tree
Showing 4 changed files with 86 additions and 24 deletions.
37 changes: 27 additions & 10 deletions clang/lib/AST/CommentSema.cpp
Expand Up @@ -688,17 +688,34 @@ void Sema::checkDeprecatedCommand(const BlockCommandComment *Command) {
FD->doesThisDeclarationHaveABody())
return;

StringRef AttributeSpelling = "__attribute__((deprecated))";
const LangOptions &LO = FD->getASTContext().getLangOpts();
const bool DoubleSquareBracket = LO.CPlusPlus14 || LO.C2x;
StringRef AttributeSpelling =
DoubleSquareBracket ? "[[deprecated]]" : "__attribute__((deprecated))";
if (PP) {
TokenValue Tokens[] = {
tok::kw___attribute, tok::l_paren, tok::l_paren,
PP->getIdentifierInfo("deprecated"),
tok::r_paren, tok::r_paren
};
StringRef MacroName = PP->getLastMacroWithSpelling(FD->getLocation(),
Tokens);
if (!MacroName.empty())
AttributeSpelling = MacroName;
// Try to find a replacement macro:
// - In C2x/C++14 we prefer [[deprecated]].
// - If not found or an older C/C++ look for __attribute__((deprecated)).
StringRef MacroName;
if (DoubleSquareBracket) {
TokenValue Tokens[] = {tok::l_square, tok::l_square,
PP->getIdentifierInfo("deprecated"),
tok::r_square, tok::r_square};
MacroName = PP->getLastMacroWithSpelling(FD->getLocation(), Tokens);
if (!MacroName.empty())
AttributeSpelling = MacroName;
}

if (MacroName.empty()) {
TokenValue Tokens[] = {
tok::kw___attribute, tok::l_paren,
tok::l_paren, PP->getIdentifierInfo("deprecated"),
tok::r_paren, tok::r_paren};
StringRef MacroName =
PP->getLastMacroWithSpelling(FD->getLocation(), Tokens);
if (!MacroName.empty())
AttributeSpelling = MacroName;
}
}

SmallString<64> TextToInsert = AttributeSpelling;
Expand Down
30 changes: 30 additions & 0 deletions clang/test/Sema/warn-documentation-fixits.c
@@ -0,0 +1,30 @@
// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -fcomment-block-commands=foobar -verify %s
// RUN %clang_cc1 -std=c18 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -fcomment-block-commands=foobar -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck -DATTRIBUTE="__attribute__((deprecated))" %s
// RUN: %clang_cc1 -std=c2x -DC2x -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -fcomment-block-commands=foobar -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefixes=CHECK,CHECK2x -DATTRIBUTE="[[deprecated]]" %s

// expected-warning@+1 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} expected-note@+2 {{add a deprecation attribute to the declaration to silence this warning}}
/// \deprecated
void test_deprecated_1();

// expected-warning@+1 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} expected-note@+2 {{add a deprecation attribute to the declaration to silence this warning}}
/// \deprecated
void test_deprecated_2(int a);

#define MY_ATTR_DEPRECATED __attribute__((deprecated))

// expected-warning@+1 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} expected-note@+2 {{add a deprecation attribute to the declaration to silence this warning}}
/// \deprecated
void test_deprecated_3(int a);

#ifdef C2x
#define ATTRIBUTE_DEPRECATED [[deprecated]]

// expected-warning@+1 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} expected-note@+2 {{add a deprecation attribute to the declaration to silence this warning}}
/// \deprecated
void test_deprecated_4(int a);
#endif

// CHECK: fix-it:"{{.*}}":{7:1-7:1}:"[[ATTRIBUTE]] "
// CHECK: fix-it:"{{.*}}":{11:1-11:1}:"[[ATTRIBUTE]] "
// CHECK: fix-it:"{{.*}}":{17:1-17:1}:"MY_ATTR_DEPRECATED "
// CHECK2x: fix-it:"{{.*}}":{24:1-24:1}:"ATTRIBUTE_DEPRECATED "
37 changes: 23 additions & 14 deletions clang/test/Sema/warn-documentation-fixits.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -fcomment-block-commands=foobar -verify %s
// RUN: %clang_cc1 -std=c++11 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -fcomment-block-commands=foobar -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck %s
// RUN: %clang_cc1 -std=c++14 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -fcomment-block-commands=foobar -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefixes=CHECK,CHECK14 %s
// RUN %clang_cc1 -std=c++11 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -fcomment-block-commands=foobar -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck -DATTRIBUTE="__attribute__((deprecated))" %s
// RUN: %clang_cc1 -std=c++14 -fsyntax-only -Wdocumentation -Wdocumentation-pedantic -fcomment-block-commands=foobar -fdiagnostics-parseable-fixits %s 2>&1 | FileCheck --check-prefixes=CHECK,CHECK14 -DATTRIBUTE="[[deprecated]]" %s

// expected-warning@+1 {{parameter 'ZZZZZZZZZZ' not found in the function declaration}} expected-note@+1 {{did you mean 'a'?}}
/// \param ZZZZZZZZZZ Blah blah.
Expand Down Expand Up @@ -96,6 +96,14 @@ class PR43753 {
/// \deprecated
void test_deprecated_9(int a);

#if __cplusplus >= 201402L
#define ATTRIBUTE_DEPRECATED [[deprecated]]

// expected-warning@+1 {{declaration is marked with '\deprecated' command but does not have a deprecation attribute}} expected-note@+2 {{add a deprecation attribute to the declaration to silence this warning}}
/// \deprecated
void test_deprecated_10(int a);
#endif

// rdar://12381408
// expected-warning@+2 {{unknown command tag name 'retur'; did you mean 'return'?}}
/// \brief testing fixit
Expand All @@ -119,16 +127,17 @@ int PR18051();
// CHECK: fix-it:"{{.*}}":{10:12-10:15}:"aaa"
// CHECK: fix-it:"{{.*}}":{14:13-14:23}:"T"
// CHECK: fix-it:"{{.*}}":{19:13-19:18}:"SomeTy"
// CHECK: fix-it:"{{.*}}":{26:1-26:1}:"__attribute__((deprecated)) "
// CHECK: fix-it:"{{.*}}":{30:1-30:1}:"__attribute__((deprecated)) "
// CHECK: fix-it:"{{.*}}":{35:3-35:3}:"__attribute__((deprecated)) "
// CHECK: fix-it:"{{.*}}":{39:3-39:3}:"__attribute__((deprecated)) "
// CHECK: fix-it:"{{.*}}":{47:3-47:3}:"__attribute__((deprecated)) "
// CHECK: fix-it:"{{.*}}":{51:3-51:3}:"__attribute__((deprecated)) "
// CHECK: fix-it:"{{.*}}":{76:3-76:3}:"__attribute__((deprecated)) "
// CHECK: fix-it:"{{.*}}":{81:3-81:3}:"__attribute__((deprecated)) "
// CHECK14: fix-it:"{{.*}}":{87:3-87:3}:"__attribute__((deprecated)) "
// CHECK: fix-it:"{{.*}}":{26:1-26:1}:"[[ATTRIBUTE]] "
// CHECK: fix-it:"{{.*}}":{30:1-30:1}:"[[ATTRIBUTE]] "
// CHECK: fix-it:"{{.*}}":{35:3-35:3}:"[[ATTRIBUTE]] "
// CHECK: fix-it:"{{.*}}":{39:3-39:3}:"[[ATTRIBUTE]] "
// CHECK: fix-it:"{{.*}}":{47:3-47:3}:"[[ATTRIBUTE]] "
// CHECK: fix-it:"{{.*}}":{51:3-51:3}:"[[ATTRIBUTE]] "
// CHECK: fix-it:"{{.*}}":{76:3-76:3}:"[[ATTRIBUTE]] "
// CHECK: fix-it:"{{.*}}":{81:3-81:3}:"[[ATTRIBUTE]] "
// CHECK14: fix-it:"{{.*}}":{87:3-87:3}:"[[ATTRIBUTE]] "
// CHECK: fix-it:"{{.*}}":{97:1-97:1}:"MY_ATTR_DEPRECATED "
// CHECK: fix-it:"{{.*}}":{102:6-102:11}:"return"
// CHECK: fix-it:"{{.*}}":{106:6-106:11}:"foobar"
// CHECK: fix-it:"{{.*}}":{115:6-115:12}:"endcode"
// CHECK14: fix-it:"{{.*}}":{104:1-104:1}:"ATTRIBUTE_DEPRECATED "
// CHECK: fix-it:"{{.*}}":{110:6-110:11}:"return"
// CHECK: fix-it:"{{.*}}":{114:6-114:11}:"foobar"
// CHECK: fix-it:"{{.*}}":{123:6-123:12}:"endcode"
6 changes: 6 additions & 0 deletions clang/test/Sema/warn-documentation.cpp
Expand Up @@ -612,6 +612,12 @@ int test_tparam22;
/// \deprecated Bbb
void test_deprecated_1(int a) __attribute__((deprecated));

#if __cplusplus >= 201402L
/// Aaa
/// \deprecated Bbb
[[deprecated]] void test_deprecated_no_warning_std14(int a);
#endif

// We don't want \deprecated to warn about empty paragraph. It is fine to use
// \deprecated by itself without explanations.

Expand Down

0 comments on commit b6d386f

Please sign in to comment.