leonardchan updated this revision to Diff 148445.
leonardchan added a comment.

- Reverted changes involving name mangling since we will only support c++ for 
now. Will concurrently raise an issue on 
https://github.com/itanium-cxx-abi/cxx-abi/ to get characters for name mangling.
- Added a flag that needs to be provided to enable usage of fixed point types. 
Not including this flag and using fixed point types throws an error. Currently, 
this patch allows for these types to be used in all versions of C, but this can 
be narrowed down to specific versions of C.
- An error is thrown when using fixed point types in C++.
- Fixed point types are ignored during USRGeneration since the type only gets 
mangled in C++.
- Fixed point types their own width and alignment accessors/variables in 
TargetInfo.
- Updated debug info to use `DW_ATE_signed_fixed` and `DW_ATE_unsigned_fixed`.
- Added tests mixing _Accum with other type specifiers


Repository:
  rC Clang

https://reviews.llvm.org/D46084

Files:
  include/clang-c/Index.h
  include/clang/AST/ASTContext.h
  include/clang/AST/BuiltinTypes.def
  include/clang/Basic/DiagnosticCommonKinds.td
  include/clang/Basic/LangOptions.def
  include/clang/Basic/Specifiers.h
  include/clang/Basic/TargetInfo.h
  include/clang/Basic/TokenKinds.def
  include/clang/Driver/Options.td
  include/clang/Sema/DeclSpec.h
  include/clang/Serialization/ASTBitCodes.h
  lib/AST/ASTContext.cpp
  lib/AST/ExprConstant.cpp
  lib/AST/ItaniumMangle.cpp
  lib/AST/MicrosoftMangle.cpp
  lib/AST/NSAPI.cpp
  lib/AST/Type.cpp
  lib/AST/TypeLoc.cpp
  lib/Analysis/PrintfFormatString.cpp
  lib/Basic/TargetInfo.cpp
  lib/CodeGen/CGDebugInfo.cpp
  lib/CodeGen/CodeGenTypes.cpp
  lib/CodeGen/ItaniumCXXABI.cpp
  lib/Driver/ToolChains/Clang.cpp
  lib/Frontend/CompilerInvocation.cpp
  lib/Index/USRGeneration.cpp
  lib/Parse/ParseDecl.cpp
  lib/Sema/DeclSpec.cpp
  lib/Sema/SemaTemplateVariadic.cpp
  lib/Sema/SemaType.cpp
  lib/Serialization/ASTCommon.cpp
  lib/Serialization/ASTReader.cpp
  test/Frontend/fixed_point.c
  test/Frontend/fixed_point_errors.c
  test/Frontend/fixed_point_errors.cpp
  test/Frontend/fixed_point_not_enabled.c
  tools/libclang/CXType.cpp

Index: tools/libclang/CXType.cpp
===================================================================
--- tools/libclang/CXType.cpp
+++ tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@
     BTCASE(Float);
     BTCASE(Double);
     BTCASE(LongDouble);
+    BTCASE(ShortAccum);
+    BTCASE(Accum);
+    BTCASE(LongAccum);
+    BTCASE(UShortAccum);
+    BTCASE(UAccum);
+    BTCASE(ULongAccum);
     BTCASE(Float16);
     BTCASE(Float128);
     BTCASE(NullPtr);
@@ -546,6 +552,12 @@
     TKIND(Float);
     TKIND(Double);
     TKIND(LongDouble);
+    TKIND(ShortAccum);
+    TKIND(Accum);
+    TKIND(LongAccum);
+    TKIND(UShortAccum);
+    TKIND(UAccum);
+    TKIND(ULongAccum);
     TKIND(Float16);
     TKIND(Float128);
     TKIND(NullPtr);
