diff options
author | John Hodge <tpg@ucc.asn.au> | 2018-06-03 14:57:05 +0800 |
---|---|---|
committer | John Hodge <tpg@ucc.asn.au> | 2018-06-03 14:57:05 +0800 |
commit | bf8f8b4b4a9fe273451be59f68acafbe61968b83 (patch) | |
tree | 82993550cb3c88de0edbd55d79e4ea8e8cefffac /tools/standalone_miri/module_tree.cpp | |
parent | 39b3cf53798683e496804f8322da2254b10850f4 (diff) | |
parent | a7fb27789a2b34543851d207120e2c0001ee9c27 (diff) | |
download | mrust-bf8f8b4b4a9fe273451be59f68acafbe61968b83.tar.gz |
Merge branch 'master' of https://github.com/thepowersgang/mrustc
Diffstat (limited to 'tools/standalone_miri/module_tree.cpp')
-rw-r--r-- | tools/standalone_miri/module_tree.cpp | 214 |
1 files changed, 108 insertions, 106 deletions
diff --git a/tools/standalone_miri/module_tree.cpp b/tools/standalone_miri/module_tree.cpp index 2513140a..8beba018 100644 --- a/tools/standalone_miri/module_tree.cpp +++ b/tools/standalone_miri/module_tree.cpp @@ -5,6 +5,7 @@ #include "lex.hpp" #include "value.hpp" #include <iostream> +#include <algorithm> // std::find #include "debug.hpp" ModuleTree::ModuleTree() @@ -31,18 +32,19 @@ struct Parser RawType parse_core_type(); ::HIR::TypeRef parse_type(); ::HIR::GenericPath parse_tuple(); + + const DataType* get_composite(::HIR::GenericPath gp); }; void ModuleTree::load_file(const ::std::string& path) { if( !loaded_files.insert(path).second ) { - ::std::cout << "DEBUG: load_file(" << path << ") - Already loaded" << ::std::endl; + LOG_DEBUG("load_file(" << path << ") - Already loaded"); return ; } - ::std::cout << "DEBUG: load_file(" << path << ")" << ::std::endl; - //TRACE_FUNCTION_F(path); + TRACE_FUNCTION_R(path, ""); auto parse = Parser { *this, path }; while(parse.parse_one()) @@ -53,8 +55,8 @@ void ModuleTree::load_file(const ::std::string& path) // Parse a single item from a .mir file bool Parser::parse_one() { - //::std::cout << "DEBUG: parse_one" << ::std::endl; - if( lex.next() == "" ) // EOF? + //TRACE_FUNCTION_F(""); + if( lex.next() == TokenClass::Eof ) { return false; } @@ -65,7 +67,7 @@ bool Parser::parse_one() lex.check(TokenClass::String); auto path = ::std::move(lex.next().strval); lex.consume(); - //::std::cout << "DEBUG: parse_one - crate '" << path << "'" << ::std::endl; + //LOG_TRACE(lex << "crate '" << path << "'"); lex.check_consume(';'); @@ -75,7 +77,7 @@ bool Parser::parse_one() else if( lex.consume_if("fn") ) { auto p = parse_path(); - //::std::cout << "DEBUG: parse_one - fn " << p << ::std::endl; + //LOG_TRACE(lex << "fn " << p); lex.check_consume('('); ::std::vector<::HIR::TypeRef> arg_tys; @@ -91,7 +93,7 @@ bool Parser::parse_one() { rv_ty = parse_type(); } - + if( lex.consume_if('=') ) { auto link_name = ::std::move(lex.check_consume(TokenClass::String).strval); @@ -99,6 +101,7 @@ bool Parser::parse_one() auto abi = ::std::move(lex.check_consume(TokenClass::String).strval); lex.check_consume(';'); + LOG_DEBUG(lex << "extern fn " << p); auto p2 = p; tree.functions.insert( ::std::make_pair(::std::move(p), Function { ::std::move(p2), ::std::move(arg_tys), rv_ty, {link_name, abi}, {} }) ); } @@ -106,6 +109,7 @@ bool Parser::parse_one() { auto body = parse_body(); + LOG_DEBUG(lex << "fn " << p); auto p2 = p; tree.functions.insert( ::std::make_pair(::std::move(p), Function { ::std::move(p2), ::std::move(arg_tys), rv_ty, {}, ::std::move(body) }) ); } @@ -113,13 +117,22 @@ bool Parser::parse_one() else if( lex.consume_if("static") ) { auto p = parse_path(); - //::std::cout << "DEBUG: parse_one - static " << p << ::std::endl; + //LOG_TRACE(lex << "static " << p); lex.check_consume(':'); auto ty = parse_type(); // TODO: externs? lex.check_consume('='); lex.check(TokenClass::String); auto data = ::std::move(lex.consume().strval); + + Static s; + s.val = Value(ty); + // - Statics need to always have an allocation (for references) + if( !s.val.allocation ) + s.val.create_allocation(); + s.val.write_bytes(0, data.data(), data.size()); + s.ty = ty; + if( lex.consume_if('{') ) { while( !lex.consume_if('}') ) @@ -134,15 +147,20 @@ bool Parser::parse_one() if( lex.next() == TokenClass::String ) { auto reloc_str = ::std::move(lex.consume().strval); - // TODO: Add relocation + + auto a = Allocation::new_alloc( reloc_str.size() ); + //a.alloc().set_tag(); + a->write_bytes(0, reloc_str.data(), reloc_str.size()); + s.val.allocation->relocations.push_back({ ofs, /*size,*/ RelocationPtr::new_alloc(::std::move(a)) }); } - else if( lex.next() == "::" ) + else if( lex.next() == "::" || lex.next() == "<" ) { auto reloc_path = parse_path(); - // TODO: Add relocation + s.val.allocation->relocations.push_back({ ofs, /*size,*/ RelocationPtr::new_fcn(reloc_path) }); } else { + LOG_FATAL(lex << "Unexepcted token " << lex.next() << " in relocation value"); throw "ERROR"; } if( ! lex.consume_if(',') ) { @@ -153,15 +171,13 @@ bool Parser::parse_one() } lex.check_consume(';'); - Value val = Value(ty); - val.write_bytes(0, data.data(), data.size()); - - tree.statics.insert(::std::make_pair( ::std::move(p), ::std::move(val) )); + LOG_DEBUG(lex << "static " << p); + tree.statics.insert(::std::make_pair( ::std::move(p), ::std::move(s) )); } else if( lex.consume_if("type") ) { auto p = (lex.consume_if('(')) ? parse_tuple() : parse_genericpath(); - //::std::cout << "DEBUG: parse_one - type " << p << ::std::endl; + //LOG_TRACE("type " << p); auto rv = DataType {}; rv.my_path = p; @@ -206,7 +222,7 @@ bool Parser::parse_one() lex.check_consume('='); auto ty = parse_type(); lex.check_consume(';'); - //::std::cout << ofs << " " << ty << ::std::endl; + //LOG_DEBUG(ofs << " " << ty); rv.fields.push_back(::std::make_pair(ofs, ::std::move(ty))); } @@ -250,7 +266,7 @@ bool Parser::parse_one() //const auto* tag_ty = &rv.fields.at(base_idx).second; //for(auto idx : other_idx) //{ - // assert(tag_ty->wrappers.size() == 0); + // assert(tag_ty->get_wrapper() == nullptr); // assert(tag_ty->inner_type == RawType::Composite); // LOG_TODO(lex << "Calculate tag offset with nested tag - " << idx << " ty=" << *tag_ty); //} @@ -272,10 +288,10 @@ bool Parser::parse_one() if( rv.alignment == 0 && rv.fields.size() != 0 ) { - ::std::cerr << lex << "Alignment of zero with fields is invalid, " << p << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Alignment of zero with fields is invalid, " << p); } + LOG_DEBUG(lex << "type " << p); auto it = this->tree.data_types.find(p); if( it != this->tree.data_types.end() ) { @@ -285,10 +301,7 @@ bool Parser::parse_one() } else { - //::std::cerr << lex << "Duplicate definition of " << p << ::std::endl; - - // Not really an error, can happen when loading crates - //throw "ERROR"; + //LOG_ERROR(lex << "Duplicate definition of " << p); } } else @@ -298,7 +311,7 @@ bool Parser::parse_one() } else { - ::std::cerr << lex << "Unexpected token at root - " << lex.next() << ::std::endl; + LOG_ERROR(lex << "Unexpected token at root - " << lex.next()); // Unknown item type throw "ERROR"; @@ -342,8 +355,7 @@ bool Parser::parse_one() lv = ::MIR::LValue::make_Argument({ idx }); } catch(const ::std::exception& e) { - ::std::cerr << lex << "Invalid argument name - " << name << " - " << e.what() << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Invalid argument name - " << name << " - " << e.what()); } } // Hard-coded "RETURN" lvalue @@ -354,8 +366,7 @@ bool Parser::parse_one() else { auto it = ::std::find(var_names.begin(), var_names.end(), name); if( it == var_names.end() ) { - ::std::cerr << lex << "Cannot find variable named '" << name << "'" << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Cannot find variable named '" << name << "'"); } lv = ::MIR::LValue::make_Local(static_cast<unsigned>(it - var_names.begin())); } @@ -366,8 +377,7 @@ bool Parser::parse_one() lv = ::MIR::LValue( ::std::move(path) ); } else { - ::std::cerr << lex << "Unexpected token in LValue - " << lex.next() << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Unexpected token in LValue - " << lex.next()); } for(;;) { @@ -437,8 +447,7 @@ bool Parser::parse_one() } else { - ::std::cerr << p.lex << "Expected an integer or float, got " << p.lex.next() << ::std::endl; - throw "ERROR"; + LOG_ERROR(p.lex << "Expected an integer or float, got " << p.lex.next()); } } else if( p.lex.consume_if("true") ) { @@ -453,8 +462,7 @@ bool Parser::parse_one() return ::MIR::Constant::make_ItemAddr({ ::std::move(path) }); } else { - ::std::cerr << p.lex << "BUG? " << p.lex.next() << ::std::endl; - throw "ERROR"; + LOG_BUG(p.lex << "BUG? " << p.lex.next()); } } @@ -635,8 +643,7 @@ bool Parser::parse_one() op = ::MIR::eUniOp::NEG; } else { - ::std::cerr << lex << "Unexpected token in uniop - " << lex.next() << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Unexpected token in uniop - " << lex.next()); } auto lv = H::parse_lvalue(*this, var_names); @@ -661,7 +668,7 @@ bool Parser::parse_one() case '<': if( t.strval[1] == '<' ) op = ::MIR::eBinOp::BIT_SHL; - else if( lex.consume_if('=') ) + else if( t.strval[1] == '=' ) op = ::MIR::eBinOp::LE; else op = ::MIR::eBinOp::LT; @@ -683,8 +690,7 @@ bool Parser::parse_one() lex.check_consume('='); break; default: - ::std::cerr << lex << "Unexpected token " << t << " in BINOP" << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Unexpected token " << t << " in BINOP"); } auto lv2 = H::parse_param(*this, var_names); @@ -705,8 +711,7 @@ bool Parser::parse_one() src_rval = ::MIR::RValue::make_DstMeta({ ::std::move(lv) }); } else { - ::std::cerr << lex << "Unexpected token in RValue - " << lex.next() << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Unexpected token in RValue - " << lex.next()); } stmts.push_back(::MIR::Statement::make_Assign({ ::std::move(dst_val), ::std::move(src_rval) })); @@ -717,8 +722,7 @@ bool Parser::parse_one() auto name = ::std::move(lex.consume().strval); auto df_it = ::std::find(drop_flag_names.begin(), drop_flag_names.end(), name); if( df_it == drop_flag_names.end() ) { - ::std::cerr << lex << "Unable to find drop flag '" << name << "'" << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Unable to find drop flag '" << name << "'"); } auto df_idx = static_cast<unsigned>( df_it - drop_flag_names.begin() ); lex.check_consume('='); @@ -736,8 +740,7 @@ bool Parser::parse_one() auto name = ::std::move(lex.consume().strval); df_it = ::std::find(drop_flag_names.begin(), drop_flag_names.end(), name); if( df_it == drop_flag_names.end() ) { - ::std::cerr << lex << "Unable to find drop flag '" << name << "'" << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Unable to find drop flag '" << name << "'"); } auto other_idx = static_cast<unsigned>( df_it - drop_flag_names.begin() ); @@ -759,8 +762,7 @@ bool Parser::parse_one() auto name = ::std::move(lex.consume().strval); auto df_it = ::std::find(drop_flag_names.begin(), drop_flag_names.end(), name); if( df_it == drop_flag_names.end() ) { - ::std::cerr << lex << "Unable to find drop flag '" << name << "'" << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Unable to find drop flag '" << name << "'"); } flag_idx = static_cast<unsigned>( df_it - drop_flag_names.begin() ); } @@ -824,7 +826,7 @@ bool Parser::parse_one() break; } lex.check_consume(';'); - //::std::cout << stmts.back() << ::std::endl; + //LOG_TRACE(stmts.back()); } lex.check(TokenClass::Ident); @@ -910,8 +912,7 @@ bool Parser::parse_one() vals = ::MIR::SwitchValues::make_String(::std::move(values)); } else { - ::std::cerr << lex << "Unexpected token for SWITCHVALUE value - " << lex.next() << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Unexpected token for SWITCHVALUE value - " << lex.next()); } lex.check_consume('_'); lex.check_consume('='); @@ -958,8 +959,7 @@ bool Parser::parse_one() } else { - ::std::cerr << lex << "Unexpected token at terminator - " << lex.next() << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Unexpected token at terminator - " << lex.next()); } lex.check_consume('}'); @@ -1050,7 +1050,7 @@ bool Parser::parse_one() } RawType Parser::parse_core_type() { - //::std::cout << lex.next() << ::std::endl; + //LOG_TRACE(lex.next()); lex.check(TokenClass::Ident); auto tok = lex.consume(); // Primitive type. @@ -1106,8 +1106,7 @@ RawType Parser::parse_core_type() return RawType::Str; } else { - ::std::cerr << lex << "Unknown core type " << tok << "'" << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Unknown core type " << tok << "'"); } } ::HIR::TypeRef Parser::parse_type() @@ -1121,19 +1120,8 @@ RawType Parser::parse_core_type() // Tuples! Should point to a composite ::HIR::GenericPath gp = parse_tuple(); - // Look up this type, then create a TypeRef referring to the type in the datastore - // - May need to create an unpopulated type? - auto it = tree.data_types.find(gp); - if( it == tree.data_types.end() ) - { - // TODO: Later on need to check if the type is valid. - auto v = ::std::make_unique<DataType>(DataType {}); - v->my_path = gp; - auto ir = tree.data_types.insert(::std::make_pair( ::std::move(gp), ::std::move(v)) ); - it = ir.first; - } // Good. - return ::HIR::TypeRef(it->second.get()); + return ::HIR::TypeRef( this->get_composite(::std::move(gp)) ); } else if( lex.consume_if('[') ) { @@ -1142,15 +1130,14 @@ RawType Parser::parse_core_type() { size_t size = lex.next().integer(); lex.consume(); - rv.wrappers.insert( rv.wrappers.begin(), { TypeWrapper::Ty::Array, size }); + lex.check_consume(']'); + return ::std::move(rv).wrap( TypeWrapper::Ty::Array, size ); } else { - // TODO: How to handle arrays? - rv.wrappers.insert( rv.wrappers.begin(), { TypeWrapper::Ty::Slice, 0 }); + lex.check_consume(']'); + return ::std::move(rv).wrap( TypeWrapper::Ty::Slice, 0 ); } - lex.check_consume(']'); - return rv; } else if( lex.consume_if('!') ) { @@ -1158,6 +1145,11 @@ RawType Parser::parse_core_type() } else if( lex.consume_if('&') ) { + if( lex.next() == TokenClass::Lifetime ) + { + // TODO: Handle lifetime names (require them?) + lex.consume(); + } auto bt = ::HIR::BorrowType::Shared; if( lex.consume_if("move") ) bt = ::HIR::BorrowType::Move; @@ -1165,9 +1157,7 @@ RawType Parser::parse_core_type() bt = ::HIR::BorrowType::Unique; else ; // keep as shared - auto rv = parse_type(); - rv.wrappers.insert( rv.wrappers.begin(), { TypeWrapper::Ty::Borrow, static_cast<size_t>(bt) }); - return rv; + return parse_type().wrap( TypeWrapper::Ty::Borrow, static_cast<size_t>(bt) ); } else if( lex.consume_if('*') ) { @@ -1180,26 +1170,12 @@ RawType Parser::parse_core_type() ; // keep as shared else throw "ERROR"; - auto rv = parse_type(); - rv.wrappers.insert( rv.wrappers.begin(), { TypeWrapper::Ty::Pointer, static_cast<size_t>(bt) }); - return rv; + return parse_type().wrap( TypeWrapper::Ty::Pointer, static_cast<size_t>(bt) ); } else if( lex.next() == "::" ) { auto path = parse_genericpath(); - // Look up this type, then create a TypeRef referring to the type in the datastore - // - May need to create an unpopulated type? - auto it = tree.data_types.find(path); - if( it == tree.data_types.end() ) - { - // TODO: Later on need to check if the type is valid. - auto v = ::std::make_unique<DataType>(DataType {}); - v->my_path = path; - auto ir = tree.data_types.insert(::std::make_pair( ::std::move(path), ::std::move(v)) ); - it = ir.first; - } - // Good. - return ::HIR::TypeRef(it->second.get()); + return ::HIR::TypeRef( this->get_composite(::std::move(path))); } else if( lex.next() == "extern" || lex.next() == "fn" || lex.next() == "unsafe" ) { @@ -1269,12 +1245,28 @@ RawType Parser::parse_core_type() ::std::vector<::HIR::GenericPath> markers; while(lex.consume_if('+')) { - // TODO: Detect/parse lifetimes? - markers.push_back(parse_genericpath()); + if( lex.next() == TokenClass::Lifetime ) + { + // TODO: Include lifetimes in output? + lex.consume(); + } + else + { + markers.push_back(parse_genericpath()); + } } lex.consume_if(')'); - return ::HIR::TypeRef(RawType::TraitObject); - // TODO: Generate the vtable path and locate that struct + + auto rv = ::HIR::TypeRef(RawType::TraitObject); + if( base_trait != ::HIR::GenericPath() ) + { + // Generate vtable path + auto vtable_path = base_trait; + vtable_path.m_simplepath.ents.back() += "#vtable"; + // - TODO: Associated types? + rv.composite_type = this->get_composite( ::std::move(vtable_path) ); + } + return rv; } else if( lex.next() == TokenClass::Ident ) { @@ -1282,10 +1274,22 @@ RawType Parser::parse_core_type() } else { - ::std::cerr << lex << "Unexpected token in type - " << lex.next() << ::std::endl; - throw "ERROR"; + LOG_ERROR(lex << "Unexpected token in type - " << lex.next()); } } +const DataType* Parser::get_composite(::HIR::GenericPath gp) +{ + auto it = tree.data_types.find(gp); + if( it == tree.data_types.end() ) + { + // TODO: Later on need to check if the type is valid. + auto v = ::std::make_unique<DataType>(DataType {}); + v->my_path = gp; + auto ir = tree.data_types.insert(::std::make_pair( ::std::move(gp), ::std::move(v)) ); + it = ir.first; + } + return it->second.get(); +} ::HIR::SimplePath ModuleTree::find_lang_item(const char* name) const { @@ -1296,8 +1300,7 @@ const Function& ModuleTree::get_function(const ::HIR::Path& p) const auto it = functions.find(p); if(it == functions.end()) { - ::std::cerr << "Unable to find function " << p << " for invoke" << ::std::endl; - throw ""; + LOG_ERROR("Unable to find function " << p << " for invoke"); } return it->second; } @@ -1310,17 +1313,16 @@ const Function* ModuleTree::get_function_opt(const ::HIR::Path& p) const } return &it->second; } -Value& ModuleTree::get_static(const ::HIR::Path& p) +Static& ModuleTree::get_static(const ::HIR::Path& p) { auto it = statics.find(p); if(it == statics.end()) { - ::std::cerr << "Unable to find static " << p << " for invoke" << ::std::endl; - throw ""; + LOG_ERROR("Unable to find static " << p << " for invoke"); } return it->second; } -Value* ModuleTree::get_static_opt(const ::HIR::Path& p) +Static* ModuleTree::get_static_opt(const ::HIR::Path& p) { auto it = statics.find(p); if(it == statics.end()) @@ -1328,4 +1330,4 @@ Value* ModuleTree::get_static_opt(const ::HIR::Path& p) return nullptr; } return &it->second; -}
\ No newline at end of file +} |