leonardchan updated this revision to Diff 150602.
leonardchan marked 14 inline comments as done.

Repository:
  rC Clang

https://reviews.llvm.org/D46915

Files:
  include/clang/AST/ASTContext.h
  include/clang/AST/Expr.h
  include/clang/AST/OperationKinds.def
  include/clang/AST/RecursiveASTVisitor.h
  include/clang/AST/Type.h
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Basic/StmtNodes.td
  include/clang/Basic/TargetInfo.h
  include/clang/Driver/Options.td
  include/clang/Lex/LiteralSupport.h
  lib/AST/ASTContext.cpp
  lib/AST/ASTDumper.cpp
  lib/AST/Expr.cpp
  lib/AST/ExprClassification.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/StmtPrinter.cpp
  lib/AST/StmtProfile.cpp
  lib/AST/Type.cpp
  lib/Basic/TargetInfo.cpp
  lib/Basic/Targets.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Index/USRGeneration.cpp
  lib/Lex/LiteralSupport.cpp
  lib/Sema/Sema.cpp
  lib/Sema/SemaExceptionSpec.cpp
  lib/Sema/SemaExpr.cpp
  lib/Sema/TreeTransform.h
  lib/Serialization/ASTReaderStmt.cpp
  lib/Serialization/ASTWriterStmt.cpp
  lib/StaticAnalyzer/Core/ExprEngine.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_declarations.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_same_fbits.c
  test/Frontend/fixed_point_validation.c
  tools/libclang/CXCursor.cpp

Index: tools/libclang/CXCursor.cpp
===================================================================
--- tools/libclang/CXCursor.cpp
+++ tools/libclang/CXCursor.cpp
@@ -305,6 +305,10 @@
     K = CXCursor_IntegerLiteral;
     break;
 
+  case Stmt::FixedPointLiteralClass:
+    llvm_unreachable("No cursor for FixedPointLiteralClass");
+    break;
+
   case Stmt::FloatingLiteralClass:
     K = CXCursor_FloatingLiteral;
     break;
Index: test/Frontend/fixed_point_validation.c
===================================================================
--- /dev/null
+++ test/Frontend/fixed_point_validation.c
@@ -0,0 +1,19 @@
+// RUN: %clang -ffixed-point -S -emit-llvm -o - %s | lli -force-interpreter=true
+
+// Run simple validation tests
+
+#define assert(b) if (!(b)) { return 1; }
+
+int main(){
+  short _Accum s_accum = 0.0hk;
+  short _Accum s_accum2 = 2.0hk;
+  short _Fract s_fract = 0.999hr;
+  short _Fract s_fract2 = -0.999hr;
+
+  assert(s_accum == 0);
+
+  s_accum = s_accum2;
+
+  assert(s_accum == s_accum2);
+  assert(s_accum == 2);
+}
Index: test/Frontend/fixed_point_same_fbits.c
===================================================================
--- /dev/null
+++ test/Frontend/fixed_point_same_fbits.c
@@ -0,0 +1,28 @@
+// RUN: %clang -ffixed-point -S -emit-llvm -o - %s | FileCheck %s -check-prefix=DEFAULT
+// RUN: %clang -ffixed-point -fsame-fbits -S -emit-llvm -o - %s | FileCheck %s -check-prefix=SAME
+
+/* The scale for unsigned fixed point types should be the same as that of signed
+ * fixed point types when -fsame-fbits is enabled. */
+
+void func() {
+  unsigned short _Accum u_short_accum = 0.5uhk;
+  unsigned _Accum u_accum = 0.5uk;
+  unsigned long _Accum u_long_accum = 0.5ulk;
+  unsigned short _Fract u_short_fract = 0.5uhr;
+  unsigned _Fract u_fract = 0.5ur;
+  unsigned long _Fract u_long_fract = 0.5ulr;
+
+// DEFAULT: store i16 128, i16* %u_short_accum, align 2
+// DEFAULT: store i32 32768, i32* %u_accum, align 4
+// DEFAULT: store i64 2147483648, i64* %u_long_accum, align 8
+// DEFAULT: store i16 128, i16* %u_short_fract, align 2
+// DEFAULT: store i32 32768, i32* %u_fract, align 4
+// DEFAULT: store i64 2147483648, i64* %u_long_fract, align 8
+
+// SAME: store i16 64, i16* %u_short_accum, align 2
+// SAME: store i32 16384, i32* %u_accum, align 4
+// SAME: store i64 1073741824, i64* %u_long_accum, align 8
+// SAME: store i16 64, i16* %u_short_fract, align 2
+// SAME: store i32 16384, i32* %u_fract, align 4
+// SAME: store i64 1073741824, i64* %u_long_fract, align 8
+}
Index: test/Frontend/fixed_point_errors.c
===================================================================
--- test/Frontend/fixed_point_errors.c
+++ test/Frontend/fixed_point_errors.c
@@ -13,7 +13,6 @@
 _Sat long long _Fract sat_longlong_fract;             // expected-error{{'long long _Fract' is invalid}}
 _Sat unsigned long long _Fract sat_u_longlong_fract;  // expected-error{{'long long _Fract' is invalid}}
 
-
 /* Although _Complex types work with floating point numbers, the extension
  * provides no info for complex fixed point types. */
 
@@ -78,6 +77,50 @@
 _Sat int i;               // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'int'}}
 _Sat _Sat _Fract fract;   // expected-warning{{duplicate '_Sat' declaration specifier}}
 
+
+/* Literals that cannot fit into types */
+signed short _Accum s_short_accum = 256.0hk;            // expected-error{{this value is too large for this fixed point type}}
+unsigned short _Accum u_short_accum = 256.0uhk;         // expected-error{{this value is too large for this fixed point type}}
+signed _Accum s_accum = 65536.0k;                       // expected-error{{this value is too large for this fixed point type}}
+unsigned _Accum u_accum = 65536.0uk;                    // expected-error{{this value is too large for this fixed point type}}
+signed long _Accum s_long_accum = 4294967296.0lk;       // expected-error{{this value is too large for this fixed point type}}
+unsigned long _Accum u_long_accum = 4294967296.0ulk;    // expected-error{{this value is too large for this fixed point type}}
+
+// Large values from decimal exponents
+short _Accum          short_accum_exp   = 2.56e2hk;           // expected-error{{this value is too large for this fixed point type}}
+_Accum                accum_exp         = 6.5536e4k;          // expected-error{{this value is too large for this fixed point type}}
+long _Accum           long_accum_exp    = 4.294967296e9lk;    // expected-error{{this value is too large for this fixed point type}}
+unsigned short _Accum u_short_accum_exp = 2.56e2uhk;          // expected-error{{this value is too large for this fixed point type}}
+unsigned _Accum       u_accum_exp       = 6.5536e4uk;         // expected-error{{this value is too large for this fixed point type}}
+unsigned long _Accum  u_long_accum_exp  = 4.294967296e9ulk;   // expected-error{{this value is too large for this fixed point type}}
+
+// Large value from hexidecimal exponents
+short _Accum          short_accum_hex_exp   = 0x1p8hk;        // expected-error{{this value is too large for this fixed point type}}
+_Accum                accum_hex_exp         = 0x1p16k;        // expected-error{{this value is too large for this fixed point type}}
+long _Accum           long_accum_hex_exp    = 0x1p32lk;       // expected-error{{this value is too large for this fixed point type}}
+unsigned short _Accum u_short_accum_hex_exp = 0x1p8uhk;       // expected-error{{this value is too large for this fixed point type}}
+unsigned _Accum       u_accum_hex_exp       = 0x1p16uk;       // expected-error{{this value is too large for this fixed point type}}
+unsigned long _Accum  u_long_accum_hex_exp  = 0x1p32ulk;      // expected-error{{this value is too large for this fixed point type}}
+
+// Very large exponent
+_Accum x = 1e1000000000000000000000000000000000k;   // expected-error{{this value is too large for this fixed point type}}
+
+/* Although _Fract's cannot equal 1, _Fract literals written as 1 are allowed
+ * and the underlying value represents the max value for that _Fract type. */
+short _Fract          short_fract_above_1    = 1.1hr;   // expected-error{{this value is too large for this fixed point type}}
+_Fract                fract_above_1          = 1.1r;    // expected-error{{this value is too large for this fixed point type}}
+long _Fract           long_fract_above_1     = 1.1lr;   // expected-error{{this value is too large for this fixed point type}}
+unsigned short _Fract u_short_fract_above_1  = 1.1uhr;  // expected-error{{this value is too large for this fixed point type}}
+unsigned _Fract       u_fract_above_1        = 1.1ur;   // expected-error{{this value is too large for this fixed point type}}
+unsigned long _Fract  u_long_fract_above_1   = 1.1ulr;  // expected-error{{this value is too large for this fixed point type}}
+
+short _Fract          short_fract_hex_exp   = 0x0.fp1hr;      // expected-error{{this value is too large for this fixed point type}}
+_Fract                fract_hex_exp         = 0x0.fp1r;       // expected-error{{this value is too large for this fixed point type}}
+long _Fract           long_fract_hex_exp    = 0x0.fp1lr;      // expected-error{{this value is too large for this fixed point type}}
+unsigned short _Fract u_short_fract_hex_exp = 0x0.fp1uhr;     // expected-error{{this value is too large for this fixed point type}}
+unsigned _Fract       u_fract_hex_exp       = 0x0.fp1ur;      // expected-error{{this value is too large for this fixed point type}}
+unsigned long _Fract  u_long_fract_hex_exp  = 0x0.fp1ulr;     // expected-error{{this value is too large for this fixed point type}}
+
 /* Do not allow typedef to be used with typedef'd types */
 typedef short _Fract shortfract_t;
 typedef short _Accum shortaccum_t;
@@ -91,3 +134,16 @@
 _Sat accum_t td_sat_accum;                  // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}
 _Sat longfract_t td_sat_long_fract;         // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}
 _Sat longaccum_t td_sat_long_accum;         // expected-error{{'_Sat' specifier is only valid on '_Fract' or '_Accum', not 'type-name'}}
