Index: clang/lib/Format/UnwrappedLineParser.h =================================================================== --- clang/lib/Format/UnwrappedLineParser.h +++ clang/lib/Format/UnwrappedLineParser.h @@ -153,7 +153,7 @@ void parseCaseLabel(); void parseSwitch(); void parseNamespace(); - void parseModuleImport(); + bool parseModuleImport(); void parseNew(); void parseAccessSpecifier(); bool parseEnum(); Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -41,7 +41,7 @@ // Returns the token that would be returned by the next call to // getNextToken(). - virtual FormatToken *peekNextToken() = 0; + virtual FormatToken *peekNextToken(bool SkipComment = false) = 0; // Returns whether we are at the end of the file. // This can be different from whether getNextToken() returned an eof token @@ -169,10 +169,10 @@ return PreviousTokenSource->getPreviousToken(); } - FormatToken *peekNextToken() override { + FormatToken *peekNextToken(bool SkipComment) override { if (eof()) return &FakeEOF; - return PreviousTokenSource->peekNextToken(); + return PreviousTokenSource->peekNextToken(SkipComment); } bool isEOF() override { return PreviousTokenSource->isEOF(); } @@ -288,8 +288,11 @@ return Position > 0 ? Tokens[Position - 1] : nullptr; } - FormatToken *peekNextToken() override { + FormatToken *peekNextToken(bool SkipComment) override { int Next = Position + 1; + if (SkipComment) + while (Tokens[Next]->is(tok::comment)) + ++Next; LLVM_DEBUG({ llvm::dbgs() << "Peeking "; dbgToken(Next); @@ -1435,8 +1438,22 @@ return Tok->Previous && Tok->Previous->isOneOf(tok::l_paren, tok::comma); } -void UnwrappedLineParser::parseModuleImport() { - nextToken(); +bool UnwrappedLineParser::parseModuleImport() { + assert(FormatTok->is(Keywords.kw_import) && "'import' expected"); + + auto CanFollowImport = [](auto Token) { + return Token->Tok.getIdentifierInfo() != nullptr || + Token->isOneOf(tok::colon, tok::less, tok::string_literal); + }; + + if (!CanFollowImport(Tokens->peekNextToken(/*SkipComment=*/true))) + return false; + + do { + nextToken(); + } while (FormatTok->is(tok::comment)); + assert(CanFollowImport(FormatTok)); + while (!eof()) { if (FormatTok->is(tok::colon)) { FormatTok->setFinalizedType(TT_ModulePartitionColon); @@ -1462,6 +1479,7 @@ } addUnwrappedLine(); + return true; } // readTokenWithJavaScriptASI reads the next token and terminates the current @@ -1682,14 +1700,12 @@ } if (Style.isCpp()) { nextToken(); - if (FormatTok->is(Keywords.kw_import)) { - parseModuleImport(); - return; - } if (FormatTok->is(tok::kw_namespace)) { parseNamespace(); return; } + if (FormatTok->is(Keywords.kw_import) && parseModuleImport()) + return; } break; case tok::kw_inline: @@ -1726,10 +1742,8 @@ addUnwrappedLine(); return; } - if (Style.isCpp()) { - parseModuleImport(); + if (Style.isCpp() && parseModuleImport()) return; - } } if (Style.isCpp() && FormatTok->isOneOf(Keywords.kw_signals, Keywords.kw_qsignals, Index: clang/unittests/Format/FormatTest.cpp =================================================================== --- clang/unittests/Format/FormatTest.cpp +++ clang/unittests/Format/FormatTest.cpp @@ -12810,6 +12810,7 @@ // But 'import' might also be a regular C++ namespace. verifyFormat("import::SomeFunction(aaaaaaaaaaaaaaaaaaaaaaaaaaa,\n" " aaaaaaaaaaaaaaaaaaaaaaaaaaaaa);"); + verifyFormat("import::Bar foo(val ? 2 : 1);"); } //===----------------------------------------------------------------------===// @@ -24654,6 +24655,8 @@ verifyFormat("import", Style); verifyFormat("module", Style); verifyFormat("export", Style); + + verifyFormat("import = val ? 2 : 1;"); } TEST_F(FormatTest, CoroutineForCoawait) {