r189108 - clang-format: Fix indentation relative to unary expressions.
Daniel Jasper
djasper at google.com
Fri Aug 23 08:14:03 PDT 2013
Author: djasper
Date: Fri Aug 23 10:14:03 2013
New Revision: 189108
URL: http://llvm.org/viewvc/llvm-project?rev=189108&view=rev
Log:
clang-format: Fix indentation relative to unary expressions.
This should be done, only if we are still in the unary expression's
scope.
Before:
bool aaaa = !aaaaaaaa( // break
aaaaaaaaaaa);
*aaaaaa = aaaaaaa( // break
aaaaaaaaaaaaaaaa);
After:
bool aaaa = !aaaaaaaa( // break
aaaaaaaaaaa); // <- (unchanged)
*aaaaaa = aaaaaaa( // break
aaaaaaaaaaaaaaaa); // <- (no longer indented relative to "*")
Modified:
cfe/trunk/lib/Format/TokenAnnotator.cpp
cfe/trunk/unittests/Format/FormatTest.cpp
Modified: cfe/trunk/lib/Format/TokenAnnotator.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Format/TokenAnnotator.cpp?rev=189108&r1=189107&r2=189108&view=diff
==============================================================================
--- cfe/trunk/lib/Format/TokenAnnotator.cpp (original)
+++ cfe/trunk/lib/Format/TokenAnnotator.cpp Fri Aug 23 10:14:03 2013
@@ -853,13 +853,21 @@ public:
/// \brief Parse expressions with the given operatore precedence.
void parse(int Precedence = 0) {
+ if (Current == NULL)
+ return;
+
// Conditional expressions need to be parsed separately for proper nesting.
if (Precedence == prec::Conditional + 1) {
parseConditionalExpr();
return;
}
- if (Precedence > prec::PointerToMember || Current == NULL)
+
+ // Parse unary operators, which all have a higher precedence than binary
+ // operators.
+ if (Precedence > prec::PointerToMember) {
+ parseUnaryOperator();
return;
+ }
FormatToken *Start = Current;
bool OperatorFound = false;
@@ -868,20 +876,11 @@ public:
// Consume operators with higher precedence.
parse(Precedence + 1);
- int CurrentPrecedence = 0;
- if (Current) {
- if (Current->Type == TT_ConditionalExpr)
- CurrentPrecedence = 1 + (int)prec::Conditional;
- else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon)
- CurrentPrecedence = 1;
- else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma))
- CurrentPrecedence = 1 + (int)Current->getPrecedence();
- else if (Current->Type == TT_ObjCSelectorName) {
- CurrentPrecedence = 1 + (int)prec::Assignment;
- if (Precedence == CurrentPrecedence)
- Start = Current;
- }
- }
+ int CurrentPrecedence = getCurrentPrecedence();
+
+ if (Current && Current->Type == TT_ObjCSelectorName &&
+ Precedence == CurrentPrecedence)
+ Start = Current;
// At the end of the line or when an operator with higher precedence is
// found, insert fake parenthesis and return.
@@ -910,12 +909,54 @@ public:
}
private:
+ /// \brief Gets the precedence (+1) of the given token for binary operators
+ /// and other tokens that we treat like binary operators.
+ int getCurrentPrecedence() {
+ if (Current) {
+ if (Current->Type == TT_ConditionalExpr)
+ return 1 + (int)prec::Conditional;
+ else if (Current->is(tok::semi) || Current->Type == TT_InlineASMColon)
+ return 1;
+ else if (Current->Type == TT_BinaryOperator || Current->is(tok::comma))
+ return 1 + (int)Current->getPrecedence();
+ else if (Current->Type == TT_ObjCSelectorName)
+ return 1 + (int)prec::Assignment;
+ }
+ return 0;
+ }
+
void addFakeParenthesis(FormatToken *Start, prec::Level Precedence) {
Start->FakeLParens.push_back(Precedence);
if (Current)
++Current->Previous->FakeRParens;
}
+ /// \brief Parse unary operator expressions and surround them with fake
+ /// parentheses if appropriate.
+ void parseUnaryOperator() {
+ if (Current == NULL || Current->Type != TT_UnaryOperator)
+ return;
+
+ FormatToken *Start = Current;
+ next();
+
+ while (Current) {
+ if (Current->opensScope()) {
+ while (Current && !Current->closesScope()) {
+ next();
+ parse();
+ }
+ next();
+ } else if (getCurrentPrecedence() == 0 && !Current->closesScope()) {
+ next();
+ } else {
+ break;
+ }
+ }
+ // The actual precedence doesn't matter.
+ addFakeParenthesis(Start, prec::Level(0));
+ }
+
void parseConditionalExpr() {
FormatToken *Start = Current;
parse(prec::LogicalOr + 1);
Modified: cfe/trunk/unittests/Format/FormatTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/Format/FormatTest.cpp?rev=189108&r1=189107&r2=189108&view=diff
==============================================================================
--- cfe/trunk/unittests/Format/FormatTest.cpp (original)
+++ cfe/trunk/unittests/Format/FormatTest.cpp Fri Aug 23 10:14:03 2013
@@ -3524,6 +3524,10 @@ TEST_F(FormatTest, IndentsRelativeToUnar
"}");
verifyFormat("aaaaaaaaaa(!aaaaaaaaaa( // break\n"
" aaaaa));");
+
+ // Only indent relative to unary operators if the expression is nested.
+ verifyFormat("*aaa = aaaaaaa( // break\n"
+ " bbbbbb);");
}
TEST_F(FormatTest, UndestandsOverloadedOperators) {
More information about the cfe-commits
mailing list