Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java30
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java6
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java365
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPSemantics.java237
-rw-r--r--core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java34
5 files changed, 432 insertions, 240 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 d6365da103e..b9fceec07a0 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
@@ -7237,4 +7237,34 @@ public class AST2CPPTests extends AST2BaseTest {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
}
+
+ // class IBase {
+ // public:
+ // virtual void base() = 0;
+ // };
+ //
+ // class IDerived : virtual public IBase {
+ // public:
+ // virtual void derived() = 0;
+ // };
+ //
+ // class BaseImplHelper : virtual public IBase {
+ // public:
+ // virtual void base() {}
+ // };
+ //
+ // class Derived : virtual public IDerived, public BaseImplHelper {
+ // public:
+ // virtual void derived() {}
+ // };
+ //
+ // int main() {
+ // Derived d;
+ // d.base(); // Parser log reports ambiguity on 'base'
+ // return 0;
+ // }
+ public void testHiddenVirtualBase_Bug282993() throws Exception {
+ final String code = getAboveComment();
+ parseAndCheckBindings(code, ParserLanguage.CPP);
+ }
}
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
index 69f00477a64..19730f261df 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/ProblemBinding.java
@@ -41,7 +41,7 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
protected char[] arg;
protected IASTNode node;
private final String message = null;
- private final IBinding[] candidateBindings;
+ private IBinding[] candidateBindings;
public ProblemBinding(IASTName name, int id) {
this(name, id, null, null);
@@ -73,6 +73,10 @@ public class ProblemBinding extends PlatformObject implements IProblemBinding, I
public IBinding[] getCandidateBindings() {
return candidateBindings != null ? candidateBindings : IBinding.EMPTY_BINDING_ARRAY;
}
+
+ public void setCandidateBindings(IBinding[] foundBindings) {
+ candidateBindings= foundBindings;
+ }
protected static final String[] errorMessages;
static {
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java
new file mode 100644
index 00000000000..4c4cd2dc1bc
--- /dev/null
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/BaseClassLookup.java
@@ -0,0 +1,365 @@
+/*******************************************************************************
+ * Copyright (c) 2009 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.cpp.semantics;
+
+import java.util.ArrayList;
+import java.util.BitSet;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+
+import org.eclipse.cdt.core.dom.ast.DOMException;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.IProblemBinding;
+import org.eclipse.cdt.core.dom.ast.IScope;
+import org.eclipse.cdt.core.dom.ast.IType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
+import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
+import org.eclipse.cdt.core.index.IIndexFileSet;
+import org.eclipse.cdt.core.parser.util.ArrayUtil;
+import org.eclipse.cdt.core.parser.util.CharArrayObjectMap;
+import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope;
+import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
+
+/**
+ * Helper class for performing the base class lookup. First a directed graph without loops is computed to represent the base
+ * class hierarchy up to those bases for which the lookup finds matches. Next, from these leaves we search for virtual bases
+ * that are hidden. With this information the matches are extracted from the graph.
+ */
+class BaseClassLookup {
+ public static void lookupInBaseClasses(LookupData data, ICPPClassScope classScope, IIndexFileSet fileSet) {
+ if (classScope == null)
+ return;
+
+ final ICPPClassType classType= classScope.getClassType();
+ if (classType == null)
+ return;
+
+ final HashMap<IScope, BaseClassLookup> infoMap = new HashMap<IScope, BaseClassLookup>();
+ BaseClassLookup rootInfo= lookupInBaseClass(data, null, false, classType, fileSet, infoMap, 0);
+ if (data.contentAssist) {
+ rootInfo.collectResultForContentAssist(data);
+ } else {
+ hideVirtualBases(rootInfo, infoMap);
+ IBinding[] result= rootInfo.collectResult(data, true, null);
+ verifyResult(data, result);
+ }
+ }
+
+
+ private final ICPPClassType fClassType;
+ private IBinding[] fBindings;
+ private List<BaseClassLookup> fChildren= Collections.emptyList();
+ private BitSet fVirtual;
+ private boolean fHiddenAsVirtualBase= false;
+ private boolean fPropagationDone= false;
+ private boolean fCollected;
+ private boolean fCollectedAsRegularBase;
+
+ private BaseClassLookup(ICPPClassType type) {
+ fClassType= type;
+ }
+ ICPPClassType getClassType() {
+ return fClassType;
+ }
+
+ IBinding[] getResult() {
+ return fBindings;
+ }
+ boolean containsVirtualBase() {
+ return (fVirtual != null && fVirtual.nextSetBit(0) >= 0);
+ }
+ boolean hasMatches() {
+ return fBindings != null && fBindings.length > 0 && fBindings[0] != null;
+ }
+
+ public void addBase(boolean virtual, BaseClassLookup baseInfo) {
+ if (virtual && fHiddenAsVirtualBase)
+ return;
+
+ if (fChildren.isEmpty()) {
+ fChildren= new ArrayList<BaseClassLookup>();
+ fVirtual= new BitSet();
+ }
+ fVirtual.set(fChildren.size(), virtual);
+ fChildren.add(baseInfo);
+ }
+
+ public void setResult(IBinding[] bindings) {
+ fBindings= bindings;
+ }
+
+ public void setHiddenAsVirtualBase() {
+ fHiddenAsVirtualBase= true;
+ }
+ public void propagateHiddenAsVirtual() {
+ if (fPropagationDone)
+ return;
+ fPropagationDone= true;
+ for (int i=0; i<fChildren.size(); i++) {
+ BaseClassLookup child = fChildren.get(i);
+ if (fVirtual.get(i)) {
+ child.setHiddenAsVirtualBase();
+ }
+ child.propagateHiddenAsVirtual();
+ }
+ }
+
+ public boolean containsNonStaticMember() {
+ for (IBinding binding : fBindings) {
+ if (binding == null)
+ return false;
+ if (binding instanceof ICPPMember) {
+ try {
+ if (!((ICPPMember) binding).isStatic())
+ return true;
+ } catch (DOMException e) {
+ // treat as non-static
+ }
+ }
+ }
+ return false;
+ }
+
+ static BaseClassLookup lookupInBaseClass(LookupData data, ICPPClassScope baseClassScope, boolean isVirtual, ICPPClassType root, IIndexFileSet fileSet, HashMap<IScope, BaseClassLookup> infoMap, int depth) {
+ if (depth++ > CPPSemantics.MAX_INHERITANCE_DEPTH)
+ return null;
+
+ if (baseClassScope != null) {
+ BaseClassLookup info= infoMap.get(baseClassScope);
+ if (info != null) {
+ // avoid loops
+ if (info.getResult() == null) {
+ data.problem = new ProblemBinding(null, IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE, root.getNameCharArray());
+ return null;
+ }
+ return info;
+ }
+ }
+
+ // this is the first time to handle the class
+ BaseClassLookup result;
+ IBinding[] matches= IBinding.EMPTY_BINDING_ARRAY;
+ if (baseClassScope == null) {
+ result= new BaseClassLookup(root);
+ try {
+ infoMap.put(root.getCompositeScope(), result);
+ } catch (DOMException e) {
+ // ignore
+ }
+ } else {
+ result= new BaseClassLookup(baseClassScope.getClassType());
+ infoMap.put(baseClassScope, result);
+ try {
+ IBinding[] members= CPPSemantics.getBindingsFromScope(baseClassScope, fileSet, data);
+ if (data.typesOnly) {
+ CPPSemantics.removeObjects(members);
+ }
+ if (members != null && members.length > 0 && members[0] != null) {
+ if (data.prefixLookup) {
+ matches= members;
+ } else {
+ result.setResult(members);
+ return result;
+ }
+ }
+ } catch (DOMException e) {
+ // continue the lookup
+ }
+ }
+
+ // there is no result in the baseClass itself or we do content assist, we have to examine its base-classes
+ ICPPClassType baseClass= result.getClassType();
+ if (baseClass != null) {
+ ICPPBase[] grandBases= null;
+ try {
+ grandBases= baseClass.getBases();
+ } catch (DOMException e) {
+ // assume that there are no bases
+ }
+ if (grandBases != null && grandBases.length > 0) {
+ HashSet<IBinding> grandBaseBindings= grandBases.length > 1 ? new HashSet<IBinding>() : null;
+ for (ICPPBase grandBase : grandBases) {
+ if (grandBase instanceof IProblemBinding)
+ continue;
+
+ try {
+ IBinding grandBaseBinding = grandBase.getBaseClass();
+ if (!(grandBaseBinding instanceof ICPPClassType)) {
+ // 14.6.2.3 scope is not examined
+ if (grandBaseBinding instanceof ICPPUnknownBinding) {
+ if (data.skippedScope == null)
+ data.skippedScope= root;
+ }
+ continue;
+ }
+
+ final ICPPClassType grandBaseClass = (ICPPClassType) grandBaseBinding;
+ if (grandBaseBindings != null && !grandBaseBindings.add(grandBaseClass))
+ continue;
+
+ final IScope grandBaseScope= grandBaseClass.getCompositeScope();
+ if (grandBaseScope == null || grandBaseScope instanceof ICPPInternalUnknownScope) {
+ // 14.6.2.3 scope is not examined
+ if (data.skippedScope == null)
+ data.skippedScope= root;
+ continue;
+ }
+ if (!(grandBaseScope instanceof ICPPClassScope))
+ continue;
+
+ BaseClassLookup baseInfo= lookupInBaseClass(data, (ICPPClassScope) grandBaseScope, grandBase.isVirtual(), root, fileSet, infoMap, depth);
+ if (baseInfo != null)
+ result.addBase(grandBase.isVirtual(), baseInfo);
+ } catch (DOMException e) {
+ // move on to next base
+ }
+ }
+ }
+ }
+ result.setResult(matches);
+ return result;
+ }
+ static void hideVirtualBases(BaseClassLookup rootInfo, HashMap<IScope, BaseClassLookup> infoMap) {
+ boolean containsVirtualBase= false;
+ final BaseClassLookup[] allInfos = infoMap.values().toArray(new BaseClassLookup[infoMap.size()]);
+ for (BaseClassLookup info : allInfos) {
+ if (info.containsVirtualBase()) {
+ containsVirtualBase= true;
+ break;
+ }
+ }
+ if (containsVirtualBase) {
+ for (BaseClassLookup info : allInfos) {
+ if (info.hasMatches()) {
+ info.hideVirtualBases(infoMap, 0);
+ }
+ }
+ }
+ }
+
+ void hideVirtualBases(HashMap<IScope, BaseClassLookup> infoMap, int depth) {
+ if (depth++ > CPPSemantics.MAX_INHERITANCE_DEPTH)
+ return;
+
+ if (fClassType != null) {
+ ICPPBase[] bases= null;
+ try {
+ bases= fClassType.getBases();
+ } catch (DOMException e) {
+ // assume that there are no bases
+ }
+ if (bases != null && bases.length > 0) {
+ for (ICPPBase base : bases) {
+ if (base instanceof IProblemBinding)
+ continue;
+
+ try {
+ IBinding baseBinding = base.getBaseClass();
+ if (!(baseBinding instanceof ICPPClassType)) {
+ continue;
+ }
+
+ final ICPPClassType baseClass = (ICPPClassType) baseBinding;
+ final IScope baseScope= baseClass.getCompositeScope();
+ if (!(baseScope instanceof ICPPClassScope))
+ continue;
+
+ BaseClassLookup baseInfo= infoMap.get(baseScope);
+ if (baseInfo != null) {
+ if (base.isVirtual()) {
+ baseInfo.setHiddenAsVirtualBase();
+ }
+ baseInfo.propagateHiddenAsVirtual();
+ } else {
+ // mark to catch recursions
+ baseInfo= new BaseClassLookup(baseClass);
+ infoMap.put(baseScope, baseInfo);
+ baseInfo.hideVirtualBases(infoMap, depth);
+ }
+ } catch (DOMException e) {
+ // move on to next base
+ }
+ }
+ }
+ }
+ }
+ public void collectResultForContentAssist(LookupData data) {
+ if (fCollected)
+ return;
+ fCollected= true;
+
+ data.foundItems = CPPSemantics.mergePrefixResults((CharArrayObjectMap) data.foundItems, fBindings, true);
+ for (int i=0; i<fChildren.size(); i++) {
+ BaseClassLookup child = fChildren.get(i);
+ child.collectResultForContentAssist(data);
+ }
+ }
+
+ public IBinding[] collectResult(LookupData data, boolean asVirtualBase, IBinding[] result) {
+ if (asVirtualBase) {
+ if (fHiddenAsVirtualBase)
+ return result;
+ } else {
+ if (fCollectedAsRegularBase && data.problem == null && containsNonStaticMember()) {
+ data.problem= new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP);
+ }
+ fCollectedAsRegularBase= true;
+ }
+
+ if (fCollected)
+ return result;
+ fCollected= true;
+
+ result= (IBinding[]) ArrayUtil.addAll(IBinding.class, result, fBindings);
+ for (int i=0; i<fChildren.size(); i++) {
+ BaseClassLookup child = fChildren.get(i);
+ result= child.collectResult(data, fVirtual.get(i), result);
+ }
+ return result;
+ }
+
+ static void verifyResult(LookupData data, IBinding[] bindings) {
+ bindings= (IBinding[]) ArrayUtil.trim(IBinding.class, bindings);
+ if (bindings.length == 0)
+ return;
+
+ if (data.problem != null) {
+ data.problem.setCandidateBindings(bindings);
+ } else {
+ ICPPClassType uniqueOwner= null;
+ for (IBinding b : bindings) {
+ if (!(b instanceof IType)) {
+ try {
+ IBinding owner= b.getOwner();
+ if (owner instanceof ICPPClassType) {
+ final ICPPClassType classOwner = (ICPPClassType) owner;
+ if (uniqueOwner == null) {
+ uniqueOwner= classOwner;
+ } else if (!uniqueOwner.isSameType(classOwner)) {
+ data.problem= new ProblemBinding(data.astName, IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, bindings);
+ return;
+ }
+ }
+ } catch (DOMException e) {
+ // ignore
+ }
+ }
+ }
+ }
+
+ data.foundItems = ArrayUtil.addAll(Object.class, (Object[]) data.foundItems, bindings);
+ }
+} \ No newline at end of file
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 370f6c8c4eb..188c76704fb 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
@@ -176,7 +176,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding;
-import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
@@ -192,7 +191,7 @@ public class CPPSemantics {
/**
* The maximum depth to search ancestors before assuming infinite looping.
*/
- public static final int MAX_INHERITANCE_DEPTH= 10;
+ public static final int MAX_INHERITANCE_DEPTH= 16;
public static final ASTNodeProperty STRING_LOOKUP_PROPERTY =
new ASTNodeProperty("CPPSemantics.STRING_LOOKUP_PROPERTY - STRING_LOOKUP"); //$NON-NLS-1$
@@ -207,8 +206,6 @@ public class CPPSemantics {
// special return value for costForFunctionCall
private static final FunctionCost CONTAINS_DEPENDENT_TYPES = new FunctionCost(null, 0);
-
-
static protected IBinding resolveBinding(IASTName name) {
if (traceBindingResolution) {
for (int i = 0; i < traceIndent; i++)
@@ -681,7 +678,7 @@ public class CPPSemantics {
* @param scoped
* @return
*/
- private static CharArrayObjectMap mergePrefixResults(CharArrayObjectMap dest, Object source, boolean scoped) {
+ static CharArrayObjectMap mergePrefixResults(CharArrayObjectMap dest, Object source, boolean scoped) {
if (source == null) return dest;
CharArrayObjectMap resultMap = (dest != null) ? dest : new CharArrayObjectMap(2);
@@ -848,7 +845,7 @@ public class CPPSemantics {
}
if (!data.usingDirectivesOnly && scope instanceof ICPPClassScope) {
- mergeResults(data, lookupInParents(data, scope, ((ICPPClassScope) scope).getClassType(), fileSet), true);
+ BaseClassLookup.lookupInBaseClasses(data, (ICPPClassScope) scope, fileSet);
}
if (!data.contentAssist && (data.problem != null || data.hasResults()))
@@ -968,7 +965,7 @@ public class CPPSemantics {
return result[0];
}
- private static IBinding[] getBindingsFromScope(ICPPScope scope, final IIndexFileSet fileSet, LookupData data) throws DOMException {
+ static IBinding[] getBindingsFromScope(ICPPScope scope, final IIndexFileSet fileSet, LookupData data) throws DOMException {
IBinding[] bindings;
if (scope instanceof ICPPASTInternalScope) {
bindings= ((ICPPASTInternalScope) scope).getBindings(data.astName, true, data.prefixLookup, fileSet, data.checkPointOfDecl);
@@ -978,7 +975,7 @@ public class CPPSemantics {
return bindings;
}
- private static void removeObjects(final IBinding[] bindings) {
+ static void removeObjects(final IBinding[] bindings) {
final int length = bindings.length;
int pos= 0;
for (int i = 0; i < length; i++) {
@@ -1033,230 +1030,6 @@ public class CPPSemantics {
return (ICPPScope) parentScope;
}
- private static Object lookupInParents(LookupData data, ICPPScope lookIn, ICPPClassType overallScope, IIndexFileSet fileSet) {
- if (lookIn instanceof ICPPClassScope == false)
- return null;
-
- final ICPPClassType classType= ((ICPPClassScope)lookIn).getClassType();
- if (classType == null)
- return null;
-
- ICPPBase[] bases= null;
- try {
- bases= classType.getBases();
- } catch (DOMException e) {
- // assume that there are no bases
- return null;
- }
- if (bases == null || bases.length == 0)
- return null;
-
- Object inherited = null;
- Object result = null;
-
- //use data to detect circular inheritance
- if (data.inheritanceChain == null)
- data.inheritanceChain = new ObjectSet<IScope>(2);
-
- data.inheritanceChain.put(lookIn);
-
- // workaround to fix 185828
- if (data.inheritanceChain.size() > CPPSemantics.MAX_INHERITANCE_DEPTH) {
- return null;
- }
-
- HashSet<IBinding> baseBindings= bases.length > 1 ? new HashSet<IBinding>() : null;
- for (ICPPBase base : bases) {
- if (base instanceof IProblemBinding)
- continue;
-
- try {
- IBinding b = base.getBaseClass();
- if (!(b instanceof ICPPClassType)) {
- // 14.6.2.3 scope is not examined
- if (b instanceof ICPPUnknownBinding) {
- if (data.skippedScope == null)
- data.skippedScope= overallScope;
- }
- continue;
- }
-
- final ICPPClassType cls = (ICPPClassType) b;
- if (baseBindings != null && !baseBindings.add(cls))
- continue;
-
- inherited = null;
- final ICPPScope classScope = (ICPPScope) cls.getCompositeScope();
- if (classScope == null || classScope instanceof ICPPInternalUnknownScope) {
- // 14.6.2.3 scope is not examined
- if (data.skippedScope == null)
- data.skippedScope= overallScope;
- continue;
- }
- if (!base.isVirtual() || !data.visited.containsKey(classScope)) {
- if (base.isVirtual()) {
- data.visited.put(classScope);
- }
-
- // if the inheritanceChain already contains the parent, then that
- // is circular inheritance
- if (!data.inheritanceChain.containsKey(classScope)) {
- //is this name define in this scope?
- IBinding[] inCurrentScope= getBindingsFromScope(classScope, fileSet, data);
- if (data.typesOnly) {
- removeObjects(inCurrentScope);
- }
- final boolean isEmpty= inCurrentScope.length == 0 || inCurrentScope[0] == null;
- if (data.contentAssist) {
- Object temp = lookupInParents(data, classScope, overallScope, fileSet);
- if (!isEmpty) {
- inherited = mergePrefixResults(null, inCurrentScope, true);
- inherited = mergePrefixResults((CharArrayObjectMap) inherited,
- (CharArrayObjectMap) temp, true);
- } else {
- inherited= temp;
- }
- } else if (isEmpty) {
- inherited= lookupInParents(data, classScope, overallScope, fileSet);
- } else {
- inherited= inCurrentScope;
- visitVirtualBaseClasses(data, cls);
- }
- } else {
- data.problem = new ProblemBinding(null, IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE,
- cls.getNameCharArray(), data.getFoundBindings());
- return null;
- }
- }
-
- if (inherited != null) {
- if (result == null) {
- result = inherited;
- } else if (!data.contentAssist) {
- if (result instanceof Object[]) {
- Object[] r = (Object[]) result;
- for (int j = 0; j < r.length && r[j] != null; j++) {
- if (checkForAmbiguity(data, r[j], inherited)) {
- data.problem = new ProblemBinding(data.astName,
- IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings());
- return null;
- }
- }
- } else {
- if (checkForAmbiguity(data, result, inherited)) {
- data.problem = new ProblemBinding(data.astName,
- IProblemBinding.SEMANTIC_AMBIGUOUS_LOOKUP, data.getFoundBindings());
- return null;
- }
- }
- } else {
- CharArrayObjectMap temp = (CharArrayObjectMap) inherited;
- CharArrayObjectMap r = (CharArrayObjectMap) result;
- char[] key = null;
- int tempSize = temp.size();
- for (int ii = 0; ii < tempSize; ii++) {
- key = temp.keyAt(ii);
- if (!r.containsKey(key)) {
- r.put(key, temp.get(key));
- } else {
- //TODO: prefixLookup ambiguity checking
- }
- }
- }
- }
- } catch (DOMException e) {
- // assume that the base has not been specified
- }
- }
-
- data.inheritanceChain.remove(lookIn);
-
- return result;
- }
-
- public static void visitVirtualBaseClasses(LookupData data, ICPPClassType cls) throws DOMException {
- if (data.inheritanceChain == null)
- data.inheritanceChain = new ObjectSet<IScope>(2);
-
- IScope scope = cls.getCompositeScope();
- if (scope != null)
- data.inheritanceChain.put(scope);
-
- ICPPBase[] bases = cls.getBases();
-
- for (ICPPBase base : bases) {
- IBinding b = base.getBaseClass();
- if (b instanceof ICPPClassType) {
- IScope bScope = ((ICPPClassType)b).getCompositeScope();
- if (base.isVirtual()) {
- if (bScope != null)
- data.visited.put(bScope);
- } else if (bScope != null) {
- if (!data.inheritanceChain.containsKey(bScope))
- visitVirtualBaseClasses(data, (ICPPClassType) b);
- else
- data.problem = new ProblemBinding(null, IProblemBinding.SEMANTIC_CIRCULAR_INHERITANCE, cls.getNameCharArray());
- }
- }
- }
-
- if (scope != null)
- data.inheritanceChain.remove(scope);
- }
-
- private static boolean checkForAmbiguity(LookupData data, Object n, Object names) throws DOMException {
- if (names instanceof Object[]) {
- names = ArrayUtil.trim(Object.class, (Object[]) names);
- if (((Object[])names).length == 0)
- return false;
- }
-
- IBinding binding= (n instanceof IBinding) ? (IBinding) n : ((IASTName) n).resolveBinding();
-
- int idx= 0;
- Object[] objs= null;
- Object o= names;
- if (names instanceof Object[]) {
- objs= (Object[]) names;
- o= objs[0];
- idx= 1;
- }
-
- while (o != null) {
- IBinding b = (o instanceof IBinding) ? (IBinding) o : ((IASTName)o).resolveBinding();
-
- if (b instanceof ICPPUsingDeclaration) {
- objs = ArrayUtil.append(Object.class, objs, ((ICPPUsingDeclaration)b).getDelegates());
- } else {
- if (binding != b)
- return true;
-
- boolean ok = false;
- // 3.4.5-4 if the id-expression in a class member access is a qualified id... the result
- // is not required to be a unique base class...
- if (binding instanceof ICPPClassType) {
- IASTNode parent = data.astName.getParent();
- if (parent instanceof ICPPASTQualifiedName &&
- parent.getPropertyInParent() == IASTFieldReference.FIELD_NAME) {
- ok = true;
- }
- }
- // it is not ambiguous if they are the same thing and it is static or an enumerator
- if (binding instanceof IEnumerator ||
- (binding instanceof IFunction && ASTInternal.isStatic((IFunction) binding, false)) ||
- (binding instanceof IVariable && ((IVariable)binding).isStatic())) {
- ok = true;
- }
- if (!ok)
- return true;
- }
- if (objs != null && idx < objs.length)
- o = objs[idx++];
- else
- o = null;
- }
- return false;
- }
/**
* Stores the using directive with the scope where the members of the nominated namespace will appear.
diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java
index c93347889e2..f799f4b3c18 100644
--- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java
+++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/LookupData.java
@@ -18,7 +18,31 @@ import java.util.Collections;
import java.util.List;
import java.util.Map;
-import org.eclipse.cdt.core.dom.ast.*;
+import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
+import org.eclipse.cdt.core.dom.ast.DOMException;
+import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression;
+import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
+import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
+import org.eclipse.cdt.core.dom.ast.IASTExpression;
+import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
+import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
+import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
+import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
+import org.eclipse.cdt.core.dom.ast.IASTInitializer;
+import org.eclipse.cdt.core.dom.ast.IASTName;
+import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
+import org.eclipse.cdt.core.dom.ast.IASTNode;
+import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
+import org.eclipse.cdt.core.dom.ast.IASTTypeId;
+import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
+import org.eclipse.cdt.core.dom.ast.IBinding;
+import org.eclipse.cdt.core.dom.ast.IPointerType;
+import org.eclipse.cdt.core.dom.ast.IScope;
+import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.c.ICASTFieldDesignator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
@@ -64,10 +88,6 @@ public class LookupData {
*/
public ObjectSet<IScope> visited= new ObjectSet<IScope>(1);
- /*
- * Used to detect circular inheritance
- */
- public ObjectSet<IScope> inheritanceChain;
@SuppressWarnings("unchecked")
public ObjectSet<IScope> associated = ObjectSet.EMPTY_SET;
@@ -560,8 +580,8 @@ public class LookupData {
}
if (checkForDependentName) {
IType[] types= getFunctionArgumentTypes();
- for (int i = 0; i < types.length; i++) {
- if (CPPTemplates.isDependentType(types[i])) {
+ for (IType type : types) {
+ if (CPPTemplates.isDependentType(type)) {
checkPointOfDecl= false;
break;
}

Back to the top