leonardchan updated this revision to Diff 153924.
leonardchan marked 7 inline comments as done.

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,618 @@
+//===- 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 {
+
+struct fixedPointSemantics Saturated(struct fixedPointSemantics Sema) {
+  Sema.isSaturated = true;
+  return Sema;
+}
+
+struct fixedPointSemantics getSAccSema() {
+  return {/*width=*/16, /*scale=*/7, /*isSigned=*/true,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getAccSema() {
+  return {/*width=*/32, /*scale=*/15, /*isSigned=*/true,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getLAccSema() {
+  return {/*width=*/64, /*scale=*/31, /*isSigned=*/true,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getSFractSema() {
+  return {/*width=*/8, /*scale=*/7, /*isSigned=*/true,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getFractSema() {
+  return {/*width=*/16, /*scale=*/15, /*isSigned=*/true,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getLFractSema() {
+  return {/*width=*/32, /*scale=*/31, /*isSigned=*/true,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getUSAccSema() {
+  return {/*width=*/16, /*scale=*/8, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getUAccSema() {
+  return {/*width=*/32, /*scale=*/16, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getULAccSema() {
+  return {/*width=*/64, /*scale=*/32, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getUSFractSema() {
+  return {/*width=*/8, /*scale=*/8, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getUFractSema() {
+  return {/*width=*/16, /*scale=*/16, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getULFractSema() {
+  return {/*width=*/32, /*scale=*/32, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/false};
+}
+
+struct fixedPointSemantics getPadUSAccSema() {
+  return {/*width=*/16, /*scale=*/7, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/true};
+}
+
+struct fixedPointSemantics getPadUAccSema() {
+  return {/*width=*/32, /*scale=*/15, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/true};
+}
+
+struct fixedPointSemantics getPadULAccSema() {
+  return {/*width=*/64, /*scale=*/31, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/true};
+}
+
+struct fixedPointSemantics getPadUSFractSema() {
+  return {/*width=*/8, /*scale=*/7, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/true};
+}
+
+struct fixedPointSemantics getPadUFractSema() {
+  return {/*width=*/16, /*scale=*/15, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/true};
+}
+
+struct fixedPointSemantics getPadULFractSema() {
+  return {/*width=*/32, /*scale=*/31, /*isSigned=*/false,
+          /*isSaturated=*/false, /*hasUnsignedPadding=*/true};
+}
+
+void CheckUnpaddedMax(const fixedPointSemantics &Sema) {
+  ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(),
+            APSInt::getMaxValue(Sema.width, !Sema.isSigned));
+}
+
+void CheckPaddedMax(const fixedPointSemantics &Sema) {
+  ASSERT_EQ(APFixedPoint::getMax(Sema).getValue(),
+            APSInt::getMaxValue(Sema.width, !Sema.isSigned) >> 1);
+}
+
+void CheckMin(const fixedPointSemantics &Sema) {
+  ASSERT_EQ(APFixedPoint::getMin(Sema).getValue(),
+            APSInt::getMinValue(Sema.width, !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.scale;
+
+  // Value with a fraction
+  APFixedPoint ValWithFract(APInt(Sema.width,
+                                  (IntPart << Scale) + (1ULL << (Scale - 1)),
+                                  Sema.isSigned),
+                            Sema);
+  ASSERT_EQ(ValWithFract.getIntPart(), IntPart);
+
+  // Just fraction
+  APFixedPoint JustFract(
+      APInt(Sema.width, (1ULL << (Scale - 1)), Sema.isSigned), Sema);
+  ASSERT_EQ(JustFract.getIntPart(), 0);
+
+  // Whole number
+  APFixedPoint WholeNum(APInt(Sema.width, (IntPart << Scale), Sema.isSigned),
+                        Sema);
+  ASSERT_EQ(WholeNum.getIntPart(), IntPart);
+
+  // Negative
+  if (Sema.isSigned) {
+    APFixedPoint Negative(APInt(Sema.width, (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(struct fixedPointSemantics Src,
+                                struct fixedPointSemantics Dst,
+                                int64_t TestVal) {
+  int64_t ScaledVal = TestVal;
+  if (Dst.scale > Src.scale) {
+    ScaledVal <<= (Dst.scale - Src.scale);
+  } else {
+    ScaledVal >>= (Src.scale - Dst.scale);
+  }
+
+  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(struct fixedPointSemantics Src,
+                                 struct 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(struct fixedPointSemantics Src,
+                                 struct 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(struct 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(struct 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(struct 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(struct 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,125 @@
+//===- 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 struct fixedPointSemantics &DstSema) const {
+  llvm::APSInt NewVal = Val;
+  unsigned DstWidth = DstSema.width;
+  unsigned DstScale = DstSema.scale;
+  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.IntegralBits());
+    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 struct fixedPointSemantics &Sema) {
+  bool IsUnsigned = !Sema.isSigned;
+  auto Val = llvm::APSInt::getMaxValue(Sema.width, IsUnsigned);
+  if (IsUnsigned && Sema.hasUnsignedPadding)
+    Val = Val.lshr(1);
+  return APFixedPoint(Val, Sema);
+}
+
+APFixedPoint APFixedPoint::getMin(const struct fixedPointSemantics &Sema) {
+  auto Val = llvm::APSInt::getMinValue(Sema.width, !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,21 @@
       return 0;
   }
 }
+
+struct fixedPointSemantics ASTContext::getFixedPointSema(QualType Ty) const {
+  assert(Ty->isFixedPointType());
+  bool isSigned = Ty->isSignedFixedPointType();
+  return {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,111 @@
+//===- 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.
+struct fixedPointSemantics {
+  unsigned width;
+  unsigned scale;
+  bool isSigned;
+  bool isSaturated;
+  bool hasUnsignedPadding;
+
+  unsigned IntegralBits() const {
+    if (isSigned || (!isSigned && hasUnsignedPadding))
+      return width - scale - 1;
+    else
+      return width - scale;
+  }
+};
+
+class APFixedPoint {
+ public:
+  APFixedPoint(const llvm::APInt &Val, const struct fixedPointSemantics &Sema)
+      : Val(Val, !Sema.isSigned), Sema(Sema) {
+    assert(Sema.width >= Sema.scale && "Not enough room for the scale");
+    assert(Val.getBitWidth() == Sema.width &&
+           "The value should have a bit width that matches the Sema width");
+  }
+
+  APFixedPoint(uint64_t Val, const struct fixedPointSemantics &Sema)
+      : APFixedPoint(llvm::APInt(Sema.width, Val, Sema.isSigned), Sema) {}
+
+  llvm::APSInt getValue() const { return llvm::APSInt(Val, !Sema.isSigned); }
+  inline unsigned getWidth() const { return Sema.width; }
+  inline unsigned getScale() const { return Sema.scale; }
+  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 struct 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 struct fixedPointSemantics &Sema);
+  static APFixedPoint getMin(const struct fixedPointSemantics &Sema);
+
+ private:
+  llvm::APSInt Val;
+  struct 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;
+  struct 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