diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java index f75d79503f8..680eba45710 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java @@ -100,4 +100,29 @@ public class BasicCompletionTest extends CompletionTestBase { assertEquals("blah", ((ITypedef)bindings[0]).getName()); } + public void testBug181624() throws Exception { + StringBuffer code = new StringBuffer(); + code.append("void foo() {"); + code.append(" switch ("); + + // C++ + IASTCompletionNode node = getGPPCompletionNode(code.toString()); + assertNotNull(node); + + // C + node = getGCCCompletionNode(code.toString()); + assertNotNull(node); + + code = new StringBuffer(); + code.append("void foo() {"); + code.append(" while ("); + + // C++ + node = getGPPCompletionNode(code.toString()); + assertNotNull(node); + + // C + node = getGCCCompletionNode(code.toString()); + assertNotNull(node); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java index a1db07b6b08..291b9001f81 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java @@ -2936,18 +2936,32 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { startOffset = consume().getOffset(); consume(IToken.tLPAREN); IASTExpression switch_condition = condition(); - consume(IToken.tRPAREN); - IASTStatement switch_body = statement(); + switch (LT(1)) { + case IToken.tRPAREN: + consume(); + break; + case IToken.tEOC: + break; + default: + throwBacktrack(LA(1)); + } + IASTStatement switch_body = null; + if (LT(1) != IToken.tEOC) + switch_body = statement(); IASTSwitchStatement switch_statement = createSwitchStatement(); ((ASTNode) switch_statement).setOffsetAndLength(startOffset, - calculateEndOffset(switch_body) - startOffset); + (switch_body != null ? calculateEndOffset(switch_body) : LA(1).getEndOffset()) - startOffset); switch_statement.setControllerExpression(switch_condition); switch_condition.setParent(switch_statement); switch_condition.setPropertyInParent(IASTSwitchStatement.CONTROLLER_EXP); - switch_statement.setBody(switch_body); - switch_body.setParent(switch_statement); - switch_body.setPropertyInParent(IASTSwitchStatement.BODY); + + if (switch_body != null) { + switch_statement.setBody(switch_body); + switch_body.setParent(switch_statement); + switch_body.setPropertyInParent(IASTSwitchStatement.BODY); + } + return switch_statement; } 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 60d77e8ecd6..1bd818528f8 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 @@ -5212,12 +5212,22 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { int startOffset = consume().getOffset(); consume(IToken.tLPAREN); IASTNode while_condition = cppStyleCondition(true); - consume(IToken.tRPAREN); - IASTStatement while_body = statement(); + switch (LT(1)) { + case IToken.tRPAREN: + consume(); + break; + case IToken.tEOC: + break; + default: + throwBacktrack(LA(1)); + } + IASTStatement while_body = null; + if (LT(1) != IToken.tEOC) + while_body = statement(); ICPPASTWhileStatement while_statement = (ICPPASTWhileStatement) createWhileStatement(); ((ASTNode) while_statement).setOffsetAndLength(startOffset, - calculateEndOffset(while_body) - startOffset); + (while_body != null ? calculateEndOffset(while_body) : LA(1).getEndOffset()) - startOffset); if (while_condition instanceof IASTExpression) { while_statement.setCondition((IASTExpression) while_condition); while_condition.setParent(while_statement); @@ -5230,9 +5240,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { while_condition .setPropertyInParent(ICPPASTWhileStatement.CONDITIONDECLARATION); } - while_statement.setBody(while_body); - while_body.setParent(while_statement); - while_body.setPropertyInParent(IASTWhileStatement.BODY); + + if (while_body != null) { + while_statement.setBody(while_body); + while_body.setParent(while_statement); + while_body.setPropertyInParent(IASTWhileStatement.BODY); + } + return while_statement; } @@ -5488,12 +5502,22 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { startOffset = consume().getOffset(); consume(IToken.tLPAREN); IASTNode switch_condition = cppStyleCondition(true); - consume(IToken.tRPAREN); - IASTStatement switch_body = statement(); + switch (LT(1)) { + case IToken.tRPAREN: + consume(); + break; + case IToken.tEOC: + break; + default: + throwBacktrack(LA(1)); + } + IASTStatement switch_body = null; + if (LT(1) != IToken.tEOC) + switch_body = statement(); ICPPASTSwitchStatement switch_statement = createSwitchStatement(); ((ASTNode) switch_statement).setOffsetAndLength(startOffset, - calculateEndOffset(switch_body) - startOffset); + (switch_body != null ? calculateEndOffset(switch_body) : LA(1).getEndOffset()) - startOffset); if( switch_condition instanceof IASTExpression ) { switch_statement.setControllerExpression((IASTExpression) switch_condition); @@ -5506,9 +5530,13 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { switch_condition.setParent(switch_statement); switch_condition.setPropertyInParent(ICPPASTSwitchStatement.CONTROLLER_DECLARATION); } - switch_statement.setBody(switch_body); - switch_body.setParent(switch_statement); - switch_body.setPropertyInParent(IASTSwitchStatement.BODY); + + if (switch_body != null) { + switch_statement.setBody(switch_body); + switch_body.setParent(switch_statement); + switch_body.setPropertyInParent(IASTSwitchStatement.BODY); + } + return switch_statement; }