@@ -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:
@@ -6426,6 +6429,66 @@ bool Compiler<Emitter>::emitDummyPtr(const DeclTy &D, const Expr *E) {
64266429 return this ->emitDecayPtr (PT_Ptr, PT, E);
64276430 return false ;
64286431 }
6432+ return true ;
6433+ }
6434+
6435+ // This function is constexpr if and only if To, From, and the types of
6436+ // all subobjects of To and From are types T such that...
6437+ // (3.1) - is_union_v<T> is false;
6438+ // (3.2) - is_pointer_v<T> is false;
6439+ // (3.3) - is_member_pointer_v<T> is false;
6440+ // (3.4) - is_volatile_v<T> is false; and
6441+ // (3.5) - T has no non-static data members of reference type
6442+ template <class Emitter >
6443+ bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
6444+ const Expr *SubExpr = E->getSubExpr ();
6445+ QualType FromType = SubExpr->getType ();
6446+ QualType ToType = E->getType ();
6447+ std::optional<PrimType> ToT = classify (ToType);
6448+
6449+ assert (!DiscardResult && " Implement DiscardResult mode for bitcasts." );
6450+
6451+ if (ToType->isNullPtrType ()) {
6452+ if (!this ->discard (SubExpr))
6453+ return false ;
6454+
6455+ return this ->emitNullPtr (nullptr , E);
6456+ }
6457+
6458+ if (FromType->isNullPtrType () && ToT) {
6459+ if (!this ->discard (SubExpr))
6460+ return false ;
6461+
6462+ return visitZeroInitializer (*ToT, ToType, E);
6463+ }
6464+ assert (!ToType->isReferenceType ());
6465+
6466+ // Get a pointer to the value-to-cast on the stack.
6467+ if (!this ->visit (SubExpr))
6468+ return false ;
6469+
6470+ if (!ToT || ToT == PT_Ptr) {
6471+ // Conversion to an array or record type.
6472+ assert (false && " Implement bitcast to pointers." );
6473+ }
6474+ assert (ToT);
6475+
6476+ const llvm::fltSemantics *TargetSemantics = nullptr ;
6477+ if (ToT == PT_Float)
6478+ TargetSemantics = &Ctx.getFloatSemantics (ToType);
6479+
6480+ // Conversion to a primitive type. FromType can be another
6481+ // primitive type, or a record/array.
6482+ bool ToTypeIsUChar = (ToType->isSpecificBuiltinType (BuiltinType::UChar) ||
6483+ ToType->isSpecificBuiltinType (BuiltinType::Char_U));
6484+ uint32_t ResultBitWidth = std::max (Ctx.getBitWidth (ToType), 8u );
6485+
6486+ if (!this ->emitBitCast (*ToT, ToTypeIsUChar || ToType->isStdByteType (),
6487+ ResultBitWidth, TargetSemantics, E))
6488+ return false ;
6489+
6490+ if (DiscardResult)
6491+ return this ->emitPop (*ToT, E);
64296492
64306493 return true ;
64316494}
0 commit comments