+
+/* Bad suffixes  */
+_Accum fk = 1.0fk;    // expected-error{{invalid suffix 'fk' on integer constant}}
+_Accum kk = 1.0kk;    // expected-error{{invalid suffix 'kk' on integer constant}}
+_Accum rk = 1.0rk;    // expected-error{{invalid suffix 'rk' on integer constant}}
+_Accum rk = 1.0rr;    // expected-error{{invalid suffix 'rr' on integer constant}}
+_Accum qk = 1.0qr;    // expected-error{{invalid suffix 'qr' on integer constant}}
+
+/* Using wrong exponent notation */
+_Accum dec_with_hex_exp1 = 0.1p10k;    // expected-error{{invalid suffix 'p10k' on integer constant}}
+_Accum dec_with_hex_exp2 = 0.1P10k;    // expected-error{{invalid suffix 'P10k' on integer constant}}
+_Accum hex_with_dex_exp1 = 0x0.1e10k;  // expected-error{{hexadecimal floating constant requires an exponent}}
+_Accum hex_with_dex_exp2 = 0x0.1E10k;  // expected-error{{hexadecimal floating constant requires an exponent}}
Index: test/Frontend/fixed_point_declarations.c
===================================================================
--- /dev/null
+++ test/Frontend/fixed_point_declarations.c
@@ -0,0 +1,113 @@
+// RUN: %clang -ffixed-point -S -emit-llvm %s -o - | 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
+signed _Accum         s_accum;        // CHECK-DAG: @s_accum        = {{.*}}global i32 0, align 4
+signed long _Accum    s_long_accum;   // CHECK-DAG: @s_long_accum   = {{.*}}global i64 0, align 8
+unsigned short _Accum u_short_accum;  // CHECK-DAG: @u_short_accum  = {{.*}}global i16 0, align 2
+unsigned _Accum       u_accum;        // CHECK-DAG: @u_accum        = {{.*}}global i32 0, align 4
+unsigned long _Accum  u_long_accum;   // CHECK-DAG: @u_long_accum   = {{.*}}global i64 0, align 8
+signed short _Fract   s_short_fract;  // CHECK-DAG: @s_short_fract  = {{.*}}global i16 0, align 2
+signed _Fract         s_fract;        // CHECK-DAG: @s_fract        = {{.*}}global i32 0, align 4
+signed long _Fract    s_long_fract;   // CHECK-DAG: @s_long_fract   = {{.*}}global i64 0, align 8
+unsigned short _Fract u_short_fract;  // CHECK-DAG: @u_short_fract  = {{.*}}global i16 0, align 2
+unsigned _Fract       u_fract;        // CHECK-DAG: @u_fract        = {{.*}}global i32 0, align 4
+unsigned long _Fract  u_long_fract;   // CHECK-DAG: @u_long_fract   = {{.*}}global i64 0, align 8
+
+// Aliased
+short _Accum  short_accum;            // CHECK-DAG: @short_accum    = {{.*}}global i16 0, align 2
+_Accum        accum;                  // CHECK-DAG: @accum          = {{.*}}global i32 0, align 4
+long _Accum   long_accum;             // CHECK-DAG: @long_accum     = {{.*}}global i64 0, align 8
+short _Fract  short_fract;            // CHECK-DAG: @short_fract    = {{.*}}global i16 0, align 2
+_Fract        fract;                  // CHECK-DAG: @fract          = {{.*}}global i32 0, align 4
+long _Fract   long_fract;             // CHECK-DAG: @long_fract     = {{.*}}global i64 0, align 8
+
+// Primary saturated
+_Sat signed short _Accum   sat_s_short_accum;  // CHECK-DAG: @sat_s_short_accum  = {{.*}}global i16 0, align 2
+_Sat signed _Accum         sat_s_accum;        // CHECK-DAG: @sat_s_accum        = {{.*}}global i32 0, align 4
+_Sat signed long _Accum    sat_s_long_accum;   // CHECK-DAG: @sat_s_long_accum   = {{.*}}global i64 0, align 8
+_Sat unsigned short _Accum sat_u_short_accum;  // CHECK-DAG: @sat_u_short_accum  = {{.*}}global i16 0, align 2
+_Sat unsigned _Accum       sat_u_accum;        // CHECK-DAG: @sat_u_accum        = {{.*}}global i32 0, align 4
+_Sat unsigned long _Accum  sat_u_long_accum;   // CHECK-DAG: @sat_u_long_accum   = {{.*}}global i64 0, align 8
+_Sat signed short _Fract   sat_s_short_fract;  // CHECK-DAG: @sat_s_short_fract  = {{.*}}global i16 0, align 2
+_Sat signed _Fract         sat_s_fract;        // CHECK-DAG: @sat_s_fract        = {{.*}}global i32 0, align 4
+_Sat signed long _Fract    sat_s_long_fract;   // CHECK-DAG: @sat_s_long_fract   = {{.*}}global i64 0, align 8
+_Sat unsigned short _Fract sat_u_short_fract;  // CHECK-DAG: @sat_u_short_fract  = {{.*}}global i16 0, align 2
+_Sat unsigned _Fract       sat_u_fract;        // CHECK-DAG: @sat_u_fract        = {{.*}}global i32 0, align 4
+_Sat unsigned long _Fract  sat_u_long_fract;   // CHECK-DAG: @sat_u_long_fract   = {{.*}}global i64 0, align 8
+
+// Aliased saturated
+_Sat short _Accum  sat_short_accum;            // CHECK-DAG: @sat_short_accum    = {{.*}}global i16 0, align 2
+_Sat _Accum        sat_accum;                  // CHECK-DAG: @sat_accum          = {{.*}}global i32 0, align 4
+_Sat long _Accum   sat_long_accum;             // CHECK-DAG: @sat_long_accum     = {{.*}}global i64 0, align 8
+_Sat short _Fract  sat_short_fract;            // CHECK-DAG: @sat_short_fract    = {{.*}}global i16 0, align 2
+_Sat _Fract        sat_fract;                  // CHECK-DAG: @sat_fract          = {{.*}}global i32 0, align 4
+_Sat long _Fract   sat_long_fract;             // CHECK-DAG: @sat_long_fract     = {{.*}}global i64 0, align 8
+
+/* Fixed point literals */
+short _Accum  short_accum_literal = 2.5hk;    // CHECK-DAG: @short_accum_literal  = {{.*}}global i16 320, align 2
+_Accum        accum_literal       = 2.5k;     // CHECK-DAG: @accum_literal        = {{.*}}global i32 81920, align 4
+long _Accum   long_accum_literal  = 2.5lk;    // CHECK-DAG: @long_accum_literal   = {{.*}}global i64 5368709120, align 8
+short _Fract  short_fract_literal = 0.5hr;    // CHECK-DAG: @short_fract_literal  = {{.*}}global i16 64, align 2
+_Fract        fract_literal       = 0.5r;     // CHECK-DAG: @fract_literal        = {{.*}}global i32 16384, align 4
+long _Fract   long_fract_literal  = 0.5lr;    // CHECK-DAG: @long_fract_literal   = {{.*}}global i64 1073741824, align 8
+
+unsigned short _Accum  u_short_accum_literal = 2.5uhk;    // CHECK-DAG: @u_short_accum_literal  = {{.*}}global i16 640, align 2
+unsigned _Accum        u_accum_literal       = 2.5uk;     // CHECK-DAG: @u_accum_literal        = {{.*}}global i32 163840, align 4
+unsigned long _Accum   u_long_accum_literal  = 2.5ulk;    // CHECK-DAG: @u_long_accum_literal   = {{.*}}global i64 10737418240, align 8
+unsigned short _Fract  u_short_fract_literal = 0.5uhr;    // CHECK-DAG: @u_short_fract_literal  = {{.*}}global i16 128, align 2
+unsigned _Fract        u_fract_literal       = 0.5ur;     // CHECK-DAG: @u_fract_literal        = {{.*}}global i32 32768, align 4
+unsigned long _Fract   u_long_fract_literal  = 0.5ulr;    // CHECK-DAG: @u_long_fract_literal   = {{.*}}global i64 2147483648, align 8
+
+// Max literal values
+short _Accum          short_accum_max   = 255.9999999999999999hk;         // CHECK-DAG: @short_accum_max   = {{.*}}global i16 32767, align 2
+_Accum                accum_max         = 65535.9999999999999999k;        // CHECK-DAG: @accum_max         = {{.*}}global i32 2147483647, align 4
+long _Accum           long_accum_max    = 4294967295.9999999999999999lk;  // CHECK-DAG: @long_accum_max    = {{.*}}global i64 9223372036854775807, align 8
+unsigned short _Accum u_short_accum_max = 255.9999999999999999uhk;        // CHECK-DAG: @u_short_accum_max = {{.*}}global i16 -1, align 2
+unsigned _Accum       u_accum_max       = 65535.9999999999999999uk;       // CHECK-DAG: @u_accum_max       = {{.*}}global i32 -1, align 4
+unsigned long _Accum  u_long_accum_max  = 4294967295.9999999999999999ulk; // CHECK-DAG: @u_long_accum_max  = {{.*}}global i64 -1, align 8
+
+short _Fract          short_fract_max   = 0.9999999999999999hr;           // CHECK-DAG: @short_fract_max   = {{.*}}global i16 127, align 2
+_Fract                fract_max         = 0.9999999999999999r;            // CHECK-DAG: @fract_max         = {{.*}}global i32 32767, align 4
+long _Fract           long_fract_max    = 0.9999999999999999lr;           // CHECK-DAG: @long_fract_max    = {{.*}}global i64 2147483647, align 8
+unsigned short _Fract u_short_fract_max = 0.9999999999999999uhr;          // CHECK-DAG: @u_short_fract_max = {{.*}}global i16 255, align 2
+unsigned _Fract       u_fract_max       = 0.9999999999999999ur;           // CHECK-DAG: @u_fract_max       = {{.*}}global i32 65535, align 4
+unsigned long _Fract  u_long_fract_max  = 0.9999999999999999ulr;          // CHECK-DAG: @u_long_fract_max  = {{.*}}global i64 4294967295, align 8
+
+// Fracts may be exactly one but evaluate to the Fract max
+short _Fract          short_fract_one   = 1.0hr;    // CHECK-DAG: @short_fract_one    = {{.*}}global i16 127, align 2
+_Fract                fract_one         = 1.0r;     // CHECK-DAG: @fract_one          = {{.*}}global i32 32767, align 4
+long _Fract           long_fract_one    = 1.0lr;    // CHECK-DAG: @long_fract_one     = {{.*}}global i64 2147483647, align 8
+unsigned short _Fract u_short_fract_one = 1.0uhr;   // CHECK-DAG: @u_short_fract_one  = {{.*}}global i16 255, align 2
+unsigned _Fract       u_fract_one       = 1.0ur;    // CHECK-DAG: @u_fract_one        = {{.*}}global i32 65535, align 4
+unsigned long _Fract  u_long_fract_one  = 1.0ulr;   // CHECK-DAG: @u_long_fract_one   = {{.*}}global i64 4294967295, align 8
+
+short _Fract          short_fract_exp_one   = 0.1e1hr;    // CHECK-DAG: @short_fract_exp_one    = {{.*}}global i16 127, align 2
+_Fract                fract_exp_one         = 0.1e1r;     // CHECK-DAG: @fract_exp_one          = {{.*}}global i32 32767, align 4
+long _Fract           long_fract_exp_one    = 0.1e1lr;    // CHECK-DAG: @long_fract_exp_one     = {{.*}}global i64 2147483647, align 8
+unsigned short _Fract u_short_fract_exp_one = 0.1e1uhr;   // CHECK-DAG: @u_short_fract_exp_one  = {{.*}}global i16 255, align 2
+unsigned _Fract       u_fract_exp_one       = 0.1e1ur;    // CHECK-DAG: @u_fract_exp_one        = {{.*}}global i32 65535, align 4
+unsigned long _Fract  u_long_fract_exp_one  = 0.1e1ulr;   // CHECK-DAG: @u_long_fract_exp_one   = {{.*}}global i64 4294967295, align 8
+
+short _Fract          short_fract_hex_exp_one   = 0x0.8p1hr;    // CHECK-DAG: @short_fract_hex_exp_one    = {{.*}}global i16 127, align 2
+_Fract                fract_hex_exp_one         = 0x0.8p1r;     // CHECK-DAG: @fract_hex_exp_one          = {{.*}}global i32 32767, align 4
+long _Fract           long_fract_hex_exp_one    = 0x0.8p1lr;    // CHECK-DAG: @long_fract_hex_exp_one     = {{.*}}global i64 2147483647, align 8
+unsigned short _Fract u_short_fract_hex_exp_one = 0x0.8p1uhr;   // CHECK-DAG: @u_short_fract_hex_exp_one  = {{.*}}global i16 255, align 2
+unsigned _Fract       u_fract_hex_exp_one       = 0x0.8p1ur;    // CHECK-DAG: @u_fract_hex_exp_one        = {{.*}}global i32 65535, align 4
+unsigned long _Fract  u_long_fract_hex_exp_one  = 0x0.8p1ulr;   // CHECK-DAG: @u_long_fract_hex_exp_one   = {{.*}}global i64 4294967295, align 8
+
+// Expsilon values
+short _Accum          short_accum_eps   = 0x1p-7hk;         // CHECK-DAG: @short_accum_eps   = {{.*}}global i16 1, align 2
+_Accum                accum_eps         = 0x1p-15k;         // CHECK-DAG: @accum_eps         = {{.*}}global i32 1, align 4
+long _Accum           long_accum_eps    = 0x1p-31lk;        // CHECK-DAG: @long_accum_eps    = {{.*}}global i64 1, align 8
+unsigned short _Accum u_short_accum_eps = 0x1p-8uhk;        // CHECK-DAG: @u_short_accum_eps = {{.*}}global i16 1, align 2
+unsigned _Accum       u_accum_eps       = 0x1p-16uk;        // CHECK-DAG: @u_accum_eps       = {{.*}}global i32 1, align 4
+unsigned long _Accum  u_long_accum_eps  = 0x1p-32ulk;       // CHECK-DAG: @u_long_accum_eps  = {{.*}}global i64 1, align 8
+
+short _Fract          short_fract_eps   = 0x1p-7hr;         // CHECK-DAG: @short_fract_eps   = {{.*}}global i16 1, align 2
+_Fract                fract_eps         = 0x1p-15r;         // CHECK-DAG: @fract_eps         = {{.*}}global i32 1, align 4
+long _Fract           long_fract_eps    = 0x1p-31lr;        // CHECK-DAG: @long_fract_eps    = {{.*}}global i64 1, align 8
+unsigned short _Fract u_short_fract_eps = 0x1p-8uhr;        // CHECK-DAG: @u_short_fract_eps = {{.*}}global i16 1, align 2
+unsigned _Fract       u_fract_eps       = 0x1p-16ur;        // CHECK-DAG: @u_fract_eps       = {{.*}}global i32 1, align 4
+unsigned long _Fract  u_long_fract_eps  = 0x1p-32ulr;       // CHECK-DAG: @u_long_fract_eps  = {{.*}}global i64 1, align 8
Index: test/Frontend/fixed_point.c
===================================================================
--- test/Frontend/fixed_point.c
+++ test/Frontend/fixed_point.c
@@ -236,4 +236,164 @@
 //CHECK-NEXT: |-VarDecl {{.*}} SatlA_type 'SatlA_t':'_Sat long _Accum'
 //CHECK-NEXT: |-VarDecl {{.*}} SatsF_type 'SatsF_t':'_Sat short _Fract'
 //CHECK-NEXT: |-VarDecl {{.*}} SatF_type 'SatF_t':'_Sat _Fract'
