mirror of
https://github.com/MaskRay/ccls.git
synced 2024-11-24 00:25:07 +00:00
Misc
Move using below #include to make preamble happy textDocument/references: if no references, first line or last line => list where this file is included malloc_trim() only if files have been indexed in last cycle Intern: use CachedHashStringRef
This commit is contained in:
parent
174466516e
commit
395e9d8724
@ -163,7 +163,9 @@ std::unique_ptr<CompilerInstance> BuildCompilerInstance(
|
|||||||
CompletionSession &session, std::unique_ptr<CompilerInvocation> CI,
|
CompletionSession &session, std::unique_ptr<CompilerInvocation> CI,
|
||||||
DiagnosticConsumer &DC, const WorkingFiles::Snapshot &snapshot,
|
DiagnosticConsumer &DC, const WorkingFiles::Snapshot &snapshot,
|
||||||
std::vector<std::unique_ptr<llvm::MemoryBuffer>> &Bufs) {
|
std::vector<std::unique_ptr<llvm::MemoryBuffer>> &Bufs) {
|
||||||
std::string main = ResolveIfRelative(session.file.directory, CI->getFrontendOpts().Inputs[0].getFile());
|
std::string main = ResolveIfRelative(
|
||||||
|
session.file.directory,
|
||||||
|
sys::path::convert_to_slash(CI->getFrontendOpts().Inputs[0].getFile()));
|
||||||
for (auto &file : snapshot.files) {
|
for (auto &file : snapshot.files) {
|
||||||
Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content));
|
Bufs.push_back(llvm::MemoryBuffer::getMemBuffer(file.content));
|
||||||
if (file.filename == main)
|
if (file.filename == main)
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "platform.h"
|
#include "platform.h"
|
||||||
#include "serializer.h"
|
#include "serializer.h"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <clang/AST/AST.h>
|
#include <clang/AST/AST.h>
|
||||||
#include <clang/Frontend/FrontendAction.h>
|
#include <clang/Frontend/FrontendAction.h>
|
||||||
@ -21,16 +20,15 @@ using namespace ccls;
|
|||||||
#include <llvm/ADT/DenseSet.h>
|
#include <llvm/ADT/DenseSet.h>
|
||||||
#include <llvm/Support/CrashRecoveryContext.h>
|
#include <llvm/Support/CrashRecoveryContext.h>
|
||||||
#include <llvm/Support/Path.h>
|
#include <llvm/Support/Path.h>
|
||||||
#include <llvm/Support/Timer.h>
|
|
||||||
using namespace clang;
|
|
||||||
using llvm::Timer;
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include <limits.h>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
|
using namespace ccls;
|
||||||
|
using namespace clang;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
constexpr int kInitializerMaxLines = 3;
|
constexpr int kInitializerMaxLines = 3;
|
||||||
@ -494,7 +492,7 @@ public:
|
|||||||
def.short_name_offset = Str.size() + qualified.size() - short_name.size();
|
def.short_name_offset = Str.size() + qualified.size() - short_name.size();
|
||||||
def.short_name_size = short_name.size();
|
def.short_name_size = short_name.size();
|
||||||
Str += StringRef(qualified.data(), qualified.size());
|
Str += StringRef(qualified.data(), qualified.size());
|
||||||
def.detailed_name = Intern(Str.str());
|
def.detailed_name = Intern(Str);
|
||||||
} else {
|
} else {
|
||||||
SetName(D, short_name, qualified, def);
|
SetName(D, short_name, qualified, def);
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,6 @@
|
|||||||
#include <llvm/ADT/DenseMap.h>
|
#include <llvm/ADT/DenseMap.h>
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <optional>
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
|
@ -8,15 +8,12 @@
|
|||||||
#include "serializers/json.h"
|
#include "serializers/json.h"
|
||||||
#include "test.h"
|
#include "test.h"
|
||||||
#include "working_files.h"
|
#include "working_files.h"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <llvm/Support/CommandLine.h>
|
#include <llvm/Support/CommandLine.h>
|
||||||
#include <llvm/Support/CrashRecoveryContext.h>
|
#include <llvm/Support/CrashRecoveryContext.h>
|
||||||
#include <llvm/Support/Process.h>
|
#include <llvm/Support/Process.h>
|
||||||
#include <llvm/Support/Program.h>
|
#include <llvm/Support/Program.h>
|
||||||
#include <llvm/Support/Signals.h>
|
#include <llvm/Support/Signals.h>
|
||||||
using namespace llvm;
|
|
||||||
using namespace llvm::cl;
|
|
||||||
|
|
||||||
#include <rapidjson/error/en.h>
|
#include <rapidjson/error/en.h>
|
||||||
|
|
||||||
@ -26,6 +23,10 @@ using namespace llvm::cl;
|
|||||||
#include <unordered_map>
|
#include <unordered_map>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace ccls;
|
||||||
|
using namespace llvm;
|
||||||
|
using namespace llvm::cl;
|
||||||
|
|
||||||
std::string g_init_options;
|
std::string g_init_options;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -75,7 +75,6 @@ MAKE_REFLECT_STRUCT(Out_CclsPublishSemanticHighlighting, jsonrpc, method,
|
|||||||
|
|
||||||
struct MessageHandler {
|
struct MessageHandler {
|
||||||
DB *db = nullptr;
|
DB *db = nullptr;
|
||||||
MultiQueueWaiter *waiter = nullptr;
|
|
||||||
Project *project = nullptr;
|
Project *project = nullptr;
|
||||||
VFS *vfs = nullptr;
|
VFS *vfs = nullptr;
|
||||||
SemanticHighlight *highlight = nullptr;
|
SemanticHighlight *highlight = nullptr;
|
||||||
|
@ -5,10 +5,11 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
|
using namespace ccls;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
MethodType kMethodType = "$ccls/call";
|
MethodType kMethodType = "$ccls/call";
|
||||||
|
@ -5,14 +5,15 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <clang/AST/Type.h>
|
#include <clang/AST/Type.h>
|
||||||
#include <llvm/ADT/DenseSet.h>
|
#include <llvm/ADT/DenseSet.h>
|
||||||
using namespace clang;
|
|
||||||
|
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
|
using namespace ccls;
|
||||||
|
using namespace clang;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
MethodType kMethodType = "$ccls/member";
|
MethodType kMethodType = "$ccls/member";
|
||||||
|
|
||||||
|
@ -5,14 +5,14 @@
|
|||||||
#include "match.h"
|
#include "match.h"
|
||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "platform.h"
|
|
||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "working_files.h"
|
#include "working_files.h"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
|
using namespace ccls;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
MethodType kMethodType = "$ccls/reload";
|
MethodType kMethodType = "$ccls/reload";
|
||||||
|
|
||||||
@ -22,8 +22,7 @@ struct In_CclsReload : public NotificationInMessage {
|
|||||||
bool dependencies = true;
|
bool dependencies = true;
|
||||||
std::vector<std::string> whitelist;
|
std::vector<std::string> whitelist;
|
||||||
std::vector<std::string> blacklist;
|
std::vector<std::string> blacklist;
|
||||||
};
|
} params;
|
||||||
Params params;
|
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(In_CclsReload::Params, dependencies, whitelist,
|
MAKE_REFLECT_STRUCT(In_CclsReload::Params, dependencies, whitelist,
|
||||||
blacklist);
|
blacklist);
|
||||||
|
@ -11,16 +11,16 @@
|
|||||||
#include "project.h"
|
#include "project.h"
|
||||||
#include "serializers/json.h"
|
#include "serializers/json.h"
|
||||||
#include "working_files.h"
|
#include "working_files.h"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <llvm/ADT/Twine.h>
|
#include <llvm/ADT/Twine.h>
|
||||||
#include <llvm/Support/Threading.h>
|
#include <llvm/Support/Threading.h>
|
||||||
using namespace llvm;
|
|
||||||
|
|
||||||
#include <iostream>
|
|
||||||
#include <stdexcept>
|
#include <stdexcept>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
|
||||||
|
using namespace ccls;
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
// TODO Cleanup global variables
|
// TODO Cleanup global variables
|
||||||
extern std::string g_init_options;
|
extern std::string g_init_options;
|
||||||
|
|
||||||
|
@ -8,16 +8,16 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "working_files.h"
|
#include "working_files.h"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <clang/Sema/CodeCompleteConsumer.h>
|
#include <clang/Sema/CodeCompleteConsumer.h>
|
||||||
#include <clang/Sema/Sema.h>
|
#include <clang/Sema/Sema.h>
|
||||||
#include <llvm/Support/Timer.h>
|
|
||||||
using namespace clang;
|
|
||||||
using namespace llvm;
|
|
||||||
|
|
||||||
#include <regex>
|
#include <regex>
|
||||||
|
|
||||||
|
using namespace ccls;
|
||||||
|
using namespace clang;
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
MethodType kMethodType = "textDocument/completion";
|
MethodType kMethodType = "textDocument/completion";
|
||||||
|
|
||||||
@ -167,10 +167,6 @@ void FilterAndSortCompletionResponse(
|
|||||||
const std::string &complete_text, bool has_open_paren) {
|
const std::string &complete_text, bool has_open_paren) {
|
||||||
if (!g_config->completion.filterAndSort)
|
if (!g_config->completion.filterAndSort)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
static Timer timer("FilterAndSortCompletionResponse", "");
|
|
||||||
TimeRegion region(timer);
|
|
||||||
|
|
||||||
auto &items = complete_response->result.items;
|
auto &items = complete_response->result.items;
|
||||||
|
|
||||||
auto finalize = [&]() {
|
auto finalize = [&]() {
|
||||||
|
@ -4,11 +4,12 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <cstdlib>
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
using namespace ccls;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
MethodType kMethodType = "textDocument/definition";
|
MethodType kMethodType = "textDocument/definition";
|
||||||
|
@ -14,8 +14,7 @@ struct In_TextDocumentDidClose : public NotificationInMessage {
|
|||||||
MethodType GetMethodType() const override { return kMethodType; }
|
MethodType GetMethodType() const override { return kMethodType; }
|
||||||
struct Params {
|
struct Params {
|
||||||
lsTextDocumentIdentifier textDocument;
|
lsTextDocumentIdentifier textDocument;
|
||||||
};
|
} params;
|
||||||
Params params;
|
|
||||||
};
|
};
|
||||||
MAKE_REFLECT_STRUCT(In_TextDocumentDidClose::Params, textDocument);
|
MAKE_REFLECT_STRUCT(In_TextDocumentDidClose::Params, textDocument);
|
||||||
MAKE_REFLECT_STRUCT(In_TextDocumentDidClose, params);
|
MAKE_REFLECT_STRUCT(In_TextDocumentDidClose, params);
|
||||||
|
@ -12,7 +12,6 @@ using namespace ccls;
|
|||||||
namespace {
|
namespace {
|
||||||
MethodType kMethodType = "textDocument/didOpen";
|
MethodType kMethodType = "textDocument/didOpen";
|
||||||
|
|
||||||
// Open, view, change, close file
|
|
||||||
struct In_TextDocumentDidOpen : public NotificationInMessage {
|
struct In_TextDocumentDidOpen : public NotificationInMessage {
|
||||||
MethodType GetMethodType() const override { return kMethodType; }
|
MethodType GetMethodType() const override { return kMethodType; }
|
||||||
|
|
||||||
@ -37,7 +36,7 @@ struct Handler_TextDocumentDidOpen
|
|||||||
// NOTE: This function blocks code lens. If it starts taking a long time
|
// NOTE: This function blocks code lens. If it starts taking a long time
|
||||||
// we will need to find a way to unblock the code lens request.
|
// we will need to find a way to unblock the code lens request.
|
||||||
const auto ¶ms = request->params;
|
const auto ¶ms = request->params;
|
||||||
std::string path = params.textDocument.uri.GetPath();
|
const std::string &path = params.textDocument.uri.GetPath();
|
||||||
|
|
||||||
WorkingFile *working_file = working_files->OnOpen(params.textDocument);
|
WorkingFile *working_file = working_files->OnOpen(params.textDocument);
|
||||||
if (std::optional<std::string> cached_file_contents =
|
if (std::optional<std::string> cached_file_contents =
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
#include "clang_complete.hh"
|
#include "clang_complete.hh"
|
||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "project.h"
|
|
||||||
using namespace ccls;
|
using namespace ccls;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
@ -32,7 +31,7 @@ struct Handler_TextDocumentDidSave
|
|||||||
|
|
||||||
void Run(In_TextDocumentDidSave *request) override {
|
void Run(In_TextDocumentDidSave *request) override {
|
||||||
const auto ¶ms = request->params;
|
const auto ¶ms = request->params;
|
||||||
std::string path = params.textDocument.uri.GetPath();
|
const std::string &path = params.textDocument.uri.GetPath();
|
||||||
pipeline::Index(path, {}, IndexMode::Normal);
|
pipeline::Index(path, {}, IndexMode::Normal);
|
||||||
clang_complete->NotifySave(path);
|
clang_complete->NotifySave(path);
|
||||||
}
|
}
|
||||||
|
@ -4,10 +4,11 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
|
|
||||||
|
using namespace ccls;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
MethodType kMethodType = "textDocument/references";
|
MethodType kMethodType = "textDocument/references";
|
||||||
|
|
||||||
@ -54,13 +55,17 @@ struct Handler_TextDocumentReferences
|
|||||||
if (!FindFileOrFail(db, project, request->id,
|
if (!FindFileOrFail(db, project, request->id,
|
||||||
params.textDocument.uri.GetPath(), &file))
|
params.textDocument.uri.GetPath(), &file))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
|
||||||
|
|
||||||
Out_TextDocumentReferences out;
|
Out_TextDocumentReferences out;
|
||||||
out.id = request->id;
|
out.id = request->id;
|
||||||
|
WorkingFile *wfile = working_files->GetFileByFilename(file->def->path);
|
||||||
|
if (!file) {
|
||||||
|
pipeline::WriteStdout(kMethodType, out);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
bool container = g_config->xref.container;
|
bool container = g_config->xref.container;
|
||||||
std::unordered_set<Use> seen_uses;
|
std::unordered_set<Use> seen_uses;
|
||||||
|
int line = params.position.line;
|
||||||
|
|
||||||
for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) {
|
for (SymbolRef sym : FindSymbolsAtLocation(wfile, file, params.position)) {
|
||||||
// Found symbol. Return references.
|
// Found symbol. Return references.
|
||||||
@ -115,7 +120,7 @@ struct Handler_TextDocumentReferences
|
|||||||
// = 0,
|
// = 0,
|
||||||
// use the current filename.
|
// use the current filename.
|
||||||
std::string path;
|
std::string path;
|
||||||
if (params.position.line == 0)
|
if (line == 0 || line >= (int)wfile->buffer_lines.size() - 1)
|
||||||
path = file->def->path;
|
path = file->def->path;
|
||||||
for (const IndexInclude &include : file->def->includes)
|
for (const IndexInclude &include : file->def->includes)
|
||||||
if (include.line == params.position.line) {
|
if (include.line == params.position.line) {
|
||||||
|
@ -4,12 +4,11 @@
|
|||||||
#include "clang_complete.hh"
|
#include "clang_complete.hh"
|
||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <clang/Sema/Sema.h>
|
#include <clang/Sema/Sema.h>
|
||||||
using namespace clang;
|
|
||||||
|
|
||||||
#include <stdint.h>
|
using namespace ccls;
|
||||||
|
using namespace clang;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
MethodType kMethodType = "textDocument/signatureHelp";
|
MethodType kMethodType = "textDocument/signatureHelp";
|
||||||
|
@ -5,13 +5,14 @@
|
|||||||
#include "message_handler.h"
|
#include "message_handler.h"
|
||||||
#include "pipeline.hh"
|
#include "pipeline.hh"
|
||||||
#include "query_utils.h"
|
#include "query_utils.h"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
using namespace ccls;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
MethodType kMethodType = "workspace/symbol";
|
MethodType kMethodType = "workspace/symbol";
|
||||||
|
|
||||||
|
@ -478,7 +478,6 @@ void MainLoop() {
|
|||||||
// Setup shared references.
|
// Setup shared references.
|
||||||
for (MessageHandler *handler : *MessageHandler::message_handlers) {
|
for (MessageHandler *handler : *MessageHandler::message_handlers) {
|
||||||
handler->db = &db;
|
handler->db = &db;
|
||||||
handler->waiter = indexer_waiter;
|
|
||||||
handler->project = &project;
|
handler->project = &project;
|
||||||
handler->vfs = &vfs;
|
handler->vfs = &vfs;
|
||||||
handler->highlight = &highlight;
|
handler->highlight = &highlight;
|
||||||
@ -487,6 +486,7 @@ void MainLoop() {
|
|||||||
handler->include_complete = &include_complete;
|
handler->include_complete = &include_complete;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool last_indexed = false;
|
||||||
while (true) {
|
while (true) {
|
||||||
std::vector<std::unique_ptr<InMessage>> messages = on_request->DequeueAll();
|
std::vector<std::unique_ptr<InMessage>> messages = on_request->DequeueAll();
|
||||||
bool did_work = messages.size();
|
bool did_work = messages.size();
|
||||||
@ -503,18 +503,22 @@ void MainLoop() {
|
|||||||
LOG_S(ERROR) << "No handler for " << message->GetMethodType();
|
LOG_S(ERROR) << "No handler for " << message->GetMethodType();
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 80; i--;) {
|
bool indexed = false;
|
||||||
|
for (int i = 20; i--;) {
|
||||||
std::optional<IndexUpdate> update = on_indexed->TryPopFront();
|
std::optional<IndexUpdate> update = on_indexed->TryPopFront();
|
||||||
if (!update)
|
if (!update)
|
||||||
break;
|
break;
|
||||||
did_work = true;
|
did_work = true;
|
||||||
|
indexed = true;
|
||||||
Main_OnIndexed(&db, &highlight, &working_files, &*update);
|
Main_OnIndexed(&db, &highlight, &working_files, &*update);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!did_work) {
|
if (!did_work) {
|
||||||
FreeUnusedMemory();
|
if (last_indexed)
|
||||||
|
FreeUnusedMemory();
|
||||||
main_waiter->Wait(on_indexed, on_request);
|
main_waiter->Wait(on_indexed, on_request);
|
||||||
}
|
}
|
||||||
|
last_indexed = indexed;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ std::string NormalizePath(const std::string &path) {
|
|||||||
|
|
||||||
void FreeUnusedMemory() {
|
void FreeUnusedMemory() {
|
||||||
#ifdef __GLIBC__
|
#ifdef __GLIBC__
|
||||||
malloc_trim(0);
|
malloc_trim(4 * 1024 * 1024);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -13,18 +13,14 @@
|
|||||||
#include "serializers/json.h"
|
#include "serializers/json.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "working_files.h"
|
#include "working_files.h"
|
||||||
using namespace ccls;
|
|
||||||
|
|
||||||
#include <clang/Driver/Compilation.h>
|
#include <clang/Driver/Compilation.h>
|
||||||
#include <clang/Driver/Driver.h>
|
#include <clang/Driver/Driver.h>
|
||||||
#include <clang/Frontend/CompilerInstance.h>
|
#include <clang/Frontend/CompilerInstance.h>
|
||||||
#include <clang/Tooling/CompilationDatabase.h>
|
#include <clang/Tooling/CompilationDatabase.h>
|
||||||
#include <llvm/ADT/ArrayRef.h>
|
|
||||||
#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>
|
||||||
using namespace clang;
|
|
||||||
using namespace llvm;
|
|
||||||
|
|
||||||
#include <rapidjson/writer.h>
|
#include <rapidjson/writer.h>
|
||||||
|
|
||||||
@ -32,10 +28,14 @@ using namespace llvm;
|
|||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <limits>
|
#include <limits.h>
|
||||||
#include <unordered_set>
|
#include <unordered_set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
using namespace ccls;
|
||||||
|
using namespace clang;
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand };
|
enum class ProjectMode { CompileCommandsJson, DotCcls, ExternalCommand };
|
||||||
@ -387,7 +387,7 @@ Project::FindCompilationEntryForFile(const std::string &filename) {
|
|||||||
// We couldn't find the file. Try to infer it.
|
// We couldn't find the file. Try to infer it.
|
||||||
// TODO: Cache inferred file in a separate array (using a lock or similar)
|
// TODO: Cache inferred file in a separate array (using a lock or similar)
|
||||||
Entry *best_entry = nullptr;
|
Entry *best_entry = nullptr;
|
||||||
int best_score = std::numeric_limits<int>::min();
|
int best_score = INT_MIN;
|
||||||
for (Entry &entry : entries) {
|
for (Entry &entry : entries) {
|
||||||
int score = ComputeGuessScore(filename, entry.filename);
|
int score = ComputeGuessScore(filename, entry.filename);
|
||||||
if (score > best_score) {
|
if (score > best_score) {
|
||||||
|
@ -154,12 +154,11 @@ void Reflect(Reader &vis, DenseMap<CachedHashStringRef, int64_t> &v) {
|
|||||||
if (vis.Format() == SerializeFormat::Json) {
|
if (vis.Format() == SerializeFormat::Json) {
|
||||||
auto &vis1 = static_cast<JsonReader&>(vis);
|
auto &vis1 = static_cast<JsonReader&>(vis);
|
||||||
for (auto it = vis1.m().MemberBegin(); it != vis1.m().MemberEnd(); ++it)
|
for (auto it = vis1.m().MemberBegin(); it != vis1.m().MemberEnd(); ++it)
|
||||||
v[CachedHashStringRef(Intern(it->name.GetString()))] =
|
v[InternH(it->name.GetString())] = it->value.GetInt64();
|
||||||
it->value.GetInt64();
|
|
||||||
} else {
|
} else {
|
||||||
vis.IterArray([&](Reader &entry) {
|
vis.IterArray([&](Reader &entry) {
|
||||||
Reflect(entry, name);
|
Reflect(entry, name);
|
||||||
Reflect(entry, v[CachedHashStringRef(Intern(name))]);
|
Reflect(entry, v[InternH(name)]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -344,18 +343,26 @@ void Reflect(Writer &visitor, SerializeFormat &value) {
|
|||||||
|
|
||||||
namespace ccls {
|
namespace ccls {
|
||||||
static BumpPtrAllocator Alloc;
|
static BumpPtrAllocator Alloc;
|
||||||
static DenseSet<StringRef> Strings;
|
static DenseSet<CachedHashStringRef> Strings;
|
||||||
static std::mutex AllocMutex;
|
static std::mutex AllocMutex;
|
||||||
|
|
||||||
const char *Intern(const std::string &str) {
|
CachedHashStringRef InternH(StringRef S) {
|
||||||
if (str.empty())
|
if (S.empty())
|
||||||
return "";
|
S = "";
|
||||||
StringRef Str(str.data(), str.size() + 1);
|
CachedHashString HS(S);
|
||||||
std::lock_guard lock(AllocMutex);
|
std::lock_guard lock(AllocMutex);
|
||||||
auto R = Strings.insert(Str);
|
auto R = Strings.insert(HS);
|
||||||
if (R.second)
|
if (R.second) {
|
||||||
*R.first = Str.copy(Alloc);
|
char *P = Alloc.Allocate<char>(S.size() + 1);
|
||||||
return R.first->data();
|
memcpy(P, S.data(), S.size());
|
||||||
|
P[S.size()] = '\0';
|
||||||
|
*R.first = CachedHashStringRef(StringRef(P, S.size()), HS.hash());
|
||||||
|
}
|
||||||
|
return *R.first;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Intern(StringRef S) {
|
||||||
|
return InternH(S).val().data();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string Serialize(SerializeFormat format, IndexFile &file) {
|
std::string Serialize(SerializeFormat format, IndexFile &file) {
|
||||||
@ -470,7 +477,7 @@ Deserialize(SerializeFormat format, const std::string &path,
|
|||||||
for (auto &it : file->dependencies) {
|
for (auto &it : file->dependencies) {
|
||||||
std::string path = it.first.val().str();
|
std::string path = it.first.val().str();
|
||||||
DoPathMapping(path);
|
DoPathMapping(path);
|
||||||
dependencies[CachedHashStringRef(Intern(path))] = it.second;
|
dependencies[InternH(path)] = it.second;
|
||||||
}
|
}
|
||||||
file->dependencies = std::move(dependencies);
|
file->dependencies = std::move(dependencies);
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,11 @@
|
|||||||
#include <type_traits>
|
#include <type_traits>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
class CachedHashStringRef;
|
||||||
|
class StringRef;
|
||||||
|
}
|
||||||
|
|
||||||
enum class SerializeFormat { Binary, Json };
|
enum class SerializeFormat { Binary, Json };
|
||||||
|
|
||||||
struct JsonNull {};
|
struct JsonNull {};
|
||||||
@ -308,7 +313,8 @@ template <typename T> void ReflectMember(Writer &vis, const char *name, T &v) {
|
|||||||
// API
|
// API
|
||||||
|
|
||||||
namespace ccls {
|
namespace ccls {
|
||||||
const char *Intern(const std::string &str);
|
const char *Intern(llvm::StringRef str);
|
||||||
|
llvm::CachedHashStringRef InternH(llvm::StringRef str);
|
||||||
std::string Serialize(SerializeFormat format, IndexFile &file);
|
std::string Serialize(SerializeFormat format, IndexFile &file);
|
||||||
std::unique_ptr<IndexFile>
|
std::unique_ptr<IndexFile>
|
||||||
Deserialize(SerializeFormat format, const std::string &path,
|
Deserialize(SerializeFormat format, const std::string &path,
|
||||||
|
Loading…
Reference in New Issue
Block a user