1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +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
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
* expressions.
*/
public static final int op_alignOf = 16;
public static final int op_alignOf = 15;
/**
* For C++, only: 'sizeof... ( parameterPack )'
* @since 5.2
*/
public static final int op_sizeofParameterPack = 17;
public static final int op_sizeofParameterPack = 16;
/**
* For C++, only: noexcept ( expression )
* @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.

View file

@ -121,10 +121,14 @@ public interface INodeFactory {
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 IASTIdExpression newIdExpression(IASTName name);
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;
* </code>
*
* @since 8.4
* @since 5.8
* @noextend This interface is not intended to be extended 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.IASTFunctionDeclarator;
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.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
@ -298,7 +299,7 @@ public class CNodeFactory extends NodeFactory implements ICNodeFactory {
}
@Override
public IASTStatement newGotoStatement(IASTName name) {
public IASTGotoStatement newGotoStatement(IASTName name) {
return new CASTGotoStatement(name);
}

View file

@ -24,14 +24,14 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTAttributeOwner;
* void *labelPtr = &&foo;
* goto *labelPtr; // this is the statement
* </code>
* @since 8.4
*
* @since 5.8
*/
public class GNUCASTGotoStatement extends ASTAttributeOwner
implements IGNUASTGotoStatement {
private IASTExpression fExpression;
public GNUCASTGotoStatement() {
}
public class GNUCASTGotoStatement extends ASTAttributeOwner implements IGNUASTGotoStatement {
private IASTExpression fExpression;
public GNUCASTGotoStatement() {
}
public GNUCASTGotoStatement(IASTExpression expression) {
setLabelNameExpression(expression);
@ -41,7 +41,7 @@ public class GNUCASTGotoStatement extends ASTAttributeOwner
public GNUCASTGotoStatement copy() {
return copy(CopyStyle.withoutLocations);
}
@Override
public GNUCASTGotoStatement copy(CopyStyle style) {
GNUCASTGotoStatement copy = new GNUCASTGotoStatement();
@ -49,24 +49,27 @@ public class GNUCASTGotoStatement extends ASTAttributeOwner
return copy(copy, style);
}
@Override
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitExpressions) {
switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT: return false;
case ASTVisitor.PROCESS_SKIP: return true;
default: break;
}
if (action.shouldVisitExpressions) {
switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT:
return false;
case ASTVisitor.PROCESS_SKIP:
return true;
default:
break;
}
}
if (fExpression != null && !fExpression.accept(action))
return false;
return false;
if (action.shouldVisitExpressions && action.leave(this) == ASTVisitor.PROCESS_ABORT)
return false;
return true;
}
}
@Override
public IASTExpression getLabelNameExpression() {
@ -77,13 +80,13 @@ public class GNUCASTGotoStatement extends ASTAttributeOwner
public void setLabelNameExpression(IASTExpression expression) {
assertNotFrozen();
this.fExpression = expression;
if (expression != null) {
expression.setParent(this);
expression.setPropertyInParent(LABEL_NAME);
}
}
}
@Override
public int getRoleForName(IASTName n) {
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.IASTExpressionStatement;
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.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
@ -430,7 +431,7 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
}
@Override
public IASTStatement newGotoStatement(IASTName name) {
public IASTGotoStatement newGotoStatement(IASTName 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
* </code>
*
* @since 8.4
* @since 5.8
*/
public class GNUCPPASTGotoStatement extends ASTAttributeOwner implements IGNUASTGotoStatement {
private IASTExpression expression;
public GNUCPPASTGotoStatement() {
public GNUCPPASTGotoStatement() {
}
public GNUCPPASTGotoStatement(IASTExpression expression) {
@ -41,35 +41,44 @@ public class GNUCPPASTGotoStatement extends ASTAttributeOwner implements IGNUAST
public GNUCPPASTGotoStatement copy() {
return copy(CopyStyle.withoutLocations);
}
@Override
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);
}
@Override
public boolean accept(ASTVisitor action) {
if (action.shouldVisitStatements) {
switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT : return false;
case ASTVisitor.PROCESS_SKIP : return true;
default : break;
}
if (action.shouldVisitStatements) {
switch (action.visit(this)) {
case ASTVisitor.PROCESS_ABORT:
return false;
case ASTVisitor.PROCESS_SKIP:
return true;
default:
break;
}
}
if (!acceptByAttributeSpecifiers(action)) return false;
if (expression != null && !expression.accept(action)) return false;
if (!acceptByAttributeSpecifiers(action))
return false;
if (expression != null && !expression.accept(action))
return false;
if (action.shouldVisitStatements) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT : return false;
case ASTVisitor.PROCESS_SKIP : return true;
default : break;
}
if (action.shouldVisitStatements) {
switch (action.leave(this)) {
case ASTVisitor.PROCESS_ABORT:
return false;
case ASTVisitor.PROCESS_SKIP:
return true;
default:
break;
}
}
return true;
}
return true;
}
@Override
public IASTExpression getLabelNameExpression() {
@ -78,15 +87,15 @@ public class GNUCPPASTGotoStatement extends ASTAttributeOwner implements IGNUAST
@Override
public void setLabelNameExpression(IASTExpression expression) {
assertNotFrozen();
this.expression = expression;
if (expression != null) {
expression.setParent(this);
expression.setPropertyInParent(LABEL_NAME);
}
assertNotFrozen();
this.expression = expression;
if (expression != null) {
expression.setParent(this);
expression.setPropertyInParent(LABEL_NAME);
}
}
@Override
public int getRoleForName(IASTName n) {
return r_unclear;