@@ -470,6 +470,9 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
470470 return this ->emitDecayPtr (*FromT, *ToT, CE);
471471 }
472472
473+ case CK_LValueToRValueBitCast:
474+ return this ->emitBuiltinBitCast (CE);
475+
473476 case CK_IntegralToBoolean:
474477 case CK_FixedPointToBoolean:
475478 case CK_BooleanToSignedIntegral:
@@ -6400,6 +6403,67 @@ bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc,
64006403 return this ->emitRecordDestruction (Desc->ElemRecord , Loc);
64016404}
64026405
6406+ // This function is constexpr if and only if To, From, and the types of
6407+ // all subobjects of To and From are types T such that...
6408+ // (3.1) - is_union_v<T> is false;
6409+ // (3.2) - is_pointer_v<T> is false;
6410+ // (3.3) - is_member_pointer_v<T> is false;
6411+ // (3.4) - is_volatile_v<T> is false; and
6412+ // (3.5) - T has no non-static data members of reference type
6413+ template <class Emitter >
6414+ bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
6415+ const Expr *SubExpr = E->getSubExpr ();
6416+ QualType FromType = SubExpr->getType ();
6417+ QualType ToType = E->getType ();
6418+ std::optional<PrimType> ToT = classify (ToType);
6419+
6420+ assert (!DiscardResult && " Implement" );
6421+
6422+ if (ToType->isNullPtrType ()) {
6423+ if (!this ->discard (SubExpr))
6424+ return false ;
6425+
6426+ return this ->emitNullPtr (nullptr , E);
6427+ }
6428+
6429+ if (FromType->isNullPtrType () && ToT) {
6430+ if (!this ->discard (SubExpr))
6431+ return false ;
6432+
6433+ return visitZeroInitializer (*ToT, ToType, E);
6434+ }
6435+ assert (!ToType->isReferenceType ());
6436+
6437+ // Get a pointer to the value-to-cast on the stack.
6438+ if (!this ->visit (SubExpr))
6439+ return false ;
6440+
6441+ if (!ToT || ToT == PT_Ptr) {
6442+ // Conversion to an array or record type.
6443+ assert (false && " Implement" );
6444+ }
6445+ assert (ToT);
6446+
6447+ const llvm::fltSemantics *TargetSemantics = nullptr ;
6448+ if (ToT == PT_Float)
6449+ TargetSemantics = &Ctx.getFloatSemantics (ToType);
6450+
6451+ // Conversion to a primitive type. FromType can be another
6452+ // primitive type, or a record/array.
6453+ bool ToTypeIsUChar = (ToType->isSpecificBuiltinType (BuiltinType::UChar) ||
6454+ ToType->isSpecificBuiltinType (BuiltinType::Char_U));
6455+ uint32_t ResultBitWidth = std::max (Ctx.getBitWidth (ToType), 8u );
6456+
6457+ if (!this ->emitBitCast (*ToT, ToTypeIsUChar || ToType->isStdByteType (),
6458+ ResultBitWidth, TargetSemantics, E))
6459+ return false ;
6460+
6461+ if (DiscardResult)
6462+ return this ->emitPop (*ToT, E);
6463+
6464+ return true ;
6465+ }
6466+
64036467namespace clang {
64046468namespace interp {
64056469
0 commit comments