1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

Rework fix for 213861 and defer even more instantiations, related to bug 229218.

This commit is contained in:
Markus Schorn 2008-05-09 12:58:26 +00:00
parent 73fe0cb572
commit 1e130b3edf
30 changed files with 186 additions and 166 deletions

View file

@ -40,6 +40,7 @@ import org.eclipse.cdt.core.dom.ast.IVariable;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
@ -60,6 +61,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.parser.ParserLanguage;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownScope;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
/**
@ -275,6 +279,7 @@ public class AST2TemplateTests extends AST2BaseTest {
tu.accept(col);
ICPPTemplateParameter T0 = (ICPPTemplateParameter) col.getName(0).resolveBinding();
ICPPClassTemplate A = (ICPPClassTemplate) col.getName(1).resolveBinding();
ICPPTemplateParameter T1 = (ICPPTemplateParameter) col.getName(3).resolveBinding();
ICPPTemplateParameter T2 = (ICPPTemplateParameter) col.getName(12).resolveBinding();
@ -287,10 +292,14 @@ public class AST2TemplateTests extends AST2BaseTest {
ITypedef TYPE = (ITypedef) col.getName(2).resolveBinding();
IBinding b0 = col.getName(8).resolveBinding();
assertInstance(b0, ICPPSpecialization.class);
assertSame(TYPE, ((ICPPSpecialization) b0).getSpecializedBinding());
IBinding b1 = col.getName(17).resolveBinding();
assertSame(TYPE, ((ICPPSpecialization) b1).getSpecializedBinding());
assertSame(b1, b0);
// the instantiation of A<T> has to be deferred.
assertInstance(b0, ICPPUnknownBinding.class);
final ICPPBinding parent = ((ICPPInternalUnknownScope)b0.getScope()).getScopeBinding();
assertInstance(parent, ICPPDeferredClassInstance.class);
assertSame(((ICPPDeferredClassInstance) parent).getSpecializedBinding(), A);
assertInstances(col, T1, 6);
}
@ -1260,9 +1269,7 @@ public class AST2TemplateTests extends AST2BaseTest {
ICPPTemplateParameter U = (ICPPTemplateParameter) col.getName(7).resolveBinding();
assertSame(U, T);
ICPPClassType A3 = (ICPPClassType) col.getName(9).resolveBinding();
assertTrue(A3 instanceof ICPPTemplateInstance);
assertSame(((ICPPTemplateInstance) A3).getTemplateDefinition(), A);
assertSame(A2, A3);
assertSame(A, A3);
ICPPTemplateParameter U2 = (ICPPTemplateParameter) col.getName(13).resolveBinding();
@ -1466,9 +1473,7 @@ public class AST2TemplateTests extends AST2BaseTest {
ICPPTemplateParameter XR = (ICPPTemplateParameter) col.getName(20).resolveBinding();
assertSame(X, XR);
ICPPClassType A3 = (ICPPClassType) col.getName(22).resolveBinding();
assertTrue(A3 instanceof ICPPTemplateInstance);
assertSame(((ICPPTemplateInstance)A3).getTemplateDefinition(), A);
assertNotSame(A2, A3);
assertSame(A3, A);
ICPPMethod g2 = (ICPPMethod) col.getName(25).resolveBinding();
assertSame(g2, g);
@ -1511,8 +1516,7 @@ public class AST2TemplateTests extends AST2BaseTest {
assertSame(C, T);
ICPPClassType B2 = (ICPPClassType) col.getName(10).resolveBinding();
assertTrue(B2 instanceof ICPPTemplateInstance);
assertSame(((ICPPTemplateInstance)B2).getTemplateDefinition(), B);
assertSame(B2, B);
ICPPTemplateParameter CR = (ICPPTemplateParameter) col.getName(12).resolveBinding();
assertSame(CR, T);
@ -1624,8 +1628,8 @@ public class AST2TemplateTests extends AST2BaseTest {
tu.accept(col);
ICPPMethod init = (ICPPMethod) col.getName(4).resolveBinding();
ICPPSpecialization b0 = (ICPPSpecialization) col.getName(19).resolveBinding();
assertSame(init, b0.getSpecializedBinding());
// the instantiation of B<T> has to be deferred, therefore 'init' is an unknown binding.
assertInstance(col.getName(19).resolveBinding(), ICPPUnknownBinding.class);
}
// template <class Tp, class Tr > class iter {

View file

@ -52,7 +52,7 @@ public class CPPClassInstance extends CPPInstance implements ICPPClassType {
ICPPBase specBinding = (ICPPBase) ((ICPPInternalBase) binding).clone();
IBinding base = binding.getBaseClass();
if (base instanceof IType) {
IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap);
IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap, instanceScope);
specBase = getUltimateType(specBase, false);
if (specBase instanceof IBinding) {
((ICPPInternalBase) specBinding).setBaseClass((IBinding) specBase);

View file

@ -6,8 +6,9 @@
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM - Initial API and implementation
* Bryan Wilkinson (QNX)
* IBM - Initial API and implementation
* Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -79,11 +80,11 @@ public class CPPClassSpecialization extends CPPSpecialization implements
if( getDefinition() == null ){
ICPPBase[] result = null;
ICPPBase[] bindings = ((ICPPClassType)getSpecializedBinding()).getBases();
for (int i = 0; i < bindings.length; i++) {
ICPPBase specBinding = (ICPPBase) ((ICPPInternalBase)bindings[i]).clone();
IBinding base = bindings[i].getBaseClass();
for (ICPPBase binding : bindings) {
ICPPBase specBinding = (ICPPBase) ((ICPPInternalBase)binding).clone();
IBinding base = binding.getBaseClass();
if (base instanceof IType) {
IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap);
IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap, getScope());
specBase = SemanticUtil.getUltimateType(specBase, false);
if (specBase instanceof IBinding) {
((ICPPInternalBase)specBinding).setBaseClass((IBinding)specBase);
@ -103,7 +104,7 @@ public class CPPClassSpecialization extends CPPSpecialization implements
bindings[i] = new CPPBaseClause(bases[i]);
IBinding base = bindings[i].getBaseClass();
if (base instanceof IType) {
IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap);
IType specBase = CPPTemplates.instantiateType((IType) base, argumentMap, null);
if (specBase instanceof ICPPClassType) {
((CPPBaseClause) bindings[i]).setBaseClass((ICPPClassType) specBase);
}
@ -168,14 +169,13 @@ public class CPPClassSpecialization extends CPPSpecialization implements
ICPPMethod [] result = null;
IASTDeclaration [] decls = getCompositeTypeSpecifier().getMembers();
for ( int i = 0; i < decls.length; i++ ) {
IASTDeclaration decl = decls[i];
for (IASTDeclaration decl : decls) {
while( decl instanceof ICPPASTTemplateDeclaration )
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration();
if( decl instanceof IASTSimpleDeclaration ){
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators();
for ( int j = 0; j < dtors.length; j++ ) {
binding = dtors[j].getName().resolveBinding();
for (IASTDeclarator dtor : dtors) {
binding = dtor.getName().resolveBinding();
if( binding instanceof ICPPMethod)
result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding );
}
@ -191,9 +191,9 @@ public class CPPClassSpecialization extends CPPSpecialization implements
binding = n.resolveBinding();
if( binding instanceof ICPPUsingDeclaration ){
IBinding [] bs = ((ICPPUsingDeclaration)binding).getDelegates();
for ( int j = 0; j < bs.length; j++ ) {
if( bs[j] instanceof ICPPMethod )
result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, bs[j] );
for (IBinding element : bs) {
if( element instanceof ICPPMethod )
result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, element );
}
} else if( binding instanceof ICPPMethod ) {
result = (ICPPMethod[]) ArrayUtil.append( ICPPMethod.class, result, binding );
@ -217,15 +217,14 @@ public class CPPClassSpecialization extends CPPSpecialization implements
return ((CPPClassScope)scope).getConstructors( true );
IASTDeclaration [] members = getCompositeTypeSpecifier().getMembers();
for( int i = 0; i < members.length; i++ ){
IASTDeclaration decl = members[i];
for (IASTDeclaration decl : members) {
if( decl instanceof ICPPASTTemplateDeclaration )
decl = ((ICPPASTTemplateDeclaration)decl).getDeclaration();
if( decl instanceof IASTSimpleDeclaration ){
IASTDeclarator [] dtors = ((IASTSimpleDeclaration)decl).getDeclarators();
for( int j = 0; j < dtors.length; j++ ){
if( dtors[j] == null ) break;
ASTInternal.addName(scope, dtors[j].getName() );
for (IASTDeclarator dtor : dtors) {
if( dtor == null ) break;
ASTInternal.addName(scope, dtor.getName() );
}
} else if( decl instanceof IASTFunctionDefinition ){
IASTDeclarator dtor = ((IASTFunctionDefinition)decl).getDeclarator();

View file

@ -76,7 +76,7 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate impl
IType arg = args[i];
//If the argument is a template parameter, we can't instantiate yet, defer for later
if( CPPTemplates.typeContainsTemplateParameter( arg ) ){
if( CPPTemplates.isDependentType( arg ) ){
return deferredInstance( argMap, args );
}
try {

View file

@ -425,4 +425,12 @@ public class CPPClassType extends PlatformObject implements ICPPInternalClassTyp
}
return null;
}
/**
* For debugging purposes, only.
*/
@Override
public String toString() {
return getName();
}
}

