MimIR
MimIR is my Intermediate Representation
Loading...
Searching...
No Matches
driver.h
Go to the documentation of this file.
1#pragma once
2
3#include <list>
4#include <utility>
5
6#include <absl/container/node_hash_map.h>
7
8#include "mim/flags.h"
9#include "mim/plugin.h"
10#include "mim/world.h"
11
12#include "mim/ast/tok.h"
13#include "mim/util/log.h"
14
15namespace mim {
16
17/// Some "global" variables needed all over the place.
18/// Well, there are not really global - that's the point of this class.
19class Driver : public fe::SymPool {
20public:
21 /// @name Construction
22 ///@{
23 Driver(std::string name);
25 : Driver(std::string{}) {}
26
27 Driver(const Driver&) = delete;
28 Driver(Driver&&) = delete;
30 ///@}
31
32 /// @name Getters
33 ///@{
34 Flags& flags() { return flags_; }
35 const Flags& flags() const { return flags_; }
36 Log& log() const { return log_; }
37 World& world() { return world_; }
38 const Version& version() const { return version_; } ///< MimIR Version.
39 ///@}
40
41 /// @name Manage Search Paths
42 /// Search paths for plugins are in the following order:
43 /// 1. The empty path. Used as prefix to look into current working directory without resorting to an absolute path.
44 /// 2. All further user-specified paths via Driver::add_search_path; paths added first will also be searched first.
45 /// 3. All paths specified in the environment variable `MIM_PLUGIN_PATH`.
46 /// 4. The path derived from the location of `libmim` (`<libmim>/mim`)
47 /// 5. `CMAKE_INSTALL_PREFIX/lib/mim`
48 ///@{
49 const auto& search_paths() const { return search_paths_; }
50 void add_search_path(fs::path path) {
51 if (fs::exists(path) && fs::is_directory(path)) search_paths_.insert(insert_, std::move(path));
52 }
53 ///@}
54
55 /// @name Manage Imports
56 /// This tracks:
57 /// 1. The distinct files that have already been parsed to avoid reparsing them,
58 /// 2. The distinct import or plugin directives that should be emitted again later.
59 ///@{
60 class Imports {
61 public:
62 struct Entry {
63 fs::path path;
64 Sym sym;
66 };
67
68 Imports(Driver& driver)
69 : driver_(driver) {}
70
71 /// @name Get imports
72 ///@{
73 const auto& entries() const { return entries_; }
74 ///@}
75
76 /// @name Iterators
77 ///@{
78 auto begin() const { return entries_.cbegin(); }
79 auto end() const { return entries_.cend(); }
80 ///@}
81
82 /// Remembers an import or plugin directive and reports whether the resolved file is new.
83 std::pair<const fs::path*, bool> add(fs::path, Sym, ast::Tok::Tag);
84
85 private:
86 Driver& driver_;
87 std::deque<Entry> entries_;
88 std::deque<fs::path> parsed_paths_;
89 };
90
91 const Imports& imports() const { return imports_; }
92 Imports& imports() { return imports_; }
93 ///@}
94
95 /// @name Load Plugin
96 /// Finds and loads a shared object file that implements the MimIR Plugin @p name.
97 /// If \a name is an absolute path to a `.so`/`.dll` file, this is used.
98 /// Otherwise, "name", "libmim_name.so" (Linux, Mac), "mim_name.dll" (Win)
99 /// are searched for in Driver::search_paths().
100 ///@{
101 void load(Sym name);
102 void load(const std::string& name) { return load(sym(name)); }
103 bool is_loaded(Sym sym) const { return lookup(plugins_, sym); }
104 void* get_fun_ptr(Sym plugin, const char* name);
105
106 template<class F>
107 auto get_fun_ptr(Sym plugin, const char* name) {
108 return reinterpret_cast<F*>(get_fun_ptr(plugin, name));
109 }
110
111 template<class F>
112 auto get_fun_ptr(const char* plugin, const char* name) {
113 return get_fun_ptr<F>(sym(plugin), name);
114 }
115 ///@}
116
117 /// @name Manage Plugins
118 /// All these lookups yield `nullptr` if the key has not been found.
119 ///@{
120 auto stage(flags_t flags) { return lookup(stages_, flags); }
121 const auto& stages() const { return stages_; }
122 auto normalizer(flags_t flags) const { return lookup(normalizers_, flags); }
123 auto normalizer(plugin_t d, tag_t t, sub_t s) const { return normalizer(Annex::flags(d, t, s)); }
124 ///@}
125
126private:
127 // This must go *first* so plugins will be unloaded *last* in the d'tor; otherwise funny things might happen ...
128 absl::node_hash_map<Sym, Plugin::Handle> plugins_;
129 Version version_;
130 Flags flags_;
131 mutable Log log_;
132 World world_;
133 std::list<fs::path> search_paths_;
134 std::list<fs::path>::iterator insert_ = search_paths_.end();
135 Flags2Stages stages_;
136 Normalizers normalizers_;
137 Imports imports_;
138};
139
140#define GET_FUN_PTR(plugin, f) get_fun_ptr<decltype(f)>(plugin, #f)
141
142} // namespace mim
auto end() const
Definition driver.h:79
Imports(Driver &driver)
Definition driver.h:68
auto begin() const
Definition driver.h:78
const auto & entries() const
Definition driver.h:73
std::pair< const fs::path *, bool > add(fs::path, Sym, ast::Tok::Tag)
Remembers an import or plugin directive and reports whether the resolved file is new.
Definition driver.cpp:14
const auto & stages() const
Definition driver.h:121
void load(Sym name)
Definition driver.cpp:76
const Imports & imports() const
Definition driver.h:91
void add_search_path(fs::path path)
Definition driver.h:50
Driver(std::string name)
Definition driver.cpp:47
const Version & version() const
MimIR Version.
Definition driver.h:38
auto normalizer(plugin_t d, tag_t t, sub_t s) const
Definition driver.h:123
World & world()
Definition driver.h:37
Log & log() const
Definition driver.h:36
const Flags & flags() const
Definition driver.h:35
bool is_loaded(Sym sym) const
Definition driver.h:103
Driver & operator=(Driver)=delete
void * get_fun_ptr(Sym plugin, const char *name)
Definition driver.cpp:122
auto normalizer(flags_t flags) const
Definition driver.h:122
Imports & imports()
Definition driver.h:92
Driver(const Driver &)=delete
void load(const std::string &name)
Definition driver.h:102
Flags & flags()
Definition driver.h:34
auto get_fun_ptr(Sym plugin, const char *name)
Definition driver.h:107
auto get_fun_ptr(const char *plugin, const char *name)
Definition driver.h:112
auto stage(flags_t flags)
Definition driver.h:120
Driver(Driver &&)=delete
const auto & search_paths() const
Definition driver.h:49
Facility to log what you are doing.
Definition log.h:18
The World represents the whole program and manages creation of MimIR nodes (Defs).
Definition world.h:36
Definition ast.h:14
u8 sub_t
Definition types.h:42
u64 flags_t
Definition types.h:39
auto lookup(const C &container, const K &key)
Yields pointer to element (or the element itself if it is already a pointer), if found and nullptr ot...
Definition util.h:99
absl::flat_hash_map< flags_t, std::function< std::unique_ptr< Stage >(World &)> > Flags2Stages
Maps an an axiom of a Stage to a function that creates one.
Definition plugin.h:25
absl::flat_hash_map< flags_t, NormalizeFn > Normalizers
Definition plugin.h:22
u64 plugin_t
Definition types.h:40
u8 tag_t
Definition types.h:41
Compiler switches that must be saved and looked up in later phases of compilation.
Definition flags.h:11
Definition span.h:122
static constexpr flags_t flags(plugin_t p, tag_t t, sub_t s=0)
Assembles the full flags from its plugin, tag, and sub fields.
Definition plugin.h:140