1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Index based name resolution for classes in namespaces (bug 217102)

This commit is contained in:
Markus Schorn 2008-01-30 17:09:15 +00:00
parent ddc6109778
commit 0aa860ee97
6 changed files with 140 additions and 15 deletions

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2006, 2007 Wind River Systems, Inc. and others.
* Copyright (c) 2006, 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
@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
@ -675,5 +676,36 @@ public class IndexCPPBindingResolutionBugs extends IndexBindingResolutionTestBas
assertTrue(tAST.isSameType(tIndex));
assertTrue(tIndex.isSameType(tAST));
}
// namespace FOO {
// namespace BAR {
// class Bar;
// }
// class Foo {
// BAR::Bar * Test(BAR::Bar * bar);
// };
// }
// #include "header.h"
// namespace FOO {
// using BAR::Bar;
//
// Bar* Foo::Test(Bar* pBar) {
// return pBar;
// }
// }
public void testAdvanceUsingDeclaration_Bug217102() throws Exception {
IBinding cl = getBindingFromASTName("Bar* Foo", 3);
assertTrue(cl instanceof ICPPDelegate);
cl= ((ICPPDelegate) cl).getBinding();
assertEquals("Bar", cl.getName());
assertTrue(cl instanceof ICPPClassType);
assertEquals("BAR", cl.getScope().getScopeName().toString());
cl = getBindingFromASTName("Bar* pBar", 3);
cl= ((ICPPDelegate) cl).getBinding();
assertEquals("Bar", cl.getName());
assertTrue(cl instanceof ICPPClassType);
assertEquals("BAR", cl.getScope().getScopeName().toString());
}
}

View file

