Skip to content

Commit 3845099

Browse files
committed
libclang_wrapper
1 parent 049e4f1 commit 3845099

File tree

14 files changed

+500
-244
lines changed

14 files changed

+500
-244
lines changed

x/libclang_wrapper/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
build/

x/libclang_wrapper/CMakeLists.txt

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
cmake_minimum_required(VERSION 2.8)
2+
project(IRONY)
3+
4+
set (CMAKE_C_COMPILER "clang")
5+
set (CMAKE_CXX_COMPILER "clang++")
6+
set (CMAKE_EXPORT_COMPILE_COMMANDS ON)
7+
8+
if (CMAKE_SOURCE_DIR STREQUAL CMAKE_BINARY_DIR AND NOT MSVC_IDE)
9+
message(FATAL_ERROR "In-source builds are not allowed.")
10+
endif()
11+
12+
set (CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake" ${CMAKE_MODULE_PATH})
13+
14+
# libclang in non standard locations can cause some troubles.
15+
option(USE_RPATH "Enable rpath for shared libraries (such as libclang.so)." OFF)
16+
17+
if (USE_RPATH)
18+
set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE)
19+
endif()
20+
21+
if (CMAKE_COMPILER_IS_GNUCXX OR CMAKE_COMPILER_IS_CLANGCXX)
22+
include(CheckCXXCompilerFlag)
23+
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wextra -Wall -Wshadow -std=c++11 -fno-rtti -fno-exceptions -O3")
24+
25+
if (${CMAKE_GENERATOR} MATCHES "Ninja")
26+
check_cxx_compiler_flag("-fcolor-diagnostics" HAS_FCOLOR_DIAGNOSTICS_FLAG)
27+
if (HAS_FCOLOR_DIAGNOSTICS_FLAG)
28+
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fcolor-diagnostics")
29+
endif()
30+
endif ()
31+
endif ()
32+
33+
set(LLVM_SUFFIX "-3.4")
34+
find_package(Llvm REQUIRED)
35+
36+
include_directories(${LLVM_INCLUDE_DIR})
37+
38+
add_definitions("-O3 -fno-rtti -fno-exceptions -Wextra -Wno-unused-parameter -std=c++11")
39+
add_definitions("${LLVM_CFLAGS}")
40+
if(UNIX)
41+
add_definitions("-DLLVM_ON_UNIX")
42+
endif()
43+
include(LLVMTools)
44+
link_directories(${LLVM_LIBRARY_DIR})
45+
46+
set(BASE_LIBS pthread m dl ncurses)
47+
set(LLVM_BASIC_LIBS LLVMIRReader LLVMAsmParser LLVMBitWriter LLVMLinker LLVMTransformUtils LLVMipa LLVMAnalysis LLVMTarget LLVMMC LLVMBitReader LLVMCore LLVMSupport)
48+
set(CLANG_BASIC_LIBS clang clangFrontend clangFrontendTool clangDriver clangSerialization clangCodeGen clangParse clangSema clangEdit clangAnalysis clangAST clangLex clangBasic clangRewriteCore clangRewriteFrontend clangStaticAnalyzerFrontend clangStaticAnalyzerCheckers clangStaticAnalyzerCore clangARCMigrate)
49+
50+
file(GLOB TU *.cc)
51+
add_executable(libclang_wrapper.out ${TU})
52+
target_link_libraries(libclang_wrapper.out ${LLVM_BASIC_LIBS} ${CLANG_BASIC_LIBS} ${BASE_LIBS})

x/libclang_wrapper/Common.cc

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#include "Common.hpp"
2+
3+
std::string getStrFromCXString(CXString const &cxstring) {
4+
std::string str;
5+
char const *cstr = clang_getCString(cxstring);
6+
if (cstr != nullptr) str = cstr;
7+
clang_disposeString(cxstring);
8+
return str;
9+
}