Index: test/Frontend/fixed_point_not_enabled.c
===================================================================
--- /dev/null
+++ test/Frontend/fixed_point_not_enabled.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c -verify %s
+
+// Primary fixed point types
+signed short _Accum s_short_accum;    // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+signed _Accum s_accum;                // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+signed long _Accum s_long_accum;      // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned short _Accum u_short_accum;  // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned _Accum u_accum;              // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+unsigned long _Accum u_long_accum;    // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+
+// Aliased fixed point types
+short _Accum short_accum;             // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+_Accum accum;                         // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
+                                      // expected-warning@-1{{type specifier missing, defaults to 'int'}}
+long _Accum long_accum;               // expected-error{{compile with '-enable-fixed-point' to enable fixed point types}}
Index: test/Frontend/fixed_point_errors.cpp
===================================================================
--- /dev/null
+++ test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c++ -enable-fixed-point %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+signed short _Accum s_short_accum;      // expected-error{{fixed point types are only allowed in C}}
+signed _Accum s_accum;                  // expected-error{{fixed point types are only allowed in C}}
+signed long _Accum s_long_accum;        // expected-error{{fixed point types are only allowed in C}}
+unsigned short _Accum u_short_accum;    // expected-error{{fixed point types are only allowed in C}}
+unsigned _Accum u_accum;                // expected-error{{fixed point types are only allowed in C}}
+unsigned long _Accum u_long_accum;      // expected-error{{fixed point types are only allowed in C}}
+
+short _Accum short_accum;               // expected-error{{fixed point types are only allowed in C}}
+_Accum accum;                           // expected-error{{fixed point types are only allowed in C}}
+                                        // expected-error@-1{{C++ requires a type specifier for all declarations}}
+long _Accum long_accum;                 // expected-error{{fixed point types are only allowed in C}}
Index: test/Frontend/fixed_point_errors.c
===================================================================
--- /dev/null
+++ test/Frontend/fixed_point_errors.c
@@ -0,0 +1,26 @@
+// RUN: %clang_cc1 -verify -enable-fixed-point %s
+
+/* We do not yet support long long. No recommended bit widths are given for this
+ * size. */
+
+long long _Accum longlong_accum;              // expected-error{{'long long _Accum' is invalid}}
+unsigned long long _Accum u_longlong_accum;   // expected-error{{'long long _Accum' is invalid}}
+
+/* Although _Complex types work with floating point numbers, the extension
+ * provides no info for complex fixed point types. */
+
+_Complex signed short _Accum cmplx_s_short_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex signed _Accum cmplx_s_accum;               // expected-error{{'_Complex _Accum' is invalid}}
+_Complex signed long _Accum cmplx_s_long_accum;     // expected-error{{'_Complex _Accum' is invalid}}
+_Complex unsigned short _Accum cmplx_u_short_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex unsigned _Accum cmplx_u_accum;             // expected-error{{'_Complex _Accum' is invalid}}
+_Complex unsigned long _Accum cmplx_u_long_accum;   // expected-error{{'_Complex _Accum' is invalid}}
+_Complex short _Accum cmplx_s_short_accum;          // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Accum cmplx_s_accum;                      // expected-error{{'_Complex _Accum' is invalid}}
+_Complex long _Accum cmplx_s_long_accum;            // expected-error{{'_Complex _Accum' is invalid}}
+
+/* Bad combinations */
+float _Accum f_accum;     // expected-error{{cannot combine with previous 'float' declaration specifier}}
+double _Accum d_accum;    // expected-error{{cannot combine with previous 'double' declaration specifier}}
+char _Accum c_accum;      // expected-error{{cannot combine with previous 'char' declaration specifier}}
+int _Accum i_accum;       // expected-error{{cannot combine with previous 'int' declaration specifier}}
Index: test/Frontend/fixed_point.c
===================================================================
--- /dev/null
+++ test/Frontend/fixed_point.c
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -x c -enable-fixed-point -ast-dump %s | FileCheck %s --strict-whitespace
+
+/*  Various contexts where type _Accum can appear. */
+
+// Primary fixed point types
+signed short _Accum s_short_accum;
+signed _Accum s_accum;
+signed long _Accum s_long_accum;
+unsigned short _Accum u_short_accum;
+unsigned _Accum u_accum;
+unsigned long _Accum u_long_accum;
+
+// Aliased fixed point types
+short _Accum short_accum;
+_Accum accum;
+long _Accum long_accum;
+
+// CHECK:      |-VarDecl {{.*}} s_short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} long_accum 'long _Accum'
+
+#define MIX_TYPE_SPEC(SPEC, SIGN, SIZE, ID) \
+  SPEC SIGN SIZE _Accum ID; \
+  SIGN SPEC SIZE _Accum ID ## 2; \
+  SIGN SIZE SPEC _Accum ID ## 3; \
+  SIGN SIZE _Accum SPEC ID ## 4;
+
+/* Mixing fixed point types with other type specifiers */
+
+#define MIX_VOLATILE(SIGN, SIZE, ID) MIX_TYPE_SPEC(volatile, SIGN, SIZE, ID)
+#define MIX_ATOMIC(SIGN, SIZE, ID) MIX_TYPE_SPEC(_Atomic, SIGN, SIZE, ID)
+#define MIX_CONST(SIGN, SIZE, ID) MIX_TYPE_SPEC(const, SIGN, SIZE, ID)
+
+MIX_VOLATILE(signed, short, vol_s_short_accum)
+MIX_ATOMIC(signed, short, atm_s_short_accum)
+MIX_CONST(signed, short, const_s_short_accum)
+
+// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum 'volatile short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum2 'volatile short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum3 'volatile short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum4 'volatile short _Accum'
+
+// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum '_Atomic(short _Accum)'
+// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum2 '_Atomic(short _Accum)'
+// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum3 '_Atomic(short _Accum)'
+// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum4 '_Atomic(short _Accum)'
+
+// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum 'const short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum2 'const short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum3 'const short _Accum'
+// CHECK-NEXT: `-VarDecl {{.*}} const_s_short_accum4 'const short _Accum'
Index: lib/Serialization/ASTReader.cpp
===================================================================
--- lib/Serialization/ASTReader.cpp
+++ lib/Serialization/ASTReader.cpp
@@ -6819,6 +6819,24 @@
     case PREDEF_TYPE_LONGDOUBLE_ID:
       T = Context.LongDoubleTy;
       break;
