[clang] 56fa7d1 - [clang-format] Fix formatting of _Atomic() qualifier
Alex Richardson via cfe-commits
cfe-commits at lists.llvm.org
Mon Sep 7 02:09:37 PDT 2020
Author: Alex Richardson
Date: 2020-09-07T10:09:18+01:00
New Revision: 56fa7d1dc6a8d23111ff84171036f333cf9cddf2
URL: https://github.com/llvm/llvm-project/commit/56fa7d1dc6a8d23111ff84171036f333cf9cddf2
DIFF: https://github.com/llvm/llvm-project/commit/56fa7d1dc6a8d23111ff84171036f333cf9cddf2.diff
LOG: [clang-format] Fix formatting of _Atomic() qualifier
Before: _Atomic(uint64_t) * a;
After: _Atomic(uint64_t) *a;
This treats _Atomic the same as the the TypenameMacros and decltype. It
also allows some cleanup by removing checks whether the token before a
paren is kw_decltype and instead checking for TT_TypeDeclarationParen.
While touching this code also extend the decltype test cases to also check
for typeof() and _Atomic(T).
Reviewed By: MyDeveloperDay
Differential Revision: https://reviews.llvm.org/D86959
Added:
Modified:
clang/lib/Format/FormatToken.cpp
clang/lib/Format/FormatToken.h
clang/lib/Format/TokenAnnotator.cpp
clang/unittests/Format/FormatTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Format/FormatToken.cpp b/clang/lib/Format/FormatToken.cpp
index 4bc865b043fd..8e4994f4c0d5 100644
--- a/clang/lib/Format/FormatToken.cpp
+++ b/clang/lib/Format/FormatToken.cpp
@@ -62,6 +62,7 @@ bool FormatToken::isSimpleTypeSpecifier() const {
case tok::kw_char32_t:
case tok::kw_typeof:
case tok::kw_decltype:
+ case tok::kw__Atomic:
return true;
default:
return false;
diff --git a/clang/lib/Format/FormatToken.h b/clang/lib/Format/FormatToken.h
index a9aeef5e9e52..8253bf18fc66 100644
--- a/clang/lib/Format/FormatToken.h
+++ b/clang/lib/Format/FormatToken.h
@@ -101,8 +101,8 @@ namespace format {
TYPE(TrailingAnnotation) \
TYPE(TrailingReturnArrow) \
TYPE(TrailingUnaryOperator) \
+ TYPE(TypeDeclarationParen) \
TYPE(TypenameMacro) \
- TYPE(TypenameMacroParen) \
TYPE(UnaryOperator) \
TYPE(UntouchableMacroFunc) \
TYPE(CSharpStringLiteral) \
@@ -526,6 +526,7 @@ struct FormatToken {
case tok::kw_decltype:
case tok::kw_noexcept:
case tok::kw_static_assert:
+ case tok::kw__Atomic:
case tok::kw___attribute:
return true;
default:
diff --git a/clang/lib/Format/TokenAnnotator.cpp b/clang/lib/Format/TokenAnnotator.cpp
index 097843bdca84..0239dbd63d94 100644
--- a/clang/lib/Format/TokenAnnotator.cpp
+++ b/clang/lib/Format/TokenAnnotator.cpp
@@ -185,6 +185,8 @@ class AnnotatingParser {
if (!CurrentToken)
return false;
FormatToken *Left = CurrentToken->Previous;
+ FormatToken *PrevNonComment =
+ Left ? Left->getPreviousNonComment() : nullptr;
Left->ParentBracket = Contexts.back().ContextKind;
ScopedContextCreator ContextCreator(*this, tok::l_paren, 1);
@@ -216,9 +218,8 @@ class AnnotatingParser {
// export type X = (...);
Contexts.back().IsExpression = false;
} else if (Left->Previous &&
- (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_decltype,
- tok::kw_while, tok::l_paren,
- tok::comma) ||
+ (Left->Previous->isOneOf(tok::kw_static_assert, tok::kw_while,
+ tok::l_paren, tok::comma) ||
Left->Previous->isIf() ||
Left->Previous->is(TT_BinaryOperator))) {
// static_assert, if and while usually contain expressions.
@@ -242,10 +243,15 @@ class AnnotatingParser {
} else if (Contexts[Contexts.size() - 2].CaretFound) {
// This is the parameter list of an ObjC block.
Contexts.back().IsExpression = false;
- } else if (Left->Previous && Left->Previous->is(tok::kw___attribute)) {
+ } else if (PrevNonComment && PrevNonComment->is(tok::kw___attribute)) {
Left->setType(TT_AttributeParen);
- } else if (Left->Previous && Left->Previous->is(TT_TypenameMacro)) {
- Left->setType(TT_TypenameMacroParen);
+ } else if (PrevNonComment &&
+ PrevNonComment->isOneOf(TT_TypenameMacro, tok::kw_decltype,
+ tok::kw_typeof, tok::kw__Atomic)) {
+ Left->setType(TT_TypeDeclarationParen);
+ // decltype() and typeof() usually contain expressions.
+ if (PrevNonComment->isOneOf(tok::kw_decltype, tok::kw_typeof))
+ Contexts.back().IsExpression = true;
} else if (Left->Previous && Left->Previous->is(TT_ForEachMacro)) {
// The first argument to a foreach macro is a declaration.
Contexts.back().IsForEachMacro = true;
@@ -337,8 +343,8 @@ class AnnotatingParser {
if (Left->is(TT_AttributeParen))
CurrentToken->setType(TT_AttributeParen);
- if (Left->is(TT_TypenameMacroParen))
- CurrentToken->setType(TT_TypenameMacroParen);
+ if (Left->is(TT_TypeDeclarationParen))
+ CurrentToken->setType(TT_TypeDeclarationParen);
if (Left->Previous && Left->Previous->is(TT_JavaAnnotation))
CurrentToken->setType(TT_JavaAnnotation);
if (Left->Previous && Left->Previous->is(TT_LeadingJavaAnnotation))
@@ -944,9 +950,9 @@ class AnnotatingParser {
return false;
if (Line.MustBeDeclaration && Contexts.size() == 1 &&
!Contexts.back().IsExpression && !Line.startsWith(TT_ObjCProperty) &&
- (!Tok->Previous ||
- !Tok->Previous->isOneOf(tok::kw_decltype, tok::kw___attribute,
- TT_LeadingJavaAnnotation)))
+ !Tok->is(TT_TypeDeclarationParen) &&
+ (!Tok->Previous || !Tok->Previous->isOneOf(tok::kw___attribute,
+ TT_LeadingJavaAnnotation)))
Line.MightBeFunctionDecl = true;
break;
case tok::l_square:
@@ -1758,9 +1764,8 @@ class AnnotatingParser {
PreviousNotConst->MatchingParen->Previous->isNot(tok::period) &&
PreviousNotConst->MatchingParen->Previous->isNot(tok::kw_template);
- if (PreviousNotConst->is(tok::r_paren) && PreviousNotConst->MatchingParen &&
- PreviousNotConst->MatchingParen->Previous &&
- PreviousNotConst->MatchingParen->Previous->is(tok::kw_decltype))
+ if (PreviousNotConst->is(tok::r_paren) &&
+ PreviousNotConst->is(TT_TypeDeclarationParen))
return true;
return (!IsPPKeyword &&
@@ -1861,7 +1866,7 @@ class AnnotatingParser {
};
bool ParensAreType =
!Tok.Previous ||
- Tok.Previous->isOneOf(TT_TemplateCloser, TT_TypenameMacroParen) ||
+ Tok.Previous->isOneOf(TT_TemplateCloser, TT_TypeDeclarationParen) ||
Tok.Previous->isSimpleTypeSpecifier() ||
IsQualifiedPointerOrReference(Tok.Previous);
bool ParensCouldEndDecl =
@@ -1931,6 +1936,9 @@ class AnnotatingParser {
if (PrevToken->is(tok::coloncolon))
return TT_PointerOrReference;
+ if (PrevToken->is(tok::r_paren) && PrevToken->is(TT_TypeDeclarationParen))
+ return TT_PointerOrReference;
+
if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
tok::comma, tok::semi, tok::kw_return, tok::colon,
tok::equal, tok::kw_delete, tok::kw_sizeof,
@@ -1946,15 +1954,6 @@ class AnnotatingParser {
if (NextToken->isOneOf(tok::comma, tok::semi))
return TT_PointerOrReference;
- if (PrevToken->is(tok::r_paren) && PrevToken->MatchingParen) {
- FormatToken *TokenBeforeMatchingParen =
- PrevToken->MatchingParen->getPreviousNonComment();
- if (TokenBeforeMatchingParen &&
- TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype,
- TT_TypenameMacro))
- return TT_PointerOrReference;
- }
-
if (PrevToken->Tok.isLiteral() ||
PrevToken->isOneOf(tok::r_paren, tok::r_square, tok::kw_true,
tok::kw_false, tok::r_brace) ||
@@ -2848,9 +2847,7 @@ bool TokenAnnotator::spaceRequiredBetween(const AnnotatedLine &Line,
return true;
FormatToken *TokenBeforeMatchingParen =
Left.MatchingParen->getPreviousNonComment();
- if (!TokenBeforeMatchingParen ||
- !TokenBeforeMatchingParen->isOneOf(tok::kw_typeof, tok::kw_decltype,
- TT_TypenameMacro))
+ if (!TokenBeforeMatchingParen || !Left.is(TT_TypeDeclarationParen))
return true;
}
return (Left.Tok.isLiteral() ||
@@ -3948,7 +3945,8 @@ bool TokenAnnotator::canBreakBefore(const AnnotatedLine &Line,
if (Left.is(tok::equal) && Right.is(tok::l_brace) &&
!Style.Cpp11BracedListStyle)
return false;
- if (Left.is(tok::l_paren) && Left.is(TT_AttributeParen))
+ if (Left.is(tok::l_paren) &&
+ Left.isOneOf(TT_AttributeParen, TT_TypeDeclarationParen))
return false;
if (Left.is(tok::l_paren) && Left.Previous &&
(Left.Previous->isOneOf(TT_BinaryOperator, TT_CastRParen)))
diff --git a/clang/unittests/Format/FormatTest.cpp b/clang/unittests/Format/FormatTest.cpp
index 978c22c6ee69..a5943847882f 100644
--- a/clang/unittests/Format/FormatTest.cpp
+++ b/clang/unittests/Format/FormatTest.cpp
@@ -168,6 +168,8 @@ TEST_F(FormatTest, NestedNameSpecifiers) {
verifyFormat("vector<::Type> v;");
verifyFormat("::ns::SomeFunction(::ns::SomeOtherFunction())");
verifyFormat("static constexpr bool Bar = decltype(bar())::value;");
+ verifyFormat("static constexpr bool Bar = typeof(bar())::value;");
+ verifyFormat("static constexpr bool Bar = _Atomic(bar())::value;");
verifyFormat("bool a = 2 < ::SomeFunction();");
verifyFormat("ALWAYS_INLINE ::std::string getName();");
verifyFormat("some::string getName();");
@@ -7904,7 +7906,10 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyFormat("auto PointerBinding = [](const char *S) {};");
verifyFormat("typedef typeof(int(int, int)) *MyFunc;");
verifyFormat("[](const decltype(*a) &value) {}");
+ verifyFormat("[](const typeof(*a) &value) {}");
+ verifyFormat("[](const _Atomic(a *) &value) {}");
verifyFormat("decltype(a * b) F();");
+ verifyFormat("typeof(a * b) F();");
verifyFormat("#define MACRO() [](A *a) { return 1; }");
verifyFormat("Constructor() : member([](A *a, B *b) {}) {}");
verifyIndependentOfContext("typedef void (*f)(int *a);");
@@ -7970,6 +7975,8 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyFormat("delete *x;", Left);
verifyFormat("typedef typeof(int(int, int))* MyFuncPtr;", Left);
verifyFormat("[](const decltype(*a)* ptr) {}", Left);
+ verifyFormat("[](const typeof(*a)* ptr) {}", Left);
+ verifyFormat("[](const _Atomic(a*)* ptr) {}", Left);
verifyFormat("typedef typeof /*comment*/ (int(int, int))* MyFuncPtr;", Left);
verifyFormat("auto x(A&&, B&&, C&&) -> D;", Left);
verifyFormat("auto x = [](A&&, B&&, C&&) -> D {};", Left);
@@ -8066,6 +8073,8 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyFormat("foo<b && false>();");
verifyFormat("foo<b & 1>();");
verifyFormat("decltype(*::std::declval<const T &>()) void F();");
+ verifyFormat("typeof(*::std::declval<const T &>()) void F();");
+ verifyFormat("_Atomic(*::std::declval<const T &>()) void F();");
verifyFormat(
"template <class T, class = typename std::enable_if<\n"
" std::is_integral<T>::value &&\n"
@@ -8089,6 +8098,9 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyIndependentOfContext("MACRO(int *i);");
verifyIndependentOfContext("MACRO(auto *a);");
verifyIndependentOfContext("MACRO(const A *a);");
+ verifyIndependentOfContext("MACRO(_Atomic(A) *a);");
+ verifyIndependentOfContext("MACRO(decltype(A) *a);");
+ verifyIndependentOfContext("MACRO(typeof(A) *a);");
verifyIndependentOfContext("MACRO(A *const a);");
verifyIndependentOfContext("MACRO(A *restrict a);");
verifyIndependentOfContext("MACRO(A *__restrict__ a);");
@@ -8639,6 +8651,10 @@ TEST_F(FormatTest, BreaksLongDeclarations) {
"LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
verifyFormat("decltype(LoooooooooooooooooooooooooooooooooooooooongName)\n"
"LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
+ verifyFormat("typeof(LoooooooooooooooooooooooooooooooooooooooooongName)\n"
+ "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
+ verifyFormat("_Atomic(LooooooooooooooooooooooooooooooooooooooooongName)\n"
+ "LooooooooooooooooooooooooooooooooooongFunctionDefinition() {}");
verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
"LooooooooooooooooooooooooooongFunctionDeclaration(T... t);");
verifyFormat("LoooooooooooooooooooooooooooooooooooooooongReturnType\n"
@@ -8988,6 +9004,8 @@ TEST_F(FormatTest, LayoutCxx11BraceInitializers) {
verifyFormat("int foo(int i) { return fo1{}(i); }");
verifyFormat("int foo(int i) { return fo1{}(i); }");
verifyFormat("auto i = decltype(x){};");
+ verifyFormat("auto i = typeof(x){};");
+ verifyFormat("auto i = _Atomic(x){};");
verifyFormat("std::vector<int> v = {1, 0 /* comment */};");
verifyFormat("Node n{1, Node{1000}, //\n"
" 2};");
@@ -11580,6 +11598,8 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
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("auto f(int x) -> typeof(x);", NoSpace);
+ verifyFormat("auto f(int x) -> _Atomic(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);
@@ -11628,6 +11648,8 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
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("auto f (int x) -> typeof (x);", Space);
+ verifyFormat("auto f (int x) -> _Atomic (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);
@@ -11680,6 +11702,8 @@ TEST_F(FormatTest, ConfigurableSpaceBeforeParens) {
verifyFormat("auto i = std::make_unique<int> (5);", SomeSpace);
verifyFormat("size_t x = sizeof (x);", SomeSpace);
verifyFormat("auto f (int x) -> decltype (x);", SomeSpace);
+ verifyFormat("auto f (int x) -> typeof (x);", SomeSpace);
+ verifyFormat("auto f (int x) -> _Atomic (x);", SomeSpace);
verifyFormat("int f (T x) noexcept (x.create());", SomeSpace);
verifyFormat("alignas (128) char a[128];", SomeSpace);
verifyFormat("size_t x = alignof (MyType);", SomeSpace);
@@ -14934,6 +14958,8 @@ TEST_F(FormatTest, FormatsLambdas) {
"});"));
verifyFormat("void f() {\n"
" SomeFunction([](decltype(x), A *a) {});\n"
+ " SomeFunction([](typeof(x), A *a) {});\n"
+ " SomeFunction([](_Atomic(x), A *a) {});\n"
"}");
verifyFormat("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa(\n"
" [](const aaaaaaaaaa &a) { return a; });");
@@ -16575,6 +16601,45 @@ TEST_F(FormatTest, TypenameMacros) {
verifyFormat("vector<STACK_OF(uint64_t)* attr> x;", Macros);
}
+TEST_F(FormatTest, AtomicQualifier) {
+ // Check that we treate _Atomic as a type and not a function call
+ FormatStyle Google = getGoogleStyleWithColumns(0);
+ verifyFormat("struct foo {\n"
+ " int a1;\n"
+ " _Atomic(a) a2;\n"
+ " _Atomic(_Atomic(int) *const) a3;\n"
+ "};",
+ Google);
+ verifyFormat("_Atomic(uint64_t) a;");
+ verifyFormat("_Atomic(uint64_t) *a;");
+ verifyFormat("_Atomic(uint64_t const *) *a;");
+ verifyFormat("_Atomic(uint64_t *const) *a;");
+ verifyFormat("_Atomic(const uint64_t *) *a;");
+ verifyFormat("_Atomic(uint64_t) a;");
+ verifyFormat("_Atomic(_Atomic(uint64_t)) a;");
+ verifyFormat("_Atomic(_Atomic(uint64_t)) a, b;");
+ verifyFormat("for (_Atomic(uint64_t) *a = NULL; a;) {\n}");
+ verifyFormat("_Atomic(uint64_t) f(_Atomic(uint64_t) *arg);");
+
+ verifyFormat("_Atomic(uint64_t) *s(InitValue);");
+ verifyFormat("_Atomic(uint64_t) *s{InitValue};");
+ FormatStyle Style = getLLVMStyle();
+ Style.PointerAlignment = FormatStyle::PAS_Left;
+ verifyFormat("_Atomic(uint64_t)* s(InitValue);", Style);
+ verifyFormat("_Atomic(uint64_t)* s{InitValue};", Style);
+ verifyFormat("_Atomic(int)* a;", Style);
+ verifyFormat("_Atomic(int*)* a;", Style);
+ verifyFormat("vector<_Atomic(uint64_t)* attr> x;", Style);
+
+ Style.SpacesInCStyleCastParentheses = true;
+ Style.SpacesInParentheses = false;
+ verifyFormat("x = ( _Atomic(uint64_t) )*a;", Style);
+ Style.SpacesInCStyleCastParentheses = false;
+ Style.SpacesInParentheses = true;
+ verifyFormat("x = (_Atomic( uint64_t ))*a;", Style);
+ verifyFormat("x = (_Atomic( uint64_t ))&a;", Style);
+}
+
TEST_F(FormatTest, AmbersandInLamda) {
// Test case reported in https://bugs.llvm.org/show_bug.cgi?id=41899
FormatStyle AlignStyle = getLLVMStyle();
More information about the cfe-commits
mailing list