@ -11,6 +11,8 @@
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import java.util.HashMap;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
@ -54,7 +56,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBasicType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexFileSet;
import org.eclipse.cdt.core.parser.ParserLanguage;
@ -63,6 +65,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent;
import org.eclipse.cdt.internal.core.dom.parser.GCCBuiltinSymbolProvider.CPPBuiltinParameter;
import org.eclipse.cdt.internal.core.index.IIndexScope;
import org.eclipse.cdt.internal.core.parser.scanner.ILocationResolver;
import org.eclipse.core.runtime.CoreException;
@ -80,11 +83,12 @@ public class CPPASTTranslationUnit extends CPPASTNode implements ICPPASTTranslat
private IASTDeclaration[] decls = new IASTDeclaration[32];
private ICPPNamespace binding = null;
private ICPPScope scope = null;
private CPPNamespaceScope scope = null;
private ILocationResolver resolver;
private IIndex index;
private IIndexFileSet fIndexFileSet;
private boolean fIsHeader;
private HashMap<IIndexScope, IScope> fMappedScopes= new HashMap<IIndexScope, IScope>();
public IASTTranslationUnit getTranslationUnit() {
return this;
@ -105,7 +109,7 @@ public class CPPASTTranslationUnit extends CPPASTNode implements ICPPASTTranslat
return (IASTDeclaration[]) ArrayUtil.trim( IASTDeclaration.class, decls );
}
public IScope getScope() {
public CPPNamespaceScope getScope() {
if (scope == null) {
scope = new CPPNamespaceScope(this);
addBuiltinOperators(scope);
@ -527,4 +531,20 @@ public class CPPASTTranslationUnit extends CPPASTNode implements ICPPASTTranslat
public void setIsHeaderUnit(boolean headerUnit) {
fIsHeader= headerUnit;
}
// bug 217102: namespace scopes from the index have to be mapped back to the AST.
IScope mapToASTScope(IIndexScope scope) {
if (scope instanceof ICPPNamespaceScope) {
IScope result= fMappedScopes.get(scope);
if (result == null) {
result= getScope().findNamespaecScope(scope);
if (result == null) {
result= scope;
}
fMappedScopes.put(scope, result);
}
return result;
}
return scope;
}
}

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2004, 2006 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
@ -15,10 +15,15 @@
package org.eclipse.cdt.internal.core.dom.parser.cpp;
import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTLinkageSpecification;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespaceScope;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.index.IIndexScope;
/**
* @author aniefer
@ -53,4 +58,45 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{
}
return null;
}
public IScope findNamespaecScope(IIndexScope scope) {
final String[] qname= scope.getScopeBinding().getQualifiedName();
final IScope[] result= {null};
final CPPASTVisitor visitor= new CPPASTVisitor () {
private int depth= 0;
{
shouldVisitNamespaces= shouldVisitDeclarations= true;
}
@Override
public int visit( IASTDeclaration declaration ){
if( declaration instanceof ICPPASTLinkageSpecification )
return PROCESS_CONTINUE;
return PROCESS_SKIP;
}
@Override
public int visit(ICPPASTNamespaceDefinition namespace) {
final String name = namespace.getName().toString();
if (name.length() == 0) {
return PROCESS_CONTINUE;
}
if (qname[depth].equals(name)) {
if (++depth == qname.length) {
result[0]= namespace.getScope();
return PROCESS_ABORT;
}
return PROCESS_CONTINUE;
}
return PROCESS_SKIP;
}
@Override
public int leave(ICPPASTNamespaceDefinition namespace) {
if (namespace.getName().toCharArray().length > 0) {
--depth;
}
return PROCESS_CONTINUE;
}
};
getPhysicalNode().accept(visitor);
return result[0];
}
}

View file

@ -858,14 +858,14 @@ public class CPPSemantics {
IType p = ps[i];
p = getUltimateType( p, true );
try {
getAssociatedScopes( p, namespaces, classes, data.astName.getTranslationUnit());
getAssociatedScopes( p, namespaces, classes, (CPPASTTranslationUnit) data.astName.getTranslationUnit());
} catch ( DOMException e ) {
}
}
return namespaces;
}
static private void getAssociatedScopes( IType t, ObjectSet namespaces, ObjectSet classes, IASTTranslationUnit tu) throws DOMException{
static private void getAssociatedScopes( IType t, ObjectSet namespaces, ObjectSet classes, CPPASTTranslationUnit tu) throws DOMException{
//3.4.2-2
if( t instanceof ICPPClassType ){
if( !classes.containsKey( t ) ){
@ -905,7 +905,7 @@ public class CPPSemantics {
return;
}
static private ICPPNamespaceScope getContainingNamespaceScope( IBinding binding, IASTTranslationUnit tu) throws DOMException{
static private ICPPNamespaceScope getContainingNamespaceScope( IBinding binding, CPPASTTranslationUnit tu) throws DOMException{
if( binding == null ) return null;
IScope scope = binding.getScope();
while( scope != null && !(scope instanceof ICPPNamespaceScope) ){
@ -1146,7 +1146,7 @@ public class CPPSemantics {
if( blockItem != null )
node = blockItem;
ICPPScope parentScope = (ICPPScope) getParentScope(scope, node.getTranslationUnit());
ICPPScope parentScope = (ICPPScope) getParentScope(scope, (CPPASTTranslationUnit) node.getTranslationUnit());
if( parentScope instanceof ICPPTemplateScope ){
IASTNode parent = node.getParent();
while( parent != null && !(parent instanceof ICPPASTTemplateDeclaration) ){
@ -1165,11 +1165,16 @@ public class CPPSemantics {
}
}
private static IScope getParentScope(IScope scope, IASTTranslationUnit unit) throws DOMException {
private static IScope getParentScope(IScope scope, CPPASTTranslationUnit unit) throws DOMException {
IScope parentScope= scope.getParent();
// the index cannot return the translation unit as parent scope
if (parentScope == null && scope instanceof IIndexScope && unit != null) {
parentScope= unit.getScope();
if (unit != null) {
if (parentScope == null && scope instanceof IIndexScope) {
parentScope= unit.getScope();
}
else if (parentScope instanceof IIndexScope) {
parentScope= unit.mapToASTScope((IIndexScope) parentScope);
}
}
return parentScope;
}
@ -1403,7 +1408,7 @@ public class CPPSemantics {
//namespace are searched at most once
if( !data.visited.containsKey( temp ) ){
enclosing = getClosestEnclosingScope( scope, temp, data.astName.getTranslationUnit());
enclosing = getClosestEnclosingScope( scope, temp, (CPPASTTranslationUnit) data.astName.getTranslationUnit());
//data.usingDirectives is a map from enclosing scope to a IScope[]
//of namespaces to consider when we reach that enclosing scope
@ -1418,7 +1423,7 @@ public class CPPSemantics {
}
static private ICPPScope getClosestEnclosingScope( IScope scope1, IScope scope2, IASTTranslationUnit tu) throws DOMException{
static private ICPPScope getClosestEnclosingScope( IScope scope1, IScope scope2, CPPASTTranslationUnit tu) throws DOMException{
ObjectSet set = new ObjectSet( 2 );
IScope parent = scope1;
while( parent != null ){

View file

@ -28,8 +28,10 @@ import java.util.regex.Pattern;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ILinkage;
import org.eclipse.cdt.core.dom.IName;
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.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFile;
@ -120,6 +122,26 @@ public class CIndex implements IIndex {
}
public IIndexName[] findNames(IBinding binding, int flags) throws CoreException {
if (binding instanceof ICPPUsingDeclaration) {
IBinding[] bindings= null;
try {
bindings = ((ICPPUsingDeclaration)binding).getDelegates();
} catch (DOMException e) {
CCorePlugin.log(e);
}
if (bindings == null || bindings.length == 0) {
return new IIndexName[0];
}
if (bindings.length > 1) {
ArrayList<IIndexName> result= new ArrayList<IIndexName>();
for (int i = 0; i < bindings.length; i++) {
IBinding b = bindings[i];
result.addAll(Arrays.asList(findNames(b, flags)));
}
return result.toArray(new IIndexName[result.size()]);
}
binding= bindings[0];
}
LinkedList<IIndexFragmentName> result= new LinkedList<IIndexFragmentName>();
int fragCount= 0;
for (int i = 0; i < fPrimaryFragmentCount; i++) {

View file

@ -1,5 +1,5 @@
/*******************************************************************************
* Copyright (c) 2000, 2007 IBM Corporation and others.
* Copyright (c) 2000, 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