diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp --- a/clang/lib/Format/TokenAnnotator.cpp +++ b/clang/lib/Format/TokenAnnotator.cpp @@ -3494,7 +3494,8 @@ } static bool isAllmanLambdaBrace(const FormatToken &Tok) { return (Tok.is(tok::l_brace) && Tok.is(BK_Block) && - !Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral)); + !Tok.isOneOf(TT_ObjCBlockLBrace, TT_DictLiteral) && + !Tok.Previous->Previous->is(tok::kw_namespace)); } static bool isAllmanBraceIncludedBreakableLambda( 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 @@ -2589,6 +2589,33 @@ Style)); } +TEST_F(FormatTest, FormatsCompactNamespacesLambdaRegression) { + FormatStyle Style = getLLVMStyle(); + Style.CompactNamespaces = true; + + // Make sure compact namespaces are not confused with lambdas + auto NoShortLambdaStyle{Style}; + NoShortLambdaStyle.AllowShortLambdasOnASingleLine = FormatStyle::SLS_None; + EXPECT_EQ("namespace out { namespace in {\n" + "}} // namespace out::in", + format("namespace out {\n" + "namespace in {\n" + "} // namespace in\n" + "} // namespace out", + NoShortLambdaStyle)); + + auto BraceWrappingBeforeLambdaBodyStyle{Style}; + BraceWrappingBeforeLambdaBodyStyle.BreakBeforeBraces = FormatStyle::BS_Custom; + BraceWrappingBeforeLambdaBodyStyle.BraceWrapping.BeforeLambdaBody = true; + EXPECT_EQ("namespace out { namespace in {\n" + "}} // namespace out::in", + format("namespace out {\n" + "namespace in {\n" + "} // namespace in\n" + "} // namespace out", + BraceWrappingBeforeLambdaBodyStyle)); +} + TEST_F(FormatTest, FormatsExternC) { verifyFormat("extern \"C\" {\nint a;"); verifyFormat("extern \"C\" {}");