ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
clang_c_convert.h
Go to the documentation of this file.
1#ifndef CLANG_C_FRONTEND_CLANG_C_CONVERT_H_
2#define CLANG_C_FRONTEND_CLANG_C_CONVERT_H_
3
4#define __STDC_LIMIT_MACROS
5#define __STDC_FORMAT_MACROS
6
10#include <util/irep/std_types.h>
12#include <unordered_map>
13
14// Forward dec, to avoid bringing in clang headers
15namespace clang
16{
17class ASTUnit;
18class ASTContext;
19class SourceManager;
20class FunctionDecl;
21class Decl;
22class LabelDecl;
23class VarDecl;
24class ParmVarDecl;
25class RecordDecl;
26class QualType;
27class Type;
28class BuiltinType;
29class Stmt;
30class BinaryOperator;
31class CompoundAssignOperator;
32class UnaryOperator;
33class AtomicExpr;
34class CastExpr;
35class NamedDecl;
36class PresumedLoc;
37class SourceLocation;
38class CharacterLiteral;
39class StringLiteral;
40class IntegerLiteral;
41class FloatingLiteral;
42class TagDecl;
43class FieldDecl;
44class ValueDecl;
45class MemberExpr;
46class EnumConstantDecl;
47class APValue;
48class AlignedAttr;
49class InitListExpr;
50class TemplateParamObjectDecl;
51class Expr;
52} // namespace clang
53
54std::string
55getFullyQualifiedName(const clang::QualType &, const clang::ASTContext &);
56
58{
59public:
61 contextt &_context,
62 std::unique_ptr<clang::ASTUnit> &_AST,
63 irep_idt _mode);
64 virtual ~clang_c_convertert() = default;
65
66 bool convert();
67
78 static void
79 gen_typecast_to_union(const namespacet &ns, exprt &dest, const typet &type);
80
81 static std::string get_decl_name(const clang::NamedDecl &nd);
82
83protected:
84 clang::ASTContext *ASTContext;
87 std::unique_ptr<clang::ASTUnit> &AST;
90
91 // set_location() cache. Profiling on ECA-style programs showed that every
92 // exprt built during AST conversion gets its own freshly-allocated
93 // locationt dt (4 named_sub entries: file/line/column/function). On a
94 // 590 KB benchmark that was 168 MB / 2M detatches — 68% of peak heap.
95 // Since consecutive AST nodes almost always share file+function (and
96 // often line+column for compiler-generated decls), share the locationt
97 // dt across calls when the source key matches.
99 unsigned last_loc_line = 0;
100 unsigned last_loc_column = 0;
101 std::string last_loc_filename;
102 std::string last_loc_function;
103 bool last_loc_valid = false;
104
105 // class symbol id prefix `tag-`
106 std::string tag_prefix = "tag-";
107
115
119 std::unordered_map<const clang::Expr *, exprt> vla_size_snapshots;
120 bool snapshot_vla_sizes(const clang::Decl &decl, codet &dest);
121 bool get_vla_size(const clang::Expr &size, exprt &new_expr);
122
123 clang::SourceManager *sm;
124
125 const clang::FunctionDecl *current_functionDecl;
126
134 std::vector<const clang::LabelDecl *> address_taken_labels;
135
136 void collect_address_taken_labels(const clang::Stmt &body);
137
139 virtual bool convert_top_level_decl();
140
146 virtual bool get_decl(const clang::Decl &decl, exprt &new_expr);
147
148 virtual bool get_var(const clang::VarDecl &vd, exprt &new_expr);
149 virtual const clang::Expr &elided_copy_source(const clang::Expr &init);
150 bool has_dynamic_local_init(const clang::VarDecl &vd) const;
151 void add_init_guard(const symbolt &var);
152 bool get_static_var_init(
153 const clang::VarDecl &vd,
154 symbolt &symbol,
155 const typet &t,
156 const locationt &location_begin,
157 exprt &new_expr);
158
159 std::string header_internal_suffix(const clang::NamedDecl &nd);
162 std::unordered_map<std::string, std::vector<const clang::Decl *>>
163 internal_copies;
164
165 virtual bool get_function(const clang::FunctionDecl &fd, exprt &new_expr);
166
167 bool get_function_signature(const clang::FunctionDecl &fd, code_typet &type);
168
169 virtual bool get_function_body(
170 const clang::FunctionDecl &fd,
171 exprt &new_expr,
172 const code_typet &ftype);
173
180 virtual void
181 annotate_exception_specification(const clang::FunctionDecl &, typet &)
182 {
183 }
184
190 virtual bool get_function_params(
191 const clang::FunctionDecl &fd,
192 code_typet::argumentst &params);
196 bool get_function_param(const clang::ParmVarDecl &pd, exprt &param);
197 /*
198 * This function determines whether we should name an unnamed function
199 * parameter and continue to add its symbol.
200 *
201 * Params:
202 * pd: the clang AST node for the function parameter we are currently dealing
203 * with id: id for this function parameter name: name for this function
204 * parameter param: ESBMC's IR representing the function parameter
205 */
206 virtual void name_param_and_continue(
207 const clang::ParmVarDecl &pd,
208 std::string &id,
209 std::string &name,
210 exprt &param);
211
212 virtual bool get_struct_union_class(const clang::RecordDecl &recordd);
213
214 /*
215 * Get class fields of the type `clang::Decl::Field`
216 *
217 * Params:
218 * recordd: clang AST of the class we are currently dealing with
219 * type: ESBMC IR representing the class' type
220 */
222 const clang::RecordDecl &recordd,
223 struct_union_typet &type);
224
225 /*
226 * This function not only gets class method but also gets
227 * the other declarations inside a class. The declarations can be
228 * of any valid type other than `clang::Decl::Field`,
229 * such as a class constructor of the type `clang::Decl::CXXConstructor`,
230 * or a class static member of the type `clang::Decl::Var`
231 *
232 * Params:
233 * recordd: clang AST of the class we are currently dealing with
234 * type: ESBMC IR representing the class' type
235 */
237 const clang::RecordDecl &recordd,
238 typet &type);
239
240 virtual bool get_type(const clang::QualType &type, typet &new_type);
241
242 virtual bool get_type(const clang::Type &the_type, typet &new_type);
243
244 void get_ref_to_struct_type(typet &type);
245
246 bool get_builtin_type(const clang::BuiltinType &bt, typet &new_type);
247
249 const clang::FieldDecl &,
250 const typet &orig_type,
251 typet &new_type);
252
253 /* If `fd` is a bitfield, replace `t` with the bitfield-wrapped type
254 * carrying the #bitfield/width-N marker symex relies on. No-op otherwise.
255 * Centralises the wrapping logic shared by struct-component construction,
256 * member-expression lowering, and ctor member-initialiser-list lowering. */
257 bool wrap_bitfield_type_if_needed(const clang::FieldDecl &fd, typet &t);
258
259 /* If `vd` is a flexible array member, give its array type `t` size zero:
260 * C17 6.7.2.1p18 sizes the struct as if the member were omitted. Every site
261 * that lowers a field's type must agree, or members and components differ. */
262 void size_flexible_array_member(const clang::ValueDecl &vd, typet &t);
263
264 virtual bool get_expr(const clang::Stmt &stmt, exprt &new_expr);
265
267 const clang::InitListExpr &init,
268 std::vector<exprt> &flat);
269
270 /* The value `init`'s array filler gives each element past its explicit
271 * initialisers, or nil where that value is zero. */
272 bool get_array_filler(const clang::InitListExpr &init, exprt &filler);
273
274 bool get_enum_value(const clang::EnumConstantDecl *e, exprt &new_expr);
275
276 virtual bool get_decl_ref(const clang::Decl &decl, exprt &new_expr);
277
278 bool
279 get_binary_operator_expr(const clang::BinaryOperator &binop, exprt &new_expr);
280
282 const clang::BinaryOperator &binop,
283 irep_idt relation,
284 exprt lhs,
285 exprt rhs,
286 const typet &type,
287 exprt &new_expr);
288
290 const clang::CompoundAssignOperator &compop,
291 exprt &new_expr);
292
293 virtual bool
294 get_unary_operator_expr(const clang::UnaryOperator &uniop, exprt &new_expr);
295
296 bool get_atomic_expr(const clang::AtomicExpr &atm, exprt &new_expr);
297
298 virtual bool get_member_expr(const clang::MemberExpr &memb, exprt &new_expr);
299
300 bool get_cast_expr(const clang::CastExpr &cast, exprt &new_expr);
301
303 symbolt &symbol,
304 irep_idt module_name,
305 typet type,
306 irep_idt base_name,
307 irep_idt unique_name,
308 locationt location);
309
310 virtual void
311 get_decl_name(const clang::NamedDecl &vd, std::string &name, std::string &id);
312
313 void
314 get_start_location_from_stmt(const clang::Stmt &stmt, locationt &location);
315
318 bool report_unsupported_init_list(const clang::InitListExpr &init_stmt);
319
320 void
321 get_final_location_from_stmt(const clang::Stmt &stmt, locationt &location);
322
323 void get_location_from_decl(const clang::Decl &decl, locationt &location);
324
325 void set_location(
326 clang::PresumedLoc &PLoc,
327 std::string &function_name,
328 locationt &location);
329
331 const clang::SourceLocation &loc,
332 clang::PresumedLoc &PLoc);
333
334 std::string get_filename_from_path(std::string path);
335 std::string get_modulename_from_path(std::string path);
336
338
340 const clang::CharacterLiteral &char_literal,
341 exprt &dest);
342
344 const clang::StringLiteral &string_literal,
345 exprt &dest);
346
348 const clang::IntegerLiteral &integer_literal,
349 exprt &dest);
350
352 const clang::FloatingLiteral &floating_literal,
353 exprt &dest);
354
355 const clang::Decl *get_DeclContext_from_Stmt(const clang::Stmt &stmt);
356
357 const clang::Decl *get_top_FunctionDecl_from_Stmt(const clang::Stmt &stmt);
358
359 /*
360 * Helper function to process an AlignedAttr and set the alignment on a type
361 * Arguments:
362 * aattr: the AlignedAttr to process
363 * t: the type to set alignment on
364 */
365 bool
366 process_aligned_attribute(const clang::AlignedAttr &aattr, typet &t) const;
367
368 /*
369 * Apply a record's packing and alignment attributes to its type
370 * Arguments:
371 * rd: the record definition whose attributes to inspect
372 * t: the struct/union type to annotate
373 */
374 bool
375 process_record_layout_attributes(const clang::RecordDecl &rd, typet &t) const;
376
377 /*
378 * add additional annotations if a class/struct/union field has alignment
379 * attribute Arguments: field: clang AST representing the class/struct/union
380 * field we are dealing with comp: a `component` in class/struct/union's
381 * symbol type type: a class/struct/union's symbol type
382 */
384 const clang::FieldDecl *field,
386
387 /*
388 * check if a class/struct/union's field has global storage
389 * (e.g. static)
390 * Arguments:
391 * field: clang AST representing the class/struct/union field we are dealing
392 * with
393 */
394 bool is_field_global_storage(const clang::FieldDecl *field);
395
396 /*
397 * Function to check whether a member function call refers to
398 * a virtual/overriding method.
399 *
400 * Params:
401 * - member: a clang::MemberExpr representing member access x.F or x->F where
402 * where F could be a field or a method
403 *
404 * For C, it always return false.
405 */
406 virtual bool perform_virtual_dispatch(const clang::MemberExpr &member);
407
408 /*
409 * Function to get the ESBMC IR representing a virtual function table dynamic
410 * binding for "->" operator Turning x->F into x->X@vtable_pointer->F
411 *
412 * Params:
413 * - member: the method to which this MemberExpr refers
414 * - new_expr: ESBMC IR to represent `x->X@vtable_ptr->F`
415 *
416 * For C, it can't happen.
417 */
418 virtual bool
419 get_vft_binding_expr(const clang::MemberExpr &member, exprt &new_expr);
420
421 /*
422 * Function to check whether a clang::FunctionDec represents a
423 * clang::CXXMethodDecl that is virtual OR overrides another function
424 *
425 * Params:
426 * - fd: a clang::FunctionDec we are currently dealing with
427 *
428 * For C, it always return false.
429 */
430 virtual bool is_fd_virtual_or_overriding(const clang::FunctionDecl &fd);
431
432 virtual bool is_aggregate_type(const clang::QualType &q_type);
433
434 bool get_mangled_id(const clang::NamedDecl &nd, std::string &id);
436 const clang::TemplateParamObjectDecl &tpo,
437 const std::string &name,
438 const std::string &id);
439 bool get_APValue_expr(
440 const clang::APValue &value,
441 exprt &new_expr,
442 const clang::QualType *type = nullptr);
443
444 /*
445 * Function to check whether a MemberExpr references to a static variable
446 */
447 bool is_member_decl_static(const clang::MemberExpr &member);
448
460 const clang::Decl &d,
461 std::string &name,
462 std::string &id) const;
463
464 bool is_unlowered_math_builtin(const std::string &name) const;
465};
466
467#endif /* CLANG_C_FRONTEND_CLANG_C_CONVERT_H_ */
std::string getFullyQualifiedName(const clang::QualType &, const clang::ASTContext &)
Definition clang_c_convert.cpp:5319
bool get_mangled_id(const clang::NamedDecl &nd, std::string &id)
The USR generator gives up on some C++20 declarations: a specialisation over a class-type template ar...
Definition clang_c_convert.cpp:5412
virtual bool get_struct_union_class_methods_decls(const clang::RecordDecl &recordd, typet &type)
Definition clang_c_convert.cpp:495
void get_default_symbol(symbolt &symbol, irep_idt module_name, typet type, irep_idt base_name, irep_idt unique_name, locationt location)
Definition clang_c_convert.cpp:5291
void convert_expression_to_code(exprt &expr)
Definition clang_c_convert.cpp:5875
const clang::Decl * get_top_FunctionDecl_from_Stmt(const clang::Stmt &stmt)
Definition clang_c_convert.cpp:5907
bool add_template_param_object(const clang::TemplateParamObjectDecl &tpo, const std::string &name, const std::string &id)
bool process_aligned_attribute(const clang::AlignedAttr &aattr, typet &t) const
Definition clang_c_convert.cpp:5967
void get_final_location_from_stmt(const clang::Stmt &stmt, locationt &location)
Definition clang_c_convert.cpp:5756
bool get_vla_size(const clang::Expr &size, exprt &new_expr)
Definition clang_c_convert.cpp:700
void set_location(clang::PresumedLoc &PLoc, std::string &function_name, locationt &location)
Definition clang_c_convert.cpp:5814
void get_presumed_location(const clang::SourceLocation &loc, clang::PresumedLoc &PLoc)
Definition clang_c_convert.cpp:5795
virtual bool perform_virtual_dispatch(const clang::MemberExpr &member)
Definition clang_c_convert.cpp:6020
std::string tag_prefix
Definition clang_c_convert.h:106
void get_ref_to_struct_type(typet &type)
Definition clang_c_convert.cpp:6043
bool get_base_flattened_inits(const clang::InitListExpr &init, std::vector< exprt > &flat)
Definition clang_c_convert.cpp:2235
unsigned last_loc_column
Definition clang_c_convert.h:100
bool is_member_decl_static(const clang::MemberExpr &member)
Definition clang_c_convert.cpp:6073
std::string get_filename_from_path(std::string path)
Definition clang_c_convert.cpp:5867
std::unordered_map< const clang::Expr *, exprt > vla_size_snapshots
A block-scope VLA's size, bound to a local just before its declarator (C11 6.7.6.2p5,...
Definition clang_c_convert.h:119
virtual bool is_aggregate_type(const clang::QualType &q_type)
Definition clang_c_convert.cpp:6068
bool get_array_filler(const clang::InitListExpr &init, exprt &filler)
Definition clang_c_convert.cpp:2199
void rewrite_builtin_ref(const clang::Decl &d, std::string &name, std::string &id) const
Rewrites references to builtin functions to their ESBMC counterparts.
Definition clang_c_convert.cpp:4258
bool get_builtin_type(const clang::BuiltinType &bt, typet &new_type)
Definition clang_c_convert.cpp:1697
bool process_record_layout_attributes(const clang::RecordDecl &rd, typet &t) const
Definition clang_c_convert.cpp:5922
unsigned int current_scope_var_num
Definition clang_c_convert.h:108
bool get_binary_operator_expr(const clang::BinaryOperator &binop, exprt &new_expr)
Definition clang_c_convert.cpp:4673
virtual bool get_function_params(const clang::FunctionDecl &fd, code_typet::argumentst &params)
Parse function parameters This function simply contains a loop to populate the code argument list and...
Definition clang_c_convert.cpp:1060
void get_location_from_decl(const clang::Decl &decl, locationt &location)
Definition clang_c_convert.cpp:5773
static void gen_typecast_to_union(const namespacet &ns, exprt &dest, const typet &type)
Perform the typecast by creating a tmp variable on RHS.
Definition typecast.cpp:78
bool get_enum_value(const clang::EnumConstantDecl *e, exprt &new_expr)
Definition clang_c_convert.cpp:4138
clang_c_convertert(contextt &_context, std::unique_ptr< clang::ASTUnit > &_AST, irep_idt _mode)
Definition clang_c_convert.cpp:42
clang::ASTContext * ASTContext
Definition clang_c_convert.h:84
bool last_loc_valid
Definition clang_c_convert.h:103
virtual bool get_struct_union_class_fields(const clang::RecordDecl &recordd, struct_union_typet &type)
Definition clang_c_convert.cpp:470
bool get_compound_assign_expr(const clang::CompoundAssignOperator &compop, exprt &new_expr)
Definition clang_c_convert.cpp:4897
void get_vector_comparison(const clang::BinaryOperator &binop, irep_idt relation, exprt lhs, exprt rhs, const typet &type, exprt &new_expr)
Definition clang_c_convert.cpp:4831
bool report_unsupported_init_list(const clang::InitListExpr &init_stmt)
Report an initializer list none of get_expr's arms models, with its type and source location....
Definition clang_c_convert.cpp:2313
virtual bool get_type(const clang::QualType &type, typet &new_type)
Definition clang_c_convert.cpp:1158
virtual bool get_unary_operator_expr(const clang::UnaryOperator &uniop, exprt &new_expr)
Definition clang_c_convert.cpp:4587
bool get_bitfield_type(const clang::FieldDecl &, const typet &orig_type, typet &new_type)
Definition clang_c_convert.cpp:2154
namespacet ns
Definition clang_c_convert.h:86
std::unique_ptr< clang::ASTUnit > & AST
Definition clang_c_convert.h:87
symbol_generator anon_symbol
Definition clang_c_convert.h:89
bool is_field_global_storage(const clang::FieldDecl *field)
Definition clang_c_convert.cpp:6012
virtual bool get_expr(const clang::Stmt &stmt, exprt &new_expr)
Definition clang_c_convert.cpp:2332
std::string last_loc_filename
Definition clang_c_convert.h:101
bool convert_integer_literal(const clang::IntegerLiteral &integer_literal, exprt &dest)
Definition clang_c_convert_literals.cpp:64
bool snapshot_vla_sizes(const clang::Decl &decl, codet &dest)
Definition clang_c_convert.cpp:644
std::vector< const clang::LabelDecl * > address_taken_labels
Address-taken labels of the function being converted, in the order the addresses appear.
Definition clang_c_convert.h:134
virtual bool get_member_expr(const clang::MemberExpr &memb, exprt &new_expr)
Definition clang_c_convert.cpp:5251
virtual void annotate_exception_specification(const clang::FunctionDecl &, typet &)
Since this class is inherited by clang-cpp-frontend, some get_* functions are made `virtual' to deal ...
Definition clang_c_convert.h:181
virtual bool convert_top_level_decl()
Definition clang_c_convert.cpp:86
unsigned last_loc_line
Definition clang_c_convert.h:99
bool check_alignment_attributes(const clang::FieldDecl *field, struct_typet::componentt &comp)
Definition clang_c_convert.cpp:5990
irep_idt mode
Definition clang_c_convert.h:88
code_blockt * current_block
During get_expr(), which also transforms blocks/scopes, this represents the latest opened blocks from...
Definition clang_c_convert.h:114
bool convert_string_literal(const clang::StringLiteral &string_literal, exprt &dest)
Definition clang_c_convert_literals.cpp:32
std::string last_loc_function
Definition clang_c_convert.h:102
bool get_atomic_expr(const clang::AtomicExpr &atm, exprt &new_expr)
Definition clang_c_convert.cpp:5026
virtual bool is_fd_virtual_or_overriding(const clang::FunctionDecl &fd)
Definition clang_c_convert.cpp:6026
bool get_APValue_expr(const clang::APValue &value, exprt &new_expr, const clang::QualType *type=nullptr)
Definition clang_c_convert.cpp:6090
bool is_unlowered_math_builtin(const std::string &name) const
__builtin_copysign and the other __builtin_ spellings of a <math.h> function have no body; the plain ...
Definition clang_c_convert.cpp:4244
static std::string get_decl_name(const clang::NamedDecl &nd)
Definition clang_c_convert.cpp:5307
virtual bool get_vft_binding_expr(const clang::MemberExpr &member, exprt &new_expr)
Definition clang_c_convert.cpp:6033
bool get_cast_expr(const clang::CastExpr &cast, exprt &new_expr)
Definition clang_c_convert.cpp:4292
bool get_function_param(const clang::ParmVarDecl &pd, exprt &param)
Parse each individual parameter of the function.
Definition clang_c_convert.cpp:1079
const clang::FunctionDecl * current_functionDecl
Definition clang_c_convert.h:125
clang::SourceManager * sm
Definition clang_c_convert.h:123
bool convert_builtin_types()
Definition clang_c_convert.cpp:67
bool wrap_bitfield_type_if_needed(const clang::FieldDecl &fd, typet &t)
Definition clang_c_convert.cpp:2132
contextt & context
Definition clang_c_convert.h:85
bool convert_float_literal(const clang::FloatingLiteral &floating_literal, exprt &dest)
Definition clang_c_convert_literals.cpp:150
virtual bool get_struct_union_class(const clang::RecordDecl &recordd)
Definition clang_c_convert.cpp:331
bool convert_character_literal(const clang::CharacterLiteral &char_literal, exprt &dest)
Definition clang_c_convert_literals.cpp:16
virtual bool get_decl_ref(const clang::Decl &decl, exprt &new_expr)
Definition clang_c_convert.cpp:4180
std::string get_modulename_from_path(std::string path)
Definition clang_c_convert.cpp:5857
locationt last_loc
Definition clang_c_convert.h:98
virtual ~clang_c_convertert()=default
void collect_address_taken_labels(const clang::Stmt &body)
Definition clang_c_convert.cpp:1027
virtual void name_param_and_continue(const clang::ParmVarDecl &pd, std::string &id, std::string &name, exprt &param)
Definition clang_c_convert.cpp:1144
void size_flexible_array_member(const clang::ValueDecl &vd, typet &t)
Definition clang_c_convert.cpp:2146
const clang::Decl * get_DeclContext_from_Stmt(const clang::Stmt &stmt)
Definition clang_c_convert.cpp:5888
bool convert()
Definition clang_c_convert.cpp:59
void get_start_location_from_stmt(const clang::Stmt &stmt, locationt &location)
Definition clang_c_convert.cpp:5739
Definition std_code.h:49
Definition std_types.h:280
std::vector< argumentt > argumentst
Definition std_types.h:283
Definition std_code.h:8
Definition context.h:57
Definition expr.h:34
Definition irep_idt.h:12
Definition location.h:7
Definition namespace.h:10
Definition std_types.h:87
Definition std_types.h:78
Definition symbol_generator.h:7
Definition symbol.h:12
Definition type.h:9
Definition toml.hpp:1531
Definition build_ast.h:13
Definition path.py:1
static std::optional< std::string > string_literal(const nlohmann::json &node)
Definition expr.cpp:7235
Definition ld_ast.h:182