@@ -31,7 +31,8 @@ void gcc_versiont::get(const std::string &executable)
3131 " bcc 0 0 0\n "
3232 " #else\n "
3333 " gcc __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__\n "
34- " #endif\n " ;
34+ " #endif\n "
35+ " default_c_standard __STDC_VERSION__\n " ;
3536 }
3637
3738 // some variants output stuff on stderr, say Apple LLVM,
@@ -52,23 +53,78 @@ void gcc_versiont::get(const std::string &executable)
5253 std::string line;
5354
5455 while (!in.fail () && std::getline (in, line))
55- if (!line.empty () && line[0 ] != ' #' )
56- break ;
57-
58- auto split = split_string (line, ' ' );
56+ {
57+ if (line.empty () || line[0 ] == ' #' )
58+ continue ;
59+
60+ auto split = split_string (line, ' ' );
61+
62+ if (split.size () >= 4 )
63+ {
64+ if (split[0 ] == " gcc" )
65+ flavor = flavort::GCC;
66+ else if (split[0 ] == " bcc" )
67+ flavor = flavort::BCC;
68+ else if (split[0 ] == " clang" )
69+ flavor = flavort::CLANG;
70+
71+ v_major = unsafe_string2unsigned (split[1 ]);
72+ v_minor = unsafe_string2unsigned (split[2 ]);
73+ v_patchlevel = unsafe_string2unsigned (split[3 ]);
74+ }
75+ else if (split.size () == 2 && split[0 ] == " default_c_standard" )
76+ {
77+ if (split[1 ] == " 199901L" )
78+ default_c_standard = configt::ansi_ct::c_standardt::C99;
79+ else if (split[1 ] == " 201112L" )
80+ default_c_standard = configt::ansi_ct::c_standardt::C11;
81+ }
82+ }
5983
60- if (split. size () >= 4 )
84+ if (flavor == flavort::GCC || flavor == flavort::CLANG )
6185 {
62- if (split[0 ] == " gcc" )
63- flavor = flavort::GCC;
64- else if (split[0 ] == " bcc" )
65- flavor = flavort::BCC;
66- else if (split[0 ] == " clang" )
67- flavor = flavort::CLANG;
68-
69- v_major = unsafe_string2unsigned (split[1 ]);
70- v_minor = unsafe_string2unsigned (split[2 ]);
71- v_patchlevel = unsafe_string2unsigned (split[3 ]);
86+ // Grab the default C++ standard. Unfortunately this requires another
87+ // run, as the compiler can't preprocess two files in one go.
88+
89+ temporary_filet cpp_in (" goto-gcc." , " .cpp" );
90+ temporary_filet cpp_out (" goto-gcc." , " .out" );
91+ temporary_filet cpp_err (" goto-gcc." , " .err" );
92+
93+ {
94+ std::ofstream out (cpp_in ());
95+ out << " default_cxx_standard __cplusplus\n " ;
96+ }
97+
98+ int result = run (
99+ executable,
100+ {executable, " -E" , " -x" , " c++" , " -" , " -o" , " -" },
101+ cpp_in (),
102+ cpp_out (),
103+ cpp_err ());
104+
105+ if (result >= 0 )
106+ {
107+ std::ifstream in (cpp_out ());
108+ std::string line;
109+
110+ while (!in.fail () && std::getline (in, line))
111+ {
112+ if (line.empty () || line[0 ] == ' #' )
113+ continue ;
114+
115+ auto split = split_string (line, ' ' );
116+
117+ if (split.size () == 2 && split[0 ] == " default_cxx_standard" )
118+ {
119+ if (split[1 ] == " 199711L" )
120+ default_cxx_standard = configt::cppt::cpp_standardt::CPP98;
121+ else if (split[1 ] == " 201103L" )
122+ default_cxx_standard = configt::cppt::cpp_standardt::CPP11;
123+ else if (split[1 ] == " 201402L" )
124+ default_cxx_standard = configt::cppt::cpp_standardt::CPP14;
125+ }
126+ }
127+ }
72128 }
73129 }
74130}
0 commit comments