Skip to content

Instantly share code, notes, and snippets.

@jeaye

jeaye/0_foo.cpp Secret

Last active August 29, 2015 14:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jeaye/243d8b992f799de6ecf0 to your computer and use it in GitHub Desktop.
Save jeaye/243d8b992f799de6ecf0 to your computer and use it in GitHub Desktop.
struct foo
{
int num{ 42 };
int age{ num };
};
$ clang++ -c -std=c++11 -Xclang -ast-dump test/simple.cpp
TranslationUnitDecl 0x1e03f30 <<invalid sloc>> <invalid sloc>
|-TypedefDecl 0x1e04470 <<invalid sloc>> <invalid sloc> implicit __int128_t '__int128'
|-TypedefDecl 0x1e044d0 <<invalid sloc>> <invalid sloc> implicit __uint128_t 'unsigned __int128'
|-TypedefDecl 0x1e04890 <<invalid sloc>> <invalid sloc> implicit __builtin_va_list '__va_list_tag [1]'
`-CXXRecordDecl 0x1e048e0 <test/simple.cpp:1:1, line:5:1> line:1:8 struct foo definition
|-CXXRecordDecl 0x1e049f0 <col:1, col:8> col:8 implicit struct foo
|-FieldDecl 0x1e04a90 <line:3:3, col:15> col:7 referenced num 'int'
| `-InitListExpr 0x1e04bd0 <col:10, col:15> 'int'
| `-IntegerLiteral 0x1e04b68 <col:12> 'int' 42
`-FieldDecl 0x1e04af0 <line:4:3, col:16> col:7 age 'int'
`-InitListExpr 0x1e47ff8 <col:10, col:16> 'int'
`-ImplicitCastExpr 0x1e48038 <col:12> 'int' <LValueToRValue>
`-MemberExpr 0x1e04c30 <col:12> 'int' lvalue ->num 0x1e04a90
`-CXXThisExpr 0x1e04c18 <col:12> 'struct foo *' this
#include <string>
#include <vector>
#include <sstream>
#include <algorithm>
#include <stdexcept>
#include <fstream>
#include <iostream>
#include <array>
#include <clang-c/Index.h>
template <typename T, typename... Ts>
std::array<std::decay_t<T>, sizeof...(Ts) + 1> make_array(T &&t, Ts &&... ts)
{ return { std::forward<T>(t), std::forward<Ts>(ts)... }; }
size_t get_filesize(std::string const &file)
{
std::ifstream ifs{ file };
if(!ifs.is_open())
{ throw std::runtime_error{ "failed to open " + file }; }
ifs.seekg(0, std::ios::end);
return ifs.tellg();
}
CXSourceRange get_filerange(CXTranslationUnit const &tu, std::string const &filename)
{
CXFile const file{ clang_getFile(tu, filename.c_str()) };
size_t const size{ get_filesize(filename.c_str()) };
CXSourceLocation const top(clang_getLocationForOffset(tu, file, 0));
CXSourceLocation const bottom(clang_getLocationForOffset(tu, file, size));
if(clang_equalLocations(top, clang_getNullLocation()) ||
clang_equalLocations(bottom, clang_getNullLocation()))
{ throw std::runtime_error{ "cannot retrieve location" }; }
CXSourceRange const range(clang_getRange(top, bottom));
if(clang_Range_isNull(range))
{ throw std::runtime_error{ "cannot retrieve range" }; }
return range;
}
CXChildVisitResult visit(CXCursor const cursor, CXCursor const parent,
CXClientData const)
{
auto const cursor_kind(cursor.kind);
auto const cursor_type(clang_getCursorType(cursor).kind);
auto const spell(clang_getCursorSpelling(cursor));
auto const loc(clang_getCursorLocation(cursor));
auto const range(clang_getCursorExtent(cursor));
auto const start(clang_getRangeStart(range));
auto const end(clang_getRangeEnd(range));
CXCursor const null_cursor(clang_getNullCursor());
CXSourceLocation const null_location(clang_getNullLocation());
CXFile cxfile;
unsigned start_line{}, start_col{}, start_offset{};
unsigned end_line{}, end_col{}, end_offset{};
clang_getSpellingLocation(start, &cxfile, &start_line, &start_col, &start_offset);
clang_getSpellingLocation(end, &cxfile, &end_line, &end_col, &end_offset);
std::cout << clang_getCString(spell) << ", ";
std::cout << start_line << ":" << start_col << " -> "
<< end_line << ":" << end_col << ", ";
std::cout <<
clang_getCString(clang_getCursorKindSpelling(clang_getCursorKind(cursor)))
<< ", ";
std::cout <<
clang_getCString(clang_getTypeKindSpelling(clang_getCursorType(cursor).kind))
<< ", ";
std::cout <<
clang_getCString(clang_getCursorDisplayName(cursor))
<< std::endl;
return CXChildVisit_Recurse;
}
int main()
{
auto const args(make_array("-I/usr/include", "-I.", "-std=c++11"));
std::string const filename{ "foo.cpp" };
CXIndex const index{ clang_createIndex(true, true) };
CXTranslationUnit const tu
{ clang_parseTranslationUnit(index, filename.c_str(),
args.data(), args.size(), nullptr, 0, CXTranslationUnit_None) };
clang_visitChildren(clang_getTranslationUnitCursor(tu), &visit, nullptr);
clang_disposeTranslationUnit(tu);
clang_disposeIndex(index);
}
$ clang++ -std=c++1y -stdlib=libc++ main.cpp -lc++abi -lclang
$ ./a.out
foo, 1:1 -> 5:2, StructDecl, Record, foo
num, 3:3 -> 3:16, FieldDecl, Int, num
age, 4:3 -> 4:17, FieldDecl, Int, age
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment