Skip to content

Commit 1711345

Browse files
author
Daniel Kroening
committed
added a factory for builtin function declarations
1 parent 4a5b952 commit 1711345

File tree

3 files changed

+191
-0
lines changed

3 files changed

+191
-0
lines changed

src/ansi-c/Makefile

+1
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ SRC = anonymous_member.cpp \
1010
ansi_c_scope.cpp \
1111
ansi_c_typecheck.cpp \
1212
ansi_c_y.tab.cpp \
13+
builtin_factory.cpp \
1314
c_misc.cpp \
1415
c_nondet_symbol_factory.cpp \
1516
c_preprocess.cpp \

src/ansi-c/builtin_factory.cpp

+169
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
/*******************************************************************\
2+
3+
Module:
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#include "builtin_factory.h"
10+
#include "ansi_c_internal_additions.h"
11+
12+
#include "ansi_c_parser.h"
13+
#include "ansi_c_typecheck.h"
14+
15+
#include <cstring>
16+
#include <ostream>
17+
#include <sstream>
18+
19+
const char windows_headers[]=
20+
"int __noop();\n"
21+
"int __assume(int);\n";
22+
23+
//! Advance to the next line
24+
static const char *next_line(const char *line)
25+
{
26+
const char *end=strchr(line, '\n');
27+
28+
if(end==NULL)
29+
return strchr(line, 0);
30+
else
31+
return end+1;
32+
}
33+
34+
//! Look for given pattern in given string.
35+
//! Add line with pattern to 'out' if found.
36+
//! \return 'true' if found
37+
static bool find_pattern(
38+
const std::string &pattern,
39+
const char *header_file,
40+
std::ostream &out)
41+
{
42+
// read line-by-line
43+
const char *line, *line_end;
44+
45+
for(line=header_file; *line!=0; line=line_end)
46+
{
47+
line_end=next_line(line);
48+
49+
// skip spaces
50+
while(*line==' ')
51+
line++;
52+
53+
if(line[0]=='/' && line[1]=='/') // comment
54+
continue;
55+
56+
for(const char *p=line; p<line_end; p++)
57+
{
58+
if(strncmp(p, pattern.c_str(), pattern.size())==0)
59+
{
60+
// copy the entire line to out
61+
for(const char *s=line; s!=line_end; s++)
62+
out << *s;
63+
64+
return true; // done, found
65+
}
66+
}
67+
}
68+
69+
return false;
70+
}
71+
72+
static bool convert(
73+
const irep_idt &identifier,
74+
const std::ostringstream &s,
75+
symbol_tablet &symbol_table,
76+
message_handlert &message_handler)
77+
{
78+
std::istringstream in(s.str());
79+
80+
ansi_c_parser.clear();
81+
ansi_c_parser.set_file(ID_built_in);
82+
ansi_c_parser.in=&in;
83+
ansi_c_parser.set_message_handler(message_handler);
84+
ansi_c_parser.for_has_scope=config.ansi_c.for_has_scope;
85+
ansi_c_parser.cpp98=false; // it's not C++
86+
ansi_c_parser.cpp11=false; // it's not C++
87+
ansi_c_parser.mode=config.ansi_c.mode;
88+
89+
ansi_c_scanner_init();
90+
91+
if(ansi_c_parser.parse())
92+
return true;
93+
94+
symbol_tablet new_symbol_table;
95+
96+
// very recursive!
97+
if(ansi_c_typecheck(
98+
ansi_c_parser.parse_tree,
99+
new_symbol_table,
100+
"", // module
101+
message_handler))
102+
{
103+
return true;
104+
}
105+
106+
// we should now have a new symbol
107+
symbol_tablet::symbolst::const_iterator s_it=
108+
new_symbol_table.symbols.find(identifier);
109+
110+
if(s_it==new_symbol_table.symbols.end())
111+
{
112+
messaget message(message_handler);
113+
message.error() << "failed to produce built-in symbol `"
114+
<< identifier << '\'' << messaget::eom;
115+
return true;
116+
}
117+
118+
// copy the new symbol
119+
symbol_table.add(s_it->second);
120+
121+
return false;
122+
}
123+
124+
//! Check whether given identifier is a compiler built-in.
125+
//! If so, add declaration to symbol table.
126+
//! \return 'true' on error
127+
bool builtin_factory(
128+
const irep_idt &identifier,
129+
symbol_tablet &symbol_table,
130+
message_handlert &mh)
131+
{
132+
// we search for "space" "identifier" "("
133+
const std::string pattern=' '+id2string(identifier)+'(';
134+
135+
std::ostringstream s;
136+
137+
std::string code;
138+
ansi_c_internal_additions(code);
139+
s << code;
140+
141+
if(find_pattern(pattern, gcc_builtin_headers_generic, s))
142+
return convert(identifier, s, symbol_table, mh);
143+
144+
if(find_pattern(pattern, gcc_builtin_headers_mem_string, s))
145+
return convert(identifier, s, symbol_table, mh);
146+
147+
if(find_pattern(pattern, gcc_builtin_headers_omp, s))
148+
return convert(identifier, s, symbol_table, mh);
149+
150+
if(find_pattern(pattern, gcc_builtin_headers_tm, s))
151+
return convert(identifier, s, symbol_table, mh);
152+
153+
if(find_pattern(pattern, gcc_builtin_headers_ubsan, s))
154+
return convert(identifier, s, symbol_table, mh);
155+
156+
if(find_pattern(pattern, gcc_builtin_headers_ia32, s))
157+
return convert(identifier, s, symbol_table, mh);
158+
159+
if(find_pattern(pattern, gcc_builtin_headers_ia32_2, s))
160+
return convert(identifier, s, symbol_table, mh);
161+
162+
if(find_pattern(pattern, gcc_builtin_headers_ia32_3, s))
163+
return convert(identifier, s, symbol_table, mh);
164+
165+
if(find_pattern(pattern, gcc_builtin_headers_ia32_4, s))
166+
return convert(identifier, s, symbol_table, mh);
167+
168+
return true;
169+
}

src/ansi-c/builtin_factory.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/*******************************************************************\
2+
3+
Module:
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#ifndef CPROVER_ANSI_C_BUILTIN_FACTORY_H
10+
#define CPROVER_ANSI_C_BUILTIN_FACTORY_H
11+
12+
#include <util/symbol_table.h>
13+
#include <util/message.h>
14+
15+
//! \return 'true' in case of error
16+
bool builtin_factory(
17+
const irep_idt &identifier,
18+
symbol_tablet &,
19+
message_handlert &);
20+
21+
#endif // CPROVER_ANSI_C_BUILTIN_FACTORY_H

0 commit comments

Comments
 (0)