x/libclang_wrapper/Common.hpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
#ifndef COMMON_HPP
2+
#define COMMON_HPP
3+
4+
#include <string>
5+
#include <clang-c/Index.h>
6+
7+
#define WITH_COLOR(color, x) \
8+
{ \
9+
llvm::errs().changeColor(color); \
10+
x; \
11+
llvm::errs().resetColor(); \
12+
}
13+
14+
std::string getStrFromCXString(CXString const &cxstring);
15+
16+
#endif

x/libclang_wrapper/CursorCounter.cc

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "CursorCounter.hpp"
2+
#include "llvm/Support/raw_ostream.h"
3+
4+
extern char const *filename;
5+
6+
CXChildVisitResult statsVisitor(CXCursor cursor, CXCursor parent,
7+
CXClientData client_data) {
8+
CursorCounter &counter = CursorCounter::getInstance();
9+
std::string file = CursorCounter::getCursorFileName(cursor);
10+
if (file == filename) {
11+
counter.insert(cursor.kind);
12+
}
13+
return CXChildVisit_Recurse;
14+
}
15+
16+
bool CursorCounter::insert(CXCursorKind kind) {
17+
auto search = cursor2counter_.find(kind);
18+
if (search != cursor2counter_.end()) {
19+
++search->second;
20+
return true;
21+
}
22+
cursor2counter_.insert(std::make_pair(kind, 1));
23+
return false;
24+
}
25+
26+
std::string CursorCounter::getCursorFileName(CXCursor cursor) {
27+
CXFile file;
28+
clang_getSpellingLocation(clang_getCursorLocation(cursor), &file, nullptr,
29+
nullptr, nullptr);
30+
CXString fileCXStr = clang_getFileName(file);
31+
return getStrFromCXString(fileCXStr);
32+
}
33+
34+
void CursorCounter::visit(CXTranslationUnit const &TU) {
35+
clang_visitChildren(clang_getTranslationUnitCursor(TU), statsVisitor,
36+
nullptr);
37+
}
38+
39+
void CursorCounter::dump() {
40+
for (auto const &ele : cursor2counter_) {
41+
CXString cursorCXStr = clang_getCursorKindSpelling(ele.first);
42+
llvm::errs() << getStrFromCXString(cursorCXStr) << ": " << ele.second
43+
<< "\n";
44+
}
45+
}

x/libclang_wrapper/CursorCounter.hpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#ifndef CURSORCOUNTER_HPP
2+
#define CURSORCOUNTER_HPP
3+
4+
#include "Common.hpp"
5+
#include <map>
6+
7+
class CursorCounter {
8+
std::string filename_;
9+
typedef std::map<CXCursorKind, unsigned> CursorCounterMap;
10+
CursorCounterMap cursor2counter_;
11+
CursorCounter() {}
12+
CursorCounter(CursorCounter const&) = delete;
13+
CursorCounter& operator=(CursorCounter const&) = delete;
14+
15+
public:
16+
static CursorCounter& getInstance(void) {
17+
static CursorCounter counter;
18+
return counter;
19+
}
20+
bool insert(CXCursorKind kind);
21+
static std::string getCursorFileName(CXCursor cursor);
22+
void visit(CXTranslationUnit const& TU);
23+
void dump();
24+
};
25+
26+
#endif

