diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index 9c9fa3f5230..56c4cd6133e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; +import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; @@ -44,6 +45,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTypeId; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -104,15 +106,15 @@ import org.eclipse.cdt.internal.core.parser.ParserException; public class AST2CPPTests extends AST2BaseTest { -// public void testBug102825() throws Exception { -// StringBuffer buffer = new StringBuffer("#define CURLOPTTYPE_OBJECTPOINT 10000\n" ); //$NON-NLS-1$ -// buffer.append("#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number\n" ); //$NON-NLS-1$ -// buffer.append("typedef enum {\n" ); //$NON-NLS-1$ -// buffer.append("CINIT(FILE, OBJECTPOINT, 1),\n" ); //$NON-NLS-1$ -// buffer.append(" CINIT(URL, OBJECTPOINT, 2)\n" ); //$NON-NLS-1$ -// buffer.append("} CURLoption ;\n" ); //$NON-NLS-1$ -// parseAndCheckBindings(buffer.toString()); -// } + public void testBug102825() throws Exception { + StringBuffer buffer = new StringBuffer("#define CURLOPTTYPE_OBJECTPOINT 10000\n" ); //$NON-NLS-1$ + buffer.append("#define CINIT(name,type,number) CURLOPT_ ## name = CURLOPTTYPE_ ## type + number\n" ); //$NON-NLS-1$ + buffer.append("typedef enum {\n" ); //$NON-NLS-1$ + buffer.append("CINIT(FILE, OBJECTPOINT, 1),\n" ); //$NON-NLS-1$ + buffer.append(" CINIT(URL, OBJECTPOINT, 2)\n" ); //$NON-NLS-1$ + buffer.append("} CURLoption ;\n" ); //$NON-NLS-1$ + parseAndCheckBindings(buffer.toString()); + } public void testBug78883() throws Exception { StringBuffer buffer = new StringBuffer("class B {\n"); //$NON-NLS-1$ @@ -5072,4 +5074,17 @@ public class AST2CPPTests extends AST2BaseTest { assertSame( i, col.getName(16).resolveBinding() ); } + public void test1043290() throws Exception { + StringBuffer buffer = new StringBuffer( "int f() { "); //$NON-NLS-1$ + buffer.append( "int x = 4; while( x < 10 ) blah: ++x; "); //$NON-NLS-1$ + buffer.append( "}"); //$NON-NLS-1$ + IASTTranslationUnit tu = parseAndCheckBindings(buffer.toString() ); + IASTFunctionDefinition fd = (IASTFunctionDefinition) tu.getDeclarations()[0]; + IASTStatement [] statements = ((IASTCompoundStatement)fd.getBody()).getStatements(); + IASTWhileStatement whileStmt = (IASTWhileStatement) statements[1]; + IASTLabelStatement labelStmt = (IASTLabelStatement) whileStmt.getBody(); + assertTrue( labelStmt.getNestedStatement() instanceof IASTExpressionStatement ); + IASTExpressionStatement es = (IASTExpressionStatement) labelStmt.getNestedStatement(); + assertTrue( es.getExpression() instanceof IASTUnaryExpression ); + } } 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 afa0ba27ea6..9bcfa335a70 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 @@ -34,6 +34,7 @@ import org.eclipse.cdt.core.dom.ast.IASTIfStatement; import org.eclipse.cdt.core.dom.ast.IASTInitializer; import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression; import org.eclipse.cdt.core.dom.ast.IASTInitializerList; +import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier; @@ -48,6 +49,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement; import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; +import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; import org.eclipse.cdt.core.dom.ast.IArrayType; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; @@ -3320,4 +3322,18 @@ public class AST2Tests extends AST2BaseTest { assertEquals( fd.getDeclSpecifier().getRawSignature(), "enum COLOR"); //$NON-NLS-1$ } + + public void test1043290() throws Exception { + StringBuffer buffer = new StringBuffer( "int f() { "); //$NON-NLS-1$ + buffer.append( "int x = 4; while( x < 10 ) blah: ++x; "); //$NON-NLS-1$ + buffer.append( "}"); //$NON-NLS-1$ + IASTTranslationUnit tu = parseAndCheckBindings(buffer.toString() ); + IASTFunctionDefinition fd = (IASTFunctionDefinition) tu.getDeclarations()[0]; + IASTStatement [] statements = ((IASTCompoundStatement)fd.getBody()).getStatements(); + IASTWhileStatement whileStmt = (IASTWhileStatement) statements[1]; + IASTLabelStatement labelStmt = (IASTLabelStatement) whileStmt.getBody(); + assertTrue( labelStmt.getNestedStatement() instanceof IASTExpressionStatement ); + IASTExpressionStatement es = (IASTExpressionStatement) labelStmt.getNestedStatement(); + assertTrue( es.getExpression() instanceof IASTUnaryExpression ); + } } \ No newline at end of file diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMSelectionParseTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMSelectionParseTest.java index db7893c9b79..b93a54581cf 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMSelectionParseTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/DOMSelectionParseTest.java @@ -465,7 +465,7 @@ public class DOMSelectionParseTest extends DOMSelectionParseBaseTest { assertTrue( node instanceof IASTName ); assertTrue( ((IASTName)node).resolveBinding() instanceof ICPPClassType ); assertEquals( ((IASTName)node).toString(), "Squaw" ); //$NON-NLS-1$ - assertEquals( ((ICPPClassType)((IASTName)node).resolveBinding()).getKey(), ICPPClassType.k_union ); + assertEquals( ((ICPPClassType)((IASTName)node).resolveBinding()).getKey(), ICompositeType.k_union ); IASTName[] decls = getDeclarationOffTU((IASTName)node); assertEquals(decls.length, 1); assertEquals( decls[0].toString(), "Squaw" ); //$NON-NLS-1$ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTLabelStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTLabelStatement.java index 9af78a13988..e7e956e233b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTLabelStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTLabelStatement.java @@ -18,6 +18,7 @@ package org.eclipse.cdt.core.dom.ast; public interface IASTLabelStatement extends IASTStatement, IASTNameOwner { public static final ASTNodeProperty NAME = new ASTNodeProperty("IASTLabelStatement.NAME - name for IASTLabelStatement"); //$NON-NLS-1$ + public static final ASTNodeProperty NESTED_STATEMENT = new ASTNodeProperty( "IASTLabelStatement.NESTED_STATEMENT - statement for IASTLabelStatement" ); //$NON-NLS-1$ /** * The name for the label. The name resolves to an ILabel binding. @@ -33,4 +34,13 @@ public interface IASTLabelStatement extends IASTStatement, IASTNameOwner { */ public void setName(IASTName name); + /** + * @return + */ + public IASTStatement getNestedStatement(); + /** + * @param s + */ + public void setNestedStatement( IASTStatement s ); + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java index e0e048242d7..74edec59c48 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java @@ -1684,14 +1684,21 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser { protected IASTStatement parseLabelStatement() throws EndOfFileException, BacktrackException { IToken labelName = consume(IToken.tIDENTIFIER); - int lastOffset = consume(IToken.tCOLON).getEndOffset(); + consume(IToken.tCOLON); + IASTStatement nestedStatement = statement(); + int lastOffset = calculateEndOffset( nestedStatement ); IASTLabelStatement label_statement = createLabelStatement(); ((ASTNode) label_statement).setOffsetAndLength(labelName.getOffset(), lastOffset - labelName.getOffset()); + IASTName name = createName(labelName); label_statement.setName(name); name.setParent(label_statement); name.setPropertyInParent(IASTLabelStatement.NAME); + + label_statement.setNestedStatement( nestedStatement ); + nestedStatement.setParent( label_statement ); + nestedStatement.setPropertyInParent( IASTLabelStatement.NESTED_STATEMENT ); return label_statement; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLabelStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLabelStatement.java index bb4329963b9..58d7fc44427 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLabelStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTLabelStatement.java @@ -13,13 +13,17 @@ package org.eclipse.cdt.internal.core.dom.parser.c; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTStatement; +import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** * @author jcamelon */ -public class CASTLabelStatement extends CASTNode implements IASTLabelStatement { +public class CASTLabelStatement extends CASTNode implements IASTLabelStatement, IASTAmbiguityParent { private IASTName name; + private IASTStatement nestedStatement; /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTLabelStatement#getName() @@ -44,6 +48,7 @@ public class CASTLabelStatement extends CASTNode implements IASTLabelStatement { } } if( name != null ) if( !name.accept( action ) ) return false; + if( nestedStatement != null ) if( !nestedStatement.accept( action ) ) return false; return true; } @@ -54,4 +59,22 @@ public class CASTLabelStatement extends CASTNode implements IASTLabelStatement { if( n == name ) return r_declaration; return r_unclear; } + + public IASTStatement getNestedStatement() { + return nestedStatement; + } + + public void setNestedStatement(IASTStatement s) { + nestedStatement = s; + } + + public void replace(IASTNode child, IASTNode other) { + if( child == nestedStatement ) + { + other.setParent( this ); + other.setPropertyInParent( child.getPropertyInParent() ); + setNestedStatement((IASTStatement) other); + } + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLabelStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLabelStatement.java index bd5a385973f..0f949b88c61 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLabelStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTLabelStatement.java @@ -13,13 +13,17 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTLabelStatement; import org.eclipse.cdt.core.dom.ast.IASTName; +import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTStatement; +import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; /** * @author jcamelon */ public class CPPASTLabelStatement extends CPPASTNode implements - IASTLabelStatement { + IASTLabelStatement, IASTAmbiguityParent { private IASTName name; + private IASTStatement nestedStatement; /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IASTLabelStatement#getName() @@ -44,6 +48,7 @@ public class CPPASTLabelStatement extends CPPASTNode implements } } if( name != null ) if( !name.accept( action ) ) return false; + if( nestedStatement != null ) if( !nestedStatement.accept( action ) ) return false; return true; } @@ -54,4 +59,22 @@ public class CPPASTLabelStatement extends CPPASTNode implements if( n == name ) return r_declaration; return r_unclear; } + + public IASTStatement getNestedStatement() { + return nestedStatement; + } + + public void setNestedStatement(IASTStatement s) { + nestedStatement = s; + } + + public void replace(IASTNode child, IASTNode other) { + if( child == nestedStatement ) + { + other.setParent( this ); + other.setPropertyInParent( child.getPropertyInParent() ); + setNestedStatement((IASTStatement) other); + } + + } } 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 8bcb7574830..0608804cd4f 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 @@ -208,7 +208,7 @@ public class CPPVisitor { } private static IBinding createBinding( IASTGotoStatement gotoStatement ) { - ICPPFunctionScope functionScope = (ICPPFunctionScope) getContainingScope( gotoStatement ); + ICPPFunctionScope functionScope = (ICPPFunctionScope) getContainingScope( gotoStatement.getName() ); IASTName name = gotoStatement.getName(); IBinding binding; try { @@ -225,7 +225,7 @@ public class CPPVisitor { } private static IBinding createBinding( IASTLabelStatement labelStatement ) { - ICPPFunctionScope functionScope = (ICPPFunctionScope) getContainingScope( labelStatement ); + ICPPFunctionScope functionScope = (ICPPFunctionScope) getContainingScope( labelStatement.getName() ); IASTName name = labelStatement.getName(); IBinding binding; try { @@ -819,6 +819,12 @@ public class CPPVisitor { if( type instanceof ICPPClassType ){ return ((ICPPClassType) type).getCompositeScope(); } + } else if( parent instanceof IASTGotoStatement || parent instanceof IASTLabelStatement ){ + while( !(parent instanceof IASTFunctionDefinition) ){ + parent = parent.getParent(); + } + IASTFunctionDefinition fdef = (IASTFunctionDefinition) parent; + return ((ICPPASTFunctionDeclarator)fdef.getDeclarator()).getFunctionScope(); } } catch( DOMException e ){ IProblemBinding problem = e.getProblem(); @@ -855,13 +861,7 @@ public class CPPVisitor { return getContainingScope( name ); } - if( statement instanceof IASTGotoStatement || statement instanceof IASTLabelStatement ){ - while( !(parent instanceof IASTFunctionDefinition) ){ - parent = parent.getParent(); - } - IASTFunctionDefinition fdef = (IASTFunctionDefinition) parent; - return ((ICPPASTFunctionDeclarator)fdef.getDeclarator()).getFunctionScope(); - } + if( scope == null ) return getContainingScope( parent );