mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-08 18:26:01 +02:00
Fixed Bug 39677 - Statements in expressions are not supported (GCC)
This commit is contained in:
parent
defd110486
commit
ad54f46853
9 changed files with 133 additions and 10 deletions
|
@ -38,10 +38,7 @@ public class ASTFailedTests extends BaseASTTest
|
||||||
{
|
{
|
||||||
assertCodeFailsParse("struct { int e1, e2; } v = { e2: 0 }");
|
assertCodeFailsParse("struct { int e1, e2; } v = { e2: 0 }");
|
||||||
}
|
}
|
||||||
public void testBug39677() throws Exception
|
|
||||||
{
|
|
||||||
assertCodeFailsParse("B::B() : a(({ 1; })) {}");
|
|
||||||
}
|
|
||||||
|
|
||||||
public void testBug39679() throws Exception
|
public void testBug39679() throws Exception
|
||||||
{
|
{
|
||||||
|
|
|
@ -37,7 +37,6 @@ public class GCCCompleteParseExtensionsTest extends CompleteParseBaseTest {
|
||||||
*/
|
*/
|
||||||
public GCCCompleteParseExtensionsTest() {
|
public GCCCompleteParseExtensionsTest() {
|
||||||
super();
|
super();
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -45,7 +44,6 @@ public class GCCCompleteParseExtensionsTest extends CompleteParseBaseTest {
|
||||||
*/
|
*/
|
||||||
public GCCCompleteParseExtensionsTest(String name) {
|
public GCCCompleteParseExtensionsTest(String name) {
|
||||||
super(name);
|
super(name);
|
||||||
// TODO Auto-generated constructor stub
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void testBug39695() throws Exception
|
public void testBug39695() throws Exception
|
||||||
|
@ -189,4 +187,25 @@ public class GCCCompleteParseExtensionsTest extends CompleteParseBaseTest {
|
||||||
code.write("}\n"); //$NON-NLS-1$
|
code.write("}\n"); //$NON-NLS-1$
|
||||||
parse(code.toString());
|
parse(code.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBug39677() throws Exception
|
||||||
|
{
|
||||||
|
parse("class B { public: B(); int a;}; B::B() : a(({ 1; })) {}"); //$NON-NLS-1$
|
||||||
|
Writer writer = new StringWriter();
|
||||||
|
writer.write( "B::B() : a(( { int y = foo (); int z;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "else z = - y;\n" );//$NON-NLS-1$
|
||||||
|
writer.write( "z; }))\n" );//$NON-NLS-1$
|
||||||
|
parse( writer.toString() );
|
||||||
|
writer = new StringWriter();
|
||||||
|
writer.write( "int x = ({ int y = foo (); int z;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "else z = - y;\n" );//$NON-NLS-1$
|
||||||
|
writer.write( "z; });\n" );//$NON-NLS-1$
|
||||||
|
writer = new StringWriter();
|
||||||
|
writer.write( "typeof({ int y = foo (); int z;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "else z = - y;\n" );//$NON-NLS-1$
|
||||||
|
writer.write( "z; }) zoot;\n" );//$NON-NLS-1$
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -129,4 +129,25 @@ public class GCCQuickParseExtensionsTest extends BaseASTTest {
|
||||||
code.write("}\n"); //$NON-NLS-1$
|
code.write("}\n"); //$NON-NLS-1$
|
||||||
parse(code.toString());
|
parse(code.toString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void testBug39677() throws Exception
|
||||||
|
{
|
||||||
|
parse("B::B() : a(({ 1; })) {}"); //$NON-NLS-1$
|
||||||
|
Writer writer = new StringWriter();
|
||||||
|
writer.write( "B::B() : a(( { int y = foo (); int z;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "else z = - y;\n" );//$NON-NLS-1$
|
||||||
|
writer.write( "z; }))\n" );//$NON-NLS-1$
|
||||||
|
parse( writer.toString() );
|
||||||
|
writer = new StringWriter();
|
||||||
|
writer.write( "int x = ({ int y = foo (); int z;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "else z = - y;\n" );//$NON-NLS-1$
|
||||||
|
writer.write( "z; });\n" );//$NON-NLS-1$
|
||||||
|
writer = new StringWriter();
|
||||||
|
writer.write( "typeof({ int y = foo (); int z;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "if (y > 0) z = y;\n" ); //$NON-NLS-1$
|
||||||
|
writer.write( "else z = - y;\n" );//$NON-NLS-1$
|
||||||
|
writer.write( "z; }) zoot;\n" );//$NON-NLS-1$
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,6 +26,7 @@ public interface IASTGCCExpression extends IASTExpression {
|
||||||
public static final Kind UNARY_TYPEOF_TYPEID = new Kind( LAST_KIND + 4 );
|
public static final Kind UNARY_TYPEOF_TYPEID = new Kind( LAST_KIND + 4 );
|
||||||
public static final Kind RELATIONAL_MAX = new Kind( LAST_KIND + 5 );
|
public static final Kind RELATIONAL_MAX = new Kind( LAST_KIND + 5 );
|
||||||
public static final Kind RELATIONAL_MIN = new Kind( LAST_KIND + 6 );
|
public static final Kind RELATIONAL_MIN = new Kind( LAST_KIND + 6 );
|
||||||
|
public static final Kind STATEMENT_EXPRESSION = new Kind( LAST_KIND + 7 );
|
||||||
|
|
||||||
protected Kind( int kind )
|
protected Kind( int kind )
|
||||||
{
|
{
|
||||||
|
|
|
@ -18,6 +18,7 @@ import org.eclipse.cdt.core.parser.ast.IASTDesignator;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTExpression;
|
import org.eclipse.cdt.core.parser.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTScope;
|
import org.eclipse.cdt.core.parser.ast.IASTScope;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind;
|
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind;
|
||||||
import org.eclipse.cdt.internal.core.parser.DeclarationWrapper;
|
import org.eclipse.cdt.internal.core.parser.DeclarationWrapper;
|
||||||
import org.eclipse.cdt.internal.core.parser.IParserData;
|
import org.eclipse.cdt.internal.core.parser.IParserData;
|
||||||
import org.eclipse.cdt.internal.core.parser.Parser;
|
import org.eclipse.cdt.internal.core.parser.Parser;
|
||||||
|
@ -67,4 +68,12 @@ public interface IParserExtension {
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
public IASTDesignator parseDesignator(IParserData parserData, IASTScope scope);
|
public IASTDesignator parseDesignator(IParserData parserData, IASTScope scope);
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public boolean supportsStatementsInExpressions();
|
||||||
|
/**
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Kind getExpressionKindForStatement();
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,7 @@ import org.eclipse.cdt.core.parser.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTScope;
|
import org.eclipse.cdt.core.parser.ast.IASTScope;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTTypeId;
|
import org.eclipse.cdt.core.parser.ast.IASTTypeId;
|
||||||
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind;
|
import org.eclipse.cdt.core.parser.ast.IASTCompletionNode.CompletionKind;
|
||||||
|
import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind;
|
||||||
import org.eclipse.cdt.core.parser.ast.gcc.IASTGCCDesignator;
|
import org.eclipse.cdt.core.parser.ast.gcc.IASTGCCDesignator;
|
||||||
import org.eclipse.cdt.core.parser.ast.gcc.IASTGCCExpression;
|
import org.eclipse.cdt.core.parser.ast.gcc.IASTGCCExpression;
|
||||||
import org.eclipse.cdt.core.parser.ast.gcc.IASTGCCSimpleTypeSpecifier;
|
import org.eclipse.cdt.core.parser.ast.gcc.IASTGCCSimpleTypeSpecifier;
|
||||||
|
@ -448,4 +449,18 @@ public class GCCParserExtension implements IParserExtension {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.core.parser.extension.IParserExtension#supportsStatementsInExpressions()
|
||||||
|
*/
|
||||||
|
public boolean supportsStatementsInExpressions() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* (non-Javadoc)
|
||||||
|
* @see org.eclipse.cdt.core.parser.extension.IParserExtension#getExpressionKindForStatement()
|
||||||
|
*/
|
||||||
|
public Kind getExpressionKindForStatement() {
|
||||||
|
return IASTGCCExpression.Kind.STATEMENT_EXPRESSION;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -804,6 +804,16 @@ public class Parser implements IParserData, IParser
|
||||||
int startingOffset = la.getOffset();
|
int startingOffset = la.getOffset();
|
||||||
int ln = la.getLineNumber();
|
int ln = la.getLineNumber();
|
||||||
char [] fn = la.getFilename();
|
char [] fn = la.getFilename();
|
||||||
|
|
||||||
|
IASTExpression resultExpression = null;
|
||||||
|
if( la.getType() == IToken.tLPAREN && LT(2) == IToken.tLBRACE && extension.supportsStatementsInExpressions() )
|
||||||
|
{
|
||||||
|
resultExpression = compoundStatementExpression(scope, la, resultExpression);
|
||||||
|
}
|
||||||
|
|
||||||
|
if( resultExpression != null )
|
||||||
|
return resultExpression;
|
||||||
|
|
||||||
IASTExpression assignmentExpression = assignmentExpression(scope, kind,
|
IASTExpression assignmentExpression = assignmentExpression(scope, kind,
|
||||||
key);
|
key);
|
||||||
while (LT(1) == IToken.tCOMMA) {
|
while (LT(1) == IToken.tCOMMA) {
|
||||||
|
@ -828,6 +838,52 @@ public class Parser implements IParserData, IParser
|
||||||
return assignmentExpression;
|
return assignmentExpression;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param scope
|
||||||
|
* @param la
|
||||||
|
* @param resultExpression
|
||||||
|
* @return
|
||||||
|
* @throws EndOfFileException
|
||||||
|
* @throws BacktrackException
|
||||||
|
*/
|
||||||
|
private IASTExpression compoundStatementExpression(IASTScope scope, IToken la, IASTExpression resultExpression) throws EndOfFileException, BacktrackException {
|
||||||
|
int startingOffset = la.getOffset();
|
||||||
|
int ln = la.getLineNumber();
|
||||||
|
char [] fn = la.getFilename();
|
||||||
|
consume( IToken.tLPAREN );
|
||||||
|
try
|
||||||
|
{
|
||||||
|
if( mode == ParserMode.QUICK_PARSE || mode == ParserMode.STRUCTURAL_PARSE )
|
||||||
|
skipOverCompoundStatement();
|
||||||
|
else if( mode == ParserMode.COMPLETION_PARSE || mode == ParserMode.SELECTION_PARSE )
|
||||||
|
{
|
||||||
|
if( scanner.isOnTopContext() )
|
||||||
|
compoundStatement(scope, true);
|
||||||
|
else
|
||||||
|
skipOverCompoundStatement();
|
||||||
|
}
|
||||||
|
else if( mode == ParserMode.COMPLETE_PARSE )
|
||||||
|
compoundStatement(scope, true);
|
||||||
|
|
||||||
|
consume( IToken.tRPAREN );
|
||||||
|
try
|
||||||
|
{
|
||||||
|
resultExpression = astFactory.createExpression( scope, extension.getExpressionKindForStatement(), null, null, null, null, null,EMPTY_STRING, null );
|
||||||
|
}
|
||||||
|
catch (ASTSemanticException e) {
|
||||||
|
throwBacktrack(e.getProblem());
|
||||||
|
} catch (Exception e) {
|
||||||
|
logException("expression::createExpression()", e); //$NON-NLS-1$
|
||||||
|
throwBacktrack(startingOffset, lastToken != null ? lastToken.getEndOffset() : 0 , ln, fn);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch( BacktrackException bte )
|
||||||
|
{
|
||||||
|
backup( la );
|
||||||
|
}
|
||||||
|
return resultExpression;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @param expression
|
* @param expression
|
||||||
* @throws BacktrackException
|
* @throws BacktrackException
|
||||||
|
@ -839,6 +895,7 @@ public class Parser implements IParserData, IParser
|
||||||
if (LT(1) == IToken.t_throw) {
|
if (LT(1) == IToken.t_throw) {
|
||||||
return throwExpression(scope, key);
|
return throwExpression(scope, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
IASTExpression conditionalExpression = conditionalExpression(scope,
|
IASTExpression conditionalExpression = conditionalExpression(scope,
|
||||||
kind, key);
|
kind, key);
|
||||||
// if the condition not taken, try assignment operators
|
// if the condition not taken, try assignment operators
|
||||||
|
@ -936,7 +993,7 @@ public class Parser implements IParserData, IParser
|
||||||
int startingOffset = la.getOffset();
|
int startingOffset = la.getOffset();
|
||||||
int ln = la.getLineNumber();
|
int ln = la.getLineNumber();
|
||||||
char [] fn = la.getFilename();
|
char [] fn = la.getFilename();
|
||||||
la = null;
|
|
||||||
IASTExpression firstExpression = logicalOrExpression(scope, kind, key);
|
IASTExpression firstExpression = logicalOrExpression(scope, kind, key);
|
||||||
if (LT(1) == IToken.tQUESTION) {
|
if (LT(1) == IToken.tQUESTION) {
|
||||||
consume(IToken.tQUESTION);
|
consume(IToken.tQUESTION);
|
||||||
|
@ -4159,6 +4216,7 @@ public class Parser implements IParserData, IParser
|
||||||
consume(IToken.tLPAREN);
|
consume(IToken.tLPAREN);
|
||||||
IASTExpression expressionList = null;
|
IASTExpression expressionList = null;
|
||||||
|
|
||||||
|
if( LT(1) != IToken.tRPAREN )
|
||||||
expressionList = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION);
|
expressionList = expression(scope, CompletionKind.SINGLE_NAME_REFERENCE, KeywordSetKey.EXPRESSION);
|
||||||
|
|
||||||
IToken rparen = consume(IToken.tRPAREN);
|
IToken rparen = consume(IToken.tRPAREN);
|
||||||
|
|
|
@ -1761,7 +1761,7 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto
|
||||||
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_XOR)
|
|| (kind == IASTExpression.Kind.ASSIGNMENTEXPRESSION_XOR)
|
||||||
){
|
){
|
||||||
ASTExpression left = (ASTExpression)lhs;
|
ASTExpression left = (ASTExpression)lhs;
|
||||||
if(left != null){
|
if(left != null && left.getResultType() != null ){
|
||||||
info =left.getResultType().getResult();
|
info =left.getResultType().getResult();
|
||||||
} else
|
} else
|
||||||
handleProblem( scope, IProblem.SEMANTIC_MALFORMED_EXPRESSION, null );
|
handleProblem( scope, IProblem.SEMANTIC_MALFORMED_EXPRESSION, null );
|
||||||
|
|
|
@ -40,6 +40,7 @@ import org.eclipse.cdt.internal.core.parser.DeclarationWrapper;
|
||||||
import org.eclipse.cdt.internal.core.parser.Declarator;
|
import org.eclipse.cdt.internal.core.parser.Declarator;
|
||||||
import org.eclipse.cdt.internal.core.parser.ast.GCCASTExtension;
|
import org.eclipse.cdt.internal.core.parser.ast.GCCASTExtension;
|
||||||
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTBinaryExpression;
|
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTBinaryExpression;
|
||||||
|
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTEmptyExpression;
|
||||||
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTypeIdExpression;
|
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTypeIdExpression;
|
||||||
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTUnaryExpression;
|
import org.eclipse.cdt.internal.core.parser.ast.complete.ASTUnaryExpression;
|
||||||
import org.eclipse.cdt.internal.core.parser.ast.complete.ExpressionFactory;
|
import org.eclipse.cdt.internal.core.parser.ast.complete.ExpressionFactory;
|
||||||
|
@ -114,6 +115,8 @@ public class GCCASTCompleteExtension extends GCCASTExtension {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
else if( kind == IASTGCCExpression.Kind.STATEMENT_EXPRESSION )
|
||||||
|
return new ASTEmptyExpression( kind, references );
|
||||||
else if( lhs != null &&
|
else if( lhs != null &&
|
||||||
(kind == IASTGCCExpression.Kind.UNARY_ALIGNOF_UNARYEXPRESSION ||
|
(kind == IASTGCCExpression.Kind.UNARY_ALIGNOF_UNARYEXPRESSION ||
|
||||||
kind == IASTGCCExpression.Kind.UNARY_TYPEOF_UNARYEXPRESSION) )
|
kind == IASTGCCExpression.Kind.UNARY_TYPEOF_UNARYEXPRESSION) )
|
||||||
|
|
Loading…
Add table
Reference in a new issue