aboutsummaryrefslogtreecommitdiff
path: root/clang/include
diff options
context:
space:
mode:
authorLeonard Chan <leonardchan@google.com>2019-01-16 18:53:05 +0000
committerLeonard Chan <leonardchan@google.com>2019-01-16 18:53:05 +0000
commit86285d2e17ea669fe53853215759c554ad101d31 (patch)
treebbedc37df9ec3971359b80ed5b9c5503f576b213 /clang/include
parent8265e390e740f0fb7464f7c20bd38d55ee145dd4 (diff)
[Fixed Point Arithmetic] Add APFixedPoint to APValue
This adds APFixedPoint to the union of values that can be represented with an APValue. Differential Revision: https://reviews.llvm.org/D56746 llvm-svn: 351368
Diffstat (limited to 'clang/include')
-rw-r--r--clang/include/clang/AST/APValue.h23
-rw-r--r--clang/include/clang/AST/Type.h2
-rw-r--r--clang/include/clang/Basic/FixedPoint.h22
3 files changed, 46 insertions, 1 deletions
diff --git a/clang/include/clang/AST/APValue.h b/clang/include/clang/AST/APValue.h
index d4057c9da5f3..f540ad739835 100644
--- a/clang/include/clang/AST/APValue.h
+++ b/clang/include/clang/AST/APValue.h
@@ -14,6 +14,7 @@
#ifndef LLVM_CLANG_AST_APVALUE_H
#define LLVM_CLANG_AST_APVALUE_H
+#include "clang/Basic/FixedPoint.h"
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/APFloat.h"
#include "llvm/ADT/APSInt.h"
@@ -43,6 +44,7 @@ public:
Uninitialized,
Int,
Float,
+ FixedPoint,
ComplexInt,
ComplexFloat,
LValue,
@@ -175,6 +177,9 @@ public:
explicit APValue(APFloat F) : Kind(Uninitialized) {
MakeFloat(); setFloat(std::move(F));
}
+ explicit APValue(APFixedPoint FX) : Kind(Uninitialized) {
+ MakeFixedPoint(std::move(FX));
+ }
explicit APValue(const APValue *E, unsigned N) : Kind(Uninitialized) {
MakeVector(); setVector(E, N);
}
@@ -233,6 +238,7 @@ public:
bool isUninit() const { return Kind == Uninitialized; }
bool isInt() const { return Kind == Int; }
bool isFloat() const { return Kind == Float; }
+ bool isFixedPoint() const { return Kind == FixedPoint; }
bool isComplexInt() const { return Kind == ComplexInt; }
bool isComplexFloat() const { return Kind == ComplexFloat; }
bool isLValue() const { return Kind == LValue; }
@@ -265,6 +271,14 @@ public:
return const_cast<APValue*>(this)->getFloat();
}
+ APFixedPoint &getFixedPoint() {
+ assert(isFixedPoint() && "Invalid accessor");
+ return *(APFixedPoint *)(char *)Data.buffer;
+ }
+ const APFixedPoint &getFixedPoint() const {
+ return const_cast<APValue *>(this)->getFixedPoint();
+ }
+
APSInt &getComplexIntReal() {
assert(isComplexInt() && "Invalid accessor");
return ((ComplexAPSInt*)(char*)Data.buffer)->Real;
@@ -406,6 +420,10 @@ public:
assert(isFloat() && "Invalid accessor");
*(APFloat *)(char *)Data.buffer = std::move(F);
}
+ void setFixedPoint(APFixedPoint FX) {
+ assert(isFixedPoint() && "Invalid accessor");
+ *(APFixedPoint *)(char *)Data.buffer = std::move(FX);
+ }
void setVector(const APValue *E, unsigned N) {
assert(isVector() && "Invalid accessor");
((Vec*)(char*)Data.buffer)->Elts = new APValue[N];
@@ -465,6 +483,11 @@ private:
new ((void*)(char*)Data.buffer) APFloat(0.0);
Kind = Float;
}
+ void MakeFixedPoint(APFixedPoint &&FX) {
+ assert(isUninit() && "Bad state change");
+ new ((void *)(char *)Data.buffer) APFixedPoint(std::move(FX));
+ Kind = FixedPoint;
+ }
void MakeVector() {
assert(isUninit() && "Bad state change");
new ((void*)(char*)Data.buffer) Vec();
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 4c48473d2e00..0ebd2bc86fe6 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -6848,6 +6848,8 @@ QualType DecayedType::getPointeeType() const {
// Get the decimal string representation of a fixed point type, represented
// as a scaled integer.
+// TODO: At some point, we should change the arguments to instead just accept an
+// APFixedPoint instead of APSInt and scale.
void FixedPointValueToString(SmallVectorImpl<char> &Str, llvm::APSInt Val,
unsigned Scale);
diff --git a/clang/include/clang/Basic/FixedPoint.h b/clang/include/clang/Basic/FixedPoint.h
index bfba55a04103..174f7cc7d0fc 100644
--- a/clang/include/clang/Basic/FixedPoint.h
+++ b/clang/include/clang/Basic/FixedPoint.h
@@ -18,6 +18,7 @@
#define LLVM_CLANG_BASIC_FIXEDPOINT_H
#include "llvm/ADT/APSInt.h"
+#include "llvm/ADT/SmallString.h"
#include "llvm/Support/raw_ostream.h"
namespace clang {
@@ -104,19 +105,25 @@ class APFixedPoint {
: APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()),
Sema) {}
+ // Zero initialization.
+ APFixedPoint(const FixedPointSemantics &Sema) : APFixedPoint(0, Sema) {}
+
llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned()); }
inline unsigned getWidth() const { return Sema.getWidth(); }
inline unsigned getScale() const { return Sema.getScale(); }
inline bool isSaturated() const { return Sema.isSaturated(); }
inline bool isSigned() const { return Sema.isSigned(); }
inline bool hasPadding() const { return Sema.hasUnsignedPadding(); }
+ FixedPointSemantics getSemantics() const { return Sema; }
+
+ bool getBoolValue() const { return Val.getBoolValue(); }
// Convert this number to match the semantics provided.
APFixedPoint convert(const FixedPointSemantics &DstSema) const;
APFixedPoint shr(unsigned Amt) const {
return APFixedPoint(Val >> Amt, Sema);
- }
+ }
APFixedPoint shl(unsigned Amt) const {
return APFixedPoint(Val << Amt, Sema);
@@ -129,6 +136,13 @@ class APFixedPoint {
return Val >> getScale();
}
+ void toString(llvm::SmallVectorImpl<char> &Str) const;
+ std::string toString() const {
+ llvm::SmallString<40> S;
+ toString(S);
+ return S.str();
+ }
+
// If LHS > RHS, return 1. If LHS == RHS, return 0. If LHS < RHS, return -1.
int compare(const APFixedPoint &Other) const;
bool operator==(const APFixedPoint &Other) const {
@@ -154,6 +168,12 @@ private:
FixedPointSemantics Sema;
};
+inline llvm::raw_ostream &operator<<(llvm::raw_ostream &OS,
+ const APFixedPoint &FX) {
+ OS << FX.toString();
+ return OS;
+}
+
} // namespace clang
#endif