1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-01 14:15:23 +02:00

fixing problems encountered when resolving bindings in some order other than top down

- declarations of template parameters
- containing scope of a method
This commit is contained in:
Andrew Niefer 2005-04-27 18:30:34 +00:00
parent 301b9f9cc3
commit af10bf00cb
21 changed files with 295 additions and 59 deletions

View file

@ -858,4 +858,21 @@ public class AST2TemplateTests extends AST2BaseTest {
assertTrue( A1 instanceof ICPPTemplateInstance );
assertSame( ((ICPPTemplateInstance)A1).getOriginalBinding(), A );
}
public void testTemplateParameterDeclarations() throws Exception {
StringBuffer buffer = new StringBuffer();
buffer.append( "template <class T> void f( T ); \n"); //$NON-NLS-1$
buffer.append( "template <class T> void f( T ) {} \n"); //$NON-NLS-1$
IASTTranslationUnit tu = parse( buffer.toString(), ParserLanguage.CPP );
CPPNameCollector col = new CPPNameCollector();
tu.accept( col );
ICPPTemplateParameter T1 = (ICPPTemplateParameter) col.getName(4).resolveBinding();
ICPPTemplateParameter T2 = (ICPPTemplateParameter) col.getName(2).resolveBinding();
assertSame( T1, T2 );
assertInstances( col, T1, 4 );
}
}

View file

@ -213,5 +213,42 @@ public class ArrayUtil {
return array;
}
/**
* Insert the obj at the beginning of the array, shifting the whole thing one index
* @param c
* @param array
* @param idx
* @param obj
* @return
*/
public static Object[] prepend(Class c, Object[] array, Object obj) {
if( obj == null )
return array;
if( array == null || array.length == 0){
array = (Object[]) Array.newInstance( c, DEFAULT_LENGTH );
array[0] = obj;
return array;
}
int i = 0;
for( ; i < array.length; i++ ){
if( array[i] == null ){
array[i] = obj;
return array;
}
}
if( i < array.length ){
System.arraycopy( array, 0, array, 1, array.length - i );
array[0] = obj;
} else {
Object [] temp = (Object[]) Array.newInstance( c, array.length * 2 );
System.arraycopy( array, 0, temp, 1, array.length );
temp[0] = obj;
array = temp;
}
return array;
}
}

View file

@ -384,12 +384,28 @@ public class CPPClassType implements ICPPClassType, ICPPInternalClassType {
//keep the lowest offset declaration in [0]
if( declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset() ){
IASTName temp = declarations[0];
declarations[0] = name;
node = temp;
declarations = (IASTName[]) ArrayUtil.prepend( IASTName.class, declarations, name );
} else {
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
}
public void removeDeclaration(IASTNode node) {
if( definition == node ){
definition = null;
return;
}
if( declarations != null ) {
for (int i = 0; i < declarations.length; i++) {
if( node == declarations[i] ) {
if( i == declarations.length - 1 )
declarations[i] = null;
else
System.arraycopy( declarations, i + 1, declarations, i, declarations.length - 1 - i );
return;
}
}
}
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
/* (non-Javadoc)

View file

@ -232,6 +232,9 @@ public class CPPDeferredClassInstance /*extends CPPInstance*/ implements
}
public void removeDeclaration(IASTNode node) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance#getOriginalBinding()
*/

View file

@ -244,6 +244,10 @@ public class CPPDeferredFunctionInstance /*extends CPPInstance*/ implements
// TODO Auto-generated method stub
}
public void removeDeclaration(IASTNode node) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalFunction#isStatic(boolean)

View file

@ -149,5 +149,9 @@ public class CPPDelegate implements ICPPDelegate, ICPPInternalBinding {
// TODO Auto-generated method stub
}
public void removeDeclaration(IASTNode node) {
}
}

View file

@ -169,6 +169,10 @@ public class CPPEnumeration implements IEnumeration, ICPPInternalBinding, ICPPBi
// TODO Auto-generated method stub
}
public void removeDeclaration(IASTNode node) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IType#isSameType(org.eclipse.cdt.core.dom.ast.IType)

View file

