From 34181fda513f92adacfbe346c07e8b78eef9a997 Mon Sep 17 00:00:00 2001 From: John Camelon Date: Tue, 23 Nov 2004 21:46:01 +0000 Subject: [PATCH] QuickParser2Tests now all pass. Commit it while you can. --- .../core/parser/tests/ParserTestSuite.java | 2 + .../tests/parser2/QuickParser2Tests.java | 283 +++++++++--------- .../core/parser/token/BasicTokenDuple.java | 2 + .../core/parser/token/TemplateTokenDuple.java | 42 +++ .../core/parser2/cpp/GNUCPPSourceParser.java | 29 +- 5 files changed, 200 insertions(+), 158 deletions(-) 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 93f88e96c31..d05f87777fa 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.QuickParser2Tests; import org.eclipse.cdt.core.parser.tests.scanner2.ObjectMapTest; import org.eclipse.cdt.core.parser.tests.scanner2.Scanner2Test; @@ -55,6 +56,7 @@ public class ParserTestSuite extends TestCase { suite.addTest( GCCParserExtensionTestSuite.suite() ); suite.addTestSuite( AST2Tests.class ); suite.addTestSuite( GCCTests.class ); + suite.addTestSuite( QuickParser2Tests.class ); return suite; } } 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 9974dfa0674..59c013215e5 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 @@ -51,11 +51,14 @@ public class QuickParser2Tests extends TestCase { public static class ProblemCollector implements IProblemRequestor { List problems = new ArrayList(); - /* (non-Javadoc) + + /* + * (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 ); + problems.add(problem); return true; } @@ -67,8 +70,11 @@ public class QuickParser2Tests extends TestCase { } } + private static final NullLogService NULL_LOG = new NullLogService(); + private static final NullSourceElementRequestor NULL_REQUESTOR = new NullSourceElementRequestor(); + /** * */ @@ -113,19 +119,20 @@ public class QuickParser2Tests extends TestCase { parse(code.toString()); } - protected void parse( String code, boolean expectedToPass, ParserLanguage lang ) throws Exception - { - parse( code, expectedToPass, lang, false ); + protected void parse(String code, boolean expectedToPass, + ParserLanguage lang) throws Exception { + parse(code, expectedToPass, lang, false); } - protected void parse( String code, boolean expectedToPass ) throws Exception - { - parse( code, expectedToPass, ParserLanguage.CPP ); + + protected void parse(String code, boolean expectedToPass) throws Exception { + parse(code, expectedToPass, ParserLanguage.CPP); } + /** * @param code */ protected void parse(String code) throws Exception { - parse( code, true, ParserLanguage.CPP ); + parse(code, true, ParserLanguage.CPP); } public void testNamespaceDefinition() throws Exception { @@ -541,13 +548,10 @@ public class QuickParser2Tests extends TestCase { } public void testBug36769A() throws Exception { - Writer code = new StringWriter(); - code - .write("template cls::operator op &() const {}\n"); //$NON-NLS-1$ - code.write("template cls::cls() {}\n"); //$NON-NLS-1$ - code.write("template cls::~cls() {}\n"); //$NON-NLS-1$ - parse(code.toString()); + parse("template cls::operator &() const {}\n"); //$NON-NLS-1$ + parse("template cls::cls() {}\n"); //$NON-NLS-1$ + parse("template cls::~cls() {}\n"); //$NON-NLS-1$ } public void testBug36714() throws Exception { @@ -578,14 +582,11 @@ public class QuickParser2Tests extends TestCase { public void testBug36699() throws Exception { Writer code = new StringWriter(); - code - .write("template < template class ThreadingModel = DEFAULT_THREADING,\n"); //$NON-NLS-1$ + code.write("template < template class ThreadingModel = DEFAULT_THREADING,\n"); //$NON-NLS-1$ code.write("std::size_t chunkSize = DEFAULT_CHUNK_SIZE,\n"); //$NON-NLS-1$ - code - .write("std::size_t maxSmallObjectSize = MAX_SMALL_OBJECT_SIZE >\n"); //$NON-NLS-1$ + code.write("std::size_t maxSmallObjectSize = MAX_SMALL_OBJECT_SIZE >\n"); //$NON-NLS-1$ code.write("class SmallObject : public ThreadingModel<\n"); //$NON-NLS-1$ - code - .write("SmallObject >\n"); //$NON-NLS-1$ + code.write("SmallObject >\n"); //$NON-NLS-1$ code.write("{};\n"); //$NON-NLS-1$ parse(code.toString()); } @@ -692,8 +693,7 @@ public class QuickParser2Tests extends TestCase { } public void testTemplateSpecialization() throws Exception { - parse( - "template<> class stream { /* ... */ };"); //$NON-NLS-1$ + parse("template<> class stream { /* ... */ };"); //$NON-NLS-1$ } public void testTemplateInstantiation() throws Exception { @@ -705,11 +705,11 @@ public class QuickParser2Tests extends TestCase { */ public void testMultipleDeclarators() throws Exception { // Parse and get the translaton unit - parse( "class A { int floor( double input ), someInt; };"); //$NON-NLS-1$ + parse("class A { int floor( double input ), someInt; };"); //$NON-NLS-1$ } public void testFunctionModifiers() throws Exception { - parse( "class A {virtual void foo( void ) const throw ( yay, nay, we::dont::care ) = 0;};"); //$NON-NLS-1$ + parse("class A {virtual void foo( void ) const throw ( yay, nay, we::dont::care ) = 0;};"); //$NON-NLS-1$ } public void testArrays() throws Exception { @@ -734,8 +734,7 @@ public class QuickParser2Tests extends TestCase { } public void testPointerOperators() throws Exception { - parse( - "int * x = 0, & y, * const * volatile * z;"); //$NON-NLS-1$ + parse("int * x = 0, & y, * const * volatile * z;"); //$NON-NLS-1$ } public void testBug26467() throws Exception { @@ -753,7 +752,7 @@ public class QuickParser2Tests extends TestCase { public void testConstructorChain() throws Exception { //TODO - requires CPPVisitor in order to reduce ambiguities - parse( "TrafficLight_Actor::TrafficLight_Actor( RTController * rtg_rts, RTActorRef * rtg_ref ) : RTActor( rtg_rts, rtg_ref ), myId( 0 ) {}"); //$NON-NLS-1$ + parse("TrafficLight_Actor::TrafficLight_Actor( RTController * rtg_rts, RTActorRef * rtg_ref ) : RTActor( rtg_rts, rtg_ref ), myId( 0 ) {}"); //$NON-NLS-1$ } public void testBug36237() throws Exception { @@ -777,11 +776,11 @@ public class QuickParser2Tests extends TestCase { } public void testTemplateDeclarationOfFunction() throws Exception { - parse( "template A aTemplatedFunction( B bInstance );"); //$NON-NLS-1$ + parse("template A aTemplatedFunction( B bInstance );"); //$NON-NLS-1$ } public void testTemplateDeclarationOfClass() throws Exception { - parse( "template class, template class AClass> class myarray { /* ... */ };"); //$NON-NLS-1$ + parse("template class, template class AClass> class myarray { /* ... */ };"); //$NON-NLS-1$ } public void testBug35906() throws Exception { @@ -812,7 +811,8 @@ public class QuickParser2Tests extends TestCase { code.write("#define CMD_GET \"g\"\n"); //$NON-NLS-1$ code.write("#define CMD_ACTION \"a\"\n"); //$NON-NLS-1$ code.write("#define CMD_QUIT \"q\"\n"); //$NON-NLS-1$ - code.write("static const memevent_cmd_func memevent_cmd_funcs[sizeof memevent_cmds - 1] = {\n"); //$NON-NLS-1$ + code + .write("static const memevent_cmd_func memevent_cmd_funcs[sizeof memevent_cmds - 1] = {\n"); //$NON-NLS-1$ code.write("memevent_get,\n"); //$NON-NLS-1$ code.write("memevent_action,\n"); //$NON-NLS-1$ code.write("memevent_quit,\n"); //$NON-NLS-1$ @@ -866,13 +866,11 @@ public class QuickParser2Tests extends TestCase { } public void testBug36708() throws Exception { - parse( - "enum { isPointer = PointerTraits::result };"); //$NON-NLS-1$ + parse("enum { isPointer = PointerTraits::result };"); //$NON-NLS-1$ } public void testBug36690() throws Exception { - parse( - "Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get())){}"); //$NON-NLS-1$ + parse("Functor(const Functor& rhs) : spImpl_(Impl::Clone(rhs.spImpl_.get())){}"); //$NON-NLS-1$ } public void testBug36703() throws Exception { @@ -933,8 +931,7 @@ public class QuickParser2Tests extends TestCase { } public void testBug36600() throws Exception { - parse( - "enum mad_flow (*input_func)(void *, struct mad_stream *);"); //$NON-NLS-1$ + parse("enum mad_flow (*input_func)(void *, struct mad_stream *);"); //$NON-NLS-1$ } public void testBug36713() throws Exception { @@ -1189,8 +1186,7 @@ public class QuickParser2Tests extends TestCase { } public void testBug43062() throws Exception { - parse( - "class X { operator short (); operator int unsigned(); operator int signed(); };"); //$NON-NLS-1$ + parse("class X { operator short (); operator int unsigned(); operator int signed(); };"); //$NON-NLS-1$ } public void testBug39531() throws Exception { @@ -1253,8 +1249,7 @@ public class QuickParser2Tests extends TestCase { } public void testBug39536A() throws Exception { - parse( - "template class X { X(); };"); //$NON-NLS-1$ + parse("template class X { X(); };"); //$NON-NLS-1$ } public void testBug39536B() throws Exception { @@ -1268,7 +1263,7 @@ public class QuickParser2Tests extends TestCase { //Here starts C99-specific section public void testBug39549() throws Exception { parse( - "struct X x = { .b = 40, .z = { sizeof(X), 42 }, .t[3] = 2, .t.f[3].x = A * B };", true, ParserLanguage.C); //$NON-NLS-1$ + "struct X x = { .b = 40, .z = { sizeof(X), 42 }, .t[3] = 2, .t.f[3].x = A * B };", true, ParserLanguage.C); //$NON-NLS-1$ // with trailing commas parse( "struct X x = { .b = 40, .z = { sizeof(X), 42,}, .t[3] = 2, .t.f[3].x = A * B ,};", true, ParserLanguage.C); //$NON-NLS-1$ @@ -1280,12 +1275,11 @@ public class QuickParser2Tests extends TestCase { } public void testBug39551B() throws Exception { - parse( - "_Imaginary double id = 99.99 * __I__;", true, ParserLanguage.C); //$NON-NLS-1$ + parse("_Imaginary double id = 99.99 * __I__;", true, ParserLanguage.C); //$NON-NLS-1$ } public void testCBool() throws Exception { - parse( "_Bool x;", true, ParserLanguage.C); //$NON-NLS-1$ + parse("_Bool x;", true, ParserLanguage.C); //$NON-NLS-1$ } public void testBug39678() throws Exception { @@ -1305,14 +1299,17 @@ public class QuickParser2Tests extends TestCase { // IASTMacro swap = (IASTMacro) macros.next(); // assertFalse( macros.hasNext() ); // assertEquals( swap.getName(), "SWAP"); //$NON-NLS-1$ - // assertEquals( swap.getMacroType(), IMacroDescriptor.MacroType.FUNCTION_LIKE ); + // assertEquals( swap.getMacroType(), + // IMacroDescriptor.MacroType.FUNCTION_LIKE ); // String [] params = swap.getParameters(); // assertEquals( params.length, 2 ); // assertEquals( params[0], "x"); //$NON-NLS-1$ // assertEquals( params[1], "y"); //$NON-NLS-1$ // String completeSignature = swap.getCompleteSignature().trim(); - // assertEquals( completeSignature, "#define SWAP(x,y) {x|=y;y|=x;x|=y;}"); //$NON-NLS-1$ - // assertEquals( swap.getExpansionSignature().trim(),"{x|=y;y|=x;x|=y;}"); //$NON-NLS-1$ + // assertEquals( completeSignature, "#define SWAP(x,y) {x|=y;y|=x;x|=y;}"); + // //$NON-NLS-1$ + // assertEquals( swap.getExpansionSignature().trim(),"{x|=y;y|=x;x|=y;}"); + // //$NON-NLS-1$ // IToken [] tokens = swap.getTokenizedExpansion(); // validateToken( tokens[0], IToken.tLBRACE); // validateIdentifier( tokens[1], "x"); //$NON-NLS-1$ @@ -1335,7 +1332,7 @@ public class QuickParser2Tests extends TestCase { // */ // private void validateIdentifier(IToken token, String identifierName ) { // validateToken( token, IToken.tIDENTIFIER); - // assertEquals( token.getImage(), identifierName ); + // assertEquals( token.getImage(), identifierName ); // } // /** // * @param token @@ -1376,7 +1373,8 @@ public class QuickParser2Tests extends TestCase { } public void testBug57652() throws Exception { - parse( "struct file_operations driver_fops = { open: device_open, release: device_release };", true, ParserLanguage.C, true); //$NON-NLS-1$ + parse( + "struct file_operations driver_fops = { open: device_open, release: device_release };", true, ParserLanguage.C, true); //$NON-NLS-1$ } /** @@ -1385,41 +1383,37 @@ public class QuickParser2Tests extends TestCase { * @param c * @param d */ - protected void parse(String code, boolean expectedToPass, ParserLanguage lang, boolean gcc ) throws Exception { - + protected void parse(String code, boolean expectedToPass, + ParserLanguage lang, boolean gcc) throws Exception { + ProblemCollector collector = new ProblemCollector(); IScanner scanner = ParserFactory.createScanner(new CodeReader(code .toCharArray()), new ScannerInfo(), ParserMode.QUICK_PARSE, - lang, NULL_REQUESTOR, - NULL_LOG, Collections.EMPTY_LIST); + lang, NULL_REQUESTOR, NULL_LOG, Collections.EMPTY_LIST); ISourceCodeParser parser2 = null; - if( lang == ParserLanguage.CPP ) - { + if (lang == ParserLanguage.CPP) { ICPPParserExtensionConfiguration config = null; - if( gcc ) + if (gcc) config = new GNUCPPParserExtensionConfiguration(); else config = new ANSICPPParserExtensionConfiguration(); - parser2 = new GNUCPPSourceParser(scanner, ParserMode.QUICK_PARSE, collector, - NULL_LOG, - config ); - } - else - { + parser2 = new GNUCPPSourceParser(scanner, ParserMode.QUICK_PARSE, + collector, NULL_LOG, config); + } else { ICParserExtensionConfiguration config = null; - if( gcc ) + if (gcc) config = new GCCParserExtensionConfiguration(); else config = new ANSICParserExtensionConfiguration(); - - parser2 = new GNUCSourceParser( scanner, ParserMode.QUICK_PARSE, collector, - NULL_LOG, config ); + + parser2 = new GNUCSourceParser(scanner, ParserMode.QUICK_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() ); + if (parser2.encounteredError() && expectedToPass) + throw new ParserException("FAILURE"); //$NON-NLS-1$ + if (expectedToPass) + assertTrue(collector.hasNoProblems()); } public void testBug60142() throws Exception { @@ -1430,8 +1424,7 @@ public class QuickParser2Tests extends TestCase { for (int i = 0; i < 2; ++i) { ParserLanguage language = (i == 0) ? ParserLanguage.C : ParserLanguage.CPP; - parse( - "int k[][] = { {0, {1}, {2,3}};", false, language); //$NON-NLS-1$ + parse("int k[][] = { {0, {1}, {2,3}};", false, language); //$NON-NLS-1$ } } @@ -1468,82 +1461,76 @@ public class QuickParser2Tests extends TestCase { writer .write("static char fmt_1002[] = \"(/,\\002At iterate\\002,i5,4x,\\002f= \\002,1p,d12\\\r\n"); //$NON-NLS-1$ writer.write(".5,4x,\\002|proj g|= \\002,1p,d12.5)\";"); //$NON-NLS-1$ - parse( - writer.toString(), true, ParserLanguage.C); + parse(writer.toString(), true, ParserLanguage.C); } - public void testBug39694() throws Exception - { + public void testBug39694() throws Exception { parse("int ab$cd = 1;"); //$NON-NLS-1$ } - - public void testBug39704A() throws Exception - { + + public void testBug39704A() throws Exception { parse("__declspec (dllimport) int foo;"); //$NON-NLS-1$ - } - public void testBug39704D() throws Exception - { + } + + public void testBug39704D() throws Exception { parse("__declspec(dllexport) int func1 (int a) {}"); //$NON-NLS-1$ } - - public void testBug39695() throws Exception - { + + public void testBug39695() throws Exception { parse("int a = __alignof__ (int);", true, ParserLanguage.CPP, true); //$NON-NLS-1$ } - - public void testBug39684() throws Exception - { - parse("typeof(foo(1)) bar () { return foo(1); }", true, ParserLanguage.CPP, true); //$NON-NLS-1$ + + public void testBug39684() throws Exception { + parse( + "typeof(foo(1)) bar () { return foo(1); }", true, ParserLanguage.CPP, true); //$NON-NLS-1$ } - - public void testBug39703() throws Exception - { + + public void testBug39703() throws Exception { Writer code = new StringWriter(); - code.write("/* __extension__ enables GNU C mode for the duration of the declaration. */\n"); //$NON-NLS-1$ + code + .write("/* __extension__ enables GNU C mode for the duration of the declaration. */\n"); //$NON-NLS-1$ code.write("__extension__ struct G {\n"); //$NON-NLS-1$ code.write(" struct { char z; };\n"); //$NON-NLS-1$ code.write(" char g;\n"); //$NON-NLS-1$ code.write("};\n"); //$NON-NLS-1$ - parse(code.toString(), true, ParserLanguage.CPP, true); + parse(code.toString(), true, ParserLanguage.CPP, true); } - public void testBug39698A() throws Exception - { + public void testBug39698A() throws Exception { parse("int c = a ? b;", true, ParserLanguage.CPP, true); //$NON-NLS-1$ + + public void testBug39698B() throws Exception { + parse("int c = a >? b;", true, ParserLanguage.CPP, true); //$NON-NLS-1$ } - public void testBug39554() throws Exception - { - parse("_Pragma(\"foobar\")", true, ParserLanguage.C ); //$NON-NLS-1$ - } + public void testBug39554() throws Exception { + parse("_Pragma(\"foobar\")", true, ParserLanguage.C); //$NON-NLS-1$ + } - public void testBug39704B() throws Exception - { - parse("extern int (* import) (void) __attribute__((dllimport));", true, ParserLanguage.CPP, true); //$NON-NLS-1$ + public void testBug39704B() throws Exception { + parse( + "extern int (* import) (void) __attribute__((dllimport));", true, ParserLanguage.CPP, true); //$NON-NLS-1$ } - public void testBug39704C() throws Exception - { - parse("int func2 (void) __attribute__((dllexport));", true, ParserLanguage.CPP, true); //$NON-NLS-1$ + + public void testBug39704C() throws Exception { + parse( + "int func2 (void) __attribute__((dllexport));", true, ParserLanguage.CPP, true); //$NON-NLS-1$ } - - public void testBug39686() throws Exception - { + + public void testBug39686() throws Exception { Writer code = new StringWriter(); code.write("__complex__ double x; // complex double\n"); //$NON-NLS-1$ code.write("__complex__ short int a; // complex short int\n"); //$NON-NLS-1$ - code.write("__complex__ float y = 2.5fi; // 2.5 imaginary float literal\n"); //$NON-NLS-1$ + code + .write("__complex__ float y = 2.5fi; // 2.5 imaginary float literal\n"); //$NON-NLS-1$ code.write("__complex__ int a = 3i; // imaginary intege r literal\n"); //$NON-NLS-1$ code.write("double v = __real__ x; // real part of expression\n"); //$NON-NLS-1$ code.write("double w = __imag__ x; // imaginary part of expression\n"); //$NON-NLS-1$ parse(code.toString(), true, ParserLanguage.C, true); } - - public void testBug39681() throws Exception - { + + public void testBug39681() throws Exception { Writer code = new StringWriter(); code.write("double\n"); //$NON-NLS-1$ code.write("foo (double a, double b)\n"); //$NON-NLS-1$ @@ -1553,42 +1540,40 @@ public class QuickParser2Tests extends TestCase { code.write("}\n"); //$NON-NLS-1$ parse(code.toString()); } - - public void testBug39677() throws Exception - { + + public void testBug39677() throws Exception { parse("B::B() : a(({ 1; })) {}", true, ParserLanguage.CPP, true); //$NON-NLS-1$ Writer writer = new StringWriter(); - writer.write( "B::B() : a(( { int y = foo (); int z;\n" ); //$NON-NLS-1$ - writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ - writer.write( "else z = - y;\n" );//$NON-NLS-1$ - writer.write( "z; }))\n" );//$NON-NLS-1$ - parse( writer.toString(), true, ParserLanguage.CPP, true ); + writer.write("B::B() : a(( { int y = foo (); int z;\n"); //$NON-NLS-1$ + writer.write("if (y > 0) z = y;\n"); //$NON-NLS-1$ + writer.write("else z = - y;\n");//$NON-NLS-1$ + writer.write("z; }))\n");//$NON-NLS-1$ + parse(writer.toString(), true, ParserLanguage.CPP, true); writer = new StringWriter(); - writer.write( "int x = ({ int y = foo (); int z;\n" ); //$NON-NLS-1$ - writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ - writer.write( "else z = - y;\n" );//$NON-NLS-1$ - writer.write( "z; });\n" );//$NON-NLS-1$ - parse( writer.toString() , true, ParserLanguage.CPP, true); + writer.write("int x = ({ int y = foo (); int z;\n"); //$NON-NLS-1$ + writer.write("if (y > 0) z = y;\n"); //$NON-NLS-1$ + writer.write("else z = - y;\n");//$NON-NLS-1$ + writer.write("z; });\n");//$NON-NLS-1$ + parse(writer.toString(), true, ParserLanguage.CPP, true); writer = new StringWriter(); - writer.write( "typeof({ int y = foo (); int z;\n" ); //$NON-NLS-1$ - writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$ - writer.write( "else z = - y;\n" );//$NON-NLS-1$ - writer.write( "z; }) zoot;\n" );//$NON-NLS-1$ - parse( writer.toString() , true, ParserLanguage.CPP, true); - } - - public void testBug39701A() throws Exception - { - parse("extern template int max (int, int);", true, ParserLanguage.CPP, true); //$NON-NLS-1$ - } - public void testBug39701B() throws Exception - { - parse("inline template class Foo;", true, ParserLanguage.CPP, true); //$NON-NLS-1$ - } - public void testBug39701C() throws Exception - { - parse("static template class Foo;", true, ParserLanguage.CPP, true); //$NON-NLS-1$ + writer.write("typeof({ int y = foo (); int z;\n"); //$NON-NLS-1$ + writer.write("if (y > 0) z = y;\n"); //$NON-NLS-1$ + writer.write("else z = - y;\n");//$NON-NLS-1$ + writer.write("z; }) zoot;\n");//$NON-NLS-1$ + parse(writer.toString(), true, ParserLanguage.CPP, true); + } + + public void testBug39701A() throws Exception { + parse( + "extern template int max (int, int);", true, ParserLanguage.CPP, true); //$NON-NLS-1$ + } + + public void testBug39701B() throws Exception { + parse("inline template class Foo;", true, ParserLanguage.CPP, true); //$NON-NLS-1$ + } + + public void testBug39701C() throws Exception { + parse("static template class Foo;", true, ParserLanguage.CPP, true); //$NON-NLS-1$ } - } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java index 9317b54618a..2ed5c09afef 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/BasicTokenDuple.java @@ -112,6 +112,8 @@ public class BasicTokenDuple implements ITokenDuple { continue; } } + ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, last ); + r.add( d ); return (ITokenDuple[]) r.toArray( new ITokenDuple[ r.size() ]); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java index 412f0ff228d..867ae8fd788 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/token/TemplateTokenDuple.java @@ -132,4 +132,46 @@ public class TemplateTokenDuple extends BasicTokenDuple { } } } + + public ITokenDuple[] getSegments() + { + List r = new ArrayList(); + IToken token = null; + IToken prev = null; + IToken last = getLastToken(); + IToken startOfSegment = getFirstToken(); + int count = 0; + for( ;; ){ + if( token == last ) + break; + prev = token; + token = ( token != null ) ? token.getNext() : getFirstToken(); + if( token.getType() == IToken.tLT ) + token = TokenFactory.consumeTemplateIdArguments( token, last ); + if( token.getType() == IToken.tCOLONCOLON ){ + List newArgs = null; + if( argLists[count] != null ) + { + newArgs = new ArrayList( 1 ); + newArgs.add( argLists[count]); + } + ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, prev, newArgs ); + r.add( d ); + startOfSegment = token.getNext(); + ++count; + continue; + } + } + List newArgs = null; + if( argLists[count] != null ) + { + newArgs = new ArrayList( 1 ); + newArgs.add( argLists[count]); + } + ITokenDuple d = TokenFactory.createTokenDuple( startOfSegment, last, newArgs); + r.add( d ); + return (ITokenDuple[]) r.toArray( new ITokenDuple[ r.size() ]); + + } + } 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 57374a2cde6..17c4b3f9b27 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 @@ -706,8 +706,19 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { case IToken.tLT: case IToken.tLTEQUAL: case IToken.tGTEQUAL: + IToken m = mark(); int t = consume().getType(); - IASTExpression secondExpression = shiftExpression(); + + IASTExpression secondExpression = null; + try + { + secondExpression = shiftExpression(); + } + catch( BacktrackException bte ) + { + backup( m ); + return firstExpression; + } int expressionKind = 0; switch (t) { case IToken.tGT: @@ -874,7 +885,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { try { declSpecifier = declSpecifierSeq(false, false); - declarator = declarator( SimpleDeclarationStrategy.TRY_CONSTRUCTOR ); + declarator = declarator( SimpleDeclarationStrategy.TRY_CONSTRUCTOR, true ); } catch( BacktrackException bt ) { @@ -2367,7 +2378,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { * @return */ private IASTName createTemplateID(ITokenDuple duple) { - return new CASTName(); //TODO + return new CASTName(); //TODO - what is a template ID? } /** @@ -3145,7 +3156,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { */ protected IASTDeclarator initDeclarator(SimpleDeclarationStrategy strategy ) throws EndOfFileException, BacktrackException { - IASTDeclarator d = declarator(strategy); + IASTDeclarator d = declarator(strategy, false); IASTInitializer initializer = optionalCPPInitializer(); if( initializer != null ) @@ -3269,14 +3280,14 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { * (oldKRParameterDeclaration)* * * declaratorId : name + * @param forTypeID TODO * @param container * IParserCallback object that represents the owner declaration. - * * @return declarator that this parsing produced. * @throws BacktrackException * request a backtrack */ - protected IASTDeclarator declarator(SimpleDeclarationStrategy strategy) throws EndOfFileException, + protected IASTDeclarator declarator(SimpleDeclarationStrategy strategy, boolean forTypeID) throws EndOfFileException, BacktrackException { IToken la = LA(1); @@ -3300,12 +3311,12 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { consumePointerOperators(pointerOps); - if (LT(1) == IToken.tLPAREN) { + if (!forTypeID && LT(1) == IToken.tLPAREN) { IToken mark = mark(); try { consume(); - innerDecl = declarator(strategy); + innerDecl = declarator(strategy, forTypeID); consume(IToken.tRPAREN); } catch( BacktrackException bte ) @@ -3652,7 +3663,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { throwBacktrack(mark.getOffset(), endOffset, mark .getLineNumber(), mark.getFilename()); } - return TokenFactory.createTokenDuple( start, end ); + return TokenFactory.createTokenDuple( start, end, argumentList.getTemplateArgumentsList() ); } int endOffset = (lastToken != null) ? lastToken .getEndOffset() : 0;