x/libclang_wrapper/CursorInfo.cc

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
#include "CursorInfo.hpp"
2+
#include "CursorCounter.hpp"
3+
#include "llvm/Support/raw_ostream.h"
4+
5+
using namespace llvm;
6+
7+
LocPoint LocPoint::getLocPoint(
8+
CXSourceLocation location,
9+
std::function<void(CXSourceLocation, CXFile *, unsigned *, unsigned *,
10+
unsigned *)> genenerator) {
11+
CXFile file;
12+
unsigned line, column, offset;
13+
genenerator(location, &file, &line, &column, &offset);
14+
CXString fileCXStr = clang_getFileName(file);
15+
return LocPoint(getStrFromCXString(fileCXStr), line, column, offset);
16+
}
17+
18+
LocPoint LocPoint::getPresumedPoint(CXSourceLocation location) {
19+
CXString fileCXStr;
20+
unsigned line, column;
21+
unsigned offset = 0;
22+
clang_getPresumedLocation(location, &fileCXStr, &line, &column);
23+
LocPoint presumed(getStrFromCXString(fileCXStr), line, column, offset);
24+
clang_disposeString(fileCXStr);
25+
return presumed;
26+
}
27+
28+
void LocPoint::dump() {
29+
errs() << filename_ << " [" << line_ << ", " << column_ << "]\n";
30+
}
31+
32+
CursorInfo CursorInfo::getCursorInfo(CXCursor cursor) {
33+
std::string &&cursorStr = getStrFromCXString(clang_getCursorSpelling(cursor));
34+
CXSourceLocation location = clang_getCursorLocation(cursor);
35+
LocPoint &&expandPoint =
36+
LocPoint::getLocPoint(location, clang_getExpansionLocation);
37+
LocPoint &&presumedPoint = LocPoint::getPresumedPoint(location);
38+
LocPoint &&instantiationPoint =
39+
LocPoint::getLocPoint(location, clang_getInstantiationLocation);
40+
LocPoint &&spellingPoint =
41+
LocPoint::getLocPoint(location, clang_getSpellingLocation);
42+
expandPoint.dump();
43+
presumedPoint.dump();
44+
instantiationPoint.dump();
45+
spellingPoint.dump();
46+
return CursorInfo(cursorStr, expandPoint, presumedPoint, instantiationPoint);
47+
}

x/libclang_wrapper/CursorInfo.hpp

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
#ifndef CURSORINFO_HPP
2+
#define CURSORINFO_HPP
3+
4+
#include <functional>
5+
6+
#include "Common.hpp"
7+
8+
class LocPoint {
9+
std::string filename_;
10+
unsigned line_, column_, offset_;
11+
12+
public:
13+
static LocPoint getLocPoint(
14+
CXSourceLocation location,
15+
std::function<void(CXSourceLocation, CXFile *, unsigned *, unsigned *,
16+
unsigned *)> genenerator);
17+
static LocPoint getPresumedPoint(CXSourceLocation location);
18+
LocPoint(std::string &&filename, unsigned line, unsigned column,
19+
unsigned offset = 0)
20+
: filename_(std::move(filename)),
21+
line_(line),
22+
column_(column),
23+
offset_(offset) {}
24+
void dump();
25+
LocPoint &operator=(LocPoint const &) = delete;
26+
};
27+
28+
class CursorInfo {
29+
std::string cursorStr_;
30+
LocPoint expand_, presumed_, instantantiation_;
31+
32+
public:
33+
static CursorInfo getCursorInfo(CXCursor cursor);
34+
CursorInfo(std::string const &cursorStr, LocPoint const &expand,
35+
LocPoint const &presumed, LocPoint const &instantantiation)
36+
: cursorStr_(std::move(cursorStr)),
37+
expand_(std::move(expand)),
38+
presumed_(std::move(presumed)),
39+
instantantiation_(std::move(instantantiation)) {}
40+
CursorInfo &operator=(CursorInfo const &) = delete;
41+
void dump();
42+
};
43+
44+
#endif

