Search code examples
.netc++-clireflection.emit

Wrong type conversion in reflection emit


I'm creating a simple compiler in C++/CLI to generate a simple il code... but, when I try to build the compiler, the compiler return the this erro:

1>------ Build started: Project: dnccpp, Configuration: Debug Win32 ------
1>  CodeGen.cpp
1>CodeGen.cpp(159): error C2664: 'void System::Reflection::Emit::ILGenerator::Emit(System::Reflection::Emit::OpCode,System::Reflection::Emit::LocalBuilder ^)' : cannot convert argument 2 from 'System::Int32 ^' to 'unsigned char'
1>          No user-defined-conversion operator available, or
1>          There is no context in which this conversion is possible
1>CodeGen.cpp(161): error C2664: 'void System::Reflection::Emit::ILGenerator::Emit(System::Reflection::Emit::OpCode,System::Reflection::Emit::LocalBuilder ^)' : cannot convert argument 2 from 'System::Double ^' to 'unsigned char'
1>          No user-defined-conversion operator available, or
1>          There is no context in which this conversion is possible
========== Build: 0 succeeded, 1 failed, 1 up-to-date, 0 skipped ==========

I can't use the "unsigned char" in argument, the compiler will generate a wrong code for this...

void CodeGenerator::GenExpr(Expr^ expr, Type^ expectedType, ILGenerator^ il, array<Type^>^ argTypes)
{
    Type^ deliveredType;

    if (dynamic_cast<Literal^>(expr) != nullptr)
    {
        Object^ val = ((Literal^)expr)->value;
        deliveredType = val->GetType();
        if (dynamic_cast<String^>(val) != nullptr)
            il->Emit(OpCodes::Ldstr, (String^)val);
        else if (dynamic_cast<Int32^>(val) != nullptr)
            il->Emit(OpCodes::Ldc_I4, (int^)val);
        else if (dynamic_cast<Double^>(val) != nullptr)
            il->Emit(OpCodes::Ldc_R8, (double^)val);
    }
}

Solution

  • None of the framework code (Reflection Emit included) uses strongly-typed boxed values.

    Get rid of the ^ from Int32^, Double^, double^ and int^.