cecko
cktables.hpp
Go to the documentation of this file.
1 
9 #ifndef cktables_hpp_
10 #define cktables_hpp_
11 
12 #include "ckir.hpp"
13 
14 #include <memory>
15 #include <functional>
16 #include <type_traits>
17 #include <unordered_set>
18 #include <unordered_map>
19 #include <optional>
20 
21 namespace cecko {
22 
24  using loc_t = unsigned;
25 
26  class CIAbstractType;
27 
29  using CKTypeObs = const CIAbstractType*; // use something smarter for safety
30 
31  class CKVoidType;
34 
35  struct CKTypeRefPack;
36 
38  template< typename ... TL>
39  inline std::size_t compute_hash(TL&& ... l)
40  {
41  return (0 ^ ... ^ std::hash<std::remove_cv_t<std::remove_reference_t<TL>>>{}(std::forward<TL>(l)));
42  }
43 
44  inline bool compute_equal()
45  {
46  return true;
47  }
48 
49  template< typename TA, typename TB, typename ... TL>
50  inline bool compute_equal(TA&& a, TB&& b, TL&& ... l)
51  {
52  return a == b && compute_equal(std::forward<TL>(l)...);
53  }
55 }
56 
58 template<>
59 class std::hash<cecko::CKIRAPInt> {
60 public:
61  std::size_t operator()(const cecko::CKIRAPInt& a) const
62  {
63  return cecko::CKHashValue(a);
64  }
65 };
66 
67 template<>
68 class std::hash<cecko::CKTypeObs> {
69 public:
70  std::size_t operator()(const cecko::CKTypeObs& a) const;
71 };
72 
73 template<>
74 class std::hash<cecko::CKTypeRefPack> {
75 public:
76  std::size_t operator()(const cecko::CKTypeRefPack& a) const;
77 };
79 
80 namespace cecko {
81  // DUMP OSTREAM
82 
84  using CIOStream = std::ostream;
85 
86  inline CIOStream& (*CIEndl)(CIOStream&) = &std::endl;
87 
88  // IMMOVABLE CLASS HELPER
89 
90  class CIImmovable {
91  public:
92  // COPYING AND MOVING DENIED
93  CIImmovable() = default;
94  CIImmovable(const CIImmovable&) = delete;
95  CIImmovable(CIImmovable&&) = delete;
96  CIImmovable& operator=(const CIImmovable&) = delete;
97  CIImmovable& operator=(CIImmovable&&) = delete;
98  };
99 
100  // HASHED STORAGE
101 
102  template< typename T>
103  class CIHashedStorage : CIImmovable {
104  public:
105  template< typename ... TL>
106  const T* emplace(TL&& ... l)
107  {
108  auto rv = data_.emplace(std::forward<TL>(l)...);
109  return &*rv.first;
110  }
111 
112  template<typename F>
113  void for_each(F&& f) const
114  {
115  for (auto&& a : data_)
116  {
117  f(&a);
118  }
119  }
120  private:
121  struct hasher_t {
122  std::size_t operator()(const T& a) const { return a.hash(); }
123  };
124  /*
125  struct comparator_t {
126  bool operator()(const T& a, const T& b) const { return a == b; }
127  };
128  */
129  using container_type_ = std::unordered_set< T, hasher_t>;
130  container_type_ data_;
131  };
132 
134 
135  // NAMED STORAGE
136 
138  using CIName = std::string;
139 
141 
142  template< typename T>
143  class CINamedStorage : CIImmovable {
144  public:
145  template< typename ... TL>
146  T* try_emplace(const CIName& n, TL&& ... l)
147  {
148  auto rv = data_.try_emplace(n, std::forward<TL>(l)...);
149  rv.first->second.set_name_ptr(&rv.first->first);
150  return &rv.first->second;
151  }
152 
153  T* find(const CIName& n)
154  {
155  auto it = data_.find(n);
156  return it == data_.end() ? nullptr : &it->second;
157  }
158 
159  const T* find(const CIName& n) const
160  {
161  auto it = data_.find(n);
162  return it == data_.end() ? nullptr : &it->second;
163  }
164 
165  template<typename F>
166  void for_each(F&& f) const
167  {
168  using container_pair_obs = const std::pair< const CIName, T>*;
169  auto pair_less = [](auto a, auto b) {
170  return a->first < b->first;
171  };
172  using ordering_set = std::vector< container_pair_obs>;
173  ordering_set os(data_.size(), nullptr);
174  std::transform(data_.begin(), data_.end(), os.begin(),
175  [](auto&& a) {
176  return &a;
177  });
178  std::sort(os.begin(), os.end(), pair_less);
179  for (auto&& p : os)
180  {
181  f(&p->second);
182  }
183  }
184  private:
185  using container_type_ = std::unordered_map< CIName, T>;
186  container_type_ data_;
187  };
189 
191  class CINamePtr {
192  public:
194  CINamePtr(loc_t def_loc)
195  : name_ptr_(nullptr), def_loc_(def_loc)
196  {}
198 
200  const CIName& get_name() const
201  {
202  assert(!!name_ptr_);
203  return *name_ptr_;
204  }
206  std::string get_dump_name() const;
207  void set_def_loc(loc_t def_loc) { def_loc_ = def_loc; }
209  private:
210  void set_name_ptr(const CIName* p)
211  {
212  name_ptr_ = p;
213  }
214 
215  const CIName* name_ptr_;
216  loc_t def_loc_;
217 
218  template< typename T>
219  friend class CINamedStorage;
220  };
221 
222  // MANGLER
223 
225  using CITypeMangle = std::string;
226 
227  using CIDecl = std::string;
229 
230  // TYPES
231 
232  class CKStructElement;
233 
238 
240  struct CKTypeRefPack {
241 
244  : type(nullptr), is_const(false)
245  {}
246 
248  CKTypeRefPack(CKTypeObs t, bool is_c)
249  : type(t), is_const(is_c)
250  {}
252  bool is_const;
253  };
254 
257 
260  : type(nullptr), is_const(false)
261  {}
262 
265  : type(t), is_const(is_c)
266  {}
268  explicit CKTypeRefSafePack(const CKTypeRefPack & tp)
269  : type(tp.type), is_const(tp.is_const)
270  {}
272  operator CKTypeRefPack() const
273  {
274  return CKTypeRefPack(type, is_const);
275  }
277  bool is_const;
278  };
279 
281  class CIAbstractType : CIImmovable {
282  public:
284  virtual ~CIAbstractType() {}
285  virtual std::size_t hash() const = 0;
287 
289  virtual CKIRTypeObs get_ir() const = 0;
290 
293 
296 
297  virtual bool is_void() const { return false; }
298  virtual bool is_bool() const { return false; }
299  virtual bool is_char() const { return false; }
300  virtual bool is_int() const { return false; }
301  virtual bool is_enum() const { return false; }
302  virtual bool is_array() const { return false; }
303  virtual bool is_function() const { return false; }
304  virtual bool is_pointer() const { return false; }
305  virtual bool is_struct() const { return false; }
307 
310 
312  virtual CKTypeRefSafePack get_pointer_points_to() const { assert(0); return {nullptr, false}; }
314 
317 
319  virtual CKTypeSafeObs get_function_return_type() const { assert(0); return nullptr; }
321  virtual CKTypeSafeObs get_function_arg_type(std::size_t ix) const { return nullptr; }
323  virtual std::size_t get_function_arg_count() const { return 0; }
325  virtual bool is_function_variadic() const { return false; }
327 
330 
332  virtual CKTypeSafeObs get_array_element_type() const { assert(0); return nullptr; }
334  virtual CKIRConstantIntObs get_array_size() const { assert(0); return nullptr; }
336 
339 
341  virtual CKStructElementSafeObs find_struct_element(const CIName&) const { assert(0); return nullptr; }
343 
345  virtual CITypeMangle mangle() const = 0;
346  virtual CIDecl declaration(bool is_const, const CIDecl& dtor = "") const = 0;
348  };
349 
351  inline bool operator==(const CKTypeRefPack& a, const CKTypeRefPack& b)
352  {
353  return compute_equal(a.type, b.type, a.is_const, b.is_const);
354  }
356 
358  class CKVoidType : public CIAbstractType {
359  public:
361  CKVoidType()
362  : irt_(nullptr)
363  {}
364  CKVoidType(CKIRContextRef Context)
365  : irt_(CKGetVoidType(Context))
366  {}
367  virtual std::size_t hash() const override { return 0; }
368  virtual CKIRTypeObs get_ir() const override { return irt_; }
369  virtual bool is_void() const override { return true; }
370  virtual CITypeMangle mangle() const override { return "V"; }
371  virtual CIDecl declaration(bool is_const, const CIDecl& dtor) const override;
373  private:
374  CKIRTypeObs irt_;
375  };
376 
378  class CKBoolType : public CIAbstractType {
379  public:
381  CKBoolType(CKIRContextRef Context)
382  : irt_(CKGetInt1Type(Context))
383  {}
384  virtual std::size_t hash() const override { return 1; }
385  virtual CKIRTypeObs get_ir() const override { return irt_; }
386  virtual bool is_bool() const override { return true; }
387  // virtual bool is_signed() const { return false; }
388  virtual CITypeMangle mangle() const override { return "B"; }
389  virtual CIDecl declaration(bool is_const, const CIDecl& dtor) const override;
391  private:
392  CKIRTypeObs irt_;
393  };
394 
396  class CKCharType : public CIAbstractType {
397  public:
399  CKCharType()
400  : irt_(nullptr)
401  {}
402  CKCharType(CKIRContextRef Context)
403  : irt_(CKGetInt8Type(Context))
404  {}
405  virtual std::size_t hash() const override { return 8; }
406  virtual CKIRTypeObs get_ir() const override { return irt_; }
407  virtual bool is_char() const override { return true; }
408  //virtual bool is_signed() const { return false; }
409  virtual CITypeMangle mangle() const override { return "X"; }
410  virtual CIDecl declaration(bool is_const, const CIDecl& dtor) const override;
412  private:
413  CKIRTypeObs irt_;
414  };
415 
417  class CKIntType : public CIAbstractType {
418  public:
420  CKIntType()
421  : irt_(nullptr)
422  {}
423  CKIntType(CKIRContextRef Context)
424  : irt_(CKGetInt32Type(Context))
425  {}
426  virtual std::size_t hash() const override { return 32; }
427  virtual CKIRTypeObs get_ir() const override { return irt_; }
428  virtual bool is_int() const override { return true; }
429  //virtual bool is_signed() const override { return true; }
430  virtual CITypeMangle mangle() const override { return "I"; }
431  virtual CIDecl declaration(bool is_const, const CIDecl& dtor) const override;
433  private:
434  CKIRTypeObs irt_;
435  };
436 
438  class CKPtrType : public CIAbstractType {
439  public:
441  CKPtrType()
442  : points_to_(nullptr,false), irt_(nullptr)
443  {}
444 
445  explicit CKPtrType(const CKTypeRefPack& points_to)
446  : points_to_(points_to), irt_(CKGetPtrType(points_to.type->get_ir()->getContext()))
447  {}
448 
449  virtual std::size_t hash() const override { return compute_hash(points_to_); }
450  virtual CKIRTypeObs get_ir() const override { return irt_; }
451  bool operator==(const CKPtrType& b) const
452  {
453  return compute_equal(points_to_, b.points_to_);
454  }
455 
456  virtual bool is_pointer() const override { return true; }
457  virtual CKTypeRefSafePack get_pointer_points_to() const override { return CKTypeRefSafePack(points_to_); }
458 
459  virtual CITypeMangle mangle() const override { return (points_to_.is_const ? "pc" : "p") + points_to_.type->mangle(); }
460  virtual CIDecl declaration(bool is_const, const CIDecl& dtor) const override;
462  private:
463  CKTypeRefPack points_to_;
464  CKIRTypeObs irt_;
465  };
466 
468  class CKArrayType : public CIAbstractType {
469  public:
471  CKArrayType()
472  : element_type_(nullptr), size_(nullptr), irt_(nullptr)
473  {}
474  CKArrayType(CKTypeObs element_type, CKIRConstantIntObs size)
475  : element_type_(element_type), size_(size), irt_(CKGetArrayType(element_type->get_ir(), size))
476  {}
477 
478  virtual std::size_t hash() const override { return compute_hash(element_type_, size_->getValue()); }
479  virtual CKIRTypeObs get_ir() const override { return irt_; }
480  bool operator==(const CKArrayType& b) const
481  {
482  return compute_equal(element_type_, b.element_type_, size_->getValue(), b.size_->getValue());
483  }
484 
485  virtual bool is_array() const override { return true; }
486  virtual CKTypeSafeObs get_array_element_type() const override { return CKTypeSafeObs(element_type_); }
487  virtual CKIRConstantIntObs get_array_size() const override { return size_; }
488 
489  virtual CITypeMangle mangle() const override { return "a" + std::to_string(size_->getValue().getZExtValue()) + element_type_->mangle(); }
490  virtual CIDecl declaration(bool is_const, const CIDecl& dtor) const override;
492  private:
493  CKTypeObs element_type_;
494  CKIRConstantIntObs size_;
495  CKIRTypeObs irt_;
496  };
497 
499  class CKStructElement : public CINamePtr, CIImmovable {
500  public:
502  explicit CKStructElement()
503  : CINamePtr(0), pack_(nullptr, false), idx_(0)
504  {}
505  explicit CKStructElement(const CKTypeRefPack& pack, unsigned int idx, loc_t def_loc)
506  : CINamePtr(def_loc), pack_(pack), idx_(idx)
507  {}
510  const CKTypeRefPack& get_type_pack() const { return pack_; }
512  unsigned int get_idx() const { return idx_; }
513  private:
514  CKTypeRefPack pack_;
515  unsigned int idx_;
516  };
517 
518  using CKStructElementObs = const CKStructElement*;
519 
521  struct CKStructItem {
524  : pack(p), name(std::move(nm)), loc(l)
525  {}
532  };
533 
535  using CKStructItemArray = std::vector< CKStructItem>;
536 
538  class CKStructType : public CIAbstractType, public CINamePtr {
539  public:
541  CKStructType()
542  : CINamePtr(0), decl_loc_(0), defined_(false), irt_(nullptr)
543  {}
544  CKStructType(CKIRContextRef Context, const CIName& n, loc_t decl_loc)
545  : CINamePtr(0), decl_loc_(decl_loc), defined_(false), irt_(CKCreateStructType(Context, n))
546  {}
547  void finalize(const CKStructItemArray& items);
548 
549  virtual std::size_t hash() const override { return std::hash<CIName>{}(get_name()); }
550  virtual CKIRTypeObs get_ir() const override { return irt_; }
551  virtual bool is_struct() const override { return true; }
553 
555  bool is_defined() const { return defined_; }
556 
558  virtual CKStructElementSafeObs find_struct_element(const CIName& n) const override
559  {
560  assert(defined_);
561  return CKStructElementSafeObs(elements_.find(n));
562  }
563 
564  virtual CITypeMangle mangle() const override { return "S" + get_name() + '$'; }
565  virtual CIDecl declaration(bool is_const, const CIDecl& dtor) const override;
566  void dump(CIOStream& os, const std::string& indent) const;
568  private:
569  using element_storage_type = CINamedStorage< CKStructElement>;
570  loc_t decl_loc_;
571  bool defined_;
572  element_storage_type elements_;
573  std::vector< CKStructElementObs> elements_ordered_;
574  CKIRStructTypeObs irt_;
575  };
576 
577  class CKConstant;
578 
583 
585  using CKConstantObsVector = std::vector<CKConstantConstObs>;
586 
588  class CKEnumType : public CIAbstractType, public CINamePtr {
589  public:
591  CKEnumType()
592  : CINamePtr(0), decl_loc_(0), defined_(false), base_type_(nullptr)
593  {}
594  CKEnumType(CKTypeObs base_type, loc_t decl_loc)
595  : CINamePtr(0), decl_loc_(decl_loc), defined_(false), base_type_(base_type)
596  {}
597  void finalize(CKConstantObsVector items);
598 
599  virtual std::size_t hash() const override { return std::hash<CIName>{}(get_name()); }
600  virtual bool is_enum() const override { return true; }
602 
604  bool is_defined() const { return defined_; }
605 
607  virtual CITypeMangle mangle() const override { return "E" + get_name() + '$'; }
608  virtual CIDecl declaration(bool is_const, const CIDecl& dtor) const override;
609  virtual CKIRTypeObs get_ir() const override { return base_type_->get_ir(); }
610  void dump(CIOStream& os, const std::string& indent) const;
612  private:
613  loc_t decl_loc_;
614  bool defined_;
615  CKTypeObs base_type_;
616  CKConstantObsVector elements_ordered_;
617  };
618 
620  using CKTypeObsArray = std::vector<CKTypeObs>;
621 
624  public:
627  : ret_type_(nullptr), variadic_(false), irt_(nullptr)
628  {}
629  CKFunctionType(CKTypeObs ret_type, CKTypeObsArray arg_types, bool variadic = false);
630 
631  bool operator==(const CKFunctionType& b) const;
632 
633  virtual std::size_t hash() const override;
634 
635  virtual CKIRTypeObs get_ir() const override { return irt_; }
636  CKIRFunctionTypeObs get_function_ir() const { return irt_; }
637  virtual bool is_function() const override { return true; }
638  virtual CKTypeSafeObs get_function_return_type() const override { return CKTypeSafeObs(ret_type_); }
639  virtual CKTypeSafeObs get_function_arg_type(std::size_t ix) const override { return CKTypeSafeObs(arg_types_[ix]); }
640  virtual std::size_t get_function_arg_count() const override { return arg_types_.size(); }
641  virtual bool is_function_variadic() const override { return variadic_; }
642 
643  virtual CITypeMangle mangle() const override;
644  virtual CIDecl declaration(bool is_const, const CIDecl& dtor) const override;
646  private:
647  CKTypeObs ret_type_;
648  CKTypeObsArray arg_types_;
649  bool variadic_;
650  CKIRFunctionTypeObs irt_;
651  };
652 
654  using CKVoidTypeObs = const CKVoidType*;
658  using CKBoolTypeObs = const CKBoolType*;
662  using CKCharTypeObs = const CKCharType*;
666  using CKIntTypeObs = const CKIntType*;
670  using CKPtrTypeObs = const CKPtrType*;
671  using CKArrayTypeObs = const CKArrayType*;
689 
691  class CKTypeTable : CIImmovable {
692  public:
693  CKTypeTable(CKIRContextRef Context)
694  : voit_(Context), boot_(Context), chrt_(Context), intt_(Context)
695  {}
696  CKVoidTypeObs get_void_type() const { return &voit_; }
697  CKBoolTypeObs get_bool_type() const { return &boot_; }
698  CKCharTypeObs get_char_type() const { return &chrt_; }
699  CKIntTypeObs get_int_type() const { return &intt_; }
700  CKPtrTypeObs get_pointer_type(const CKTypeRefPack& pack) { return ptrts_.emplace(pack); }
701  CKArrayTypeObs get_array_type(CKTypeObs element_type, CKIRConstantIntObs size) { return arrts_.emplace(element_type, size); }
702  CKFunctionTypeObs get_function_type(CKTypeObs ret_type, CKTypeObsArray arg_types, bool variadic = false) { return fncts_.emplace(ret_type, std::move(arg_types), variadic); }
703  void dump(CIOStream& os) const;
704  private:
705  CKVoidType voit_;
706  CKBoolType boot_;
707  CKCharType chrt_;
708  CKIntType intt_;
709  CIHashedStorage< CKPtrType> ptrts_;
710  CIHashedStorage< CKArrayType> arrts_;
711  CIHashedStorage< CKFunctionType> fncts_;
712  };
714 
716  class CKAbstractNamed : public CINamePtr, CIImmovable {
717  public:
719  CKAbstractNamed(loc_t def_loc)
720  : CINamePtr(def_loc)
721  {}
722  virtual ~CKAbstractNamed() {}
726  //virtual bool is_typedef() const { return false; }
727 
729  virtual bool is_var() const { return false; }
731  virtual bool is_function() const { return false; }
733  virtual bool is_constant() const { return false; }
735 
738 
740  virtual CKTypeSafeObs get_type() const = 0;
742  virtual bool is_const() const { return false; }
744 
747 
749  virtual CKIRValueObs get_ir() const { return nullptr; };
751  virtual CKIRFunctionObs get_function_ir() const { return nullptr; };
753  };
754 
759 
761  class CKTypedef : public CINamePtr, CIImmovable {
762  public:
764  CKTypedef()
765  : CINamePtr(0), type_pack_(nullptr, false)
766  {}
767  CKTypedef(CKTypeRefPack type_pack, loc_t def_loc)
768  : CINamePtr(def_loc), type_pack_(type_pack)
769  {}
771  //virtual bool is_typedef() const { return true; }
772  //CKTypeObs get_type() const { return type_pack_.type; }
773  //bool is_const() const { return type_pack_.is_const; }
774 
776  CKTypeRefSafePack get_type_pack() const { return CKTypeRefSafePack(type_pack_); }
777 
779  void dump(CIOStream& os) const;
781  private:
782  CKTypeRefPack type_pack_;
783  };
784 
786  using CKTypedefConstObs = const CKTypedef*;
789 
791  class CKConstant : public CKAbstractNamed {
792  public:
794  CKConstant()
795  : CKAbstractNamed(0), type_pack_(nullptr, true), value_(nullptr)
796  {}
797  CKConstant(CKTypeObs type, CKIRConstantIntObs value, loc_t def_loc)
798  : CKAbstractNamed(def_loc), type_pack_(type, true), value_(value)
799  {}
800  virtual bool is_constant() const override { return true; }
801  virtual CKTypeSafeObs get_type() const override { return CKTypeSafeObs(type_pack_.type); }
802  virtual bool is_const() const override { return type_pack_.is_const; }
803  //const CKTypeRefPack& get_type_pack() const { return type_pack_; }
805 
807  CKIRConstantIntObs get_constant_value() const { return value_; }
809  virtual CKIRValueObs get_ir() const override { return value_; }
810  std::string declaration() const;
812  private:
813  CKTypeRefPack type_pack_;
814  CKIRConstantIntObs value_;
815  };
816 
818  class CKVar : public CKAbstractNamed {
819  public:
821  CKVar(CKTypeRefPack type_pack, loc_t def_loc)
822  : CKAbstractNamed(def_loc), type_pack_(type_pack)
823  {}
825  virtual bool is_var() const override { return true; }
826  virtual CKTypeSafeObs get_type() const override { return CKTypeSafeObs(type_pack_.type); }
827  virtual bool is_const() const override { return type_pack_.is_const; }
828  //const CKTypeRefPack& get_type_pack() const { return type_pack_; }
830  void dump(CIOStream& os, const std::string& indent) const;
832  private:
833  CKTypeRefPack type_pack_;
834  };
835 
837  class CKGlobalVar : public CKVar {
838  public:
840  CKGlobalVar(CKTypeRefPack type_pack, CKIRConstantObs address, loc_t def_loc)
841  : CKVar(type_pack, def_loc), address_(address)
842  {}
843  virtual CKIRValueObs get_ir() const override { return address_; }
844  CKIRConstantObs get_address() const { return address_; }
846  private:
847  CKIRConstantObs address_;
848  };
849 
851  using CKGlobalVarObs = CKGlobalVar*;
853 
855  using CINameOpt = std::optional< CIName>;
856 
861  : name(std::move(nm)), is_const(c), loc( loc)
862  {}
866  bool is_const;
869  };
870 
872  class CKLocalTable;
873 
874  using CKLocalTableOwner = std::unique_ptr< CKLocalTable>;
875  using CKLocalTableObs = CKLocalTable*;
876 
877  class CKAbstractScope : CIImmovable {
878  public:
879  virtual ~CKAbstractScope() {}
880  virtual CKStructTypeObs find_struct_type(const CIName& n) = 0;
881  virtual CKEnumTypeObs find_enum_type(const CIName& n) = 0;
882  virtual CKTypedefConstObs find_typedef(const CIName& n) const = 0;
883  virtual CKNamedObs find(const CIName& n) = 0;
884  virtual CKLocalTableObs get_local();
885  };
886 
887  using CKAbstractScopeObs = CKAbstractScope*;
889 
891  using CKFunctionFormalPackArray = std::vector< CKFunctionFormalPack>;
892 
894  class CKFunction : public CKAbstractNamed {
895  public:
897  CKFunction(CKIRModuleObs M, CKFunctionTypeObs type, const CIName& irname, loc_t def_loc)
898  : CKAbstractNamed(def_loc), type_(type), irf_(CKCreateFunction(type->get_function_ir(), irname, M))
899  {}
900  virtual bool is_function() const override { return true; }
901 
903  bool is_defined() const { return !!loctab_; }
904 
905  virtual CKTypeSafeObs get_type() const override { return CKTypeSafeObs(type_); }
906  CKFunctionTypeObs get_function_type() const { return type_; }
907  virtual CKIRValueObs get_ir() const override { return irf_; }
908  virtual CKIRFunctionObs get_function_ir() const override { return irf_; }
909  const CKFunctionFormalPack& get_formal_pack(std::size_t ix) const { return formal_packs_[ix]; }
910  CKLocalTableObs define(CKAbstractScopeObs parent, CKIRBuilderRef builder, CKFunctionFormalPackArray formal_packs);
911  void dump(CIOStream& os) const;
913  private:
914  CKFunctionTypeObs type_;
915  CKIRFunctionObs irf_;
916  CKFunctionFormalPackArray formal_packs_;
917  CKLocalTableOwner loctab_;
918  };
919 
921  class CKUniversalTable : public CKAbstractScope {
922  public:
923  CKStructTypeObs declare_struct_type_here(const CIName& n, CKIRContextRef Context, loc_t decl_loc)
924  {
925  return strts_.try_emplace(n, Context, n, decl_loc);
926  }
927  CKStructTypeObs find_struct_type_here(const CIName& n) { return strts_.find(n); }
928  CKEnumTypeObs declare_enum_type_here(const CIName& n, CKTypeObs base_type, loc_t decl_loc)
929  {
930  return enmts_.try_emplace(n, base_type, decl_loc);
931  }
932  CKEnumTypeObs find_enum_type_here(const CIName& n) { return enmts_.find(n); }
933  CKTypedefConstObs declare_typedef(const CIName& name, const CKTypeRefPack& type_pack, loc_t def_loc);
934  CKConstantConstObs declare_constant(const CIName& name, CKTypeObs type, CKIRConstantIntObs value, loc_t def_loc);
935  CKTypedefConstObs find_typedef_here(const CIName& n) const;
936  CKNamedObs find_constant_here(const CIName& n);
937  bool conflicting_tag_enum(const std::string& name);
938  bool conflicting_tag_struct(const std::string& name);
939  bool find_idf_here_universal(const CIName& n);
940  void dump_universal(CIOStream& os, const std::string& indent) const;
941  private:
942  CINamedStorage< CKStructType> strts_;
943  CINamedStorage< CKEnumType> enmts_;
944  CINamedStorage< CKTypedef> typedefs_;
945  CINamedStorage< CKConstant> constants_;
946  };
948 
953 
955  using CKFunctionConstObs = const CKFunction*;
956 
957  class CKGlobalTable : public CKUniversalTable {
958  public:
959  CKGlobalTable()
960  {}
961  CKGlobalVarObs varDefine(CKIRModuleObs M, const CIName& name, const CKTypeRefPack& type_pack, loc_t def_loc);
962  CKGlobalVarObs declare_extern_variable(CKIRModuleObs M, const CIName& name, const CKTypeRefPack& type_pack);
963  CKStructTypeObs declare_struct_type(const CIName& n, CKIRContextRef Context, loc_t decl_loc)
964  {
965  return declare_struct_type_here(n, Context, decl_loc);
966  }
967  virtual CKStructTypeObs find_struct_type(const CIName& n) override { return find_struct_type_here(n); }
968  CKEnumTypeObs declare_enum_type(const CIName& n, CKTypeObs base_type, loc_t decl_loc)
969  {
970  return declare_enum_type_here(n, base_type, decl_loc);
971  }
972  virtual CKEnumTypeObs find_enum_type(const CIName& n) override { return find_enum_type_here(n); }
973  CKFunctionObs declare_function(const CIName& n, CKIRModuleObs M, CKFunctionTypeObs type, loc_t decl_loc);
974  CKFunctionObs declare_function(const CIName& n, CKIRModuleObs M, CKFunctionTypeObs type, const CIName& irname);
975  CKFunctionObs find_function(const CIName& n);
976  CKFunctionConstObs find_function(const CIName& n) const;
977  virtual CKTypedefConstObs find_typedef(const CIName& n) const override;
978  virtual CKNamedObs find(const CIName& n) override;
979  CKNamedObs find_here(const CIName& n);
980  bool conflicting_idf(const CIName& n);
981  bool conflicting_idf_function(const CIName& n, CKFunctionTypeObs type);
982 
983  void dump(CIOStream& os) const;
984  private:
985  CINamedStorage< CKFunction> fncs_;
986  CINamedStorage< CKGlobalVar> vars_;
987  };
989 
991  class CKLocalVar : public CKVar {
992  public:
994  CKLocalVar(CKTypeRefPack type_pack, CKIRAllocaInstObs address, loc_t def_loc, bool is_arg)
995  : CKVar(type_pack, def_loc), address_(address), is_arg_(is_arg)
996  {}
997  virtual CKIRValueObs get_ir() const override { return address_; }
998  CKIRAllocaInstObs get_address() const { return address_; }
999  bool is_arg() const { return is_arg_; }
1001  private:
1002  CKIRAllocaInstObs address_;
1003  bool is_arg_;
1004  };
1005 
1007  using CKLocalVarObs = CKLocalVar*;
1008 
1009  class CKLocalTable : public CKUniversalTable {
1010  public:
1011  CKLocalTable(CKAbstractScopeObs parent)
1012  : parent_scope_(parent)
1013  {}
1014 
1015  CKStructTypeObs declare_struct_type(const CIName& n, CKIRContextRef Context, loc_t decl_loc);
1016  virtual CKStructTypeObs find_struct_type(const CIName& n) override;
1017  CKEnumTypeObs declare_enum_type(const CIName& n, CKTypeObs base_type, loc_t decl_loc);
1018  virtual CKEnumTypeObs find_enum_type(const CIName& n) override;
1019 
1020  void varsFromArgs(CKIRBuilderRef builder, CKFunctionObs f, const CKFunctionFormalPackArray& formal_packs);
1021 
1022  CKLocalVarObs varDefine(CKIRBuilderRef builder, const CIName& name, const CKTypeRefPack& type_pack, loc_t def_loc);
1023 
1024  virtual CKTypedefConstObs find_typedef(const CIName& n) const override;
1025  virtual CKNamedObs find(const CIName& n) override;
1026  CKNamedObs find_here(const CIName& n);
1027  bool conflicting_idf(const CIName& n);
1028 
1029  void dump(CIOStream& os, const std::string & indent) const;
1030 
1031  virtual CKLocalTableObs get_local() override;
1032 
1033  CKLocalTableObs create_block();
1034  CKLocalTableObs parent_block() const;
1035 
1036  private:
1037  CKAbstractScopeObs parent_scope_;
1038  CINamedStorage< CKLocalVar> vars_;
1039  std::vector< CKLocalTableOwner> block_scopes_;
1040  };
1042 
1043  // CONTEXT
1044 
1046  using CKTypeTableObs = CKTypeTable*;
1047  using CKGlobalTableObs = CKGlobalTable*;
1048  using CKGlobalTableConstObs = const CKGlobalTable*;
1049 
1050  struct CKTables {
1051  CKTables(CKIREnvironmentObs irenv);
1052 
1053  CKIRModuleObs module() const
1054  {
1055  return module_;
1056  }
1057 
1058  CKTypeTableObs typetable()
1059  {
1060  return &typetable_;
1061  }
1062 
1063  CKGlobalTableObs globtable()
1064  {
1065  return &globtable_;
1066  }
1067 
1068  CKGlobalTableConstObs globtable() const
1069  {
1070  return &globtable_;
1071  }
1072 
1073  void dump_tables(std::ostream& os) const;
1074 
1075  void dump_ir_module(std::ostream& os) const;
1076 
1077  std::error_code write_bitcode_module(const std::string& fname) const;
1078 
1079  CKIRDataLayoutObs data_layout() const
1080  {
1081  return data_layout_;
1082  }
1083 
1084  private:
1085  void declare_library();
1086 
1087  CKIREnvironmentObs irenv_;
1088  CKIRModuleObs module_;
1089  CKIRDataLayoutObs data_layout_;
1090 
1091  CKTypeTable typetable_;
1092  CKGlobalTable globtable_;
1093  };
1094 
1095  using CKTablesObs = CKTables*;
1097 
1098  class context;
1099 
1101  struct CKContext {
1103  CKContext(CKTablesObs tab);
1105 
1108 
1114  void enter_block();
1116  void exit_block();
1120 
1123 
1125  CKVoidTypeSafeObs get_void_type() const { return CKVoidTypeSafeObs(typetable_->get_void_type()); }
1127  CKBoolTypeSafeObs get_bool_type() const { return CKBoolTypeSafeObs(typetable_->get_bool_type()); }
1129  CKCharTypeSafeObs get_char_type() const { return CKCharTypeSafeObs(typetable_->get_char_type()); }
1131  CKIntTypeSafeObs get_int_type() const { return CKIntTypeSafeObs(typetable_->get_int_type()); }
1133 
1136 
1138  CKPtrTypeSafeObs get_pointer_type(const CKTypeRefPack& pack) { return CKPtrTypeSafeObs(typetable_->get_pointer_type(pack)); }
1142  CKFunctionTypeSafeObs get_function_type(CKTypeObs ret_type, CKTypeObsArray arg_types, bool variadic = false);
1144 
1147 
1155 
1158 
1166 
1169 
1171  void define_var(const CIName& name, const CKTypeRefPack& type_pack, loc_t loc);
1173 
1176 
1178  CKTypedefConstSafeObs define_typedef(const CIName& name, const CKTypeRefPack& type_pack, loc_t loc);
1180 
1183 
1187 
1190 
1194 
1197 
1200 
1204 
1207 
1209  bool is_typedef(const CIName& n) const;
1211 
1214 
1217  {
1218  return llvm::Type::getInt64Ty(builder_.getContext());
1219  }
1221 
1224 
1227  {
1228  return CKGetInt8Constant(builder_.getContext(), v);
1229  }
1230 
1233  {
1234  return CKGetInt32Constant(builder_.getContext(), v);
1235  }
1237 
1240 
1242  CKIRBasicBlockObs create_basic_block(const std::string & name)
1243  {
1244  if (!current_function_ir_)
1245  return nullptr;
1246  return CKCreateBasicBlock(name, current_function_ir_);
1247  }
1249 
1252 
1255  {
1256  return &builder_;
1257  }
1259 
1262 
1265  {
1266  return CKGetInt32Constant(builder_.getContext(), CKGetTypeSize(data_layout_, type->get_ir()));
1267  }
1269 
1271  CKIRDataLayoutObs data_layout() const
1272  {
1273  return data_layout_;
1274  }
1275 
1276  bool conflicting_idf(const std::string& name);
1277  bool conflicting_idf_function(const std::string& name, CKFunctionTypeObs type);
1278  bool conflicting_tag_enum(const std::string& name);
1279  bool conflicting_tag_struct(const std::string& name);
1281  private:
1282  CKTypeTableObs typetable_;
1283  CKGlobalTableObs globtable_;
1284  CKIRModuleObs module_;
1285  CKLocalTableObs loctable_;
1286  std::unique_ptr<CKLocalTable> dummy_loctable_;
1287 
1288  CKFunctionObs current_function_;
1289  CKIRFunctionObs current_function_ir_;
1290  CKIRBuilder alloca_builder_;
1291  CKIRBuilder builder_;
1292  CKIRBasicBlockObs start_bb_;
1293  CKIRDataLayoutObs data_layout_;
1294 
1295  context* get_ctx();
1296  };
1297 }
1298 
1300 inline std::size_t std::hash<cecko::CKTypeObs>::operator()(const cecko::CKTypeObs& a) const
1301 {
1302  return cecko::compute_hash(a->hash());
1303 }
1304 
1305 inline std::size_t std::hash<cecko::CKTypeRefPack>::operator()(const cecko::CKTypeRefPack& a) const
1306 {
1307  return cecko::compute_hash(a.type, a.is_const);
1308 }
1310 
1311 #endif
llvm::BasicBlock * CKIRBasicBlockObs
Definition: ckir.hpp:97
llvm::Type * CKIRTypeObs
Definition: ckir.hpp:80
llvm::ConstantInt * CKIRConstantIntObs
Definition: ckir.hpp:91
llvm::AllocaInst * CKIRAllocaInstObs
Definition: ckir.hpp:99
llvm::Module * CKIRModuleObs
Definition: ckir.hpp:93
llvm::LLVMContext & CKIRContextRef
Definition: ckir.hpp:78
llvm::Function * CKIRFunctionObs
Definition: ckir.hpp:95
llvm::Constant * CKIRConstantObs
Definition: ckir.hpp:90
llvm::FunctionType * CKIRFunctionTypeObs
Definition: ckir.hpp:82
llvm::APInt CKIRAPInt
Definition: ckir.hpp:76
CKIRBuilder * CKIRBuilderObs
Definition: ckir.hpp:103
llvm::StructType * CKIRStructTypeObs
Definition: ckir.hpp:81
llvm::Value * CKIRValueObs
Definition: ckir.hpp:86
CKIRBuilder & CKIRBuilderRef
Definition: ckir.hpp:102
std::vector< CKFunctionFormalPack > CKFunctionFormalPackArray
Temporary array of additional function argument descriptors (CKFunctionFormalPack)
Definition: cktables.hpp:891
const CKConstant * CKConstantConstObs
Pointer to an enumeration constant descriptor (CKConstant)
Definition: cktables.hpp:580
CKEnumType * CKEnumTypeObs
Enumeration type descriptor (CKEnumType)
Definition: cktables.hpp:686
const CKTypedef * CKTypedefConstObs
Typedef descriptor (CKTypedef)
Definition: cktables.hpp:786
const CIAbstractType * CKTypeObs
Pointer to a type descriptor (CIAbstractType)
Definition: cktables.hpp:29
unsigned loc_t
Line number in the compiled source file.
Definition: cktables.hpp:24
std::vector< CKConstantConstObs > CKConstantObsVector
Temporary vector of enumeration constant descriptors (CKConstantConstObs)
Definition: cktables.hpp:585
std::vector< CKStructItem > CKStructItemArray
A temporary array of struct element descriptors (CKStructItem)
Definition: cktables.hpp:535
std::optional< CIName > CINameOpt
Optional (function argument) name.
Definition: cktables.hpp:855
std::vector< CKTypeObs > CKTypeObsArray
Array of (function argument) type descriptors (CKTypeObs)
Definition: cktables.hpp:620
CKAbstractNamed * CKNamedObs
Pointer to a named-object (constant, variable, or function) descriptor (CKAbstractNamed)
Definition: cktables.hpp:756
std::string CIName
Identifier as represented in the attribute of a IDF/TYPEIDF token.
Definition: cktables.hpp:138
Abstract type descriptor.
Definition: cktables.hpp:281
virtual bool is_bool() const
Built-in "_Bool" type.
Definition: cktables.hpp:298
virtual bool is_struct() const
Struct type.
Definition: cktables.hpp:305
virtual bool is_char() const
Built-in "char" type.
Definition: cktables.hpp:299
virtual CKStructElementSafeObs find_struct_element(const CIName &) const
Find a struct type element by name.
Definition: cktables.hpp:341
virtual CKTypeSafeObs get_array_element_type() const
The element type of an array.
Definition: cktables.hpp:332
virtual bool is_pointer() const
Pointer type.
Definition: cktables.hpp:304
virtual CKTypeSafeObs get_function_arg_type(std::size_t ix) const
The selected argument type of a function type.
Definition: cktables.hpp:321
virtual bool is_void() const
Built-in "void" type.
Definition: cktables.hpp:297
virtual CKTypeRefSafePack get_pointer_points_to() const
The (optionally const) type a pointer type points to.
Definition: cktables.hpp:312
virtual bool is_array() const
Array type.
Definition: cktables.hpp:302
virtual CKIRTypeObs get_ir() const =0
Get LLVM type descriptor.
virtual std::size_t get_function_arg_count() const
The number of arguments of a function type.
Definition: cktables.hpp:323
virtual bool is_function() const
Function type.
Definition: cktables.hpp:303
virtual bool is_function_variadic() const
Check whether a function type is variadic.
Definition: cktables.hpp:325
virtual bool is_enum() const
Enumeration type.
Definition: cktables.hpp:301
virtual CKTypeSafeObs get_function_return_type() const
The return type of a function type.
Definition: cktables.hpp:319
virtual CKIRConstantIntObs get_array_size() const
The size of an array.
Definition: cktables.hpp:334
virtual CKIRConstantObs get_null_value() const
Get LLVM null value.
virtual bool is_int() const
Built-in "int" type.
Definition: cktables.hpp:300
The common base for all named objects.
Definition: cktables.hpp:191
const CIName & get_name() const
The name of the object.
Definition: cktables.hpp:200
Abstract named-object (constant, variable, or function) descriptor.
Definition: cktables.hpp:716
virtual bool is_var() const
Global or local variable.
Definition: cktables.hpp:729
virtual bool is_function() const
Function.
Definition: cktables.hpp:731
virtual CKTypeSafeObs get_type() const =0
Type of the named object.
virtual CKIRValueObs get_ir() const
The address of a variable, the value of a constant.
Definition: cktables.hpp:749
virtual bool is_constant() const
Enumeration constant.
Definition: cktables.hpp:733
virtual CKIRFunctionObs get_function_ir() const
The address of a function.
Definition: cktables.hpp:751
virtual bool is_const() const
Optional "const" flag on a variable.
Definition: cktables.hpp:742
Array type descriptor.
Definition: cktables.hpp:468
The built-in "_Bool" type.
Definition: cktables.hpp:378
The built-in "char" type.
Definition: cktables.hpp:396
Enumeration constant descriptor.
Definition: cktables.hpp:791
CKIRConstantIntObs get_constant_value() const
LLVM value of the enumeration constant.
Definition: cktables.hpp:807
Enumeration type descriptor.
Definition: cktables.hpp:588
bool is_defined() const
Check whether the type is already defined.
Definition: cktables.hpp:604
Function type descriptor.
Definition: cktables.hpp:623
Function descriptor.
Definition: cktables.hpp:894
Global variable descriptor.
Definition: cktables.hpp:837
The built-in "int" type.
Definition: cktables.hpp:417
Local variable descriptor.
Definition: cktables.hpp:991
Pointer type descriptor.
Definition: cktables.hpp:438
Struct element descriptor.
Definition: cktables.hpp:499
const CKTypeRefPack & get_type_pack() const
The (optionally const) type of a struct element.
Definition: cktables.hpp:510
unsigned int get_idx() const
LLVM index of a struct element.
Definition: cktables.hpp:512
Struct type descriptor.
Definition: cktables.hpp:538
bool is_defined() const
Check whether the struct type is already defined.
Definition: cktables.hpp:555
Typedef descriptor.
Definition: cktables.hpp:761
CKTypeRefSafePack get_type_pack() const
The type and the optional "const" represented by the typedef.
Definition: cktables.hpp:776
Common base of variable descriptors.
Definition: cktables.hpp:818
virtual bool is_const() const override
Optional "const" flag on a variable.
Definition: cktables.hpp:827
virtual bool is_var() const override
Global or local variable.
Definition: cktables.hpp:825
virtual CKTypeSafeObs get_type() const override
Type of the named object.
Definition: cktables.hpp:826
The built-in "void" type.
Definition: cktables.hpp:358
Semantic layer of compiler context.
Definition: cktables.hpp:1101
CKNamedSafeObs find(const CIName &n)
Find a named (constant, variable, or function) object.
void exit_function()
Signalize exiting of the compound statement of the definition of a function.
CKPtrTypeSafeObs get_pointer_type(const CKTypeRefPack &pack)
A pointer type descriptor.
Definition: cktables.hpp:1138
CKCharTypeSafeObs get_char_type() const
The built-in "char" type descriptor.
Definition: cktables.hpp:1129
CKTypedefConstSafeObs define_typedef(const CIName &name, const CKTypeRefPack &type_pack, loc_t loc)
Define a typedef.
CKIRBasicBlockObs create_basic_block(const std::string &name)
Create a new basic block in the current function.
Definition: cktables.hpp:1242
CKEnumTypeSafeObs declare_enum_type(const CIName &n, loc_t loc)
Reference or declare an enum type.
CKTypedefConstSafeObs find_typedef(const CIName &n) const
Find a typedef.
CKTypeSafeObs current_function_return_type()
The return type of the current function.
CKFunctionTypeSafeObs get_function_type(CKTypeObs ret_type, CKTypeObsArray arg_types, bool variadic=false)
A function type descriptor.
CKBoolTypeSafeObs get_bool_type() const
The built-in "_Bool" type descriptor.
Definition: cktables.hpp:1127
CKIntTypeSafeObs get_int_type() const
The built-in "int" type descriptor.
Definition: cktables.hpp:1131
CKStructTypeSafeObs declare_struct_type(const CIName &n, loc_t loc)
Reference or declare a struct type.
CKEnumTypeSafeObs define_enum_type_open(const CIName &n, loc_t loc)
Signalize entering the definition of the enum type named n.
CKIRBuilderObs builder()
The active builder for the currently open basic block (or inactive)
Definition: cktables.hpp:1254
CKIRConstantIntObs get_int8_constant(std::int_fast32_t v)
LLVM constant of type "char".
Definition: cktables.hpp:1226
CKIRTypeObs get_ir_int64()
LLVM representation of C-types "int64_t" and "uint64_t".
Definition: cktables.hpp:1216
CKArrayTypeSafeObs get_array_type(CKTypeObs element_type, CKIRConstantIntObs size)
An array type descriptor.
void define_enum_type_close(CKEnumTypeObs type, CKConstantObsVector items)
Signalize exiting the definition of the enum type type.
void define_var(const CIName &name, const CKTypeRefPack &type_pack, loc_t loc)
Define a global or local variable.
void enter_function(CKFunctionObs f, CKFunctionFormalPackArray pack, loc_t loc)
Signalize entering of the compound statement of the definition of the function f.
CKFunctionSafeObs declare_function(const CIName &n, CKTypeObs type, loc_t loc)
Declare a function (with or without body)
CKConstantConstSafeObs define_constant(const CIName &name, CKIRConstantIntObs value, loc_t loc)
Define an enumeration constant.
CKVoidTypeSafeObs get_void_type() const
The built-in "void" type descriptor.
Definition: cktables.hpp:1125
void define_struct_type_close(CKStructTypeObs type, const CKStructItemArray &items)
Signalize exiting the definition of the struct type type.
void exit_block()
Signalize exiting of a compound statement other than a function definition.
CKStructTypeSafeObs define_struct_type_open(const CIName &n, loc_t loc)
Signalize entering the definition of the struct type named n.
bool is_typedef(const CIName &n) const
Check whether the name is a typedef (for the lexer)
CKIRConstantIntObs get_int32_constant(std::int_fast32_t v)
LLVM constant of type "int".
Definition: cktables.hpp:1232
CKIRConstantIntObs get_type_size(CKTypeObs type) const
Size of a type in bytes.
Definition: cktables.hpp:1264
void enter_block()
Signalize entering of a compound statement other than a function definition.
Temporary additional function argument descriptor.
Definition: cktables.hpp:858
loc_t loc
Definition line number.
Definition: cktables.hpp:868
CKFunctionFormalPack(CINameOpt nm, bool c, loc_t loc)
Construct from arguments.
Definition: cktables.hpp:860
bool is_const
Optional "const" flag.
Definition: cktables.hpp:866
CINameOpt name
Optional name of the argument.
Definition: cktables.hpp:864
Temporary struct element descriptor.
Definition: cktables.hpp:521
CKTypeRefPack pack
The (optionally const) type of a struct element.
Definition: cktables.hpp:527
CKStructItem(const CKTypeRefPack &p, CIName nm, loc_t l)
Construct from arguments.
Definition: cktables.hpp:523
loc_t loc
Definition line number.
Definition: cktables.hpp:531
CIName name
Name of a struct element.
Definition: cktables.hpp:529
Type descriptor with optional "const" flag.
Definition: cktables.hpp:240
bool is_const
Indicates the presence of the const flag.
Definition: cktables.hpp:252
CKTypeRefPack(CKTypeObs t, bool is_c)
Construct from the arguments.
Definition: cktables.hpp:248
CKTypeRefPack()
Construct as null.
Definition: cktables.hpp:243
CKTypeObs type
The type.
Definition: cktables.hpp:251
Type descriptor with optional "const" flag.
Definition: cktables.hpp:256
CKTypeRefSafePack(const CKTypeRefPack &tp)
Convert from unsafe pack.
Definition: cktables.hpp:268
CKTypeRefSafePack(CKTypeObs t, bool is_c)
Construct from the arguments.
Definition: cktables.hpp:264
bool is_const
Indicates the presence of the const flag.
Definition: cktables.hpp:277
CKTypeRefSafePack()
Construct as null.
Definition: cktables.hpp:259
CKTypeSafeObs type
The type.
Definition: cktables.hpp:276