funning@funning-PC:~/workspace/workspace/recode/gg/TestApp$ tree
.
├── CMakeLists.txt
├── FindLibClang.cmake
├── main.cpp
├── modela.cpp
└── modela.hpp
if (NOT CLANG_ROOT)
set(CLANG_ROOT $ENV{CLANG_ROOT})
endif ()
if (NOT LLVM_CONFIG)
set(LLVM_CONFIG $ENV{LLVM_CONFIG})
if (NOT LLVM_CONFIG)
set(llvm_config_names llvm-config)
foreach(minor RANGE 9 1)
list(APPEND llvm_config_names "llvm-config3${minor}" "llvm-config-3.${minor}" "llvm-config-mp-3.${minor}")
endforeach ()
find_program(LLVM_CONFIG NAMES ${llvm_config_names})
endif ()
endif ()
if (LLVM_CONFIG)
message(STATUS "llvm-config found at: ${LLVM_CONFIG}")
else ()
message(FATAL_ERROR "Could NOT find llvm-config executable.")
endif ()
if (NOT EXISTS ${CLANG_INCLUDEDIR})
execute_process(COMMAND ${LLVM_CONFIG} --includedir OUTPUT_VARIABLE CLANG_INCLUDEDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
if (NOT EXISTS ${CLANG_INCLUDEDIR})
message(FATAL_ERROR "Could NOT find clang includedir. You can fix this by setting CLANG_INCLUDEDIR in your shell or as a cmake variable.")
endif ()
endif ()
if (NOT EXISTS ${CLANG_LIBDIR})
execute_process(COMMAND ${LLVM_CONFIG} --libdir OUTPUT_VARIABLE CLANG_LIBDIR OUTPUT_STRIP_TRAILING_WHITESPACE)
if (NOT EXISTS ${CLANG_LIBDIR})
message(FATAL_ERROR "Could NOT find clang libdir. You can fix this by setting CLANG_LIBDIR in your shell or as a cmake variable.")
endif ()
endif ()
if (NOT CLANG_LIBS)
find_library(CLANG_LIB_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT NAMES clang libclang ${CLANG_ROOT}/lib ${CLANG_LIBDIR} NO_DEFAULT_PATH)
if (NOT EXISTS ${CLANG_CLANG_LIB_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT})
find_library(CLANG_LIBS NAMES clang libclang)
if (NOT EXISTS ${CLANG_LIBS})
if (MSVC)
set (CLANG_LIBS "${CLANG_LIBDIR}/libclang.lib")
else()
set (CLANG_LIBS "-L${CLANG_LIBDIR}" "-lclang" "-Wl,-rpath,${CLANG_LIBDIR}")
endif()
endif ()
else ()
set(CLANG_LIBS "${CLANG_LIB_HACK_CMAKECACHE_DOT_TEXT_BULLSHIT}")
endif ()
endif ()
execute_process(COMMAND ${LLVM_CONFIG} --version OUTPUT_VARIABLE CLANG_VERSION OUTPUT_STRIP_TRAILING_WHITESPACE)
message("-- Using Clang ${CLANG_VERSION} from ${CLANG_LIBDIR} with LIBS ${CLANG_LIBS} and CXXFLAGS ${CLANG_CXXFLAGS}")
cmake_minimum_required(VERSION 2.8)
set(CMAKE_VERBOSE_MAKEFILE ON)
project(untitled2)
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}")
find_package(LibClang REQUIRED)
include_directories(${CLANG_INCLUDEDIR})
add_executable(${PROJECT_NAME} main.cpp modela.hpp modela.cpp)
target_link_libraries(${PROJECT_NAME} ${CLANG_LIBS})
#include
#include
#include
using namespace std;
ostream& operator<<(ostream& stream, const CXString& str)
{
stream << clang_getCString(str);
clang_disposeString(str);
return stream;
}
typedef struct{
CXFile file;
CXTranslationUnit unit;
}VisitData;
CXChildVisitResult printVisitChildren(CXCursor current, CXCursor parent, CXClientData client_data)
{
auto iData = (VisitData*)(client_data);
CXFile visitFile;
unsigned int line;
unsigned int col;
unsigned int offset;
clang_getSpellingLocation(clang_getCursorLocation(current), &visitFile, &line, &col, &offset);
auto srcCursor = clang_getCursor(iData->unit, clang_getCursorLocation(current));
CXFile srcFile;
unsigned int srcLine;
unsigned int srcCol;
unsigned int srcOffset;
clang_getSpellingLocation(clang_getCursorLocation(srcCursor), &srcFile, &srcLine, &srcCol, &srcOffset);
std::set filterSet;
filterSet.insert(CXCursorKind::CXCursor_StructDecl);
filterSet.insert(CXCursorKind::CXCursor_UnionDecl);
filterSet.insert(CXCursorKind::CXCursor_ClassDecl);
filterSet.insert(CXCursorKind::CXCursor_EnumDecl);
filterSet.insert(CXCursorKind::CXCursor_FieldDecl);
filterSet.insert(CXCursorKind::CXCursor_EnumConstantDecl);
filterSet.insert(CXCursorKind::CXCursor_FunctionDecl);
filterSet.insert(CXCursorKind::CXCursor_VarDecl);
filterSet.insert(CXCursorKind::CXCursor_ParmDecl);
filterSet.insert(CXCursorKind::CXCursor_TypedefDecl);
filterSet.insert(CXCursorKind::CXCursor_CXXMethod);
filterSet.insert(CXCursorKind::CXCursor_Constructor);
filterSet.insert(CXCursorKind::CXCursor_Destructor);
if(filterSet.end() != filterSet.find(clang_getCursorKind(current))) {
std::cout << "SourceFile: " << clang_getFileName(iData->file) << "\n"
<< " range.begin:" << clang_getCursorExtent(srcCursor).begin_int_data << "\n"
<< " range.end:" << clang_getCursorExtent(srcCursor).begin_int_data << "\n"
<< " SourceCursor: " << clang_getCursorSpelling(srcCursor) << "\n"
<< " Kind: " << clang_getCursorKindSpelling(clang_getCursorKind(srcCursor)) << "\n"
<< " Type: " << clang_getTypeSpelling(clang_getCursorType(srcCursor)) << "\n"
<< " FileName: " << clang_getFileName(srcFile) << "\n"
<< " Line: " << srcLine << "\n"
<< " colunm: " << srcCol << "\n"
<< " offset: " << srcOffset << "\n"
<< "Location: \n"
<< " Cursor: " << clang_getCursorSpelling(current) << "\n"
<< " Kind: " << clang_getCursorKindSpelling(clang_getCursorKind(current)) << "\n"
<< " Type: " << clang_getTypeSpelling(clang_getCursorType(current)) << "\n"
<< " FileName: " << clang_getFileName(visitFile) << "\n"
<< " Line: " << line << "\n"
<< " colunm: " << col << "\n"
<< " offset: " << offset << "\n"
<< std::endl;
}
return CXChildVisit_Recurse;
};
#include "modela.hpp"
int main()
{
Test2 test2;
const char *loadFile = "/home/funning/workspace/workspace/recode/gg/TestApp/modela.cpp";
CXIndex index = clang_createIndex(0, 0);
CXTranslationUnit unit = clang_parseTranslationUnit(
index,
loadFile, nullptr, 0,
nullptr, 0,
CXTranslationUnit_None);
if (unit == nullptr) {
cerr << "Unable to parse translation unit. Quitting." << endl;
exit(-1);
}
VisitData data;
data.file = clang_getFile(unit, loadFile);
data.unit = unit;
clang_visitChildren(clang_getTranslationUnitCursor(unit), printVisitChildren, &data);
clang_disposeTranslationUnit(unit);
clang_disposeIndex(index);
}
注:main函数中路径需要替换成自己的源码文件路径。
#ifndef MODELA_H
#define MODELA_H
#include
union unionTest
{
int a;
char b;
};
enum {
One,
Two
};
class Test
{
char Pri_M_T1 = 'c';
public:
Test(){}
~Test(){}
virtual void virtualFoo();
void foo();
inline void inlineFoo(){}
};
class Test2 : public Test
{
char PM_M_T2;
public:
Test2(){}
};
void foo();
#endif MODELA_H
#include "modela.hpp"
void Test::virtualFoo(){}
void Test::foo(){}
void foo()
{
std::cout << __FUNCTION__ <
SourceFile: /home/funning/workspace/workspace/recode/gg/TestApp/modela.cpp
range.begin:1830468
range.end:1830468
SourceCursor: __sb
Kind: VarDecl
Type: __streambuf_type *
FileName: /../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/istream.tcc
Line: 1033
colunm: 25
offset: 28342
Location:
Cursor: __sb
Kind: VarDecl
Type: __streambuf_type *
FileName: /../lib/gcc/x86_64-linux-gnu/8/../../../../include/c++/8/bits/istream.tcc
Line: 1033
colunm: 25
offset: 28342