From fb6b4d9509ff4bcc72573c7e7c8e7b13c40be6e5 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Thu, 15 May 2008 14:04:25 +0000 Subject: [PATCH] Resolve typedefs in arguments before template instantiation. --- ...CPPClassTemplatePartialSpecialization.java | 3 + .../parser/cpp/semantics/CPPTemplates.java | 2 + .../parser/cpp/semantics/SemanticUtil.java | 60 +++++++++++++++++++ ...CPPClassTemplatePartialSpecialization.java | 4 ++ 4 files changed, 69 insertions(+) diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java index fe4ba28a952..accfc1355a9 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPClassTemplatePartialSpecialization.java @@ -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 { diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java index 318c5408549..89fc3749fc1 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/CPPTemplates.java @@ -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]; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java index 96f609d8770..f7b031b700d 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/semantics/SemanticUtil.java @@ -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; + } + } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java index 38a6f4b5b23..64880645ff3 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/pdom/dom/cpp/PDOMCPPClassTemplatePartialSpecialization.java @@ -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 {