Skip to content

Commit 5b3030a

Browse files
author
Daniel Kroening
committed
added gcc_versiont
1 parent aa81141 commit 5b3030a

File tree

3 files changed

+131
-0
lines changed

3 files changed

+131
-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

+88
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
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_micro = 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_micro = unsafe_string2unsigned(split[3]);
72+
}
73+
}
74+
}
75+
76+
bool gcc_versiont::is_at_least(
77+
unsigned _major,
78+
unsigned _minor,
79+
unsigned _micro) const
80+
{
81+
return v_major > _major || (v_major == _major && v_minor > _minor) ||
82+
(v_major == _major && v_minor == _minor && v_micro >= _micro);
83+
}
84+
85+
std::ostream &operator<<(std::ostream &out, const gcc_versiont &v)
86+
{
87+
return out << v.v_major << '.' << v.v_minor << '.' << v.v_micro;
88+
}

src/goto-cc/gcc_version.h

+42
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
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_micro;
21+
22+
void get(const std::string &executable);
23+
24+
bool is_at_least(unsigned v_major, unsigned v_minor = 0, unsigned v_micro = 0)
25+
const;
26+
27+
enum class flavort
28+
{
29+
UNKNOWN,
30+
CLANG,
31+
GCC,
32+
BCC
33+
} flavor;
34+
35+
gcc_versiont() : v_major(0), v_minor(0), v_micro(0), flavor(flavort::UNKNOWN)
36+
{
37+
}
38+
};
39+
40+
std::ostream &operator<<(std::ostream &, const gcc_versiont &);
41+
42+
#endif

0 commit comments

Comments
 (0)