diff --git a/src/project.cc b/src/project.cc index f547d6a2..54248750 100644 --- a/src/project.cc +++ b/src/project.cc @@ -75,7 +75,11 @@ enum OptionClass { struct ProjectProcessor { ProjectConfig *config; std::unordered_set command_set; - ProjectProcessor(ProjectConfig *config) : config(config) {} + StringSet<> excludeArgs; + ProjectProcessor(ProjectConfig *config) : config(config) { + for (auto &arg : g_config->clang.excludeArgs) + excludeArgs.insert(arg); + } void Process(Project::Entry &entry) { const std::string base_name = sys::path::filename(entry.filename); @@ -93,7 +97,7 @@ struct ProjectProcessor { args.push_back(arg + 5); } else if (strcmp(arg, "%clang") == 0) { args.push_back(lang == LanguageId::Cpp ? "clang++" : "clang"); - } else if (!llvm::is_contained(g_config->clang.excludeArgs, arg)) { + } else if (!excludeArgs.count(arg)) { args.push_back(arg); } } @@ -103,22 +107,30 @@ struct ProjectProcessor { args.push_back(Intern(arg)); size_t hash = std::hash{}(entry.directory); + bool OPT_o = false; for (auto &arg : args) { - if (arg[0] != '-' && EndsWith(arg, base_name)) { + bool last_o = OPT_o; + OPT_o = false; + if (arg[0] == '-') { + OPT_o = arg[1] == 'o' && arg[2] == '\0'; + if (OPT_o || arg[1] == 'D' || arg[1] == 'W') + continue; + } else if (last_o) { + continue; + } else if (sys::path::filename(arg) == base_name) { LanguageId lang = lookupExtension(arg).first; if (lang != LanguageId::Unknown) { - hash_combine(hash, size_t(lang)); + hash_combine(hash, (size_t)lang); continue; } } - hash_combine(hash, std::hash{}(arg)); + hash_combine(hash, std::hash{}(arg)); } args.push_back(Intern("-working-directory=" + entry.directory)); - - if (!command_set.insert(hash).second) { - entry.args = std::move(args); + entry.args = args; + args.push_back("-fsyntax-only"); + if (!command_set.insert(hash).second) return; - } // a weird C++ deduction guide heap-use-after-free causes libclang to crash. IgnoringDiagConsumer DiagC; @@ -137,8 +149,6 @@ struct ProjectProcessor { } Driver.setCheckInputsExist(false); - args.push_back("-fsyntax-only"); - std::unique_ptr C(Driver.BuildCompilation(args)); const driver::JobList &Jobs = C->getJobs(); if (Jobs.size() != 1) @@ -168,7 +178,6 @@ struct ProjectProcessor { break; } } - entry.args = std::move(args); } };