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

Name resolution for qualified member declarations, bug 222026.

This commit is contained in:
Markus Schorn 2008-03-10 16:27:45 +00:00
parent 07fd280fc9
commit 4ae9346289
9 changed files with 176 additions and 61 deletions

View file

@ -5729,4 +5729,101 @@ public class AST2CPPTests extends AST2BaseTest {
bh.assertNonProblem("func(qualified)", 4);
bh.assertNonProblem("func(unqualified)", 4);
}
// class Test {
// void Test::member1();
// void Test::member2() {};
// };
// void Test::member1(){
// member2();
// }
public void testQualifiedMemberDeclaration_Bug222026() throws Exception {
final String code = getContents(1)[0].toString();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
IBinding b= bh.assertNonProblem("member1", 7);
IBinding b2= bh.assertNonProblem("member1(){", 7);
assertTrue(b instanceof ICPPMethod);
ICPPMethod m1= (ICPPMethod) b;
assertEquals("member1", m1.getName());
assertEquals("Test", m1.getScope().getScopeName().toString());
assertSame(b, b2);
bh= new BindingAssertionHelper(code, true);
b= bh.assertNonProblem("member2", 7);
b2= bh.assertNonProblem("member2();", 7);
assertTrue(b instanceof ICPPMethod);
m1= (ICPPMethod) b;
assertEquals("member2", m1.getName());
assertEquals("Test", m1.getScope().getScopeName().toString());
assertSame(b, b2);
// different resolution order
bh= new BindingAssertionHelper(code, true);
b2= bh.assertNonProblem("member1(){", 7);
b= bh.assertNonProblem("member1", 7);
assertTrue(b instanceof ICPPMethod);
m1= (ICPPMethod) b;
assertEquals("member1", m1.getName());
assertEquals("Test", m1.getScope().getScopeName().toString());
assertSame(b, b2);
bh= new BindingAssertionHelper(code, true);
b2= bh.assertNonProblem("member2();", 7);
b= bh.assertNonProblem("member2", 7);
assertTrue(b instanceof ICPPMethod);
m1= (ICPPMethod) b;
assertEquals("member2", m1.getName());
assertEquals("Test", m1.getScope().getScopeName().toString());
assertSame(b, b2);
}
// namespace Test {
// void Test::member1();
// void Test::member2() {};
// }
// void Test::member1(){
// member2();
// }
public void testQualifiedMemberDeclarationInNamespace_Bug222026() throws Exception {
final String code = getContents(1)[0].toString();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
IBinding b= bh.assertNonProblem("member1", 7);
IBinding b2= bh.assertNonProblem("member1(){", 7);
assertTrue(b instanceof ICPPFunction);
ICPPFunction m1= (ICPPFunction) b;
assertEquals("member1", m1.getName());
assertEquals("Test", m1.getScope().getScopeName().toString());
assertSame(b, b2);
bh= new BindingAssertionHelper(code, true);
b= bh.assertNonProblem("member2", 7);
b2= bh.assertNonProblem("member2();", 7);
assertTrue(b instanceof ICPPFunction);
m1= (ICPPFunction) b;
assertEquals("member2", m1.getName());
assertEquals("Test", m1.getScope().getScopeName().toString());
assertSame(b, b2);
// different resolution order
bh= new BindingAssertionHelper(code, true);
b2= bh.assertNonProblem("member1(){", 7);
b= bh.assertNonProblem("member1", 7);
assertTrue(b instanceof ICPPFunction);
m1= (ICPPFunction) b;
assertEquals("member1", m1.getName());
assertEquals("Test", m1.getScope().getScopeName().toString());
assertSame(b, b2);
bh= new BindingAssertionHelper(code, true);
b2= bh.assertNonProblem("member2();", 7);
b= bh.assertNonProblem("member2", 7);
assertTrue(b instanceof ICPPFunction);
m1= (ICPPFunction) b;
assertEquals("member2", m1.getName());
assertEquals("Test", m1.getScope().getScopeName().toString());
assertSame(b, b2);
}
}

