Merge remote-tracking branch 'upstream/master'

This commit is contained in:
Yan Pas 2019-01-28 23:17:55 +03:00
commit d0fcb786f1
23 changed files with 67 additions and 396 deletions

View File

@ -15,7 +15,7 @@ install:
- 7z x llvm.tar - 7z x llvm.tar
- git submodule update --init --recursive - git submodule update --init --recursive
build_script: build_script:
- cmake -G"Visual Studio 15 2017 Win64" -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DSYSTEM_CLANG=ON -DCLANG_ROOT=C:\projects\ccls\llvm+clang-7.0.0-win64-msvc-release - cmake -G"Visual Studio 15 2017 Win64" -H. -Bbuild -DCMAKE_BUILD_TYPE=Release -DCMAKE_PREFIX_PATH=C:\projects\ccls\llvm+clang-7.0.0-win64-msvc-release
- cmake --build build --target ccls --config Release - cmake --build build --target ccls --config Release
artifacts: artifacts:

View File

@ -5,13 +5,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/)
include(DefaultCMakeBuildType) include(DefaultCMakeBuildType)
# Required Clang version # Required Clang version
set(CLANG_DOWNLOAD_LOCATION ${CMAKE_BINARY_DIR}
CACHE STRING "Downloaded Clang location")
option(SYSTEM_CLANG "Use system installation of Clang instead of \
downloading Clang" OFF)
option(ASAN "Compile with address sanitizers" OFF)
option(LLVM_ENABLE_RTTI "-fno-rtti if OFF. This should match LLVM libraries" OFF) option(LLVM_ENABLE_RTTI "-fno-rtti if OFF. This should match LLVM libraries" OFF)
option(CLANG_USE_BUNDLED_LIBC++ "Let Clang use bundled libc++" OFF)
option(USE_SHARED_LLVM "Link against libLLVM.so instead separate LLVM{Option,Support,...}" OFF) option(USE_SHARED_LLVM "Link against libLLVM.so instead separate LLVM{Option,Support,...}" OFF)
# Sources for the executable are specified at end of CMakeLists.txt # Sources for the executable are specified at end of CMakeLists.txt
@ -30,10 +24,7 @@ add_executable(ccls "")
# Enable C++17 (Required) # Enable C++17 (Required)
set_property(TARGET ccls PROPERTY CXX_STANDARD 17) set_property(TARGET ccls PROPERTY CXX_STANDARD 17)
set_property(TARGET ccls PROPERTY CXX_STANDARD_REQUIRED ON) set_property(TARGET ccls PROPERTY CXX_STANDARD_REQUIRED ON)
# Disable gnu extensions except for Cygwin which needs them to build properly
if(NOT CYGWIN)
set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF) set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF)
endif()
if(NOT LLVM_ENABLE_RTTI) if(NOT LLVM_ENABLE_RTTI)
# releases.llvm.org libraries are compiled with -fno-rtti # releases.llvm.org libraries are compiled with -fno-rtti
@ -76,43 +67,12 @@ else()
target_compile_options(ccls PRIVATE target_compile_options(ccls PRIVATE
$<$<CONFIG:Debug>:-fno-limit-debug-info>) $<$<CONFIG:Debug>:-fno-limit-debug-info>)
endif() endif()
if(ASAN)
target_compile_options(ccls PRIVATE -fsanitize=address,undefined)
# target_link_libraries also takes linker flags
target_link_libraries(ccls PRIVATE -fsanitize=address,undefined)
endif()
endif()
### Download Clang if required
if(NOT SYSTEM_CLANG)
message(STATUS "Using downloaded Clang")
include(DownloadAndExtractClang)
download_and_extract_clang(${CLANG_DOWNLOAD_LOCATION})
# Used by FindClang
set(CLANG_ROOT ${DOWNLOADED_CLANG_DIR})
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)
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++abi)
# FreeBSD defaults to -stdlib=libc++ and uses system libcxxrt.a
endif()
endif()
else()
message(STATUS "Using system Clang")
endif() endif()
### Libraries ### Libraries
# See cmake/FindClang.cmake # See cmake/FindClang.cmake
find_package(Clang 6.0.0) find_package(Clang 7.0.0)
target_link_libraries(ccls PRIVATE Clang::Clang) target_link_libraries(ccls PRIVATE Clang::Clang)
# Enable threading support # Enable threading support
@ -143,31 +103,6 @@ target_include_directories(ccls SYSTEM PRIVATE
install(TARGETS ccls RUNTIME DESTINATION bin) install(TARGETS ccls RUNTIME DESTINATION bin)
if(NOT SYSTEM_CLANG AND NOT ${CMAKE_SYSTEM_NAME} STREQUAL Windows)
if(${CMAKE_SYSTEM_NAME} MATCHES Linux|FreeBSD)
set_property(TARGET ccls APPEND PROPERTY
INSTALL_RPATH $ORIGIN/../lib)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
set_property(TARGET ccls APPEND PROPERTY
INSTALL_RPATH @loader_path/../lib)
endif()
file(GLOB LIBCLANG_PLUS_SYMLINKS
${DOWNLOADED_CLANG_DIR}/lib/libclang.[so,dylib]*)
install(FILES ${LIBCLANG_PLUS_SYMLINKS} DESTINATION lib)
endif()
# Allow running from build Windows by copying libclang.dll to build directory
if(NOT SYSTEM_CLANG AND ${CMAKE_SYSTEM_NAME} STREQUAL Windows)
add_custom_command(TARGET ccls
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy
${DOWNLOADED_CLANG_DIR}/bin/libclang.dll
$<TARGET_FILE_DIR:ccls>
COMMENT "Copying libclang.dll to build directory ...")
endif()
### Tools ### Tools
# We use glob here since source files are already manually added with # We use glob here since source files are already manually added with

View File

@ -1 +0,0 @@
74b197a3959b0408adf0824be01db8dddfa2f9a967f4085af3fad900ed5fdbf6

View File

@ -1 +0,0 @@
95ceb933ccf76e3ddaa536f41ab82c442bbac07cdea6f9fbf6e3b13cc1711255

View File

@ -1 +0,0 @@
b3ad93c3d69dfd528df9c5bb1a434367babb8f3baea47fbb99bf49f1b03c94ca

View File

@ -1 +0,0 @@
5c90e61b06d37270bc26edb305d7e498e2c7be22d99e0afd9f2274ef5458575a

View File

@ -1 +0,0 @@
69b85c833cd28ea04ce34002464f10a6ad9656dd2bba0f7133536a9927c660d2

View File

@ -1,52 +0,0 @@
# Downloads and extracts the 7-Zip MSI installer from https://www.7-zip.org/.
#
# Returns the extracted 7-Zip directory in DOWNLOADED_7ZIP_DIR
function(download_and_extract_7zip 7ZIP_DOWNLOAD_LOCATION)
set(7ZIP_VERSION 1801)
set(7ZIP_EXT .msi)
set(7ZIP_NAME 7z${7ZIP_VERSION}-x64)
set(7ZIP_FULL_NAME ${7ZIP_NAME}${7ZIP_EXT})
set(7ZIP_FILE ${7ZIP_DOWNLOAD_LOCATION}/${7ZIP_FULL_NAME})
set(7ZIP_EXTRACT_DIR ${7ZIP_DOWNLOAD_LOCATION}/${7ZIP_NAME})
set(7ZIP_URL https://www.7-zip.org/a/${7ZIP_FULL_NAME})
# Exit if 7-Zip is already downloaded and extracted
find_program(7ZIP_EXECUTABLE 7z NO_DEFAULT_PATH
PATHS ${7ZIP_EXTRACT_DIR}/Files/7-Zip)
if(7ZIP_EXECUTABLE)
message(STATUS "7-Zip already downloaded")
return()
endif()
message(STATUS "Downloading 7-Zip ${7ZIP_VERSION} (${7ZIP_URL}) ...")
file(DOWNLOAD ${7ZIP_URL} ${7ZIP_FILE})
find_program(MSIEXEC_EXECUTABLE msiexec)
if(NOT MSIEXEC_EXECUTABLE)
message(FATAL_ERROR "Unable to find msiexec (required to extract 7-Zip msi \
installer). Install 7-Zip yourself and make sure it is available in the path")
endif()
message(STATUS "Extracting downloaded 7-Zip ...")
# msiexec requires Windows path separators (\)
file(TO_NATIVE_PATH ${7ZIP_FILE} 7ZIP_FILE)
file(TO_NATIVE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR)
# msiexec with /a option allows extraction of msi installers without requiring
# admin privileges. We use this to extract the 7-Zip installer without
# requiring any actions from the user
execute_process(COMMAND ${MSIEXEC_EXECUTABLE} /a ${7ZIP_FILE} /qn
TARGETDIR=${7ZIP_EXTRACT_DIR}
WORKING_DIRECTORY ${7ZIP_DOWNLOAD_LOCATION}
OUTPUT_QUIET)
# Convert back to CMake separators (/) before returning
file(TO_CMAKE_PATH ${7ZIP_EXTRACT_DIR} 7ZIP_EXTRACT_DIR)
# Actual 7-Zip directory is nested inside the extract directory.
set(DOWNLOADED_7ZIP_DIR ${7ZIP_EXTRACT_DIR}/Files/7-Zip PARENT_SCOPE)
endfunction()

View File

@ -1,129 +0,0 @@
# Downloads and extracts the Clang archive for the current system from
# https://releases.llvm.org
#
# Returns the extracted Clang archive directory in DOWNLOADED_CLANG_DIR
#
# Downloads 7-Zip to extract Clang if it isn't available in the PATH
function(download_and_extract_clang CLANG_DOWNLOAD_LOCATION)
set(CLANG_VERSION 7.0.0)
set(CLANG_ARCHIVE_EXT .tar.xz)
if(${CMAKE_SYSTEM_NAME} STREQUAL Linux)
# Default to Ubuntu 16.04
set(CLANG_ARCHIVE_NAME
clang+llvm-${CLANG_VERSION}-x86_64-linux-gnu-ubuntu-16.04)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Darwin)
set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-x86_64-apple-darwin)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL Windows)
set(CLANG_ARCHIVE_NAME LLVM-${CLANG_VERSION}-win64)
set(CLANG_ARCHIVE_EXT .exe)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL FreeBSD)
set(CLANG_ARCHIVE_NAME clang+llvm-${CLANG_VERSION}-amd64-unknown-freebsd11)
endif()
set(CLANG_ARCHIVE_FULL_NAME ${CLANG_ARCHIVE_NAME}${CLANG_ARCHIVE_EXT})
set(CLANG_ARCHIVE_FILE ${CLANG_DOWNLOAD_LOCATION}/${CLANG_ARCHIVE_FULL_NAME})
set(CLANG_ARCHIVE_EXTRACT_DIR ${CLANG_DOWNLOAD_LOCATION}/${CLANG_ARCHIVE_NAME})
set(CLANG_ARCHIVE_URL
https://releases.llvm.org/${CLANG_VERSION}/${CLANG_ARCHIVE_FULL_NAME})
set(CLANG_ARCHIVE_HASH_FILE
${CMAKE_SOURCE_DIR}/clang_archive_hashes/${CLANG_ARCHIVE_FULL_NAME}.SHA256)
# Exit if Clang is already downloaded and extracted
set(CLANG_ROOT ${CLANG_ARCHIVE_EXTRACT_DIR})
find_package(Clang ${CLANG_VERSION} QUIET)
if(Clang_FOUND)
message(STATUS "Clang already downloaded")
set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE)
return()
endif()
if(NOT CLANG_ARCHIVE_NAME)
message(FATAL_ERROR "No Clang archive url specified for current platform \
(${CMAKE_SYSTEM_NAME}). Please file an issue to get it added.")
endif()
if(NOT EXISTS ${CLANG_ARCHIVE_HASH_FILE})
message(FATAL_ERROR "No SHA256 hash available for the current platform \
(${CMAKE_SYSTEM_NAME}) + clang version (${CLANG_VERSION}) combination. Please \
file an issue to get it added.")
endif()
# Download Clang archive
message(STATUS "Downloading Clang ${CLANG_VERSION} (${CLANG_ARCHIVE_URL}) ...")
file(DOWNLOAD ${CLANG_ARCHIVE_URL} ${CLANG_ARCHIVE_FILE}
STATUS CLANG_ARCHIVE_DOWNLOAD_RESULT)
# Abort if download failed
list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 0 ERROR_CODE)
if(${ERROR_CODE})
list(GET ${CLANG_ARCHIVE_DOWNLOAD_RESULT} 1 ERROR_STRING)
message(FATAL_ERROR ${ERROR_STRING})
endif()
# Retrieve expected hash from file and strip newline
file(READ ${CLANG_ARCHIVE_HASH_FILE} CLANG_ARCHIVE_EXPECTED_HASH)
string(STRIP ${CLANG_ARCHIVE_EXPECTED_HASH} CLANG_ARCHIVE_EXPECTED_HASH)
# Calculate actual hash
file(SHA256 ${CLANG_ARCHIVE_FILE} CLANG_ARCHIVE_HASH)
# Abort if hashes do not match
if(NOT ${CLANG_ARCHIVE_EXPECTED_HASH} STREQUAL ${CLANG_ARCHIVE_HASH})
message(FATAL_ERROR "SHA256 hash of downloaded Clang does not match \
expected hash. Remove the build directory and try running CMake again. If this \
keeps happening, file an issue to report the problem.")
endif()
if(${CLANG_ARCHIVE_EXT} STREQUAL .exe)
# Download and extract 7-zip if not found in PATH
find_program(7ZIP_EXECUTABLE 7z)
if(NOT 7ZIP_EXECUTABLE)
message(STATUS "7-Zip not found in PATH")
include(DownloadAndExtract7zip)
download_and_extract_7zip(${CLANG_DOWNLOAD_LOCATION})
find_program(7ZIP_EXECUTABLE
NAMES 7z
NO_DEFAULT_PATH
PATHS ${DOWNLOADED_7ZIP_DIR}
)
else()
message(STATUS "7-Zip found in PATH")
endif()
message(STATUS "Extracting downloaded Clang with 7-Zip ...")
# Avoid running the Clang installer by extracting the exe with 7-Zip
execute_process(
COMMAND ${7ZIP_EXECUTABLE} x
-o${CLANG_ARCHIVE_EXTRACT_DIR}
-xr!$PLUGINSDIR ${CLANG_ARCHIVE_FILE}
WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION}
OUTPUT_QUIET
)
elseif(${CLANG_ARCHIVE_EXT} STREQUAL .tar.xz)
message(STATUS "Extracting downloaded Clang with CMake built-in tar ...")
# CMake has builtin support for tar via the -E flag
execute_process(
COMMAND ${CMAKE_COMMAND} -E tar -xf ${CLANG_ARCHIVE_FILE}
# Specify working directory to allow running cmake from
# everywhere
# (example: cmake -H"$HOME/cquery" -B"$home/cquery/build")
WORKING_DIRECTORY ${CLANG_DOWNLOAD_LOCATION}
OUTPUT_QUIET
)
endif()
set(DOWNLOADED_CLANG_DIR ${CLANG_ARCHIVE_EXTRACT_DIR} PARENT_SCOPE)
endfunction()