@ -62,7 +62,8 @@ public class CPPEnumerator implements IEnumerator, ICPPInternalBinding, ICPPBind
public IASTNode getDefinition() {
return enumName;
}
public void removeDeclaration(IASTNode node) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.IBinding#getName()
*/

View file

@ -225,12 +225,31 @@ public class CPPFunction implements ICPPFunction, ICPPInternalFunction {
//keep the lowest offset declaration in [0]
if( declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset() ){
ICPPASTFunctionDeclarator temp = declarations[0];
declarations[0] = dtor;
dtor = temp;
declarations = (ICPPASTFunctionDeclarator[]) ArrayUtil.prepend( ICPPASTFunctionDeclarator.class, declarations, dtor );
} else {
declarations = (ICPPASTFunctionDeclarator[]) ArrayUtil.append( ICPPASTFunctionDeclarator.class, declarations, dtor );
}
}
public void removeDeclaration(IASTNode node) {
while( node instanceof IASTName ){
node = node.getParent();
}
if( definition == node ){
definition = null;
return;
}
if( declarations != null ) {
for (int i = 0; i < declarations.length; i++) {
if( node == declarations[i] ) {
if( i == declarations.length - 1 )
declarations[i] = null;
else
System.arraycopy( declarations, i + 1, declarations, i, declarations.length - 1 - i );
return;
}
}
}
declarations = (ICPPASTFunctionDeclarator[]) ArrayUtil.append( ICPPASTFunctionDeclarator.class, declarations, dtor );
}
/* (non-Javadoc)

View file

@ -94,6 +94,10 @@ public class CPPInstance implements ICPPTemplateInstance {
// TODO Auto-generated method stub
}
public void removeDeclaration(IASTNode node) {
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance#getArguments()
*/

View file

@ -139,6 +139,9 @@ public class CPPLabel implements ILabel, ICPPInternalBinding, ICPPBinding {
// TODO Auto-generated method stub
}
public void removeDeclaration(IASTNode node) {
}
}

View file

@ -134,6 +134,14 @@ public class CPPMethod extends CPPFunction implements ICPPMethod {
public IScope getScope() {
IASTNode node = (declarations != null && declarations.length > 0) ? declarations[0] : definition;
if( node instanceof IASTDeclarator ){
IASTName name = ((IASTDeclarator)node).getName();
if( name instanceof ICPPASTQualifiedName ){
IASTName [] ns = ((ICPPASTQualifiedName)name).getNames();
name = ns[ ns.length - 1 ];
}
return CPPVisitor.getContainingScope( name );
}
return CPPVisitor.getContainingScope( node );
}
@ -174,8 +182,22 @@ public class CPPMethod extends CPPFunction implements ICPPMethod {
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod#isVirtual()
*/
public boolean isVirtual() throws DOMException {
// TODO Auto-generated method stub
public boolean isVirtual() {
if( definition != null ){
IASTNode node = definition.getParent();
while( node instanceof IASTDeclarator )
node = node.getParent();
ICPPASTDeclSpecifier declSpec = null;
if( node instanceof IASTSimpleDeclaration )
declSpec = (ICPPASTDeclSpecifier) ((IASTSimpleDeclaration)node).getDeclSpecifier();
else if( node instanceof IASTFunctionDefinition )
declSpec = (ICPPASTDeclSpecifier) ((IASTFunctionDefinition)node).getDeclSpecifier();
if( declSpec != null ){
return declSpec.isVirtual();
}
}
return false;
}

View file

@ -232,12 +232,10 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
}
if( namespaceDefinitions.length > 0 && ((ASTNode)name).getOffset() < ((ASTNode)namespaceDefinitions[0]).getOffset() ){
IASTName temp = namespaceDefinitions[0];
namespaceDefinitions[0] = name;
name = temp;
namespaceDefinitions = (IASTName[]) ArrayUtil.prepend( IASTName.class, namespaceDefinitions, name );
} else {
namespaceDefinitions = (IASTName[]) ArrayUtil.append( IASTName.class, namespaceDefinitions, name );
}
namespaceDefinitions = (IASTName[]) ArrayUtil.append( IASTName.class, namespaceDefinitions, name );
}
/* (non-Javadoc)
@ -246,5 +244,18 @@ public class CPPNamespace implements ICPPNamespace, ICPPInternalBinding {
public void addDeclaration(IASTNode node) {
addDefinition( node );
}
public void removeDeclaration(IASTNode node) {
if( namespaceDefinitions != null ) {
for (int i = 0; i < namespaceDefinitions.length; i++) {
if( node == namespaceDefinitions[i] ) {
if( i == namespaceDefinitions.length - 1 )
namespaceDefinitions[i] = null;
else
System.arraycopy( namespaceDefinitions, i + 1, namespaceDefinitions, i, namespaceDefinitions.length - 1 - i );
return;
}
}
}
}
}

View file

@ -143,4 +143,7 @@ public class CPPNamespaceAlias implements ICPPNamespaceAlias, ICPPInternalBindin
*/
public void addDeclaration(IASTNode node) {
}
public void removeDeclaration(IASTNode node) {
}
}

