#include <tuple>
#include <iostream>
#include <my/disguise>
#include <clang-c/Index.h>
#include <boost/filesystem.hpp>
namespace fs = boost::filesystem;
using unique_index = my::disguise::unique<CXIndex, RELEASER(clang_disposeIndex)>;
using unique_translation_unit = my::disguise::unique<CXTranslationUnit, RELEASER(clang_disposeTranslationUnit)>;
using unique_string = my::disguise::unique<CXString, RELEASER(clang_disposeString)>;
int main()
{
const unique_index index { clang_createIndex(1, 0) };
if (!index)
{
std::cerr << "failed creating index" << std::endl;
return 1;
}
const unique_translation_unit mickey
{
clang_parseTranslationUnit(
index,
"mickey.cpp",
nullptr,
0,
0,
0,
CXTranslationUnit_PrecompiledPreamble)
};
if (!mickey)
{
std::cerr << "mickey parsing failed" << std::endl;
return 1;
}
std::cout << "Parsing mickey.cpp" << std::endl;
clang_reparseTranslationUnit(mickey, 0, nullptr, 0);
const unique_translation_unit minnie
{
clang_parseTranslationUnit(
index,
"minnie.cpp",
nullptr,
0,
0,
0,
CXTranslationUnit_PrecompiledPreamble)
};
if (!minnie)
{
std::cerr << "minnie parsing failed" << std::endl;
return 1;
}
std::cout << "Parsing minnie.cpp" << std::endl;
clang_reparseTranslationUnit(minnie, 0, nullptr, 0);
std::cout << "Done parsing" << std::endl;
CXFile file;
unsigned line;
unsigned column;
unsigned offset;
CXFile mickey_file = clang_getFile(mickey, "mickey.cpp");
CXSourceLocation mickey_location = clang_getLocation(mickey, mickey_file, 6, 8);
CXCursor mickey_cursor = clang_getCursor(mickey, mickey_location);
CXCursor minnie_decl_cursor = clang_getCursorReferenced(mickey_cursor);
CXSourceLocation minnie_decl_location = clang_getCursorLocation(minnie_decl_cursor);
clang_getExpansionLocation(minnie_decl_location, &file, &line, &column, &offset);
fs::path minnie_decl_file_name(fs::canonical(clang_getCString(unique_string(clang_getFileName(file)))));
std::cout << minnie_decl_file_name << " " << line << " " << column << std::endl;
CXCursor minnie_cursor = clang_getTranslationUnitCursor(minnie);
using ClientData = std::tuple<CXCursor &, const CXCursorVisitor &, const std::string &, const size_t>;
CXCursor minnie_def_cursor = clang_getNullCursor();
CXCursorVisitor minnie_visitor = [](CXCursor cursor, CXCursor parent, CXClientData client_data) -> CXChildVisitResult
{
CXCursor &minnie_def_cursor = std::get<0>(*static_cast<ClientData *>(client_data));
const CXCursorVisitor &minnie_visitor = std::get<1>(*static_cast<ClientData *>(client_data));
const std::string &minnie_decl_usr = std::get<2>(*static_cast<ClientData *>(client_data));
const size_t depth = std::get<3>(*static_cast<ClientData *>(client_data));
static size_t current_depth = 0;
if(clang_isDeclaration(clang_getCursorKind(cursor)))
{
if(minnie_decl_usr == clang_getCString(unique_string(clang_getCursorUSR(cursor))))
{
minnie_def_cursor = cursor;
return CXChildVisit_Break;
}
if(current_depth < depth)
{
++current_depth;
clang_visitChildren(cursor, minnie_visitor, client_data);
--current_depth;
}
}
return CXChildVisit_Continue;
};
std::string minnie_decl_usr(clang_getCString(unique_string(clang_getCursorUSR(minnie_decl_cursor))));
ClientData client_data(minnie_def_cursor, minnie_visitor, minnie_decl_usr, 10);
clang_visitChildren(minnie_cursor, minnie_visitor, &client_data);
if(!clang_Cursor_isNull(minnie_def_cursor))
{
minnie_def_cursor = clang_getCursorDefinition(minnie_def_cursor);
if(!clang_Cursor_isNull(minnie_def_cursor))
{
CXSourceLocation minnie_def_location = clang_getCursorLocation(minnie_def_cursor);
clang_getExpansionLocation(minnie_def_location, &file, &line, &column, &offset);
fs::path minnie_def_file_name(fs::canonical(clang_getCString(unique_string(clang_getFileName(file)))));
std::cout << minnie_def_file_name << " " << line << " " << column << std::endl;
}
}
return 0;
}