@@ -759,7 +759,8 @@ bool Compiler<Emitter>::VisitFloatingLiteral(const FloatingLiteral *E) {
759
759
if (DiscardResult)
760
760
return true ;
761
761
762
- return this ->emitConstFloat (E->getValue (), E);
762
+ APFloat F = E->getValue ();
763
+ return this ->emitFloat (F, E);
763
764
}
764
765
765
766
template <class Emitter >
@@ -4196,8 +4197,10 @@ bool Compiler<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
4196
4197
nullptr , E);
4197
4198
case PT_MemberPtr:
4198
4199
return this ->emitNullMemberPtr (0 , nullptr , E);
4199
- case PT_Float:
4200
- return this ->emitConstFloat (APFloat::getZero (Ctx.getFloatSemantics (QT)), E);
4200
+ case PT_Float: {
4201
+ APFloat F = APFloat::getZero (Ctx.getFloatSemantics (QT));
4202
+ return this ->emitFloat (F, E);
4203
+ }
4201
4204
case PT_FixedPoint: {
4202
4205
auto Sem = Ctx.getASTContext ().getFixedPointSemantics (E->getType ());
4203
4206
return this ->emitConstFixedPoint (FixedPoint::zero (Sem), E);
@@ -4685,10 +4688,7 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
4685
4688
if (!visitInitializer (Init))
4686
4689
return false ;
4687
4690
4688
- if (!this ->emitFinishInit (Init))
4689
- return false ;
4690
-
4691
- return this ->emitPopPtr (Init);
4691
+ return this ->emitFinishInitGlobal (Init);
4692
4692
};
4693
4693
4694
4694
DeclScope<Emitter> LocalScope (this , VD);
@@ -4709,51 +4709,45 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
4709
4709
return false ;
4710
4710
4711
4711
return !Init || (checkDecl () && initGlobal (*GlobalIndex));
4712
- } else {
4713
- InitLinkScope<Emitter> ILS (this , InitLink::Decl (VD));
4714
-
4715
- if (VarT) {
4716
- unsigned Offset = this ->allocateLocalPrimitive (
4717
- VD, *VarT, VD->getType ().isConstQualified (), nullptr ,
4718
- ScopeKind::Block, IsConstexprUnknown);
4719
- if (Init) {
4720
- // If this is a toplevel declaration, create a scope for the
4721
- // initializer.
4722
- if (Toplevel) {
4723
- LocalScope<Emitter> Scope (this );
4724
- if (!this ->visit (Init))
4725
- return false ;
4726
- return this ->emitSetLocal (*VarT, Offset, VD) && Scope.destroyLocals ();
4727
- } else {
4728
- if (!this ->visit (Init))
4729
- return false ;
4730
- return this ->emitSetLocal (*VarT, Offset, VD);
4731
- }
4732
- }
4733
- } else {
4734
- if (std::optional<unsigned > Offset =
4735
- this ->allocateLocal (VD, VD->getType (), nullptr , ScopeKind::Block,
4736
- IsConstexprUnknown)) {
4737
- if (!Init)
4738
- return true ;
4712
+ }
4713
+ // Local variables.
4714
+ InitLinkScope<Emitter> ILS (this , InitLink::Decl (VD));
4739
4715
4740
- if (!this ->emitGetPtrLocal (*Offset, Init))
4716
+ if (VarT) {
4717
+ unsigned Offset = this ->allocateLocalPrimitive (
4718
+ VD, *VarT, VD->getType ().isConstQualified (), nullptr , ScopeKind::Block,
4719
+ IsConstexprUnknown);
4720
+ if (Init) {
4721
+ // If this is a toplevel declaration, create a scope for the
4722
+ // initializer.
4723
+ if (Toplevel) {
4724
+ LocalScope<Emitter> Scope (this );
4725
+ if (!this ->visit (Init))
4741
4726
return false ;
4742
-
4743
- if (!visitInitializer (Init))
4727
+ return this ->emitSetLocal (*VarT, Offset, VD) && Scope.destroyLocals ();
4728
+ } else {
4729
+ if (!this ->visit (Init))
4744
4730
return false ;
4731
+ return this ->emitSetLocal (*VarT, Offset, VD);
4732
+ }
4733
+ }
4734
+ } else {
4735
+ if (std::optional<unsigned > Offset = this ->allocateLocal (
4736
+ VD, VD->getType (), nullptr , ScopeKind::Block, IsConstexprUnknown)) {
4737
+ if (!Init)
4738
+ return true ;
4745
4739
4746
- if (!this ->emitFinishInit ( Init))
4747
- return false ;
4740
+ if (!this ->emitGetPtrLocal (*Offset, Init))
4741
+ return false ;
4748
4742
4749
- return this ->emitPopPtr (Init);
4750
- }
4751
- return false ;
4743
+ if (!visitInitializer (Init))
4744
+ return false ;
4745
+
4746
+ return this ->emitFinishInitPop (Init);
4752
4747
}
4753
- return true ;
4748
+ return false ;
4754
4749
}
4755
-
4756
- return false ;
4750
+ return true ;
4757
4751
}
4758
4752
4759
4753
template <class Emitter >
@@ -4762,8 +4756,10 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,
4762
4756
assert (!DiscardResult);
4763
4757
if (Val.isInt ())
4764
4758
return this ->emitConst (Val.getInt (), ValType, E);
4765
- else if (Val.isFloat ())
4766
- return this ->emitConstFloat (Val.getFloat (), E);
4759
+ else if (Val.isFloat ()) {
4760
+ APFloat F = Val.getFloat ();
4761
+ return this ->emitFloat (F, E);
4762
+ }
4767
4763
4768
4764
if (Val.isLValue ()) {
4769
4765
if (Val.isNullPointer ())
@@ -6144,8 +6140,10 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
6144
6140
const auto &TargetSemantics = Ctx.getFloatSemantics (E->getType ());
6145
6141
if (!this ->emitLoadFloat (E))
6146
6142
return false ;
6147
- if (!this ->emitConstFloat (llvm::APFloat (TargetSemantics, 1 ), E))
6143
+ APFloat F (TargetSemantics, 1 );
6144
+ if (!this ->emitFloat (F, E))
6148
6145
return false ;
6146
+
6149
6147
if (!this ->emitAddf (getFPOptions (E), E))
6150
6148
return false ;
6151
6149
if (!this ->emitStoreFloat (E))
@@ -6187,8 +6185,10 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
6187
6185
const auto &TargetSemantics = Ctx.getFloatSemantics (E->getType ());
6188
6186
if (!this ->emitLoadFloat (E))
6189
6187
return false ;
6190
- if (!this ->emitConstFloat (llvm::APFloat (TargetSemantics, 1 ), E))
6188
+ APFloat F (TargetSemantics, 1 );
6189
+ if (!this ->emitFloat (F, E))
6191
6190
return false ;
6191
+
6192
6192
if (!this ->emitSubf (getFPOptions (E), E))
6193
6193
return false ;
6194
6194
if (!this ->emitStoreFloat (E))
@@ -6964,6 +6964,20 @@ bool Compiler<Emitter>::emitDummyPtr(const DeclTy &D, const Expr *E) {
6964
6964
return true ;
6965
6965
}
6966
6966
6967
+ template <class Emitter >
6968
+ bool Compiler<Emitter>::emitFloat(const APFloat &F, const Expr *E) {
6969
+ assert (!DiscardResult && " Should've been checked before" );
6970
+
6971
+ if (Floating::singleWord (F.getSemantics ()))
6972
+ return this ->emitConstFloat (Floating (F), E);
6973
+
6974
+ APInt I = F.bitcastToAPInt ();
6975
+ return this ->emitConstFloat (
6976
+ Floating (const_cast <uint64_t *>(I.getRawData ()),
6977
+ llvm::APFloatBase::SemanticsToEnum (F.getSemantics ())),
6978
+ E);
6979
+ }
6980
+
6967
6981
// This function is constexpr if and only if To, From, and the types of
6968
6982
// all subobjects of To and From are types T such that...
6969
6983
// (3.1) - is_union_v<T> is false;
0 commit comments