aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/Format/Format.h3
-rw-r--r--lib/Format/Format.cpp23
-rw-r--r--test/Index/comment-c-decls.c4
-rw-r--r--test/Index/format-comment-cdecls.c4
-rw-r--r--unittests/Format/FormatTest.cpp21
5 files changed, 38 insertions, 17 deletions
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 32bb53c8d4..7713cf784a 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -78,6 +78,9 @@ tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
SourceManager &SourceMgr,
std::vector<CharSourceRange> Ranges);
+/// \brief Returns the \c LangOpts that the formatter expects you to set.
+LangOptions getFormattingLangOpts();
+
} // end namespace format
} // end namespace clang
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index 00a4b77980..c0ed6c5be1 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -34,6 +34,7 @@ enum TokenType {
TT_CtorInitializerColon,
TT_DirectorySeparator,
TT_LineComment,
+ TT_ObjCBlockLParen,
TT_ObjCMethodSpecifier,
TT_OverloadedOperator,
TT_PointerOrReference,
@@ -627,6 +628,8 @@ public:
}
bool parseParens() {
+ if (CurrentToken != NULL && CurrentToken->is(tok::caret))
+ CurrentToken->Parent->Type = TT_ObjCBlockLParen;
while (CurrentToken != NULL) {
if (CurrentToken->is(tok::r_paren)) {
next();
@@ -995,7 +998,8 @@ private:
if (Left.is(tok::at) &&
(Right.is(tok::identifier) || Right.is(tok::string_literal) ||
Right.is(tok::char_constant) || Right.is(tok::numeric_constant) ||
- Right.is(tok::l_paren) || Right.is(tok::l_brace)))
+ Right.is(tok::l_paren) || Right.is(tok::l_brace) ||
+ Right.is(tok::kw_true) || Right.is(tok::kw_false)))
return false;
if (Left.is(tok::less) || Right.is(tok::greater) || Right.is(tok::less))
return false;
@@ -1024,8 +1028,7 @@ private:
if (Right.is(tok::l_paren)) {
return Left.is(tok::kw_if) || Left.is(tok::kw_for) ||
Left.is(tok::kw_while) || Left.is(tok::kw_switch) ||
- (Left.isNot(tok::identifier) && Left.isNot(tok::kw_sizeof) &&
- Left.isNot(tok::kw_typeof) && Left.isNot(tok::kw_alignof));
+ Left.is(tok::kw_return) || Left.is(tok::kw_catch);
}
if (Left.is(tok::at) &&
Right.FormatTok.Tok.getObjCKeywordID() != tok::objc_not_keyword)
@@ -1050,11 +1053,11 @@ private:
return false;
}
- if (Tok.Type == TT_CtorInitializerColon)
+ if (Tok.Type == TT_CtorInitializerColon || Tok.Type == TT_ObjCBlockLParen)
return true;
if (Tok.Type == TT_OverloadedOperator)
return Tok.is(tok::identifier) || Tok.is(tok::kw_new) ||
- Tok.is(tok::kw_delete);
+ Tok.is(tok::kw_delete) || Tok.is(tok::kw_bool);
if (Tok.Parent->Type == TT_OverloadedOperator)
return false;
if (Tok.is(tok::colon))
@@ -1290,5 +1293,15 @@ tooling::Replacements reformat(const FormatStyle &Style, Lexer &Lex,
return formatter.format();
}
+LangOptions getFormattingLangOpts() {
+ LangOptions LangOpts;
+ LangOpts.CPlusPlus = 1;
+ LangOpts.CPlusPlus11 = 1;
+ LangOpts.Bool = 1;
+ LangOpts.ObjC1 = 1;
+ LangOpts.ObjC2 = 1;
+ return LangOpts;
+}
+
} // namespace format
} // namespace clang
diff --git a/test/Index/comment-c-decls.c b/test/Index/comment-c-decls.c
index f6d3feec81..261481a5ea 100644
--- a/test/Index/comment-c-decls.c
+++ b/test/Index/comment-c-decls.c
@@ -95,10 +95,10 @@ enum e {
*\brief block declaration
*/
int (^Block) (int i, int j);
-// CHECK: <Declaration>int (^Block) (int, int)</Declaration>
+// CHECK: <Declaration>int (^Block)(int, int)</Declaration>
/**
*\brief block declaration
*/
int (^Block1) (int i, int j) = ^(int i, int j) { return i + j; };
-// CHECK: <Declaration>int (^Block1) (int, int) = ^(int i, int j) {\n}</Declaration>
+// CHECK: <Declaration>int (^Block1)(int, int) = ^(int i, int j) {\n}</Declaration>
diff --git a/test/Index/format-comment-cdecls.c b/test/Index/format-comment-cdecls.c
index 31ec95b921..ff36dd7fd0 100644
--- a/test/Index/format-comment-cdecls.c
+++ b/test/Index/format-comment-cdecls.c
@@ -90,10 +90,10 @@ enum e {
*\brief block declaration
*/
int (^Block) (int i, int j);
-// CHECK: <Declaration>int (^Block) (int, int)</Declaration>
+// CHECK: <Declaration>int (^Block)(int, int)</Declaration>
/**
*\brief block declaration
*/
int (^Block1) (int i, int j) = ^(int i, int j) { return i + j; };
-// CHECK: <Declaration>int (^Block1) (int, int) = ^(int i, int j) {\n}</Declaration>
+// CHECK: <Declaration>int (^Block1)(int, int) = ^(int i, int j) {\n}</Declaration>
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 860661b432..39d8bb8f77 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -26,12 +26,8 @@ protected:
std::vector<CharSourceRange> Ranges(
1,
CharSourceRange::getCharRange(Start, Start.getLocWithOffset(Length)));
- LangOptions LangOpts;
- LangOpts.CPlusPlus = 1;
- LangOpts.CPlusPlus11 = 1;
- LangOpts.ObjC1 = 1;
- LangOpts.ObjC2 = 1;
- Lexer Lex(ID, Context.Sources.getBuffer(ID), Context.Sources, LangOpts);
+ Lexer Lex(ID, Context.Sources.getBuffer(ID), Context.Sources,
+ getFormattingLangOpts());
tooling::Replacements Replace = reformat(Style, Lex, Context.Sources,
Ranges);
EXPECT_TRUE(applyAllReplacements(Replace, Context.Rewrite));
@@ -1029,6 +1025,15 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyGoogleFormat("int a = b ? *c : *d;");
}
+TEST_F(FormatTest, FormatsFunctionTypes) {
+ // FIXME: Determine the cases that need a space after the return type and fix.
+ verifyFormat("A<bool()> a;");
+ verifyFormat("A<SomeType()> a;");
+ verifyFormat("A<void(*)(int, std::string)> a;");
+
+ verifyFormat("int(*func)(void *);");
+}
+
TEST_F(FormatTest, DoesNotBreakBeforePointerOrReference) {
verifyFormat("int *someFunction(int LoooooooooooooooongParam1,\n"
" int LoooooooooooooooongParam2) {\n}");
@@ -1177,8 +1182,8 @@ TEST_F(FormatTest, FormatForObjectiveCMethodDecls) {
}
TEST_F(FormatTest, FormatObjCBlocks) {
- verifyFormat("int (^Block) (int, int);");
- verifyFormat("int (^Block1) (int, int) = ^(int i, int j)");
+ verifyFormat("int (^Block)(int, int);");
+ verifyFormat("int (^Block1)(int, int) = ^(int i, int j)");
}
TEST_F(FormatTest, FormatObjCInterface) {