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:
parent
64b00d9187
commit
c49ffa51b6
3 changed files with 133 additions and 56 deletions
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Add table
Reference in a new issue