Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -2001,6 +2001,7 @@ LangOpts.ObjC2 = 1; LangOpts.MicrosoftExt = 1; // To get kw___try, kw___finally. LangOpts.DeclSpecKeyword = 1; // To get __declspec. + LangOpts.CoroutinesTS = Style.isCpp(); return LangOpts; } Index: lib/Format/TokenAnnotator.cpp =================================================================== --- lib/Format/TokenAnnotator.cpp +++ lib/Format/TokenAnnotator.cpp @@ -609,6 +609,8 @@ if (CurrentToken && CurrentToken->is(Keywords.kw_await)) next(); } + if (CurrentToken && CurrentToken->is(tok::kw_co_await)) + next(); Contexts.back().ColonIsForRangeExpr = true; next(); if (!parseParens()) @@ -2245,6 +2247,11 @@ if (Right.is(tok::l_paren)) { if (Left.is(tok::r_paren) && Left.is(TT_AttributeParen)) return true; + if (Left.is(tok::kw_co_await) && Left.Previous && + Left.Previous->is(tok::kw_operator)) + return false; + if (Left.isOneOf(tok::kw_co_await, tok::kw_co_yield, tok::kw_co_return)) + return true; return Line.Type == LT_ObjCDecl || Left.is(tok::semi) || (Style.SpaceBeforeParens != FormatStyle::SBPO_Never && (Left.isOneOf(tok::kw_if, tok::pp_elif, tok::kw_for, tok::kw_while, @@ -2292,6 +2299,18 @@ if (Style.isCpp()) { if (Left.is(tok::kw_operator)) return Right.is(tok::coloncolon); + // for await ( ... + if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && + Left.Previous && Left.Previous->is(tok::kw_for)) + return true; + if (Right.is(tok::l_paren) && Left.is(tok::kw_co_await) && + Left.Previous && Left.Previous->is(tok::kw_operator)) + return false; + if (Right.is(tok::star) && Left.is(tok::kw_co_yield)) + return false; + if (Right.isOneOf(tok::l_brace, tok::l_square) && + Left.isOneOf(tok::kw_co_yield, tok::kw_co_await)) + return true; } else if (Style.Language == FormatStyle::LK_Proto || Style.Language == FormatStyle::LK_TextProto) { if (Right.is(tok::period) && Index: lib/Format/UnwrappedLineParser.cpp =================================================================== --- lib/Format/UnwrappedLineParser.cpp +++ lib/Format/UnwrappedLineParser.cpp @@ -1700,6 +1700,8 @@ if (Style.Language == FormatStyle::LK_JavaScript && FormatTok->is(Keywords.kw_await)) nextToken(); + if (Style.isCpp() && FormatTok->is(tok::kw_co_await)) + nextToken(); if (FormatTok->Tok.is(tok::l_paren)) parseParens(); if (FormatTok->Tok.is(tok::l_brace)) { Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -11085,6 +11085,40 @@ EXPECT_EQ("auto c = u8'a';", format("auto c = u8'a';")); } +TEST_F(FormatTest, CoawaitForRangeCpp11) { + EXPECT_EQ("for co_await (auto x : range())\n ;", + format("for co_await(auto x : range());")); +} + +TEST_F(FormatTest, Coawait) { + EXPECT_EQ("int x = co_await foo();", + format("int x = co_await foo();")); + EXPECT_EQ("int x = (co_await foo());", + format("int x = (co_await foo());")); + EXPECT_EQ("co_await (42);", + format("co_await(42);")); + EXPECT_EQ("void operator co_await(int);", + format("void operator co_await (int);")); +} + +TEST_F(FormatTest, Coyield) { + EXPECT_EQ("int x = co_yield foo();", + format("int x = co_yield foo();")); + EXPECT_EQ("int x = (co_yield foo());", + format("int x = (co_yield foo());")); + EXPECT_EQ("co_yield (42);", + format("co_yield(42);")); +} + +TEST_F(FormatTest, Coreturn) { + EXPECT_EQ("int x = co_return foo();", + format("int x = co_return foo();")); + EXPECT_EQ("int x = (co_return foo());", + format("int x = (co_return foo());")); + EXPECT_EQ("co_return (42);", + format("co_return(42);")); +} + } // end namespace } // end namespace format } // end namespace clang