Improve handling of bool expressions in template arguments.

Now correctly formats:
  foo<true && false>();

llvm-svn: 204950
This commit is contained in:
Manuel Klimek 2014-03-27 19:00:52 +00:00
parent 8018e414bb
commit 1f9d80ac66
3 changed files with 17 additions and 3 deletions

View File

@ -282,6 +282,10 @@ struct FormatToken {
(!ColonRequired || (Next && Next->is(tok::colon)));
}
bool isLiteral() const {
return Tok.isLiteral() || isOneOf(tok::kw_true, tok::kw_false);
}
/// \brief Determine whether the token is a simple-type-specifier.
bool isSimpleTypeSpecifier() const;

View File

@ -67,7 +67,11 @@ private:
// parameters.
// FIXME: This is getting out of hand, write a decent parser.
if (CurrentToken->Previous->isOneOf(tok::pipepipe, tok::ampamp) &&
(CurrentToken->Previous->Type == TT_BinaryOperator ||
((CurrentToken->Previous->Type == TT_BinaryOperator &&
// Toplevel bool expressions do not make lots of sense;
// If we're on the top level, it contains only the base context and
// the context for the current opening angle bracket.
Contexts.size() > 2) ||
Contexts[Contexts.size() - 2].IsExpression) &&
Line.First->isNot(tok::kw_template))
return false;
@ -858,9 +862,9 @@ private:
PrevToken->MatchingParen->Previous->is(tok::kw_typeof))
return TT_PointerOrReference;
if (PrevToken->Tok.isLiteral() ||
if (PrevToken->isLiteral() ||
PrevToken->isOneOf(tok::r_paren, tok::r_square) ||
NextToken->Tok.isLiteral() || NextToken->isUnaryOperator() ||
NextToken->isLiteral() || NextToken->isUnaryOperator() ||
// If we know we're in a template argument, there are no named
// declarations. Thus, having an identifier on the right-hand side
// indicates a binary operator.

View File

@ -4537,6 +4537,12 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyFormat("vector<int *const **const *> v;");
verifyFormat("vector<int *volatile> v;");
verifyFormat("vector<a * b> v;");
verifyFormat("foo<b && false>();");
verifyFormat("foo<b & 1>();");
// FIXME: We cannot handle this case yet; we might be able to figure out that
// foo<x> d > v; doesn't make sense.
verifyFormat("foo<a < b && c> d > v;");
}
TEST_F(FormatTest, UnderstandsAttributes) {