Beispiel #1
0
bool 
Frame::has_references () const
{
  std::set<symbol> all;
  entries (all);
  
  for (std::set<symbol>::const_iterator i = all.begin ();
       i != all.end ();
       i++)
    {
      const symbol key = *i;
      if (is_reference (key))
        return true;;
      if (!check (key))
        continue;
      
      Attribute::type type = lookup (key);
      int size = type_size (key);
      switch (type)
        {
        case Attribute::Submodel:
          if (size == Attribute::Singleton)
            {
              if (submodel (key).has_references ())
                return true;
            }
          else
            {
              const std::vector<boost::shared_ptr<const FrameSubmodel> >& models
                = submodel_sequence (key);
              for (size_t i = 0; i < models.size (); i++)
                if (models[i]->has_references ())
                  return true;
            }
          break;
        case Attribute::Model:
          if (size == Attribute::Singleton)
            {
              if (model (key).has_references ())
                return true;
            }
          else
            {
              const std::vector<boost::shared_ptr<const FrameModel> >& models
                = model_sequence (key);
              for (size_t i = 0; i < models.size (); i++)
                if (models[i]->has_references ())
                  return true;
            }
          break;
        default:
          break;
        }
    }
  return false;
}
Beispiel #2
0
// Returns the value associated with the declaration.
llvm::Value*
Generator::gen(Decl_expr const* e)
{
  auto const* bind = stack.lookup(e->declaration());
  llvm::Value* result = bind->second;


  // Fetch the value from a reference declaration.
  Decl const* decl = bind->first;
  if (is_reference(decl))
    return build.CreateLoad(result);

  return result;
}
Beispiel #3
0
void cpp_typecheckt::convert_argument(
  const irep_idt &mode,
  code_typet::argumentt &argument)
{
  std::string identifier=id2string(argument.get_identifier());

  if(identifier.empty())
  {
    identifier="#anon_arg"+i2string(anon_counter++);
    argument.set_base_name(identifier);
  }

  identifier=language_prefix+
             cpp_scopes.current_scope().prefix+
             id2string(identifier);

  argument.set_identifier(identifier);

  symbolt symbol;

  symbol.name=identifier;
  symbol.base_name=argument.get_base_name();
  symbol.location=argument.location();
  symbol.mode=mode;
  symbol.module=module;
  symbol.type=argument.type();
  symbol.is_state_var=true;
  symbol.is_lvalue=!is_reference(symbol.type);

  assert(!symbol.base_name.empty());

  symbolt *new_symbol;

  if(symbol_table.move(symbol, new_symbol))
  {
    err_location(symbol.location);
    str << "cpp_typecheckt::convert_argument: symbol_table.move("
        << symbol.name << ") failed";
    throw 0;
  }

  // put into scope
  cpp_scopes.put_into_scope(*new_symbol);
}
Beispiel #4
0
/*
 *	Routine:	convert_port_to_space
 *	Purpose:
 *		Convert from a port to a space.
 *		Doesn't consume the port ref; produces a space ref,
 *		which may be null.
 *	Conditions:
 *		Nothing locked.
 */
