mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-02 13:55:39 +02:00
Bug 84144 - [Parser2] GCC: labels as values
Add support for GNU goto label references. "http://gcc.gnu.org/onlinedocs/gcc-3.3.2/gcc/Labels-as-Values.html#Labels%20as%20Values GCC extensions to C allow taking the address of labels. These addresses can be used in a goto statement where any expression of type void * is allowed: foo: void* labelPtr = &&foo; goto *labelPtr;", comment from Andrew Niefer Add new classes and necessary changes in existing classes to support the above. Updated to not change API. Signed-off-by: Anders Dahlberg <anders.xb.dahlberg@ericsson.com> Change-Id: Ibb69ce7748f201c15bdf2da05348c157cdd5aaae Reviewed-on: https://git.eclipse.org/r/29574 Tested-by: Hudson CI Reviewed-by: Thomas Corbat <tcorbat@hsr.ch> Tested-by: Thomas Corbat <tcorbat@hsr.ch>
This commit is contained in:
parent
17d10e5823
commit
bf0ac98464
7 changed files with 84 additions and 65 deletions
|
@ -106,29 +106,30 @@ public interface IASTUnaryExpression extends IASTExpression {
|
||||||
@Deprecated
|
@Deprecated
|
||||||
public static final int op_typeof = 14;
|
public static final int op_typeof = 14;
|
||||||
|
|
||||||
/**
|
|
||||||
* For GCC parsers, only. {@code op_labelReference} is used for &&label type
|
|
||||||
* expressions.
|
|
||||||
*/
|
|
||||||
public static final int op_labelReference = 15;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For GCC parsers, only. {@code op_alignOf} is used for __alignOf( unaryExpression ) type
|
* For GCC parsers, only. {@code op_alignOf} is used for __alignOf( unaryExpression ) type
|
||||||
* expressions.
|
* expressions.
|
||||||
*/
|
*/
|
||||||
public static final int op_alignOf = 16;
|
public static final int op_alignOf = 15;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For C++, only: 'sizeof... ( parameterPack )'
|
* For C++, only: 'sizeof... ( parameterPack )'
|
||||||
* @since 5.2
|
* @since 5.2
|
||||||
*/
|
*/
|
||||||
public static final int op_sizeofParameterPack = 17;
|
public static final int op_sizeofParameterPack = 16;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For C++, only: noexcept ( expression )
|
* For C++, only: noexcept ( expression )
|
||||||
* @since 5.5
|
* @since 5.5
|
||||||
*/
|
*/
|
||||||
public static final int op_noexcept = 18;
|
public static final int op_noexcept = 17;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* For GCC parsers, only. {@code op_labelReference} is used for &&label type
|
||||||
|
* expressions.
|
||||||
|
* @since 5.8
|
||||||
|
*/
|
||||||
|
public static final int op_labelReference = 18;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@code op_last} is made available for subclasses.
|
* {@code op_last} is made available for subclasses.
|
||||||
|
|
|
@ -121,10 +121,14 @@ public interface INodeFactory {
|
||||||
|
|
||||||
public IGNUASTCompoundStatementExpression newGNUCompoundStatementExpression(IASTCompoundStatement compoundStatement);
|
public IGNUASTCompoundStatementExpression newGNUCompoundStatementExpression(IASTCompoundStatement compoundStatement);
|
||||||
|
|
||||||
public IASTStatement newGotoStatement(IASTName name);
|
public IASTGotoStatement newGotoStatement(IASTName name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Note: Adding as separate function to avoid changing API.
|
||||||
|
* @since 5.8
|
||||||
|
*/
|
||||||
public IASTStatement newGotoStatement(IASTExpression expression);
|
public IASTStatement newGotoStatement(IASTExpression expression);
|
||||||
|
|
||||||
public IASTIdExpression newIdExpression(IASTName name);
|
public IASTIdExpression newIdExpression(IASTName name);
|
||||||
|
|
||||||
public IASTIfStatement newIfStatement(IASTExpression condition, IASTStatement then, IASTStatement elseClause);
|
public IASTIfStatement newIfStatement(IASTExpression condition, IASTStatement then, IASTStatement elseClause);
|
||||||
|
|
|
@ -24,7 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
* goto *labelPtr;
|
* goto *labelPtr;
|
||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* @since 8.4
|
* @since 5.8
|
||||||
* @noextend This interface is not intended to be extended by clients.
|
* @noextend This interface is not intended to be extended by clients.
|
||||||
* @noimplement This interface is not intended to be implemented by clients.
|
* @noimplement This interface is not intended to be implemented by clients.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -41,6 +41,7 @@ import org.eclipse.cdt.core.dom.ast.IASTForStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTIfStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||||
|
@ -298,7 +299,7 @@ public class CNodeFactory extends NodeFactory implements ICNodeFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IASTStatement newGotoStatement(IASTName name) {
|
public IASTGotoStatement newGotoStatement(IASTName name) {
|
||||||
return new CASTGotoStatement(name);
|
return new CASTGotoStatement(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -24,14 +24,14 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTAttributeOwner;
|
||||||
* void *labelPtr = &&foo;
|
* void *labelPtr = &&foo;
|
||||||
* goto *labelPtr; // this is the statement
|
* goto *labelPtr; // this is the statement
|
||||||
* </code>
|
* </code>
|
||||||
* @since 8.4
|
*
|
||||||
|
* @since 5.8
|
||||||
*/
|
*/
|
||||||
public class GNUCASTGotoStatement extends ASTAttributeOwner
|
public class GNUCASTGotoStatement extends ASTAttributeOwner implements IGNUASTGotoStatement {
|
||||||
implements IGNUASTGotoStatement {
|
private IASTExpression fExpression;
|
||||||
private IASTExpression fExpression;
|
|
||||||
|
public GNUCASTGotoStatement() {
|
||||||
public GNUCASTGotoStatement() {
|
}
|
||||||
}
|
|
||||||
|
|
||||||
public GNUCASTGotoStatement(IASTExpression expression) {
|
public GNUCASTGotoStatement(IASTExpression expression) {
|
||||||
setLabelNameExpression(expression);
|
setLabelNameExpression(expression);
|
||||||
|
@ -41,7 +41,7 @@ public class GNUCASTGotoStatement extends ASTAttributeOwner
|
||||||
public GNUCASTGotoStatement copy() {
|
public GNUCASTGotoStatement copy() {
|
||||||
return copy(CopyStyle.withoutLocations);
|
return copy(CopyStyle.withoutLocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GNUCASTGotoStatement copy(CopyStyle style) {
|
public GNUCASTGotoStatement copy(CopyStyle style) {
|
||||||
GNUCASTGotoStatement copy = new GNUCASTGotoStatement();
|
GNUCASTGotoStatement copy = new GNUCASTGotoStatement();
|
||||||
|
@ -49,24 +49,27 @@ public class GNUCASTGotoStatement extends ASTAttributeOwner
|
||||||
return copy(copy, style);
|
return copy(copy, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(ASTVisitor action) {
|
public boolean accept(ASTVisitor action) {
|
||||||
if (action.shouldVisitExpressions) {
|
if (action.shouldVisitExpressions) {
|
||||||
switch (action.visit(this)) {
|
switch (action.visit(this)) {
|
||||||
case ASTVisitor.PROCESS_ABORT: return false;
|
case ASTVisitor.PROCESS_ABORT:
|
||||||
case ASTVisitor.PROCESS_SKIP: return true;
|
return false;
|
||||||
default: break;
|
case ASTVisitor.PROCESS_SKIP:
|
||||||
}
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fExpression != null && !fExpression.accept(action))
|
if (fExpression != null && !fExpression.accept(action))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (action.shouldVisitExpressions && action.leave(this) == ASTVisitor.PROCESS_ABORT)
|
if (action.shouldVisitExpressions && action.leave(this) == ASTVisitor.PROCESS_ABORT)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IASTExpression getLabelNameExpression() {
|
public IASTExpression getLabelNameExpression() {
|
||||||
|
@ -77,13 +80,13 @@ public class GNUCASTGotoStatement extends ASTAttributeOwner
|
||||||
public void setLabelNameExpression(IASTExpression expression) {
|
public void setLabelNameExpression(IASTExpression expression) {
|
||||||
assertNotFrozen();
|
assertNotFrozen();
|
||||||
this.fExpression = expression;
|
this.fExpression = expression;
|
||||||
|
|
||||||
if (expression != null) {
|
if (expression != null) {
|
||||||
expression.setParent(this);
|
expression.setParent(this);
|
||||||
expression.setPropertyInParent(LABEL_NAME);
|
expression.setPropertyInParent(LABEL_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRoleForName(IASTName n) {
|
public int getRoleForName(IASTName n) {
|
||||||
return r_unclear;
|
return r_unclear;
|
||||||
|
|
|
@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTGotoStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
|
||||||
|
@ -430,7 +431,7 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IASTStatement newGotoStatement(IASTName name) {
|
public IASTGotoStatement newGotoStatement(IASTName name) {
|
||||||
return new CPPASTGotoStatement(name);
|
return new CPPASTGotoStatement(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,12 +25,12 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTAttributeOwner;
|
||||||
* goto *labelPtr; // this is the statement
|
* goto *labelPtr; // this is the statement
|
||||||
* </code>
|
* </code>
|
||||||
*
|
*
|
||||||
* @since 8.4
|
* @since 5.8
|
||||||
*/
|
*/
|
||||||
public class GNUCPPASTGotoStatement extends ASTAttributeOwner implements IGNUASTGotoStatement {
|
public class GNUCPPASTGotoStatement extends ASTAttributeOwner implements IGNUASTGotoStatement {
|
||||||
private IASTExpression expression;
|
private IASTExpression expression;
|
||||||
|
|
||||||
public GNUCPPASTGotoStatement() {
|
public GNUCPPASTGotoStatement() {
|
||||||
}
|
}
|
||||||
|
|
||||||
public GNUCPPASTGotoStatement(IASTExpression expression) {
|
public GNUCPPASTGotoStatement(IASTExpression expression) {
|
||||||
|
@ -41,35 +41,44 @@ public class GNUCPPASTGotoStatement extends ASTAttributeOwner implements IGNUAST
|
||||||
public GNUCPPASTGotoStatement copy() {
|
public GNUCPPASTGotoStatement copy() {
|
||||||
return copy(CopyStyle.withoutLocations);
|
return copy(CopyStyle.withoutLocations);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GNUCPPASTGotoStatement copy(CopyStyle style) {
|
public GNUCPPASTGotoStatement copy(CopyStyle style) {
|
||||||
GNUCPPASTGotoStatement copy = new GNUCPPASTGotoStatement(expression == null ? null : expression.copy(style));
|
GNUCPPASTGotoStatement copy = new GNUCPPASTGotoStatement(expression == null ? null
|
||||||
|
: expression.copy(style));
|
||||||
return copy(copy, style);
|
return copy(copy, style);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept(ASTVisitor action) {
|
public boolean accept(ASTVisitor action) {
|
||||||
if (action.shouldVisitStatements) {
|
if (action.shouldVisitStatements) {
|
||||||
switch (action.visit(this)) {
|
switch (action.visit(this)) {
|
||||||
case ASTVisitor.PROCESS_ABORT : return false;
|
case ASTVisitor.PROCESS_ABORT:
|
||||||
case ASTVisitor.PROCESS_SKIP : return true;
|
return false;
|
||||||
default : break;
|
case ASTVisitor.PROCESS_SKIP:
|
||||||
}
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!acceptByAttributeSpecifiers(action)) return false;
|
if (!acceptByAttributeSpecifiers(action))
|
||||||
if (expression != null && !expression.accept(action)) return false;
|
return false;
|
||||||
|
if (expression != null && !expression.accept(action))
|
||||||
|
return false;
|
||||||
|
|
||||||
if (action.shouldVisitStatements) {
|
if (action.shouldVisitStatements) {
|
||||||
switch (action.leave(this)) {
|
switch (action.leave(this)) {
|
||||||
case ASTVisitor.PROCESS_ABORT : return false;
|
case ASTVisitor.PROCESS_ABORT:
|
||||||
case ASTVisitor.PROCESS_SKIP : return true;
|
return false;
|
||||||
default : break;
|
case ASTVisitor.PROCESS_SKIP:
|
||||||
}
|
return true;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public IASTExpression getLabelNameExpression() {
|
public IASTExpression getLabelNameExpression() {
|
||||||
|
@ -78,15 +87,15 @@ public class GNUCPPASTGotoStatement extends ASTAttributeOwner implements IGNUAST
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setLabelNameExpression(IASTExpression expression) {
|
public void setLabelNameExpression(IASTExpression expression) {
|
||||||
assertNotFrozen();
|
assertNotFrozen();
|
||||||
this.expression = expression;
|
this.expression = expression;
|
||||||
|
|
||||||
if (expression != null) {
|
if (expression != null) {
|
||||||
expression.setParent(this);
|
expression.setParent(this);
|
||||||
expression.setPropertyInParent(LABEL_NAME);
|
expression.setPropertyInParent(LABEL_NAME);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRoleForName(IASTName n) {
|
public int getRoleForName(IASTName n) {
|
||||||
return r_unclear;
|
return r_unclear;
|
||||||
|
|
Loading…
Add table
Reference in a new issue