leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch contains the addition of the precision macros for integral and 
fractional bits according to clause 7.18a.3 of 
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf. The macros are 
integer constants and added as predefined macros.

  // Fractional bits of _Accum types
  __SACCUM_FBIT__
  __ACCUM_FBIT__
  __LACCUM_FBIT__
  __USACCUM_FBIT__
  __UACCUM_FBIT__
  __ULACCUM_FBIT__
  
  // Fractional bits of _Fract types
  __SFRACT_FBIT__
  __FRACT_FBIT__
  __LFRACT_FBIT__
  __USFRACT_FBIT__
  __UFRACT_FBIT__
  __ULFRACT_FBIT__
  
  // Integral bits of _Accum types
  __SACCUM_IBIT__
  __ACCUM_IBIT__
  __LACCUM_IBIT__
  __USACCUM_IBIT__
  __UACCUM_IBIT__
  __ULACCUM_IBIT__

This is a child of https://reviews.llvm.org/D46927


Repository:
  rC Clang

https://reviews.llvm.org/D46960

Files:
  include/clang/Lex/Preprocessor.h
  lib/Lex/PPMacroExpansion.cpp
  test/Frontend/fixed_point_builtin_macros.c

Index: test/Frontend/fixed_point_builtin_macros.c
===================================================================
--- /dev/null
+++ test/Frontend/fixed_point_builtin_macros.c
@@ -0,0 +1,31 @@
+// RUN: %clang_cc1 -S -emit-llvm -o - %s | lli
+
+#define assert(b) if (!(b)) { return 1; }
+
+int main() {
+  // Test using the recommended values for a typical desktop processor (Annex
+  // A.3). These are also the default values when building clang.
+  // Fractional bits of _Accum types
+  assert(__SACCUM_FBIT__  == 7);
+  assert(__ACCUM_FBIT__   == 15);
+  assert(__LACCUM_FBIT__  == 31);
+  assert(__USACCUM_FBIT__ == 8);
+  assert(__UACCUM_FBIT__  == 16);
+  assert(__ULACCUM_FBIT__ == 32);
+
+  // Fractional bits of _Fract types
+  assert(__SFRACT_FBIT__  == 7);
+  assert(__FRACT_FBIT__   == 15);
+  assert(__LFRACT_FBIT__  == 31);
+  assert(__USFRACT_FBIT__ == 8);
+  assert(__UFRACT_FBIT__  == 16);
+  assert(__ULFRACT_FBIT__ == 32);
+
+  // Integral bits of _Accum types
+  assert(__SACCUM_IBIT__  == 8);
+  assert(__ACCUM_IBIT__   == 16);
+  assert(__LACCUM_IBIT__  == 32);
+  assert(__USACCUM_IBIT__ == 8);
+  assert(__UACCUM_IBIT__  == 16);
+  assert(__ULACCUM_IBIT__ == 32);
+}
Index: lib/Lex/PPMacroExpansion.cpp
===================================================================
--- lib/Lex/PPMacroExpansion.cpp
+++ lib/Lex/PPMacroExpansion.cpp
@@ -14,6 +14,7 @@
 
 #include "clang/Basic/Attributes.h"
 #include "clang/Basic/FileManager.h"
+#include "clang/Basic/FixedPoint.h"
 #include "clang/Basic/IdentifierTable.h"
 #include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
@@ -355,6 +356,31 @@
   Ident__INCLUDE_LEVEL__ = RegisterBuiltinMacro(*this, "__INCLUDE_LEVEL__");
   Ident__TIMESTAMP__     = RegisterBuiltinMacro(*this, "__TIMESTAMP__");
 
