Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to 'core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java')
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java64
1 files changed, 63 insertions, 1 deletions
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 c79dee6062a..2e32732f1e0 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);

Back to the top