At the risk of over-promising, I'm working on a replacement for SWIG using clang. The basic idea is very simple: create a wrapper for each public function and method that is reachable from the source spec (ideally a system header to make it as friction free as possible). These wrappers will substitute pointers instead of references, objects with constructors, etc.
Obviously, clang makes it easy to get the list of functions and methods, and massaging "dangerous" types to pointers isn't that hard (as an aside, the documentation for PointerType would benefit from a sentence directing you to ASTContext for getting your hands on instances programmatically).
I have been using QualType.print(), but it has a couple of problems:
a) TypedefTypes aren't printed with their appropriate scope, and when I started using QualType.getCanonicalType() before printing (to eliminate typedefs),
b) NullPtrType is printed as "nullptr_t" rather than "std::nullptr_t" (or even "decltype(nullptr)")
Upon deciding to get my hands dirty, I investigated TypePrinter.cpp, and indeed printTypedefBefore() made no attempt to provide the scope of a typedef (even when PrintingPolicy.SuppressScope is false). I tried copying the relevant part of printTag(), which works for most cases, but now I get more subtle errors:
dummy.cc.cc:12176:102: error: 'new_allocator' is not a class, namespace, or scoped enumeration
__gnu_cxx::new_allocator is a template, but in this case size_type doesn't depend on a template parameter (the source uses std::size_t unconditionally), from what I can gather from the source, the TypedefDecl is given the context of the CXXRecord, (and not the ClassTemplateSpecializationDecl) so it doesn't know that it should be giving template arguments.
If that is correct (is it correct?) then I don't know how I can safely output TypedefTypes without convincing the compiler to parse it differently, which puts me back to using getCanonicalType().
For ElaboratedTypes I need to ignore printing the NestedNameSpecifier, and then NOT enable PrintingPolicy::SuppressScope (which is done by the ElaboratedTypePolicyRAII). My current diff for the method uses SuppressScope to decide whether to print the full scope, which is (obviously) a potentially breaking change. Arguably instead of SuppressScope there should be a tri-state enum AsSource/Suppress/Force but I don't know whether you would be interested in making such a change.