-//CHECK-NEXT: `-VarDecl {{.*}} SatlF_type 'SatlF_t':'_Sat long _Fract'
+//CHECK-NEXT: |-VarDecl {{.*}} SatlF_type 'SatlF_t':'_Sat long _Fract'
+
+// Fixed point literal exponent syntax
+_Accum decexp1 = 1.575e1k;
+_Accum decexp2 = 1.575E1k;
+_Accum decexp3 = 1575e-2k;
+_Accum decexp4 = 1575E-2k;
+
+_Accum hexexp1 = 0x0.3p10k;
+_Accum hexexp2 = 0x0.3P10k;
+_Accum hexexp3 = 0x30000p-10k;
+_Accum hexexp4 = 0x30000P-10k;
+
+_Accum zeroexp1 = 1e0k;
+_Accum zeroexp2 = 1e-0k;
+
+//CHECK-NEXT: |-VarDecl {{.*}} decexp1 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 15.75
+//CHECK-NEXT: |-VarDecl {{.*}} decexp2 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 15.75
+//CHECK-NEXT: |-VarDecl {{.*}} decexp3 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 15.75
+//CHECK-NEXT: |-VarDecl {{.*}} decexp4 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 15.75
+
+//CHECK-NEXT: |-VarDecl {{.*}} hexexp1 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 192.0
+//CHECK-NEXT: |-VarDecl {{.*}} hexexp2 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 192.0
+//CHECK-NEXT: |-VarDecl {{.*}} hexexp3 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 192.0
+//CHECK-NEXT: |-VarDecl {{.*}} hexexp4 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 192.0
+
+//CHECK-NEXT: |-VarDecl {{.*}} zeroexp1 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 1.0
+//CHECK-NEXT: |-VarDecl {{.*}} zeroexp2 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 1.0
+
+// Fixed point literal values
+_Accum literal1 = 2.5k;       // Precise decimal
+_Accum literal2 = 0.0k;       // Zero
+_Accum literal3 = 1.1k;       // Imprecise decimal
+_Accum literal4 = 1.11k;
+_Accum literal5 = 1.111k;
+_Accum literal6 = 1.1111k;
+_Accum literal7 = 1.11111k;   // After some point after the radix, adding any more
+                              // digits to the literal will not result in any
+                              // further precision since the nth digit added may
+                              // be less than the precision that can be
+                              // represented by the fractional bits of the type.
+                              // This results in the same value being stored for
+                              // the type.
+
+//CHECK-NEXT: |-VarDecl {{.*}} literal1 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 2.5
+//CHECK-NEXT: |-VarDecl {{.*}} literal2 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 0.0
+//CHECK-NEXT: |-VarDecl {{.*}} literal3 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 1.0999755859375
+//CHECK-NEXT: |-VarDecl {{.*}} literal4 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 1.1099853515625
+//CHECK-NEXT: |-VarDecl {{.*}} literal5 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 1.110992431640625
+//CHECK-NEXT: |-VarDecl {{.*}} literal6 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 1.111083984375
+//CHECK-NEXT: |-VarDecl {{.*}} literal7 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 1.111083984375
+
+long _Accum longaccumliteral     = 0.99999999lk;
+long _Accum longaccumliteral2    = 0.999999999lk;
+long _Accum verylongaccumliteral = 0.99999999999999999999999999lk;
+long _Fract longfractliteral     = 0.99999999lr;
+long _Fract longfractliteral2    = 0.999999999lr;
+long _Fract verylongfractliteral = 0.99999999999999999999999999lr;
+
+//CHECK-NEXT: |-VarDecl {{.*}} longaccumliteral 'long _Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'long _Accum' 0.999999989755451679229736328125
+//CHECK-NEXT: |-VarDecl {{.*}} longaccumliteral2 'long _Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999986030161380767822265625
+//CHECK-NEXT: |-VarDecl {{.*}} verylongaccumliteral 'long _Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999995343387126922607421875
+//CHECK-NEXT: |-VarDecl {{.*}} longfractliteral 'long _Fract' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'long _Fract' 0.999999989755451679229736328125
+//CHECK-NEXT: |-VarDecl {{.*}} longfractliteral2 'long _Fract' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999986030161380767822265625
+//CHECK-NEXT: |-VarDecl {{.*}} verylongfractliteral 'long _Fract' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999995343387126922607421875
+
+unsigned _Accum uliteral1 = 2.5uk;    // Unsigned
+_Accum literal8 = -2.5k;              // Negative
+
+//CHECK-NEXT: |-VarDecl {{.*}} uliteral1 'unsigned _Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'unsigned _Accum' 2.5
+//CHECK-NEXT: |-VarDecl {{.*}} literal8 '_Accum' cinit
+//CHECK-NEXT:   `-UnaryOperator {{.*}} '_Accum' prefix '-'
+//CHECK-NEXT:     `-FixedPointLiteral {{.*}} '_Accum' 2.5
+
+short _Accum  literalexact1 = 0.9921875hk;  // Exact value
+_Accum        literalexact2 = 0.999969482421875k;
+
+//CHECK-NEXT: |-VarDecl {{.*}} literalexact1 'short _Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'short _Accum' 0.9921875
+//CHECK-NEXT: |-VarDecl {{.*}} literalexact2 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 0.999969482421875
+
+// Unfortunately we do not have enough space to store the exact decimal value of
+// 0.9999999995343387126922607421875 ((1 << 31) - 1), but we can still use a
+// large number of 9s to get the max fractional value.
+long _Accum   long_accum_max = 0.999999999999999999999999999lk;
+
+//CHECK-NEXT: |-VarDecl {{.*}} long_accum_max 'long _Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'long _Accum' 0.9999999995343387126922607421875
+
+// Epsilon
+short _Accum  short_accum_eps   = 0.0078125hk;
+short _Accum  short_accum_eps2  = 0.0078124hk;  // Less than epsilon floors to zero
+_Accum        accum_eps         = 0.000030517578125k;
+_Accum        accum_eps2        = 0.000030517578124k;
+long _Accum   long_accum_eps    = 0x1p-31lk;
+long _Accum   long_accum_eps2   = 0x0.99999999p-31lk;
+
+//CHECK-NEXT: |-VarDecl {{.*}} short_accum_eps 'short _Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'short _Accum' 0.0078125
+//CHECK-NEXT: |-VarDecl {{.*}} short_accum_eps2 'short _Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'short _Accum' 0.0
+//CHECK-NEXT: |-VarDecl {{.*}} accum_eps '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 0.000030517578125
+//CHECK-NEXT: |-VarDecl {{.*}} accum_eps2 '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 0.0
+//CHECK-NEXT: |-VarDecl {{.*}} long_accum_eps 'long _Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'long _Accum' 0.0000000004656612873077392578125
+//CHECK-NEXT: |-VarDecl {{.*}} long_accum_eps2 'long _Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'long _Accum' 0.0
+
+// Fract literals can be one but evaluate to the respective Fract max
+short _Fract           short_fract_one   = 1.0hr;
+_Fract                 fract_one         = 1.0r;
+long _Fract            long_fract_one    = 1.0lr;
+unsigned short _Fract  u_short_fract_one = 1.0uhr;
+unsigned _Fract        u_fract_one       = 1.0ur;
+unsigned long _Fract   u_long_fract_one  = 1.0ulr;
+
+//CHECK-NEXT: |-VarDecl {{.*}} short_fract_one 'short _Fract' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'short _Fract' 0.9921875
+//CHECK-NEXT: |-VarDecl {{.*}} fract_one '_Fract' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Fract' 0.999969482421875
+//CHECK-NEXT: |-VarDecl {{.*}} long_fract_one 'long _Fract' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'long _Fract' 0.9999999995343387126922607421875
+
+//CHECK-NEXT: |-VarDecl {{.*}} u_short_fract_one 'unsigned short _Fract' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'unsigned short _Fract' 0.99609375
+//CHECK-NEXT: |-VarDecl {{.*}} u_fract_one 'unsigned _Fract' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'unsigned _Fract' 0.9999847412109375
+//CHECK-NEXT: |-VarDecl {{.*}} u_long_fract_one 'unsigned long _Fract' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} 'unsigned long _Fract' 0.99999999976716935634613037109375
+
+_Accum literallast = 1.0k;    // One
+
+//CHECK-NEXT: `-VarDecl {{.*}} literallast '_Accum' cinit
+//CHECK-NEXT:   `-FixedPointLiteral {{.*}} '_Accum' 1.0
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -328,6 +328,9 @@
     const LocationContext *LCtx = Pred->getLocationContext();
 
     switch (CastE->getCastKind()) {
+      case CK_IntegralToFixedPoint:
+        llvm_unreachable(
+            "ExprEngine::VisitCast CK_IntegralToFixedPoint");  // TODO
       case CK_LValueToRValue:
         llvm_unreachable("LValueToRValue casts handled earlier.");
       case CK_ToVoid:
Index: lib/StaticAnalyzer/Core/ExprEngine.cpp
===================================================================
--- lib/StaticAnalyzer/Core/ExprEngine.cpp
+++ lib/StaticAnalyzer/Core/ExprEngine.cpp
@@ -1297,6 +1297,7 @@
     case Stmt::AddrLabelExprClass:
     case Stmt::AttributedStmtClass:
     case Stmt::IntegerLiteralClass:
+    case Stmt::FixedPointLiteralClass:
     case Stmt::CharacterLiteralClass:
     case Stmt::ImplicitValueInitExprClass:
     case Stmt::CXXScalarValueInitExprClass:
Index: lib/Serialization/ASTWriterStmt.cpp
===================================================================
--- lib/Serialization/ASTWriterStmt.cpp
+++ lib/Serialization/ASTWriterStmt.cpp
@@ -444,6 +444,10 @@
   Code = serialization::EXPR_INTEGER_LITERAL;
 }
 
+void ASTStmtWriter::VisitFixedPointLiteral(FixedPointLiteral *E) {
+  llvm_unreachable("ASTStmtWriter::VisitFixedPointLiteral");
+}
+
 void ASTStmtWriter::VisitFloatingLiteral(FloatingLiteral *E) {
   VisitExpr(E);
   Record.push_back(E->getRawSemantics());
Index: lib/Serialization/ASTReaderStmt.cpp
===================================================================
--- lib/Serialization/ASTReaderStmt.cpp
+++ lib/Serialization/ASTReaderStmt.cpp
@@ -533,6 +533,12 @@
   E->setValue(Record.getContext(), Record.readAPInt());
 }
 
+void ASTStmtReader::VisitFixedPointLiteral(FixedPointLiteral *E) {
+  VisitExpr(E);
+  E->setLocation(ReadSourceLocation());
+  E->setValue(Record.getContext(), Record.readAPInt());
+}
+
 void ASTStmtReader::VisitFloatingLiteral(FloatingLiteral *E) {
   VisitExpr(E);
   E->setRawSemantics(static_cast<Stmt::APFloatSemantics>(Record.readInt()));
Index: lib/Sema/TreeTransform.h
===================================================================
--- lib/Sema/TreeTransform.h
+++ lib/Sema/TreeTransform.h
@@ -8888,6 +8888,12 @@
   return E;
 }
 
+template <typename Derived>
+ExprResult TreeTransform<Derived>::TransformFixedPointLiteral(
+    FixedPointLiteral *E) {
+  return E;
+}
+
 template<typename Derived>
 ExprResult
 TreeTransform<Derived>::TransformFloatingLiteral(FloatingLiteral *E) {
Index: lib/Sema/SemaExpr.cpp
===================================================================
--- lib/Sema/SemaExpr.cpp
+++ lib/Sema/SemaExpr.cpp
@@ -26,6 +26,7 @@
 #include "clang/AST/ExprOpenMP.h"
 #include "clang/AST/RecursiveASTVisitor.h"
 #include "clang/AST/TypeLoc.h"
+#include "clang/Basic/FixedPoint.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SourceManager.h"
 #include "clang/Basic/TargetInfo.h"
@@ -1218,6 +1219,46 @@
                               CK_IntegralRealToComplex);
   return ComplexType;
 }
+/// \brief Handle arithmetic conversion from integer to fixed point.  Helper
+/// function of UsualArithmeticConversions()
+static QualType handleIntToFixedPointConversion(Sema &S,
+                                                ExprResult &FixedPointExpr,
+                                                ExprResult &IntExpr,
+                                                QualType FixedPointTy,
+                                                QualType IntTy) {
+  assert(IntTy->isIntegerType());
+  assert(FixedPointTy->isFixedPointType());
+
+  IntExpr =
+      S.ImpCastExprToType(IntExpr.get(), FixedPointTy, CK_IntegralToFixedPoint);
+  return FixedPointTy;
+}
+
+/// \brief Handle arithmethic conversion with fixed point types.  Helper
+/// function of UsualArithmeticConversions().
+static QualType handleFixedPointConversion(Sema &S, ExprResult &LHS,
+                                           ExprResult &RHS, QualType LHSType,
+                                           QualType RHSType,
+                                           bool IsCompAssign) {
+  // At this point, the only other type we should be able to convert to is
+  // integer types since all prior types were handled beforehand in
+  // UsualArithmeticConventions().
+  bool LHSFixed = LHSType->isFixedPointType();
+  bool RHSFixed = RHSType->isFixedPointType();
+
+  if (LHSFixed && RHSFixed) {
+    // Cast up the smaller operand to the bigger
+    llvm_unreachable("Unhandled conversion between fixed point types");  // TODO
+  } else if (LHSFixed) {
+    assert(RHSType->isIntegerType());
+    return handleIntToFixedPointConversion(S, LHS, RHS, LHSType, RHSType);
+  } else if (RHSFixed) {
+    assert(LHSType->isIntegerType());
+    return handleIntToFixedPointConversion(S, RHS, LHS, RHSType, LHSType);
+  } else {
+    llvm_unreachable("Expected LHS and RHS to both be fixed point types.");
+  }
+}
 
 /// UsualArithmeticConversions - Performs various conversions that are common to
 /// binary operators (C99 6.3.1.8). If both operands aren't arithmetic, this
@@ -1291,6 +1332,11 @@
     return handleComplexIntConversion(*this, LHS, RHS, LHSType, RHSType,
                                       IsCompAssign);
 