x/libclang_wrapper/cmake/Common.cmake

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
function(replace_compiler_option var old new)
2+
# Replaces a compiler option or switch `old' in `var' by `new'.
3+
# If `old' is not in `var', appends `new' to `var'.
4+
# Example: replace_compiler_option(CMAKE_CXX_FLAGS_RELEASE "-O3" "-O2")
5+
# If the option already is on the variable, don't add it:
6+
if( "${${var}}" MATCHES "(^| )${new}($| )" )
7+
set(n "")
8+
else()
9+
set(n "${new}")
10+
endif()
11+
if( "${${var}}" MATCHES "(^| )${old}($| )" )
12+
string( REGEX REPLACE "(^| )${old}($| )" " ${n} " ${var} "${${var}}" )
13+
else()
14+
set( ${var} "${${var}} ${n}" )
15+
endif()
16+
set( ${var} "${${var}}" PARENT_SCOPE )
17+
endfunction(replace_compiler_option)
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
# Find the native LLVM includes and library
2+
#
3+
# LLVM_INCLUDE_DIR - where to find llvm include files
4+
# LLVM_LIBRARY_DIR - where to find llvm libs
5+
# LLVM_CFLAGS - llvm compiler flags
6+
# LLVM_LDFLAGS - llvm linker flags
7+
# LLVM_MODULE_LIBS - list of llvm libs for working with modules.
8+
# LLVM_FOUND - True if llvm found.
9+
10+
find_program(LLVM_CONFIG_EXECUTABLE llvm-config${LLVM_SUFFIX})
11+
12+
if (NOT LLVM_CONFIG_EXECUTABLE)
13+
message(FATAL_ERROR "Could not find llvm-config")
14+
endif (NOT LLVM_CONFIG_EXECUTABLE)
15+
16+
execute_process(
17+
COMMAND ${LLVM_CONFIG_EXECUTABLE} --includedir
18+
OUTPUT_VARIABLE LLVM_INCLUDE_DIR
19+
OUTPUT_STRIP_TRAILING_WHITESPACE
20+
)
21+
22+
execute_process(
23+
COMMAND ${LLVM_CONFIG_EXECUTABLE} --libdir
24+
OUTPUT_VARIABLE LLVM_LIBRARY_DIR
25+
OUTPUT_STRIP_TRAILING_WHITESPACE
26+
)
27+
28+
execute_process(
29+
COMMAND ${LLVM_CONFIG_EXECUTABLE} --cflags
30+
OUTPUT_VARIABLE LLVM_CFLAGS
31+
OUTPUT_STRIP_TRAILING_WHITESPACE
32+
)
33+
34+
execute_process(
35+
COMMAND ${LLVM_CONFIG_EXECUTABLE} --ldflags
36+
OUTPUT_VARIABLE LLVM_LDFLAGS
37+
OUTPUT_STRIP_TRAILING_WHITESPACE
38+
)
39+
40+
execute_process(
41+
COMMAND ${LLVM_CONFIG_EXECUTABLE} --version
42+
OUTPUT_VARIABLE LLVM_VERSION
43+
OUTPUT_STRIP_TRAILING_WHITESPACE
44+
)
45+
STRING(REGEX MATCH "[0-9]+\\.[0-9]+" LLVM_VERSION ${LLVM_VERSION})
46+
47+
execute_process(
48+
COMMAND ${LLVM_CONFIG_EXECUTABLE} --bindir
49+
OUTPUT_VARIABLE LLVM_BINARY_DIR
50+
OUTPUT_STRIP_TRAILING_WHITESPACE
51+
)
52+
53+
include(Common)
54+
replace_compiler_option(LLVM_CFLAGS "-DNDEBUG" "-UNDEBUG")
55+
foreach(OPTLEVEL "-O" "-O0" "-O1" "O2" "-O3" "-O4" "-Os")
56+
replace_compiler_option(LLVM_CFLAGS ${OPTLEVEL} "")
57+
endforeach()
58+
59+
message(STATUS "LLVM-config version: ${LLVM_VERSION}")
60+
message(STATUS "LLVM lib dir: ${LLVM_LIBRARY_DIR}")
61+
message(STATUS "LLVM bin dir: ${LLVM_BINARY_DIR}")
62+
message(STATUS "LLVM compile flags: ${LLVM_CFLAGS}")
63+
# message(STATUS "LLVM include dir: ${LLVM_INCLUDE_DIR}")
64+
# message(STATUS "LLVM ldflags: ${LLVM_LDFLAGS}")

0 commit comments

Comments
 (0)