diff options
| author | John Hodge <tpg@mutabah.net> | 2018-02-11 21:57:10 +0800 | 
|---|---|---|
| committer | John Hodge <tpg@mutabah.net> | 2018-02-11 21:57:10 +0800 | 
| commit | a3a0c6437302c60bd6f521fc11e30c0a16bd79fc (patch) | |
| tree | 83b536f1d5b170a88417015ec0a7f378ab6ea4c4 | |
| parent | 14fea32f414df2d1e0b8e2669c8fe13132210ae9 (diff) | |
| download | mrust-a3a0c6437302c60bd6f521fc11e30c0a16bd79fc.tar.gz | |
Standalone MIRI - Implementation sprint, statics in process.
| -rw-r--r-- | src/trans/codegen_mmir.cpp | 274 | ||||
| -rw-r--r-- | tools/standalone_miri/hir_sim.cpp | 26 | ||||
| -rw-r--r-- | tools/standalone_miri/hir_sim.hpp | 1 | ||||
| -rw-r--r-- | tools/standalone_miri/main.cpp | 156 | ||||
| -rw-r--r-- | tools/standalone_miri/module_tree.cpp | 61 | ||||
| -rw-r--r-- | tools/standalone_miri/module_tree.hpp | 9 | ||||
| -rw-r--r-- | tools/standalone_miri/value.cpp | 183 | ||||
| -rw-r--r-- | tools/standalone_miri/value.hpp | 72 | ||||
| -rw-r--r-- | vsproject/mrustc.vcxproj.filters | 24 | ||||
| -rw-r--r-- | vsproject/standalone_miri/standalone_miri.vcxproj | 5 | 
10 files changed, 766 insertions, 45 deletions
| diff --git a/src/trans/codegen_mmir.cpp b/src/trans/codegen_mmir.cpp index 09167486..d4b9f799 100644 --- a/src/trans/codegen_mmir.cpp +++ b/src/trans/codegen_mmir.cpp @@ -97,6 +97,9 @@ namespace              os << (sign ? "-" : "+") << "0x1." << ::std::setw(52/4) << ::std::setfill('0') << ::std::hex << frac << ::std::dec << "p" << (exp - 1023);              os << " " << v.t;              } break; +        TU_ARM(e, ItemAddr, v) { +            os << "ADDROF " << v; +            } break;          default:              os << e;              break; @@ -160,13 +163,13 @@ namespace                  {                      m_of << "\tlet m: fn();\n";                      m_of << "\t0: {\n"; -                    m_of << "\t\tASSIGN m = &" << ::HIR::GenericPath(m_resolve.m_crate.get_lang_item_path(Span(), "mrustc-main")) << ";\n"; -                    m_of << "\t\tCALL RETURN = " << ::HIR::GenericPath(m_resolve.m_crate.get_lang_item_path(Span(), "start")) << "(m, arg1, arg2) goto 1 else 1\n"; +                    m_of << "\t\tASSIGN m = ADDROF " << ::HIR::GenericPath(m_resolve.m_crate.get_lang_item_path(Span(), "mrustc-main")) << ";\n"; +                    m_of << "\t\tCALL RETURN = " << ::HIR::GenericPath(m_resolve.m_crate.get_lang_item_path(Span(), "start")) << "(m, arg0, arg1) goto 1 else 1\n";                  }                  else                  {                      m_of << "\t0: {\n"; -                    m_of << "\t\tCALL RETURN = " << ::HIR::GenericPath(c_start_path) << "(arg1, arg2) goto 1 else 1;\n"; +                    m_of << "\t\tCALL RETURN = " << ::HIR::GenericPath(c_start_path) << "(arg0, arg1) goto 1 else 1;\n";                  }                  m_of << "\t}\n";                  m_of << "\t1: {\n"; @@ -509,6 +512,271 @@ namespace  #endif              m_mir_res = nullptr;          } +        struct Reloc { +            size_t  ofs; +            size_t  len; +            const ::HIR::Path* p; +            ::std::string   bytes; +        }; +        void emit_literal_as_bytes(const ::HIR::Literal& lit, const ::HIR::TypeRef& ty, ::std::vector<Reloc>& out_relocations, size_t base_ofs) +        { +            TRACE_FUNCTION_F(lit << ", " << ty); +            auto putb = [&](uint8_t b) { +                if( b == 0 ) { +                    m_of << "\\0"; +                } +                else if( b == '\\' ) { +                    m_of << "\\\\"; +                } +                else if( b == '"' ) { +                    m_of << "\\\""; +                } +                else if( ' ' <= b && b <= 'z' && b != '\\' ) { +                    m_of << b; +                } +                else if( b < 16 ) { +                    m_of << "\\x0" << ::std::hex << int(b) << ::std::dec; +                } +                else { +                    m_of << "\\x" << ::std::hex << int(b) << ::std::dec; +                } +                }; +            auto putu32 = [&](uint32_t v) { +                putb(v & 0xFF); +                putb(v >> 8); +                putb(v >> 16); +                putb(v >> 24); +                }; +            auto putsize = [&](uint64_t v) { +                if( true ) { +                    putu32(v      ); +                    putu32(v >> 32); +                } +                else {  +                    putu32(v   ); +                } +                }; +            switch(ty.m_data.tag()) +            { +            case ::HIR::TypeRef::Data::TAGDEAD: throw ""; +            case ::HIR::TypeRef::Data::TAG_Generic: +            case ::HIR::TypeRef::Data::TAG_ErasedType: +            case ::HIR::TypeRef::Data::TAG_Diverge: +            case ::HIR::TypeRef::Data::TAG_Infer: +            case ::HIR::TypeRef::Data::TAG_TraitObject: +            case ::HIR::TypeRef::Data::TAG_Slice: +            case ::HIR::TypeRef::Data::TAG_Closure: +                BUG(sp, "Unexpected " << ty << " in decoding literal"); +            TU_ARM(ty.m_data, Primitive, te) { +                switch(te) +                { +                case ::HIR::CoreType::U8: +                case ::HIR::CoreType::I8: +                case ::HIR::CoreType::Bool: +                    ASSERT_BUG(sp, lit.is_Integer(), ty << " not Literal::Integer - " << lit); +                    putb(lit.as_Integer()); +                    break; +                case ::HIR::CoreType::U16: +                case ::HIR::CoreType::I16: +                    ASSERT_BUG(sp, lit.is_Integer(), ty << " not Literal::Integer - " << lit); +                    putb(lit.as_Integer() & 0xFF); +                    putb(lit.as_Integer() >> 8); +                    break; +                case ::HIR::CoreType::U32: +                case ::HIR::CoreType::I32: +                case ::HIR::CoreType::Char: +                    ASSERT_BUG(sp, lit.is_Integer(), ty << " not Literal::Integer - " << lit); +                    putu32(lit.as_Integer()   ); +                    break; +                case ::HIR::CoreType::U64: +                case ::HIR::CoreType::I64: +                    ASSERT_BUG(sp, lit.is_Integer(), ty << " not Literal::Integer - " << lit); +                    putu32(lit.as_Integer()      ); +                    putu32(lit.as_Integer() >> 32); +                    break; +                case ::HIR::CoreType::U128: +                case ::HIR::CoreType::I128: +                    ASSERT_BUG(sp, lit.is_Integer(), ty << " not Literal::Integer - " << lit); +                    putu32(lit.as_Integer()      ); +                    putu32(lit.as_Integer() >> 32); +                    putu32(0); +                    putu32(0); +                    break; +                case ::HIR::CoreType::Usize: +                case ::HIR::CoreType::Isize: +                    ASSERT_BUG(sp, lit.is_Integer(), ty << " not Literal::Integer - " << lit); +                    putsize(lit.as_Integer()); +                    break; +                case ::HIR::CoreType::F32: { +                    ASSERT_BUG(sp, lit.is_Float(), "not Literal::Float - " << lit); +                    uint32_t v; +                    memcpy(&v, &double(lit.as_Float()), 4); +                    putu32(v); +                    } break; +                case ::HIR::CoreType::F64: { +                    ASSERT_BUG(sp, lit.is_Float(), "not Literal::Float - " << lit); +                    uint64_t v; +                    memcpy(&v, &lit.as_Float(), 8); +                    putu32(v); +                    } break; +                case ::HIR::CoreType::Str: +                    BUG(sp, "Unexpected " << ty << " in decoding literal"); +                } +                } break; +            case ::HIR::TypeRef::Data::TAG_Path: +            case ::HIR::TypeRef::Data::TAG_Tuple: { +                const auto* repr = Target_GetTypeRepr(sp, m_resolve, ty); +                assert(repr); +                size_t cur_ofs = 0; +                if( lit.is_List() ) +                { +                    const auto& le = lit.as_List(); +                    assert(le.size() == repr->fields.size()); +                    for(size_t i = 0; i < repr->fields.size(); i ++) +                    { +                        assert(cur_ofs <= repr->fields[i].offset); +                        while(cur_ofs < repr->fields[i].offset) +                        { +                            putb(0); +                            cur_ofs ++; +                        } +                        emit_literal_as_bytes(le[i], repr->fields[i].ty, out_relocations, base_ofs + cur_ofs); +                        size_t size; +                        assert(Target_GetSizeOf(sp, m_resolve, repr->fields[i].ty, size)); +                        cur_ofs += size; +                    } +                    while(cur_ofs < repr->size) +                    { +                        putb(0); +                        cur_ofs ++; +                    } +                } +                else if( lit.is_Variant() ) +                { +                    const auto& le = lit.as_Variant(); +                    if( *le.val != ::HIR::Literal::make_List({}) ) +                    { +                        assert(le.idx < repr->fields.size()); +                        while(cur_ofs < repr->fields[le.idx].offset) +                        { +                            putb(0); +                            cur_ofs ++; +                        } + +                        emit_literal_as_bytes(*le.val, repr->fields[le.idx].ty, out_relocations, base_ofs + cur_ofs); + +                        size_t size; +                        assert(Target_GetSizeOf(sp, m_resolve, repr->fields[le.idx].ty, size)); +                        cur_ofs += size; +                    } + +                    if(const auto* ve = repr->variants.opt_Values()) +                    { +                        ASSERT_BUG(sp, cur_ofs <= repr->fields[ve->field.index].offset, "Bad offset before enum tag"); +                        while(cur_ofs < repr->fields[ve->field.index].offset) +                        { +                            putb(0); +                            cur_ofs ++; +                        } +                        auto v = ::HIR::Literal::make_Integer(le.idx); +                        emit_literal_as_bytes(v, repr->fields[ve->field.index].ty, out_relocations, base_ofs + cur_ofs); +                    } +                    // TODO: Nonzero? +                    while(cur_ofs < repr->size) +                    { +                        putb(0); +                        cur_ofs ++; +                    } +                } +                else +                { +                    TODO(sp, "Composites - " << ty << " w/ " << lit); +                } +                } break; +            case ::HIR::TypeRef::Data::TAG_Borrow: +                if( *ty.m_data.as_Borrow().inner == ::HIR::CoreType::Str ) +                { +                    ASSERT_BUG(sp, lit.is_String(), ty << " not Literal::String - " << lit); +                    const auto& s = lit.as_String(); +                    putsize(0); +                    putsize(s.size()); +                    out_relocations.push_back(Reloc { base_ofs, 8, nullptr, s }); +                    break; +                } +                // fall +            case ::HIR::TypeRef::Data::TAG_Pointer: { +                const auto& ity = (ty.m_data.is_Borrow() ? *ty.m_data.as_Borrow().inner : *ty.m_data.as_Pointer().inner); +                size_t ity_size, ity_align; +                Target_GetSizeAndAlignOf(sp, m_resolve, ity, ity_size, ity_align); +                bool is_unsized = (ity_size == SIZE_MAX); +                if( lit.is_BorrowPath() ) +                { +                    putsize(0); +                    out_relocations.push_back(Reloc { base_ofs, 8, &lit.as_BorrowPath(), "" }); +                    if( is_unsized ) +                    { +                        // TODO: Get the size of the pointed-to array +                        // OR: Find out the source item type and the target trait. +                        putsize(0); +                    } +                    break; +                } +                else if( lit.is_Integer() ) +                { +                    ASSERT_BUG(sp, lit.as_Integer() == 0, "Pointer from integer not 0"); +                    ASSERT_BUG(sp, ty.m_data.is_Pointer(), "Borrow from integer"); +                    putsize(0); +                    if( is_unsized ) +                    { +                        putsize(0); +                    } +                    break; +                } +                TODO(sp, "Pointers - " << ty << " w/ " << lit); +                } break; +            case ::HIR::TypeRef::Data::TAG_Function: +                ASSERT_BUG(sp, lit.is_BorrowPath(), ty << " not Literal::BorrowPath - " << lit); +                putsize(0); +                out_relocations.push_back(Reloc { base_ofs, 8, &lit.as_BorrowPath(), "" }); +                break; +            TU_ARM(ty.m_data, Array, te) { +                // What about byte strings? +                // TODO: Assert size +                ASSERT_BUG(sp, lit.is_List(), "not Literal::List - " << lit); +                for(const auto& v : lit.as_List()) +                { +                    emit_literal_as_bytes(v, *te.inner, out_relocations, base_ofs); +                    size_t size; +                    assert(Target_GetSizeOf(sp, m_resolve, *te.inner, size)); +                    base_ofs += size; +                } +                } break; +            } +        } +        void emit_static_local(const ::HIR::Path& p, const ::HIR::Static& item, const Trans_Params& params) override +        { +            ::MIR::Function empty_fcn; +            ::MIR::TypeResolve  top_mir_res { sp, m_resolve, FMT_CB(ss, ss << "static " << p;), ::HIR::TypeRef(), {}, empty_fcn }; +            m_mir_res = &top_mir_res; + +            TRACE_FUNCTION_F(p); + +            ::std::vector<Reloc>    relocations; + +            auto type = params.monomorph(m_resolve, item.m_type); +            m_of << "static " << p << ": " << type << " = \""; +            emit_literal_as_bytes(item.m_value_res, type, relocations, 0); +            m_of << "\""; +            m_of << "{"; +            for(const auto& r : relocations) +            { +                // TODO. +            } +            m_of << "}"; +            m_of << ";\n"; + +            m_mir_res = nullptr; +        }          void emit_function_code(const ::HIR::Path& p, const ::HIR::Function& item, const Trans_Params& params, bool is_extern_def, const ::MIR::FunctionPointer& code) override          {              TRACE_FUNCTION_F(p); diff --git a/tools/standalone_miri/hir_sim.cpp b/tools/standalone_miri/hir_sim.cpp index 0010e202..7fccc806 100644 --- a/tools/standalone_miri/hir_sim.cpp +++ b/tools/standalone_miri/hir_sim.cpp @@ -6,6 +6,8 @@  #include "hir_sim.hpp"  #include "module_tree.hpp" +const size_t POINTER_SIZE = 8; +  //::HIR::Path::Path(::HIR::SimplePath sp)  //{  //} @@ -22,6 +24,7 @@ size_t HIR::TypeRef::get_size(size_t ofs) const          case RawType::Composite:              return this->composite_type->size;          case RawType::Unreachable: +        case RawType::TraitObject:          case RawType::Str:              throw "Invalid";          case RawType::U8:   case RawType::I8: @@ -35,6 +38,16 @@ size_t HIR::TypeRef::get_size(size_t ofs) const          case RawType::U128: case RawType::I128:              return 16; +        case RawType::Bool: +            return 1; +        case RawType::Char: +            return 4; + +        case RawType::F32: +            return 4; +        case RawType::F64: +            return 8; +          case RawType::Function: // This should probably be invalid?          case RawType::USize: case RawType::ISize:              return POINTER_SIZE; @@ -52,7 +65,10 @@ size_t HIR::TypeRef::get_size(size_t ofs) const          {              // Need to look up the metadata type for the actual type              if( this->inner_type == RawType::Composite ) -                throw "TODO"; +            { +                ::std::cerr << "TODO: Check metadata type for pointer " << *this << ", assuming none" << ::std::endl; +                return POINTER_SIZE; +            }              else if( this->inner_type == RawType::Str )                  return POINTER_SIZE*2;              else if( this->inner_type == RawType::TraitObject ) @@ -175,6 +191,12 @@ namespace HIR {          case RawType::Unreachable:              os << "!";              break; +        case RawType::Function: +            os << "function_?"; +            break; +        case RawType::TraitObject: +            os << "traitobject_?"; +            break;          case RawType::Bool: os << "bool"; break;          case RawType::Char: os << "char"; break;          case RawType::Str:  os << "str";  break; @@ -191,6 +213,8 @@ namespace HIR {          case RawType::I128: os << "i128";   break;          case RawType::USize: os << "usize";   break;          case RawType::ISize: os << "isize";   break; +        case RawType::F32:  os << "f32";    break; +        case RawType::F64:  os << "f64";    break;          }          for(auto it = x.wrappers.rbegin(); it != x.wrappers.rend(); ++it)          { diff --git a/tools/standalone_miri/hir_sim.hpp b/tools/standalone_miri/hir_sim.hpp index 1303f077..96887536 100644 --- a/tools/standalone_miri/hir_sim.hpp +++ b/tools/standalone_miri/hir_sim.hpp @@ -82,6 +82,7 @@ namespace HIR {      /// Definition of a type      struct TypeRef      { +        // Top to bottom list of wrappers (first entry is the outermost wrapper)          ::std::vector<TypeWrapper>  wrappers;          RawType inner_type = RawType::Unit;          const DataType* composite_type = nullptr; diff --git a/tools/standalone_miri/main.cpp b/tools/standalone_miri/main.cpp index a6a58a91..c7069ed2 100644 --- a/tools/standalone_miri/main.cpp +++ b/tools/standalone_miri/main.cpp @@ -7,8 +7,6 @@  #include <algorithm>  #include <iomanip> -#pragma warning( error : 4061)  -  struct ProgramOptions  {      ::std::string   infile; @@ -16,7 +14,7 @@ struct ProgramOptions      int parse(int argc, const char* argv[]);  }; -Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> args); +Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> args);  int main(int argc, const char* argv[])  { @@ -31,15 +29,32 @@ int main(int argc, const char* argv[])      tree.load_file(opts.infile); -    auto rv = MIRI_Invoke(tree, tree.find_lang_item("start"), {}); +    auto val_argc = Value( ::HIR::TypeRef{RawType::I32} ); +    ::HIR::TypeRef  argv_ty { RawType::I8 }; +    argv_ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Pointer, 0 }); +    argv_ty.wrappers.push_back(TypeWrapper { TypeWrapper::Ty::Pointer, 0 }); +    auto val_argv = Value(argv_ty); +    val_argc.write_bytes(0, "\0\0\0", 4); +    val_argv.write_bytes(0, "\0\0\0\0\0\0\0", argv_ty.get_size()); + +    ::std::vector<Value>    args; +    args.push_back(::std::move(val_argc)); +    args.push_back(::std::move(val_argv)); +    auto rv = MIRI_Invoke( tree, tree.find_lang_item("start"), ::std::move(args) );      ::std::cout << rv << ::std::endl;      return 0;  } -Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> args) +Value MIRI_Invoke(ModuleTree& modtree, ::HIR::Path path, ::std::vector<Value> args)  { +    //TRACE_FUNCTION_FR(path,path)      const auto& fcn = modtree.get_function(path); +    for(size_t i = 0; i < args.size(); i ++) +    { +        //DEBUG(a); +        ::std::cout << "Argument(" << i << ") = " << args[i] << ::std::endl; +    }      ::std::vector<bool> drop_flags = fcn.m_mir.drop_flags;      ::std::vector<Value>    locals; locals.reserve( fcn.m_mir.locals.size() ); @@ -52,12 +67,14 @@ Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Val      struct State      { +        ModuleTree& modtree;          const Function& fcn;          Value   ret;          ::std::vector<Value>    args;          ::std::vector<Value>    locals; -        State(const Function& fcn, ::std::vector<Value> args): +        State(ModuleTree& modtree, const Function& fcn, ::std::vector<Value> args): +            modtree(modtree),              fcn(fcn),              ret(fcn.ret_ty),              args(::std::move(args)) @@ -73,6 +90,7 @@ Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Val          {              switch(lv.tag())              { +            case ::MIR::LValue::TAGDEAD:    throw "";              TU_ARM(lv, Return, _e) {                  ofs = 0;                  ty = fcn.ret_ty; @@ -88,6 +106,9 @@ Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Val                  ty = fcn.args.at(e.idx);                  return args.at(e.idx);                  } break; +            TU_ARM(lv, Static, e) { +                return modtree.get_static(e); +                } break;              TU_ARM(lv, Index, e) {                  auto idx = read_lvalue(*e.idx).as_usize();                  ::HIR::TypeRef  array_ty; @@ -118,6 +139,23 @@ Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Val                  ofs += inner_ofs;                  return base_val;                  } +            TU_ARM(lv, Downcast, e) { +                ::HIR::TypeRef  composite_ty; +                auto& base_val = get_value_type_and_ofs(*e.val, ofs, composite_ty); + +                size_t inner_ofs; +                ty = composite_ty.get_field(e.variant_index, inner_ofs); +                ::std::cerr << "TODO: Read from Downcast - " << lv << ::std::endl; +                throw "TODO"; +                ofs += inner_ofs; +                return base_val; +                } +            TU_ARM(lv, Deref, e) { +                //auto addr = read_lvalue(*e.val); + +                ::std::cerr << "TODO: Read from deref - " << lv << ::std::endl; +                throw "TODO"; +                } break;              }              throw "";          } @@ -161,6 +199,7 @@ Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Val          {              switch(c.tag())              { +            case ::MIR::Constant::TAGDEAD:  throw "";              TU_ARM(c, Int, ce) {                  ty = ::HIR::TypeRef(ce.t);                  Value val = Value(ty); @@ -174,6 +213,42 @@ Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Val                  val.write_bytes(0, &ce.v, ::std::min(ty.get_size(), sizeof(ce.v)));  // TODO: Endian                  return val;                  } break; +            TU_ARM(c, Bool, ce) { +                Value val = Value(::HIR::TypeRef { RawType::Bool }); +                val.write_bytes(0, &ce.v, 1); +                return val; +                } break; +            TU_ARM(c, Float, ce) { +                ty = ::HIR::TypeRef(ce.t); +                Value val = Value(ty); +                if( ce.t.raw_type == RawType::F64 ) { +                    val.write_bytes(0, &ce.v, ::std::min(ty.get_size(), sizeof(ce.v)));  // TODO: Endian/format? +                } +                else if( ce.t.raw_type == RawType::F32 ) { +                    float v = static_cast<float>(ce.v); +                    val.write_bytes(0, &v, ::std::min(ty.get_size(), sizeof(v)));  // TODO: Endian/format? +                } +                else { +                    throw ::std::runtime_error("BUG: Invalid type in Constant::Float"); +                } +                return val; +                } break; +            TU_ARM(c, Const, ce) { +                throw ::std::runtime_error("BUG: Constant::Const in mmir"); +                } break; +            TU_ARM(c, Bytes, ce) { +                throw ::std::runtime_error("TODO: Constant::Bytes"); +                } break; +            TU_ARM(c, StaticString, ce) { +                throw ::std::runtime_error("TODO: Constant::StaticString"); +                } break; +            TU_ARM(c, ItemAddr, ce) { +                // Create a value with a special backing allocation of zero size that references the specified item. +                if( const auto* fn = modtree.get_function_opt(ce) ) { +                    return Value::new_fnptr(ce); +                } +                throw ::std::runtime_error("TODO: Constant::ItemAddr"); +                } break;              }              throw "";          } @@ -186,6 +261,7 @@ Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Val          {              switch(p.tag())              { +            case ::MIR::Param::TAGDEAD: throw "";              TU_ARM(p, Constant, pe)                  return const_to_value(pe, ty);              TU_ARM(p, LValue, pe) @@ -198,7 +274,7 @@ Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Val              ::HIR::TypeRef  ty;              return param_to_value(p, ty);          } -    } state { fcn, ::std::move(args) }; +    } state { modtree, fcn, ::std::move(args) };      size_t bb_idx = 0;      for(;;) @@ -210,16 +286,38 @@ Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Val              ::std::cout << "BB" << bb_idx << "/" << (&stmt - bb.statements.data()) << ": " << stmt << ::std::endl;              switch(stmt.tag())              { +            case ::MIR::Statement::TAGDEAD: throw "";              TU_ARM(stmt, Assign, se) {                  Value   val;                  switch(se.src.tag())                  { +                case ::MIR::RValue::TAGDEAD: throw "";                  TU_ARM(se.src, Use, re) {                      state.write_lvalue(se.dst, state.read_lvalue(re));                      } break;                  TU_ARM(se.src, Constant, re) {                      state.write_lvalue(se.dst, state.const_to_value(re));                      } break; +                TU_ARM(se.src, Borrow, re) { +                    ::HIR::TypeRef  src_ty; +                    size_t ofs = 0; +                    Value&  base_value = state.get_value_type_and_ofs(re.val, ofs, src_ty); +                    if( !base_value.allocation ) +                    { +                        // TODO: Need to convert this value into an allocation version +                        ::std::cerr << "TODO: RValue::Borrow - " << se.src << " - convert to non-inline" << ::std::endl; +                        throw "TODO"; +                        //base_value.to_allocation(); +                    } +                    ofs += base_value.meta.indirect_meta.offset; +                    src_ty.wrappers.insert(src_ty.wrappers.begin(), TypeWrapper { TypeWrapper::Ty::Borrow, static_cast<size_t>(re.type) }); +                    Value new_val = Value(src_ty); +                    // ^ Pointer value +                    new_val.allocation.alloc().relocations.push_back(Relocation { 0, base_value.allocation }); +                    new_val.write_bytes(0, &ofs, src_ty.get_size()); +                    ::std::cerr << "TODO: RValue::Borrow - " << se.src << ::std::endl; +                    throw "TODO"; +                    } break;                  TU_ARM(se.src, SizedArray, re) {                      throw "TODO";                      } break; @@ -272,17 +370,61 @@ Value MIRI_Invoke(const ModuleTree& modtree, ::HIR::Path path, ::std::vector<Val              case ::MIR::Statement::TAG_SetDropFlag:                  throw "TODO";                  break; +            case ::MIR::Statement::TAG_ScopeEnd: +                throw "TODO"; +                break;              }          }          ::std::cout << "BB" << bb_idx << "/TERM: " << bb.terminator << ::std::endl;          switch(bb.terminator.tag())          { +        case ::MIR::Terminator::TAGDEAD:    throw ""; +        TU_ARM(bb.terminator, Incomplete, _te) +            throw ::std::runtime_error("BUG: Terminator::Incomplete hit"); +        TU_ARM(bb.terminator, Diverge, _te) +            throw ::std::runtime_error("BUG: Terminator::Diverge hit"); +        TU_ARM(bb.terminator, Panic, _te) +            throw ::std::runtime_error("TODO: Terminator::Panic");          TU_ARM(bb.terminator, Goto, te)              bb_idx = te;              continue;          TU_ARM(bb.terminator, Return, _te)              return state.ret; +        TU_ARM(bb.terminator, If, _te) +            throw ::std::runtime_error("TODO: Terminator::If"); +        TU_ARM(bb.terminator, Switch, _te) +            throw ::std::runtime_error("TODO: Terminator::Switch"); +        TU_ARM(bb.terminator, SwitchValue, _te) +            throw ::std::runtime_error("TODO: Terminator::SwitchValue"); +        TU_ARM(bb.terminator, Call, te) { +            if( te.fcn.is_Intrinsic() ) { +                throw ::std::runtime_error("TODO: Terminator::Call - intrinsic"); +            } +            else { +                const ::HIR::Path* fcn_p; +                if( te.fcn.is_Path() ) { +                    fcn_p = &te.fcn.as_Path(); +                } +                else { +                    ::HIR::TypeRef ty; +                    auto v = state.read_lvalue_with_ty(te.fcn.as_Value(), ty); +                    // TODO: Assert type +                    // TODO: Assert offset/content. +                    assert(v.as_usize() == 0); +                    fcn_p = &v.allocation.alloc().relocations.at(0).backing_alloc.fcn(); +                } + +                ::std::vector<Value>    sub_args; sub_args.reserve(te.args.size()); +                for(const auto& a : te.args) +                { +                    sub_args.push_back( state.param_to_value(a) ); +                } +                ::std::cout << "TODO: Call " << *fcn_p << ::std::endl; +                MIRI_Invoke(modtree, *fcn_p, ::std::move(sub_args)); +            } +            throw ::std::runtime_error("TODO: Terminator::Call"); +            } break;          }          throw "";      } diff --git a/tools/standalone_miri/module_tree.cpp b/tools/standalone_miri/module_tree.cpp index f056481b..90d599c8 100644 --- a/tools/standalone_miri/module_tree.cpp +++ b/tools/standalone_miri/module_tree.cpp @@ -3,6 +3,7 @@  //  #include "module_tree.hpp"  #include "lex.hpp" +#include "value.hpp"  #include <iostream>  ModuleTree::ModuleTree() @@ -73,7 +74,7 @@ bool Parser::parse_one()      else if( lex.consume_if("fn") )      {          auto p = parse_path(); -        //::std::cout << "DEBUG:p arse_one - fn " << p << ::std::endl; +        //::std::cout << "DEBUG: parse_one - fn " << p << ::std::endl;          lex.check_consume('(');          ::std::vector<::HIR::TypeRef>  arg_tys; @@ -91,17 +92,33 @@ bool Parser::parse_one()          }          auto body = parse_body(); -        tree.functions.insert( ::std::make_pair(::std::move(p), Function { ::std::move(arg_tys), rv_ty, ::std::move(body) }) ); +        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) }) );      }      else if( lex.consume_if("static") )      {          auto p = parse_path();          //::std::cout << "DEBUG: parse_one - static " << p << ::std::endl; +        lex.check_consume(':'); +        auto ty = parse_type(); +        // TODO: externs?          lex.check_consume('='); -        // TODO: Body? Value? -        //auto body = parse_body(); -        //auto data = ::std::move(lex.consume().strval); -        throw "TODO"; +        lex.check(TokenClass::String); +        auto data = ::std::move(lex.consume().strval); +        if( lex.consume_if('{') ) +        { +            while( !lex.consume_if('}') ) +            { +                // TODO: Parse relocation entries +                throw "TODO"; +            } +        } +        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) ));      }      else if( lex.consume_if("type") )      { @@ -354,7 +371,7 @@ bool Parser::parse_one()              else if( p.lex.consume_if("false") ) {                  return ::MIR::Constant::make_Bool({ false });              } -            else if( p.lex.consume_if("&") ) { +            else if( p.lex.consume_if("ADDROF") ) {                  auto path = p.parse_path();                  return ::MIR::Constant::make_ItemAddr({ ::std::move(path) }); @@ -371,6 +388,7 @@ bool Parser::parse_one()              if( p.lex.next() == TokenClass::Integer || p.lex.next() == TokenClass::String || p.lex.next() == TokenClass::ByteString                  || p.lex.next() == '+' || p.lex.next() == '-' || p.lex.next() == '&'                  || p.lex.next() == "true" || p.lex.next() == "false" +                || p.lex.next() == "ADDROF"                  )              {                  return parse_const(p); @@ -432,6 +450,7 @@ bool Parser::parse_one()                  if( lex.next() == TokenClass::Integer || lex.next() == TokenClass::String || lex.next() == TokenClass::ByteString                      || lex.next() == '+' || lex.next() == '-'                      || lex.next() == "true" || lex.next() == "false" +                    || lex.next() == "ADDROF"                      )                  {                      src_rval = H::parse_const(*this); @@ -1203,4 +1222,32 @@ const Function& ModuleTree::get_function(const ::HIR::Path& p) const          throw "";      }      return it->second; +} +const Function* ModuleTree::get_function_opt(const ::HIR::Path& p) const +{ +    auto it = functions.find(p); +    if(it == functions.end()) +    { +        return nullptr; +    } +    return &it->second; +} +Value& 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 ""; +    } +    return it->second; +} +Value* ModuleTree::get_static_opt(const ::HIR::Path& p) +{ +    auto it = statics.find(p); +    if(it == statics.end()) +    { +        return nullptr; +    } +    return &it->second;  }
\ No newline at end of file diff --git a/tools/standalone_miri/module_tree.hpp b/tools/standalone_miri/module_tree.hpp index ce831621..96a77718 100644 --- a/tools/standalone_miri/module_tree.hpp +++ b/tools/standalone_miri/module_tree.hpp @@ -10,8 +10,11 @@  #include "../../src/mir/mir.hpp"  #include "hir_sim.hpp" +struct Value; +  struct Function  { +    ::HIR::Path my_path;      ::std::vector<::HIR::TypeRef>   args;      ::HIR::TypeRef   ret_ty;      ::MIR::Function m_mir; @@ -25,6 +28,9 @@ class ModuleTree      ::std::set<::std::string>   loaded_files;      ::std::map<::HIR::Path, Function>    functions; +    ::std::map<::HIR::Path, Value>    statics; +    // TODO: statics +      // Hack: Tuples are stored as `::""::<A,B,C,...>`      ::std::map<::HIR::GenericPath, ::std::unique_ptr<DataType>>  data_types;  public: @@ -34,6 +40,9 @@ public:      ::HIR::SimplePath find_lang_item(const char* name) const;      const Function& get_function(const ::HIR::Path& p) const; +    const Function* get_function_opt(const ::HIR::Path& p) const; +    Value& get_static(const ::HIR::Path& p); +    Value* get_static_opt(const ::HIR::Path& p);  };  // struct/union/enum diff --git a/tools/standalone_miri/value.cpp b/tools/standalone_miri/value.cpp index e04154f6..59b68ea0 100644 --- a/tools/standalone_miri/value.cpp +++ b/tools/standalone_miri/value.cpp @@ -8,6 +8,54 @@  #include <iomanip>  #include <algorithm> + +AllocationPtr Allocation::new_alloc(size_t size) +{ +    Allocation* rv = new Allocation(); +    rv->refcount = 1; +    rv->data.resize( (size + 8-1) / 8 );    // QWORDS +    rv->mask.resize( (size + 8-1) / 8 );    // bitmap bytes +    return AllocationPtr(rv); +} +AllocationPtr AllocationPtr::new_fcn(::HIR::Path p) +{ +    AllocationPtr   rv; +    auto* ptr = new ::HIR::Path(::std::move(p)); +    rv.m_ptr = reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(ptr) + static_cast<uintptr_t>(Ty::Function) ); +    return rv; +} +AllocationPtr::AllocationPtr(const AllocationPtr& x): +    m_ptr(x.m_ptr) +{ +    if( is_alloc() ) { +        assert(alloc().refcount != SIZE_MAX); +        alloc().refcount += 1; +    } +} +AllocationPtr::~AllocationPtr() +{ +    if( *this ) +    { +        switch(get_ty()) +        { +        case Ty::Allocation: { +            auto* ptr = &alloc(); +            ptr->refcount -= 1; +            if(ptr->refcount == 0) +                delete ptr; +            } break; +        case Ty::Function: { +            auto* ptr = const_cast<::HIR::Path*>(&fcn()); +            delete ptr; +            } break; +        case Ty::Unused1: { +            } break; +        case Ty::Unused2: { +            } break; +        } +    } +} +  Value::Value()  {      this->meta.direct_data.size = 0; @@ -18,6 +66,7 @@ Value::Value(::HIR::TypeRef ty)  {      size_t size = ty.get_size();  #if 1 +    // Support inline data if the data will fit within the inline region (which is the size of the metadata)      if( ty.get_size() <= sizeof(this->meta.direct_data.data) )      {          struct H @@ -26,6 +75,11 @@ Value::Value(::HIR::TypeRef ty)              {                  if( ty.wrappers.empty() || ::std::all_of(ty.wrappers.begin(), ty.wrappers.end(), [](const auto& x){ return x.type == TypeWrapper::Ty::Array; }) )                  { +                    // TODO: Function pointers should be _pointers_ +                    if( ty.inner_type == RawType::Function ) +                    { +                        return true; +                    }                      // Check the inner type                      if( ty.inner_type != RawType::Composite )                      { @@ -45,28 +99,69 @@ Value::Value(::HIR::TypeRef ty)          if( ! H::has_pointer(ty) )          {              // Will fit in a inline allocation, nice. +            ::std::cout << "Value::Value(): No pointers in " << ty << ", storing inline" << ::std::endl;              this->meta.direct_data.size = static_cast<uint8_t>(size); +            this->meta.direct_data.mask[0] = 0; +            this->meta.direct_data.mask[1] = 0;              return ;          }      }  #endif      // Fallback: Make a new allocation -    throw "TODO"; +    ::std::cout << "Value::Value(): Creating allocation for " << ty << ::std::endl; +    this->allocation = Allocation::new_alloc(size); +    this->meta.indirect_meta.offset = 0; +    this->meta.indirect_meta.size = size; +} +Value Value::new_fnptr(const ::HIR::Path& fn_path) +{ +    Value   rv( ::HIR::TypeRef(::HIR::CoreType { RawType::Function }) ); +    assert(rv.allocation); +    rv.allocation.alloc().relocations.push_back(Relocation { 0, AllocationPtr::new_fcn(fn_path) }); +    rv.allocation.alloc().data.at(0) = 0; +    rv.allocation.alloc().mask.at(0) = 0xFF;    // TODO: Get pointer size and make that much valid instead of 8 bytes +    return rv;  }  void Value::check_bytes_valid(size_t ofs, size_t size) const  {      if( this->allocation )      { -        throw "TODO"; +        const auto& alloc = this->allocation.alloc(); +        if( ofs >= this->meta.indirect_meta.size || ofs+size > this->meta.indirect_meta.size ) { +            ::std::cerr << "ERROR: OOB read" << ::std::endl; +            throw "ERROR"; +        } +        ofs += this->meta.indirect_meta.offset; +        //assert(ofs + size < alloc.size()); +        for(size_t i = ofs; i < ofs + size; i++) +        { +            if( !(alloc.mask[i/8] & (1 << i%8)) ) +            { +                ::std::cerr << "ERROR: Invalid bytes in value" << ::std::endl; +                throw "ERROR"; +            } +        }      }      else      { -        for(size_t i = 0; i < this->meta.direct_data.size; i++) +        if( size == 0 && this->meta.direct_data.size > 0 ) { +            return ; +        } +        if( ofs >= this->meta.direct_data.size ) { +            ::std::cerr << "ERROR: OOB read" << ::std::endl; +            throw "ERROR"; +        } +        if( ofs+size > this->meta.direct_data.size ) { +            ::std::cerr << "ERROR: OOB read" << ::std::endl; +            throw "ERROR"; +        } +        for(size_t i = ofs; i < ofs + size; i++)          {              if( !(this->meta.direct_data.mask[i/8] & (1 << i%8)) )              { +                ::std::cerr << "ERROR: Invalid bytes in value" << ::std::endl;                  throw "ERROR";              }          } @@ -76,7 +171,14 @@ void Value::mark_bytes_valid(size_t ofs, size_t size)  {      if( this->allocation )      { -        throw "TODO"; +        auto& alloc = this->allocation.alloc(); +        // TODO: Assert range. +        ofs += this->meta.indirect_meta.offset; +        assert( (ofs+size+8-1) / 8 < alloc.mask.size() ); +        for(size_t i = ofs; i < ofs + size; i++) +        { +            alloc.mask[i/8] |= (1 << i%8); +        }      }      else      { @@ -93,7 +195,29 @@ Value Value::read_value(size_t ofs, size_t size) const      check_bytes_valid(ofs, size);      if( this->allocation )      { -        throw "TODO"; +        const auto& alloc = this->allocation.alloc(); +        // TODO: Determine if this can become an inline allocation. +        bool has_reloc = false; +        for(const auto& r : alloc.relocations) +        { +            if( this->meta.indirect_meta.offset+ofs <= r.slot_ofs && r.slot_ofs < this->meta.indirect_meta.offset + ofs + size ) +            { +                has_reloc = true; +            } +        } +        Value   rv; +        if( has_reloc && size < sizeof(this->meta.direct_data.data) ) +        { +            rv.allocation = Allocation::new_alloc(size); +            rv.meta.indirect_meta.offset = 0; +            rv.meta.indirect_meta.size = size; +        } +        else +        { +            rv.meta.direct_data.size = static_cast<uint8_t>(size); +        } +        rv.write_bytes(0, this->data_ptr() + ofs, size); +        return rv;      }      else      { @@ -114,7 +238,12 @@ void Value::write_bytes(size_t ofs, const void* src, size_t count)  {      if( this->allocation )      { -        throw "TODO"; +        if(ofs >= this->meta.indirect_meta.size ) +            throw "ERROR"; +        if(count > this->meta.indirect_meta.size ) +            throw "ERROR"; +        if(ofs+count > this->meta.indirect_meta.size ) +            throw "ERROR";      }      else      { @@ -124,21 +253,36 @@ void Value::write_bytes(size_t ofs, const void* src, size_t count)              throw "ERROR";          if(ofs+count > this->meta.direct_data.size )              throw "ERROR"; -        ::std::memcpy(this->meta.direct_data.data+ofs, src, count); -        mark_bytes_valid(ofs, count);      } +    ::std::memcpy(this->data_ptr() + ofs, src, count); +    mark_bytes_valid(ofs, count);  }  void Value::write_value(size_t ofs, Value v)  {      if( v.allocation )      { -        throw "TODO"; +        v.check_bytes_valid(0, v.meta.indirect_meta.size); +        const auto& src_alloc = v.allocation.alloc(); +        write_bytes(ofs, v.data_ptr(), v.meta.indirect_meta.size); +        // Find any relocations that apply and copy those in. +        // - Any relocations in the source within `v.meta.indirect_meta.offset` .. `v.meta.indirect_meta.offset + v.meta.indirect_meta.size` +        for(const auto& r : src_alloc.relocations) +        { +            // TODO: Negative offsets in destination? +            if( v.meta.indirect_meta.offset <= r.slot_ofs && r.slot_ofs < v.meta.indirect_meta.offset + v.meta.indirect_meta.size ) +            { +                // Applicable +                if( !this->allocation ) { +                    throw ::std::runtime_error("TODO: Writing value with a relocation into a slot without a relocation"); +                } +                this->allocation.alloc().relocations.push_back( r ); +            } +        }      }      else      {          v.check_bytes_valid(0, v.meta.direct_data.size);          write_bytes(ofs, v.meta.direct_data.data, v.meta.direct_data.size); -        mark_bytes_valid(ofs, meta.direct_data.size);      }  } @@ -146,7 +290,7 @@ size_t Value::as_usize() const  {      uint64_t    v;      this->read_bytes(0, &v, 8); -    // TODO: Handle endian +    // TODO: Handle endian and different architectures      return v;  }  ::std::ostream& operator<<(::std::ostream& os, const Value& v) @@ -155,7 +299,22 @@ size_t Value::as_usize() const      os << ::std::hex;      if( v.allocation )      { -        throw "TODO"; +        const auto& alloc = v.allocation.alloc(); +        for(size_t i = 0; i < v.meta.indirect_meta.size; i++) +        { +            if( i != 0 ) +                os << " "; +            size_t j = i + v.meta.indirect_meta.offset; + +            if( alloc.mask[j/8] & (1 << i%8) ) +            { +                os << ::std::setw(2) << ::std::setfill('0') << (int)alloc.data_ptr()[j]; +            } +            else +            { +                os << "--"; +            } +        }      }      else      { diff --git a/tools/standalone_miri/value.hpp b/tools/standalone_miri/value.hpp index 65403a81..9f9e68f4 100644 --- a/tools/standalone_miri/value.hpp +++ b/tools/standalone_miri/value.hpp @@ -6,33 +6,95 @@  #include <vector>  #include <memory>  #include <cstdint> +#include <cassert>  namespace HIR {      struct TypeRef; +    struct Path;  }  class Allocation; +  class AllocationPtr  {      friend class Allocation; -    Allocation* m_ptr; +    void* m_ptr; +public: + +    enum class Ty +    { +        Allocation, +        Function,   // m_ptr is a pointer to the function. +        Unused1, +        Unused2, +    }; + +private: +    AllocationPtr(Allocation* p): +        m_ptr(p) +    { +    }  public:      AllocationPtr(): m_ptr(nullptr) {} +    AllocationPtr(AllocationPtr&& x): m_ptr(x.m_ptr) { +        x.m_ptr = nullptr; +    } +    AllocationPtr(const AllocationPtr& x); +    ~AllocationPtr(); +    static AllocationPtr new_fcn(::HIR::Path p); + +    AllocationPtr& operator=(AllocationPtr&& x) { +        this->~AllocationPtr(); +        this->m_ptr = x.m_ptr; +        x.m_ptr = nullptr; +        return *this; +    }      operator bool() const { return m_ptr != 0; } -    Allocation& operator*() { return *m_ptr; } -    Allocation* operator->() { return m_ptr; } +    bool is_alloc() { +        return *this && get_ty() == Ty::Allocation; +    } +    Allocation& alloc() { +        assert(get_ty() == Ty::Allocation); +        return *static_cast<Allocation*>(get_ptr()); +    } +    const Allocation& alloc() const { +        assert(get_ty() == Ty::Allocation); +        return *static_cast<Allocation*>(get_ptr()); +    } +    const ::HIR::Path& fcn() const { +        assert(get_ty() == Ty::Function); +        return *static_cast<const ::HIR::Path*>(get_ptr()); +    } + +    Ty get_ty() const { +        return static_cast<Ty>( reinterpret_cast<uintptr_t>(m_ptr) & 3 ); +    } +private: +    void* get_ptr() const { +        return reinterpret_cast<void*>( reinterpret_cast<uintptr_t>(m_ptr) & ~3 ); +    }  };  struct Relocation  { +    // Offset within parent allocation where this relocation is performed. +    // TODO: Size?      size_t  slot_ofs;      AllocationPtr   backing_alloc;  };  class Allocation  { +    friend class AllocationPtr;      size_t  refcount; +    // TODO: Read-only flag?  public: +    static AllocationPtr new_alloc(size_t size); + +    const uint8_t* data_ptr() const { return reinterpret_cast<const uint8_t*>(this->data.data()); } +          uint8_t* data_ptr()       { return reinterpret_cast<      uint8_t*>(this->data.data()); } +      ::std::vector<uint64_t> data; +    ::std::vector<uint8_t> mask;      ::std::vector<Relocation>   relocations;  }; @@ -54,6 +116,7 @@ struct Value      Value();      Value(::HIR::TypeRef ty); +    static Value new_fnptr(const ::HIR::Path& fn_path);      void check_bytes_valid(size_t ofs, size_t size) const;      void mark_bytes_valid(size_t ofs, size_t size); @@ -65,5 +128,8 @@ struct Value      void write_bytes(size_t ofs, const void* src, size_t count);      size_t as_usize() const; +private: +    const uint8_t* data_ptr() const { return allocation ? allocation.alloc().data_ptr() + meta.indirect_meta.offset : meta.direct_data.data; } +          uint8_t* data_ptr()       { return allocation ? allocation.alloc().data_ptr() + meta.indirect_meta.offset : meta.direct_data.data; }  };  extern ::std::ostream& operator<<(::std::ostream& os, const Value& v); diff --git a/vsproject/mrustc.vcxproj.filters b/vsproject/mrustc.vcxproj.filters index 6c0ba794..997e4849 100644 --- a/vsproject/mrustc.vcxproj.filters +++ b/vsproject/mrustc.vcxproj.filters @@ -412,9 +412,6 @@      <ClInclude Include="..\src\hir_expand\main_bindings.hpp">        <Filter>Header Files</Filter>      </ClInclude> -    <ClInclude Include="..\src\hir_typeck\main_bindings.hpp"> -      <Filter>Header Files</Filter> -    </ClInclude>      <ClInclude Include="..\src\include\cpp_unpack.h">        <Filter>Header Files</Filter>      </ClInclude> @@ -460,18 +457,9 @@      <ClInclude Include="..\src\parse\lex.hpp">        <Filter>Header Files</Filter>      </ClInclude> -    <ClInclude Include="..\src\parse\parseerror.hpp"> -      <Filter>Header Files</Filter> -    </ClInclude>      <ClInclude Include="..\src\resolve\main_bindings.hpp">        <Filter>Header Files</Filter>      </ClInclude> -    <ClInclude Include="..\src\trans\main_bindings.hpp"> -      <Filter>Header Files</Filter> -    </ClInclude> -    <ClInclude Include="..\src\trans\mangling.hpp"> -      <Filter>Header Files</Filter> -    </ClInclude>      <ClInclude Include="..\src\ast\attrs.hpp">        <Filter>Header Files\ast</Filter>      </ClInclude> @@ -601,6 +589,18 @@      <ClInclude Include="..\src\hir\hir.hpp">        <Filter>Header Files\hir</Filter>      </ClInclude> +    <ClInclude Include="..\src\hir_typeck\main_bindings.hpp"> +      <Filter>Header Files\hir_typeck</Filter> +    </ClInclude> +    <ClInclude Include="..\src\trans\main_bindings.hpp"> +      <Filter>Header Files\trans</Filter> +    </ClInclude> +    <ClInclude Include="..\src\trans\mangling.hpp"> +      <Filter>Header Files\trans</Filter> +    </ClInclude> +    <ClInclude Include="..\src\parse\parseerror.hpp"> +      <Filter>Header Files\parse</Filter> +    </ClInclude>    </ItemGroup>    <ItemGroup>      <None Include="packages.config" /> diff --git a/vsproject/standalone_miri/standalone_miri.vcxproj b/vsproject/standalone_miri/standalone_miri.vcxproj index e992e3df..ed5dc733 100644 --- a/vsproject/standalone_miri/standalone_miri.vcxproj +++ b/vsproject/standalone_miri/standalone_miri.vcxproj @@ -90,6 +90,7 @@        <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>        <SDLCheck>true</SDLCheck>        <AdditionalIncludeDirectories>$(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> +      <TreatSpecificWarningsAsErrors>4062;4061;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>      </ClCompile>      <Link>        <SubSystem>Console</SubSystem> @@ -105,6 +106,7 @@        <PreprocessorDefinitions>_DEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>        <SDLCheck>true</SDLCheck>        <AdditionalIncludeDirectories>$(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> +      <TreatSpecificWarningsAsErrors>4062;4061;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>      </ClCompile>      <Link>        <SubSystem>Console</SubSystem> @@ -122,6 +124,7 @@        <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>        <SDLCheck>true</SDLCheck>        <AdditionalIncludeDirectories>$(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> +      <TreatSpecificWarningsAsErrors>4062;4061;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>      </ClCompile>      <Link>        <SubSystem>Console</SubSystem> @@ -141,6 +144,7 @@        <PreprocessorDefinitions>NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>        <SDLCheck>true</SDLCheck>        <AdditionalIncludeDirectories>$(SolutionDir)..\src\include;$(SolutionDir)..\tools\standalone_miri;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories> +      <TreatSpecificWarningsAsErrors>4062;4061;%(TreatSpecificWarningsAsErrors)</TreatSpecificWarningsAsErrors>      </ClCompile>      <Link>        <SubSystem>Console</SubSystem> @@ -153,6 +157,7 @@      <Text Include="ReadMe.txt" />    </ItemGroup>    <ItemGroup> +    <ClInclude Include="..\..\tools\standalone_miri\debug.h" />      <ClInclude Include="..\..\tools\standalone_miri\hir_sim.hpp" />      <ClInclude Include="..\..\tools\standalone_miri\lex.hpp" />      <ClInclude Include="..\..\tools\standalone_miri\module_tree.hpp" /> | 