+  // Handle fixed point types
+  if (LHSType->isFixedPointType() || RHSType->isFixedPointType())
+    return handleFixedPointConversion(*this, LHS, RHS, LHSType, RHSType,
+                                      IsCompAssign);
+
   // Finally, we have two differing integer types.
   return handleIntegerConversion<doIntegralCast, doIntegralCast>
            (*this, LHS, RHS, LHSType, RHSType, IsCompAssign);
@@ -3144,33 +3190,40 @@
                                 Context.IntTy, Loc);
 }
 
-static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal,
-                                  QualType Ty, SourceLocation Loc) {
-  const llvm::fltSemantics &Format = S.Context.getFloatTypeSemantics(Ty);
-
-  using llvm::APFloat;
-  APFloat Val(Format);
-
-  APFloat::opStatus result = Literal.GetFloatValue(Val);
-
+static void HandleFloatOverflow(Sema &S, QualType Ty, SourceLocation Loc,
+                                const llvm::APFloat::opStatus &result,
+                                const llvm::APFloat &Val,
+                                const llvm::fltSemantics &Format) {
   // Overflow is always an error, but underflow is only an error if
   // we underflowed to zero (APFloat reports denormals as underflow).
-  if ((result & APFloat::opOverflow) ||
-      ((result & APFloat::opUnderflow) && Val.isZero())) {
+  if ((result & llvm::APFloat::opOverflow) ||
+      ((result & llvm::APFloat::opUnderflow) && Val.isZero())) {
     unsigned diagnostic;
     SmallString<20> buffer;
-    if (result & APFloat::opOverflow) {
+    if (result & llvm::APFloat::opOverflow) {
       diagnostic = diag::warn_float_overflow;
-      APFloat::getLargest(Format).toString(buffer);
+      llvm::APFloat::getLargest(Format).toString(buffer);
     } else {
       diagnostic = diag::warn_float_underflow;
-      APFloat::getSmallest(Format).toString(buffer);
+      llvm::APFloat::getSmallest(Format).toString(buffer);
     }
 
     S.Diag(Loc, diagnostic)
       << Ty
       << StringRef(buffer.data(), buffer.size());
   }
+}
+
+static Expr *BuildFloatingLiteral(Sema &S, NumericLiteralParser &Literal,
+                                  QualType Ty, SourceLocation Loc) {
+  const llvm::fltSemantics &Format = S.Context.getFloatTypeSemantics(Ty);
+
+  using llvm::APFloat;
+  APFloat Val(Format);
+
+  APFloat::opStatus result = Literal.GetFloatValue(Val);
+
+  HandleFloatOverflow(S, Ty, Loc, result, Val, Format);
 
   bool isExact = (result == APFloat::opOK);
   return FloatingLiteral::Create(S.Context, Val, isExact, Ty, Loc);
@@ -3326,7 +3379,52 @@
 
   Expr *Res;
 
-  if (Literal.isFloatingLiteral()) {
+  if (Literal.isFixedPointLiteral()) {
+    QualType Ty;
+
+    if (Literal.isAccum) {
+      if (Literal.isHalf) {
+        Ty = Context.ShortAccumTy;
+      } else if (Literal.isLong) {
+        Ty = Context.LongAccumTy;
+      } else {
+        Ty = Context.AccumTy;
+      }
+    } else if (Literal.isFract) {
+      if (Literal.isHalf) {
+        Ty = Context.ShortFractTy;
+      } else if (Literal.isLong) {
+        Ty = Context.LongFractTy;
+      } else {
+        Ty = Context.FractTy;
+      }
+    }
+
+    if (Literal.isUnsigned) Ty = Context.getCorrespondingUnsignedType(Ty);
+
+    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);
+
+    // Do not use bit_width since some types may have padding like _Fract or
+    // unsigned _Accums if SameFBits is set.
+    auto MaxVal = llvm::APInt::getMaxValue(ibits + scale).zextOrSelf(bit_width);
+    if (Literal.isFract && Val == MaxVal + 1)
+      // 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
+      // the maximal value for the type.
+      --Val;
+    else if (Val.ugt(MaxVal) || Overflowed)
+      Diag(Tok.getLocation(), diag::err_too_large_for_fixed_point);
+
+    Res = FixedPointLiteral::CreateFromRawInt(Context, Val, Ty,
+                                              Tok.getLocation(), scale);
+  } else if (Literal.isFloatingLiteral()) {
     QualType Ty;
     if (Literal.isHalf){
       if (getOpenCLOptions().isEnabled("cl_khr_fp16"))
@@ -5807,13 +5905,21 @@
     case Type::STK_FloatingComplex:
     case Type::STK_IntegralComplex:
     case Type::STK_MemberPointer:
+    case Type::STK_FixedPoint:
       llvm_unreachable("illegal cast from pointer");
     }
     llvm_unreachable("Should have returned before this");
 
+  case Type::STK_FixedPoint:
+    llvm_unreachable(
+        "Sema::PrepareScalarCast from STK_FixedPoint to anything");  // TODO
+
   case Type::STK_Bool: // casting from bool is like casting from an integer
   case Type::STK_Integral:
     switch (DestTy->getScalarTypeKind()) {
+    case Type::STK_FixedPoint:
+      llvm_unreachable(
+          "Sema::PrepareScalarCast from STK_Integral to STK_FixedPoint");  // TODO
     case Type::STK_CPointer:
     case Type::STK_ObjCObjectPointer:
     case Type::STK_BlockPointer:
@@ -5844,6 +5950,9 @@
 
   case Type::STK_Floating:
     switch (DestTy->getScalarTypeKind()) {
+    case Type::STK_FixedPoint:
+      llvm_unreachable(
+          "Sema::PrepareScalarCast from STK_Floating to STK_FixedPoint");  // TODO
     case Type::STK_Floating:
       return CK_FloatingCast;
     case Type::STK_Bool:
@@ -5871,6 +5980,10 @@
 
   case Type::STK_FloatingComplex:
     switch (DestTy->getScalarTypeKind()) {
+    case Type::STK_FixedPoint:
+      llvm_unreachable(
+          "Sema::PrepareScalarCast from STK_FloatingComplex to "
+          "STK_FixedPoint");  // TODO
     case Type::STK_FloatingComplex:
       return CK_FloatingComplexCast;
     case Type::STK_IntegralComplex:
@@ -5900,6 +6013,10 @@
 
   case Type::STK_IntegralComplex:
     switch (DestTy->getScalarTypeKind()) {
+    case Type::STK_FixedPoint:
+      llvm_unreachable(
+          "Sema::PrepareScalarCast from STK_IntegralComplex to "
+          "STK_FixedPoint");  // TODO
     case Type::STK_FloatingComplex:
       return CK_IntegralComplexToFloatingComplex;
     case Type::STK_IntegralComplex:
@@ -13122,7 +13239,7 @@
     CondExpr = CondICE.get();
     CondIsTrue = condEval.getZExtValue();
 
-    // If the condition is > zero, then the AST type is the same as the LSHExpr.
+    // If the condition is > zero, then the AST type is the same as the LHSExpr.
     Expr *ActiveExpr = CondIsTrue ? LHSExpr : RHSExpr;
 
     resType = ActiveExpr->getType();
Index: lib/Sema/SemaExceptionSpec.cpp
===================================================================
--- lib/Sema/SemaExceptionSpec.cpp
+++ lib/Sema/SemaExceptionSpec.cpp
@@ -1258,6 +1258,7 @@
   case Expr::ImaginaryLiteralClass:
   case Expr::ImplicitValueInitExprClass:
   case Expr::IntegerLiteralClass:
+  case Expr::FixedPointLiteralClass:
   case Expr::ArrayInitIndexExprClass:
   case Expr::NoInitExprClass:
   case Expr::ObjCEncodeExprClass:
Index: lib/Sema/Sema.cpp
===================================================================
--- lib/Sema/Sema.cpp
+++ lib/Sema/Sema.cpp
@@ -532,6 +532,9 @@
   case Type::STK_Floating: return CK_FloatingToBoolean;
   case Type::STK_IntegralComplex: return CK_IntegralComplexToBoolean;
   case Type::STK_FloatingComplex: return CK_FloatingComplexToBoolean;
+  case Type::STK_FixedPoint:
+    llvm_unreachable(
+        "Sema::ScalarTypeToBooleanCastKind for fixed point");  // TODO
   }
   llvm_unreachable("unknown scalar type kind");
 }
Index: lib/Lex/LiteralSupport.cpp
===================================================================
--- lib/Lex/LiteralSupport.cpp
+++ lib/Lex/LiteralSupport.cpp
@@ -27,6 +27,7 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ConvertUTF.h"
 #include "llvm/Support/ErrorHandling.h"
+#include "llvm/Support/ScaledNumber.h"
 #include <algorithm>
 #include <cassert>
 #include <cstddef>
@@ -538,6 +539,7 @@
   saw_exponent = false;
   saw_period = false;
   saw_ud_suffix = false;
+  saw_fixed_point_suffix = false;
   isLong = false;
   isUnsigned = false;
   isLongLong = false;
@@ -547,6 +549,8 @@
   isFloat16 = false;
   isFloat128 = false;
   MicrosoftInteger = 0;
+  isFract = false;
+  isAccum = false;
   hadError = false;
 
   if (*s == '0') { // parse radix
@@ -568,19 +572,37 @@
   SuffixBegin = s;
   checkSeparator(TokLoc, s, CSK_AfterDigits);
 
+  // Initial scan to lookahead for fixed point suffix.
+  for (const char *c = s; c != ThisTokEnd; ++c) {
+    if (*c == 'r' || *c == 'k' || *c == 'R' || *c == 'K') {
+      saw_fixed_point_suffix = true;
+      break;
+    }
+  }
+
   // Parse the suffix.  At this point we can classify whether we have an FP or
   // integer constant.
   bool isFPConstant = isFloatingLiteral();
 
   // Loop over all of the characters of the suffix.  If we see something bad,
   // we break out of the loop.
   for (; s != ThisTokEnd; ++s) {
     switch (*s) {
+    case 'R':
+    case 'r':
+      if (isFract || isAccum) break;
+      isFract = true;
+      continue;
+    case 'K':
+    case 'k':
+      if (isFract || isAccum) break;
+      isAccum = true;
+      continue;
     case 'h':      // FP Suffix for "half".
     case 'H':
       // OpenCL Extension v1.2 s9.5 - h or H suffix for half type.
-      if (!PP.getLangOpts().Half) break;
-      if (!isFPConstant) break;  // Error for integer constant.
+      if (!(PP.getLangOpts().Half || PP.getLangOpts().FixedPoint)) break;
+      if (isIntegerLiteral()) break;          // Error for integer constant.
       if (isHalf || isFloat || isLong) break; // HH, FH, LH invalid.
       isHalf = true;
       continue;  // Success.
@@ -693,6 +715,9 @@
         isHalf = false;
         isImaginary = false;
         MicrosoftInteger = 0;
+        saw_fixed_point_suffix = false;
+        isFract = false;
+        isAccum = false;
       }
 
       saw_ud_suffix = true;
@@ -707,6 +732,11 @@
       hadError = true;
     }
   }
+
+  if (!hadError && saw_fixed_point_suffix) {
+    assert(isFract || isAccum);
+    assert(radix == 16 || radix == 10);
+  }
 }
 
 /// ParseDecimalOrOctalCommon - This method is called for decimal or octal
@@ -1012,6 +1042,272 @@
   return Result.convertFromString(Str, APFloat::rmNearestTiesToEven);
 }
 
+static inline bool IsExponentPart(char c) {
+  return c == 'p' || c == 'P' || c == 'e' || c == 'E';
+}
+
+bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale) {
+  assert(radix == 16 || radix == 10);
+
+  // Find how many digits are needed to store the whole literal.
+  unsigned NumDigits = SuffixBegin - DigitsBegin;
+  if (saw_period) --NumDigits;
+  unsigned NumBitsNeeded;
+
+  // Initial scan of the exponent if it exists
+  bool ExpOverflowOccurred = false;
+  unsigned Exponent = 0;  // APInt takes unsigned for bit width
+  int64_t BaseShift = 0;
+  bool NegativeExponent = false;
+  if (saw_exponent) {
+    const char *Ptr = DigitsBegin;
+
+    while (!IsExponentPart(*Ptr)) ++Ptr;
+    ++Ptr;
+    NegativeExponent = *Ptr == '-';
+    if (NegativeExponent) ++Ptr;
+
+    for (; Ptr < SuffixBegin; ++Ptr) {
+      unsigned C = llvm::hexDigitValue(*Ptr);
+      assert(C < 10 && "NumericLiteralParser ctor should have rejected this");
+
+      auto OldExponent = Exponent;
+      Exponent *= 10;
+      ExpOverflowOccurred |= (Exponent / 10 != OldExponent);
+      Exponent += C;
+      ExpOverflowOccurred |= (Exponent < C);
+    }
+
+    if (NegativeExponent) BaseShift -= Exponent;
+    else BaseShift += Exponent;
+  }
+
+  if (radix == 10) {
+    // Number of bits needed for decimal literal is
+    //   ceil(NumDigits * log2(10))       Integral part
+    // + Scale                            Fractional part
+    // + ceil(Exponent * log2(10))        Exponent
+    // --------------------------------------------------
+    //   ceil((NumDigits + Exponent) * log2(10)) + Scale
+    //
+    // But for simplicity in handling integers, we can round up log2(10) to 4,
+    // makeing:
+    // 4 * (NumDigits + Exponent) + Scale
+    NumBitsNeeded = NumDigits;
+    if (saw_exponent && !NegativeExponent) {
+      // Only want the max number of digits needed during calculations
+      NumBitsNeeded += Exponent;
+      ExpOverflowOccurred |= NumBitsNeeded < Exponent;
+    }
+
+    auto OldVal = NumBitsNeeded;
+    NumBitsNeeded *= 4;
+    ExpOverflowOccurred |= NumBitsNeeded / 4 != OldVal;
+
+    NumBitsNeeded += Scale;
+    ExpOverflowOccurred |= NumBitsNeeded < Scale;
+  } else {
+    // Number of digits needed for hexadecimal literal is
+    //   4 * NumDigits                    Integral part
+    // + Scale                            Fractional part
+    // + Exponent                         Exponent
+    // --------------------------------------------------
+    //   (4 * NumDigits) + Scale + Exponent
+    NumBitsNeeded = 4 * NumDigits;
+    ExpOverflowOccurred |= NumBitsNeeded / 4 != NumDigits;
+
+    NumBitsNeeded += Scale;
+    ExpOverflowOccurred |= NumBitsNeeded < Scale;
+
+    if (saw_exponent && !NegativeExponent) {
+      NumBitsNeeded += Exponent;
+      ExpOverflowOccurred |= NumBitsNeeded < Exponent;
+    }
+  }
+
+  llvm::APInt Val(NumBitsNeeded, 0, /*isSigned=*/false);
+
+  bool IntOverflowOccurred = false;
+  bool FractOverflowOccurred = false;
+  bool FoundExponent = false;
+  bool FoundDecimal = false;
+
+  int64_t FractBaseShift = 0;
+  for (const char *Ptr = DigitsBegin; Ptr < SuffixBegin; ++Ptr) {
+    if (*Ptr == '.') {
+      FoundDecimal = true;
+      continue;
+    }
+    if ((radix == 16 && (*Ptr == 'p' || *Ptr == 'P')) ||
+        (radix == 10 && (*Ptr == 'e' || *Ptr == 'E'))) {
+      FoundExponent = true;
+      ++Ptr;
+      break;
+    }
+
+    // Normal reading of an integer
+    unsigned C = llvm::hexDigitValue(*Ptr);
+    assert(C < radix && "NumericLiteralParser ctor should have rejected this");
+
+    // TODO: We may not need to account for overflow since we should have all
+    // digits necessary to fit the result.
+    auto OldVal = Val;
+    Val *= radix;
+    if (!FoundDecimal)
+      IntOverflowOccurred |= Val.udiv(radix) != OldVal;
+    else
+      FractOverflowOccurred |= Val.udiv(radix) != OldVal;
+
+    Val += C;
+    if (!FoundDecimal)
+      IntOverflowOccurred |= Val.ult(C);
+    else
+      FractOverflowOccurred |= Val.ult(C);
+
+    if (FractOverflowOccurred) {
+      // We do not mark as an error if we cannot fully store the fractional
+      // part, but we may not get full precision.
+      Val = OldVal;
+      break;
+    } else if (FoundDecimal) {
+      // Keep track of how much we will need to adjust this value by from the
+      // number of digits past the radix point.
+      --FractBaseShift;
+    }
+  }
+
+  // For a radix of 16, we will be multiplying by 2 instead of 16.
+  if (radix == 16) FractBaseShift *= 4;
+  BaseShift += FractBaseShift;
+
+  auto OldVal = Val;
+  Val <<= Scale;
+  IntOverflowOccurred |= Val.lshr(Scale) != OldVal;
+
+  uint64_t Base = (radix == 16) ? 2 : 10;
+  if (BaseShift > 0) {
+    for (int64_t i = 0; i < BaseShift && !IntOverflowOccurred; ++i) {
+      OldVal = Val;
+      Val *= Base;
+      IntOverflowOccurred |= Val.udiv(Base) != OldVal;
+    }
+  } else if (BaseShift < 0) {
+    for (int64_t i = BaseShift; i < 0 && !Val.isNullValue(); ++i)
+      Val = Val.udiv(Base);
+  }
+
+  auto MaxVal = llvm::APInt::getMaxValue(StoreVal.getBitWidth());
+  if (Val.getBitWidth() > StoreVal.getBitWidth()) {
+    IntOverflowOccurred |= Val.ugt(MaxVal.zext(Val.getBitWidth()));
+    StoreVal = Val.trunc(StoreVal.getBitWidth());
+  } else if (Val.getBitWidth() < StoreVal.getBitWidth()) {
+    IntOverflowOccurred |= Val.zext(MaxVal.getBitWidth()).ugt(MaxVal);
+    StoreVal = Val.zext(StoreVal.getBitWidth());
+  } else {
+    StoreVal = Val;
+  }
+
+  return IntOverflowOccurred || ExpOverflowOccurred;
+}
+
+//bool NumericLiteralParser::GetFixedPointValue(llvm::APInt &Val, unsigned Scale) {
+//  assert(radix == 16 || radix == 10);
+//
+//  // Need as much storage space as possible
+//  __int128 TmpVal = 0;
+//  bool IntOverflowOccurred = false;
+//  bool FractOverflowOccurred = false;
+//  bool FoundExponent = false;
+//  bool FoundDecimal = false;
+//
+//  int64_t BaseShift = 0;
+//  const char *Ptr = DigitsBegin;
+//  for (; Ptr < SuffixBegin; ++Ptr) {
+//    if (*Ptr == '.') {
+//      FoundDecimal = true;
+//      continue;
+//    }
+//    if (*Ptr == 'p' || *Ptr == 'P' || *Ptr == 'e' || *Ptr == 'E') {
+//      FoundExponent = true;
+//      ++Ptr;
+//      break;
+//    }
+//
+//    // Normal reading of an integer
+//    unsigned C = llvm::hexDigitValue(*Ptr);
+//    assert(C < radix && "NumericLiteralParser ctor should have rejected this");
+//
+//    auto OldVal = TmpVal;
+//    TmpVal *= radix;
+//    if (!FoundDecimal)
+//      IntOverflowOccurred |= (TmpVal / radix != OldVal);
+//    else
+//      FractOverflowOccurred |= (TmpVal / radix != OldVal);
+//
+//    TmpVal += C;
+//    if (!FoundDecimal)
+//      IntOverflowOccurred |= (TmpVal < C);
+//    else
+//      FractOverflowOccurred |= (TmpVal < C);
+//
+//    if (FractOverflowOccurred) {
+//      // We do not mark as an error if we cannot fully store the fractional
+//      // part, but we may not get full precision.
+//      TmpVal = OldVal;
+//      break;
+//    } else if (FoundDecimal) {
+//      // Keep track of how much we will need to adjust this value by from the
+//      // number of digits past the radix point.
+//      --BaseShift;
+//    }
+//  }
+//
+//  // For a radix of 16, we will be multiplying by 2 instead of 16.
+//  if (radix == 16) BaseShift *= 4;
+//
+//  bool ExpOverflowOccurred = false;
+//  if (FoundExponent) {
+//    uint64_t Exponent = 0;
+//    bool NegativeExponent = *Ptr == '-';
+//    if (NegativeExponent) ++Ptr;
+//    for (; Ptr < SuffixBegin; ++Ptr) {
+//      unsigned C = llvm::hexDigitValue(*Ptr);
+//      assert(C < 10 && "NumericLiteralParser ctor should have rejected this");
+//
+//      uint64_t OldExponent = Exponent;
+//      Exponent *= 10;
+//      ExpOverflowOccurred |= (Exponent / 10 != OldExponent);
+//      Exponent += C;
+//      ExpOverflowOccurred |= (Exponent < C);
+//    }
+//
+//    if (NegativeExponent)
+//      BaseShift -= Exponent;
+//    else
+//      BaseShift += Exponent;
+//  }
+//
+//  auto OldVal = TmpVal;
+//  TmpVal <<= Scale;
+//  IntOverflowOccurred |= (TmpVal >> Scale) != OldVal;
+//
+//  uint64_t Base = (radix == 16) ? 2 : 10;
+//  if (BaseShift > 0) {
+//    for (int64_t i = 0; i < BaseShift && !IntOverflowOccurred; ++i) {
+//      OldVal = TmpVal;
+//      TmpVal *= Base;
+//      IntOverflowOccurred |= (TmpVal / Base != OldVal);
+//    }
+//  } else if (BaseShift < 0) {
+//    for (int64_t i = BaseShift; i < 0 && TmpVal; ++i) TmpVal /= Base;
+//  }
+//
+//  uint64_t MaxVal = llvm::APInt::getMaxValue(Val.getBitWidth()).getZExtValue();
+//  IntOverflowOccurred |= TmpVal > MaxVal;
+//  Val = TmpVal;
+//  return IntOverflowOccurred || ExpOverflowOccurred;
+//}
+
 /// \verbatim
 ///       user-defined-character-literal: [C++11 lex.ext]
 ///         character-literal ud-suffix
Index: lib/Index/USRGeneration.cpp
===================================================================
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -743,6 +743,7 @@
           c = 'e'; break;
       }
       Out << c;
+
       return;
     }
 
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2337,6 +2337,10 @@
   Opts.FixedPoint =
       Args.hasFlag(OPT_ffixed_point, OPT_fno_fixed_point, /*Default=*/false) &&
       !Opts.CPlusPlus;
+  Opts.SameFBits =
+      Args.hasFlag(OPT_fsame_fbits, OPT_fno_same_fbits,
+                   /*Default=*/false) &&
+      Opts.FixedPoint;
 
   // Handle exception personalities
   Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions,
Index: lib/Edit/RewriteObjCFoundationAPI.cpp
===================================================================
--- lib/Edit/RewriteObjCFoundationAPI.cpp
+++ lib/Edit/RewriteObjCFoundationAPI.cpp
@@ -1002,6 +1002,9 @@
 
   if (const ImplicitCastExpr *ICE = dyn_cast<ImplicitCastExpr>(Arg)) {
     switch (ICE->getCastKind()) {
+    case CK_IntegralToFixedPoint:
+      llvm_unreachable(
+          "rewriteToNumericBoxedExpression CK_IntegralToFixedPoint");  // TODO
     case CK_LValueToRValue:
     case CK_NoOp:
     case CK_UserDefinedConversion:
Index: lib/Driver/ToolChains/Clang.cpp
===================================================================
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -3761,6 +3761,11 @@
                    /*Default=*/false))
     Args.AddLastArg(CmdArgs, options::OPT_ffixed_point);
 
+  if (Args.hasFlag(options::OPT_fsame_fbits,
+                   options::OPT_fno_same_fbits,
+                   /*Default=*/false))
+    Args.AddLastArg(CmdArgs, options::OPT_fsame_fbits);
+
   // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
   // (-ansi is equivalent to -std=c89 or -std=c++98).
   //
Index: lib/CodeGen/CGExprScalar.cpp
===================================================================
--- lib/CodeGen/CGExprScalar.cpp
+++ lib/CodeGen/CGExprScalar.cpp
@@ -23,6 +23,7 @@
 #include "clang/AST/Expr.h"
 #include "clang/AST/RecordLayout.h"
 #include "clang/AST/StmtVisitor.h"
+#include "clang/Basic/FixedPoint.h"
 #include "clang/Basic/TargetInfo.h"
 #include "clang/Frontend/CodeGenOptions.h"
 #include "llvm/ADT/Optional.h"
@@ -387,6 +388,9 @@
   Value *VisitIntegerLiteral(const IntegerLiteral *E) {
     return Builder.getInt(E->getValue());
   }
+  Value *VisitFixedPointLiteral(const FixedPointLiteral *E) {
+    return Builder.getInt(E->getValue());
+  }
   Value *VisitFloatingLiteral(const FloatingLiteral *E) {
     return llvm::ConstantFP::get(VMContext, E->getValue());
   }
@@ -1772,6 +1776,15 @@
     return Builder.CreateVectorSplat(NumElements, Elt, "splat");
   }
 
+  case CK_IntegralToFixedPoint: {
+    assert(DestTy->isFixedPointType());
+    assert(E->getType()->isIntegerType());
+    unsigned scale = CGF.getContext().getFixedPointScale(DestTy);
+    return Builder.CreateShl(
+        EmitScalarConversion(Visit(E), E->getType(), DestTy, CE->getExprLoc()),
+        scale, "integral_to_fixed_point");
+  }
+
   case CK_IntegralCast:
   case CK_IntegralToFloating:
   case CK_FloatingToIntegral:
Index: lib/CodeGen/CGExprConstant.cpp
===================================================================
--- lib/CodeGen/CGExprConstant.cpp
+++ lib/CodeGen/CGExprConstant.cpp
@@ -740,6 +740,8 @@
     Expr *subExpr = E->getSubExpr();
 
     switch (E->getCastKind()) {
+    case CK_IntegralToFixedPoint:
+      llvm_unreachable("VisitCastExpr CK_IntegralToFixedPoint");  // TODO
     case CK_ToUnion: {
       // GCC cast to union extension
       assert(E->getType()->isUnionType() &&
Index: lib/CodeGen/CGExprComplex.cpp
===================================================================
--- lib/CodeGen/CGExprComplex.cpp
+++ lib/CodeGen/CGExprComplex.cpp
@@ -509,6 +509,7 @@
   case CK_ZeroToOCLQueue:
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
+  case CK_IntegralToFixedPoint:
     llvm_unreachable("invalid cast kind for complex value");
 
   case CK_FloatingRealToComplex:
Index: lib/CodeGen/CGExprAgg.cpp
===================================================================
--- lib/CodeGen/CGExprAgg.cpp
+++ lib/CodeGen/CGExprAgg.cpp
@@ -684,12 +684,12 @@
       CGF.EmitDynamicCast(LV.getAddress(), cast<CXXDynamicCastExpr>(E));
     else
       CGF.CGM.ErrorUnsupported(E, "non-simple lvalue dynamic_cast");
-    
+
     if (!Dest.isIgnored())
       CGF.CGM.ErrorUnsupported(E, "lvalue dynamic_cast with a destination");
     break;
   }
-      
+
   case CK_ToUnion: {
     // Evaluate even if the destination is ignored.
     if (Dest.isIgnored()) {
@@ -851,6 +851,7 @@
   case CK_ZeroToOCLQueue:
   case CK_AddressSpaceConversion:
   case CK_IntToOCLSampler:
+  case CK_IntegralToFixedPoint:
     llvm_unreachable("cast kind invalid for aggregate types");
   }
 }
Index: lib/CodeGen/CGExpr.cpp
===================================================================
--- lib/CodeGen/CGExpr.cpp
+++ lib/CodeGen/CGExpr.cpp
@@ -4051,6 +4051,9 @@
 /// cast from scalar to union.
 LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
   switch (E->getCastKind()) {
+  case CK_IntegralToFixedPoint:
+    llvm_unreachable(
+        "CodeGenFunction::EmitCastLValue CK_IntegralToFixedPoint");  // TODO
   case CK_ToVoid:
   case CK_BitCast:
   case CK_ArrayToPointerDecay:
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -652,5 +652,7 @@
   if (!Target->validateTarget(Diags))
     return nullptr;
 
+  Target->CheckFixedPointBits();
+
   return Target.release();
 }
Index: lib/Basic/TargetInfo.cpp
===================================================================
--- lib/Basic/TargetInfo.cpp
+++ lib/Basic/TargetInfo.cpp
@@ -40,12 +40,26 @@
   IntWidth = IntAlign = 32;
   LongWidth = LongAlign = 32;
   LongLongWidth = LongLongAlign = 64;
+
+  // Fixed point default bit widths
   ShortAccumWidth = ShortAccumAlign = 16;
   AccumWidth = AccumAlign = 32;
   LongAccumWidth = LongAccumAlign = 64;
   ShortFractWidth = ShortFractAlign = 16;
   FractWidth = FractAlign = 32;
   LongFractWidth = LongFractAlign = 64;
+
+  // Fixed point default integral and fractional bit sizes
+  ShortAccumFBits = ShortFractFBits =  7;
+  ShortAccumIBits = UnsignedShortAccumIBits = 8;
+  AccumFBits = FractFBits = 15;
+  AccumIBits = UnsignedAccumIBits = 16;
+  LongAccumFBits = LongFractFBits = 31;
+  LongAccumIBits = UnsignedLongAccumIBits = 32;
+  UnsignedShortAccumFBits = UnsignedShortFractFBits = 8;
+  UnsignedAccumFBits = UnsignedFractFBits = 16;
+  UnsignedLongAccumFBits = UnsignedLongFractFBits = 32;
+
   SuitableAlign = 64;
   DefaultAlignForAttributeAligned = 128;
   MinGlobalAlign = 0;
@@ -303,6 +317,7 @@
     return false;
   };
 }
+#include "llvm/Support/raw_ostream.h"
 
 /// adjust - Set forced language options.
 /// Apply changes to the target information with respect to certain
@@ -362,6 +377,17 @@
 
   if (Opts.NewAlignOverride)
     NewAlign = Opts.NewAlignOverride * getCharWidth();
+
+  // Each unsigned fixed point type has the same number of fractional bits as
+  // its corresponding signed type.
+  if (Opts.SameFBits) {
+    UnsignedShortAccumFBits = ShortAccumFBits;
+    UnsignedAccumFBits = AccumFBits;
+    UnsignedLongAccumFBits = LongAccumFBits;
+    UnsignedShortFractFBits = ShortFractFBits;
+    UnsignedFractFBits = FractFBits;
+    UnsignedLongFractFBits = LongFractFBits;
+  }
 }
 
 bool TargetInfo::initFeatureMap(
@@ -716,3 +742,62 @@
 
   return true;
 }
