From c5c4bacda9c54b600a5ae7bd6d9701a401f37bad Mon Sep 17 00:00:00 2001
From: Christian Kamm <christian.d.kamm@nokia.com>
Date: Wed, 1 Dec 2010 10:19:53 +0100
Subject: [PATCH] C++ indenter: Fix labels.

Reviewed-by: Roberto Raggi
---
 src/plugins/cpptools/cppcodeformatter.cpp     | 20 +++++++++++++++++++
 src/plugins/cpptools/cppcodeformatter.h       |  1 +
 .../codeformatter/tst_codeformatter.cpp       | 16 +++++++++++++++
 3 files changed, 37 insertions(+)

diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp
index f46f469e53f..c744d292a4b 100644
--- a/src/plugins/cpptools/cppcodeformatter.cpp
+++ b/src/plugins/cpptools/cppcodeformatter.cpp
@@ -382,6 +382,12 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
             default:            leave(); continue;
             } break;
 
+        case label:
+            switch (kind) {
+            case T_COLON:       leave(); break;
+            default:            leave(); continue; // shouldn't happen
+            } break;
+
         case multiline_comment_start:
         case multiline_comment_cont:
             if (kind != T_COMMENT && kind != T_DOXY_COMMENT) {
@@ -710,6 +716,10 @@ bool CodeFormatter::tryDeclaration()
                 enter(qt_like_macro);
                 return true;
             }
+            if (m_tokens.size() > 1 && m_tokens.at(1).kind() == T_COLON) {
+                enter(label);
+                return true;
+            }
         }
         // fallthrough
     case T_CHAR:
@@ -1428,6 +1438,16 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
                 *indentDepth = 0;
         }
         break;
+    case T_IDENTIFIER:
+        if (topState.type == substatement
+                || topState.type == substatement_open
+                || topState.type == case_cont
+                || topState.type == block_open
+                || topState.type == defun_open) {
+            if (tokens.size() > 1 && tokens.at(1).kind() == T_COLON) // label?
+                *indentDepth = 0;
+        }
+        break;
     }
 }
 
diff --git a/src/plugins/cpptools/cppcodeformatter.h b/src/plugins/cpptools/cppcodeformatter.h
index fa306d2c340..e828b7b7db6 100644
--- a/src/plugins/cpptools/cppcodeformatter.h
+++ b/src/plugins/cpptools/cppcodeformatter.h
@@ -112,6 +112,7 @@ public: // must be public to make Q_GADGET introspection work
         cpp_macro_cont, // Subsequent lines of a multi-line C preprocessor macro definition.
         cpp_macro_conditional, // Special marker used for separating saved from current state when dealing with #ifdef
         qt_like_macro, // after an identifier starting with Q_ or QT_ at the beginning of the line
+        label, // after an identifier followed by a colon
 
         defun_open, // Brace that opens a top-level function definition.
         using_start, // right after the "using" token
diff --git a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
index 6c0dd5eff32..3122b5d22c9 100644
--- a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
+++ b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
@@ -57,6 +57,7 @@ private Q_SLOTS:
     void gnuStyleSwitch();
     void whitesmithsStyleSwitch();
     void indentToNextToken();
+    void labels();
 };
 
 struct Line {
@@ -1116,6 +1117,21 @@ void tst_CodeFormatter::indentToNextToken()
     checkIndent(data);
 }
 
+void tst_CodeFormatter::labels()
+{
+    QList<Line> data;
+    data << Line("void foo() {")
+         << Line("lab:")
+         << Line("    int abc;")
+         << Line("def:")
+         << Line("    if (a)")
+         << Line("boo:")
+         << Line("        foo;")
+         << Line("    int j;")
+         ;
+    checkIndent(data);
+}
+
 QTEST_APPLESS_MAIN(tst_CodeFormatter)
 #include "tst_codeformatter.moc"
 
-- 
GitLab