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

C++: handle globally qualified qualified names "::a"

: handle typedefs in  base clauses
C : handle nested structures
This commit is contained in:
Andrew Niefer 2005-01-28 20:56:18 +00:00
parent 64b00d9187
commit c49ffa51b6
3 changed files with 133 additions and 56 deletions

View file

@ -100,7 +100,22 @@ public class CompleteParser2Tests extends TestCase {
}
public int size() { return nameList.size(); }
}
static protected class CNameCollector extends CVisitor.CBaseVisitorAction {
{
processNames = true;
}
public List nameList = new ArrayList();
public int processName( IASTName name ){
nameList.add( name );
return PROCESS_CONTINUE;
}
public IASTName getName( int idx ){
if( idx < 0 || idx >= nameList.size() )
return null;
return (IASTName) nameList.get( idx );
}
public int size() { return nameList.size(); }
}
protected void assertInstances( CPPNameCollector nameCollector, IBinding binding, int num ) throws Exception {
int count = 0;
for( int i = 0; i < nameCollector.size(); i++ )
@ -109,7 +124,14 @@ public class CompleteParser2Tests extends TestCase {
assertEquals( count, num );
}
protected void assertInstances( CNameCollector nameCollector, IBinding binding, int num ) throws Exception {
int count = 0;
for( int i = 0; i < nameCollector.size(); i++ )
if( nameCollector.getName( i ).resolveBinding() == binding )
count++;
assertEquals( count, num );
}
protected IASTTranslationUnit parse(String code, boolean expectedToPass,
ParserLanguage lang) throws Exception {
return parse(code, expectedToPass, lang, false);
@ -1654,7 +1676,21 @@ public class CompleteParser2Tests extends TestCase {
writer.write(" ::s outer = { 42 };"); //$NON-NLS-1$
writer.write("}"); //$NON-NLS-1$
parse( writer.toString() );
IASTTranslationUnit tu = parse( writer.toString() );
CPPNameCollector col = new CPPNameCollector();
CPPVisitor.visitTranslationUnit( tu, col );
assertEquals( col.size(), 11 );
ICPPClassType s = (ICPPClassType) col.getName(0).resolveBinding();
ICPPClassType s2 = (ICPPClassType) col.getName(3).resolveBinding();
ICPPClassType ref1 = (ICPPClassType) col.getName(5).resolveBinding();
ICPPClassType ref2 = (ICPPClassType) col.getName( 9 ).resolveBinding();
assertSame( s, ref2 );
assertSame( s2, ref1 );
}
public void testBug57754() throws Exception
@ -1685,7 +1721,16 @@ public class CompleteParser2Tests extends TestCase {
writer.write( "class G2 { int j; };"); //$NON-NLS-1$
writer.write( "typedef G2 AltG2;"); //$NON-NLS-1$
writer.write( "class AltG3 : AltG2 { int x;};"); //$NON-NLS-1$
parse( writer.toString() );
IASTTranslationUnit tu = parse( writer.toString() );
CPPNameCollector col = new CPPNameCollector();
CPPVisitor.visitTranslationUnit( tu, col );
assertEquals( col.size(), 7 );
ICPPClassType G2 = (ICPPClassType) col.getName(0).resolveBinding();
ITypedef alt = (ITypedef) col.getName(3).resolveBinding();
assertInstances( col, G2, 2 );
assertInstances( col, alt, 2 );
}
public void testBug46246() throws Exception
@ -1698,7 +1743,16 @@ public class CompleteParser2Tests extends TestCase {
writer.write( "struct A a1; "); //$NON-NLS-1$
writer.write( "struct B b1; "); //$NON-NLS-1$
parse( writer.toString(), true, ParserLanguage.C );
IASTTranslationUnit tu = parse( writer.toString(), true, ParserLanguage.C );
CNameCollector col = new CNameCollector();
CVisitor.visitTranslationUnit( tu, col );
assertEquals( col.size(), 9 );
ICompositeType A = (ICompositeType) col.getName(0).resolveBinding();
ICompositeType B = (ICompositeType) col.getName(1).resolveBinding();
assertInstances( col, A, 2 );
assertInstances( col, B, 2 );
}
public void testBug45235() throws Exception

View file

@ -939,6 +939,7 @@ public class CVisitor {
if( binding != null )
return binding;
}
boolean typesOnly = (bits & TAGS) != 0;
if( nodes != null ){
for( int i = 0; i < nodes.length; i++ ){
IASTNode node = nodes[i];
@ -946,26 +947,20 @@ public class CVisitor {
break;
if( node instanceof IASTDeclarationStatement ){
IASTDeclarationStatement declStatement = (IASTDeclarationStatement) node;
binding = checkForBinding( declStatement.getDeclaration(), name );
binding = checkForBinding( declStatement.getDeclaration(), name, typesOnly );
} else if( node instanceof IASTDeclaration ){
binding = checkForBinding( (IASTDeclaration) node, name );
binding = checkForBinding( (IASTDeclaration) node, name, typesOnly );
}
if( binding != null ){
if( (bits & TAGS) != 0 && !(binding instanceof ICompositeType || binding instanceof IEnumeration) ||
(bits & TAGS) == 0 && (binding instanceof ICompositeType || binding instanceof IEnumeration) )
{
binding = null;
} else {
return binding;
}
return binding;
}
}
} else {
//check the parent
if( parent instanceof IASTDeclaration ){
binding = checkForBinding( (IASTDeclaration) parent, name );
binding = checkForBinding( (IASTDeclaration) parent, name, typesOnly );
} else if( parent instanceof IASTStatement ){
binding = checkForBinding( (IASTStatement) parent, name );
binding = checkForBinding( (IASTStatement) parent, name, typesOnly );
}
if( binding != null ){
if( (bits & TAGS) != 0 && !(binding instanceof ICompositeType) ||
@ -1008,49 +1003,71 @@ public class CVisitor {
return external;
}
private static IBinding checkForBinding( IASTDeclaration declaration, IASTName name ){
if( declaration instanceof IASTSimpleDeclaration ){
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
for( int i = 0; i < declarators.length; i++ ){
IASTDeclarator declarator = declarators[i];
IASTName declaratorName = declarator.getName();
if( CharArrayUtils.equals( declaratorName.toCharArray(), name.toCharArray() ) ){
return declaratorName.resolveBinding();
}
}
//decl spec
IASTDeclSpecifier declSpec = simpleDeclaration.getDeclSpecifier();
private static IBinding checkForBinding( IASTDeclSpecifier declSpec, IASTName name, boolean typesOnly ){
IASTName tempName = null;
if( typesOnly ){
if( declSpec instanceof ICASTElaboratedTypeSpecifier ){
IASTName elabName = ((ICASTElaboratedTypeSpecifier)declSpec).getName();
if( CharArrayUtils.equals( elabName.toCharArray(), name.toCharArray() ) ){
return elabName.resolveBinding();
tempName = ((ICASTElaboratedTypeSpecifier)declSpec).getName();
if( CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
return tempName.resolveBinding();
}
} else if( declSpec instanceof ICASTCompositeTypeSpecifier ){
IASTName compName = ((ICASTCompositeTypeSpecifier)declSpec).getName();
if( CharArrayUtils.equals( compName.toCharArray(), name.toCharArray() ) ){
return compName.resolveBinding();
tempName = ((ICASTCompositeTypeSpecifier)declSpec).getName();
if( CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
return tempName.resolveBinding();
}
//also have to check for any nested structs
IASTDeclaration [] nested = ((ICASTCompositeTypeSpecifier)declSpec).getMembers();
for( int i = 0; i < nested.length; i++ ){
if( nested[i] instanceof IASTSimpleDeclaration ){
IASTDeclSpecifier d = ((IASTSimpleDeclaration)nested[i]).getDeclSpecifier();
if( d instanceof ICASTCompositeTypeSpecifier ) {
IBinding temp = checkForBinding( d, name, typesOnly );
if( temp != null )
return temp;
}
}
}
} else if( declSpec instanceof ICASTEnumerationSpecifier ){
ICASTEnumerationSpecifier enumeration = (ICASTEnumerationSpecifier) declSpec;
IASTName eName = enumeration.getName();
if( CharArrayUtils.equals( eName.toCharArray(), name.toCharArray() ) ){
return eName.resolveBinding();
tempName = enumeration.getName();
if( CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
return tempName.resolveBinding();
}
//check enumerators too
IASTEnumerator [] list = enumeration.getEnumerators();
}
} else {
if( declSpec instanceof ICASTEnumerationSpecifier ) {
//check enumerators
IASTEnumerator [] list = ((ICASTEnumerationSpecifier) declSpec).getEnumerators();
for( int i = 0; i < list.length; i++ ) {
IASTEnumerator enumerator = list[i];
if( enumerator == null ) break;
eName = enumerator.getName();
if( CharArrayUtils.equals( eName.toCharArray(), name.toCharArray() ) ){
return eName.resolveBinding();
tempName = enumerator.getName();
if( CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
return tempName.resolveBinding();
}
}
}
} else if( declaration instanceof IASTFunctionDefinition ){
}
return null;
}
private static IBinding checkForBinding( IASTDeclaration declaration, IASTName name, boolean typesOnly ){
IASTName tempName = null;
if( declaration instanceof IASTSimpleDeclaration ){
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
if( !typesOnly ){
IASTDeclarator [] declarators = simpleDeclaration.getDeclarators();
for( int i = 0; i < declarators.length; i++ ){
IASTDeclarator declarator = declarators[i];
tempName = declarator.getName();
if( CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
return tempName.resolveBinding();
}
}
}
return checkForBinding( simpleDeclaration.getDeclSpecifier(), name, typesOnly );
} else if( !typesOnly && declaration instanceof IASTFunctionDefinition ){
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
if (functionDef.getDeclarator() instanceof IASTStandardFunctionDeclarator) {
@ -1097,13 +1114,13 @@ public class CVisitor {
return null;
}
private static IBinding checkForBinding( IASTStatement statement, IASTName name ){
private static IBinding checkForBinding( IASTStatement statement, IASTName name, boolean typesOnly ){
if( statement instanceof IASTDeclarationStatement ){
return checkForBinding( ((IASTDeclarationStatement)statement).getDeclaration(), name );
return checkForBinding( ((IASTDeclarationStatement)statement).getDeclaration(), name, typesOnly );
} else if( statement instanceof IASTForStatement ){
IASTForStatement forStatement = (IASTForStatement) statement;
if( forStatement.getInitDeclaration() != null ){
return checkForBinding( forStatement.getInitDeclaration(), name );
return checkForBinding( forStatement.getInitDeclaration(), name, typesOnly );
}
}
return null;

View file

@ -77,6 +77,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.parser.Keywords;
import org.eclipse.cdt.core.parser.ast.IASTNamespaceDefinition;
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectMap;
@ -289,16 +290,13 @@ public class CPPSemantics {
}
}
static protected IBinding resolveBinding( IASTName name ){
if( name.toCharArray().length == 0 ){
if( name.toCharArray().length == 2 && CharArrayUtils.equals( name.toCharArray(), Keywords.cpCOLONCOLON ) ){
IASTNode node = name.getParent();
if( node instanceof ICPPASTQualifiedName ){
ICPPASTQualifiedName qname = (ICPPASTQualifiedName) node;
if( qname.getNames()[0] == name ){
//translation unit
while( ! (node instanceof ICPPASTTranslationUnit ) ){
node = node.getParent();
}
return ((ICPPASTTranslationUnit) node).resolveBinding();
return ((ICPPASTTranslationUnit)node.getTranslationUnit()).resolveBinding();
}
}
return null;
@ -479,8 +477,16 @@ public class CPPSemantics {
int size = bases.length;
for( int i = 0; i < size; i++ )
{
ICPPClassType binding = (ICPPClassType) bases[i].getName().resolveBinding();
ICPPClassScope parent = (ICPPClassScope) binding.getCompositeScope();
ICPPClassType cls = null;
IBinding binding = bases[i].getName().resolveBinding();
while( binding instanceof ITypedef && ((ITypedef)binding).getType() instanceof IBinding ){
binding = (IBinding) ((ITypedef)binding).getType();
}
if( binding instanceof ICPPClassType )
cls = (ICPPClassType) binding;
else
continue;
ICPPClassScope parent = (ICPPClassScope) cls.getCompositeScope();
if( parent == null )
continue;