cprover
ansi_c_declaration.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module: ANSI-C Language Type Checking
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
11 
12 #include "ansi_c_declaration.h"
13 
14 #include <ostream>
15 #include <cassert>
16 
17 #include <util/config.h>
18 #include <util/std_types.h>
19 
21 {
22  typet *p=static_cast<typet *>(&src);
23 
24  // walk down subtype until we hit symbol or "abstract"
25  while(true)
26  {
27  typet &t=*p;
28 
29  if(t.id()==ID_symbol)
30  {
31  set_base_name(t.get(ID_C_base_name));
33  t.make_nil();
34  break;
35  }
36  else if(t.id().empty() ||
37  t.is_nil())
38  {
39  assert(0);
40  }
41  else if(t.id()==ID_abstract)
42  {
43  t.make_nil();
44  break;
45  }
46  else if(t.id()==ID_merged_type)
47  {
48  // we always walk down the _last_ member of a merged type
49  assert(!t.subtypes().empty());
50  p=&(t.subtypes().back());
51  }
52  else
53  p=&t.subtype();
54  }
55 
56  type()=static_cast<const typet &>(src);
57  value().make_nil();
58 }
59 
60 void ansi_c_declarationt::output(std::ostream &out) const
61 {
62  out << "Flags:";
63  if(get_is_typedef())
64  out << " is_typedef";
65  if(get_is_enum_constant())
66  out << " is_enum_constant";
67  if(get_is_static())
68  out << " is_static";
69  if(get_is_parameter())
70  out << " is_parameter";
71  if(get_is_global())
72  out << " is_global";
73  if(get_is_register())
74  out << " is_register";
75  if(get_is_thread_local())
76  out << " is_thread_local";
77  if(get_is_inline())
78  out << " is_inline";
79  if(get_is_extern())
80  out << " is_extern";
81  if(get_is_static_assert())
82  out << " is_static_assert";
83  out << "\n";
84 
85  out << "Type: " << type().pretty() << "\n";
86 
87  for(const auto &declarator : declarators())
88  out << "Declarator: " << declarator.pretty() << "\n";
89 }
90 
92  const ansi_c_declaratort &declarator) const
93 {
94  typet result=declarator.type();
95  typet *p=&result;
96 
97  // this gets types that are still raw parse trees
98  while(p->is_not_nil())
99  {
100  if(p->id()==ID_pointer || p->id()==ID_array ||
101  p->id()==ID_vector || p->id()==ID_c_bit_field ||
102  p->id()==ID_block_pointer || p->id()==ID_code)
103  p=&p->subtype();
104  else if(p->id()==ID_merged_type)
105  {
106  // we always go down on the right-most subtype
107  assert(!p->subtypes().empty());
108  p=&(p->subtypes().back());
109  }
110  else
111  assert(false);
112  }
113 
114  *p=type();
115 
116  // retain typedef for dump-c
117  if(get_is_typedef())
118  result.set(ID_C_typedef, declarator.get_name());
119 
120  return result;
121 }
122 
124  const ansi_c_declaratort &declarator,
125  symbolt &symbol) const
126 {
127  symbol.clear();
128  symbol.value=declarator.value();
129  symbol.type=full_type(declarator);
130  symbol.name=declarator.get_name();
131  symbol.pretty_name=symbol.name;
132  symbol.base_name=declarator.get_base_name();
133  symbol.is_type=get_is_typedef();
134  symbol.location=declarator.source_location();
135  symbol.is_extern=get_is_extern();
136  symbol.is_macro=get_is_typedef() || get_is_enum_constant();
137  symbol.is_parameter=get_is_parameter();
138  symbol.is_weak=get_is_weak();
139 
140  // is it a function?
141 
142  if(symbol.type.id()==ID_code && !symbol.is_type)
143  {
144  symbol.is_static_lifetime=false;
145  symbol.is_thread_local=false;
146 
147  symbol.is_file_local=get_is_static();
148 
149  if(get_is_inline())
150  symbol.type.set(ID_C_inlined, true);
151 
155  {
156  // GCC extern inline cleanup, to enable remove_internal_symbols
157  // do its full job
158  // https://gcc.gnu.org/ml/gcc/2006-11/msg00006.html
159  // __attribute__((__gnu_inline__))
160  if(get_is_inline())
161  {
162  if(get_is_static()) // C99 and above
163  symbol.is_extern=false;
164  else if(get_is_extern()) // traditional GCC
165  symbol.is_file_local=true;
166  }
167  }
168  }
169  else // non-function
170  {
171  symbol.is_static_lifetime=
172  !symbol.is_macro &&
173  !symbol.is_type &&
174  (get_is_global() || get_is_static());
175 
176  symbol.is_thread_local=
177  (!symbol.is_static_lifetime && !get_is_extern()) ||
178  get_is_thread_local();
179 
180  symbol.is_file_local=
181  symbol.is_macro ||
182  (!get_is_global() && !get_is_extern()) ||
183  (get_is_global() && get_is_static()) ||
184  symbol.is_parameter;
185  }
186 }
The type of an expression.
Definition: type.h:20
irep_idt name
The unique identifier.
Definition: symbol.h:46
struct configt::ansi_ct ansi_c
bool is_nil() const
Definition: irep.h:103
bool is_not_nil() const
Definition: irep.h:104
bool is_thread_local
Definition: symbol.h:70
std::string pretty(unsigned indent=0, unsigned max_indent=0) const
Definition: irep.cpp:641
void clear()
Definition: symbol.h:79
void build(irept &src)
subtypest & subtypes()
Definition: type.h:56
exprt value
Initial value of symbol.
Definition: symbol.h:40
void to_symbol(const ansi_c_declaratort &, symbolt &symbol) const
irep_idt pretty_name
Language-specific display name.
Definition: symbol.h:58
typet & type()
Definition: expr.h:60
Symbol table entry.This is a symbol in the symbol table, stored in an object of type symbol_tablet...
Definition: symbol.h:33
configt config
Definition: config.cpp:21
typet full_type(const ansi_c_declaratort &) const
bool is_static_lifetime
Definition: symbol.h:70
const irep_idt & id() const
Definition: irep.h:189
irep_idt get_base_name() const
void set_base_name(const irep_idt &base_name)
flavourt mode
Definition: config.h:105
bool is_parameter
Definition: symbol.h:71
const irep_idt & get(const irep_namet &name) const
Definition: irep.cpp:213
irep_idt get_name() const
Base class for tree-like data structures with sharing.
Definition: irep.h:87
const source_locationt & source_location() const
Definition: type.h:95
void output(std::ostream &) const
bool is_extern
Definition: symbol.h:71
typet type
Type of symbol.
Definition: symbol.h:37
source_locationt location
Source code location of definition of symbol.
Definition: symbol.h:43
API to type classes.
irep_idt base_name
Base (non-scoped) name.
Definition: symbol.h:52
const source_locationt & source_location() const
Definition: expr.h:142
bool is_file_local
Definition: symbol.h:71
ANSI-CC Language Type Checking.
void make_nil()
Definition: irep.h:243
bool is_weak
Definition: symbol.h:71
source_locationt & add_source_location()
Definition: expr.h:147
bool is_type
Definition: symbol.h:66
const typet & subtype() const
Definition: type.h:31
bool empty() const
Definition: dstring.h:61
bool is_macro
Definition: symbol.h:66
void set(const irep_namet &name, const irep_idt &value)
Definition: irep.h:214