View file

@ -33,7 +33,7 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
private IType[] fArguments;
private ObjectMap fArgmap;
private ICPPScope fUnknownScope;
// private ICPPScope fUnknownScope;
public CPPDeferredClassInstance(ICPPClassTemplate orig, ObjectMap argMap, IType[] arguments) {
super(orig);
@ -89,12 +89,12 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
}
@Override
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) {
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) {
IType[] arguments = getArguments();
IType[] newArgs = new IType[arguments.length];
int size = arguments.length;
for (int i = 0; i < size; i++) {
newArgs[i] = CPPTemplates.instantiateType(arguments[i], argMap);
newArgs[i] = CPPTemplates.instantiateType(arguments[i], argMap, instantiationScope);
}
ICPPClassTemplate classTemplate = getClassTemplate();
@ -108,19 +108,4 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
public IBinding getSpecializedBinding() {
return getTemplateDefinition();
}
@Override
public ICPPScope getUnknownScope() throws DOMException {
if (fUnknownScope != null)
return fUnknownScope;
final ICPPClassTemplate classTemplate = getClassTemplate();
if (classTemplate.getPartialSpecializations().length == 0) {
if (fArgmap == null) {
return fUnknownScope= (ICPPScope) classTemplate.getCompositeScope();
}
return fUnknownScope= new CPPClassSpecializationScope(this);
}
return super.getUnknownScope();
}
}