+    case PREDEF_TYPE_SHORT_ACCUM_ID:
+      T = Context.ShortAccumTy;
+      break;
+    case PREDEF_TYPE_ACCUM_ID:
+      T = Context.AccumTy;
+      break;
+    case PREDEF_TYPE_LONG_ACCUM_ID:
+      T = Context.LongAccumTy;
+      break;
+    case PREDEF_TYPE_USHORT_ACCUM_ID:
+      T = Context.UnsignedShortAccumTy;
+      break;
+    case PREDEF_TYPE_UACCUM_ID:
+      T = Context.UnsignedAccumTy;
+      break;
+    case PREDEF_TYPE_ULONG_ACCUM_ID:
+      T = Context.UnsignedLongAccumTy;
+      break;
     case PREDEF_TYPE_FLOAT16_ID:
       T = Context.Float16Ty;
       break;
Index: lib/Serialization/ASTCommon.cpp
===================================================================
--- lib/Serialization/ASTCommon.cpp
+++ lib/Serialization/ASTCommon.cpp
@@ -91,6 +91,24 @@
   case BuiltinType::LongDouble:
     ID = PREDEF_TYPE_LONGDOUBLE_ID;
     break;
+  case BuiltinType::ShortAccum:
+    ID = PREDEF_TYPE_SHORT_ACCUM_ID;
+    break;
+  case BuiltinType::Accum:
+    ID = PREDEF_TYPE_ACCUM_ID;
+    break;
+  case BuiltinType::LongAccum:
+    ID = PREDEF_TYPE_LONG_ACCUM_ID;
+    break;
+  case BuiltinType::UShortAccum:
+    ID = PREDEF_TYPE_USHORT_ACCUM_ID;
+    break;
+  case BuiltinType::UAccum:
+    ID = PREDEF_TYPE_UACCUM_ID;
+    break;
+  case BuiltinType::ULongAccum:
+    ID = PREDEF_TYPE_ULONG_ACCUM_ID;
+    break;
   case BuiltinType::Float16:
     ID = PREDEF_TYPE_FLOAT16_ID;
     break;
Index: lib/Sema/SemaType.cpp
===================================================================
--- lib/Sema/SemaType.cpp
+++ lib/Sema/SemaType.cpp
@@ -1391,6 +1391,41 @@
     }
     break;
   }
+  case DeclSpec::TST_accum: {
+    if (DS.getTypeSpecSign() != DeclSpec::TSS_unsigned) {
+      switch (DS.getTypeSpecWidth()) {
+        case DeclSpec::TSW_short:
+          Result = Context.ShortAccumTy;
+          break;
+        case DeclSpec::TSW_unspecified:
+          Result = Context.AccumTy;
+          break;
+        case DeclSpec::TSW_long:
+          Result = Context.LongAccumTy;
+          break;
+        case DeclSpec::TSW_longlong:
+          // Unreachable b/c this is caught in final analysis of the DeclSpec.
+          llvm_unreachable("Unable to specify long long as _Accum width");
+          break;
+      }
+    } else {
+      switch (DS.getTypeSpecWidth()) {
+        case DeclSpec::TSW_short:
+          Result = Context.UnsignedShortAccumTy;
+          break;
+        case DeclSpec::TSW_unspecified:
+          Result = Context.UnsignedAccumTy;
+          break;
+        case DeclSpec::TSW_long:
+          Result = Context.UnsignedLongAccumTy;
+          break;
+        case DeclSpec::TSW_longlong:
+          llvm_unreachable("Unable to specify long long as _Accum width");
+          break;
+      }
+    }
+    break;
+  }
   case DeclSpec::TST_int128:
     if (!S.Context.getTargetInfo().hasInt128Type())
       S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported)
Index: lib/Sema/SemaTemplateVariadic.cpp
===================================================================
--- lib/Sema/SemaTemplateVariadic.cpp
+++ lib/Sema/SemaTemplateVariadic.cpp
@@ -830,6 +830,7 @@
   case TST_half:
   case TST_float:
   case TST_double:
+  case TST_Accum:
   case TST_Float16:
   case TST_float128:
   case TST_bool:
Index: lib/Sema/DeclSpec.cpp
===================================================================
--- lib/Sema/DeclSpec.cpp
+++ lib/Sema/DeclSpec.cpp
@@ -339,6 +339,7 @@
     case TST_decimal32:
     case TST_decimal64:
     case TST_double:
+    case TST_Accum:
     case TST_Float16:
     case TST_float128:
     case TST_enum:
@@ -510,6 +511,7 @@
   case DeclSpec::TST_half:        return "half";
   case DeclSpec::TST_float:       return "float";
   case DeclSpec::TST_double:      return "double";
