1 // -*- mode: C++ -*-
2 //
3 // Copyright (c) 2007, 2008, 2010, 2011, 2013, 2014, 2015, 2016 The University of Utah
4 // All rights reserved.
5 //
6 // This file is part of `csmith', a random generator of C programs.
7 //
8 // Redistribution and use in source and binary forms, with or without
9 // modification, are permitted provided that the following conditions are met:
10 //
11 //   * Redistributions of source code must retain the above copyright notice,
12 //     this list of conditions and the following disclaimer.
13 //
14 //   * Redistributions in binary form must reproduce the above copyright
15 //     notice, this list of conditions and the following disclaimer in the
16 //     documentation and/or other materials provided with the distribution.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 // ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
22 // LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 // CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 // SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 // CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 // POSSIBILITY OF SUCH DAMAGE.
29 
30 //
31 // This file was derived from a random program generator written by Bryan
32 // Turner.  The attributions in that file was:
33 //
34 // Random Program Generator
35 // Bryan Turner (bryan.turner@pobox.com)
36 // July, 2005
37 //
38 
39 #ifndef TYPE_H
40 #define TYPE_H
41 
42 ///////////////////////////////////////////////////////////////////////////////
43 
44 #include <string>
45 #include <ostream>
46 #include <vector>
47 #include "CommonMacros.h"
48 #include "StatementAssign.h"
49 #include "CVQualifiers.h"
50 
51 template <class Name> class Enumerator;
52 using namespace std;
53 
54 #define SIZE_UNKNOWN 0xFFFF
55 
56 /*
57  *
58  */
59 enum eTypeDesc
60 {
61 	eSimple,
62 	ePointer,
63 	eUnion,
64     eStruct,
65 };
66 #define MAX_TYPE_DESC ((eTypeDesc) (eStruct+1))
67 
68 /*
69  *
70  */
71 enum eSimpleType
72 {
73 	eVoid,
74 	eChar,
75 	eInt,
76 	eShort,
77 	eLong,
78 	eLongLong,
79 	eUChar,
80 	eUInt,
81 	eUShort,
82 	eULong,
83 	eFloat,
84 	// eDouble,
85 	eULongLong,
86 };
87 #define MAX_SIMPLE_TYPES ((eSimpleType) (eULongLong+1))
88 
89 enum eMatchType
90 {
91 	eExact,
92 	eConvert,
93 	eDereference,
94 	eDerefExact,
95 	eFlexible,
96 };
97 
98 /*
99  *
100  */
101 class Type
102 {
103 public:
104 	// Pseudo-factory method.  This is `choose_random()' rather than
105 	// `make_random()' because the returned object is not fresh.
106 	static const Type *choose_random();
107 
108 	static const Type *choose_random_nonvoid();
109 
110 	// choose a random integer type
111 	static const Type *choose_random_simple(void);
112 
113 	// choose a random pointer type
114 	static const Type* choose_random_pointer_type(void);
115 
116 	static const Type *choose_random_struct_from_type(const Type* type, bool no_volatile);
117 
118 	static void get_all_ok_struct_union_types(vector<Type *> &ok_types, bool no_const, bool no_volatile, bool need_int_field, bool bStruct);
119 
120 	static bool if_struct_will_have_assign_ops();
121 	static bool if_union_will_have_assign_ops();
122 
123 	bool has_int_field() const;
124 
125 	bool signed_overflow_possible() const;
126 
127 	static const Type* choose_random_struct_union_type(vector<Type *> &ok_types);
128 
129 	static const Type * choose_random_nonvoid_nonvolatile(void);
130 
131 	static bool has_pointer_type(void);
132 
133 	static const Type* random_type_from_type(const Type* type, bool no_volatile=false, bool strict_simple_type=false);
134 
135 	static void copy_all_fields_types(vector<const Type*> &dest_types, vector<const Type*> &src_types);
136 
137 	static void reset_accum_types(vector<const Type*> &accum_types);
138 
139 	static void delete_useless_structs(vector<const Type*> &all_types, vector<const Type*> &accum_types);
140 
141 	static void init_is_bitfield_enumerator(Enumerator<string> &enumerator, int bitfield_prob);
142 
143 	static void init_fields_enumerator(Enumerator<std::string> &enumerator,
144 				Enumerator<string> &bitfield_enumerator,
145 				int type_bound, int qual_bound, int bitfield_qual_bound);
146 
147 	static bool make_one_normal_field_by_enum(Enumerator<string> &enumerator, vector<const Type*> &all_types,
148 				vector<CVQualifiers> &all_quals, vector<const Type*> &fields,
149 				vector<CVQualifiers> &quals, vector<int> &fields_length, int i);
150 
151 	static bool make_one_bitfield_by_enum(Enumerator<string> &enumerator,
152 				vector<CVQualifiers> &all_bitfield_quals,
153 				vector<const Type*> &random_fields,
154 				vector<CVQualifiers> &qualifiers,
155 				vector<int> &fields_length,
156 				int index, bool &last_is_zero);
157 
158 	static int get_bitfield_length(int length_flag);
159 
160 	static void make_all_struct_types_(Enumerator<string> &bitfields_enumerator, vector<const Type*> &accum_types,
161 				vector<const Type*> &all_types, vector<CVQualifiers> &all_quals,
162 				vector<CVQualifiers> &all_bitfield_quals);
163 
164 	static void make_all_struct_types_with_bitfields(Enumerator<string> &enumerator,
165 					Enumerator<string> &bitfields_enumerator,
166 					vector<const Type*> &accum_types, vector<const Type*> &all_types,
167 					vector<CVQualifiers> &all_quals, vector<CVQualifiers> &all_bitfield_quals);
168 
169 	static void make_all_struct_types(int level, vector<const Type*> &accum_types);
170 
171 	static void make_all_struct_union_types();
172 
173 	// make a random struct or union type
174 	static Type* make_random_struct_type(void);
175 	static Type* make_random_union_type(void);
176 
177 	static void make_one_bitfield(vector<const Type*> &random_fields,
178 				vector<CVQualifiers> &qualifiers,
179 				vector<int> &fields_length);
180 
181 	static void make_one_struct_field(vector<const Type*> &random_fields,
182 					vector<CVQualifiers> &qualifiers,
183 					vector<int> &fields_length,
184 					bool structHasAssignOps);
185 	static void make_one_union_field(vector<const Type*> &fields, vector<CVQualifiers> &qfers, vector<int> &lens);
186 
187 	static void make_full_bitfields_struct_fields(size_t field_cnt, vector<const Type*> &random_fields,
188 					vector<CVQualifiers> &qualifiers,
189 					vector<int> &fields_length,
190 					bool structHasAssignOps);
191 
192 	static void make_normal_struct_fields(size_t field_cnt, vector<const Type*> &random_fields,
193 					vector<CVQualifiers> &qualifiers,
194 					vector<int> &fields_length,
195 					bool structHasAssignOps);
196 
197 	// make a random pointer type
198 	static Type* make_random_pointer_type(void);
199 
200 	static const Type *get_type_from_string(const string &type_string);
201 
202 	// generate all simple types except void and long long(if it is not allowed)
203 	static void GenerateSimpleTypes(void);
204 
205 	void get_type_sizeof_string(std::string &s) const;
206 
207 	// For choosing a random, non-void `eSimpleType'.
208 	static eSimpleType choose_random_nonvoid_simple(void);
209 
210 	// select a type for LHS
211 	static const Type *SelectLType(bool no_volatile, eAssignOps op);
212 
213 	static bool has_aggregate_field(const vector<const Type *> &fields);
214 
215 	static bool has_longlong_field(const vector<const Type *> &fields);
216 
217 	explicit Type(eSimpleType simple_type);
218 	Type(vector<const Type*>& fields, bool isStruct, bool packed,
219 			vector<CVQualifiers> &qfers, vector<int> &fields_length, bool hasAssignOps, bool hasImplicitNontrivialAssignOps);
220 	Type(vector<unsigned int>& array_dims, eSimpleType st);
221 	explicit Type(const Type* t);
222 	~Type(void);
223 
224 	static const Type &get_simple_type(eSimpleType simple_type);
225 
226 	static void doFinalization(void);
227 
228 	const Type* get_base_type(void) const;
229 	int get_indirect_level(void) const;
230 	int get_struct_depth(void) const;
231 	void get_int_subfield_names(string prefix, vector<string>& names,
232 		vector<const Type *>& types, const vector<int>& excluded_fields) const;
233 	bool is_signed(void) const;
is_long_long(void)234 	bool is_long_long(void) const {
235 		return ((eType == eSimple) && (simple_type == eLongLong || simple_type == eULongLong));
236 	}
237 	const Type* to_unsigned(void) const;
is_pointer_to_char(void)238 	bool is_pointer_to_char(void) const { return ptr_type && ptr_type->eType == eSimple && (ptr_type->simple_type==eChar || ptr_type->simple_type==eUChar);}
is_signed_char()239 	bool is_signed_char() const {
240 		return ((eType == eSimple) && (simple_type == eChar));
241 	}
is_float()242 	bool is_float() const {
243 		return ((eType == eSimple) && (simple_type == eFloat));
244 	}
245 	bool is_promotable(const Type* t) const;
246 	bool is_convertable(const Type* t) const;
247 	bool is_derivable(const Type* t) const;
248 	bool is_dereferenced_from(const Type* t) const;
249 	bool is_equivalent(const Type* t) const;
250 	bool needs_cast(const Type* t) const;
251 	bool is_unamed_padding(size_t index) const;
252 	bool is_full_bitfields_struct() const;
253 	bool is_bitfield(size_t index) const ;
254 	bool has_bitfields() const;
255 	bool has_padding(void) const;
256 	bool contain_pointer_field(void) const;
257 	bool is_const_struct_union() const;
258 	bool is_volatile_struct_union() const;
has_assign_ops()259 	bool has_assign_ops() const  { return has_assign_ops_; }
has_implicit_nontrivial_assign_ops()260     bool has_implicit_nontrivial_assign_ops() const {
261         return has_implicit_nontrivial_assign_ops_;
262     }
is_int(void)263 	bool is_int(void) const { return eType == eSimple && simple_type != eVoid;}
is_aggregate(void)264 	bool is_aggregate(void) const { return eType == eStruct || eType == eUnion;}
265 	bool match(const Type* t, enum eMatchType mt) const;
266 	unsigned long SizeInBytes(void) const;
267 	void Output(std::ostream &) const;
268 	std::string printf_directive(void) const;
269 	static Type* find_pointer_type(const Type* t, bool add);
270 	static Type* find_type(const Type* t);
271 
272 // private:
273 	eTypeDesc eType;
274 	const Type *ptr_type;
275 	eSimpleType simple_type;
276 	vector<unsigned int> dimensions;    // for array types
277 	vector<const Type*> fields;         // for struct/union types
278 	unsigned int sid;                   // sequence id, for struct/union types
279 
280 	bool used;                          // whether any variable declared with this type
281 	bool printed;                       // whether this struct/union has been printed in the random program
282 	const bool packed_;					// whether this struct/union should be packed
283 	bool has_assign_ops_;				// assign ops are needed if we have:
284 										// struct S0 foo; volatile struct S0 bar; ... foo=bar;
285     bool has_implicit_nontrivial_assign_ops_;   // if a struct has a struct with assign ops as a field,
286                                         // than the former struct also has assign ops;
287                                         // also true if struct itself has assign ops
288 	vector<CVQualifiers> qfers_;		// conresponds to each element of fields
289 					// It's a tradeoff between the current implementation and the
290 					// need of struct's level type qualifiers.
291 	vector<int> bitfields_length_;		// -1 means it's a regular field
292 
293 	static Type *void_type;
294 private:
295 	DISALLOW_COPY_AND_ASSIGN(Type);
296 
297 	static const Type *simple_types[MAX_SIMPLE_TYPES];
298 
299 	// Package init.
300 	friend void GenerateAllTypes(void);
301 };
302 
303 void GenerateAllTypes(void);
304 const Type * get_int_type(void);
305 void OutputStructUnionDeclarations(std::ostream &);
306 void OutputStructAssignOps(Type* type, std::ostream &out, bool vol);
307 void OutputStructUnion(Type* type, std::ostream &out);
308 
309 ///////////////////////////////////////////////////////////////////////////////
310 
311 #endif // TYPE_H
312 
313 // Local Variables:
314 // c-basic-offset: 4
315 // tab-width: 4
316 // End:
317 
318 // End of file.
319