View file

@ -93,7 +93,7 @@ public class CPPDeferredFunctionInstance extends CPPInstance implements ICPPFunc
if( functionType == null ){
IFunctionType ft = ((ICPPFunction)getTemplateDefinition()).getType();
IType returnType = ft.getReturnType();
returnType = CPPTemplates.instantiateType( returnType, getArgumentMap() );
returnType = CPPTemplates.instantiateType( returnType, getArgumentMap(), null);
functionType = CPPVisitor.createImplicitFunctionType( returnType, getParameters() );
}

View file

@ -45,7 +45,7 @@ public class CPPFieldSpecialization extends CPPSpecialization implements ICPPFie
public IType getType() throws DOMException {
if( type == null ){
type = CPPTemplates.instantiateType( getField().getType(), argumentMap );
type = CPPTemplates.instantiateType( getField().getType(), argumentMap, getScope());
}
return type;
}

View file

@ -72,7 +72,7 @@ public class CPPFunctionInstance extends CPPInstance implements ICPPFunction, IC
*/
public IFunctionType getType() throws DOMException {
if( type == null ){
type = (IFunctionType) CPPTemplates.instantiateType( ((ICPPFunction)getTemplateDefinition()).getType(), getArgumentMap() );
type = (IFunctionType) CPPTemplates.instantiateType( ((ICPPFunction)getTemplateDefinition()).getType(), getArgumentMap(), getScope() );
}
return type;
}

View file

@ -75,7 +75,7 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
if (type == null) {
ICPPFunction function = (ICPPFunction) getSpecializedBinding();
type = function.getType();
type = (IFunctionType) CPPTemplates.instantiateType(type, argumentMap);
type = (IFunctionType) CPPTemplates.instantiateType(type, argumentMap, getScope());
}
return type;

