clang-format: Correct SBPO_Always-behavior after function-like keywords

Before:
  auto f (int x) -> decltype(x) { return sizeof(x); }
  int g () noexcept(someCall ());
  static_assert(sizeof(char) == 1, "Your compiler is broken");

After:
  auto f (int x) -> decltype (x) { return sizeof (x); }
  int g () noexcept (someCall ());
  static_assert (sizeof (char) == 1, "Your compiler is broken");

This fixes llvm.org/PR20559.
Patch by Roman Kashitsyn, thank you!

llvm-svn: 214969
This commit is contained in:
Daniel Jasper 2014-08-06 14:15:41 +00:00
parent ce5377afa0
commit 78b1949950
3 changed files with 35 additions and 1 deletions

View File

@ -353,6 +353,26 @@ struct FormatToken {
return is(tok::comment) && (!Next || Next->NewlinesBefore > 0);
}
/// \brief Returns \c true if this is a keyword that can be used
/// like a function call (e.g. sizeof, typeid, ...).
bool isFunctionLikeKeyword() const {
switch (Tok.getKind()) {
case tok::kw_throw:
case tok::kw_typeid:
case tok::kw_return:
case tok::kw_sizeof:
case tok::kw_alignof:
case tok::kw_alignas:
case tok::kw_decltype:
case tok::kw_noexcept:
case tok::kw_static_assert:
case tok::kw___attribute:
return true;
default:
return false;
}
}
prec::Level getPrecedence() const {
return getBinOpPrecedence(Tok.getKind(), true, true);
}

View File

@ -1549,7 +1549,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
tok::kw_switch, tok::kw_catch, tok::kw_case) ||
Left.IsForEachMacro)) ||
(Style.SpaceBeforeParens == FormatStyle::SBPO_Always &&
Left.isOneOf(tok::identifier, tok::kw___attribute) &&
(Left.is(tok::identifier) || Left.isFunctionLikeKeyword()) &&
Line.Type != LT_PreprocessorDirective);
}
if (Left.is(tok::at) && Right.Tok.getObjCKeywordID() != tok::objc_not_keyword)

View File

@ -7544,6 +7544,13 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
" break;\n"
"}", NoSpace);
verifyFormat("auto i = std::make_unique<int>(5);", NoSpace);
verifyFormat("size_t x = sizeof(x);", NoSpace);
verifyFormat("auto f(int x) -> decltype(x);", NoSpace);
verifyFormat("int f(T x) noexcept(x.create());", NoSpace);
verifyFormat("alignas(128) char a[128];", NoSpace);
verifyFormat("size_t x = alignof(MyType);", NoSpace);
verifyFormat("static_assert(sizeof(char) == 1, \"Impossible!\");", NoSpace);
verifyFormat("int f() throw(Deprecated);", NoSpace);
FormatStyle Space = getLLVMStyle();
Space.SpaceBeforeParens = FormatStyle::SBPO_Always;
@ -7581,6 +7588,13 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
"#endif",
Space);
verifyFormat("auto i = std::make_unique<int> (5);", Space);
verifyFormat("size_t x = sizeof (x);", Space);
verifyFormat("auto f (int x) -> decltype (x);", Space);
verifyFormat("int f (T x) noexcept (x.create ());", Space);
verifyFormat("alignas (128) char a[128];", Space);
verifyFormat("size_t x = alignof (MyType);", Space);
verifyFormat("static_assert (sizeof (char) == 1, \"Impossible!\");", Space);
verifyFormat("int f () throw (Deprecated);", Space);
}
TEST_F(FormatTest, ConfigurableSpacesInParentheses) {