Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[clang] Support fixed point types in C++ #67750

Merged
merged 1 commit into from
Sep 29, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
6 changes: 3 additions & 3 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -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],
Expand Down
59 changes: 58 additions & 1 deletion clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -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;
Expand Down
3 changes: 3 additions & 0 deletions clang/lib/Parse/ParseExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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"
{
Expand Down
9 changes: 9 additions & 0 deletions clang/lib/Parse/ParseExprCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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, \
Expand Down
6 changes: 6 additions & 0 deletions clang/lib/Parse/ParseTentative.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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))
Expand Down Expand Up @@ -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;
Expand Down
45 changes: 45 additions & 0 deletions clang/test/CodeGenCXX/fixed-point-mangle.cpp
Original file line number Diff line number Diff line change
@@ -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
24 changes: 14 additions & 10 deletions clang/test/Frontend/fixed_point_errors.cpp
Original file line number Diff line number Diff line change
@@ -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@-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@-1{{a type specifier is required for all declarations}}
_Fract fract; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
// expected-error@-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@-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