View file

@ -42,7 +42,7 @@ public class CPPParameterSpecialization extends CPPSpecialization implements ICP
*/
public IType getType() throws DOMException {
if( type == null ){
type = CPPTemplates.instantiateType( getParameter().getType(), argumentMap );
type = CPPTemplates.instantiateType( getParameter().getType(), argumentMap, getScope());
}
return type;
}

View file

@ -235,7 +235,7 @@ public class CPPTemplateTemplateParameter extends CPPTemplateParameter implement
return null;
}
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) {
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) {
return null;
}

View file

@ -67,7 +67,7 @@ public class CPPTemplateTypeParameter extends CPPTemplateParameter implements
return false;
}
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) {
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) {
// Cannot do resolution here since the result is not necessarily a binding.
return null;
}

View file

@ -7,6 +7,7 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -43,7 +44,7 @@ public class CPPTypedefSpecialization extends CPPSpecialization implements IType
*/
public IType getType() throws DOMException {
if (type == null) {
type = CPPTemplates.instantiateType(getTypedef().getType(), argumentMap);
type = CPPTemplates.instantiateType(getTypedef().getType(), argumentMap, getScope());
}
return type;
}

View file

@ -1,13 +1,14 @@
/*******************************************************************************
* Copyright (c) 2004, 2005 IBM Corporation and others.
* Copyright (c) 2004, 2008 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
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Sergey Prigogin (Google)
* IBM Corporation - initial API and implementation
* Sergey Prigogin (Google)
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -24,6 +25,7 @@ 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.ICPPField;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.parser.util.ObjectMap;
/**
@ -93,7 +95,7 @@ public class CPPUnknownClass extends CPPUnknownBinding implements ICPPUnknownCla
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) {
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) {
if (parentBinding == this.scopeBinding) {
return this;
}

View file

@ -14,6 +14,7 @@ import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
@ -34,12 +35,9 @@ public class CPPUnknownClassInstance extends CPPUnknownClass implements ICPPUnkn
return arguments;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknownClassType#resolvePartially(org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInternalUnknown, org.eclipse.cdt.core.parser.util.ObjectMap)
*/
@Override
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) {
IType[] newArgs = CPPTemplates.instantiateTypes(arguments, argMap);
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) {
IType[] newArgs = CPPTemplates.instantiateTypes(arguments, argMap, instantiationScope);
return new CPPUnknownClassInstance(parentBinding, name, newArgs);
}

View file

@ -51,7 +51,8 @@ public interface ICPPUnknownBinding extends ICPPBinding {
* of the original parent binding, or <code>null</code> for deferred template
* instantiations.
* @param argMap template argument map.
* @param instantiationScope the scope in which the current instantiation takes place, may be <code>null</code>.
* @return a partially resolved, but still unknown, binding.
*/
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap);
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope);
}

View file

