From: Chris Lattner Date: Sat, 22 Sep 2007 18:29:59 +0000 (+0000) Subject: Use APFloat for the representation of FP immediates, ask the target X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=525a05093a4816af961fe2bc6b8a81c17e2e26c2;p=clang Use APFloat for the representation of FP immediates, ask the target for *which* apfloat to use for a particular type. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@42234 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index 6420f0f051..cb5588b4b7 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -190,6 +190,7 @@ ASTContext::getTypeInfo(QualType T, SourceLocation L) { case Type::Builtin: { // FIXME: need to use TargetInfo to derive the target specific sizes. This // implementation will suffice for play with vector support. + const llvm::fltSemantics *F; switch (cast(T)->getKind()) { default: assert(0 && "Unknown builtin type!"); case BuiltinType::Void: @@ -207,9 +208,9 @@ ASTContext::getTypeInfo(QualType T, SourceLocation L) { case BuiltinType::Long: Target.getLongInfo(Size, Align, L); break; case BuiltinType::ULongLong: case BuiltinType::LongLong: Target.getLongLongInfo(Size, Align, L); break; - case BuiltinType::Float: Target.getFloatInfo(Size, Align, L); break; - case BuiltinType::Double: Target.getDoubleInfo(Size, Align, L); break; - case BuiltinType::LongDouble: Target.getLongDoubleInfo(Size, Align,L);break; + case BuiltinType::Float: Target.getFloatInfo(Size, Align, F, L); break; + case BuiltinType::Double: Target.getDoubleInfo(Size, Align, F, L);break; + case BuiltinType::LongDouble:Target.getLongDoubleInfo(Size,Align,F,L);break; } break; } diff --git a/Basic/TargetInfo.cpp b/Basic/TargetInfo.cpp index 1b780108e5..2b0af7ed24 100644 --- a/Basic/TargetInfo.cpp +++ b/Basic/TargetInfo.cpp @@ -15,12 +15,40 @@ #include "clang/Basic/Diagnostic.h" #include "clang/AST/Builtins.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/APFloat.h" #include using namespace clang; void TargetInfoImpl::ANCHOR() {} // out-of-line virtual method for class. +//===----------------------------------------------------------------------===// +// FIXME: These are temporary hacks, they should revector into the +// TargetInfoImpl. + +void TargetInfo::getFloatInfo(uint64_t &Size, unsigned &Align, + const llvm::fltSemantics *&Format, + SourceLocation Loc) { + Align = 32; // FIXME: implement correctly. + Size = 32; + Format = &llvm::APFloat::IEEEsingle; +} +void TargetInfo::getDoubleInfo(uint64_t &Size, unsigned &Align, + const llvm::fltSemantics *&Format, + SourceLocation Loc) { + Size = Align = 64; // FIXME: implement correctly. + Format = &llvm::APFloat::IEEEdouble; +} +void TargetInfo::getLongDoubleInfo(uint64_t &Size, unsigned &Align, + const llvm::fltSemantics *&Format, + SourceLocation Loc) { + Size = 80; Align = 32; // FIXME: implement correctly. + Format = &llvm::APFloat::x87DoubleExtended; +} + + +//===----------------------------------------------------------------------===// + /// DiagnoseNonPortability - When a use of a non-portable target feature is /// used, this method emits the diagnostic and marks the translation unit as /// non-portable. diff --git a/Lex/LiteralSupport.cpp b/Lex/LiteralSupport.cpp index c2bdd8e5f5..3449c2769a 100644 --- a/Lex/LiteralSupport.cpp +++ b/Lex/LiteralSupport.cpp @@ -17,7 +17,6 @@ #include "clang/Basic/Diagnostic.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/TargetInfo.h" -#include "llvm/ADT/APInt.h" #include "llvm/ADT/StringExtras.h" using namespace clang; @@ -411,11 +410,12 @@ bool NumericLiteralParser::GetIntegerValue(llvm::APInt &Val) { } // GetFloatValue - Poor man's floatvalue (FIXME). -float NumericLiteralParser::GetFloatValue() { +llvm::APFloat NumericLiteralParser:: +GetFloatValue(const llvm::fltSemantics &Format) { char floatChars[256]; strncpy(floatChars, ThisTokBegin, ThisTokEnd-ThisTokBegin); floatChars[ThisTokEnd-ThisTokBegin] = '\0'; - return (float)strtod(floatChars, 0); + return llvm::APFloat(Format, floatChars); } void NumericLiteralParser::Diag(SourceLocation Loc, unsigned DiagID, diff --git a/Sema/SemaExpr.cpp b/Sema/SemaExpr.cpp index 11c3eccb36..15bf4fd0cb 100644 --- a/Sema/SemaExpr.cpp +++ b/Sema/SemaExpr.cpp @@ -150,9 +150,23 @@ Action::ExprResult Sema::ActOnNumericConstant(const Token &Tok) { Expr *Res; if (Literal.isFloatingLiteral()) { - // FIXME: handle float values > 32 (including compute the real type...). - QualType Ty = Literal.isFloat ? Context.FloatTy : Context.DoubleTy; - Res = new FloatingLiteral(Literal.GetFloatValue(), Ty, Tok.getLocation()); + QualType Ty; + const llvm::fltSemantics *Format; + uint64_t Size; unsigned Align; + + if (Literal.isFloat) { + Ty = Context.FloatTy; + Context.Target.getFloatInfo(Size, Align, Format, Tok.getLocation()); + } else if (Literal.isLong) { + Ty = Context.LongDoubleTy; + Context.Target.getLongDoubleInfo(Size, Align, Format, Tok.getLocation()); + } else { + Ty = Context.DoubleTy; + Context.Target.getDoubleInfo(Size, Align, Format, Tok.getLocation()); + } + + Res = new FloatingLiteral(Literal.GetFloatValue(*Format), Ty, + Tok.getLocation()); } else if (!Literal.isIntegerLiteral()) { return ExprResult(true); } else { diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 24eecf597c..08b2b6c036 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -18,6 +18,7 @@ #include "clang/AST/Type.h" #include "clang/AST/Decl.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/APFloat.h" namespace clang { class IdentifierInfo; @@ -216,13 +217,13 @@ public: }; class FloatingLiteral : public Expr { - float Value; // FIXME: Change to APFloat + llvm::APFloat Value; SourceLocation Loc; public: - FloatingLiteral(float value, QualType type, SourceLocation l) - : Expr(FloatingLiteralClass, type), Value(value), Loc(l) {} + FloatingLiteral(const llvm::APFloat &V, QualType Type, SourceLocation L) + : Expr(FloatingLiteralClass, Type), Value(V), Loc(L) {} - float getValue() const { return Value; } + float getValue() const { return Value.convertToDouble(); } virtual SourceRange getSourceRange() const { return SourceRange(Loc); } diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h index 72cde09c38..f437e4b712 100644 --- a/include/clang/Basic/TargetInfo.h +++ b/include/clang/Basic/TargetInfo.h @@ -19,6 +19,8 @@ #include #include +namespace llvm { struct fltSemantics; } + namespace clang { class TargetInfoImpl; @@ -148,23 +150,17 @@ public: Size = Align = 64; // FIXME: implement correctly. } - /// getFloatInfo - Return the size of 'float' for this target, in bits. - void getFloatInfo(uint64_t &Size, unsigned &Align, SourceLocation Loc) { - Align = 32; // FIXME: implement correctly. - Size = 32; - } + /// getFloatInfo - Characterize 'float' for this target. + void getFloatInfo(uint64_t &Size, unsigned &Align, + const llvm::fltSemantics *&Format, SourceLocation Loc); - /// getDoubleInfo - Return the size of 'double' for this target, in bits. - void getDoubleInfo(uint64_t &Size, unsigned &Align, SourceLocation Loc) { - Size = Align = 64; // FIXME: implement correctly. - } + /// getDoubleInfo - Characterize 'double' for this target. + void getDoubleInfo(uint64_t &Size, unsigned &Align, + const llvm::fltSemantics *&Format, SourceLocation Loc); - /// getLongDoubleInfo - Return the size of 'long double' for this target, in - /// bits. + /// getLongDoubleInfo - Characterize 'long double' for this target. void getLongDoubleInfo(uint64_t &Size, unsigned &Align, - SourceLocation Loc) { - Size = Align = 64; // FIXME: implement correctly. - } + const llvm::fltSemantics *&Format, SourceLocation Loc); /// getWCharInfo - Return the size of wchar_t in bits. /// diff --git a/include/clang/Lex/LiteralSupport.h b/include/clang/Lex/LiteralSupport.h index 9c4c4cd924..dde2d91976 100644 --- a/include/clang/Lex/LiteralSupport.h +++ b/include/clang/Lex/LiteralSupport.h @@ -20,6 +20,8 @@ namespace llvm { class APInt; + class APFloat; + struct fltSemantics; } namespace clang { @@ -73,9 +75,10 @@ public: /// bits of the result and return true. Otherwise, return false. bool GetIntegerValue(llvm::APInt &Val); - /// GetFloatValue - Convert this numeric literal to a float. - /// FIXME: the return value is fixed size - make more general. - float GetFloatValue(); + /// GetFloatValue - Convert this numeric literal to a floating value, using + /// the specified APFloat fltSemantics (specifying float, double, etc). + /// + llvm::APFloat GetFloatValue(const llvm::fltSemantics &Format); private: void Diag(SourceLocation Loc, unsigned DiagID,