diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java index d05f87777fa..2900f2cd871 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ParserTestSuite.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.model.tests.CModelElementsTests; import org.eclipse.cdt.core.model.tests.StructuralCModelElementsTests; import org.eclipse.cdt.core.parser.tests.ast2.AST2Tests; import org.eclipse.cdt.core.parser.tests.ast2.GCCTests; +import org.eclipse.cdt.core.parser.tests.parser2.CompleteParser2Tests; import org.eclipse.cdt.core.parser.tests.parser2.QuickParser2Tests; import org.eclipse.cdt.core.parser.tests.scanner2.ObjectMapTest; import org.eclipse.cdt.core.parser.tests.scanner2.Scanner2Test; @@ -57,6 +58,7 @@ public class ParserTestSuite extends TestCase { suite.addTestSuite( AST2Tests.class ); suite.addTestSuite( GCCTests.class ); suite.addTestSuite( QuickParser2Tests.class ); + suite.addTestSuite( CompleteParser2Tests.class ); return suite; } } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java index a737f8f0736..178c962ad5d 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2BaseTest.java @@ -44,7 +44,7 @@ import org.eclipse.cdt.core.parser.ParserFactory; import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ScannerInfo; -import org.eclipse.cdt.core.parser.tests.parser2.QuickParser2Tests.ProblemCollector; +import org.eclipse.cdt.core.parser.tests.parser2.ProblemCollector; import org.eclipse.cdt.internal.core.parser.ParserException; import org.eclipse.cdt.internal.core.parser2.ISourceCodeParser; import org.eclipse.cdt.internal.core.parser2.c.ANSICParserExtensionConfiguration; diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/CompleteParser2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/CompleteParser2Tests.java new file mode 100644 index 00000000000..014722fb014 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/CompleteParser2Tests.java @@ -0,0 +1,1412 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.core.parser.tests.parser2; + +import java.io.StringWriter; +import java.io.Writer; +import java.util.Collections; + +import junit.framework.TestCase; + +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.parser.CodeReader; +import org.eclipse.cdt.core.parser.IScanner; +import org.eclipse.cdt.core.parser.NullLogService; +import org.eclipse.cdt.core.parser.NullSourceElementRequestor; +import org.eclipse.cdt.core.parser.ParserFactory; +import org.eclipse.cdt.core.parser.ParserLanguage; +import org.eclipse.cdt.core.parser.ParserMode; +import org.eclipse.cdt.core.parser.ScannerInfo; +import org.eclipse.cdt.internal.core.parser.ParserException; +import org.eclipse.cdt.internal.core.parser2.ISourceCodeParser; +import org.eclipse.cdt.internal.core.parser2.c.ANSICParserExtensionConfiguration; +import org.eclipse.cdt.internal.core.parser2.c.GCCParserExtensionConfiguration; +import org.eclipse.cdt.internal.core.parser2.c.GNUCSourceParser; +import org.eclipse.cdt.internal.core.parser2.c.ICParserExtensionConfiguration; +import org.eclipse.cdt.internal.core.parser2.cpp.ANSICPPParserExtensionConfiguration; +import org.eclipse.cdt.internal.core.parser2.cpp.GNUCPPParserExtensionConfiguration; +import org.eclipse.cdt.internal.core.parser2.cpp.GNUCPPSourceParser; +import org.eclipse.cdt.internal.core.parser2.cpp.ICPPParserExtensionConfiguration; + +/** + * @author jcamelon + */ +public class CompleteParser2Tests extends TestCase { + + private static final NullLogService NULL_LOG = new NullLogService(); + private static final NullSourceElementRequestor NULL_REQUESTOR = new NullSourceElementRequestor(); + + protected IASTTranslationUnit parse(String code, boolean expectedToPass, + ParserLanguage lang) throws Exception { + return parse(code, expectedToPass, lang, false); + } + + protected IASTTranslationUnit parse(String code, boolean expectedToPass) throws Exception { + return parse(code, expectedToPass, ParserLanguage.CPP); + } + + /** + * @param code + */ + protected IASTTranslationUnit parse(String code) throws Exception { + return parse(code, true, ParserLanguage.CPP); + } + + ProblemCollector collector; + /** + * @param string + * @param b + * @param c + * @param d + */ + protected IASTTranslationUnit parse(String code, boolean expectedToPass, + ParserLanguage lang, boolean gcc) throws Exception { + + collector = new ProblemCollector(); + IScanner scanner = ParserFactory.createScanner(new CodeReader(code + .toCharArray()), new ScannerInfo(), ParserMode.COMPLETE_PARSE, + lang, NULL_REQUESTOR, NULL_LOG, Collections.EMPTY_LIST); + ISourceCodeParser parser2 = null; + if (lang == ParserLanguage.CPP) { + ICPPParserExtensionConfiguration config = null; + if (gcc) + config = new GNUCPPParserExtensionConfiguration(); + else + config = new ANSICPPParserExtensionConfiguration(); + parser2 = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, + collector, NULL_LOG, config); + } else { + ICParserExtensionConfiguration config = null; + if (gcc) + config = new GCCParserExtensionConfiguration(); + else + config = new ANSICParserExtensionConfiguration(); + + parser2 = new GNUCSourceParser(scanner, ParserMode.COMPLETE_PARSE, + collector, NULL_LOG, config); + } + IASTTranslationUnit tu = parser2.parse(); + if (parser2.encounteredError() && expectedToPass) + throw new ParserException("FAILURE"); //$NON-NLS-1$ + if (expectedToPass) + assertTrue(collector.hasNoProblems()); + return tu; + } + + public void testEmptyCompilationUnit() throws Exception + { + parse( "// no real code "); //$NON-NLS-1$ + } + + public void testSimpleNamespace() throws Exception + { + parse( "namespace A { }").getDeclarations(); //$NON-NLS-1$ + } + + public void testMultipleNamespaceDefinitions() throws Exception + { + parse( "namespace A { } namespace A { }"); //$NON-NLS-1$ + } + + public void testNestedNamespaceDefinitions() throws Exception + { + parse( "namespace A { namespace B { } }"); //$NON-NLS-1$ + } + + public void testEmptyClassDeclaration() throws Exception + { + parse( "class A { };"); //$NON-NLS-1$ + } + + public void testSimpleSubclass() throws Exception + { + parse( "class A { }; class B : public A { };"); //$NON-NLS-1$ + } + + public void testNestedSubclass() throws Exception + { + parse( "namespace N { class A { }; } class B : protected virtual N::A { };"); //$NON-NLS-1$ + } + + public void testSimpleVariable() throws Exception + { + parse( "int x;"); //$NON-NLS-1$ + } + + public void testSimpleClassReferenceVariable() throws Exception + { + parse( "class A { }; A x;"); //$NON-NLS-1$ + } + + public void testNestedClassReferenceVariable() throws Exception + { + parse( "namespace N { class A { }; } N::A x;"); //$NON-NLS-1$ + } + + public void testMultipleDeclaratorsVariable() throws Exception + { + parse( "class A { }; A x, y, z;"); //$NON-NLS-1$ + } + + public void testSimpleField() throws Exception + { + parse( "class A { double x; };"); //$NON-NLS-1$ + } + + public void testUsingClauses() throws Exception + { + parse( "namespace A { namespace B { int x; class C { static int y = 5; }; } } \n using namespace A::B;\n using A::B::x;using A::B::C;using A::B::C::y;"); //$NON-NLS-1$ + } + + public void testEnumerations() throws Exception + { + parse( "namespace A { enum E { e1, e2, e3 }; E varE;}"); //$NON-NLS-1$ + } + + public void testSimpleFunction() throws Exception + { + parse( "void foo( void );"); //$NON-NLS-1$ + } + + public void testSimpleFunctionWithTypes() throws Exception + { + parse( "class A { public: \n class B { }; }; const A::B & foo( A * myParam );"); //$NON-NLS-1$ + } + + public void testSimpleMethod() throws Exception + { + parse( "class A { void foo(); };"); //$NON-NLS-1$ + } + + public void testSimpleMethodWithTypes() throws Exception + { + parse( "class U { }; class A { U foo( U areDumb ); };"); //$NON-NLS-1$ + } + + public void testUsingDeclarationWithFunctionsAndMethods() throws Exception + { + parse( "namespace N { int foo(void); } class A { static int bar(void); }; using N::foo; using ::A::bar;" ); //$NON-NLS-1$ + } + + public void testLinkageSpec() throws Exception + { + parse( "extern \"C\" { int foo(); }"); //$NON-NLS-1$ + } + + + public void testBogdansExample() throws Exception + { + parse( "namespace A { namespace B { enum e1{e_1,e_2}; int x; class C { static int y = 5; }; }} "); //$NON-NLS-1$ + } + + public void testAndrewsExample() throws Exception + { + parse( "namespace N{ class A {}; } using namespace N; class B: public A{};"); //$NON-NLS-1$ + } + + public void testSimpleTypedef() throws Exception + { + parse( "typedef int myInt;\n myInt var;"); //$NON-NLS-1$ + } + + public void testComplexTypedef() throws Exception + { + parse( "class A{ }; typedef A ** A_DOUBLEPTR;"); //$NON-NLS-1$ + } + + + protected void assertQualifiedName(String [] fromAST, String [] theTruth) + { + assertNotNull( fromAST ); + assertNotNull( theTruth ); + assertEquals( fromAST.length, theTruth.length ); + for( int i = 0; i < fromAST.length; ++i ) + { + assertEquals( fromAST[i], theTruth[i]); + } + } + + public void testBug40842() throws Exception{ + Writer code = new StringWriter(); + code.write("class A {} a;\n"); //$NON-NLS-1$ + parse(code.toString()); + } + + public void testNestedClassname() throws Exception + { + parse( "namespace A { } \n class A::B { };"); //$NON-NLS-1$ + } + + public void testForwardDeclaration() throws Exception + { + parse( "class forward;"); //$NON-NLS-1$ + } + + public void testElaboratedType() throws Exception + { + parse( "class A; class A * a;"); //$NON-NLS-1$ + } + + public void testForewardDeclarationWithUsage() throws Exception + { + parse( "class A; A * anA;class A { };"); //$NON-NLS-1$ + } + + + public void testASM() throws Exception + { + parse( "asm ( \"blah blah blah\" );" ); //$NON-NLS-1$ + } + + public void testOverride() throws Exception + { + parse( "void foo();\n void foo( int );\n"); //$NON-NLS-1$ + } + + public void testSimpleExpression() throws Exception + { + parse( "int x; int y = x;"); //$NON-NLS-1$ + } + + public void testParameterExpressions() throws Exception + { + parse( "int x = 5; void foo( int sub = x ) { }"); //$NON-NLS-1$ + } + + public void testNestedNamespaceExpression() throws Exception + { + parse( "namespace A { int x = 666; } int y = A::x;"); //$NON-NLS-1$ + } + + public void testConstructorChain() throws Exception + { + parse( "int x = 5;\n class A \n{ public : \n int a; \n A() : a( x ) { } };"); //$NON-NLS-1$ + } + + public void testArrayModExpression() throws Exception + { + parse( "const int x = 5; int y [ x ]; "); //$NON-NLS-1$ + } + + + public void testPointerVariable() throws Exception + { + parse( "class A { }; A * anA;"); //$NON-NLS-1$ + } + + public void testExceptionSpecification() throws Exception + { + parse( "class A { }; void foo( void ) throw ( A );"); //$NON-NLS-1$ + } + + public void testNewExpressions() throws Exception + { + parse( "int A; int B; int C; int D; int P; int*p = new (P) (A)[B][C][D];" ); //$NON-NLS-1$ + } + + public void testBug41520() throws Exception + { + parse( "const int x = 666; const int y( x );"); //$NON-NLS-1$ + } + + public void testNewXReferences() throws Exception + { + parse( "const int max = 5;\n int * x = new int[max];"); //$NON-NLS-1$ + } + + public void testQualifiedNameReferences() throws Exception + { + // Used to cause AST Semantic exception + parse( "class A{ class B{ class C { public: int cMethod(); }; }; }; \n int A::B::C::cMethod() {}; \n" ); //$NON-NLS-1$ + } + + public void testIsConstructor() throws Exception + { + parse( "class A{ public: A(); }; \n A::A() {}; \n" ); //$NON-NLS-1$ + } + + public void testIsDestructor() throws Exception + { + parse( "class A{ public: ~A(); }; \n A::~A() {}; \n" ); //$NON-NLS-1$ + } + + public void testBug41445() throws Exception + { + parse( "class A { }; namespace N { class B : public A { struct A {}; }; }"); //$NON-NLS-1$ + } + + public void testSimpleFunctionBody() throws Exception + { + parse( "class A { int f1(); }; const int x = 4; int f() { return x; } int A::f1() { return x; }"); //$NON-NLS-1$ + } + + + public void testSimpleForLoop() throws Exception + { + parse( "const int FIVE = 5; void f() { int x = 0; for( int i = 0; i < FIVE; ++i ) { x += i; } }"); //$NON-NLS-1$ + } + + public void testBug42541() throws Exception + { + parse( "union{ int v; char a; } id;" ); //$NON-NLS-1$ + } + + + + public void testSimpleIfStatement() throws Exception + { + parse( "const bool T = true; int foo() { if( T ) { return 5; } else if( ! T ) return 20; else { return 10; } }"); //$NON-NLS-1$ + } + + public void testSimpleWhileStatement() throws Exception + { + parse( "const bool T = true; void foo() { int x = 0; while( T ) { ++x; if( x == 100 ) break; } }"); //$NON-NLS-1$ + } + + public void testSimpleSwitchStatement() throws Exception + { + parse( "const int x = 5; const int y = 10; void foo() { switch( x ) { case 1: break; case 2: goto blah; case y: continue; default: break;} }"); //$NON-NLS-1$ + } + + public void testSimpleDoStatement() throws Exception + { + parse( "const int x = 3; int counter = 0; void foo() { do { ++counter; } while( counter != x ); } "); //$NON-NLS-1$ + } + + public void testThrowStatement() throws Exception + { + parse( "class A { }; void foo() throw ( A ) { throw A; throw; } "); //$NON-NLS-1$ + } + + public void testScoping() throws Exception + { + parse( "void foo() { int x = 3; if( x == 1 ) { int x = 4; } else int x = 2; }"); //$NON-NLS-1$ + } + + public void testEnumeratorReferences() throws Exception + { + parse( "enum E { e1, e2, e3 }; E anE = e1;"); //$NON-NLS-1$ + } + + public void testBug42840() throws Exception + { + parse( "void foo(); void foo() { } class SearchMe { };"); //$NON-NLS-1$ + } + + public void testBug42872() throws Exception + { + parse( "struct B {}; struct D : B {}; void foo(D* dp) { B* bp = dynamic_cast(dp); }" ); //$NON-NLS-1$ + } + + public void testBug43503A() throws Exception { + parse("class SD_01 { void f_SD_01() {}}; int main(){ SD_01 * a = new SD_01(); a->f_SD_01(); } "); //$NON-NLS-1$ + } + + + public void testBug42979() throws Exception + { + Writer code = new StringWriter(); + code.write( "class OperatorOverload{\n" ); //$NON-NLS-1$ + code.write( "public:\n" ); //$NON-NLS-1$ + code.write( " bool operator==( const class OperatorOverload& that )\n" ); //$NON-NLS-1$ + code.write( " { return true; }\n" ); //$NON-NLS-1$ + code.write( " bool operator!=( const class OperatorOverload& that );\n" ); //$NON-NLS-1$ + code.write( "}; \n" ); //$NON-NLS-1$ + + code.write( "bool OperatorOverload::operator!=( const class OperatorOverload& that )\n" ); //$NON-NLS-1$ + code.write( "{ return false; }\n" ); //$NON-NLS-1$ + + parse( code.toString() ); + } + /** + * class A { static int x; } int A::x = 5; + */ + public void testBug43373() throws Exception + { + parse( "class A { static int x; }; int A::x = 5;" ); //$NON-NLS-1$ + } + + public void testBug39504() throws Exception + { + parse( "const int w = 2; int x[ 5 ]; int y = sizeof (x[w]);" ); //$NON-NLS-1$ + } + + public void testBug43375() throws Exception + { + parse( "extern int x;"); //$NON-NLS-1$ + } + + public void testBug43503() throws Exception + { + StringBuffer buff = new StringBuffer(); + + buff.append( "class SD_02 {"); //$NON-NLS-1$ + buff.append( " public:"); //$NON-NLS-1$ + buff.append( " void f_SD_02();"); //$NON-NLS-1$ + buff.append( " };"); //$NON-NLS-1$ + buff.append( "class SD_01 {\n"); //$NON-NLS-1$ + buff.append( " public:\n"); //$NON-NLS-1$ + buff.append( " SD_02 *next;"); // REFERENCE SD_02 //$NON-NLS-1$ + buff.append( " void f_SD_01();\n"); //$NON-NLS-1$ + buff.append( "};\n"); //$NON-NLS-1$ + buff.append( "int main(){\n"); //$NON-NLS-1$ + buff.append( " SD_01 a = new SD_01();\n"); // REFERENCE SD_01 * 2 //$NON-NLS-1$ + buff.append( " a->f_SD_01();\n"); // REFERENCE a && REFERENCE f_SD_01 //$NON-NLS-1$ + buff.append( "}\n"); //$NON-NLS-1$ + buff.append( "void SD_01::f_SD_01()\n"); // REFERENCE SD_01 //$NON-NLS-1$ + buff.append( "{\n"); //$NON-NLS-1$ + buff.append( " next->f_SD_02();\n"); // REFERENCE next && reference f_SD_02 //$NON-NLS-1$ + buff.append( "}\n"); //$NON-NLS-1$ + parse( buff.toString() ); + } + + public void testBug43679_A () throws Exception + { + parse( "struct Sample { int size() const; }; extern const Sample * getSample(); int trouble() { return getSample()->size(); } ", false ); //$NON-NLS-1$ + } + + public void testBug43679_B () throws Exception + { + parse( "struct Sample{int size() const; }; struct Sample; ", false ); //$NON-NLS-1$ + } + + public void testBug43951() throws Exception + { + parse( "class B{ B(); ~B(); }; B::B(){} B::~B(){}", false ); //$NON-NLS-1$ + } + + public void testBug44342() throws Exception { + parse("class A { void f(){} void f(int){} }; int main(){ A * a = new A(); a->f();} "); //$NON-NLS-1$ + } + + + public void testCDesignatedInitializers() throws Exception + { + StringBuffer buffer = new StringBuffer(); + buffer.append( "struct Inner { int a,b,c; };"); //$NON-NLS-1$ + buffer.append( "struct A { int x; int y[]; struct Inner innerArray[]; int z []; };"); //$NON-NLS-1$ + buffer.append( "struct A myA = { .x = 4, .y[3] = 4, .y[4] = 3, .innerArray[0].a = 3, .innerArray[1].b = 5, .innerArray[2].c=6, .z = { 1,4,5} };"); //$NON-NLS-1$ + parse( buffer.toString(), true, ParserLanguage.C ); + } + + public void testBug39551A() throws Exception + { + parse("extern float _Complex conjf (float _Complex);", true, ParserLanguage.C); //$NON-NLS-1$ + } + + public void testBug39551B() throws Exception + { + //this used to be 99.99 * __I__, but I don't know where the __I__ came from, its not in C99, nor in GCC + parse("_Imaginary double id = 99.99 * 1i;", true, ParserLanguage.C); //$NON-NLS-1$ + } + + public void testCBool() throws Exception + { + parse( "_Bool x;", true, ParserLanguage.C ); //$NON-NLS-1$ + } + + public void testCBoolAsParameter() throws Exception + { + parse( "void f( _Bool b ) {} " + //$NON-NLS-1$ + "_Bool g( _Bool b ) {} " + //$NON-NLS-1$ + "void main(){" + //$NON-NLS-1$ + " _Bool b; " + //$NON-NLS-1$ + " f(b);" + //$NON-NLS-1$ + " f( g( (_Bool) 1 ) );" + //$NON-NLS-1$ + "}", //$NON-NLS-1$ + true, ParserLanguage.C ); + } + + public void testBug44510() throws Exception + { + parse( "int initialize(); " + //$NON-NLS-1$ + "int initialize( char ){} " + //$NON-NLS-1$ + "int initialize(){ return 1; } " + //$NON-NLS-1$ + "void main(){ int i = initialize(); }" ); //$NON-NLS-1$ + } + + public void testBug44925() throws Exception + { + StringBuffer buffer = new StringBuffer(); + buffer.append( "class MyClass { };"); //$NON-NLS-1$ + buffer.append( "class MyClass myObj1;"); //$NON-NLS-1$ + buffer.append( "enum MyEnum { Item1 };"); //$NON-NLS-1$ + buffer.append( "enum MyEnum myObj2;"); //$NON-NLS-1$ + parse( buffer.toString() ); + } + + public void testBug44838() throws Exception + { + StringBuffer buffer = new StringBuffer(); + buffer.append( "class A { int myX; A( int x ); };\n"); //$NON-NLS-1$ + buffer.append( "A::A( int x ) : myX( x ) { if( x == 5 ) myX++; }\n"); //$NON-NLS-1$ + parse( buffer.toString() ); + } + + public void testBug46165() throws Exception + { + StringBuffer buffer = new StringBuffer(); + buffer.append( "class A { int myX; A( int x ); };\n"); //$NON-NLS-1$ + buffer.append( "A::A( int x ) : myX( x ) { if( x == 5 ) myX++; }\n"); //$NON-NLS-1$ + parse( buffer.toString() ); + } + + public void testBug47624() throws Exception + { + StringBuffer buffer = new StringBuffer(); + buffer.append( "struct s { }; \n" ); //$NON-NLS-1$ + buffer.append( "void f ( int s ) { \n" ); //$NON-NLS-1$ + buffer.append( " struct s sInstance; \n" ); //$NON-NLS-1$ + buffer.append( "}\n"); //$NON-NLS-1$ + parse( buffer.toString() ); + } + + public void testQualifiedLookup() throws Exception{ + //this is meant to test that on a->f, the lookup for f is qualified + //the namespace is necessary because of bug 47926 + StringBuffer buffer = new StringBuffer(); + buffer.append( "namespace N {" ); //$NON-NLS-1$ + buffer.append( " void f () {} \n" ); //$NON-NLS-1$ + buffer.append( " class A { }; \n" ); //$NON-NLS-1$ + buffer.append( "}" ); //$NON-NLS-1$ + buffer.append( "void main() { N::A * a = new N::A(); a->f(); } "); //$NON-NLS-1$ + parse( buffer.toString() ); + } + + public void testBug43110() throws Exception + { + StringBuffer buffer = new StringBuffer(); + buffer.append("void x( int y, ... );\n"); //$NON-NLS-1$ + buffer.append("void y( int x... );\n"); //$NON-NLS-1$ + buffer.append("void z(...);"); //$NON-NLS-1$ + parse(buffer.toString() ); + } + + public void testBug43110_XRef() throws Exception + { + StringBuffer buffer = new StringBuffer(); + buffer.append( "void foo( ... ) {}\n" ); //$NON-NLS-1$ + buffer.append( "void main( ){ foo( 1 ); }\n" ); //$NON-NLS-1$ + + parse( buffer.toString() ); + } + + public void testErrorHandling_1() throws Exception + { + parse( "A anA; int x = c; class A {}; A * anotherA = &anA; int b;", false ); //$NON-NLS-1$ + } + + public void testBug44340() throws Exception { + // inline function with reference to variables declared after them + parse ("class A{ int getX() {return x[1];} int x[10];};", false ); //$NON-NLS-1$ + } + + public void testBug47628() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "void h(char) { }\n"); //$NON-NLS-1$ + writer.write( "void h(unsigned char) { }\n"); //$NON-NLS-1$ + writer.write( "void h(signed char) { } // not shown in outline, parsed as char\n"); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug47636() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "void f( char [] ); \n" ); //$NON-NLS-1$ + writer.write( "void f( char * ){} \n" ); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug45697() throws Exception + { + Writer writer = new StringWriter(); + writer.write( " int f( bool ); \n"); //$NON-NLS-1$ + writer.write( " int f( char ){ } "); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug54639() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "typedef enum _A { } A, *pA; " ); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug55163() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "void foo() { \n"); //$NON-NLS-1$ + writer.write( " int i, n; \n"); //$NON-NLS-1$ + writer.write( " double di; \n"); //$NON-NLS-1$ + writer.write( " for( i = n - 1, di = (double)( i + i ); i > 0; i-- ){ } \n"); //$NON-NLS-1$ + writer.write( "}\n"); //$NON-NLS-1$ + + parse( writer.toString() ); + } + public void testBug55673() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "struct Example { int i; int ( * pfi ) ( int ); }; "); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug54531() throws Exception + { + parse( "typedef enum _A {} A, *pA;" ); //$NON-NLS-1$ + } + + public void testBug56516() throws Exception + { + parse( "typedef struct blah sb;"); //$NON-NLS-1$ + } + + public void testBug53786() throws Exception + { + parse( "struct Example { struct Data * data; };"); //$NON-NLS-1$ + } + + public void testBug54029() throws Exception + { + parse( "typedef int T; T i;" ); //$NON-NLS-1$ + } + + public void testBug47625() throws Exception + { + Writer writer = new StringWriter(); + writer.write("struct s { int num; }; "); //$NON-NLS-1$ + writer.write("namespace ns{ "); //$NON-NLS-1$ + writer.write(" struct s { double num; };"); //$NON-NLS-1$ + writer.write(" s inner = { 3.14 };"); //$NON-NLS-1$ + writer.write(" ::s outer = { 42 };"); //$NON-NLS-1$ + writer.write("}"); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug57754() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "struct X { " ); //$NON-NLS-1$ + writer.write( " typedef int T; " ); //$NON-NLS-1$ + writer.write( " void f( T ); " ); //$NON-NLS-1$ + writer.write( "}; " ); //$NON-NLS-1$ + writer.write( "void X::f( T ) { } " ); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug57800() throws Exception + { + Writer writer= new StringWriter(); + writer.write( "class G2 { int j; };"); //$NON-NLS-1$ + writer.write( "typedef G2 AltG2;"); //$NON-NLS-1$ + writer.write( "class AltG3 : AltG2 { int x;};"); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug46246() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "struct A { "); //$NON-NLS-1$ + writer.write( " struct B { int ab; } b; "); //$NON-NLS-1$ + writer.write( " int a; "); //$NON-NLS-1$ + writer.write( "}; "); //$NON-NLS-1$ + writer.write( "struct A a1; "); //$NON-NLS-1$ + writer.write( "struct B b1; "); //$NON-NLS-1$ + + parse( writer.toString(), true, ParserLanguage.C ); + } + + public void testBug45235() throws Exception + { + parse( "class A { friend class B; friend void f(); }; " ); //$NON-NLS-1$ + } + + public void testBug57791() throws Exception + { + Writer writer = new StringWriter(); + writer.write(" void f() { "); //$NON-NLS-1$ + writer.write(" struct astruct astruct; "); //$NON-NLS-1$ + writer.write(" astruct.foo++; "); //$NON-NLS-1$ + writer.write(" }"); //$NON-NLS-1$ + + parse( writer.toString(), true, ParserLanguage.C ); + } + + public void testBug44249() throws Exception + { + + parse( "class SD_01 { public:\n void SD_01::f_SD_01();};" ); //$NON-NLS-1$ + } + + public void testBug59149() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "class A{ friend class B; friend class B; };" ); //$NON-NLS-1$ + writer.write( "class B{ };" ); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug59302() throws Exception + { + Writer writer = new StringWriter(); + writer.write("class A { class N{}; }; "); //$NON-NLS-1$ + writer.write("class B { friend class A::N; }; "); //$NON-NLS-1$ + parse( writer.toString() ); + } + + + + public void testULong() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "#ifndef ASMINCLUDE\n"); //$NON-NLS-1$ + writer.write( "typedef unsigned short ushort;\n"); //$NON-NLS-1$ + writer.write( "typedef volatile unsigned long semaphore;\n"); //$NON-NLS-1$ + writer.write( "typedef unsigned long ulong;\n"); //$NON-NLS-1$ + writer.write( "#ifndef _NO_LONGLONG\n"); //$NON-NLS-1$ + writer.write( "typedef long long longlong;\n"); //$NON-NLS-1$ + writer.write( "typedef unsigned long long ulonglong;\n"); //$NON-NLS-1$ + writer.write( "#endif /* _NO_LONGLONG */\n"); //$NON-NLS-1$ + writer.write( "#endif /* ASMINCLUDE */\n"); //$NON-NLS-1$ + writer.write( "typedef struct section_type_ {\n"); //$NON-NLS-1$ + writer.write( "ulong source;\n"); //$NON-NLS-1$ + writer.write( "ulong dest;\n"); //$NON-NLS-1$ + writer.write( "ulong bytes;\n"); //$NON-NLS-1$ + writer.write( "} section_type;\n"); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug47926() throws Exception + { + parse( "void f() {} class A {}; void main() { A * a = new A(); a->f(); }", false ); //$NON-NLS-1$ + } + + public void testBug50984_ASTMethod_getOwnerClassSpecifier_ClassCastException() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "template < typename _OutIter > " ); //$NON-NLS-1$ + writer.write( "class num_put { " ); //$NON-NLS-1$ + writer.write( " typedef _OutIter iter_type; " ); //$NON-NLS-1$ + writer.write( " template< typename _ValueT > " ); //$NON-NLS-1$ + writer.write( " iter_type _M_convert_float( iter_type ); " ); //$NON-NLS-1$ + writer.write( "}; " ); //$NON-NLS-1$ + writer.write( "template < typename _OutIter > " ); //$NON-NLS-1$ + writer.write( "template < typename _ValueT > " ); //$NON-NLS-1$ + writer.write( "_OutIter num_put<_OutIter>::_M_convert_float( _OutIter ) { } " ); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testGloballyQualifiedUsingDeclaration() throws Exception + { + parse( "int iii; namespace N { using ::iii; }" ); //$NON-NLS-1$ + } + + public void test57513_new() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "class A{ A(); A( int ); }; \n" ); //$NON-NLS-1$ + writer.write( " void f() { \n" ); //$NON-NLS-1$ + writer.write( " A * a1 = new A; \n" ); //$NON-NLS-1$ + writer.write( " A * a2 = new(1)A(); \n" ); //$NON-NLS-1$ + writer.write( " A * a3 = new A( 1 ); \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void test57513_NoConstructor() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "class A{ }; \n" ); //$NON-NLS-1$ + writer.write( " void f() { \n" ); //$NON-NLS-1$ + writer.write( " A * a1 = new A; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void test57513_ctorinit() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "class A{ A(); A( A * ); }; \n" ); //$NON-NLS-1$ + writer.write( "class B : public A { B(); }; \n" ); //$NON-NLS-1$ + writer.write( "B::B():A( new A ){} \n" ); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void test575513_qualified() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "namespace Foo{ " ); //$NON-NLS-1$ + writer.write( " class Bar{ public : Bar(); }; " ); //$NON-NLS-1$ + writer.write( "} " ); //$NON-NLS-1$ + writer.write( "void main(){ " ); //$NON-NLS-1$ + writer.write( " Foo::Bar * bar = new Foo::Bar(); " ); //$NON-NLS-1$ + writer.write( "} " ); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug60944() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "typedef int OurInt;\n"); //$NON-NLS-1$ + writer.write( "class A { int x; };\n"); //$NON-NLS-1$ + writer.write( "typedef A AnotherA;\n"); //$NON-NLS-1$ + writer.write( "typedef AnotherA SecondA;\n"); //$NON-NLS-1$ + writer.write( "typedef OurInt AnotherInt;\n" ); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testDestructorReference() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "class ABC {\n"); //$NON-NLS-1$ + writer.write( " public:\n"); //$NON-NLS-1$ + writer.write( " ~ABC(){ }\n"); //$NON-NLS-1$ + writer.write( "};\n"); //$NON-NLS-1$ + writer.write( "int main() { ABC * abc = new ABC();\n"); //$NON-NLS-1$ + writer.write( "abc->~ABC();\n"); //$NON-NLS-1$ + writer.write( "}\n"); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug39676_tough() throws Exception + { + parse( "int widths[] = { [0 ... 9] = 1, [10 ... 99] = 2, [100] = 3 };", true, ParserLanguage.C, true ); //$NON-NLS-1$ + } + + public void testBug60939() throws Exception + { + for( int i = 0; i < 2; ++i ) + { + Writer writer = new StringWriter(); + writer.write( "namespace ABC { class DEF { }; }\n"); //$NON-NLS-1$ + if( i == 0 ) + writer.write( "using namespace ABC;\n"); //$NON-NLS-1$ + else + writer.write( "using ABC::DEF;\n"); //$NON-NLS-1$ + writer.write( "class GHI : public DEF { };"); //$NON-NLS-1$ + parse( writer.toString() ); + } + + + } + + public void testBug64010() throws Exception + { + Writer writer = new StringWriter(); + writer.write( " #define ONE else if (0) { } \n"); //$NON-NLS-1$ + writer.write( " #define TEN ONE ONE ONE ONE ONE ONE ONE ONE ONE ONE \n "); //$NON-NLS-1$ + writer.write( " #define HUN TEN TEN TEN TEN TEN TEN TEN TEN TEN TEN \n "); //$NON-NLS-1$ + writer.write( " #define THOU HUN HUN HUN HUN HUN HUN HUN HUN HUN HUN \n"); //$NON-NLS-1$ + writer.write("void foo() "); //$NON-NLS-1$ + writer.write("{ "); //$NON-NLS-1$ + writer.write(" if (0) { } "); //$NON-NLS-1$ + writer.write(" /* 11,000 else if's. */ "); //$NON-NLS-1$ + writer.write(" THOU THOU THOU THOU THOU THOU THOU THOU THOU THOU THOU "); //$NON-NLS-1$ + writer.write("} "); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug64271() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "typedef int DWORD;\n" ); //$NON-NLS-1$ + writer.write( "typedef char BYTE;\n"); //$NON-NLS-1$ + writer.write( "#define MAKEFOURCC(ch0, ch1, ch2, ch3) \\\n"); //$NON-NLS-1$ + writer.write( "((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \\\n"); //$NON-NLS-1$ + writer.write( "((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 ))\n"); //$NON-NLS-1$ + writer.write( "enum e {\n"); //$NON-NLS-1$ + writer.write( "blah1 = 5,\n"); //$NON-NLS-1$ + writer.write( "blah2 = MAKEFOURCC('a', 'b', 'c', 'd'),\n"); //$NON-NLS-1$ + writer.write( "blah3\n"); //$NON-NLS-1$ + writer.write( "};\n"); //$NON-NLS-1$ + writer.write( "e mye = blah;\n"); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug47752() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "class BBC\n"); //$NON-NLS-1$ + writer.write( "{\n"); //$NON-NLS-1$ + writer.write( "int x;\n"); //$NON-NLS-1$ + writer.write( "};\n"); //$NON-NLS-1$ + writer.write( "void func( BBC bar )\n"); //$NON-NLS-1$ + writer.write( "try\n"); //$NON-NLS-1$ + writer.write( "{\n"); //$NON-NLS-1$ + writer.write( "}\n"); //$NON-NLS-1$ + writer.write( "catch ( BBC error )\n"); //$NON-NLS-1$ + writer.write( "{\n"); //$NON-NLS-1$ + writer.write( " //... error handling code ...\n"); //$NON-NLS-1$ + writer.write( "}\n"); //$NON-NLS-1$ + parse( writer.toString() ); + } + public void testBug61972() throws Exception + { + parse( "#define DEF1(A1) A1\n#define DEF2 DEF1(DEF2)\nDEF2;", false ); //$NON-NLS-1$ + } + + public void testBug65569() throws Exception + { + parse( "class Sample;\nstruct Sample { /* ... */ };" ); //$NON-NLS-1$ + } + + public void testBug64268() throws Exception + { + Writer writer = new StringWriter(); + writer.write("#define BODY \\\n"); //$NON-NLS-1$ + writer.write("for (;;) { \\\n"); //$NON-NLS-1$ + writer.write("/* this multi-line comment messes \\\n"); //$NON-NLS-1$ + writer.write("up the parser. */ }\n"); //$NON-NLS-1$ + writer.write(" void abc() {\n"); //$NON-NLS-1$ + writer.write("BODY\n"); //$NON-NLS-1$ + writer.write("}\n"); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug67622() throws Exception + { + parse( "const char * x = __FILE__;"); //$NON-NLS-1$ + } + + public void testBug67680() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "template < class T> class Base {}; \n" ); //$NON-NLS-1$ + writer.write( "class Derived : public Base, Base, foo {}; \n" ); //$NON-NLS-1$ + + parse( writer.toString(), false ); + } + + public void testTypeIDSignature() throws Exception + { + parse( "int * v = (int*)0;");//$NON-NLS-1$ + } + + public void testUnaryAmperCast() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "void f( char * ); \r\n "); //$NON-NLS-1$ + writer.write( "void f( char ); \n "); //$NON-NLS-1$ + writer.write( "void main() { \n "); //$NON-NLS-1$ + writer.write( " char * t = new char [ 5 ]; \n "); //$NON-NLS-1$ + writer.write( " f( &t[1] ); \n "); //$NON-NLS-1$ + writer.write( "} \n "); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug68235() throws Exception{ + Writer writer = new StringWriter(); + writer.write( " struct xTag { int x; }; "); //$NON-NLS-1$ + writer.write( " typedef xTag xType; "); //$NON-NLS-1$ + writer.write( " typedef struct yTag { int x; } yType; "); //$NON-NLS-1$ + writer.write( " class C1 { xType x; yType y; }; "); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug60407() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "struct ZZZ { int x, y, z; };\r\n" ); //$NON-NLS-1$ + writer.write( "typedef struct ZZZ _FILE;\n" ); //$NON-NLS-1$ + writer.write( "typedef _FILE FILE;\n" ); //$NON-NLS-1$ + writer.write( "static void static_function(FILE * lcd){}\n" ); //$NON-NLS-1$ + writer.write( "int main(int argc, char **argv) {\n" ); //$NON-NLS-1$ + writer.write( "FILE * file = 0;\n" ); //$NON-NLS-1$ + writer.write( "static_function( file );\n" ); //$NON-NLS-1$ + writer.write( "return 0;\n" ); //$NON-NLS-1$ + writer.write( "}\n" ); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug68623() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "class A { \n" ); //$NON-NLS-1$ + writer.write( " A(); \n" ); //$NON-NLS-1$ + writer.write( " class sub{}; \n" ); //$NON-NLS-1$ + writer.write( " sub * x; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + writer.write( "A::A() : x( (sub *) 0 ) {} \n" ); //$NON-NLS-1$ + + parse( writer.toString() ); + + writer = new StringWriter(); + writer.write( "class A { \n" ); //$NON-NLS-1$ + writer.write( " A() : x (0) {} \n" ); //$NON-NLS-1$ + writer.write( " int x; \n" ); //$NON-NLS-1$ + writer.write( "}; \n" ); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug69798() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "enum Flags { FLAG1, FLAG2 }; \n" ); //$NON-NLS-1$ + writer.write( "int f() { int a, b; b = ( a ? FLAG1 : 0 ) | FLAG2; } \n" ); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + public void testBug69662() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "class A { operator float * (); }; \n" ); //$NON-NLS-1$ + writer.write( "A::operator float * () { } \n" ); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + + public void testBug68528() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "namespace N526026\n" ); //$NON-NLS-1$ + writer.write( "{\n" ); //$NON-NLS-1$ + writer.write( "template \n" ); //$NON-NLS-1$ + writer.write( "class T526026\n" ); //$NON-NLS-1$ + writer.write( "{\n" ); //$NON-NLS-1$ + writer.write( "typedef int diff;\n" ); //$NON-NLS-1$ + writer.write( "};\n" ); //$NON-NLS-1$ + writer.write( "\n" ); //$NON-NLS-1$ + writer.write( "template\n" ); //$NON-NLS-1$ + writer.write( "inline T526026< T >\n" ); //$NON-NLS-1$ + writer.write( "operator+(typename T526026::diff d, const T526026 & x )\n" ); //$NON-NLS-1$ + writer.write( "{ return T526026< T >(); }\n" ); //$NON-NLS-1$ + writer.write( "}\n" ); //$NON-NLS-1$ + parse( writer.toString(), false ); + } + + public void testBug71094() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "using namespace DOESNOTEXIST;\n" ); //$NON-NLS-1$ + writer.write( "class A { int x; };\n" ); //$NON-NLS-1$ + parse( writer.toString(), false ); + } + + public void testPredefinedSymbol_bug70928() throws Exception { + // GNU builtin storage class type __cdecl preceded by a custom return type + parse("typedef int size_t; \n int __cdecl foo(); \n");//$NON-NLS-1$ + } + + public void testBug73652() throws Exception + { + StringWriter writer = new StringWriter(); + writer.write( "#define DoSuperMethodA IDoSuperMethodA\n" ); //$NON-NLS-1$ + writer.write( "#define IDoSuperMethodA(a,b,c) IIntuition->IDoSuperMethodA(a,b,c)\n" ); //$NON-NLS-1$ + writer.write( "void hang(void)\n" ); //$NON-NLS-1$ + writer.write( "{\n" ); //$NON-NLS-1$ + writer.write( "DoSuperMethodA(0,0,0);\n" ); //$NON-NLS-1$ + writer.write( "}\n" ); //$NON-NLS-1$ + parse( writer.toString() , false ); + } + + public void testBug73428() throws Exception + { + parse( "namespace { }");//$NON-NLS-1$ + parse( "namespace { };");//$NON-NLS-1$ + parse( "namespace { int abc; };");//$NON-NLS-1$ + parse( "namespace { int abc; }");//$NON-NLS-1$ + } + + public void testBug73615() throws Exception + { + for( int i = 0; i < 2; ++i ) + { + StringWriter writer = new StringWriter(); + if( i == 0 ) + writer.write( "class B;\n"); //$NON-NLS-1$ + writer.write( "class A { A( B * ); };\n"); //$NON-NLS-1$ + if( i == 0 ) + parse( writer.toString() ); + else + parse( writer.toString(), false ); + } + } + + public void testBug74180() throws Exception + { + parse( "enum DHCPFOBoolean { false, true } additionalHB, more_payload; \n", true, ParserLanguage.C ); //$NON-NLS-1$ + } + + public void testBug72691() throws Exception{ + StringWriter writer = new StringWriter(); + writer.write( "typedef int * PINT; \n" ); //$NON-NLS-1$ + writer.write( "typedef int * PINT; \n" ); //$NON-NLS-1$ + writer.write( "PINT pint; \n" ); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug72691_2() throws Exception{ + StringWriter writer = new StringWriter(); + writer.write( "typedef int * PINT; \n" ); //$NON-NLS-1$ + writer.write( "namespace N { \n" ); //$NON-NLS-1$ + writer.write( " typedef int * PINT; \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + writer.write( "using namespace N; \n" ); //$NON-NLS-1$ + writer.write( "PINT pint; \n" ); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug74328() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "int\n" ); //$NON-NLS-1$ + writer.write( "main(int argc, char **argv) {\n" ); //$NON-NLS-1$ + writer.write( " char *sign;\n" ); //$NON-NLS-1$ + writer.write( "sign = \"\"; // IProblem generated here, syntax error\n" ); //$NON-NLS-1$ + writer.write( "return argc;\n" ); //$NON-NLS-1$ + writer.write( "}\n" ); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug71733() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "void foo( int );\n"); //$NON-NLS-1$ + writer.write( "#define BLAH() \\\n"); //$NON-NLS-1$ + writer.write( " foo ( /* slash / is misinterpreted as end of comment */ \\\n"); //$NON-NLS-1$ + writer.write( " 4 );\n"); //$NON-NLS-1$ + writer.write( "int f() { BLAH() }\n"); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug69526() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "unsigned inkernel;\n" ); //$NON-NLS-1$ + writer.write( "#define lock_kernel() (inkernel |= 0x01)" ); //$NON-NLS-1$ + writer.write( "int main(int argc, char **argv) {" ); //$NON-NLS-1$ + writer.write( "lock_kernel();" ); //$NON-NLS-1$ + writer.write( "}" ); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug69454() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "#define CATCH_ALL_EXCEPTIONS() \\\n" ); //$NON-NLS-1$ + writer.write( " catch( Exception &ex ) { handleException( ex ); } \\\n" ); //$NON-NLS-1$ + writer.write( " catch( ... ) { handleException(); } \n" ); //$NON-NLS-1$ + writer.write( "class Exception; \n" ); //$NON-NLS-1$ + writer.write( "void handleException( Exception & ex ) {} \n" ); //$NON-NLS-1$ + writer.write( "void handleException() {} \n" ); //$NON-NLS-1$ + writer.write( "void f() { \n" ); //$NON-NLS-1$ + writer.write( " try { int i; } \n" ); //$NON-NLS-1$ + writer.write( " CATCH_ALL_EXCEPTIONS(); \n" ); //$NON-NLS-1$ + writer.write( "} \n" ); //$NON-NLS-1$ + + parse( writer.toString() ); + } + + + public void testBug72692A() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "extern double pow(double, double);\n"); //$NON-NLS-1$ + writer.write( "extern double pow2(double, double){}\n"); //$NON-NLS-1$ + writer.write( "namespace DS {\n"); //$NON-NLS-1$ + writer.write( "using ::pow;\n"); //$NON-NLS-1$ + writer.write( "using ::pow2;\n"); //$NON-NLS-1$ + writer.write( "}\n"); //$NON-NLS-1$ + writer.write( "using DS::pow;\n"); //$NON-NLS-1$ + writer.write( "using DS::pow2;\n"); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug72692B() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "extern double pow(double, double);\n"); //$NON-NLS-1$ + writer.write( "namespace DS {\n"); //$NON-NLS-1$ + writer.write( "using ::pow;\n"); //$NON-NLS-1$ + writer.write( "inline float pow(float __x, float __y)\n" ); //$NON-NLS-1$ + writer.write( "{ return ::pow(static_cast(__x), static_cast(__y)); }\n" ); //$NON-NLS-1$ + writer.write( "}\n"); //$NON-NLS-1$ + writer.write( "using namespace DS;\n"); //$NON-NLS-1$ + writer.write( "float foo() { double d1 = 3.0, d2 = 4.0; return pow(d1, d2); }"); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug72692C() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "extern double pow(double, double){}\n"); //$NON-NLS-1$ + writer.write( "namespace DS {\n"); //$NON-NLS-1$ + writer.write( "using ::pow;\n"); //$NON-NLS-1$ + writer.write( "}\n"); //$NON-NLS-1$ + writer.write( "using DS::pow;\n"); //$NON-NLS-1$ + parse( writer.toString() ); + } + + + public void testBug74575A() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "double pow(double, double);\n"); //$NON-NLS-1$ + writer.write( "float pow(float __x, float __y)\n" ); //$NON-NLS-1$ + writer.write( "{ return 0; }\n"); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug75338() throws Exception + { + Writer writer = new StringWriter(); + writer.write( "class Thrown { };\n"); //$NON-NLS-1$ + writer.write( "void foo() throw( Thrown );"); //$NON-NLS-1$ + parse( writer.toString() ); + } + + public void testBug74847() throws Exception { + String code = "class A : public FOO {};"; //$NON-NLS-1$ + parse( code, false ); + } + + public void testBug76696() throws Exception{ + Writer writer = new StringWriter(); + writer.write(" void f(){ \n"); //$NON-NLS-1$ + writer.write(" if( A a) { \n"); //$NON-NLS-1$ + writer.write(" } else { \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + writer.write(" } \n"); //$NON-NLS-1$ + + parse( writer.toString(), false ); + } + + public void testBug74069() throws Exception{ + Writer writer = new StringWriter(); + writer.write( "int f() { \n"); //$NON-NLS-1$ + writer.write( " int a, b, c; \n"); //$NON-NLS-1$ + writer.write( " if( a < b ) \n"); //$NON-NLS-1$ + writer.write( " if( b < c ) \n"); //$NON-NLS-1$ + writer.write( " return b; \n"); //$NON-NLS-1$ + writer.write( " else if ( a < c ) \n"); //$NON-NLS-1$ + writer.write( " return c; \n"); //$NON-NLS-1$ + writer.write( " else \n"); //$NON-NLS-1$ + writer.write( " return a; \n"); //$NON-NLS-1$ + writer.write( " else if( a < c ) \n"); //$NON-NLS-1$ + writer.write( " return a; \n"); //$NON-NLS-1$ + writer.write( " else if( b < c ) \n"); //$NON-NLS-1$ + writer.write( " return c; \n"); //$NON-NLS-1$ + writer.write( " else \n"); //$NON-NLS-1$ + writer.write( " return b; \n"); //$NON-NLS-1$ + writer.write( "} \n"); //$NON-NLS-1$ + + parse( writer.toString() ); + } + public void testBug77805() throws Exception { + Writer writer = new StringWriter(); + writer.write("#if X // Do something only if X is true\n"); //$NON-NLS-1$ + writer.write("/* some statements */\n"); //$NON-NLS-1$ + writer.write("#endif\n"); //$NON-NLS-1$ + parse(writer.toString()); + } + + public void testBug77821() throws Exception { + Writer writer = new StringWriter(); + writer.write("typedef struct { /* ... */ }TYPE;\n"); //$NON-NLS-1$ + writer.write("void ptrArith(const TYPE* pType) {\n"); //$NON-NLS-1$ + writer.write("TYPE *temp = 0;\n"); //$NON-NLS-1$ + writer.write("temp = (TYPE*)(pType + 1); /* Parser error is here */\n}\n"); //$NON-NLS-1$ + parse(writer.toString()); + } + + public void testBug77009() throws Exception + { + parse("int foo(volatile int &);\n"); //$NON-NLS-1$ + } + + + public void testBug77281() throws Exception { + Writer writer = new StringWriter(); + writer.write("void fun2(float a, float b) {}\n"); //$NON-NLS-1$ + writer.write("int main() { fun2(0.24f, 0.25f); }\n"); //$NON-NLS-1$ + parse(writer.toString()); + } + + public void testBug77921() throws Exception { + Writer writer = new StringWriter(); + writer.write("void f()\n{\n"); //$NON-NLS-1$ + writer.write("static float v0[] = { -1.0f, -1.0f, 1.0f };\n}\n"); //$NON-NLS-1$ + parse(writer.toString()); + } + + + public void testBug71317A() throws Exception { + Writer writer = new StringWriter(); + writer.write("void f();\n"); //$NON-NLS-1$ + writer.write("namespace NS {\n"); //$NON-NLS-1$ + writer.write("using ::f;\n"); //$NON-NLS-1$ + writer.write("using ::f;\n}"); //$NON-NLS-1$ + parse(writer.toString()); + } + + public void testBug71317B() throws Exception { + Writer writer = new StringWriter(); + writer.write("void f();\n"); //$NON-NLS-1$ + writer.write("namespace NS {\n"); //$NON-NLS-1$ + writer.write("void f();\n"); //$NON-NLS-1$ + writer.write("using ::f;\n}"); //$NON-NLS-1$ + parse(writer.toString()); + } + + public void testBug77097() throws Exception { + Writer writer = new StringWriter(); + writer.write("#define SOME_MACRO() { \\\r\n"); //$NON-NLS-1$ + writer.write("printf(\"Hello World\"); \\\r\n"); //$NON-NLS-1$ + writer.write("printf(\"Good morning\"); \\\r\n"); //$NON-NLS-1$ + parse(writer.toString()); + } + + public void testBug77276() throws Exception { + Writer writer = new StringWriter(); + writer.write("#if (!defined(OS_LIBMODE_R) && !defined(OS_LIBMODE_RP) && \\\r\n"); //$NON-NLS-1$ + writer.write("!defined(OS_LIBMODE_T))\r\n"); //$NON-NLS-1$ + writer.write("#define OS_LIBMODE_DP\r\n"); //$NON-NLS-1$ + writer.write("#endif\r\n"); //$NON-NLS-1$ + parse(writer.toString()); + } + + public void testBug78165() throws Exception { + Writer writer = new StringWriter(); + writer.write("struct Node {\n"); //$NON-NLS-1$ + writer.write("struct Node* Next; // OK: Refers to Node at global scope\n"); //$NON-NLS-1$ + writer.write("struct Data* Data; // OK: Declares type Data at global scope and member Data\n"); //$NON-NLS-1$ + writer.write("};\n"); //$NON-NLS-1$ + writer.write("struct Data {\n"); //$NON-NLS-1$ + writer.write("struct Node* Node; // OK: Refers to Node at global scope\n"); //$NON-NLS-1$ + writer.write("friend struct Glob; // OK: Refers to (as yet) undeclared Glob at global scope.\n"); //$NON-NLS-1$ + writer.write("};\n"); //$NON-NLS-1$ + writer.write("struct Base {\n"); //$NON-NLS-1$ + writer.write("struct Data; // OK: Declares nested Data\n"); //$NON-NLS-1$ + writer.write("struct ::Data* thatData; // OK: Refers to ::Data\n"); //$NON-NLS-1$ + writer.write("struct Base::Data* thisData; // OK: Refers to nested Data\n"); //$NON-NLS-1$ + writer.write("friend class ::Data; // OK: global Data is a friend\n"); //$NON-NLS-1$ + writer.write("friend class Data; // OK: nested Data is a friend\n"); //$NON-NLS-1$ + writer.write("struct Data { /* ... */ }; // Defines nested Data\n"); //$NON-NLS-1$ + writer.write("struct Data; // OK: Redeclares nested Data\n"); //$NON-NLS-1$ + writer.write("};\n"); //$NON-NLS-1$ + writer.write("struct Data; // OK: Redeclares Data at global scope\n"); //$NON-NLS-1$ + writer.write("struct Base::Data* pBase; // OK: refers to nested Data\n"); //$NON-NLS-1$ + + parse( writer.toString() ); + } + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/ProblemCollector.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/ProblemCollector.java new file mode 100644 index 00000000000..05713748e70 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/ProblemCollector.java @@ -0,0 +1,44 @@ +/********************************************************************** + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM - Initial API and implementation + **********************************************************************/ +package org.eclipse.cdt.core.parser.tests.parser2; + +import java.util.ArrayList; +import java.util.List; + +import org.eclipse.cdt.core.parser.IProblem; +import org.eclipse.cdt.internal.core.parser2.IProblemRequestor; + + +/** + * @author jcamelon + */ +public class ProblemCollector implements IProblemRequestor { + + List problems = new ArrayList(); + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.IProblemRequestor#acceptProblem(org.eclipse.cdt.core.parser.IProblem) + */ + public boolean acceptProblem(IProblem problem) { + problems.add(problem); + return true; + } + + /** + * @return + */ + public boolean hasNoProblems() { + return problems.isEmpty(); + } + +} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/QuickParser2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/QuickParser2Tests.java index 6f3b57083fa..ebe9611656f 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/QuickParser2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/parser2/QuickParser2Tests.java @@ -12,15 +12,11 @@ package org.eclipse.cdt.core.parser.tests.parser2; import java.io.IOException; import java.io.StringWriter; import java.io.Writer; -import java.util.ArrayList; import java.util.Collections; -import java.util.List; import junit.framework.TestCase; -import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.parser.CodeReader; -import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.NullLogService; import org.eclipse.cdt.core.parser.NullSourceElementRequestor; @@ -29,7 +25,6 @@ import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ParserMode; import org.eclipse.cdt.core.parser.ScannerInfo; import org.eclipse.cdt.internal.core.parser.ParserException; -import org.eclipse.cdt.internal.core.parser2.IProblemRequestor; import org.eclipse.cdt.internal.core.parser2.ISourceCodeParser; import org.eclipse.cdt.internal.core.parser2.c.ANSICParserExtensionConfiguration; import org.eclipse.cdt.internal.core.parser2.c.GCCParserExtensionConfiguration; @@ -45,34 +40,7 @@ import org.eclipse.cdt.internal.core.parser2.cpp.ICPPParserExtensionConfiguratio */ public class QuickParser2Tests extends TestCase { - /** - * @author jcamelon - */ - public static class ProblemCollector implements IProblemRequestor { - - List problems = new ArrayList(); - - /* - * (non-Javadoc) - * - * @see org.eclipse.cdt.internal.core.parser2.IProblemRequestor#acceptProblem(org.eclipse.cdt.core.parser.IProblem) - */ - public boolean acceptProblem(IProblem problem) { - problems.add(problem); - return true; - } - - /** - * @return - */ - public boolean hasNoProblems() { - return problems.isEmpty(); - } - - } - private static final NullLogService NULL_LOG = new NullLogService(); - private static final NullSourceElementRequestor NULL_REQUESTOR = new NullSourceElementRequestor(); /** @@ -1409,7 +1377,7 @@ public class QuickParser2Tests extends TestCase { parser2 = new GNUCSourceParser(scanner, ParserMode.QUICK_PARSE, collector, NULL_LOG, config); } - IASTTranslationUnit tu = parser2.parse(); + parser2.parse(); if (parser2.encounteredError() && expectedToPass) throw new ParserException("FAILURE"); //$NON-NLS-1$ if (expectedToPass) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/AbstractGNUSourceCodeParser.java index 385e2f01549..b5327f617ff 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/AbstractGNUSourceCodeParser.java @@ -846,9 +846,12 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { IASTUnaryExpression result = createUnaryExpression(); ((ASTNode)result).setOffset(offset); result.setOperator(operator); - result.setOperand(operand); - operand.setParent(result); - operand.setPropertyInParent(IASTUnaryExpression.OPERAND); + if( operand != null ) + { + result.setOperand(operand); + operand.setParent(result); + operand.setPropertyInParent(IASTUnaryExpression.OPERAND); + } return result; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/DeclarationWrapper.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/DeclarationWrapper.java deleted file mode 100644 index 9f8c4efdb24..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/DeclarationWrapper.java +++ /dev/null @@ -1,497 +0,0 @@ -/********************************************************************** - * Copyright (c) 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - **********************************************************************/ -package org.eclipse.cdt.internal.core.parser2; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Hashtable; -import java.util.Iterator; -import java.util.List; -import java.util.Map; - -import org.eclipse.cdt.core.parser.ITokenDuple; -import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier; -import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier.Type; - -public class DeclarationWrapper implements IDeclaratorOwner -{ - private int flag = 0; - protected void setBit(boolean b, int mask){ - if( b ){ - flag = flag | mask; - } else { - flag = flag & ~mask; - } - } - - protected boolean checkBit(int mask){ - return (flag & mask) != 0; - } - - private static final int DEFAULT_LIST_SIZE = 4; - - protected static final int IS_IMAGINARY = 0x00000010; - protected static final int IS_COMPLEX = 0x00000020; - protected static final int IS_RESTRICT = 0x00000040; - protected static final int IS_SIGNED = 0x00000080; - protected static final int IS_SHORT = 0x00000100; - protected static final int IS_UNSIGNED = 0x00000200; - protected static final int IS_LONG = 0x00000400; - protected static final int IS_TYPENAMED = 0x00000800; - protected static final int IS_VOLATILE = 0x00001000; - protected static final int IS_VIRTUAL = 0x00002000; - protected static final int IS_TYPEDEF = 0x00004000; - protected static final int IS_STATIC = 0x00008000; - protected static final int IS_REGISTER = 0x00010000; - protected static final int IS_EXTERN = 0x00020000; - protected static final int IS_EXPLICIT = 0x00040000; - protected static final int IS_CONST = 0x00080000; - protected static final int IS_AUTO = 0x00100000; - protected static final int IS_GLOBAL = 0x00200000; - protected static final int IS_MUTABLE = 0x00400000; - protected static final int IS_FRIEND = 0x00800000; - protected static final int IS_INLINE = 0x01000000; - - - public int startingOffset = 0; - public int startingLine; - public int endOffset; - - private ITokenDuple name; - private Type simpleType = IASTSimpleTypeSpecifier.Type.UNSPECIFIED; - private final Object templateDeclaration; - private final Object scope; - private Object typeSpecifier; - - private List declarators = Collections.EMPTY_LIST; - /** - * @param b - */ - public void setAuto(boolean b) - { - setBit( b, IS_AUTO ); - } - /** - * @return - */ - public Object getScope() - { - return scope; - } - - /** - * @param scope - * @param filename TODO - */ - public DeclarationWrapper( - Object scope, - int startingOffset, - int startingLine, Object templateDeclaration, char[] filename) - { - this.scope = scope; - this.startingOffset = startingOffset; - this.startingLine = startingLine; - this.templateDeclaration = templateDeclaration; - this.fn = filename; - } - /** - * @param b - */ - public void setTypenamed(boolean b) - { - setBit( b, IS_TYPENAMED ); - } - /** - * @param b - */ - public void setMutable(boolean b) - { - setBit( b, IS_MUTABLE); - } - /** - * @param b - */ - public void setFriend(boolean b) - { - setBit( b, IS_FRIEND ); - } - /** - * @param b - */ - public void setInline(boolean b) - { - setBit( b, IS_INLINE ); - } - /** - * @param b - */ - public void setRegister(boolean b) - { - setBit( b, IS_REGISTER ); - } - /** - * @param b - */ - public void setStatic(boolean b) - { - setBit( b, IS_STATIC ); - } - /** - * @param b - */ - public void setTypedef(boolean b) - { - setBit( b, IS_TYPEDEF ); - } - /** - * @param b - */ - public void setVirtual(boolean b) - { - setBit( b, IS_VIRTUAL ); - } - /** - * @param b - */ - public void setVolatile(boolean b) - { - setBit( b, IS_VOLATILE ); - } - /** - * @param b - */ - public void setExtern(boolean b) - { - setBit( b, IS_EXTERN ); - } - /** - * @param b - */ - public void setExplicit(boolean b) - { - setBit( b, IS_EXPLICIT ); - } - /** - * @param b - */ - public void setConst(boolean b) - { - setBit( b, IS_CONST ); - } - /** - * @return - */ - public boolean isAuto() - { - return checkBit( IS_AUTO ); - } - /** - * @return - */ - public boolean isConst() - { - return checkBit( IS_CONST ); - } - /** - * @return - */ - public boolean isExplicit() - { - return checkBit( IS_EXPLICIT ); - } - /** - * @return - */ - public boolean isExtern() - { - return checkBit( IS_EXTERN ); - } - /** - * @return - */ - public boolean isFriend() - { - return checkBit( IS_FRIEND ); - } - /** - * @return - */ - public boolean isInline() - { - return checkBit( IS_INLINE ); - } - /** - * @return - */ - public boolean isMutable() - { - return checkBit( IS_MUTABLE ); - } - /** - * @return - */ - public boolean isRegister() - { - return checkBit( IS_REGISTER ); - } - - /** - * @return - */ - public boolean isStatic() - { - return checkBit( IS_STATIC ); - } - /** - * @return - */ - public boolean isTypedef() - { - return checkBit( IS_TYPEDEF ); - } - /** - * @return - */ - public boolean isTypeNamed() - { - return checkBit( IS_TYPENAMED ); - } - /** - * @return - */ - public boolean isVirtual() - { - return checkBit( IS_VIRTUAL ); - } - /** - * @return - */ - public boolean isVolatile() - { - return checkBit( IS_VOLATILE ); - } - - public void addDeclarator(Declarator d) - { - if( declarators == Collections.EMPTY_LIST ) - declarators = new ArrayList(DEFAULT_LIST_SIZE); - declarators.add(d); - } - public Iterator getDeclarators() - { - return declarators.iterator(); - } - /** - * @return - */ - public Object getTypeSpecifier() - { - return typeSpecifier; - } - /** - * @param enumeration - */ - public void setTypeSpecifier(Object enumeration) - { - typeSpecifier = enumeration; - } - public int endLine; - - public final char[] fn; - - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IDeclaratorOwner#getDeclarationWrapper() - */ - public DeclarationWrapper getDeclarationWrapper() - { - return this; - } - /** - * @return - */ - public boolean isUnsigned() - { - return checkBit( IS_UNSIGNED ); - } - /** - * @return - */ - public boolean isSigned() - { - return checkBit( IS_SIGNED ); - } - /** - * @return - */ - public boolean isShort() - { - return checkBit( IS_SHORT ); - } - /** - * @return - */ - public boolean isLong() - { - return checkBit( IS_LONG ); - } - /** - * @param b - */ - public void setLong(boolean b) - { - setBit( b, IS_LONG ); - } - /** - * @param b - */ - public void setShort(boolean b) - { - setBit( b, IS_SHORT ); - } - /** - * @param b - */ - public void setSigned(boolean b) - { - setBit( b, IS_SIGNED ); - } - /** - * @param b - */ - public void setUnsigned(boolean b) - { - setBit( b, IS_UNSIGNED ); - } - /** - * @return - */ - public Type getSimpleType() - { - return simpleType; - } - /** - * @param type - */ - public void setSimpleType(Type type) - { - simpleType = type; - } - /** - * @param duple - */ - public void setTypeName(ITokenDuple duple) - { - name = duple; - } - /** - * @return - */ - public final ITokenDuple getName() - { - return name; - } - - /** - * @return - */ - public final Object getOwnerTemplate() - { - return templateDeclaration; - } - /** - * @param i - */ - public void setEndingOffsetAndLineNumber(int offset, int lineNumber) - { - endOffset = offset; - endLine = lineNumber; - } - /** - * @param b - */ - public void setRestrict(boolean b) - { - setBit( b, IS_RESTRICT ); - } - - - /** - * @return - */ - public boolean isRestrict() - { - return checkBit( IS_RESTRICT ); - } - /** - * @param b - */ - public void setImaginary(boolean b) - { - setBit( b, IS_IMAGINARY ); - } - - /** - * @return - */ - public boolean isComplex() - { - return checkBit( IS_COMPLEX ); - } - - /** - * @return - */ - public boolean isImaginary() - { - return checkBit( IS_IMAGINARY ); - } - - /** - * @param b - */ - public void setComplex(boolean b) - { - setBit( b, IS_COMPLEX ); - } - /** - * @param b - */ - public void setGloballyQualified(boolean b) { - setBit( b, IS_GLOBAL ); - } - - public boolean isGloballyQualified(){ - return checkBit( IS_GLOBAL ); - } - - private Map extensionParameters = Collections.EMPTY_MAP; - /** - * @param key - * @param typeOfExpression - */ - public void setExtensionParameter(String key, Object value) { - if( extensionParameters == Collections.EMPTY_MAP ) - extensionParameters = new Hashtable( 4 ); - extensionParameters.put( key, value ); - } - - public Map getExtensionParameters() - { - return extensionParameters; - } - /** - * @return - */ - public boolean consumedRawType() { - return( getSimpleType() != IASTSimpleTypeSpecifier.Type.UNSPECIFIED ); - } -} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/Declarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/Declarator.java deleted file mode 100644 index 5360329c05a..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/Declarator.java +++ /dev/null @@ -1,428 +0,0 @@ -/********************************************************************** - * Copyright (c) 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - **********************************************************************/ -package org.eclipse.cdt.internal.core.parser2; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; - -import org.eclipse.cdt.core.parser.ITokenDuple; -import org.eclipse.cdt.internal.core.parser.ast.EmptyIterator; - -public class Declarator implements IParameterCollection, IDeclaratorOwner, IDeclarator -{ - private static final int DEFAULT_ARRAYLIST_SIZE = 4; - private static final char[] EMPTY_STRING = new char[0]; //$NON-NLS-1$ - - private final IDeclaratorOwner owner; - private ITokenDuple pointerOperatorNameDuple = null; - private ITokenDuple namedDuple = null; - private Object constructorExpression = null; - private Declarator ownedDeclarator = null; - private Object initializerClause = null; - private Object exceptionSpecification = null; - private Object bitFieldExpression = null; - - private int flag = 0; - protected void setBit(boolean b, int mask){ - if( b ){ - flag = flag | mask; - } else { - flag = flag & ~mask; - } - } - - protected boolean checkBit(int mask){ - return (flag & mask) != 0; - } - - protected static final int IS_FUNCTION = 0x000020; - protected static final int HAS_TRY_BLOCK = 0x000040; - protected static final int HAS_FUNCTION_BODY = 0x000080; - protected static final int IS_PURE_VIRTUAL = 0x000100; - protected static final int IS_VAR_ARGS = 0x000200; - protected static final int IS_VOLATILE = 0x000400; - protected static final int IS_CONST = 0x000800; - - private List ptrOps = Collections.EMPTY_LIST; - private List parameters = Collections.EMPTY_LIST; - private List arrayModifiers = Collections.EMPTY_LIST; - private List constructorMemberInitializers = Collections.EMPTY_LIST; - - - - public Declarator( IDeclaratorOwner owner ) - { - this.owner = owner; - } - - /** - * @return - */ - public char[] getName() - { - if( namedDuple == null ) return EMPTY_STRING; - return namedDuple.toCharArray(); - } - - /** - * @return - */ - public int getNameEndOffset() - { - if( namedDuple == null ) return -1; - return namedDuple.getEndOffset(); - } - - public int getNameLine() - { - if( namedDuple == null ) return -1; - return namedDuple.getLineNumber(); - } - - /** - * @return - */ - public int getNameStartOffset() - { - if( namedDuple == null ) return -1; - return namedDuple.getStartOffset(); - } - - /** - * @return - */ - public IDeclaratorOwner getOwner() - { - return owner; - } - - - /** - * @return - */ - public List getPointerOperators() - { - return ptrOps; - } - - public void addPointerOperator( Object ptrOp ) - { - if( ptrOps == Collections.EMPTY_LIST ) - ptrOps = new ArrayList( DEFAULT_ARRAYLIST_SIZE ); - - ptrOps.add( ptrOp ); - } - /** - * @return - */ - public List getParameters() - { - return parameters; - } - - public void addParameter( DeclarationWrapper param ) - { - if( parameters == Collections.EMPTY_LIST ) - parameters = new ArrayList( DEFAULT_ARRAYLIST_SIZE ); - - parameters.add( param ); - } - /** - * @return - */ - public Object getInitializerClause() - { - return initializerClause; - } - - /** - * @param clause - */ - public void setInitializerClause(Object clause) - { - initializerClause = clause; - } - - /** - * @return - */ - public Declarator getOwnedDeclarator() - { - return ownedDeclarator; - } - - /** - * @param declarator - */ - public void setOwnedDeclarator(Declarator declarator) - { - ownedDeclarator = declarator; - } - - public void setName( ITokenDuple duple ) - { - namedDuple = duple; - } - - /** - * @return - */ - public Object getExceptionSpecification() - { - return exceptionSpecification; - } - - /** - * @return - */ - public boolean isConst() - { - return checkBit(IS_CONST); - } - - /** - * @return - */ - public boolean isVolatile() - { - return checkBit( IS_VOLATILE); - } - - /** - * @param specification - */ - public void setExceptionSpecification(Object specification) - { - exceptionSpecification = specification; - } - - /** - * @param b - */ - public void setConst(boolean b) - { - setBit(b, IS_CONST ); - } - - /** - * @param b - */ - public void setVolatile(boolean b) - { - setBit( b, IS_VOLATILE ); - } - - /** - * @param b - */ - public void setPureVirtual(boolean b) - { - setBit( b, IS_PURE_VIRTUAL ); - } - - /** - * @return - */ - public boolean isPureVirtual() - { - return checkBit( IS_PURE_VIRTUAL ); - } - - /** - * @param arrayMod - */ - public void addArrayModifier(Object arrayMod) - { - if( arrayModifiers == Collections.EMPTY_LIST ) - arrayModifiers = new ArrayList( DEFAULT_ARRAYLIST_SIZE ); - arrayModifiers.add( arrayMod ); - } - - /** - * @return - */ - public List getArrayModifiers() - { - return arrayModifiers; - } - - /** - * @return - */ - public Object getBitFieldExpression() - { - return bitFieldExpression; - } - - /** - * @param exp - */ - public void setBitFieldExpression(Object exp) - { - bitFieldExpression = exp; - } - - /** - * @param astExpression - */ - public void setConstructorExpression(Object astExpression) - { - constructorExpression = astExpression; - } - - /** - * @return - */ - public Object getConstructorExpression() - { - return constructorExpression; - } - - /** - * @param initializer - */ - public void addConstructorMemberInitializer(Object initializer) - { - if( constructorMemberInitializers == Collections.EMPTY_LIST ) - constructorMemberInitializers = new ArrayList( DEFAULT_ARRAYLIST_SIZE ); - constructorMemberInitializers.add( initializer ); - } - - /** - * @return - */ - public List getConstructorMemberInitializers() - { - return constructorMemberInitializers; - } - - - /** - * @return - */ - public boolean isFunction() - { - return checkBit( IS_FUNCTION ); - } - - /** - * @param b - */ - public void setIsFunction(boolean b) - { - setBit( b, IS_FUNCTION ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IDeclaratorOwner#getDeclarators() - */ - public Iterator getDeclarators() - { - if( ownedDeclarator == null ) - return EmptyIterator.EMPTY_ITERATOR; - - List l = new ArrayList(1); - l.add( ownedDeclarator ); - return l.iterator(); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IDeclaratorOwner#getDeclarationWrapper() - */ - public DeclarationWrapper getDeclarationWrapper() - { - Declarator d = this; - while( d.getOwner() instanceof Declarator ) - d = (Declarator)d.getOwner(); - return (DeclarationWrapper)d.getOwner(); - } - - - /** - * @return - */ - public ITokenDuple getNameDuple() - { - return namedDuple; - } - - /** - * @param nameDuple - */ - public void setPointerOperatorName(ITokenDuple nameDuple) - { - pointerOperatorNameDuple = nameDuple; - } - - /** - * @return - */ - public ITokenDuple getPointerOperatorNameDuple() - { - return pointerOperatorNameDuple; - } - - /** - * @return - */ - public boolean hasFunctionBody() - { - return checkBit( HAS_FUNCTION_BODY ); - } - - /** - * @param b - */ - public void setHasFunctionBody(boolean b) - { - setBit( b, HAS_FUNCTION_BODY ); - } - - /** - * @param b - */ - public void setFunctionTryBlock(boolean b) - { - setBit( b, HAS_TRY_BLOCK ); - } - - /** - * @return - */ - public boolean hasFunctionTryBlock() - { - return checkBit( HAS_TRY_BLOCK ); - } - - /** - * @param b - */ - public void setIsVarArgs(boolean b) { - setBit( b, IS_VAR_ARGS ); - } - - /** - * @return Returns the varArgs. - */ - public boolean isVarArgs() { - return checkBit( IS_VAR_ARGS ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IDeclarator#getScope() - */ - public Object getScope() { - return getDeclarationWrapper().getScope(); - } - -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/IDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/IDeclarator.java deleted file mode 100644 index 2ac76010b2c..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/IDeclarator.java +++ /dev/null @@ -1,43 +0,0 @@ -/********************************************************************** - * Copyright (c) 2002-2004 IBM Canada and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v05.html - * - * Contributors: - * IBM Rational Software - Initial API and implementation */ -package org.eclipse.cdt.internal.core.parser2; - -import java.util.List; - -import org.eclipse.cdt.core.parser.ITokenDuple; - -/** - * @author jcamelon - */ -public interface IDeclarator -{ - public Object getScope(); - /** - * @return - */ - public abstract List getPointerOperators(); - public abstract void addPointerOperator(Object ptrOp); - /** - * @param arrayMod - */ - public abstract void addArrayModifier(Object arrayMod); - /** - * @return - */ - public abstract List getArrayModifiers(); - - /** - * @param nameDuple - */ - public void setPointerOperatorName(ITokenDuple nameDuple); - - public ITokenDuple getPointerOperatorNameDuple(); - -} \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/IDeclaratorOwner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/IDeclaratorOwner.java deleted file mode 100644 index ee5225a3832..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/IDeclaratorOwner.java +++ /dev/null @@ -1,23 +0,0 @@ -/********************************************************************** - * Copyright (c) 2002-2004 IBM Canada and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v05.html - * - * Contributors: - * IBM Rational Software - Initial API and implementation */ -package org.eclipse.cdt.internal.core.parser2; - -import java.util.Iterator; - - -/** - * @author jcamelon - */ -public interface IDeclaratorOwner { - - public Iterator getDeclarators(); - public DeclarationWrapper getDeclarationWrapper(); - -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/IParameterCollection.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/IParameterCollection.java deleted file mode 100644 index b8aa44f375f..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/IParameterCollection.java +++ /dev/null @@ -1,21 +0,0 @@ -/********************************************************************** - * Copyright (c) 2002-2004 IBM Canada and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v05.html - * - * Contributors: - * IBM Rational Software - Initial API and implementation */ -package org.eclipse.cdt.internal.core.parser2; - -import java.util.List; - - -/** - * @author jcamelon - */ -public interface IParameterCollection { - public List getParameters(); - public void addParameter( DeclarationWrapper param ); -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/ParameterCollection.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/ParameterCollection.java deleted file mode 100644 index 9142ba62433..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/ParameterCollection.java +++ /dev/null @@ -1,34 +0,0 @@ -/********************************************************************** - * Copyright (c) 2004 IBM Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v1.0 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v10.html - * - * Contributors: - * IBM - Initial API and implementation - **********************************************************************/ -package org.eclipse.cdt.internal.core.parser2; - -import java.util.ArrayList; -import java.util.List; - - -public class ParameterCollection implements IParameterCollection -{ - private List list = new ArrayList(); - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IParameterCollection#getParameters() - */ - public List getParameters() - { - return list; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IParameterCollection#addParameter(org.eclipse.cdt.internal.core.parser.DeclarationWrapper) - */ - public void addParameter(DeclarationWrapper param) - { - list.add( param ); - } -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/TypeId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/TypeId.java deleted file mode 100644 index 55e678a358d..00000000000 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/TypeId.java +++ /dev/null @@ -1,99 +0,0 @@ -/********************************************************************** - * Copyright (c) 2002,2003 Rational Software Corporation and others. - * All rights reserved. This program and the accompanying materials - * are made available under the terms of the Common Public License v0.5 - * which accompanies this distribution, and is available at - * http://www.eclipse.org/legal/cpl-v05.html - * - * Contributors: - * IBM Rational Software - Initial API and implementation -***********************************************************************/ -package org.eclipse.cdt.internal.core.parser2; - -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; - -import org.eclipse.cdt.core.parser.ITokenDuple; - -/** - * @author jcamelon - * - */ -public class TypeId implements IDeclarator -{ - private static final int DEFAULT_ARRAYLIST_SIZE = 4; - private ITokenDuple name; - private List arrayModifiers; - private List pointerOperators; - private Object scope; - - /** - * @param scope2 - */ - public void reset(Object scope2) { - this.scope = scope2; - arrayModifiers = Collections.EMPTY_LIST; - pointerOperators = Collections.EMPTY_LIST; - name = null; - } - /** - * - */ - public TypeId() - { - reset( null ); - } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IDeclarator#getPointerOperators() - */ - public List getPointerOperators() - { - return pointerOperators; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IDeclarator#addPointerOperator(org.eclipse.cdt.core.parser.ast.ASTPointerOperator) - */ - public void addPointerOperator(Object ptrOp) - { - if( pointerOperators == Collections.EMPTY_LIST ) - pointerOperators = new ArrayList( DEFAULT_ARRAYLIST_SIZE ); - pointerOperators.add( ptrOp ); - } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IDeclarator#addArrayModifier(org.eclipse.cdt.core.parser.ast.IASTArrayModifier) - */ - public void addArrayModifier(Object arrayMod) - { - if( arrayModifiers == Collections.EMPTY_LIST ) - arrayModifiers = new ArrayList( DEFAULT_ARRAYLIST_SIZE ); - arrayModifiers.add( arrayMod ); - } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IDeclarator#getArrayModifiers() - */ - public List getArrayModifiers() - { - return arrayModifiers; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IDeclarator#setPointerOperatorName(org.eclipse.cdt.core.parser.ITokenDuple) - */ - public void setPointerOperatorName(ITokenDuple nameDuple) - { - name = nameDuple; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IDeclarator#getPointerOperatorNameDuple() - */ - public ITokenDuple getPointerOperatorNameDuple() - { - return name; - } - /* (non-Javadoc) - * @see org.eclipse.cdt.internal.core.parser.IDeclarator#getScope() - */ - public Object getScope() { - return scope; - } -} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java index 641a8f878ca..4450d7a6ac3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/c/GNUCSourceParser.java @@ -82,6 +82,7 @@ import org.eclipse.cdt.core.parser.BacktrackException; import org.eclipse.cdt.core.parser.EndOfFileException; import org.eclipse.cdt.core.parser.IGCCToken; import org.eclipse.cdt.core.parser.IParserLogService; +import org.eclipse.cdt.core.parser.IProblem; import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.ParseError; @@ -2085,33 +2086,74 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser { return compound; // selection statement case IToken.t_if: - startOffset = consume(IToken.t_if).getOffset(); - consume(IToken.tLPAREN); - IASTExpression if_condition = condition(); - consume(IToken.tRPAREN); - IASTStatement then_clause = statement(); - IASTStatement else_clause = null; - if (LT(1) == IToken.t_else) { - consume(IToken.t_else); - else_clause = statement(); - } - - IASTIfStatement if_stmt = createIfStatement(); - if_stmt.setCondition( if_condition ); - ((ASTNode)if_stmt).setOffset( startOffset ); - if_condition.setParent( if_stmt ); - if_condition.setPropertyInParent( IASTIfStatement.CONDITION ); - if_stmt.setThenClause( then_clause ); - then_clause.setParent( if_stmt ); - then_clause.setPropertyInParent( IASTIfStatement.THEN ); - if( else_clause != null ) - { - if_stmt.setElseClause( else_clause ); - else_clause.setParent( if_stmt ); - else_clause.setPropertyInParent( IASTIfStatement.ELSE ); - } - cleanupLastToken(); - return if_stmt; + IASTIfStatement if_statement = null; + if_loop: while( true ){ + int so = consume(IToken.t_if).getOffset(); + consume(IToken.tLPAREN); + IToken start = LA(1); + boolean passedCondition = true; + IASTExpression condition = null; + try { + condition = condition(); + consume(IToken.tRPAREN); + } catch (BacktrackException b) { + //if the problem has no offset info, make a new one that does + if( b.getProblem() != null && b.getProblem().getSourceLineNumber() == -1 ){ + IProblem p = b.getProblem(); + IProblem p2 = problemFactory.createProblem( p.getID(), start.getOffset(), + lastToken != null ? lastToken.getEndOffset() : start.getEndOffset(), + start.getLineNumber(), p.getOriginatingFileName(), + p.getArguments() != null ? p.getArguments().toCharArray() : null, + p.isWarning(), p.isError() ); + b.initialize( p2 ); + } + failParse(b); + failParseWithErrorHandling(); + passedCondition = false; + } + + IASTStatement thenClause = null; + if( passedCondition ){ + thenClause = statement(); + } + + IASTIfStatement new_if_statement = createIfStatement(); + ((ASTNode)new_if_statement).setOffset( so ); + new_if_statement.setCondition( condition ); + condition.setParent( new_if_statement ); + condition.setPropertyInParent( IASTIfStatement.CONDITION ); + if( thenClause != null ) + { + new_if_statement.setThenClause( thenClause ); + thenClause.setParent( new_if_statement ); + thenClause.setPropertyInParent(IASTIfStatement.THEN ); + } + if (LT(1) == IToken.t_else) { + consume(IToken.t_else); + if (LT(1) == IToken.t_if) { + //an else if, don't recurse, just loop and do another if + cleanupLastToken(); + if( if_statement != null ) + { + if_statement.setElseClause( new_if_statement ); + new_if_statement.setParent( if_statement ); + new_if_statement.setPropertyInParent( IASTIfStatement.ELSE ); + if_statement = new_if_statement; + } + continue if_loop; + } + IASTStatement elseStatement = statement(); + new_if_statement.setElseClause( elseStatement ); + elseStatement.setParent( new_if_statement ); + elseStatement.setPropertyInParent( IASTIfStatement.ELSE ); + if_statement = new_if_statement; + } + else + if_statement = new_if_statement; + break if_loop; + } + cleanupLastToken(); + return if_statement; case IToken.t_switch: startOffset = consume( IToken.t_switch ).getOffset(); consume(IToken.tLPAREN); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/GNUCPPSourceParser.java index ddf1e7d8028..e09baea0a3f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser2/cpp/GNUCPPSourceParser.java @@ -708,7 +708,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { protected IASTExpression throwExpression() throws EndOfFileException, BacktrackException { IToken throwToken = consume(IToken.t_throw); - IASTExpression throwExpression = expression(); + IASTExpression throwExpression = null; + try + { + throwExpression = expression(); + } + catch( BacktrackException bte ) + { + } return buildUnaryExpression( ICPPASTUnaryExpression.op_throw, throwExpression, throwToken.getOffset() ); } @@ -4431,34 +4438,75 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { return compound; // selection statement case IToken.t_if: - startOffset = consume(IToken.t_if).getOffset(); - consume(IToken.tLPAREN); - IASTExpression if_condition = condition(); - consume(IToken.tRPAREN); - IASTStatement then_clause = statement(); - IASTStatement else_clause = null; - if (LT(1) == IToken.t_else) { - consume(IToken.t_else); - else_clause = statement(); - } - - IASTIfStatement if_stmt = createIfStatement(); - if_stmt.setCondition( if_condition ); - ((ASTNode)if_stmt).setOffset( startOffset ); - if_condition.setParent( if_stmt ); - if_condition.setPropertyInParent( IASTIfStatement.CONDITION ); - if_stmt.setThenClause( then_clause ); - then_clause.setParent( if_stmt ); - then_clause.setPropertyInParent( IASTIfStatement.THEN ); - if( else_clause != null ) - { - if_stmt.setElseClause( else_clause ); - else_clause.setParent( if_stmt ); - else_clause.setPropertyInParent( IASTIfStatement.ELSE ); - } - cleanupLastToken(); - return if_stmt; - case IToken.t_switch: + IASTIfStatement if_statement = null; + if_loop: while( true ){ + int so = consume(IToken.t_if).getOffset(); + consume(IToken.tLPAREN); + IToken start = LA(1); + boolean passedCondition = true; + IASTExpression condition = null; + try { + condition = condition(); + consume(IToken.tRPAREN); + } catch (BacktrackException b) { + //if the problem has no offset info, make a new one that does + if( b.getProblem() != null && b.getProblem().getSourceLineNumber() == -1 ){ + IProblem p = b.getProblem(); + IProblem p2 = problemFactory.createProblem( p.getID(), start.getOffset(), + lastToken != null ? lastToken.getEndOffset() : start.getEndOffset(), + start.getLineNumber(), p.getOriginatingFileName(), + p.getArguments() != null ? p.getArguments().toCharArray() : null, + p.isWarning(), p.isError() ); + b.initialize( p2 ); + } + failParse(b); + failParseWithErrorHandling(); + passedCondition = false; + } + + IASTStatement thenClause = null; + if( passedCondition ){ + thenClause = statement(); + } + + IASTIfStatement new_if_statement = createIfStatement(); + ((ASTNode)new_if_statement).setOffset( so ); + new_if_statement.setCondition( condition ); + condition.setParent( new_if_statement ); + condition.setPropertyInParent( IASTIfStatement.CONDITION ); + if( thenClause != null ) + { + new_if_statement.setThenClause( thenClause ); + thenClause.setParent( new_if_statement ); + thenClause.setPropertyInParent(IASTIfStatement.THEN ); + } + if (LT(1) == IToken.t_else) { + consume(IToken.t_else); + if (LT(1) == IToken.t_if) { + //an else if, don't recurse, just loop and do another if + cleanupLastToken(); + if( if_statement != null ) + { + if_statement.setElseClause( new_if_statement ); + new_if_statement.setParent( if_statement ); + new_if_statement.setPropertyInParent( IASTIfStatement.ELSE ); + if_statement = new_if_statement; + } + continue if_loop; + } + IASTStatement elseStatement = statement(); + new_if_statement.setElseClause( elseStatement ); + elseStatement.setParent( new_if_statement ); + elseStatement.setPropertyInParent( IASTIfStatement.ELSE ); + if_statement = new_if_statement; + } + else + if_statement = new_if_statement; + break if_loop; + } + cleanupLastToken(); + return if_statement; + case IToken.t_switch: startOffset = consume( IToken.t_switch ).getOffset(); consume(IToken.tLPAREN); IASTExpression switch_condition = condition();