typet ansi_c_declarationt::full_type( const ansi_c_declaratort &declarator) const { typet result=declarator.type(); typet *p=&result; // this gets types that are still raw parse trees while(p->is_not_nil()) { if(p->id()==ID_pointer || p->id()==ID_array || p->id()==ID_vector || p->id()==ID_c_bit_field || p->id()==ID_block_pointer || p->id()==ID_code) p=&p->subtype(); else if(p->id()==ID_merged_type) { // we always go down on the right-most subtype assert(!p->subtypes().empty()); p=&(p->subtypes().back()); } else assert(false); } *p=type(); // retain typedef for dump-c if(get_is_typedef()) result.set(ID_C_typedef, declarator.get_name()); return result; }
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; } }