mirror of
				https://github.com/MaskRay/ccls.git
				synced 2025-10-30 20:22:38 +00:00 
			
		
		
		
	Support %c %cpp %clang in clang command line and remove -std=gnu11 -std=gnu++14 defaults
If you want to mix C/C++ source files in a `.cquery` project: echo -e '%clang\n%cpp -std=gnu++14' > .cquery
This commit is contained in:
		
							parent
							
								
									62e6f91808
								
							
						
					
					
						commit
						b53c41408e
					
				| @ -134,17 +134,35 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( | |||||||
| 
 | 
 | ||||||
|   Project::Entry result; |   Project::Entry result; | ||||||
|   result.filename = NormalizePathWithTestOptOut(entry.file); |   result.filename = NormalizePathWithTestOptOut(entry.file); | ||||||
|   if (entry.args.empty()) |   const std::string base_name = GetBaseName(entry.file); | ||||||
|  | 
 | ||||||
|  |   // Expand %c %cpp %clang
 | ||||||
|  |   std::vector<std::string> args; | ||||||
|  |   const LanguageId lang = SourceFileLanguage(entry.file); | ||||||
|  |   for (const std::string& arg : entry.args) { | ||||||
|  |     if (arg.compare(0, 3, "%c ") == 0) { | ||||||
|  |       if (lang == LanguageId::C) | ||||||
|  |         args.push_back(arg.substr(3)); | ||||||
|  |     } else if (arg.compare(0, 5, "%cpp ") == 0) { | ||||||
|  |       if (lang == LanguageId::Cpp) | ||||||
|  |         args.push_back(arg.substr(5)); | ||||||
|  |     } else if (arg == "%clang") { | ||||||
|  |       args.push_back(lang == LanguageId::Cpp ? "clang++" : "clang"); | ||||||
|  |     } else { | ||||||
|  |       args.push_back(arg); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  |   if (args.empty()) | ||||||
|     return result; |     return result; | ||||||
|   std::string base_name = GetBaseName(entry.file); | 
 | ||||||
|   bool clang_cl = strstr(entry.args[0].c_str(), "clang-cl") || |   bool clang_cl = strstr(args[0].c_str(), "clang-cl") || | ||||||
|                   strstr(entry.args[0].c_str(), "cl.exe") || |                   strstr(args[0].c_str(), "cl.exe") || | ||||||
|                   AnyStartsWith(entry.args, "--driver-mode=cl"); |                   AnyStartsWith(args, "--driver-mode=cl"); | ||||||
|   size_t i = 1; |   size_t i = 1; | ||||||
| 
 | 
 | ||||||
|   // If |compilationDatabaseCommand| is specified, the external command provides
 |   // If |compilationDatabaseCommand| is specified, the external command provides
 | ||||||
|   // us the JSON compilation database which should be strict. We should do very
 |   // us the JSON compilation database which should be strict. We should do very
 | ||||||
|   // little processing on |entry.args|.
 |   // little processing on |args|.
 | ||||||
|   if (config->mode != ProjectMode::ExternalCommand && !clang_cl) { |   if (config->mode != ProjectMode::ExternalCommand && !clang_cl) { | ||||||
|     // 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,
 | ||||||
| @ -152,41 +170,27 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( | |||||||
|     // command lines like "goma clang -c foo".
 |     // command lines like "goma clang -c foo".
 | ||||||
|     std::string::size_type dot; |     std::string::size_type dot; | ||||||
|     while ( |     while ( | ||||||
|         i < entry.args.size() && entry.args[i][0] != '-' && |         i < args.size() && args[i][0] != '-' && | ||||||
|         // Do not skip over main source filename
 |         // Do not skip over main source filename
 | ||||||
|         NormalizePathWithTestOptOut(entry.args[i]) != result.filename && |         NormalizePathWithTestOptOut(args[i]) != result.filename && | ||||||
|         // There may be other filenames (e.g. more than one source filenames)
 |         // There may be other filenames (e.g. more than one source filenames)
 | ||||||
|         // preceding main source filename. We use a heuristic here. `.` may
 |         // preceding main source filename. We use a heuristic here. `.` may
 | ||||||
|         // occur in both command names and source filenames. If `.` occurs in
 |         // occur in both command names and source filenames. If `.` occurs in
 | ||||||
|         // the last 4 bytes of entry.args[i] and not followed by a digit, e.g.
 |         // the last 4 bytes of args[i] and not followed by a digit, e.g.
 | ||||||
|         // .c .cpp, We take it as a source filename. Others (like ./a/b/goma
 |         // .c .cpp, We take it as a source filename. Others (like ./a/b/goma
 | ||||||
|         // clang-4.0) are seen as commands.
 |         // clang-4.0) are seen as commands.
 | ||||||
|         ((dot = entry.args[i].rfind('.')) == std::string::npos || |         ((dot = args[i].rfind('.')) == std::string::npos || | ||||||
|          dot + 4 < entry.args[i].size() || isdigit(entry.args[i][dot + 1]) || |          dot + 4 < args[i].size() || isdigit(args[i][dot + 1]) || | ||||||
|          !entry.args[i].compare(dot + 1, 3, "exe"))) |          !args[i].compare(dot + 1, 3, "exe"))) | ||||||
|       ++i; |       ++i; | ||||||
|   } |   } | ||||||
|   // Compiler driver.
 |   // Compiler driver.
 | ||||||
|   result.args.push_back(entry.args[i - 1]); |   result.args.push_back(args[i - 1]); | ||||||
| 
 | 
 | ||||||
|   // Add -working-directory if not provided.
 |   // Add -working-directory if not provided.
 | ||||||
|   if (!AnyStartsWith(entry.args, "-working-directory")) |   if (!AnyStartsWith(args, "-working-directory")) | ||||||
|     result.args.emplace_back("-working-directory=" + entry.directory); |     result.args.emplace_back("-working-directory=" + entry.directory); | ||||||
| 
 | 
 | ||||||
|   if (config->mode == ProjectMode::DotCquery && |  | ||||||
|       !AnyStartsWith(entry.args, "-std=")) { |  | ||||||
|     switch (SourceFileLanguage(entry.file)) { |  | ||||||
|       case LanguageId::C: |  | ||||||
|         result.args.push_back("-std=gnu11"); |  | ||||||
|         break; |  | ||||||
|       case LanguageId::Cpp: |  | ||||||
|         result.args.push_back("-std=gnu++14"); |  | ||||||
|         break; |  | ||||||
|       default: |  | ||||||
|         break; |  | ||||||
|     } |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   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; | ||||||
|   bool add_next_flag_to_angle_dirs = false; |   bool add_next_flag_to_angle_dirs = false; | ||||||
| @ -194,9 +198,9 @@ Project::Entry GetCompilationEntryFromCompileCommandEntry( | |||||||
|   // Note that when processing paths, some arguments support multiple forms, ie,
 |   // Note that when processing paths, some arguments support multiple forms, ie,
 | ||||||
|   // {"-Ifoo"} or {"-I", "foo"}.  Support both styles.
 |   // {"-Ifoo"} or {"-I", "foo"}.  Support both styles.
 | ||||||
| 
 | 
 | ||||||
|   result.args.reserve(entry.args.size() + config->extra_flags.size()); |   result.args.reserve(args.size() + config->extra_flags.size()); | ||||||
|   for (; i < entry.args.size(); ++i) { |   for (; i < args.size(); ++i) { | ||||||
|     std::string arg = entry.args[i]; |     std::string arg = args[i]; | ||||||
| 
 | 
 | ||||||
|     // If blacklist skip.
 |     // If blacklist skip.
 | ||||||
|     if (!next_flag_is_path) { |     if (!next_flag_is_path) { | ||||||
| @ -342,24 +346,6 @@ std::vector<Project::Entry> LoadFromDirectoryListing(Config* init_opts, | |||||||
|     e.file = file; |     e.file = file; | ||||||
|     e.args = GetCompilerArgumentForFile(file); |     e.args = GetCompilerArgumentForFile(file); | ||||||
|     e.args.push_back(e.file); |     e.args.push_back(e.file); | ||||||
|     auto idx = e.args[0].rfind("clang"); |  | ||||||
|     if (idx != std::string::npos) { |  | ||||||
|       idx += 5; |  | ||||||
|       switch (SourceFileLanguage(e.file)) { |  | ||||||
|         case LanguageId::C: |  | ||||||
|           if (e.args[0].compare(idx, 2, "++") == 0) |  | ||||||
|             e.args[0].erase(idx, 2); |  | ||||||
|           break; |  | ||||||
|         case LanguageId::Cpp: |  | ||||||
|           // Neither clang++ nor clang-cl
 |  | ||||||
|           if (e.args[0].compare(idx, 2, "++") && |  | ||||||
|               e.args[0].compare(idx, 3, "-cl")) |  | ||||||
|             e.args[0].insert(idx, "++"); |  | ||||||
|           break; |  | ||||||
|         default: |  | ||||||
|           break; |  | ||||||
|       } |  | ||||||
|     } |  | ||||||
|     result.push_back( |     result.push_back( | ||||||
|         GetCompilationEntryFromCompileCommandEntry(init_opts, config, e)); |         GetCompilationEntryFromCompileCommandEntry(init_opts, config, e)); | ||||||
|   } |   } | ||||||
| @ -574,11 +560,7 @@ Project::Entry Project::FindCompilationEntryForFile( | |||||||
|   result.is_inferred = true; |   result.is_inferred = true; | ||||||
|   result.filename = filename; |   result.filename = filename; | ||||||
|   if (!best_entry) { |   if (!best_entry) { | ||||||
|     // FIXME
 |     result.args.push_back("%clang"); | ||||||
|     if (SourceFileLanguage(filename) == LanguageId::Cpp) |  | ||||||
|       result.args.push_back("clang++"); |  | ||||||
|     else |  | ||||||
|       result.args.push_back("clang"); |  | ||||||
|     result.args.push_back(filename); |     result.args.push_back(filename); | ||||||
|   } else { |   } else { | ||||||
|     result.args = best_entry->args; |     result.args = best_entry->args; | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user