Use APFloat for the representation of FP immediates, ask the target
for *which* apfloat to use for a particular type. llvm-svn: 42234
This commit is contained in:
parent
20e469e99b
commit
ec0a6d9be5
|
@ -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<BuiltinType>(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;
|
||||
}
|
||||
|
|
|
@ -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 <set>
|
||||
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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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); }
|
||||
|
||||
|
|
|
@ -19,6 +19,8 @@
|
|||
#include <vector>
|
||||
#include <string>
|
||||
|
||||
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.
|
||||
///
|
||||
|
|
|
@ -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,
|
||||
|
|
Loading…
Reference in New Issue