mirror of
https://github.com/MaskRay/ccls.git
synced 2025-01-19 12:05:50 +00:00
Serialize clang_parseTranslationUnit2FullArgv requests.
Also try to emit diagnostics when translation unit creation fails.
This commit is contained in:
parent
29185c2fe3
commit
f1f2cc3bd1
@ -1,5 +1,6 @@
|
||||
#include "clang_translation_unit.h"
|
||||
|
||||
#include "clang_utils.h"
|
||||
#include "platform.h"
|
||||
#include "utils.h"
|
||||
|
||||
@ -8,8 +9,65 @@
|
||||
#include <cassert>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <mutex>
|
||||
#include <sstream>
|
||||
|
||||
namespace {
|
||||
|
||||
// We need to serialize requests to clang_parseTranslationUnit2FullArgv and
|
||||
// clang_reparseTranslationUnit. See
|
||||
// https://github.com/jacobdufault/cquery/issues/43#issuecomment-347614504.
|
||||
std::mutex g_parse_translation_unit_mutex;
|
||||
std::mutex g_reparse_translation_unit_mutex;
|
||||
|
||||
void EmitDiagnostics(std::string path, CXTranslationUnit tu) {
|
||||
std::string output = "Fatal errors while trying to parse " + path + "\n";
|
||||
|
||||
size_t num_diagnostics = clang_getNumDiagnostics(tu);
|
||||
for (unsigned i = 0; i < num_diagnostics; ++i) {
|
||||
output += " - ";
|
||||
|
||||
CXDiagnostic diagnostic = clang_getDiagnostic(tu, i);
|
||||
|
||||
// Location.
|
||||
CXFile file;
|
||||
unsigned int line, column;
|
||||
clang_getSpellingLocation(clang_getDiagnosticLocation(diagnostic), &file,
|
||||
&line, &column, nullptr);
|
||||
std::string path = FileName(file);
|
||||
output += path + ":" + std::to_string(line - 1) + ":" +
|
||||
std::to_string(column) + " ";
|
||||
|
||||
// Severity
|
||||
switch (clang_getDiagnosticSeverity(diagnostic)) {
|
||||
case CXDiagnostic_Ignored:
|
||||
case CXDiagnostic_Note:
|
||||
output += "[info]";
|
||||
break;
|
||||
case CXDiagnostic_Warning:
|
||||
output += "[warning]";
|
||||
break;
|
||||
case CXDiagnostic_Error:
|
||||
output += "[error]";
|
||||
break;
|
||||
case CXDiagnostic_Fatal:
|
||||
output += "[fatal]";
|
||||
break;
|
||||
}
|
||||
|
||||
// Content.
|
||||
output += " " + ToString(clang_getDiagnosticSpelling(diagnostic));
|
||||
|
||||
clang_disposeDiagnostic(diagnostic);
|
||||
|
||||
output += "\n";
|
||||
}
|
||||
|
||||
std::cerr << output;
|
||||
std::cerr.flush();
|
||||
}
|
||||
} // namespace
|
||||
|
||||
// static
|
||||
std::unique_ptr<ClangTranslationUnit> ClangTranslationUnit::Create(
|
||||
ClangIndex* index,
|
||||
@ -26,9 +84,16 @@ std::unique_ptr<ClangTranslationUnit> ClangTranslationUnit::Create(
|
||||
args.push_back(arg.c_str());
|
||||
|
||||
CXTranslationUnit cx_tu;
|
||||
CXErrorCode error_code = clang_parseTranslationUnit2FullArgv(
|
||||
CXErrorCode error_code;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_parse_translation_unit_mutex);
|
||||
error_code = clang_parseTranslationUnit2FullArgv(
|
||||
index->cx_index, filepath.c_str(), args.data(), (int)args.size(),
|
||||
unsaved_files.data(), (unsigned)unsaved_files.size(), flags, &cx_tu);
|
||||
}
|
||||
|
||||
if (error_code != CXError_Success && cx_tu)
|
||||
EmitDiagnostics(filepath, cx_tu);
|
||||
|
||||
switch (error_code) {
|
||||
case CXError_Success:
|
||||
@ -58,9 +123,17 @@ std::unique_ptr<ClangTranslationUnit> ClangTranslationUnit::Create(
|
||||
std::unique_ptr<ClangTranslationUnit> ClangTranslationUnit::Reparse(
|
||||
std::unique_ptr<ClangTranslationUnit> tu,
|
||||
std::vector<CXUnsavedFile>& unsaved) {
|
||||
int error_code = clang_reparseTranslationUnit(
|
||||
int error_code;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(g_reparse_translation_unit_mutex);
|
||||
error_code = clang_reparseTranslationUnit(
|
||||
tu->cx_tu, (unsigned)unsaved.size(), unsaved.data(),
|
||||
clang_defaultReparseOptions(tu->cx_tu));
|
||||
}
|
||||
|
||||
if (error_code != CXError_Success && tu->cx_tu)
|
||||
EmitDiagnostics("<unknown>", tu->cx_tu);
|
||||
|
||||
switch (error_code) {
|
||||
case CXError_Success:
|
||||
return tu;
|
||||
|
Loading…
Reference in New Issue
Block a user