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

Resolution of dependent names, bug 262163.

This commit is contained in:
Markus Schorn 2009-01-23 14:40:56 +00:00
parent 5d1c767a34
commit 21bdc56dc0
12 changed files with 114 additions and 56 deletions

View file

@ -3631,4 +3631,32 @@ public class AST2TemplateTests extends AST2BaseTest {
ICPPConstructor ctor= bh.assertNonProblem("XT/**/", 2);
ctor= bh.assertNonProblem("XT<T>/**/", 5);
}
// template <typename T> class XT {
// public:
// typedef typename T::Nested TD;
// };
//
// class Base {
// public:
// typedef int Nested;
// };
//
// class Derived : public Base {
// };
//
// void test() {
// XT<Derived>::TD x;
// }
public void testResolutionOfUnknownBindings_262163() throws Exception {
final String code = getAboveComment();
parseAndCheckBindings(code, ParserLanguage.CPP);
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
IVariable x= bh.assertNonProblem("x;", 1);
ITypedef Nested= bh.assertNonProblem("Nested;", 6);
IType t= x.getType();
assertInstance(t, ITypedef.class);
t= ((ITypedef) t).getType();
assertSame(t, Nested);
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2005, 2008 IBM Corporation and others.
* Copyright (c) 2005, 2009 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
@ -35,7 +35,7 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
private final ICPPScope fLookupScope;
public CPPDeferredClassInstance(ICPPClassTemplate template, ICPPTemplateArgument[] arguments, ICPPScope lookupScope) throws DOMException {
super(template.getOwner(), new CPPASTName(template.getNameCharArray()));
super(template.getOwner(), template.getNameCharArray());
fArguments= arguments;
fClassTemplate= template;
fLookupScope= lookupScope;

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* Copyright (c) 2004, 2009 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
@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.internal.core.dom.Linkage;
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.PlatformObject;
@ -35,9 +36,10 @@ public class CPPUnknownBinding extends PlatformObject
private ICPPScope unknownScope;
protected IASTName name;
public CPPUnknownBinding(IBinding owner, IASTName name) {
public CPPUnknownBinding(IBinding owner, char[] name) {
super();
this.name = name;
this.name = new CPPASTName(name);
this.name.setPropertyInParent(CPPSemantics.STRING_LOOKUP_PROPERTY);
fOwner= owner;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2008 IBM Corporation and others.
* Copyright (c) 2004, 2009 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
@ -13,7 +13,6 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IField;
import org.eclipse.cdt.core.dom.ast.IScope;
@ -31,10 +30,10 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
*/
public class CPPUnknownClass extends CPPUnknownBinding implements ICPPUnknownClassType {
public static CPPUnknownClass createUnnamedInstance() {
return new CPPUnknownClass(null, new CPPASTName());
return new CPPUnknownClass(null, CharArrayUtils.EMPTY);
}
public CPPUnknownClass(IBinding binding, IASTName name) {
public CPPUnknownClass(IBinding binding, char[] name) {
super(binding, name);
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Google, Inc and others.
* Copyright (c) 2008, 2009 Google, 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
@ -13,7 +13,6 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
@ -28,7 +27,7 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
public class CPPUnknownClassInstance extends CPPUnknownClass implements ICPPUnknownClassInstance {
private final ICPPTemplateArgument[] arguments;
public CPPUnknownClassInstance(ICPPUnknownBinding scopeBinding, IASTName name, ICPPTemplateArgument[] arguments) {
public CPPUnknownClassInstance(ICPPUnknownBinding scopeBinding, char[] name, ICPPTemplateArgument[] arguments) {
super(scopeBinding, name);
this.arguments = arguments;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 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
@ -11,7 +11,6 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
@ -21,8 +20,8 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor;
*/
public class CPPUnknownConstructor extends CPPUnknownFunction implements ICPPConstructor {
public CPPUnknownConstructor(ICPPClassType owner, IASTName name) {
super(owner, name);
public CPPUnknownConstructor(ICPPClassType owner) {
super(owner, owner.getNameCharArray());
}
public boolean isExplicit() throws DOMException {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 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
@ -29,14 +29,14 @@ public class CPPUnknownFunction extends CPPUnknownBinding implements ICPPFunctio
public static IFunction createForSample(IFunction sample, IASTName name) throws DOMException {
if (sample instanceof ICPPConstructor)
return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner(), name);
return new CPPUnknownConstructor(((ICPPConstructor) sample).getClassOwner());
return new CPPUnknownFunction(sample.getOwner(), name.getLastName());
return new CPPUnknownFunction(sample.getOwner(), sample.getNameCharArray());
}
private ICPPFunctionType fType;
public CPPUnknownFunction(IBinding owner, IASTName name) {
public CPPUnknownFunction(IBinding owner, char[] name) {
super(owner, name);
}

View file

@ -148,11 +148,11 @@ public class CPPUnknownScope implements ICPPScope, ICPPInternalUnknownScope {
IBinding result= o[idx];
if (result == null) {
if (type) {
result= new CPPUnknownClass(binding, name.getLastName());
result= new CPPUnknownClass(binding, name.getSimpleID());
} else if (function) {
result= new CPPUnknownFunction(binding, name.getLastName());
result= new CPPUnknownFunction(binding, name.getSimpleID());
} else {
result= new CPPUnknownBinding(binding, name.getLastName());
result= new CPPUnknownBinding(binding, name.getSimpleID());
}
o[idx]= result;
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2008 Wind River Systems, Inc. and others.
* Copyright (c) 2008, 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

View file

@ -340,7 +340,7 @@ public class CPPSemantics {
}
}
if (cls instanceof ICPPDeferredClassInstance) {
binding= new CPPUnknownConstructor(cls, data.astName);
binding= new CPPUnknownConstructor(cls);
} else {
// Force resolution of constructor bindings
final ICPPConstructor[] constructors = cls.getConstructors();
@ -377,12 +377,12 @@ public class CPPSemantics {
final ASTNodeProperty namePropertyInParent = name.getPropertyInParent();
if (binding == null && data.skippedScope != null) {
if (data.functionParameters != null) {
binding= new CPPUnknownFunction(data.skippedScope, name.getLastName());
binding= new CPPUnknownFunction(data.skippedScope, name.getSimpleID());
} else {
if (namePropertyInParent == IASTNamedTypeSpecifier.NAME) {
binding= new CPPUnknownClass(data.skippedScope, name.getLastName());
binding= new CPPUnknownClass(data.skippedScope, name.getSimpleID());
} else {
binding= new CPPUnknownBinding(data.skippedScope, name.getLastName());
binding= new CPPUnknownBinding(data.skippedScope, name.getSimpleID());
}
}
}
@ -733,7 +733,7 @@ public class CPPSemantics {
blockItem = CPPVisitor.getContainingBlockItem(blockItem);
if (!data.usingDirectivesOnly) {
IBinding[] bindings= scope.getBindings(data.astName, true, data.prefixLookup, fileSet);
IBinding[] bindings= getBindingsFromScope(scope, fileSet, data);
if (data.typesOnly) {
removeObjects(bindings);
}
@ -773,7 +773,7 @@ public class CPPSemantics {
}
if (!data.usingDirectivesOnly && scope instanceof ICPPClassScope) {
mergeResults(data, lookupInParents(data, scope, ((ICPPClassScope) scope).getClassType()), true);
mergeResults(data, lookupInParents(data, scope, ((ICPPClassScope) scope).getClassType(), fileSet), true);
}
if (!data.contentAssist && (data.problem != null || data.hasResults()))
@ -795,6 +795,16 @@ public class CPPSemantics {
}
}
private 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);
} else {
bindings= scope.getBindings(data.astName, true, data.prefixLookup, fileSet);
}
return bindings;
}
private static void removeObjects(final IBinding[] bindings) {
final int length = bindings.length;
int pos= 0;
@ -850,7 +860,7 @@ public class CPPSemantics {
return (ICPPScope) parentScope;
}
private static Object lookupInParents(LookupData data, ICPPScope lookIn, ICPPClassType overallScope) {
private static Object lookupInParents(LookupData data, ICPPScope lookIn, ICPPClassType overallScope, IIndexFileSet fileSet) {
if (lookIn instanceof ICPPClassScope == false)
return null;
@ -916,13 +926,13 @@ public class CPPSemantics {
// is circular inheritance
if (!data.inheritanceChain.containsKey(classScope)) {
//is this name define in this scope?
IBinding[] inCurrentScope= classScope.getBindings(data.astName, true, data.prefixLookup);
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);
Object temp = lookupInParents(data, classScope, overallScope, fileSet);
if (!isEmpty) {
inherited = mergePrefixResults(null, inCurrentScope, true);
inherited = mergePrefixResults((CharArrayObjectMap)inherited, (CharArrayObjectMap)temp, true);
@ -930,7 +940,7 @@ public class CPPSemantics {
inherited= temp;
}
} else if (isEmpty) {
inherited= lookupInParents(data, classScope, overallScope);
inherited= lookupInParents(data, classScope, overallScope, fileSet);
} else {
inherited= inCurrentScope;
visitVirtualBaseClasses(data, cls);
@ -1658,7 +1668,7 @@ public class CPPSemantics {
Object[] items = (Object[]) data.foundItems;
for (int i = 0; i < items.length && items[i] != null; i++) {
Object o = items[i];
boolean declaredBefore = declaredBefore(o, name, indexBased);
boolean declaredBefore = !data.checkPointOfDecl || declaredBefore(o, name, indexBased);
boolean checkResolvedNamesOnly= false;
if (!data.checkWholeClassScope && !declaredBefore) {
if (name.getRoleOfName(false) != IASTNameOwner.r_reference) {
@ -2727,4 +2737,33 @@ public class CPPSemantics {
}
return false;
}
static protected IBinding resolveUnknownName(IScope scope, ICPPUnknownBinding unknown) {
final IASTName unknownName = unknown.getUnknownName();
LookupData data = new LookupData(unknownName);
data.checkPointOfDecl= false;
data.typesOnly= unknown instanceof IType;
try {
// 2: lookup
lookup(data, scope);
} catch (DOMException e) {
data.problem = (ProblemBinding) e.getProblem();
}
if (data.problem != null)
return data.problem;
// 3: resolve ambiguities
IBinding binding;
try {
binding = resolveAmbiguities(data, unknownName);
} catch (DOMException e) {
binding = e.getProblem();
}
// 4: post processing
binding = postResolution(binding, data);
return binding;
}
}

View file

@ -125,7 +125,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClass;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPASTInternalTemplateDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPClassSpecializationScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
@ -552,7 +551,7 @@ public class CPPTemplates {
IBinding owner= template.getOwner();
if (owner instanceof ICPPUnknownBinding) {
ICPPTemplateArgument[] args= createTemplateArgumentArray(id);
return new CPPUnknownClassInstance((ICPPUnknownBinding) template.getOwner(), id, args);
return new CPPUnknownClassInstance((ICPPUnknownBinding) template.getOwner(), id.getSimpleID(), args);
}
}
@ -2034,35 +2033,26 @@ public class CPPTemplates {
final ICPPTemplateArgument[] arguments = ucli.getArguments();
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(arguments, tpMap, within);
if (!t.equals(owner) && newArgs != arguments) {
result= new CPPUnknownClassInstance((ICPPUnknownBinding) t, ucli.getUnknownName(), newArgs);
result= new CPPUnknownClassInstance((ICPPUnknownBinding) t, ucli.getNameCharArray(), newArgs);
}
} else if (!t.equals(owner)) {
if (unknown instanceof ICPPUnknownClassType) {
result= new CPPUnknownClass((ICPPUnknownBinding)t, unknown.getUnknownName());
result= new CPPUnknownClass((ICPPUnknownBinding)t, unknown.getNameCharArray());
} else if (unknown instanceof IFunction) {
result= new CPPUnknownClass((ICPPUnknownBinding)t, unknown.getUnknownName());
result= new CPPUnknownClass((ICPPUnknownBinding)t, unknown.getNameCharArray());
} else {
result= new CPPUnknownBinding((ICPPUnknownBinding) t, unknown.getUnknownName());
result= new CPPUnknownBinding((ICPPUnknownBinding) t, unknown.getNameCharArray());
}
}
} else if (t instanceof ICPPClassType) {
IScope s = ((ICPPClassType) t).getCompositeScope();
if (s != null) {
IASTName name= unknown.getUnknownName();
if (name != null) {
IBinding[] candidates;
if (s instanceof ICPPASTInternalScope) {
candidates= ((ICPPASTInternalScope) s).getBindings(name, true, false, null, false);
} else {
candidates= s.getBindings(name, true, false, null);
result= CPPSemantics.resolveUnknownName(s, unknown);
if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) {
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, within);
if (result instanceof ICPPClassTemplate) {
result = instantiate((ICPPClassTemplate) result, newArgs);
}
result= CPPSemantics.resolveAmbiguities(name, candidates);
if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) {
ICPPTemplateArgument[] newArgs = CPPTemplates.instantiateArguments(((ICPPUnknownClassInstance) unknown).getArguments(), tpMap, within);
if (result instanceof ICPPClassTemplate) {
result = instantiate((ICPPClassTemplate) result, newArgs);
}
}
}
}
}

View file

@ -99,6 +99,7 @@ public class LookupData {
public boolean prefixLookup = false;
public boolean typesOnly = false;
public boolean considerConstructors = false;
public boolean checkPointOfDecl= true; // for lookup of unknown bindings the point of declaration can be reversed.
public ICPPClassType skippedScope;
public Object foundItems = null;
@ -245,7 +246,8 @@ public class LookupData {
private boolean considerConstructors() {
if (astName == null) return false;
if (astName.getPropertyInParent() == CPPSemantics.STRING_LOOKUP_PROPERTY) return false;
final ASTNodeProperty propertyInParent = astName.getPropertyInParent();
if (propertyInParent == CPPSemantics.STRING_LOOKUP_PROPERTY || propertyInParent == null) return false;
IASTNode p1 = astName.getParent();
IASTNode p2 = p1.getParent();