~/Documentos/pendrive/home/francisco/Projetos/samples/clang-hacking/lab.cpp

#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;

}