mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-30 04:15:35 +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(); }
|
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 {
|
protected void assertInstances( CPPNameCollector nameCollector, IBinding binding, int num ) throws Exception {
|
||||||
int count = 0;
|
int count = 0;
|
||||||
for( int i = 0; i < nameCollector.size(); i++ )
|
for( int i = 0; i < nameCollector.size(); i++ )
|
||||||
|
@ -109,7 +124,14 @@ public class CompleteParser2Tests extends TestCase {
|
||||||
|
|
||||||
assertEquals( count, num );
|
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,
|
protected IASTTranslationUnit parse(String code, boolean expectedToPass,
|
||||||
ParserLanguage lang) throws Exception {
|
ParserLanguage lang) throws Exception {
|
||||||
return parse(code, expectedToPass, lang, false);
|
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(" ::s outer = { 42 };"); //$NON-NLS-1$
|
||||||
writer.write("}"); //$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
|
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( "class G2 { int j; };"); //$NON-NLS-1$
|
||||||
writer.write( "typedef G2 AltG2;"); //$NON-NLS-1$
|
writer.write( "typedef G2 AltG2;"); //$NON-NLS-1$
|
||||||
writer.write( "class AltG3 : AltG2 { int x;};"); //$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
|
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 A a1; "); //$NON-NLS-1$
|
||||||
writer.write( "struct B b1; "); //$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
|
public void testBug45235() throws Exception
|
||||||
|
|
|
@ -939,6 +939,7 @@ public class CVisitor {
|
||||||
if( binding != null )
|
if( binding != null )
|
||||||
return binding;
|
return binding;
|
||||||
}
|
}
|
||||||
|
boolean typesOnly = (bits & TAGS) != 0;
|
||||||
if( nodes != null ){
|
if( nodes != null ){
|
||||||
for( int i = 0; i < nodes.length; i++ ){
|
for( int i = 0; i < nodes.length; i++ ){
|
||||||
IASTNode node = nodes[i];
|
IASTNode node = nodes[i];
|
||||||
|
@ -946,26 +947,20 @@ public class CVisitor {
|
||||||
break;
|
break;
|
||||||
if( node instanceof IASTDeclarationStatement ){
|
if( node instanceof IASTDeclarationStatement ){
|
||||||
IASTDeclarationStatement declStatement = (IASTDeclarationStatement) node;
|
IASTDeclarationStatement declStatement = (IASTDeclarationStatement) node;
|
||||||
binding = checkForBinding( declStatement.getDeclaration(), name );
|
binding = checkForBinding( declStatement.getDeclaration(), name, typesOnly );
|
||||||
} else if( node instanceof IASTDeclaration ){
|
} else if( node instanceof IASTDeclaration ){
|
||||||
binding = checkForBinding( (IASTDeclaration) node, name );
|
binding = checkForBinding( (IASTDeclaration) node, name, typesOnly );
|
||||||
}
|
}
|
||||||
if( binding != null ){
|
if( binding != null ){
|
||||||
if( (bits & TAGS) != 0 && !(binding instanceof ICompositeType || binding instanceof IEnumeration) ||
|
return binding;
|
||||||
(bits & TAGS) == 0 && (binding instanceof ICompositeType || binding instanceof IEnumeration) )
|
|
||||||
{
|
|
||||||
binding = null;
|
|
||||||
} else {
|
|
||||||
return binding;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
//check the parent
|
//check the parent
|
||||||
if( parent instanceof IASTDeclaration ){
|
if( parent instanceof IASTDeclaration ){
|
||||||
binding = checkForBinding( (IASTDeclaration) parent, name );
|
binding = checkForBinding( (IASTDeclaration) parent, name, typesOnly );
|
||||||
} else if( parent instanceof IASTStatement ){
|
} else if( parent instanceof IASTStatement ){
|
||||||
binding = checkForBinding( (IASTStatement) parent, name );
|
binding = checkForBinding( (IASTStatement) parent, name, typesOnly );
|
||||||
}
|
}
|
||||||
if( binding != null ){
|
if( binding != null ){
|
||||||
if( (bits & TAGS) != 0 && !(binding instanceof ICompositeType) ||
|
if( (bits & TAGS) != 0 && !(binding instanceof ICompositeType) ||
|
||||||
|
@ -1008,49 +1003,71 @@ public class CVisitor {
|
||||||
return external;
|
return external;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IBinding checkForBinding( IASTDeclaration declaration, IASTName name ){
|
private static IBinding checkForBinding( IASTDeclSpecifier declSpec, IASTName name, boolean typesOnly ){
|
||||||
if( declaration instanceof IASTSimpleDeclaration ){
|
IASTName tempName = null;
|
||||||
IASTSimpleDeclaration simpleDeclaration = (IASTSimpleDeclaration) declaration;
|
if( typesOnly ){
|
||||||
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();
|
|
||||||
if( declSpec instanceof ICASTElaboratedTypeSpecifier ){
|
if( declSpec instanceof ICASTElaboratedTypeSpecifier ){
|
||||||
IASTName elabName = ((ICASTElaboratedTypeSpecifier)declSpec).getName();
|
tempName = ((ICASTElaboratedTypeSpecifier)declSpec).getName();
|
||||||
if( CharArrayUtils.equals( elabName.toCharArray(), name.toCharArray() ) ){
|
if( CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
|
||||||
return elabName.resolveBinding();
|
return tempName.resolveBinding();
|
||||||
}
|
}
|
||||||
} else if( declSpec instanceof ICASTCompositeTypeSpecifier ){
|
} else if( declSpec instanceof ICASTCompositeTypeSpecifier ){
|
||||||
IASTName compName = ((ICASTCompositeTypeSpecifier)declSpec).getName();
|
tempName = ((ICASTCompositeTypeSpecifier)declSpec).getName();
|
||||||
if( CharArrayUtils.equals( compName.toCharArray(), name.toCharArray() ) ){
|
if( CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
|
||||||
return compName.resolveBinding();
|
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 ){
|
} else if( declSpec instanceof ICASTEnumerationSpecifier ){
|
||||||
ICASTEnumerationSpecifier enumeration = (ICASTEnumerationSpecifier) declSpec;
|
ICASTEnumerationSpecifier enumeration = (ICASTEnumerationSpecifier) declSpec;
|
||||||
IASTName eName = enumeration.getName();
|
tempName = enumeration.getName();
|
||||||
if( CharArrayUtils.equals( eName.toCharArray(), name.toCharArray() ) ){
|
if( CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
|
||||||
return eName.resolveBinding();
|
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++ ) {
|
for( int i = 0; i < list.length; i++ ) {
|
||||||
IASTEnumerator enumerator = list[i];
|
IASTEnumerator enumerator = list[i];
|
||||||
if( enumerator == null ) break;
|
if( enumerator == null ) break;
|
||||||
eName = enumerator.getName();
|
tempName = enumerator.getName();
|
||||||
if( CharArrayUtils.equals( eName.toCharArray(), name.toCharArray() ) ){
|
if( CharArrayUtils.equals( tempName.toCharArray(), name.toCharArray() ) ){
|
||||||
return eName.resolveBinding();
|
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;
|
IASTFunctionDefinition functionDef = (IASTFunctionDefinition) declaration;
|
||||||
|
|
||||||
if (functionDef.getDeclarator() instanceof IASTStandardFunctionDeclarator) {
|
if (functionDef.getDeclarator() instanceof IASTStandardFunctionDeclarator) {
|
||||||
|
@ -1097,13 +1114,13 @@ public class CVisitor {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IBinding checkForBinding( IASTStatement statement, IASTName name ){
|
private static IBinding checkForBinding( IASTStatement statement, IASTName name, boolean typesOnly ){
|
||||||
if( statement instanceof IASTDeclarationStatement ){
|
if( statement instanceof IASTDeclarationStatement ){
|
||||||
return checkForBinding( ((IASTDeclarationStatement)statement).getDeclaration(), name );
|
return checkForBinding( ((IASTDeclarationStatement)statement).getDeclaration(), name, typesOnly );
|
||||||
} else if( statement instanceof IASTForStatement ){
|
} else if( statement instanceof IASTForStatement ){
|
||||||
IASTForStatement forStatement = (IASTForStatement) statement;
|
IASTForStatement forStatement = (IASTForStatement) statement;
|
||||||
if( forStatement.getInitDeclaration() != null ){
|
if( forStatement.getInitDeclaration() != null ){
|
||||||
return checkForBinding( forStatement.getInitDeclaration(), name );
|
return checkForBinding( forStatement.getInitDeclaration(), name, typesOnly );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
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.ICPPReferenceType;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
|
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.ast.IASTNamespaceDefinition;
|
||||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||||
|
@ -289,16 +290,13 @@ public class CPPSemantics {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
static protected IBinding resolveBinding( IASTName name ){
|
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();
|
IASTNode node = name.getParent();
|
||||||
if( node instanceof ICPPASTQualifiedName ){
|
if( node instanceof ICPPASTQualifiedName ){
|
||||||
ICPPASTQualifiedName qname = (ICPPASTQualifiedName) node;
|
ICPPASTQualifiedName qname = (ICPPASTQualifiedName) node;
|
||||||
if( qname.getNames()[0] == name ){
|
if( qname.getNames()[0] == name ){
|
||||||
//translation unit
|
//translation unit
|
||||||
while( ! (node instanceof ICPPASTTranslationUnit ) ){
|
return ((ICPPASTTranslationUnit)node.getTranslationUnit()).resolveBinding();
|
||||||
node = node.getParent();
|
|
||||||
}
|
|
||||||
return ((ICPPASTTranslationUnit) node).resolveBinding();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -479,8 +477,16 @@ public class CPPSemantics {
|
||||||
int size = bases.length;
|
int size = bases.length;
|
||||||
for( int i = 0; i < size; i++ )
|
for( int i = 0; i < size; i++ )
|
||||||
{
|
{
|
||||||
ICPPClassType binding = (ICPPClassType) bases[i].getName().resolveBinding();
|
ICPPClassType cls = null;
|
||||||
ICPPClassScope parent = (ICPPClassScope) binding.getCompositeScope();
|
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 )
|
if( parent == null )
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Add table
Reference in a new issue