+
+void TargetInfo::CheckFixedPointBits() const {
+  // Check that the number of fractional and integral bits (and maybe sign) can
+  // fit into the bits given for a fixed point type.
+  assert(ShortAccumFBits + ShortAccumIBits + 1 <= ShortAccumWidth);
+  assert(AccumFBits + AccumIBits + 1 <= AccumWidth);
+  assert(LongAccumFBits + LongAccumIBits + 1 <= LongAccumWidth);
+  assert(UnsignedShortAccumFBits + UnsignedShortAccumIBits <= ShortAccumWidth);
+  assert(UnsignedAccumFBits + UnsignedAccumIBits <= AccumWidth);
+  assert(UnsignedLongAccumFBits + UnsignedLongAccumIBits <= LongAccumWidth);
+
+  assert(ShortFractFBits + 1 <= ShortFractWidth);
+  assert(FractFBits + 1 <= FractWidth);
+  assert(LongFractFBits + 1 <= LongFractWidth);
+  assert(UnsignedShortFractFBits <= ShortFractWidth);
+  assert(UnsignedFractFBits <= FractWidth);
+  assert(UnsignedLongFractFBits <= LongFractWidth);
+
+  // Each unsigned fract type has either the same number of fractional bits
+  // as, or one more fractional bit than, its corresponding signed fract type.
+  assert(ShortFractFBits == UnsignedShortFractFBits ||
+         ShortFractFBits == UnsignedShortFractFBits - 1);
+  assert(FractFBits == UnsignedFractFBits ||
+         FractFBits == UnsignedFractFBits - 1);
+  assert(LongFractFBits == UnsignedLongFractFBits ||
+         LongFractFBits == UnsignedLongFractFBits - 1);
+
+  // When arranged in order of increasing rank (see 6.3.1.3a), the number of
+  // fractional bits is nondecreasing for each of the following sets of
+  // fixed-point types:
+  // - signed fract types
+  // - unsigned fract types
+  // - signed accum types
+  // - unsigned accum types.
+  assert(LongFractFBits >= FractFBits && FractFBits >= ShortFractFBits);
+  assert(UnsignedLongFractFBits >= UnsignedFractFBits &&
+         UnsignedFractFBits >= UnsignedShortFractFBits);
+  assert(LongAccumFBits >= AccumFBits && AccumFBits >= ShortAccumFBits);
+  assert(UnsignedLongAccumFBits >= UnsignedAccumFBits &&
+         UnsignedAccumFBits >= UnsignedShortAccumFBits);
+
+  // When arranged in order of increasing rank (see 6.3.1.3a), the number of
+  // integral bits is nondecreasing for each of the following sets of
+  // fixed-point types:
+  // - signed accum types
+  // - unsigned accum types
+  assert(LongAccumIBits >= AccumIBits && AccumIBits >= ShortAccumIBits);
+  assert(UnsignedLongAccumIBits >= UnsignedAccumIBits &&
+         UnsignedAccumIBits >= UnsignedShortAccumIBits);
+
+  // Each signed accum type has at least as many integral bits as its
+  // corresponding unsigned accum type.
+  assert(ShortAccumIBits == UnsignedShortAccumIBits ||
+         ShortAccumIBits == UnsignedShortAccumIBits - 1);
+  assert(AccumIBits == UnsignedAccumIBits ||
+         AccumIBits == UnsignedAccumIBits - 1);
+  assert(LongAccumIBits == UnsignedLongAccumIBits ||
+         LongAccumIBits == UnsignedLongAccumIBits - 1);
+}
Index: lib/AST/Type.cpp
===================================================================
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -50,6 +50,7 @@
 #include <cassert>
 #include <cstdint>
 #include <cstring>
