[PATCH] D46979: [Fixed Point Arithmetic] Test for Conversion Between Valid Builtin Types

2018-05-21 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan updated this revision to Diff 147902.
leonardchan added a comment.

formatting


Repository:
  rC Clang

https://reviews.llvm.org/D46979

Files:
  include/clang/AST/OperationKinds.def
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point_all_conversions.c

Index: test/Frontend/fixed_point_all_conversions.c
===
--- /dev/null
+++ test/Frontend/fixed_point_all_conversions.c
@@ -0,0 +1,74 @@
+// RUN: %clang_cc1 -Werror %s
+
+// Test for conversions between fixed point types and all other valid types.
+
+// Conversion from one type to another type
+#define CONVERT(FROM_TYPE, FROM_ID, TO_TYPE, TO_ID) \
+  TO_TYPE FROM_ID##_to_##TO_ID(FROM_TYPE x) { return x; }
+
+// Conversion between 2 types
+#define CONVERT_COMBINATION(TYPE1, ID1, TYPE2, ID2) \
+  CONVERT(TYPE1, ID1, TYPE2, ID2)   \
+  CONVERT(TYPE2, ID2, TYPE1, ID1)
+
+// Conversion between one type and floating point types
+#define CONVERT_BETWEEN_FLOATS(TYPE, ID)  \
+  CONVERT_COMBINATION(TYPE, ID, float, Float) \
+  CONVERT_COMBINATION(TYPE, ID, double, Double)
+
+// Conversion between one type and an integral type with differant signage
+#define CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, INT_TYPE, INT_ID) \
+  CONVERT_COMBINATION(TYPE, ID, INT_TYPE, INT_ID)   \
+  CONVERT_COMBINATION(TYPE, ID, signed INT_TYPE, Signed##INT_ID)\
+  CONVERT_COMBINATION(TYPE, ID, unsigned INT_TYPE, Unsigned##INT_ID)
+
+// Conversion between one type and all integral types
+#define CONVERT_BETWEEN_INTEGRALS(TYPE, ID)   \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, char, Char)   \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, short, Short) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, int, Int) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long, Long)   \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long long, LongLong)
+
+// Conversion between one type and a fixed point type with different saturation
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_COMBINATION(TYPE, ID, FIXED_TYPE, FIXED_ID)\
+  CONVERT_COMBINATION(TYPE, ID, _Sat FIXED_TYPE, Sat##FIXED_ID)
+
+// Conversion between one type and a fixed point type with different signage
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID)\
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, signed FIXED_TYPE,   \
+   Signed##FIXED_ID)  \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, unsigned FIXED_TYPE, \
+   Unsigned##FIXED_ID)
+
+// Convert between one type and all fixed point types.
+// Add "Type" to the end of the ID to avoid multiple definitions of a function
+// if the Type is a fixed point type.
+#define CONVERT_BETWEEN_FIXED_POINT(TYPE, ID)\
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Fract, FractType) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Accum, AccumType)
+
+// Convert between one type and all other types
+#define CONVERT_BETWEEN_ALL_TYPES(TYPE, ID) \
+  CONVERT_BETWEEN_FLOATS(TYPE, ID)  \
+  CONVERT_BETWEEN_INTEGRALS(TYPE, ID)   \
+  CONVERT_BETWEEN_FIXED_POINT(TYPE, ID)
+
+#define CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID) \
+  CONVERT_BETWEEN_ALL_TYPES(TYPE, ID)   \
+  CONVERT_BETWEEN_ALL_TYPES(_Sat TYPE, Sat##ID)
+
+#define CONVERT_FIXED_POINT_TYPE(TYPE, ID)   \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID)\
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(signed TYPE, Signed##ID) \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(unsigned TYPE, Unsigned##ID)
+
+CONVERT_FIXED_POINT_TYPE(short _Fract, ShortFract);
+CONVERT_FIXED_POINT_TYPE(_Fract, Fract);
+CONVERT_FIXED_POINT_TYPE(long _Fract, LongFract);
+
+CONVERT_FIXED_POINT_TYPE(short _Accum, ShortAccum);
+CONVERT_FIXED_POINT_TYPE(_Accum, Accum);
+CONVERT_FIXED_POINT_TYPE(long _Accum, LongAccum);
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -323,6 +323,8 @@
 switch (CastE->getCastKind()) {
   case CK_FixedPointCast:
 llvm_unreachable("CK_FixedPointCast");  // TODO
+  case CK_FloatingToFixedPoint:
+llvm_unreachable("CK_FloatingToFixedPoint");
   case CK_IntegralToFixedPoint:
 llvm_unreachable(
 "ExprEngine::VisitCast CK_IntegralToFixedPoint");  // TODO
Index: 

[PATCH] D46979: [Fixed Point Arithmetic] Test for Conversion Between Valid Builtin Types

2018-05-16 Thread Leonard Chan via Phabricator via cfe-commits
leonardchan created this revision.
leonardchan added reviewers: phosek, mcgrathr, jakehehrlich.
leonardchan added a project: clang.

This patch contains changes and a test for checking that fixed point types can 
be converted between all other valid types. Fixed point types can be converted 
between floating point types, integral types, and other fixed point types.

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


Repository:
  rC Clang

https://reviews.llvm.org/D46979

Files:
  include/clang/AST/OperationKinds.def
  lib/AST/Expr.cpp
  lib/AST/ExprConstant.cpp
  lib/CodeGen/CGExpr.cpp
  lib/CodeGen/CGExprAgg.cpp
  lib/CodeGen/CGExprComplex.cpp
  lib/CodeGen/CGExprConstant.cpp
  lib/CodeGen/CGExprScalar.cpp
  lib/Edit/RewriteObjCFoundationAPI.cpp
  lib/Sema/SemaExpr.cpp
  lib/StaticAnalyzer/Core/ExprEngineC.cpp
  test/Frontend/fixed_point_all_conversions.c

Index: test/Frontend/fixed_point_all_conversions.c
===
--- /dev/null
+++ test/Frontend/fixed_point_all_conversions.c
@@ -0,0 +1,72 @@
+// RUN: %clang_cc1 -Werror %s
+
+// Test for conversions between fixed point types and all other valid types.
+
+// Conversion from one type to another type
+#define CONVERT(FROM_TYPE, FROM_ID, TO_TYPE, TO_ID) \
+  TO_TYPE FROM_ID ## _to_ ## TO_ID (FROM_TYPE x) { return x; }
+
+// Conversion between 2 types
+#define CONVERT_COMBINATION(TYPE1, ID1, TYPE2, ID2) \
+  CONVERT(TYPE1, ID1, TYPE2, ID2) \
+  CONVERT(TYPE2, ID2, TYPE1, ID1)
+
+// Conversion between one type and floating point types
+#define CONVERT_BETWEEN_FLOATS(TYPE, ID) \
+  CONVERT_COMBINATION(TYPE, ID, float, Float) \
+  CONVERT_COMBINATION(TYPE, ID, double, Double)
+
+// Conversion between one type and an integral type with differant signage
+#define CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, INT_TYPE, INT_ID) \
+  CONVERT_COMBINATION(TYPE, ID, INT_TYPE, INT_ID) \
+  CONVERT_COMBINATION(TYPE, ID, signed INT_TYPE, Signed ## INT_ID) \
+  CONVERT_COMBINATION(TYPE, ID, unsigned INT_TYPE, Unsigned ## INT_ID)
+
+// Conversion between one type and all integral types
+#define CONVERT_BETWEEN_INTEGRALS(TYPE, ID) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, char, Char) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, short, Short) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, int, Int) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long, Long) \
+  CONVERT_BETWEEN_INTEGRALS_WITH_SIGN(TYPE, ID, long long, LongLong)
+
+// Conversion between one type and a fixed point type with different saturation
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_COMBINATION(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_COMBINATION(TYPE, ID, _Sat FIXED_TYPE, Sat ## FIXED_ID)
+
+// Conversion between one type and a fixed point type with different signage
+#define CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, FIXED_TYPE, FIXED_ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, signed FIXED_TYPE, Signed ## FIXED_ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SAT(TYPE, ID, unsigned FIXED_TYPE, Unsigned ## FIXED_ID)
+
+// Convert between one type and all fixed point types.
+// Add "Type" to the end of the ID to avoid multiple definitions of a function
+// if the Type is a fixed point type.
+#define CONVERT_BETWEEN_FIXED_POINT(TYPE, ID) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Fract, FractType) \
+  CONVERT_BETWEEN_FIXED_POINT_WITH_SIGN(TYPE, ID, _Accum, AccumType)
+
+// Convert between one type and all other types
+#define CONVERT_BETWEEN_ALL_TYPES(TYPE, ID) \
+  CONVERT_BETWEEN_FLOATS(TYPE, ID) \
+  CONVERT_BETWEEN_INTEGRALS(TYPE, ID) \
+  CONVERT_BETWEEN_FIXED_POINT(TYPE, ID)
+
+#define CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID) \
+  CONVERT_BETWEEN_ALL_TYPES(TYPE, ID) \
+  CONVERT_BETWEEN_ALL_TYPES(_Sat TYPE, Sat ## ID)
+
+#define CONVERT_FIXED_POINT_TYPE(TYPE, ID) \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(TYPE, ID) \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(signed TYPE, Signed ## ID) \
+  CONVERT_FIXED_POINT_TYPE_WITH_SAT(unsigned TYPE, Unsigned ## ID)
+
+CONVERT_FIXED_POINT_TYPE(short _Fract, ShortFract);
+CONVERT_FIXED_POINT_TYPE(_Fract, Fract);
+CONVERT_FIXED_POINT_TYPE(long _Fract, LongFract);
+
+CONVERT_FIXED_POINT_TYPE(short _Accum, ShortAccum);
+CONVERT_FIXED_POINT_TYPE(_Accum, Accum);
+CONVERT_FIXED_POINT_TYPE(long _Accum, LongAccum);
Index: lib/StaticAnalyzer/Core/ExprEngineC.cpp
===
--- lib/StaticAnalyzer/Core/ExprEngineC.cpp
+++ lib/StaticAnalyzer/Core/ExprEngineC.cpp
@@ -321,6 +321,7 @@
 const LocationContext *LCtx = Pred->getLocationContext();
 
 switch (CastE->getCastKind()) {
+  case CK_FloatingToFixedPoint: llvm_unreachable("CK_FloatingToFixedPoint");
   case CK_FixedPointToFloating: llvm_unreachable("Unimplemented logic for CK_FixedPointToFloating");
   case