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

Bug 368404: Current instantiation of class template partial specializations.

This commit is contained in:
Markus Schorn 2012-01-13 14:51:22 +01:00
parent 856f097e70
commit 1467a456bd
27 changed files with 213 additions and 268 deletions

View file

@ -628,6 +628,8 @@ public class AST2BaseTest extends BaseTestCase {
} }
public <T extends IBinding> T assertNonProblem(String section, int len, Class<T> type, Class... cs) { public <T extends IBinding> T assertNonProblem(String section, int len, Class<T> type, Class... cs) {
if (len <= 0)
len+= section.length();
IBinding binding= binding(section, len); IBinding binding= binding(section, len);
assertTrue("ProblemBinding for name: " + section.substring(0, len), assertTrue("ProblemBinding for name: " + section.substring(0, len),
!(binding instanceof IProblemBinding)); !(binding instanceof IProblemBinding));

View file

@ -3274,8 +3274,7 @@ public class AST2TemplateTests extends AST2BaseTest {
public void testBug238180_ClassCast() throws Exception { public void testBug238180_ClassCast() throws Exception {
// the code above used to trigger a ClassCastException // the code above used to trigger a ClassCastException
BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true); BindingAssertionHelper ba= new BindingAssertionHelper(getAboveComment(), true);
String tmplId= "str<true, true, false, A, B>"; ICPPClassType p= ba.assertNonProblem("str<true, true, false, A, B>", 0, ICPPClassType.class);
ICPPClassType p= ba.assertNonProblem(tmplId, tmplId.length(), ICPPClassType.class);
ICPPConstructor con= p.getConstructors()[1]; ICPPConstructor con= p.getConstructors()[1];
ICPPReferenceType reftype= (ICPPReferenceType) con.getType().getParameterTypes()[0]; ICPPReferenceType reftype= (ICPPReferenceType) con.getType().getParameterTypes()[0];
IQualifierType qt= (IQualifierType) reftype.getType(); IQualifierType qt= (IQualifierType) reftype.getType();
@ -4197,7 +4196,7 @@ public class AST2TemplateTests extends AST2BaseTest {
// void test(A<int> x) { // void test(A<int> x) {
// f(x); // f(x);
// } // }
public void _testInlineFriendFunction_284690_2() throws Exception { public void testInlineFriendFunction_287409() throws Exception {
final String code = getAboveComment(); final String code = getAboveComment();
BindingAssertionHelper bh= new BindingAssertionHelper(code, true); BindingAssertionHelper bh= new BindingAssertionHelper(code, true);
ICPPFunction func= bh.assertNonProblem("f(x)", 1, ICPPFunction.class); ICPPFunction func= bh.assertNonProblem("f(x)", 1, ICPPFunction.class);

View file

@ -11,7 +11,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.core.dom.ast.cpp; package org.eclipse.cdt.core.dom.ast.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
/** /**
* @noextend This interface is not intended to be extended by clients. * @noextend This interface is not intended to be extended by clients.
@ -24,5 +23,5 @@ public interface ICPPClassTemplate extends ICPPTemplateDefinition, ICPPClassType
* Returns a deferred instance that allows lookups within this class template. * Returns a deferred instance that allows lookups within this class template.
* @since 5.1 * @since 5.1
*/ */
public ICPPTemplateInstance asDeferredInstance() throws DOMException; public ICPPTemplateInstance asDeferredInstance();
} }

View file

@ -38,7 +38,7 @@ public interface ICPPClassTemplatePartialSpecialization extends ICPPClassTemplat
* Returns the arguments of this partial specialization. * Returns the arguments of this partial specialization.
* @since 5.1 * @since 5.1
*/ */
public ICPPTemplateArgument[] getTemplateArguments() throws DOMException; public ICPPTemplateArgument[] getTemplateArguments();
/** /**
* @deprecated use {@link #getTemplateArguments()}, instead. * @deprecated use {@link #getTemplateArguments()}, instead.

View file

@ -226,8 +226,8 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
@Override @Override
public IBinding[] getFriends() { public IBinding[] getFriends() {
// not yet supported IBinding[] friends = specialClass.getSpecializedBinding().getFriends();
return IBinding.EMPTY_BINDING_ARRAY; return specializeMembers(friends);
} }
@Override @Override

View file

@ -23,7 +23,6 @@ import java.util.ArrayList;
import java.util.List; import java.util.List;
import org.eclipse.cdt.core.dom.IName; import org.eclipse.cdt.core.dom.IName;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.EScopeKind; import org.eclipse.cdt.core.dom.ast.EScopeKind;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier; import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTDeclaration; import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
@ -62,7 +61,6 @@ import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.core.parser.util.ObjectSet; import org.eclipse.cdt.core.parser.util.ObjectSet;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory; import org.eclipse.cdt.internal.core.parser.util.ContentAssistMatcherFactory;
@ -99,10 +97,7 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
ICPPClassType clsType = (ICPPClassType) binding; ICPPClassType clsType = (ICPPClassType) binding;
if (clsType instanceof ICPPClassTemplate) { if (clsType instanceof ICPPClassTemplate) {
try { clsType= (ICPPClassType) ((ICPPClassTemplate) clsType).asDeferredInstance();
clsType= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) clsType);
} catch (DOMException e) {
}
} }
char[] className = name.getLookupKey(); char[] className = name.getLookupKey();

View file

@ -225,18 +225,13 @@ public class CPPClassTemplate extends CPPTemplateDefinition implements ICPPClass
} }
@Override @Override
public final ICPPDeferredClassInstance asDeferredInstance() throws DOMException { public final ICPPDeferredClassInstance asDeferredInstance() {
if (fDeferredInstance == null) { if (fDeferredInstance == null) {
fDeferredInstance= createDeferredInstance(); fDeferredInstance= CPPTemplates.createDeferredInstance(this);
} }
return fDeferredInstance; return fDeferredInstance;
} }
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
@Override @Override
public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException { public ICPPTemplateArgument getDefaultArgFromIndex(int paramPos) throws DOMException {
ICPPClassTemplate ib = getIndexBinding(); ICPPClassTemplate ib = getIndexBinding();

View file

@ -41,7 +41,7 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate
} }
@Override @Override
public ICPPTemplateArgument[] getTemplateArguments() throws DOMException { public ICPPTemplateArgument[] getTemplateArguments() {
return arguments; return arguments;
} }
@ -61,25 +61,12 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate
@Override @Override
public ICPPTemplateParameterMap getTemplateParameterMap() { public ICPPTemplateParameterMap getTemplateParameterMap() {
try { return CPPTemplates.createParameterMap(getPrimaryClassTemplate(), getTemplateArguments());
return CPPTemplates.createParameterMap(getPrimaryClassTemplate(), getTemplateArguments());
} catch (DOMException e) {
return CPPTemplateParameterMap.EMPTY;
}
}
@Override
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
return new CPPDeferredClassInstance(this, getTemplateArguments(), getCompositeScope());
} }
@Override @Override
public String toString() { public String toString() {
try { return super.toString() + ASTTypeUtil.getArgumentListString(getTemplateArguments(), true);
return super.toString() + ASTTypeUtil.getArgumentListString(getTemplateArguments(), true);
} catch (DOMException e) {
return super.toString() + '<' + e.getProblem().toString() + '>';
}
} }
@Override @Override
@ -113,23 +100,19 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate
public static boolean isSamePartialClassSpecialization( public static boolean isSamePartialClassSpecialization(
ICPPClassTemplatePartialSpecialization lhs, ICPPClassTemplatePartialSpecialization lhs,
ICPPClassTemplatePartialSpecialization rhs) { ICPPClassTemplatePartialSpecialization rhs) {
try { ICPPClassType ct1= lhs.getPrimaryClassTemplate();
ICPPClassType ct1= lhs.getPrimaryClassTemplate(); ICPPClassType ct2= rhs.getPrimaryClassTemplate();
ICPPClassType ct2= rhs.getPrimaryClassTemplate(); if(!ct1.isSameType(ct2))
if(!ct1.isSameType(ct2))
return false;
ICPPTemplateArgument[] args1= lhs.getTemplateArguments();
ICPPTemplateArgument[] args2= rhs.getTemplateArguments();
if (args1.length != args2.length)
return false;
for (int i = 0; i < args2.length; i++) {
if (args1[i].isSameValue(args2[i]))
return false;
}
} catch (DOMException e) {
return false; return false;
ICPPTemplateArgument[] args1= lhs.getTemplateArguments();
ICPPTemplateArgument[] args2= rhs.getTemplateArguments();
if (args1.length != args2.length)
return false;
for (int i = 0; i < args2.length; i++) {
if (!args1[i].isSameValue(args2[i]))
return false;
} }
return true; return true;
} }

View file

@ -14,6 +14,7 @@ import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; 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.ICPPClassTemplatePartialSpecialization;
@ -81,10 +82,9 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas
} }
@Override @Override
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException { public ICPPDeferredClassInstance asDeferredInstance() {
if (fDeferredInstance == null) { if (fDeferredInstance == null) {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters()); fDeferredInstance= CPPTemplates.createDeferredInstance(this);
fDeferredInstance= new CPPDeferredClassInstance(this, args, getCompositeScope());
} }
return fDeferredInstance; return fDeferredInstance;
} }
@ -95,13 +95,18 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas
} }
@Override @Override
public ICPPTemplateArgument[] getTemplateArguments() throws DOMException { public ICPPTemplateArgument[] getTemplateArguments() {
ICPPTemplateArgument[] args = ((ICPPClassTemplatePartialSpecialization) getSpecializedBinding()).getTemplateArguments(); ICPPTemplateArgument[] args = ((ICPPClassTemplatePartialSpecialization) getSpecializedBinding()).getTemplateArguments();
final IBinding owner = getOwner(); try {
if (owner instanceof ICPPClassSpecialization) { final IBinding owner = getOwner();
return CPPTemplates.instantiateArguments(args, getTemplateParameterMap(), -1, (ICPPClassSpecialization) owner); if (owner instanceof ICPPClassSpecialization) {
return CPPTemplates.instantiateArguments(args, getTemplateParameterMap(), -1,
(ICPPClassSpecialization) owner);
}
return CPPTemplates.instantiateArguments(args, getTemplateParameterMap(), -1, null);
} catch (DOMException e) {
return args;
} }
return CPPTemplates.instantiateArguments(args, getTemplateParameterMap(), -1, null);
} }
@Override @Override
@ -114,12 +119,21 @@ public class CPPClassTemplatePartialSpecializationSpecialization extends CPPClas
} }
@Override @Override
public String toString() { public boolean isSameType(IType type) {
try { if (type == this)
return super.toString() + ASTTypeUtil.getArgumentListString(getTemplateArguments(), true); return true;
} catch (DOMException e) { if (type instanceof ITypedef)
return super.toString() + '<' + e.getProblem().toString() + '>'; return type.isSameType(this);
if (type instanceof ICPPClassTemplatePartialSpecializationSpecialization) {
return CPPClassTemplatePartialSpecialization.isSamePartialClassSpecialization(this, (ICPPClassTemplatePartialSpecializationSpecialization) type);
} }
return false;
}
@Override
public String toString() {
return super.toString() + ASTTypeUtil.getArgumentListString(getTemplateArguments(), true);
} }
@Override @Override

View file

@ -105,10 +105,9 @@ public class CPPClassTemplateSpecialization extends CPPClassSpecialization
} }
@Override @Override
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException { public final ICPPDeferredClassInstance asDeferredInstance() {
if (fDeferredInstance == null) { if (fDeferredInstance == null) {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters()); fDeferredInstance= CPPTemplates.createDeferredInstance(this);
fDeferredInstance= new CPPDeferredClassInstance(this, args, getCompositeScope());
} }
return fDeferredInstance; return fDeferredInstance;
} }

View file

@ -35,7 +35,7 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
private final ICPPScope fLookupScope; private final ICPPScope fLookupScope;
public CPPDeferredClassInstance(ICPPClassTemplate template, ICPPTemplateArgument[] arguments, public CPPDeferredClassInstance(ICPPClassTemplate template, ICPPTemplateArgument[] arguments,
ICPPScope lookupScope) throws DOMException { ICPPScope lookupScope) {
// With template template parameters the owner must not be calculated, it'd lead to an infinite loop. // With template template parameters the owner must not be calculated, it'd lead to an infinite loop.
// Rather than that we override getOwner(). // Rather than that we override getOwner().
super(null, template.getNameCharArray()); super(null, template.getNameCharArray());
@ -44,7 +44,7 @@ public class CPPDeferredClassInstance extends CPPUnknownClass implements ICPPDef
fLookupScope= lookupScope; fLookupScope= lookupScope;
} }
public CPPDeferredClassInstance(ICPPClassTemplate template, ICPPTemplateArgument[] arguments) throws DOMException { public CPPDeferredClassInstance(ICPPClassTemplate template, ICPPTemplateArgument[] arguments) {
this(template, arguments, null); this(template, arguments, null);
} }

View file

@ -24,6 +24,7 @@ import org.eclipse.cdt.core.dom.ast.IFunctionType;
import org.eclipse.cdt.core.dom.ast.IScope; import org.eclipse.cdt.core.dom.ast.IScope;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunction;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameter;
@ -42,9 +43,22 @@ public class CPPFunctionSpecialization extends CPPSpecialization implements ICPP
private ICPPFunctionType type = null; private ICPPFunctionType type = null;
private ICPPParameter[] fParams = null; private ICPPParameter[] fParams = null;
private IType[] specializedExceptionSpec = null; private IType[] specializedExceptionSpec = null;
private final ICPPClassSpecialization fContext;
public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap) { public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap) {
this(orig, owner, argMap, null);
}
public CPPFunctionSpecialization(ICPPFunction orig, IBinding owner, ICPPTemplateParameterMap argMap, ICPPClassSpecialization context) {
super(orig, owner, argMap); super(orig, owner, argMap);
fContext= context;
}
@Override
protected ICPPClassSpecialization getSpecializationContext() {
if (fContext != null)
return fContext;
return super.getSpecializationContext();
} }
private ICPPFunction getFunction() { private ICPPFunction getFunction() {

View file

@ -53,27 +53,26 @@ public abstract class CPPSpecialization extends PlatformObject implements ICPPSp
} }
public IType specializeType(IType type) { public IType specializeType(IType type) {
if (owner instanceof ICPPClassSpecialization) { return CPPTemplates.instantiateType(type, getTemplateParameterMap(), -1, getSpecializationContext());
ICPPClassSpecialization within = getWithin((ICPPClassSpecialization) owner);
return CPPTemplates.instantiateType(type, getTemplateParameterMap(), -1, within);
} else {
return CPPTemplates.instantiateType(type, getTemplateParameterMap(), -1, null);
}
} }
private ICPPClassSpecialization getWithin(ICPPClassSpecialization within) { protected ICPPClassSpecialization getSpecializationContext() {
ICPPClassType orig = within.getSpecializedBinding(); if (owner instanceof ICPPClassSpecialization) {
for(;;) { ICPPClassSpecialization within = (ICPPClassSpecialization) owner;
IBinding o1 = within.getOwner(); ICPPClassType orig = within.getSpecializedBinding();
IBinding o2 = orig.getOwner(); for(;;) {
if (!(o1 instanceof ICPPClassSpecialization && o2 instanceof ICPPClassType)) IBinding o1 = within.getOwner();
return within; IBinding o2 = orig.getOwner();
ICPPClassSpecialization nextWithin = (ICPPClassSpecialization) o1; if (!(o1 instanceof ICPPClassSpecialization && o2 instanceof ICPPClassType))
orig= (ICPPClassType) o2; return within;
if (orig.isSameType(nextWithin)) ICPPClassSpecialization nextWithin = (ICPPClassSpecialization) o1;
return within; orig= (ICPPClassType) o2;
within= nextWithin; if (orig.isSameType(nextWithin))
return within;
within= nextWithin;
}
} }
return null;
} }
public IType[] specializeTypePack(ICPPParameterPackType type) { public IType[] specializeTypePack(ICPPParameterPackType type) {

View file

@ -19,17 +19,7 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.LVALUE;
import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE; import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeOrFunctionSet; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeOrFunctionSet;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCat; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.valueCat;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ARRAY;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.MPTR;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.PTR;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.calculateInheritanceDepth;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.isConversionOperator;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@ -337,9 +327,11 @@ public class CPPSemantics {
if (prop != ICPPASTTemplateId.TEMPLATE_NAME && !data.astName.isQualified()) { if (prop != ICPPASTTemplateId.TEMPLATE_NAME && !data.astName.isQualified()) {
// You cannot use a class template name outside of the class template scope, // You cannot use a class template name outside of the class template scope,
// mark it as a problem. // mark it as a problem.
IBinding replacement= CPPTemplates.isUsedInClassTemplateScope((ICPPClassTemplate) binding, data.astName); IBinding user= CPPTemplates.isUsedInClassTemplateScope((ICPPClassTemplate) binding, data.astName);
if (replacement != null) { if (user instanceof ICPPClassTemplate) {
binding= replacement; binding= ((ICPPClassTemplate) user).asDeferredInstance();
} else if (user != null) {
binding= user;
} else { } else {
boolean ok= false; boolean ok= false;
IASTNode node= data.astName.getParent(); IASTNode node= data.astName.getParent();
@ -372,10 +364,12 @@ public class CPPSemantics {
// try to replace binding by the one pointing to the enclosing template declaration. // try to replace binding by the one pointing to the enclosing template declaration.
ICPPDeferredClassInstance dcl= (ICPPDeferredClassInstance) binding; ICPPDeferredClassInstance dcl= (ICPPDeferredClassInstance) binding;
IBinding usedHere= CPPTemplates.isUsedInClassTemplateScope(dcl.getClassTemplate(), data.astName); IBinding usedHere= CPPTemplates.isUsedInClassTemplateScope(dcl.getClassTemplate(), data.astName);
if (usedHere instanceof ICPPDeferredClassInstance) { if (usedHere instanceof ICPPClassTemplatePartialSpecialization) {
ICPPDeferredClassInstance alt= (ICPPDeferredClassInstance) usedHere; if (CPPTemplates.areSameArguments(((ICPPClassTemplatePartialSpecialization) usedHere).getTemplateArguments(), dcl.getTemplateArguments()))
if (CPPTemplates.areSameArguments(alt.getTemplateArguments(), dcl.getTemplateArguments())) { binding= ((ICPPClassTemplatePartialSpecialization) usedHere).asDeferredInstance();
binding= alt; } else if (usedHere instanceof ICPPClassTemplate) {
if (CPPTemplates.areSameArguments(CPPTemplates.templateParametersAsArguments(((ICPPClassTemplate) usedHere).getTemplateParameters()), dcl.getTemplateArguments())) {
binding= ((ICPPClassTemplate) usedHere).asDeferredInstance();
} }
} }
} }
@ -544,12 +538,14 @@ public class CPPSemantics {
private static void doKoenigLookup(LookupData data) throws DOMException { private static void doKoenigLookup(LookupData data) throws DOMException {
data.ignoreUsingDirectives = true; data.ignoreUsingDirectives = true;
data.forceQualified = true; data.forceQualified = true;
Set<ICPPNamespaceScope> associated = getAssociatedScopes(data); Set<ICPPFunction> friendFns = new HashSet<ICPPFunction>(2);
Set<ICPPNamespaceScope> associated = getAssociatedScopes(data, friendFns);
for (ICPPNamespaceScope scope : associated) { for (ICPPNamespaceScope scope : associated) {
if (!data.visited.containsKey(scope)) { if (!data.visited.containsKey(scope)) {
lookup(data, scope); lookup(data, scope);
} }
} }
mergeResults(data, friendFns.toArray(), false);
} }
static IBinding checkDeclSpecifier(IBinding binding, IASTName name, IASTNode decl) { static IBinding checkDeclSpecifier(IBinding binding, IASTName name, IASTNode decl) {
@ -645,7 +641,7 @@ public class CPPSemantics {
return data; return data;
} }
private static Set<ICPPNamespaceScope> getAssociatedScopes(LookupData data) { private static Set<ICPPNamespaceScope> getAssociatedScopes(LookupData data, Set<ICPPFunction> friendFns) {
if (!data.hasFunctionArguments()) if (!data.hasFunctionArguments())
return Collections.emptySet(); return Collections.emptySet();
@ -654,7 +650,7 @@ public class CPPSemantics {
ObjectSet<IType> handled = new ObjectSet<IType>(2); ObjectSet<IType> handled = new ObjectSet<IType>(2);
for (IType p : ps) { for (IType p : ps) {
try { try {
getAssociatedScopes(p, namespaces, handled, data.tu); getAssociatedScopes(p, namespaces, friendFns, handled, data.tu);
} catch (DOMException e) { } catch (DOMException e) {
} }
} }
@ -682,7 +678,7 @@ public class CPPSemantics {
// 3.4.2-2 // 3.4.2-2
private static void getAssociatedScopes(IType t, Set<ICPPNamespaceScope> namespaces, private static void getAssociatedScopes(IType t, Set<ICPPNamespaceScope> namespaces,
ObjectSet<IType> handled, CPPASTTranslationUnit tu) throws DOMException { Set<ICPPFunction> friendFns, ObjectSet<IType> handled, CPPASTTranslationUnit tu) throws DOMException {
t = getNestedType(t, TDEF | CVTYPE | PTR | ARRAY | REF); t = getNestedType(t, TDEF | CVTYPE | PTR | ARRAY | REF);
if (t instanceof IBinding) { if (t instanceof IBinding) {
if (handled.containsKey(t)) if (handled.containsKey(t))
@ -691,7 +687,7 @@ public class CPPSemantics {
IBinding owner= ((IBinding) t).getOwner(); IBinding owner= ((IBinding) t).getOwner();
if (owner instanceof ICPPClassType) { if (owner instanceof ICPPClassType) {
getAssociatedScopes((IType) owner, namespaces, handled, tu); getAssociatedScopes((IType) owner, namespaces, friendFns, handled, tu);
} else { } else {
getAssociatedNamespaceScopes(getContainingNamespaceScope((IBinding) t, tu), namespaces); getAssociatedNamespaceScopes(getContainingNamespaceScope((IBinding) t, tu), namespaces);
} }
@ -702,35 +698,40 @@ public class CPPSemantics {
for (ICPPBase base : bases) { for (ICPPBase base : bases) {
IBinding b = base.getBaseClass(); IBinding b = base.getBaseClass();
if (b instanceof IType) if (b instanceof IType)
getAssociatedScopes((IType) b, namespaces, handled, tu); getAssociatedScopes((IType) b, namespaces, friendFns, handled, tu);
} }
// Furthermore, if T is a class template ... // Furthermore, if T is a class template ...
// * ... types of the template arguments for template type parameters // * ... types of the template arguments for template type parameters
// (excluding template template parameters); // (excluding template template parameters);
// * ... owners of which any template template arguments are members; // * ... owners of which any template template arguments are members;
if (ct instanceof ICPPTemplateInstance) { if (ct instanceof ICPPTemplateInstance) {
for (IBinding friend : ct.getFriends()) {
if (friend instanceof ICPPFunction) {
friendFns.add((ICPPFunction) friend);
}
}
ICPPTemplateArgument[] args = ((ICPPTemplateInstance) ct).getTemplateArguments(); ICPPTemplateArgument[] args = ((ICPPTemplateInstance) ct).getTemplateArguments();
for (ICPPTemplateArgument arg : args) { for (ICPPTemplateArgument arg : args) {
if (arg.isTypeValue()) { if (arg.isTypeValue()) {
getAssociatedScopes(arg.getTypeValue(), namespaces, handled, tu); getAssociatedScopes(arg.getTypeValue(), namespaces, friendFns, handled, tu);
} }
} }
} }
} else if (t instanceof IFunctionType) { } else if (t instanceof IFunctionType) {
IFunctionType ft = (IFunctionType) t; IFunctionType ft = (IFunctionType) t;
getAssociatedScopes(ft.getReturnType(), namespaces, handled, tu); getAssociatedScopes(ft.getReturnType(), namespaces, friendFns, handled, tu);
IType[] ps = ft.getParameterTypes(); IType[] ps = ft.getParameterTypes();
for (IType pt : ps) { for (IType pt : ps) {
getAssociatedScopes(pt, namespaces, handled, tu); getAssociatedScopes(pt, namespaces, friendFns, handled, tu);
} }
} else if (t instanceof ICPPPointerToMemberType) { } else if (t instanceof ICPPPointerToMemberType) {
final ICPPPointerToMemberType pmt = (ICPPPointerToMemberType) t; final ICPPPointerToMemberType pmt = (ICPPPointerToMemberType) t;
getAssociatedScopes(pmt.getMemberOfClass(), namespaces, handled, tu); getAssociatedScopes(pmt.getMemberOfClass(), namespaces, friendFns, handled, tu);
getAssociatedScopes(pmt.getType(), namespaces, handled, tu); getAssociatedScopes(pmt.getType(), namespaces, friendFns, handled, tu);
} else if (t instanceof FunctionSetType) { } else if (t instanceof FunctionSetType) {
FunctionSetType fst= (FunctionSetType) t; FunctionSetType fst= (FunctionSetType) t;
for (ICPPFunction fn : fst.getFunctionSet()) { for (ICPPFunction fn : fst.getFunctionSet()) {
getAssociatedScopes(fn.getType(), namespaces, handled, tu); getAssociatedScopes(fn.getType(), namespaces, friendFns, handled, tu);
} }
} }
} }
@ -2397,6 +2398,7 @@ public class CPPSemantics {
// Loop over all functions // Loop over all functions
List<FunctionCost> potentialCosts= null; List<FunctionCost> potentialCosts= null;
IFunction unknownFunction= null;
for (ICPPFunction fn : fns) { for (ICPPFunction fn : fns) {
if (fn == null) if (fn == null)
continue; continue;
@ -2407,9 +2409,9 @@ public class CPPSemantics {
if (fnCost == CONTAINS_DEPENDENT_TYPES) { if (fnCost == CONTAINS_DEPENDENT_TYPES) {
if (viableCount == 1) if (viableCount == 1)
return fns[0]; return fn;
setTargetedFunctionsToUnknown(argTypes); unknownFunction = fn;
return CPPUnknownFunction.createForSample(fns[0]); continue;
} }
if (fnCost.hasDeferredUDC()) { if (fnCost.hasDeferredUDC()) {
@ -2442,8 +2444,13 @@ public class CPPSemantics {
} }
} }
if (bestFnCost == null) if (bestFnCost == null) {
return null; if (unknownFunction == null)
return null;
setTargetedFunctionsToUnknown(argTypes);
return CPPUnknownFunction.createForSample(unknownFunction);
}
if (ambiguousFunctions != null) { if (ambiguousFunctions != null) {
ambiguousFunctions= ArrayUtil.append(IFunction.class, ambiguousFunctions, bestFnCost.getFunction()); ambiguousFunctions= ArrayUtil.append(IFunction.class, ambiguousFunctions, bestFnCost.getFunction());
@ -2723,7 +2730,7 @@ public class CPPSemantics {
IType implicitType; IType implicitType;
ICPPClassType owner= m.getClassOwner(); ICPPClassType owner= m.getClassOwner();
if (owner instanceof ICPPClassTemplate) { if (owner instanceof ICPPClassTemplate) {
owner= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) owner); owner= (ICPPClassType) ((ICPPClassTemplate) owner).asDeferredInstance();
} }
ICPPFunctionType ft= m.getType(); ICPPFunctionType ft= m.getType();
implicitType= SemanticUtil.addQualifiers(owner, ft.isConst(), ft.isVolatile(), false); implicitType= SemanticUtil.addQualifiers(owner, ft.isConst(), ft.isVolatile(), false);

View file

@ -79,6 +79,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPFunctionType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPParameterPackType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateDefinition;
@ -273,12 +274,12 @@ public class CPPTemplates {
if (scope instanceof ICPPClassScope) { if (scope instanceof ICPPClassScope) {
ICPPClassType b= ((ICPPClassScope) scope).getClassType(); ICPPClassType b= ((ICPPClassScope) scope).getClassType();
if (b != null && ct.isSameType(b)) { if (b != null && ct.isSameType(b)) {
return CPPTemplates.instantiateWithinClassTemplate(ct); return ct;
} }
if (b instanceof ICPPClassTemplatePartialSpecialization) { if (b instanceof ICPPClassTemplatePartialSpecialization) {
ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) b; ICPPClassTemplatePartialSpecialization pspec= (ICPPClassTemplatePartialSpecialization) b;
if (ct.isSameType(pspec.getPrimaryClassTemplate())) { if (ct.isSameType(pspec.getPrimaryClassTemplate())) {
return CPPTemplates.instantiateWithinClassTemplate(pspec); return pspec;
} }
} else if (b instanceof ICPPClassSpecialization) { } else if (b instanceof ICPPClassSpecialization) {
ICPPClassSpecialization specialization= (ICPPClassSpecialization) b; ICPPClassSpecialization specialization= (ICPPClassSpecialization) b;
@ -466,34 +467,21 @@ public class CPPTemplates {
return completeArgs; return completeArgs;
} }
/** public static ICPPDeferredClassInstance createDeferredInstance(ICPPClassTemplate ct) {
* Instantiates the template for usage within its own body. May return <code>null</code>.
*/
public static ICPPClassType instantiateWithinClassTemplate(ICPPClassTemplate template) throws DOMException {
ICPPTemplateInstance di= template.asDeferredInstance();
if (di instanceof ICPPClassType)
return (ICPPClassType) di;
ICPPTemplateArgument[] args; ICPPTemplateArgument[] args;
if (template instanceof ICPPClassTemplatePartialSpecialization) { if (ct instanceof ICPPClassTemplatePartialSpecialization) {
args= ((ICPPClassTemplatePartialSpecialization) template).getTemplateArguments(); args= ((ICPPClassTemplatePartialSpecialization) ct).getTemplateArguments();
} else { } else {
ICPPTemplateParameter[] templateParameters = template.getTemplateParameters(); args = CPPTemplates.templateParametersAsArguments(ct.getTemplateParameters());
args = templateParametersAsArguments(templateParameters);
} }
IBinding result = deferredInstance(template, args); return new CPPDeferredClassInstance(ct, args, (ICPPScope) ct.getCompositeScope());
if (result instanceof ICPPClassType)
return (ICPPClassType) result;
return template;
} }
public static ICPPTemplateArgument[] templateParametersAsArguments( public static ICPPTemplateArgument[] templateParametersAsArguments(ICPPTemplateParameter[] tpars) {
ICPPTemplateParameter[] templateParameters) throws DOMException {
ICPPTemplateArgument[] args; ICPPTemplateArgument[] args;
args = new ICPPTemplateArgument[templateParameters.length]; args = new ICPPTemplateArgument[tpars.length];
for (int i = 0; i < templateParameters.length; i++) { for (int i = 0; i < tpars.length; i++) {
final ICPPTemplateParameter tp = templateParameters[i]; final ICPPTemplateParameter tp = tpars[i];
if (tp instanceof IType) { if (tp instanceof IType) {
IType t= (IType) tp; IType t= (IType) tp;
if (tp.isParameterPack()) { if (tp.isParameterPack()) {
@ -773,7 +761,12 @@ public class CPPTemplates {
} else if (decl instanceof ICPPClassTemplate) { } else if (decl instanceof ICPPClassTemplate) {
spec = new CPPClassTemplateSpecialization((ICPPClassTemplate) decl, owner, tpMap); spec = new CPPClassTemplateSpecialization((ICPPClassTemplate) decl, owner, tpMap);
} else if (decl instanceof ICPPClassType) { } else if (decl instanceof ICPPClassType) {
spec = new CPPClassSpecialization((ICPPClassType) decl, owner, tpMap); IBinding oldOwner = decl.getOwner();
if (oldOwner instanceof IType && owner.getSpecializedBinding().isSameType((IType) oldOwner)) {
spec = new CPPClassSpecialization((ICPPClassType) decl, owner, tpMap);
} else {
spec = new CPPClassSpecialization((ICPPClassType) decl, oldOwner, tpMap);
}
} else if (decl instanceof ICPPField) { } else if (decl instanceof ICPPField) {
spec = new CPPFieldSpecialization(decl, owner, tpMap); spec = new CPPFieldSpecialization(decl, owner, tpMap);
} else if (decl instanceof ICPPFunctionTemplate) { } else if (decl instanceof ICPPFunctionTemplate) {
@ -788,7 +781,8 @@ public class CPPTemplates {
} else if (decl instanceof ICPPMethod) { } else if (decl instanceof ICPPMethod) {
spec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap); spec = new CPPMethodSpecialization((ICPPMethod) decl, owner, tpMap);
} else if (decl instanceof ICPPFunction) { } else if (decl instanceof ICPPFunction) {
spec = new CPPFunctionSpecialization((ICPPFunction) decl, owner, tpMap); IBinding oldOwner = decl.getOwner();
spec = new CPPFunctionSpecialization((ICPPFunction) decl, oldOwner, tpMap, owner);
} else if (decl instanceof ITypedef) { } else if (decl instanceof ITypedef) {
spec = new CPPTypedefSpecialization(decl, owner, tpMap); spec = new CPPTypedefSpecialization(decl, owner, tpMap);
} else if (decl instanceof IEnumeration || decl instanceof IEnumerator) { } else if (decl instanceof IEnumeration || decl instanceof IEnumerator) {
@ -1081,11 +1075,11 @@ public class CPPTemplates {
} }
/** /**
* This method propagates the specialization of a member to the types used by the member. * Instantiates the given type with the provided map and packoffset.
* @param type a type to instantiate. * The context is used to replace templates with their specialization, where appropriate.
* @param tpMap a mapping between template parameters and the corresponding arguments.
*/ */
public static IType instantiateType(IType type, ICPPTemplateParameterMap tpMap, int packOffset, ICPPClassSpecialization within) { public static IType instantiateType(IType type, ICPPTemplateParameterMap tpMap, int packOffset,
ICPPClassSpecialization within) {
try { try {
if (tpMap == null) if (tpMap == null)
return type; return type;
@ -1145,24 +1139,25 @@ public class CPPTemplates {
} }
if (within != null && type instanceof IBinding) { if (within != null && type instanceof IBinding) {
IType unwound= getNestedType(type, TDEF);
if (unwound instanceof ICPPClassType) {
// Convert (partial) class-templates (specializations) or typedefs to such to
// the actual instance.
ICPPClassType originalClass= within.getSpecializedBinding();
if (originalClass.isSameType(unwound))
return within;
}
IBinding typeAsBinding= (IBinding) type; IBinding typeAsBinding= (IBinding) type;
IBinding typeOwner= typeAsBinding.getOwner(); IBinding owner= typeAsBinding.getOwner();
if (typeOwner instanceof IType) { if (owner instanceof IType) {
IType newOwner= instantiateType((IType) typeOwner, tpMap, packOffset, within); final IType ownerAsType = getNestedType((IType) owner, TDEF);
if (newOwner != typeOwner && newOwner instanceof ICPPClassSpecialization) { Object newOwner= owner;
if (ownerAsType instanceof ICPPClassType && ownerAsType.isSameType(within.getSpecializedBinding())) {
// Convert (partial) class-templates (specializations) that are used as owner of
// another binding, to the more specialized version.
newOwner= within;
} else {
newOwner= instantiateType(ownerAsType, tpMap, packOffset, within);
}
if (newOwner != owner && newOwner instanceof ICPPClassSpecialization) {
return (IType) ((ICPPClassSpecialization) newOwner).specializeMember(typeAsBinding); return (IType) ((ICPPClassSpecialization) newOwner).specializeMember(typeAsBinding);
} }
} }
IType unwound= getNestedType(type, TDEF);
if (unwound instanceof ICPPTemplateInstance && !(unwound instanceof ICPPDeferredClassInstance)) { if (unwound instanceof ICPPTemplateInstance && !(unwound instanceof ICPPDeferredClassInstance)) {
// Argument of a class specialization can be a nested class subject to specialization. // Argument of a class specialization can be a nested class subject to specialization.
final ICPPTemplateInstance classInstance = (ICPPTemplateInstance) unwound; final ICPPTemplateInstance classInstance = (ICPPTemplateInstance) unwound;
@ -1944,12 +1939,8 @@ public class CPPTemplates {
if (pspecs != null && pspecs.length > 0) { if (pspecs != null && pspecs.length > 0) {
final String argStr= ASTTypeUtil.getArgumentListString(args, true); final String argStr= ASTTypeUtil.getArgumentListString(args, true);
for (ICPPClassTemplatePartialSpecialization pspec : pspecs) { for (ICPPClassTemplatePartialSpecialization pspec : pspecs) {
try { if (argStr.equals(ASTTypeUtil.getArgumentListString(pspec.getTemplateArguments(), true)))
if (argStr.equals(ASTTypeUtil.getArgumentListString(pspec.getTemplateArguments(), true))) return pspec;
return pspec;
} catch (DOMException e) {
// ignore partial specializations with problems
}
} }
} }
return null; return null;
@ -2311,6 +2302,11 @@ public class CPPTemplates {
t= ((ITypeContainer) t).getType(); t= ((ITypeContainer) t).getType();
} else if (t instanceof InitializerListType) { } else if (t instanceof InitializerListType) {
return isDependentInitializerList(((InitializerListType) t).getInitializerList()); return isDependentInitializerList(((InitializerListType) t).getInitializerList());
} else if (t instanceof IBinding) {
IBinding owner = ((IBinding) t).getOwner();
if (owner instanceof ICPPClassTemplate)
return true;
return (owner instanceof IType) && owner != t && isDependentType((IType) owner);
} else { } else {
return false; return false;
} }
@ -2414,7 +2410,15 @@ public class CPPTemplates {
} }
if (changed) { if (changed) {
IBinding inst= instantiate(classTemplate, newArgs); IBinding inst= null;
if (classTemplate instanceof ICPPClassTemplatePartialSpecialization) {
try {
inst= instantiatePartialSpecialization((ICPPClassTemplatePartialSpecialization) classTemplate, newArgs, false, null);
} catch (DOMException e) {
}
} else {
inst= instantiate(classTemplate, newArgs);
}
if (inst != null) if (inst != null)
return inst; return inst;
} }

View file

@ -13,11 +13,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics; package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ; import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getNestedType;
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
@ -2175,7 +2171,7 @@ public class CPPVisitor extends ASTQueries {
ICPPClassScope cScope = (ICPPClassScope) s; ICPPClassScope cScope = (ICPPClassScope) s;
IType type = cScope.getClassType(); IType type = cScope.getClassType();
if (type instanceof ICPPClassTemplate) { if (type instanceof ICPPClassTemplate) {
type= CPPTemplates.instantiateWithinClassTemplate((ICPPClassTemplate) type); type= (ICPPClassType) ((ICPPClassTemplate) type).asDeferredInstance();
} }
return SemanticUtil.addQualifiers(type, dtor.isConst(), dtor.isVolatile(), false); return SemanticUtil.addQualifiers(type, dtor.isConst(), dtor.isVolatile(), false);
} }

View file

@ -32,6 +32,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTemplateParameter; 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.ICPPTemplateTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPUnknownClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
@ -53,6 +54,9 @@ public class IndexCPPSignatureUtil {
*/ */
public static String getSignature(IBinding binding) throws CoreException, DOMException { public static String getSignature(IBinding binding) throws CoreException, DOMException {
StringBuilder buffer = new StringBuilder(); StringBuilder buffer = new StringBuilder();
if (binding instanceof ICPPDeferredClassInstance) {
buffer.append(getSignature(((ICPPDeferredClassInstance) binding).getTemplateDefinition()));
}
if (binding instanceof ICPPTemplateInstance) { if (binding instanceof ICPPTemplateInstance) {
ICPPTemplateInstance inst = (ICPPTemplateInstance) binding; ICPPTemplateInstance inst = (ICPPTemplateInstance) binding;
buffer.append(getTemplateArgString(inst.getTemplateArguments(), true)); buffer.append(getTemplateArgString(inst.getTemplateArguments(), true));

View file

@ -12,7 +12,6 @@
package org.eclipse.cdt.internal.core.index.composite.cpp; package org.eclipse.cdt.internal.core.index.composite.cpp;
import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.CCorePlugin;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; 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.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
@ -20,7 +19,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
@ -80,20 +78,15 @@ public class CompositeCPPClassTemplate extends CompositeCPPClassType
} }
@Override @Override
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException { public final ICPPDeferredClassInstance asDeferredInstance() {
CompositeInstanceCache cache= CompositeInstanceCache.getCache(cf, rbinding); CompositeInstanceCache cache= CompositeInstanceCache.getCache(cf, rbinding);
synchronized (cache) { synchronized (cache) {
ICPPDeferredClassInstance dci= cache.getDeferredInstance(); ICPPDeferredClassInstance dci= cache.getDeferredInstance();
if (dci == null) { if (dci == null) {
dci= createDeferredInstance(); dci= CPPTemplates.createDeferredInstance(this);
cache.putDeferredInstance(dci); cache.putDeferredInstance(dci);
} }
return dci; return dci;
} }
} }
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
} }

View file

@ -10,7 +10,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp; package org.eclipse.cdt.internal.core.index.composite.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; 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.ICPPClassTemplatePartialSpecialization;
@ -18,7 +17,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplatePartialSpecializationSp
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
@ -68,23 +66,18 @@ public class CompositeCPPClassTemplatePartialSpecializationSpecialization extend
} }
@Override @Override
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException { public ICPPDeferredClassInstance asDeferredInstance() {
CompositeInstanceCache cache= CompositeInstanceCache.getCache(cf, rbinding); CompositeInstanceCache cache= CompositeInstanceCache.getCache(cf, rbinding);
synchronized (cache) { synchronized (cache) {
ICPPDeferredClassInstance dci= cache.getDeferredInstance(); ICPPDeferredClassInstance dci= cache.getDeferredInstance();
if (dci == null) { if (dci == null) {
dci= createDeferredInstance(); dci= CPPTemplates.createDeferredInstance(this);
cache.putDeferredInstance(dci); cache.putDeferredInstance(dci);
} }
return dci; return dci;
} }
} }
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
@Override @Override
@Deprecated @Deprecated
public IType[] getArguments() { public IType[] getArguments() {

View file

@ -11,14 +11,12 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.index.composite.cpp; package org.eclipse.cdt.internal.core.index.composite.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; 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.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
@ -63,20 +61,15 @@ CompositeCPPClassSpecialization implements ICPPClassTemplate, ICPPInstanceCache{
@Override @Override
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException { public final ICPPDeferredClassInstance asDeferredInstance() {
CompositeInstanceCache cache= CompositeInstanceCache.getCache(cf, rbinding); CompositeInstanceCache cache= CompositeInstanceCache.getCache(cf, rbinding);
synchronized (cache) { synchronized (cache) {
ICPPDeferredClassInstance dci= cache.getDeferredInstance(); ICPPDeferredClassInstance dci= cache.getDeferredInstance();
if (dci == null) { if (dci == null) {
dci= createDeferredInstance(); dci= CPPTemplates.createDeferredInstance(this);
cache.putDeferredInstance(dci); cache.putDeferredInstance(dci);
} }
return dci; return dci;
} }
} }
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
} }

View file

@ -61,13 +61,7 @@ public class TemplateInstanceUtil {
} }
public static ICPPTemplateArgument[] getTemplateArguments(ICompositesFactory cf, ICPPClassTemplatePartialSpecialization rbinding) { public static ICPPTemplateArgument[] getTemplateArguments(ICompositesFactory cf, ICPPClassTemplatePartialSpecialization rbinding) {
try { return convert(cf, rbinding.getTemplateArguments());
return convert(cf, rbinding.getTemplateArguments());
} catch (DOMException e) {
// index bindings don't throw DOMExceptions
assert false;
}
return ICPPTemplateArgument.EMPTY_ARGUMENTS;
} }
public static IBinding getSpecializedBinding(ICompositesFactory cf, IIndexBinding rbinding) { public static IBinding getSpecializedBinding(ICompositesFactory cf, IIndexBinding rbinding) {

View file

@ -33,7 +33,6 @@ 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.ICPPTemplateTypeParameter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
@ -303,20 +302,15 @@ public class PDOMCPPClassTemplate extends PDOMCPPClassType
} }
@Override @Override
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException { public final ICPPDeferredClassInstance asDeferredInstance() {
PDOMInstanceCache cache= PDOMInstanceCache.getCache(this); PDOMInstanceCache cache= PDOMInstanceCache.getCache(this);
synchronized (cache) { synchronized (cache) {
ICPPDeferredClassInstance dci= cache.getDeferredInstance(); ICPPDeferredClassInstance dci= cache.getDeferredInstance();
if (dci == null) { if (dci == null) {
dci= createDeferredInstance(); dci= CPPTemplates.createDeferredInstance(this);
cache.putDeferredInstance(dci); cache.putDeferredInstance(dci);
} }
return dci; return dci;
} }
} }
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
} }

View file

@ -18,13 +18,13 @@ import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate; 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.ICPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameterMap;
import org.eclipse.cdt.core.parser.util.ObjectMap; import org.eclipse.cdt.core.parser.util.ObjectMap;
import org.eclipse.cdt.internal.core.Util; import org.eclipse.cdt.internal.core.Util;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassTemplatePartialSpecialization;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants; import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
import org.eclipse.cdt.internal.core.index.IndexCPPSignatureUtil; import org.eclipse.cdt.internal.core.index.IndexCPPSignatureUtil;
@ -184,25 +184,7 @@ class PDOMCPPClassTemplatePartialSpecialization extends PDOMCPPClassTemplate
} }
final ICPPClassTemplatePartialSpecialization rhs = (ICPPClassTemplatePartialSpecialization)type; final ICPPClassTemplatePartialSpecialization rhs = (ICPPClassTemplatePartialSpecialization)type;
try { return CPPClassTemplatePartialSpecialization.isSamePartialClassSpecialization(this, rhs);
ICPPClassType ct1= getPrimaryClassTemplate();
ICPPClassType ct2= rhs.getPrimaryClassTemplate();
if(!ct1.isSameType(ct2))
return false;
ICPPTemplateArgument[] args1= getTemplateArguments();
ICPPTemplateArgument[] args2= rhs.getTemplateArguments();
if (args1.length != args2.length)
return false;
for (int i = 0; i < args2.length; i++) {
if (args1[i].isSameValue(args2[i]))
return false;
}
} catch (DOMException e) {
return false;
}
return true;
} }
@Override @Override

View file

@ -11,7 +11,6 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.pdom.dom.cpp; package org.eclipse.cdt.internal.core.pdom.dom.cpp;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IProblemBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding;
import org.eclipse.cdt.core.dom.ast.IType; import org.eclipse.cdt.core.dom.ast.IType;
@ -26,7 +25,6 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateNonTypeParameter;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter; import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.core.parser.util.CharArrayUtils;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPInstanceCache;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
@ -169,20 +167,15 @@ class PDOMCPPClassTemplateSpecialization extends PDOMCPPClassSpecialization
} }
@Override @Override
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException { public final ICPPDeferredClassInstance asDeferredInstance() {
PDOMInstanceCache cache= PDOMInstanceCache.getCache(this); PDOMInstanceCache cache= PDOMInstanceCache.getCache(this);
synchronized (cache) { synchronized (cache) {
ICPPDeferredClassInstance dci= cache.getDeferredInstance(); ICPPDeferredClassInstance dci= cache.getDeferredInstance();
if (dci == null) { if (dci == null) {
dci= createDeferredInstance(); dci= CPPTemplates.createDeferredInstance(this);
cache.putDeferredInstance(dci); cache.putDeferredInstance(dci);
} }
return dci; return dci;
} }
} }
protected ICPPDeferredClassInstance createDeferredInstance() throws DOMException {
ICPPTemplateArgument[] args = CPPTemplates.templateParametersAsArguments(getTemplateParameters());
return new CPPDeferredClassInstance(this, args, getCompositeScope());
}
} }

View file

@ -186,8 +186,6 @@ class PDOMCPPLinkage extends PDOMLinkage implements IIndexCPPBindingConstants {
partial.setArguments(args); partial.setArguments(args);
} catch (CoreException e) { } catch (CoreException e) {
CCorePlugin.log(e); CCorePlugin.log(e);
} catch (DOMException e) {
CCorePlugin.log(e);
} finally { } finally {
partial = null; partial = null;
binding = null; binding = null;

View file

@ -363,7 +363,7 @@ public class PDOMCPPTemplateTemplateParameter extends PDOMCPPBinding
} }
@Override @Override
public ICPPDeferredClassInstance asDeferredInstance() throws DOMException { public ICPPDeferredClassInstance asDeferredInstance() {
return null; return null;
} }
} }

View file

@ -23,7 +23,6 @@ import org.eclipse.ui.PlatformUI;
import org.eclipse.cdt.core.dom.IPDOMNode; import org.eclipse.cdt.core.dom.IPDOMNode;
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil; import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.ICompositeType;
import org.eclipse.cdt.core.dom.ast.IEnumeration; import org.eclipse.cdt.core.dom.ast.IEnumeration;
import org.eclipse.cdt.core.dom.ast.IEnumerator; import org.eclipse.cdt.core.dom.ast.IEnumerator;
@ -112,15 +111,11 @@ public class IndexLabelProvider extends LabelProvider {
StringBuffer buffer = new StringBuffer("Part: "); //$NON-NLS-1$ StringBuffer buffer = new StringBuffer("Part: "); //$NON-NLS-1$
buffer.append(result); buffer.append(result);
buffer.append('<'); buffer.append('<');
try { ICPPTemplateArgument[] types = ((ICPPClassTemplatePartialSpecialization) element).getTemplateArguments();
ICPPTemplateArgument[] types = ((ICPPClassTemplatePartialSpecialization) element).getTemplateArguments(); for (int i = 0; i < types.length; i++) {
for (int i = 0; i < types.length; i++) { if (i > 0)
if (i > 0) buffer.append(',');
buffer.append(','); buffer.append(ASTTypeUtil.getArgumentString(types[i], false));
buffer.append(ASTTypeUtil.getArgumentString(types[i], false));
}
} catch (DOMException e) {
buffer.append(e.getProblem().toString());
} }
buffer.append('>'); buffer.append('>');
result = buffer.toString(); result = buffer.toString();