111 lines
4.0 KiB
C++
111 lines
4.0 KiB
C++
//===--- GlobalSymbolBuilderMain.cpp -----------------------------*- C++-*-===//
|
|
//
|
|
// The LLVM Compiler Infrastructure
|
|
//
|
|
// This file is distributed under the University of Illinois Open Source
|
|
// License. See LICENSE.TXT for details.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// GlobalSymbolBuilder is a tool to generate YAML-format symbols across the
|
|
// whole project. This tools is for **experimental** only. Don't use it in
|
|
// production code.
|
|
//
|
|
//===---------------------------------------------------------------------===//
|
|
|
|
#include "index/Index.h"
|
|
#include "index/SymbolCollector.h"
|
|
#include "index/SymbolYAML.h"
|
|
#include "clang/Frontend/FrontendActions.h"
|
|
#include "clang/Index/IndexingAction.h"
|
|
#include "clang/Index/IndexDataConsumer.h"
|
|
#include "clang/Tooling/CommonOptionsParser.h"
|
|
#include "clang/Tooling/Tooling.h"
|
|
#include "clang/Tooling/CommonOptionsParser.h"
|
|
#include "llvm/Support/MemoryBuffer.h"
|
|
#include "llvm/Support/Signals.h"
|
|
#include "llvm/Support/Path.h"
|
|
#include "llvm/Support/CommandLine.h"
|
|
#include "llvm/Support/ThreadPool.h"
|
|
|
|
using namespace llvm;
|
|
using namespace clang::tooling;
|
|
using clang::clangd::SymbolSlab;
|
|
|
|
namespace clang {
|
|
namespace clangd {
|
|
|
|
class SymbolIndexActionFactory : public tooling::FrontendActionFactory {
|
|
public:
|
|
SymbolIndexActionFactory() = default;
|
|
|
|
clang::FrontendAction *create() override {
|
|
index::IndexingOptions IndexOpts;
|
|
IndexOpts.SystemSymbolFilter =
|
|
index::IndexingOptions::SystemSymbolFilterKind::All;
|
|
IndexOpts.IndexFunctionLocals = false;
|
|
Collector = std::make_shared<SymbolCollector>();
|
|
return index::createIndexingAction(Collector, IndexOpts, nullptr).release();
|
|
}
|
|
|
|
std::shared_ptr<SymbolCollector> Collector;
|
|
};
|
|
|
|
} // namespace clangd
|
|
} // namespace clang
|
|
|
|
int main(int argc, const char **argv) {
|
|
llvm::sys::PrintStackTraceOnErrorSignal(argv[0]);
|
|
|
|
const char* Overview =
|
|
"This is an **experimental** tool to generate YAML-format "
|
|
"project-wide symbols for clangd (global code completion). It would be "
|
|
"changed and deprecated eventually. Don't use it in production code!";
|
|
CommonOptionsParser OptionsParser(argc, argv, cl::GeneralCategory,
|
|
/*Overview=*/Overview);
|
|
|
|
// No compilation database found, fallback to single TU analysis, this is
|
|
// mainly for debugging purpose:
|
|
// global-symbol-buidler /tmp/t.cc -- -std=c++11.
|
|
if (OptionsParser.getCompilations().getAllFiles().empty()) {
|
|
llvm::errs() << "No compilation database found, processing individual "
|
|
"files with flags from command-line\n.";
|
|
ClangTool Tool(OptionsParser.getCompilations(),
|
|
OptionsParser.getSourcePathList());
|
|
clang::clangd::SymbolIndexActionFactory IndexAction;
|
|
Tool.run(&IndexAction);
|
|
llvm::outs() << SymbolToYAML(IndexAction.Collector->takeSymbols());
|
|
return 0;
|
|
}
|
|
|
|
// Found compilation database, we iterate all TUs from database to get all
|
|
// symbols, and then merge them into a single SymbolSlab.
|
|
SymbolSlab::Builder GlobalSymbols;
|
|
std::mutex SymbolMutex;
|
|
auto AddSymbols = [&](const SymbolSlab& NewSymbols) {
|
|
// Synchronize set accesses.
|
|
std::unique_lock<std::mutex> LockGuard(SymbolMutex);
|
|
for (auto Sym : NewSymbols) {
|
|
// FIXME: Better handling the overlap symbols, currently we overwrite it
|
|
// with the latest one, but we always want to good declarations (class
|
|
// definitions, instead of forward declarations).
|
|
GlobalSymbols.insert(Sym);
|
|
}
|
|
};
|
|
|
|
{
|
|
llvm::ThreadPool Pool;
|
|
for (auto& file : OptionsParser.getCompilations().getAllFiles()) {
|
|
Pool.async([&OptionsParser, &AddSymbols](llvm::StringRef Path) {
|
|
ClangTool Tool(OptionsParser.getCompilations(), {Path});
|
|
clang::clangd::SymbolIndexActionFactory IndexAction;
|
|
Tool.run(&IndexAction);
|
|
AddSymbols(IndexAction.Collector->takeSymbols());
|
|
}, file);
|
|
}
|
|
}
|
|
|
|
llvm::outs() << SymbolToYAML(std::move(GlobalSymbols).build());
|
|
return 0;
|
|
}
|