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
"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) ||
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;
}
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