aboutsummaryrefslogtreecommitdiff
path: root/clang/lib/AST/ByteCode/Compiler.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/AST/ByteCode/Compiler.cpp')
-rw-r--r--clang/lib/AST/ByteCode/Compiler.cpp113
1 files changed, 63 insertions, 50 deletions
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index 9fe4803..c5ac402 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -748,7 +748,8 @@ bool Compiler<Emitter>::VisitFloatingLiteral(const FloatingLiteral *E) {
if (DiscardResult)
return true;
- return this->emitConstFloat(E->getValue(), E);
+ APFloat F = E->getValue();
+ return this->emitFloat(F, E);
}
template <class Emitter>
@@ -4185,13 +4186,14 @@ bool Compiler<Emitter>::visitZeroInitializer(PrimType T, QualType QT,
nullptr, E);
case PT_MemberPtr:
return this->emitNullMemberPtr(0, nullptr, E);
- case PT_Float:
- return this->emitConstFloat(APFloat::getZero(Ctx.getFloatSemantics(QT)), E);
+ case PT_Float: {
+ APFloat F = APFloat::getZero(Ctx.getFloatSemantics(QT));
+ return this->emitFloat(F, E);
+ }
case PT_FixedPoint: {
auto Sem = Ctx.getASTContext().getFixedPointSemantics(E->getType());
return this->emitConstFixedPoint(FixedPoint::zero(Sem), E);
}
- llvm_unreachable("Implement");
}
llvm_unreachable("unknown primitive type");
}
@@ -4674,10 +4676,7 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
if (!visitInitializer(Init))
return false;
- if (!this->emitFinishInit(Init))
- return false;
-
- return this->emitPopPtr(Init);
+ return this->emitFinishInitGlobal(Init);
};
DeclScope<Emitter> LocalScope(this, VD);
@@ -4698,51 +4697,45 @@ VarCreationState Compiler<Emitter>::visitVarDecl(const VarDecl *VD,
return false;
return !Init || (checkDecl() && initGlobal(*GlobalIndex));
- } else {
- InitLinkScope<Emitter> ILS(this, InitLink::Decl(VD));
-
- if (VarT) {
- unsigned Offset = this->allocateLocalPrimitive(
- VD, *VarT, VD->getType().isConstQualified(), nullptr,
- ScopeKind::Block, IsConstexprUnknown);
- if (Init) {
- // If this is a toplevel declaration, create a scope for the
- // initializer.
- if (Toplevel) {
- LocalScope<Emitter> Scope(this);
- if (!this->visit(Init))
- return false;
- return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
- } else {
- if (!this->visit(Init))
- return false;
- return this->emitSetLocal(*VarT, Offset, VD);
- }
- }
- } else {
- if (std::optional<unsigned> Offset =
- this->allocateLocal(VD, VD->getType(), nullptr, ScopeKind::Block,
- IsConstexprUnknown)) {
- if (!Init)
- return true;
+ }
+ // Local variables.
+ InitLinkScope<Emitter> ILS(this, InitLink::Decl(VD));
- if (!this->emitGetPtrLocal(*Offset, Init))
+ if (VarT) {
+ unsigned Offset = this->allocateLocalPrimitive(
+ VD, *VarT, VD->getType().isConstQualified(), nullptr, ScopeKind::Block,
+ IsConstexprUnknown);
+ if (Init) {
+ // If this is a toplevel declaration, create a scope for the
+ // initializer.
+ if (Toplevel) {
+ LocalScope<Emitter> Scope(this);
+ if (!this->visit(Init))
return false;
-
- if (!visitInitializer(Init))
+ return this->emitSetLocal(*VarT, Offset, VD) && Scope.destroyLocals();
+ } else {
+ if (!this->visit(Init))
return false;
+ return this->emitSetLocal(*VarT, Offset, VD);
+ }
+ }
+ } else {
+ if (std::optional<unsigned> Offset = this->allocateLocal(
+ VD, VD->getType(), nullptr, ScopeKind::Block, IsConstexprUnknown)) {
+ if (!Init)
+ return true;
- if (!this->emitFinishInit(Init))
- return false;
+ if (!this->emitGetPtrLocal(*Offset, Init))
+ return false;
- return this->emitPopPtr(Init);
- }
- return false;
+ if (!visitInitializer(Init))
+ return false;
+
+ return this->emitFinishInitPop(Init);
}
- return true;
+ return false;
}
-
- return false;
+ return true;
}
template <class Emitter>
@@ -4751,8 +4744,10 @@ bool Compiler<Emitter>::visitAPValue(const APValue &Val, PrimType ValType,
assert(!DiscardResult);
if (Val.isInt())
return this->emitConst(Val.getInt(), ValType, E);
- else if (Val.isFloat())
- return this->emitConstFloat(Val.getFloat(), E);
+ else if (Val.isFloat()) {
+ APFloat F = Val.getFloat();
+ return this->emitFloat(F, E);
+ }
if (Val.isLValue()) {
if (Val.isNullPointer())
@@ -6133,8 +6128,10 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
if (!this->emitLoadFloat(E))
return false;
- if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
+ APFloat F(TargetSemantics, 1);
+ if (!this->emitFloat(F, E))
return false;
+
if (!this->emitAddf(getFPOptions(E), E))
return false;
if (!this->emitStoreFloat(E))
@@ -6176,8 +6173,10 @@ bool Compiler<Emitter>::VisitUnaryOperator(const UnaryOperator *E) {
const auto &TargetSemantics = Ctx.getFloatSemantics(E->getType());
if (!this->emitLoadFloat(E))
return false;
- if (!this->emitConstFloat(llvm::APFloat(TargetSemantics, 1), E))
+ APFloat F(TargetSemantics, 1);
+ if (!this->emitFloat(F, E))
return false;
+
if (!this->emitSubf(getFPOptions(E), E))
return false;
if (!this->emitStoreFloat(E))
@@ -6953,6 +6952,20 @@ bool Compiler<Emitter>::emitDummyPtr(const DeclTy &D, const Expr *E) {
return true;
}
+template <class Emitter>
+bool Compiler<Emitter>::emitFloat(const APFloat &F, const Expr *E) {
+ assert(!DiscardResult && "Should've been checked before");
+
+ if (Floating::singleWord(F.getSemantics()))
+ return this->emitConstFloat(Floating(F), E);
+
+ APInt I = F.bitcastToAPInt();
+ return this->emitConstFloat(
+ Floating(const_cast<uint64_t *>(I.getRawData()),
+ llvm::APFloatBase::SemanticsToEnum(F.getSemantics())),
+ E);
+}
+
// This function is constexpr if and only if To, From, and the types of
// all subobjects of To and From are types T such that...
// (3.1) - is_union_v<T> is false;