diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
index 2aec0ef83a0..d005ecb1ef8 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java
@@ -106,6 +106,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPPointerType;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
@@ -1653,18 +1654,26 @@ public class AST2CPPTests extends AST2BaseTest {
// friend struct Glob;
// };
public void testBug84692() throws Exception {
- IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP);
- CPPNameCollector col = new CPPNameCollector();
- tu.accept(col);
-
- assertEquals(col.size(), 9);
-
- ICPPClassType Node = (ICPPClassType) col.getName(1).resolveBinding();
- ICPPClassType Data = (ICPPClassType) col.getName(3).resolveBinding();
- assertSame(Data.getScope(), tu.getScope());
-
- assertInstances(col, Node, 3);
- assertInstances(col, Data, 2);
+ // also tests bug 234042.
+ boolean old= CPPASTName.fAllowRecursionBindings;
+ CPPASTName.fAllowRecursionBindings= false;
+ try {
+ IASTTranslationUnit tu = parse(getAboveComment(), ParserLanguage.CPP);
+ CPPNameCollector col = new CPPNameCollector();
+ tu.accept(col);
+
+ assertEquals(col.size(), 9);
+
+ ICPPClassType Node = (ICPPClassType) col.getName(1).resolveBinding();
+ ICPPClassType Data = (ICPPClassType) col.getName(3).resolveBinding();
+ assertSame(Data.getScope(), tu.getScope());
+
+ assertInstances(col, Node, 3);
+ assertInstances(col, Data, 2);
+ }
+ finally {
+ CPPASTName.fAllowRecursionBindings= old;
+ }
}
// namespace B { int b; }
diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java
index 135d3c97a2d..44590f0e434 100644
--- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java
+++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2Tests.java
@@ -4736,4 +4736,23 @@ public class AST2Tests extends AST2BaseTest {
assertFalse(t instanceof ITypedef);
}
}
+
+ // int a;
+ // int b= a; // ref
+ // struct S;
+ // typedef struct S S; // td
+ public void testRedefineStructInScopeThatIsFullyResolved() throws Exception {
+ final boolean[] isCpps= {false, true};
+ String code= getAboveComment();
+ for (boolean isCpp : isCpps) {
+ BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), isCpp);
+ ba.assertNonProblem("a; // ref", 1);
+ // now scope is fully resolved
+ ICompositeType ct= ba.assertNonProblem("S;", 1, ICompositeType.class);
+ ITypedef td= ba.assertNonProblem("S; // td", 1, ITypedef.class);
+ IType t= td.getType();
+ assertFalse(t instanceof IProblemBinding);
+ assertSame(t, ct);
+ }
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTName.java
index b73de62ca4a..ebe12ad830b 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTName.java
@@ -1,14 +1,14 @@
/*******************************************************************************
- * Copyright (c) 2004, 2007 IBM Corporation and others.
+ * Copyright (c) 2004, 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM - Initial API and implementation
- * Markus Schorn (Wind River Systems)
- * Bryan Wilkinson (QNX)
+ * IBM - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
+ * Bryan Wilkinson (QNX)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
@@ -51,6 +51,18 @@ public interface IASTName extends IASTNode, IName {
*/
public IBinding resolveBinding();
+ /**
+ * Get the role of this name. If the name needs to be resolved to determine that and
+ * allowResolution
is set to false
, then {@link IASTNameOwner#r_unclear}
+ * is returned.
+ *
+ * @param allowResolution whether or not resolving the name is allowed.
+ * @return {@link IASTNameOwner#r_definition}, {@link IASTNameOwner#r_declaration},
+ * {@link IASTNameOwner#r_reference}, {@link IASTNameOwner#r_unclear}.
+ * @since 5.0
+ */
+ public int getRoleOfName(boolean allowResolution);
+
/**
* Return the completion context for this name.
*
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNameOwner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNameOwner.java
index 2e0eff2166d..64b451426a5 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNameOwner.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IASTNameOwner.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2005 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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,11 +7,12 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
+ * Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.dom.ast;
/**
- * This interface repesents a mechanism for a name to discover more information about it's parent.
+ * This interface represents a mechanism for a name to discover more information about it's parent.
* All interfaces that claim ownership/residence of a name should extend this interface.
*
* @author jcamelon
@@ -39,9 +40,9 @@ public interface IASTNameOwner {
/**
* Get the role for the name.
*
- * @param n IASTName
- * @return r_declaration, r_reference or r_unclear.
+ * @param name the name to determine the role for.
+ * @return r_definition, r_declaration, r_reference or r_unclear.
*/
- public int getRoleForName( IASTName n );
+ public int getRoleForName(IASTName name);
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalNameOwner.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalNameOwner.java
new file mode 100644
index 00000000000..3296032b76c
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/IASTInternalNameOwner.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * Copyright (c) 2008 Wind River Systems, Inc. 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
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * Markus Schorn - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.cdt.internal.core.dom.parser;
+
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
+
+/**
+ * Provides additional methods for internal use by the name resolution.
+ */
+public interface IASTInternalNameOwner extends IASTNameOwner {
+
+ /**
+ * Get the role for the name. If the name needs to be resolved to determine that and
+ * allowResolution
is set to false
, then {@link IASTNameOwner#r_unclear}
+ * is returned.
+ *
+ * @param n a name to determine the role of.
+ * @param allowResolution whether or not resolving the name is allowed.
+ * @return r_definition, r_declaration, r_reference or r_unclear.
+ */
+ public int getRoleForName(IASTName n, boolean allowResolution);
+}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java
index 53dcdf0d6fb..d4721e269a0 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java
@@ -1,15 +1,15 @@
/*******************************************************************************
- * Copyright (c) 2005, 2007 IBM Corporation and others.
+ * Copyright (c) 2005, 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
- * IBM Rational Software - Initial API and implementation
- * Markus Schorn (Wind River Systems)
- * Yuan Zhang / Beth Tibbitts (IBM Research)
- * Bryan Wilkinson (QNX)
+ * IBM Rational Software - Initial API and implementation
+ * Markus Schorn (Wind River Systems)
+ * Yuan Zhang / Beth Tibbitts (IBM Research)
+ * Bryan Wilkinson (QNX)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.c;
@@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage;
+import org.eclipse.cdt.internal.core.dom.parser.IASTInternalNameOwner;
/**
* @author jcamelon
@@ -117,6 +118,17 @@ public class CASTName extends CASTNode implements IASTName, IASTCompletionContex
}
+ public int getRoleOfName(boolean allowResolution) {
+ IASTNode parent = getParent();
+ if (parent instanceof IASTInternalNameOwner) {
+ return ((IASTInternalNameOwner) parent).getRoleForName(this, allowResolution);
+ }
+ if (parent instanceof IASTNameOwner) {
+ return ((IASTNameOwner) parent).getRoleForName(this);
+ }
+ return IASTNameOwner.r_unclear;
+ }
+
public boolean isDeclaration() {
IASTNode parent = getParent();
if (parent instanceof IASTNameOwner) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTElaboratedTypeSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTElaboratedTypeSpecifier.java
index 55c16d28013..3fcb16626a7 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTElaboratedTypeSpecifier.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTElaboratedTypeSpecifier.java
@@ -11,20 +11,22 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
-import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.internal.core.dom.parser.IASTInternalNameOwner;
/**
* @author jcamelon
*/
public class CPPASTElaboratedTypeSpecifier extends CPPASTBaseDeclSpecifier
- implements ICPPASTElaboratedTypeSpecifier {
+ implements ICPPASTElaboratedTypeSpecifier, IASTInternalNameOwner {
private int kind;
private IASTName name;
@@ -78,24 +80,36 @@ public class CPPASTElaboratedTypeSpecifier extends CPPASTBaseDeclSpecifier
}
public int getRoleForName(IASTName n) {
+ return getRoleForName(n, true);
+ }
+
+ public int getRoleForName(IASTName n, boolean allowResolution) {
if (n != name) return r_unclear;
IASTNode parent = getParent();
- if (!(parent instanceof IASTDeclaration))
- return r_reference;
-
if (parent instanceof IASTSimpleDeclaration) {
IASTDeclarator[] dtors = ((IASTSimpleDeclaration)parent).getDeclarators();
if (dtors.length == 0)
return r_declaration;
}
- //can't tell, resolve the binding
- IBinding binding = name.resolveBinding();
- if (binding instanceof ICPPInternalBinding) {
- IASTNode[] decls = ((ICPPInternalBinding)binding).getDeclarations();
- if (ArrayUtil.contains(decls, name))
- return r_declaration;
+ // 7.1.5.3.2: check for simple form , then it may be a declaration
+ final int kind= getKind();
+ if (kind == k_class || kind == k_union || kind == k_struct) {
+ if (name instanceof ICPPASTQualifiedName == false
+ && name instanceof ICPPASTTemplateId == false) {
+ IBinding binding = allowResolution ? name.resolveBinding() : name.getBinding();
+ if (binding != null) {
+ if (binding instanceof ICPPInternalBinding) {
+ IASTNode[] decls = ((ICPPInternalBinding)binding).getDeclarations();
+ if (ArrayUtil.contains(decls, name))
+ return r_declaration;
+ }
+ return r_reference;
+ }
+ // resolution is not allowed.
+ return r_unclear;
+ }
}
return r_reference;
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java
index 0ce37b74c82..dcc3f451d08 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java
@@ -30,19 +30,24 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage;
+import org.eclipse.cdt.internal.core.dom.parser.IASTInternalNameOwner;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
+import org.eclipse.core.runtime.Assert;
/**
* @author jcamelon
*/
public class CPPASTName extends CPPASTNode implements IASTName, IASTCompletionContext {
+ /**
+ * For test-purposes, only.
+ */
+ public static boolean fAllowRecursionBindings= true;
final static class RecursionResolvingBinding extends ProblemBinding {
public RecursionResolvingBinding(IASTName node) {
super(node, IProblemBinding.SEMANTIC_RECURSION_IN_LOOKUP, node.toCharArray());
- if (fShowRecursionProblems)
- System.out.println(getMessage());
+ Assert.isTrue(fAllowRecursionBindings, getMessage());
}
}
@@ -51,7 +56,6 @@ public class CPPASTName extends CPPASTNode implements IASTName, IASTCompletionCo
static final int MAX_RESOLUTION_DEPTH = 5;
- private static boolean fShowRecursionProblems = false;
private char[] name;
private IBinding binding = null;
@@ -209,6 +213,17 @@ public class CPPASTName extends CPPASTNode implements IASTName, IASTCompletionCo
}
return true;
}
+
+ public int getRoleOfName(boolean allowResolution) {
+ IASTNode parent = getParent();
+ if (parent instanceof IASTInternalNameOwner) {
+ return ((IASTInternalNameOwner) parent).getRoleForName(this, allowResolution);
+ }
+ if (parent instanceof IASTNameOwner) {
+ return ((IASTNameOwner) parent).getRoleForName(this);
+ }
+ return IASTNameOwner.r_unclear;
+ }
public boolean isDeclaration() {
IASTNode parent = getParent();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java
index 11558e19c62..9d651bd4b4a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTQualifiedName.java
@@ -37,6 +37,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.Linkage;
+import org.eclipse.cdt.internal.core.dom.parser.IASTInternalNameOwner;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
/**
@@ -182,6 +183,17 @@ public class CPPASTQualifiedName extends CPPASTNode implements
return true;
}
+
+ public int getRoleOfName(boolean allowResolution) {
+ IASTNode parent = getParent();
+ if (parent instanceof IASTInternalNameOwner) {
+ return ((IASTInternalNameOwner) parent).getRoleForName(this, allowResolution);
+ }
+ if (parent instanceof IASTNameOwner) {
+ return ((IASTNameOwner) parent).getRoleForName(this);
+ }
+ return IASTNameOwner.r_unclear;
+ }
public boolean isDeclaration() {
IASTNode parent = getParent();
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java
index c8c46ad0f0c..9329912db9a 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTTemplateId.java
@@ -26,6 +26,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.Linkage;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
+import org.eclipse.cdt.internal.core.dom.parser.IASTInternalNameOwner;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
/**
@@ -170,6 +171,17 @@ public class CPPASTTemplateId extends CPPASTNode implements ICPPASTTemplateId, I
}
}
+ public int getRoleOfName(boolean allowResolution) {
+ IASTNode parent = getParent();
+ if (parent instanceof IASTInternalNameOwner) {
+ return ((IASTInternalNameOwner) parent).getRoleForName(this, allowResolution);
+ }
+ if (parent instanceof IASTNameOwner) {
+ return ((IASTNameOwner) parent).getRoleForName(this);
+ }
+ return IASTNameOwner.r_unclear;
+ }
+
public boolean isDefinition() {
IASTNode parent = getParent();
if (parent instanceof IASTNameOwner) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
index 3699949b21b..1e411a0e4c4 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java
@@ -44,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
@@ -1649,7 +1650,7 @@ public class CPPSemantics {
boolean declaredBefore = declaredBefore(o, name, indexBased);
boolean checkResolvedNamesOnly= false;
if (!data.checkWholeClassScope && !declaredBefore) {
- if (!name.isReference()) {
+ if (name.getRoleOfName(false) != IASTNameOwner.r_reference) {
checkResolvedNamesOnly= true;
declaredBefore= true;
} else {
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 bdbbc9e398f..a3d685a6ce9 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
@@ -532,10 +532,9 @@ public class CPPVisitor {
}
while (tmpNode instanceof IASTDeclarator);
- IASTName name = declarator.getName();
+ IASTName name= declarator.getName();
if (name instanceof ICPPASTQualifiedName) {
- IASTName[] ns = ((ICPPASTQualifiedName)name).getNames();
- name = ns[ns.length - 1];
+ name= ((ICPPASTQualifiedName)name).getLastName();
}
ASTNodeProperty prop = parent.getPropertyInParent();
@@ -613,7 +612,13 @@ public class CPPVisitor {
}
return new ProblemBinding(name, IProblemBinding.SEMANTIC_INVALID_REDECLARATION, name.toCharArray());
}
- binding = new CPPTypedef(name);
+ // if we don't resolve the target type first, we get a problem binding in case the typedef
+ // redeclares the target type:
+ // typedef struct S S;
+ IType targetType= CPPVisitor.createType(declarator);
+ CPPTypedef td= new CPPTypedef(name);
+ td.setType(targetType);
+ binding = td;
} else if (funcDeclarator != null) {
if (binding instanceof ICPPInternalBinding && binding instanceof IFunction) {
IFunction function = (IFunction) binding;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java
index 02191d88239..7ad3c74dc81 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/scanner/ASTPreprocessorName.java
@@ -16,6 +16,7 @@ import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNameOwner;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTNodeLocation;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
@@ -66,6 +67,10 @@ class ASTPreprocessorName extends ASTPreprocessorNode implements IASTName {
return new String(fName);
}
public void setBinding(IBinding binding) {assert false;}
+
+ public int getRoleOfName(boolean allowResolution) {
+ return IASTNameOwner.r_unclear;
+ }
}
class ASTPreprocessorDefinition extends ASTPreprocessorName {
@@ -78,6 +83,11 @@ class ASTPreprocessorDefinition extends ASTPreprocessorName {
public boolean isDefinition() {
return true;
}
+
+ @Override
+ public int getRoleOfName(boolean allowResolution) {
+ return IASTNameOwner.r_definition;
+ }
}
@@ -132,6 +142,11 @@ class ASTMacroReferenceName extends ASTPreprocessorName {
fImageLocationInfo= imgLocationInfo;
}
+ @Override
+ public int getRoleOfName(boolean allowResolution) {
+ return IASTNameOwner.r_unclear;
+ }
+
@Override
public boolean isReference() {
return true;
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java
index 5d79f606fdd..d8a2446c38c 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/PDOMASTAdapter.java
@@ -115,6 +115,10 @@ public class PDOMASTAdapter {
return fDelegate.getTranslationUnit();
}
+ public int getRoleOfName(boolean allowResolution) {
+ return fDelegate.getRoleOfName(allowResolution);
+ }
+
public boolean isDeclaration() {
return fDelegate.isDeclaration();
}