1
0
Fork 0
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:
qdagans 2014-07-08 03:43:20 +02:00 committed by Thomas Corbat
parent 17d10e5823
commit bf0ac98464
7 changed files with 84 additions and 65 deletions

View file

@ -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.

View file

@ -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);

View file

@ -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.
*/ */

View file

@ -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);
} }

View file

@ -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;

View file

@ -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);
} }

View file

@ -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;