+  case DeclSpec::TST_accum:       return "_Accum";
   case DeclSpec::TST_float16:     return "_Float16";
   case DeclSpec::TST_float128:    return "__float128";
   case DeclSpec::TST_bool:        return Policy.Bool ? "bool" : "_Bool";
@@ -1100,12 +1102,13 @@
     }
   }
 
-  // signed/unsigned are only valid with int/char/wchar_t.
+  // signed/unsigned are only valid with int/char/wchar_t/_Accum.
   if (TypeSpecSign != TSS_unspecified) {
     if (TypeSpecType == TST_unspecified)
       TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int.
-    else if (TypeSpecType != TST_int  && TypeSpecType != TST_int128 &&
-             TypeSpecType != TST_char && TypeSpecType != TST_wchar) {
+    else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 &&
+             TypeSpecType != TST_char && TypeSpecType != TST_wchar &&
+             TypeSpecType != TST_accum) {
       S.Diag(TSSLoc, diag::err_invalid_sign_spec)
         << getSpecifierName((TST)TypeSpecType, Policy);
       // signed double -> double.
@@ -1120,7 +1123,8 @@
   case TSW_longlong: // long long int
     if (TypeSpecType == TST_unspecified)
       TypeSpecType = TST_int; // short -> short int, long long -> long long int.
-    else if (TypeSpecType != TST_int) {
+    else if (!(TypeSpecType == TST_int ||
+               (TypeSpecType == TST_accum && TypeSpecWidth != TSW_longlong))) {
       S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)
           << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy);
       TypeSpecType = TST_int;
@@ -1130,7 +1134,8 @@
   case TSW_long:  // long double, long int
     if (TypeSpecType == TST_unspecified)
       TypeSpecType = TST_int;  // long -> long int.
-    else if (TypeSpecType != TST_int && TypeSpecType != TST_double) {
+    else if (TypeSpecType != TST_int && TypeSpecType != TST_double &&
+             TypeSpecType != TST_accum) {
       S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec)
           << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy);
       TypeSpecType = TST_int;
Index: lib/Parse/ParseDecl.cpp
===================================================================
--- lib/Parse/ParseDecl.cpp
+++ lib/Parse/ParseDecl.cpp
@@ -3580,6 +3580,19 @@
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float16, Loc, PrevSpec,
                                      DiagID, Policy);
       break;
+    case tok::kw__Accum:
+      if (!getLangOpts().FixedPointEnabled) {
+        if (getLangOpts().CPlusPlus)
+          DiagID = diag::err_fixed_point_only_allowed_in_c;
+        else
+          DiagID = diag::err_fixed_point_not_enabled;
+        PrevSpec = "";  // Not used by diagnostic
+        isInvalid = true;
+      } else {
+        isInvalid = DS.SetTypeSpecType(DeclSpec::TST_accum, Loc, PrevSpec,
+                                       DiagID, Policy);
+      }
+      break;
     case tok::kw___float128:
       isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec,
                                      DiagID, Policy);
@@ -4606,6 +4619,7 @@
   case tok::kw_half:
   case tok::kw_float:
   case tok::kw_double:
+  case tok::kw__Accum:
   case tok::kw__Float16:
   case tok::kw___float128:
   case tok::kw_bool:
@@ -4683,6 +4697,7 @@
   case tok::kw_half:
   case tok::kw_float:
   case tok::kw_double:
+  case tok::kw__Accum:
   case tok::kw__Float16:
   case tok::kw___float128:
   case tok::kw_bool:
@@ -4841,6 +4856,7 @@
   case tok::kw_half:
   case tok::kw_float:
   case tok::kw_double:
+  case tok::kw__Accum:
   case tok::kw__Float16:
   case tok::kw___float128:
   case tok::kw_bool:
Index: lib/Index/USRGeneration.cpp
===================================================================
--- lib/Index/USRGeneration.cpp
+++ lib/Index/USRGeneration.cpp
@@ -709,6 +709,12 @@
         case BuiltinType::OCLQueue:
         case BuiltinType::OCLReserveID:
         case BuiltinType::OCLSampler:
+        case BuiltinType::ShortAccum:
+        case BuiltinType::Accum:
+        case BuiltinType::LongAccum:
+        case BuiltinType::UShortAccum:
+        case BuiltinType::UAccum:
+        case BuiltinType::ULongAccum:
           IgnoreResults = true;
           return;
         case BuiltinType::ObjCId:
Index: lib/Frontend/CompilerInvocation.cpp
===================================================================
--- lib/Frontend/CompilerInvocation.cpp
+++ lib/Frontend/CompilerInvocation.cpp
@@ -2329,6 +2329,10 @@
   Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions);
   Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions);
 
+  // -enable-fixed-point
+  Opts.FixedPointEnabled =
+      Args.hasArg(OPT_enable_fixed_point) && !Opts.CPlusPlus;
+
   // Handle exception personalities
   Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions,
                            options::OPT_fseh_exceptions,
