diff options
author | Daniel Jasper <djasper@google.com> | 2013-01-10 13:08:12 +0000 |
---|---|---|
committer | Daniel Jasper <djasper@google.com> | 2013-01-10 13:08:12 +0000 |
commit | 46ef852618b18bc79e403b37a12c9b692e76126b (patch) | |
tree | 0f056c2efc19968c4dca28215efbcbda6892fd2a | |
parent | e1d792f0ee02b5beb4b8e94506b3a0c353df43dd (diff) |
Improvements to function type and ObjC block formatting.
Before: int (^myBlock) (int) = ^(int num) {}
A<void ()>;
int (*b)(int);
After: int (^myBlock)(int) = ^(int num) {}
A<void()>;
int(*b)(int);
For function types and function pointer types, this patch only makes
the behavior consistent (for types that are keywords and other types).
For the latter function pointer type declarations, we'll probably
want to add a space after "int".
Also added LangOpts.Bool = 1, so we handle "A<bool()>" appropriately
Moved the LangOpts-settings to a public place for use by tests
and clang-format binary.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@172065 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Format/Format.h | 3 | ||||
-rw-r--r-- | lib/Format/Format.cpp | 23 | ||||
-rw-r--r-- | test/Index/comment-c-decls.c | 4 | ||||
-rw-r--r-- | test/Index/format-comment-cdecls.c | 4 | ||||
-rw-r--r-- | unittests/Format/FormatTest.cpp | 21 |
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) { |