forked from OSchip/llvm-project
85 lines
3.0 KiB
C++
85 lines
3.0 KiB
C++
#include "IndexAction.h"
|
|
#include "clang/Frontend/CompilerInstance.h"
|
|
#include "clang/Index/IndexDataConsumer.h"
|
|
#include "clang/Index/IndexingAction.h"
|
|
#include "clang/Tooling/Tooling.h"
|
|
|
|
using namespace llvm;
|
|
namespace clang {
|
|
namespace clangd {
|
|
namespace {
|
|
|
|
// Wraps the index action and reports index data after each translation unit.
|
|
class IndexAction : public WrapperFrontendAction {
|
|
public:
|
|
IndexAction(std::shared_ptr<SymbolCollector> C,
|
|
std::unique_ptr<CanonicalIncludes> Includes,
|
|
const index::IndexingOptions &Opts,
|
|
std::function<void(SymbolSlab)> SymbolsCallback,
|
|
std::function<void(RefSlab)> RefsCallback)
|
|
: WrapperFrontendAction(index::createIndexingAction(C, Opts, nullptr)),
|
|
SymbolsCallback(SymbolsCallback), RefsCallback(RefsCallback),
|
|
Collector(C), Includes(std::move(Includes)),
|
|
PragmaHandler(collectIWYUHeaderMaps(this->Includes.get())) {}
|
|
|
|
std::unique_ptr<ASTConsumer> CreateASTConsumer(CompilerInstance &CI,
|
|
StringRef InFile) override {
|
|
CI.getPreprocessor().addCommentHandler(PragmaHandler.get());
|
|
return WrapperFrontendAction::CreateASTConsumer(CI, InFile);
|
|
}
|
|
|
|
bool BeginInvocation(CompilerInstance &CI) override {
|
|
// We want all comments, not just the doxygen ones.
|
|
CI.getLangOpts().CommentOpts.ParseAllComments = true;
|
|
return WrapperFrontendAction::BeginInvocation(CI);
|
|
}
|
|
|
|
void EndSourceFileAction() override {
|
|
WrapperFrontendAction::EndSourceFileAction();
|
|
|
|
const auto &CI = getCompilerInstance();
|
|
if (CI.hasDiagnostics() &&
|
|
CI.getDiagnostics().hasUncompilableErrorOccurred()) {
|
|
errs() << "Skipping TU due to uncompilable errors\n";
|
|
return;
|
|
}
|
|
SymbolsCallback(Collector->takeSymbols());
|
|
if (RefsCallback != nullptr)
|
|
RefsCallback(Collector->takeRefs());
|
|
}
|
|
|
|
private:
|
|
std::function<void(SymbolSlab)> SymbolsCallback;
|
|
std::function<void(RefSlab)> RefsCallback;
|
|
std::shared_ptr<SymbolCollector> Collector;
|
|
std::unique_ptr<CanonicalIncludes> Includes;
|
|
std::unique_ptr<CommentHandler> PragmaHandler;
|
|
};
|
|
|
|
} // namespace
|
|
|
|
std::unique_ptr<FrontendAction>
|
|
createStaticIndexingAction(SymbolCollector::Options Opts,
|
|
std::function<void(SymbolSlab)> SymbolsCallback,
|
|
std::function<void(RefSlab)> RefsCallback) {
|
|
index::IndexingOptions IndexOpts;
|
|
IndexOpts.SystemSymbolFilter =
|
|
index::IndexingOptions::SystemSymbolFilterKind::All;
|
|
Opts.CollectIncludePath = true;
|
|
Opts.CountReferences = true;
|
|
Opts.Origin = SymbolOrigin::Static;
|
|
if (RefsCallback != nullptr) {
|
|
Opts.RefFilter = RefKind::All;
|
|
Opts.RefsInHeaders = true;
|
|
}
|
|
auto Includes = llvm::make_unique<CanonicalIncludes>();
|
|
addSystemHeadersMapping(Includes.get());
|
|
Opts.Includes = Includes.get();
|
|
return llvm::make_unique<IndexAction>(
|
|
std::make_shared<SymbolCollector>(std::move(Opts)), std::move(Includes),
|
|
IndexOpts, SymbolsCallback, RefsCallback);
|
|
}
|
|
|
|
} // namespace clangd
|
|
} // namespace clang
|