cprover
Loading...
Searching...
No Matches
cpp_typecheck_declaration.cpp
Go to the documentation of this file.
1/*******************************************************************\
2
3Module: C++ Language Type Checking
4
5Author: Daniel Kroening, kroening@cs.cmu.edu
6
7\********************************************************************/
8
11
12#include "cpp_typecheck.h"
13
15
16#include <util/c_types.h>
17
18#include "cpp_util.h"
19
21{
22 // see if the declaration is empty
23 if(declaration.is_empty())
24 return;
25
26 // The function bodies must not be checked here,
27 // but only at the very end when all declarations have been
28 // processed (or considering forward declarations at least)
29
30 // templates are done in a dedicated function
31 if(declaration.is_template())
33 else
35}
36
38{
39 codet new_code(ID_decl_block);
40 new_code.reserve_operands(declaration.declarators().size());
41
42 // unnamed object
43 std::string identifier="#anon_union"+std::to_string(anon_counter++);
44
45 const cpp_namet cpp_name(identifier, declaration.source_location());
46 cpp_declaratort declarator;
47 declarator.name()=cpp_name;
48
49 cpp_declarator_convertert cpp_declarator_converter(*this);
50
51 const symbolt &symbol=
52 cpp_declarator_converter.convert(declaration, declarator);
53
54 if(!cpp_is_pod(declaration.type()))
55 {
57 error() << "anonymous union is not POD" << eom;
58 throw 0;
59 }
60
62
63 // do scoping
64 symbolt union_symbol =
66
67 for(const auto &c : to_union_type(union_symbol.type).components())
68 {
69 if(c.type().id() == ID_code)
70 {
72 error() << "anonymous union '" << union_symbol.base_name
73 << "' shall not have function members" << eom;
74 throw 0;
75 }
76
77 const irep_idt &base_name = c.get_base_name();
78
79 if(cpp_scopes.current_scope().contains(base_name))
80 {
82 error() << "identifier '" << base_name << "' already in scope" << eom;
83 throw 0;
84 }
85
86 cpp_idt &id=cpp_scopes.current_scope().insert(base_name);
88 id.identifier = c.get_name();
89 id.class_identifier=union_symbol.name;
90 id.is_member=true;
91 }
92
94 .type.set(ID_C_unnamed_object, symbol.base_name);
95
96 return new_code;
97}
98
100 cpp_declarationt &declaration)
101{
102 assert(!declaration.is_template());
103
104 // we first check if this is a typedef
105 typet &declaration_type=declaration.type();
106 bool is_typedef=declaration.is_typedef();
107
108 // the name anonymous tag types
109 declaration.name_anon_struct_union();
110
111 // do the type of the declaration
112 if(declaration.declarators().empty() || !has_auto(declaration_type))
113 typecheck_type(declaration_type);
114
115 // Elaborate any class template instance _unless_ we do a typedef.
116 // These are only elaborated on usage!
117 if(!is_typedef)
118 elaborate_class_template(declaration_type);
119
120 // mark as 'already typechecked'
121 if(!declaration.declarators().empty())
123
124 // Special treatment for anonymous unions
125 if(declaration.declarators().empty() &&
126 follow(declaration.type()).get_bool(ID_C_is_anonymous))
127 {
128 typet final_type=follow(declaration.type());
129
130 if(final_type.id()!=ID_union)
131 {
133 error() << "top-level declaration does not declare anything"
134 << eom;
135 throw 0;
136 }
137
138 convert_anonymous_union(declaration);
139 }
140
141 // do the declarators (optional)
142 for(auto &d : declaration.declarators())
143 {
144 // copy the declarator (we destroy the original)
145 cpp_declaratort declarator=d;
146
147 cpp_declarator_convertert cpp_declarator_converter(*this);
148
149 cpp_declarator_converter.is_typedef=is_typedef;
150
151 symbolt &symbol=cpp_declarator_converter.convert(
152 declaration_type, declaration.storage_spec(),
153 declaration.member_spec(), declarator);
154
155 if(!symbol.is_type && !symbol.is_extern && symbol.type.id() == ID_empty)
156 {
157 error().source_location = symbol.location;
158 error() << "void-typed symbol not permitted" << eom;
159 throw 0;
160 }
161
162 // any template instance to remember?
163 if(declaration.find(ID_C_template).is_not_nil())
164 {
165 symbol.type.set(ID_C_template, declaration.find(ID_C_template));
166 symbol.type.set(
167 ID_C_template_arguments,
168 declaration.find(ID_C_template_arguments));
169 }
170
171 // replace declarator by symbol expression
172 exprt tmp=cpp_symbol_expr(symbol);
173 d.swap(tmp);
174
175 // is there a constructor to be called for the declarator?
176 if(symbol.is_lvalue &&
177 declarator.init_args().has_operands())
178 {
179 auto constructor = cpp_constructor(
180 symbol.location,
181 cpp_symbol_expr(symbol),
182 declarator.init_args().operands());
183
184 if(constructor.has_value())
185 symbol.value = constructor.value();
186 else
187 symbol.value = nil_exprt();
188 }
189 }
190}
const union_typet & to_union_type(const typet &type)
Cast a typet to a union_typet.
Definition: c_types.h:162
static void make_already_typechecked(typet &type)
symbol_tablet & symbol_table
A codet representing the declaration of a local variable.
Definition: std_code.h:347
Data structure for representing an arbitrary statement in a program.
Definition: std_code_base.h:29
const declaratorst & declarators() const
const cpp_member_spect & member_spec() const
const cpp_storage_spect & storage_spec() const
bool is_template() const
bool is_empty() const
bool is_typedef() const
void name_anon_struct_union()
symbolt & convert(const typet &type, const cpp_storage_spect &storage_spec, const cpp_member_spect &member_spec, cpp_declaratort &declarator)
cpp_namet & name()
exprt & init_args()
Definition: cpp_id.h:23
id_classt id_class
Definition: cpp_id.h:45
cpp_scopet & current_scope()
Definition: cpp_scopes.h:32
cpp_idt & insert(const irep_idt &_base_name)
Definition: cpp_scope.h:52
bool contains(const irep_idt &base_name_to_lookup)
Definition: cpp_scope.cpp:201
void typecheck_type(typet &) override
void convert_template_declaration(cpp_declarationt &declaration)
void convert_non_template_declaration(cpp_declarationt &declaration)
unsigned anon_counter
bool cpp_is_pod(const typet &type) const
Definition: cpp_is_pod.cpp:16
void convert(cpp_linkage_spect &)
optionalt< codet > cpp_constructor(const source_locationt &source_location, const exprt &object, const exprt::operandst &operands)
void elaborate_class_template(const typet &type)
elaborate class template instances
static bool has_auto(const typet &type)
codet convert_anonymous_union(cpp_declarationt &declaration)
cpp_scopest cpp_scopes
dstringt has one field, an unsigned integer no which is an index into a static table of strings.
Definition: dstring.h:37
Base class for all expressions.
Definition: expr.h:54
bool has_operands() const
Return true if there is at least one operand.
Definition: expr.h:89
void reserve_operands(operandst::size_type n)
Definition: expr.h:124
typet & type()
Return the type of the expression.
Definition: expr.h:82
operandst & operands()
Definition: expr.h:92
const source_locationt & source_location() const
Definition: expr.h:230
void add_to_operands(const exprt &expr)
Add the given argument to the end of exprt's operands.
Definition: expr.h:136
bool get_bool(const irep_idt &name) const
Definition: irep.cpp:58
const irept & find(const irep_idt &name) const
Definition: irep.cpp:106
const irep_idt & get(const irep_idt &name) const
Definition: irep.cpp:45
void set(const irep_idt &name, const irep_idt &value)
Definition: irep.h:420
bool is_not_nil() const
Definition: irep.h:380
const irep_idt & id() const
Definition: irep.h:396
source_locationt source_location
Definition: message.h:247
mstreamt & error() const
Definition: message.h:399
static eomt eom
Definition: message.h:297
const typet & follow(const typet &) const
Resolve type symbol to the type it points to.
Definition: namespace.cpp:49
The NIL expression.
Definition: std_expr.h:2874
const componentst & components() const
Definition: std_types.h:147
symbolt & get_writeable_ref(const irep_idt &name)
Find a symbol in the symbol table for read-write access.
Symbol table entry.
Definition: symbol.h:28
irep_idt base_name
Base (non-scoped) name.
Definition: symbol.h:46
bool is_extern
Definition: symbol.h:66
bool is_type
Definition: symbol.h:61
source_locationt location
Source code location of definition of symbol.
Definition: symbol.h:37
typet type
Type of symbol.
Definition: symbol.h:31
irep_idt name
The unique identifier.
Definition: symbol.h:40
bool is_lvalue
Definition: symbol.h:66
exprt value
Initial value of symbol.
Definition: symbol.h:34
The type of an expression, extends irept.
Definition: type.h:29
const source_locationt & source_location() const
Definition: type.h:74
C++ Language Type Checking.
C++ Language Type Checking.
symbol_exprt cpp_symbol_expr(const symbolt &symbol)
Definition: cpp_util.cpp:14