cprover
ansi_c_parser.cpp
Go to the documentation of this file.
1 /*******************************************************************\
2 
3 Module:
4 
5 Author: Daniel Kroening, kroening@kroening.com
6 
7 \*******************************************************************/
8 
9 #include "ansi_c_parser.h"
10 
11 #include "c_storage_spec.h"
12 
14 
16  const irep_idt &base_name,
17  irep_idt &identifier, // output
18  bool tag,
19  bool label)
20 {
21  // labels and tags have a separate name space
22  const irep_idt scope_name=
23  tag?"tag-"+id2string(base_name):
24  label?"label-"+id2string(base_name):
25  base_name;
26 
27  for(scopest::const_reverse_iterator it=scopes.rbegin();
28  it!=scopes.rend();
29  it++)
30  {
31  scopet::name_mapt::const_iterator n_it=
32  it->name_map.find(scope_name);
33 
34  if(n_it!=it->name_map.end())
35  {
36  identifier=n_it->second.prefixed_name;
37  return n_it->second.id_class;
38  }
39  }
40 
41  // Not found.
42  // If it's a tag, we will add to current scope.
43  if(tag)
44  {
46  current_scope().name_map[scope_name];
49  i.base_name=base_name;
50  identifier=i.prefixed_name;
52  }
53 
54  identifier=base_name;
56 }
57 
59 {
60  const std::string scope_name=
61  "tag-"+tag.get_string(ID_C_base_name);
62 
63  irep_idt prefixed_name=current_scope().prefix+scope_name;
64 
65  if(prefixed_name!=tag.get(ID_identifier))
66  {
67  // re-defined in a deeper scope
68  ansi_c_identifiert &identifier=
69  current_scope().name_map[scope_name];
71  identifier.prefixed_name=prefixed_name;
72  tag.set(ID_identifier, prefixed_name);
73  }
74 }
75 
76 extern char *yyansi_ctext;
77 
78 int yyansi_cerror(const std::string &error)
79 {
81  return 0;
82 }
83 
85  exprt &declaration,
86  irept &declarator)
87 {
88  assert(declarator.is_not_nil());
89  ansi_c_declarationt &ansi_c_declaration=
90  to_ansi_c_declaration(declaration);
91 
92  ansi_c_declaratort new_declarator;
93  new_declarator.build(declarator);
94 
95  irep_idt base_name=new_declarator.get_base_name();
96 
97  bool is_member=ansi_c_declaration.get_is_member();
98  bool is_parameter=ansi_c_declaration.get_is_parameter();
99 
100  if(is_member)
101  {
102  // we don't put them into a struct scope (unlike C++)
103  new_declarator.set_name(base_name);
104  ansi_c_declaration.declarators().push_back(new_declarator);
105  return; // done
106  }
107 
108  // global?
109  if(current_scope().prefix.empty())
110  ansi_c_declaration.set_is_global(true);
111 
112  // abstract?
113  if(!base_name.empty())
114  {
115  c_storage_spect c_storage_spec(ansi_c_declaration.type());
116  bool is_typedef=c_storage_spec.is_typedef;
117  bool is_extern=c_storage_spec.is_extern;
118 
119  bool force_root_scope=false;
120 
121  // Functions always go into global scope, unless
122  // declared as a parameter or are typedefs.
123  if(new_declarator.type().id()==ID_code &&
124  !is_parameter &&
125  !is_typedef)
126  force_root_scope=true;
127 
128  // variables marked as 'extern' always go into global scope
129  if(is_extern)
130  force_root_scope=true;
131 
132  ansi_c_id_classt id_class=is_typedef?
135 
136  scopet &scope=
137  force_root_scope?root_scope():current_scope();
138 
139  // set the final name
140  irep_idt prefixed_name=force_root_scope?
141  base_name:
142  current_scope().prefix+id2string(base_name);
143  new_declarator.set_name(prefixed_name);
144 
145  // add to scope
146  ansi_c_identifiert &identifier=scope.name_map[base_name];
147  identifier.id_class=id_class;
148  identifier.prefixed_name=prefixed_name;
149 
150  if(force_root_scope)
151  current_scope().name_map[base_name] = identifier;
152  }
153 
154  ansi_c_declaration.declarators().push_back(new_declarator);
155 }
156 
158 {
159  if(type.id()==ID_typedef)
161  else if(type.id()==ID_struct ||
162  type.id()==ID_union ||
163  type.id()==ID_c_enum)
165  else if(type.id()==ID_merged_type)
166  {
167  forall_subtypes(it, type)
170  }
171  else if(type.has_subtype())
172  return get_class(type.subtype());
173 
175 }
ansi_c_parser
ansi_c_parsert ansi_c_parser
Definition: ansi_c_parser.cpp:13
dstringt
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:37
typet::subtype
const typet & subtype() const
Definition: type.h:47
ansi_c_declarationt::declarators
const declaratorst & declarators() const
Definition: ansi_c_declaration.h:217
ansi_c_parsert::add_declarator
void add_declarator(exprt &declaration, irept &declarator)
Definition: ansi_c_parser.cpp:84
ansi_c_id_classt::ANSI_C_UNKNOWN
@ ANSI_C_UNKNOWN
typet
The type of an expression, extends irept.
Definition: type.h:29
typet::has_subtype
bool has_subtype() const
Definition: type.h:65
c_storage_spec.h
ansi_c_id_classt
ansi_c_id_classt
Definition: ansi_c_scope.h:18
c_storage_spect::is_extern
bool is_extern
Definition: c_storage_spec.h:44
exprt
Base class for all expressions.
Definition: expr.h:53
ansi_c_id_classt::ANSI_C_TYPEDEF
@ ANSI_C_TYPEDEF
ansi_c_scopet::prefix
std::string prefix
Definition: ansi_c_scope.h:47
ansi_c_declarationt::set_is_global
void set_is_global(bool is_global)
Definition: ansi_c_declaration.h:134
ansi_c_parsert::lookup
ansi_c_id_classt lookup(const irep_idt &base_name, irep_idt &identifier, bool tag, bool label)
Definition: ansi_c_parser.cpp:15
ansi_c_declaratort::build
void build(irept &src)
Definition: ansi_c_declaration.cpp:23
exprt::type
typet & type()
Return the type of the expression.
Definition: expr.h:81
irept::is_not_nil
bool is_not_nil() const
Definition: irep.h:402
ansi_c_declarationt::get_is_parameter
bool get_is_parameter() const
Definition: ansi_c_declaration.h:109
ansi_c_parsert::get_class
static ansi_c_id_classt get_class(const typet &type)
Definition: ansi_c_parser.cpp:157
ansi_c_declaratort
Definition: ansi_c_declaration.h:21
ansi_c_declaratort::get_base_name
irep_idt get_base_name() const
Definition: ansi_c_declaration.h:47
ansi_c_scopet
Definition: ansi_c_scope.h:40
id2string
const std::string & id2string(const irep_idt &d)
Definition: irep.h:44
ansi_c_identifiert::prefixed_name
irep_idt prefixed_name
Definition: ansi_c_scope.h:32
ansi_c_parsert
Definition: ansi_c_parser.h:28
irept::id
const irep_idt & id() const
Definition: irep.h:418
ansi_c_identifiert
Definition: ansi_c_scope.h:29
dstringt::empty
bool empty() const
Definition: dstring.h:88
to_ansi_c_declaration
ansi_c_declarationt & to_ansi_c_declaration(exprt &expr)
Definition: ansi_c_declaration.h:264
c_storage_spect
Definition: c_storage_spec.h:16
ansi_c_declarationt::get_is_member
bool get_is_member() const
Definition: ansi_c_declaration.h:119
parsert::parse_error
void parse_error(const std::string &message, const std::string &before)
Definition: parser.cpp:30
forall_subtypes
#define forall_subtypes(it, type)
Definition: type.h:216
ansi_c_parsert::scopes
scopest scopes
Definition: ansi_c_parser.h:91
ansi_c_parsert::add_tag_with_body
void add_tag_with_body(irept &tag)
Definition: ansi_c_parser.cpp:58
irept::get_string
const std::string & get_string(const irep_namet &name) const
Definition: irep.h:431
ansi_c_identifiert::base_name
irep_idt base_name
Definition: ansi_c_scope.h:32
ansi_c_declarationt
Definition: ansi_c_declaration.h:73
ansi_c_declaratort::set_name
void set_name(const irep_idt &name)
Definition: ansi_c_declaration.h:37
yyansi_ctext
char * yyansi_ctext
irept::get
const irep_idt & get(const irep_namet &name) const
Definition: irep.cpp:51
ansi_c_parsert::current_scope
scopet & current_scope()
Definition: ansi_c_parser.h:108
irept::set
void set(const irep_namet &name, const irep_idt &value)
Definition: irep.h:442
yyansi_cerror
int yyansi_cerror(const std::string &error)
Definition: ansi_c_parser.cpp:78
ansi_c_id_classt::ANSI_C_TAG
@ ANSI_C_TAG
ansi_c_id_classt::ANSI_C_SYMBOL
@ ANSI_C_SYMBOL
ansi_c_identifiert::id_class
ansi_c_id_classt id_class
Definition: ansi_c_scope.h:31
irept
There are a large number of kinds of tree structured or tree-like data in CPROVER.
Definition: irep.h:394
ansi_c_parsert::root_scope
scopet & root_scope()
Definition: ansi_c_parser.h:93
ansi_c_parser.h
c_storage_spect::is_typedef
bool is_typedef
Definition: c_storage_spec.h:44
ansi_c_scopet::name_map
name_mapt name_map
Definition: ansi_c_scope.h:45