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