Skip to content

Commit fd910a7

Browse files
author
Daniel Kroening
committed
added gcc_versiont
1 parent 09a4e6c commit fd910a7

File tree

3 files changed

+135
-0
lines changed

3 files changed

+135
-0
lines changed

src/goto-cc/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ SRC = armcc_cmdline.cpp \
88
cw_mode.cpp \
99
gcc_cmdline.cpp \
1010
gcc_mode.cpp \
11+
gcc_version.cpp \
1112
goto_cc_cmdline.cpp \
1213
goto_cc_languages.cpp \
1314
goto_cc_main.cpp \

src/goto-cc/gcc_version.cpp

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*******************************************************************\
2+
3+
Module: GCC Mode
4+
5+
Author: Daniel Kroening, 2018
6+
7+
\*******************************************************************/
8+
9+
#include "gcc_version.h"
10+
11+
#include <util/prefix.h>
12+
#include <util/run.h>
13+
#include <util/string2int.h>
14+
#include <util/string_utils.h>
15+
#include <util/tempfile.h>
16+
17+
#include <fstream>
18+
19+
void gcc_versiont::get(const std::string &executable)
20+
{
21+
temporary_filet tmp_file_in("goto-gcc.", ".in");
22+
temporary_filet tmp_file_out("goto-gcc.", ".out");
23+
temporary_filet tmp_file_err("goto-gcc.", ".err");
24+
25+
{
26+
std::ofstream out(tmp_file_in());
27+
28+
out << "#if defined(__clang_major__)\n"
29+
"clang __clang_major__ __clang_minor__ __clang_patchlevel__\n"
30+
"#elif defined(__BCC__)\n"
31+
"bcc 0 0 0\n"
32+
"#else\n"
33+
"gcc __GNUC__ __GNUC_MINOR__ __GNUC_PATCHLEVEL__\n"
34+
"#endif\n";
35+
}
36+
37+
// some variants output stuff on stderr, say Apple LLVM,
38+
// which we silence.
39+
int result = run(
40+
executable,
41+
{executable, "-E", "-", "-o", "-"},
42+
tmp_file_in(),
43+
tmp_file_out(),
44+
tmp_file_err());
45+
46+
v_major = v_minor = v_patchlevel = 0;
47+
flavor = flavort::UNKNOWN;
48+
49+
if(result >= 0)
50+
{
51+
std::ifstream in(tmp_file_out());
52+
std::string line;
53+
54+
while(!in.fail() && std::getline(in, line))
55+
if(!line.empty() && line[0] != '#')
56+
break;
57+
58+
auto split = split_string(line, ' ');
59+
60+
if(split.size() >= 4)
61+
{
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]);
72+
}
73+
}
74+
}
75+
76+
bool gcc_versiont::is_at_least(
77+
unsigned _major,
78+
unsigned _minor,
79+
unsigned _patchlevel) const
80+
{
81+
return v_major > _major || (v_major == _major && v_minor > _minor) ||
82+
(v_major == _major && v_minor == _minor &&
83+
v_patchlevel >= _patchlevel);
84+
}
85+
86+
std::ostream &operator<<(std::ostream &out, const gcc_versiont &v)
87+
{
88+
return out << v.v_major << '.' << v.v_minor << '.' << v.v_patchlevel;
89+
}

src/goto-cc/gcc_version.h

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/*******************************************************************\
2+
3+
Module: gcc version numbering scheme
4+
5+
Author: Daniel Kroening
6+
7+
Date: May 2018
8+
9+
\*******************************************************************/
10+
11+
#ifndef CPROVER_GOTO_CC_GCC_VERSION_H
12+
#define CPROVER_GOTO_CC_GCC_VERSION_H
13+
14+
#include <iosfwd>
15+
#include <string>
16+
17+
class gcc_versiont
18+
{
19+
public:
20+
unsigned v_major, v_minor, v_patchlevel;
21+
22+
void get(const std::string &executable);
23+
24+
bool is_at_least(
25+
unsigned v_major,
26+
unsigned v_minor = 0,
27+
unsigned v_patchlevel = 0) const;
28+
29+
enum class flavort
30+
{
31+
UNKNOWN,
32+
CLANG,
33+
GCC,
34+
BCC
35+
} flavor;
36+
37+
gcc_versiont()
38+
: v_major(0), v_minor(0), v_patchlevel(0), flavor(flavort::UNKNOWN)
39+
{
40+
}
41+
};
42+
43+
std::ostream &operator<<(std::ostream &, const gcc_versiont &);
44+
45+
#endif

0 commit comments

Comments
 (0)