Nearly CC
An educational compiler skeleton
type.h
1 // Copyright (c) 2021-2023, David H. Hovemeyer <david.hovemeyer@gmail.com>
2 //
3 // Permission is hereby granted, free of charge, to any person obtaining a
4 // copy of this software and associated documentation files (the "Software"),
5 // to deal in the Software without restriction, including without limitation
6 // the rights to use, copy, modify, merge, publish, distribute, sublicense,
7 // and/or sell copies of the Software, and to permit persons to whom the
8 // Software is furnished to do so, subject to the following conditions:
9 //
10 // The above copyright notice and this permission notice shall be included
11 // in all copies or substantial portions of the Software.
12 //
13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
16 // THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
17 // OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
18 // ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
19 // OTHER DEALINGS IN THE SOFTWARE.
20 
21 #ifndef TYPE_H
22 #define TYPE_H
23 
24 #include <memory>
25 #include <vector>
26 #include <string>
27 
31 enum class BasicTypeKind {
32  CHAR,
33  SHORT,
34  INT,
35  LONG,
36  VOID,
37 };
38 
40 enum class TypeQualifier {
41  VOLATILE,
42  CONST,
43 };
44 
45 // forward declaration
46 class Member;
47 
60 class Type {
61 private:
62  // value semantics not allowed
63  Type(const Type &);
64  Type& operator=(const Type &);
65 
66 protected:
67  Type();
68 
69 public:
70  virtual ~Type();
71 
72  // Some member functions for convenience
73 
75  bool is_integral() const { return is_basic() && get_basic_type_kind() != BasicTypeKind::VOID; }
76 
81  const Member *find_member(const std::string &name) const;
82 
83  // Note that Type provides default implementations of virtual
84  // member functions that will be appropriate for most of the
85  // subclasses. Each subclass should be able to just override the
86  // member functions that are necessary to provide that
87  // subclass's functionality.
88 
91  virtual bool is_same(const Type *other) const = 0;
92 
95  virtual std::string as_str() const = 0;
96 
99  virtual const Type *get_unqualified_type() const;
100 
101  // subtype tests (safe to call on any Type object)
102 
107  virtual bool is_basic() const;
108 
111  virtual bool is_void() const;
112 
115  virtual bool is_struct() const;
116 
119  virtual bool is_pointer() const;
120 
123  virtual bool is_array() const;
124 
127  virtual bool is_function() const;
128 
129  // qualifier tests (safe to call on any Type object)
130 
133  virtual bool is_volatile() const;
134 
137  virtual bool is_const() const;
138 
139  // BasicType-only member functions
140 
144  virtual BasicTypeKind get_basic_type_kind() const;
145 
149  virtual bool is_signed() const;
150 
151  // Functions common to StructType and FunctionType.
152  // A "member" is a parameter (for FunctionTypes) or a field (for StructTypes).
153 
157  virtual void add_member(const Member &member);
158 
162  virtual unsigned get_num_members() const;
163 
169  virtual const Member &get_member(unsigned index) const;
170 
175  virtual unsigned get_field_offset(const std::string &name) const;
176 
182  virtual std::shared_ptr<Type> get_base_type() const;
183 
184  // FunctionType-only member functions
185  // (there aren't any, at least for now...)
186 
187  // PointerType-only member functions
188  // (there actually aren't any, at least for now...)
189 
193  virtual unsigned get_array_size() const;
194 
195  // These member functions can be used on any kind of type other
196  // than FunctionType.
197 
201  virtual unsigned get_storage_size() const = 0;
202 
208  virtual unsigned get_alignment() const = 0;
209 };
210 
213 class HasBaseType : virtual public Type {
214 private:
215  std::shared_ptr<Type> m_base_type;
216 
217  // value semantics are not allowed
218  HasBaseType(const HasBaseType &);
219  HasBaseType &operator=(const HasBaseType &);
220 
221 public:
222  HasBaseType(const std::shared_ptr<Type> &base_type);
223  virtual ~HasBaseType();
224 
225  virtual std::shared_ptr<Type> get_base_type() const;
226 };
227 
229 class Member {
230 private:
231  const std::string m_name;
232  std::shared_ptr<Type> m_type;
233  // Note: you could add additional information here, such as an
234  // offset value (for struct fields), etc.
235 
236 public:
237  Member(const std::string &name, const std::shared_ptr<Type> &type);
238  ~Member();
239 
241  const std::string &get_name() const;
242 
244  std::shared_ptr<Type> get_type() const;
245 };
246 
249 class HasMembers : virtual public Type {
250 private:
251  std::vector<Member> m_members;
252 
253  // value semantics are disallowed
254  HasMembers(const HasMembers &);
255  HasMembers &operator=(const HasMembers &);
256 
257 public:
258  HasMembers();
259  virtual ~HasMembers();
260 
261  virtual std::string as_str() const;
262  virtual void add_member(const Member &member);
263  virtual unsigned get_num_members() const;
264  virtual const Member &get_member(unsigned index) const;
265 };
266 
270 class QualifiedType : public HasBaseType {
271 private:
272  TypeQualifier m_type_qualifier;
273 
274  // value semantics are not allowed
275  QualifiedType(const QualifiedType &);
276  QualifiedType &operator=(const QualifiedType &);
277 
278 public:
279  QualifiedType(const std::shared_ptr<Type> &delegate, TypeQualifier type_qualifier);
280  virtual ~QualifiedType();
281 
282  virtual bool is_same(const Type *other) const;
283  virtual std::string as_str() const;
284  virtual const Type *get_unqualified_type() const;
285  virtual bool is_basic() const;
286  virtual bool is_void() const;
287  virtual bool is_struct() const;
288  virtual bool is_pointer() const;
289  virtual bool is_array() const;
290  virtual bool is_function() const;
291  virtual bool is_volatile() const;
292  virtual bool is_const() const;
293  virtual BasicTypeKind get_basic_type_kind() const;
294  virtual bool is_signed() const;
295  virtual void add_member(const Member &member);
296  virtual unsigned get_num_members() const;
297  virtual const Member &get_member(unsigned index) const;
298  virtual unsigned get_array_size() const;
299  virtual unsigned get_storage_size() const;
300  virtual unsigned get_alignment() const;
301 };
302 
304 class BasicType : public Type {
305 private:
306  BasicTypeKind m_kind;
307  bool m_is_signed;
308 
309  // value semantics not allowed
310  BasicType(const BasicType &);
311  BasicType &operator=(const BasicType &);
312 
313 public:
314  BasicType(BasicTypeKind kind, bool is_signed);
315  virtual ~BasicType();
316 
317  virtual bool is_same(const Type *other) const;
318  virtual std::string as_str() const;
319  virtual bool is_basic() const;
320  virtual bool is_void() const;
321  virtual BasicTypeKind get_basic_type_kind() const;
322  virtual bool is_signed() const;
323  virtual unsigned get_storage_size() const;
324  virtual unsigned get_alignment() const;
325 };
326 
329 class StructType : public HasMembers {
330 private:
331  std::string m_name;
332  mutable unsigned m_storage_size, m_alignment;
333 
334  // value semantics not allowed
335  StructType(const StructType &);
336  StructType &operator=(const StructType &);
337 
338 public:
339  StructType(const std::string &name);
340  virtual ~StructType();
341 
342  std::string get_name() const { return m_name; }
343 
344  virtual bool is_same(const Type *other) const;
345  virtual std::string as_str() const;
346  virtual bool is_struct() const;
347  virtual unsigned get_storage_size() const;
348  virtual unsigned get_alignment() const;
349 
350  virtual unsigned get_field_offset(const std::string &name) const;
351 
352 private:
353  void calculate_storage() const;
354 };
355 
359 class FunctionType : public HasBaseType, public HasMembers {
360 private:
361  // value semantics not allowed
362  FunctionType(const FunctionType &);
363  FunctionType &operator=(const FunctionType &);
364 
365 public:
366  FunctionType(const std::shared_ptr<Type> &base_type);
367  virtual ~FunctionType();
368 
369  virtual bool is_same(const Type *other) const;
370  virtual std::string as_str() const;
371  virtual bool is_function() const;
372  virtual unsigned get_storage_size() const;
373  virtual unsigned get_alignment() const;
374 };
375 
378 class PointerType : public HasBaseType {
379 private:
380  // value semantics not allowed
381  PointerType(const PointerType &);
382  PointerType &operator=(const PointerType &);
383 
384 public:
385  PointerType(const std::shared_ptr<Type> &base_type);
386  virtual ~PointerType();
387 
388  virtual bool is_same(const Type *other) const;
389  virtual std::string as_str() const;
390  virtual bool is_pointer() const;
391  virtual unsigned get_storage_size() const;
392  virtual unsigned get_alignment() const;
393 };
394 
397 class ArrayType : public HasBaseType {
398 private:
399  unsigned m_size;
400 
401  // value semantics not allowed
402  ArrayType(const ArrayType &);
403  ArrayType &operator=(const ArrayType &);
404 
405 public:
406  ArrayType(const std::shared_ptr<Type> &base_type, unsigned size);
407  virtual ~ArrayType();
408 
409  virtual bool is_same(const Type *other) const;
410  virtual std::string as_str() const;
411  virtual bool is_array() const;
412  virtual unsigned get_array_size() const;
413  virtual unsigned get_storage_size() const;
414  virtual unsigned get_alignment() const;
415 };
416 
417 #endif // TYPE_H
ArrayType represents an array type.
Definition: type.h:397
virtual unsigned get_storage_size() const
Get the number of bytes required to store an instance of this type.
Definition: type.cpp:614
virtual unsigned get_alignment() const
Get the storage alignment multiple in bytes for an instance of this type.
Definition: type.cpp:618
virtual bool is_array() const
Check whether the type is an ArrayType.
Definition: type.cpp:606
virtual unsigned get_array_size() const
Get the array size (number of elements).
Definition: type.cpp:610
virtual bool is_same(const Type *other) const
Equality comparison.
Definition: type.cpp:581
virtual std::string as_str() const
Convert to a readable string representation of this type.
Definition: type.cpp:595
A BasicType represents a basic type (int, char, etc.)
Definition: type.h:304
virtual bool is_void() const
Check whether the type represents void.
Definition: type.cpp:348
virtual bool is_signed() const
Check whether the BasicType is a signed type.
Definition: type.cpp:356
virtual bool is_same(const Type *other) const
Equality comparison.
Definition: type.cpp:314
virtual unsigned get_storage_size() const
Get the number of bytes required to store an instance of this type.
Definition: type.cpp:360
virtual unsigned get_alignment() const
Get the storage alignment multiple in bytes for an instance of this type.
Definition: type.cpp:372
virtual bool is_basic() const
Check whether the type is a BasicType.
Definition: type.cpp:344
virtual BasicTypeKind get_basic_type_kind() const
Get the BasicTypeKind of a BasicType.
Definition: type.cpp:352
virtual std::string as_str() const
Convert to a readable string representation of this type.
Definition: type.cpp:321
A FunctionType represents the type of a function.
Definition: type.h:359
virtual unsigned get_alignment() const
Get the storage alignment multiple in bytes for an instance of this type.
Definition: type.cpp:526
virtual unsigned get_storage_size() const
Get the number of bytes required to store an instance of this type.
Definition: type.cpp:522
virtual bool is_same(const Type *other) const
Equality comparison.
Definition: type.cpp:486
virtual std::string as_str() const
Convert to a readable string representation of this type.
Definition: type.cpp:507
virtual bool is_function() const
Check whether the type is a FunctionType.
Definition: type.cpp:518
Common base class for QualifiedType, FunctionType, PointerType, and ArrayType.
Definition: type.h:213
virtual std::shared_ptr< Type > get_base_type() const
Get the base type.
Definition: type.cpp:125
Common base class for StructType and FunctionType, which both have "members" (fields or parameters).
Definition: type.h:249
virtual std::string as_str() const
Convert to a readable string representation of this type.
Definition: type.cpp:159
virtual void add_member(const Member &member)
Add a member.
Definition: type.cpp:190
virtual const Member & get_member(unsigned index) const
Get the Member with the position indicated by the given index.
Definition: type.cpp:198
virtual unsigned get_num_members() const
Get the number of members (fields or parameters).
Definition: type.cpp:194
A parameter of a FunctionType or a field of a StructType.
Definition: type.h:229
const std::string & get_name() const
Definition: type.cpp:141
std::shared_ptr< Type > get_type() const
Definition: type.cpp:145
PointerType represents a pointer type.
Definition: type.h:378
virtual unsigned get_storage_size() const
Get the number of bytes required to store an instance of this type.
Definition: type.cpp:561
virtual std::string as_str() const
Convert to a readable string representation of this type.
Definition: type.cpp:548
virtual bool is_same(const Type *other) const
Equality comparison.
Definition: type.cpp:541
virtual unsigned get_alignment() const
Get the storage alignment multiple in bytes for an instance of this type.
Definition: type.cpp:565
virtual bool is_pointer() const
Check whether the type is a PointerType.
Definition: type.cpp:557
A QualifiedType modifies a "delegate" type with a TypeQualifier (const or volatile).
Definition: type.h:270
virtual bool is_pointer() const
Check whether the type is a PointerType.
Definition: type.cpp:250
virtual BasicTypeKind get_basic_type_kind() const
Get the BasicTypeKind of a BasicType.
Definition: type.cpp:270
virtual bool is_basic() const
Check whether the type is a BasicType.
Definition: type.cpp:238
virtual void add_member(const Member &member)
Add a member.
Definition: type.cpp:278
virtual bool is_void() const
Check whether the type represents void.
Definition: type.cpp:242
virtual bool is_volatile() const
Check whether the type is qualified as volatile.
Definition: type.cpp:262
virtual bool is_struct() const
Check whether the type is a StructType.
Definition: type.cpp:246
virtual unsigned get_alignment() const
Get the storage alignment multiple in bytes for an instance of this type.
Definition: type.cpp:298
virtual unsigned get_num_members() const
Get the number of members (fields or parameters).
Definition: type.cpp:282
virtual unsigned get_array_size() const
Get the array size (number of elements).
Definition: type.cpp:290
virtual bool is_same(const Type *other) const
Equality comparison.
Definition: type.cpp:215
virtual unsigned get_storage_size() const
Get the number of bytes required to store an instance of this type.
Definition: type.cpp:294
virtual bool is_function() const
Check whether the type is a FunctionType.
Definition: type.cpp:258
virtual bool is_signed() const
Check whether the BasicType is a signed type.
Definition: type.cpp:274
virtual std::string as_str() const
Convert to a readable string representation of this type.
Definition: type.cpp:226
virtual const Member & get_member(unsigned index) const
Get the Member with the position indicated by the given index.
Definition: type.cpp:286
virtual bool is_array() const
Check whether the type is an ArrayType.
Definition: type.cpp:254
virtual const Type * get_unqualified_type() const
Get unqualified type (strip off type qualifiers, if any).
Definition: type.cpp:234
virtual bool is_const() const
Check whether the type is qualified as const.
Definition: type.cpp:266
StructType represents a struct type.
Definition: type.h:329
virtual bool is_struct() const
Check whether the type is a StructType.
Definition: type.cpp:437
virtual unsigned get_field_offset(const std::string &name) const
Get the offset of the named field.
Definition: type.cpp:453
virtual std::string as_str() const
Convert to a readable string representation of this type.
Definition: type.cpp:425
virtual bool is_same(const Type *other) const
Equality comparison.
Definition: type.cpp:389
virtual unsigned get_alignment() const
Get the storage alignment multiple in bytes for an instance of this type.
Definition: type.cpp:447
virtual unsigned get_storage_size() const
Get the number of bytes required to store an instance of this type.
Definition: type.cpp:441
Representation of a C data type.
Definition: type.h:60
virtual const Member & get_member(unsigned index) const
Get the Member with the position indicated by the given index.
Definition: type.cpp:98
virtual bool is_const() const
Check whether the type is qualified as const.
Definition: type.cpp:78
virtual bool is_signed() const
Check whether the BasicType is a signed type.
Definition: type.cpp:86
virtual std::string as_str() const =0
Convert to a readable string representation of this type.
virtual bool is_void() const
Check whether the type represents void.
Definition: type.cpp:54
virtual unsigned get_field_offset(const std::string &name) const
Get the offset of the named field.
Definition: type.cpp:102
virtual unsigned get_storage_size() const =0
Get the number of bytes required to store an instance of this type.
virtual bool is_array() const
Check whether the type is an ArrayType.
Definition: type.cpp:66
virtual bool is_pointer() const
Check whether the type is a PointerType.
Definition: type.cpp:62
virtual unsigned get_array_size() const
Get the array size (number of elements).
Definition: type.cpp:110
bool is_integral() const
Return true if the type is an integral (integer) type.
Definition: type.h:75
virtual const Type * get_unqualified_type() const
Get unqualified type (strip off type qualifiers, if any).
Definition: type.cpp:45
virtual std::shared_ptr< Type > get_base_type() const
Get the base type.
Definition: type.cpp:106
virtual bool is_basic() const
Check whether the type is a BasicType.
Definition: type.cpp:50
virtual bool is_function() const
Check whether the type is a FunctionType.
Definition: type.cpp:70
virtual bool is_same(const Type *other) const =0
Equality comparison.
const Member * find_member(const std::string &name) const
Find named member.
Definition: type.cpp:36
virtual bool is_volatile() const
Check whether the type is qualified as volatile.
Definition: type.cpp:74
virtual unsigned get_alignment() const =0
Get the storage alignment multiple in bytes for an instance of this type.
virtual void add_member(const Member &member)
Add a member.
Definition: type.cpp:90
virtual BasicTypeKind get_basic_type_kind() const
Get the BasicTypeKind of a BasicType.
Definition: type.cpp:82
virtual unsigned get_num_members() const
Get the number of members (fields or parameters).
Definition: type.cpp:94
virtual bool is_struct() const
Check whether the type is a StructType.
Definition: type.cpp:58