Hi list
I’m developing a CDT
plug-in to visualize template instantiations with a colleague for our bachelor
thesis. The idea is that the user can select a template instance that is not
deferred (e.g. std::vector<int>) and we open a new view with the vector
code. The user then can open further template instances or other names that
depend on a template argument. So the user can see which function overload and
specialization gets chosen and the deduced template arguments.
You can see our
current result in the attached image or under http://i.imgur.com/0wq8Ee4.png.
Function templates and parts of class templates already work. Member functions
do not yet work.
I first need to
explain how and why we instantiate dependent templates:
We need to instantiate
the nested templates that depend on other template arguments by ourselves since
CDT does not yet support nested template instantiations. For function templates
we create a subclass of LookupData with the surrounding
ICPPTemplateParameterMap and then pass this LookupData to
CPPSemantics.resolveFunction(LookupData, ICPPFunction[], boolean). We then
call the private CPPTemplates.instantiateForFunctionCall(ICPPFunctionTemplate,
ICPPTemplateArgument[], List<IType>, List<ValueCategory>, boolean,
IASTNode) via reflection to get an ICPPSpecialization with an
ICPPTemplateParameterMap. We first built the ICPPTemplateParameterMap with our
own code but there are too many special cases we might have missed and why
should we implement it again if it already exists in CDT even if it’s not
public.
For class templates we
have an even uglier and unmaintainable solution. We copied the whole
CPPTemplates.createBinding(ICPPASTTemplateId) method, added a new
parameter to pass the ICPPTemplateParameterMap of the surrounding template
instance, call all non accessible methods in the createBinding body via reflection
and added an else when no template declaration could be found for the
template-id. More precisely I’ve added the following else in my code.
if (hasDependentArgument(args)) {
ICPPASTTemplateDeclaration tdecl = getTemplateDeclaration(id);
if (tdecl != null) {
// ...
} else {
for (int i = 0; i < args.length; i++) {
ICPPTemplateArgument arg = args[i];
IType typeValue = arg.getTypeValue();
if (typeValue instanceof ICPPTemplateParameter) {
args[i] = parentMap.getArgument((ICPPTemplateParameter) typeValue);
}
}
}
}
Now to my question respectively my request: Would it be possible to change some methods to public or maybe default and add one method so we don’t have to call methods via reflection?
— The method org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates.instantiateForFunctionCall(ICPPFunctionTemplate, ICPPTemplateArgument[], List<IType>, List<ValueCategory>, boolean, IASTNode) should be public or the method org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates.instantiateForFunctionCall(ICPPFunction[], ICPPTemplateArgument[], List<IType>, List<ValueCategory>, boolean, IASTNode) with default visibility should have a parameter to specify whether it’s ok to have dependent types.
— org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPTemplates.createBinding(ICPPASTTemplateId) should exist in a version with a second parameter of type ICPPTemplateParameterMap with the template arguments from the surrounding template instance. But I don‘t think my solution from above is enough and doesn’t always work.
So, would it be possible to implement those changes or would this cause to many problems? Did I miss something with my solution or is it ok?