Skip to content

Commit 686cf22

Browse files
Josh Learnmemfrob
authored andcommitted
[clang-format] Constructor initializer lists format with pp directives
Currently constructor initializer lists sometimes format incorrectly when there is a preprocessor directive in the middle of the list. This patch fixes the issue when parsing the initilizer list by ignoring the preprocessor directive when checking if a block is part of an initializer list. rdar://82554274 Reviewed By: MyDeveloperDay, HazardyKnusperkeks Differential Revision: https://reviews.llvm.org/D109951
1 parent e6caa87 commit 686cf22

File tree

2 files changed

+83
-0
lines changed

2 files changed

+83
-0
lines changed

clang/lib/Format/UnwrappedLineParser.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -489,6 +489,17 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
489489
if (Style.Language == FormatStyle::LK_Proto) {
490490
ProbablyBracedList = NextTok->isOneOf(tok::comma, tok::r_square);
491491
} else {
492+
// Skip NextTok over preprocessor lines, otherwise we may not
493+
// properly diagnose the block as a braced intializer
494+
// if the comma separator appears after the pp directive.
495+
while (NextTok->is(tok::hash)) {
496+
ScopedMacroState MacroState(*Line, Tokens, NextTok);
497+
do {
498+
NextTok = Tokens->getNextToken();
499+
++ReadTokens;
500+
} while (NextTok->isNot(tok::eof));
501+
}
502+
492503
// Using OriginalColumn to distinguish between ObjC methods and
493504
// binary operators is a bit hacky.
494505
bool NextIsObjCMethod = NextTok->isOneOf(tok::plus, tok::minus) &&

clang/unittests/Format/FormatTest.cpp

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19298,6 +19298,78 @@ TEST_F(FormatTest, BreakConstructorInitializersBeforeComma) {
1929819298
Style);
1929919299
}
1930019300

19301+
TEST_F(FormatTest, ConstructorInitializersWithPreprocessorDirective) {
19302+
FormatStyle Style = getLLVMStyle();
19303+
Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma;
19304+
Style.ConstructorInitializerIndentWidth = 4;
19305+
verifyFormat("SomeClass::Constructor()\n"
19306+
" : a{a}\n"
19307+
" , b{b} {}",
19308+
Style);
19309+
verifyFormat("SomeClass::Constructor()\n"
19310+
" : a{a}\n"
19311+
"#if CONDITION\n"
19312+
" , b{b}\n"
19313+
"#endif\n"
19314+
"{\n}",
19315+
Style);
19316+
Style.ConstructorInitializerIndentWidth = 2;
19317+
verifyFormat("SomeClass::Constructor()\n"
19318+
"#if CONDITION\n"
19319+
" : a{a}\n"
19320+
"#endif\n"
19321+
" , b{b}\n"
19322+
" , c{c} {\n}",
19323+
Style);
19324+
Style.ConstructorInitializerIndentWidth = 0;
19325+
verifyFormat("SomeClass::Constructor()\n"
19326+
": a{a}\n"
19327+
"#ifdef CONDITION\n"
19328+
", b{b}\n"
19329+
"#else\n"
19330+
", c{c}\n"
19331+
"#endif\n"
19332+
", d{d} {\n}",
19333+
Style);
19334+
Style.ConstructorInitializerIndentWidth = 4;
19335+
verifyFormat("SomeClass::Constructor()\n"
19336+
" : a{a}\n"
19337+
"#if WINDOWS\n"
19338+
"#if DEBUG\n"
19339+
" , b{0}\n"
19340+
"#else\n"
19341+
" , b{1}\n"
19342+
"#endif\n"
19343+
"#else\n"
19344+
"#if DEBUG\n"
19345+
" , b{2}\n"
19346+
"#else\n"
19347+
" , b{3}\n"
19348+
"#endif\n"
19349+
"#endif\n"
19350+
"{\n}",
19351+
Style);
19352+
verifyFormat("SomeClass::Constructor()\n"
19353+
" : a{a}\n"
19354+
"#if WINDOWS\n"
19355+
" , b{0}\n"
19356+
"#if DEBUG\n"
19357+
" , c{0}\n"
19358+
"#else\n"
19359+
" , c{1}\n"
19360+
"#endif\n"
19361+
"#else\n"
19362+
"#if DEBUG\n"
19363+
" , c{2}\n"
19364+
"#else\n"
19365+
" , c{3}\n"
19366+
"#endif\n"
19367+
" , b{1}\n"
19368+
"#endif\n"
19369+
"{\n}",
19370+
Style);
19371+
}
19372+
1930119373
TEST_F(FormatTest, Destructors) {
1930219374
verifyFormat("void F(int &i) { i.~int(); }");
1930319375
verifyFormat("void F(int &i) { i->~int(); }");

0 commit comments

Comments
 (0)