View File

@ -72,7 +72,6 @@ _Clang_find_library(Clang_LIBRARY clangIndex)
_Clang_find_add_library(clangFormat) _Clang_find_add_library(clangFormat)
_Clang_find_add_library(clangTooling) _Clang_find_add_library(clangTooling)
# TODO Remove after dropping clang 6
_Clang_find_library(clangToolingInclusions_LIBRARY clangToolingInclusions) _Clang_find_library(clangToolingInclusions_LIBRARY clangToolingInclusions)
if (clangToolingInclusions_LIBRARY) if (clangToolingInclusions_LIBRARY)
list(APPEND _Clang_LIBRARIES ${clangToolingInclusions_LIBRARY}) list(APPEND _Clang_LIBRARIES ${clangToolingInclusions_LIBRARY})

View File

@ -156,7 +156,6 @@ const char *ClangBuiltinTypeName(int kind) {
return "double"; return "double";
case BuiltinType::LongDouble: case BuiltinType::LongDouble:
return "long double"; return "long double";
#if LLVM_VERSION_MAJOR >= 7
case BuiltinType::ShortAccum: case BuiltinType::ShortAccum:
return "short _Accum"; return "short _Accum";
case BuiltinType::Accum: case BuiltinType::Accum:
@ -205,7 +204,6 @@ const char *ClangBuiltinTypeName(int kind) {
return "_Sat unsigned _Fract"; return "_Sat unsigned _Fract";
case BuiltinType::BuiltinType::SatULongFract: case BuiltinType::BuiltinType::SatULongFract:
return "_Sat unsigned long _Fract"; return "_Sat unsigned long _Fract";
#endif
case BuiltinType::Float16: case BuiltinType::Float16:
return "_Float16"; return "_Float16";
case BuiltinType::Float128: case BuiltinType::Float128:
@ -213,10 +211,8 @@ const char *ClangBuiltinTypeName(int kind) {
case BuiltinType::WChar_S: case BuiltinType::WChar_S:
case BuiltinType::WChar_U: case BuiltinType::WChar_U:
return "wchar_t"; return "wchar_t";
#if LLVM_VERSION_MAJOR >= 7
case BuiltinType::Char8: case BuiltinType::Char8:
return "char8_t"; return "char8_t";
#endif
case BuiltinType::Char16: case BuiltinType::Char16:
return "char16_t"; return "char16_t";
case BuiltinType::Char32: case BuiltinType::Char32:

View File

@ -593,11 +593,7 @@ public:
if (init) { if (init) {
SourceManager &SM = Ctx->getSourceManager(); SourceManager &SM = Ctx->getSourceManager();
const LangOptions &Lang = Ctx->getLangOpts(); const LangOptions &Lang = Ctx->getLangOpts();
SourceRange R = SM.getExpansionRange(init->getSourceRange()) SourceRange R = SM.getExpansionRange(init->getSourceRange()).getAsRange();
#if LLVM_VERSION_MAJOR >= 7
.getAsRange()
#endif
;
SourceLocation L = D->getLocation(); SourceLocation L = D->getLocation();
if (L.isMacroID() || !SM.isBeforeInTranslationUnit(L, R.getBegin())) if (L.isMacroID() || !SM.isBeforeInTranslationUnit(L, R.getBegin()))
return; return;
@ -688,41 +684,15 @@ public:
} }
bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles,
ArrayRef<index::SymbolRelation> Relations, ArrayRef<index::SymbolRelation> Relations,
#if LLVM_VERSION_MAJOR >= 7 SourceLocation Loc, ASTNodeInfo ASTNode) override {
SourceLocation Loc,
#else
FileID LocFID, unsigned LocOffset,
#endif
ASTNodeInfo ASTNode) override {
SourceManager &SM = Ctx->getSourceManager(); SourceManager &SM = Ctx->getSourceManager();
const LangOptions &Lang = Ctx->getLangOpts(); const LangOptions &Lang = Ctx->getLangOpts();
#if LLVM_VERSION_MAJOR < 7
SourceLocation Loc;
{
const SrcMgr::SLocEntry &Entry = SM.getSLocEntry(LocFID);
unsigned off = Entry.getOffset() + LocOffset;
if (!Entry.isFile())
off |= 1u << 31;
Loc = SourceLocation::getFromRawEncoding(off);
}
#else
FileID LocFID; FileID LocFID;
#endif
SourceLocation Spell = SM.getSpellingLoc(Loc); SourceLocation Spell = SM.getSpellingLoc(Loc);
const FileEntry *FE; const FileEntry *FE;
Range loc; Range loc;
#if LLVM_VERSION_MAJOR < 7
CharSourceRange R;
if (SM.isMacroArgExpansion(Loc))
R = CharSourceRange::getTokenRange(Spell);
else {
auto P = SM.getExpansionRange(Loc);
R = CharSourceRange::getTokenRange(P.first, P.second);
}
#else
auto R = SM.isMacroArgExpansion(Loc) ? CharSourceRange::getTokenRange(Spell) auto R = SM.isMacroArgExpansion(Loc) ? CharSourceRange::getTokenRange(Spell)
: SM.getExpansionRange(Loc); : SM.getExpansionRange(Loc);
#endif
loc = FromCharSourceRange(SM, Lang, R); loc = FromCharSourceRange(SM, Lang, R);
LocFID = SM.getFileID(R.getBegin()); LocFID = SM.getFileID(R.getBegin());
FE = SM.getFileEntryForID(LocFID); FE = SM.getFileEntryForID(LocFID);
@ -1085,12 +1055,8 @@ public:
StringRef Included, bool IsAngled, StringRef Included, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File, CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath, StringRef SearchPath, StringRef RelativePath,
const Module *Imported const Module *Imported,
#if LLVM_VERSION_MAJOR >= 7 SrcMgr::CharacteristicKind FileType) override {
,
SrcMgr::CharacteristicKind FileType
#endif
) override {
if (!File) if (!File)
return; return;
llvm::sys::fs::UniqueID UniqueID; llvm::sys::fs::UniqueID UniqueID;
@ -1283,9 +1249,7 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs,
IndexOpts.SystemSymbolFilter = IndexOpts.SystemSymbolFilter =
index::IndexingOptions::SystemSymbolFilterKind::All; index::IndexingOptions::SystemSymbolFilterKind::All;
IndexOpts.IndexFunctionLocals = true; IndexOpts.IndexFunctionLocals = true;
#if LLVM_VERSION_MAJOR >= 7
IndexOpts.IndexImplicitInstantiation = true; IndexOpts.IndexImplicitInstantiation = true;
#endif
std::unique_ptr<FrontendAction> Action = createIndexingAction( std::unique_ptr<FrontendAction> Action = createIndexingAction(
DataConsumer, IndexOpts, std::make_unique<IndexFrontendAction>(param)); DataConsumer, IndexOpts, std::make_unique<IndexFrontendAction>(param));

View File

@ -72,6 +72,7 @@ Message::~Message() {
std::lock_guard<std::mutex> lock(mtx); std::lock_guard<std::mutex> lock(mtx);
stream_ << '\n'; stream_ << '\n';
fputs(stream_.str().c_str(), file); fputs(stream_.str().c_str(), file);
fflush(file);
if (verbosity_ == Verbosity_FATAL) if (verbosity_ == Verbosity_FATAL)
abort(); abort();
} }

View File

@ -58,10 +58,10 @@ opt<std::string> opt_index("index",
value_desc("root"), cat(C)); value_desc("root"), cat(C));
list<std::string> opt_init("init", desc("extra initialization options in JSON"), list<std::string> opt_init("init", desc("extra initialization options in JSON"),
cat(C)); cat(C));
opt<std::string> opt_log_file("log-file", desc("log"), value_desc("filename"), opt<std::string> opt_log_file("log-file", desc("stderr or log file"),
value_desc("file"), init("stderr"), cat(C));
opt<bool> opt_log_file_append("log-file-append", desc("append to log file"),
cat(C)); cat(C));
opt<std::string> opt_log_file_append("log-file-append", desc("log"),
value_desc("filename"), cat(C));
void CloseLog() { fclose(ccls::log::file); } void CloseLog() { fclose(ccls::log::file); }
@ -95,14 +95,13 @@ int main(int argc, char **argv) {
bool language_server = true; bool language_server = true;
if (opt_log_file.size() || opt_log_file_append.size()) { if (opt_log_file.size()) {
ccls::log::file = opt_log_file.size() ccls::log::file =
? fopen(opt_log_file.c_str(), "wb") opt_log_file == "stderr"
: fopen(opt_log_file_append.c_str(), "ab"); ? stderr
: fopen(opt_log_file.c_str(), opt_log_file_append ? "ab" : "wb");
if (!ccls::log::file) { if (!ccls::log::file) {
fprintf( fprintf(stderr, "failed to open %s\n", opt_log_file.c_str());
stderr, "failed to open %s\n",
(opt_log_file.size() ? opt_log_file : opt_log_file_append).c_str());
return 2; return 2;
} }
setbuf(ccls::log::file, NULL); setbuf(ccls::log::file, NULL);

View File

@ -274,6 +274,8 @@ MessageHandler::FindOrFail(const std::string &path, ReplyOnce &reply,
} }
QueryFile *file = FindFile(path, out_file_id); QueryFile *file = FindFile(path, out_file_id);
if (!file) { if (!file) {
if (!overdue)
throw NotIndexed{path};
reply.Error(ErrorCode::InvalidRequest, "not indexed"); reply.Error(ErrorCode::InvalidRequest, "not indexed");
return {nullptr, nullptr}; return {nullptr, nullptr};
} }

View File

@ -436,7 +436,6 @@ public:
ls_items[j].label = ls_items[j].filterText; ls_items[j].label = ls_items[j].filterText;
} }
} }
#if LLVM_VERSION_MAJOR >= 7
for (const FixItHint &FixIt : R.FixIts) { for (const FixItHint &FixIt : R.FixIts) {
auto &AST = S.getASTContext(); auto &AST = S.getASTContext();
TextEdit ls_edit = TextEdit ls_edit =
@ -444,7 +443,6 @@ public:
for (size_t j = first_idx; j < ls_items.size(); j++) for (size_t j = first_idx; j < ls_items.size(); j++)
ls_items[j].additionalTextEdits.push_back(ls_edit); ls_items[j].additionalTextEdits.push_back(ls_edit);
} }
#endif
} }
} }
@ -474,9 +472,7 @@ void MessageHandler::textDocument_completion(CompletionParam &param,
clang::CodeCompleteOptions CCOpts; clang::CodeCompleteOptions CCOpts;
CCOpts.IncludeBriefComments = true; CCOpts.IncludeBriefComments = true;
CCOpts.IncludeCodePatterns = StringRef(buffer_line).ltrim().startswith("#"); CCOpts.IncludeCodePatterns = StringRef(buffer_line).ltrim().startswith("#");
#if LLVM_VERSION_MAJOR >= 7
CCOpts.IncludeFixIts = true; CCOpts.IncludeFixIts = true;
#endif
CCOpts.IncludeMacros = true; CCOpts.IncludeMacros = true;
if (param.context.triggerKind == CompletionTriggerKind::TriggerCharacter && if (param.context.triggerKind == CompletionTriggerKind::TriggerCharacter &&

View File

@ -65,7 +65,7 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam &param) {
void MessageHandler::textDocument_didSave(TextDocumentParam &param) { void MessageHandler::textDocument_didSave(TextDocumentParam &param) {
const std::string &path = param.textDocument.uri.GetPath(); const std::string &path = param.textDocument.uri.GetPath();
pipeline::Index(path, {}, IndexMode::Normal, true); pipeline::Index(path, {}, IndexMode::Normal, false);
manager->OnSave(path); manager->OnSave(path);
} }
} // namespace ccls } // namespace ccls

View File

@ -69,7 +69,7 @@ void MessageHandler::workspace_didChangeWatchedFiles(
break; break;
} }
case FileChangeType::Deleted: case FileChangeType::Deleted:
pipeline::Index(path, {}, mode, true); pipeline::Index(path, {}, mode, false);
manager->OnClose(path); manager->OnClose(path);
break; break;
} }