Index: lib/Driver/ToolChains/Clang.cpp
===================================================================
--- lib/Driver/ToolChains/Clang.cpp
+++ lib/Driver/ToolChains/Clang.cpp
@@ -3756,6 +3756,10 @@
   Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
   Args.AddLastArg(CmdArgs, options::OPT_w);
 
+  // Fixed point flags
+  if (Args.hasArg(options::OPT_enable_fixed_point))
+    Args.AddLastArg(CmdArgs, options::OPT_enable_fixed_point);
+
   // Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
   // (-ansi is equivalent to -std=c89 or -std=c++98).
   //
Index: lib/CodeGen/ItaniumCXXABI.cpp
===================================================================
--- lib/CodeGen/ItaniumCXXABI.cpp
+++ lib/CodeGen/ItaniumCXXABI.cpp
@@ -2719,6 +2719,12 @@
     case BuiltinType::OCLClkEvent:
     case BuiltinType::OCLQueue:
     case BuiltinType::OCLReserveID:
+    case BuiltinType::ShortAccum:
+    case BuiltinType::Accum:
+    case BuiltinType::LongAccum:
+    case BuiltinType::UShortAccum:
+    case BuiltinType::UAccum:
+    case BuiltinType::ULongAccum:
       return false;
 
     case BuiltinType::Dependent:
Index: lib/CodeGen/CodeGenTypes.cpp
===================================================================
--- lib/CodeGen/CodeGenTypes.cpp
+++ lib/CodeGen/CodeGenTypes.cpp
@@ -440,6 +440,12 @@
     case BuiltinType::Char8:
     case BuiltinType::Char16:
     case BuiltinType::Char32:
+    case BuiltinType::ShortAccum:
+    case BuiltinType::Accum:
+    case BuiltinType::LongAccum:
+    case BuiltinType::UShortAccum:
+    case BuiltinType::UAccum:
+    case BuiltinType::ULongAccum:
       ResultType = llvm::IntegerType::get(getLLVMContext(),
                                  static_cast<unsigned>(Context.getTypeSize(T)));
       break;
Index: lib/CodeGen/CGDebugInfo.cpp
===================================================================
--- lib/CodeGen/CGDebugInfo.cpp
+++ lib/CodeGen/CGDebugInfo.cpp
@@ -702,6 +702,16 @@
     // floating point types of the same size.
     Encoding = llvm::dwarf::DW_ATE_float;
     break;