ipc_space_t
convert_port_to_space(
	ipc_port_t	port)
{
	ipc_space_t space;
	task_t task;

	task = convert_port_to_locked_task(port);

	if (task == TASK_NULL)
		return IPC_SPACE_NULL;

	if (!task->active) {
		task_unlock(task);
		return IPC_SPACE_NULL;
	}
		
	space = task->itk_space;
	is_reference(space);
	task_unlock(task);
	return (space);
}
symbolt &cpp_declarator_convertert::convert_new_symbol(
    const cpp_storage_spect &storage_spec,
    const cpp_member_spect &member_spec,
    cpp_declaratort &declarator)
{
    irep_idt pretty_name=get_pretty_name();

    symbolt symbol;

    symbol.name=final_identifier;
    symbol.base_name=base_name;
    symbol.value=declarator.value();
    symbol.location=declarator.name().source_location();
    symbol.mode=linkage_spec==ID_auto?ID_cpp:linkage_spec;
    symbol.module=cpp_typecheck.module;
    symbol.type=final_type;
    symbol.is_type=is_typedef;
    symbol.is_macro=is_typedef && !is_template_parameter;
    symbol.pretty_name=pretty_name;

    // Constant? These are propagated.
    if(symbol.type.get_bool(ID_C_constant) &&
            symbol.value.is_not_nil())
        symbol.is_macro=true;

    if(member_spec.is_inline())
        symbol.type.set(ID_C_inlined, true);

    if(!symbol.is_type)
    {
        if(is_code)
        {
            // it is a function
            if(storage_spec.is_static())
                symbol.is_file_local=true;
        }
        else
        {
            // it is a variable
            symbol.is_state_var=true;
            symbol.is_lvalue = !is_reference(symbol.type) &&
                               !(symbol.type.get_bool(ID_C_constant) &&
                                 is_number(symbol.type) &&
                                 symbol.value.id() == ID_constant);

            if(cpp_typecheck.cpp_scopes.current_scope().is_global_scope())
            {
                symbol.is_static_lifetime=true;

                if(storage_spec.is_extern())
                    symbol.is_extern=true;
            }
            else
            {
                if(storage_spec.is_static())
                {
                    symbol.is_static_lifetime=true;
                    symbol.is_file_local=true;
                }
                else if(storage_spec.is_extern())
                {
                    cpp_typecheck.err_location(storage_spec);
                    throw "external storage not permitted here";
                }
            }
        }
    }

    if(symbol.is_static_lifetime)
        cpp_typecheck.dynamic_initializations.push_back(symbol.name);

    // move early, it must be visible before doing any value
    symbolt *new_symbol;

    if(cpp_typecheck.symbol_table.move(symbol, new_symbol))
        throw "cpp_typecheckt::convert_declarator: symbol_table.move() failed";

    if(!is_code)
    {
        cpp_scopest::id_sett id_set;

        cpp_typecheck.cpp_scopes.current_scope().lookup(
            base_name, cpp_scopet::SCOPE_ONLY, id_set);

        for(cpp_scopest::id_sett::const_iterator
                id_it=id_set.begin();
                id_it!=id_set.end();
                id_it++)
        {
            const cpp_idt &id=**id_it;
            // the name is already in the scope
            // this is ok if they belong to different categories

            if(!id.is_class() && !id.is_enum())
            {
                cpp_typecheck.err_location(new_symbol->location);
                cpp_typecheck.str << "`" << base_name << "' already in scope";
                throw 0;
            }
        }
    }

    // put into scope
    cpp_idt &identifier=
        cpp_typecheck.cpp_scopes.put_into_scope(*new_symbol, *scope, is_friend);

    if(is_template)
        identifier.id_class=cpp_idt::TEMPLATE;
    else if(is_template_parameter)
        identifier.id_class=cpp_idt::TEMPLATE_PARAMETER;
    else if(is_typedef)
        identifier.id_class=cpp_idt::TYPEDEF;
    else
        identifier.id_class=cpp_idt::SYMBOL;

    // do the value
    if(!new_symbol->is_type)
    {
        if(is_code && declarator.type().id()!=ID_template)
            cpp_typecheck.add_function_body(new_symbol);

        if(!is_code)
            cpp_typecheck.convert_initializer(*new_symbol);
    }

    enforce_rules(*new_symbol);

    return *new_symbol;
}
Beispiel #6
0
// Implementation note: don't use l2 (use l3, l4 instead if required) since its
// space can be used in case of 64-bit return value.
NativeCodePtr compile_create_lil_jni_stub(Method_Handle method, void* func, NativeStubOverride nso)
{
    ASSERT_NO_INTERPRETER;
    const Class_Handle clss = method->get_class();
    bool is_static = method->is_static();
    bool is_synchronised = method->is_synchronized();
    Method_Signature_Handle msh = method_get_signature(method);
    unsigned num_args = method->get_num_args();
    Type_Info_Handle ret_tih = method_ret_type_get_type_info(msh);
    VM_Data_Type ret_type = type_info_get_type(ret_tih);
    unsigned i;

    unsigned num_ref_args = 0; // among original args, does not include jclass for static methods
    for(i=0; i<num_args; i++)
        if (is_reference(method_args_get_type_info(msh, i))) num_ref_args++;

    //***** Part 1: Entry, Stats, Override, push m2n, allocate space for handles
    LilCodeStub* cs = lil_parse_code_stub("entry 0:managed:%0m;",
                                          method);
    assert(cs);

    // Increment stats (total number of calls)
#ifdef VM_STATS
    cs = lil_parse_onto_end(cs,
                            "inc [%0i:pint];",
                            &((Method*)method)->num_accesses);
    assert(cs);
#endif //VM_STATS

    // Do stub override here
    if (nso) cs = nso(cs, method);
    assert(cs);

    // Increment stats (number of nonoverridden calls)
#ifdef VM_STATS
    cs = lil_parse_onto_end(cs,
                            "inc [%0i:pint];",
                            &((Method*)method)->num_slow_accesses);
    assert(cs);
#endif

    // Push M2nFrame
    cs = lil_parse_onto_end(cs, "push_m2n %0i, %1i, handles; locals 3;",
                            method, (POINTER_SIZE_INT)FRAME_JNI);
    assert(cs);

    // Allocate space for handles
    unsigned number_of_object_handles = num_ref_args + (is_static ? 1 : 0);
    cs = oh_gen_allocate_handles(cs, number_of_object_handles, "l0", "l1");
    assert(cs);

    //***** Part 2: Initialize object handles

    if (is_static) {
        void *jlc = clss->get_class_handle();
        cs = lil_parse_onto_end(cs,
                                //"ld l1,[%0i:pint];"
                                "ld l1,[%0i:ref];",
                                jlc);
        assert(cs);
        cs = oh_gen_init_handle(cs, "l0", 0, "l1", false);
        assert(cs);
    } else {
        cs = oh_gen_init_handle(cs, "l0", 0, "i0", true);
    }

    // The remaining handles are for the proper arguments (not including this)
    // Loop over the arguments, skipping 0th argument for instance methods. If argument is a reference, generate code
    unsigned hn = 1;
    for(i=(is_static?0:1); i<num_args; i++) {
        if (is_reference(method_args_get_type_info(msh, i))) {
            char buf[20];
            sprintf(buf, "i%d", i);
            cs = oh_gen_init_handle(cs, "l0", hn, buf, true);
            assert(cs);
            hn++;
        }
    }

    //***** Part 3: Synchronize
    if (is_synchronised) {
        if (is_static) {
            cs = lil_parse_onto_end(cs,
                                    "out stdcall:pint:pint;"
                                    "o0=%0i;"
                                    "call %1i;"
                                    "out stdcall:pint:void;"
                                    "o0=r;"
                                    "call %2i;",
                                    clss,
                                    lil_npc_to_fp(vm_helper_get_addr(VM_RT_CLASS_2_JLC)),
                                    lil_npc_to_fp(vm_helper_get_addr(VM_RT_MONITOR_ENTER)));
            assert(cs);
        } else {
            cs = lil_parse_onto_end(cs,
                                    "out stdcall:ref:void;"
                                    "o0=i0;"
                                    "call %0i;",
                                    lil_npc_to_fp(vm_helper_get_addr(VM_RT_MONITOR_ENTER)));
            assert(cs);
        }
    }

    //***** Call JVMTI MethodEntry
    DebugUtilsTI* ti = VM_Global_State::loader_env->TI;
    if (ti->isEnabled() &&
        ti->get_global_capability(DebugUtilsTI::TI_GC_ENABLE_METHOD_ENTRY))
    {
        cs = lil_parse_onto_end(cs,
                                "out platform:pint:void;"
                                "o0=%0i:pint;"
                                "call %1i;",
                                (jmethodID)method,
                                jvmti_process_method_entry_event);
        assert(cs);
    }

    //***** Part 4: Enable GC
    cs = lil_parse_onto_end(cs,
                            "out platform::void;"
                            "call %0i;",
                            hythread_suspend_enable);
    assert(cs);

    //***** Part 5: Set up arguments

    // Setup outputs, set JNIEnv, set class/this handle
    cs = lil_parse_onto_end(cs,
                            "out jni:%0j;"
                            "l1=ts;"
                            "ld o0,[l1 + %1i:pint];"
                            "o1=l0+%2i;",
                            method,
                            (POINTER_SIZE_INT)APR_OFFSETOF(VM_thread, jni_env),
                            oh_get_handle_offset(0));
    assert(cs);

    // Loop over arguments proper, setting rest of outputs
    unsigned int arg_base = 1 + (is_static ? 1 : 0);
    hn = 1;
    for(i=(is_static?0:1); i<num_args; i++) {
        if (is_reference(method_args_get_type_info(msh, i))) {
            POINTER_SIZE_INT handle_offset = oh_get_handle_offset(hn);
            REFS_RUNTIME_SWITCH_IF
#ifdef REFS_RUNTIME_OR_COMPRESSED
                cs = lil_parse_onto_end(cs,
                                        "jc i%0i=%1i:ref,%n;"
                                        "o%2i=l0+%3i;"
                                        "j %o;"
                                        ":%g;"
                                        "o%4i=0;"
                                        ":%g;",
                                        i,
                                        VM_Global_State::loader_env->managed_null,
                                        arg_base+i, handle_offset, arg_base+i);
#endif // REFS_RUNTIME_OR_COMPRESSED
            REFS_RUNTIME_SWITCH_ELSE
#ifdef REFS_RUNTIME_OR_UNCOMPRESSED
                cs = lil_parse_onto_end(cs,
                                        "jc i%0i=0:ref,%n;"
                                        "o%1i=l0+%2i;"
                                        "j %o;"
                                        ":%g;"
                                        "o%3i=0;"
                                        ":%g;",
                                        i,
                                        arg_base+i, handle_offset,
                                        arg_base+i);
#endif // REFS_RUNTIME_OR_UNCOMPRESSED
            REFS_RUNTIME_SWITCH_ENDIF
            hn++;
        } else {
            cs = lil_parse_onto_end(cs, "o%0i=i%1i;", arg_base+i, i);
        }
        assert(cs);
    }

    //***** Part 6: Call
    cs = lil_parse_onto_end(cs,
                            "call %0i;",
                            func);
    assert(cs);

    //***** Part 7: Save return, widening if necessary
    switch (ret_type) {
    case VM_DATA_TYPE_VOID:
        break;
    case VM_DATA_TYPE_INT32:
        cs = lil_parse_onto_end(cs, "l1=r;");
        break;
    case VM_DATA_TYPE_BOOLEAN:
        cs = lil_parse_onto_end(cs, "l1=zx1 r;");
        break;
    case VM_DATA_TYPE_INT16:
        cs = lil_parse_onto_end(cs, "l1=sx2 r;");
        break;
    case VM_DATA_TYPE_INT8:
        cs = lil_parse_onto_end(cs, "l1=sx1 r;");
        break;
    case VM_DATA_TYPE_CHAR:
        cs = lil_parse_onto_end(cs, "l1=zx2 r;");
        break;
    default:
        cs = lil_parse_onto_end(cs, "l1=r;");
        break;
    }
    assert(cs);

    //***** Part 8: Disable GC
    cs = lil_parse_onto_end(cs,
                            "out platform::void;"
                            "call %0i;",
                            hythread_suspend_disable);
    assert(cs);

    // Exception offsets
    POINTER_SIZE_INT eoo = (POINTER_SIZE_INT)&((VM_thread*)0)->thread_exception.exc_object;
    POINTER_SIZE_INT eco = (POINTER_SIZE_INT)&((VM_thread*)0)->thread_exception.exc_class;

    //***** Call JVMTI MethodExit
    if (ti->isEnabled() &&
        ti->get_global_capability(DebugUtilsTI::TI_GC_ENABLE_METHOD_EXIT))
    {
        cs = lil_parse_onto_end(cs,
                                "out platform:pint,g1,g8:void;"
                                "l2=ts;"
                                "ld l2,[l2+%0i:ref];"
                                "jc l2!=0,_mex_exn_raised;"
                                "l2=ts;"
                                "ld l2,[l2+%1i:ref];"
                                "jc l2!=0,_mex_exn_raised;"
                                "o1=%2i:g1;"
                                "o2=l1:g8;"
                                "j _mex_exn_cont;"
                                ":_mex_exn_raised;"
                                "o1=%3i:g1;"
                                "o2=0:g8;"
                                ":_mex_exn_cont;"
                                "o0=%4i:pint;"
                                "call %5i;",
                                eoo,
                                eco,
                                (POINTER_SIZE_INT)JNI_FALSE,
                                (POINTER_SIZE_INT)JNI_TRUE,
                                (jmethodID)method,
                                jvmti_process_method_exit_event);
        assert(cs);
    }

    //***** Part 9: Synchronize
    if (is_synchronised) {
        if (is_static) {
            cs = lil_parse_onto_end(cs,
                "out stdcall:pint:pint;"
                "o0=%0i;"
                "call %1i;"
                "out stdcall:pint:void;"
                "o0=r;"
                "call %2i;",
                clss,
                lil_npc_to_fp(vm_helper_get_addr(VM_RT_CLASS_2_JLC)),
                lil_npc_to_fp(vm_helper_get_addr(VM_RT_MONITOR_EXIT)));
        } else {
            cs = lil_parse_onto_end(cs,
                "ld l0,[l0+%0i:ref];"
                "out stdcall:ref:void; o0=l0; call %1i;",
                oh_get_handle_offset(0),
                lil_npc_to_fp(vm_helper_get_addr(VM_RT_MONITOR_EXIT)));
        }
        assert(cs);
    }

    //***** Part 10: Unhandle the return if it is a reference
    if (is_reference(ret_tih)) {
        cs = lil_parse_onto_end(cs,
                                "jc l1=0,ret_done;"
                                "ld l1,[l1+0:ref];"
                                ":ret_done;");
#ifdef REFS_RUNTIME_OR_COMPRESSED
        REFS_RUNTIME_SWITCH_IF
            cs = lil_parse_onto_end(cs,
                                    "jc l1!=0,done_translating_ret;"
                                    "l1=%0i:ref;"
                                    ":done_translating_ret;",
                                    VM_Global_State::loader_env->managed_null);
        REFS_RUNTIME_SWITCH_ENDIF
#endif // REFS_RUNTIME_OR_UNCOMPRESSED
        assert(cs);
    }

    //***** Part 11: Rethrow exception
    cs = lil_parse_onto_end(cs,
                            "l0=ts;"
                            "ld l2,[l0+%0i:ref];"
                            "jc l2!=0,_exn_raised;"
                            "ld l2,[l0+%1i:ref];"
                            "jc l2=0,_no_exn;"
                            ":_exn_raised;"
                            "m2n_save_all;"
                            "out platform::void;"
                            "call.noret %2i;"
                            ":_no_exn;",
                            eoo, eco, exn_rethrow);
    assert(cs);

    //***** Part 12: Restore return variable, pop_m2n, return
    if (ret_type != VM_DATA_TYPE_VOID) {
        cs = lil_parse_onto_end(cs, "r=l1;");
        assert(cs);
    }
    cs = lil_parse_onto_end(cs,
                            "pop_m2n;"
                            "ret;");
    assert(cs);

    //***** Now generate code

    assert(lil_is_valid(cs));
    NativeCodePtr addr = LilCodeGenerator::get_platform()->compile(cs, clss->get_class_loader()->GetCodePool());

#ifndef NDEBUG
    char buf[100];
    apr_snprintf(buf, sizeof(buf)-1, "jni_stub.%s::%s", clss->get_name()->bytes,
        method->get_name()->bytes);
    DUMP_STUB(addr, buf, lil_cs_get_code_size(cs));
#endif

#ifdef VM_STATS
    VM_Statistics::get_vm_stats().jni_stub_bytes += lil_cs_get_code_size(cs);
#endif

    lil_free_code_stub(cs);
    return addr;
} // compile_create_lil_jni_stub
Beispiel #7
0
bool cpp_typecheckt::cpp_is_pod(const typet &type) const
{
  if(type.id()==ID_struct)
  {
    // Not allowed in PODs:
    // * Non-PODs
    // * Constructors/Destructors
    // * virtuals
    // * private/protected, unless static
    // * overloading assignment operator
    // * Base classes

    const struct_typet &struct_type=to_struct_type(type);

    if(!type.find(ID_bases).get_sub().empty())
      return false;

    const struct_typet::componentst &components=
      struct_type.components();

    for(struct_typet::componentst::const_iterator
        it=components.begin();
        it!=components.end();
        it++)
    {
      if(it->get_bool(ID_is_type))
        continue;

      if(it->get_base_name()=="operator=")
        return false;

      if(it->get_bool(ID_is_virtual))
        return false;

      const typet &sub_type=it->type();

      if(sub_type.id()==ID_code)
      {
        if(it->get_bool(ID_is_virtual))
          return false;

        const typet &return_type=to_code_type(sub_type).return_type();

        if(return_type.id()==ID_constructor ||
           return_type.id()==ID_destructor)
          return false;
      }
      else if(it->get(ID_access)!=ID_public &&
              !it->get_bool(ID_is_static))
        return false;

      if(!cpp_is_pod(sub_type))
        return false;
    }

    return true;
  }
  else if(type.id()==ID_array)
  {
    return cpp_is_pod(type.subtype());
  }
  else if(type.id()==ID_pointer)
  {
    if(is_reference(type)) // references are not PODs
      return false;

    // but pointers are PODs!
    return true;
  }
  else if(type.id()==ID_symbol)
  {
    const symbolt &symb=lookup(type.get(ID_identifier));
    assert(symb.is_type);
    return cpp_is_pod(symb.type);
  }

  // everything else is POD
  return true;
}
Beispiel #8
0
bool cpp_typecheck_fargst::match(
  const code_typet &code_type,
  unsigned &distance,
  cpp_typecheckt &cpp_typecheck) const
{
  distance=0;

  exprt::operandst ops = operands;
  const code_typet::argumentst &arguments=code_type.arguments();

  if(arguments.size()>ops.size())
  {
    // Check for default values.
    ops.reserve(arguments.size());

    for(unsigned i=ops.size(); i<arguments.size(); i++)
    {
      const exprt &default_value=
        arguments[i].default_value();

      if(default_value.is_nil())
        return false;
        
      ops.push_back(default_value);
    }
  }
  else if(arguments.size()<ops.size())
  {
    // check for ellipsis
    if(!code_type.has_ellipsis())
      return false;
  }

  for(unsigned i=0; i<ops.size(); i++)
  {
    // read
    // http://publib.boulder.ibm.com/infocenter/comphelp/v8v101/topic/com.ibm.xlcpp8a.doc/language/ref/implicit_conversion_sequences.htm
    //
    // The following are the three categories of conversion sequences in order from best to worst:
    // * Standard conversion sequences
    // * User-defined conversion sequences
    // * Ellipsis conversion sequences
    
    if(i>=arguments.size())
    {
      // Ellipsis is the 'worst' of the conversion sequences
      distance+=1000;
      continue;
    }
    
    exprt argument=arguments[i];

    exprt &operand=ops[i];

    #if 0
    // unclear, todo
    if(is_reference(operand.type()))
      std::cout << "O: " << operand.pretty() << std::endl;

    assert(!is_reference(operand.type()));
    #endif

    // "this" is a special case -- we turn the pointer type
    // into a reference type to do the type matching
    if(i==0 && argument.get("#base_name")==ID_this)
    {
      argument.type().set("#reference", true);
      argument.type().set("#this", true);
    }

    unsigned rank = 0;
    exprt new_expr;

    #if 0
    std::cout << "C: " << cpp_typecheck.to_string(operand.type())
              << " -> " << cpp_typecheck.to_string(argument.type()) << std::endl;
    #endif

    // can we do the standard conversion sequence?
    if(cpp_typecheck.implicit_conversion_sequence(
        operand, argument.type(), new_expr, rank))
    {
      // ok
      distance+=rank;
      #if 0
      std::cout << "OK " << rank << std::endl;
      #endif
    }
    else
    {
      #if 0
      std::cout << "NOT OK" << std::endl;
      #endif
      return false; // no conversion possible
    }
  }

  return true;
}
Beispiel #9
0
void
ipc_space_reference(
    ipc_space_t	space)
{
    is_reference(space);
}
Beispiel #10
0
Token *build_type (typeID t, Token o, Token ret[]) 
{
/* XXX: elliptics */
	if (is_reference (t))
		t = ptrdown (dereference (t));

	Token tmp [100], *dcls = &tmp [20], *dcle = dcls;
	Token *st = open_typeID (t);
	int i = 1, b = 0;

	if (o) {
		*(++dcle) = -1;
		*dcls-- = o;
	} else  *dcls-- = -1;

	for (;;i++) {
		switch (st [i]) {
		case '*':
			*dcls-- = '*';
			b = 1;
			continue;
		case '[':
			if (b) *dcls-- = '(', *dcle++ = ')', b = 0;
			*dcle++ = '['; *dcle++ = ']';
			continue;
		case '(':
			if (b) *dcls-- = '(', *dcle++ = ')', b = 0;
			*dcle++ = '(';
			for (i++;;)
				if (st [i] == B_ELLIPSIS) {
					*dcle++ = ELLIPSIS;
					break;
				} else {
					if (st [i] == INTERNAL_ARGEND) break;
					Token arg [50];
					intcpy (dcle, build_type (st [i++], 0, arg));
					dcle += intlen (dcle);
					*dcle++ = ',';
				}
			if (dcle [-1] == ',') --dcle;
			*dcle++ = ')';
			continue;
		case -1: break;
		default: PRINTF ("UNKNWOWN %i\n", st [i]);
		}
		break;
	}
	*dcle = -1;

	if (st [0] >= 0)
		if (ISSYMBOL (st [0])) sintprintf (ret, st [0], -1);
		else sintprintf (ret, isunion (st [0]) ? RESERVED_union : iRESERVED_struct (st [0]),
			    name_of_struct (st [0]), -1);
	else switch (st [0]) {
	 case B_UCHAR:  sintprintf (ret, RESERVED_unsigned, RESERVED_char, -1);
	ncase B_SCHAR:  sintprintf (ret, RESERVED_char, -1);
	ncase B_USINT:  sintprintf (ret, RESERVED_unsigned, RESERVED_short, RESERVED_int, -1);
	ncase B_SSINT:  sintprintf (ret, RESERVED_short, RESERVED_int, -1);
	ncase B_UINT:   sintprintf (ret, RESERVED_unsigned, RESERVED_int, -1);
	ncase B_SINT:   sintprintf (ret, RESERVED_int, -1);
	ncase B_ULONG:  sintprintf (ret, RESERVED_unsigned, RESERVED_long, -1);
	ncase B_SLONG:  sintprintf (ret, RESERVED_long, -1);
	ncase B_ULLONG: sintprintf (ret, RESERVED_unsigned, RESERVED_long, RESERVED_long, -1);
	ncase B_SLLONG: sintprintf (ret, RESERVED_long, RESERVED_long, -1);
	ncase B_FLOAT:  sintprintf (ret, RESERVED_float, -1);
	ncase B_DOUBLE: sintprintf (ret, RESERVED_double, -1);
	ncase B_VOID:   sintprintf (ret, RESERVED_void, -1);
	}

	intcat (ret, dcls + 1);

	return ret;
}
void CheckCapitalization::check_capitalization(vector < int >&chapters, vector < ustring > &verses, ustring & text, vector < size_t > &pointers, bool end_check)
/*
Check capitalization in text.
If "end_check" is true, it also check for final sentence closing.
*/
{
  /*
     Note that this at first used gtk_text_iter_starts_sentence (&iter) and
     gtk_text_iter_ends_sentence (&iter), but these functions are not good enough,
     because do not work in several cases, like e.g. in the following line, it does
     not indicate the end of the sentence:
     As soon as the leaders of the tribes of Israel took their places, the 
     Israelites said, “How could such a horrible thing happen?"
     Therefore we use other means to check sentences.
   */

  // No check if there's no text.
  if (trim(text).empty())
    return;
  // Some variables needed.
  bool expect_capital_now = false;
  bool expect_capital_caused_by_reference = false;
  gunichar previous_char = 0;
  int localchapter = 0;
  ustring localverse = "0";
  GtkTextBuffer *textbuffer;
  textbuffer = gtk_text_buffer_new(NULL);
  gtk_text_buffer_set_text(textbuffer, text.c_str(), -1);
  GtkTextIter iter;
  gtk_text_buffer_get_start_iter(textbuffer, &iter);
  bool going = true;
  while (going) {
    // Get the unicode character.
    gunichar unichar = gtk_text_iter_get_char(&iter);
    // See whether to expect a capital now.
    if (punctuation_followed_by_capitals_set.find(unichar) != punctuation_followed_by_capitals_set.end()) {
      // Ok, expect capital.
      expect_capital_now = true;
      expect_capital_caused_by_reference = false;
      // Was this expectation caused by a reference?
      if (is_reference(iter))
        expect_capital_caused_by_reference = true;
    }
    // If we expect a capital, and we find one, no longer look for one.
    if (expect_capital_now) {
      if (g_unichar_isupper(unichar)) {
        expect_capital_now = false;
      }
    }
    // If we expect a capital, and we get lower case, that might be trouble.
    if (expect_capital_now) {
      if (g_unichar_islower(unichar)) {
        // There is no trouble if it follows a character after which to ignore lower case.
        if (ignore_lower_case_following_set.find(previous_char) != ignore_lower_case_following_set.end()) {
          expect_capital_now = false;
        }
        // If the lowercase character follows an abbreviation, there is no trouble either.
        GtkTextIter iter2 = iter;
        gtk_text_iter_backward_word_start(&iter2);
        GtkTextIter iter3 = iter2;
        gtk_text_iter_forward_word_end(&iter3);
        gtk_text_iter_forward_char(&iter3);
        ustring abbreviation = gtk_text_iter_get_text(&iter2, &iter3);
        if (abbreviations.find(abbreviation) != abbreviations.end()) {
          expect_capital_now = false;
        }
        // If it follows a reference, there is no trouble.
        if (expect_capital_caused_by_reference)
          expect_capital_now = false;
        // Ok, give message.
        if (expect_capital_now) {
          // Determine chapter and verse.
          get_chapter_and_verse(chapters, verses, pointers, iter, localchapter, localverse);
          message(book, localchapter, localverse, _("Capital expected: ") + get_context(iter));
        }
        // Only give one message about missing capitals in this context.
        expect_capital_now = false;
      }
    }
    // Store this characters as the previous characters for the next round.
    if (g_unichar_isgraph(unichar))
      previous_char = unichar;
    // Next round.
    going = gtk_text_iter_forward_char(&iter);
  }
  // The sentence should be ended with proper punctuation.
  if (end_check) {
    if (expect_capital_now)
      if (g_unichar_isdigit(previous_char))
        expect_capital_now = false;
    if (!expect_capital_now) {
      message(book, chapter, verse, _("Unended sentence: ") + get_context(iter));
    }
  }
  // Free memory
  g_object_unref(textbuffer);
}
Beispiel #12
0
codet cpp_typecheckt::cpp_constructor(
  const source_locationt &source_location,
  const exprt &object,
  const exprt::operandst &operands)
{
  exprt object_tc=object;

  typecheck_expr(object_tc);

  elaborate_class_template(object_tc.type());

  typet tmp_type(object_tc.type());
  follow_symbol(tmp_type);

  assert(!is_reference(tmp_type));

  if(tmp_type.id()==ID_array)
  {
    // We allow only one operand and it must be tagged with '#array_ini'.
    // Note that the operand is an array that is used for copy-initialization.
    // In the general case, a program is not allow to use this form of
    // construct. This way of initializing an array is used internaly only.
    // The purpose of the tag #arra_ini is to rule out ill-formed
    // programs.

    if(!operands.empty() && !operands.front().get_bool("#array_ini"))
    {
      error().source_location=source_location;
      error() << "bad array initializer" << eom;
      throw 0;
    }

    assert(operands.empty() || operands.size()==1);

    if(operands.empty() && cpp_is_pod(tmp_type))
    {
      codet nil;
      nil.make_nil();
      return nil;
    }

    const exprt &size_expr=
      to_array_type(tmp_type).size();

    if(size_expr.id()=="infinity")
    {
      // don't initialize
      codet nil;
      nil.make_nil();
      return nil;
    }

    exprt tmp_size=size_expr;
    make_constant_index(tmp_size);

    mp_integer s;
    if(to_integer(tmp_size, s))
    {
      error().source_location=source_location;
      error() << "array size `" << to_string(size_expr)
              << "' is not a constant" << eom;
      throw 0;
    }

    /*if(cpp_is_pod(tmp_type))
    {
      code_expressiont new_code;
      exprt op_tc=operands.front();
      typecheck_expr(op_tc);
       // Override constantness
      object_tc.type().set("#constant", false);
      object_tc.set("#lvalue", true);
      side_effect_exprt assign("assign");
      assign.add_source_location()=source_location;
      assign.copy_to_operands(object_tc, op_tc);
      typecheck_side_effect_assignment(assign);
      new_code.expression()=assign;
      return new_code;
    }
    else*/
    {
      codet new_code(ID_block);

      // for each element of the array, call the default constructor
      for(mp_integer i=0; i < s; ++i)
      {
        exprt::operandst tmp_operands;

        exprt constant=from_integer(i, index_type());
        constant.add_source_location()=source_location;

        exprt index(ID_index);
        index.copy_to_operands(object);
        index.copy_to_operands(constant);
        index.add_source_location()=source_location;

        if(!operands.empty())
        {
          exprt operand(ID_index);
          operand.copy_to_operands(operands.front());
          operand.copy_to_operands(constant);
          operand.add_source_location()=source_location;
          tmp_operands.push_back(operand);
        }

        exprt i_code =
          cpp_constructor(source_location, index, tmp_operands);

        if(i_code.is_nil())
        {
          new_code.is_nil();
          break;
        }

        new_code.move_to_operands(i_code);
      }
      return new_code;
    }
  }
  else if(cpp_is_pod(tmp_type))
  {
    code_expressiont new_code;
    exprt::operandst operands_tc=operands;

    for(exprt::operandst::iterator
      it=operands_tc.begin();
      it!=operands_tc.end();
      it++)
    {
      typecheck_expr(*it);
      add_implicit_dereference(*it);
    }

    if(operands_tc.empty())
    {
      // a POD is NOT initialized
      new_code.make_nil();
    }
    else if(operands_tc.size()==1)
    {
      // Override constantness
      object_tc.type().set(ID_C_constant, false);
      object_tc.set(ID_C_lvalue, true);
      side_effect_exprt assign(ID_assign);
      assign.add_source_location()=source_location;
      assign.copy_to_operands(object_tc, operands_tc.front());
      typecheck_side_effect_assignment(assign);
      new_code.expression()=assign;
    }
    else
    {
      error().source_location=source_location;
      error() << "initialization of POD requires one argument, "
                 "but got " << operands.size() << eom;
      throw 0;
    }

    return new_code;
  }
  else if(tmp_type.id()==ID_union)
  {
    assert(0); // Todo: union
  }
  else if(tmp_type.id()==ID_struct)
  {
    exprt::operandst operands_tc=operands;

    for(exprt::operandst::iterator
      it=operands_tc.begin();
      it!=operands_tc.end();
      it++)
    {
      typecheck_expr(*it);
      add_implicit_dereference(*it);
    }

    const struct_typet &struct_type=
      to_struct_type(tmp_type);

    // set most-derived bits
    codet block(ID_block);
    for(std::size_t i=0; i < struct_type.components().size(); i++)
    {
      const irept &component=struct_type.components()[i];
      if(component.get(ID_base_name)!="@most_derived")
        continue;

      exprt member(ID_member, bool_typet());
      member.set(ID_component_name, component.get(ID_name));
      member.copy_to_operands(object_tc);
      member.add_source_location()=source_location;
      member.set(ID_C_lvalue, object_tc.get_bool(ID_C_lvalue));

      exprt val=false_exprt();

      if(!component.get_bool("from_base"))
        val=true_exprt();

      side_effect_exprt assign(ID_assign);
      assign.add_source_location()=source_location;
      assign.move_to_operands(member, val);
      typecheck_side_effect_assignment(assign);
      code_expressiont code_exp;
      code_exp.expression()=assign;
      block.move_to_operands(code_exp);
    }

    // enter struct scope
    cpp_save_scopet save_scope(cpp_scopes);
    cpp_scopes.set_scope(struct_type.get(ID_name));

    // find name of constructor
    const struct_typet::componentst &components=
      struct_type.components();

    irep_idt constructor_name;

    for(struct_typet::componentst::const_iterator
        it=components.begin();
        it!=components.end();
        it++)
    {
      const typet &type=it->type();

      if(!it->get_bool(ID_from_base) &&
         type.id()==ID_code &&
         type.find(ID_return_type).id()==ID_constructor)
      {
        constructor_name=it->get(ID_base_name);
        break;
      }
    }

    // there is always a constructor for non-PODs
    assert(constructor_name!="");

    irept cpp_name(ID_cpp_name);
    cpp_name.get_sub().push_back(irept(ID_name));
    cpp_name.get_sub().back().set(ID_identifier, constructor_name);
    cpp_name.get_sub().back().set(ID_C_source_location, source_location);

    side_effect_expr_function_callt function_call;
    function_call.add_source_location()=source_location;
    function_call.function().swap(static_cast<exprt&>(cpp_name));
    function_call.arguments().reserve(operands_tc.size());

    for(exprt::operandst::iterator
        it=operands_tc.begin();
        it!=operands_tc.end();
        it++)
      function_call.op1().copy_to_operands(*it);

    typecheck_side_effect_function_call(function_call);
    assert(function_call.get(ID_statement)==ID_temporary_object);

    exprt &initializer =
      static_cast<exprt &>(function_call.add(ID_initializer));

    assert(initializer.id()==ID_code &&
           initializer.get(ID_statement)==ID_expression);

    side_effect_expr_function_callt &func_ini=
      to_side_effect_expr_function_call(initializer.op0());

    exprt &tmp_this=func_ini.arguments().front();
    assert(tmp_this.id()==ID_address_of
           && tmp_this.op0().id()=="new_object");

    exprt address_of(ID_address_of, typet(ID_pointer));
    address_of.type().subtype()=object_tc.type();
    address_of.copy_to_operands(object_tc);
    tmp_this.swap(address_of);

    if(block.operands().empty())
      return to_code(initializer);
    else
    {
      block.move_to_operands(initializer);
      return block;
    }
  }
  else
    assert(false);

  codet nil;
  nil.make_nil();
  return nil;
}
Beispiel #13
0
static void *
format_parse (const char *format, bool translated, char *fdi,
              char **invalid_reason)
{
  struct spec spec;
  struct spec *result;

  spec.base = NULL;

#if DYNLOAD_LIBEXPAT || HAVE_LIBEXPAT
  if (LIBEXPAT_AVAILABLE ())
    {
      XML_Parser parser;
      const char *str = format;
      const char *str_limit = str + strlen (format);
      size_t amp_count;
      char *buffer, *bp;

      for (amp_count = 0; str < str_limit; amp_count++)
        {
          const char *amp = strchrnul (str, '&');
          if (*amp != '&')
            break;
          str = amp + 1;
        }

      buffer = xmalloc (amp_count * 4
                        + strlen (format)
                        + strlen ("<gt:kuit xmlns:gt=\"" XML_NS "\"></gt:kuit>")
                        + 1);
      *buffer = '\0';

      bp = buffer;
      bp = stpcpy (bp, "<gt:kuit xmlns:gt=\"" XML_NS "\">");
      str = format;
      while (str < str_limit)
        {
          const char *amp = strchrnul (str, '&');

          bp = stpncpy (bp, str, amp - str);
          if (*amp != '&')
            break;

          bp = stpcpy (bp, is_reference (amp) ? "&" : "&amp;");
          str = amp + 1;
        }
      stpcpy (bp, "</gt:kuit>");

      parser = XML_ParserCreate (NULL);
      if (parser == NULL)
        {
          *invalid_reason = xasprintf (_("memory exhausted"));
          free (buffer);
          return NULL;
        }

      XML_SetElementHandler (parser,
                             start_element_handler,
                             end_element_handler);

      if (XML_Parse (parser, buffer, strlen (buffer), 0) == 0)
        {
          *invalid_reason =
            xasprintf (_("error while parsing: %s"),
                       XML_ErrorString (XML_GetErrorCode (parser)));
          free (buffer);
          XML_ParserFree (parser);
          return NULL;
        }

      if (XML_Parse (parser, NULL, 0, 1) == 0)
        {
          *invalid_reason =
            xasprintf (_("error while parsing: %s"),
                       XML_ErrorString (XML_GetErrorCode (parser)));
          free (buffer);
          XML_ParserFree (parser);
          return NULL;
        }

      free (buffer);
      XML_ParserFree (parser);
    }
#endif

  spec.base = formatstring_kde.parse (format, translated, fdi, invalid_reason);
  if (spec.base == NULL)
    return NULL;

  result = XMALLOC (struct spec);
  *result = spec;
  return result;
}
symbolt &cpp_declarator_convertert::convert_new_symbol(
    const cpp_storage_spect &storage_spec,
    const cpp_member_spect &member_spec,
    cpp_declaratort &declarator)
{
    irep_idt pretty_name=get_pretty_name();

    symbolt symbol;

    symbol.name=final_identifier;
    symbol.base_name=base_name;
    symbol.value=declarator.value();
    symbol.location=declarator.name().location();
    symbol.mode=mode;
    symbol.module=cpp_typecheck.module;
    symbol.type=final_type;
    symbol.is_type=is_typedef;
    symbol.is_macro=is_typedef && !is_template_argument;
    symbol.pretty_name=pretty_name;
    symbol.mode=cpp_typecheck.current_mode;

    // We always insert throw_decl to the begin of the function
    if(declarator.throw_decl().statement()=="throw_decl")
    {
        symbol.value.operands().insert(
            symbol.value.operands().begin(),
            declarator.throw_decl());

        // Insert flag to end of constructor
        // so we know when to remove throw_decl
        symbol.value.operands().push_back(
            codet("throw_decl_end"));
    }

    // Constant? These are propagated.
    if(symbol.type.cmt_constant() &&
            symbol.value.is_not_nil())
        symbol.is_macro=true;

    if(member_spec.is_inline())
        symbol.type.set("#inlined", true);

    if(!symbol.is_type)
    {
        if(!is_code)
        {
            // it is a variable
            symbol.is_statevar=true;
            symbol.lvalue = !is_reference(symbol.type) &&
                            !(symbol.type.cmt_constant() &&
                              is_number(symbol.type) &&
                              symbol.value.id() == "constant");

            if(cpp_typecheck.cpp_scopes.current_scope().is_global_scope())
            {
                symbol.static_lifetime=true;

                if(storage_spec.is_extern())
                    symbol.is_extern=true;
            }
            else
            {
                if(storage_spec.is_static())
                {
                    //symbol.static_lifetime=true;
                    symbol.file_local=true;
                }
                else if(storage_spec.is_extern())
                {
                    cpp_typecheck.err_location(storage_spec);
                    throw "external storage not permitted here";
                }
            }
        }
    }

    if(symbol.static_lifetime)
        cpp_typecheck.dinis.push_back(symbol.name);

    // move early, it must be visible before doing any value
    symbolt *new_symbol;

    if(cpp_typecheck.context.move(symbol, new_symbol))
        throw "cpp_typecheckt::convert_declarator: context.move() failed";

    if(!is_code)
    {
        cpp_scopest::id_sett id_set;

        cpp_typecheck.cpp_scopes.current_scope().lookup(
            base_name, cpp_scopet::SYMBOL, id_set);

        for(cpp_scopest::id_sett::const_iterator
                id_it=id_set.begin();
                id_it!=id_set.end();
                id_it++)
        {
            const cpp_idt &id=**id_it;
            // the name is already in the scope
            // this is ok if they belong to different categories

            if(!id.is_class() && !id.is_enum())
            {
                cpp_typecheck.err_location(new_symbol->location);
                cpp_typecheck.str << "`" << base_name << "' already in scope";
                throw 0;
            }
        }
    }

    // put into scope
    cpp_idt &identifier=
        cpp_typecheck.cpp_scopes.put_into_scope(*new_symbol, *scope, is_friend);

    if(is_template)
        identifier.id_class=cpp_idt::TEMPLATE;
    else if(is_template_argument)
        identifier.id_class=cpp_idt::TEMPLATE_ARGUMENT;
    else if(is_typedef)
        identifier.id_class=cpp_idt::TYPEDEF;
    else
        identifier.id_class=cpp_idt::SYMBOL;

    // do the value
    if(!new_symbol->is_type)
    {
        if(is_code && declarator.type().id()!="template")
            cpp_typecheck.add_function_body(new_symbol);

        if(!is_code && !declarator.find("name").get_bool("catch_decl"))
            cpp_typecheck.convert_initializer(*new_symbol);
    }

    enforce_rules(*new_symbol);

    return *new_symbol;
}