Skip to content

Commit 3329421

Browse files
author
Daniel Kroening
committed
introduce typedef_type in the C frontend
1 parent 114030b commit 3329421

File tree

6 files changed

+118
-20
lines changed

6 files changed

+118
-20
lines changed

src/ansi-c/ansi_c_declaration.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,12 @@ void ansi_c_declaratort::build(irept &src)
2222
{
2323
typet *p=static_cast<typet *>(&src);
2424

25-
// walk down subtype until we hit symbol or "abstract"
25+
// walk down subtype until we hit typedef_type, symbol or "abstract"
2626
while(true)
2727
{
2828
typet &t=*p;
2929

30-
if(t.id()==ID_symbol)
30+
if(t.id() == ID_typedef_type || t.id() == ID_symbol)
3131
{
3232
set_base_name(t.get(ID_C_base_name));
3333
add_source_location()=t.source_location();

src/ansi-c/c_typecheck_base.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,8 @@ class c_typecheck_baset:
209209
virtual void typecheck_c_enum_type(typet &type);
210210
virtual void typecheck_c_enum_tag_type(c_enum_tag_typet &type);
211211
virtual void typecheck_code_type(code_typet &type);
212-
virtual void typecheck_symbol_type(typet &type);
212+
virtual void typecheck_symbol_type(symbol_typet &type);
213+
virtual void typecheck_typedef_type(typet &type);
213214
virtual void typecheck_c_bit_field_type(c_bit_field_typet &type);
214215
virtual void typecheck_typeof_type(typet &type);
215216
virtual void typecheck_array_type(array_typet &type);

src/ansi-c/c_typecheck_type.cpp

+41-17
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ Author: Daniel Kroening, [email protected]
2424
#include "gcc_types.h"
2525
#include "padding.h"
2626
#include "type2name.h"
27+
#include "typedef_type.h"
2728

2829
void c_typecheck_baset::typecheck_type(typet &type)
2930
{
@@ -89,7 +90,9 @@ void c_typecheck_baset::typecheck_type(typet &type)
8990
else if(type.id()==ID_typeof)
9091
typecheck_typeof_type(type);
9192
else if(type.id()==ID_symbol)
92-
typecheck_symbol_type(type);
93+
typecheck_symbol_type(to_symbol_type(type));
94+
else if(type.id() == ID_typedef_type)
95+
typecheck_typedef_type(type);
9396
else if(type.id()==ID_vector)
9497
typecheck_vector_type(to_vector_type(type));
9598
else if(type.id()==ID_custom_unsignedbv ||
@@ -1425,10 +1428,10 @@ void c_typecheck_baset::typecheck_typeof_type(typet &type)
14251428
c_qualifiers.write(type);
14261429
}
14271430

1428-
void c_typecheck_baset::typecheck_symbol_type(typet &type)
1431+
void c_typecheck_baset::typecheck_symbol_type(symbol_typet &type)
14291432
{
1430-
const irep_idt &identifier=
1431-
to_symbol_type(type).get_identifier();
1433+
// we do some consistency checking only
1434+
const irep_idt &identifier = type.get_identifier();
14321435

14331436
symbol_tablet::symbolst::const_iterator s_it=
14341437
symbol_table.symbols.find(identifier);
@@ -1449,25 +1452,46 @@ void c_typecheck_baset::typecheck_symbol_type(typet &type)
14491452
error() << "expected type symbol" << eom;
14501453
throw 0;
14511454
}
1455+
}
14521456

1453-
if(symbol.is_macro)
1454-
{
1455-
// overwrite, but preserve (add) any qualifiers and other flags
1457+
void c_typecheck_baset::typecheck_typedef_type(typet &type)
1458+
{
1459+
const irep_idt &identifier = to_typedef_type(type).get_identifier();
14561460

1457-
c_qualifierst c_qualifiers(type);
1458-
bool is_packed=type.get_bool(ID_C_packed);
1459-
irept alignment=type.find(ID_C_alignment);
1461+
symbol_tablet::symbolst::const_iterator s_it =
1462+
symbol_table.symbols.find(identifier);
14601463

1461-
c_qualifiers+=c_qualifierst(symbol.type);
1462-
type=symbol.type;
1463-
c_qualifiers.write(type);
1464+
if(s_it == symbol_table.symbols.end())
1465+
{
1466+
error().source_location = type.source_location();
1467+
error() << "typedef symbol `" << identifier << "' not found" << eom;
1468+
throw 0;
1469+
}
14641470

1465-
if(is_packed)
1466-
type.set(ID_C_packed, true);
1467-
if(alignment.is_not_nil())
1468-
type.set(ID_C_alignment, alignment);
1471+
const symbolt &symbol = s_it->second;
1472+
1473+
if(!symbol.is_type)
1474+
{
1475+
error().source_location = type.source_location();
1476+
error() << "expected type symbol for typedef" << eom;
1477+
throw 0;
14691478
}
14701479

1480+
// overwrite, but preserve (add) any qualifiers and other flags
1481+
1482+
c_qualifierst c_qualifiers(type);
1483+
bool is_packed = type.get_bool(ID_C_packed);
1484+
irept alignment = type.find(ID_C_alignment);
1485+
1486+
c_qualifiers += c_qualifierst(symbol.type);
1487+
type = symbol.type;
1488+
c_qualifiers.write(type);
1489+
1490+
if(is_packed)
1491+
type.set(ID_C_packed, true);
1492+
if(alignment.is_not_nil())
1493+
type.set(ID_C_alignment, alignment);
1494+
14711495
// CPROVER extensions
14721496
if(symbol.base_name=="__CPROVER_rational")
14731497
{

src/ansi-c/scanner.l

+6
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,15 @@ int make_identifier()
9898
stack(yyansi_clval).set(ID_C_id_class, static_cast<int>(result));
9999

100100
if(result==ansi_c_id_classt::ANSI_C_TYPEDEF)
101+
{
102+
stack(yyansi_clval).id(ID_typedef_type);
101103
return TOK_TYPEDEFNAME;
104+
}
102105
else
106+
{
107+
stack(yyansi_clval).id(ID_symbol);
103108
return TOK_IDENTIFIER;
109+
}
104110
}
105111
}
106112

src/ansi-c/typedef_type.h

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*******************************************************************\
2+
3+
Module:
4+
5+
Author: Daniel Kroening, [email protected]
6+
7+
\*******************************************************************/
8+
9+
#ifndef CPROVER_ANSI_C_TYPEDEF_TYPE_H
10+
#define CPROVER_ANSI_C_TYPEDEF_TYPE_H
11+
12+
#include <util/type.h>
13+
14+
/*! \brief A typedef
15+
*/
16+
class typedef_typet : public typet
17+
{
18+
public:
19+
explicit typedef_typet(const irep_idt &identifier) : typet(ID_typedef_type)
20+
{
21+
set_identifier(identifier);
22+
}
23+
24+
void set_identifier(const irep_idt &identifier)
25+
{
26+
set(ID_identifier, identifier);
27+
}
28+
29+
const irep_idt &get_identifier() const
30+
{
31+
return get(ID_identifier);
32+
}
33+
};
34+
35+
/*! \brief Cast a generic typet to a \ref typedef_typet
36+
*
37+
* This is an unchecked conversion. \a type must be known to be \ref
38+
* typedef_typet.
39+
*
40+
* \param type Source type
41+
* \return Object of type \ref typedef_typet
42+
*
43+
* \ingroup gr_std_types
44+
*/
45+
inline const typedef_typet &to_typedef_type(const typet &type)
46+
{
47+
PRECONDITION(type.id() == ID_typedef_type);
48+
return static_cast<const typedef_typet &>(type);
49+
}
50+
51+
/*! \copydoc to_typedef_type(const typet &)
52+
* \ingroup gr_std_types
53+
*/
54+
inline typedef_typet &to_typedef_type(typet &type)
55+
{
56+
PRECONDITION(type.id() == ID_typedef_type);
57+
return static_cast<typedef_typet &>(type);
58+
}
59+
60+
template <>
61+
inline bool can_cast_type<typedef_typet>(const typet &type)
62+
{
63+
return type.id() == ID_typedef_type;
64+
}
65+
66+
#endif // CPROVER_ANSI_C_TYPEDEF_TYPE_H

src/util/irep_ids.def

+1
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,7 @@ IREP_ID_ONE(concatenation)
244244
IREP_ID_ONE(infinity)
245245
IREP_ID_ONE(return_type)
246246
IREP_ID_ONE(typedef)
247+
IREP_ID_ONE(typedef_type)
247248
IREP_ID_TWO(C_typedef, #typedef)
248249
IREP_ID_ONE(extern)
249250
IREP_ID_ONE(static)

0 commit comments

Comments
 (0)