Skip to content

Commit

Permalink
[clang-format] Fix preprocessor nesting after commit 529aa4b
Browse files Browse the repository at this point in the history
In 529aa4b
by setting the identifier info to nullptr, we started to subtly
interfere with the parts in the beginning of the function,
https://github.com/llvm/llvm-project/blob/529aa4b011c4ae808d658022ef643c44dd9b2c9c/clang/lib/Format/UnwrappedLineParser.cpp#L991
causing the preprocessor nesting to change in some cases. E.g., for the
added regression test, clang-format started incorrectly guessing the
language as C++.

This tries to address this by introducing an internal identifier info
element to use instead.

Reviewed By: curdeius, MyDeveloperDay

Differential Revision: https://reviews.llvm.org/D120315
  • Loading branch information
krasimirgg committed Feb 22, 2022
1 parent ffa4dfc commit c9592ae
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 2 deletions.
7 changes: 7 additions & 0 deletions clang/lib/Format/FormatToken.h
Expand Up @@ -949,6 +949,10 @@ struct AdditionalKeywords {
kw_slots = &IdentTable.get("slots");
kw_qslots = &IdentTable.get("Q_SLOTS");

// For internal clang-format use.
kw_internal_ident_after_define =
&IdentTable.get("__CLANG_FORMAT_INTERNAL_IDENT_AFTER_DEFINE__");

// C# keywords
kw_dollar = &IdentTable.get("dollar");
kw_base = &IdentTable.get("base");
Expand Down Expand Up @@ -1069,6 +1073,9 @@ struct AdditionalKeywords {
IdentifierInfo *kw_slots;
IdentifierInfo *kw_qslots;

// For internal use by clang-format.
IdentifierInfo *kw_internal_ident_after_define;

// C# keywords
IdentifierInfo *kw_dollar;
IdentifierInfo *kw_base;
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/Format/UnwrappedLineParser.cpp
Expand Up @@ -1089,9 +1089,10 @@ void UnwrappedLineParser::parsePPDefine() {
// In the context of a define, even keywords should be treated as normal
// identifiers. Setting the kind to identifier is not enough, because we need
// to treat additional keywords like __except as well, which are already
// identifiers.
// identifiers. Setting the identifier info to null interferes with include
// guard processing above, and changes preprocessing nesting.
FormatTok->Tok.setKind(tok::identifier);
FormatTok->Tok.setIdentifierInfo(nullptr);
FormatTok->Tok.setIdentifierInfo(Keywords.kw_internal_ident_after_define);
nextToken();
if (FormatTok->Tok.getKind() == tok::l_paren &&
!FormatTok->hasWhitespaceBefore())
Expand Down
7 changes: 7 additions & 0 deletions clang/unittests/Format/FormatTest.cpp
Expand Up @@ -22724,6 +22724,13 @@ TEST_F(FormatTest, FileAndCode) {
EXPECT_EQ(
FormatStyle::LK_Cpp,
guessLanguage("foo.h", "#define FOO(...) auto bar = [] __VA_ARGS__;"));
// Only one of the two preprocessor regions has ObjC-like code.
EXPECT_EQ(FormatStyle::LK_ObjC,
guessLanguage("foo.h", "#if A\n"
"#define B() C\n"
"#else\n"
"#define B() [NSString a:@\"\"]\n"
"#endif\n"));
}

TEST_F(FormatTest, GuessLanguageWithCpp11AttributeSpecifiers) {
Expand Down

0 comments on commit c9592ae

Please sign in to comment.