9#include <fe/container.h>
13#include <fe/profile.h>
23namespace fs = std::filesystem;
28using Keys = fe::SymTab<ast::Tok::Tag, ast::Num_Keys + ast::Num_Subst>;
44 static bool claim(
const Driver&, Sym sym, uint32_t gid);
51class Diag :
public fe::CodeDiag {
56 std::string
render(
const std::function<std::string()>&)
const override;
68 Driver(std::string name = {});
79 fe::Log&
log() {
return log_; }
80 const fe::Log&
log()
const {
return log_; }
82 const fe::Profiler&
profiler()
const {
return profiler_; }
115 if (std::error_code ec; fs::is_directory(path, ec)) paths_.insert(insert_, std::move(path));
119 void seal() { insert_ = paths_.begin(); }
121 auto begin()
const {
return paths_.cbegin(); }
122 auto end()
const {
return paths_.cend(); }
125 std::list<fs::path> paths_;
126 std::list<fs::path>::iterator insert_ = paths_.end();
144 fe::Vector<fs::path>
rt_paths()
const;
161 const auto&
entries()
const {
return entries_; }
166 auto begin()
const {
return entries_.cbegin(); }
167 auto end()
const {
return entries_.cend(); }
174 std::deque<Entry> entries_;
188 void load(std::string_view name, Loc loc = {});
192 static std::string
plugin_name(std::string_view name);
193 bool is_loaded(std::string_view name)
const {
return fe::lookup(plugins_, name); }
197 auto loaded = fe::lookup(plugins_, name);
198 return loaded && !loaded->dir.empty() ? &loaded->dir :
nullptr;
200 void*
get_fun_ptr(std::string_view plugin,
const char* name);
204 return reinterpret_cast<F*
>(
get_fun_ptr(plugin, name));
212 const auto&
phases()
const {
return phases_; }
221 void add_arg(std::string_view plugin, std::string arg) { plugin_args_[plugin].emplace_back(std::move(arg)); }
223 const fe::Vector<std::string>&
args(std::string_view plugin)
const;
225 std::optional<nat_t>
arg_nat(std::string_view plugin, std::string_view key);
239 fe::View<PluginSym> syms;
243 fe::StrMap<Loaded> plugins_;
247 mutable Names names_;
248 fe::Profiler profiler_;
250 std::unique_ptr<World> library_;
251 Paths plugin_dirs_, import_dirs_, prefixes_;
254 fe::StrMap<fe::Vector<std::string>> plugin_args_;
255 std::vector<std::pair<std::string, fe::View<PluginArg>>> known_args_;
256 std::vector<std::pair<std::string, fe::View<PluginEnv>>> known_envs_;
261#define GET_FUN_PTR(plugin, f) get_fun_ptr<decltype(f)>(plugin, #f)
Diag(const Driver &driver)
std::string render(const std::function< std::string()> &) const override
void add(const fe::Src *src, Sym, ast::Tok::Tag, bool path)
Remembers the directive that pulled in src; a repeated import of the same file adds nothing.
const auto & entries() const
bool path
The directive spelled a path (import "a/b.mim") rather than a name.
An ordered list of directories.
void seal()
Later Paths::add calls insert in front of everything added so far.
Some "global" variables needed all over the place.
const auto & known_envs() const
The PluginEnvs each loaded Plugin declares, in load order; only for listing them, see PluginEnv.
void add_prefix_path(fs::path path)
const Imports & imports() const
auto get_fun_ptr(std::string_view plugin, const char *name)
Driver(std::string name={})
void load(std::string_view name, Loc loc={})
static std::string plugin_name(std::string_view name)
Bare plugin name of a possibly path-qualified name: foo/libmim_bar.so → bar.
void add_import_path(fs::path path)
const Version & version() const
MimIR Version.
const auto & known_args() const
The PluginArgs each loaded Plugin declares, in load order; only for listing them, see PluginArg.
auto normalizer(plugin_t d, tag_t t, sub_t s) const
const Flags & flags() const
fe::Vector< fs::path > import_paths() const
Where ast::Parser looks for <name>.mim; plugin directories are included, as a plugin ships both halve...
bool is_loaded(std::string_view name) const
Driver & operator=(Driver)=delete
const fe::Profiler & profiler() const
const fs::path * plugin_dir(std::string_view name) const
Directory the Plugin was loaded from, so that its <name>.mim half cannot come from elsewhere.
const World * library() const
void add_arg(std::string_view plugin, std::string arg)
auto normalizer(flags_t flags) const
fe::Vector< fs::path > rt_paths() const
Where a backend looks for its runtime modules.
World * library()
nullptr before move_to_library().
static void add_static_plugin(const char *name, Plugin(*get_plugin)())
Makes a Plugin linked into this binary available to Driver::load under name; see cmake/Mim....
Driver(const Driver &)=delete
void move_to_library(World &world)
Moves everything of world into library() and imports only its externals back.
const fe::Vector< std::string > & args(std::string_view plugin) const
Yields an empty fe::Vector if plugin has none.
void add_plugin_path(fs::path path)
fe::Vector< fs::path > plugin_paths() const
Where Driver::load looks for libmim_<name>.
fe::SymMap< u32 > sym2gid
void * get_fun_ptr(std::string_view plugin, const char *name)
fe::Profiler & profiler()
const auto & phases() const
const Keys & keys() const
Interned once here: every ast::Lexer borrows them.
auto phase(flags_t flags)
const fe::Log & log() const
std::optional< nat_t > arg_nat(std::string_view plugin, std::string_view key)
The number passed as -X <plugin>:<key>=<n>, if any; warns about and ignores a non-number.
PlainNames(const Driver *driver)
Activates plain naming on driver until this guard dies; a null driver leaves it off.
static bool claim(const Driver &, Sym sym, uint32_t gid)
Registers that gid renders as sym and reports whether the plain sym may be used.
The World represents the whole program and manages creation of MimIR nodes (Defs).
ankerl::unordered_dense::map< flags_t, NormalizeFn > Normalizers
fe::SymTab< ast::Tok::Tag, ast::Num_Keys+ast::Num_Subst > Keys
The reserved words the ast::Lexer looks up, keyed by the Sym it has just interned.
ankerl::unordered_dense::map< flags_t, std::function< std::unique_ptr< Phase >(World &)> > Flags2Phases
Maps an axiom of a Phase to a function that creates one.
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.
Compiler switches that must be saved and looked up in later phases of compilation.
std::unique_ptr< void, void(*)(void *)> Handle