CBMC
builtin_factory.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "builtin_factory.h"
11 
12 #include "ansi_c_parser.h"
13 #include "ansi_c_typecheck.h"
14 
15 #include <util/config.h>
16 #include <util/prefix.h>
17 #include <util/string_utils.h>
18 
19 #include <sstream>
20 
21 static bool find_pattern(
22  const std::string &pattern,
23  const char *header_file,
24  std::ostream &out)
25 {
26  std::istringstream hdr(header_file);
27  std::string line;
28  while(std::getline(hdr, line))
29  {
30  line = strip_string(line);
31  if(has_prefix(line, "//") || line.find(pattern) == std::string::npos)
32  continue;
33 
34  out << line;
35  return true;
36  }
37 
38  return false;
39 }
40 
41 static bool convert(
42  const irep_idt &identifier,
43  const std::ostringstream &s,
44  symbol_tablet &symbol_table,
45  message_handlert &message_handler)
46 {
47  std::istringstream in(s.str());
48 
50  ansi_c_parser.set_file(ID_built_in);
51  ansi_c_parser.in=&in;
52  ansi_c_parser.set_message_handler(message_handler);
54  ansi_c_parser.cpp98=false; // it's not C++
55  ansi_c_parser.cpp11=false; // it's not C++
57 
59 
60  if(ansi_c_parser.parse())
61  return true;
62 
63  symbol_tablet new_symbol_table;
64 
65  // this is recursive -- builtin_factory is called
66  // from the typechecker
69  new_symbol_table,
70  "", // module
71  message_handler))
72  {
73  return true;
74  }
75 
76  // we should now have a new symbol
77  symbol_tablet::symbolst::const_iterator s_it=
78  new_symbol_table.symbols.find(identifier);
79 
80  if(s_it==new_symbol_table.symbols.end())
81  {
82  messaget message(message_handler);
83  message.error() << "failed to produce built-in symbol '" << identifier
84  << '\'' << messaget::eom;
85  return true;
86  }
87 
88  // copy the new symbol
89  symbol_table.add(s_it->second);
90 
91  return false;
92 }
93 
98  const irep_idt &identifier,
99  symbol_tablet &symbol_table,
100  message_handlert &mh)
101 {
102  // we search for "space" "identifier" "("
103  const std::string pattern=' '+id2string(identifier)+'(';
104 
105  std::ostringstream s;
106 
107  std::string code;
109  s << code;
110 
111  // our own extensions
112  if(find_pattern(pattern, cprover_builtin_headers, s))
113  return convert(identifier, s, symbol_table, mh);
114 
115  // this is Visual C/C++ only
117  {
118  if(find_pattern(pattern, windows_builtin_headers, s))
119  return convert(identifier, s, symbol_table, mh);
120  }
121 
122  // ARM stuff
124  {
125  if(find_pattern(pattern, arm_builtin_headers, s))
126  return convert(identifier, s, symbol_table, mh);
127  }
128 
129  // CW stuff
131  {
132  if(find_pattern(pattern, cw_builtin_headers, s))
133  return convert(identifier, s, symbol_table, mh);
134  }
135 
136  // GCC junk stuff, also for CLANG and ARM
137  if(
141  {
143  return convert(identifier, s, symbol_table, mh);
144 
145  if(find_pattern(pattern, gcc_builtin_headers_math, s))
146  return convert(identifier, s, symbol_table, mh);
147 
149  return convert(identifier, s, symbol_table, mh);
150 
151  if(find_pattern(pattern, gcc_builtin_headers_omp, s))
152  return convert(identifier, s, symbol_table, mh);
153 
154  if(find_pattern(pattern, gcc_builtin_headers_tm, s))
155  return convert(identifier, s, symbol_table, mh);
156 
157  if(find_pattern(pattern, gcc_builtin_headers_ubsan, s))
158  return convert(identifier, s, symbol_table, mh);
159 
160  if(find_pattern(pattern, clang_builtin_headers, s))
161  return convert(identifier, s, symbol_table, mh);
162 
163  if(config.ansi_c.arch=="i386" ||
164  config.ansi_c.arch=="x86_64" ||
165  config.ansi_c.arch=="x32")
166  {
167  if(find_pattern(pattern, gcc_builtin_headers_ia32, s))
168  return convert(identifier, s, symbol_table, mh);
169 
171  return convert(identifier, s, symbol_table, mh);
172 
174  return convert(identifier, s, symbol_table, mh);
175 
177  return convert(identifier, s, symbol_table, mh);
178 
180  return convert(identifier, s, symbol_table, mh);
181  }
182  else if(config.ansi_c.arch=="arm64" ||
183  config.ansi_c.arch=="armel" ||
184  config.ansi_c.arch=="armhf" ||
185  config.ansi_c.arch=="arm")
186  {
187  if(find_pattern(pattern, gcc_builtin_headers_arm, s))
188  return convert(identifier, s, symbol_table, mh);
189  }
190  else if(config.ansi_c.arch=="mips64el" ||
191  config.ansi_c.arch=="mipsn32el" ||
192  config.ansi_c.arch=="mipsel" ||
193  config.ansi_c.arch=="mips64" ||
194  config.ansi_c.arch=="mipsn32" ||
195  config.ansi_c.arch=="mips")
196  {
197  if(find_pattern(pattern, gcc_builtin_headers_mips, s))
198  return convert(identifier, s, symbol_table, mh);
199  }
200  else if(config.ansi_c.arch=="powerpc" ||
201  config.ansi_c.arch=="ppc64" ||
202  config.ansi_c.arch=="ppc64le")
203  {
204  if(find_pattern(pattern, gcc_builtin_headers_power, s))
205  return convert(identifier, s, symbol_table, mh);
206  }
207  }
208 
209  return true;
210 }
messaget
Class that provides messages with a built-in verbosity 'level'.
Definition: message.h:154
ansi_c_parser
ansi_c_parsert ansi_c_parser
Definition: ansi_c_parser.cpp:13
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:36
symbol_tablet
The symbol table.
Definition: symbol_table.h:13
ansi_c_typecheck.h
gcc_builtin_headers_omp
const char gcc_builtin_headers_omp[]
Definition: ansi_c_internal_additions.cpp:38
configt::ansi_ct::for_has_scope
bool for_has_scope
Definition: config.h:138
gcc_builtin_headers_arm
const char gcc_builtin_headers_arm[]
Definition: ansi_c_internal_additions.cpp:73
string_utils.h
configt::ansi_ct::flavourt::CODEWARRIOR
@ CODEWARRIOR
ansi_c_parsert::cpp98
bool cpp98
Definition: ansi_c_parser.h:74
windows_builtin_headers
const char windows_builtin_headers[]
Definition: ansi_c_internal_additions.cpp:103
configt::ansi_ct::os
ost os
Definition: config.h:201
prefix.h
builtin_factory
bool builtin_factory(const irep_idt &identifier, symbol_tablet &symbol_table, message_handlert &mh)
Check whether given identifier is a compiler built-in.
Definition: builtin_factory.cpp:97
gcc_builtin_headers_mem_string
const char gcc_builtin_headers_mem_string[]
Definition: ansi_c_internal_additions.cpp:33
messaget::eom
static eomt eom
Definition: message.h:297
configt::ansi_c
struct configt::ansi_ct ansi_c
configt::ansi_ct::flavourt::ARM
@ ARM
configt::ansi_ct::flavourt::CLANG
@ CLANG
gcc_builtin_headers_ubsan
const char gcc_builtin_headers_ubsan[]
Definition: ansi_c_internal_additions.cpp:46
clang_builtin_headers
const char clang_builtin_headers[]
Definition: ansi_c_internal_additions.cpp:95
strip_string
std::string strip_string(const std::string &s)
Remove all whitespace characters from either end of a string.
Definition: string_utils.cpp:21
convert
static bool convert(const irep_idt &identifier, const std::ostringstream &s, symbol_tablet &symbol_table, message_handlert &message_handler)
Definition: builtin_factory.cpp:41
messaget::error
mstreamt & error() const
Definition: message.h:399
has_prefix
bool has_prefix(const std::string &s, const std::string &prefix)
Definition: converter.cpp:13
parsert::in
std::istream * in
Definition: parser.h:26
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:47
find_pattern
static bool find_pattern(const std::string &pattern, const char *header_file, std::ostream &out)
Definition: builtin_factory.cpp:21
ansi_c_parsert::clear
virtual void clear() override
Definition: ansi_c_parser.h:45
ansi_c_internal_additions.h
ansi_c_scanner_init
void ansi_c_scanner_init()
gcc_builtin_headers_ia32
const char gcc_builtin_headers_ia32[]
Definition: ansi_c_internal_additions.cpp:51
messaget::set_message_handler
virtual void set_message_handler(message_handlert &_message_handler)
Definition: message.h:179
ansi_c_internal_additions
void ansi_c_internal_additions(std::string &code)
Definition: ansi_c_internal_additions.cpp:148
gcc_builtin_headers_ia32_2
const char gcc_builtin_headers_ia32_2[]
Definition: ansi_c_internal_additions.cpp:55
cw_builtin_headers
const char cw_builtin_headers[]
Definition: ansi_c_internal_additions.cpp:91
configt::ansi_ct::arch
irep_idt arch
Definition: config.h:206
configt::ansi_ct::ost::OS_WIN
@ OS_WIN
message_handlert
Definition: message.h:27
arm_builtin_headers
const char arm_builtin_headers[]
Definition: ansi_c_internal_additions.cpp:87
builtin_factory.h
config
configt config
Definition: config.cpp:25
ansi_c_parsert::cpp11
bool cpp11
Definition: ansi_c_parser.h:74
ansi_c_parsert::mode
modet mode
Definition: ansi_c_parser.h:71
gcc_builtin_headers_mips
const char gcc_builtin_headers_mips[]
Definition: ansi_c_internal_additions.cpp:77
symbol_table_baset::add
bool add(const symbolt &symbol)
Add a new symbol to the symbol table.
Definition: symbol_table_base.cpp:18
configt::ansi_ct::mode
flavourt mode
Definition: config.h:237
cprover_builtin_headers
const char cprover_builtin_headers[]
Definition: ansi_c_internal_additions.cpp:99
ansi_c_parsert::parse_tree
ansi_c_parse_treet parse_tree
Definition: ansi_c_parser.h:26
gcc_builtin_headers_power
const char gcc_builtin_headers_power[]
Definition: ansi_c_internal_additions.cpp:82
symbol_table_baset::symbols
const symbolst & symbols
Read-only field, used to look up symbols given their names.
Definition: symbol_table_base.h:30
gcc_builtin_headers_ia32_3
const char gcc_builtin_headers_ia32_3[]
Definition: ansi_c_internal_additions.cpp:58
ansi_c_parsert::parse
virtual bool parse() override
Definition: ansi_c_parser.h:40
gcc_builtin_headers_tm
const char gcc_builtin_headers_tm[]
Definition: ansi_c_internal_additions.cpp:42
ansi_c_typecheck
bool ansi_c_typecheck(ansi_c_parse_treet &ansi_c_parse_tree, symbol_tablet &symbol_table, const std::string &module, message_handlert &message_handler)
Definition: ansi_c_typecheck.cpp:24
config.h
configt::ansi_ct::flavourt::GCC
@ GCC
gcc_builtin_headers_ia32_4
const char gcc_builtin_headers_ia32_4[]
Definition: ansi_c_internal_additions.cpp:61
gcc_builtin_headers_ia32_5
const char gcc_builtin_headers_ia32_5[]
Definition: ansi_c_internal_additions.cpp:64
gcc_builtin_headers_generic
const char gcc_builtin_headers_generic[]
Definition: ansi_c_internal_additions.cpp:23
ansi_c_parser.h
ansi_c_parsert::for_has_scope
bool for_has_scope
Definition: ansi_c_parser.h:77
parsert::set_file
void set_file(const irep_idt &file)
Definition: parser.h:85
gcc_builtin_headers_math
const char gcc_builtin_headers_math[]
Definition: ansi_c_internal_additions.cpp:28