+#include <sstream>
 
 using namespace clang;
 
@@ -1936,6 +1937,7 @@
     if (BT->getKind() == BuiltinType::NullPtr) return STK_CPointer;
     if (BT->isInteger()) return STK_Integral;
     if (BT->isFloatingPoint()) return STK_Floating;
+    if (BT->isFixedPointType()) return STK_FixedPoint;
     llvm_unreachable("unknown scalar builtin type");
   } else if (isa<PointerType>(T)) {
     return STK_CPointer;
@@ -3986,3 +3988,19 @@
 CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
   return getClass()->getAsCXXRecordDecl()->getMostRecentNonInjectedDecl();
 }
+
+void clang::FixedPointValueToString(SmallVectorImpl<char> &Str,
+                                    const llvm::APSInt &Val, unsigned Scale,
+                                    unsigned Radix) {
+  llvm::APSInt ScaleVal = llvm::APSInt::getUnsigned(1ULL << Scale);
+  llvm::APSInt IntPart = Val / ScaleVal;
+  llvm::APSInt FractPart = Val % ScaleVal;
+  llvm::APSInt RadixInt = llvm::APSInt::getUnsigned(Radix);
+
+  IntPart.toString(Str, Radix);
+  Str.push_back('.');
+  do {
+    (FractPart * RadixInt / ScaleVal).toString(Str, Radix);
+    FractPart = (FractPart * RadixInt) % ScaleVal;
+  } while (FractPart.getExtValue());
+}
Index: lib/AST/StmtProfile.cpp
===================================================================
--- lib/AST/StmtProfile.cpp
+++ lib/AST/StmtProfile.cpp
@@ -1007,6 +1007,12 @@
   ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
 }
 
+void StmtProfiler::VisitFixedPointLiteral(const FixedPointLiteral *S) {
+  VisitExpr(S);
+  S->getValue().Profile(ID);
+  ID.AddInteger(S->getType()->castAs<BuiltinType>()->getKind());
+}
+
 void StmtProfiler::VisitCharacterLiteral(const CharacterLiteral *S) {
   VisitExpr(S);
   ID.AddInteger(S->getKind());
Index: lib/AST/StmtPrinter.cpp
===================================================================
--- lib/AST/StmtPrinter.cpp
+++ lib/AST/StmtPrinter.cpp
@@ -1529,6 +1529,28 @@
   }
 }
 
+void StmtPrinter::VisitFixedPointLiteral(FixedPointLiteral *Node) {
+  if (Policy.ConstantsAsWritten && printExprAsWritten(OS, Node, Context))
+    return;
+  OS << Node->getValueAsString(/*Radix=*/10);
+
+  switch (Node->getType()->getAs<BuiltinType>()->getKind()) {
+    default: llvm_unreachable("Unexpected type for fixed point literal!");
+    case BuiltinType::ShortFract:   OS << "hr"; break;
+    case BuiltinType::ShortAccum:   OS << "hk"; break;
+    case BuiltinType::UShortFract:  OS << "uhr"; break;
+    case BuiltinType::UShortAccum:  OS << "uhk"; break;
+    case BuiltinType::Fract:        OS << "r"; break;
+    case BuiltinType::Accum:        OS << "k"; break;
+    case BuiltinType::UFract:       OS << "ur"; break;
+    case BuiltinType::UAccum:       OS << "uk"; break;
+    case BuiltinType::LongFract:    OS << "lr"; break;
+    case BuiltinType::LongAccum:    OS << "lk"; break;
+    case BuiltinType::ULongFract:   OS << "ulr"; break;
+    case BuiltinType::ULongAccum:   OS << "ulk"; break;
+  }
+}
+
 static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
                                  bool PrintSuffix) {
   SmallString<16> Str;
Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp
+++ lib/AST/ItaniumMangle.cpp
@@ -3445,6 +3445,8 @@
   
 recurse:
   switch (E->getStmtClass()) {
+  case Expr::FixedPointLiteralClass:
+    llvm_unreachable("Unknown mangling for FixedPointLiteralClass");
   case Expr::NoStmtClass:
 #define ABSTRACT_STMT(Type)
 #define EXPR(Type, Base)
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -7220,6 +7220,73 @@
 
   // FIXME: Missing: array subscript of vector, member of vector
 };
+
+class FixedPointExprEvaluator
+    : public ExprEvaluatorBase<FixedPointExprEvaluator> {
+  APValue &Result;
+
+ public:
+  FixedPointExprEvaluator(EvalInfo &info, APValue &result)
+      : ExprEvaluatorBaseTy(info), Result(result) {}
+
+  bool Success(const llvm::APSInt &SI, const Expr *E, APValue &Result) {
+    assert(E->getType()->isFixedPointType() && "Invalid evaluation result.");
+    assert(SI.isSigned() == E->getType()->isSignedFixedPointType() &&
+           "Invalid evaluation result.");
+    assert(SI.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
+           "Invalid evaluation result.");
+    Result = APValue(SI);
+    return true;
+  }
+  bool Success(const llvm::APSInt &SI, const Expr *E) {
+    return Success(SI, E, Result);
+  }
+
+  bool Success(const llvm::APInt &I, const Expr *E, APValue &Result) {
+    assert(E->getType()->isFixedPointType() && "Invalid evaluation result.");
+    assert(I.getBitWidth() == Info.Ctx.getIntWidth(E->getType()) &&
+           "Invalid evaluation result.");
+    Result = APValue(APSInt(I));
+    Result.getInt().setIsUnsigned(E->getType()->isUnsignedFixedPointType());
+    return true;
+  }
+  bool Success(const llvm::APInt &I, const Expr *E) {
+    return Success(I, E, Result);
+  }
+
+  bool Success(uint64_t Value, const Expr *E, APValue &Result) {
+    assert(E->getType()->isFixedPointType() && "Invalid evaluation result.");
+    Result = APValue(Info.Ctx.MakeIntValue(Value, E->getType()));
+    return true;
+  }
+  bool Success(uint64_t Value, const Expr *E) {
+    return Success(Value, E, Result);
+  }
+
+  bool Success(CharUnits Size, const Expr *E) {
+    return Success(Size.getQuantity(), E);
+  }
+
+  bool Success(const APValue &V, const Expr *E) {
+    if (V.isLValue() || V.isAddrLabelDiff()) {
+      Result = V;
+      return true;
+    }
+    return Success(V.getInt(), E);
+  }
+
+  bool ZeroInitialization(const Expr *E) { return Success(0, E); }
+
+  //===--------------------------------------------------------------------===//
+  //                            Visitor Methods
+  //===--------------------------------------------------------------------===//
+
+  bool VisitFixedPointLiteral(const FixedPointLiteral *E) {
+    return Success(E->getValue(), E);
+  }
+
+  bool VisitUnaryOperator(const UnaryOperator *E);
+};
 } // end anonymous namespace
 
 /// EvaluateIntegerOrLValue - Evaluate an rvalue integral-typed expression, and
