clang-format: Enable formatting of lambdas with explicit return type.

So clang-format can now format:

  int c = []()->int { return 2; }();
  int c = []()->vector<int> { return { 2 }; }();

llvm-svn: 199368
This commit is contained in:
Daniel Jasper 2014-01-16 09:11:55 +00:00
parent 157d911b42
commit cb51cf409b
5 changed files with 47 additions and 34 deletions

View File

@ -22,6 +22,36 @@
namespace clang {
namespace format {
// FIXME: This is copy&pasted from Sema. Put it in a common place and remove
// duplication.
bool FormatToken::isSimpleTypeSpecifier() const {
switch (Tok.getKind()) {
case tok::kw_short:
case tok::kw_long:
case tok::kw___int64:
case tok::kw___int128:
case tok::kw_signed:
case tok::kw_unsigned:
case tok::kw_void:
case tok::kw_char:
case tok::kw_int:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
case tok::kw_wchar_t:
case tok::kw_bool:
case tok::kw___underlying_type:
case tok::annot_typename:
case tok::kw_char16_t:
case tok::kw_char32_t:
case tok::kw_typeof:
case tok::kw_decltype:
return true;
default:
return false;
}
}
TokenRole::~TokenRole() {}
void TokenRole::precomputeFormattingInfos(const FormatToken *Token) {}

View File

@ -280,6 +280,9 @@ struct FormatToken {
(!ColonRequired || (Next && Next->is(tok::colon)));
}
/// \brief Determine whether the token is a simple-type-specifier.
bool isSimpleTypeSpecifier() const;
bool isObjCAccessSpecifier() const {
return is(tok::at) && Next && (Next->isObjCAtKeyword(tok::objc_public) ||
Next->isObjCAtKeyword(tok::objc_protected) ||

View File

@ -697,7 +697,7 @@ private:
bool ParensAreType = !Current.Previous ||
Current.Previous->Type == TT_PointerOrReference ||
Current.Previous->Type == TT_TemplateCloser ||
isSimpleTypeSpecifier(*Current.Previous);
Current.Previous->isSimpleTypeSpecifier();
bool ParensCouldEndDecl =
Current.Next &&
Current.Next->isOneOf(tok::equal, tok::semi, tok::l_brace);
@ -778,7 +778,7 @@ private:
return (!IsPPKeyword && PreviousNotConst->is(tok::identifier)) ||
PreviousNotConst->Type == TT_PointerOrReference ||
isSimpleTypeSpecifier(*PreviousNotConst);
PreviousNotConst->isSimpleTypeSpecifier();
}
/// \brief Return the type of the given token assuming it is * or &.
@ -853,36 +853,6 @@ private:
return TT_UnaryOperator;
}
// FIXME: This is copy&pasted from Sema. Put it in a common place and remove
// duplication.
/// \brief Determine whether the token kind starts a simple-type-specifier.
bool isSimpleTypeSpecifier(const FormatToken &Tok) const {
switch (Tok.Tok.getKind()) {
case tok::kw_short:
case tok::kw_long:
case tok::kw___int64:
case tok::kw___int128:
case tok::kw_signed:
case tok::kw_unsigned:
case tok::kw_void:
case tok::kw_char:
case tok::kw_int:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
case tok::kw_wchar_t:
case tok::kw_bool:
case tok::kw___underlying_type:
case tok::annot_typename:
case tok::kw_char16_t:
case tok::kw_char32_t:
case tok::kw_typeof:
case tok::kw_decltype:
return true;
default:
return false;
}
}
SmallVector<Context, 8> Contexts;

View File

@ -762,15 +762,22 @@ bool UnwrappedLineParser::tryToParseLambda() {
if (!tryToParseLambdaIntroducer())
return false;
while (FormatTok->isNot(tok::l_brace)) {
while (FormatTok && FormatTok->isNot(tok::l_brace)) {
if (FormatTok->isSimpleTypeSpecifier()) {
nextToken();
continue;
}
switch (FormatTok->Tok.getKind()) {
case tok::l_brace:
break;
case tok::l_paren:
parseParens();
break;
case tok::less:
case tok::greater:
case tok::identifier:
case tok::kw_mutable:
case tok::arrow:
nextToken();
break;
default:
@ -956,7 +963,6 @@ void UnwrappedLineParser::parseSquare() {
if (tryToParseLambda())
return;
do {
// llvm::errs() << FormatTok->Tok.getName() << "\n";
switch (FormatTok->Tok.getKind()) {
case tok::l_paren:
parseParens();

View File

@ -7890,6 +7890,10 @@ TEST_F(FormatTest, FormatsLambdas) {
" [&](int, int) { return 1; });\n"
"}\n");
// Lambdas with return types.
verifyFormat("int c = []()->int { return 2; }();\n");
verifyFormat("int c = []()->vector<int> { return { 2 }; }();\n");
// Not lambdas.
verifyFormat("constexpr char hello[]{ \"hello\" };");
verifyFormat("double &operator[](int i) { return 0; }\n"