mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Resolve typedefs in arguments before template instantiation.
This commit is contained in:
parent
7a78073d7d
commit
fb6b4d9509
4 changed files with 69 additions and 0 deletions
|
@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||
|
||||
/**
|
||||
* @author aniefer
|
||||
|
@ -59,6 +60,7 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate impl
|
|||
|
||||
@Override
|
||||
public IBinding instantiate( IType [] args ){
|
||||
args= SemanticUtil.getSimplifiedTypes(args);
|
||||
ICPPSpecialization instance = getInstance( args );
|
||||
if( instance != null ){
|
||||
return instance;
|
||||
|
@ -77,6 +79,7 @@ public class CPPClassTemplatePartialSpecialization extends CPPClassTemplate impl
|
|||
|
||||
//If the argument is a template parameter, we can't instantiate yet, defer for later
|
||||
if( CPPTemplates.isDependentType( arg ) ){
|
||||
// mstodo the argmap may be partially filled
|
||||
return deferredInstance( argMap, args );
|
||||
}
|
||||
try {
|
||||
|
|
|
@ -1458,6 +1458,7 @@ public class CPPTemplates {
|
|||
return null;
|
||||
}
|
||||
|
||||
args= SemanticUtil.getSimplifiedTypes(args);
|
||||
ICPPClassTemplatePartialSpecialization[] specializations = template.getPartialSpecializations();
|
||||
if (specializations == null) {
|
||||
return template;
|
||||
|
@ -1720,6 +1721,7 @@ public class CPPTemplates {
|
|||
IType[] actualArgs = new IType[numParams];
|
||||
boolean argsContainDependentType = false;
|
||||
|
||||
arguments= SemanticUtil.getSimplifiedTypes(arguments);
|
||||
for (int i = 0; i < numParams; i++) {
|
||||
arg = null;
|
||||
param = parameters[i];
|
||||
|
|
|
@ -15,6 +15,7 @@ package org.eclipse.cdt.internal.core.dom.parser.cpp.semantics;
|
|||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IFunctionType;
|
||||
import org.eclipse.cdt.core.dom.ast.IPointerType;
|
||||
import org.eclipse.cdt.core.dom.ast.IProblemBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IQualifierType;
|
||||
|
@ -22,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
|||
import org.eclipse.cdt.core.dom.ast.ITypedef;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBase;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
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.ICPPPointerToMemberType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
|
@ -30,6 +32,8 @@ import org.eclipse.cdt.core.parser.util.ArrayUtil;
|
|||
import org.eclipse.cdt.core.parser.util.CharArraySet;
|
||||
import org.eclipse.cdt.core.parser.util.CharArrayUtils;
|
||||
import org.eclipse.cdt.core.parser.util.ObjectSet;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.ITypeContainer;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunctionType;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.OverloadableOperator;
|
||||
|
||||
/**
|
||||
|
@ -221,4 +225,60 @@ public class SemanticUtil {
|
|||
return type;
|
||||
}
|
||||
|
||||
/**
|
||||
* Simplifies type by resolving typedefs within the given type.
|
||||
*/
|
||||
static IType getSimplifiedType(IType type) {
|
||||
try {
|
||||
if (type instanceof IFunctionType) {
|
||||
IType ret = null;
|
||||
IType[] params = null;
|
||||
final IType r = ((IFunctionType) type).getReturnType();
|
||||
ret = getSimplifiedType(r);
|
||||
IType[] ps = ((IFunctionType) type).getParameterTypes();
|
||||
params = getSimplifiedTypes(ps);
|
||||
if (ret == r && params == ps) {
|
||||
return type;
|
||||
}
|
||||
return new CPPFunctionType(ret, params, ((ICPPFunctionType) type).isConst(),
|
||||
((ICPPFunctionType) type).isVolatile());
|
||||
}
|
||||
|
||||
if (type instanceof ITypeContainer) {
|
||||
final IType nestedType= ((ITypeContainer) type).getType();
|
||||
if (nestedType == null)
|
||||
return type;
|
||||
|
||||
IType newType= getSimplifiedType(nestedType);
|
||||
if (newType != nestedType) {
|
||||
type= (IType) type.clone();
|
||||
((ITypeContainer) type).setType(newType);
|
||||
return type;
|
||||
}
|
||||
return type;
|
||||
}
|
||||
} catch (DOMException e) {
|
||||
}
|
||||
return type;
|
||||
}
|
||||
|
||||
public static IType[] getSimplifiedTypes(IType[] types) {
|
||||
// Don't create a new array until it's really needed.
|
||||
IType[] result = types;
|
||||
for (int i = 0; i < types.length; i++) {
|
||||
final IType type = types[i];
|
||||
final IType newType= getSimplifiedType(type);
|
||||
if (result != types) {
|
||||
result[i]= newType;
|
||||
} else if (type != newType) {
|
||||
result = new IType[types.length];
|
||||
if (i > 0) {
|
||||
System.arraycopy(types, 0, result, 0, i);
|
||||
}
|
||||
result[i]= newType;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
|||
import org.eclipse.cdt.core.parser.util.ObjectMap;
|
||||
import org.eclipse.cdt.internal.core.Util;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||
import org.eclipse.cdt.internal.core.index.IIndexCPPBindingConstants;
|
||||
import org.eclipse.cdt.internal.core.index.IndexCPPSignatureUtil;
|
||||
import org.eclipse.cdt.internal.core.pdom.PDOM;
|
||||
|
@ -168,6 +169,8 @@ class PDOMCPPClassTemplatePartialSpecialization extends
|
|||
|
||||
@Override
|
||||
public IBinding instantiate(IType[] args) {
|
||||
args= SemanticUtil.getSimplifiedTypes(args);
|
||||
|
||||
ICPPSpecialization instance = getInstance( args );
|
||||
if( instance != null ){
|
||||
return instance;
|
||||
|
@ -186,6 +189,7 @@ class PDOMCPPClassTemplatePartialSpecialization extends
|
|||
|
||||
//If the argument is a template parameter, we can't instantiate yet, defer for later
|
||||
if( CPPTemplates.isDependentType( arg ) ){
|
||||
// mstodo argMap may be partially initialized.
|
||||
return deferredInstance( argMap, args );
|
||||
}
|
||||
try {
|
||||
|
|
Loading…
Add table
Reference in a new issue