Skip to content

Commit

Permalink
[clang-format] Fix ObjC style guesser to also iterate over child lines
Browse files Browse the repository at this point in the history
Summary:
When I wrote `ObjCHeaderStyleGuesser`, I incorrectly assumed the
correct way to iterate over all tokens in `AnnotatedLine` was to
iterate over the linked list tokens starting with
`AnnotatedLine::First`.

However, `AnnotatedLine` also contains a vector
`AnnotedLine::Children` with child `AnnotedLine`s which have their own
tokens which we need to iterate over.

Because I didn't iterate over the tokens in the children lines, the
ObjC style guesser would fail on syntax like:

  #define FOO ({ NSString *s = ... })

as the statement(s) inside { ... } are child lines.

This fixes the bug and adds a test. I confirmed the test
failed before the fix, and passed after the fix.

Test Plan: New tests added. Ran tests with:
  % make -j12 FormatTests && ./tools/clang/unittests/Format/FormatTests

Reviewers: djasper, jolesiak, Wizard

Reviewed By: djasper

Subscribers: klimek, cfe-commits

Differential Revision: https://reviews.llvm.org/D44790

llvm-svn: 328220
  • Loading branch information
bhamiltoncx committed Mar 22, 2018
1 parent 36cdfad commit 6432afe
Showing 2 changed files with 18 additions and 2 deletions.
13 changes: 11 additions & 2 deletions clang/lib/Format/Format.cpp
Original file line number Diff line number Diff line change
@@ -1514,8 +1514,8 @@ class ObjCHeaderStyleGuesser : public TokenAnalyzer {
"UIView",
};

for (auto &Line : AnnotatedLines) {
for (FormatToken *FormatTok = Line->First; FormatTok;
auto LineContainsObjCCode = [&Keywords](const AnnotatedLine &Line) {
for (const FormatToken *FormatTok = Line.First; FormatTok;
FormatTok = FormatTok->Next) {
if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) &&
(FormatTok->isObjCAtKeyword(tok::objc_interface) ||
@@ -1536,6 +1536,15 @@ class ObjCHeaderStyleGuesser : public TokenAnalyzer {
return true;
}
}
return false;
};
for (auto Line : AnnotatedLines) {
if (LineContainsObjCCode(*Line))
return true;
for (auto ChildLine : Line->Children) {
if (LineContainsObjCCode(*ChildLine))
return true;
}
}
return false;
}
7 changes: 7 additions & 0 deletions clang/unittests/Format/FormatTest.cpp
Original file line number Diff line number Diff line change
@@ -12166,6 +12166,13 @@ TEST_F(FormatTest, GuessLanguageWithCaret) {
guessLanguage("foo.h", "int(^foo[(kNumEntries + 10)])(char, float);"));
}

TEST_F(FormatTest, GuessLanguageWithChildLines) {
EXPECT_EQ(FormatStyle::LK_Cpp,
guessLanguage("foo.h", "#define FOO ({ std::string s; })"));
EXPECT_EQ(FormatStyle::LK_ObjC,
guessLanguage("foo.h", "#define FOO ({ NSString *s; })"));
}

} // end namespace
} // end namespace format
} // end namespace clang

0 comments on commit 6432afe

Please sign in to comment.