From 656d059c2511f1435c978becdc114cd35c9b7e55 Mon Sep 17 00:00:00 2001 From: Andrew Niefer Date: Tue, 14 Dec 2004 15:33:13 +0000 Subject: [PATCH] - IArrayType - function types and parameter bindings --- .../core/parser/tests/ast2/AST2CPPTests.java | 92 +++++++++++- .../eclipse/cdt/core/dom/ast/IArrayType.java | 23 +++ .../cdt/core/dom/ast/cpp/ICPPScope.java | 3 +- .../core/dom/parser/cpp/CPPASTName.java | 3 + .../core/dom/parser/cpp/CPPArrayType.java | 33 ++++ .../core/dom/parser/cpp/CPPClassScope.java | 3 +- .../core/dom/parser/cpp/CPPFunction.java | 91 +++++++++-- .../core/dom/parser/cpp/CPPFunctionScope.java | 3 +- .../core/dom/parser/cpp/CPPFunctionType.java | 66 ++++++++ .../dom/parser/cpp/CPPNamespaceScope.java | 28 +++- .../core/dom/parser/cpp/CPPPointerType.java | 2 +- .../core/dom/parser/cpp/CPPQualifierType.java | 55 +++++++ .../core/dom/parser/cpp/CPPSemantics.java | 62 +++++++- .../core/dom/parser/cpp/CPPTypedef.java | 2 +- .../core/dom/parser/cpp/CPPVisitor.java | 142 +++++++++++++++--- .../dom/parser/cpp/ICPPTypeContainer.java | 24 +++ 16 files changed, 584 insertions(+), 48 deletions(-) create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IArrayType.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPTypeContainer.java diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java index bd3df1c5cc1..3ab8454e9c2 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2CPPTests.java @@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IField; import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IParameter; import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; @@ -439,7 +440,7 @@ public class AST2CPPTests extends AST2BaseTest { assertInstances( collector, f, 1 ); assertInstances( collector, myS, 2 ); } - public void _testStructureTags() throws Exception { + public void testStructureTags_1() throws Exception { StringBuffer buffer = new StringBuffer(); buffer.append( "struct A; \n" ); //$NON-NLS-1$ buffer.append( "void f(){ \n" ); //$NON-NLS-1$ @@ -451,11 +452,94 @@ public class AST2CPPTests extends AST2BaseTest { CPPNameCollector collector = new CPPNameCollector(); CPPVisitor.visitTranslationUnit( tu, collector ); - ICPPClassType A = (ICPPClassType) collector.getName( 0 ).resolveBinding(); + ICPPClassType A1 = (ICPPClassType) collector.getName( 0 ).resolveBinding(); + ICPPClassType A2 = (ICPPClassType) collector.getName( 2 ).resolveBinding(); IVariable a = (IVariable) collector.getName( 4 ).resolveBinding(); - assertInstances( collector, A, 3 ); - assertInstances( collector, a, 1 ); + assertNotNull( a ); + assertNotNull( A1 ); + assertNotNull( A2 ); + assertNotSame( A1, A2 ); + assertInstances( collector, A1, 1 ); + assertInstances( collector, A2, 2 ); + } + + public void testStructureTags_2() throws Exception{ + StringBuffer buffer = new StringBuffer(); + buffer.append( "struct A; \n" ); //$NON-NLS-1$ + buffer.append( "void f(){ \n" ); //$NON-NLS-1$ + buffer.append( " struct A * a; \n" ); //$NON-NLS-1$ + buffer.append( "} \r\n" ); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector collector = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, collector ); + + ICPPClassType A1 = (ICPPClassType) collector.getName( 0 ).resolveBinding(); + ICPPClassType A2 = (ICPPClassType) collector.getName( 2 ).resolveBinding(); + IVariable a = (IVariable) collector.getName( 3 ).resolveBinding(); + + assertNotNull( a ); + assertNotNull( A1 ); + assertNotNull( A2 ); + assertSame( A1, A2 ); + assertInstances( collector, A1, 2 ); + } + + public void testStructureDef() throws Exception{ + StringBuffer buffer = new StringBuffer(); + buffer.append( "struct A; \r\n"); //$NON-NLS-1$ + buffer.append( "struct A * a; \n"); //$NON-NLS-1$ + buffer.append( "struct A { int i; }; \n"); //$NON-NLS-1$ + buffer.append( "void f() { \n"); //$NON-NLS-1$ + buffer.append( " a->i; \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector collector = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, collector ); + + ICPPClassType A1 = (ICPPClassType) collector.getName( 0 ).resolveBinding(); + IVariable a = (IVariable) collector.getName( 2 ).resolveBinding(); + ICPPField i = (ICPPField) collector.getName( 4 ).resolveBinding(); + + assertInstances( collector, A1, 3 ); + assertInstances( collector, a, 2 ); + assertInstances( collector, i, 2 ); + } + + public void testStructureNamespace() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "struct x {}; \n" ); //$NON-NLS-1$ + buffer.append( "void f( int x ) { \n" ); //$NON-NLS-1$ + buffer.append( " struct x i; \n" ); //$NON-NLS-1$ + buffer.append( "} \n" ); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector collector = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, collector ); + + ICPPClassType x = (ICPPClassType) collector.getName(0).resolveBinding(); + + assertInstances( collector, x, 2 ); + } + + public void testFunctionDef() throws Exception { + StringBuffer buffer = new StringBuffer(); + buffer.append( "void f( int a ); \n"); //$NON-NLS-1$ + buffer.append( "void f( int b ){ \n"); //$NON-NLS-1$ + buffer.append( " b; \n"); //$NON-NLS-1$ + buffer.append( "} \n"); //$NON-NLS-1$ + + IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP ); + CPPNameCollector collector = new CPPNameCollector(); + CPPVisitor.visitTranslationUnit( tu, collector ); + + IFunction f = (IFunction) collector.getName(0).resolveBinding(); + IParameter a = (IParameter) collector.getName( 1 ).resolveBinding(); + + assertInstances( collector, f, 2 ); + assertInstances( collector, a, 3 ); } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IArrayType.java new file mode 100644 index 00000000000..4d23480c99a --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/IArrayType.java @@ -0,0 +1,23 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Dec 13, 2004 + */ +package org.eclipse.cdt.core.dom.ast; + +/** + * @author aniefer + */ +public interface IArrayType extends IType { + + IType getType(); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPScope.java index 1fc6b913878..214f273fb5d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/core/dom/ast/cpp/ICPPScope.java @@ -13,6 +13,7 @@ */ package org.eclipse.cdt.core.dom.ast.cpp; +import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IScope; @@ -23,5 +24,5 @@ import org.eclipse.cdt.core.dom.ast.IScope; public interface ICPPScope extends IScope { public IASTNode getPhysicalNode(); public void addBinding( IBinding binding ); - public IBinding getBinding( int namespaceType, char [] name ); + public IBinding getBinding( IASTName name ); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java index ec5b7db85d6..519d7540c31 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java @@ -49,6 +49,9 @@ public class CPPASTName extends CPPASTNode implements IASTName { protected void setBinding( IBinding binding ){ this.binding = binding; } + protected IBinding getBinding(){ + return binding; + } /* (non-Javadoc) * @see java.lang.Object#toString() diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java new file mode 100644 index 00000000000..94d73db14cc --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPArrayType.java @@ -0,0 +1,33 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Dec 13, 2004 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IArrayType; +import org.eclipse.cdt.core.dom.ast.IType; + +/** + * @author aniefer + */ +public class CPPArrayType implements IArrayType, ICPPTypeContainer { + private IType type = null; + + public CPPArrayType( IType type ){ + this.type = type; + } + + public IType getType(){ + return type; + } +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java index 6b8eff43896..e0d5fabdc0a 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassScope.java @@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import java.util.List; +import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; @@ -39,7 +40,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope { /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[]) */ - public IBinding getBinding(int namespaceType, char[] name) { + public IBinding getBinding( IASTName name ) { // TODO Auto-generated method stub return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java index dcd08f4748f..4ddca342d25 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunction.java @@ -13,11 +13,15 @@ */ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.ArrayList; import java.util.List; import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration; +import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IScope; @@ -27,23 +31,26 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; * @author aniefer */ public class CPPFunction implements IFunction { - protected IASTFunctionDeclarator [] declarations; - protected IASTFunctionDeclarator definition; + protected ICPPASTFunctionDeclarator [] declarations; + protected ICPPASTFunctionDeclarator definition; + private IFunctionType type = null; public CPPFunction( ICPPASTFunctionDeclarator declarator ){ IASTNode parent = declarator.getParent(); if( parent instanceof IASTFunctionDefinition ) definition = declarator; else - declarations = new IASTFunctionDeclarator [] { declarator }; + declarations = new ICPPASTFunctionDeclarator [] { declarator }; } - public void addDefinition( IASTFunctionDeclarator dtor ){ + public void addDefinition( ICPPASTFunctionDeclarator dtor ){ + updateParameterBindings( dtor ); definition = dtor; } - public void addDeclaration( IASTFunctionDeclarator dtor ){ + public void addDeclaration( ICPPASTFunctionDeclarator dtor ){ + updateParameterBindings( dtor ); if( declarations == null ){ - declarations = new IASTFunctionDeclarator [] { dtor }; + declarations = new ICPPASTFunctionDeclarator [] { dtor }; return; } for( int i = 0; i < declarations.length; i++ ){ @@ -52,7 +59,7 @@ public class CPPFunction implements IFunction { return; } } - IASTFunctionDeclarator [] tmp = new IASTFunctionDeclarator[ declarations.length * 2 ]; + ICPPASTFunctionDeclarator [] tmp = new ICPPASTFunctionDeclarator[ declarations.length * 2 ]; System.arraycopy( declarations, 0, tmp, 0, declarations.length ); tmp[ declarations.length ] = dtor; declarations = tmp; @@ -61,16 +68,28 @@ public class CPPFunction implements IFunction { * @see org.eclipse.cdt.core.dom.ast.IFunction#getParameters() */ public List getParameters() { - // TODO Auto-generated method stub - return null; + IASTFunctionDeclarator dtor = ( definition != null ) ? definition : declarations[0]; + IASTParameterDeclaration[] params = dtor.getParameters(); + int size = params.length; + List result = new ArrayList( size ); + if( size > 0 ){ + for( int i = 0; i < size; i++ ){ + IASTParameterDeclaration p = params[i]; + result.add( p.getDeclarator().getName().resolveBinding() ); + } + } + return result; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IFunction#getFunctionScope() */ public IScope getFunctionScope() { - IASTFunctionDefinition def = (IASTFunctionDefinition) definition.getParent(); - return def.getScope(); + if( definition != null ){ + IASTFunctionDefinition def = (IASTFunctionDefinition) definition.getParent(); + return def.getScope(); + } + return null; } /* (non-Javadoc) @@ -98,16 +117,58 @@ public class CPPFunction implements IFunction { * @see org.eclipse.cdt.core.dom.ast.IBinding#getPhysicalNode() */ public IASTNode getPhysicalNode() { - // TODO Auto-generated method stub - return null; + return ( definition != null ) ? definition : declarations[0]; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IFunction#getType() */ public IFunctionType getType() { - // TODO Auto-generated method stub - return null; + if( type == null ) + type = CPPVisitor.createType( ( definition != null ) ? definition : declarations[0] ); + return type; } + public IBinding resolveParameter( IASTParameterDeclaration param ){ + IASTName name = param.getDeclarator().getName(); + IBinding binding = ((CPPASTName)name).getBinding(); + if( binding != null ) + return binding; + + IASTFunctionDeclarator fdtor = (IASTFunctionDeclarator) param.getParent(); + IASTParameterDeclaration [] ps = fdtor.getParameters(); + int i = 0; + for( ; i < ps.length; i++ ){ + if( param == ps[i] ) + break; + } + + //create a new binding and set it for the corresponding parameter in all known defns and decls + binding = new CPPParameter( param.getDeclarator() ); + IASTParameterDeclaration temp = null; + if( definition != null ){ + temp = definition.getParameters()[i]; + ((CPPASTName)temp.getDeclarator().getName()).setBinding( binding ); + } + if( declarations != null ){ + for( int j = 0; j < declarations.length; j++ ){ + temp = declarations[j].getParameters()[i]; + ((CPPASTName)temp.getDeclarator().getName()).setBinding( binding ); + } + } + return binding; + } + + private void updateParameterBindings( ICPPASTFunctionDeclarator fdtor ){ + ICPPASTFunctionDeclarator orig = (ICPPASTFunctionDeclarator) getPhysicalNode(); + IASTParameterDeclaration [] ops = orig.getParameters(); + IASTParameterDeclaration [] nps = fdtor.getParameters(); + IBinding temp = null; + for( int i = 0; i < nps.length; i++ ){ + temp = ((CPPASTName)ops[i].getDeclarator().getName()).getBinding(); + if( temp != null ){ + ((CPPASTName)nps[i].getDeclarator().getName()).setBinding( temp ); + } + } + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java index 20a35ff54b7..f3c7924b607 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionScope.java @@ -16,6 +16,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import java.util.List; import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition; +import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; import org.eclipse.cdt.core.dom.ast.IScope; @@ -45,7 +46,7 @@ public class CPPFunctionScope extends CPPScope implements ICPPFunctionScope { /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[]) */ - public IBinding getBinding(int namespaceType, char[] name) { + public IBinding getBinding( IASTName name ) { // TODO Auto-generated method stub return null; } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java new file mode 100644 index 00000000000..695ea429dfc --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionType.java @@ -0,0 +1,66 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Dec 13, 2004 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IFunctionType; +import org.eclipse.cdt.core.dom.ast.IType; + +/** + * @author aniefer + */ +public class CPPFunctionType implements IFunctionType { + IType[] parameters = null; + IType returnType = null; + + /** + * @param returnType + * @param types + */ + public CPPFunctionType( IType returnType, IType [] types ) { + this.returnType = returnType; + this.parameters = types; + } + + public boolean equals( Object o ){ + if( o instanceof IFunctionType ){ + IFunctionType ft = (IFunctionType) o; + IType [] fps = ft.getParameterTypes(); + + if( fps.length != parameters.length ) + return false; + if( ! returnType.equals( ft.getReturnType() ) ) + return false; + for( int i = 0; i < parameters.length; i++ ) + if( ! parameters[i].equals( fps[i] ) ) + return false; + return true; + } + return false; + } + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunctionType#getReturnType() + */ + public IType getReturnType() { + return returnType; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IFunctionType#getParameterTypes() + */ + public IType[] getParameterTypes() { + return parameters; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java index cf70c13ba8f..a3f0007fb3d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPNamespaceScope.java @@ -13,8 +13,10 @@ */ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.ArrayList; import java.util.List; +import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDirective; @@ -36,14 +38,34 @@ public class CPPNamespaceScope extends CPPScope implements ICPPNamespaceScope{ public void addBinding(IBinding binding) { if( bindings == CharArrayObjectMap.EMPTY_MAP ) bindings = new CharArrayObjectMap(1); - bindings.put( binding.getNameCharArray(), binding ); + char [] c = binding.getNameCharArray(); + Object o = bindings.get( c ); + if( o != null ){ + if( o instanceof List ){ + ((List)o).add( binding ); + } else { + List list = new ArrayList(2); + list.add( o ); + list.add( binding ); + bindings.put( c, list ); + } + } else { + bindings.put( c, binding ); + } } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getBinding(int, char[]) */ - public IBinding getBinding(int namespaceType, char[] name) { - return (IBinding) bindings.get( name ); + public IBinding getBinding( IASTName name ) { + char [] c = name.toCharArray(); + Object obj = bindings.get( c ); + if( obj != null ){ + if( obj instanceof List ){ + obj = CPPSemantics.resolveAmbiguities( name, (List) obj ); + } + } + return (IBinding) obj; } /* (non-Javadoc) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java index cee3d20326d..c355add5443 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPPointerType.java @@ -20,7 +20,7 @@ import org.eclipse.cdt.core.dom.ast.IType; /** * @author aniefer */ -public class CPPPointerType implements IPointerType { +public class CPPPointerType implements IPointerType, ICPPTypeContainer { private IASTPointer operator = null; private IType type = null; /** diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java new file mode 100644 index 00000000000..09efd937c80 --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPQualifierType.java @@ -0,0 +1,55 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Dec 13, 2004 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IQualifierType; +import org.eclipse.cdt.core.dom.ast.IType; + +/** + * @author aniefer + */ +public class CPPQualifierType implements IQualifierType, ICPPTypeContainer { + private boolean isConst = false; + private boolean isVolatile = false; + private IType type = null; + + public CPPQualifierType( IType type, boolean isConst, boolean isVolatile ){ + this.type = type; + this.isConst = isConst; + this.isVolatile = isVolatile; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IQualifierType#isConst() + */ + public boolean isConst() { + return isConst; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IQualifierType#isVolatile() + */ + public boolean isVolatile() { + return isVolatile; + } + + /* (non-Javadoc) + * @see org.eclipse.cdt.core.dom.ast.IQualifierType#getType() + */ + public IType getType() { + return type; + } + +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java index 139d6672381..e31862ac621 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPSemantics.java @@ -47,6 +47,7 @@ import org.eclipse.cdt.core.dom.ast.IQualifierType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.ITypedef; +import org.eclipse.cdt.core.dom.ast.IVariable; import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; @@ -668,12 +669,69 @@ public class CPPSemantics { IASTNode node = name.getParent(); if( node instanceof ICPPASTQualifiedName ) node = node.getParent(); - if( node instanceof IASTFunctionDeclarator ){ - ((CPPFunction)binding).addDefinition( (IASTFunctionDeclarator) node ); + if( node instanceof ICPPASTFunctionDeclarator ){ + ((CPPFunction)binding).addDefinition( (ICPPASTFunctionDeclarator) node ); } } } + static protected IBinding resolveAmbiguities( IASTName name, List bindings ){ + if( bindings == null || bindings.size() == 0 ) + return null; + else if( bindings.size() == 1 ) + return (IBinding) bindings.get( 0 ); + + LookupData data = createLookupData( name ); + + IBinding type = null; + IBinding obj = null; + List fns = null; + for( int i = 0; i < data.foundItems.size(); i++ ){ + IBinding b = (IBinding) bindings.get( i ); + + if( b instanceof IFunction ){ + if( fns == null ) + fns = new ArrayList(2); + IASTName n = ((IASTFunctionDeclarator) ((IFunction)b).getPhysicalNode() ).getName(); + fns.add( n ); + } else if( b instanceof IVariable ){ + if( obj == null ){ + obj = b; + } else { + //TODO + } + } else { + if( type == null ){ + type = b; + } else { + //TODO + } + } + } + + if( type != null ) { + if( obj == null && fns == null ) + return type; + IScope typeScope = type.getScope(); + if( obj != null && obj.getScope() != typeScope ){ + return null;//ambiguous + } else if( fns != null ){ + for( int i = 0; i < fns.size(); i++ ){ + if( ((IBinding)fns.get(i)).getScope() != typeScope ) + return null; //ambiguous + } + } + } + if( fns != null){ + if( obj != null ) + return null; //ambiguous + IASTName n = resolveFunction( data, fns ); + return ( n != null ) ? n.resolveBinding() : null; + } + + return obj; + } + static private IASTName resolveAmbiguities( CPPSemantics.LookupData data, IASTName name ) { if( data.foundItems == null || data.foundItems.size() == 0 ) return null; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java index c2e25c97f3b..8c73b755bc3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTypedef.java @@ -23,7 +23,7 @@ import org.eclipse.cdt.core.dom.ast.ITypedef; /** * @author aniefer */ -public class CPPTypedef implements ITypedef { +public class CPPTypedef implements ITypedef, ICPPTypeContainer { private IASTDeclarator declarator = null; /** * @param declarator diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java index cb88cd66171..4c783b0611f 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPVisitor.java @@ -14,6 +14,12 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator; +import org.eclipse.cdt.core.dom.ast.IASTArrayModifier; import org.eclipse.cdt.core.dom.ast.IASTArraySubscriptExpression; import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression; import org.eclipse.cdt.core.dom.ast.IASTCaseStatement; @@ -62,6 +68,7 @@ import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; import org.eclipse.cdt.core.dom.ast.IBasicType; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IFunction; +import org.eclipse.cdt.core.dom.ast.IFunctionType; import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IVariable; @@ -143,7 +150,7 @@ public class CPPVisitor { } ICPPScope scope = (ICPPScope) getContainingScope( elabType ); - CPPClassType binding = (CPPClassType) scope.getBinding( 0, elabType.getName().toCharArray() ); + CPPClassType binding = (CPPClassType) scope.getBinding( elabType.getName() ); if( binding == null ){ if( elabType.getKind() != IASTElaboratedTypeSpecifier.k_enum ) binding = new CPPClassType( elabType ); @@ -155,12 +162,12 @@ public class CPPVisitor { } private static IBinding createBinding( ICPPASTCompositeTypeSpecifier compType ){ ICPPScope scope = (ICPPScope) getContainingScope( compType ); - CPPClassType binding = (CPPClassType) scope.getBinding( 0, compType.getName().toCharArray() ); - if( binding == null ){ + IBinding binding = scope.getBinding( compType.getName() ); + if( binding == null || !(binding instanceof ICPPClassType) ){ binding = new CPPClassType( compType ); scope.addBinding( binding ); } else { - binding.addDefinition( compType ); + ((CPPClassType)binding).addDefinition( compType ); } return binding; } @@ -168,7 +175,7 @@ public class CPPVisitor { if( declaration instanceof ICPPASTNamespaceDefinition ){ ICPPASTNamespaceDefinition namespaceDef = (ICPPASTNamespaceDefinition) declaration; ICPPScope scope = (ICPPScope) getContainingScope( namespaceDef ); - CPPNamespace binding = (CPPNamespace) scope.getBinding( 0, namespaceDef.getName().toCharArray() ); + CPPNamespace binding = (CPPNamespace) scope.getBinding( namespaceDef.getName() ); if( binding == null ) binding = new CPPNamespace( namespaceDef ); else @@ -182,10 +189,25 @@ public class CPPVisitor { return null; } private static IBinding createBinding( IASTDeclarator declarator ){ - IBinding binding = null; + IASTNode parent = declarator.getParent(); + ICPPScope scope = (ICPPScope) getContainingScope( parent ); + IBinding binding = ( scope != null ) ? scope.getBinding( declarator.getName() ) : null; + if( declarator instanceof ICPPASTFunctionDeclarator ){ - IScope scope = getContainingScope( parent ); + if( binding != null && binding instanceof IFunction ){ + IFunction function = (IFunction) binding; + IFunctionType ftype = function.getType(); + IType type = createType( (ICPPASTFunctionDeclarator) declarator ); + if( ftype.equals( type ) ){ + if( parent instanceof IASTSimpleDeclaration ) + ((CPPFunction)function).addDeclaration( (ICPPASTFunctionDeclarator) declarator ); + else + ((CPPFunction)function).addDefinition( (ICPPASTFunctionDeclarator) declarator ); + + return function; + } + } if( scope instanceof ICPPClassScope ) binding = new CPPMethod( (ICPPASTFunctionDeclarator) declarator ); else @@ -201,11 +223,16 @@ public class CPPVisitor { binding = new CPPVariable( declarator ); } } else if( parent instanceof IASTParameterDeclaration ){ - binding = new CPPParameter( declarator ); + IASTParameterDeclaration param = (IASTParameterDeclaration) parent; + IASTFunctionDeclarator fDtor = (IASTFunctionDeclarator) param.getParent(); + IFunction function = (IFunction) fDtor.getName().resolveBinding(); + binding = ((CPPFunction) function).resolveParameter( param ); } else if( parent instanceof IASTFunctionDefinition ){ } } + if( scope != null ) + scope.addBinding( binding ); return binding; } @@ -745,11 +772,65 @@ public class CPPVisitor { return true; } + public static IFunctionType createType( ICPPASTFunctionDeclarator fnDtor ){ + List pTypes = Collections.EMPTY_LIST; + IASTParameterDeclaration [] params = fnDtor.getParameters(); + IType pt = null; + + for( int i = 0; i < params.length; i++ ){ + IASTDeclSpecifier pDeclSpec = params[i].getDeclSpecifier(); + IASTDeclarator pDtor = params[i].getDeclarator(); + //8.3.5-3 + //Any cv-qualifier modifying a parameter type is deleted. + //so only create the base type from the declspec and not the qualifiers + pt = getBaseType( pDeclSpec ); + + pt = getPointerTypes( pt, pDtor ); + + //any parameter of type array of T is adjusted to be pointer to T + if( pDtor instanceof IASTArrayDeclarator ){ + IASTArrayModifier [] mods = ((IASTArrayDeclarator)pDtor).getArrayModifiers(); + for( int j = 0; j < mods.length - 1; j++ ){ + pt = new CPPArrayType( pt ); + } + if( mods.length > 0 ){ + pt = new CPPPointerType( pt ); + } + } + + //any parameter to type function returning T is adjusted to be pointer to function + if( pt instanceof IFunctionType ){ + pt = new CPPPointerType( pt ); + } + + if( pTypes == Collections.EMPTY_LIST ){ + pTypes = new ArrayList(); + } + pTypes.add( pt ); + } + + IASTNode node = fnDtor.getParent(); + IASTDeclSpecifier declSpec = null; + if( node instanceof IASTSimpleDeclaration ) + declSpec = ((IASTSimpleDeclaration)node).getDeclSpecifier(); + else if ( node instanceof IASTFunctionDefinition ) + declSpec = ((IASTFunctionDefinition)node).getDeclSpecifier(); + + IType returnType = createType( declSpec ); + returnType = getPointerTypes( returnType, fnDtor ); + + IType [] array = new IType [ pTypes.size() ]; + return new CPPFunctionType( returnType, (IType[]) pTypes.toArray( array ) ); + } + /** * @param declarator * @return */ public static IType createType(IASTDeclarator declarator) { + if( declarator instanceof ICPPASTFunctionDeclarator ) + return createType( (ICPPASTFunctionDeclarator)declarator ); + IASTNode parent = declarator.getParent(); IASTDeclSpecifier declSpec = null; if( parent instanceof IASTParameterDeclaration ) @@ -759,26 +840,50 @@ public class CPPVisitor { IType type = createType( declSpec ); - IASTPointerOperator [] ptrOps = declarator.getPointerOperators(); + type = getPointerTypes( type, declarator ); + if( declarator instanceof IASTArrayDeclarator ) + type = getArrayTypes( type, (IASTArrayDeclarator) declarator ); + return type; + } + + private static IType getPointerTypes( IType type, IASTDeclarator declarator ){ + IASTPointerOperator [] ptrOps = declarator.getPointerOperators(); for( int i = ptrOps.length - 1; i >= 0; i-- ){ type = new CPPPointerType( type, (IASTPointer) ptrOps[i] ); } return type; } - + private static IType getArrayTypes( IType type, IASTArrayDeclarator declarator ){ + IASTArrayModifier [] mods = declarator.getArrayModifiers(); + for( int i = 0; i < mods.length; i++ ){ + type = new CPPArrayType( type ); + } + return type; + } + /** * @param declSpec * @return */ - protected static IType createType(IASTDeclSpecifier declSpec) { - if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){ + protected static IType createType(IASTDeclSpecifier declSpec ) { + IType type = getBaseType( declSpec ); + + if( type != null && ( declSpec.isConst() || declSpec.isVolatile() ) ){ + type = new CPPQualifierType( type, declSpec.isConst(), declSpec.isVolatile() ); + } + return type; + } + + private static IType getBaseType( IASTDeclSpecifier declSpec ){ + IType type = null; + if( declSpec instanceof ICPPASTCompositeTypeSpecifier ){ IBinding binding = ((ICPPASTCompositeTypeSpecifier) declSpec).getName().resolveBinding(); if( binding instanceof IType) - return (IType) binding; + type = (IType) binding; } else if( declSpec instanceof ICPPASTElaboratedTypeSpecifier ){ IBinding binding = ((ICPPASTElaboratedTypeSpecifier)declSpec).getName().resolveBinding(); if( binding instanceof IType ) - return (IType) binding; + type = (IType) binding; } else if( declSpec instanceof ICPPASTSimpleDeclSpecifier ){ ICPPASTSimpleDeclSpecifier spec = (ICPPASTSimpleDeclSpecifier) declSpec; int bits = ( spec.isLong() ? CPPBasicType.IS_LONG : 0 ) & @@ -788,14 +893,13 @@ public class CPPVisitor { if( spec instanceof IGPPASTSimpleDeclSpecifier ){ IGPPASTSimpleDeclSpecifier gspec = (IGPPASTSimpleDeclSpecifier) spec; bits &= ( gspec.isLongLong() ? GPPBasicType.IS_LONGLONG : 0 ); - return new GPPBasicType( spec.getType(), bits, getExpressionType(gspec.getTypeofExpression()) ); + type = new GPPBasicType( spec.getType(), bits, getExpressionType(gspec.getTypeofExpression()) ); + } else { + type = new CPPBasicType( spec.getType(), bits ); } - return new CPPBasicType( spec.getType(), bits ); - } - return null; + return type; } - /** * @param expression * @return diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPTypeContainer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPTypeContainer.java new file mode 100644 index 00000000000..3583b27081c --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPTypeContainer.java @@ -0,0 +1,24 @@ +/******************************************************************************* + * Copyright (c) 2004 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ + +/* + * Created on Dec 13, 2004 + */ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IType; + +/** + * @author aniefer + */ +public interface ICPPTypeContainer extends IType{ + IType getType(); +}