ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
clang_cpp_convert.cpp File Reference
#include <util/base/compiler_defs.h>
#include <clang/Basic/Version.inc>
#include <clang/AST/Attr.h>
#include <clang/AST/DeclCXX.h>
#include <clang/AST/DeclFriend.h>
#include <clang/AST/DeclTemplate.h>
#include <clang/AST/Expr.h>
#include <clang/AST/ExprCXX.h>
#include <clang/AST/QualTypeNames.h>
#include <clang/AST/RecursiveASTVisitor.h>
#include <clang/AST/RecordLayout.h>
#include <clang/AST/Type.h>
#include <clang/Index/USRGeneration.h>
#include <clang/Frontend/ASTUnit.h>
#include <clang/AST/ParentMapContext.h>
#include <llvm/ADT/SmallVector.h>
#include <llvm/ADT/STLExtras.h>
#include <llvm/Support/raw_os_ostream.h>
#include <clang-c-frontend/clang_ast_dump.h>
#include <clang-cpp-frontend/clang_cpp_convert.h>
#include <clang-cpp-frontend/clang_cpp_exception_id.h>
#include <util/expr/expr_util.h>
#include <util/message/message.h>
#include <util/irep/std_code.h>
#include <util/irep/std_expr.h>
#include <fmt/core.h>
#include <clang-c-frontend/typecast.h>
#include <util/arith/arith_tools.h>
#include <util/lang/c_types.h>
#include <util/lang/exception_specification.h>
#include <util/expr/string_constant.h>
#include <util/expr/symbolic_types.h>
#include <util/symtab/base_subobject.h>
Include dependency graph for clang_cpp_convert.cpp:

Functions

static bool print_nullptr_arg_types (llvm::ArrayRef< clang::TemplateArgument > args, llvm::raw_ostream &os)
static std::string usr_gap_suffix (const clang::Decl &decl, const clang::ASTContext &ctx)
static void replace_new_object_with (const exprt &object, exprt &dest)
static bool is_aligned_deallocation (const clang::FunctionDecl &op_del)
static const clang::FunctionDecl * resolve_deallocation_function (const clang::FunctionDecl *op_del, bool array_form)
static bool zero_initialises (const clang::Expr &init)
static void set_handler_exception_id (const namespacet &ns, exprt &handler)
 The id a catch handler matches a throw on.
static void reduce_pseudo_destructor_call (exprt &expr)
 A pseudo-destructor call does nothing but evaluate its base ([expr.pseudo]/1) – there is nothing to call.
static bool exception_id_needs_no_lookup (const typet &type)
 Whether a thrown type's exception ids follow from the type alone, and cannot change between here and the adjust pass.
static void record_primitive_exception_ids (exprt &throw_expr, const namespacet &ns)
 Record a throw's exception ids at conversion time, for the operand types whose ids follow from the type alone.
static bool ctor_needs_is_complete_param (const clang::CXXConstructorDecl &cxxcd)
static code_function_callt destructor_call (const symbolt &sym, exprt arg)
static std::size_t construction_position (const clang::CXXCtorInitializer &init, const std::vector< const clang::Type * > &bases)
 The position in construction order of the subobject init builds, as subobject_destructors numbers them; bases are the direct non-virtual bases in declaration order.
static bool cannot_throw (const clang::CXXConstructorDecl &cd)
static code_blockt catch_all_handler ()
static code_blockt destroy_built_subobjects (const exprt &built, const std::vector< clang_cpp_convertert::subobject_destructort > &dtors)
 catch (...) { <destroy each built subobject, newest first> }
static const clang::Expr * peel_initializer_wrapper (const clang::Expr *e)
static const clang::Expr * peel_elided_copy (const clang::Expr *e)
static const clang::Expr & member_result_object (const clang::Expr &init)
static bool is_constructor_temporary (const exprt &e)
static const clang::Expr & conditional_branch_source (const clang::Expr &branch)

Function Documentation

◆ cannot_throw()

bool cannot_throw ( const clang::CXXConstructorDecl & cd)
static

◆ catch_all_handler()

code_blockt catch_all_handler ( )
static

◆ conditional_branch_source()

const clang::Expr & conditional_branch_source ( const clang::Expr & branch)
static

◆ construction_position()

