Skip to content

Commit

Permalink
Use clang+llvm C++ in cmake; parse args with clang driver
Browse files Browse the repository at this point in the history
  • Loading branch information
MaskRay committed May 13, 2018
1 parent 99e7c56 commit 224ba97
Show file tree
Hide file tree
Showing 7 changed files with 99 additions and 252 deletions.
31 changes: 8 additions & 23 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,12 @@ if(NOT SYSTEM_CLANG)
if(${CMAKE_CXX_COMPILER_ID} STREQUAL Clang AND CLANG_USE_BUNDLED_LIBC++)
message(STATUS "Using bundled libc++")
target_compile_options(ccls PRIVATE -nostdinc++ -cxx-isystem ${CLANG_ROOT}/include/c++/v1)
target_link_libraries(ccls PRIVATE -stdlib=libc++ -L${CLANG_ROOT}/lib -lc++experimental)
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
# Don't use -stdlib=libc++ because while ccls is linked with libc++, bundled clang+llvm require libstdc++
target_link_libraries(ccls PRIVATE -L${CLANG_ROOT}/lib c++ c++experimental c++abi)
else()
# FreeBSD uses system libcxxrt.a and does not need libc++abi.
target_link_libraries(ccls PRIVATE c++abi)
target_link_libraries(ccls PRIVATE -stdlib=libc++ -L${CLANG_ROOT}/lib c++experimental)
endif()
endif()

Expand All @@ -101,7 +103,11 @@ endif()

# See cmake/FindClang.cmake
find_package(Clang ${CLANG_VERSION} REQUIRED)
find_package(Curses REQUIRED)
target_link_libraries(ccls PRIVATE Clang::Clang)
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows)
target_link_libraries(ccls PRIVATE Clang::Clang ${CURSES_LIBRARIES})
endif()

