@@ -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:
@@ -6409,6 +6412,67 @@ bool Compiler<Emitter>::emitDestruction(const Descriptor *Desc,
64096412 return this ->emitRecordDestruction (Desc->ElemRecord , Loc);
64106413}
64116414
6415+ // This function is constexpr if and only if To, From, and the types of
6416+ // all subobjects of To and From are types T such that...
6417+ // (3.1) - is_union_v<T> is false;
6418+ // (3.2) - is_pointer_v<T> is false;
6419+ // (3.3) - is_member_pointer_v<T> is false;
6420+ // (3.4) - is_volatile_v<T> is false; and
6421+ // (3.5) - T has no non-static data members of reference type
6422+ template <class Emitter >
6423+ bool Compiler<Emitter>::emitBuiltinBitCast(const CastExpr *E) {
6424+ const Expr *SubExpr = E->getSubExpr ();
6425+ QualType FromType = SubExpr->getType ();
6426+ QualType ToType = E->getType ();
6427+ std::optional<PrimType> ToT = classify (ToType);
6428+
6429+ assert (!DiscardResult && " Implement" );
6430+
6431+ if (ToType->isNullPtrType ()) {
6432+ if (!this ->discard (SubExpr))
6433+ return false ;
6434+
6435+ return this ->emitNullPtr (nullptr , E);
6436+ }
6437+
6438+ if (FromType->isNullPtrType () && ToT) {
6439+ if (!this ->discard (SubExpr))
6440+ return false ;
6441+
6442+ return visitZeroInitializer (*ToT, ToType, E);
6443+ }
6444+ assert (!ToType->isReferenceType ());
6445+
6446+ // Get a pointer to the value-to-cast on the stack.
6447+ if (!this ->visit (SubExpr))
6448+ return false ;
6449+
6450+ if (!ToT || ToT == PT_Ptr) {
6451+ // Conversion to an array or record type.
6452+ assert (false && " Implement" );
6453+ }
6454+ assert (ToT);
6455+
6456+ const llvm::fltSemantics *TargetSemantics = nullptr ;
6457+ if (ToT == PT_Float)
6458+ TargetSemantics = &Ctx.getFloatSemantics (ToType);
6459+
6460+ // Conversion to a primitive type. FromType can be another
6461+ // primitive type, or a record/array.
6462+ bool ToTypeIsUChar = (ToType->isSpecificBuiltinType (BuiltinType::UChar) ||
6463+ ToType->isSpecificBuiltinType (BuiltinType::Char_U));
6464+ uint32_t ResultBitWidth = std::max (Ctx.getBitWidth (ToType), 8u );
6465+
6466+ if (!this ->emitBitCast (*ToT, ToTypeIsUChar || ToType->isStdByteType (),
6467+ ResultBitWidth, TargetSemantics, E))
6468+ return false ;
6469+
6470+ if (DiscardResult)
6471+ return this ->emitPop (*ToT, E);
6472+
6473+ return true ;
6474+ }
6475+
64126476namespace clang {
64136477namespace interp {
64146478
0 commit comments