diff --git a/.appveyor.yml b/.appveyor.yml index 0fc36d3f..42a7a4c0 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -15,7 +15,7 @@ install: - 7z x llvm.tar - git submodule update --init --recursive 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 artifacts: diff --git a/CMakeLists.txt b/CMakeLists.txt index bf39ebfd..993376d8 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,13 +5,7 @@ list(APPEND CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) include(DefaultCMakeBuildType) # 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(CLANG_USE_BUNDLED_LIBC++ "Let Clang use bundled libc++" 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 @@ -30,10 +24,7 @@ add_executable(ccls "") # Enable C++17 (Required) set_property(TARGET ccls PROPERTY CXX_STANDARD 17) 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) -endif() +set_property(TARGET ccls PROPERTY CXX_EXTENSIONS OFF) if(NOT LLVM_ENABLE_RTTI) # releases.llvm.org libraries are compiled with -fno-rtti @@ -76,43 +67,12 @@ else() target_compile_options(ccls PRIVATE $<$:-fno-limit-debug-info>) 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() ### Libraries # See cmake/FindClang.cmake -find_package(Clang 6.0.0) +find_package(Clang 7.0.0) target_link_libraries(ccls PRIVATE Clang::Clang) # Enable threading support @@ -143,31 +103,6 @@ target_include_directories(ccls SYSTEM PRIVATE 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 - $ - COMMENT "Copying libclang.dll to build directory ...") -endif() - ### Tools # We use glob here since source files are already manually added with diff --git a/clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 b/clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 deleted file mode 100644 index 54bea9e6..00000000 --- a/clang_archive_hashes/LLVM-7.0.0-win64.exe.SHA256 +++ /dev/null @@ -1 +0,0 @@ -74b197a3959b0408adf0824be01db8dddfa2f9a967f4085af3fad900ed5fdbf6 \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 deleted file mode 100644 index b8a56bfa..00000000 --- a/clang_archive_hashes/clang+llvm-7.0.0-amd64-unknown-freebsd11.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -95ceb933ccf76e3ddaa536f41ab82c442bbac07cdea6f9fbf6e3b13cc1711255 \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 deleted file mode 100644 index 86f733c9..00000000 --- a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-apple-darwin.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -b3ad93c3d69dfd528df9c5bb1a434367babb8f3baea47fbb99bf49f1b03c94ca \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 deleted file mode 100644 index bc830691..00000000 --- a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-14.04.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -5c90e61b06d37270bc26edb305d7e498e2c7be22d99e0afd9f2274ef5458575a \ No newline at end of file diff --git a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 b/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 deleted file mode 100644 index 1475a0a8..00000000 --- a/clang_archive_hashes/clang+llvm-7.0.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz.SHA256 +++ /dev/null @@ -1 +0,0 @@ -69b85c833cd28ea04ce34002464f10a6ad9656dd2bba0f7133536a9927c660d2 \ No newline at end of file diff --git a/cmake/DownloadAndExtract7zip.cmake b/cmake/DownloadAndExtract7zip.cmake deleted file mode 100644 index 72bc879d..00000000 --- a/cmake/DownloadAndExtract7zip.cmake +++ /dev/null @@ -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() \ No newline at end of file diff --git a/cmake/DownloadAndExtractClang.cmake b/cmake/DownloadAndExtractClang.cmake deleted file mode 100644 index 9365b188..00000000 --- a/cmake/DownloadAndExtractClang.cmake +++ /dev/null @@ -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() diff --git a/cmake/FindClang.cmake b/cmake/FindClang.cmake index 19402900..078395dd 100644 --- a/cmake/FindClang.cmake +++ b/cmake/FindClang.cmake @@ -72,7 +72,6 @@ _Clang_find_library(Clang_LIBRARY clangIndex) _Clang_find_add_library(clangFormat) _Clang_find_add_library(clangTooling) -# TODO Remove after dropping clang 6 _Clang_find_library(clangToolingInclusions_LIBRARY clangToolingInclusions) if (clangToolingInclusions_LIBRARY) list(APPEND _Clang_LIBRARIES ${clangToolingInclusions_LIBRARY}) diff --git a/src/clang_tu.cc b/src/clang_tu.cc index a2d982b4..70078c61 100644 --- a/src/clang_tu.cc +++ b/src/clang_tu.cc @@ -156,7 +156,6 @@ const char *ClangBuiltinTypeName(int kind) { return "double"; case BuiltinType::LongDouble: return "long double"; -#if LLVM_VERSION_MAJOR >= 7 case BuiltinType::ShortAccum: return "short _Accum"; case BuiltinType::Accum: @@ -205,7 +204,6 @@ const char *ClangBuiltinTypeName(int kind) { return "_Sat unsigned _Fract"; case BuiltinType::BuiltinType::SatULongFract: return "_Sat unsigned long _Fract"; -#endif case BuiltinType::Float16: return "_Float16"; case BuiltinType::Float128: @@ -213,10 +211,8 @@ const char *ClangBuiltinTypeName(int kind) { case BuiltinType::WChar_S: case BuiltinType::WChar_U: return "wchar_t"; -#if LLVM_VERSION_MAJOR >= 7 case BuiltinType::Char8: return "char8_t"; -#endif case BuiltinType::Char16: return "char16_t"; case BuiltinType::Char32: diff --git a/src/indexer.cc b/src/indexer.cc index 43969f23..716a092f 100644 --- a/src/indexer.cc +++ b/src/indexer.cc @@ -593,11 +593,7 @@ public: if (init) { SourceManager &SM = Ctx->getSourceManager(); const LangOptions &Lang = Ctx->getLangOpts(); - SourceRange R = SM.getExpansionRange(init->getSourceRange()) -#if LLVM_VERSION_MAJOR >= 7 - .getAsRange() -#endif - ; + SourceRange R = SM.getExpansionRange(init->getSourceRange()).getAsRange(); SourceLocation L = D->getLocation(); if (L.isMacroID() || !SM.isBeforeInTranslationUnit(L, R.getBegin())) return; @@ -688,41 +684,15 @@ public: } bool handleDeclOccurence(const Decl *D, index::SymbolRoleSet Roles, ArrayRef Relations, -#if LLVM_VERSION_MAJOR >= 7 - SourceLocation Loc, -#else - FileID LocFID, unsigned LocOffset, -#endif - ASTNodeInfo ASTNode) override { + SourceLocation Loc, ASTNodeInfo ASTNode) override { SourceManager &SM = Ctx->getSourceManager(); 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; -#endif SourceLocation Spell = SM.getSpellingLoc(Loc); const FileEntry *FE; 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) : SM.getExpansionRange(Loc); -#endif loc = FromCharSourceRange(SM, Lang, R); LocFID = SM.getFileID(R.getBegin()); FE = SM.getFileEntryForID(LocFID); @@ -1085,12 +1055,8 @@ public: StringRef Included, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const Module *Imported -#if LLVM_VERSION_MAJOR >= 7 - , - SrcMgr::CharacteristicKind FileType -#endif - ) override { + const Module *Imported, + SrcMgr::CharacteristicKind FileType) override { if (!File) return; llvm::sys::fs::UniqueID UniqueID; @@ -1283,9 +1249,7 @@ Index(SemaManager *manager, WorkingFiles *wfiles, VFS *vfs, IndexOpts.SystemSymbolFilter = index::IndexingOptions::SystemSymbolFilterKind::All; IndexOpts.IndexFunctionLocals = true; -#if LLVM_VERSION_MAJOR >= 7 IndexOpts.IndexImplicitInstantiation = true; -#endif std::unique_ptr Action = createIndexingAction( DataConsumer, IndexOpts, std::make_unique(param)); diff --git a/src/log.cc b/src/log.cc index a10a4a7d..3e2b5592 100644 --- a/src/log.cc +++ b/src/log.cc @@ -72,6 +72,7 @@ Message::~Message() { std::lock_guard lock(mtx); stream_ << '\n'; fputs(stream_.str().c_str(), file); + fflush(file); if (verbosity_ == Verbosity_FATAL) abort(); } diff --git a/src/main.cc b/src/main.cc index 95cd0363..39c6457f 100644 --- a/src/main.cc +++ b/src/main.cc @@ -58,10 +58,10 @@ opt opt_index("index", value_desc("root"), cat(C)); list opt_init("init", desc("extra initialization options in JSON"), cat(C)); -opt opt_log_file("log-file", desc("log"), value_desc("filename"), +opt opt_log_file("log-file", desc("stderr or log file"), + value_desc("file"), init("stderr"), cat(C)); +opt opt_log_file_append("log-file-append", desc("append to log file"), cat(C)); -opt opt_log_file_append("log-file-append", desc("log"), - value_desc("filename"), cat(C)); void CloseLog() { fclose(ccls::log::file); } @@ -95,14 +95,13 @@ int main(int argc, char **argv) { bool language_server = true; - if (opt_log_file.size() || opt_log_file_append.size()) { - ccls::log::file = opt_log_file.size() - ? fopen(opt_log_file.c_str(), "wb") - : fopen(opt_log_file_append.c_str(), "ab"); + if (opt_log_file.size()) { + ccls::log::file = + opt_log_file == "stderr" + ? stderr + : fopen(opt_log_file.c_str(), opt_log_file_append ? "ab" : "wb"); if (!ccls::log::file) { - fprintf( - stderr, "failed to open %s\n", - (opt_log_file.size() ? opt_log_file : opt_log_file_append).c_str()); + fprintf(stderr, "failed to open %s\n", opt_log_file.c_str()); return 2; } setbuf(ccls::log::file, NULL); diff --git a/src/message_handler.cc b/src/message_handler.cc index 5d8cf655..a9878f81 100644 --- a/src/message_handler.cc +++ b/src/message_handler.cc @@ -274,6 +274,8 @@ MessageHandler::FindOrFail(const std::string &path, ReplyOnce &reply, } QueryFile *file = FindFile(path, out_file_id); if (!file) { + if (!overdue) + throw NotIndexed{path}; reply.Error(ErrorCode::InvalidRequest, "not indexed"); return {nullptr, nullptr}; } diff --git a/src/messages/textDocument_completion.cc b/src/messages/textDocument_completion.cc index f401931e..a1f0884e 100644 --- a/src/messages/textDocument_completion.cc +++ b/src/messages/textDocument_completion.cc @@ -436,7 +436,6 @@ public: ls_items[j].label = ls_items[j].filterText; } } -#if LLVM_VERSION_MAJOR >= 7 for (const FixItHint &FixIt : R.FixIts) { auto &AST = S.getASTContext(); TextEdit ls_edit = @@ -444,7 +443,6 @@ public: for (size_t j = first_idx; j < ls_items.size(); j++) ls_items[j].additionalTextEdits.push_back(ls_edit); } -#endif } } @@ -474,9 +472,7 @@ void MessageHandler::textDocument_completion(CompletionParam ¶m, clang::CodeCompleteOptions CCOpts; CCOpts.IncludeBriefComments = true; CCOpts.IncludeCodePatterns = StringRef(buffer_line).ltrim().startswith("#"); -#if LLVM_VERSION_MAJOR >= 7 CCOpts.IncludeFixIts = true; -#endif CCOpts.IncludeMacros = true; if (param.context.triggerKind == CompletionTriggerKind::TriggerCharacter && diff --git a/src/messages/textDocument_did.cc b/src/messages/textDocument_did.cc index f48185cd..d664c537 100644 --- a/src/messages/textDocument_did.cc +++ b/src/messages/textDocument_did.cc @@ -65,7 +65,7 @@ void MessageHandler::textDocument_didOpen(DidOpenTextDocumentParam ¶m) { void MessageHandler::textDocument_didSave(TextDocumentParam ¶m) { const std::string &path = param.textDocument.uri.GetPath(); - pipeline::Index(path, {}, IndexMode::Normal, true); + pipeline::Index(path, {}, IndexMode::Normal, false); manager->OnSave(path); } } // namespace ccls diff --git a/src/messages/workspace.cc b/src/messages/workspace.cc index 8ce192a8..5435d98f 100644 --- a/src/messages/workspace.cc +++ b/src/messages/workspace.cc @@ -69,7 +69,7 @@ void MessageHandler::workspace_didChangeWatchedFiles( break; } case FileChangeType::Deleted: - pipeline::Index(path, {}, mode, true); + pipeline::Index(path, {}, mode, false); manager->OnClose(path); break; } diff --git a/src/platform.hh b/src/platform.hh index 12446263..79aca558 100644 --- a/src/platform.hh +++ b/src/platform.hh @@ -28,8 +28,5 @@ void FreeUnusedMemory(); // Stop self and wait for SIGCONT. void TraceMe(); -std::string GetExternalCommandOutput(const std::vector &command, - std::string_view input); - void SpawnThread(void *(*fn)(void *), void *arg); } // namespace ccls diff --git a/src/platform_posix.cc b/src/platform_posix.cc index 35d8d271..c172446b 100644 --- a/src/platform_posix.cc +++ b/src/platform_posix.cc @@ -73,49 +73,6 @@ void TraceMe() { raise(traceme[0] == 's' ? SIGSTOP : SIGTSTP); } -std::string GetExternalCommandOutput(const std::vector &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(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) { pthread_t thd; pthread_attr_t attr; diff --git a/src/platform_win.cc b/src/platform_win.cc index a2ca5185..f933b257 100644 --- a/src/platform_win.cc +++ b/src/platform_win.cc @@ -57,11 +57,6 @@ void FreeUnusedMemory() {} // TODO Wait for debugger to attach void TraceMe() {} -std::string GetExternalCommandOutput(const std::vector &command, - std::string_view input) { - return ""; -} - void SpawnThread(void *(*fn)(void *), void *arg) { std::thread(fn, arg).detach(); } diff --git a/src/project.cc b/src/project.cc index d7fa1ed9..c2bcf718 100644 --- a/src/project.cc +++ b/src/project.cc @@ -31,13 +31,17 @@ limitations under the License. #include #include #include +#include #include -#if defined(__unix__) || defined(__APPLE__) -#include +#ifdef _WIN32 +# include +#else +# include #endif +#include #include #include #include @@ -308,7 +312,8 @@ int ComputeGuessScore(std::string_view a, std::string_view b) { } // namespace 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(); if (g_config->compilationDatabaseCommand.empty()) { 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 // compdb. #ifdef _WIN32 - // TODO + char tmpdir[L_tmpnam]; + tmpnam_s(tmpdir, L_tmpnam); + CDBDir = tmpdir; + if (sys::fs::create_directory(tmpdir, false)) + return; #else char tmpdir[] = "/tmp/ccls-compdb-XXXXXX"; if (!mkdtemp(tmpdir)) return; CDBDir = tmpdir; - sys::path::append(Path, CDBDir, "compile_commands.json"); - rapidjson::StringBuffer input; - rapidjson::Writer writer(input); - JsonWriter json_writer(&writer); - Reflect(json_writer, *g_config); - std::string contents = GetExternalCommandOutput( - std::vector{g_config->compilationDatabaseCommand, root}, - input.GetString()); - FILE *fout = fopen(Path.c_str(), "wb"); - fwrite(contents.c_str(), contents.size(), 1, fout); - fclose(fout); #endif + sys::path::append(Path, CDBDir, "compile_commands.json"); + sys::path::append(StdinPath, CDBDir, "stdin"); + { + rapidjson::StringBuffer sb; + rapidjson::Writer writer(sb); + JsonWriter json_writer(&writer); + Reflect(json_writer, *g_config); + std::string input = sb.GetString(); + FILE *fout = fopen(StdinPath.c_str(), "wb"); + fwrite(input.c_str(), input.size(), 1, fout); + fclose(fout); + } + std::array, 3> Redir{StringRef(StdinPath), + StringRef(Path), StringRef()}; + std::vector 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 CDB = tooling::CompilationDatabase::loadFromDirectory(CDBDir, err_msg); if (!g_config->compilationDatabaseCommand.empty()) { #ifdef _WIN32 - // TODO + DeleteFileA(StdinPath.c_str()); + DeleteFileA(Path.c_str()); + RemoveDirectoryA(CDBDir.c_str()); #else + unlink(StdinPath.c_str()); unlink(Path.c_str()); rmdir(CDBDir.c_str()); #endif @@ -354,7 +375,10 @@ void Project::LoadDirectory(const std::string &root, Project::Folder &folder) { ProjectProcessor proc(folder); StringSet<> Seen; std::vector 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(); for (tooling::CompileCommand &Cmd : CDB->getAllCompileCommands()) { static bool once; diff --git a/src/sema_manager.cc b/src/sema_manager.cc index c352f0f4..a80bd0d7 100644 --- a/src/sema_manager.cc +++ b/src/sema_manager.cc @@ -190,11 +190,8 @@ public: StringRef FileName, bool IsAngled, CharSourceRange FilenameRange, const FileEntry *File, StringRef SearchPath, StringRef RelativePath, - const clang::Module *Imported -#if LLVM_VERSION_MAJOR >= 7 - , SrcMgr::CharacteristicKind FileKind -#endif - ) override { + const clang::Module *Imported, + SrcMgr::CharacteristicKind FileKind) override { (void)SM; if (File && Seen.insert(File).second) out.emplace_back(PathFromFileEntry(*File), File->getModificationTime()); @@ -304,15 +301,10 @@ std::unique_ptr BuildCompilerInstance( IntrusiveRefCntPtr FS, DiagnosticConsumer &DC, const PreambleData *preamble, const std::string &main, std::unique_ptr &Buf) { - if (preamble) { -#if LLVM_VERSION_MAJOR >= 7 + if (preamble) preamble->Preamble.OverridePreamble(*CI, FS, Buf.get()); -#else - preamble->Preamble.AddImplicitPreamble(*CI, FS, Buf.get()); -#endif - } else { + else CI->getPreprocessorOpts().addRemappedFile(main, Buf.get()); - } auto Clang = std::make_unique(session.PCH); Clang->setInvocation(std::move(CI));