[clang] a3a7d63 - [clang] Support fixed point types in C++ (#67750)

via cfe-commits cfe-commits at lists.llvm.org
Fri Sep 29 13:57:00 PDT 2023


Author: PiJoules
Date: 2023-09-29T13:56:55-07:00
New Revision: a3a7d6318027bb86e6614c022e77e0bd81aef6dc

URL: https://github.com/llvm/llvm-project/commit/a3a7d6318027bb86e6614c022e77e0bd81aef6dc
DIFF: https://github.com/llvm/llvm-project/commit/a3a7d6318027bb86e6614c022e77e0bd81aef6dc.diff

LOG: [clang] Support fixed point types in C++ (#67750)

This initially just adds support for mangling.

Added: 
    clang/test/CodeGenCXX/fixed-point-mangle.cpp

Modified: 
    clang/include/clang/Basic/TokenKinds.def
    clang/include/clang/Driver/Options.td
    clang/lib/AST/ItaniumMangle.cpp
    clang/lib/Parse/ParseExpr.cpp
    clang/lib/Parse/ParseExprCXX.cpp
    clang/lib/Parse/ParseTentative.cpp
    clang/test/Frontend/fixed_point_errors.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Basic/TokenKinds.def b/clang/include/clang/Basic/TokenKinds.def
index 72e8df8c793a7b6..94db56a9fd5d78c 100644
--- a/clang/include/clang/Basic/TokenKinds.def
+++ b/clang/include/clang/Basic/TokenKinds.def
@@ -423,9 +423,9 @@ C23_KEYWORD(typeof                  , KEYGNU)
 C23_KEYWORD(typeof_unqual           , 0)
 
 // ISO/IEC JTC1 SC22 WG14 N1169 Extension
-KEYWORD(_Accum                      , KEYNOCXX)
-KEYWORD(_Fract                      , KEYNOCXX)
-KEYWORD(_Sat                        , KEYNOCXX)
+KEYWORD(_Accum                      , KEYALL)
+KEYWORD(_Fract                      , KEYALL)
+KEYWORD(_Sat                        , KEYALL)
 
 // GNU Extensions (in impl-reserved namespace)
 KEYWORD(_Decimal32                  , KEYALL)

diff  --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 31ecf98b806b843..efd90942948af27 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -2054,7 +2054,7 @@ defm fixed_point : BoolFOption<"fixed-point",
   LangOpts<"FixedPoint">, DefaultFalse,
   PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
   NegFlag<SetFalse, [], [ClangOption], "Disable">,
-  BothFlags<[], [ClangOption], " fixed point types">>, ShouldParseIf<!strconcat("!", cplusplus.KeyPath)>;
+  BothFlags<[], [ClangOption], " fixed point types">>;
 defm cxx_static_destructors : BoolFOption<"c++-static-destructors",
   LangOpts<"RegisterStaticDestructors">, DefaultTrue,
   NegFlag<SetFalse, [], [ClangOption, CC1Option],

diff  --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index a11dbe22b196e41..830a35b98d60725 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -3048,7 +3048,17 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
   //                 ::= Di # char32_t
   //                 ::= Ds # char16_t
   //                 ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
+  //                 ::= [DS] DA  # N1169 fixed-point [_Sat] T _Accum
+  //                 ::= [DS] DR  # N1169 fixed-point [_Sat] T _Fract
   //                 ::= u <source-name>    # vendor extended type
+  //
+  //  <fixed-point-size>
+  //                 ::= s # short
+  //                 ::= t # unsigned short
+  //                 ::= i # plain
+  //                 ::= j # unsigned
+  //                 ::= l # long
+  //                 ::= m # unsigned long
   std::string type_name;
   // Normalize integer types as vendor extended types:
   // u<length>i<type size>
@@ -3193,30 +3203,77 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
     Out << "DF16_";
     break;
   case BuiltinType::ShortAccum:
+    Out << "DAs";
+    break;
   case BuiltinType::Accum:
+    Out << "DAi";
+    break;
   case BuiltinType::LongAccum:
+    Out << "DAl";
+    break;
   case BuiltinType::UShortAccum:
+    Out << "DAt";
+    break;
   case BuiltinType::UAccum:
+    Out << "DAj";
+    break;
   case BuiltinType::ULongAccum:
+    Out << "DAm";
+    break;
   case BuiltinType::ShortFract:
+    Out << "DRs";
+    break;
   case BuiltinType::Fract:
+    Out << "DRi";
+    break;
   case BuiltinType::LongFract:
+    Out << "DRl";
+    break;
   case BuiltinType::UShortFract:
+    Out << "DRt";
+    break;
   case BuiltinType::UFract:
+    Out << "DRj";
+    break;
   case BuiltinType::ULongFract:
+    Out << "DRm";
+    break;
   case BuiltinType::SatShortAccum:
+    Out << "DSDAs";
+    break;
   case BuiltinType::SatAccum:
+    Out << "DSDAi";
+    break;
   case BuiltinType::SatLongAccum:
+    Out << "DSDAl";
+    break;
   case BuiltinType::SatUShortAccum:
+    Out << "DSDAt";
+    break;
   case BuiltinType::SatUAccum:
+    Out << "DSDAj";
+    break;
   case BuiltinType::SatULongAccum:
+    Out << "DSDAm";
+    break;
   case BuiltinType::SatShortFract:
+    Out << "DSDRs";
+    break;
   case BuiltinType::SatFract:
+    Out << "DSDRi";
+    break;
   case BuiltinType::SatLongFract:
+    Out << "DSDRl";
+    break;
   case BuiltinType::SatUShortFract:
+    Out << "DSDRt";
+    break;
   case BuiltinType::SatUFract:
+    Out << "DSDRj";
+    break;
   case BuiltinType::SatULongFract:
-    llvm_unreachable("Fixed point types are disabled for c++");
+    Out << "DSDRm";
+    break;
   case BuiltinType::Half:
     Out << "Dh";
     break;

diff  --git a/clang/lib/Parse/ParseExpr.cpp b/clang/lib/Parse/ParseExpr.cpp
index 74664c34abdbd89..711990bff2851e1 100644
--- a/clang/lib/Parse/ParseExpr.cpp
+++ b/clang/lib/Parse/ParseExpr.cpp
@@ -1564,6 +1564,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
   case tok::kw_typename:
   case tok::kw_typeof:
   case tok::kw___vector:
+  case tok::kw__Accum:
+  case tok::kw__Fract:
+  case tok::kw__Sat:
 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
 #include "clang/Basic/OpenCLImageTypes.def"
   {

diff  --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 99b4931004546c1..79db094e098f8e6 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -2354,6 +2354,15 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
   case tok::kw_bool:
     DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy);
     break;
+  case tok::kw__Accum:
+    DS.SetTypeSpecType(DeclSpec::TST_accum, Loc, PrevSpec, DiagID, Policy);
+    break;
+  case tok::kw__Fract:
+    DS.SetTypeSpecType(DeclSpec::TST_fract, Loc, PrevSpec, DiagID, Policy);
+    break;
+  case tok::kw__Sat:
+    DS.SetTypeSpecSat(Loc, PrevSpec, DiagID);
+    break;
 #define GENERIC_IMAGE_TYPE(ImgType, Id)                                        \
   case tok::kw_##ImgType##_t:                                                  \
     DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID,     \

diff  --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index 45e73226d706b8a..03c19bf5d96e388 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -1764,6 +1764,9 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
   case tok::kw___ibm128:
   case tok::kw_void:
   case tok::annot_decltype:
+  case tok::kw__Accum:
+  case tok::kw__Fract:
+  case tok::kw__Sat:
 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
 #include "clang/Basic/OpenCLImageTypes.def"
     if (NextToken().is(tok::l_paren))
@@ -1883,6 +1886,9 @@ bool Parser::isCXXDeclarationSpecifierAType() {
   case tok::kw_void:
   case tok::kw___unknown_anytype:
   case tok::kw___auto_type:
+  case tok::kw__Accum:
+  case tok::kw__Fract:
+  case tok::kw__Sat:
 #define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
 #include "clang/Basic/OpenCLImageTypes.def"
     return true;

diff  --git a/clang/test/CodeGenCXX/fixed-point-mangle.cpp b/clang/test/CodeGenCXX/fixed-point-mangle.cpp
new file mode 100644
index 000000000000000..103990a61316a9c
--- /dev/null
+++ b/clang/test/CodeGenCXX/fixed-point-mangle.cpp
@@ -0,0 +1,45 @@
+// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - -triple=x86_64-unknown-linux-gnu | FileCheck %s
+
+// Primary fixed point types
+void func(signed short _Accum){}    // CHECK: @_Z4funcDAs
+void func(signed _Accum){}          // CHECK: @_Z4funcDAi
+void func(signed long _Accum){}     // CHECK: @_Z4funcDAl
+void func(unsigned short _Accum){}  // CHECK: @_Z4funcDAt
+void func(unsigned _Accum){}        // CHECK: @_Z4funcDAj
+void func(unsigned long _Accum){}   // CHECK: @_Z4funcDAm
+void func(signed short _Fract){}    // CHECK: @_Z4funcDRs
+void func(signed _Fract){}          // CHECK: @_Z4funcDRi
+void func(signed long _Fract){}     // CHECK: @_Z4funcDRl
+void func(unsigned short _Fract){}  // CHECK: @_Z4funcDRt
+void func(unsigned _Fract){}        // CHECK: @_Z4funcDRj
+void func(unsigned long _Fract){}   // CHECK: @_Z4funcDRm
+
+// Aliased
+void func2(short _Accum){}          // CHECK: @_Z5func2DAs
+void func2(_Accum){}                // CHECK: @_Z5func2DAi
+void func2(long _Accum){}           // CHECK: @_Z5func2DAl
+void func2(short _Fract){}          // CHECK: @_Z5func2DRs
+void func2(_Fract){}                // CHECK: @_Z5func2DRi
+void func2(long _Fract){}           // CHECK: @_Z5func2DRl
+
+// Primary saturated
+void func(_Sat signed short _Accum){}    // CHECK: @_Z4funcDSDAs
+void func(_Sat signed _Accum){}          // CHECK: @_Z4funcDSDAi
+void func(_Sat signed long _Accum){}     // CHECK: @_Z4funcDSDAl
+void func(_Sat unsigned short _Accum){}  // CHECK: @_Z4funcDSDAt
+void func(_Sat unsigned _Accum){}        // CHECK: @_Z4funcDSDAj
+void func(_Sat unsigned long _Accum){}   // CHECK: @_Z4funcDSDAm
+void func(_Sat signed short _Fract){}    // CHECK: @_Z4funcDSDRs
+void func(_Sat signed _Fract){}          // CHECK: @_Z4funcDSDRi
+void func(_Sat signed long _Fract){}     // CHECK: @_Z4funcDSDRl
+void func(_Sat unsigned short _Fract){}  // CHECK: @_Z4funcDSDRt
+void func(_Sat unsigned _Fract){}        // CHECK: @_Z4funcDSDRj
+void func(_Sat unsigned long _Fract){}   // CHECK: @_Z4funcDSDRm
+
+// Aliased saturated
+void func2(_Sat short _Accum){}          // CHECK: @_Z5func2DSDAs
+void func2(_Sat _Accum){}                // CHECK: @_Z5func2DSDAi
+void func2(_Sat long _Accum){}           // CHECK: @_Z5func2DSDAl
+void func2(_Sat short _Fract){}          // CHECK: @_Z5func2DSDRs
+void func2(_Sat _Fract){}                // CHECK: @_Z5func2DSDRi
+void func2(_Sat long _Fract){}           // CHECK: @_Z5func2DSDRl

diff  --git a/clang/test/Frontend/fixed_point_errors.cpp b/clang/test/Frontend/fixed_point_errors.cpp
index cdd90ceb7548f94..2264622a2e8c870 100644
--- a/clang/test/Frontend/fixed_point_errors.cpp
+++ b/clang/test/Frontend/fixed_point_errors.cpp
@@ -1,14 +1,18 @@
-// RUN: %clang_cc1 -x c++ %s -verify
-// RUN: %clang_cc1 -x c++ -ffixed-point %s -verify
+// RUN: %clang_cc1 -x c++ %s -verify -DWITHOUT_FIXED_POINT
+// RUN: %clang_cc1 -x c++ %s -verify -ffixed-point
 
-// Name namgling is not provided for fixed point types in c++
-
-_Accum accum;                           // expected-error{{unknown type name '_Accum'}}
-_Fract fract;                           // expected-error{{unknown type name '_Fract'}}
-_Sat _Accum sat_accum;                  // expected-error{{unknown type name '_Sat'}}
-                                        // expected-error at -1{{expected ';' after top level declarator}}
+#ifdef WITHOUT_FIXED_POINT
+_Accum accum;                           // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+                                        // expected-error at -1{{a type specifier is required for all declarations}}
+_Fract fract;                           // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+                                        // expected-error at -1{{a type specifier is required for all declarations}}
+_Sat _Accum sat_accum;                  // expected-error 2{{compile with '-ffixed-point' to enable fixed point types}}
+                                        // expected-error at -1{{a type specifier is required for all declarations}}
+#endif
 
 int accum_int = 10k;     // expected-error{{invalid suffix 'k' on integer constant}}
 int fract_int = 10r;     // expected-error{{invalid suffix 'r' on integer constant}}
-float accum_flt = 10.0k; // expected-error{{invalid suffix 'k' on floating constant}}
-float fract_flt = 10.0r; // expected-error{{invalid suffix 'r' on floating constant}}
+#ifdef WITHOUT_FIXED_POINT
+float accum_flt = 0.0k;  // expected-error{{invalid suffix 'k' on floating constant}}
+float fract_flt = 0.0r;  // expected-error{{invalid suffix 'r' on floating constant}}
+#endif


        


More information about the cfe-commits mailing list