From 49724e630c7531a756571106ba65c13da42c00c8 Mon Sep 17 00:00:00 2001 From: Doug Schaefer Date: Wed, 4 Apr 2007 15:30:20 +0000 Subject: [PATCH] Patch for Bryan continuing 167098: - implements base classes for class instances and class specializations - allows for instantiation/specialization during incremental reindexes - prior to this a full reindex was required to properly resolve newly added implicit instances and specializations - renders templates less exception-prone - cleaned up code from last patch --- core/org.eclipse.cdt.core.tests/.cproject | 13 + .../.settings/org.eclipse.cdt.core.prefs | 3 +- .../parser/tests/ast2/AST2TemplateTests.java | 7 +- .../tests/IndexCPPBindingResolutionTest.java | 2 +- .../core/dom/parser/cpp/CPPClassInstance.java | 5 +- .../parser/cpp/CPPClassSpecialization.java | 7 +- .../cpp/CPPClassSpecializationScope.java | 359 +++++------------- .../cpp/CPPClassTemplateSpecialization.java | 2 +- .../parser/cpp/CPPDeferredClassInstance.java | 6 +- .../core/dom/parser/cpp/CPPFunction.java | 8 +- .../parser/cpp/CPPFunctionSpecialization.java | 9 +- .../core/dom/parser/cpp/CPPSemantics.java | 23 +- .../dom/parser/cpp/CPPTemplateDefinition.java | 4 +- .../core/dom/parser/cpp/CPPTemplates.java | 6 +- .../ICPPInternalDeferredClassInstance.java | 27 ++ .../composite/CompositeIndexBinding.java | 12 + .../cpp/InternalTemplateInstantiatorUtil.java | 8 +- .../composite/cpp/TemplateInstanceUtil.java | 8 +- .../eclipse/cdt/internal/core/pdom/PDOM.java | 3 +- .../internal/core/pdom/dom/PDOMArrayType.java | 46 ++- .../internal/core/pdom/dom/PDOMBinding.java | 5 +- .../internal/core/pdom/dom/PDOMLinkage.java | 55 ++- .../cdt/internal/core/pdom/dom/PDOMName.java | 12 + .../core/pdom/dom/PDOMPointerType.java | 53 ++- .../core/pdom/dom/PDOMQualifierType.java | 48 ++- .../core/pdom/dom/cpp/PDOMCPPBase.java | 27 ++ .../core/pdom/dom/cpp/PDOMCPPBinding.java | 5 +- .../pdom/dom/cpp/PDOMCPPClassInstance.java | 91 ++++- .../dom/cpp/PDOMCPPClassSpecialization.java | 227 +++++++++-- .../pdom/dom/cpp/PDOMCPPClassTemplate.java | 14 +- ...CPPClassTemplatePartialSpecialization.java | 50 ++- .../PDOMCPPClassTemplateSpecialization.java | 45 +-- .../core/pdom/dom/cpp/PDOMCPPClassType.java | 4 +- .../dom/cpp/PDOMCPPDeferredClassInstance.java | 25 +- .../cpp/PDOMCPPDeferredFunctionInstance.java | 3 +- .../dom/cpp/PDOMCPPFieldSpecialization.java | 3 +- .../pdom/dom/cpp/PDOMCPPFunctionInstance.java | 3 +- .../pdom/dom/cpp/PDOMCPPFunctionTemplate.java | 52 ++- .../core/pdom/dom/cpp/PDOMCPPLinkage.java | 135 ++++--- .../pdom/dom/cpp/PDOMCPPOverloaderUtil.java | 16 +- .../dom/cpp/PDOMCPPPointerToMemberType.java | 19 +- .../pdom/dom/cpp/PDOMCPPReferenceType.java | 46 ++- .../pdom/dom/cpp/PDOMCPPSpecialization.java | 25 +- .../core/pdom/dom/cpp/PDOMCPPTypedef.java | 69 +++- .../cdt/internal/ui/IndexLabelProvider.java | 31 +- 45 files changed, 1076 insertions(+), 545 deletions(-) create mode 100644 core/org.eclipse.cdt.core.tests/.cproject create mode 100644 core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalDeferredClassInstance.java diff --git a/core/org.eclipse.cdt.core.tests/.cproject b/core/org.eclipse.cdt.core.tests/.cproject new file mode 100644 index 00000000000..43105daf504 --- /dev/null +++ b/core/org.eclipse.cdt.core.tests/.cproject @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/core/org.eclipse.cdt.core.tests/.settings/org.eclipse.cdt.core.prefs b/core/org.eclipse.cdt.core.tests/.settings/org.eclipse.cdt.core.prefs index 0e9287b8de5..6e53470f84f 100644 --- a/core/org.eclipse.cdt.core.tests/.settings/org.eclipse.cdt.core.prefs +++ b/core/org.eclipse.cdt.core.tests/.settings/org.eclipse.cdt.core.prefs @@ -1,3 +1,4 @@ -#Sun Apr 02 23:10:10 EDT 2006 +#Wed Apr 04 11:14:22 EDT 2007 eclipse.preferences.version=1 +indexer/indexerId=org.eclipse.cdt.core.nullindexer indexerId=org.eclipse.cdt.core.nullindexer diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java index a9e67bc2dc8..da6fa4f08e5 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/ast2/AST2TemplateTests.java @@ -8,6 +8,7 @@ * Contributors: * IBM - Initial API and implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ /* * Created on Mar 11, 2005 @@ -1107,10 +1108,12 @@ public class AST2TemplateTests extends AST2BaseTest { assertTrue( B2 instanceof ICPPSpecialization ); assertSame( ((ICPPSpecialization)B2).getSpecializedBinding(), B ); - //we might want this to be a specialization of a specialization, but for now, this is easier ICPPMethod f1 = (ICPPMethod) col.getName(20).resolveBinding(); assertTrue( f1 instanceof ICPPSpecialization ); - assertSame( ((ICPPSpecialization)f1).getSpecializedBinding(), f ); + assertTrue( ((ICPPSpecialization)f1).getSpecializedBinding() instanceof ICPPMethod ); + ICPPMethod f2 = (ICPPMethod) ((ICPPSpecialization)f1).getSpecializedBinding(); + assertTrue( f2 instanceof ICPPSpecialization ); + assertSame( ((ICPPSpecialization)f2).getSpecializedBinding(), f ); IFunctionType ft = f1.getType(); assertTrue( ft.getReturnType() instanceof IBasicType ); diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java index 05d50cf73d8..92ffb676745 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/internal/index/tests/IndexCPPBindingResolutionTest.java @@ -72,7 +72,7 @@ public class IndexCPPBindingResolutionTest extends IndexBindingResolutionTestBas // class Int {}; // Int a,b; // Int c= left(a,b); - public void _testSimpleFunctionTemplate() { + public void testSimpleFunctionTemplate() { IBinding b0 = getBindingFromASTName("sanity();", 6); IBinding b1 = getBindingFromASTName("left(a,b)", 4); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java index ae56175d0d9..42d99564675 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassInstance.java @@ -58,7 +58,10 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType, ICPP IBinding base = bindings[i].getBaseClass(); if (bindings[i] instanceof CPPBaseClause && base instanceof IType) { IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap); - ((CPPBaseClause)bindings[i]).setBaseClass((ICPPClassType)specBase); + specBase = CPPSemantics.getUltimateType(specBase, false); + if (specBase instanceof ICPPClassType) { + ((CPPBaseClause)bindings[i]).setBaseClass((ICPPClassType)specBase); + } } } return bindings; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java index 71b6b23c280..8d85ecde54d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecialization.java @@ -80,7 +80,10 @@ public class CPPClassSpecialization extends CPPSpecialization implements IBinding base = bindings[i].getBaseClass(); if (bindings[i] instanceof CPPBaseClause && base instanceof IType) { IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap); - ((CPPBaseClause)bindings[i]).setBaseClass((ICPPClassType)specBase); + specBase = CPPSemantics.getUltimateType(specBase, false); + if (specBase instanceof ICPPClassType) { + ((CPPBaseClause)bindings[i]).setBaseClass((ICPPClassType)specBase); + } } } return bindings; @@ -217,7 +220,7 @@ public class CPPClassSpecialization extends CPPSpecialization implements if (scope != null && scope.getClassType() == this) { //explicit specialization: can use composite type specifier scope specScope = scope; - } else if (scope != null) { + } else { //implicit specialization: must specialize bindings in scope specScope = new CPPClassSpecializationScope(this); } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java index 26c9b6305a1..c52622df4e8 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassSpecializationScope.java @@ -17,24 +17,20 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp; import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.ast.DOMException; -import org.eclipse.cdt.core.dom.ast.IASTDeclarator; 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; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.parser.util.ArrayUtil; -import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.ObjectMap; -import org.eclipse.cdt.core.parser.util.ObjectSet; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; @@ -42,111 +38,52 @@ import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; * @author aniefer */ public class CPPClassSpecializationScope implements ICPPClassScope, IASTInternalScope { - private static final char[] CONSTRUCTOR_KEY = "!!!CTOR!!!".toCharArray(); //$NON-NLS-1$ - - private CharArrayObjectMap bindings; private ObjectMap instanceMap = ObjectMap.EMPTY_MAP; - - private ICPPSpecialization specialization; - private boolean isFullyCached = false; - private boolean doneConstructors = false; + final private ICPPSpecialization specialization; /** * @param instance */ - public CPPClassSpecializationScope(CPPClassSpecialization specialization ) { + public CPPClassSpecializationScope( ICPPSpecialization specialization ) { this.specialization = specialization; } - - /** - * @param instance - */ - public CPPClassSpecializationScope(CPPClassInstance instance ) { - this.specialization = instance; - } private ICPPClassType getOriginalClass(){ return (ICPPClassType) specialization.getSpecializedBinding(); } - public boolean isFullyCached(){ - if( !isFullyCached ){ - CPPSemantics.LookupData data = new CPPSemantics.LookupData(); - try { - CPPSemantics.lookupInScope( data, this, null ); - } catch (DOMException e) { - } + + private IBinding getInstance(IBinding binding) { + if( instanceMap.containsKey( binding ) ) { + return (IBinding) instanceMap.get( binding ); + } else if (!(binding instanceof ICPPClassTemplatePartialSpecialization)) { + IBinding spec = CPPTemplates.createSpecialization( this, binding, specialization.getArgumentMap() ); + if( instanceMap == ObjectMap.EMPTY_MAP ) + instanceMap = new ObjectMap(2); + instanceMap.put( binding, spec ); + return spec; } - return true; + return null; } - public IBinding getBinding( IASTName name, boolean forceResolve ) { + public IBinding getBinding( IASTName name, boolean forceResolve ) throws DOMException { char [] c = name.toCharArray(); - if( bindings == null ) - return null; - - if( CharArrayUtils.equals( c, specialization.getNameCharArray() ) ){ - if (CPPClassScope.isConstructorReference( name )) - c = CONSTRUCTOR_KEY; - else - return specialization; - } - - Object cache = bindings.get( c ); - if( cache != null ){ - int i = ( cache instanceof ObjectSet ) ? 0 : -1; - ObjectSet set = ( cache instanceof ObjectSet ) ? (ObjectSet) cache : null; - Object obj = ( set != null ) ? set.keyAt( i ) : cache; - IBinding [] bs = null; - IBinding binding = null; - while( obj != null ){ - if( obj instanceof IASTName ){ - IASTName n = (IASTName) obj; - if( n instanceof ICPPASTQualifiedName ){ - IASTName [] ns = ((ICPPASTQualifiedName)n).getNames(); - n = ns[ ns.length - 1 ]; - } - if( instanceMap.containsKey( n ) ){ - binding = (IBinding) instanceMap.get( n ); - } else { - binding = CPPClassScope.shouldResolve(forceResolve, n, name) ? n.resolveBinding() : n.getBinding(); - if (binding instanceof ICPPClassTemplatePartialSpecialization ){ - binding = null; - } - if( binding != null ){ - binding = CPPTemplates.createSpecialization( this, binding, specialization.getArgumentMap() ); - if( instanceMap == ObjectMap.EMPTY_MAP ) - instanceMap = new ObjectMap(2); - instanceMap.put( n, binding ); - } - } - } else if( obj instanceof IBinding ){ - if( instanceMap.containsKey( obj ) ){ - binding = (IBinding) instanceMap.get( obj ); - } else { - binding = CPPTemplates.createSpecialization( this, (IBinding) obj, specialization.getArgumentMap() ); - if( instanceMap == ObjectMap.EMPTY_MAP ) - instanceMap = new ObjectMap(2); - instanceMap.put( obj, binding ); - } - } - if( binding != null ){ - if( i == -1 ) - return binding; - bs = (IBinding[]) ArrayUtil.append( IBinding.class, bs, binding ); - binding = null; - } - if( i != -1 && ++i < set.size() ){ - obj = set.keyAt( i ); - } else { - obj = null; - } - } - bs = (IBinding[]) ArrayUtil.trim( IBinding.class, bs ); - if( bs.length == 1 ) - return bs[0]; - return CPPSemantics.resolveAmbiguities( name, bs ); - } - return null; + + if( CharArrayUtils.equals( c, specialization.getNameCharArray() ) ) + if (!CPPClassScope.isConstructorReference( name )) + return specialization; + + ICPPClassType specialized = (ICPPClassType) specialization.getSpecializedBinding(); + IScope classScope = specialized.getCompositeScope(); + IBinding[] bindings = classScope != null ? classScope.find(name.toString()) : null; + + if (bindings == null) return null; + + IBinding[] specs = new IBinding[0]; + for (int i = 0; i < bindings.length; i++) { + specs = (IBinding[]) ArrayUtil.append(IBinding.class, specs, getInstance(bindings[i])); + } + specs = (IBinding[]) ArrayUtil.trim(IBinding.class, specs); + return CPPSemantics.resolveAmbiguities( name, specs ); } /* (non-Javadoc) @@ -160,128 +97,49 @@ public class CPPClassSpecializationScope implements ICPPClassScope, IASTInternal * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope#getImplicitMethods() */ public ICPPMethod[] getImplicitMethods() { - // TODO Auto-generated method stub - return null; + //implicit methods shouldn't have implicit specializations + return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#getScopeName() */ public IName getScopeName() { - return (IASTName) ((ICPPInternalBinding)specialization).getDefinition(); + if (specialization instanceof ICPPInternalBinding) + return (IASTName) ((ICPPInternalBinding)specialization).getDefinition(); + //TODO: get the scope name for non-internal bindings + return null; } - public void addName(IASTName name) { - if( name instanceof ICPPASTQualifiedName ) - return; + protected ICPPConstructor [] getConstructors() throws DOMException { + ICPPClassType specialized = (ICPPClassType) specialization.getSpecializedBinding(); + ICPPConstructor[] bindings = specialized.getConstructors(); - if( bindings == null ) - bindings = new CharArrayObjectMap(1); - char [] c = name.toCharArray(); + if (bindings == null) return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; - IASTNode parent = name.getParent(); - if( parent instanceof IASTDeclarator && CPPVisitor.isConstructor( this, (IASTDeclarator) parent ) ){ - c = CONSTRUCTOR_KEY; + ICPPConstructor[] specs = new ICPPConstructor[0]; + for (int i = 0; i < bindings.length; i++) { + specs = (ICPPConstructor[]) ArrayUtil.append(ICPPConstructor.class, specs, getInstance(bindings[i])); } - Object o = bindings.get( c ); - if( o != null ){ - if( o instanceof ObjectSet ){ - ((ObjectSet)o).put( name ); - } else { - ObjectSet temp = new ObjectSet( 2 ); - temp.put( o ); - temp.put( name ); - bindings.put( c, temp ); - } - } else { - bindings.put( c, name ); - } - } - - protected ICPPConstructor [] getConstructors( ){ - if( bindings == null ) - return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; - - if( !doneConstructors ){ - ICPPConstructor[] ctors; - try { - ctors = ((ICPPClassType)specialization.getSpecializedBinding()).getConstructors(); - for (int i = 0; i < ctors.length; i++) { - addBinding( ctors[i] ); - } - doneConstructors = true; - } catch (DOMException e) { - } - } - ICPPConstructor[] ctors = CPPClassScope.getConstructors( bindings, true ); - for (int i = 0; i < ctors.length; i++) { - if( instanceMap.containsKey( ctors[i] ) ){ - ctors[i] = (ICPPConstructor) instanceMap.get( ctors[i] ); - } else { - IBinding b = CPPTemplates.createSpecialization( this, ctors[i], specialization.getArgumentMap() ); - if( instanceMap == ObjectMap.EMPTY_MAP ) - instanceMap = new ObjectMap(2); - instanceMap.put( ctors[i], b ); - ctors[i] = (ICPPConstructor) b; - } - } - return ctors; + return (ICPPConstructor[]) ArrayUtil.trim(ICPPConstructor.class, specs); } protected ICPPMethod[] getConversionOperators() { - if( bindings == null ) - return ICPPConstructor.EMPTY_CONSTRUCTOR_ARRAY; + ICPPClassType specialized = (ICPPClassType) specialization.getSpecializedBinding(); - ICPPMethod [] result = null; - - Object[] values = bindings.valueArray(); - for (int i = 0; i < values.length; i++) { - int j = ( values[i] instanceof ObjectSet ) ? 0 : -1; - ObjectSet set = ( values[i] instanceof ObjectSet ) ? (ObjectSet) values[i] : null; - Object obj = ( set != null ) ? set.keyAt( j ) : values[i]; - IBinding binding = null; - while( obj != null ){ - if( obj instanceof IASTName ){ - IASTName n = (IASTName) obj; - if( n instanceof ICPPASTQualifiedName ){ - IASTName [] ns = ((ICPPASTQualifiedName)n).getNames(); - n = ns[ ns.length - 1 ]; - } - - if (n instanceof ICPPASTConversionName) { - if( instanceMap.containsKey( n ) ){ - binding = (IBinding) instanceMap.get( n ); - } else { - binding = n.resolveBinding(); - if( binding != null ){ - binding = CPPTemplates.createSpecialization( this, binding, specialization.getArgumentMap() ); - if( instanceMap == ObjectMap.EMPTY_MAP ) - instanceMap = new ObjectMap(2); - instanceMap.put( n, binding ); - } - } - } - } - if( binding != null ){ - result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding ); - binding = null; - } - if( j != -1 && ++j < set.size() ){ - obj = set.keyAt( j ); - } else { - obj = null; - } - } + if (!(specialized instanceof ICPPInternalClassType)) { + return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; } + + ICPPMethod[] bindings = ((ICPPInternalClassType)specialized).getConversionOperators(); - return (ICPPMethod[]) ArrayUtil.trim( ICPPMethod.class, result ); - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#setFullyCached(boolean) - */ - public void setFullyCached(boolean b) { - isFullyCached = b; + if (bindings == null) return ICPPMethod.EMPTY_CPPMETHOD_ARRAY; + + ICPPMethod[] specs = new ICPPMethod[0]; + for (int i = 0; i < bindings.length; i++) { + specs = (ICPPMethod[]) ArrayUtil.append(ICPPMethod.class, specs, getInstance(bindings[i])); + } + return (ICPPMethod[]) ArrayUtil.trim(ICPPMethod.class, specs); } /* (non-Javadoc) @@ -303,89 +161,46 @@ public class CPPClassSpecializationScope implements ICPPClassScope, IASTInternal /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) */ - public IBinding[] find(String name) { + public IBinding[] find(String name) throws DOMException { return find(name, false); } /* (non-Javadoc) * @see org.eclipse.cdt.core.dom.ast.IScope#find(java.lang.String) */ - public IBinding[] find(String name, boolean prefixLookup) { - if( name != null ) {} - return null; + public IBinding[] find(String name, boolean prefixLookup) throws DOMException { + ICPPClassType specialized = (ICPPClassType) specialization.getSpecializedBinding(); + IBinding[] bindings = specialized.getCompositeScope().find(name.toString(), prefixLookup); + + if (bindings == null) return null; + + IBinding[] specs = new IBinding[0]; + for (int i = 0; i < bindings.length; i++) { + specs = (IBinding[]) ArrayUtil.append(IBinding.class, specs, getInstance(bindings[i])); + } + return (IBinding[]) ArrayUtil.trim(IBinding.class, specs); } /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.IScope#getPhysicalNode() + * @see org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope#isFullyCached() */ - public IASTNode getPhysicalNode() throws DOMException { - ICPPClassType cls = getOriginalClass(); - ICPPClassScope scope = (ICPPClassScope)cls.getCompositeScope(); - - IASTNode node= ASTInternal.getPhysicalNodeOfScope(scope); - if (node != null) { - return node; + public boolean isFullyCached() throws DOMException { + ICPPScope origScope = (ICPPScope) getOriginalClass().getCompositeScope(); + if (!ASTInternal.isFullyCached(origScope)) { + CPPSemantics.LookupData data = new CPPSemantics.LookupData(); + try { + CPPSemantics.lookupInScope( data, origScope, null ); + } catch (DOMException e) { + } } - - IASTNode[] nds= ASTInternal.getDeclarationsOfBinding(cls); - - if( nds != null && nds.length > 0 ) - return nds[0]; - - return null; - } - - /* (non-Javadoc) - * @see org.eclipse.cdt.core.dom.ast.cpp.ICPPScope#removeBinding(org.eclipse.cdt.core.dom.ast.IBinding) - */ - public void removeBinding(IBinding binding) { - char [] name = binding.getNameCharArray(); - if( ! bindings.containsKey( name ) ) - return; - - Object obj = bindings.get( name ); - if( obj instanceof ObjectSet ){ - ObjectSet set = (ObjectSet) obj; - set.remove( binding ); - if( set.size() == 0 ) - bindings.remove( name, 0, name.length ); - } else { - bindings.remove( name, 0, name.length ); - } - - if( instanceMap != null && instanceMap.containsKey( binding ) ) - instanceMap.remove( binding ); - isFullyCached = false; - } - - public void flushCache() { - if( bindings != null ) - bindings.clear(); - isFullyCached = false; - } - - public void addBinding(IBinding binding) { - if( bindings == null ) - bindings = new CharArrayObjectMap(1); - char [] c = (binding instanceof ICPPConstructor) ? CONSTRUCTOR_KEY : binding.getNameCharArray(); - Object o = bindings.get( c ); - if( o != null ){ - if( o instanceof ObjectSet ){ - ((ObjectSet)o).put( binding ); - } else { - ObjectSet set = new ObjectSet(2); - set.put( o ); - set.put( binding ); - bindings.put( c, set ); - } - } else { - bindings.put( c, binding ); - } + return true; } - public IBinding getInstance( IBinding binding ){ - if( instanceMap != null && instanceMap.containsKey( binding ) ) - return (IBinding) instanceMap.get( binding ); - return null; - } + //this scope does not cache its own names + public void setFullyCached(boolean b) {} + public void flushCache() {} + public void addName(IASTName name) {} + public IASTNode getPhysicalNode() {return null;} + public void removeBinding(IBinding binding) {} + public void addBinding(IBinding binding) {} } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java index 4bda14bea14..742bad31fe2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplateSpecialization.java @@ -103,7 +103,7 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization if( template instanceof IProblemBinding ) return template; if( template != null && template instanceof ICPPClassTemplatePartialSpecialization ){ - return ((CPPTemplateDefinition)template).instantiate( arguments ); + return ((ICPPInternalTemplateInstantiator)template).instantiate( arguments ); } return CPPTemplates.instantiateTemplate( this, arguments, argumentMap ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java index 0f929f1080b..a5914edf40e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPDeferredClassInstance.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005 IBM Corporation and others. + * Copyright (c) 2005, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -34,7 +34,7 @@ import org.eclipse.cdt.core.parser.util.ObjectMap; * @author aniefer */ public class CPPDeferredClassInstance extends CPPInstance implements - ICPPClassType, ICPPDeferredTemplateInstance { + ICPPClassType, ICPPDeferredTemplateInstance, ICPPInternalDeferredClassInstance { public IType [] arguments = null; public ICPPClassTemplate classTemplate = null; @@ -160,7 +160,7 @@ public class CPPDeferredClassInstance extends CPPInstance implements classTemplate = (ICPPClassTemplate) argMap.get( classTemplate ); } - return (IType) ((ICPPInternalTemplate)classTemplate).instantiate( newArgs ); + return (IType) ((ICPPInternalTemplateInstantiator)classTemplate).instantiate( newArgs ); } /* (non-Javadoc) 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 b3a9e2653c2..1bf3b918f68 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2004, 2006 IBM Corporation and others. + * Copyright (c) 2004, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -496,7 +496,11 @@ public class CPPFunction extends PlatformObject implements ICPPFunction, ICPPInt } static public boolean hasStorageClass( ICPPInternalFunction function, int storage ){ - ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) function.getDefinition(); + IASTNode def = function.getDefinition(); + while (def instanceof IASTName) { + def = def.getParent(); + } + ICPPASTFunctionDeclarator dtor = (ICPPASTFunctionDeclarator) def; ICPPASTFunctionDeclarator[] ds = (ICPPASTFunctionDeclarator[]) function.getDeclarations(); int i = -1; do{ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java index 96f7c1bf633..5899777bebe 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPFunctionSpecialization.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005 IBM Corporation and others. + * Copyright (c) 2005, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -7,6 +7,7 @@ * * Contributors: * IBM - Initial API and implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ /* * Created on Apr 22, 2005 @@ -97,9 +98,9 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP } public boolean isStatic(boolean resolveAll) { //TODO resolveAll - ICPPInternalFunction f = (ICPPInternalFunction) getSpecializedBinding(); - if( f != null ) - return f.isStatic( resolveAll ); + IBinding f = getSpecializedBinding(); + if( f instanceof ICPPInternalFunction) + return ((ICPPInternalFunction)f).isStatic( resolveAll ); return CPPFunction.hasStorageClass( this, IASTDeclSpecifier.sc_static ); } 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 9c3063dc782..1740a4d0490 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 @@ -1038,6 +1038,7 @@ public class CPPSemantics { IASTNode parent = ASTInternal.getPhysicalNodeOfScope(scope); if (parent == null) { IBinding[] bindings = scope.find(data.astName.toString(), data.prefixLookup); + bindings = appendClassType(bindings, scope, data); mergeResults(data, bindings, true); useASTResults = false; } else { @@ -1158,6 +1159,19 @@ public class CPPSemantics { } } + private static IBinding[] appendClassType(IBinding[] bindings, ICPPScope scope, CPPSemantics.LookupData data) throws DOMException { + if (scope instanceof ICPPClassScope) { + IBinding binding = ((ICPPClassScope)scope).getClassType(); + char[] c = binding.getNameCharArray(); + char[] n = data.astName.toCharArray(); + if ((data.prefixLookup && CharArrayUtils.equals(c, 0, n.length, n, true)) + || (!data.prefixLookup && CharArrayUtils.equals(c, n))) { + return (IBinding[]) ArrayUtil.append(IBinding.class, bindings, binding); + } + } + return bindings; + } + private static IScope getParentScope(IScope scope, IASTTranslationUnit unit) throws DOMException { IScope parentScope= scope.getParent(); // the index cannot return the translation unit as parent scope @@ -1213,12 +1227,12 @@ public class CPPSemantics { //is circular inheritance if( ! data.inheritanceChain.containsKey( parent ) ){ //is this name define in this scope? - if( data.astName != null && !data.contentAssist && ASTInternal.isFullyCached(parent) ) + if( ASTInternal.isFullyCached(parent) && data.astName != null && !data.contentAssist ) inherited = parent.getBinding( data.astName, true ); - else if (ASTInternal.getPhysicalNodeOfScope(lookIn) != null - && ASTInternal.getPhysicalNodeOfScope(parent) == null) + else if (ASTInternal.getPhysicalNodeOfScope(parent) == null) { inherited = parent.find(data.astName.toString(), data.prefixLookup); - else + inherited = appendClassType((IBinding[]) inherited, parent, data); + } else inherited = lookupInScope( data, parent, null ); if( inherited == null || data.contentAssist ){ @@ -1617,6 +1631,7 @@ public class CPPSemantics { } } else if (ASTInternal.getPhysicalNodeOfScope(temp) == null) { IBinding[] bindings = temp.find(data.astName.toString(), data.prefixLookup); + bindings = appendClassType(bindings, temp, data); if (bindings != null && bindings.length > 0) { mergeResults( data, bindings, true ); found = true; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java index 883618d4890..5821eebd115 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplateDefinition.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2005, 2006 IBM Corporation and others. + * Copyright (c) 2005, 2007 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at @@ -122,7 +122,7 @@ public abstract class CPPTemplateDefinition extends PlatformObject implements IC if( template instanceof IProblemBinding ) return template; if( template != null && template instanceof ICPPClassTemplatePartialSpecialization ){ - return ((CPPTemplateDefinition)template).instantiate( arguments ); + return ((ICPPInternalTemplateInstantiator)template).instantiate( arguments ); } return CPPTemplates.instantiateTemplate( this, arguments, null ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java index 31970632b3e..07b93ddf509 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPTemplates.java @@ -690,8 +690,8 @@ public class CPPTemplates { } } else if( type instanceof ICPPTemplateParameter && argMap.containsKey( type ) ){ newType = (IType) argMap.get( type ); - } else if( type instanceof CPPDeferredClassInstance ){ - newType = ((CPPDeferredClassInstance)type).instantiate( argMap ); + } else if( type instanceof ICPPInternalDeferredClassInstance ){ + newType = ((ICPPInternalDeferredClassInstance)type).instantiate( argMap ); } else if( type instanceof ICPPInternalUnknown ){ IBinding binding; try { @@ -1145,7 +1145,7 @@ public class CPPTemplates { } return false; } - static protected boolean deduceTemplateArgument( ObjectMap map, IType p, IType a ) throws DOMException { + static public boolean deduceTemplateArgument( ObjectMap map, IType p, IType a ) throws DOMException { boolean pIsAReferenceType = ( p instanceof ICPPReferenceType ); p = getParameterTypeForDeduction( p ); a = getArgumentTypeForDeduction( a, pIsAReferenceType ); diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalDeferredClassInstance.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalDeferredClassInstance.java new file mode 100644 index 00000000000..24d23facc4c --- /dev/null +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/ICPPInternalDeferredClassInstance.java @@ -0,0 +1,27 @@ +/******************************************************************************* + * Copyright (c) 2007 QNX Software Systems and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * QNX - Initial API and implementation + *******************************************************************************/ +package org.eclipse.cdt.internal.core.dom.parser.cpp; + +import org.eclipse.cdt.core.dom.ast.IType; +import org.eclipse.cdt.core.parser.util.ObjectMap; + +/** + * @author Bryan Wilkinson + * + */ +public interface ICPPInternalDeferredClassInstance { + + /** + * instantiate the original template + * @return + */ + public IType instantiate(ObjectMap argMap); +} diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeIndexBinding.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeIndexBinding.java index d831cc531dc..a82025c0434 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeIndexBinding.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/CompositeIndexBinding.java @@ -8,6 +8,7 @@ * Contributors: * Andrew Ferguson (Symbian) - Initial implementation * Markus Schorn (Wind River Systems) + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite; @@ -88,4 +89,15 @@ public abstract class CompositeIndexBinding implements IIndexBinding { public boolean isFileLocal() throws CoreException { return rbinding instanceof IIndexBinding ? ((IIndexBinding)rbinding).isFileLocal() : true; } + + public boolean equals(Object obj) { + if (obj == this) + return true; + if (obj instanceof IIndexFragmentBinding) + return rbinding.equals(obj); + if (obj instanceof CompositeIndexBinding) + return rbinding.equals(((CompositeIndexBinding)obj).rbinding); + + return super.equals(obj); + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/InternalTemplateInstantiatorUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/InternalTemplateInstantiatorUtil.java index 1b301679825..764cf5b9c66 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/InternalTemplateInstantiatorUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/InternalTemplateInstantiatorUtil.java @@ -7,6 +7,7 @@ * * Contributors: * Andrew Ferguson (Symbian) - Initial implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.cpp; @@ -31,6 +32,11 @@ public class InternalTemplateInstantiatorUtil { public static IBinding instantiate(IType[] arguments, ICompositesFactory cf, IIndexBinding rbinding) { IBinding ins= ((ICPPInternalTemplateInstantiator)rbinding).instantiate(arguments); - return (IBinding) cf.getCompositeBinding((IIndexFragmentBinding)ins); + if (ins instanceof IIndexFragmentBinding) { + return (IBinding) cf.getCompositeBinding((IIndexFragmentBinding)ins); + } else { + //instantiation of an index template can result in a non-index binding + return ins; + } } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java index 21a924f64b1..1c5aca31d3e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/index/composite/cpp/TemplateInstanceUtil.java @@ -7,6 +7,7 @@ * * Contributors: * Andrew Ferguson (Symbian) - Initial implementation + * Bryan Wilkinson (QNX) *******************************************************************************/ package org.eclipse.cdt.internal.core.index.composite.cpp; @@ -17,7 +18,6 @@ import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; -import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.internal.core.index.IIndexFragmentBinding; @@ -33,8 +33,10 @@ public class TemplateInstanceUtil { ObjectMap result= new ObjectMap(preresult.size()); Object[] keys= preresult.keyArray(); for(int i=0; i'); result = buffer.toString(); } else if (element instanceof ICPPSpecialization) { - PDOMNode parentOfSpec = ((PDOMNode)((ICPPSpecialization)element).getSpecializedBinding()).getParentNode(); - PDOMNode parent = ((PDOMNode)element).getParentNode(); - PDOMNode grandParent = parent != null ? parent.getParentNode() : null; - boolean showArgs = parentOfSpec == null || grandParent == null || !parentOfSpec.equals(grandParent); - showArgs = showArgs && ((element instanceof ICPPClassType || element instanceof ICPPFunction) - && !(element instanceof ICPPTemplateDefinition)); + ICPPSpecialization spec = (ICPPSpecialization) element; StringBuffer buffer = null; buffer = new StringBuffer("Spec: "); //$NON-NLS-1$ buffer.append(result); - if (showArgs) { - buffer.append('<'); - ObjectMap argMap = ((ICPPSpecialization) element).getArgumentMap(); - for (int i = 0; i < argMap.size(); i++) { - if (i > 0) - buffer.append(','); - buffer.append(ASTTypeUtil.getType((IType) argMap.getAt(i))); + if (!(spec instanceof ICPPTemplateDefinition) + && spec.getSpecializedBinding() instanceof ICPPTemplateDefinition) { + ICPPTemplateDefinition template = (ICPPTemplateDefinition) spec.getSpecializedBinding(); + try { + ICPPTemplateParameter[] params = template.getTemplateParameters(); + buffer.append('<'); + ObjectMap argMap = ((ICPPSpecialization) element).getArgumentMap(); + for (int i = 0; i < params.length; i++) { + if (i > 0) + buffer.append(','); + buffer.append(ASTTypeUtil.getType((IType) argMap.get(params[i]))); + } + buffer.append('>'); + } catch (DOMException e) { } - buffer.append('>'); } result = buffer.toString();