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"