# Enable threading support
set(THREADS_PREFER_PTHREAD_FLAG ON)
Expand Down Expand Up @@ -188,27 +194,6 @@ endif()
file(GLOB SOURCES src/*.cc src/*.h src/serializers/*.cc src/serializers/*.h
src/messages/*.h src/messages/*.cc)

if(Clang_FORMAT AND ${Clang_VERSION} STREQUAL 6.0.0)
add_custom_target(format
COMMAND ${Clang_FORMAT} -i ${SOURCES}
# .clang-format is located in the ccls root project dir
WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}
COMMENT "Running clang-format ...")
else()
# Set error message depending on which condition was false
if (NOT Clang_FORMAT)
set(Clang_FORMAT_ERROR "Error: clang-format executable not found")
elseif(NOT ${Clang_VERSION} STREQUAL 6.0.0)
set(Clang_FORMAT_ERROR "Error: clang-format version does not match \
6.0.0. Due to differences in clang-format output between versions we only \
support clang-format 6.0.0")
endif()

add_custom_target(format
COMMAND ${CMAKE_COMMAND} -E cmake_echo_color --red --bold
${Clang_FORMAT_ERROR})
endif()

### Sources

target_sources(ccls PRIVATE third_party/siphash.cc)
Expand Down
60 changes: 19 additions & 41 deletions cmake/FindClang.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#
# Clang_FOUND - True if headers and requested libraries were found
# Clang_EXECUTABLE - Clang executable
# Clang_FORMAT - Clang-format executable
# Clang_RESOURCE_DIR - Clang resource directory
# Clang_VERSION - Clang version as reported by Clang executable
#
Expand All @@ -19,7 +18,6 @@
# This module reads hints about which libraries to look for and where to find
# them from the following variables::
#
# CLANG_CXX - Search for and add Clang C++ libraries
# CLANG_ROOT - If set, only look for Clang components in CLANG_ROOT
#
# Example to link against Clang target::
Expand All @@ -41,6 +39,11 @@ macro(_Clang_find_library VAR NAME)
endif()
endmacro()

macro(_Clang_find_add_library NAME)
_Clang_find_library(${NAME}_LIBRARY ${NAME})
list(APPEND _Clang_LIBRARIES ${${NAME}_LIBRARY})
endmacro()

macro(_Clang_find_path VAR INCLUDE_FILE)
if (CLANG_ROOT)
find_path(${VAR} ${INCLUDE_FILE}
Expand All @@ -59,45 +62,22 @@ macro(_Clang_find_program VAR NAME)
endif()
endmacro()

# Macro to avoid duplicating logic for each Clang C++ library
macro(_Clang_find_and_add_cxx_lib NAME INCLUDE_FILE)
# Find library
_Clang_find_library(Clang_${NAME}_LIBRARY ${NAME})
list(APPEND _Clang_REQUIRED_VARS Clang_${NAME}_LIBRARY)
list(APPEND _Clang_CXX_LIBRARIES ${Clang_${NAME}_LIBRARY})

# Find corresponding include directory
_Clang_find_path(Clang_${NAME}_INCLUDE_DIR ${INCLUDE_FILE})
list(APPEND _Clang_REQUIRED_VARS Clang_${NAME}_INCLUDE_DIR)
list(APPEND _Clang_CXX_INCLUDE_DIRS ${Clang_${NAME}_INCLUDE_DIR})
endmacro()

### Start

set(_Clang_REQUIRED_VARS Clang_LIBRARY Clang_INCLUDE_DIR Clang_EXECUTABLE
Clang_RESOURCE_DIR Clang_VERSION)
Clang_RESOURCE_DIR Clang_VERSION
LLVM_INCLUDE_DIR LLVM_BUILD_INCLUDE_DIR)

_Clang_find_library(Clang_LIBRARY clang)
_Clang_find_add_library(clangDriver)
_Clang_find_add_library(LLVMOption)
_Clang_find_add_library(LLVMSupport)
_Clang_find_add_library(LLVMDemangle)
_Clang_find_path(Clang_INCLUDE_DIR clang-c/Index.h)
_Clang_find_path(Clang_BUILD_INCLUDE_DIR clang/Driver/Options.inc)
_Clang_find_path(LLVM_INCLUDE_DIR llvm/PassInfo.h)
_Clang_find_path(LLVM_BUILD_INCLUDE_DIR llvm/Config/llvm-config.h)

if(CLANG_CXX)
# The order is derived by topological sorting LINK_LIBS in
# clang/lib/*/CMakeLists.txt
_Clang_find_and_add_cxx_lib(clangFormat clang/Format/Format.h)
_Clang_find_and_add_cxx_lib(clangToolingCore clang/Tooling/Core/Diagnostic.h)
_Clang_find_and_add_cxx_lib(clangRewrite clang/Rewrite/Core/Rewriter.h)
_Clang_find_and_add_cxx_lib(clangAST clang/AST/AST.h)
_Clang_find_and_add_cxx_lib(clangLex clang/Lex/Lexer.h)
_Clang_find_and_add_cxx_lib(clangBasic clang/Basic/ABI.h)

# The order is derived from llvm-config --libs core
_Clang_find_and_add_cxx_lib(LLVMCore llvm/Pass.h)
_Clang_find_and_add_cxx_lib(LLVMBinaryFormat llvm/BinaryFormat/Dwarf.h)
_Clang_find_and_add_cxx_lib(LLVMSupport llvm/Support/Error.h)
_Clang_find_and_add_cxx_lib(LLVMDemangle llvm/Demangle/Demangle.h)
endif()

_Clang_find_program(Clang_FORMAT clang-format)
_Clang_find_program(Clang_EXECUTABLE clang)
if(Clang_EXECUTABLE)
# Find Clang resource directory with Clang executable
Expand Down Expand Up @@ -127,12 +107,10 @@ find_package_handle_standard_args(Clang
)

if(Clang_FOUND AND NOT TARGET Clang::Clang)
set(_Clang_LIBRARIES ${Clang_LIBRARY} ${_Clang_CXX_LIBRARIES})
set(_Clang_INCLUDE_DIRS ${Clang_INCLUDE_DIR} ${_Clang_CXX_INCLUDE_DIRS})
add_library(Clang::Clang UNKNOWN IMPORTED)
set_target_properties(Clang::Clang PROPERTIES
IMPORTED_LOCATION ${Clang_LIBRARY}
INTERFACE_INCLUDE_DIRECTORIES "${Clang_INCLUDE_DIR};${Clang_BUILD_INCLUDE_DIR};${LLVM_INCLUDE_DIR};${LLVM_BUILD_INCLUDE_DIR}")

add_library(Clang::Clang INTERFACE IMPORTED)
set_property(TARGET Clang::Clang PROPERTY
INTERFACE_LINK_LIBRARIES ${_Clang_LIBRARIES})
set_property(TARGET Clang::Clang PROPERTY
INTERFACE_INCLUDE_DIRECTORIES ${_Clang_INCLUDE_DIRS})
set_property(TARGET Clang::Clang PROPERTY INTERFACE_LINK_LIBRARIES ${_Clang_LIBRARIES})
endif()
3 changes: 2 additions & 1 deletion src/messages/initialize.cc
Original file line number Diff line number Diff line change
Expand Up @@ -517,7 +517,8 @@ struct Handler_Initialize : BaseMessageHandler<In_InitializeRequest> {
for (int i = 0; i < g_config->index.threads; i++) {
std::thread([=]() {
g_thread_id = i + 1;
SetThreadName("indexer" + std::to_string(i));
std::string name = "indexer" + std::to_string(i);
SetThreadName(name.c_str());
Indexer_Main(diag_engine, vfs, import_pipeline_status, project,
working_files, waiter);
}).detach();
Expand Down
9 changes: 3 additions & 6 deletions src/platform.h
Original file line number Diff line number Diff line change
@@ -1,20 +1,17 @@
#pragma once

#include <optional>
#include <string_view>

#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>

void PlatformInit();

std::string GetExecutablePath();
std::string NormalizePath(const std::string& path);

void SetThreadName(const std::string& thread_name);

std::optional<int64_t> GetLastModificationTime(const std::string& absolute_path);
void SetThreadName(const char* name);

// Free any unused memory and return it to the system.
void FreeUnusedMemory();
Expand Down
21 changes: 9 additions & 12 deletions src/platform_posix.cc
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#include <llvm/ADT/Twine.h>
#include <llvm/Support/Threading.h>

#if defined(__unix__) || defined(__APPLE__)
#include "platform.h"

#include "utils.h"

#include "loguru.hpp"
#include <loguru.hpp>

#include <pthread.h>
#if defined(__FreeBSD__)
Expand Down Expand Up @@ -155,17 +158,6 @@ std::string NormalizePath(const std::string& path) {
return resolved ? *resolved : path;
}

void SetThreadName(const std::string& thread_name) {
loguru::set_thread_name(thread_name.c_str());
#if defined(__APPLE__)
pthread_setname_np(thread_name.c_str());
#elif defined(__FreeBSD__) || defined(__OpenBSD__)
pthread_set_name_np(pthread_self(), thread_name.c_str());
#elif defined(__linux__)
pthread_setname_np(pthread_self(), thread_name.c_str());
#endif
}

void FreeUnusedMemory() {
#if defined(__GLIBC__)
malloc_trim(0);
Expand Down Expand Up @@ -225,3 +217,8 @@ std::string GetExternalCommandOutput(const std::vector<std::string>& command,
}

#endif

void SetThreadName(const char* name) {
loguru::set_thread_name(name);
llvm::set_thread_name(name);
}
30 changes: 0 additions & 30 deletions src/platform_win.cc
Original file line number Diff line number Diff line change
Expand Up @@ -49,36 +49,6 @@ std::string NormalizePath(const std::string& path) {
return result;
}

// See https://msdn.microsoft.com/en-us/library/xcb2z8hs.aspx
const DWORD MS_VC_EXCEPTION = 0x406D1388;
#pragma pack(push, 8)
typedef struct tagTHREADNAME_INFO {
DWORD dwType; // Must be 0x1000.
LPCSTR szName; // Pointer to name (in user addr space).
DWORD dwThreadID; // Thread ID (-1=caller thread).
DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)
void SetThreadName(const std::string& thread_name) {
loguru::set_thread_name(thread_name.c_str());

THREADNAME_INFO info;
info.dwType = 0x1000;
info.szName = thread_name.c_str();
info.dwThreadID = (DWORD)-1;
info.dwFlags = 0;

__try {
RaiseException(MS_VC_EXCEPTION, 0, sizeof(info) / sizeof(ULONG_PTR),
(ULONG_PTR*)&info);
#ifdef _MSC_VER
} __except (EXCEPTION_EXECUTE_HANDLER) {
#else
} catch (...) {
#endif
}
}

void FreeUnusedMemory() {}

// TODO Wait for debugger to attach
Expand Down
Loading

0 comments on commit 224ba97

Please sign in to comment.