summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/ast/crate.cpp16
-rw-r--r--src/ast/crate.hpp1
-rw-r--r--src/ast/dump.cpp9
-rw-r--r--src/hir/from_ast.cpp7
-rw-r--r--src/main.cpp11
-rw-r--r--src/resolve/absolute.cpp1
-rw-r--r--src/resolve/use.cpp4
-rw-r--r--src/trans/mangling.cpp22
8 files changed, 62 insertions, 9 deletions
diff --git a/src/ast/crate.cpp b/src/ast/crate.cpp
index d6992ca4..332ee2b8 100644
--- a/src/ast/crate.cpp
+++ b/src/ast/crate.cpp
@@ -52,13 +52,12 @@ Crate::Crate():
void Crate::load_externs()
{
auto cb = [this](Module& mod) {
- for( const auto& it : mod.items() )
+ for( /*const*/ auto& it : mod.items() )
{
TU_IFLET(AST::Item, it.data, Crate, c,
- auto name = c.name;
if( check_item_cfg(it.data.attrs) )
{
- name = load_extern_crate( it.data.span, name );
+ c.name = load_extern_crate( it.data.span, c.name );
}
)
}
@@ -142,7 +141,10 @@ void Crate::load_externs()
}
// NOTE: Creating `ExternCrate` loads the crate from the specified path
- auto res = m_extern_crates.insert(::std::make_pair( name, ExternCrate { name, path } ));
+ auto ec = ExternCrate { name, path };
+ auto real_name = ec.m_hir->m_crate_name;
+ assert(!real_name.empty());
+ auto res = m_extern_crates.insert(::std::make_pair( real_name, mv$(ec) ));
if( !res.second ) {
// Crate already loaded?
}
@@ -164,9 +166,8 @@ void Crate::load_externs()
}
}
- assert(!ext_crate.m_hir->m_crate_name.empty());
- DEBUG("Loaded '" << name << "' from '" << basename << "' (actual name is '" << ext_crate.m_hir->m_crate_name << "')");
- return ext_crate.m_hir->m_crate_name;
+ DEBUG("Loaded '" << name << "' from '" << basename << "' (actual name is '" << real_name << "')");
+ return real_name;
}
ExternCrate::ExternCrate(const ::std::string& name, const ::std::string& path):
@@ -177,6 +178,7 @@ ExternCrate::ExternCrate(const ::std::string& name, const ::std::string& path):
m_hir = HIR_Deserialise(path, name);
m_hir->post_load_update(name);
+ m_name = m_hir->m_crate_name;
}
void ExternCrate::with_all_macros(::std::function<void(const ::std::string& , const MacroRules&)> cb) const
diff --git a/src/ast/crate.hpp b/src/ast/crate.hpp
index 4fd5c421..1723868c 100644
--- a/src/ast/crate.hpp
+++ b/src/ast/crate.hpp
@@ -55,6 +55,7 @@ public:
LOAD_CORE,
LOAD_NONE,
} m_load_std = LOAD_STD;
+ ::std::string m_crate_name_suffix;
::std::string m_crate_name;
AST::Path m_prelude_path;
diff --git a/src/ast/dump.cpp b/src/ast/dump.cpp
index 363123fa..7026f61d 100644
--- a/src/ast/dump.cpp
+++ b/src/ast/dump.cpp
@@ -617,6 +617,15 @@ void RustPrinter::handle_module(const AST::Module& mod)
for( const auto& item : mod.items() )
{
+ if( !item.data.is_Crate() ) continue ;
+ const auto& e = item.data.as_Crate();
+
+ print_attrs(item.data.attrs);
+ m_os << indent() << "extern crate \"" << e.name << "\" as " << item.name << ";\n";
+ }
+
+ for( const auto& item : mod.items() )
+ {
if( !item.data.is_ExternBlock() ) continue ;
const auto& e = item.data.as_ExternBlock();
diff --git a/src/hir/from_ast.cpp b/src/hir/from_ast.cpp
index 50e4a290..1f5c473b 100644
--- a/src/hir/from_ast.cpp
+++ b/src/hir/from_ast.cpp
@@ -1550,6 +1550,11 @@ public:
if(crate.m_crate_type != ::AST::Crate::Type::Executable)
{
rv.m_crate_name = crate.m_crate_name;
+ if(crate.m_crate_name_suffix != "")
+ {
+ rv.m_crate_name += "-";
+ rv.m_crate_name += crate.m_crate_name_suffix;
+ }
}
g_crate_ptr = &rv;
@@ -1625,7 +1630,7 @@ public:
}
path_Sized = rv.get_lang_item_path(sp, "sized");
- rv.m_root_module = LowerHIR_Module( crate.m_root_module, ::HIR::ItemPath(crate.m_crate_name) );
+ rv.m_root_module = LowerHIR_Module( crate.m_root_module, ::HIR::ItemPath(rv.m_crate_name) );
LowerHIR_Module_Impls(crate.m_root_module, rv);
diff --git a/src/main.cpp b/src/main.cpp
index fb229a0c..20c525d5 100644
--- a/src/main.cpp
+++ b/src/main.cpp
@@ -150,6 +150,7 @@ struct ProgramParams
::AST::Crate::Type crate_type = ::AST::Crate::Type::Unknown;
::std::string crate_name;
+ ::std::string crate_name_suffix;
unsigned opt_level = 0;
bool emit_debug_info = false;
@@ -219,6 +220,7 @@ int main(int argc, char *argv[])
return Parse_Crate(params.infile);
});
crate.m_test_harness = params.test_harness;
+ crate.m_crate_name_suffix = params.crate_name_suffix;
if( params.last_stage == ProgramParams::STAGE_PARSE ) {
return 0;
@@ -725,6 +727,15 @@ ProgramParams::ProgramParams(int argc, char *argv[])
auto path = ::std::string(pos+1);
this->crate_overrides.insert(::std::make_pair( mv$(name), mv$(path) ));
}
+ // --crate-tag <name> >> Specify a version/identifier suffix for the crate
+ else if( strcmp(arg, "--crate-tag") == 0 ) {
+ if( i == argc - 1 ) {
+ ::std::cerr << "Flag " << arg << " requires an argument" << ::std::endl;
+ exit(1);
+ }
+ const char* name_str = argv[++i];
+ this->crate_name_suffix = name_str;
+ }
// --crate-name <name> >> Specify the crate name (overrides `#![crate_name="<name>"]`)
else if( strcmp(arg, "--crate-name") == 0 ) {
if( i == argc - 1 ) {
diff --git a/src/resolve/absolute.cpp b/src/resolve/absolute.cpp
index cee4df7e..8b5732a8 100644
--- a/src/resolve/absolute.cpp
+++ b/src/resolve/absolute.cpp
@@ -785,6 +785,7 @@ namespace {
void Resolve_Absolute_Path_BindAbsolute__hir_from(Context& context, const Span& sp, Context::LookupMode& mode, ::AST::Path& path, const AST::ExternCrate& crate, unsigned int start)
{
+ assert(crate.m_hir->m_crate_name == crate.m_name);
TRACE_FUNCTION_FR( crate.m_hir->m_crate_name << " - " << path << " start=" << start, path);
auto& path_abs = path.m_class.as_Absolute();
diff --git a/src/resolve/use.cpp b/src/resolve/use.cpp
index 2b02fc0d..01a5d22c 100644
--- a/src/resolve/use.cpp
+++ b/src/resolve/use.cpp
@@ -314,6 +314,7 @@ void Resolve_Use_Mod(const ::AST::Crate& crate, ::AST::Module& mod, ::AST::Path
),
(Crate,
if( allow != Lookup::Value )
+ ASSERT_BUG(span, crate.m_extern_crates.count(e.name), "Crate '" << e.name << "' not loaded");
return ::AST::PathBinding::make_Crate({ &crate.m_extern_crates.at(e.name) });
),
(Type,
@@ -669,9 +670,11 @@ namespace {
),
// TODO: What happens if these two refer to an enum constructor?
(StructConstant,
+ ASSERT_BUG(span, crate.m_extern_crates.count(e.ty.m_crate_name), "Crate '" << e.ty.m_crate_name << "' not loaded for " << e.ty);
return ::AST::PathBinding::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(span, e.ty, true).as_Struct() });
),
(StructConstructor,
+ ASSERT_BUG(span, crate.m_extern_crates.count(e.ty.m_crate_name), "Crate '" << e.ty.m_crate_name << "' not loaded for " << e.ty);
return ::AST::PathBinding::make_Struct({ nullptr, &crate.m_extern_crates.at(e.ty.m_crate_name).m_hir->get_typeitem_by_path(span, e.ty, true).as_Struct() });
),
(Function,
@@ -700,6 +703,7 @@ namespace {
if( path.m_class.is_Absolute() && path.m_class.as_Absolute().crate != "" ) {
const auto& path_abs = path.m_class.as_Absolute();
+ ASSERT_BUG(span, crate.m_extern_crates.count(path_abs.crate), "Crate '" << path_abs.crate << "' not loaded");
return Resolve_Use_GetBinding__ext(span, crate, path, crate.m_extern_crates.at( path_abs.crate ), 0, allow);
}
diff --git a/src/trans/mangling.cpp b/src/trans/mangling.cpp
index 0f3acfd9..78409827 100644
--- a/src/trans/mangling.cpp
+++ b/src/trans/mangling.cpp
@@ -54,7 +54,27 @@ namespace {
::FmtLambda Trans_Mangle(const ::HIR::SimplePath& path)
{
return FMT_CB(ss,
- ss << "_ZN" << path.m_crate_name.size() << path.m_crate_name;
+ ss << "_ZN";
+ {
+ ::std::string cn;
+ for(auto c : path.m_crate_name)
+ {
+ if(c == '-') {
+ cn += "$$";
+ }
+ else if( ('0' <= c && c <= '9')
+ || ('A' <= c && c <= 'Z')
+ || ('a' <= c && c <= 'z')
+ || c == '_'
+ )
+ {
+ cn += c;
+ }
+ else {
+ }
+ }
+ ss << cn.size() << cn;
+ }
for(const auto& comp : path.m_components) {
auto v = escape_str(comp);
ss << v.size() << v;