Add loose mode in project.cc

This commit is contained in:
Fangrui Song 2018-02-19 17:19:50 -08:00
parent f9d7361953
commit e83fce65c2
2 changed files with 77 additions and 50 deletions

View File

@ -289,8 +289,13 @@ void TraceMe() {
std::string GetExternalCommandOutput(const std::vector<std::string>& command, std::string GetExternalCommandOutput(const std::vector<std::string>& command,
std::string_view input) { std::string_view input) {
int pin[2], pout[2]; int pin[2], pout[2];
pipe(pin); if (pipe(pin) < 0)
pipe(pout); return "";
if (pipe(pout) < 0) {
close(pin[0]);
close(pin[1]);
return "";
}
pid_t child = fork(); pid_t child = fork();
if (child == 0) { if (child == 0) {
dup2(pout[0], 0); dup2(pout[0], 0);

View File

@ -97,15 +97,18 @@ bool ShouldAddToAngleIncludes(const std::string& arg) {
return StartsWithAny(arg, kAngleIncludeArgs); 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")) if (EndsWith(path, ".c"))
return std::string("c"); return LanguageId::C;
else if (EndsWith(path, ".cpp") || EndsWith(path, ".cc")) else if (EndsWith(path, ".cpp") || EndsWith(path, ".cc"))
return std::string("c++"); return LanguageId::Cpp;
else if (EndsWith(path, ".mm")) else if (EndsWith(path, ".mm"))
return std::string("objective-c++"); return LanguageId::ObjCpp;
else if (EndsWith(path, ".m")) else if (EndsWith(path, ".m"))
return std::string("objective-c"); return LanguageId::ObjC;
return nullopt; return nullopt;
} }
@ -131,8 +134,14 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
result.filename = NormalizePathWithTestOptOut(entry.file); result.filename = NormalizePathWithTestOptOut(entry.file);
std::string base_name = GetBaseName(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; size_t i = 0;
if (loose) {
// Strip all arguments consisting the compiler command, // Strip all arguments consisting the compiler command,
// as there may be non-compiler related commands beforehand, // as there may be non-compiler related commands beforehand,
// ie, compiler schedular such as goma. This allows correct parsing for // 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]) || dot + 4 < entry.args[i].size() || isdigit(entry.args[i][dot + 1]) ||
!entry.args[i].compare(dot + 1, 3, "exe"))) !entry.args[i].compare(dot + 1, 3, "exe")))
++i; ++i;
// Include the compiler in the args. } else {
if (entry.args.size())
i = 1;
}
// Compiler driver.
if (i > 0) if (i > 0)
result.args.push_back(entry.args[i - 1]); 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. // Add -working-directory if not provided.
if (!AnyStartsWith(entry.args, "-working-directory")) { if (!AnyStartsWith(entry.args, "-working-directory")) {
@ -168,19 +174,26 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
result.args.push_back(entry.directory); result.args.push_back(entry.directory);
} }
// Clang does not have good hueristics for determining source language, we if (loose) {
// should explicitly specify it. // FIXME
if (optional<std::string> file_type = SourceFileType(entry.file)) { if (auto lang = SourceFileType(entry.file)) {
if (!AnyStartsWith(entry.args, "-x")) { 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 (!AnyStartsWith(entry.args, "-std=")) {
if (*file_type == "c") if (*lang == LanguageId::C)
result.args.push_back("-std=gnu11"); result.args.push_back("-std=gnu11");
else if (*file_type == "c++") else if (*lang == LanguageId::Cpp)
result.args.push_back("-std=c++14"); result.args.push_back("-std=c++14");
} }
} }
}
bool next_flag_is_path = false; bool next_flag_is_path = false;
bool add_next_flag_to_quote_dirs = false; bool add_next_flag_to_quote_dirs = false;
@ -215,9 +228,7 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry(
next_flag_is_path = false; next_flag_is_path = false;
add_next_flag_to_quote_dirs = false; add_next_flag_to_quote_dirs = false;
add_next_flag_to_angle_dirs = false; add_next_flag_to_angle_dirs = false;
} } else {
else {
// Check to see if arg is a path and needs to be updated. // Check to see if arg is a path and needs to be updated.
for (const std::string& flag_type : kPathArgs) { for (const std::string& flag_type : kPathArgs) {
// {"-I", "foo"} style. // {"-I", "foo"} style.
@ -551,7 +562,18 @@ Project::Entry Project::FindCompilationEntryForFile(
result.filename = filename; result.filename = filename;
if (!best_entry) { if (!best_entry) {
// FIXME // 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++"); result.args.push_back("clang++");
break;
default:
break;
}
}
result.args.push_back(filename); result.args.push_back(filename);
} else { } else {
result.args = best_entry->args; result.args = best_entry->args;
@ -687,9 +709,9 @@ TEST_SUITE("Project") {
TEST_CASE("Implied binary") { TEST_CASE("Implied binary") {
CheckFlags( CheckFlags(
"/home/user", "/home/user/foo/bar.cc", "/home/user", "/home/user/foo/bar.cc",
/* raw */ {"-DDONT_IGNORE_ME"}, /* raw */ {"clang", "-DDONT_IGNORE_ME"},
/* expected */ /* 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/", "-DDONT_IGNORE_ME", "-resource-dir=/w/resource_dir/",
"-Wno-unknown-warning-option", "-fparse-all-comments"}); "-Wno-unknown-warning-option", "-fparse-all-comments"});
} }