#ifndef SYNTH_CGWRAPPERS_HPP_INCLUDED
#define SYNTH_CGWRAPPERS_HPP_INCLUDED
#include <clang-c/CXCompilationDatabase.h>
#include <clang-c/Index.h>
#include <boost/noncopyable.hpp>
#include <memory>
#include <type_traits> // remove_pointer_t
#include <vector>
namespace synth {
class CgTokensHandle {
public:
CgTokensHandle(CXToken* data, unsigned ntokens, CXTranslationUnit tu_)
: m_data(data), m_ntokens(ntokens), m_tu(tu_)
{}
~CgTokensHandle() { destroy(); }
CgTokensHandle(CgTokensHandle&& other)
: m_data(other.m_data)
, m_ntokens(other.m_ntokens)
, m_tu(other.m_tu)
{
other.release();
}
CgTokensHandle& operator= (CgTokensHandle&& other)
{
destroy();
m_data = other.m_data;
m_ntokens = other.m_ntokens;
m_tu = other.m_tu;
other.release();
return *this;
}
CXTranslationUnit tu() const { return m_tu; }
unsigned size() const { return m_ntokens; }
CXToken* tokens() { return m_data; }
private:
void destroy()
{
if (m_data)
clang_disposeTokens(m_tu, m_data, m_ntokens);
}
void release()
{
m_ntokens = 0;
m_data = nullptr;
}
CXToken* m_data;
unsigned m_ntokens;
CXTranslationUnit m_tu;
};
#define SYNTH_DEF_DELETER(n, t, f) \
struct DeleterFor##n { \
void operator() (t v) const { f(v); } \
};
#define SYNTH_DEF_HANDLE(n, t, delf) \
SYNTH_DEF_DELETER(n, t, delf) \
using n = std::unique_ptr< \
std::remove_pointer_t<t>, DeleterFor##n>;
SYNTH_DEF_HANDLE(CgIdxHandle, CXIndex, clang_disposeIndex)
SYNTH_DEF_HANDLE(CgTuHandle, CXTranslationUnit, clang_disposeTranslationUnit)
SYNTH_DEF_HANDLE(
CgDbHandle, CXCompilationDatabase, clang_CompilationDatabase_dispose)
SYNTH_DEF_HANDLE(
CgCmdsHandle, CXCompileCommands, clang_CompileCommands_dispose)
SYNTH_DEF_HANDLE(CgSourceRangesHandle, CXSourceRangeList*, clang_disposeSourceRangeList)
} // namespace synth
#endif // SYNTH_CGWRAPPERS_HPP_INCLUDED