Templates are one of the extremely powerful features of C++ that set it apart from most other languages. You can do most everything with them, from extremly complicated compile-time meta-programming like binary self-balanced trees, down to simple shared pointers or generic container classes.
When I switched to Linux a few years ago, I found KDevelop3 and liked it. However I noticed that it didn’t support code-completion for even the simplest C++ templates like for example a reference-counter pointer. That was my entry into KDevelop development. I implemented template support in KDevelop3 that had most of the needed features, and worked quite well when the needed libraries were processed. However the quality it could reach had some upper bounds, since there was no powerful backing structure like the DUChain, but rather just a flat completely string-based code-model.
Actually it was quite hard making the static DUChain structure compatible with dynamic templates, where a new declaration can be created with every use of a class. However I finally succeeded, and today I’ve reached a milestone that is far above of what KDevelop3, and probably even most other IDEs can reach: Full support for C++ template specialization instantiations.
Explicit Template Specializations
What basically motivated me to finish this was that even though the template support was already quite mature, the code-completion for __gnu_cxx::normal_iterator, the iterator used by std::vector, did not work correctly. The problem: It uses the template-class iterator_traits to compute its used types, which looks something like this:
template<class T>
struct Traits {
typedef T Type;
};
template<class T>
struct Traits<T*> {
typedef T Type;
};
This means that, depending one the template-parameter given, another class with different content is instantiated. This case is relatively easy, but this whole principle allows implementing most any algorithm statically, and thus can become arbitrarily complex. The good thing is that I already implemented a framework for the matching of implicit template-parameters to template-functions, that could partially be re-used to do the actual matching.
So the result of the last days is: Full code-completion for all stdc++ functions/classes that use iterator_traits, which is mainly the iterators, and well, also code-completion for any other C++ classes that use explicit specialization. And important: Without any hacks, it’s based on pure language understanding. 🙂 Technically this means that the internal C++ engine is now, apart from bugs and slowness, mostly feature-complete.
Meta Programming
As said above, explicit template specialization can not only be used to form new types, but also to compute numerical stuff statically. While this is not very useful in the form I’m going to present, it does serve as a utility to create really efficient code in practice. Today I’ve pushed the C++ engine in KDevelop4 so far, that it can actually evaluate such meta programs right within KDevelop. So here we go:
What you see on the screenshot is mainly a simple meta-program I found on the internet that can compute whether a number is a prime-number. I tuned it a little so the results can nicely be visualized graphically be KDevelop’s declaration highlighting: At the bottom, you see all the lines highlighted that were computed as prime numbers.
Useful Stuff
What I’ve presented until now is mainly backend features, that will be very helpful in practice without you noticing it, because they will make code-completion, use-building, etc. for more complex template-code “just work”.
There is also some annoying stuff about templates though. One of the main problem: They are not nice to write. You never know what types you’re actually dealing with. Even if the types are supposed to fit into some pattern, most IDEs cannot give you any code-completion while you’re writing a template class.
There is a feature in KDevelop4 to recover you from that misery though. So consider the following screenshot:
You see a very simple template class called TemplateClass. Within its member function, you can not have any code-completion for the template type T, because it is unknown. However if you put the cursor above one of the instantiations at the bottom, in our case above “TemplateClass<Struct1>”, and push the shortcut to jump to its declaration, then KDevelop will remember that you’re interested in that specific instantiation, and will give you total correct code-completion for that instantiation within that class:
Development Status
Apart from those features, I’ve worked a bit more on the backend, and fixed a lot of thread-safety and stability issues. This went so far that now, after a very long single-threaded time, I have enabled multi-threaded parsing again. This also leads to faster reparsing and re-highlighting while editing the document, because one parsing-thread is reserved only for parsing triggered by user-input.