Author: Krasimir Georgiev Date: 2022-02-22T15:43:18+01:00 New Revision: c9592ae49b8c486754a745e0c7b1a30b92a12e8b
URL: https://github.com/llvm/llvm-project/commit/c9592ae49b8c486754a745e0c7b1a30b92a12e8b DIFF: https://github.com/llvm/llvm-project/commit/c9592ae49b8c486754a745e0c7b1a30b92a12e8b.diff LOG: [clang-format] Fix preprocessor nesting after commit 529aa4b011c4ae808d658022ef643c44dd9b2c9c In https://github.com/llvm/llvm-project/commit/529aa4b011c4ae808d658022ef643c44dd9b2c9c 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 Added: Modified: clang/lib/Format/FormatToken.h clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTest.cpp Removed: ################################################################################ diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h index 5f05986addf6a..bd1d447328a0a 100644 --- a/clang/lib/Format/FormatToken.h +++ b/clang/lib/Format/FormatToken.h @@ -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"); @@ -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; diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp index 7d29afb0c042c..09e209e856541 100644 --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -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()) diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp index 51f6239bf2100..7d8b74c9c455f 100644 --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -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) { _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits