mirror of
https://github.com/MaskRay/ccls.git
synced 2025-01-19 03:55:49 +00:00
Add loose mode in project.cc
This commit is contained in:
parent
f9d7361953
commit
e83fce65c2
@ -289,8 +289,13 @@ void TraceMe() {
|
||||
std::string GetExternalCommandOutput(const std::vector<std::string>& command,
|
||||
std::string_view input) {
|
||||
int pin[2], pout[2];
|
||||
pipe(pin);
|
||||
pipe(pout);
|
||||
if (pipe(pin) < 0)
|
||||
return "";
|
||||
if (pipe(pout) < 0) {
|
||||
close(pin[0]);
|
||||
close(pin[1]);
|
||||
return "";
|
||||
}
|
||||
pid_t child = fork();
|
||||
if (child == 0) {
|
||||
dup2(pout[0], 0);
|
||||
|
@ -97,15 +97,18 @@ bool ShouldAddToAngleIncludes(const std::string& arg) {
|
||||
return StartsWithAny(arg, kAngleIncludeArgs);
|
||||
}
|
||||
|
||||
optional<std::string> SourceFileType(const std::string& path) {
|
||||
// FIXME
|
||||
enum class LanguageId { Unknown = 0, C = 1, Cpp = 2, ObjC = 3, ObjCpp = 4 };
|
||||
|
||||
optional<LanguageId> SourceFileType(const std::string& path) {
|
||||
if (EndsWith(path, ".c"))
|
||||
return std::string("c");
|
||||
return LanguageId::C;
|
||||
else if (EndsWith(path, ".cpp") || EndsWith(path, ".cc"))
|
||||
return std::string("c++");
|
||||
return LanguageId::Cpp;
|
||||
else if (EndsWith(path, ".mm"))
|
||||
return std::string("objective-c++");
|
||||
return LanguageId::ObjCpp;
|
||||
else if (EndsWith(path, ".m"))
|
||||
return std::string("objective-c");
|
||||
return LanguageId::ObjC;
|
||||
return nullopt;
|
||||
}
|
||||
|
||||
@ -131,8 +134,14 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
result.filename = NormalizePathWithTestOptOut(entry.file);
|
||||
std::string base_name = GetBaseName(entry.file);
|
||||
|
||||
// If |compilationDatabaseCommand| is specified, the external command provides
|
||||
// us the JSON compilation database which should be strict. We should do very
|
||||
// little processing on |entry.args|. The
|
||||
bool loose = init_opts->compilationDatabaseCommand.empty();
|
||||
|
||||
size_t i = 0;
|
||||
|
||||
if (loose) {
|
||||
// Strip all arguments consisting the compiler command,
|
||||
// as there may be non-compiler related commands beforehand,
|
||||
// ie, compiler schedular such as goma. This allows correct parsing for
|
||||
@ -151,16 +160,13 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
dot + 4 < entry.args[i].size() || isdigit(entry.args[i][dot + 1]) ||
|
||||
!entry.args[i].compare(dot + 1, 3, "exe")))
|
||||
++i;
|
||||
// Include the compiler in the args.
|
||||
} else {
|
||||
if (entry.args.size())
|
||||
i = 1;
|
||||
}
|
||||
// Compiler driver.
|
||||
if (i > 0)
|
||||
result.args.push_back(entry.args[i - 1]);
|
||||
else {
|
||||
// TODO Drop this back compatibility
|
||||
// Args probably came from a /.cquery file, which likely has just flags.
|
||||
// clang_parseTranslationUnit2FullArgv() expects the binary path as the
|
||||
// first arg, so the first flag would end up being ignored. Add a dummy.
|
||||
result.args.push_back("clang++");
|
||||
}
|
||||
|
||||
// Add -working-directory if not provided.
|
||||
if (!AnyStartsWith(entry.args, "-working-directory")) {
|
||||
@ -168,19 +174,26 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
result.args.push_back(entry.directory);
|
||||
}
|
||||
|
||||
// Clang does not have good hueristics for determining source language, we
|
||||
// should explicitly specify it.
|
||||
if (optional<std::string> file_type = SourceFileType(entry.file)) {
|
||||
if (loose) {
|
||||
// FIXME
|
||||
if (auto lang = SourceFileType(entry.file)) {
|
||||
if (!AnyStartsWith(entry.args, "-x")) {
|
||||
result.args.push_back("-x" + *file_type);
|
||||
switch (*lang) {
|
||||
case LanguageId::Unknown: break;
|
||||
case LanguageId::C: result.args.push_back("-xc"); break;
|
||||
case LanguageId::Cpp: result.args.push_back("-xc++"); break;
|
||||
case LanguageId::ObjC: result.args.push_back("-xobjective-c"); break;
|
||||
case LanguageId::ObjCpp: result.args.push_back("-xobjective-cpp"); break;
|
||||
}
|
||||
}
|
||||
if (!AnyStartsWith(entry.args, "-std=")) {
|
||||
if (*file_type == "c")
|
||||
if (*lang == LanguageId::C)
|
||||
result.args.push_back("-std=gnu11");
|
||||
else if (*file_type == "c++")
|
||||
else if (*lang == LanguageId::Cpp)
|
||||
result.args.push_back("-std=c++14");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool next_flag_is_path = false;
|
||||
bool add_next_flag_to_quote_dirs = false;
|
||||
@ -215,9 +228,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
|
||||
next_flag_is_path = false;
|
||||
add_next_flag_to_quote_dirs = false;
|
||||
add_next_flag_to_angle_dirs = false;
|
||||
}
|
||||
|
||||
else {
|
||||
} else {
|
||||
// Check to see if arg is a path and needs to be updated.
|
||||
for (const std::string& flag_type : kPathArgs) {
|
||||
// {"-I", "foo"} style.
|
||||
@ -551,7 +562,18 @@ Project::Entry Project::FindCompilationEntryForFile(
|
||||
result.filename = filename;
|
||||
if (!best_entry) {
|
||||
// FIXME
|
||||
if (auto lang = SourceFileType(filename)) {
|
||||
switch (*lang) {
|
||||
case LanguageId::C:
|
||||
result.args.push_back("clang");
|
||||
break;
|
||||
case LanguageId::Cpp:
|
||||
result.args.push_back("clang++");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
result.args.push_back(filename);
|
||||
} else {
|
||||
result.args = best_entry->args;
|
||||
@ -687,9 +709,9 @@ TEST_SUITE("Project") {
|
||||
TEST_CASE("Implied binary") {
|
||||
CheckFlags(
|
||||
"/home/user", "/home/user/foo/bar.cc",
|
||||
/* raw */ {"-DDONT_IGNORE_ME"},
|
||||
/* raw */ {"clang", "-DDONT_IGNORE_ME"},
|
||||
/* expected */
|
||||
{"clang++", "-working-directory", "/home/user", "-xc++", "-std=c++14",
|
||||
{"clang", "-working-directory", "/home/user", "-xc++", "-std=c++14",
|
||||
"-DDONT_IGNORE_ME", "-resource-dir=/w/resource_dir/",
|
||||
"-Wno-unknown-warning-option", "-fparse-all-comments"});
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user