diff --git a/clang/lib/Format/UnwrappedLineParser.cpp b/clang/lib/Format/UnwrappedLineParser.cpp --- a/clang/lib/Format/UnwrappedLineParser.cpp +++ b/clang/lib/Format/UnwrappedLineParser.cpp @@ -459,6 +459,17 @@ ++ReadTokens; } while (NextTok->is(tok::comment)); + // Skip over preprocessor lines, otherwise we may not + // properly diagnose the block as a braced intializer + // if the comma separator appears after the pp directive. + if (NextTok->is(tok::hash)) { + ScopedMacroState MacroState(*Line, Tokens, NextTok); + do { + NextTok = Tokens->getNextToken(); + ++ReadTokens; + } while (NextTok->isNot(tok::eof)); + } + switch (Tok->Tok.getKind()) { case tok::l_brace: if (Style.Language == FormatStyle::LK_JavaScript && PrevTok) { diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp --- a/clang/unittests/Format/FormatTest.cpp +++ b/clang/unittests/Format/FormatTest.cpp @@ -19268,6 +19268,38 @@ Style); } +TEST_F(FormatTest, ConstructorInitializersWithPreprocessorDirective) { + FormatStyle Style = getLLVMStyle(); + Style.BreakConstructorInitializers = FormatStyle::BCIS_BeforeComma; + Style.ConstructorInitializerIndentWidth = 4; + verifyFormat("SomeClass::Constructor()\n" + " : a{a}\n" + "#if CONDITION\n" + " , b{b}\n" + "#endif\n" + "{\n}", + Style); + Style.ConstructorInitializerIndentWidth = 2; + verifyFormat("SomeClass::Constructor()\n" + "#if CONDITION\n" + " : a{a}\n" + "#endif\n" + " , b{b}\n" + " , c{c} {\n}", + Style); + Style.ConstructorInitializerIndentWidth = 0; + Style.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_All; + verifyFormat("SomeClass::Constructor()\n" + ": a{a}\n" + "#ifdef CONDITION\n" + ", b{b}\n" + "#else\n" + ", c{c}\n" + "#endif\n" + ", d{d} {\n}", + Style); +} + TEST_F(FormatTest, Destructors) { verifyFormat("void F(int &i) { i.~int(); }"); verifyFormat("void F(int &i) { i->~int(); }");