Skip to content

Commit a69575d

Browse files
author
Daniel Kroening
committed
introduce typedef_type in the C/C++ frontend
1 parent 449b048 commit a69575d

File tree

6 files changed

+115
-21
lines changed

6 files changed

+115
-21
lines changed

src/ansi-c/ansi_c_declaration.cpp

Lines changed: 2 additions & 2 deletions
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_type 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_type || 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

Lines changed: 2 additions & 1 deletion
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

Lines changed: 43 additions & 17 deletions
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_type)
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,48 @@ 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=
1460+
to_typedef_type(type).get_identifier();
14561461

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

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

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

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

src/ansi-c/scanner.l

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ int make_identifier()
9898

9999
if(result==ansi_c_id_classt::ANSI_C_TYPEDEF)
100100
{
101-
stack(yyansi_clval).id(ID_symbol_type);
101+
stack(yyansi_clval).id(ID_typedef_type);
102102
return TOK_TYPEDEFNAME;
103103
}
104104
else

src/ansi-c/typedef_type.h

Lines changed: 66 additions & 0 deletions
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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,6 +245,7 @@ IREP_ID_ONE(concatenation)
245245
IREP_ID_ONE(infinity)
246246
IREP_ID_ONE(return_type)
247247
IREP_ID_ONE(typedef)
248+
IREP_ID_ONE(typedef_type)
248249
IREP_ID_TWO(C_typedef, #typedef)
249250
IREP_ID_ONE(extern)
250251
IREP_ID_ONE(static)

0 commit comments

Comments
 (0)