Contexts.size() == 2 && Contexts[0].ColonIsForRangeExpr;
bool StartsObjCMethodExpr = false;
- if (CurrentToken->is(tok::caret)) {
- // (^ can start a block type.
- Left->Type = TT_ObjCBlockLParen;
- } else if (FormatToken *MaybeSel = Left->Previous) {
+ if (FormatToken *MaybeSel = Left->Previous) {
// @selector( starts a selector.
if (MaybeSel->isObjCAtKeyword(tok::objc_selector) && MaybeSel->Previous &&
MaybeSel->Previous->is(tok::at)) {
Left->Type = TT_ObjCMethodExpr;
}
+ // MightBeFunctionType and ProbablyFunctionType are used for
+ // function pointer and reference types as well as Objective-C
+ // block types:
+ //
+ // void (*FunctionPointer)(void);
+ // void (&FunctionReference)(void);
+ // void (^ObjCBlock)(void);
bool MightBeFunctionType = !Contexts[Contexts.size() - 2].IsExpression;
- bool ProbablyFunctionType = CurrentToken->isOneOf(tok::star, tok::amp);
+ bool ProbablyFunctionType =
+ CurrentToken->isOneOf(tok::star, tok::amp, tok::caret);
bool HasMultipleLines = false;
bool HasMultipleParametersOnALine = false;
bool MightBeObjCForRangeLoop =
if (MightBeFunctionType && ProbablyFunctionType && CurrentToken->Next &&
(CurrentToken->Next->is(tok::l_paren) ||
(CurrentToken->Next->is(tok::l_square) && Line.MustBeDeclaration)))
- Left->Type = TT_FunctionTypeLParen;
+ Left->Type = Left->Next->is(tok::caret) ? TT_ObjCBlockLParen
+ : TT_FunctionTypeLParen;
Left->MatchingParen = CurrentToken;
CurrentToken->MatchingParen = Left;
EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "[[foo::bar, ...]]"));
}
+TEST_F(FormatTest, GuessLanguageWithCaret) {
+ EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "FOO(^);"));
+ EXPECT_EQ(FormatStyle::LK_Cpp, guessLanguage("foo.h", "FOO(^, Bar);"));
+ EXPECT_EQ(FormatStyle::LK_ObjC,
+ guessLanguage("foo.h", "int(^)(char, float);"));
+ EXPECT_EQ(FormatStyle::LK_ObjC,
+ guessLanguage("foo.h", "int(^foo)(char, float);"));
+ EXPECT_EQ(FormatStyle::LK_ObjC,
+ guessLanguage("foo.h", "int(^foo[10])(char, float);"));
+ EXPECT_EQ(FormatStyle::LK_ObjC,
+ guessLanguage("foo.h", "int(^foo[kNumEntries])(char, float);"));
+ EXPECT_EQ(
+ FormatStyle::LK_ObjC,
+ guessLanguage("foo.h", "int(^foo[(kNumEntries + 10)])(char, float);"));
+}
+
} // end namespace
} // end namespace format
} // end namespace clang
verifyFormat("@ /*foo*/ interface");
}
+TEST_F(FormatTestObjC, ObjCBlockTypesAndVariables) {
+ verifyFormat("void DoStuffWithBlockType(int (^)(char));");
+ verifyFormat("int (^foo)(char, float);");
+ verifyFormat("int (^foo[10])(char, float);");
+ verifyFormat("int (^foo[kNumEntries])(char, float);");
+ verifyFormat("int (^foo[kNumEntries + 10])(char, float);");
+ verifyFormat("int (^foo[(kNumEntries + 10)])(char, float);");
+}
+
TEST_F(FormatTestObjC, ObjCSnippets) {
verifyFormat("@autoreleasepool {\n"
" foo();\n"