From bf0ac984648cf00b5b40fbd402afafd103ee8ced Mon Sep 17 00:00:00 2001 From: qdagans Date: Tue, 8 Jul 2014 03:43:20 +0200 Subject: [PATCH] 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 Change-Id: Ibb69ce7748f201c15bdf2da05348c157cdd5aaae Reviewed-on: https://git.eclipse.org/r/29574 Tested-by: Hudson CI Reviewed-by: Thomas Corbat Tested-by: Thomas Corbat --- .../cdt/core/dom/ast/IASTUnaryExpression.java | 19 +++--- .../cdt/core/dom/ast/INodeFactory.java | 10 ++- .../dom/ast/gnu/IGNUASTGotoStatement.java | 2 +- .../core/dom/parser/c/CNodeFactory.java | 3 +- .../dom/parser/c/GNUCASTGotoStatement.java | 45 +++++++------ .../core/dom/parser/cpp/CPPNodeFactory.java | 3 +- .../parser/cpp/GNUCPPASTGotoStatement.java | 67 +++++++++++-------- 7 files changed, 84 insertions(+), 65 deletions(-) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java index c01f6713ea8..ebd297d633a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java @@ -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. diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/INodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/INodeFactory.java index ad82acc1748..b3ad6582b1f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/INodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/INodeFactory.java @@ -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); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/IGNUASTGotoStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/IGNUASTGotoStatement.java index 2b666e98ee6..0cd1f5dde22 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/IGNUASTGotoStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/IGNUASTGotoStatement.java @@ -24,7 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement; * goto *labelPtr; * * - * @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. */ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CNodeFactory.java index 96fd8720d27..57e88259ec7 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CNodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CNodeFactory.java @@ -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); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCASTGotoStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCASTGotoStatement.java index f3b90d94c7a..29dd0d282b6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCASTGotoStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCASTGotoStatement.java @@ -24,14 +24,14 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTAttributeOwner; * void *labelPtr = &&foo; * goto *labelPtr; // this is the statement * - * @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; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java index a4146d99a73..e1545e71ffa 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java @@ -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); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPASTGotoStatement.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPASTGotoStatement.java index 9fa287d601b..f2af1111b41 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPASTGotoStatement.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPASTGotoStatement.java @@ -25,12 +25,12 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTAttributeOwner; * goto *labelPtr; // this is the statement * * - * @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;