Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMarkus Schorn2010-11-04 13:08:37 +0000
committerMarkus Schorn2010-11-04 13:08:37 +0000
commit67ae4bb5a00e798580560ae1fbf284db8613bba7 (patch)
treebaf098019658dd998797842902772d786e51da7c
parent12d516a0fbf65f231846b5dcd3ee2c7d8874c0c0 (diff)
downloadorg.eclipse.cdt-67ae4bb5a00e798580560ae1fbf284db8613bba7.tar.gz
org.eclipse.cdt-67ae4bb5a00e798580560ae1fbf284db8613bba7.tar.xz
org.eclipse.cdt-67ae4bb5a00e798580560ae1fbf284db8613bba7.zip
Bug 328802: Overriding a method which is declared with a using declaration.
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java18
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java2
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPVisitor.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java65
4 files changed, 85 insertions, 6 deletions
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 87d89a67d59..48083ddbc42 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
@@ -9263,4 +9263,22 @@ public class AST2CPPTests extends AST2BaseTest {
public void testRangeBasedForLoop_327223() throws Exception {
parseAndCheckBindings();
}
+
+ // struct A{};
+ // struct B : A {};
+ // struct C {
+ // A& get();
+ // };
+ // struct D : C {
+ // using C::get;
+ // B& get();
+ // };
+ //
+ // void func(A&) {}
+ // void test(D& c) {
+ // func(c.get()); // error.
+ // }
+ public void testOverrideUsingDeclaredMethod_328802() throws Exception {
+ parseAndCheckBindings();
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java
index 43b600965d7..116628d8186 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPScope.java
@@ -191,7 +191,7 @@ abstract public class CPPScope implements ICPPASTInternalScope {
}
public IBinding getBindingInAST(IASTName name, boolean forceResolve) {
- IBinding[] bs= getBindingsInAST(name, forceResolve, false, false, true);
+ IBinding[] bs= getBindingsInAST(name, forceResolve, false, false, false);
return CPPSemantics.resolveAmbiguities(name, bs);
}
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 15a7c11e7e9..160a611f007 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
@@ -437,6 +437,12 @@ public class CPPVisitor extends ASTQueries {
}
if (scope != null) {
binding = scope.getBinding(elabType.getName(), false);
+ if (binding instanceof ICPPUsingDeclaration) {
+ IBinding[] expanded = ((ICPPUsingDeclaration) binding).getDelegates();
+ if (expanded.length == 1 && expanded[0] instanceof IType) {
+ binding= expanded[0];
+ }
+ }
}
if (!(binding instanceof ICPPInternalBinding) || !(binding instanceof ICPPClassType) && name.isActive()) {
if (elabType.getKind() != IASTElaboratedTypeSpecifier.k_enum) {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java
index 6d2c0e06e77..b7e933cf1a3 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/FunctionCost.java
@@ -23,6 +23,8 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates.TypeSelection;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.Cost.DeferredUDC;
@@ -146,10 +148,12 @@ class FunctionCost {
haveBetter |= (cmp < 0);
}
+ final ICPPFunction f1 = getFunction();
+ final ICPPFunction f2 = other.getFunction();
if (!haveWorse && !haveBetter) {
// If they are both template functions, we can order them that way
- ICPPFunctionTemplate asTemplate= asTemplate(getFunction());
- ICPPFunctionTemplate otherAsTemplate= asTemplate(other.getFunction());
+ ICPPFunctionTemplate asTemplate= asTemplate(f1);
+ ICPPFunctionTemplate otherAsTemplate= asTemplate(f2);
final boolean isTemplate = asTemplate != null;
final boolean otherIsTemplate = otherAsTemplate != null;
@@ -159,7 +163,7 @@ class FunctionCost {
} else if (!isTemplate && otherIsTemplate) {
haveBetter = true;
} else if (isTemplate && otherIsTemplate) {
- TypeSelection ts= SemanticUtil.isConversionOperator(getFunction()) ? RETURN_TYPE : PARAMETERS;
+ TypeSelection ts= SemanticUtil.isConversionOperator(f1) ? RETURN_TYPE : PARAMETERS;
int order = CPPTemplates.orderFunctionTemplates(otherAsTemplate, asTemplate, ts);
if (order < 0) {
haveBetter= true;
@@ -169,9 +173,14 @@ class FunctionCost {
}
}
- // if we are ambiguous at this point prefer non-index bindings
if (haveBetter == haveWorse) {
- return -CPPSemantics.compareByRelevance(tu, getFunction(), other.getFunction());
+ // 7.3.3-15 Using declarations in classes can be overridden
+ int cmp= overridesUsingDeclaration(f1, f2);
+ if (cmp != 0)
+ return cmp;
+
+ // At this point prefer non-index bindings
+ return -CPPSemantics.compareByRelevance(tu, f1, f2);
}
if (haveBetter)
@@ -180,6 +189,52 @@ class FunctionCost {
return 1;
}
+ private int overridesUsingDeclaration(ICPPFunction f1, ICPPFunction f2) {
+ if (f1.takesVarArgs() != f2.takesVarArgs())
+ return 0;
+ if (!(f1 instanceof ICPPMethod && f2 instanceof ICPPMethod))
+ return 0;
+
+ final ICPPMethod m1 = (ICPPMethod) f1;
+ final ICPPMethod m2 = (ICPPMethod) f2;
+ ICPPClassType o1= m1.getClassOwner();
+ ICPPClassType o2= m2.getClassOwner();
+ if (o1.isSameType(o2))
+ return 0;
+
+ final ICPPFunctionType ft1 = m1.getType();
+ final ICPPFunctionType ft2 = m2.getType();
+ if (ft1.isConst() != ft2.isConst() || ft2.isVolatile() != ft2.isVolatile())
+ return 0;
+
+ if (!parameterTypesMatch(ft1, ft2))
+ return 0;
+
+ int diff= SemanticUtil.calculateInheritanceDepth(o2, o1);
+ if (diff >= 0)
+ return diff;
+ return -SemanticUtil.calculateInheritanceDepth(o1, o2);
+ }
+
+ private boolean parameterTypesMatch(final ICPPFunctionType ft1, final ICPPFunctionType ft2) {
+ IType[] p1= ft1.getParameterTypes();
+ IType[] p2= ft2.getParameterTypes();
+ if (p1.length != p2.length) {
+ if (p1.length == 0)
+ return p2.length == 1 && SemanticUtil.isVoidType(p2[0]);
+ if (p2.length == 0)
+ return p1.length == 1 && SemanticUtil.isVoidType(p1[0]);
+ return false;
+ }
+
+ for (int i = 0; i < p2.length; i++) {
+ if (!p1[i].isSameType(p2[i])) {
+ return false;
+ }
+ }
+ return true;
+ }
+
public boolean mustBeWorse(FunctionCost other) {
if (other == null)
return false;

Back to the top