leonardchan updated this revision to Diff 154020.
leonardchan marked 2 inline comments as done.
leonardchan added a comment.

- Renamed `fixedPointSemantics` to `FixedPointSemantics` and hid the members 
behind getters


Repository:
  rC Clang

https://reviews.llvm.org/D48661

Files:
  include/clang/AST/ASTContext.h
  include/clang/Basic/FixedPoint.h
  include/clang/Basic/TargetInfo.h
  lib/AST/ASTContext.cpp
  lib/Basic/CMakeLists.txt
  lib/Basic/FixedPoint.cpp
  lib/Sema/SemaExpr.cpp
  test/Frontend/fixed_point_declarations.c
  unittests/Basic/CMakeLists.txt
  unittests/Basic/FixedPointTest.cpp

Index: unittests/Basic/FixedPointTest.cpp
===================================================================
--- /dev/null
+++ unittests/Basic/FixedPointTest.cpp
@@ -0,0 +1,633 @@
+//===- unittests/Basic/FixedPointTest.cpp -- fixed point number tests -----===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Basic/FixedPoint.h"
+#include "llvm/ADT/APSInt.h"
+#include "gtest/gtest.h"
+
+using clang::APFixedPoint;
+using clang::FixedPointSemantics;
+using llvm::APInt;
+using llvm::APSInt;
+
+namespace {
+
+FixedPointSemantics Saturated(FixedPointSemantics Sema) {
+  Sema.setSaturated(true);
+  return Sema;
+}
+
+FixedPointSemantics getSAccSema() {
+  return FixedPointSemantics(/*width=*/16, /*scale=*/7, /*isSigned=*/true,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getAccSema() {
+  return FixedPointSemantics(/*width=*/32, /*scale=*/15, /*isSigned=*/true,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getLAccSema() {
+  return FixedPointSemantics(/*width=*/64, /*scale=*/31, /*isSigned=*/true,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getSFractSema() {
+  return FixedPointSemantics(/*width=*/8, /*scale=*/7, /*isSigned=*/true,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getFractSema() {
+  return FixedPointSemantics(/*width=*/16, /*scale=*/15, /*isSigned=*/true,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getLFractSema() {
+  return FixedPointSemantics(/*width=*/32, /*scale=*/31, /*isSigned=*/true,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getUSAccSema() {
+  return FixedPointSemantics(/*width=*/16, /*scale=*/8, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getUAccSema() {
+  return FixedPointSemantics(/*width=*/32, /*scale=*/16, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getULAccSema() {
+  return FixedPointSemantics(/*width=*/64, /*scale=*/32, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getUSFractSema() {
+  return FixedPointSemantics(/*width=*/8, /*scale=*/8, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getUFractSema() {
+  return FixedPointSemantics(/*width=*/16, /*scale=*/16, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getULFractSema() {
+  return FixedPointSemantics(/*width=*/32, /*scale=*/32, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/false);
+}
+
+FixedPointSemantics getPadUSAccSema() {
+  return FixedPointSemantics(/*width=*/16, /*scale=*/7, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/true);
+}
+
+FixedPointSemantics getPadUAccSema() {
+  return FixedPointSemantics(/*width=*/32, /*scale=*/15, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/true);
+}
+
+FixedPointSemantics getPadULAccSema() {
+  return FixedPointSemantics(/*width=*/64, /*scale=*/31, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/true);
+}
+
+FixedPointSemantics getPadUSFractSema() {
+  return FixedPointSemantics(/*width=*/8, /*scale=*/7, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/true);
+}
+
+FixedPointSemantics getPadUFractSema() {
+  return FixedPointSemantics(/*width=*/16, /*scale=*/15, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/true);
+}
+
+FixedPointSemantics getPadULFractSema() {
+  return FixedPointSemantics(/*width=*/32, /*scale=*/31, /*isSigned=*/false,
+                             /*isSaturated=*/false,
+                             /*hasUnsignedPadding=*/true);
+}
+
+void CheckUnpaddedMax(const FixedPointSemantics &Sema) {
+  ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(),
+            APSInt::getMaxValue(Sema.getWidth(), !Sema.isSigned()));
+}
+
+void CheckPaddedMax(const FixedPointSemantics &Sema) {
+  ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(),
+            APSInt::getMaxValue(Sema.getWidth(), !Sema.isSigned()) >> 1);
+}
+
+void CheckMin(const FixedPointSemantics &Sema) {
+  ASSERT_EQ(APFixedPoint::getMin(Sema).getValue(),
+            APSInt::getMinValue(Sema.getWidth(), !Sema.isSigned()));
+}
+
+TEST(FixedPointTest, getMax) {
+  CheckUnpaddedMax(getSAccSema());
+  CheckUnpaddedMax(getAccSema());
+  CheckUnpaddedMax(getLAccSema());
+  CheckUnpaddedMax(getUSAccSema());
+  CheckUnpaddedMax(getUAccSema());
+  CheckUnpaddedMax(getULAccSema());
+  CheckUnpaddedMax(getSFractSema());
+  CheckUnpaddedMax(getFractSema());
+  CheckUnpaddedMax(getLFractSema());
+  CheckUnpaddedMax(getUSFractSema());
+  CheckUnpaddedMax(getUFractSema());
+  CheckUnpaddedMax(getULFractSema());
+
+  CheckPaddedMax(getPadUSAccSema());
+  CheckPaddedMax(getPadUAccSema());
+  CheckPaddedMax(getPadULAccSema());
+  CheckPaddedMax(getPadUSFractSema());
+  CheckPaddedMax(getPadUFractSema());
+  CheckPaddedMax(getPadULFractSema());
+}
+
+TEST(FixedPointTest, getMin) {
+  CheckMin(getSAccSema());
+  CheckMin(getAccSema());
+  CheckMin(getLAccSema());
+  CheckMin(getUSAccSema());
+  CheckMin(getUAccSema());
+  CheckMin(getULAccSema());
+  CheckMin(getSFractSema());
+  CheckMin(getFractSema());
+  CheckMin(getLFractSema());
+  CheckMin(getUSFractSema());
+  CheckMin(getUFractSema());
+  CheckMin(getULFractSema());
+
+  CheckMin(getPadUSAccSema());
+  CheckMin(getPadUAccSema());
+  CheckMin(getPadULAccSema());
+  CheckMin(getPadUSFractSema());
+  CheckMin(getPadUFractSema());
+  CheckMin(getPadULFractSema());
+}
+
+void CheckIntPart(const FixedPointSemantics &Sema, int64_t IntPart) {
+  unsigned Scale = Sema.getScale();
+
+  // Value with a fraction
+  APFixedPoint ValWithFract(APInt(Sema.getWidth(),
+                                  (IntPart << Scale) + (1ULL << (Scale - 1)),
+                                  Sema.isSigned()),
+                            Sema);
+  ASSERT_EQ(ValWithFract.getIntPart(), IntPart);
+
+  // Just fraction
+  APFixedPoint JustFract(
+      APInt(Sema.getWidth(), (1ULL << (Scale - 1)), Sema.isSigned()), Sema);
+  ASSERT_EQ(JustFract.getIntPart(), 0);
+
+  // Whole number
+  APFixedPoint WholeNum(
+      APInt(Sema.getWidth(), (IntPart << Scale), Sema.isSigned()), Sema);
+  ASSERT_EQ(WholeNum.getIntPart(), IntPart);
+
+  // Negative
+  if (Sema.isSigned()) {
+    APFixedPoint Negative(
+        APInt(Sema.getWidth(), (IntPart << Scale), Sema.isSigned()), Sema);
+    ASSERT_EQ(Negative.getIntPart(), IntPart);
+  }
+}
+
+void CheckIntPartMin(const FixedPointSemantics &Sema, int64_t Expected) {
+  ASSERT_EQ(APFixedPoint::getMin(Sema).getIntPart(), Expected);
+}
+
+void CheckIntPartMax(const FixedPointSemantics &Sema, uint64_t Expected) {
+  ASSERT_EQ(APFixedPoint::getMax(Sema).getIntPart(), Expected);
+}
+
+TEST(FixedPoint, getIntPart) {
+  // Normal values
+  CheckIntPart(getSAccSema(), 2);
+  CheckIntPart(getAccSema(), 2);
+  CheckIntPart(getLAccSema(), 2);
+  CheckIntPart(getUSAccSema(), 2);
+  CheckIntPart(getUAccSema(), 2);
+  CheckIntPart(getULAccSema(), 2);
+
+  // Zero
+  CheckIntPart(getSAccSema(), 0);
+  CheckIntPart(getAccSema(), 0);
+  CheckIntPart(getLAccSema(), 0);
+  CheckIntPart(getUSAccSema(), 0);
+  CheckIntPart(getUAccSema(), 0);
+  CheckIntPart(getULAccSema(), 0);
+
+  CheckIntPart(getSFractSema(), 0);
+  CheckIntPart(getFractSema(), 0);
+  CheckIntPart(getLFractSema(), 0);
+  CheckIntPart(getUSFractSema(), 0);
+  CheckIntPart(getUFractSema(), 0);
+  CheckIntPart(getULFractSema(), 0);
+
+  // Min
+  CheckIntPartMin(getSAccSema(), -256);
+  CheckIntPartMin(getAccSema(), -65536);
+  CheckIntPartMin(getLAccSema(), -4294967296);
+
+  CheckIntPartMin(getSFractSema(), -1);
+  CheckIntPartMin(getFractSema(), -1);
+  CheckIntPartMin(getLFractSema(), -1);
+
+  // Max
+  CheckIntPartMax(getSAccSema(), 255);
+  CheckIntPartMax(getAccSema(), 65535);
+  CheckIntPartMax(getLAccSema(), 4294967295);
+  CheckIntPartMax(getUSAccSema(), 255);
+  CheckIntPartMax(getUAccSema(), 65535);
+  CheckIntPartMax(getULAccSema(), 4294967295);
+
+  CheckIntPartMax(getSFractSema(), 0);
+  CheckIntPartMax(getFractSema(), 0);
+  CheckIntPartMax(getLFractSema(), 0);
+  CheckIntPartMax(getUSFractSema(), 0);
+  CheckIntPartMax(getUFractSema(), 0);
+  CheckIntPartMax(getULFractSema(), 0);
+
+  // Padded
+  // Normal Values
+  CheckIntPart(getPadUSAccSema(), 2);
+  CheckIntPart(getPadUAccSema(), 2);
+  CheckIntPart(getPadULAccSema(), 2);
+
+  // Zero
+  CheckIntPart(getPadUSAccSema(), 0);
+  CheckIntPart(getPadUAccSema(), 0);
+  CheckIntPart(getPadULAccSema(), 0);
+
+  CheckIntPart(getPadUSFractSema(), 0);
+  CheckIntPart(getPadUFractSema(), 0);
+  CheckIntPart(getPadULFractSema(), 0);
+
+  // Max
+  CheckIntPartMax(getPadUSAccSema(), 255);
+  CheckIntPartMax(getPadUAccSema(), 65535);
+  CheckIntPartMax(getPadULAccSema(), 4294967295);
+
+  CheckIntPartMax(getPadUSFractSema(), 0);
+  CheckIntPartMax(getPadUFractSema(), 0);
+  CheckIntPartMax(getPadULFractSema(), 0);
+}
+
+TEST(FixedPoint, compare) {
+  // Equality
+  // With fractional part (2.5)
+  // Across sizes
+  ASSERT_EQ(APFixedPoint(320, getSAccSema()),
+            APFixedPoint(81920, getAccSema()));
+  ASSERT_EQ(APFixedPoint(320, getSAccSema()),
+            APFixedPoint(5368709120, getLAccSema()));
+  ASSERT_EQ(APFixedPoint(0, getSAccSema()), APFixedPoint(0, getLAccSema()));
+
+  // Across types (0.5)
+  ASSERT_EQ(APFixedPoint(64, getSAccSema()), APFixedPoint(64, getSFractSema()));
+  ASSERT_EQ(APFixedPoint(16384, getAccSema()),
+            APFixedPoint(16384, getFractSema()));
+  ASSERT_EQ(APFixedPoint(1073741824, getLAccSema()),
+            APFixedPoint(1073741824, getLFractSema()));
+
+  // Across widths and types (0.5)
+  ASSERT_EQ(APFixedPoint(64, getSAccSema()),
+            APFixedPoint(16384, getFractSema()));
+  ASSERT_EQ(APFixedPoint(64, getSAccSema()),
+            APFixedPoint(1073741824, getLFractSema()));
+
+  // Across saturation
+  ASSERT_EQ(APFixedPoint(320, getSAccSema()),
+            APFixedPoint(81920, Saturated(getAccSema())));
+
+  // Across signs
+  ASSERT_EQ(APFixedPoint(320, getSAccSema()),
+            APFixedPoint(640, getUSAccSema()));
+  ASSERT_EQ(APFixedPoint(-320, getSAccSema()),
+            APFixedPoint(-81920, getAccSema()));
+
+  // Across padding
+  ASSERT_EQ(APFixedPoint(320, getSAccSema()),
+            APFixedPoint(320, getPadUSAccSema()));
+  ASSERT_EQ(APFixedPoint(640, getUSAccSema()),
+            APFixedPoint(320, getPadUSAccSema()));
+
+  // Less than
+  ASSERT_LT(APFixedPoint(-1, getSAccSema()), APFixedPoint(0, getAccSema()));
+  ASSERT_LT(APFixedPoint(-1, getSAccSema()), APFixedPoint(0, getUAccSema()));
+  ASSERT_LT(APFixedPoint(0, getSAccSema()), APFixedPoint(1, getAccSema()));
+  ASSERT_LT(APFixedPoint(0, getSAccSema()), APFixedPoint(1, getUAccSema()));
+  ASSERT_LT(APFixedPoint(0, getUSAccSema()), APFixedPoint(1, getAccSema()));
+  ASSERT_LT(APFixedPoint(0, getUSAccSema()), APFixedPoint(1, getUAccSema()));
+
+  // Greater than
+  ASSERT_GT(APFixedPoint(0, getAccSema()), APFixedPoint(-1, getSAccSema()));
+  ASSERT_GT(APFixedPoint(0, getUAccSema()), APFixedPoint(-1, getSAccSema()));
+  ASSERT_GT(APFixedPoint(1, getAccSema()), APFixedPoint(0, getSAccSema()));
+  ASSERT_GT(APFixedPoint(1, getUAccSema()), APFixedPoint(0, getSAccSema()));
+  ASSERT_GT(APFixedPoint(1, getAccSema()), APFixedPoint(0, getUSAccSema()));
+  ASSERT_GT(APFixedPoint(1, getUAccSema()), APFixedPoint(0, getUSAccSema()));
+}
+
+// Check that a fixed point value in one sema is the same in another sema
+void CheckUnsaturatedConversion(FixedPointSemantics Src,
+                                FixedPointSemantics Dst, int64_t TestVal) {
+  int64_t ScaledVal = TestVal;
+  if (Dst.getScale() > Src.getScale()) {
+    ScaledVal <<= (Dst.getScale() - Src.getScale());
+  } else {
+    ScaledVal >>= (Src.getScale() - Dst.getScale());
+  }
+
+  APFixedPoint Fixed(TestVal, Src);
+  APFixedPoint Expected(ScaledVal, Dst);
+  ASSERT_EQ(Fixed.convert(Dst), Expected);
+}
+
+// Check the value in a given fixed point sema overflows to the saturated min
+// for another sema
+void CheckSaturatedConversionMin(FixedPointSemantics Src,
+                                 FixedPointSemantics Dst, int64_t TestVal) {
+  APFixedPoint Fixed(TestVal, Src);
+  ASSERT_EQ(Fixed.convert(Dst), APFixedPoint::getMin(Dst));
+}
+
+// Check the value in a given fixed point sema overflows to the saturated max
+// for another sema
+void CheckSaturatedConversionMax(FixedPointSemantics Src,
+                                 FixedPointSemantics Dst, int64_t TestVal) {
+  APFixedPoint Fixed(TestVal, Src);
+  ASSERT_EQ(Fixed.convert(Dst), APFixedPoint::getMax(Dst));
+}
+
+// Check one signed _Accum sema converted to other sema for different values.
+void CheckSignedAccumConversionsAgainstOthers(FixedPointSemantics Src,
+                                              int64_t OneVal) {
+  int64_t NormalVal = (OneVal * 2) + (OneVal / 2); // 2.5
+  int64_t HalfVal = (OneVal / 2);                  // 0.5
+
+  // +Accs to Accs
+  CheckUnsaturatedConversion(Src, getSAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getLAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getUSAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getUAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getULAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getPadUSAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getPadUAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getPadULAccSema(), NormalVal);
+
+  // -Accs to Accs
+  CheckUnsaturatedConversion(Src, getSAccSema(), -NormalVal);
+  CheckUnsaturatedConversion(Src, getAccSema(), -NormalVal);
+  CheckUnsaturatedConversion(Src, getLAccSema(), -NormalVal);
+  CheckSaturatedConversionMin(Src, Saturated(getUSAccSema()), -NormalVal);
+  CheckSaturatedConversionMin(Src, Saturated(getUAccSema()), -NormalVal);
+  CheckSaturatedConversionMin(Src, Saturated(getULAccSema()), -NormalVal);
+  CheckSaturatedConversionMin(Src, Saturated(getPadUSAccSema()), -NormalVal);
+  CheckSaturatedConversionMin(Src, Saturated(getPadUAccSema()), -NormalVal);
+  CheckSaturatedConversionMin(Src, Saturated(getPadULAccSema()), -NormalVal);
+
+  // +Accs to Fracts
+  CheckUnsaturatedConversion(Src, getSFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getLFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getUSFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getUFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getULFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getPadUSFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getPadUFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getPadULFractSema(), HalfVal);
+
+  // -Accs to Fracts
+  CheckUnsaturatedConversion(Src, getSFractSema(), -HalfVal);
+  CheckUnsaturatedConversion(Src, getFractSema(), -HalfVal);
+  CheckUnsaturatedConversion(Src, getLFractSema(), -HalfVal);
+  CheckSaturatedConversionMin(Src, Saturated(getUSFractSema()), -HalfVal);
+  CheckSaturatedConversionMin(Src, Saturated(getUFractSema()), -HalfVal);
+  CheckSaturatedConversionMin(Src, Saturated(getULFractSema()), -HalfVal);
+  CheckSaturatedConversionMin(Src, Saturated(getPadUSFractSema()), -HalfVal);
+  CheckSaturatedConversionMin(Src, Saturated(getPadUFractSema()), -HalfVal);
+  CheckSaturatedConversionMin(Src, Saturated(getPadULFractSema()), -HalfVal);
+
+  // 0 to Accs
+  CheckUnsaturatedConversion(Src, getSAccSema(), 0);
+  CheckUnsaturatedConversion(Src, getAccSema(), 0);
+  CheckUnsaturatedConversion(Src, getLAccSema(), 0);
+  CheckUnsaturatedConversion(Src, getUSAccSema(), 0);
+  CheckUnsaturatedConversion(Src, getUAccSema(), 0);
+  CheckUnsaturatedConversion(Src, getULAccSema(), 0);
+  CheckUnsaturatedConversion(Src, getPadUSAccSema(), 0);
+  CheckUnsaturatedConversion(Src, getPadUAccSema(), 0);
+  CheckUnsaturatedConversion(Src, getPadULAccSema(), 0);
+
+  // 0 to Fracts
+  CheckUnsaturatedConversion(Src, getSFractSema(), 0);
+  CheckUnsaturatedConversion(Src, getFractSema(), 0);
+  CheckUnsaturatedConversion(Src, getLFractSema(), 0);
+  CheckUnsaturatedConversion(Src, getUSFractSema(), 0);
+  CheckUnsaturatedConversion(Src, getUFractSema(), 0);
+  CheckUnsaturatedConversion(Src, getULFractSema(), 0);
+  CheckUnsaturatedConversion(Src, getPadUSFractSema(), 0);
+  CheckUnsaturatedConversion(Src, getPadUFractSema(), 0);
+  CheckUnsaturatedConversion(Src, getPadULFractSema(), 0);
+}
+
+// Check one unsigned _Accum sema converted to other sema for different values.
+void CheckUnsignedAccumConversionsAgainstOthers(FixedPointSemantics Src,
+                                                int64_t OneVal) {
+  int64_t NormalVal = (OneVal * 2) + (OneVal / 2); // 2.5
+  int64_t HalfVal = (OneVal / 2);                  // 0.5
+
+  // +UAccs to Accs
+  CheckUnsaturatedConversion(Src, getSAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getLAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getUSAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getUAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getULAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getPadUSAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getPadUAccSema(), NormalVal);
+  CheckUnsaturatedConversion(Src, getPadULAccSema(), NormalVal);
+
+  // +UAccs to Fracts
+  CheckUnsaturatedConversion(Src, getSFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getLFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getUSFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getUFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getULFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getPadUSFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getPadUFractSema(), HalfVal);
+  CheckUnsaturatedConversion(Src, getPadULFractSema(), HalfVal);
+}
+
+TEST(FixedPoint, AccumConversions) {
+  // Normal conversions
+  CheckSignedAccumConversionsAgainstOthers(getSAccSema(), 128);
+  CheckUnsignedAccumConversionsAgainstOthers(getUSAccSema(), 256);
+  CheckSignedAccumConversionsAgainstOthers(getAccSema(), 32768);
+  CheckUnsignedAccumConversionsAgainstOthers(getUAccSema(), 65536);
+  CheckSignedAccumConversionsAgainstOthers(getLAccSema(), 2147483648);
+  CheckUnsignedAccumConversionsAgainstOthers(getULAccSema(), 4294967296);
+
+  CheckUnsignedAccumConversionsAgainstOthers(getPadUSAccSema(), 128);
+  CheckUnsignedAccumConversionsAgainstOthers(getPadUAccSema(), 32768);
+  CheckUnsignedAccumConversionsAgainstOthers(getPadULAccSema(), 2147483648);
+}
+
+TEST(FixedPoint, AccConversionOverflow) {
+  // To SAcc max limit (65536)
+  CheckSaturatedConversionMax(getLAccSema(), Saturated(getAccSema()),
+                              140737488355328);
+  CheckSaturatedConversionMax(getLAccSema(), Saturated(getUAccSema()),
+                              140737488355328);
+  CheckSaturatedConversionMax(getLAccSema(), Saturated(getPadUAccSema()),
+                              140737488355328);
+  CheckSaturatedConversionMax(getULAccSema(), Saturated(getAccSema()),
+                              281474976710656);
+  CheckSaturatedConversionMax(getULAccSema(), Saturated(getUAccSema()),
+                              281474976710656);
+  CheckSaturatedConversionMax(getULAccSema(), Saturated(getPadUAccSema()),
+                              281474976710656);
+
+  CheckSaturatedConversionMax(getPadULAccSema(), Saturated(getAccSema()),
+                              140737488355328);
+  CheckSaturatedConversionMax(getPadULAccSema(), Saturated(getUAccSema()),
+                              140737488355328);
+  CheckSaturatedConversionMax(getPadULAccSema(), Saturated(getPadUAccSema()),
+                              140737488355328);
+
+  // To SAcc min limit (-65536)
+  CheckSaturatedConversionMin(getLAccSema(), Saturated(getAccSema()),
+                              -140737488355328);
+  CheckSaturatedConversionMin(getLAccSema(), Saturated(getUAccSema()),
+                              -140737488355328);
+  CheckSaturatedConversionMin(getLAccSema(), Saturated(getPadUAccSema()),
+                              -140737488355328);
+}
+
+TEST(FixedPoint, SAccConversionOverflow) {
+  // To SAcc max limit (256)
+  CheckSaturatedConversionMax(getAccSema(), Saturated(getSAccSema()), 8388608);
+  CheckSaturatedConversionMax(getAccSema(), Saturated(getUSAccSema()), 8388608);
+  CheckSaturatedConversionMax(getAccSema(), Saturated(getPadUSAccSema()),
+                              8388608);
+  CheckSaturatedConversionMax(getUAccSema(), Saturated(getSAccSema()),
+                              16777216);
+  CheckSaturatedConversionMax(getUAccSema(), Saturated(getUSAccSema()),
+                              16777216);
+  CheckSaturatedConversionMax(getUAccSema(), Saturated(getPadUSAccSema()),
+                              16777216);
+  CheckSaturatedConversionMax(getLAccSema(), Saturated(getSAccSema()),
+                              549755813888);
+  CheckSaturatedConversionMax(getLAccSema(), Saturated(getUSAccSema()),
+                              549755813888);
+  CheckSaturatedConversionMax(getLAccSema(), Saturated(getPadUSAccSema()),
+                              549755813888);
+  CheckSaturatedConversionMax(getULAccSema(), Saturated(getSAccSema()),
+                              1099511627776);
+  CheckSaturatedConversionMax(getULAccSema(), Saturated(getUSAccSema()),
+                              1099511627776);
+  CheckSaturatedConversionMax(getULAccSema(), Saturated(getPadUSAccSema()),
+                              1099511627776);
+
+  CheckSaturatedConversionMax(getPadUAccSema(), Saturated(getSAccSema()),
+                              8388608);
+  CheckSaturatedConversionMax(getPadUAccSema(), Saturated(getUSAccSema()),
+                              8388608);
+  CheckSaturatedConversionMax(getPadUAccSema(), Saturated(getPadUSAccSema()),
+                              8388608);
+  CheckSaturatedConversionMax(getPadULAccSema(), Saturated(getSAccSema()),
+                              549755813888);
+  CheckSaturatedConversionMax(getPadULAccSema(), Saturated(getUSAccSema()),
+                              549755813888);
+  CheckSaturatedConversionMax(getPadULAccSema(), Saturated(getPadUSAccSema()),
+                              549755813888);
+
+  // To SAcc min limit (-256)
+  CheckSaturatedConversionMin(getAccSema(), Saturated(getSAccSema()), -8388608);
+  CheckSaturatedConversionMin(getAccSema(), Saturated(getUSAccSema()),
+                              -8388608);
+  CheckSaturatedConversionMin(getAccSema(), Saturated(getPadUSAccSema()),
+                              -8388608);
+  CheckSaturatedConversionMin(getLAccSema(), Saturated(getSAccSema()),
+                              -549755813888);
+  CheckSaturatedConversionMin(getLAccSema(), Saturated(getUSAccSema()),
+                              -549755813888);
+  CheckSaturatedConversionMin(getLAccSema(), Saturated(getPadUSAccSema()),
+                              -549755813888);
+}
+
+void CheckSaturatedConversionToFractMax(FixedPointSemantics Src,
+                                        int64_t OneVal) {
+  CheckSaturatedConversionMax(Src, Saturated(getSFractSema()), OneVal);
+  CheckSaturatedConversionMax(Src, Saturated(getFractSema()), OneVal);
+  CheckSaturatedConversionMax(Src, Saturated(getLFractSema()), OneVal);
+  CheckSaturatedConversionMax(Src, Saturated(getUSFractSema()), OneVal);
+  CheckSaturatedConversionMax(Src, Saturated(getUFractSema()), OneVal);
+  CheckSaturatedConversionMax(Src, Saturated(getPadULFractSema()), OneVal);
+  CheckSaturatedConversionMax(Src, Saturated(getPadUSFractSema()), OneVal);
+  CheckSaturatedConversionMax(Src, Saturated(getPadUFractSema()), OneVal);
+  CheckSaturatedConversionMax(Src, Saturated(getPadULFractSema()), OneVal);
+}
+
+void CheckSaturatedConversionToFractMin(FixedPointSemantics Src,
+                                        int64_t MinusOneVal) {
+  CheckSaturatedConversionMin(Src, Saturated(getSFractSema()), MinusOneVal);
+  CheckSaturatedConversionMin(Src, Saturated(getFractSema()), MinusOneVal);
+  CheckSaturatedConversionMin(Src, Saturated(getLFractSema()), MinusOneVal);
+  CheckSaturatedConversionMin(Src, Saturated(getUSFractSema()), MinusOneVal);
+  CheckSaturatedConversionMin(Src, Saturated(getUFractSema()), MinusOneVal);
+  CheckSaturatedConversionMin(Src, Saturated(getPadULFractSema()), MinusOneVal);
+  CheckSaturatedConversionMin(Src, Saturated(getPadUSFractSema()), MinusOneVal);
+  CheckSaturatedConversionMin(Src, Saturated(getPadUFractSema()), MinusOneVal);
+  CheckSaturatedConversionMin(Src, Saturated(getPadULFractSema()), MinusOneVal);
+}
+
+TEST(FixedPoint, OverflowConversionsToFract) {
+  CheckSaturatedConversionToFractMax(getSAccSema(), 128);
+  CheckSaturatedConversionToFractMin(getSAccSema(), -128);
+  CheckSaturatedConversionToFractMax(getAccSema(), 32768);
+  CheckSaturatedConversionToFractMin(getAccSema(), -32768);
+  CheckSaturatedConversionToFractMax(getLAccSema(), 2147483648);
+  CheckSaturatedConversionToFractMin(getLAccSema(), -2147483648);
+
+  // Unsigned
+  CheckSaturatedConversionToFractMax(getUSAccSema(), 256);
+  CheckSaturatedConversionToFractMax(getUAccSema(), 65536);
+  CheckSaturatedConversionToFractMax(getULAccSema(), 4294967296);
+
+  // Padded unsigned
+  CheckSaturatedConversionToFractMax(getPadUSAccSema(), 128);
+  CheckSaturatedConversionToFractMax(getPadUAccSema(), 32768);
+  CheckSaturatedConversionToFractMax(getPadULAccSema(), 2147483648);
+}
+
+} // namespace
Index: unittests/Basic/CMakeLists.txt
===================================================================
--- unittests/Basic/CMakeLists.txt
+++ unittests/Basic/CMakeLists.txt
@@ -6,13 +6,15 @@
   CharInfoTest.cpp
   DiagnosticTest.cpp
   FileManagerTest.cpp
+  FixedPointTest.cpp
   MemoryBufferCacheTest.cpp
   SourceManagerTest.cpp
   VirtualFileSystemTest.cpp
   )
 
 target_link_libraries(BasicTests
   PRIVATE
+  clangAST
   clangBasic
   clangLex
   )
Index: test/Frontend/fixed_point_declarations.c
===================================================================
--- test/Frontend/fixed_point_declarations.c
+++ test/Frontend/fixed_point_declarations.c
@@ -1,5 +1,4 @@
 // RUN: %clang -ffixed-point -S -emit-llvm %s -o - --target=x86_64-linux | FileCheck %s
-// RUN: %clang -ffixed-point -S -emit-llvm %s -o - --target=x86_64-scei-ps4-ubuntu-fast | FileCheck %s
 
 // Primary fixed point types
 signed short _Accum   s_short_accum;  // CHECK-DAG: @s_short_accum  = {{.*}}global i16 0, align 2
@@ -111,3 +110,18 @@
 unsigned short _Fract u_short_fract_eps = 0x1p-8uhr;        // CHECK-DAG: @u_short_fract_eps = {{.*}}global i8  1, align 1
 unsigned _Fract       u_fract_eps       = 0x1p-16ur;        // CHECK-DAG: @u_fract_eps       = {{.*}}global i16 1, align 2
 unsigned long _Fract  u_long_fract_eps  = 0x1p-32ulr;       // CHECK-DAG: @u_long_fract_eps  = {{.*}}global i32 1, align 4
+
+// Zero
+short _Accum          short_accum_zero    = 0.0hk;    // CHECK-DAG: @short_accum_zero     = {{.*}}global i16 0, align 2
+ _Accum               accum_zero          = 0.0k;     // CHECK-DAG: @accum_zero           = {{.*}}global i32 0, align 4
+long _Accum           long_accum_zero     = 0.0lk;    // CHECK-DAG: @long_accum_zero      = {{.*}}global i64 0, align 8
+unsigned short _Accum u_short_accum_zero  = 0.0uhk;   // CHECK-DAG: @u_short_accum_zero   = {{.*}}global i16 0, align 2
+unsigned  _Accum      u_accum_zero        = 0.0uk;    // CHECK-DAG: @u_accum_zero         = {{.*}}global i32 0, align 4
+unsigned long _Accum  u_long_accum_zero   = 0.0ulk;   // CHECK-DAG: @u_long_accum_zero    = {{.*}}global i64 0, align 8
+
+short _Fract          short_fract_zero    = 0.0hr;    // CHECK-DAG: @short_fract_zero     = {{.*}}global i8  0, align 1
+ _Fract               fract_zero          = 0.0r;     // CHECK-DAG: @fract_zero           = {{.*}}global i16 0, align 2
+long _Fract           long_fract_zero     = 0.0lr;    // CHECK-DAG: @long_fract_zero      = {{.*}}global i32 0, align 4
+unsigned short _Fract u_short_fract_zero  = 0.0uhr;   // CHECK-DAG: @u_short_fract_zero   = {{.*}}global i8  0, align 1
+unsigned  _Fract      u_fract_zero        = 0.0ur;    // CHECK-DAG: @u_fract_zero         = {{.*}}global i16 0, align 2
+unsigned long _Fract  u_long_fract_zero   = 0.0ulr;   // CHECK-DAG: @u_long_fract_zero    = {{.*}}global i32 0, align 4
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -3351,16 +3351,14 @@
 
     bool isSigned = !Literal.isUnsigned;
     unsigned scale = Context.getFixedPointScale(Ty);
-    unsigned ibits = Context.getFixedPointIBits(Ty);
     unsigned bit_width = Context.getTypeInfo(Ty).Width;
 
     llvm::APInt Val(bit_width, 0, isSigned);
     bool Overflowed = Literal.GetFixedPointValue(Val, scale);
+    bool ValIsZero = Val.isNullValue() && !Overflowed;
 
-    // Do not use bit_width since some types may have padding like _Fract or
-    // unsigned _Accums if PaddingOnUnsignedFixedPoint is set.
-    auto MaxVal = llvm::APInt::getMaxValue(ibits + scale).zextOrSelf(bit_width);
-    if (Literal.isFract && Val == MaxVal + 1)
+    auto MaxVal = Context.getFixedPointMax(Ty).getValue();
+    if (Literal.isFract && Val == MaxVal + 1 && !ValIsZero)
       // Clause 6.4.4 - The value of a constant shall be in the range of
       // representable values for its type, with exception for constants of a
       // fract type with a value of exactly 1; such a constant shall denote
Index: lib/Basic/FixedPoint.cpp
===================================================================
--- /dev/null
+++ lib/Basic/FixedPoint.cpp
@@ -0,0 +1,124 @@
+//===- FixedPoint.cpp - Fixed point constant handling -----------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Defines the implementation for the fixed point number interface.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/AST/ASTContext.h"
+#include "clang/Basic/FixedPoint.h"
+
+namespace clang {
+
+APFixedPoint APFixedPoint::convert(const FixedPointSemantics &DstSema) const {
+  llvm::APSInt NewVal = Val;
+  unsigned DstWidth = DstSema.getWidth();
+  unsigned DstScale = DstSema.getScale();
+  bool Upscaling = DstScale > getScale();
+
+  // Scaling and resizing
+  if (DstWidth > NewVal.getBitWidth())
+    NewVal = NewVal.extend(DstWidth);
+
+  if (Upscaling) {
+    NewVal = NewVal.extend(NewVal.getBitWidth() + DstScale - getScale());
+    NewVal <<= (DstScale - getScale());
+  } else {
+    NewVal >>= (getScale() - DstScale);
+  }
+
+  if (DstSema.isSaturated()) {
+    auto Mask = llvm::APInt::getBitsSetFrom(
+        NewVal.getBitWidth(), DstScale + DstSema.getIntegralBits());
+    llvm::APInt Masked(NewVal & Mask);
+    if (!DstSema.isSigned() && NewVal.isNegative()) {
+      NewVal = 0;
+    } else if (!(Masked == Mask || Masked == 0)) {
+      // Change in the bits above the sign
+      if (NewVal.isNegative()) {
+        // Min val
+        if (DstSema.isSigned())
+          NewVal = Mask;
+        else
+          NewVal = 0;
+      } else {
+        NewVal = ~Mask; // Max val
+      }
+    }
+  }
+
+  NewVal = NewVal.extOrTrunc(DstWidth);
+  return APFixedPoint(NewVal, DstSema);
+}
+
+int APFixedPoint::compare(const APFixedPoint &Other) const {
+  llvm::APSInt ThisVal = Val;
+  llvm::APSInt OtherVal = Other.getValue();
+  bool ThisSigned = Val.isSigned();
+  bool OtherSigned = OtherVal.isSigned();
+  unsigned OtherScale = Other.getScale();
+  unsigned OtherWidth = OtherVal.getBitWidth();
+
+  unsigned CommonWidth = std::max(Val.getBitWidth(), OtherWidth);
+
+  // Prevent overflow in the event the widths are the same but the scales differ
+  CommonWidth += std::abs(static_cast<int>(getScale() - OtherScale));
+
+  ThisVal = ThisVal.extOrTrunc(CommonWidth);
+  OtherVal = OtherVal.extOrTrunc(CommonWidth);
+
+  unsigned CommonScale = std::max(getScale(), OtherScale);
+  ThisVal = ThisVal.shl(CommonScale - getScale());
+  OtherVal = OtherVal.shl(CommonScale - OtherScale);
+
+  if (ThisSigned && OtherSigned) {
+    if (ThisVal.sgt(OtherVal))
+      return 1;
+    else if (ThisVal.slt(OtherVal))
+      return -1;
+  } else if (!ThisSigned && !OtherSigned) {
+    if (ThisVal.ugt(OtherVal))
+      return 1;
+    else if (ThisVal.ult(OtherVal))
+      return -1;
+  } else if (ThisSigned && !OtherSigned) {
+    if (ThisVal.isSignBitSet())
+      return -1;
+    else if (ThisVal.ugt(OtherVal))
+      return 1;
+    else if (ThisVal.ult(OtherVal))
+      return -1;
+  } else {
+    // !ThisSigned && OtherSigned
+    if (OtherVal.isSignBitSet())
+      return 1;
+    else if (ThisVal.ugt(OtherVal))
+      return 1;
+    else if (ThisVal.ult(OtherVal))
+      return -1;
+  }
+
+  return 0;
+}
+
+APFixedPoint APFixedPoint::getMax(const FixedPointSemantics &Sema) {
+  bool IsUnsigned = !Sema.isSigned();
+  auto Val = llvm::APSInt::getMaxValue(Sema.getWidth(), IsUnsigned);
+  if (IsUnsigned && Sema.hasUnsignedPadding())
+    Val = Val.lshr(1);
+  return APFixedPoint(Val, Sema);
+}
+
+APFixedPoint APFixedPoint::getMin(const FixedPointSemantics &Sema) {
+  auto Val = llvm::APSInt::getMinValue(Sema.getWidth(), !Sema.isSigned());
+  return APFixedPoint(Val, Sema);
+}
+
+}  // namespace clang
Index: lib/Basic/CMakeLists.txt
===================================================================
--- lib/Basic/CMakeLists.txt
+++ lib/Basic/CMakeLists.txt
@@ -54,6 +54,7 @@
   DiagnosticOptions.cpp
   FileManager.cpp
   FileSystemStatCache.cpp
+  FixedPoint.cpp
   IdentifierTable.cpp
   LangOptions.cpp
   MemoryBufferCache.cpp
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -10282,3 +10282,22 @@
       return 0;
   }
 }
+
+FixedPointSemantics ASTContext::getFixedPointSema(QualType Ty) const {
+  assert(Ty->isFixedPointType());
+  bool isSigned = Ty->isSignedFixedPointType();
+  return FixedPointSemantics(
+      static_cast<unsigned>(getTypeSize(Ty)), getFixedPointScale(Ty), isSigned,
+      Ty->isSaturatedFixedPointType(),
+      !isSigned && getTargetInfo().doUnsignedFixedPointTypesHavePadding());
+}
+
+APFixedPoint ASTContext::getFixedPointMax(QualType Ty) const {
+  assert(Ty->isFixedPointType());
+  return APFixedPoint::getMax(getFixedPointSema(Ty));
+}
+
+APFixedPoint ASTContext::getFixedPointMin(QualType Ty) const {
+  assert(Ty->isFixedPointType());
+  return APFixedPoint::getMin(getFixedPointSema(Ty));
+}
Index: include/clang/Basic/TargetInfo.h
===================================================================
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -312,6 +312,14 @@
     }
   }
 
+  /// In the event this target uses the same number of fractional bits for its
+  /// unsigned types as it does with its signed counterparts, there will be
+  /// exactly one bit of padding.
+  /// Return true if unsigned fixed point types have padding for this target.
+  bool doUnsignedFixedPointTypesHavePadding() const {
+    return PaddingOnUnsignedFixedPoint;
+  }
+
   /// Return the width (in bits) of the specified integer type enum.
   ///
   /// For example, SignedInt -> getIntWidth().
Index: include/clang/Basic/FixedPoint.h
===================================================================
--- /dev/null
+++ include/clang/Basic/FixedPoint.h
@@ -0,0 +1,128 @@
+//===- FixedPoint.h - Fixed point constant handling -------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+/// \file
+/// Defines the fixed point number interface.
+/// This is a class for abstracting various operations performed on fixed point
+/// types described in ISO/IEC JTC1 SC22 WG14 N1169 starting at clause 4.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_BASIC_FIXEDPOINT_H
+#define LLVM_CLANG_BASIC_FIXEDPOINT_H
+
+#include "llvm/ADT/APSInt.h"
+
+namespace clang {
+
+class ASTContext;
+class QualType;
+
+// The fixed point semantics work similarly to llvm::fltSemantics. The width
+// specifies the whole bit width of the underlying scaled integer (with padding
+// if any). The scale represents the number of fractional bits in this type.
+// When HasUnsignedPadding is true and this type is signed, the first bit
+// in the value this represents is treaded as padding.
+class FixedPointSemantics {
+public:
+  FixedPointSemantics(unsigned Width, unsigned Scale, bool IsSigned,
+                      bool IsSaturated, bool HasUnsignedPadding)
+      : Width(Width), Scale(Scale), IsSigned(IsSigned),
+        IsSaturated(IsSaturated), HasUnsignedPadding(HasUnsignedPadding) {
+    assert(Width >= Scale && "Not enough room for the scale");
+  }
+
+  inline unsigned getWidth() const { return Width; }
+  inline unsigned getScale() const { return Scale; }
+  inline bool isSigned() const { return IsSigned; }
+  inline bool isSaturated() const { return IsSaturated; }
+  inline bool hasUnsignedPadding() const { return HasUnsignedPadding; }
+
+  void setSaturated(bool Saturated) { IsSaturated = Saturated; }
+
+  unsigned getIntegralBits() const {
+    if (IsSigned || (!IsSigned && HasUnsignedPadding))
+      return Width - Scale - 1;
+    else
+      return Width - Scale;
+  }
+
+private:
+  unsigned Width;
+  unsigned Scale;
+  bool IsSigned;
+  bool IsSaturated;
+  bool HasUnsignedPadding;
+};
+
+class APFixedPoint {
+ public:
+   APFixedPoint(const llvm::APInt &Val, const FixedPointSemantics &Sema)
+       : Val(Val, !Sema.isSigned()), Sema(Sema) {
+     assert(Val.getBitWidth() == Sema.getWidth() &&
+            "The value should have a bit width that matches the Sema width");
+   }
+
+   APFixedPoint(uint64_t Val, const FixedPointSemantics &Sema)
+       : APFixedPoint(llvm::APInt(Sema.getWidth(), Val, Sema.isSigned()),
+                      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(); }
+
+   // 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);
+  }
+
+  llvm::APSInt getIntPart() const {
+    if (Val < 0 && Val != -Val) // Cover the case when we have the min val
+      return -(-Val >> getScale());
+    else
+      return Val >> getScale();
+  }
+
+  // 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 {
+    return compare(Other) == 0;
+  }
+  bool operator!=(const APFixedPoint &Other) const {
+    return compare(Other) != 0;
+  }
+  bool operator>(const APFixedPoint &Other) const { return compare(Other) > 0; }
+  bool operator<(const APFixedPoint &Other) const { return compare(Other) < 0; }
+  bool operator>=(const APFixedPoint &Other) const {
+    return compare(Other) >= 0;
+  }
+  bool operator<=(const APFixedPoint &Other) const {
+    return compare(Other) <= 0;
+  }
+
+  static APFixedPoint getMax(const FixedPointSemantics &Sema);
+  static APFixedPoint getMin(const FixedPointSemantics &Sema);
+
+private:
+  llvm::APSInt Val;
+  FixedPointSemantics Sema;
+};
+
+}  // namespace clang
+
+#endif
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -30,6 +30,7 @@
 #include "clang/AST/TemplateName.h"
 #include "clang/AST/Type.h"
 #include "clang/Basic/AddressSpaces.h"
+#include "clang/Basic/FixedPoint.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
@@ -1949,6 +1950,9 @@
 
   unsigned char getFixedPointScale(QualType Ty) const;
   unsigned char getFixedPointIBits(QualType Ty) const;
+  FixedPointSemantics getFixedPointSema(QualType Ty) const;
+  APFixedPoint getFixedPointMax(QualType Ty) const;
+  APFixedPoint getFixedPointMin(QualType Ty) const;
 
   DeclarationNameInfo getNameForTemplate(TemplateName Name,
                                          SourceLocation NameLoc) const;
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to