+  case BuiltinType::ShortAccum:
+  case BuiltinType::Accum:
+  case BuiltinType::LongAccum:
+    Encoding = llvm::dwarf::DW_ATE_signed_fixed;
+    break;
+  case BuiltinType::UShortAccum:
+  case BuiltinType::UAccum:
+  case BuiltinType::ULongAccum:
+    Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
+    break;
   }
 
   switch (BT->getKind()) {
Index: lib/Basic/TargetInfo.cpp
===================================================================
--- lib/Basic/TargetInfo.cpp
+++ lib/Basic/TargetInfo.cpp
@@ -40,6 +40,9 @@
   IntWidth = IntAlign = 32;
   LongWidth = LongAlign = 32;
   LongLongWidth = LongLongAlign = 64;
+  ShortAccumWidth = ShortAccumAlign = 16;
+  AccumWidth = AccumAlign = 32;
+  LongAccumWidth = LongAccumAlign = 64;
   SuitableAlign = 64;
   DefaultAlignForAttributeAligned = 128;
   MinGlobalAlign = 0;
Index: lib/Analysis/PrintfFormatString.cpp
===================================================================
--- lib/Analysis/PrintfFormatString.cpp
+++ lib/Analysis/PrintfFormatString.cpp
@@ -655,6 +655,12 @@
   case BuiltinType::Half:
   case BuiltinType::Float16:
   case BuiltinType::Float128:
+  case BuiltinType::ShortAccum:
+  case BuiltinType::Accum:
+  case BuiltinType::LongAccum:
+  case BuiltinType::UShortAccum:
+  case BuiltinType::UAccum:
+  case BuiltinType::ULongAccum:
     // Various types which are non-trivial to correct.
     return false;
 
Index: lib/AST/TypeLoc.cpp
===================================================================
--- lib/AST/TypeLoc.cpp
+++ lib/AST/TypeLoc.cpp
@@ -344,6 +344,12 @@
   case BuiltinType::LongDouble:
   case BuiltinType::Float16:
   case BuiltinType::Float128:
+  case BuiltinType::ShortAccum:
+  case BuiltinType::Accum:
+  case BuiltinType::LongAccum:
+  case BuiltinType::UShortAccum:
+  case BuiltinType::UAccum:
+  case BuiltinType::ULongAccum:
     llvm_unreachable("Builtin type needs extra local data!");
     // Fall through, if the impossible happens.
       
Index: lib/AST/Type.cpp
===================================================================
--- lib/AST/Type.cpp
+++ lib/AST/Type.cpp
@@ -2656,6 +2656,18 @@
     return "double";
   case LongDouble:
     return "long double";
+  case ShortAccum:
+    return "short _Accum";
+  case Accum:
+    return "_Accum";
+  case LongAccum:
+    return "long _Accum";
+  case UShortAccum:
+    return "unsigned short _Accum";
+  case UAccum:
+    return "unsigned _Accum";
+  case ULongAccum:
+    return "unsigned long _Accum";
   case Float16:
     return "_Float16";
   case Float128:
Index: lib/AST/NSAPI.cpp
===================================================================
--- lib/AST/NSAPI.cpp
+++ lib/AST/NSAPI.cpp
@@ -441,6 +441,12 @@
   case BuiltinType::Char32:
   case BuiltinType::Int128:
   case BuiltinType::LongDouble:
+  case BuiltinType::ShortAccum:
+  case BuiltinType::Accum:
+  case BuiltinType::LongAccum:
+  case BuiltinType::UShortAccum:
+  case BuiltinType::UAccum:
+  case BuiltinType::ULongAccum:
   case BuiltinType::UInt128:
   case BuiltinType::Float16:
   case BuiltinType::Float128:
Index: lib/AST/MicrosoftMangle.cpp
===================================================================
--- lib/AST/MicrosoftMangle.cpp
+++ lib/AST/MicrosoftMangle.cpp
@@ -1926,6 +1926,12 @@
     mangleArtificalTagType(TTK_Struct, "_Half", {"__clang"});
     break;
 
+  case BuiltinType::ShortAccum:
+  case BuiltinType::Accum:
+  case BuiltinType::LongAccum:
+  case BuiltinType::UShortAccum:
+  case BuiltinType::UAccum:
+  case BuiltinType::ULongAccum:
   case BuiltinType::Char8:
   case BuiltinType::Float128: {
     DiagnosticsEngine &Diags = Context.getDiags();
Index: lib/AST/ItaniumMangle.cpp
===================================================================
--- lib/AST/ItaniumMangle.cpp
+++ lib/AST/ItaniumMangle.cpp
@@ -2552,6 +2552,13 @@
   case BuiltinType::Float16:
     Out << "DF16_";
     break;
+  case BuiltinType::ShortAccum:
+  case BuiltinType::Accum:
+  case BuiltinType::LongAccum:
+  case BuiltinType::UShortAccum:
+  case BuiltinType::UAccum:
+  case BuiltinType::ULongAccum:
+    llvm_unreachable("Fixed point types are disabled for c++");
   case BuiltinType::Half:
     Out << "Dh";
     break;
Index: lib/AST/ExprConstant.cpp
===================================================================
--- lib/AST/ExprConstant.cpp
+++ lib/AST/ExprConstant.cpp
@@ -7355,6 +7355,13 @@
     case BuiltinType::UInt128:
       return GCCTypeClass::Integer;
 
+    case BuiltinType::UShortAccum:
+    case BuiltinType::UAccum:
+    case BuiltinType::ULongAccum:
+      // GCC does not cover FIXED_POINT_TYPE in it's switch stmt and defaults to
+      // no_type_class
+      return GCCTypeClass::None;
+
     case BuiltinType::NullPtr:
 
     case BuiltinType::ObjCId:
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -1134,6 +1134,14 @@
   // C11 extension ISO/IEC TS 18661-3
   InitBuiltinType(Float16Ty,           BuiltinType::Float16);
 
+  // ISO/IEC JTC1 SC22 WG14 N1169 Extension
+  InitBuiltinType(ShortAccumTy,         BuiltinType::ShortAccum);
+  InitBuiltinType(AccumTy,              BuiltinType::Accum);
+  InitBuiltinType(LongAccumTy,          BuiltinType::LongAccum);
+  InitBuiltinType(UnsignedShortAccumTy, BuiltinType::UShortAccum);
+  InitBuiltinType(UnsignedAccumTy,      BuiltinType::UAccum);
+  InitBuiltinType(UnsignedLongAccumTy,  BuiltinType::ULongAccum);
+
   // GNU extension, 128-bit integers.
   InitBuiltinType(Int128Ty,            BuiltinType::Int128);
   InitBuiltinType(UnsignedInt128Ty,    BuiltinType::UInt128);
@@ -1785,6 +1793,21 @@
       Width = 128;
       Align = 128; // int128_t is 128-bit aligned on all targets.
       break;
+    case BuiltinType::ShortAccum:
+    case BuiltinType::UShortAccum:
+      Width = Target->getShortAccumWidth();
+      Align = Target->getShortAccumAlign();
+      break;
+    case BuiltinType::Accum:
+    case BuiltinType::UAccum:
+      Width = Target->getAccumWidth();
+      Align = Target->getAccumAlign();
+      break;
+    case BuiltinType::LongAccum:
+    case BuiltinType::ULongAccum:
+      Width = Target->getLongAccumWidth();
+      Align = Target->getLongAccumAlign();
+      break;
     case BuiltinType::Float16:
     case BuiltinType::Half:
       Width = Target->getHalfWidth();
@@ -6222,6 +6245,12 @@
     case BuiltinType::Float16:
     case BuiltinType::Float128:
     case BuiltinType::Half:
+    case BuiltinType::ShortAccum:
+    case BuiltinType::Accum:
+    case BuiltinType::LongAccum:
+    case BuiltinType::UShortAccum:
+    case BuiltinType::UAccum:
+    case BuiltinType::ULongAccum:
       // FIXME: potentially need @encodes for these!
       return ' ';
 
Index: include/clang/Serialization/ASTBitCodes.h
===================================================================
--- include/clang/Serialization/ASTBitCodes.h
+++ include/clang/Serialization/ASTBitCodes.h
@@ -939,6 +939,26 @@
       /// The C++ 'char8_t' type.
       PREDEF_TYPE_CHAR8_ID = 45,
 
+      /// \brief The 'short _Accum' type
+      PREDEF_TYPE_SHORT_ACCUM_ID    = 46,
+
+      /// \brief The '_Accum' type
+      PREDEF_TYPE_ACCUM_ID      = 47,
+
+      /// \brief The 'long _Accum' type
+      PREDEF_TYPE_LONG_ACCUM_ID = 48,
+
+      /// \brief The 'unsigned short _Accum' type
+      PREDEF_TYPE_USHORT_ACCUM_ID   = 49,
+
+      /// \brief The 'unsigned _Accum' type
+      PREDEF_TYPE_UACCUM_ID     = 50,
+
+      /// \brief The 'unsigned long _Accum' type
+      PREDEF_TYPE_ULONG_ACCUM_ID    = 51,
+
+      /// \brief OpenCL image types with auto numeration
+
       /// OpenCL image types with auto numeration
 #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
       PREDEF_TYPE_##Id##_ID,
Index: include/clang/Sema/DeclSpec.h
===================================================================
--- include/clang/Sema/DeclSpec.h
+++ include/clang/Sema/DeclSpec.h
@@ -282,6 +282,7 @@
   static const TST TST_float = clang::TST_float;
   static const TST TST_double = clang::TST_double;
   static const TST TST_float16 = clang::TST_Float16;
+  static const TST TST_accum = clang::TST_Accum;
   static const TST TST_float128 = clang::TST_float128;
   static const TST TST_bool = clang::TST_bool;
   static const TST TST_decimal32 = clang::TST_decimal32;
Index: include/clang/Driver/Options.td
===================================================================
--- include/clang/Driver/Options.td
+++ include/clang/Driver/Options.td
@@ -118,6 +118,10 @@
 def f_Group : OptionGroup<"<f group>">, Group<CompileOnly_Group>,
               DocName<"Target-independent compilation options">;
 
+def fixed_point_Group : OptionGroup<"<fixed point group>">,
+			Group<CompileOnly_Group>,
+			DocName<"Fixed Point Flags">;
+
 def f_clang_Group : OptionGroup<"<f (clang-only) group>">,
                     Group<CompileOnly_Group>, DocFlatten;
 def pedantic_Group : OptionGroup<"<pedantic group>">, Group<f_Group>,
@@ -875,6 +879,9 @@
   Group<f_Group>, Flags<[CC1Option]>,
   HelpText<"Disable support for int128_t type">;
 
+def enable_fixed_point : Flag<["-", "--"], "enable-fixed-point">, Group<fixed_point_Group>,
+			 Flags<[CC1Option]>, HelpText<"Enable fixed point types">;
+
 // Begin sanitizer flags. These should all be core options exposed in all driver
 // modes.
 let Flags = [CC1Option, CoreOption] in {
Index: include/clang/Basic/TokenKinds.def
===================================================================
--- include/clang/Basic/TokenKinds.def
+++ include/clang/Basic/TokenKinds.def
@@ -389,6 +389,9 @@
 // C11 Extension
 KEYWORD(_Float16                    , KEYALL)
 
+// ISO/IEC JTC1 SC22 WG14 N1169 Extension
+KEYWORD(_Accum                      , KEYALL)
+
 // GNU Extensions (in impl-reserved namespace)
 KEYWORD(_Decimal32                  , KEYALL)
 KEYWORD(_Decimal64                  , KEYALL)
Index: include/clang/Basic/TargetInfo.h
===================================================================
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -74,6 +74,9 @@
   unsigned char LargeArrayMinWidth, LargeArrayAlign;
   unsigned char LongWidth, LongAlign;
   unsigned char LongLongWidth, LongLongAlign;
+  unsigned char ShortAccumWidth, ShortAccumAlign;
+  unsigned char AccumWidth, AccumAlign;
+  unsigned char LongAccumWidth, LongAccumAlign;
   unsigned char SuitableAlign;
   unsigned char DefaultAlignForAttributeAligned;
   unsigned char MinGlobalAlign;
@@ -358,6 +361,21 @@
   unsigned getLongLongWidth() const { return LongLongWidth; }
   unsigned getLongLongAlign() const { return LongLongAlign; }
 
+  /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and
+  /// 'unsigned short _Accum' for this target, in bits.
+  unsigned getShortAccumWidth() const { return ShortAccumWidth; }
+  unsigned getShortAccumAlign() const { return ShortAccumAlign; }
+
+  /// getAccumWidth/Align - Return the size of 'signed _Accum' and
+  /// 'unsigned _Accum' for this target, in bits.
+  unsigned getAccumWidth() const { return AccumWidth; }
+  unsigned getAccumAlign() const { return AccumAlign; }
+
+  /// getLongAccumWidth/Align - Return the size of 'signed long _Accum' and
+  /// 'unsigned long _Accum' for this target, in bits.
+  unsigned getLongAccumWidth() const { return LongAccumWidth; }
+  unsigned getLongAccumAlign() const { return LongAccumAlign; }
+
   /// Determine whether the __int128 type is supported on this target.
   virtual bool hasInt128Type() const {
     return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128;
Index: include/clang/Basic/Specifiers.h
===================================================================
--- include/clang/Basic/Specifiers.h
+++ include/clang/Basic/Specifiers.h
@@ -54,6 +54,7 @@
     TST_int128,
     TST_half,         // OpenCL half, ARM NEON __fp16
     TST_Float16,      // C11 extension ISO/IEC TS 18661-3
+    TST_Accum,        // ISO/IEC JTC1 SC22 WG14 N1169 Extension
     TST_float,
     TST_double,
     TST_float128,
Index: include/clang/Basic/LangOptions.def
===================================================================
--- include/clang/Basic/LangOptions.def
+++ include/clang/Basic/LangOptions.def
@@ -298,6 +298,8 @@
 
 COMPATIBLE_VALUE_LANGOPT(FunctionAlignment, 5, 0, "Default alignment for functions")
 
+LANGOPT(FixedPointEnabled, 1, 0, "Fixed point types are enabled")
+
 #undef LANGOPT
 #undef COMPATIBLE_LANGOPT
 #undef BENIGN_LANGOPT
Index: include/clang/Basic/DiagnosticCommonKinds.td
===================================================================
--- include/clang/Basic/DiagnosticCommonKinds.td
+++ include/clang/Basic/DiagnosticCommonKinds.td
@@ -168,6 +168,10 @@
                           InGroup<GccCompat>;
 def ext_clang_diagnose_if : Extension<"'diagnose_if' is a clang extension">,
                             InGroup<GccCompat>;
+def err_fixed_point_only_allowed_in_c : Error<
+  "fixed point types are only allowed in C">;
+def err_fixed_point_not_enabled : Error<"compile with "
+  "'-enable-fixed-point' to enable fixed point types">;
 
 // SEH
 def err_seh_expected_handler : Error<
Index: include/clang/AST/BuiltinTypes.def
===================================================================
--- include/clang/AST/BuiltinTypes.def
+++ include/clang/AST/BuiltinTypes.def
@@ -122,6 +122,26 @@
 // '__int128_t'
 SIGNED_TYPE(Int128, Int128Ty)
 
+//===- Fixed point types --------------------------------------------------===//
+
+// 'short _Accum'
+SIGNED_TYPE(ShortAccum, ShortAccumTy)
+
+// '_Accum'
+SIGNED_TYPE(Accum, AccumTy)
+
+// 'long _Accum'
+SIGNED_TYPE(LongAccum, LongAccumTy)
+
+// 'unsigned short _Accum'
+UNSIGNED_TYPE(UShortAccum, UnsignedShortAccumTy)
+
+// 'unsigned _Accum'
+UNSIGNED_TYPE(UAccum, UnsignedAccumTy)
+
+// 'unsigned long _Accum'
+UNSIGNED_TYPE(ULongAccum, UnsignedLongAccumTy)
+
 //===- Floating point types -----------------------------------------------===//
 
 // 'half' in OpenCL, '__fp16' in ARM NEON.
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -1007,6 +1007,9 @@
   CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
   CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
   CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
+  CanQualType ShortAccumTy, AccumTy,
+      LongAccumTy;  // ISO/IEC JTC1 SC22 WG14 N1169 Extension
+  CanQualType UnsignedShortAccumTy, UnsignedAccumTy, UnsignedLongAccumTy;
   CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
   CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
   CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
Index: include/clang-c/Index.h
===================================================================
--- include/clang-c/Index.h
+++ include/clang-c/Index.h
@@ -3182,8 +3182,14 @@
   CXType_Float128 = 30,
   CXType_Half = 31,
   CXType_Float16 = 32,
+  CXType_ShortAccum = 33,
+  CXType_Accum = 34,
+  CXType_LongAccum = 35,
+  CXType_UShortAccum = 36,
+  CXType_UAccum = 37,
+  CXType_ULongAccum = 38,
   CXType_FirstBuiltin = CXType_Void,
-  CXType_LastBuiltin  = CXType_Float16,
+  CXType_LastBuiltin = CXType_ULongAccum,
 
   CXType_Complex = 100,
   CXType_Pointer = 101,
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to