Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorqdagans2014-06-20 01:09:30 +0000
committerElena Laskavaia2014-07-06 00:34:13 +0000
commit8649b655701c4e56d00da6ff0f7361ff71572e2b (patch)
tree59f4dea6827b5ff1ca085ff5895644a64004a25c
parent92c9224591743885ca263ed2d372368e8245b697 (diff)
downloadorg.eclipse.cdt-8649b655701c4e56d00da6ff0f7361ff71572e2b.tar.gz
org.eclipse.cdt-8649b655701c4e56d00da6ff0f7361ff71572e2b.tar.xz
org.eclipse.cdt-8649b655701c4e56d00da6ff0f7361ff71572e2b.zip
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. Change-Id: I60b64957af3fdfd5463e89c2a36eea13bd280887 Signed-off-by: qdagans <anders.xb.dahlberg@ericsson.com> Reviewed-on: https://git.eclipse.org/r/28826 Tested-by: Hudson CI Reviewed-by: Elena Laskavaia <elaskavaia.cdt@gmail.com>
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java16
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CSpecTest.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTUnaryExpression.java17
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/INodeFactory.java5
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/IGNUASTGotoStatement.java61
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java20
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/BacktrackException.java16
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CNodeFactory.java9
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java67
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCASTGotoStatement.java91
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java3
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNodeFactory.java9
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPASTGotoStatement.java94
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java3
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java64
-rw-r--r--lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java6
16 files changed, 472 insertions, 25 deletions
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java
index 21bf614a86..e778847f82 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPSpecTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2013 IBM Corporation and others.
+ * Copyright (c) 2005, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -10,6 +10,7 @@
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
* Nathan Ridge
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2;
@@ -1010,6 +1011,19 @@ public class AST2CPPSpecTest extends AST2SpecTestBase {
parse(getAboveComment(), ParserLanguage.CPP, true, 1);
}
+ // void f()
+ // {
+ // // ...
+ // void* labelPtr;
+ // labelPtr = &&foo;
+ // goto *labelPtr;
+ // foo:
+ // return;
+ // }
+ public void test6_bug84144() throws Exception {
+ parse(getAboveComment(), ParserLanguage.CPP, true, 0);
+ }
+
// int foo(int i)
// {
// static int s = foo(2*i); // recursive call - undefined
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CSpecTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CSpecTest.java
index 9ad87f0b99..d8312b5578 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CSpecTest.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CSpecTest.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2009 IBM Corporation and others.
+ * Copyright (c) 2005, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.ast2;
@@ -1728,6 +1729,19 @@ public class AST2CSpecTest extends AST2SpecTestBase {
parseCandCPP(buffer.toString(), false, 0);
}
+ // void f()
+ // {
+ // // ...
+ // void* labelPtr;
+ // labelPtr = &&foo;
+ // goto *labelPtr;
+ // foo:
+ // return;
+ // }
+ public void test6_bug84144() throws Exception {
+ parseCandCPP(getAboveComment(), true, 0);
+ }
+
/**
[--Start Example(C 6.8.6.4-4):
struct s { double i; } f(void);
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 de04aa6ec1..c01f6713ea 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
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2011 IBM Corporation and others.
+ * Copyright (c) 2004, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* John Camelon (IBM Rational Software) - Initial API and implementation
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@@ -104,24 +105,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 = 15;
+ public static final int op_alignOf = 16;
/**
* For C++, only: 'sizeof... ( parameterPack )'
* @since 5.2
*/
- public static final int op_sizeofParameterPack = 16;
+ public static final int op_sizeofParameterPack = 17;
/**
* For C++, only: noexcept ( expression )
* @since 5.5
*/
- public static final int op_noexcept = 17;
+ public static final int op_noexcept = 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 69c2573a95..ad82acc174 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
@@ -10,6 +10,7 @@
* Markus Schorn (Wind River Systems)
* Sergey Prigogin (Google)
* Thoams Corbat (IFS)
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@@ -120,7 +121,9 @@ public interface INodeFactory {
public IGNUASTCompoundStatementExpression newGNUCompoundStatementExpression(IASTCompoundStatement compoundStatement);
- public IASTGotoStatement newGotoStatement(IASTName name);
+ public IASTStatement newGotoStatement(IASTName name);
+
+ public IASTStatement newGotoStatement(IASTExpression expression);
public IASTIdExpression newIdExpression(IASTName name);
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
new file mode 100644
index 0000000000..2b666e98ee
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/gnu/IGNUASTGotoStatement.java
@@ -0,0 +1,61 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anders Dahlberg (Ericsson) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.core.dom.ast.gnu;
+
+import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
+import org.eclipse.cdt.core.dom.ast.IASTExpression;
+import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
+import org.eclipse.cdt.core.dom.ast.IASTStatement;
+
+/**
+ * Represents a GNU goto expression.
+ *
+ * <code>
+ * foo:
+ * void *labelPtr = &&foo;
+ * goto *labelPtr;
+ * </code>
+ *
+ * @since 8.4
+ * @noextend This interface is not intended to be extended by clients.
+ * @noimplement This interface is not intended to be implemented by clients.
+ */
+public interface IGNUASTGotoStatement extends IASTStatement, IASTNameOwner {
+ public static final ASTNodeProperty LABEL_NAME =
+ new ASTNodeProperty("IASTGotoExpression.LABEL_NAME [IASTExpression]"); //$NON-NLS-1$
+
+ /**
+ * Returns the label-name expression. The expression resolves to a ILabel binding.
+ *
+ * @return <code>IASTExpression</code>
+ */
+ public IASTExpression getLabelNameExpression();
+
+ /**
+ * Set the label-name expression.
+ *
+ * @param expression
+ * <code>IASTExpression</code>
+ */
+ public void setLabelNameExpression(IASTExpression expression);
+
+ /**
+ * @since 5.1
+ */
+ @Override
+ public IGNUASTGotoStatement copy();
+
+ /**
+ * @since 5.3
+ */
+ @Override
+ public IGNUASTGotoStatement copy(CopyStyle style);
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
index 2750988e60..d73353a481 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/AbstractGNUSourceCodeParser.java
@@ -12,6 +12,7 @@
* Mike Kucera (IBM) - bug #206952
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@@ -23,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.ASTGenericVisitor;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTAttribute;
+import org.eclipse.cdt.core.dom.ast.IASTAttributeOwner;
import org.eclipse.cdt.core.dom.ast.IASTAttributeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTBreakStatement;
@@ -43,7 +45,6 @@ import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
-import org.eclipse.cdt.core.dom.ast.IASTAttributeOwner;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
@@ -51,7 +52,6 @@ import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
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.IASTIfStatement;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerClause;
@@ -112,7 +112,7 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
}
}
- protected static class Decl extends Exception {
+ protected static class Decl {
public Decl() {
}
@@ -1991,10 +1991,18 @@ public abstract class AbstractGNUSourceCodeParser implements ISourceCodeParser {
protected IASTStatement parseGotoStatement() throws EndOfFileException, BacktrackException {
int startOffset = consume().getOffset(); // t_goto
- IASTName goto_label_name = identifier();
+ IASTStatement goto_statement = null;
+
+ if (LT(1) == IToken.tSTAR)
+ {
+ IASTExpression goto_label_name_expression = expression();
+ goto_statement = nodeFactory.newGotoStatement(goto_label_name_expression);
+ } else {
+ IASTName goto_label_name = identifier();
+ goto_statement = nodeFactory.newGotoStatement(goto_label_name);
+ }
+
int lastOffset = consume(IToken.tSEMI).getEndOffset();
-
- IASTGotoStatement goto_statement = nodeFactory.newGotoStatement(goto_label_name);
((ASTNode) goto_statement).setOffsetAndLength(startOffset, lastOffset - startOffset);
return goto_statement;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/BacktrackException.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/BacktrackException.java
index 0be886eca5..f0f465a5c0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/BacktrackException.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/BacktrackException.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2008 IBM Corporation and others.
+ * Copyright (c) 2004, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -8,6 +8,7 @@
* Contributors:
* IBM - Initial API and implementation
* Markus Schorn (Wind River Systems)
+ * Anders Dahlberg (Ericsson) - bug 84144, indexer optimization
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser;
@@ -18,6 +19,8 @@ import org.eclipse.cdt.core.dom.ast.IASTProblem;
* @author jcamelon
*/
public class BacktrackException extends Exception {
+ private static final StackTraceElement[] EMPTY_STACK = new StackTraceElement[0];
+
private IASTProblem problem;
private IASTNode nodeBeforeProblem; // a node has been created in spite of the problem.
private int offset, length;
@@ -82,4 +85,15 @@ public class BacktrackException extends Exception {
public int getOffset() {
return offset;
}
+
+ @Override
+ public Throwable fillInStackTrace() {
+ // Do nothing, performance optimization
+ return this;
+ }
+
+ @Override
+ public StackTraceElement[] getStackTrace() {
+ return EMPTY_STACK;
+ }
}
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 22786b1e92..96fd8720d2 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
@@ -9,6 +9,7 @@
* Mike Kucera (IBM Corporation) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Thomas Corbat (IFS)
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@@ -40,7 +41,6 @@ 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,11 +298,16 @@ public class CNodeFactory extends NodeFactory implements ICNodeFactory {
}
@Override
- public IASTGotoStatement newGotoStatement(IASTName name) {
+ public IASTStatement newGotoStatement(IASTName name) {
return new CASTGotoStatement(name);
}
@Override
+ public IASTStatement newGotoStatement(IASTExpression expression) {
+ return new GNUCASTGotoStatement(expression);
+ }
+
+ @Override
public IASTIdExpression newIdExpression(IASTName name) {
return new CASTIdExpression(name);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
index 648c774806..9521c60abb 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005, 2013 IBM Corporation and others.
+ * Copyright (c) 2005, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -13,6 +13,7 @@
* Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion)
* Sergey Prigogin (Google)
* Marc-Andre Laperle (Ericsson)
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@@ -57,6 +58,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
+import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IArrayType;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
@@ -104,6 +106,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPLabel;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory;
@@ -455,7 +458,17 @@ public class CVisitor extends ASTQueries {
IBinding binding = null;
IASTNode parent = name.getParent();
- if (parent instanceof CASTIdExpression) {
+ // GNU Goto label reference
+ //
+ // void* labelPtr = &&foo; <-- label reference
+ // foo:
+ //
+ boolean labelReference = isLabelReference(parent);
+
+ if (labelReference) {
+ IASTUnaryExpression expression = (IASTUnaryExpression) parent.getParent();
+ binding = createLabelReferenceBinding(name, expression);
+ } else if (parent instanceof CASTIdExpression) {
binding = resolveBinding(parent);
} else if (parent instanceof ICASTTypedefNameSpecifier) {
binding = resolveBinding(parent);
@@ -596,6 +609,56 @@ public class CVisitor extends ASTQueries {
return null;
}
+
+ private static boolean isLabelReference(IASTNode node) {
+ boolean labelReference = false;
+ IASTNode parent = node.getParent();
+
+ if (parent instanceof IASTUnaryExpression) {
+ int operator = ((IASTUnaryExpression) parent).getOperator();
+ labelReference = operator == IASTUnaryExpression.op_labelReference;
+ }
+
+ return labelReference;
+ }
+
+ private static IBinding createLabelReferenceBinding(IASTName name, IASTUnaryExpression expression) {
+ IBinding binding = null;
+
+ // Find function scope for r-value expression
+ // void* labelPtr = &&foo;
+ // foo: ^^^
+ // return
+ IScope scope = getContainingScope(name);
+ IASTInternalScope s = (IASTInternalScope) scope;
+ IASTNode node = s.getPhysicalNode();
+
+ while (node != null && !(node instanceof IASTFunctionDefinition)) {
+ node = node.getParent();
+ }
+
+ if (node != null) {
+ IASTFunctionDefinition definition = (IASTFunctionDefinition) node;
+ CASTFunctionDeclarator declarator = (CASTFunctionDeclarator) definition.getDeclarator();
+ scope = declarator.getFunctionScope();
+
+ if (scope != null) {
+ binding = scope.getBinding(name, false);
+ if (!(binding instanceof ILabel)) {
+ binding = new CPPLabel(name);
+ ASTInternal.addName(scope, name);
+ }
+ }
+ }
+
+ if (binding == null) {
+ binding = new ProblemBinding(expression, IProblemBinding.SEMANTIC_BAD_SCOPE,
+ expression.getRawSignature().toCharArray());
+ }
+
+ return binding;
+ }
+
/**
* if prefix == false, return an IBinding or null
* if prefix == true, return an IBinding[] or null
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
new file mode 100644
index 0000000000..f3b90d94c7
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCASTGotoStatement.java
@@ -0,0 +1,91 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anders Dahlberg (Ericsson) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.c;
+
+import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTExpression;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTGotoStatement;
+import org.eclipse.cdt.internal.core.dom.parser.ASTAttributeOwner;
+
+/**
+ * GNU C goto statement.
+ *
+ * <code>
+ * foo:
+ * void *labelPtr = &&foo;
+ * goto *labelPtr; // this is the statement
+ * </code>
+ * @since 8.4
+ */
+public class GNUCASTGotoStatement extends ASTAttributeOwner
+ implements IGNUASTGotoStatement {
+ private IASTExpression fExpression;
+
+ public GNUCASTGotoStatement() {
+ }
+
+ public GNUCASTGotoStatement(IASTExpression expression) {
+ setLabelNameExpression(expression);
+ }
+
+ @Override
+ public GNUCASTGotoStatement copy() {
+ return copy(CopyStyle.withoutLocations);
+ }
+
+ @Override
+ public GNUCASTGotoStatement copy(CopyStyle style) {
+ GNUCASTGotoStatement copy = new GNUCASTGotoStatement();
+ copy.setLabelNameExpression(fExpression == null ? null : fExpression.copy(style));
+ return copy(copy, style);
+ }
+
+ @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 (fExpression != null && !fExpression.accept(action))
+ return false;
+
+ if (action.shouldVisitExpressions && action.leave(this) == ASTVisitor.PROCESS_ABORT)
+ return false;
+
+ return true;
+ }
+
+ @Override
+ public IASTExpression getLabelNameExpression() {
+ return fExpression;
+ }
+
+ @Override
+ 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/c/GNUCSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
index 94ec7c33a2..3375657765 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/GNUCSourceParser.java
@@ -12,6 +12,7 @@
* Mike Kucera (IBM) - bug #206952
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@@ -594,6 +595,8 @@ public class GNUCSourceParser extends AbstractGNUSourceCodeParser {
return unaryExpression(IASTUnaryExpression.op_star, ctx, strat);
case IToken.tAMPER:
return unaryExpression(IASTUnaryExpression.op_amper, ctx, strat);
+ case IToken.tAND:
+ return unaryExpression(IASTUnaryExpression.op_labelReference, ctx, strat);
case IToken.tPLUS:
return unaryExpression(IASTUnaryExpression.op_plus, ctx, strat);
case IToken.tMINUS:
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 883a84030d..a4146d99a7 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
@@ -9,6 +9,7 @@
* Mike Kucera (IBM) - initial API and implementation
* Markus Schorn (Wind River Systems)
* Thomas Corbat (IFS)
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -31,7 +32,6 @@ 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,11 +430,16 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
}
@Override
- public IASTGotoStatement newGotoStatement(IASTName name) {
+ public IASTStatement newGotoStatement(IASTName name) {
return new CPPASTGotoStatement(name);
}
@Override
+ public IASTStatement newGotoStatement(IASTExpression expression) {
+ return new GNUCPPASTGotoStatement(expression);
+ }
+
+ @Override
public IASTIdExpression newIdExpression(IASTName name) {
return new CPPASTIdExpression(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
new file mode 100644
index 0000000000..9fa287d601
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPASTGotoStatement.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * Copyright (c) 2014 Ericsson.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Anders Dahlberg (Ericsson) - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser.cpp;
+
+import org.eclipse.cdt.core.dom.ast.ASTVisitor;
+import org.eclipse.cdt.core.dom.ast.IASTExpression;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.gnu.IGNUASTGotoStatement;
+import org.eclipse.cdt.internal.core.dom.parser.ASTAttributeOwner;
+
+/**
+ * GNU C++ goto statement.
+ *
+ * <code>
+ * foo:
+ * void *labelPtr = &&foo;
+ * goto *labelPtr; // this is the statement
+ * </code>
+ *
+ * @since 8.4
+ */
+public class GNUCPPASTGotoStatement extends ASTAttributeOwner implements IGNUASTGotoStatement {
+ private IASTExpression expression;
+
+ public GNUCPPASTGotoStatement() {
+ }
+
+ public GNUCPPASTGotoStatement(IASTExpression expression) {
+ setLabelNameExpression(expression);
+ }
+
+ @Override
+ public GNUCPPASTGotoStatement copy() {
+ return copy(CopyStyle.withoutLocations);
+ }
+
+ @Override
+ public GNUCPPASTGotoStatement copy(CopyStyle 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 (!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;
+ }
+ }
+ return true;
+ }
+
+ @Override
+ public IASTExpression getLabelNameExpression() {
+ return expression;
+ }
+
+ @Override
+ public void setLabelNameExpression(IASTExpression expression) {
+ assertNotFrozen();
+ this.expression = 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/GNUCPPSourceParser.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
index d8463f1dc0..00d36d76c4 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/GNUCPPSourceParser.java
@@ -14,6 +14,7 @@
* Andrew Ferguson (Symbian)
* Sergey Prigogin (Google)
* Thomas Corbat (IFS)
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@@ -1327,6 +1328,8 @@ public class GNUCPPSourceParser extends AbstractGNUSourceCodeParser {
return unaryExpression(IASTUnaryExpression.op_star, ctx, strat);
case IToken.tAMPER:
return unaryExpression(IASTUnaryExpression.op_amper, ctx, strat);
+ case IToken.tAND:
+ return unaryExpression(IASTUnaryExpression.op_labelReference, ctx, strat);
case IToken.tPLUS:
return unaryExpression(IASTUnaryExpression.op_plus, ctx, strat);
case IToken.tMINUS:
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
index c79dee6062..2e32732f1e 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java
@@ -13,6 +13,7 @@
* Thomas Corbat (IFS)
* Nathan Ridge
* Marc-Andre Laperle
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
@@ -178,6 +179,7 @@ import org.eclipse.cdt.internal.core.dom.parser.SizeofCalculator;
import org.eclipse.cdt.internal.core.dom.parser.Value;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionCallExpression;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
@@ -299,7 +301,18 @@ public class CPPVisitor extends ASTQueries {
id.resolveBinding();
return name.getBinding();
}
- if (parent instanceof IASTIdExpression) {
+
+ // GNU Goto label reference
+ //
+ // void* labelPtr = &&foo; <-- label reference
+ // foo:
+ //
+ boolean labelReference = isLabelReference(parent);
+
+ if (labelReference) {
+ IASTUnaryExpression expression = (IASTUnaryExpression) parent.getParent();
+ return createLabelReferenceBinding(name, expression);
+ } else if (parent instanceof IASTIdExpression) {
return resolveBinding(parent);
} else if (parent instanceof ICPPASTFieldReference) {
return resolveBinding(parent);
@@ -376,6 +389,55 @@ public class CPPVisitor extends ASTQueries {
return scope == inScope;
}
+ private static boolean isLabelReference(IASTNode node) {
+ boolean labelReference = false;
+ IASTNode parent = node.getParent();
+
+ if (parent instanceof IASTUnaryExpression) {
+ int operator = ((IASTUnaryExpression) parent).getOperator();
+ labelReference = operator == IASTUnaryExpression.op_labelReference;
+ }
+
+ return labelReference;
+ }
+
+ private static IBinding createLabelReferenceBinding(IASTName name, IASTUnaryExpression expression) {
+ IBinding binding = null;
+
+ // Find function scope for r-value expression
+ // void* labelPtr = &&foo;
+ // foo: ^^^
+ // return
+ IScope scope = getContainingScope(name);
+ IASTInternalScope s = (IASTInternalScope) scope;
+ IASTNode node = s.getPhysicalNode();
+
+ while (node != null && !(node instanceof IASTFunctionDefinition)) {
+ node = node.getParent();
+ }
+
+ if (node != null) {
+ IASTFunctionDefinition definition = (IASTFunctionDefinition) node;
+ CPPASTFunctionDeclarator declarator = (CPPASTFunctionDeclarator) definition.getDeclarator();
+ scope = declarator.getFunctionScope();
+
+ if (scope != null) {
+ binding = scope.getBinding(name, false);
+ if (!(binding instanceof ILabel)) {
+ binding = new CPPLabel(name);
+ ASTInternal.addName(scope, name);
+ }
+ }
+ }
+
+ if (binding == null) {
+ binding = new CPPScope.CPPScopeProblem(expression, IProblemBinding.SEMANTIC_BAD_SCOPE,
+ expression.getRawSignature().toCharArray());
+ }
+
+ return binding;
+ }
+
private static IBinding createBinding(IASTGotoStatement gotoStatement) {
IASTName name = gotoStatement.getName();
ICPPFunctionScope functionScope = (ICPPFunctionScope) getContainingScope(name);
diff --git a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java
index 0ff7eb74b4..422dfd265f 100644
--- a/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java
+++ b/lrparser/org.eclipse.cdt.core.lrparser/src/org/eclipse/cdt/core/dom/lrparser/action/BuildASTParserAction.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006, 2010 IBM Corporation and others.
+ * Copyright (c) 2006, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Anders Dahlberg (Ericsson) - bug 84144
*******************************************************************************/
package org.eclipse.cdt.core.dom.lrparser.action;
@@ -44,7 +45,6 @@ import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
import org.eclipse.cdt.core.dom.ast.IASTFieldDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
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;
@@ -598,7 +598,7 @@ public abstract class BuildASTParserAction extends AbstractParserAction {
*/
public void consumeStatementGoto() {
IASTName name = createName(stream.getRuleTokens().get(1));
- IASTGotoStatement gotoStat = nodeFactory.newGotoStatement(name);
+ IASTStatement gotoStat = nodeFactory.newGotoStatement(name);
setOffsetAndLength(gotoStat);
astStack.push(gotoStat);
}

Back to the top