benhamilton created this revision. benhamilton added reviewers: krasimir, djasper. Herald added a project: clang. Herald added a subscriber: cfe-commits.
Currently, `UnwrappedLineParser` thinks an arrow token after an ObjC method expression is a C++ lambda arrow, so it formats: [foo bar]->baz as: [foo bar] -> baz Because `UnwrappedLineParser` runs before `TokenAnnotator`, it can't know if the arrow token is after an ObjC method expression or not. This diff makes `TokenAnnotator` remove the TT_LambdaArrow on the arrow token if it follows an ObjC method expression. Test Plan: New test added. Ran test with: % ninja FormatTests && ./tools/clang/unittests/Format/FormatTests Confirmed test failed before diff and passed after diff. Repository: rG LLVM Github Monorepo https://reviews.llvm.org/D57923 Files: clang/lib/Format/TokenAnnotator.cpp clang/lib/Format/UnwrappedLineParser.cpp clang/unittests/Format/FormatTestObjC.cpp Index: clang/unittests/Format/FormatTestObjC.cpp =================================================================== --- clang/unittests/Format/FormatTestObjC.cpp +++ clang/unittests/Format/FormatTestObjC.cpp @@ -611,6 +611,7 @@ TEST_F(FormatTestObjC, FormatObjCMethodExpr) { verifyFormat("[foo bar:baz];"); + verifyFormat("[foo bar]->baz;"); verifyFormat("return [foo bar:baz];"); verifyFormat("return (a)[foo bar:baz];"); verifyFormat("f([foo bar:baz]);"); Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -1426,6 +1426,9 @@ nextToken(); break; case tok::arrow: + // This might or might not actually be a lambda arrow (this could be an + // ObjC method invocation followed by a dereferencing arrow). We might + // reset this back to TT_Unknown in TokenAnnotator. FormatTok->Type = TT_LambdaArrow; nextToken(); break; Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -520,6 +520,11 @@ if (Parent && Parent->is(TT_PointerOrReference)) Parent->Type = TT_BinaryOperator; } + // An arrow after an ObjC method expression is not a lambda arrow. + if (CurrentToken->Type == TT_ObjCMethodExpr) { + if (CurrentToken->Next && CurrentToken->Next->is(TT_LambdaArrow)) + CurrentToken->Next->Type = TT_Unknown; + } Left->MatchingParen = CurrentToken; CurrentToken->MatchingParen = Left; // FirstObjCSelectorName is set when a colon is found. This does
Index: clang/unittests/Format/FormatTestObjC.cpp =================================================================== --- clang/unittests/Format/FormatTestObjC.cpp +++ clang/unittests/Format/FormatTestObjC.cpp @@ -611,6 +611,7 @@ TEST_F(FormatTestObjC, FormatObjCMethodExpr) { verifyFormat("[foo bar:baz];"); + verifyFormat("[foo bar]->baz;"); verifyFormat("return [foo bar:baz];"); verifyFormat("return (a)[foo bar:baz];"); verifyFormat("f([foo bar:baz]);"); Index: clang/lib/Format/UnwrappedLineParser.cpp =================================================================== --- clang/lib/Format/UnwrappedLineParser.cpp +++ clang/lib/Format/UnwrappedLineParser.cpp @@ -1426,6 +1426,9 @@ nextToken(); break; case tok::arrow: + // This might or might not actually be a lambda arrow (this could be an + // ObjC method invocation followed by a dereferencing arrow). We might + // reset this back to TT_Unknown in TokenAnnotator. FormatTok->Type = TT_LambdaArrow; nextToken(); break; Index: clang/lib/Format/TokenAnnotator.cpp =================================================================== --- clang/lib/Format/TokenAnnotator.cpp +++ clang/lib/Format/TokenAnnotator.cpp @@ -520,6 +520,11 @@ if (Parent && Parent->is(TT_PointerOrReference)) Parent->Type = TT_BinaryOperator; } + // An arrow after an ObjC method expression is not a lambda arrow. + if (CurrentToken->Type == TT_ObjCMethodExpr) { + if (CurrentToken->Next && CurrentToken->Next->is(TT_LambdaArrow)) + CurrentToken->Next->Type = TT_Unknown; + } Left->MatchingParen = CurrentToken; CurrentToken->MatchingParen = Left; // FirstObjCSelectorName is set when a colon is found. This does
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits