@@ -31,7 +31,8 @@ void gcc_versiont::get(const std::string &executable)
31
31
" bcc 0 0 0\n "
32
32
" #else\n "
33
33
" gcc __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__\n "
34
- " #endif\n " ;
34
+ " #endif\n "
35
+ " default_c_standard __STDC_VERSION__\n " ;
35
36
}
36
37
37
38
// some variants output stuff on stderr, say Apple LLVM,
@@ -52,23 +53,78 @@ void gcc_versiont::get(const std::string &executable)
52
53
std::string line;
53
54
54
55
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
+ }
59
83
60
- if (split. size () >= 4 )
84
+ if (flavor == flavort::GCC || flavor == flavort::CLANG )
61
85
{
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
+ }
72
128
}
73
129
}
74
130
}
0 commit comments