As part of my recent gearing up for working on our super secret game project, I’ve been decking out my Vim installation with useful scripts.
During part of this process, I found that the OmniCPPComplete script is almost completely unusable when working with the Boost libraries and STL. OCC uses exuberant-ctags to gather information, but the tag files it generates are…rather large (in the case of Boost), and doing autocompletion with STL requires a set of specially modified headers.
While both those problems are not exactly unsurmountable, the main problem I had with OCC is that it is very stupid. Using it with the libraries I wanted to use produce a lot of tag pollution – autocompletion on anything produced an extremely long list of stuff that was nothing near what I wanted. Also, it was completely static: I didn’t get completion on instances, or even of tags in my current file.
So, I discarded OmniCppComplete, and embarked on a quest to use Clang_Complete.
Clang_Complete is an interesting project. Some professional IDEs use the actual compiler to generate the Abstract Syntax Tree of the code – actual living, breathing information about the code as you type it. However, due to some paranoia in the world of the Gnu, gcc does not export it’s AST. Thus, clang_complete uses…clang! Clang is a compiler based on the LLVM.
Luckily for me, even as I was working on this, Debian brought up-to-date packages of LLVM and Clang to my doorstep
However…
As I am working on a multithreaded project, and I’m endevouring to use as modern and as cross-platform code as possible, I hit a stumbling block when trying to use std::atomic:
error: Non-inline namespace cannot be reopened as inline
Clang doesn’t like the nested-namespaces technique used the gnu standard libc++ to version and control what ABI gets inlined. I wrested around for a while, trying to coax clang into getting past this. Nothing was working, so I started looking at it like a platform problem. One platform being actual compiling, the other being clang_complete.
Since my goal was NOT to compile with clang, but only to make autocompletion work nicely for me – and since this so far seems to be only in the files where I want to use atomic operations, I start putting this in the tops of those files:
// headers like you'd normally expect
#include <iostream>
// Now for the conditional stuff
#ifdef __clang__
#include <clang_complete_compat/atomic.h>
using namespace std::atomic;
#else
#include <atomic>
#endif
Then, I took the regular <atomic>, and started butchering it into something to forward declare what I wanted. I know I could do better, because I’ve missed some detail that entails using the extra “using namespace”. However, for the moment, it works.