@@ -9166,6 +9233,9 @@
   QualType SrcType = SubExpr->getType();
 
   switch (E->getCastKind()) {
+  case CK_IntegralToFixedPoint:
+    llvm_unreachable(
+        "IntExprEvaluator::VisitCastExpr CK_IntegralToFixedPoint");  // TODO
   case CK_BaseToDerived:
   case CK_DerivedToBase:
   case CK_UncheckedDerivedToBase:
@@ -9342,6 +9412,39 @@
   return Success(E->getValue(), E);
 }
 
+bool FixedPointExprEvaluator::VisitUnaryOperator(const UnaryOperator *E) {
+  switch (E->getOpcode()) {
+    default:
+      // Invalid unary operators
+      return Error(E);
+    case UO_Plus:
+      // The result is just the value.
+      return Visit(E->getSubExpr());
+    case UO_Minus: {
+      if (!Visit(E->getSubExpr())) return false;
+      if (!Result.isInt()) return Error(E);
+      const APSInt &Value = Result.getInt();
+      if (Value.isSigned() && Value.isMinSignedValue() && E->canOverflow()) {
+        SmallString<64> S;
+        FixedPointValueToString(
+            S,
+            Value,
+            Info.Ctx.getTypeInfo(E->getType()).Width,
+            /*Radix=*/10);
+        Info.CCEDiag(E, diag::note_constexpr_overflow) << S << E->getType();
+        if (Info.noteUndefinedBehavior()) return false;
+      }
+      return Success(-Value, E);
+    }
+    case UO_LNot: {
+      bool bres;
+      if (!EvaluateAsBooleanCondition(E->getSubExpr(), bres, Info))
+        return false;
+      return Success(!bres, E);
+    }
+  }
+}
+
 //===----------------------------------------------------------------------===//
 // Float Evaluation
 //===----------------------------------------------------------------------===//
@@ -9659,6 +9762,9 @@
 bool ComplexExprEvaluator::VisitCastExpr(const CastExpr *E) {
 
   switch (E->getCastKind()) {
+  case CK_IntegralToFixedPoint:
+    llvm_unreachable(
+        "ComplexExprEvaluator::VisitCastExpr CK_IntegralToFixedPoint");  // TODO
   case CK_BitCast:
   case CK_BaseToDerived:
   case CK_DerivedToBase:
@@ -10193,6 +10299,8 @@
     if (!EvaluateComplex(E, C, Info))
       return false;
     C.moveInto(Result);
+  } else if (T->isFixedPointType()) {
+    if (!FixedPointExprEvaluator(Info, Result).Visit(E)) return false;
   } else if (T->isMemberPointerType()) {
     MemberPtr P;
     if (!EvaluateMemberPointer(E, P, Info))
@@ -10641,6 +10749,7 @@
   case Expr::GenericSelectionExprClass:
     return CheckICE(cast<GenericSelectionExpr>(E)->getResultExpr(), Ctx);
   case Expr::IntegerLiteralClass:
+  case Expr::FixedPointLiteralClass:
   case Expr::CharacterLiteralClass:
   case Expr::ObjCBoolLiteralExprClass:
   case Expr::CXXBoolLiteralExprClass:
Index: lib/AST/ExprClassification.cpp
===================================================================
--- lib/AST/ExprClassification.cpp
+++ lib/AST/ExprClassification.cpp
@@ -161,6 +161,7 @@
   case Expr::ShuffleVectorExprClass:
   case Expr::ConvertVectorExprClass:
   case Expr::IntegerLiteralClass:
+  case Expr::FixedPointLiteralClass:
   case Expr::CharacterLiteralClass:
   case Expr::AddrLabelExprClass:
   case Expr::CXXDeleteExprClass:
Index: lib/AST/Expr.cpp
===================================================================
--- lib/AST/Expr.cpp
+++ lib/AST/Expr.cpp
@@ -755,6 +755,37 @@
   return new (C) IntegerLiteral(Empty);
 }
 
+FixedPointLiteral::FixedPointLiteral(const ASTContext &C, const llvm::APInt &V,
+                                     QualType type, SourceLocation l,
+                                     unsigned Scale)
+    : Expr(FixedPointLiteralClass, type, VK_RValue, OK_Ordinary, false, false,
+           false, false),
+      Loc(l), Scale(Scale) {
+  assert(type->isFixedPointType() && "Illegal type in FixedPointLiteral");
+  assert(V.getBitWidth() == C.getTypeInfo(type).Width &&
+         "Fixed point type is not the correct size for constant.");
+  setValue(C, V);
+}
+
+FixedPointLiteral *FixedPointLiteral::CreateFromRawInt(const ASTContext &C,
+                                                       const llvm::APInt &V,
+                                                       QualType type,
+                                                       SourceLocation l,
+                                                       unsigned Scale) {
+  return new (C) FixedPointLiteral(C, V, type, l, Scale);
+}
+
+std::string FixedPointLiteral::getValueAsString(unsigned Radix) const {
+  // Currently the longest decimal number that can be printed is the max for an
+  // unsigned long _Accum: 4294967295.99999999976716935634613037109375
+  // which is 43 characters.
+  SmallString<64> S;
+  FixedPointValueToString(S,
+      llvm::APSInt::getUnsigned(getValue().getZExtValue()),
+      Scale, Radix);
+  return S.str();
+}
+
 FloatingLiteral::FloatingLiteral(const ASTContext &C, const llvm::APFloat &V,
                                  bool isexact, QualType Type, SourceLocation L)
   : Expr(FloatingLiteralClass, Type, VK_RValue, OK_Ordinary, false, false,
@@ -1610,6 +1641,7 @@
   case CK_ZeroToOCLEvent:
   case CK_ZeroToOCLQueue:
   case CK_IntToOCLSampler:
+  case CK_IntegralToFixedPoint:
     assert(!getType()->isBooleanType() && "unheralded conversion to bool");
     goto CheckNoBasePath;
 
@@ -2991,6 +3023,7 @@
   case ObjCIvarRefExprClass:
   case PredefinedExprClass:
   case IntegerLiteralClass:
+  case FixedPointLiteralClass:
   case FloatingLiteralClass:
   case ImaginaryLiteralClass:
   case StringLiteralClass:
Index: lib/AST/ASTDumper.cpp
===================================================================
--- lib/AST/ASTDumper.cpp
+++ lib/AST/ASTDumper.cpp
@@ -525,6 +525,7 @@
     void VisitPredefinedExpr(const PredefinedExpr *Node);
     void VisitCharacterLiteral(const CharacterLiteral *Node);
     void VisitIntegerLiteral(const IntegerLiteral *Node);
+    void VisitFixedPointLiteral(const FixedPointLiteral *Node);
     void VisitFloatingLiteral(const FloatingLiteral *Node);
     void VisitStringLiteral(const StringLiteral *Str);
     void VisitInitListExpr(const InitListExpr *ILE);
@@ -2177,6 +2178,13 @@
   OS << " " << Node->getValue().toString(10, isSigned);
 }
 
+void ASTDumper::VisitFixedPointLiteral(const FixedPointLiteral *Node) {
+  VisitExpr(Node);
+
+  ColorScope Color(*this, ValueColor);
+  OS << " " << Node->getValueAsString(/*Radix=*/10);
+}
+
 void ASTDumper::VisitFloatingLiteral(const FloatingLiteral *Node) {
   VisitExpr(Node);
   ColorScope Color(*this, ValueColor);
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -10131,3 +10131,92 @@
 clang::LazyGenerationalUpdatePtr<
     const Decl *, Decl *, &ExternalASTSource::CompleteRedeclChain>::makeValue(
         const clang::ASTContext &Ctx, Decl *Value);
+
+unsigned char ASTContext::getFixedPointScale(const QualType &Ty) const {
+  assert(Ty->isFixedPointType());
+
+  const auto *BT = Ty->getAs<BuiltinType>();
+  const TargetInfo &Target = getTargetInfo();
+  switch (BT->getKind()) {
+    default:
+      llvm_unreachable("Not a fixed point type!");
+    case BuiltinType::ShortAccum:
+    case BuiltinType::SatShortAccum:
+      return Target.getShortAccumFBits();
+    case BuiltinType::Accum:
+    case BuiltinType::SatAccum:
+      return Target.getAccumFBits();
+    case BuiltinType::LongAccum:
+    case BuiltinType::SatLongAccum:
+      return Target.getLongAccumFBits();
+    case BuiltinType::UShortAccum:
+    case BuiltinType::SatUShortAccum:
+      return Target.getUnsignedShortAccumFBits();
+    case BuiltinType::UAccum:
+    case BuiltinType::SatUAccum:
+      return Target.getUnsignedAccumFBits();
+    case BuiltinType::ULongAccum:
+    case BuiltinType::SatULongAccum:
+      return Target.getUnsignedLongAccumFBits();
+    case BuiltinType::ShortFract:
+    case BuiltinType::SatShortFract:
+      return Target.getShortFractFBits();
+    case BuiltinType::Fract:
+    case BuiltinType::SatFract:
+      return Target.getFractFBits();
+    case BuiltinType::LongFract:
+    case BuiltinType::SatLongFract:
+      return Target.getLongFractFBits();
+    case BuiltinType::UShortFract:
+    case BuiltinType::SatUShortFract:
+      return Target.getUnsignedShortFractFBits();
+    case BuiltinType::UFract:
+    case BuiltinType::SatUFract:
+      return Target.getUnsignedFractFBits();
+    case BuiltinType::ULongFract:
+    case BuiltinType::SatULongFract:
+      return Target.getUnsignedLongFractFBits();
+  }
+}
+
+unsigned char ASTContext::getFixedPointIBits(const QualType &Ty) const {
+  assert(Ty->isFixedPointType());
+
+  const auto *BT = Ty->getAs<BuiltinType>();
+  const TargetInfo &Target = getTargetInfo();
+  switch (BT->getKind()) {
+    default:
+      llvm_unreachable("Not a fixed point type!");
+    case BuiltinType::ShortAccum:
+    case BuiltinType::SatShortAccum:
+      return Target.getShortAccumIBits();
+    case BuiltinType::Accum:
+    case BuiltinType::SatAccum:
+      return Target.getAccumIBits();
+    case BuiltinType::LongAccum:
+    case BuiltinType::SatLongAccum:
+      return Target.getLongAccumIBits();
+    case BuiltinType::UShortAccum:
+    case BuiltinType::SatUShortAccum:
+      return Target.getUnsignedShortAccumIBits();
+    case BuiltinType::UAccum:
+    case BuiltinType::SatUAccum:
+      return Target.getUnsignedAccumIBits();
+    case BuiltinType::ULongAccum:
+    case BuiltinType::SatULongAccum:
+      return Target.getUnsignedLongAccumIBits();
+    case BuiltinType::ShortFract:
+    case BuiltinType::SatShortFract:
+    case BuiltinType::Fract:
+    case BuiltinType::SatFract:
+    case BuiltinType::LongFract:
+    case BuiltinType::SatLongFract:
+    case BuiltinType::UShortFract:
+    case BuiltinType::SatUShortFract:
+    case BuiltinType::UFract:
+    case BuiltinType::SatUFract:
+    case BuiltinType::ULongFract:
+    case BuiltinType::SatULongFract:
+      return 0;
+  }
+}
Index: include/clang/Lex/LiteralSupport.h
===================================================================
--- include/clang/Lex/LiteralSupport.h
+++ include/clang/Lex/LiteralSupport.h
@@ -50,7 +50,7 @@
 
   unsigned radix;
 
-  bool saw_exponent, saw_period, saw_ud_suffix;
+  bool saw_exponent, saw_period, saw_ud_suffix, saw_fixed_point_suffix;
 
   SmallString<32> UDSuffixBuf;
 
@@ -69,11 +69,16 @@
   bool isFloat128 : 1;      // 1.0q
   uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.
 
+  bool isFract : 1;         // 1.0hr/r/lr/uhr/ur/ulr
+  bool isAccum : 1;         // 1.0hk/k/lk/uhk/uk/ulk
+
+  bool isFixedPointLiteral() const { return saw_fixed_point_suffix; }
+
   bool isIntegerLiteral() const {
-    return !saw_period && !saw_exponent;
+    return !saw_period && !saw_exponent && !isFixedPointLiteral();
   }
   bool isFloatingLiteral() const {
-    return saw_period || saw_exponent;
+    return (saw_period || saw_exponent) && !isFixedPointLiteral();
   }
 
   bool hasUDSuffix() const {
@@ -105,6 +110,12 @@
   /// literal exactly, and false otherwise.
   llvm::APFloat::opStatus GetFloatValue(llvm::APFloat &Result);
 
+  /// GetFixedPointValue - Convert this numeric literal value into a
+  /// scaled integer that represents this value. Returns true if an overflow
+  /// occurred when calculating the integral part of the scaled integer or
+  /// calculating the digit sequence of the exponent.
+  bool GetFixedPointValue(llvm::APInt &StoreVal, unsigned Scale);
+
 private:
 
   void ParseNumberStartingWithZero(SourceLocation TokLoc);
@@ -157,7 +168,6 @@
       ptr++;
     return ptr;
   }
-
 };
 
 /// CharLiteralParser - Perform interpretation and semantic analysis of a
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -891,6 +891,10 @@
                    Flags<[CC1Option]>, HelpText<"Enable fixed point types">;
 def fno_fixed_point : Flag<["-"], "fno-fixed-point">, Group<f_Group>,
                       HelpText<"Disable fixed point types">;
+def fsame_fbits : Flag<["-"], "fsame-fbits">, Group<f_Group>,
+                  Flags<[CC1Option]>,
+		  HelpText<"Force each unsigned fixed point type to have the same number of fractional bits as its corresponding signed type">;
+def fno_same_fbits : Flag<["-"], "fno-same-fbits">, Group<f_Group>;
 
 // Begin sanitizer flags. These should all be core options exposed in all driver
 // modes.
Index: include/clang/Basic/TargetInfo.h
===================================================================
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -74,12 +74,31 @@
   unsigned char LargeArrayMinWidth, LargeArrayAlign;
   unsigned char LongWidth, LongAlign;
   unsigned char LongLongWidth, LongLongAlign;
+
+  // Fixed point bit widths
   unsigned char ShortAccumWidth, ShortAccumAlign;
   unsigned char AccumWidth, AccumAlign;
   unsigned char LongAccumWidth, LongAccumAlign;
   unsigned char ShortFractWidth, ShortFractAlign;
   unsigned char FractWidth, FractAlign;
   unsigned char LongFractWidth, LongFractAlign;
+
+  // Fixed point integral and fractional bit sizes
+  // Saturated types share the same integral/fractional bits as their
+  // corresponding unsaturated types.
+  unsigned char ShortAccumFBits, ShortAccumIBits;
+  unsigned char AccumFBits, AccumIBits;
+  unsigned char LongAccumFBits, LongAccumIBits;
+  unsigned char UnsignedShortAccumFBits, UnsignedShortAccumIBits;
+  unsigned char UnsignedAccumFBits, UnsignedAccumIBits;
+  unsigned char UnsignedLongAccumFBits, UnsignedLongAccumIBits;
+  unsigned char ShortFractFBits;
+  unsigned char FractFBits;
+  unsigned char LongFractFBits;
+  unsigned char UnsignedShortFractFBits;
+  unsigned char UnsignedFractFBits;
+  unsigned char UnsignedLongFractFBits;
+
   unsigned char SuitableAlign;
   unsigned char DefaultAlignForAttributeAligned;
   unsigned char MinGlobalAlign;
@@ -394,6 +413,60 @@
   unsigned getLongFractWidth() const { return LongFractWidth; }
   unsigned getLongFractAlign() const { return LongFractAlign; }
 
+  /// getShortAccumFBits/IBits - Return the number of fractional/integral bits
+  /// in a 'signed short _Accum' type.
+  unsigned getShortAccumFBits() const { return ShortAccumFBits; }
+  unsigned getShortAccumIBits() const { return ShortAccumIBits; }
+
+  /// getAccumFBits/IBits - Return the number of fractional/integral bits
+  /// in a 'signed _Accum' type.
+  unsigned getAccumFBits() const { return AccumFBits; }
+  unsigned getAccumIBits() const { return AccumIBits; }
+
+  /// getLongAccumFBits/IBits - Return the number of fractional/integral bits
+  /// in a 'signed long _Accum' type.
+  unsigned getLongAccumFBits() const { return LongAccumFBits; }
+  unsigned getLongAccumIBits() const { return LongAccumIBits; }
+
+  /// getUnsignedShortAccumFBits/IBits - Return the number of fractional/integral bits
+  /// in a 'unsigned short _Accum' type.
+  unsigned getUnsignedShortAccumFBits() const { return UnsignedShortAccumFBits; }
+  unsigned getUnsignedShortAccumIBits() const { return UnsignedShortAccumIBits; }
+
+  /// getUnsignedAccumFBits/IBits - Return the number of fractional/integral bits
+  /// in a 'unsigned _Accum' type.
+  unsigned getUnsignedAccumFBits() const { return UnsignedAccumFBits; }
+  unsigned getUnsignedAccumIBits() const { return UnsignedAccumIBits; }
+
+  /// getUnsignedLongAccumFBits/IBits - Return the number of fractional/integral bits
+  /// in a 'unsigned long _Accum' type.
+  unsigned getUnsignedLongAccumFBits() const { return UnsignedLongAccumFBits; }
+  unsigned getUnsignedLongAccumIBits() const { return UnsignedLongAccumIBits; }
+
+  /// getShortFractFBits - Return the number of fractional bits
+  /// in a 'signed short _Fract' type.
+  unsigned getShortFractFBits() const { return ShortFractFBits; }
+
+  /// getFractFBits - Return the number of fractional bits
+  /// in a 'signed _Fract' type.
+  unsigned getFractFBits() const { return FractFBits; }
+
+  /// getLongFractFBits - Return the number of fractional bits
+  /// in a 'signed long _Fract' type.
+  unsigned getLongFractFBits() const { return LongFractFBits; }
+
+  /// getUnsignedShortFractFBits - Return the number of fractional bits
+  /// in a 'unsigned short _Fract' type.
+  unsigned getUnsignedShortFractFBits() const { return UnsignedShortFractFBits; }
+
+  /// getUnsignedFractFBits - Return the number of fractional bits
+  /// in a 'unsigned _Fract' type.
+  unsigned getUnsignedFractFBits() const { return UnsignedFractFBits; }
+
+  /// getUnsignedLongFractFBits - Return the number of fractional bits
+  /// in a 'unsigned long _Fract' type.
+  unsigned getUnsignedLongFractFBits() const { return UnsignedLongFractFBits; }
+
   /// Determine whether the __int128 type is supported on this target.
   virtual bool hasInt128Type() const {
     return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128;
@@ -1189,6 +1262,11 @@
   virtual ArrayRef<AddlRegName> getGCCAddlRegNames() const {
     return None;
   }
+
+ private:
+  // Assert the values for the fractional and integral bits for each fixed point
+  // type follow the restrictions given in clause 6.2.6.3 of N1169.
+  void CheckFixedPointBits() const;
 };
 
 }  // end namespace clang
