From 8d833f012a81dac41a0d33c7e0f047c1dfe415f2 Mon Sep 17 00:00:00 2001 From: John Camelon Date: Wed, 19 Jan 2005 20:24:01 +0000 Subject: [PATCH] Patch for Devin Steffler. This patch adds basic K&R C support to the GNUCSourceParser. - added support for K&R C syntax - added support for ASTProblemDeclaration with faulty K&R C syntax - added simple tests --- .../core/parser/tests/ParserTestSuite.java | 2 + .../core/parser/tests/ast2/AST2BaseTest.java | 19 +- .../core/parser/tests/ast2/AST2KnRTests.java | 327 ++ .../cdt/core/parser/tests/ast2/AST2Tests.java | 55 +- .../core/dom/ast/IASTFunctionDeclarator.java | 13 - .../ast/IASTStandardFunctionDeclarator.java | 34 + .../ast/cpp/ICPPASTFunctionDeclarator.java | 4 +- .../ast/gnu/c/ICASTKnRFunctionDeclarator.java | 32 + .../dom/parser/c/CASTFunctionDeclarator.java | 4 +- .../parser/c/CASTKnRFunctionDeclarator.java | 55 + .../internal/core/dom/parser/c/CFunction.java | 41 +- .../core/dom/parser/c/CKnRParameter.java | 85 + .../internal/core/dom/parser/c/CVisitor.java | 176 +- .../c/GCCParserExtensionConfiguration.java | 7 + .../core/dom/parser/c/GNUCSourceParser.java | 4603 +++++++++-------- .../core/dom/parser/cpp/CPPFunction.java | 6 +- .../core/dom/parser/cpp/CPPSemantics.java | 17 +- .../core/dom/parser/cpp/CPPVisitor.java | 7 +- .../dom/parser/cpp/GNUCPPSourceParser.java | 8 +- 19 files changed, 3202 insertions(+), 2293 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2KnRTests.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTStandardFunctionDeclarator.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/ICASTKnRFunctionDeclarator.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTKnRFunctionDeclarator.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CKnRParameter.java 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 2745a415e6d..d27e8368391 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 @@ -17,6 +17,7 @@ import junit.framework.TestSuite; import org.eclipse.cdt.core.model.tests.CModelElementsTests; import org.eclipse.cdt.core.model.tests.StructuralCModelElementsTests; import org.eclipse.cdt.core.parser.tests.ast2.AST2CPPTests; +import org.eclipse.cdt.core.parser.tests.ast2.AST2KnRTests; import org.eclipse.cdt.core.parser.tests.ast2.AST2Tests; import org.eclipse.cdt.core.parser.tests.ast2.CompleteParser2Tests; import org.eclipse.cdt.core.parser.tests.ast2.DOMLocationTests; @@ -63,6 +64,7 @@ public class ParserTestSuite extends TestCase { suite.addTestSuite( QuickParser2Tests.class ); suite.addTestSuite( CompleteParser2Tests.class ); suite.addTestSuite( DOMLocationTests.class ); + suite.addTestSuite( AST2KnRTests.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 96941b7f600..7df72b06d13 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 @@ -45,11 +45,13 @@ import org.eclipse.cdt.internal.core.dom.SavedCodeReaderFactory; import org.eclipse.cdt.internal.core.dom.parser.ISourceCodeParser; import org.eclipse.cdt.internal.core.dom.parser.c.ANSICParserExtensionConfiguration; import org.eclipse.cdt.internal.core.dom.parser.c.CVisitor; +import org.eclipse.cdt.internal.core.dom.parser.c.GCCParserExtensionConfiguration; import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser; import org.eclipse.cdt.internal.core.dom.parser.c.ICParserExtensionConfiguration; import org.eclipse.cdt.internal.core.dom.parser.cpp.ANSICPPParserExtensionConfiguration; import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser; +import org.eclipse.cdt.internal.core.dom.parser.cpp.GPPParserExtensionConfiguration; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPParserExtensionConfiguration; import org.eclipse.cdt.internal.core.parser.ParserException; import org.eclipse.cdt.internal.core.parser.scanner2.DOMScanner; @@ -64,13 +66,17 @@ public class AST2BaseTest extends TestCase { private static final IParserLogService NULL_LOG = new NullLogService(); + protected IASTTranslationUnit parse( String code, ParserLanguage lang ) throws ParserException { + return parse(code, lang, false); + } + /** * @param string * @param c * @return * @throws ParserException */ - protected IASTTranslationUnit parse( String code, ParserLanguage lang ) throws ParserException { + protected IASTTranslationUnit parse( String code, ParserLanguage lang, boolean useGNUExtensions ) throws ParserException { CodeReader codeReader = new CodeReader(code .toCharArray()); ScannerInfo scannerInfo = new ScannerInfo(); @@ -85,7 +91,10 @@ public class AST2BaseTest extends TestCase { if( lang == ParserLanguage.CPP ) { ICPPParserExtensionConfiguration config = null; - config = new ANSICPPParserExtensionConfiguration(); + if (useGNUExtensions) + config = new GPPParserExtensionConfiguration(); + else + config = new ANSICPPParserExtensionConfiguration(); parser2 = new GNUCPPSourceParser(scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, config ); @@ -93,7 +102,11 @@ public class AST2BaseTest extends TestCase { else { ICParserExtensionConfiguration config = null; - config = new ANSICParserExtensionConfiguration(); + + if (useGNUExtensions) + config = new GCCParserExtensionConfiguration(); + else + config = new ANSICParserExtensionConfiguration(); parser2 = new GNUCSourceParser( scanner, ParserMode.COMPLETE_PARSE, NULL_LOG, config ); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2KnRTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2KnRTests.java new file mode 100644 index 00000000000..1d339741a54 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2KnRTests.java @@ -0,0 +1,327 @@ +/********************************************************************** + * Copyright (c) 2005 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.core.parser.tests.ast2; + +import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement; +import org.eclipse.cdt.core.dom.ast.IASTDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTIdExpression; +import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; +import org.eclipse.cdt.core.dom.ast.IASTProblemDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTReturnStatement; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; +import org.eclipse.cdt.core.dom.ast.IBasicType; +import org.eclipse.cdt.core.dom.ast.IParameter; +import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; +import org.eclipse.cdt.core.parser.ParserLanguage; + +/** + * @author dsteffle + */ +public class AST2KnRTests extends AST2BaseTest { + public void testSimpleKRCTest1() throws Exception { + StringBuffer buffer = new StringBuffer(); //$NON-NLS-1$ + buffer.append( "int f(char x);\n" ); //$NON-NLS-1$ + buffer.append( "int f(x) char x;\n" ); //$NON-NLS-1$ + buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true ); + + IASTSimpleDeclaration f1 = (IASTSimpleDeclaration)tu.getDeclarations()[0]; + IASTFunctionDefinition f2 = (IASTFunctionDefinition)tu.getDeclarations()[1]; + + assertTrue( f1.getDeclarators()[0] instanceof IASTStandardFunctionDeclarator ); + + IParameter x4 = (IParameter)((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f2.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().resolveBinding(); + IParameter x3 = (IParameter)((IASTSimpleDeclaration)((ICASTKnRFunctionDeclarator)f2.getDeclarator()).getParameterDeclarations()[0]).getDeclarators()[0].getName().resolveBinding(); + IParameter x2 = (IParameter)((ICASTKnRFunctionDeclarator)f2.getDeclarator()).getParameterNames()[0].resolveBinding(); + IParameter x1 = (IParameter)((IASTStandardFunctionDeclarator)f1.getDeclarators()[0]).getParameters()[0].getDeclarator().getName().resolveBinding(); + + assertNotNull( x1 ); + assertNotNull( x2 ); + assertNotNull( x3 ); + assertNotNull( x4 ); + assertEquals( x1, x2 ); + assertEquals( x2, x3 ); + assertEquals( x3, x4 ); + } + + public void testSimpleKRCTest2() throws Exception { + StringBuffer buffer = new StringBuffer(); //$NON-NLS-1$ + buffer.append( "int f();\n" ); //$NON-NLS-1$ + buffer.append( "int f(x) char x;\n" ); //$NON-NLS-1$ + buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true ); + + IASTSimpleDeclaration f1 = (IASTSimpleDeclaration)tu.getDeclarations()[0]; + IASTFunctionDefinition f2 = (IASTFunctionDefinition)tu.getDeclarations()[1]; + + assertTrue( f1.getDeclarators()[0] instanceof IASTStandardFunctionDeclarator ); + + IParameter x4 = (IParameter)((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f2.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().resolveBinding(); + IParameter x3 = (IParameter)((IASTSimpleDeclaration)((ICASTKnRFunctionDeclarator)f2.getDeclarator()).getParameterDeclarations()[0]).getDeclarators()[0].getName().resolveBinding(); + IParameter x2 = (IParameter)((ICASTKnRFunctionDeclarator)f2.getDeclarator()).getParameterNames()[0].resolveBinding(); + + assertNotNull( x2 ); + assertNotNull( x3 ); + assertNotNull( x4 ); + assertEquals( x2, x3 ); + assertEquals( x3, x4 ); + } + + public void testSimpleKRCTest3() throws Exception { + StringBuffer buffer = new StringBuffer(); //$NON-NLS-1$ + buffer.append( "int const *f();\n" ); //$NON-NLS-1$ + buffer.append( "int const *f(x) char x;\n" ); //$NON-NLS-1$ + buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true ); + + IASTSimpleDeclaration f1 = (IASTSimpleDeclaration)tu.getDeclarations()[0]; + IASTFunctionDefinition f2 = (IASTFunctionDefinition)tu.getDeclarations()[1]; + + assertTrue( f1.getDeclarators()[0] instanceof IASTStandardFunctionDeclarator ); + + IParameter x4 = (IParameter)((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f2.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().resolveBinding(); + IParameter x3 = (IParameter)((IASTSimpleDeclaration)((ICASTKnRFunctionDeclarator)f2.getDeclarator()).getParameterDeclarations()[0]).getDeclarators()[0].getName().resolveBinding(); + IParameter x2 = (IParameter)((ICASTKnRFunctionDeclarator)f2.getDeclarator()).getParameterNames()[0].resolveBinding(); + + assertNotNull( x2 ); + assertNotNull( x3 ); + assertNotNull( x4 ); + assertEquals( x2, x3 ); + assertEquals( x3, x4 ); + } + + public void testKRC_1() throws Exception { + StringBuffer buffer = new StringBuffer(); //$NON-NLS-1$ + buffer.append( "int isroot (x, y) /* comment */ \n" ); //$NON-NLS-1$ + buffer.append( "int x;\n" ); //$NON-NLS-1$ + buffer.append( "int y;\n" ); //$NON-NLS-1$ + buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true ); + + IASTFunctionDefinition isroot_def = (IASTFunctionDefinition)tu.getDeclarations()[0]; + + IASTName ret_x = ((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)isroot_def.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName(); + IASTDeclarator isroot_decltor = isroot_def.getDeclarator(); + + assertTrue( isroot_decltor instanceof ICASTKnRFunctionDeclarator ); + IASTDeclarator x1 = ((IASTSimpleDeclaration)((ICASTKnRFunctionDeclarator)isroot_decltor).getParameterDeclarations()[0]).getDeclarators()[0]; + IASTDeclarator y1 = ((IASTSimpleDeclaration)((ICASTKnRFunctionDeclarator)isroot_decltor).getParameterDeclarations()[1]).getDeclarators()[0]; + + IParameter x_parm = (IParameter)x1.getName().resolveBinding(); + IParameter y_parm = (IParameter)y1.getName().resolveBinding(); + assertNotNull( x_parm ); + assertNotNull( y_parm ); + + IASTDeclarator x2 = ((IASTSimpleDeclaration)((ICASTKnRFunctionDeclarator)isroot_decltor).getParameterDeclarations()[0]).getDeclarators()[0]; + IASTDeclarator y2 = ((IASTSimpleDeclaration)((ICASTKnRFunctionDeclarator)isroot_decltor).getParameterDeclarations()[1]).getDeclarators()[0]; + + IParameter x_parm2 = (IParameter)x2.getName().resolveBinding(); + IParameter y_parm2 = (IParameter)y2.getName().resolveBinding(); + + assertNotNull( x_parm2 ); + assertNotNull( y_parm2 ); + assertNotNull( ret_x.resolveBinding() ); + + assertEquals( x_parm, x_parm2 ); + assertEquals( y_parm, y_parm2 ); + assertEquals( ret_x.resolveBinding(), x_parm ); + + } + + public void testKRCWithTypes() throws Exception { + StringBuffer buffer = new StringBuffer(); //$NON-NLS-1$ + buffer.append( "typedef char c;\n" ); //$NON-NLS-1$ + buffer.append( "int isroot (c);\n" ); //$NON-NLS-1$ + buffer.append( "int isroot (x) \n" ); //$NON-NLS-1$ + buffer.append( "c x;\n" ); //$NON-NLS-1$ + buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true ); + + IASTSimpleDeclaration c_decl = (IASTSimpleDeclaration)tu.getDeclarations()[0]; + IASTSimpleDeclaration isroot_decl = (IASTSimpleDeclaration)tu.getDeclarations()[1]; + IASTFunctionDefinition isroot_def = (IASTFunctionDefinition)tu.getDeclarations()[2]; + + IASTName x1 = ((ICASTKnRFunctionDeclarator)isroot_def.getDeclarator()).getParameterNames()[0]; + IASTName x2 = ((IASTSimpleDeclaration)((ICASTKnRFunctionDeclarator)isroot_def.getDeclarator()).getParameterDeclarations()[0]).getDeclarators()[0].getName(); + IASTName x3 = ((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)isroot_def.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName(); + + IParameter x1_var = (IParameter)x1.resolveBinding(); + IParameter x2_var = (IParameter)x2.resolveBinding(); + IParameter x3_var = (IParameter)x3.resolveBinding(); + + assertNotNull(x1_var); + assertNotNull(x2_var); + assertNotNull(x3_var); + assertEquals(x1_var, x2_var); + assertEquals(x2_var, x3_var); + + IASTName c1 = c_decl.getDeclarators()[0].getName(); + IASTName c2 = ((IASTNamedTypeSpecifier)((IASTStandardFunctionDeclarator)isroot_decl.getDeclarators()[0]).getParameters()[0].getDeclSpecifier()).getName(); + IASTName c3 = ((IASTNamedTypeSpecifier)((IASTSimpleDeclaration)((ICASTKnRFunctionDeclarator)isroot_def.getDeclarator()).getParameterDeclarations()[0]).getDeclSpecifier()).getName(); + + ITypedef c1_t = (ITypedef)c1.resolveBinding(); + ITypedef c2_t = (ITypedef)c2.resolveBinding(); + ITypedef c3_t = (ITypedef)c3.resolveBinding(); + + assertNotNull(c1_t); + assertNotNull(c2_t); + assertNotNull(c3_t); + assertEquals(c1_t, c2_t); + assertEquals(c2_t, c3_t); + assertTrue(c1_t.getType() instanceof IBasicType); + assertEquals(((IBasicType)c1_t.getType()).getType(), IBasicType.t_char); + + } + + public void testKRCProblem1() throws Exception { + StringBuffer buffer = new StringBuffer(); //$NON-NLS-1$ + buffer.append( "int f(x) char\n" ); //$NON-NLS-1$ + buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true ); + + IASTFunctionDefinition f = (IASTFunctionDefinition)tu.getDeclarations()[0]; + assertTrue(f.getDeclarator() instanceof ICASTKnRFunctionDeclarator); + ICASTKnRFunctionDeclarator f_kr = (ICASTKnRFunctionDeclarator)f.getDeclarator(); + assertEquals(f_kr.getName().toString(), "f"); //$NON-NLS-1$ + assertEquals(f_kr.getParameterNames()[0].toString(), "x"); //$NON-NLS-1$ + assertTrue(f_kr.getParameterDeclarations()[0] instanceof IASTProblemDeclaration); + assertTrue(f.getBody() instanceof IASTCompoundStatement); + assertTrue(((IASTCompoundStatement)f.getBody()).getStatements()[0] instanceof IASTReturnStatement); + assertTrue(((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue() instanceof IASTBinaryExpression); + assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1() instanceof IASTIdExpression); + assertEquals(((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().toString(), "x"); //$NON-NLS-1$ + assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2() instanceof IASTLiteralExpression); + assertEquals(((IASTLiteralExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2()).toString(), "0"); //$NON-NLS-1$ + + // TODO problem bindings, right now both bindings for x are null, similarly for the below KRCProblem tests +// f_kr.getParameterNames()[0].resolveBinding(); +// ((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().resolveBinding(); + + } + + public void testKRCProblem2() throws Exception { + StringBuffer buffer = new StringBuffer(); //$NON-NLS-1$ + buffer.append( "int i=0;\n" ); //$NON-NLS-1$ + buffer.append( "int f(x) i++;\n" ); //$NON-NLS-1$ + buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true ); + + IASTFunctionDefinition f = (IASTFunctionDefinition)tu.getDeclarations()[1]; + assertTrue(f.getDeclarator() instanceof ICASTKnRFunctionDeclarator); + ICASTKnRFunctionDeclarator f_kr = (ICASTKnRFunctionDeclarator)f.getDeclarator(); + assertEquals(f_kr.getName().toString(), "f"); //$NON-NLS-1$ + assertEquals(f_kr.getParameterNames()[0].toString(), "x"); //$NON-NLS-1$ + assertTrue(f_kr.getParameterDeclarations()[0] instanceof IASTProblemDeclaration); + assertTrue(f.getBody() instanceof IASTCompoundStatement); + assertTrue(((IASTCompoundStatement)f.getBody()).getStatements()[0] instanceof IASTReturnStatement); + assertTrue(((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue() instanceof IASTBinaryExpression); + assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1() instanceof IASTIdExpression); + assertEquals(((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().toString(), "x"); //$NON-NLS-1$ + assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2() instanceof IASTLiteralExpression); + assertEquals(((IASTLiteralExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2()).toString(), "0"); //$NON-NLS-1$ + + } + + public void testKRCProblem3() throws Exception { + StringBuffer buffer = new StringBuffer(); //$NON-NLS-1$ + buffer.append( "int f(x) char y;\n" ); //$NON-NLS-1$ + buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true ); + + IASTFunctionDefinition f = (IASTFunctionDefinition)tu.getDeclarations()[0]; + assertTrue(f.getDeclarator() instanceof ICASTKnRFunctionDeclarator); + ICASTKnRFunctionDeclarator f_kr = (ICASTKnRFunctionDeclarator)f.getDeclarator(); + assertEquals(f_kr.getName().toString(), "f"); //$NON-NLS-1$ + assertEquals(f_kr.getParameterNames()[0].toString(), "x"); //$NON-NLS-1$ + assertTrue(f_kr.getParameterDeclarations()[0] instanceof IASTProblemDeclaration); + assertTrue(f.getBody() instanceof IASTCompoundStatement); + assertTrue(((IASTCompoundStatement)f.getBody()).getStatements()[0] instanceof IASTReturnStatement); + assertTrue(((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue() instanceof IASTBinaryExpression); + assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1() instanceof IASTIdExpression); + assertEquals(((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().toString(), "x"); //$NON-NLS-1$ + assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2() instanceof IASTLiteralExpression); + assertEquals(((IASTLiteralExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2()).toString(), "0"); //$NON-NLS-1$ + + } + + public void testKRCProblem4() throws Exception { + StringBuffer buffer = new StringBuffer(); //$NON-NLS-1$ + buffer.append( "int f(x,y,z) char x,y,z; int a;\n" ); //$NON-NLS-1$ + buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true ); + + IASTFunctionDefinition f = (IASTFunctionDefinition)tu.getDeclarations()[0]; + assertTrue(f.getDeclarator() instanceof ICASTKnRFunctionDeclarator); + ICASTKnRFunctionDeclarator f_kr = (ICASTKnRFunctionDeclarator)f.getDeclarator(); + assertEquals(f_kr.getName().toString(), "f"); //$NON-NLS-1$ + assertEquals(f_kr.getParameterNames()[0].toString(), "x"); //$NON-NLS-1$ + assertTrue(f_kr.getParameterDeclarations()[0] instanceof IASTSimpleDeclaration); + assertTrue(f_kr.getParameterDeclarations()[1] instanceof IASTProblemDeclaration); + assertTrue(f.getBody() instanceof IASTCompoundStatement); + assertTrue(((IASTCompoundStatement)f.getBody()).getStatements()[0] instanceof IASTReturnStatement); + assertTrue(((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue() instanceof IASTBinaryExpression); + assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1() instanceof IASTIdExpression); + assertEquals(((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().toString(), "x"); //$NON-NLS-1$ + assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2() instanceof IASTLiteralExpression); + assertEquals(((IASTLiteralExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2()).toString(), "0"); //$NON-NLS-1$ + + // bindings should still be ok + IASTName x1 = f_kr.getParameterNames()[0]; + IASTName y1 = f_kr.getParameterNames()[1]; + IASTName z1 = f_kr.getParameterNames()[2]; + IASTName x2 = ((IASTSimpleDeclaration)f_kr.getParameterDeclarations()[0]).getDeclarators()[0].getName(); + IASTName y2 = ((IASTSimpleDeclaration)f_kr.getParameterDeclarations()[0]).getDeclarators()[1].getName(); + IASTName z2 = ((IASTSimpleDeclaration)f_kr.getParameterDeclarations()[0]).getDeclarators()[2].getName(); + IASTName x3 = ((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName(); + + IParameter x1_parm = (IParameter)x1.resolveBinding(); + IParameter x2_parm = (IParameter)x2.resolveBinding(); + IParameter x3_parm = (IParameter)x3.resolveBinding(); + IParameter y1_parm = (IParameter)y1.resolveBinding(); + IParameter y2_parm = (IParameter)y2.resolveBinding(); + IParameter z1_parm = (IParameter)z1.resolveBinding(); + IParameter z2_parm = (IParameter)z2.resolveBinding(); + + assertEquals(x1_parm, x2_parm); + assertEquals(x2_parm, x3_parm); + assertEquals(y1_parm, y2_parm); + assertEquals(z1_parm, z2_parm); + } + + public void testKRCProblem5() throws Exception { + StringBuffer buffer = new StringBuffer(); //$NON-NLS-1$ + buffer.append( "int f(x) char x,a;\n" ); //$NON-NLS-1$ + buffer.append( "{ return x == 0; }\n" ); //$NON-NLS-1$ + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C, true ); + + IASTFunctionDefinition f = (IASTFunctionDefinition)tu.getDeclarations()[0]; + assertTrue(f.getDeclarator() instanceof ICASTKnRFunctionDeclarator); + ICASTKnRFunctionDeclarator f_kr = (ICASTKnRFunctionDeclarator)f.getDeclarator(); + assertEquals(f_kr.getName().toString(), "f"); //$NON-NLS-1$ + assertEquals(f_kr.getParameterNames()[0].toString(), "x"); //$NON-NLS-1$ + assertTrue(f_kr.getParameterDeclarations()[0] instanceof IASTProblemDeclaration); + assertTrue(f.getBody() instanceof IASTCompoundStatement); + assertTrue(((IASTCompoundStatement)f.getBody()).getStatements()[0] instanceof IASTReturnStatement); + assertTrue(((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue() instanceof IASTBinaryExpression); + assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1() instanceof IASTIdExpression); + assertEquals(((IASTIdExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand1()).getName().toString(), "x"); //$NON-NLS-1$ + assertTrue(((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2() instanceof IASTLiteralExpression); + assertEquals(((IASTLiteralExpression)((IASTBinaryExpression)((IASTReturnStatement)((IASTCompoundStatement)f.getBody()).getStatements()[0]).getReturnValue()).getOperand2()).toString(), "0"); //$NON-NLS-1$ + } + +} diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java index c75e54db43b..ad570ebb5ca 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java @@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFieldReference; import org.eclipse.cdt.core.dom.ast.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTIfStatement; @@ -115,7 +116,8 @@ public class AST2Tests extends AST2BaseTest { assertEquals("f", name_f.toString()); //$NON-NLS-1$ // parameter - int y - IASTParameterDeclaration decl_y = declor_f.getParameters()[0]; + assertTrue(declor_f instanceof IASTStandardFunctionDeclarator); + IASTParameterDeclaration decl_y = ((IASTStandardFunctionDeclarator)declor_f).getParameters()[0]; IASTSimpleDeclSpecifier declspec_y = (IASTSimpleDeclSpecifier) decl_y .getDeclSpecifier(); assertEquals(IASTSimpleDeclSpecifier.t_int, declspec_y.getType()); @@ -629,7 +631,8 @@ public class AST2Tests extends AST2BaseTest { IASTName x_1 = typeSpec.getName(); IASTFunctionDefinition fdef = (IASTFunctionDefinition) tu.getDeclarations()[1]; - IASTParameterDeclaration param = fdef.getDeclarator().getParameters()[0]; + assertTrue(fdef.getDeclarator() instanceof IASTStandardFunctionDeclarator); + IASTParameterDeclaration param = ((IASTStandardFunctionDeclarator)fdef.getDeclarator()).getParameters()[0]; IASTName x_2 = param.getDeclarator().getName(); IASTCompoundStatement compound = (IASTCompoundStatement) fdef.getBody(); @@ -692,7 +695,7 @@ public class AST2Tests extends AST2BaseTest { //void f( IASTSimpleDeclaration f_decl = (IASTSimpleDeclaration) tu.getDeclarations()[0]; - IASTFunctionDeclarator dtor = (IASTFunctionDeclarator) f_decl.getDeclarators()[0]; + IASTStandardFunctionDeclarator dtor = (IASTStandardFunctionDeclarator) f_decl.getDeclarators()[0]; IASTName f_name1 = dtor.getName(); // int a ); IASTParameterDeclaration param1 = dtor.getParameters()[0]; @@ -701,7 +704,8 @@ public class AST2Tests extends AST2BaseTest { //void f( IASTFunctionDefinition f_defn = (IASTFunctionDefinition) tu.getDeclarations()[1]; - dtor = f_defn.getDeclarator(); + assertTrue(f_defn.getDeclarator() instanceof IASTStandardFunctionDeclarator); + dtor = (IASTStandardFunctionDeclarator)f_defn.getDeclarator(); IASTName f_name2 = dtor.getName(); // int b ); IASTParameterDeclaration param2 = dtor.getParameters()[0]; @@ -764,7 +768,8 @@ public class AST2Tests extends AST2BaseTest { IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); IASTFunctionDefinition fDef = (IASTFunctionDefinition) tu.getDeclarations()[0]; - IASTFunctionDeclarator fDtor = fDef.getDeclarator(); + assertTrue(fDef.getDeclarator() instanceof IASTStandardFunctionDeclarator); + IASTStandardFunctionDeclarator fDtor = (IASTStandardFunctionDeclarator)fDef.getDeclarator(); IASTName fName = fDtor.getName(); IASTParameterDeclaration a = fDtor.getParameters()[0]; @@ -812,7 +817,7 @@ public class AST2Tests extends AST2BaseTest { //void f(); IASTSimpleDeclaration fdecl = (IASTSimpleDeclaration) tu.getDeclarations()[0]; - IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) fdecl.getDeclarators()[0]; + IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) fdecl.getDeclarators()[0]; IASTName name_f = fdtor.getName(); //void g() { @@ -828,7 +833,8 @@ public class AST2Tests extends AST2BaseTest { //void f() {} IASTFunctionDefinition fdef = (IASTFunctionDefinition) tu.getDeclarations()[2]; - fdtor = fdef.getDeclarator(); + assertTrue(fdef.getDeclarator() instanceof IASTStandardFunctionDeclarator); + fdtor = (IASTStandardFunctionDeclarator)fdef.getDeclarator(); IASTName name_fdef = fdtor.getName(); //bindings @@ -1024,8 +1030,8 @@ public class AST2Tests extends AST2BaseTest { IASTSimpleDeclaration decl2 = (IASTSimpleDeclaration)tu.getDeclarations()[1]; IASTName name_X1 = decl1.getDeclarators()[0].getName(); IASTName name_f = decl2.getDeclarators()[0].getName(); - IASTName name_X2 = ((IASTNamedTypeSpecifier)((IASTFunctionDeclarator)decl2.getDeclarators()[0]).getParameters()[0].getDeclSpecifier()).getName(); - IASTName name_x = ((IASTFunctionDeclarator)decl2.getDeclarators()[0]).getParameters()[0].getDeclarator().getName(); + IASTName name_X2 = ((IASTNamedTypeSpecifier)((IASTStandardFunctionDeclarator)decl2.getDeclarators()[0]).getParameters()[0].getDeclSpecifier()).getName(); + IASTName name_x = ((IASTStandardFunctionDeclarator)decl2.getDeclarators()[0]).getParameters()[0].getDeclarator().getName(); IASTName[] decls = tu.getDeclarations(name_X1.resolveBinding()); assertEquals( decls.length, 1 ); @@ -1207,7 +1213,7 @@ public class AST2Tests extends AST2BaseTest { assertEquals( tu.getDeclarations().length, 1 ); IASTSimpleDeclaration d = (IASTSimpleDeclaration) tu.getDeclarations()[0]; assertEquals( d.getDeclarators().length, 1 ); - IASTFunctionDeclarator f = (IASTFunctionDeclarator) d.getDeclarators()[0]; + IASTStandardFunctionDeclarator f = (IASTStandardFunctionDeclarator) d.getDeclarators()[0]; assertNull( f.getName().toString() ); assertNotNull( f.getNestedDeclarator() ); assertEquals( f.getNestedDeclarator().getName().toString(), "pfi"); //$NON-NLS-1$ @@ -1223,7 +1229,7 @@ public class AST2Tests extends AST2BaseTest { assertEquals( tu.getDeclarations().length, 1 ); d = (IASTSimpleDeclaration) tu.getDeclarations()[0]; assertEquals( d.getDeclarators().length, 1 ); - f = (IASTFunctionDeclarator) d.getDeclarators()[0]; + f = (IASTStandardFunctionDeclarator) d.getDeclarators()[0]; assertNull( f.getName().toString() ); assertNotNull( f.getNestedDeclarator() ); assertEquals( f.getNestedDeclarator().getName().toString(), "pfi"); //$NON-NLS-1$ @@ -1521,19 +1527,19 @@ public class AST2Tests extends AST2BaseTest { decl = (IASTSimpleDeclaration) tu.getDeclarations()[1]; IFunction f = (IFunction) decl.getDeclarators()[0].getName().resolveBinding(); IASTName name_f = decl.getDeclarators()[0].getName(); - IASTName name_i = ((IASTFunctionDeclarator)decl.getDeclarators()[0]).getParameters()[0].getDeclarator().getName(); - IASTName name_c = ((IASTFunctionDeclarator)decl.getDeclarators()[0]).getParameters()[1].getDeclarator().getName(); + IASTName name_i = ((IASTStandardFunctionDeclarator)decl.getDeclarators()[0]).getParameters()[0].getDeclarator().getName(); + IASTName name_c = ((IASTStandardFunctionDeclarator)decl.getDeclarators()[0]).getParameters()[1].getDeclarator().getName(); decl = (IASTSimpleDeclaration) tu.getDeclarations()[2]; IVariable g = (IVariable) decl.getDeclarators()[0].getNestedDeclarator().getName().resolveBinding(); IASTName name_g = decl.getDeclarators()[0].getNestedDeclarator().getName(); - IASTName name_A2 = ((IASTElaboratedTypeSpecifier)((IASTFunctionDeclarator)decl.getDeclarators()[0]).getParameters()[0].getDeclSpecifier()).getName(); + IASTName name_A2 = ((IASTElaboratedTypeSpecifier)((IASTStandardFunctionDeclarator)decl.getDeclarators()[0]).getParameters()[0].getDeclSpecifier()).getName(); decl = (IASTSimpleDeclaration) tu.getDeclarations()[3]; IVariable h = (IVariable) decl.getDeclarators()[0].getNestedDeclarator().getNestedDeclarator().getName().resolveBinding(); IASTName name_h = decl.getDeclarators()[0].getNestedDeclarator().getNestedDeclarator().getName(); - IASTName name_A3 = ((IASTElaboratedTypeSpecifier)((IASTFunctionDeclarator)decl.getDeclarators()[0].getNestedDeclarator()).getParameters()[0].getDeclSpecifier()).getName(); - IASTName name_d = ((IASTFunctionDeclarator)decl.getDeclarators()[0]).getParameters()[0].getDeclarator().getName(); + IASTName name_A3 = ((IASTElaboratedTypeSpecifier)((IASTStandardFunctionDeclarator)decl.getDeclarators()[0].getNestedDeclarator()).getParameters()[0].getDeclSpecifier()).getName(); + IASTName name_d = ((IASTStandardFunctionDeclarator)decl.getDeclarators()[0]).getParameters()[0].getDeclarator().getName(); IFunctionType t_f = f.getType(); IType t_f_return = t_f.getReturnType(); @@ -1774,7 +1780,7 @@ public class AST2Tests extends AST2BaseTest { buffer.append( "typedef s t;\n" ); //$NON-NLS-1$ buffer.append( "typedef t y;\n" ); //$NON-NLS-1$ buffer.append( "y x = {.a=1,.b=2};\n" ); //$NON-NLS-1$ - IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); // TODO Devin make sure that loop I put in works properly for types + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.C ); IASTSimpleDeclaration S_decl = (IASTSimpleDeclaration)tu.getDeclarations()[0]; IASTSimpleDeclaration x_decl = (IASTSimpleDeclaration)tu.getDeclarations()[3]; @@ -1827,7 +1833,7 @@ public class AST2Tests extends AST2BaseTest { assertTrue( ((IPointerType)ft.getParameterTypes()[0]).isConst() ); // test tu.getDeclarations(IBinding) - IASTName name_parm = ((IASTFunctionDeclarator)def.getDeclarators()[0]).getParameters()[0].getDeclarator().getName(); + IASTName name_parm = ((IASTStandardFunctionDeclarator)def.getDeclarators()[0]).getParameters()[0].getDeclarator().getName(); IASTName[] decls = tu.getDeclarations(name_parm.resolveBinding()); assertEquals( decls.length, 1 ); assertEquals( decls[0], name_parm ); @@ -1892,7 +1898,8 @@ public class AST2Tests extends AST2BaseTest { assertEquals( ((IBasicType)gt_parm).getType(), IBasicType.t_void ); // test tu.getDeclarations(IBinding) - IASTName name_g = def.getDeclarator().getParameters()[0].getDeclarator().getName(); + assertTrue(def.getDeclarator() instanceof IASTStandardFunctionDeclarator); + IASTName name_g = ((IASTStandardFunctionDeclarator)def.getDeclarator()).getParameters()[0].getDeclarator().getName(); IASTName name_g_call = ((IASTIdExpression)((IASTFunctionCallExpression)((IASTReturnStatement)((IASTCompoundStatement)def.getBody()).getStatements()[0]).getReturnValue()).getFunctionNameExpression()).getName(); IASTName[] decls = tu.getDeclarations(name_g_call.resolveBinding()); assertEquals( decls.length, 1 ); @@ -1903,7 +1910,7 @@ public class AST2Tests extends AST2BaseTest { IASTTranslationUnit tu = parse( "int (*v[])(int *x, int *y);", ParserLanguage.C ); //$NON-NLS-1$ IASTSimpleDeclaration decl = (IASTSimpleDeclaration) tu.getDeclarations()[0]; - IVariable v = (IVariable)((IASTFunctionDeclarator) decl.getDeclarators()[0]).getNestedDeclarator().getName().resolveBinding(); + IVariable v = (IVariable)((IASTStandardFunctionDeclarator) decl.getDeclarators()[0]).getNestedDeclarator().getName().resolveBinding(); IType vt_1 = v.getType(); assertTrue( vt_1 instanceof IArrayType ); @@ -1927,9 +1934,9 @@ public class AST2Tests extends AST2BaseTest { assertEquals( ((IBasicType)vpt_2_2).getType(), IBasicType.t_int ); // test tu.getDeclarations(IBinding) - IASTName[] decls = tu.getDeclarations(((IASTFunctionDeclarator) decl.getDeclarators()[0]).getNestedDeclarator().getName().resolveBinding()); + IASTName[] decls = tu.getDeclarations(((IASTStandardFunctionDeclarator) decl.getDeclarators()[0]).getNestedDeclarator().getName().resolveBinding()); assertEquals( decls.length, 1 ); - assertEquals( decls[0], ((IASTFunctionDeclarator) decl.getDeclarators()[0]).getNestedDeclarator().getName() ); + assertEquals( decls[0], ((IASTStandardFunctionDeclarator) decl.getDeclarators()[0]).getNestedDeclarator().getName() ); } public void testTypedefExample4a() throws Exception { @@ -2043,7 +2050,7 @@ public class AST2Tests extends AST2BaseTest { // test tu.getDeclarations(IBinding) IASTName name_pfv = decl2.getDeclarators()[0].getNestedDeclarator().getName(); IASTName name_pfv1 = ((IASTNamedTypeSpecifier)decl3.getDeclSpecifier()).getName(); - IASTName name_pfv2 = ((IASTNamedTypeSpecifier)((IASTFunctionDeclarator)decl3.getDeclarators()[0]).getParameters()[1].getDeclSpecifier()).getName(); + IASTName name_pfv2 = ((IASTNamedTypeSpecifier)((IASTStandardFunctionDeclarator)decl3.getDeclarators()[0]).getParameters()[1].getDeclSpecifier()).getName(); IASTName[] decls = tu.getDeclarations(name_pfv1.resolveBinding()); assertEquals( decls.length, 1 ); @@ -2118,7 +2125,7 @@ public class AST2Tests extends AST2BaseTest { { StringBuffer buffer =new StringBuffer(); //$NON-NLS-1$ buffer.append( "int y ( int [ const *] );"); //$NON-NLS-1$ - ICASTArrayModifier mod = (ICASTArrayModifier)((IASTArrayDeclarator)((IASTFunctionDeclarator) ((IASTSimpleDeclaration) parse( buffer.toString(), ParserLanguage.C ).getDeclarations()[0]).getDeclarators()[0]).getParameters()[0].getDeclarator() ).getArrayModifiers()[0]; + ICASTArrayModifier mod = (ICASTArrayModifier)((IASTArrayDeclarator)((IASTStandardFunctionDeclarator) ((IASTSimpleDeclaration) parse( buffer.toString(), ParserLanguage.C ).getDeclarations()[0]).getDeclarators()[0]).getParameters()[0].getDeclarator() ).getArrayModifiers()[0]; assertTrue( mod.isConst() ); assertTrue( mod.isVariableSized() ); assertFalse( mod.isStatic() ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTFunctionDeclarator.java index f8d2db946c7..480e7af4c63 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTFunctionDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTFunctionDeclarator.java @@ -18,17 +18,4 @@ package org.eclipse.cdt.core.dom.ast; */ public interface IASTFunctionDeclarator extends IASTDeclarator { - ASTNodeProperty FUNCTION_PARAMETER = new ASTNodeProperty( "Parameter"); //$NON-NLS-1$ - /** - * Gets the parameter declarations for the function - * - * @return List of IASTParameterDeclaration - */ - public IASTParameterDeclaration[] getParameters(); - - public void addParameterDeclaration( IASTParameterDeclaration parameter ); - - public boolean takesVarArgs(); - - public void setVarArgs( boolean value ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTStandardFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTStandardFunctionDeclarator.java new file mode 100644 index 00000000000..128e44e4a93 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTStandardFunctionDeclarator.java @@ -0,0 +1,34 @@ +/********************************************************************** + * 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.dom.ast; + + +/** + * This is a declarator for a non K&R C function. + * + * @author Doug Schaefer + */ +public interface IASTStandardFunctionDeclarator extends IASTFunctionDeclarator { + + public final static ASTNodeProperty FUNCTION_PARAMETER = new ASTNodeProperty( "Parameter"); //$NON-NLS-1$ + /** + * Gets the parameter declarations for the function + * + * @return List of IASTParameterDeclaration + */ + public IASTParameterDeclaration[] getParameters(); + + public void addParameterDeclaration( IASTParameterDeclaration parameter ); + + public boolean takesVarArgs(); + + public void setVarArgs( boolean value ); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java index 905e7fc1a10..77919404d71 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPASTFunctionDeclarator.java @@ -11,7 +11,7 @@ package org.eclipse.cdt.core.dom.ast.cpp; import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; -import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTTypeId; /** @@ -19,7 +19,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId; * * @author Doug Schaefer */ -public interface ICPPASTFunctionDeclarator extends IASTFunctionDeclarator { +public interface ICPPASTFunctionDeclarator extends IASTStandardFunctionDeclarator { public boolean isConst(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/ICASTKnRFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/ICASTKnRFunctionDeclarator.java new file mode 100644 index 00000000000..d563d45adc0 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/c/ICASTKnRFunctionDeclarator.java @@ -0,0 +1,32 @@ +/********************************************************************** + * Copyright (c) 2005 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.dom.ast.gnu.c; + +import org.eclipse.cdt.core.dom.ast.ASTNodeProperty; +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTName; + +/** + * This is the declarator for a K&R C Function. + * + * @author dsteffle + */ +public interface ICASTKnRFunctionDeclarator extends IASTFunctionDeclarator { + + public static final ASTNodeProperty PARAMETER_NAME = new ASTNodeProperty( "Parameter Name"); //$NON-NLS-1$ + public void setParameterNames(IASTName[] names); + public IASTName[] getParameterNames(); + + public static final ASTNodeProperty FUNCTION_PARAMETER = new ASTNodeProperty( "Parameter"); //$NON-NLS-1$ + public void setParameterDeclarations(IASTDeclaration[] decls); + public IASTDeclaration[] getParameterDeclarations(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionDeclarator.java index b8175f65b50..4207d3ef518 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionDeclarator.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTFunctionDeclarator.java @@ -9,14 +9,14 @@ * IBM Rational Software - Initial API and implementation */ package org.eclipse.cdt.internal.core.dom.parser.c; -import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; /** * @author jcamelon */ public class CASTFunctionDeclarator extends CASTDeclarator implements - IASTFunctionDeclarator { + IASTStandardFunctionDeclarator { private IASTParameterDeclaration [] parameters = null; private static final int DEFAULT_PARAMETERS_LIST_SIZE = 2; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTKnRFunctionDeclarator.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTKnRFunctionDeclarator.java new file mode 100644 index 00000000000..af959349ed7 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTKnRFunctionDeclarator.java @@ -0,0 +1,55 @@ +/********************************************************************** + * Copyright (c) 2005 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.dom.parser.c; + +import org.eclipse.cdt.core.dom.ast.IASTDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; + +/** + * A K&R C function declarator. + * + * @author dsteffle + */ +public class CASTKnRFunctionDeclarator extends CASTDeclarator implements ICASTKnRFunctionDeclarator { + + IASTName[] parameterNames = null; + IASTDeclaration[] parameterDeclarations = null; + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator#setParameterNames(org.eclipse.cdt.core.dom.ast.IASTName[]) + */ + public void setParameterNames(IASTName[] names) { + parameterNames = names; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator#getParameterNames() + */ + public IASTName[] getParameterNames() { + return parameterNames; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator#setParameterDeclarations(org.eclipse.cdt.core.dom.ast.IASTDeclaration[]) + */ + public void setParameterDeclarations(IASTDeclaration[] decls) { + parameterDeclarations = decls; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator#getParameterDeclarations() + */ + public IASTDeclaration[] getParameterDeclarations() { + return parameterDeclarations; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java index 2866fae2dec..7ca3d368021 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CFunction.java @@ -16,6 +16,8 @@ import java.util.List; import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; @@ -23,6 +25,7 @@ import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator; /** * Created on Nov 5, 2004 @@ -45,7 +48,7 @@ public class CFunction implements IFunction { return ( definition != null ) ? definition : declarators[0]; } public void addDeclarator( IASTFunctionDeclarator fnDeclarator ){ - if( fnDeclarator instanceof IASTFunctionDefinition ) + if( fnDeclarator instanceof IASTFunctionDefinition || fnDeclarator instanceof ICASTKnRFunctionDeclarator ) definition = fnDeclarator; else { if( declarators == null ){ @@ -80,17 +83,37 @@ public class CFunction implements IFunction { * @see org.eclipse.cdt.core.dom.ast.IFunction#getParameters() */ public List getParameters() { + List result = null; + IASTFunctionDeclarator dtor = ( definition != null ) ? definition : declarators[0]; - IASTParameterDeclaration[] params = dtor.getParameters(); - int size = params.length; - List result = new ArrayList( size ); - if( size > 0 ){ - for( int i = 0; i < size; i++ ){ - IASTParameterDeclaration p = params[i]; - result.add( p.getDeclarator().getName().resolveBinding() ); + if (dtor instanceof IASTStandardFunctionDeclarator) { + IASTParameterDeclaration[] params = ((IASTStandardFunctionDeclarator)dtor).getParameters(); + int size = params.length; + result = new ArrayList( size ); + if( size > 0 ){ + for( int i = 0; i < size; i++ ){ + IASTParameterDeclaration p = params[i]; + result.add( p.getDeclarator().getName().resolveBinding() ); + } + } + } else if (dtor instanceof ICASTKnRFunctionDeclarator) { + IASTDeclaration[] params = ((ICASTKnRFunctionDeclarator)dtor).getParameterDeclarations(); + int size = params.length; + result = new ArrayList( size ); + if( size > 0 ){ + for( int i = 0; i < size; i++ ){ + IASTDeclaration p = params[i]; + if ( p instanceof IASTSimpleDeclaration ) { + IASTDeclarator[] decltors = ((IASTSimpleDeclaration)p).getDeclarators(); + for( int j=0; j= 0 && index < params.size() ){ + return (IBinding) params.get( index ); + } + } + } + + + for (int i=0; i 0) { // KnR C parameters were found so + // handle the declarator accordingly + parmNames = new IASTName[numKnRCParms]; + parmDeclarations = new IASTDeclaration[numKnRCParms]; + + for (int i = 0; i <= parmNames.length; i++) { + switch (LT(1)) { + case IToken.tCOMMA: + last = consume(); + seenParameter = false; + case IToken.tIDENTIFIER: + if (seenParameter) + throwBacktrack(startingOffset, last + .getEndOffset() + - startingOffset); + + parmNames[i] = createName(identifier()); + + seenParameter = true; + break; + case IToken.tRPAREN: + last = consume(); + break; + default: + break; + } + } + + // now that the parameter names are parsed, parse the + // parameter declarations + for (int i = 0; i < numKnRCParms + && LT(1) != IToken.tLBRACE; i++) { // max + // parameter + // declarations + // same as + // parameter + // name count + // (could be + // less) + try { + boolean hasValidDecltors = true; + IASTStatement stmt = parseDeclarationOrExpressionStatement(); + if (stmt instanceof IASTDeclarationStatement) { + IASTDeclaration declaration = ((IASTDeclarationStatement) stmt) + .getDeclaration(); + + if (declaration instanceof IASTSimpleDeclaration) { + IASTDeclarator[] decltors = ((IASTSimpleDeclaration) declaration) + .getDeclarators(); + for (int k = 0; k < decltors.length; k++) { + boolean decltorOk = false; + for (int j = 0; j < parmNames.length; j++) { + if (CharArrayUtils.equals( + decltors[k].getName() + .toCharArray(), + parmNames[j] + .toCharArray())) { + decltorOk = true; + break; + } + } + if (!decltorOk) + hasValidDecltors = false; + } + } + } else { + hasValidDecltors = false; + } + + if (hasValidDecltors) { + parmDeclarations[i] = ((IASTDeclarationStatement) stmt) + .getDeclaration(); + } else { + parmDeclarations[i] = createKnRCProblemDeclaration( + ((ASTNode) stmt).getLength(), + ((ASTNode) stmt).getOffset()); + } + } catch (BacktrackException b) { + parmDeclarations[i] = createKnRCProblemDeclaration( + b.getLength(), b.getOffset()); + } + } + + break overallLoop; + } + + parameterDeclarationLoop: for (;;) { + switch (LT(1)) { + case IToken.tRPAREN: + last = consume(); + finalOffset = last.getEndOffset(); + break parameterDeclarationLoop; + case IToken.tELLIPSIS: + last = consume(); + encounteredVarArgs = true; + finalOffset = last.getEndOffset(); + break; + case IToken.tCOMMA: + last = consume(); + finalOffset = last.getEndOffset(); + seenParameter = false; + break; + default: + if (seenParameter) + throwBacktrack(startingOffset, last + .getEndOffset() + - startingOffset); + IASTParameterDeclaration pd = parameterDeclaration(); + finalOffset = calculateEndOffset(pd); + if (parameters == Collections.EMPTY_LIST) + parameters = new ArrayList( + DEFAULT_PARAMETERS_LIST_SIZE); + parameters.add(pd); + seenParameter = true; + } + } + + break; + case IToken.tLBRACKET: + if (arrayMods == Collections.EMPTY_LIST) + arrayMods = new ArrayList(DEFAULT_POINTEROPS_LIST_SIZE); + consumeArrayModifiers(arrayMods); + if (!arrayMods.isEmpty()) + finalOffset = calculateEndOffset((IASTArrayModifier) arrayMods + .get(arrayMods.size() - 1)); + continue; + case IToken.tCOLON: + consume(IToken.tCOLON); + bitField = constantExpression(); + finalOffset = calculateEndOffset(bitField); + default: + break; + } + break; + } + if (LA(1).getType() != IToken.tIDENTIFIER) + break; + + } while (true); + + IASTDeclarator d = null; + if (numKnRCParms > 0) { + ICASTKnRFunctionDeclarator functionDecltor = createKnRFunctionDeclarator(); + for (int i = 0; i < parmDeclarations.length; ++i) { + if (parmDeclarations[i] != null + && !(parmDeclarations[i] instanceof IASTProblemDeclaration)) { + parmDeclarations[i].setParent(functionDecltor); + parmDeclarations[i] + .setPropertyInParent(ICASTKnRFunctionDeclarator.FUNCTION_PARAMETER); + } + } + functionDecltor.setParameterDeclarations(parmDeclarations); + functionDecltor.setParameterNames(parmNames); + if (declaratorName != null) { + functionDecltor.setName(declaratorName); + declaratorName.setParent(functionDecltor); + declaratorName + .setPropertyInParent(IASTDeclarator.DECLARATOR_NAME); + } + + for (int i = 0; i < parmNames.length; ++i) { + parmNames[i].setParent(functionDecltor); + parmNames[i] + .setPropertyInParent(ICASTKnRFunctionDeclarator.PARAMETER_NAME); + } + + d = functionDecltor; + } else if (isFunction) { + IASTStandardFunctionDeclarator fc = createFunctionDeclarator(); + fc.setVarArgs(encounteredVarArgs); + for (int i = 0; i < parameters.size(); ++i) { + IASTParameterDeclaration p = (IASTParameterDeclaration) parameters + .get(i); + p.setParent(fc); + p + .setPropertyInParent(IASTStandardFunctionDeclarator.FUNCTION_PARAMETER); + fc.addParameterDeclaration(p); + } + d = fc; + } else if (arrayMods != Collections.EMPTY_LIST) { + d = createArrayDeclarator(); + for (int i = 0; i < arrayMods.size(); ++i) { + IASTArrayModifier m = (IASTArrayModifier) arrayMods.get(i); + m.setParent(d); + m.setPropertyInParent(IASTArrayDeclarator.ARRAY_MODIFIER); + ((IASTArrayDeclarator) d).addArrayModifier(m); + } + } else if (bitField != null) { + IASTFieldDeclarator fl = createFieldDeclarator(); + fl.setBitFieldSize(bitField); + d = fl; + } else { + d = createDeclarator(); + } + for (int i = 0; i < pointerOps.size(); ++i) { + IASTPointerOperator po = (IASTPointerOperator) pointerOps.get(i); + d.addPointerOperator(po); + po.setParent(d); + po.setPropertyInParent(IASTDeclarator.POINTER_OPERATOR); + } + if (innerDecl != null) { + d.setNestedDeclarator(innerDecl); + innerDecl.setParent(d); + innerDecl.setPropertyInParent(IASTDeclarator.NESTED_DECLARATOR); + } + if (declaratorName != null) { + d.setName(declaratorName); + declaratorName.setParent(d); + declaratorName.setPropertyInParent(IASTDeclarator.DECLARATOR_NAME); + } + + ((ASTNode) d).setOffsetAndLength(startingOffset, finalOffset + - startingOffset); + return d; + } + + protected IASTArrayDeclarator createArrayDeclarator() { + return new CASTArrayDeclarator(); + } + + /** + * @return + */ + protected IASTFieldDeclarator createFieldDeclarator() { + return new CASTFieldDeclarator(); + } + + /** + * @return + */ + protected IASTStandardFunctionDeclarator createFunctionDeclarator() { + return new CASTFunctionDeclarator(); + } + + /** + * @return + */ + protected ICASTKnRFunctionDeclarator createKnRFunctionDeclarator() { + return new CASTKnRFunctionDeclarator(); + } + + /** + * @param t + * @return + */ + protected IASTName createName(IToken t) { + IASTName n = new CASTName(t.getCharImage()); + ((ASTNode) n).setOffsetAndLength(t.getOffset(), t.getEndOffset() + - t.getOffset()); + return n; + } + + /** + * @return + */ + protected IASTDeclarator createDeclarator() { + return new CASTDeclarator(); + } + + protected void consumeArrayModifiers(List arrayMods) + throws EndOfFileException, BacktrackException { + + while (LT(1) == IToken.tLBRACKET) { + //eat the '[' + int startOffset = consume(IToken.tLBRACKET).getOffset(); + + boolean isStatic = false; + boolean isConst = false; + boolean isRestrict = false; + boolean isVolatile = false; + boolean isVarSized = false; + + outerLoop: do { + switch (LT(1)) { + case IToken.t_static: + isStatic = true; + consume(); + break; + case IToken.t_const: + isConst = true; + consume(); + break; + case IToken.t_volatile: + isVolatile = true; + consume(); + break; + case IToken.t_restrict: + isRestrict = true; + consume(); + break; + case IToken.tSTAR: + isVarSized = true; + consume(); + //deliberate fall through + default: + break outerLoop; + } + } while (true); + + IASTExpression exp = null; + + if (LT(1) != IToken.tRBRACKET) { + if (!(isStatic || isRestrict || isConst || isVolatile)) + exp = assignmentExpression(); + else + exp = constantExpression(); + } + int lastOffset = consume(IToken.tRBRACKET).getEndOffset(); + + IASTArrayModifier arrayMod = null; + if (!(isStatic || isRestrict || isConst || isVolatile)) + arrayMod = createArrayModifier(); + else { + ICASTArrayModifier temp = createCArrayModifier(); + temp.setStatic(isStatic); + temp.setConst(isConst); + temp.setVolatile(isVolatile); + temp.setRestrict(isRestrict); + temp.setVariableSized(isVarSized); + arrayMod = temp; + } + ((ASTNode) arrayMod).setOffsetAndLength(startOffset, lastOffset + - startOffset); + if (exp != null) { + arrayMod.setConstantExpression(exp); + exp.setParent(arrayMod); + exp.setPropertyInParent(IASTArrayModifier.CONSTANT_EXPRESSION); + } + arrayMods.add(arrayMod); + } + } + + /** + * @return + */ + protected ICASTArrayModifier createCArrayModifier() { + return new CASTModifiedArrayModifier(); + } + + /** + * @return + */ + protected IASTArrayModifier createArrayModifier() { + return new CASTArrayModifier(); + } + + protected IASTParameterDeclaration parameterDeclaration() + throws BacktrackException, EndOfFileException { + IToken current = LA(1); + int startingOffset = current.getOffset(); + IASTDeclSpecifier declSpec = declSpecifierSeq(true); + + IASTDeclarator declarator = null; + if (LT(1) != IToken.tSEMI) + declarator = initDeclarator(); + + if (current == LA(1)) + throwBacktrack(current.getOffset(), figureEndOffset(declSpec, + declarator) + - current.getOffset()); + + IASTParameterDeclaration result = createParameterDeclaration(); + ((ASTNode) result).setOffsetAndLength(startingOffset, figureEndOffset( + declSpec, declarator) + - startingOffset); + result.setDeclSpecifier(declSpec); + declSpec.setParent(result); + declSpec.setPropertyInParent(IASTParameterDeclaration.DECL_SPECIFIER); + result.setDeclarator(declarator); + declarator.setParent(result); + declarator.setPropertyInParent(IASTParameterDeclaration.DECLARATOR); + return result; + } + + /** + * @return + */ + protected IASTParameterDeclaration createParameterDeclaration() { + return new CASTParameterDeclaration(); + } + + /** + * @throws BacktrackException + */ + protected IASTNode forInitStatement() throws BacktrackException, + EndOfFileException { + IToken mark = mark(); + try { + IASTExpression e = expression(); + consume(IToken.tSEMI); + //TODO is this a problem? Should we wrap this in an expression + // statement? + return e; + } catch (BacktrackException bt) { + backup(mark); + try { + return simpleDeclaration(); + } catch (BacktrackException b) { + IASTProblem p = failParse(b); + IASTProblemExpression pe = createProblemExpression(); + ((CASTNode) pe).setOffsetAndLength(((CASTNode) p)); + pe.setProblem(p); + p.setParent(pe); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + return pe; + } + } + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#getTranslationUnit() + */ + protected IASTTranslationUnit getTranslationUnit() { + return translationUnit; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatement() + */ + protected IASTCompoundStatement createCompoundStatement() { + return new CASTCompoundStatement(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createBinaryExpression() + */ + protected IASTBinaryExpression createBinaryExpression() { + return new CASTBinaryExpression(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createConditionalExpression() + */ + protected IASTConditionalExpression createConditionalExpression() { + return new CASTConditionalExpression(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createUnaryExpression() + */ + protected IASTUnaryExpression createUnaryExpression() { + return new CASTUnaryExpression(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createCompoundStatementExpression() + */ + protected IGNUASTCompoundStatementExpression createCompoundStatementExpression() { + return new CASTCompoundStatementExpression(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createExpressionList() + */ + protected IASTExpressionList createExpressionList() { + return new CASTExpressionList(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.parser2.AbstractGNUSourceCodeParser#createEnumerator() + */ + protected IASTEnumerator createEnumerator() { + return new CASTEnumerator(); + } + + /** + * @return + */ + protected IASTLabelStatement createLabelStatement() { + return new CASTLabelStatement(); + } + + /** + * @return + */ + protected IASTGotoStatement createGoToStatement() { + return new CASTGotoStatement(); + } + + /** + * @return + */ + protected IASTReturnStatement createReturnStatement() { + return new CASTReturnStatement(); + } + + /** + * @return + */ + protected IASTForStatement createForStatement() { + return new CASTForStatement(); + } + + /** + * @return + */ + protected IASTContinueStatement createContinueStatement() { + return new CASTContinueStatement(); + } + + /** + * @return + */ + protected IASTDoStatement createDoStatement() { + return new CASTDoStatement(); + } + + /** + * @return + */ + protected IASTBreakStatement createBreakStatement() { + return new CASTBreakStatement(); + } + + /** + * @return + */ + protected IASTWhileStatement createWhileStatement() { + return new CASTWhileStatement(); + } + + /** + * @return + */ + protected IASTNullStatement createNullStatement() { + return new CASTNullStatement(); + } + + /** + * @return + */ + protected IASTSwitchStatement createSwitchStatement() { + return new CASTSwitchStatement(); + } + + /** + * @return + */ + protected IASTIfStatement createIfStatement() { + return new CASTIfStatement(); + } + + /** + * @return + */ + protected IASTDefaultStatement createDefaultStatement() { + return new CASTDefaultStatement(); + } + + /** + * @return + */ + protected IASTCaseStatement createCaseStatement() { + return new CASTCaseStatement(); + } + + /** + * @return + */ + protected IASTExpressionStatement createExpressionStatement() { + return new CASTExpressionStatement(); + } + + /** + * @return + */ + protected IASTDeclarationStatement createDeclarationStatement() { + return new CASTDeclarationStatement(); + } + + /** + * @return + */ + protected IASTASMDeclaration createASMDirective() { + return new CASTASMDeclaration(); + } + + protected IASTEnumerationSpecifier createEnumerationSpecifier() { + return new CASTEnumerationSpecifier(); + } + + /** + * @return + */ + protected IASTCastExpression createCastExpression() { + return new CASTCastExpression(); + } + + protected IASTStatement statement() throws EndOfFileException, + BacktrackException { + switch (LT(1)) { + // labeled statements + case IToken.t_case: + return parseCaseStatement(); + case IToken.t_default: + return parseDefaultStatement(); + // compound statement + case IToken.tLBRACE: + return parseCompoundStatement(); + // selection statement + case IToken.t_if: + return parseIfStatement(); + case IToken.t_switch: + return parseSwitchStatement(); + //iteration statements + case IToken.t_while: + return parseWhileStatement(); + case IToken.t_do: + return parseDoStatement(); + case IToken.t_for: + return parseForStatement(); + //jump statement + case IToken.t_break: + return parseBreakStatement(); + case IToken.t_continue: + return parseContinueStatement(); + case IToken.t_return: + return parseReturnStatement(); + case IToken.t_goto: + return parseGotoStatement(); + case IToken.tSEMI: + return parseNullStatement(); + default: + // can be many things: + // label + if (LT(1) == IToken.tIDENTIFIER && LT(2) == IToken.tCOLON) { + return parseLabelStatement(); + } + + return parseDeclarationOrExpressionStatement(); + } + + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#nullifyTranslationUnit() + */ + protected void nullifyTranslationUnit() { + translationUnit = null; + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemStatement() + */ + protected IASTProblemStatement createProblemStatement() { + return new CASTProblemStatement(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblemExpression() + */ + protected IASTProblemExpression createProblemExpression() { + return new CASTProblemExpression(); + } + + /* + * (non-Javadoc) + * + * @see org.eclipse.cdt.internal.core.dom.parser.AbstractGNUSourceCodeParser#createProblem(int, + * int, int) + */ + protected IASTProblem createProblem(int signal, int offset, int length) { + IASTProblem result = new CASTProblem(signal, EMPTY_STRING, false, true); + ((ASTNode) result).setOffsetAndLength(offset, length); + return result; + } + + private int countKnRCParms() { + IToken mark = null; + int parmCount = 0; + boolean previousWasIdentifier = false; + + try { + mark = mark(); + + // starts at the beginning of the parameter list + for (;;) { + if (LT(1) == IToken.tCOMMA) { + consume(); + previousWasIdentifier = false; + } else if (LT(1) == IToken.tIDENTIFIER) { + consume(); + if (previousWasIdentifier == true) { + backup(mark); + return 0; // i.e. KnR C won't have int f(typedef x) char + // x; {} + } + previousWasIdentifier = true; + parmCount++; + } else if (LT(1) == IToken.tRPAREN) { + consume(); + break; + } else { + backup(mark); + return 0; // i.e. KnR C won't have int f(char) char x; {} + } + } + + // if the next token is a tSEMI then the declaration was a regular + // declaration statement i.e. int f(type_def); + if (LT(1) == IToken.tSEMI) { + backup(mark); + return 0; + } + + // look ahead for the start of the function body, if end of file is + // found then return 0 parameters found (implies not KnR C) + while (LT(1) != IToken.tLBRACE) { + consume(); + } + + backup(mark); + return parmCount; + } catch (EndOfFileException eof) { + if (mark != null) + backup(mark); + + return 0; + } + } + + private IASTProblemDeclaration createKnRCProblemDeclaration(int length, + int offset) throws EndOfFileException { + IASTProblem p = createProblem(IASTProblem.SYNTAX_ERROR, offset, length); + IASTProblemDeclaration pd = createProblemDeclaration(); + pd.setProblem(p); + ((ASTNode) pd).setOffsetAndLength(((ASTNode) p).getOffset(), + ((ASTNode) p).getLength()); + p.setParent(pd); + p.setPropertyInParent(IASTProblemHolder.PROBLEM); + + // consume until LBRACE is found (to leave off at the function body and + // continue from there) + while (LT(1) != IToken.tLBRACE) + consume(); + + return pd; + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index 7ccab8046cc..22777d28719 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -16,7 +16,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import java.util.ArrayList; import java.util.List; -import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; @@ -69,7 +69,7 @@ public class CPPFunction implements IFunction { * @see org.eclipse.cdt.core.dom.ast.IFunction#getParameters() */ public List getParameters() { - IASTFunctionDeclarator dtor = ( definition != null ) ? definition : declarations[0]; + IASTStandardFunctionDeclarator dtor = ( definition != null ) ? definition : declarations[0]; IASTParameterDeclaration[] params = dtor.getParameters(); int size = params.length; List result = new ArrayList( size ); @@ -136,7 +136,7 @@ public class CPPFunction implements IFunction { if( binding != null ) return binding; - IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) param.getParent(); + IASTStandardFunctionDeclarator fdtor = (IASTStandardFunctionDeclarator) param.getParent(); IASTParameterDeclaration [] ps = fdtor.getParameters(); int i = 0; for( ; i < ps.length; i++ ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index d2258ee2096..d48b6882213 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -36,6 +36,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; +import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -742,13 +743,15 @@ public class CPPSemantics { } if( checkAux ) { //check the parameters - IASTParameterDeclaration [] parameters = declarator.getParameters(); - for( int i = 0; i < parameters.length; i++ ){ - IASTParameterDeclaration parameterDeclaration = parameters[i]; - if( parameterDeclaration == null ) break; - declName = parameterDeclaration.getDeclarator().getName(); - if( CharArrayUtils.equals( declName.toCharArray(), data.name ) ){ - return declName; + if ( declarator instanceof IASTStandardFunctionDeclarator ) { + IASTParameterDeclaration [] parameters = ((IASTStandardFunctionDeclarator)declarator).getParameters(); + for( int i = 0; i < parameters.length; i++ ){ + IASTParameterDeclaration parameterDeclaration = parameters[i]; + if( parameterDeclaration == null ) break; + declName = parameterDeclaration.getDeclarator().getName(); + if( CharArrayUtils.equals( declName.toCharArray(), data.name ) ){ + return declName; + } } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index ec7adab3df5..265c7b2e990 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -41,6 +41,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFieldReference; import org.eclipse.cdt.core.dom.ast.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTGotoStatement; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; @@ -310,7 +311,7 @@ public class CPPVisitor { } } else if( parent instanceof IASTParameterDeclaration ){ IASTParameterDeclaration param = (IASTParameterDeclaration) parent; - IASTFunctionDeclarator fDtor = (IASTFunctionDeclarator) param.getParent(); + IASTStandardFunctionDeclarator fDtor = (IASTStandardFunctionDeclarator) param.getParent(); IFunction function = (IFunction) fDtor.getName().resolveBinding(); binding = ((CPPFunction) function).resolveParameter( param ); } else if( parent instanceof IASTSimpleDeclaration ){ @@ -460,8 +461,8 @@ public class CPPVisitor { */ public static IScope getContainingScope(IASTParameterDeclaration parameterDeclaration) { IASTNode parent = parameterDeclaration.getParent(); - if( parent instanceof IASTFunctionDeclarator ){ - IASTFunctionDeclarator functionDeclarator = (IASTFunctionDeclarator) parent; + if( parent instanceof IASTStandardFunctionDeclarator ){ + IASTStandardFunctionDeclarator functionDeclarator = (IASTStandardFunctionDeclarator) parent; if( functionDeclarator.getNestedDeclarator() != null ){ return getContainingScope( functionDeclarator ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java index 9490217e677..ed3823eb89a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java @@ -41,7 +41,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFieldReference; import org.eclipse.cdt.core.dom.ast.IASTForStatement; import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression; -import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTGotoStatement; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; @@ -2613,7 +2613,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset); IASTDeclarator declarator = (IASTDeclarator) declarators.get(0); - if (!(declarator instanceof IASTFunctionDeclarator)) + if (!(declarator instanceof IASTStandardFunctionDeclarator)) throwBacktrack(firstOffset, LA(1).getEndOffset() - firstOffset); if (!constructorChain.isEmpty() @@ -2635,7 +2635,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { declSpec.setParent(funcDefinition); declSpec.setPropertyInParent(IASTFunctionDefinition.DECL_SPECIFIER); - funcDefinition.setDeclarator((IASTFunctionDeclarator) declarator); + funcDefinition.setDeclarator((IASTStandardFunctionDeclarator) declarator); declarator.setParent(funcDefinition); declarator.setPropertyInParent(IASTFunctionDefinition.DECLARATOR); @@ -3670,7 +3670,7 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser { IASTParameterDeclaration p = (IASTParameterDeclaration) parameters .get(i); p.setParent(fc); - p.setPropertyInParent(IASTFunctionDeclarator.FUNCTION_PARAMETER); + p.setPropertyInParent(IASTStandardFunctionDeclarator.FUNCTION_PARAMETER); fc.addParameterDeclaration(p); } fc.setConst(isConst);