@@ -35,6 +35,16 @@ using namespace solidity;
35
35
using namespace solidity ::util;
36
36
using namespace solidity ::frontend;
37
37
38
+ string YulUtilFunctions::identityFunction ()
39
+ {
40
+ string functionName = " identity" ;
41
+ return m_functionCollector.createFunction (" identity" , [&](vector<string>& _args, vector<string>& _rets) {
42
+ _args.push_back (" value" );
43
+ _rets.push_back (" ret" );
44
+ return " ret := value" ;
45
+ });
46
+ }
47
+
38
48
string YulUtilFunctions::combineExternalFunctionIdFunction ()
39
49
{
40
50
string functionName = " combine_external_function_id" ;
@@ -3272,48 +3282,38 @@ string YulUtilFunctions::conversionFunction(Type const& _from, Type const& _to)
3272
3282
if (rational->isFractional ())
3273
3283
solAssert (toCategory == Type::Category::FixedPoint, " " );
3274
3284
3275
- if (toCategory == Type::Category::FixedBytes)
3276
- {
3277
- FixedBytesType const & toBytesType = dynamic_cast <FixedBytesType const &>(_to);
3278
- body =
3279
- Whiskers (" converted := <shiftLeft>(<clean>(value))" )
3280
- (" shiftLeft" , shiftLeftFunction (256 - toBytesType.numBytes () * 8 ))
3281
- (" clean" , cleanupFunction (_from))
3282
- .render ();
3283
- }
3284
- else if (toCategory == Type::Category::Enum)
3285
- body =
3286
- Whiskers (" converted := <cleanEnum>(<cleanInt>(value))" )
3287
- (" cleanEnum" , cleanupFunction (_to))
3288
- (" cleanInt" , cleanupFunction (_from))
3289
- .render ();
3290
- else if (toCategory == Type::Category::FixedPoint)
3291
- solUnimplemented (" Not yet implemented - FixedPointType." );
3292
- else if (toCategory == Type::Category::Address || toCategory == Type::Category::Contract)
3285
+ if (toCategory == Type::Category::Address || toCategory == Type::Category::Contract)
3293
3286
body =
3294
3287
Whiskers (" converted := <convert>(value)" )
3295
3288
(" convert" , conversionFunction (_from, IntegerType (160 )))
3296
3289
.render ();
3297
- else if (toCategory == Type::Category::Integer)
3290
+ else
3298
3291
{
3299
- IntegerType const & to = dynamic_cast <IntegerType const &>(_to);
3300
-
3301
- // Clean according to the "to" type, except if this is
3302
- // a widening conversion.
3303
- IntegerType const * cleanupType = &to;
3304
- if (fromCategory == Type::Category::Integer)
3292
+ Whiskers bodyTemplate (" converted := <cleanOutput>(<convert>(<cleanInput>(value)))" );
3293
+ bodyTemplate (" cleanInput" , cleanupFunction (_from));
3294
+ bodyTemplate (" cleanOutput" , cleanupFunction (_to));
3295
+ string convert;
3296
+
3297
+ if (auto const * toFixedBytes = dynamic_cast <FixedBytesType const *>(&_to))
3298
+ convert = shiftLeftFunction (256 - toFixedBytes->numBytes () * 8 );
3299
+ else if (dynamic_cast <FixedPointType const *>(&_to))
3300
+ solUnimplementedAssert (false , " " );
3301
+ else if (dynamic_cast <IntegerType const *>(&_to))
3305
3302
{
3306
- IntegerType const & from = dynamic_cast <IntegerType const &>(_from);
3307
- if (to.numBits () > from.numBits ())
3308
- cleanupType = &from;
3303
+ solUnimplementedAssert (fromCategory != Type::Category::FixedPoint, " " );
3304
+ convert = identityFunction ();
3309
3305
}
3310
- body =
3311
- Whiskers (" converted := <cleanInt>(value)" )
3312
- (" cleanInt" , cleanupFunction (*cleanupType))
3313
- .render ();
3306
+ else if (toCategory == Type::Category::Enum)
3307
+ {
3308
+ solAssert (fromCategory != Type::Category::FixedPoint, " " );
3309
+ convert = identityFunction ();
3310
+ }
3311
+ else
3312
+ solAssert (false , " " );
3313
+ solAssert (!convert.empty (), " " );
3314
+ bodyTemplate (" convert" , convert);
3315
+ body = bodyTemplate.render ();
3314
3316
}
3315
- else
3316
- solAssert (false , " " );
3317
3317
break ;
3318
3318
}
3319
3319
case Type::Category::Bool:
0 commit comments