1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-23 17:05:26 +02:00

Hidden virtual bases, bug 282993.

This commit is contained in:
Markus Schorn 2009-07-22 09:48:53 +00:00
parent 818d85f171
commit 6b57ac7cf2
5 changed files with 432 additions and 240 deletions

View file

@ -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);
}
}

View file

@ -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 {

View file

@ -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);
}
}

View file

@ -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.

View file

@ -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;
}