@@ -82,7 +82,7 @@ libclang_compile_config::libclang_compile_config() : libclang_compile_config(CPP
82
82
83
83
libclang_compile_config::libclang_compile_config (std::string clang_binary)
84
84
: compile_config({}), write_preprocessed_(false ), fast_preprocessing_(false ),
85
- remove_comments_in_macro_(false )
85
+ remove_comments_in_macro_(false ), use_c_( false )
86
86
{
87
87
// set given clang binary
88
88
set_clang_binary (clang_binary);
@@ -226,6 +226,11 @@ cppast::libclang_compile_config::libclang_compile_config(
226
226
for (auto i = 0u ; i != size; ++i)
227
227
{
228
228
auto cmd = clang_CompileCommands_getCommand (commands.get (), i);
229
+
230
+ // If ++ exists within the compiler name (e.g. clang++, g++, etc), use C++
231
+ std::string exe (clang_getCString (clang_CompileCommand_getArg (cmd, 0 )));
232
+ use_c_ = (exe.find (" ++" , 0 ) == std::string::npos);
233
+
229
234
auto dir = detail::cxstring (clang_CompileCommand_getDirectory (cmd));
230
235
parse_flags (cmd, [&](std::string flag, std::string args) {
231
236
if (flag == " -I" )
@@ -243,11 +248,21 @@ cppast::libclang_compile_config::libclang_compile_config(
243
248
add_flag (std::move (flag));
244
249
}
245
250
else if (flag == " -std" )
246
- // standard
251
+ {
252
+ use_c_ = (args.find (" ++" ) == std::string::npos);
247
253
add_flag (std::move (flag) + " =" + std::move (args));
254
+ }
248
255
else if (flag == " -f" )
249
256
// other options
250
257
add_flag (std::move (flag) + std::move (args));
258
+ else if (flag == " -x" )
259
+ {
260
+ // language
261
+ if (args == " c" )
262
+ use_c_ = true ;
263
+ else
264
+ use_c_ = false ;
265
+ }
251
266
});
252
267
}
253
268
}
@@ -270,8 +285,9 @@ bool is_valid_binary(const std::string& binary)
270
285
void add_default_include_dirs (libclang_compile_config& config)
271
286
{
272
287
std::string verbose_output;
288
+ std::string language = config.use_c () ? " -xc" : " -xc++" ;
273
289
tpl::Process process (
274
- detail::libclang_compile_config_access::clang_binary (config) + " -x c++ -v -" , " " ,
290
+ detail::libclang_compile_config_access::clang_binary (config) + " " + language + " -v -" , " " ,
275
291
[](const char *, std::size_t ) {},
276
292
[&](const char * str, std::size_t n) { verbose_output.append (str, n); }, true );
277
293
process.write (" " , 1 );
@@ -424,6 +440,57 @@ void libclang_compile_config::do_set_flags(cpp_standard standard, compile_flags
424
440
add_flag (" -std=c++2a" );
425
441
break ;
426
442
}
443
+ else
444
+ throw std::invalid_argument (" c++2b is not yet supported for current version of clang" );
445
+ case cpp_standard::c_89:
446
+ if (flags & compile_flag::gnu_extensions)
447
+ add_flag (" -std=gnu89" );
448
+ else
449
+ add_flag (" -std=c89" );
450
+ break ;
451
+ case cpp_standard::c_99:
452
+ if (flags & compile_flag::gnu_extensions)
453
+ add_flag (" -std=gnu99" );
454
+ else
455
+ add_flag (" -std=c99" );
456
+ break ;
457
+ case cpp_standard::c_11:
458
+ if (flags & compile_flag::gnu_extensions)
459
+ add_flag (" -std=gnu11" );
460
+ else
461
+ add_flag (" -std=c11" );
462
+ break ;
463
+ case cpp_standard::c_17:
464
+ if (libclang_parser::libclang_minor_version () >= 45 )
465
+ { // Corresponds to Clang version 6
466
+ if (flags & compile_flag::gnu_extensions)
467
+ add_flag (" -std=gnu17" );
468
+ else
469
+ add_flag (" -std=c17" );
470
+ break ;
471
+ }
472
+ else
473
+ throw std::invalid_argument (" c17 is not yet supported for current version of clang" );
474
+ case cpp_standard::c_2x:
475
+ if (libclang_parser::libclang_minor_version () >= 59 )
476
+ { // Corresponds to Clang version 9
477
+ if (flags & compile_flag::gnu_extensions)
478
+ add_flag (" -std=gnu2x" );
479
+ else
480
+ add_flag (" -std=c2x" );
481
+ break ;
482
+ }
483
+ else
484
+ throw std::invalid_argument (" c2x is not yet supported for current version of clang" );
485
+ }
486
+
487
+ // Add language flag for C or C++
488
+ if (is_c_standard (standard)) {
489
+ add_flag (" -xc" );
490
+ use_c_ = true ;
491
+ } else {
492
+ add_flag (" -xc++" );
493
+ use_c_ = false ;
427
494
}
428
495
429
496
if (flags & compile_flag::ms_compatibility)
@@ -461,6 +528,11 @@ void libclang_compile_config::do_remove_macro_definition(std::string name)
461
528
add_flag (" -U" + std::move (name));
462
529
}
463
530
531
+ bool libclang_compile_config::do_use_c () const noexcept
532
+ {
533
+ return use_c_;
534
+ }
535
+
464
536
type_safe::optional<libclang_compile_config> cppast::find_config_for (
465
537
const libclang_compilation_database& database, std::string file_name)
466
538
{
@@ -474,7 +546,7 @@ type_safe::optional<libclang_compile_config> cppast::find_config_for(
474
546
if (database.has_config (file_name))
475
547
return libclang_compile_config (database, std::move (file_name));
476
548
static const char * extensions[]
477
- = {" .h" , " .hpp" , " .cpp" , " .h++" , " .c++" , " .hxx" , " .cxx" , " .hh" , " .cc" , " .H" , " .C" };
549
+ = {" .h" , " .hpp" , " .cpp" , " .h++" , " .c++" , " .hxx" , " .cxx" , " .hh" , " .cc" , " .H" , " .C" , " .c " };
478
550
for (auto ext : extensions)
479
551
{
480
552
auto name = file_name + ext;
@@ -511,8 +583,8 @@ namespace
511
583
std::vector<const char *> get_arguments (const libclang_compile_config& config)
512
584
{
513
585
std::vector<const char *> args
514
- // TODO: Why? and Why?
515
- = {" -x " , " c++ " , " - I." }; // force C++ and enable current directory for include search
586
+ // TODO: Why?
587
+ = {" -I." }; // enable current directory for include search
516
588
for (auto & flag : detail::libclang_compile_config_access::flags (config))
517
589
args.push_back (flag.c_str ());
518
590
return args;
0 commit comments