View file

@ -134,6 +134,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
}
}
@Override
public IScope getParent() {
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
IASTName compName = compType.getName();
@ -147,6 +148,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#addBinding(org.eclipse.cdt.core.dom.ast.IBinding)
*/
@Override
public void addBinding(IBinding binding) {
if (binding instanceof ICPPConstructor) {
addConstructor(binding);
@ -155,11 +157,16 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
super.addBinding(binding);
}
public void addName(IASTName name) {
if (name instanceof ICPPASTQualifiedName)
return;
@Override
public void addName(IASTName name) throws DOMException {
IASTNode parent = name.getParent();
if (name instanceof ICPPASTQualifiedName) {
final IASTName[] qn= ((ICPPASTQualifiedName) name).getNames();
final IASTName ln= qn[qn.length-1];
if (CPPVisitor.getContainingScope(name) != CPPVisitor.getContainingScope(ln)) {
return;
}
}
if (parent instanceof IASTDeclarator) {
if (CPPVisitor.isConstructor(this, (IASTDeclarator) parent)) {
addConstructor(name);
@ -194,6 +201,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[])
*/
@Override
public IBinding getBinding(IASTName name, boolean resolve, IIndexFileSet fileSet) throws DOMException {
char[] c = name.toCharArray();
@ -213,6 +221,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
return super.getBinding(name, resolve, fileSet);
}
@Override
public IBinding[] getBindings(IASTName name, boolean resolve, boolean prefixLookup, IIndexFileSet fileSet) throws DOMException {
char[] c = name.toCharArray();
@ -298,6 +307,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String)
*/
@Override
public IBinding[] find(String name) throws DOMException {
char[] n = name.toCharArray();
ICPPASTCompositeTypeSpecifier compType = (ICPPASTCompositeTypeSpecifier) getPhysicalNode();
@ -370,6 +380,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#removeBinding(org.eclipse.cdt.core.dom.ast.IBinding)
*/
@Override
public void removeBinding(IBinding binding) {
if (binding instanceof ICPPConstructor) {
removeBinding(CONSTRUCTOR_KEY, binding);

View file

@ -259,7 +259,7 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt
return getASTName().toCharArray();
}
private IASTName getASTName() {
protected IASTName getASTName() {
IASTDeclarator dtor = (definition != null) ? definition : declarations[0];
IASTDeclarator nested= dtor.getNestedDeclarator();
while (nested != null) {

View file

@ -176,32 +176,13 @@ public class CPPMethod extends CPPFunction implements ICPPMethod {
}
@Override
public String getName() {
if( definition != null ){
IASTName n = definition.getName();
if( n instanceof ICPPASTQualifiedName ){
IASTName [] ns = ((ICPPASTQualifiedName)n).getNames();
return ns[ ns.length - 1 ].toString();
}
return n.toString();
protected IASTName getASTName() {
IASTName name= definition != null ? definition.getName() : declarations[0].getName();
if( name instanceof ICPPASTQualifiedName ){
final IASTName[] ns = ((ICPPASTQualifiedName)name).getNames();
return ns[ns.length - 1];
}
return declarations[0].getName().toString();
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getNameCharArray()
*/
@Override
public char[] getNameCharArray() {
if( definition != null ){
IASTName n = definition.getName();
if( n instanceof ICPPASTQualifiedName ){
IASTName [] ns = ((ICPPASTQualifiedName)n).getNames();
return ns[ ns.length - 1 ].toCharArray();
}
return n.toCharArray();
}
return declarations[0].getName().toCharArray();
return name;
}
/* (non-Javadoc)

View file

@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
@ -73,14 +74,25 @@ abstract public class CPPScope implements ICPPScope, IASTInternalScope {
protected CharArrayObjectMap bindings = null;
public void addName(IASTName name) {
public void addName(IASTName name) throws DOMException {
if( bindings == null )
bindings = new CharArrayObjectMap(1);
if( name instanceof ICPPASTQualifiedName ){
//name belongs to a different scope, don't add it here
return;
char[] c;
if (name instanceof ICPPASTQualifiedName) {
if (physicalNode instanceof ICPPASTCompositeTypeSpecifier == false &&
physicalNode instanceof ICPPASTNamespaceDefinition == false)
return;
//name belongs to a different scope, don't add it here except it names this scope
final IASTName[] ns= ((ICPPASTQualifiedName) name).getNames();
final IASTName ln= ns[ns.length-1];
if (CPPVisitor.getContainingScope(name) != CPPVisitor.getContainingScope(ln))
return;
c= ln.toCharArray();
}
else {
c= name.toCharArray();
}
char [] c = name.toCharArray();
Object o = bindings.get( c );
if( o != null ){
if( o instanceof ObjectSet ){

View file

@ -1485,7 +1485,7 @@ public class CPPSemantics {
//9-2 a class name is also inserted into the scope of the class itself
IASTName n = comp.getName();
if( nameMatches( data, n ) ) {
if( nameMatches( data, n, scope) ) {
found = (IASTName[]) ArrayUtil.append( IASTName.class, found, n );
}
} else if ( parent instanceof ICPPASTNamespaceDefinition ){
@ -1716,14 +1716,14 @@ public class CPPSemantics {
dtor = dtor.getNestedDeclarator();
IASTName declName = dtor.getName();
ASTInternal.addName( scope, declName );
if( !data.typesOnly && nameMatches( data, declName ) ) {
if( !data.typesOnly && nameMatches( data, declName, scope ) ) {
return declName;
}
}
} else if( node instanceof ICPPASTTemplateParameter ){
IASTName name = CPPTemplates.getTemplateParameterName( (ICPPASTTemplateParameter) node );
ASTInternal.addName( scope, name );
if( nameMatches( data, name ) ) {
if( nameMatches( data, name, scope ) ) {
return name;
}
}
@ -1742,7 +1742,7 @@ public class CPPSemantics {
IASTName declaratorName = declarator.getName();
ASTInternal.addName( scope, declaratorName );
if( !data.typesOnly || simpleDeclaration.getDeclSpecifier().getStorageClass() == IASTDeclSpecifier.sc_typedef ) {
if( nameMatches( data, declaratorName ) ) {
if( nameMatches( data, declaratorName, scope ) ) {
if( resultName == null )
resultName = declaratorName;
else if( resultArray == null )
@ -1805,7 +1805,7 @@ public class CPPSemantics {
if( enumerator == null ) break;
tempName = enumerator.getName();
ASTInternal.addName( scope, tempName );
if( !data.typesOnly && nameMatches( data, tempName ) ) {
if( !data.typesOnly && nameMatches( data, tempName, scope ) ) {
if( resultName == null )
resultName = tempName;
else if( resultArray == null )
@ -1817,7 +1817,7 @@ public class CPPSemantics {
}
if( specName != null ) {
ASTInternal.addName( scope, specName );
if( nameMatches( data, specName ) ) {
if( nameMatches( data, specName, scope ) ) {
if( resultName == null )
resultName = specName;
else if( resultArray == null )
@ -1834,18 +1834,18 @@ public class CPPSemantics {
name = ns[ ns.length - 1 ];
}
ASTInternal.addName( scope, name );
if( nameMatches( data, name ) ) {
if( nameMatches( data, name, scope ) ) {
return name;
}
} else if( declaration instanceof ICPPASTNamespaceDefinition ){
IASTName namespaceName = ((ICPPASTNamespaceDefinition) declaration).getName();
ASTInternal.addName( scope, namespaceName );
if( nameMatches( data, namespaceName ) )
if( nameMatches( data, namespaceName, scope ) )
return namespaceName;
} else if( declaration instanceof ICPPASTNamespaceAlias ){
IASTName alias = ((ICPPASTNamespaceAlias) declaration).getAlias();
ASTInternal.addName( scope, alias );
if( nameMatches( data, alias ) )
if( nameMatches( data, alias, scope ) )
return alias;
} else if( declaration instanceof IASTFunctionDefinition ){
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
@ -1856,7 +1856,7 @@ public class CPPSemantics {
IASTName declName = declarator.getName();
ASTInternal.addName( scope, declName );
if( !data.typesOnly && nameMatches( data, declName ) ) {
if( !data.typesOnly && nameMatches( data, declName, scope ) ) {
return declName;
}
}
@ -1867,11 +1867,20 @@ public class CPPSemantics {
return resultName;
}
private static final boolean nameMatches( LookupData data, IASTName potential ){
private static final boolean nameMatches( LookupData data, IASTName potential, IScope scope) throws DOMException{
if( potential instanceof ICPPASTQualifiedName ){
IASTNode phn= ASTInternal.getPhysicalNodeOfScope(scope);
if (phn instanceof ICPPASTCompositeTypeSpecifier == false && phn instanceof ICPPASTNamespaceDefinition == false)
return false;
//A qualified name implies the name actually belongs to a different scope, and should
//not be considered here.
return false;
//not be considered here, except the qualifier names the scope itself
final IASTName[] qn= ((ICPPASTQualifiedName) potential).getNames();
final IASTName ln= qn[qn.length-1];
if (CPPVisitor.getContainingScope(ln) != scope)
return false;
potential= ln;
}
char[] c = potential.toCharArray();
char [] n = data.name();

View file

@ -167,16 +167,21 @@ public class CPPVisitor {
if( binding instanceof IProblemBinding && parent instanceof ICPPASTQualifiedName
&& !(parent.getParent() instanceof ICPPASTNamespaceAlias))
{
if( ((IProblemBinding)binding).getID() == IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND ){
final ICPPASTQualifiedName qname= (ICPPASTQualifiedName)parent;
final IASTName[] ns= qname.getNames();
if (ns[ns.length-1] != name)
return binding;
parent = parent.getParent();
if( ((IProblemBinding)binding).getID() == IProblemBinding.SEMANTIC_MEMBER_DECLARATION_NOT_FOUND ){
IASTNode node = getContainingBlockItem( name.getParent() );
if( node.getPropertyInParent() != IASTCompositeTypeSpecifier.MEMBER_DECLARATION )
ASTNodeProperty prop= node.getPropertyInParent();
if (prop != IASTCompositeTypeSpecifier.MEMBER_DECLARATION && prop != ICPPASTNamespaceDefinition.OWNED_DECLARATION)
return binding;
if (getContainingScope(qname) != getContainingScope(name))
return binding;
}
IASTName [] ns = ((ICPPASTQualifiedName)parent).getNames();
if( ns[ ns.length - 1 ] == name )
parent = parent.getParent();
else
return binding;
} else {
return binding;
}

View file

@ -13,8 +13,7 @@ package org.eclipse.cdt.internal.core.dom.rewrite.changegenerator;
import org.eclipse.osgi.util.NLS;
/**
* mstodo
*
* External strings for the change generator.
* @since 5.0
*/
public class Messages extends NLS {

View file

@ -1,13 +1,13 @@
/*******************************************************************************
* Copyright (c) 2007 Symbian Software Systems and others.
* Copyright (c) 2007, 2008 Symbian Software Systems 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:
* Andrew Ferguson (Symbian) - Initial implementation
* Bryan Wilkinson (QNX)
* Andrew Ferguson (Symbian) - Initial implementation
* Bryan Wilkinson (QNX)
*******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp;
@ -44,7 +44,8 @@ public class TemplateInstanceUtil {
if(specd instanceof ICPPTemplateDefinition) {
keysToAdapt= ((ICPPTemplateDefinition)specd).getTemplateParameters();
}
for(int i=0; i<keys.length; i++) {
final int length= Math.min(keys.length, keysToAdapt.length);
for(int i=0; i<length; i++) {
IType type= (IType) preresult.get(keys[i]);
result.put(
cf.getCompositeBinding((IIndexFragmentBinding)keysToAdapt[i]),