diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java index a5688da4f6e..eb1bca81bab 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/CompleteParseASTTest.java @@ -18,6 +18,7 @@ import org.eclipse.cdt.core.parser.ParserLanguage; import org.eclipse.cdt.core.parser.ast.ASTAccessVisibility; import org.eclipse.cdt.core.parser.ast.ASTClassKind; import org.eclipse.cdt.core.parser.ast.ASTPointerOperator; +import org.eclipse.cdt.core.parser.ast.ASTUtil; import org.eclipse.cdt.core.parser.ast.IASTASMDefinition; import org.eclipse.cdt.core.parser.ast.IASTAbstractTypeSpecifierDeclaration; import org.eclipse.cdt.core.parser.ast.IASTBaseSpecifier; @@ -27,6 +28,7 @@ import org.eclipse.cdt.core.parser.ast.IASTCodeScope; import org.eclipse.cdt.core.parser.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.parser.ast.IASTEnumerationSpecifier; import org.eclipse.cdt.core.parser.ast.IASTEnumerator; +import org.eclipse.cdt.core.parser.ast.IASTExpression; import org.eclipse.cdt.core.parser.ast.IASTField; import org.eclipse.cdt.core.parser.ast.IASTFunction; import org.eclipse.cdt.core.parser.ast.IASTLinkageSpecification; @@ -1559,7 +1561,9 @@ public class CompleteParseASTTest extends CompleteParseBaseTest Iterator i = parse("int a = __alignof__ (int);").getDeclarations(); //$NON-NLS-1$ IASTVariable a = (IASTVariable) i.next(); assertFalse( i.hasNext() ); - assertEquals( a.getInitializerClause().getAssigmentExpression().getExpressionKind(), IASTGCCExpression.Kind.UNARY_ALIGNOF_TYPEID ); + IASTExpression exp = a.getInitializerClause().getAssigmentExpression(); + assertEquals( exp.getExpressionKind(), IASTGCCExpression.Kind.UNARY_ALIGNOF_TYPEID ); + assertEquals( exp.toString(), "__alignof__(int)"); } public void testBug39684() throws Exception @@ -1590,11 +1594,17 @@ public class CompleteParseASTTest extends CompleteParseBaseTest public void testBug39698A() throws Exception { - parse("int c = a ? b;"); //$NON-NLS-1$ + Iterator i = parse("int c = a >? b;").getDeclarations(); //$NON-NLS-1$ + IASTVariable c = (IASTVariable) i.next(); + IASTExpression exp = c.getInitializerClause().getAssigmentExpression(); + assertEquals( ASTUtil.getExpressionString( exp ), "a >? b" ); } public void testULong() throws Exception diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/ASTUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/ASTUtil.java index 797d79cd7ae..acf30a2767f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/ASTUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/ASTUtil.java @@ -264,7 +264,17 @@ public class ASTUtil { } public static final String EMPTY_STRING = ""; //$NON-NLS-1$ + /** + * Return a string for the given expression. Expressions having an extension kind should + * provide their own toString method which will be called by this. + * @param expression + * @return + */ public static String getExpressionString( IASTExpression expression ){ + + if( expression.getExpressionKind().isExtensionKind() ) + return expression.toString(); + String literal = expression.getLiteralString(); String idExpression = expression.getIdExpression(); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTExpression.java index 3ad3b136e5f..839e1a0e9db 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/ast/IASTExpression.java @@ -122,6 +122,10 @@ public interface IASTExpression extends ISourceElementCallbackDelegate, IASTNode super(enumValue); } + public boolean isExtensionKind(){ + return getEnumValue() > LAST_KIND; + } + private static final Hashtable names; static { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/extension/IASTFactoryExtension.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/extension/IASTFactoryExtension.java index 25e43a633a3..91703cb4ce9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/extension/IASTFactoryExtension.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/parser/extension/IASTFactoryExtension.java @@ -10,6 +10,7 @@ package org.eclipse.cdt.core.parser.extension; +import java.util.List; import java.util.Map; import org.eclipse.cdt.core.parser.IToken; @@ -39,7 +40,10 @@ public interface IASTFactoryExtension { IASTExpression rhs, IASTExpression thirdExpression, IASTTypeId typeId, - ITokenDuple idExpression, String literal, IASTNewExpressionDescriptor newDescriptor); + ITokenDuple idExpression, + String literal, + IASTNewExpressionDescriptor newDescriptor, + List references); public boolean canHandleExpressionKind( IASTExpression.Kind kind ); /** @@ -65,4 +69,5 @@ public interface IASTFactoryExtension { public boolean overrideCreateDesignatorMethod( IASTDesignator.DesignatorKind kind ); public IASTDesignator createDesignator( IASTDesignator.DesignatorKind kind, IASTExpression constantExpression, IToken fieldIdentifier, Map extensionParms ); + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserExtensionFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserExtensionFactory.java index 49f9ef2cda6..869946bd57b 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserExtensionFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ParserExtensionFactory.java @@ -58,7 +58,7 @@ public class ParserExtensionFactory implements IParserExtensionFactory { */ public IASTFactoryExtension createASTExtension(ParserMode mode) { if( dialect == ExtensionDialect.GCC ) - return new GCCASTExtension( mode ); + return GCCASTExtension.createExtension( mode ); throw new ParserFactoryError( ParserFactoryError.Kind.BAD_DIALECT ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/GCCASTExtension.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/GCCASTExtension.java index a7dd5352a96..be1fa7f34fe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/GCCASTExtension.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/GCCASTExtension.java @@ -16,14 +16,12 @@ import java.util.Map; import org.eclipse.cdt.core.parser.IToken; import org.eclipse.cdt.core.parser.ITokenDuple; import org.eclipse.cdt.core.parser.ParserMode; -import org.eclipse.cdt.core.parser.ast.ASTExpressionEvaluationException; import org.eclipse.cdt.core.parser.ast.IASTDesignator; import org.eclipse.cdt.core.parser.ast.IASTExpression; import org.eclipse.cdt.core.parser.ast.IASTScope; import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier; import org.eclipse.cdt.core.parser.ast.IASTTypeId; import org.eclipse.cdt.core.parser.ast.IASTDesignator.DesignatorKind; -import org.eclipse.cdt.core.parser.ast.IASTExpression.IASTNewExpressionDescriptor; import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind; import org.eclipse.cdt.core.parser.ast.IASTSimpleTypeSpecifier.Type; import org.eclipse.cdt.core.parser.ast.gcc.IASTGCCDesignator; @@ -33,8 +31,8 @@ import org.eclipse.cdt.core.parser.extension.IASTFactoryExtension; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTExpression; import org.eclipse.cdt.internal.core.parser.ast.complete.ASTTypeId; import org.eclipse.cdt.internal.core.parser.ast.complete.gcc.ASTGCCSimpleTypeSpecifier; -import org.eclipse.cdt.internal.core.parser.ast.expression.ASTIdExpression; -import org.eclipse.cdt.internal.core.parser.ast.expression.ExpressionFactory; +import org.eclipse.cdt.internal.core.parser.ast.complete.gcc.GCCASTCompleteExtension; +import org.eclipse.cdt.internal.core.parser.ast.expression.GCCASTExpressionExtension; import org.eclipse.cdt.internal.core.parser.ast.gcc.ASTGCCDesignator; import org.eclipse.cdt.internal.core.parser.pst.ISymbol; import org.eclipse.cdt.internal.core.parser.pst.ParserSymbolTable; @@ -44,62 +42,16 @@ import org.eclipse.cdt.internal.core.parser.pst.TypeInfo; * @author jcamelon * */ -public class GCCASTExtension implements IASTFactoryExtension { - private final ParserMode mode; - private static final String EMPTY_STRING = ""; //$NON-NLS-1$ +public abstract class GCCASTExtension implements IASTFactoryExtension { + protected final ParserMode mode; + protected static final String EMPTY_STRING = ""; //$NON-NLS-1$ /** * @param mode */ public GCCASTExtension(ParserMode mode) { this.mode = mode; } - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.extension.IASTFactoryExtension#overrideExpressionFactory() - */ - public boolean overrideCreateExpressionMethod() { - if( mode == ParserMode.EXPRESSION_PARSE ) - return true; - return false; - } - - /** - * @param kind - * @param lhs - * @param rhs - * @param thirdExpression - * @param typeId - * @param string - * @param literal - * @param newDescriptor - * @return - */ - protected static IASTExpression createExpression(Kind kind, IASTExpression lhs, IASTExpression rhs, IASTExpression thirdExpression, IASTTypeId typeId, String idExpression, String literal, IASTNewExpressionDescriptor newDescriptor) { - if( !idExpression.equals( EMPTY_STRING ) && literal.equals( EMPTY_STRING )) - return new ASTIdExpression( kind, idExpression ) - { - public long evaluateExpression() throws ASTExpressionEvaluationException { - if( getExpressionKind() == Kind.ID_EXPRESSION ) - return 0; - return super.evaluateExpression(); - } - }; - - return ExpressionFactory.createExpression( kind, lhs, rhs, thirdExpression, typeId, idExpression, literal, newDescriptor ); - } - - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.parser.extension.IASTFactoryExtension#createExpression(org.eclipse.cdt.core.parser.ast.IASTScope, org.eclipse.cdt.core.parser.ast.IASTExpression.Kind, org.eclipse.cdt.core.parser.ast.IASTExpression, org.eclipse.cdt.core.parser.ast.IASTExpression, org.eclipse.cdt.core.parser.ast.IASTExpression, org.eclipse.cdt.core.parser.ast.IASTTypeId, org.eclipse.cdt.core.parser.ITokenDuple, java.lang.String, org.eclipse.cdt.core.parser.ast.IASTExpression.IASTNewExpressionDescriptor) - */ - public IASTExpression createExpression(IASTScope scope, Kind kind, - IASTExpression lhs, IASTExpression rhs, - IASTExpression thirdExpression, IASTTypeId typeId, - ITokenDuple idExpression, String literal, - IASTNewExpressionDescriptor newDescriptor) - { - return createExpression( kind, lhs, rhs, thirdExpression, typeId, (idExpression == null ) ? EMPTY_STRING : idExpression.toString(), literal, newDescriptor ); - } /* (non-Javadoc) * @see org.eclipse.cdt.core.parser.extension.IASTFactoryExtension#canHandleExpressionKind(org.eclipse.cdt.core.parser.ast.IASTExpression.Kind) */ @@ -183,4 +135,15 @@ public class GCCASTExtension implements IASTFactoryExtension { IASTExpression secondExpression = (IASTExpression) extensionParms.get( IASTGCCDesignator.SECOND_EXRESSION ); return new ASTGCCDesignator( kind, constantExpression, EMPTY_STRING, -1, secondExpression ); } + + /** + * @param mode2 + * @return + */ + public static IASTFactoryExtension createExtension(ParserMode parseMode) { + if( parseMode == ParserMode.EXPRESSION_PARSE || parseMode == ParserMode.QUICK_PARSE ) + return new GCCASTExpressionExtension( parseMode ); + + return new GCCASTCompleteExtension( parseMode ); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java index da42071be26..765ddf4e54e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/CompleteParseASTFactory.java @@ -1130,8 +1130,12 @@ public class CompleteParseASTFactory extends BaseASTFactory implements IASTFacto // expression results could be empty, but should not be null // assert expressionResult != null : expressionResult; //throw new ASTSemanticException(); - // create the ASTExpression - ASTExpression expression = ExpressionFactory.createExpression( kind, lhs, rhs, thirdExpression, typeId, idExpression, literal, newDescriptor, references ); + // create the ASTExpression + ASTExpression expression = null; + if( extension.overrideCreateExpressionMethod() ) + expression = (ASTExpression) extension.createExpression( scope, kind, lhs, rhs, thirdExpression, typeId, idExpression, literal, newDescriptor, references ); + else + expression = ExpressionFactory.createExpression( kind, lhs, rhs, thirdExpression, typeId, idExpression, literal, newDescriptor, references ); // Assign the result to the created expression expression.setResultType (expressionResult); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/gcc/GCCASTCompleteExtension.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/gcc/GCCASTCompleteExtension.java new file mode 100644 index 00000000000..fabe2341e7c --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/ast/complete/gcc/GCCASTCompleteExtension.java @@ -0,0 +1,124 @@ +/********************************************************************** + * Copyright (c) 2004 IBM - 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 +***********************************************************************/ + +/* + * Created on Jun 8, 2004 + */ +package org.eclipse.cdt.internal.core.parser.ast.complete.gcc; + +import java.util.List; + +import org.eclipse.cdt.core.parser.GCCKeywords; +import org.eclipse.cdt.core.parser.ITokenDuple; +import org.eclipse.cdt.core.parser.ParserMode; +import org.eclipse.cdt.core.parser.ast.ASTExpressionEvaluationException; +import org.eclipse.cdt.core.parser.ast.ASTUtil; +import org.eclipse.cdt.core.parser.ast.IASTExpression; +import org.eclipse.cdt.core.parser.ast.IASTScope; +import org.eclipse.cdt.core.parser.ast.IASTTypeId; +import org.eclipse.cdt.core.parser.ast.IASTExpression.IASTNewExpressionDescriptor; +import org.eclipse.cdt.core.parser.ast.IASTExpression.Kind; +import org.eclipse.cdt.core.parser.ast.gcc.IASTGCCExpression; +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.ASTIdExpression; +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.ExpressionFactory; + +/** + * @author aniefer + */ +public class GCCASTCompleteExtension extends GCCASTExtension { + + /** + * @param mode + */ + public GCCASTCompleteExtension(ParserMode mode) { + super(mode); + } + + public boolean overrideCreateExpressionMethod() { + if( mode == ParserMode.STRUCTURAL_PARSE || mode == ParserMode.COMPLETE_PARSE ) + return true; + return false; + } + + protected IASTExpression createExpression(IASTExpression.Kind kind, IASTExpression lhs, IASTExpression rhs, IASTExpression thirdExpression, IASTTypeId typeId, ITokenDuple idExpression, String literal, IASTNewExpressionDescriptor newDescriptor, List references) { + if( lhs != null && rhs != null && + (kind == IASTGCCExpression.Kind.RELATIONAL_MAX || + kind == IASTGCCExpression.Kind.RELATIONAL_MIN ) ) + { + return new ASTBinaryExpression( kind, references, lhs, rhs ){ + public String toString(){ + IASTExpression.Kind kind = getExpressionKind(); + StringBuffer buffer = new StringBuffer(); + buffer.append( ASTUtil.getExpressionString( getLHSExpression() ) ); + if( kind == IASTGCCExpression.Kind.RELATIONAL_MAX ) + buffer.append( " >? " ); //$NON-NLS-1$ + else + buffer.append( " ? " ); //$NON-NLS-1$ + else + buffer.append( "