Index: lib/Format/Format.cpp =================================================================== --- lib/Format/Format.cpp +++ lib/Format/Format.cpp @@ -1446,6 +1446,14 @@ private: static bool guessIsObjC(const SmallVectorImpl &AnnotatedLines, const AdditionalKeywords &Keywords) { + for (auto Line : AnnotatedLines) + if (LineContainsObjCCode(*Line, Keywords)) + return true; + return false; + } + + static bool LineContainsObjCCode(const AnnotatedLine &Line, + const AdditionalKeywords &Keywords) { // Keep this array sorted, since we are binary searching over it. static constexpr llvm::StringLiteral FoundationIdentifiers[] = { "CGFloat", @@ -1514,40 +1522,32 @@ "UIView", }; - auto LineContainsObjCCode = [&Keywords](const AnnotatedLine &Line) { - for (const FormatToken *FormatTok = Line.First; FormatTok; - FormatTok = FormatTok->Next) { - if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) && - (FormatTok->isObjCAtKeyword(tok::objc_interface) || - FormatTok->isObjCAtKeyword(tok::objc_implementation) || - FormatTok->isObjCAtKeyword(tok::objc_protocol) || - FormatTok->isObjCAtKeyword(tok::objc_end) || - FormatTok->isOneOf(tok::numeric_constant, tok::l_square, - tok::l_brace))) || - (FormatTok->Tok.isAnyIdentifier() && - std::binary_search(std::begin(FoundationIdentifiers), - std::end(FoundationIdentifiers), - FormatTok->TokenText)) || - FormatTok->is(TT_ObjCStringLiteral) || - FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS, - TT_ObjCBlockLBrace, TT_ObjCBlockLParen, - TT_ObjCDecl, TT_ObjCForIn, TT_ObjCMethodExpr, - TT_ObjCMethodSpecifier, TT_ObjCProperty)) { - return true; - } - } - return false; - }; - for (auto Line : AnnotatedLines) { - if (LineContainsObjCCode(*Line)) + for (const FormatToken *FormatTok = Line.First; FormatTok; + FormatTok = FormatTok->Next) { + if ((FormatTok->Previous && FormatTok->Previous->is(tok::at) && + (FormatTok->isObjCAtKeyword(tok::objc_interface) || + FormatTok->isObjCAtKeyword(tok::objc_implementation) || + FormatTok->isObjCAtKeyword(tok::objc_protocol) || + FormatTok->isObjCAtKeyword(tok::objc_end) || + FormatTok->isOneOf(tok::numeric_constant, tok::l_square, + tok::l_brace))) || + (FormatTok->Tok.isAnyIdentifier() && + std::binary_search(std::begin(FoundationIdentifiers), + std::end(FoundationIdentifiers), + FormatTok->TokenText)) || + FormatTok->is(TT_ObjCStringLiteral) || + FormatTok->isOneOf(Keywords.kw_NS_ENUM, Keywords.kw_NS_OPTIONS, + TT_ObjCBlockLBrace, TT_ObjCBlockLParen, + TT_ObjCDecl, TT_ObjCForIn, TT_ObjCMethodExpr, + TT_ObjCMethodSpecifier, TT_ObjCProperty)) { return true; - for (auto ChildLine : Line->Children) { - if (LineContainsObjCCode(*ChildLine)) - return true; } + for (auto ChildLine : Line.Children) + if (LineContainsObjCCode(*ChildLine, Keywords)) + return true; } return false; - } + }; bool IsObjC; }; Index: unittests/Format/FormatTest.cpp =================================================================== --- unittests/Format/FormatTest.cpp +++ unittests/Format/FormatTest.cpp @@ -12171,6 +12171,12 @@ guessLanguage("foo.h", "#define FOO ({ std::string s; })")); EXPECT_EQ(FormatStyle::LK_ObjC, guessLanguage("foo.h", "#define FOO ({ NSString *s; })")); + EXPECT_EQ( + FormatStyle::LK_Cpp, + guessLanguage("foo.h", "#define FOO ({ foo(); ({ std::string s; }) })")); + EXPECT_EQ( + FormatStyle::LK_ObjC, + guessLanguage("foo.h", "#define FOO ({ foo(); ({ NSString *s; }) })")); } } // end namespace