Index: include/clang/Basic/StmtNodes.td
===================================================================
--- include/clang/Basic/StmtNodes.td
+++ include/clang/Basic/StmtNodes.td
@@ -57,6 +57,7 @@
 def PredefinedExpr : DStmt<Expr>;
 def DeclRefExpr : DStmt<Expr>;
 def IntegerLiteral : DStmt<Expr>;
+def FixedPointLiteral : DStmt<Expr>;
 def FloatingLiteral : DStmt<Expr>;
 def ImaginaryLiteral : DStmt<Expr>;
 def StringLiteral : DStmt<Expr>;
Index: include/clang/Basic/LangOptions.def
===================================================================
--- include/clang/Basic/LangOptions.def
+++ include/clang/Basic/LangOptions.def
@@ -303,6 +303,8 @@
 COMPATIBLE_VALUE_LANGOPT(FunctionAlignment, 5, 0, "Default alignment for functions")
 
 LANGOPT(FixedPoint, 1, 0, "fixed point types")
+LANGOPT(SameFBits, 1, 0,
+        "unsigned and signed fixed point type having the same number of fractional bits")
 
 #undef LANGOPT
 #undef COMPATIBLE_LANGOPT
Index: include/clang/Basic/DiagnosticCommonKinds.td
===================================================================
--- include/clang/Basic/DiagnosticCommonKinds.td
+++ include/clang/Basic/DiagnosticCommonKinds.td
@@ -168,6 +168,8 @@
                           InGroup<GccCompat>;
 def ext_clang_diagnose_if : Extension<"'diagnose_if' is a clang extension">,
                             InGroup<GccCompat>;
+def err_too_large_for_fixed_point : Error<
+  "this value is too large for this fixed point type">;
 def err_fixed_point_not_enabled : Error<"compile with "
   "'-ffixed-point' to enable fixed point types">;
 
Index: include/clang/AST/Type.h
===================================================================
--- include/clang/AST/Type.h
+++ include/clang/AST/Type.h
@@ -30,6 +30,7 @@
 #include "clang/Basic/Specifiers.h"
 #include "clang/Basic/Visibility.h"
 #include "llvm/ADT/APInt.h"
+#include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/None.h"
@@ -1918,7 +1919,8 @@
     STK_Integral,
     STK_Floating,
     STK_IntegralComplex,
-    STK_FloatingComplex
+    STK_FloatingComplex,
+    STK_FixedPoint
   };
 
   /// Given that this is a scalar type, classify it.
@@ -6546,6 +6548,12 @@
   return cast<PointerType>(Decayed)->getPointeeType();
 }
 
+// Get the decimal string representation of a fixed point type, represented
+// as a scaled integer.
+void FixedPointValueToString(SmallVectorImpl<char> &Str,
+                             const llvm::APSInt &Val,
+                             unsigned Scale, unsigned Radix);
+
 } // namespace clang
 
 #endif // LLVM_CLANG_AST_TYPE_H
Index: include/clang/AST/RecursiveASTVisitor.h
===================================================================
--- include/clang/AST/RecursiveASTVisitor.h
+++ include/clang/AST/RecursiveASTVisitor.h
@@ -2585,6 +2585,7 @@
 
 // These literals (all of them) do not need any action.
 DEF_TRAVERSE_STMT(IntegerLiteral, {})
+DEF_TRAVERSE_STMT(FixedPointLiteral, {})
 DEF_TRAVERSE_STMT(CharacterLiteral, {})
 DEF_TRAVERSE_STMT(FloatingLiteral, {})
 DEF_TRAVERSE_STMT(ImaginaryLiteral, {})
Index: include/clang/AST/OperationKinds.def
===================================================================
--- include/clang/AST/OperationKinds.def
+++ include/clang/AST/OperationKinds.def
@@ -197,6 +197,10 @@
 ///    float f = i;
 CAST_OPERATION(IntegralToFloating)
 
+/// CK_IntegralToFixedPoint - Integral to fixed point.
+///    (short _Accum) i;
+CAST_OPERATION(IntegralToFixedPoint)
+
 /// CK_FloatingToIntegral - Floating point to integral.  Rounds
 /// towards zero, discarding any fractional component.
 ///    (int) f
Index: include/clang/AST/Expr.h
===================================================================
--- include/clang/AST/Expr.h
+++ include/clang/AST/Expr.h
@@ -1351,6 +1351,47 @@
   }
 };
 
+class FixedPointLiteral : public Expr, public APIntStorage {
+  SourceLocation Loc;
+  unsigned Scale;
+
+  /// \brief Construct an empty integer literal.
+  explicit FixedPointLiteral(EmptyShell Empty)
+      : Expr(FixedPointLiteralClass, Empty) {}
+
+ public:
+  FixedPointLiteral(const ASTContext &C, const llvm::APInt &V, QualType type,
+                    SourceLocation l, unsigned Scale);
+
+  // Store the int as is without any bit shifting.
+  static FixedPointLiteral *CreateFromRawInt(const ASTContext &C,
+                                             const llvm::APInt &V,
+                                             QualType type, SourceLocation l,
+                                             unsigned Scale);
+
+  SourceLocation getLocStart() const LLVM_READONLY { return Loc; }
+  SourceLocation getLocEnd() const LLVM_READONLY { return Loc; }
+
+  /// \brief Retrieve the location of the literal.
+  SourceLocation getLocation() const { return Loc; }
+
+  void setLocation(SourceLocation Location) { Loc = Location; }
+
+  static bool classof(const Stmt *T) {
+    return T->getStmtClass() == FixedPointLiteralClass;
+  }
+
+  std::string getValueAsString(unsigned Radix) const;
+
+  // Iterators
+  child_range children() {
+    return child_range(child_iterator(), child_iterator());
+  }
+  const_child_range children() const {
+    return const_child_range(const_child_iterator(), const_child_iterator());
+  }
+};
+
 class CharacterLiteral : public Expr {
 public:
   enum CharacterKind {
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -1947,6 +1947,9 @@
     return getQualifiedType(type.getUnqualifiedType(), Qs);
   }
 
+  unsigned char getFixedPointScale(const QualType &Ty) const;
+  unsigned char getFixedPointIBits(const 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