View File

@ -28,8 +28,5 @@ void FreeUnusedMemory();
// Stop self and wait for SIGCONT. // Stop self and wait for SIGCONT.
void TraceMe(); void TraceMe();
std::string GetExternalCommandOutput(const std::vector<std::string> &command,
std::string_view input);
void SpawnThread(void *(*fn)(void *), void *arg); void SpawnThread(void *(*fn)(void *), void *arg);
} // namespace ccls } // namespace ccls

View File

@ -73,49 +73,6 @@ void TraceMe() {
raise(traceme[0] == 's' ? SIGSTOP : SIGTSTP); raise(traceme[0] == 's' ? SIGSTOP : SIGTSTP);
} }
std::string GetExternalCommandOutput(const std::vector<std::string> &command,
std::string_view input) {
int pin[2], pout[2];
if (pipe(pin) < 0) {
perror("pipe(stdin)");
return "";
}
if (pipe(pout) < 0) {
perror("pipe(stdout)");
close(pin[0]);
close(pin[1]);
return "";
}
pid_t child = fork();
if (child == 0) {
dup2(pout[0], 0);
dup2(pin[1], 1);
close(pin[0]);
close(pin[1]);
close(pout[0]);
close(pout[1]);
auto argv = new char *[command.size() + 1];
for (size_t i = 0; i < command.size(); i++)
argv[i] = const_cast<char *>(command[i].c_str());
argv[command.size()] = nullptr;
execvp(argv[0], argv);
_Exit(127);
}
close(pin[1]);
close(pout[0]);
// O_NONBLOCK is disabled, write(2) blocks until all bytes are written.
(void)write(pout[1], input.data(), input.size());
close(pout[1]);
std::string ret;
char buf[4096];
ssize_t n;
while ((n = read(pin[0], buf, sizeof buf)) > 0)
ret.append(buf, n);
close(pin[0]);
waitpid(child, NULL, 0);
return ret;
}
void SpawnThread(void *(*fn)(void *), void *arg) { void SpawnThread(void *(*fn)(void *), void *arg) {
pthread_t thd; pthread_t thd;
pthread_attr_t attr; pthread_attr_t attr;

View File

@ -57,11 +57,6 @@ void FreeUnusedMemory() {}
// TODO Wait for debugger to attach // TODO Wait for debugger to attach
void TraceMe() {} void TraceMe() {}
std::string GetExternalCommandOutput(const std::vector<std::string> &command,
std::string_view input) {
return "";
}
void SpawnThread(void *(*fn)(void *), void *arg) { void SpawnThread(void *(*fn)(void *), void *arg) {
std::thread(fn, arg).detach(); std::thread(fn, arg).detach();
} }

View File

@ -31,13 +31,17 @@ limitations under the License.
#include <llvm/ADT/STLExtras.h> #include <llvm/ADT/STLExtras.h>
#include <llvm/ADT/StringSet.h> #include <llvm/ADT/StringSet.h>
#include <llvm/Support/LineIterator.h> #include <llvm/Support/LineIterator.h>
#include <llvm/Support/Program.h>
#include <rapidjson/writer.h> #include <rapidjson/writer.h>
#if defined(__unix__) || defined(__APPLE__) #ifdef _WIN32
# include <Windows.h>
#else
# include <unistd.h> # include <unistd.h>
#endif #endif
#include <array>
#include <limits.h> #include <limits.h>
#include <unordered_set> #include <unordered_set>
#include <vector> #include <vector>
@ -308,7 +312,8 @@ int ComputeGuessScore(std::string_view a, std::string_view b) {
} // namespace } // namespace
void Project::LoadDirectory(const std::string &root, Project::Folder &folder) { void Project::LoadDirectory(const std::string &root, Project::Folder &folder) {
SmallString<256> Path, CDBDir; SmallString<256> CDBDir, Path, StdinPath;
std::string err_msg;
folder.entries.clear(); folder.entries.clear();
if (g_config->compilationDatabaseCommand.empty()) { if (g_config->compilationDatabaseCommand.empty()) {
CDBDir = root; CDBDir = root;
@ -319,33 +324,49 @@ void Project::LoadDirectory(const std::string &root, Project::Folder &folder) {
// If `compilationDatabaseCommand` is specified, execute it to get the // If `compilationDatabaseCommand` is specified, execute it to get the
// compdb. // compdb.
#ifdef _WIN32 #ifdef _WIN32
// TODO char tmpdir[L_tmpnam];
tmpnam_s(tmpdir, L_tmpnam);
CDBDir = tmpdir;
if (sys::fs::create_directory(tmpdir, false))
return;
#else #else
char tmpdir[] = "/tmp/ccls-compdb-XXXXXX"; char tmpdir[] = "/tmp/ccls-compdb-XXXXXX";
if (!mkdtemp(tmpdir)) if (!mkdtemp(tmpdir))
return; return;
CDBDir = tmpdir; CDBDir = tmpdir;
#endif
sys::path::append(Path, CDBDir, "compile_commands.json"); sys::path::append(Path, CDBDir, "compile_commands.json");
rapidjson::StringBuffer input; sys::path::append(StdinPath, CDBDir, "stdin");
rapidjson::Writer<rapidjson::StringBuffer> writer(input); {
rapidjson::StringBuffer sb;
rapidjson::Writer<rapidjson::StringBuffer> writer(sb);
JsonWriter json_writer(&writer); JsonWriter json_writer(&writer);
Reflect(json_writer, *g_config); Reflect(json_writer, *g_config);
std::string contents = GetExternalCommandOutput( std::string input = sb.GetString();
std::vector<std::string>{g_config->compilationDatabaseCommand, root}, FILE *fout = fopen(StdinPath.c_str(), "wb");
input.GetString()); fwrite(input.c_str(), input.size(), 1, fout);
FILE *fout = fopen(Path.c_str(), "wb");
fwrite(contents.c_str(), contents.size(), 1, fout);
fclose(fout); fclose(fout);
#endif }
std::array<Optional<StringRef>, 3> Redir{StringRef(StdinPath),
StringRef(Path), StringRef()};
std::vector<StringRef> args{g_config->compilationDatabaseCommand, root};
if (sys::ExecuteAndWait(args[0], args, llvm::None, Redir, 0, 0, &err_msg) <
0) {
LOG_S(ERROR) << "failed to execute " << args[0].str() << " "
<< args[1].str() << ": " << err_msg;
return;
}
} }
std::string err_msg;
std::unique_ptr<tooling::CompilationDatabase> CDB = std::unique_ptr<tooling::CompilationDatabase> CDB =
tooling::CompilationDatabase::loadFromDirectory(CDBDir, err_msg); tooling::CompilationDatabase::loadFromDirectory(CDBDir, err_msg);
if (!g_config->compilationDatabaseCommand.empty()) { if (!g_config->compilationDatabaseCommand.empty()) {
#ifdef _WIN32 #ifdef _WIN32
// TODO DeleteFileA(StdinPath.c_str());
DeleteFileA(Path.c_str());
RemoveDirectoryA(CDBDir.c_str());
#else #else
unlink(StdinPath.c_str());
unlink(Path.c_str()); unlink(Path.c_str());
rmdir(CDBDir.c_str()); rmdir(CDBDir.c_str());
#endif #endif
@ -354,7 +375,10 @@ void Project::LoadDirectory(const std::string &root, Project::Folder &folder) {
ProjectProcessor proc(folder); ProjectProcessor proc(folder);
StringSet<> Seen; StringSet<> Seen;
std::vector<Project::Entry> result; std::vector<Project::Entry> result;
if (CDB) { if (!CDB) {
if (g_config->compilationDatabaseCommand.size() || sys::fs::exists(Path))
LOG_S(ERROR) << "failed to load " << Path.c_str();
} else {
LOG_S(INFO) << "loaded " << Path.c_str(); LOG_S(INFO) << "loaded " << Path.c_str();
for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) {
static bool once; static bool once;

View File

@ -190,11 +190,8 @@ public:
StringRef FileName, bool IsAngled, StringRef FileName, bool IsAngled,
CharSourceRange FilenameRange, const FileEntry *File, CharSourceRange FilenameRange, const FileEntry *File,
StringRef SearchPath, StringRef RelativePath, StringRef SearchPath, StringRef RelativePath,
const clang::Module *Imported const clang::Module *Imported,
#if LLVM_VERSION_MAJOR >= 7 SrcMgr::CharacteristicKind FileKind) override {
, SrcMgr::CharacteristicKind FileKind
#endif
) override {
(void)SM; (void)SM;
if (File && Seen.insert(File).second) if (File && Seen.insert(File).second)
out.emplace_back(PathFromFileEntry(*File), File->getModificationTime()); out.emplace_back(PathFromFileEntry(*File), File->getModificationTime());
@ -304,15 +301,10 @@ std::unique_ptr<CompilerInstance> BuildCompilerInstance(
IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, DiagnosticConsumer &DC, IntrusiveRefCntPtr<llvm::vfs::FileSystem> FS, DiagnosticConsumer &DC,
const PreambleData *preamble, const std::string &main, const PreambleData *preamble, const std::string &main,
std::unique_ptr<llvm::MemoryBuffer> &Buf) { std::unique_ptr<llvm::MemoryBuffer> &Buf) {
if (preamble) { if (preamble)
#if LLVM_VERSION_MAJOR >= 7
preamble->Preamble.OverridePreamble(*CI, FS, Buf.get()); preamble->Preamble.OverridePreamble(*CI, FS, Buf.get());
#else else
preamble->Preamble.AddImplicitPreamble(*CI, FS, Buf.get());
#endif
} else {
CI->getPreprocessorOpts().addRemappedFile(main, Buf.get()); CI->getPreprocessorOpts().addRemappedFile(main, Buf.get());
}
auto Clang = std::make_unique<CompilerInstance>(session.PCH); auto Clang = std::make_unique<CompilerInstance>(session.PCH);
Clang->setInvocation(std::move(CI)); Clang->setInvocation(std::move(CI));