std::size_t construction_position ( const clang::CXXCtorInitializer & init,
const std::vector< const clang::Type * > & bases )
static

The position in construction order of the subobject init builds, as subobject_destructors numbers them; bases are the direct non-virtual bases in declaration order.

◆ ctor_needs_is_complete_param()

bool ctor_needs_is_complete_param ( const clang::CXXConstructorDecl & cxxcd)
static

◆ destroy_built_subobjects()

code_blockt destroy_built_subobjects ( const exprt & built,
const std::vector< clang_cpp_convertert::subobject_destructort > & dtors )
static

catch (...) { <destroy each built subobject, newest first> }

◆ destructor_call()

code_function_callt destructor_call ( const symbolt & sym,
exprt arg )
static

◆ exception_id_needs_no_lookup()

bool exception_id_needs_no_lookup ( const typet & type)
static

Whether a thrown type's exception ids follow from the type alone, and cannot change between here and the adjust pass.

A class type's id is its symbol's name and its bases come from the symbol table, a lookup this early in conversion cannot rely on; everything else resolves to the #cpp_type spelling, which the IREP2 seam does not carry, so those ids are recorded at conversion time instead (§7.6). Pointer layers are stripped because convert_exception_id recurses through them.

An array operand is excluded: it decays between here and the legacy pass, so an id recorded from the pre-decay type is not the one the handler is matched against. A pointer is fine and is recursed through, as convert_exception_id does.

◆ is_aligned_deallocation()

bool is_aligned_deallocation ( const clang::FunctionDecl & op_del)
static

◆ is_constructor_temporary()

bool is_constructor_temporary ( const exprt & e)
static

◆ member_result_object()

const clang::Expr & member_result_object ( const clang::Expr & init)
static

◆ peel_elided_copy()

const clang::Expr * peel_elided_copy ( const clang::Expr * e)
static

◆ peel_initializer_wrapper()

const clang::Expr * peel_initializer_wrapper ( const clang::Expr * e)
static

◆ print_nullptr_arg_types()

bool print_nullptr_arg_types ( llvm::ArrayRef< clang::TemplateArgument > args,
llvm::raw_ostream & os )
static

◆ record_primitive_exception_ids()

void record_primitive_exception_ids ( exprt & throw_expr,
const namespacet & ns )
static

Record a throw's exception ids at conversion time, for the operand types whose ids follow from the type alone.

A primitive's id is its #cpp_type spelling, and the IREP2 seam does not carry that: computed from a back-migrated type, throw 1 reads as signedbv while the handler, whose ids never cross the seam, still reads signed_int, and the throw escapes uncaught. A class type is left to the adjust pass instead: its id is the type symbol's name, which crosses intact, and resolving its bases needs a lookup this early in conversion (docs/roadmap/scope-clang-cpp-irep2.md §7.6).

◆ reduce_pseudo_destructor_call()

void reduce_pseudo_destructor_call ( exprt & expr)
static

A pseudo-destructor call does nothing but evaluate its base ([expr.pseudo]/1) – there is nothing to call.

Reduce it where it is built, so the node never reaches the goto program: IREP2 has no kind for it, and an adjust pass that migrates first therefore cannot see it at all (docs/roadmap/scope-clang-cpp-irep2.md §3.15). Applied at get_expr's exit so it covers every call spelling, as clang_cpp_adjust's arm did.

◆ replace_new_object_with()

void replace_new_object_with ( const exprt & object,
exprt & dest )
static

◆ resolve_deallocation_function()

const clang::FunctionDecl * resolve_deallocation_function ( const clang::FunctionDecl * op_del,
bool array_form )
static

◆ set_handler_exception_id()

void set_handler_exception_id ( const namespacet & ns,
exprt & handler )
static

The id a catch handler matches a throw on.

The catch type rides on the handler block's own type and is read off it exactly once – here. clang_cpp_adjust used to do it, which is too late for an IREP2 adjust pass: code_block2t has no type to carry it across the seam (docs/roadmap/scope-clang-cpp-irep2.md §3.13).

◆ usr_gap_suffix()

std::string usr_gap_suffix ( const clang::Decl & decl,
const clang::ASTContext & ctx )
static

◆ zero_initialises()

bool zero_initialises ( const clang::Expr & init)
static