View file

@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
/**
* @author aniefer
@ -90,14 +91,30 @@ public class CPPParameter implements ICPPParameter, ICPPInternalBinding {
if( !(node instanceof IASTName ) )
return;
IASTName name = (IASTName) node;
if( declarations == null ){
declarations = new IASTName [] { name };
return;
}
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
if( declarations == null )
declarations = new IASTName[] { name };
else {
//keep the lowest offset declaration in [0]
if( declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset() ){
declarations = (IASTName[]) ArrayUtil.prepend( IASTName.class, declarations, name );
} else {
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
}
}
public void removeDeclaration(IASTNode node) {
if( declarations != null ) {
for (int i = 0; i < declarations.length; i++) {
if( node == declarations[i] ) {
if( i == declarations.length - 1 )
declarations[i] = null;
else
System.arraycopy( declarations, i + 1, declarations, i, declarations.length - 1 - i );
}
}
}
}
private IASTName getPrimaryDeclaration(){
if( declarations != null ){
for( int i = 0; i < declarations.length && declarations[i] != null; i++ ){

View file

@ -41,6 +41,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
/**
@ -365,13 +366,35 @@ public abstract class CPPTemplateDefinition implements ICPPTemplateDefinition, I
return;
IASTName declName = (IASTName) node;
updateTemplateParameterBindings( declName );
if( declarations == null ){
declarations = new IASTName [] { declName };
return;
}
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, declName );
if( declarations == null )
declarations = new IASTName[] { declName };
else {
//keep the lowest offset declaration in [0]
if( declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset() ){
declarations = (IASTName[]) ArrayUtil.prepend( IASTName.class, declarations, declName );
} else {
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, declName );
}
}
}
public void removeDeclaration(IASTNode node) {
if( definition == node ){
definition = null;
return;
}
if( declarations != null ) {
for (int i = 0; i < declarations.length; i++) {
if( node == declarations[i] ) {
if( i == declarations.length - 1 )
declarations[i] = null;
else
System.arraycopy( declarations, i + 1, declarations, i, declarations.length - 1 - i );
return;
}
}
}
}
protected void updateTemplateParameterBindings( IASTName name ){
IASTName orig = definition != null ? definition : declarations[0];
ICPPASTTemplateDeclaration origTemplate = CPPTemplates.getTemplateDeclaration( orig );

View file

@ -17,9 +17,10 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPDelegate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
/**
* @author aniefer
@ -65,20 +66,6 @@ public class CPPTemplateParameter implements ICPPTemplateParameter, ICPPInternal
return CPPVisitor.getContainingScope( getPrimaryDeclaration () );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#isTemplateInstance()
*/
public boolean isTemplateInstance() {
return false;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#getTemplatedBinding()
*/
public ICPPBinding getTemplatedBinding() {
return null;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding#getQualifiedName()
*/
@ -114,6 +101,8 @@ public class CPPTemplateParameter implements ICPPTemplateParameter, ICPPInternal
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#getDefinition()
*/
public IASTNode getDefinition() {
if( declarations != null && declarations.length > 0 )
return declarations[0];
return null;
}
@ -129,15 +118,39 @@ public class CPPTemplateParameter implements ICPPTemplateParameter, ICPPInternal
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDefinition(org.eclipse.cdt.core.dom.ast.IASTNode)
*/
public void addDefinition(IASTNode node) {
// TODO Auto-generated method stub
addDeclaration( node );
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalBinding#addDeclaration(org.eclipse.cdt.core.dom.ast.IASTNode)
*/
public void addDeclaration(IASTNode node) {
// TODO Auto-generated method stub
if( !(node instanceof IASTName) )
return;
IASTName name = (IASTName) node;
if( declarations == null )
declarations = new IASTName[] { name };
else {
//keep the lowest offset declaration in [0]
if( declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset() ){
IASTName temp = declarations[0];
declarations[0] = name;
name = temp;
}
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
}
public void removeDeclaration(IASTNode node) {
if( declarations != null ) {
for (int i = 0; i < declarations.length; i++) {
if( node == declarations[i] ) {
if( i == declarations.length - 1 )
declarations[i] = null;
else
System.arraycopy( declarations, i + 1, declarations, i, declarations.length - 1 - i );
return;
}
}
}
}
}

View file

@ -557,8 +557,12 @@ public class CPPTemplates {
this.bindings = bindings;
}
public int visit(IASTName name) {
if( name.getBinding() != null && bindings.containsKey( name.getBinding() ) )
if( name.getBinding() != null && bindings.containsKey( name.getBinding() ) ){
IBinding binding = name.getBinding();
if( binding instanceof ICPPInternalBinding )
((ICPPInternalBinding)binding).removeDeclaration( name );
name.setBinding( null );
}
return PROCESS_CONTINUE;
}
public int visit(IASTStatement statement) {
@ -590,6 +594,7 @@ public class CPPTemplates {
if( bindingsToClear == null )
bindingsToClear = new ObjectSet( templateParams.length );
tn.setBinding( defParams[i] );
((ICPPInternalBinding)defParams[i]).addDeclaration( tn );
bindingsToClear.put( defParams[i] );
}
@ -641,7 +646,7 @@ public class CPPTemplates {
}
}
if( bindingsToClear != null ){
if( bindingsToClear != null && !result ){
ClearBindingAction action = new ClearBindingAction( bindingsToClear );
templateDecl.accept( action );
}

View file

@ -191,11 +191,24 @@ public class CPPTypedef implements ITypedef, ITypeContainer, ICPPInternalBinding
else {
//keep the lowest offset declaration in [0]
if( declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset() ){
IASTName temp = declarations[0];
declarations[0] = name;
name = temp;
declarations = (IASTName[]) ArrayUtil.prepend( IASTName.class, declarations, name );
} else {
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
}
public void removeDeclaration(IASTNode node) {
if( declarations != null ) {
for (int i = 0; i < declarations.length; i++) {
if( node == declarations[i] ) {
if( i == declarations.length - 1 )
declarations[i] = null;
else
System.arraycopy( declarations, i + 1, declarations, i, declarations.length - 1 - i );
return;
}
}
}
}
}

View file

@ -150,13 +150,30 @@ public class CPPVariable implements ICPPVariable, ICPPInternalBinding {
else {
//keep the lowest offset declaration in [0]
if( declarations.length > 0 && ((ASTNode)node).getOffset() < ((ASTNode)declarations[0]).getOffset() ){
IASTName temp = declarations[0];
declarations[0] = name;
name = temp;
declarations = (IASTName[]) ArrayUtil.prepend( IASTName.class, declarations, name );
} else {
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
declarations = (IASTName[]) ArrayUtil.append( IASTName.class, declarations, name );
}
}
public void removeDeclaration(IASTNode node) {
if( node == definition ){
definition = null;
return;
}
if( declarations != null ) {
for (int i = 0; i < declarations.length; i++) {
if( node == declarations[i] ) {
if( i == declarations.length - 1 )
declarations[i] = null;
else
System.arraycopy( declarations, i + 1, declarations, i, declarations.length - 1 - i );
}
}
}
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPBinding#getDeclarations()
*/
@ -339,5 +356,4 @@ public class CPPVariable implements ICPPVariable, ICPPInternalBinding {
public boolean isRegister() {
return hasStorageClass( IASTDeclSpecifier.sc_register );
}
}

View file

@ -36,4 +36,5 @@ public interface ICPPInternalBinding extends IBinding {
*/
void addDefinition( IASTNode node );
void addDeclaration( IASTNode node );
void removeDeclaration(IASTNode node);
}