diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java
index c26b65b589a..5c423f46deb 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMLocationTests.java
@@ -52,6 +52,7 @@ import org.eclipse.cdt.core.dom.ast.IASTProblem;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
@@ -703,6 +704,26 @@ public class DOMLocationTests extends AST2TestBase {
assertSoleLocation(declarator, code.indexOf(rawDeclarator), rawDeclarator.length());
}
+ public void testSwitchInitStatement_1() throws Exception {
+ String code = "void foo() { switch (int i = 1; i) {} }"; //$NON-NLS-1$
+ IASTTranslationUnit tu = parse(code, ParserLanguage.CPP);
+ ICPPASTFunctionDefinition definition = (ICPPASTFunctionDefinition) tu.getDeclarations()[0];
+ IASTCompoundStatement body = (IASTCompoundStatement) definition.getBody();
+ IASTSwitchStatement statement = (IASTSwitchStatement) body.getStatements()[0];
+ String rawDeclarator = "switch (int i = 1; i) {}"; //$NON-NLS-1$
+ assertSoleLocation(statement, code.indexOf(rawDeclarator), rawDeclarator.length());
+ }
+
+ public void testSwitchInitStatement_2() throws Exception {
+ String code = "void foo() { char c = 'a'; switch (; c) {} }"; //$NON-NLS-1$
+ IASTTranslationUnit tu = parse(code, ParserLanguage.CPP);
+ ICPPASTFunctionDefinition definition = (ICPPASTFunctionDefinition) tu.getDeclarations()[0];
+ IASTCompoundStatement body = (IASTCompoundStatement) definition.getBody();
+ IASTSwitchStatement statement = (IASTSwitchStatement) body.getStatements()[1];
+ String rawDeclarator = "switch (; c) {}"; //$NON-NLS-1$
+ assertSoleLocation(statement, code.indexOf(rawDeclarator), rawDeclarator.length());
+ }
+
public void testIfInitStatement_1() throws Exception {
String code = "void foo() { if (int i = 1; i == 1) {} }"; //$NON-NLS-1$
IASTTranslationUnit tu = parse(code, ParserLanguage.CPP);
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/SwitchStatementTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/SwitchStatementTests.java
index b71ca340b80..7d6d1b03d0e 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/SwitchStatementTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/cxx14/constexpr/SwitchStatementTests.java
@@ -244,4 +244,46 @@ public class SwitchStatementTests extends TestBase {
public void testSwitchWithNestedContinueStatement() throws Exception {
assertEvaluationEquals(3);
}
+
+ // constexpr int triple(int x) {
+ // return x * 3;
+ // }
+ // constexpr int f(int y) {
+ // switch(int x = triple(y); x) {
+ // case 9:
+ // return 1;
+ // case 12:
+ // return 2;
+ // case 15:
+ // return 3;
+ // default:
+ // return 4;
+ // }
+ // }
+
+ // constexpr int x = f(5);
+ public void testDeclarationInSwitchInitStatement() throws Exception {
+ assertEvaluationEquals(3);
+ }
+
+ // constexpr int triple(int x) {
+ // return x * 3;
+ // }
+ // constexpr int f(int y) {
+ // switch(; int x = triple(y)) {
+ // case 9:
+ // return 1;
+ // case 12:
+ // return 2;
+ // case 15:
+ // return 3;
+ // default:
+ // return 4;
+ // }
+ // }
+
+ // constexpr int x = f(5);
+ public void testDeclarationInSwitchStatementControllerEmptyInit() throws Exception {
+ assertEvaluationEquals(3);
+ }
}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterStatementTestSource.awts b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterStatementTestSource.awts
index 766d3c6e588..41cd52b2d28 100644
--- a/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterStatementTestSource.awts
+++ b/core/org.eclipse.cdt.core.tests/resources/rewrite/ASTWriterStatementTestSource.awts
@@ -400,4 +400,25 @@ void f()
constexpr int k{42};
if constexpr (;k == 42){
}
+}
+
+//!Switch with emtpy init statement
+//%CPP
+void f()
+{
+ constexpr int k{42};
+ switch (;k){
+ case 42:
+ break;
+ }
+}
+
+//!Switch with init statement
+//%CPP
+void f()
+{
+ switch (constexpr int k{42};k){
+ case 42:
+ break;
+ }
}
\ No newline at end of file
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTSwitchStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTSwitchStatement.java
index 0bac682ae31..94dd4609e2b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTSwitchStatement.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTSwitchStatement.java
@@ -12,6 +12,7 @@ package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.IScope;
@@ -21,6 +22,15 @@ import org.eclipse.cdt.core.dom.ast.IScope;
*/
public interface ICPPASTSwitchStatement extends IASTSwitchStatement {
+ /**
+ * {@code INIT_STATEMENT} represents the relationship between an
+ * {@code ICPPASTSwitchStatement} and its nested {@code IASTStatement}.
+ *
+ * @since 6.5
+ */
+ public static final ASTNodeProperty INIT_STATEMENT = new ASTNodeProperty(
+ "ICPPASTSwitchStatement.INIT_STATEMENT - IASTStatement init-statement for ICPPASTSwitchStatement"); //$NON-NLS-1$
+
/**
* CONTROLLER_DECLARATION
represents the relationship between an
* IASTSwitchStatement
and it's nested
@@ -42,7 +52,27 @@ public interface ICPPASTSwitchStatement extends IASTSwitchStatement {
* @param d IASTDeclaration
*/
public void setControllerDeclaration( IASTDeclaration d );
-
+
+ /**
+ * Returns the init-statement for a switch.
+ *
+ * @return the init-statement, or null
if the 'switch' statement doesn't
+ * have one.
+ *
+ * @since 6.5
+ */
+ public IASTStatement getInitializerStatement();
+
+ /**
+ * Sets the optional init-statement of an switch.
+ *
+ * @param statement this statement should either be a IASTSimpleDeclaration
or a
+ * IASTExpressionStatement
.
+ *
+ * @since 6.5
+ */
+ public void setInitializerStatement(IASTStatement statement);
+
/**
* Get the IScope
represented by this switch.
*
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSwitchStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSwitchStatement.java
index e331ab2b6bb..20068999c34 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSwitchStatement.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTSwitchStatement.java
@@ -30,6 +30,7 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExecSwitch;
*/
public class CPPASTSwitchStatement extends CPPASTAttributeOwner implements ICPPASTSwitchStatement, ICPPExecutionOwner {
private IScope scope;
+ private IASTStatement initStatement;
private IASTExpression controllerExpression;
private IASTDeclaration controllerDeclaration;
private IASTStatement body;
@@ -55,6 +56,8 @@ public class CPPASTSwitchStatement extends CPPASTAttributeOwner implements ICPPA
@Override
public CPPASTSwitchStatement copy(CopyStyle style) {
CPPASTSwitchStatement copy = new CPPASTSwitchStatement();
+ copy.setInitializerStatement(initStatement == null ?
+ null : initStatement.copy(style));
copy.setControllerDeclaration(controllerDeclaration == null ?
null : controllerDeclaration.copy(style));
copy.setControllerExpression(controllerExpression == null ?
@@ -63,6 +66,22 @@ public class CPPASTSwitchStatement extends CPPASTAttributeOwner implements ICPPA
return copy(copy, style);
}
+ @Override
+ public IASTStatement getInitializerStatement() {
+ return initStatement;
+ }
+
+ @Override
+ public void setInitializerStatement(IASTStatement statement) {
+ assertNotFrozen();
+ this.initStatement = statement;
+ if (statement != null) {
+ statement.setParent(this);
+ statement.setPropertyInParent(INIT_STATEMENT);
+ statement = null;
+ }
+ }
+
@Override
public IASTExpression getControllerExpression() {
return controllerExpression;
@@ -105,6 +124,7 @@ public class CPPASTSwitchStatement extends CPPASTAttributeOwner implements ICPPA
}
if (!acceptByAttributeSpecifiers(action)) return false;
+ if (initStatement != null && !initStatement.accept(action)) return false;
if (controllerExpression != null && !controllerExpression.accept(action)) return false;
if (controllerDeclaration != null && !controllerDeclaration.accept(action)) return false;
if (body != null && !body.accept(action)) return false;
@@ -121,6 +141,12 @@ public class CPPASTSwitchStatement extends CPPASTAttributeOwner implements ICPPA
@Override
public void replace(IASTNode child, IASTNode other) {
+ if (initStatement == child) {
+ other.setParent(child.getParent());
+ other.setPropertyInParent(child.getPropertyInParent());
+ initStatement = (IASTStatement) other;
+ return;
+ }
if (body == child) {
other.setPropertyInParent(child.getPropertyInParent());
other.setParent(child.getParent());
@@ -162,6 +188,7 @@ public class CPPASTSwitchStatement extends CPPASTAttributeOwner implements ICPPA
@Override
public ICPPExecution getExecution() {
+ ICPPExecution initStmtExec = EvalUtil.getExecutionFromStatement(getInitializerStatement());
ICPPASTExpression controllerExpr = (ICPPASTExpression) getControllerExpression();
ICPPExecutionOwner controllerDecl = (ICPPExecutionOwner) getControllerDeclaration();
ICPPEvaluation controllerExprEval = controllerExpr != null ? controllerExpr.getEvaluation() : null;
@@ -178,6 +205,6 @@ public class CPPASTSwitchStatement extends CPPASTAttributeOwner implements ICPPA
for (int i = 0; i < bodyStmts.length; i++) {
bodyStmtExecutions[i] = EvalUtil.getExecutionFromStatement(bodyStmts[i]);
}
- return new ExecSwitch(controllerExprEval, controllerDeclExec, bodyStmtExecutions);
+ return new ExecSwitch(initStmtExec, controllerExprEval, controllerDeclExec, bodyStmtExecutions);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
index d3717ffe206..cbb9a201dbe 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
@@ -5377,6 +5377,17 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
int startOffset;
startOffset = consume().getOffset();
consume(IToken.tLPAREN);
+
+ ICPPASTSwitchStatement switch_statement = getNodeFactory().newSwitchStatement();
+ // init-statement
+ IToken mark= mark();
+ try {
+ IASTStatement statement = initStatement();
+ switch_statement.setInitializerStatement(statement);
+ } catch (BacktrackException e) {
+ backup(mark);
+ }
+
IASTNode switch_condition = cppStyleCondition(IToken.tRPAREN);
switch (LT(1)) {
case IToken.tRPAREN:
@@ -5389,7 +5400,6 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
}
IASTStatement switch_body = parseSwitchBody();
- ICPPASTSwitchStatement switch_statement = getNodeFactory().newSwitchStatement();
((ASTNode) switch_statement).setOffsetAndLength(startOffset,
(switch_body != null ? calculateEndOffset(switch_body) : LA(1).getEndOffset()) - startOffset);
if (switch_condition instanceof IASTExpression) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
index 53ab4f75f1c..97c6db6177b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
@@ -1622,7 +1622,14 @@ public class CPPSemantics {
nodes= new IASTNode[] {initDeclaration};
}
} else if (parent instanceof ICPPASTSwitchStatement) {
- nodes = new IASTNode[] { ((ICPPASTSwitchStatement) parent).getControllerDeclaration() };
+ ICPPASTSwitchStatement ifStatement = (ICPPASTSwitchStatement) parent;
+ final IASTStatement initStatement = ifStatement.getInitializerStatement();
+ final IASTDeclaration controllerDeclaration = ifStatement.getControllerDeclaration();
+ if (initStatement != null) {
+ nodes = new IASTNode[] {initStatement, controllerDeclaration};
+ } else {
+ nodes = new IASTNode[] {controllerDeclaration};
+ }
} else if (parent instanceof ICPPASTIfStatement) {
ICPPASTIfStatement ifStatement = (ICPPASTIfStatement) parent;
final IASTStatement initStatement = ifStatement.getInitializerStatement();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecIf.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecIf.java
index 4c12afdafa3..bd3179e98bd 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecIf.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecIf.java
@@ -32,12 +32,6 @@ public class ExecIf implements ICPPExecution {
this.elseClauseExec = elseClauseExec;
}
- private void executeInitStatement(ActivationRecord record, ConstexprEvaluationContext context) {
- if (initStmtExec != null) {
- EvalUtil.executeStatement(initStmtExec, record, context);
- }
- }
-
private boolean conditionSatisfied(ActivationRecord record, ConstexprEvaluationContext context) {
if (conditionExprEval != null) {
return EvalUtil.conditionExprSatisfied(conditionExprEval, record, context);
@@ -49,7 +43,7 @@ public class ExecIf implements ICPPExecution {
@Override
public ICPPExecution executeForFunctionCall(ActivationRecord record, ConstexprEvaluationContext context) {
- executeInitStatement(record, context);
+ EvalUtil.executeStatement(initStmtExec, record, context);
if (conditionSatisfied(record, context)) {
return EvalUtil.executeStatement(thenClauseExec, record, context);
} else if (elseClauseExec != null) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecSwitch.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecSwitch.java
index 29fde99e858..bfab9d5d5fa 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecSwitch.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/ExecSwitch.java
@@ -17,11 +17,13 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.InstantiationContext;
import org.eclipse.core.runtime.CoreException;
public class ExecSwitch implements ICPPExecution {
+ private final ICPPExecution initStmtExec;
private final ICPPEvaluation controllerExprEval;
private final ExecSimpleDeclaration controllerDeclExec;
private final ICPPExecution[] bodyStmtExecutions;
- public ExecSwitch(ICPPEvaluation controllerExprEval, ExecSimpleDeclaration controllerDeclExec, ICPPExecution[] bodyStmtExecutions) {
+ public ExecSwitch(ICPPExecution initStmtExec, ICPPEvaluation controllerExprEval, ExecSimpleDeclaration controllerDeclExec, ICPPExecution[] bodyStmtExecutions) {
+ this.initStmtExec = initStmtExec;
this.controllerExprEval = controllerExprEval;
this.controllerDeclExec = controllerDeclExec;
this.bodyStmtExecutions = bodyStmtExecutions;
@@ -29,6 +31,7 @@ public class ExecSwitch implements ICPPExecution {
@Override
public ICPPExecution executeForFunctionCall(ActivationRecord record, ConstexprEvaluationContext context) {
+ EvalUtil.executeStatement(initStmtExec, record, context);
final int caseIndex = getMatchingCaseIndex(record, context);
for (int i = caseIndex; i < bodyStmtExecutions.length; ++i) {
ICPPExecution stmtExec = bodyStmtExecutions[i];
@@ -72,6 +75,7 @@ public class ExecSwitch implements ICPPExecution {
@Override
public ICPPExecution instantiate(InstantiationContext context, int maxDepth) {
+ ICPPExecution newInitStmtExec = initStmtExec != null ? initStmtExec.instantiate(context, maxDepth) : null;
ICPPEvaluation newControllerExprEval = controllerExprEval != null ? controllerExprEval.instantiate(context, maxDepth) : null;
ExecSimpleDeclaration newControllerDeclExec = controllerDeclExec != null ? (ExecSimpleDeclaration) controllerDeclExec.instantiate(context, maxDepth) : null;
ICPPExecution[] newBodyStmtExecutions = new ICPPExecution[bodyStmtExecutions.length];
@@ -85,15 +89,16 @@ public class ExecSwitch implements ICPPExecution {
newBodyStmtExecutions[i] = newBodyStmtExec;
}
- if (newControllerExprEval == controllerExprEval && newControllerDeclExec == controllerDeclExec && !executionsDidChange) {
+ if (newInitStmtExec == initStmtExec && newControllerExprEval == controllerExprEval && newControllerDeclExec == controllerDeclExec && !executionsDidChange) {
return this;
}
- return new ExecSwitch(newControllerExprEval, newControllerDeclExec, newBodyStmtExecutions);
+ return new ExecSwitch(newInitStmtExec, newControllerExprEval, newControllerDeclExec, newBodyStmtExecutions);
}
@Override
public void marshal(ITypeMarshalBuffer buffer, boolean includeValue) throws CoreException {
buffer.putShort(ITypeMarshalBuffer.EXEC_SWITCH);
+ buffer.marshalExecution(initStmtExec, includeValue);
buffer.marshalEvaluation(controllerExprEval, includeValue);
buffer.marshalExecution(controllerDeclExec, includeValue);
buffer.putInt(bodyStmtExecutions.length);
@@ -103,6 +108,7 @@ public class ExecSwitch implements ICPPExecution {
}
public static ICPPExecution unmarshal(short firstBytes, ITypeMarshalBuffer buffer) throws CoreException {
+ ICPPExecution initStmtExec = buffer.unmarshalExecution();
ICPPEvaluation controllerExprEval = buffer.unmarshalEvaluation();
ExecSimpleDeclaration controllerDeclExec = (ExecSimpleDeclaration) buffer.unmarshalExecution();
int len = buffer.getInt();
@@ -110,6 +116,6 @@ public class ExecSwitch implements ICPPExecution {
for (int i = 0; i < bodyStmtExecutions.length; i++) {
bodyStmtExecutions[i] = buffer.unmarshalExecution();
}
- return new ExecSwitch(controllerExprEval, controllerDeclExec, bodyStmtExecutions);
+ return new ExecSwitch(initStmtExec, controllerExprEval, controllerDeclExec, bodyStmtExecutions);
}
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/StatementWriter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/StatementWriter.java
index ce6713198a7..013e03aa78b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/StatementWriter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/rewrite/astwriter/StatementWriter.java
@@ -365,6 +365,10 @@ public class StatementWriter extends NodeWriter {
scribe.noNewLines();
if (switchStatement instanceof ICPPASTSwitchStatement) {
ICPPASTSwitchStatement cppSwitchStatement = (ICPPASTSwitchStatement) switchStatement;
+ IASTStatement initStatement = cppSwitchStatement.getInitializerStatement();
+ if (initStatement != null) {
+ writeStatement(initStatement, false);
+ }
if (cppSwitchStatement.getControllerDeclaration() == null) {
cppSwitchStatement.getControllerExpression().accept(visitor);
} else {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
index 127f9bf3628..9c2519c8dca 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/PDOM.java
@@ -292,10 +292,11 @@ public class PDOM extends PlatformObject implements IPDOM {
*
* CDT 9.5 development (version not supported on the 9.4.x branch)
* 212.0 - C++ constexpr if and if init-statement evaluation
+ * 213.0 - C++ switch init-statement evaluation
*/
- private static final int MIN_SUPPORTED_VERSION= version(212, 0);
- private static final int MAX_SUPPORTED_VERSION= version(212, Short.MAX_VALUE);
- private static final int DEFAULT_VERSION = version(212, 0);
+ private static final int MIN_SUPPORTED_VERSION= version(213, 0);
+ private static final int MAX_SUPPORTED_VERSION= version(213, Short.MAX_VALUE);
+ private static final int DEFAULT_VERSION = version(213, 0);
private static int version(int major, int minor) {
return (major << 16) + minor;
diff --git a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java
index 37c34403a62..7cec2794187 100644
--- a/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java
+++ b/core/org.eclipse.cdt.core/src/org/eclipse/cdt/internal/formatter/CodeFormatterVisitor.java
@@ -134,6 +134,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTRangeBasedForStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeConstructorExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSwitchStatement;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
@@ -3588,23 +3589,43 @@ public class CodeFormatterVisitor extends ASTVisitor implements ICPPASTVisitor,
return PROCESS_SKIP;
}
+ private void beginSwitchClause() {
+ scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_switch);
+ if (preferences.insert_space_after_opening_paren_in_switch) {
+ scribe.space();
+ }
+ }
+
private int visit(IASTSwitchStatement node) {
final int headerIndent= scribe.numberOfIndentations;
// 'switch' keyword
if (!startsWithMacroExpansion(node)) {
scribe.printNextToken(Token.t_switch);
}
- // Controller expression
IASTExpression controllerExpression = node.getControllerExpression();
- if (!doNodesHaveSameOffset(node, controllerExpression)) {
- scribe.printNextToken(Token.tLPAREN, preferences.insert_space_before_opening_paren_in_switch);
- if (preferences.insert_space_after_opening_paren_in_switch) {
- scribe.space();
+ try {
+ // optional init-statement
+ if(node instanceof ICPPASTSwitchStatement) {
+ IASTStatement initStatement = ((ICPPASTSwitchStatement) node).getInitializerStatement();
+ if (initStatement != null) {
+ beginSwitchClause();
+ fHasClauseInitStatement = true;
+ initStatement.accept(this);
+ if (preferences.insert_space_after_semicolon_in_for) {
+ scribe.space();
+ }
+ }
}
- }
- controllerExpression.accept(this);
- if (peekNextToken() == Token.tRPAREN) {
- scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_switch);
+ // Controller expression
+ if (!doNodesHaveSameOffset(node, controllerExpression) && !fHasClauseInitStatement) {
+ beginSwitchClause();
+ }
+ controllerExpression.accept(this);
+ if (peekNextToken() == Token.tRPAREN) {
+ scribe.printNextToken(Token.tRPAREN, preferences.insert_space_before_closing_paren_in_switch);
+ }
+ } finally {
+ fHasClauseInitStatement = false;
}
// switch body
String brace_position = preferences.brace_position_for_switch;
diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java
index 7477575c0f8..0b56b5b6905 100644
--- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java
+++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/CodeFormatterTest.java
@@ -3312,4 +3312,63 @@ public class CodeFormatterTest extends BaseUITestCase {
public void testIfInitStatementFormat_4() throws Exception {
assertFormatterResult();
}
+
+ //void foo() {
+ // switch (constexpr bool k = true; k) {
+ // }
+ //}
+
+ //void foo() {
+ // switch (constexpr bool k = true; k) {
+ // }
+ //}
+
+ public void testSwitchInitStatementFormat_1() throws Exception {
+ assertFormatterResult();
+ }
+
+ //void foo() {
+ // switch
+ // (constexpr bool k = true; k) {
+ // }
+ //}
+
+ //void foo() {
+ // switch (constexpr bool k = true; k) {
+ // }
+ //}
+ public void testSwitchInitStatementFormat_2() throws Exception {
+ assertFormatterResult();
+ }
+
+ //void foo() {
+ // switch
+ //
+ //
+ // (constexpr bool k = true; k) {
+ // }
+ //}
+
+ //void foo() {
+ // switch
+ //
+ // (constexpr bool k = true; k) {
+ // }
+ //}
+ public void testSwitchInitStatementFormat_3() throws Exception {
+ assertFormatterResult();
+ }
+
+ //void foo() {
+ // switch (constexpr bool k = true;k) {
+ // }
+ //}
+
+ //void foo() {
+ // switch (constexpr bool k = true; k) {
+ // }
+ //}
+ public void testSwitchInitStatementFormat_4() throws Exception {
+ assertFormatterResult();
+ }
}