Пример #1
0
void cpp_declarator_convertert::handle_initializer(
    symbolt &symbol,
    cpp_declaratort &declarator)
{
    exprt &value=declarator.value();

    // moves member initializers into 'value'
    cpp_typecheck.move_member_initializers(
        declarator.member_initializers(),
        symbol.type,
        value);

    // any initializer to be done?
    if(value.is_nil())
        return;

    if(symbol.is_extern)
    {
        // the symbol is really located here
        symbol.is_extern=false;
    }

    if(symbol.value.is_nil())
    {
        // no initial value yet
        symbol.value.swap(value);

        if(is_code && declarator.type().id()!=ID_template)
            cpp_typecheck.add_function_body(&symbol);

        if(!is_code)
            cpp_typecheck.convert_initializer(symbol);
    }
    else
    {
#if 0
        cpp_typecheck.err_location(declarator.name());

        if(is_code)
            cpp_typecheck.str << "body of function `"
                              << symbol.display_name()
                              << "' has already been defined";
        else
            cpp_typecheck.str << "symbol `"
                              << symbol.display_name()
                              << "' already has an initializer";

        throw 0;
#endif
    }
}
Пример #2
0
void xml_symbol_convertt::convert(const symbolt& sym, xmlt &root)
{
  xmlt &xmlsym = root.new_element("symbol");
  irepcache.push_back(irept());
  sym.to_irep(irepcache.back());  
  irepconverter.reference_convert(irepcache.back(), xmlsym);
}
Пример #3
0
void xml_symbol_convertt::convert(const xmlt &xmlsym, symbolt& symbol)
{  
  irept t;
  
  irepconverter.convert(xmlsym, t);
  irepconverter.resolve_references(t);
  symbol.from_irep(t); 
}
Пример #4
0
void assign_in_cprover_init(goto_functionst &gf, symbolt &symbol,
    const exprt &value)
{
  symbol.value=value;
  goto_programt &body=get_body(gf, CPROVER_INIT);
  goto_programt::instructionst &instrs=body.instructions;
  const auto p(std::mem_fun_ref(&goto_programt::instructiont::is_end_function));
  goto_programt::targett pos=std::find_if(instrs.begin(), instrs.end(), p);
  assert(instrs.end() != pos);
  pos=insert_before_preserving_source_location(body, pos);
  pos->type=goto_program_instruction_typet::ASSIGN;
  const symbol_exprt lhs(symbol.symbol_expr());
  pos->code=code_assignt(lhs, value);
}
Пример #5
0
void cpp_declarator_convertert::combine_types(
    const source_locationt &source_location,
    const typet &decl_type,
    symbolt &symbol)
{
    if(symbol.type.id()==decl_type.id() &&
            decl_type.id()==ID_code)
    {
        // functions need special treatment due
        // to argument names, default values, and inlined-ness
        const code_typet &decl_code_type=to_code_type(decl_type);
        code_typet &symbol_code_type=to_code_type(symbol.type);

        if(decl_code_type.get_inlined())
            symbol_code_type.set_inlined(true);

        if(decl_code_type.return_type()==symbol_code_type.return_type() &&
                decl_code_type.parameters().size()==symbol_code_type.parameters().size())
        {
            for(unsigned i=0; i<decl_code_type.parameters().size(); i++)
            {
                const code_typet::parametert &decl_parameter=decl_code_type.parameters()[i];
                code_typet::parametert &symbol_parameter=symbol_code_type.parameters()[i];

                // first check type
                if(decl_parameter.type()!=symbol_parameter.type())
                {
                    // The 'this' parameter of virtual functions mismatches
                    if(i!=0 || !symbol_code_type.get_bool("#is_virtual"))
                    {
                        cpp_typecheck.err_location(source_location);
                        cpp_typecheck.str << "symbol `" << symbol.display_name()
                                          << "': parameter " << (i+1) << " type mismatch"
                                          << std::endl;
                        cpp_typecheck.str << "previous type: "
                                          << cpp_typecheck.to_string(symbol_parameter.type()) << std::endl;
                        cpp_typecheck.str << "new type: "
                                          << cpp_typecheck.to_string(decl_parameter.type());
                        throw 0;
                    }
                }

                if(symbol.value.is_nil())
                {
                    symbol_parameter.set_base_name(decl_parameter.get_base_name());
                    symbol_parameter.set_identifier(decl_parameter.get_identifier());
                    symbol_parameter.add_source_location()=decl_parameter.source_location();
                }
            }

            // ok
            return;
        }
    }
    else if(symbol.type==decl_type)
        return; // ok
    else if(symbol.type.id()==ID_array &&
            symbol.type.find(ID_size).is_nil() &&
            decl_type.id()==ID_array &&
            symbol.type.subtype()==decl_type.subtype())
    {
        symbol.type = decl_type;
        return; // ok
    }

    cpp_typecheck.err_location(source_location);
    cpp_typecheck.str << "symbol `" << symbol.display_name()
                      << "' already declared with different type:"
                      << std::endl;
    cpp_typecheck.str << "original: "
                      << cpp_typecheck.to_string(symbol.type) << std::endl;
    cpp_typecheck.str << "     new: "
                      << cpp_typecheck.to_string(final_type);
    throw 0;
}
Пример #6
0
void c_typecheck_baset::typecheck_symbol(symbolt &symbol)
{
  current_symbol_id=symbol.name;

  bool is_function=symbol.type.id()==ID_code;

  const typet &final_type=follow(symbol.type);
  
  // set a few flags
  symbol.is_lvalue=!symbol.is_type && !symbol.is_macro;
  
  irep_idt root_name=symbol.base_name;
  irep_idt new_name=symbol.name;

  if(symbol.is_file_local)
  {
    // file-local stuff -- stays as is
    // collisions are resolved during linking
  }
  else if(symbol.is_extern && !is_function)
  {
    // variables marked as "extern" go into the global namespace
    // and have static lifetime
    new_name=root_name;
    symbol.is_static_lifetime=true;
  }
  else if(!is_function && symbol.value.id()==ID_code)
  {
    err_location(symbol.value);
    throw "only functions can have a function body";
  }
  
  // set the pretty name
  if(symbol.is_type &&
     (final_type.id()==ID_struct ||
      final_type.id()==ID_incomplete_struct))
  {
    symbol.pretty_name="struct "+id2string(symbol.base_name);
  }
  else if(symbol.is_type &&
          (final_type.id()==ID_union ||
           final_type.id()==ID_incomplete_union))
  {
    symbol.pretty_name="union "+id2string(symbol.base_name);
  }
  else if(symbol.is_type &&
          (final_type.id()==ID_c_enum ||
           final_type.id()==ID_incomplete_c_enum))
  {
    symbol.pretty_name="enum "+id2string(symbol.base_name);
  }
  else
  {
    symbol.pretty_name=new_name;
  }
  
  // see if we have it already
  symbol_tablet::symbolst::iterator old_it=symbol_table.symbols.find(symbol.name);
  
  if(old_it==symbol_table.symbols.end())
  {
    // just put into symbol_table
    symbolt *new_symbol;
    move_symbol(symbol, new_symbol);
    
    typecheck_new_symbol(*new_symbol);
  }    
  else
  {
    if(old_it->second.is_type!=symbol.is_type)
    {
      err_location(symbol.location);
      str << "redeclaration of `" << symbol.display_name()
          << "' as a different kind of symbol";
      throw 0;
    }

    if(symbol.is_type)
      typecheck_redefinition_type(old_it->second, symbol);
    else
      typecheck_redefinition_non_type(old_it->second, symbol);
  }
}
Пример #7
0
void c_typecheck_baset::typecheck_redefinition_non_type(
  symbolt &old_symbol,
  symbolt &new_symbol)
{
  const typet &final_old=follow(old_symbol.type);
  const typet &initial_new=follow(new_symbol.type);

  if(final_old.id()==ID_array &&
     to_array_type(final_old).size().is_not_nil() &&
     initial_new.id()==ID_array &&
     to_array_type(initial_new).size().is_nil() &&
     final_old.subtype()==initial_new.subtype())
  {
    // this is ok, just use old type
    new_symbol.type=old_symbol.type;
  }

  // do initializer, this may change the type
  if(follow(new_symbol.type).id()!=ID_code)
    do_initializer(new_symbol);
  
  const typet &final_new=follow(new_symbol.type);
  
  // K&R stuff?
  if(old_symbol.type.id()==ID_KnR)
  {
    // check the type
    if(final_new.id()==ID_code)
    {
      err_location(new_symbol.location);
      throw "function type not allowed for K&R function parameter";
    }
    
    // fix up old symbol -- we now got the type
    old_symbol.type=new_symbol.type;
    return;
  }
  
  if(final_new.id()==ID_code)
  {
    bool inlined=
       (new_symbol.type.get_bool(ID_C_inlined) ||
        old_symbol.type.get_bool(ID_C_inlined));
        
    if(final_old.id()!=ID_code)
    {
      err_location(new_symbol.location);
      str << "error: function symbol `" << new_symbol.display_name()
          << "' redefined with a different type:" << "\n";
      str << "Original: " << to_string(old_symbol.type) << "\n";
      str << "     New: " << to_string(new_symbol.type);
      throw 0;
    }

    code_typet &old_ct=to_code_type(old_symbol.type);
    code_typet &new_ct=to_code_type(new_symbol.type);
    
    if(old_ct.has_ellipsis() && !new_ct.has_ellipsis())
      old_ct=new_ct;
    else if(!old_ct.has_ellipsis() && new_ct.has_ellipsis())
      new_ct=old_ct;

    if(inlined)
    {
      old_symbol.type.set(ID_C_inlined, true);
      new_symbol.type.set(ID_C_inlined, true);
    }

    // do body
    
    if(new_symbol.value.is_not_nil())
    {  
      if(old_symbol.value.is_not_nil())
      {
        // gcc allows re-definition if the first
        // definition is marked as "extern inline"
        
        if(old_symbol.type.get_bool(ID_C_inlined) &&
           (config.ansi_c.mode==configt::ansi_ct::flavourt::MODE_GCC_C ||
            config.ansi_c.mode==configt::ansi_ct::flavourt::MODE_ARM_C_CPP))
        {
          // overwrite "extern inline" properties
          old_symbol.is_extern=new_symbol.is_extern;
          old_symbol.is_file_local=new_symbol.is_file_local;

          // remove parameter declarations to avoid conflicts
          const code_typet::parameterst &old_p=old_ct.parameters();
          for(code_typet::parameterst::const_iterator
              p_it=old_p.begin();
              p_it!=old_p.end();
              p_it++)
          {
            const irep_idt &identifier=p_it->get_identifier();

            symbol_tablet::symbolst::iterator p_s_it=
              symbol_table.symbols.find(identifier);
            if(p_s_it!=symbol_table.symbols.end())
              symbol_table.symbols.erase(p_s_it);
          }
        }
        else
        {
          err_location(new_symbol.location);
          str << "function body `" << new_symbol.display_name()
              << "' defined twice";
          error_msg();
          throw 0;
        }
      }
      else if(inlined)
      {
        // preserve "extern inline" properties
        old_symbol.is_extern=new_symbol.is_extern;
        old_symbol.is_file_local=new_symbol.is_file_local;
      }

      typecheck_function_body(new_symbol);
    
      // overwrite location
      old_symbol.location=new_symbol.location;
    
      // move body
      old_symbol.value.swap(new_symbol.value);

      // overwrite type (because of parameter names)
      old_symbol.type=new_symbol.type;
    }

    return;
  }

  if(final_old!=final_new)
  {
    if(final_old.id()==ID_array &&
            to_array_type(final_old).size().is_nil() &&
            final_new.id()==ID_array &&
            to_array_type(final_new).size().is_not_nil() &&
            final_old.subtype()==final_new.subtype())
    {
      // this is also ok
      if(old_symbol.type.id()==ID_symbol)
      {
        // fix the symbol, not just the type
        const irep_idt identifier=
          to_symbol_type(old_symbol.type).get_identifier();

        symbol_tablet::symbolst::iterator s_it=symbol_table.symbols.find(identifier);
  
        if(s_it==symbol_table.symbols.end())
        {
          err_location(old_symbol.location);
          str << "typecheck_redefinition_non_type: "
                 "failed to find symbol `" << identifier << "'";
          throw 0;
        }
                  
        symbolt &symbol=s_it->second;
          
        symbol.type=final_new;          
      }
      else
        old_symbol.type=new_symbol.type;
    }
    else if((final_old.id()==ID_incomplete_c_enum ||
             final_old.id()==ID_c_enum) &&
            (final_new.id()==ID_incomplete_c_enum ||
             final_new.id()==ID_c_enum))
    {
      // this is ok for now
    }
    else if(final_old.id()==ID_pointer &&
            follow(final_old).subtype().id()==ID_code &&
            to_code_type(follow(final_old).subtype()).has_ellipsis() &&
            final_new.id()==ID_pointer &&
            follow(final_new).subtype().id()==ID_code)
    {
      // to allow 
      // int (*f) ();
      // int (*f) (int)=0;
      old_symbol.type=new_symbol.type;
    }
    else if(final_old.id()==ID_pointer &&
            follow(final_old).subtype().id()==ID_code &&
            final_new.id()==ID_pointer &&
            follow(final_new).subtype().id()==ID_code &&
            to_code_type(follow(final_new).subtype()).has_ellipsis())
    {
      // to allow 
      // int (*f) (int)=0;
      // int (*f) ();
    }
    else
    {
      err_location(new_symbol.location);
      str << "error: symbol `" << new_symbol.display_name()
          << "' redefined with a different type:" << "\n";
      str << "Original: " << to_string(old_symbol.type) << "\n";
      str << "     New: " << to_string(new_symbol.type);
      throw 0;
    }
  }
  else // finals are equal
  {
  }

  // do value
  if(new_symbol.value.is_not_nil())
  {
    // see if we already have one
    if(old_symbol.value.is_not_nil())
    {
      if(new_symbol.value.get_bool(ID_C_zero_initializer))
      {
        // do nothing
      }
      else if(old_symbol.value.get_bool(ID_C_zero_initializer))
      {
        old_symbol.value=new_symbol.value;
        old_symbol.type=new_symbol.type;
      }
      else
      {
        if(new_symbol.is_macro &&
           (final_new.id()==ID_incomplete_c_enum ||
            final_new.id()==ID_c_enum) &&
            old_symbol.value.is_constant() &&
            new_symbol.value.is_constant() &&
            old_symbol.value.get(ID_value)==new_symbol.value.get(ID_value))
        {
          // ignore
        }
        else
        {
          err_location(new_symbol.value);
          str << "symbol `" << new_symbol.display_name()
              << "' already has an initial value";
          warning_msg();
        }
      }
    }
    else
    {
      old_symbol.value=new_symbol.value;
      old_symbol.type=new_symbol.type;
    }
  }
  
  // take care of some flags
  if(old_symbol.is_extern && !new_symbol.is_extern)
    old_symbol.location=new_symbol.location;

  old_symbol.is_extern=old_symbol.is_extern && new_symbol.is_extern;
  
  // We should likely check is_volatile and
  // is_thread_local for consistency. GCC complains if these
  // mismatch.
}
Пример #8
0
void c_typecheck_baset::typecheck_redefinition_type(
  symbolt &old_symbol,
  symbolt &new_symbol)
{
  const typet &final_old=follow(old_symbol.type);
  const typet &final_new=follow(new_symbol.type);

  // see if we had s.th. incomplete before
  if(final_old.id()==ID_incomplete_struct ||
     final_old.id()==ID_incomplete_union ||
     final_old.id()==ID_incomplete_c_enum)
  {
    // new one complete?
    if("incomplete_"+final_new.id_string()==final_old.id_string())
    {
      // overwrite location
      old_symbol.location=new_symbol.location;
      
      // move body
      old_symbol.type.swap(new_symbol.type);
    }
    else if(new_symbol.type.id()==old_symbol.type.id())
      return;
    else
    {
      err_location(new_symbol.location);
      str << "error: conflicting definition of type symbol `"
          << new_symbol.display_name()
          << "'";
      throw 0;
    }
  }
  else
  {
    // see if new one is just a tag
    if(final_new.id()==ID_incomplete_struct ||
       final_new.id()==ID_incomplete_union ||
       final_new.id()==ID_incomplete_c_enum)
    {
      if("incomplete_"+final_old.id_string()==final_new.id_string())
      {
        // just ignore silently  
      }
      else
      {
        // arg! new tag type
        err_location(new_symbol.location);
        str << "error: conflicting definition of tag symbol `"
            << new_symbol.display_name()
            << "'";
        throw 0;
      }
    }
    else if(config.ansi_c.os==configt::ansi_ct::ost::OS_WIN &&
            final_new.id()==ID_c_enum && final_old.id()==ID_c_enum)              
    {        
      // under Windows, ignore this silently;
      // MSC doesn't think this is a problem, but GCC complains.
    }
    else if(config.ansi_c.os==configt::ansi_ct::ost::OS_WIN &&
            final_new.id()==ID_pointer && final_old.id()==ID_pointer &&
            follow(final_new.subtype()).id()==ID_c_enum &&
            follow(final_old.subtype()).id()==ID_c_enum)
    {
      // under Windows, ignore this silently;
      // MSC doesn't think this is a problem, but GCC complains.
    }
    else
    {
      // see if it changed
      if(follow(new_symbol.type)!=follow(old_symbol.type))
      {
        err_location(new_symbol.location);
        str << "error: type symbol `" << new_symbol.display_name()
            << "' defined twice:" << "\n";
        str << "Original: " << to_string(old_symbol.type) << "\n";
        str << "     New: " << to_string(new_symbol.type);
        throw 0;
      }
    }
  }
}
Пример #9
0
void linkingt::duplicate_non_type_symbol(
  symbolt &old_symbol,
  symbolt &new_symbol)
{
  // We first take care of file-local non-type symbols.
  // These are static functions, or static variables
  // inside function bodies.
  if(new_symbol.is_file_local ||
     old_symbol.is_file_local)
  {
    // we just always rename these
    irep_idt old_identifier=new_symbol.name;
    irep_idt new_identifier=rename(old_identifier);
    replace_symbol.insert(
        old_identifier,
        symbol_exprt(new_identifier, new_symbol.type));

    new_symbol.name=new_identifier;
    
    // move over!
    bool result=main_context.move(new_symbol);
    assert(!result);
    
    return;
  }
  
  // see if it is a function or a variable

  bool is_code_old_symbol=old_symbol.type.id()==ID_code;
  bool is_code_new_symbol=new_symbol.type.id()==ID_code;

  if(is_code_old_symbol!=is_code_new_symbol)
  {
    err_location(new_symbol.location);
    str << "error: conflicting definition for symbol \""
        << old_symbol.display_name()
        << "\"" << std::endl;
    str << "old definition: " << to_string(old_symbol.type)
        << std::endl;
    str << "Module: " << old_symbol.module << std::endl;
    str << "new definition: " << to_string(new_symbol.type)
        << std::endl;
    str << "Module: " << new_symbol.module;
    throw 0;
  }

  if(is_code_old_symbol)
  {
    // Both are functions.
    // We don't compare the types, they will be too different;
    // we just care about the code

    if(!new_symbol.value.is_nil())
    {
      if(old_symbol.value.is_nil())
      {
        // the one with body wins!
        old_symbol.value=new_symbol.value;
        old_symbol.type=new_symbol.type; // for argument identifiers
      }
      else if(to_code_type(old_symbol.type).get_inlined())
      {
        // ok
      }
      else if(base_type_eq(old_symbol.type, new_symbol.type, ns))
      {
        // keep the one in old_symbol -- libraries come last!
        str << "warning: function `" << old_symbol.name << "' in module `" << 
          new_symbol.module << "' is shadowed by a definition in module `" << 
          old_symbol.module << "'";
        warning();
      }
      else
      {
        err_location(new_symbol.value);
        str << "error: duplicate definition of function `"
            << old_symbol.name
            << "'" << std::endl;
        str << "In module `" << old_symbol.module
            << "' and module `" << new_symbol.module << "'";
        throw 0;
      }
    }
  }
  else
  {
    // both are variables

    if(!base_type_eq(old_symbol.type, new_symbol.type, ns))
    {
      if(ns.follow(old_symbol.type).id()==ID_array &&
         ns.follow(new_symbol.type).id()==ID_array)
      {
        if(to_array_type(ns.follow(old_symbol.type)).size().is_nil() &&
           to_array_type(ns.follow(new_symbol.type)).size().is_not_nil())
          old_symbol.type=new_symbol.type; // store new type
      }
      else if(ns.follow(old_symbol.type).id()==ID_pointer &&
              ns.follow(new_symbol.type).id()==ID_array)
      {
        // store new type
        old_symbol.type=new_symbol.type;
      }
      else if(ns.follow(old_symbol.type).id()==ID_array &&
              ns.follow(new_symbol.type).id()==ID_pointer)
      {
        // ignore
      }
      else if(ns.follow(old_symbol.type).id()==ID_pointer &&
              ns.follow(new_symbol.type).id()==ID_pointer)
      {
        // ignore, generally ok
      }
      else if(old_symbol.type.id()==ID_incomplete_struct &&
              new_symbol.type.id()==ID_struct)
      {
        // store new type
        old_symbol.type=new_symbol.type;
      }
      else if(old_symbol.type.id()==ID_struct &&
              new_symbol.type.id()==ID_incomplete_struct)
      {
        // ignore
      }
      else
      {
        err_location(new_symbol.location);
        str << "error: conflicting definition for variable `"
            << old_symbol.name
            << "'" << std::endl;
        str << "old definition: " << to_string_verbose(old_symbol.type)
            << std::endl;
        str << "Module: " << old_symbol.module << std::endl;
        str << "new definition: " << to_string_verbose(new_symbol.type)
            << std::endl;
        str << "Module: " << new_symbol.module;
        throw 0;
      }
    }

    // care about initializers    

    if(!new_symbol.value.is_nil() &&
       !new_symbol.value.get_bool(ID_C_zero_initializer))
    {
      if(old_symbol.value.is_nil() ||
         old_symbol.value.get_bool(ID_C_zero_initializer))
      {
        // new_symbol wins
        old_symbol.value=new_symbol.value;
      }
      else
      {
        // try simplifier
        exprt tmp_old=old_symbol.value,
              tmp_new=new_symbol.value;
              
        simplify(tmp_old, ns);
        simplify(tmp_new, ns);
        
        if(base_type_eq(tmp_old, tmp_new, ns))
        {
          // ok, the same
        }
        else
        {
          err_location(new_symbol.value);
          str << "error: conflicting initializers for variable `"
              << old_symbol.name
              << "'" << std::endl;
          str << "old value: " << to_string(tmp_old)
              << std::endl;
          str << "Module: " << old_symbol.module << std::endl;
          str << "new value: " << to_string(tmp_new)
              << std::endl;
          str << "Module: " << new_symbol.module;
          throw 0;
        }
      }
    }
  }
}
Пример #10
0
void ansi_c_declarationt::to_symbol(
  const ansi_c_declaratort &declarator,
  symbolt &symbol) const
{
  symbol.clear();    
  symbol.value=declarator.value();
  symbol.type=full_type(declarator);
  symbol.name=declarator.get_name();
  symbol.base_name=declarator.get_base_name();
  symbol.is_type=get_is_typedef();
  symbol.location=declarator.source_location();
  symbol.is_extern=get_is_extern();
  symbol.is_macro=get_is_typedef() || get_is_enum_constant();
  symbol.is_parameter=get_is_parameter();
  
  // is it a function?
  
  if(symbol.type.id()==ID_code && !symbol.is_type)
  {
    symbol.is_static_lifetime=false;
    symbol.is_thread_local=false;

    symbol.is_file_local=get_is_static();
    
    if(get_is_inline())
      symbol.type.set(ID_C_inlined, true);

    if(config.ansi_c.mode==configt::ansi_ct::flavourt::MODE_GCC_C ||
       config.ansi_c.mode==configt::ansi_ct::flavourt::MODE_ARM_C_CPP)
    {
      // GCC extern inline cleanup, to enable remove_internal_symbols
      // do its full job
      // https://gcc.gnu.org/ml/gcc/2006-11/msg00006.html
      // __attribute__((__gnu_inline__))
      if(get_is_inline())
      {
        if(get_is_static()) // C99 and above
          symbol.is_extern=false;
        else  if(get_is_extern()) // traditional GCC
          symbol.is_file_local=true;
      }
    }
  }
  else // non-function
  {
    symbol.is_static_lifetime=
      !symbol.is_macro &&
      !symbol.is_type &&
      (get_is_global() || get_is_static());
      
    symbol.is_thread_local=
      (!symbol.is_static_lifetime && !get_is_extern()) ||
      get_is_thread_local();
       
    symbol.is_file_local=
      symbol.is_macro || 
      (!get_is_global() && !get_is_extern()) ||
      (get_is_global() && get_is_static()) ||
      symbol.is_parameter;
  }
}
void symbol_serializationt::convert(const symbolt& sym, std::ostream &out)
{
  irepcache.push_back(irept());
  sym.to_irep(irepcache.back());  
  irepconverter.reference_convert(irepcache.back(), out);
}
Пример #12
0
void java_record_outputs(
  const symbolt &function,
  const exprt::operandst &main_arguments,
  code_blockt &init_code,
  symbol_tablet &symbol_table)
{
  const code_typet::parameterst &parameters=
    to_code_type(function.type).parameters();

  exprt::operandst result;
  result.reserve(parameters.size()+1);

  bool has_return_value=
    to_code_type(function.type).return_type()!=empty_typet();

  if(has_return_value)
  {
    // record return value
    codet output(ID_output);
    output.operands().resize(2);

    const symbolt &return_symbol=symbol_table.lookup("return'");

    output.op0()=
      address_of_exprt(
        index_exprt(
          string_constantt(return_symbol.base_name),
          from_integer(0, index_type())));
    output.op1()=return_symbol.symbol_expr();
    output.add_source_location()=function.location;

    init_code.move_to_operands(output);
  }

  for(std::size_t param_number=0;
      param_number<parameters.size();
      param_number++)
  {
    const symbolt &p_symbol=
      symbol_table.lookup(parameters[param_number].get_identifier());

    if(p_symbol.type.id()==ID_pointer)
    {
      // record as an output
      codet output(ID_output);
      output.operands().resize(2);
      output.op0()=
        address_of_exprt(
          index_exprt(
            string_constantt(p_symbol.base_name),
            from_integer(0, index_type())));
      output.op1()=main_arguments[param_number];
      output.add_source_location()=function.location;

      init_code.move_to_operands(output);
    }
  }

  // record exceptional return variable as output
  codet output(ID_output);
  output.operands().resize(2);

  assert(symbol_table.has_symbol(id2string(function.name)+EXC_SUFFIX));

  // retrieve the exception variable
  const symbolt exc_symbol=symbol_table.lookup(
    id2string(function.name)+EXC_SUFFIX);

  output.op0()=address_of_exprt(
    index_exprt(string_constantt(exc_symbol.base_name),
                from_integer(0, index_type())));
  output.op1()=exc_symbol.symbol_expr();
  output.add_source_location()=function.location;

  init_code.move_to_operands(output);
}