Skip to content

Commit

Permalink
[clang-format] [PR34574] Handle [[nodiscard]] attribute in class decl…
Browse files Browse the repository at this point in the history
…aration

Summary:
https://bugs.llvm.org/show_bug.cgi?id=34574
https://bugs.llvm.org/show_bug.cgi?id=38401

```
template <typename T>
class [[nodiscard]] result
{
  public:
    result(T&&)
    {
    }
};
```

formats incorrectly to

```
template <typename T>
class [[nodiscard]] result{public : result(T &&){}};
```

Reviewed By: krasimir

Subscribers: cfe-commits

Tags: #clang, #clang-format

Differential Revision: https://reviews.llvm.org/D79354
  • Loading branch information
mydeveloperday committed May 9, 2020
1 parent 3c5dd58 commit 31fd12a
Show file tree
Hide file tree
Showing 2 changed files with 16 additions and 3 deletions.
15 changes: 12 additions & 3 deletions clang/lib/Format/UnwrappedLineParser.cpp
Expand Up @@ -2399,9 +2399,10 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {

// The actual identifier can be a nested name specifier, and in macros
// it is often token-pasted.
// An [[attribute]] can be before the identifier.
while (FormatTok->isOneOf(tok::identifier, tok::coloncolon, tok::hashhash,
tok::kw___attribute, tok::kw___declspec,
tok::kw_alignas) ||
tok::kw_alignas, TT_AttributeSquare) ||
((Style.Language == FormatStyle::LK_Java ||
Style.Language == FormatStyle::LK_JavaScript) &&
FormatTok->isOneOf(tok::period, tok::comma))) {
Expand All @@ -2421,8 +2422,16 @@ void UnwrappedLineParser::parseRecord(bool ParseAsExpr) {
FormatTok->TokenText != FormatTok->TokenText.upper();
nextToken();
// We can have macros or attributes in between 'class' and the class name.
if (!IsNonMacroIdentifier && FormatTok->Tok.is(tok::l_paren))
parseParens();
if (!IsNonMacroIdentifier) {
if (FormatTok->Tok.is(tok::l_paren)) {
parseParens();
} else if (FormatTok->is(TT_AttributeSquare)) {
parseSquare();
// Consume the closing TT_AttributeSquare.
if (FormatTok->Next && FormatTok->is(TT_AttributeSquare))
nextToken();
}
}
}

// Note that parsing away template declarations here leads to incorrectly
Expand Down
4 changes: 4 additions & 0 deletions clang/unittests/Format/FormatTest.cpp
Expand Up @@ -7647,6 +7647,10 @@ TEST_F(FormatTest, UnderstandsSquareAttributes) {
verifyFormat("void f() [[deprecated(\"so sorry\")]];");
verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\n"
" [[unused]] aaaaaaaaaaaaaaaaaaaaaaa(int i);");
verifyFormat("[[nodiscard]] bool f() { return false; }");
verifyFormat("class [[nodiscard]] f {\npublic:\n f() {}\n}");
verifyFormat("class [[deprecated(\"so sorry\")]] f {\npublic:\n f() {}\n}");
verifyFormat("class [[gnu::unused]] f {\npublic:\n f() {}\n}");

// Make sure we do not mistake attributes for array subscripts.
verifyFormat("int a() {}\n"
Expand Down

0 comments on commit 31fd12a

Please sign in to comment.