+  // Fixed point macros (ISO/IEC JTC1 SC22 WG14 N1169)
+  // Fractional bits of _Accum types
+  Ident__SACCUM_FBIT__   = RegisterBuiltinMacro(*this, "__SACCUM_FBIT__");
+  Ident__ACCUM_FBIT__    = RegisterBuiltinMacro(*this, "__ACCUM_FBIT__");
+  Ident__LACCUM_FBIT__   = RegisterBuiltinMacro(*this, "__LACCUM_FBIT__");
+  Ident__USACCUM_FBIT__  = RegisterBuiltinMacro(*this, "__USACCUM_FBIT__");
+  Ident__UACCUM_FBIT__   = RegisterBuiltinMacro(*this, "__UACCUM_FBIT__");
+  Ident__ULACCUM_FBIT__  = RegisterBuiltinMacro(*this, "__ULACCUM_FBIT__");
+
+  // Fractional bits of _Fract types
+  Ident__SFRACT_FBIT__   = RegisterBuiltinMacro(*this, "__SFRACT_FBIT__");
+  Ident__FRACT_FBIT__    = RegisterBuiltinMacro(*this, "__FRACT_FBIT__");
+  Ident__LFRACT_FBIT__   = RegisterBuiltinMacro(*this, "__LFRACT_FBIT__");
+  Ident__USFRACT_FBIT__  = RegisterBuiltinMacro(*this, "__USFRACT_FBIT__");
+  Ident__UFRACT_FBIT__   = RegisterBuiltinMacro(*this, "__UFRACT_FBIT__");
+  Ident__ULFRACT_FBIT__  = RegisterBuiltinMacro(*this, "__ULFRACT_FBIT__");
+
+  // Integral bits of _Accum types
+  Ident__SACCUM_IBIT__   = RegisterBuiltinMacro(*this, "__SACCUM_IBIT__");
+  Ident__ACCUM_IBIT__    = RegisterBuiltinMacro(*this, "__ACCUM_IBIT__");
+  Ident__LACCUM_IBIT__   = RegisterBuiltinMacro(*this, "__LACCUM_IBIT__");
+  Ident__USACCUM_IBIT__  = RegisterBuiltinMacro(*this, "__USACCUM_IBIT__");
+  Ident__UACCUM_IBIT__   = RegisterBuiltinMacro(*this, "__UACCUM_IBIT__");
+  Ident__ULACCUM_IBIT__  = RegisterBuiltinMacro(*this, "__ULACCUM_IBIT__");
+
   // Microsoft Extensions.
   if (LangOpts.MicrosoftExt) {
     Ident__identifier = RegisterBuiltinMacro(*this, "__identifier");
@@ -1696,6 +1722,68 @@
     // __LINE__ expands to a simple numeric value.
     OS << (PLoc.isValid()? PLoc.getLine() : 1);
     Tok.setKind(tok::numeric_constant);
+
+  // Fixed point macros
+  // Fractional bits of _Accum types
+  } else if (II == Ident__SACCUM_FBIT__) {
+    OS << BUILTIN_SACCUM_FBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__ACCUM_FBIT__) {
+    OS << BUILTIN_ACCUM_FBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__LACCUM_FBIT__) {
+    OS << BUILTIN_LACCUM_FBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__USACCUM_FBIT__) {
+    OS << BUILTIN_USACCUM_FBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__UACCUM_FBIT__) {
+    OS << BUILTIN_UACCUM_FBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__ULACCUM_FBIT__) {
+    OS << BUILTIN_ULACCUM_FBIT;
+    Tok.setKind(tok::numeric_constant);
+
+  // Fractional bits of _Fract types
+  } else if (II == Ident__SFRACT_FBIT__) {
+    OS << BUILTIN_SFRACT_FBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__FRACT_FBIT__) {
+    OS << BUILTIN_FRACT_FBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__LFRACT_FBIT__) {
+    OS << BUILTIN_LFRACT_FBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__USFRACT_FBIT__) {
+    OS << BUILTIN_USFRACT_FBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__UFRACT_FBIT__) {
+    OS << BUILTIN_UFRACT_FBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__ULFRACT_FBIT__) {
+    OS << BUILTIN_ULFRACT_FBIT;
+    Tok.setKind(tok::numeric_constant);
+
+  // Integral bits of _Accum types
+  } else if (II == Ident__SACCUM_IBIT__) {
+    OS << BUILTIN_SACCUM_IBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__ACCUM_IBIT__) {
+    OS << BUILTIN_ACCUM_IBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__LACCUM_IBIT__) {
+    OS << BUILTIN_LACCUM_IBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__USACCUM_IBIT__) {
+    OS << BUILTIN_USACCUM_IBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__UACCUM_IBIT__) {
+    OS << BUILTIN_UACCUM_IBIT;
+    Tok.setKind(tok::numeric_constant);
+  } else if (II == Ident__ULACCUM_IBIT__) {
+    OS << BUILTIN_ULACCUM_IBIT;
+    Tok.setKind(tok::numeric_constant);
+
   } else if (II == Ident__FILE__ || II == Ident__BASE_FILE__) {
     // C99 6.10.8: "__FILE__: The presumed name of the current source file (a
     // character string literal)". This can be affected by #line.
Index: include/clang/Lex/Preprocessor.h
===================================================================
--- include/clang/Lex/Preprocessor.h
+++ include/clang/Lex/Preprocessor.h
@@ -180,6 +180,31 @@
   IdentifierInfo *Ident__is_target_os;             // __is_target_os
   IdentifierInfo *Ident__is_target_environment;    // __is_target_environment
 
+  // Fixed point macros (ISO/IEC JTC1 SC22 WG14 N1169)
+  // Fractional bits of _Accum types
+  IdentifierInfo *Ident__SACCUM_FBIT__;            // __SACCUM_FBIT__
+  IdentifierInfo *Ident__ACCUM_FBIT__;             // __ACCUM_FBIT__
+  IdentifierInfo *Ident__LACCUM_FBIT__;            // __LACCUM_FBIT__
+  IdentifierInfo *Ident__USACCUM_FBIT__;           // __USACCUM_FBIT__
+  IdentifierInfo *Ident__UACCUM_FBIT__;            // __UACCUM_FBIT__
+  IdentifierInfo *Ident__ULACCUM_FBIT__;           // __ULACCUM_FBIT__
+
+  // Fractional bits of _Fract types
+  IdentifierInfo *Ident__SFRACT_FBIT__;            // __SFRACT_FBIT__
+  IdentifierInfo *Ident__FRACT_FBIT__;             // __FRACT_FBIT__
+  IdentifierInfo *Ident__LFRACT_FBIT__;            // __LFRACT_FBIT__
+  IdentifierInfo *Ident__USFRACT_FBIT__;           // __USFRACT_FBIT__
+  IdentifierInfo *Ident__UFRACT_FBIT__;            // __UFRACT_FBIT__
+  IdentifierInfo *Ident__ULFRACT_FBIT__;           // __ULFRACT_FBIT__
+
+  // Integral bits of _Accum types
+  IdentifierInfo *Ident__SACCUM_IBIT__;            // __SACCUM_IBIT__
+  IdentifierInfo *Ident__ACCUM_IBIT__;             // __ACCUM_IBIT__
+  IdentifierInfo *Ident__LACCUM_IBIT__;            // __LACCUM_IBIT__
+  IdentifierInfo *Ident__USACCUM_IBIT__;           // __USACCUM_IBIT__
+  IdentifierInfo *Ident__UACCUM_IBIT__;            // __UACCUM_IBIT__
+  IdentifierInfo *Ident__ULACCUM_IBIT__;           // __ULACCUM_IBIT__
+
   SourceLocation DATELoc, TIMELoc;
 
   // Next __COUNTER__ value, starts at 0.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to