Joos1W Compiler Framework
All Classes Functions Typedefs Pages
CompilationUnit.h
1 #pragma once
2 
3 #include <string_view>
4 #include <unordered_map>
5 
6 #include "tir/Constant.h"
7 #include "tir/Context.h"
8 #include "utils/Generator.h"
9 
10 namespace tir {
11 
13 public:
14  CompilationUnit(Context& ctx);
15  CompilationUnit(const CompilationUnit&) = delete;
16  CompilationUnit(CompilationUnit&&) = delete;
17  CompilationUnit& operator=(const CompilationUnit&) = delete;
18  CompilationUnit& operator=(CompilationUnit&&) = delete;
19 
20  /**
21  * @brief Create a new function with the given type and name.
22  *
23  * @param type The type of the function
24  * @param name The name of the function
25  * @return Function* The function, or nullptr if it already exists
26  */
27  Function* CreateFunction(FunctionType* type, const std::string_view name) {
28  if(findFunction(std::string{name})) return nullptr;
29  auto* buf = ctx_.alloc().allocate_bytes(sizeof(Function), alignof(Function));
30  auto* func = new(buf) Function{ctx_, this, type, name};
31  globals_.emplace(name, func);
32  return func;
33  }
34 
35  /**
36  * @brief Create a new global variable with the given type and name.
37  *
38  * @param type
39  * @param name
40  * @return GlobalVariable*
41  */
42  GlobalVariable* CreateGlobalVariable(Type* type, const std::string_view name) {
43  if(findGlobalVariable(std::string{name})) return nullptr;
44  auto* buf = ctx_.alloc().allocate_bytes(sizeof(GlobalVariable),
45  alignof(GlobalVariable));
46  auto* gv = new(buf) GlobalVariable{ctx_, type};
47  globals_.emplace(name, gv);
48  return gv;
49  }
50 
51  /**
52  * @brief Get the function with the given name.
53  *
54  * @param name The name of the function
55  * @return Function* The function, or nullptr if it does not exist
56  */
57  Function* findFunction(const std::string_view name) {
58  auto it = globals_.find(std::string{name});
59  if(it == globals_.end()) return nullptr;
60  auto go = it->second;
61  return dyn_cast<Function>(go);
62  }
63 
64  /**
65  * @brief Find the global variable with the given name.
66  *
67  * @param name The name of the global variable
68  * @return GlobalVariable* The global variable, or nullptr if it does not exist
69  */
70  GlobalVariable* findGlobalVariable(const std::string_view name) {
71  auto it = globals_.find(std::string{name});
72  if(it == globals_.end()) return nullptr;
73  auto go = it->second;
74  return dyn_cast<GlobalVariable>(go);
75  }
76 
77  // Print the compilation unit to the given output stream.
78  std::ostream& print(std::ostream& os) const;
79  void dump() const;
80 
81  /// @brief Filters through the global objects and yields just the functions
83  for(auto& [name, func] : globals_) {
84  if(auto* f = dyn_cast<Function>(func)) co_yield f;
85  }
86  }
87 
88  /// @brief Yields all global objects in the compilation unit
90  for(auto& [name, go] : globals_) co_yield go;
91  }
92 
93  /// @brief Yields all global objects in the compilation unit
95  const {
96  for(auto& [name, go] : globals_) co_yield std::pair{name, go};
97  }
98 
99  /// @brief Get the context associated with this compilation unit
100  auto& ctx() { return ctx_; }
101 
102  /// @brief Filters through the global objects and yields just the variables
104  for(auto& [name, go] : globals_) {
105  if(auto* gv = dyn_cast<GlobalVariable>(go)) co_yield gv;
106  }
107  }
108 
109  /// @brief Remove the global object with the given name
110  void removeGlobalObject(std::string const& name) { globals_.erase(name); }
111 
112 public:
113  Function* builtinMalloc() { return findFunction("__malloc"); }
114  Function* builtinException() { return findFunction("__exception"); }
115 
116 private:
117  Context& ctx_;
118  std::pmr::unordered_map<std::string, GlobalObject*> globals_;
119 };
120 
121 } // namespace tir