Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
[cdt-dev] Instantiating templates with dependent arguments

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?

Marco

Attachment: templator.png
Description: PNG image


Back to the top