diff options
author | Tim Northover <Tim.Northover@arm.com> | 2013-01-22 09:46:51 +0000 |
---|---|---|
committer | Tim Northover <Tim.Northover@arm.com> | 2013-01-22 09:46:51 +0000 |
commit | 9ec55f24b8f848bb37a9971100cf2fca379d5572 (patch) | |
tree | fdb28f0db2d5d873ef4c3bbfa1ce7aaddf5b5399 /lib/AST/Expr.cpp | |
parent | 6a94c1ea2d9ee397cc9d75045117a39e8f62235d (diff) |
Switch to APFloat constructor taking fltSemantics.
This change also makes the serialisation store the required semantics,
fixing an issue where PPC128 was always assumed when re-reading a
128-bit value.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173139 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/Expr.cpp')
-rw-r--r-- | lib/AST/Expr.cpp | 41 |
1 files changed, 37 insertions, 4 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index e3ff29d2d0..6888c46ae4 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -646,16 +646,14 @@ FloatingLiteral::FloatingLiteral(ASTContext &C, const llvm::APFloat &V, bool isexact, QualType Type, SourceLocation L) : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false, false, false), Loc(L) { - FloatingLiteralBits.IsIEEE = - &C.getTargetInfo().getLongDoubleFormat() == &llvm::APFloat::IEEEquad; + setSemantics(V.getSemantics()); FloatingLiteralBits.IsExact = isexact; setValue(C, V); } FloatingLiteral::FloatingLiteral(ASTContext &C, EmptyShell Empty) : Expr(FloatingLiteralClass, Empty) { - FloatingLiteralBits.IsIEEE = - &C.getTargetInfo().getLongDoubleFormat() == &llvm::APFloat::IEEEquad; + setRawSemantics(IEEEhalf); FloatingLiteralBits.IsExact = false; } @@ -670,6 +668,41 @@ FloatingLiteral::Create(ASTContext &C, EmptyShell Empty) { return new (C) FloatingLiteral(C, Empty); } +const llvm::fltSemantics &FloatingLiteral::getSemantics() const { + switch(FloatingLiteralBits.Semantics) { + case IEEEhalf: + return llvm::APFloat::IEEEhalf; + case IEEEsingle: + return llvm::APFloat::IEEEsingle; + case IEEEdouble: + return llvm::APFloat::IEEEdouble; + case x87DoubleExtended: + return llvm::APFloat::x87DoubleExtended; + case IEEEquad: + return llvm::APFloat::IEEEquad; + case PPCDoubleDouble: + return llvm::APFloat::PPCDoubleDouble; + } + llvm_unreachable("Unrecognised floating semantics"); +} + +void FloatingLiteral::setSemantics(const llvm::fltSemantics &Sem) { + if (&Sem == &llvm::APFloat::IEEEhalf) + FloatingLiteralBits.Semantics = IEEEhalf; + else if (&Sem == &llvm::APFloat::IEEEsingle) + FloatingLiteralBits.Semantics = IEEEsingle; + else if (&Sem == &llvm::APFloat::IEEEdouble) + FloatingLiteralBits.Semantics = IEEEdouble; + else if (&Sem == &llvm::APFloat::x87DoubleExtended) + FloatingLiteralBits.Semantics = x87DoubleExtended; + else if (&Sem == &llvm::APFloat::IEEEquad) + FloatingLiteralBits.Semantics = IEEEquad; + else if (&Sem == &llvm::APFloat::PPCDoubleDouble) + FloatingLiteralBits.Semantics = PPCDoubleDouble; + else + llvm_unreachable("Unknown floating semantics"); +} + /// getValueAsApproximateDouble - This returns the value as an inaccurate /// double. Note that this may cause loss of precision, but is useful for /// debugging dumps, etc. |