@ -91,6 +91,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
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.ICPPDeferredTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
@ -117,6 +118,7 @@ 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.DebugUtil;
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.ASTNode;
@ -296,7 +298,27 @@ public class CPPSemantics {
}
}
// in template declarations the template-ids get instantiated to deferred instances, revert that.
IASTName name = data.astName;
if (name instanceof ICPPASTTemplateId) {
if (CPPTemplates.getTemplateDeclaration(name) != null && binding instanceof ICPPDeferredTemplateInstance) {
ICPPDeferredTemplateInstance deferred= (ICPPDeferredTemplateInstance) binding;
boolean useOriginal= true;
final ObjectMap argMap = deferred.getArgumentMap();
if (argMap != null) {
for (int i = 0; useOriginal && i < argMap.size(); i++) {
if (!argMap.keyAt(i).equals(argMap.getAt(i))) {
useOriginal= false;
break;
}
}
}
if (useOriginal) {
binding= deferred.getSpecializedBinding();
}
}
}
if (name.getParent() instanceof ICPPASTTemplateId) {
if (binding instanceof ICPPTemplateInstance) {
IBinding b = binding;

View file

@ -56,6 +56,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplatedTypeTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@ -681,74 +682,91 @@ public class CPPTemplates {
* @param type a type to instantiate.
* @param argMap a mapping between template parameters and the corresponding arguments.
*/
public static IType instantiateType(IType type, ObjectMap argMap) {
public static IType instantiateType(IType type, ObjectMap argMap, IScope instantiationScope) {
if (argMap == null)
return type;
IType newType = type;
IType temp = null;
if (type instanceof IFunctionType) {
IType ret = null;
IType[] params = null;
try {
ret = instantiateType(((IFunctionType) type).getReturnType(), argMap);
ret = instantiateType(((IFunctionType) type).getReturnType(), argMap, instantiationScope);
IType[] ps = ((IFunctionType) type).getParameterTypes();
params = new IType[ps.length];
for (int i = 0; i < params.length; i++) {
temp = instantiateType(ps[i], argMap);
params[i] = temp;
params[i]= instantiateType(ps[i], argMap, instantiationScope);
}
} catch (DOMException e) {
}
newType = new CPPFunctionType(ret, params, ((ICPPFunctionType) type).isConst(),
return new CPPFunctionType(ret, params, ((ICPPFunctionType) type).isConst(),
((ICPPFunctionType) type).isVolatile());
} else if (type instanceof ITypedef) {
}
if (type instanceof ITypedef) {
// Typedef requires special treatment (bug 213861).
final ITypedef typedef = (ITypedef) type;
try {
ITypedef typedef = (ITypedef) type;
newType = new CPPTypedefSpecialization(typedef, (ICPPScope) typedef.getScope(), argMap);
} catch (DOMException e) {
return type;
}
} else if (type instanceof ITypeContainer) {
try {
temp = ((ITypeContainer) type).getType();
} catch (DOMException e) {
return type;
}
newType = instantiateType(temp, argMap);
if (newType != temp) {
temp = (IType) type.clone();
((ITypeContainer) temp).setType(newType);
newType = temp;
} else {
newType = type;
}
} else if (type instanceof ICPPTemplateParameter) {
IType t = (IType) argMap.get(type);
if (t == null) {
for (int i = 0; i < argMap.size(); i++) {
Object key = argMap.keyAt(i);
if (key instanceof IType && type.isSameType((IType) key)) {
newType = (IType) argMap.getAt(i);
break;
final IScope scopeOfTypedef= typedef.getScope();
if (scopeOfTypedef instanceof ICPPClassScope) {
if (instantiationScope instanceof ICPPClassScope) {
ICPPClassType owner= ((ICPPClassScope) scopeOfTypedef).getClassType();
IBinding instance= ((ICPPClassScope) instantiationScope).getClassType();
if (instance instanceof ICPPSpecialization) {
instance= ((ICPPSpecialization) instance).getSpecializedBinding();
if (instance instanceof IType && owner.isSameType((IType) instance)) {
return new CPPTypedefSpecialization(typedef, (ICPPScope) instantiationScope, argMap);
}
}
}
// we cannot instantiate a typedef contained in a class without knowing the scope of instantiation.
return type;
}
} else {
newType = t;
} catch (DOMException e) {
}
} else if (type instanceof ICPPUnknownBinding) {
}
if (type instanceof ITypeContainer) {
try {
IType temp = ((ITypeContainer) type).getType();
IType newType = instantiateType(temp, argMap, instantiationScope);
if (newType != temp) {
temp = (IType) type.clone();
((ITypeContainer) temp).setType(newType);
return temp;
}
} catch (DOMException e) {
}
return type;
}
if (type instanceof ICPPTemplateParameter) {
IType t = (IType) argMap.get(type);
if (t != null) {
return t;
}
for (int i = 0; i < argMap.size(); i++) {
Object key = argMap.keyAt(i);
if (key instanceof IType && type.isSameType((IType) key)) {
return (IType) argMap.getAt(i);
}
}
return type;
}
if (type instanceof ICPPUnknownBinding) {
IBinding binding;
try {
binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) type, argMap);
binding = CPPTemplates.resolveUnknown((ICPPUnknownBinding) type, argMap, (ICPPScope) instantiationScope);
} catch (DOMException e) {
binding = e.getProblem();
}
if (binding instanceof IType)
newType = (IType) binding;
return (IType) binding;
return type;
}
return newType;
return type;
}
/**
@ -757,11 +775,11 @@ public class CPPTemplates {
* @param argMap template argument map
* @return an array containing instantiated types.
*/
public static IType[] instantiateTypes(IType[] types, ObjectMap argMap) {
public static IType[] instantiateTypes(IType[] types, ObjectMap argMap, ICPPScope instantiationScope) {
// Don't create a new array until it's really needed.
IType[] result = types;
for (int i = 0; i < types.length; i++) {
IType type = CPPTemplates.instantiateType(types[i], argMap);
IType type = CPPTemplates.instantiateType(types[i], argMap, instantiationScope);
if (type != types[i]) {
if (result == types) {
result = new IType[types.length];
@ -1640,11 +1658,11 @@ public class CPPTemplates {
return template;
}
public static boolean typeContainsTemplateParameter(IType t) {
public static boolean isDependentType(IType t) {
if (t instanceof ICPPTemplateParameter)
return true;
t = SemanticUtil.getUltimateType(t, false);
return (t instanceof ICPPTemplateParameter);
return t instanceof ICPPUnknownBinding;
}
public static IBinding instantiateTemplate(ICPPTemplateDefinition template, IType[] arguments,
@ -1670,7 +1688,7 @@ public class CPPTemplates {
ICPPTemplateParameter param = null;
IType arg = null;
IType[] actualArgs = new IType[numParams];
boolean argsContainTemplateParameters = false;
boolean argsContainDependentType = false;
for (int i = 0; i < numParams; i++) {
arg = null;
@ -1700,7 +1718,7 @@ public class CPPTemplates {
// parameter: template<typename T1, typename T2 = A<T1> > class B {};
IType resolvedType= null;
try {
IBinding resolved= CPPTemplates.resolveUnknown((ICPPUnknownBinding) defaultType, map);
IBinding resolved= CPPTemplates.resolveUnknown((ICPPUnknownBinding) defaultType, map, null);
if (resolved instanceof IType) {
resolvedType= (IType) resolved;
}
@ -1721,8 +1739,8 @@ public class CPPTemplates {
map.put(param, arg);
}
actualArgs[i] = arg;
if (typeContainsTemplateParameter(arg)) {
argsContainTemplateParameters = true;
if (isDependentType(arg)) {
argsContainDependentType = true;
}
} else {
//TODO problem
@ -1730,10 +1748,7 @@ public class CPPTemplates {
}
}
if (argsContainTemplateParameters) {
if (map.isEmpty()) {
map = null;
}
if (argsContainDependentType) {
return ((ICPPInternalTemplateInstantiator) template).deferredInstance(map, arguments);
}
@ -1778,7 +1793,7 @@ public class CPPTemplates {
ICPPBase specBase = (ICPPBase) ((ICPPInternalBase) origBase).clone();
IBinding origClass = origBase.getBaseClass();
if (origClass instanceof IType) {
IType specClass = CPPTemplates.instantiateType((IType) origClass, classInstance.getArgumentMap());
IType specClass = CPPTemplates.instantiateType((IType) origClass, classInstance.getArgumentMap(), ((ICPPClassType) classInstance).getCompositeScope());
specClass = SemanticUtil.getUltimateType(specClass, true);
if (specClass instanceof IBinding) {
((ICPPInternalBase) specBase).setBaseClass((IBinding) specClass);
@ -1796,14 +1811,14 @@ public class CPPTemplates {
/**
* Attempts to (partially) resolve an unknown binding with the given arguments.
*/
public static IBinding resolveUnknown(ICPPUnknownBinding unknown, ObjectMap argMap) throws DOMException {
public static IBinding resolveUnknown(ICPPUnknownBinding unknown, ObjectMap argMap, ICPPScope instantiationScope) throws DOMException {
ICPPBinding parentBinding= unknown.getContainerBinding();
IBinding result = unknown;
IType t = null;
if (parentBinding instanceof ICPPTemplateTypeParameter) {
t = CPPTemplates.instantiateType((ICPPTemplateTypeParameter) parentBinding, argMap);
t = CPPTemplates.instantiateType((ICPPTemplateTypeParameter) parentBinding, argMap, null);
} else if (parentBinding instanceof ICPPUnknownClassType) {
IBinding binding= CPPTemplates.resolveUnknown((ICPPUnknownClassType) parentBinding, argMap);
IBinding binding= CPPTemplates.resolveUnknown((ICPPUnknownClassType) parentBinding, argMap, instantiationScope);
if (binding instanceof IType) {
t = (IType) binding;
}
@ -1811,7 +1826,7 @@ public class CPPTemplates {
if (t != null) {
t = SemanticUtil.getUltimateType(t, false);
if (t instanceof ICPPUnknownBinding) {
result = unknown.resolvePartially((ICPPUnknownBinding) t, argMap);
result = unknown.resolvePartially((ICPPUnknownBinding) t, argMap, instantiationScope);
} else if (t instanceof ICPPClassType) {
IScope s = ((ICPPClassType) t).getCompositeScope();
if (s != null && ASTInternal.isFullyCached(s)) {
@ -1829,14 +1844,14 @@ public class CPPTemplates {
}
}
if (unknown instanceof ICPPUnknownClassInstance && result instanceof ICPPTemplateDefinition) {
IType[] newArgs = CPPTemplates.instantiateTypes(((ICPPUnknownClassInstance) unknown).getArguments(), argMap);
IType[] newArgs = CPPTemplates.instantiateTypes(((ICPPUnknownClassInstance) unknown).getArguments(), argMap, null);
result = CPPTemplates.instantiateTemplate((ICPPTemplateDefinition) result, newArgs, null);
}
}
}
}
} else if (unknown instanceof ICPPDeferredTemplateInstance) {
result= unknown.resolvePartially(null, argMap);
result= unknown.resolvePartially(null, argMap, instantiationScope);
}
return result;

View file

@ -16,7 +16,6 @@ import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
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.ICPPClassTemplate;
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.ICPPScope;
@ -64,27 +63,18 @@ public class CompositeCPPDeferredClassInstance extends CompositeCPPClassType imp
public ICPPScope getUnknownScope() throws DOMException {
if (unknownScope == null) {
final ICPPClassTemplate classTemplate= (ICPPClassTemplate) getTemplateDefinition();
if (classTemplate.getPartialSpecializations().length == 0) {
unknownScope= new CompositeCPPClassSpecializationScope(cf, rbinding);
}
else {
unknownScope= new CompositeCPPUnknownScope(this, getUnknownName());
}
unknownScope= new CompositeCPPUnknownScope(this, getUnknownName());
}
return unknownScope;
}
/* (non-Javadoc)
* @see org.eclipse.cdt.core.dom.ast.cpp.ICPPUnknownBinding#resolvePartially(org.eclipse.cdt.core.dom.ast.cpp.ICPPUnknownClassBinding, org.eclipse.cdt.core.parser.util.ObjectMap)
*/
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) {
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) {
IType[] arguments = getArguments();
IType [] newArgs = new IType[ arguments.length ];
int size = arguments.length;
for( int i = 0; i < size; i++ ){
newArgs[i] = CPPTemplates.instantiateType( arguments[i], argMap );
newArgs[i] = CPPTemplates.instantiateType( arguments[i], argMap, instantiationScope);
}
return ((ICPPInternalTemplateInstantiator)getTemplateDefinition()).instantiate( newArgs );

View file

@ -135,8 +135,8 @@ class CompositeCPPUnknownClassType extends CompositeCPPBinding implements ICPPUn
return unknownScope;
}
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) {
return ((ICPPUnknownClassType) rbinding).resolvePartially(parentBinding, argMap);
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) {
return ((ICPPUnknownClassType) rbinding).resolvePartially(parentBinding, argMap, instantiationScope);
}
public IASTName getUnknownName() {

View file

@ -104,7 +104,7 @@ public class PDOM extends PlatformObject implements IPDOM {
private static int version(int major, int minor) {
return major << 16 + minor;
}
public static final int MAJOR_VERSION = 58;
public static final int MAJOR_VERSION = 59;
public static final int MINOR_VERSION = 0; // minor versions must be compatible
public static final int CURRENT_VERSION= version(MAJOR_VERSION, MINOR_VERSION);

View file

@ -161,7 +161,7 @@ class PDOMCPPClassSpecialization extends PDOMCPPSpecialization implements
ICPPBase specBase = (ICPPBase) ((ICPPInternalBase)origBase).clone();
IBinding origClass = origBase.getBaseClass();
if (origClass instanceof IType) {
IType specClass = CPPTemplates.instantiateType((IType) origClass, getArgumentMap());
IType specClass = CPPTemplates.instantiateType((IType) origClass, getArgumentMap(), getScope());
specClass = SemanticUtil.getUltimateType(specClass, true);
if (specClass instanceof IBinding) {
((ICPPInternalBase)specBase).setBaseClass((IBinding) specClass);

View file

@ -185,7 +185,7 @@ class PDOMCPPClassTemplatePartialSpecialization extends
IType arg = args[i];
//If the argument is a template parameter, we can't instantiate yet, defer for later
if( CPPTemplates.typeContainsTemplateParameter( arg ) ){
if( CPPTemplates.isDependentType( arg ) ){
return deferredInstance( argMap, args );
}
try {

View file

@ -154,20 +154,15 @@ class PDOMCPPDeferredClassInstance extends PDOMCPPInstance implements ICPPDeferr
@Override
public Object clone() {fail();return null;}
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) {
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) {
IType[] arguments = getArguments();
IType[] newArgs = CPPTemplates.instantiateTypes(arguments, argMap);
IType[] newArgs = CPPTemplates.instantiateTypes(arguments, argMap, instantiationScope);
return ((ICPPInternalTemplateInstantiator) getTemplateDefinition()).instantiate(newArgs);
}
public ICPPScope getUnknownScope() throws DOMException {
if (unknownScope == null) {
final ICPPClassTemplate classTemplate= (ICPPClassTemplate) getTemplateDefinition();
if (classTemplate.getPartialSpecializations().length == 0) {
unknownScope= new PDOMCPPClassSpecializationScope(this);
} else {
unknownScope= new PDOMCPPUnknownScope(this, new CPPASTName(getNameCharArray()));
}
unknownScope= new PDOMCPPUnknownScope(this, new CPPASTName(getNameCharArray()));
}
return unknownScope;
}

View file

@ -17,7 +17,6 @@ import java.util.List;
import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.IPDOMVisitor;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IScope;
@ -196,9 +195,9 @@ abstract class PDOMCPPSpecialization extends PDOMCPPBinding implements
public String toString() {
StringBuilder result = new StringBuilder();
result.append(getName());
result.append(" <"); //$NON-NLS-1$
result.append(ASTTypeUtil.getTypeListString(getArguments()));
result.append("> "); //$NON-NLS-1$
result.append(' ');
result.append(getArgumentMap().toString());
result.append(' ');
try {
result.append(getConstantNameForValue(getLinkageImpl(), getNodeType()));
} catch (CoreException ce) {

View file

@ -132,7 +132,7 @@ class PDOMCPPTemplateNonTypeParameter extends PDOMCPPVariable implements IPDOMMe
return null;
}
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) {
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) {
return null;
}
}

View file

@ -144,7 +144,7 @@ class PDOMCPPTemplateTypeParameter extends PDOMCPPBinding implements IPDOMMember
return null;
}
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) { fail(); return null;}
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) { fail(); return null;}
public IASTName getUnknownName() {
return null;
}

View file

@ -22,6 +22,7 @@ import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPUnknownClassInstance;
@ -103,9 +104,9 @@ class PDOMCPPUnknownClassInstance extends PDOMCPPUnknownClassType implements ICP
}
@Override
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) {
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) {
IType[] arguments = getArguments();
IType[] newArgs = CPPTemplates.instantiateTypes(arguments, argMap);
IType[] newArgs = CPPTemplates.instantiateTypes(arguments, argMap, instantiationScope);
if (parentBinding instanceof PDOMNode && isChildOf((PDOMNode) parentBinding) &&
Arrays.equals(newArgs, arguments)) {
return this;

View file

@ -247,7 +247,7 @@ class PDOMCPPUnknownClassType extends PDOMCPPBinding implements ICPPClassScope,
return ICPPClassType.EMPTY_CLASS_ARRAY;
}
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap) {
public IBinding resolvePartially(ICPPUnknownBinding parentBinding, ObjectMap argMap, ICPPScope instantiationScope) {
try {
if (parentBinding == getParentBinding()) {
return this;