diff --git a/src/plugins/cpptools/cppcodeformatter.cpp b/src/plugins/cpptools/cppcodeformatter.cpp
index 33aa6aedefd445ad01824aac552336fc4d733837..fecee6d04361712b66d6fd06b757f2a2f53bcb3b 100644
--- a/src/plugins/cpptools/cppcodeformatter.cpp
+++ b/src/plugins/cpptools/cppcodeformatter.cpp
@@ -107,6 +107,20 @@ void CodeFormatter::recalculateStateAfter(const QTextBlock &block)
             case T_RBRACE:      leave(); continue; // always nested in namespace_start
             } break;
 
+        case extern_start:
+            switch (kind) {
+            case T_STRING_LITERAL: break; // continue looking for the lbrace
+            case T_LBRACE:      enter(extern_open); break;
+            default:            leave(); continue;
+            } break;
+
+        case extern_open:
+            if (tryDeclaration())
+                break;
+            switch (kind) {
+            case T_RBRACE:      leave(); leave(); break; // always nested in extern_start
+            } break;
+
         case class_start:
             switch (kind) {
             case T_SEMICOLON:   leave(); break;
@@ -680,6 +694,7 @@ bool CodeFormatter::tryExpression(bool alsoExpression)
                     || type == substatement_open
                     || type == defun_open
                     || type == namespace_open
+                    || type == extern_open
                     || type == class_open
                     || type == brace_list_open) {
                 break;
@@ -759,6 +774,10 @@ bool CodeFormatter::tryDeclaration()
         enter(namespace_start);
         return true;
 
+    case T_EXTERN:
+        enter(extern_start);
+        return true;
+
     case T_STRUCT:
     case T_UNION:
     case T_CLASS:
@@ -1067,6 +1086,7 @@ void QtStyleCodeFormatter::onEnter(int newState, int *indentDepth, int *savedInd
         *paddingDepth = 0;
 
     switch (newState) {
+    case extern_start:
     case namespace_start:
         if (firstToken) {
             *savedIndentDepth = tokenPosition;
@@ -1364,6 +1384,7 @@ void QtStyleCodeFormatter::adjustIndent(const QList<CPlusPlus::Token> &tokens, i
             const int type = state(i).type;
             if (type == class_open
                     || type == namespace_open
+                    || type == extern_open
                     || type == enum_open
                     || type == defun_open) {
                 *indentDepth = state(i).savedIndentDepth;
@@ -1468,6 +1489,8 @@ bool QtStyleCodeFormatter::shouldClearPaddingOnEnter(int state)
     case enum_open:
     case namespace_start:
     case namespace_open:
+    case extern_start:
+    case extern_open:
     case template_start:
     case if_statement:
     case else_clause:
diff --git a/src/plugins/cpptools/cppcodeformatter.h b/src/plugins/cpptools/cppcodeformatter.h
index 28f5dd62f8b19b3b9c3779f6da800fcc2d99415d..2a21d2ffc01084598c57c2f346d0637ab987ec50 100644
--- a/src/plugins/cpptools/cppcodeformatter.h
+++ b/src/plugins/cpptools/cppcodeformatter.h
@@ -134,6 +134,9 @@ public: // must be public to make Q_GADGET introspection work
         namespace_start, // after the namespace token, before the opening brace.
         namespace_open, // Brace that opens a C++ namespace block.
 
+        extern_start, // after the extern token, before the opening brace.
+        extern_open, // Brace that opens a C++ extern block.
+
         declaration_start, // shifted a token which could start a declaration.
         operator_declaration, // after 'operator' in declaration_start
 
diff --git a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
index d0c3ee811a0e3eb6770926087911ffc83993522b..ade32d8c2e98f278f4e08787a868c552e92279aa 100644
--- a/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
+++ b/tests/auto/cplusplus/codeformatter/tst_codeformatter.cpp
@@ -92,6 +92,7 @@ private Q_SLOTS:
     void indentToNextToken();
     void labels();
     void functionsWithExtraSpecifier();
+    void externSpec();
 };
 
 struct Line {
@@ -1192,6 +1193,22 @@ void tst_CodeFormatter::functionsWithExtraSpecifier()
     checkIndent(data);
 }
 
+void tst_CodeFormatter::externSpec()
+{
+    QList<Line> data;
+    data << Line("extern void foo() {}")
+         << Line("extern \"C\" {")
+         << Line("void foo() {}")
+         << Line("int a;")
+         << Line("class C {")
+         << Line("    int a;")
+         << Line("}")
+         << Line("}")
+         << Line("int a;")
+         ;
+    checkIndent(data);
+}
+
 QTEST_APPLESS_MAIN(tst_CodeFormatter)
 #include "tst_codeformatter.moc"