diff --git a/core/org.eclipse.cdt.core/parser/ChangeLog b/core/org.eclipse.cdt.core/parser/ChangeLog index 822d97ff014..18243db167f 100644 --- a/core/org.eclipse.cdt.core/parser/ChangeLog +++ b/core/org.eclipse.cdt.core/parser/ChangeLog @@ -1,10 +1,15 @@ -2003-06-07 Victor Mozgin - Fixes for templated constructor/destructor/operator declarations. - This fixed PR 36766, 36767, 36769 (STL parsing problems). +2003-06-09 Victor Mozgin + Fixed Bug 36932 - RTS: Parser fails on "new" in ctor initializer + Improved handling of new-expressions: placements, arrays and + multiple parameters in initializers are now parsed. 2003-06-09 Victor Mozgin Fixed Bug 36701 - Scanner looses non-token chars while macro stringizing +2003-06-07 Victor Mozgin + Fixes for templated constructor/destructor/operator declarations. + This fixed PR 36766, 36767, 36769 (STL parsing problems). + 2003-06-06 Victor Mozgin Fixed Bug 38065 - Scanner skipped backslashes inside the code diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java index e2c6565a730..5bc212befcf 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/Parser.java @@ -2584,34 +2584,110 @@ c, quickParse); consume (Token.t_new); - // TODO: We are still not handling placement new right - // there are some ambiguities here that make it difficult to look ahead on - // we will need a better strategy in order to not do 3 or 4 backtracks - // every new expression - - boolean typeIdInBrackets = false; + boolean typeIdInParen = false; + boolean placementParseFailure = true; + Token beforeSecondParen = null; + Token backtrackMarker = null; + if( LT(1) == Token.tLPAREN ) { consume( Token.tLPAREN ); - typeIdInBrackets = true; + + try { + // Try to consume placement list + // Note: since expressionList and expression are the same... + backtrackMarker = mark(); + expression(expression); + consume( Token.tRPAREN ); + + placementParseFailure = false; + + if( LT(1) == Token.tLPAREN ) { + beforeSecondParen = mark(); + consume( Token.tLPAREN ); + typeIdInParen = true; + } + } catch (Backtrack e) { + backup(backtrackMarker); + } + + if (placementParseFailure) { + // CASE: new (typeid-not-looking-as-placement) ... + // the first expression in () is not a placement + // - then it has to be typeId + typeId(); + consume(Token.tRPAREN); + } else { + if (!typeIdInParen) { + if (LT(1) == Token.tLBRACKET) { + // CASE: new (typeid-looking-as-placement) [expr]... + // the first expression in () has been parsed as a placement; + // however, we assume that it was in fact typeId, and this + // new statement creates an array. + // Do nothing, fallback to array/initializer processing + } else { + // CASE: new (placement) typeid ... + // the first expression in () is parsed as a placement, + // and the next expression doesn't start with '(' or '[' + // - then it has to be typeId + try { backtrackMarker = mark(); typeId(); } catch (Backtrack e) { + // Hmmm, so it wasn't typeId after all... Then it is + // CASE: new (typeid-looking-as-placement) + backup(backtrackMarker); + return; + } + } + } else { + // Tricky cases: first expression in () is parsed as a placement, + // and the next expression starts with '('. + // The problem is, the first expression might as well be a typeid + try { + typeId(); + consume(Token.tRPAREN); + + if (LT(1) == Token.tLPAREN || LT(1) == Token.tLBRACKET) { + // CASE: new (placement)(typeid)(initializer) + // CASE: new (placement)(typeid)[] ... + // Great, so far all our assumptions have been correct + // Do nothing, fallback to array/initializer processing + } else { + // CASE: new (placement)(typeid) + // CASE: new (typeid-looking-as-placement)(initializer-looking-as-typeid) + // Worst-case scenario - this cannot be resolved w/o more semantic information. + // Luckily, we don't need to know what was that - we only know that + // new-expression ends here. + return; + } + } catch (Backtrack e) { + // CASE: new (typeid-looking-as-placement)(initializer-not-looking-as-typeid) + // Fallback to initializer processing + backup(beforeSecondParen); + } + } + } + } else { + // CASE: new typeid ... + // new parameters do not start with '(' + // i.e it has to be a plain typeId + typeId(); } - - typeId(); - - if( typeIdInBrackets ) - { - consume( Token.tRPAREN ); - } - + + while (LT(1) == Token.tLBRACKET) { + // array new + consume(); + assignmentExpression(expression); + consume(Token.tRBRACKET); + } + // newinitializer if( LT(1) == Token.tLPAREN ) { consume( Token.tLPAREN ); if( LT(1) != Token.tRPAREN ) - assignmentExpression( expression ); - consume( Token.tRPAREN ); + expression( expression ); + consume( Token.tRPAREN ); + } - } /** diff --git a/core/org.eclipse.cdt.ui.tests/ChangeLog b/core/org.eclipse.cdt.ui.tests/ChangeLog index 6a2131f7d6b..6b396031e45 100644 --- a/core/org.eclipse.cdt.ui.tests/ChangeLog +++ b/core/org.eclipse.cdt.ui.tests/ChangeLog @@ -1,13 +1,17 @@ -2003-06-07 Victor Mozgin - Moved testBug36766A(), testBug36766B() & testBug36766C() from STLFailedTests.java to DOMTests.java. - Renamed them to testBug36766and36769x(), as they cover both PRs. - Added testBug36766and36769D() - test for templated destructor. +2003-06-09 Victor Mozgin + Moved testBug36932() from DOMFailedTest.java to DOMTests.java. + Added DOMTests.testBug36932B() and DOMTests.testBug36932C(). 2003-06-09 Victor Mozgin Moved testBug36701() from ScannerFailedTests.java to ScannerTestCase.java. Renamed it to testBug36701A() and fixed it. Added ScannerTestCase.testBug36701B(). +2003-06-07 Victor Mozgin + Moved testBug36766A(), testBug36766B() & testBug36766C() from STLFailedTests.java to DOMTests.java. + Renamed them to testBug36766and36769x(), as they cover both PRs. + Added testBug36766and36769D() - test for templated destructor. + 2003-06-05 John Camelon Moved testBug23478A() & testBug23478B() from failed tests to TranslationUnitTests.java. Removed TranslationUnitFailedTests.java as it was empty. diff --git a/core/org.eclipse.cdt.ui.tests/failures/org/eclipse/cdt/core/parser/failedTests/DOMFailedTest.java b/core/org.eclipse.cdt.ui.tests/failures/org/eclipse/cdt/core/parser/failedTests/DOMFailedTest.java index 1947c1b646d..1bdb96ea75a 100644 --- a/core/org.eclipse.cdt.ui.tests/failures/org/eclipse/cdt/core/parser/failedTests/DOMFailedTest.java +++ b/core/org.eclipse.cdt.ui.tests/failures/org/eclipse/cdt/core/parser/failedTests/DOMFailedTest.java @@ -20,13 +20,8 @@ public class DOMFailedTest extends BaseDOMTest { public DOMFailedTest(String name) { super(name); } - - public void testBug36932() { - failTest("A::A( ) : var( new char [ (unsigned)bufSize ] ) {}"); - } public void testBug36730()throws Exception { failTest("FUNCTION_MACRO( 1, a )\n int i;"); - } - + } } diff --git a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java index cf0b8e83e19..60163b22ebc 100644 --- a/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java +++ b/core/org.eclipse.cdt.ui.tests/parser/org/eclipse/cdt/core/parser/tests/DOMTests.java @@ -1818,5 +1818,229 @@ public class DOMTests extends BaseDOMTest { code.write("{}\n"); parse(code.toString()); } + + public void testBug36932A() throws Exception { + parse("A::A( ) : var( new char [ (unsigned)bufSize ] ) {}"); + } + + public void testBug36932B() throws Exception { + parse(" p = new int; "); + parse(" p = new int(5); "); + parse(" p = new int(B); "); + parse(" p = new int(B,C); "); + parse(" p = new int[5]; "); + parse(" p = new int[5][10]; "); + parse(" p = new int[B]; "); + parse(" p = new int[B][C][D]; "); + + parse(" p = new A; "); + parse(" p = new A(5); "); + parse(" p = new A(B); "); + parse(" p = new A(B,C); "); + parse(" p = new A[5]; "); + parse(" p = new A[5][10]; "); + parse(" p = new A[B]; "); + parse(" p = new A[B][C][D]; "); + + parse(" p = new (int); "); + parse(" p = new (int)(5); "); + parse(" p = new (int)(B); "); + parse(" p = new (int)(B,C); "); + parse(" p = new (int)[5]; "); + parse(" p = new (int)[5][10]; "); + parse(" p = new (int)[B]; "); + parse(" p = new (int)[B][C][D]; "); + + parse(" p = new (A); "); + parse(" p = new (A)(5); "); + parse(" p = new (A)(B); "); + parse(" p = new (A)(B,C); "); + parse(" p = new (A)[5]; "); + parse(" p = new (A)[5][10]; "); + parse(" p = new (A)[B]; "); + parse(" p = new (A)[B][C][D]; "); + + parse(" p = new (0) int; "); + parse(" p = new (0) int(5); "); + parse(" p = new (0) int(B); "); + parse(" p = new (0) int(B,C); "); + parse(" p = new (0) int[5]; "); + parse(" p = new (0) int[5][10]; "); + parse(" p = new (0) int[B]; "); + parse(" p = new (0) int[B][C][D]; "); + + parse(" p = new (0) A; "); + parse(" p = new (0) A(5); "); + parse(" p = new (0) A(B); "); + parse(" p = new (0) A(B,C); "); + parse(" p = new (0) A[5]; "); + parse(" p = new (0) A[5][10]; "); + parse(" p = new (0) A[B]; "); + parse(" p = new (0) A[B][C][D]; "); + + parse(" p = new (0) (int); "); + parse(" p = new (0) (int)(5); "); + parse(" p = new (0) (int)(B); "); + parse(" p = new (0) (int)(B,C); "); + parse(" p = new (0) (int)[5]; "); + parse(" p = new (0) (int)[5][10]; "); + parse(" p = new (0) (int)[B]; "); + parse(" p = new (0) (int)[B][C][D]; "); + + parse(" p = new (0) (A); "); + parse(" p = new (0) (A)(5); "); + parse(" p = new (0) (A)(B); "); + parse(" p = new (0) (A)(B,C); "); + parse(" p = new (0) (A)[5]; "); + parse(" p = new (0) (A)[5][10]; "); + parse(" p = new (0) (A)[B]; "); + parse(" p = new (0) (A)[B][C][D]; "); + + parse(" p = new (P) int; "); + parse(" p = new (P) int(5); "); + parse(" p = new (P) int(B); "); + parse(" p = new (P) int(B,C); "); + parse(" p = new (P) int[5]; "); + parse(" p = new (P) int[5][10]; "); + parse(" p = new (P) int[B]; "); + parse(" p = new (P) int[B][C][D]; "); + + parse(" p = new (P) A; "); + parse(" p = new (P) A(5); "); + parse(" p = new (P) A(B); "); + parse(" p = new (P) A(B,C); "); + parse(" p = new (P) A[5]; "); + parse(" p = new (P) A[5][10]; "); + parse(" p = new (P) A[B]; "); + parse(" p = new (P) A[B][C][D]; "); + + parse(" p = new (P) (int); "); + parse(" p = new (P) (int)(5); "); + parse(" p = new (P) (int)(B); "); + parse(" p = new (P) (int)(B,C); "); + parse(" p = new (P) (int)[5]; "); + parse(" p = new (P) (int)[5][10]; "); + parse(" p = new (P) (int)[B]; "); + parse(" p = new (P) (int)[B][C][D]; "); + + parse(" p = new (P) (A); "); + parse(" p = new (P) (A)(5); "); + parse(" p = new (P) (A)(B); "); + parse(" p = new (P) (A)(B,C); "); + parse(" p = new (P) (A)[5]; "); + parse(" p = new (P) (A)[5][10]; "); + parse(" p = new (P) (A)[B]; "); + parse(" p = new (P) (A)[B][C][D]; "); + } + + public void testBug36932C() throws Exception { + parse("X::X( ) : var( new int ) {}"); + parse("X::X( ) : var( new int(5) ) {}"); + parse("X::X( ) : var( new int(B) ) {}"); + parse("X::X( ) : var( new int(B,C) ) {}"); + parse("X::X( ) : var( new int[5] ) {}"); + parse("X::X( ) : var( new int[5][10] ) {}"); + parse("X::X( ) : var( new int[B] ) {}"); + parse("X::X( ) : var( new int[B][C][D] ) {}"); + + parse("X::X( ) : var( new A ) {}"); + parse("X::X( ) : var( new A(5) ) {}"); + parse("X::X( ) : var( new A(B) ) {}"); + parse("X::X( ) : var( new A(B,C) ) {}"); + parse("X::X( ) : var( new A[5] ) {}"); + parse("X::X( ) : var( new A[5][10] ) {}"); + parse("X::X( ) : var( new A[B] ) {}"); + parse("X::X( ) : var( new A[B][C][D] ) {}"); + + parse("X::X( ) : var( new (int) ) {}"); + parse("X::X( ) : var( new (int)(5) ) {}"); + parse("X::X( ) : var( new (int)(B) ) {}"); + parse("X::X( ) : var( new (int)(B,C) ) {}"); + parse("X::X( ) : var( new (int)[5] ) {}"); + parse("X::X( ) : var( new (int)[5][10] ) {}"); + parse("X::X( ) : var( new (int)[B] ) {}"); + parse("X::X( ) : var( new (int)[B][C][D] ) {}"); + + parse("X::X( ) : var( new (A) ) {}"); + parse("X::X( ) : var( new (A)(5) ) {}"); + parse("X::X( ) : var( new (A)(B) ) {}"); + parse("X::X( ) : var( new (A)(B,C) ) {}"); + parse("X::X( ) : var( new (A)[5] ) {}"); + parse("X::X( ) : var( new (A)[5][10] ) {}"); + parse("X::X( ) : var( new (A)[B] ) {}"); + parse("X::X( ) : var( new (A)[B][C][D] ) {}"); + + parse("X::X( ) : var( new (0) int ) {}"); + parse("X::X( ) : var( new (0) int(5) ) {}"); + parse("X::X( ) : var( new (0) int(B) ) {}"); + parse("X::X( ) : var( new (0) int(B,C) ) {}"); + parse("X::X( ) : var( new (0) int[5] ) {}"); + parse("X::X( ) : var( new (0) int[5][10] ) {}"); + parse("X::X( ) : var( new (0) int[B] ) {}"); + parse("X::X( ) : var( new (0) int[B][C][D] ) {}"); + + parse("X::X( ) : var( new (0) A ) {}"); + parse("X::X( ) : var( new (0) A(5) ) {}"); + parse("X::X( ) : var( new (0) A(B) ) {}"); + parse("X::X( ) : var( new (0) A(B,C) ) {}"); + parse("X::X( ) : var( new (0) A[5] ) {}"); + parse("X::X( ) : var( new (0) A[5][10] ) {}"); + parse("X::X( ) : var( new (0) A[B] ) {}"); + parse("X::X( ) : var( new (0) A[B][C][D] ) {}"); + + parse("X::X( ) : var( new (0) (int) ) {}"); + parse("X::X( ) : var( new (0) (int)(5) ) {}"); + parse("X::X( ) : var( new (0) (int)(B) ) {}"); + parse("X::X( ) : var( new (0) (int)(B,C) ) {}"); + parse("X::X( ) : var( new (0) (int)[5] ) {}"); + parse("X::X( ) : var( new (0) (int)[5][10] ) {}"); + parse("X::X( ) : var( new (0) (int)[B] ) {}"); + parse("X::X( ) : var( new (0) (int)[B][C][D] ) {}"); + + parse("X::X( ) : var( new (0) (A) ) {}"); + parse("X::X( ) : var( new (0) (A)(5) ) {}"); + parse("X::X( ) : var( new (0) (A)(B) ) {}"); + parse("X::X( ) : var( new (0) (A)(B,C) ) {}"); + parse("X::X( ) : var( new (0) (A)[5] ) {}"); + parse("X::X( ) : var( new (0) (A)[5][10] ) {}"); + parse("X::X( ) : var( new (0) (A)[B] ) {}"); + parse("X::X( ) : var( new (0) (A)[B][C][D] ) {}"); + + parse("X::X( ) : var( new (P) int ) {}"); + parse("X::X( ) : var( new (P) int(5) ) {}"); + parse("X::X( ) : var( new (P) int(B) ) {}"); + parse("X::X( ) : var( new (P) int(B,C) ) {}"); + parse("X::X( ) : var( new (P) int[5] ) {}"); + parse("X::X( ) : var( new (P) int[5][10] ) {}"); + parse("X::X( ) : var( new (P) int[B] ) {}"); + parse("X::X( ) : var( new (P) int[B][C][D] ) {}"); + + parse("X::X( ) : var( new (P) A ) {}"); + parse("X::X( ) : var( new (P) A(5) ) {}"); + parse("X::X( ) : var( new (P) A(B) ) {}"); + parse("X::X( ) : var( new (P) A(B,C) ) {}"); + parse("X::X( ) : var( new (P) A[5] ) {}"); + parse("X::X( ) : var( new (P) A[5][10] ) {}"); + parse("X::X( ) : var( new (P) A[B] ) {}"); + parse("X::X( ) : var( new (P) A[B][C][D] ) {}"); + + parse("X::X( ) : var( new (P) (int) ) {}"); + parse("X::X( ) : var( new (P) (int)(5) ) {}"); + parse("X::X( ) : var( new (P) (int)(B) ) {}"); + parse("X::X( ) : var( new (P) (int)(B,C) ) {}"); + parse("X::X( ) : var( new (P) (int)[5] ) {}"); + parse("X::X( ) : var( new (P) (int)[5][10] ) {}"); + parse("X::X( ) : var( new (P) (int)[B] ) {}"); + parse("X::X( ) : var( new (P) (int)[B][C][D] ) {}"); + + parse("X::X( ) : var( new (P) (A) ) {}"); + parse("X::X( ) : var( new (P) (A)(5) ) {}"); + parse("X::X( ) : var( new (P) (A)(B) ) {}"); + parse("X::X( ) : var( new (P) (A)(B,C) ) {}"); + parse("X::X( ) : var( new (P) (A)[5] ) {}"); + parse("X::X( ) : var( new (P) (A)[5][10] ) {}"); + parse("X::X( ) : var( new (P) (A)[B] ) {}"); + parse("X::X( ) : var( new (P) (A)[B][C][D] ) {}"); + } }