Skip to content

Commit a3a7d63

Browse files
authored
[clang] Support fixed point types in C++ (#67750)
This initially just adds support for mangling.
1 parent 1bff5f6 commit a3a7d63

File tree

8 files changed

+139
-15
lines changed

8 files changed

+139
-15
lines changed

clang/include/clang/Basic/TokenKinds.def

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -423,9 +423,9 @@ C23_KEYWORD(typeof , KEYGNU)
423423
C23_KEYWORD(typeof_unqual , 0)
424424

425425
// ISO/IEC JTC1 SC22 WG14 N1169 Extension
426-
KEYWORD(_Accum , KEYNOCXX)
427-
KEYWORD(_Fract , KEYNOCXX)
428-
KEYWORD(_Sat , KEYNOCXX)
426+
KEYWORD(_Accum , KEYALL)
427+
KEYWORD(_Fract , KEYALL)
428+
KEYWORD(_Sat , KEYALL)
429429

430430
// GNU Extensions (in impl-reserved namespace)
431431
KEYWORD(_Decimal32 , KEYALL)

clang/include/clang/Driver/Options.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2054,7 +2054,7 @@ defm fixed_point : BoolFOption<"fixed-point",
20542054
LangOpts<"FixedPoint">, DefaultFalse,
20552055
PosFlag<SetTrue, [], [ClangOption, CC1Option], "Enable">,
20562056
NegFlag<SetFalse, [], [ClangOption], "Disable">,
2057-
BothFlags<[], [ClangOption], " fixed point types">>, ShouldParseIf<!strconcat("!", cplusplus.KeyPath)>;
2057+
BothFlags<[], [ClangOption], " fixed point types">>;
20582058
defm cxx_static_destructors : BoolFOption<"c++-static-destructors",
20592059
LangOpts<"RegisterStaticDestructors">, DefaultTrue,
20602060
NegFlag<SetFalse, [], [ClangOption, CC1Option],

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 58 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3048,7 +3048,17 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
30483048
// ::= Di # char32_t
30493049
// ::= Ds # char16_t
30503050
// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
3051+
// ::= [DS] DA # N1169 fixed-point [_Sat] T _Accum
3052+
// ::= [DS] DR # N1169 fixed-point [_Sat] T _Fract
30513053
// ::= u <source-name> # vendor extended type
3054+
//
3055+
// <fixed-point-size>
3056+
// ::= s # short
3057+
// ::= t # unsigned short
3058+
// ::= i # plain
3059+
// ::= j # unsigned
3060+
// ::= l # long
3061+
// ::= m # unsigned long
30523062
std::string type_name;
30533063
// Normalize integer types as vendor extended types:
30543064
// u<length>i<type size>
@@ -3193,30 +3203,77 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
31933203
Out << "DF16_";
31943204
break;
31953205
case BuiltinType::ShortAccum:
3206+
Out << "DAs";
3207+
break;
31963208
case BuiltinType::Accum:
3209+
Out << "DAi";
3210+
break;
31973211
case BuiltinType::LongAccum:
3212+
Out << "DAl";
3213+
break;
31983214
case BuiltinType::UShortAccum:
3215+
Out << "DAt";
3216+
break;
31993217
case BuiltinType::UAccum:
3218+
Out << "DAj";
3219+
break;
32003220
case BuiltinType::ULongAccum:
3221+
Out << "DAm";
3222+
break;
32013223
case BuiltinType::ShortFract:
3224+
Out << "DRs";
3225+
break;
32023226
case BuiltinType::Fract:
3227+
Out << "DRi";
3228+
break;
32033229
case BuiltinType::LongFract:
3230+
Out << "DRl";
3231+
break;
32043232
case BuiltinType::UShortFract:
3233+
Out << "DRt";
3234+
break;
32053235
case BuiltinType::UFract:
3236+
Out << "DRj";
3237+
break;
32063238
case BuiltinType::ULongFract:
3239+
Out << "DRm";
3240+
break;
32073241
case BuiltinType::SatShortAccum:
3242+
Out << "DSDAs";
3243+
break;
32083244
case BuiltinType::SatAccum:
3245+
Out << "DSDAi";
3246+
break;
32093247
case BuiltinType::SatLongAccum:
3248+
Out << "DSDAl";
3249+
break;
32103250
case BuiltinType::SatUShortAccum:
3251+
Out << "DSDAt";
3252+
break;
32113253
case BuiltinType::SatUAccum:
3254+
Out << "DSDAj";
3255+
break;
32123256
case BuiltinType::SatULongAccum:
3257+
Out << "DSDAm";
3258+
break;
32133259
case BuiltinType::SatShortFract:
3260+
Out << "DSDRs";
3261+
break;
32143262
case BuiltinType::SatFract:
3263+
Out << "DSDRi";
3264+
break;
32153265
case BuiltinType::SatLongFract:
3266+
Out << "DSDRl";
3267+
break;
32163268
case BuiltinType::SatUShortFract:
3269+
Out << "DSDRt";
3270+
break;
32173271
case BuiltinType::SatUFract:
3272+
Out << "DSDRj";
3273+
break;
32183274
case BuiltinType::SatULongFract:
3219-
llvm_unreachable("Fixed point types are disabled for c++");
3275+
Out << "DSDRm";
3276+
break;
32203277
case BuiltinType::Half:
32213278
Out << "Dh";
32223279
break;

clang/lib/Parse/ParseExpr.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1564,6 +1564,9 @@ ExprResult Parser::ParseCastExpression(CastParseKind ParseKind,
15641564
case tok::kw_typename:
15651565
case tok::kw_typeof:
15661566
case tok::kw___vector:
1567+
case tok::kw__Accum:
1568+
case tok::kw__Fract:
1569+
case tok::kw__Sat:
15671570
#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
15681571
#include "clang/Basic/OpenCLImageTypes.def"
15691572
{

clang/lib/Parse/ParseExprCXX.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2354,6 +2354,15 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
23542354
case tok::kw_bool:
23552355
DS.SetTypeSpecType(DeclSpec::TST_bool, Loc, PrevSpec, DiagID, Policy);
23562356
break;
2357+
case tok::kw__Accum:
2358+
DS.SetTypeSpecType(DeclSpec::TST_accum, Loc, PrevSpec, DiagID, Policy);
2359+
break;
2360+
case tok::kw__Fract:
2361+
DS.SetTypeSpecType(DeclSpec::TST_fract, Loc, PrevSpec, DiagID, Policy);
2362+
break;
2363+
case tok::kw__Sat:
2364+
DS.SetTypeSpecSat(Loc, PrevSpec, DiagID);
2365+
break;
23572366
#define GENERIC_IMAGE_TYPE(ImgType, Id) \
23582367
case tok::kw_##ImgType##_t: \
23592368
DS.SetTypeSpecType(DeclSpec::TST_##ImgType##_t, Loc, PrevSpec, DiagID, \

clang/lib/Parse/ParseTentative.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1764,6 +1764,9 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
17641764
case tok::kw___ibm128:
17651765
case tok::kw_void:
17661766
case tok::annot_decltype:
1767+
case tok::kw__Accum:
1768+
case tok::kw__Fract:
1769+
case tok::kw__Sat:
17671770
#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
17681771
#include "clang/Basic/OpenCLImageTypes.def"
17691772
if (NextToken().is(tok::l_paren))
@@ -1883,6 +1886,9 @@ bool Parser::isCXXDeclarationSpecifierAType() {
18831886
case tok::kw_void:
18841887
case tok::kw___unknown_anytype:
18851888
case tok::kw___auto_type:
1889+
case tok::kw__Accum:
1890+
case tok::kw__Fract:
1891+
case tok::kw__Sat:
18861892
#define GENERIC_IMAGE_TYPE(ImgType, Id) case tok::kw_##ImgType##_t:
18871893
#include "clang/Basic/OpenCLImageTypes.def"
18881894
return true;
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
// RUN: %clang_cc1 -ffixed-point -S -emit-llvm %s -o - -triple=x86_64-unknown-linux-gnu | FileCheck %s
2+
3+
// Primary fixed point types
4+
void func(signed short _Accum){} // CHECK: @_Z4funcDAs
5+
void func(signed _Accum){} // CHECK: @_Z4funcDAi
6+
void func(signed long _Accum){} // CHECK: @_Z4funcDAl
7+
void func(unsigned short _Accum){} // CHECK: @_Z4funcDAt
8+
void func(unsigned _Accum){} // CHECK: @_Z4funcDAj
9+
void func(unsigned long _Accum){} // CHECK: @_Z4funcDAm
10+
void func(signed short _Fract){} // CHECK: @_Z4funcDRs
11+
void func(signed _Fract){} // CHECK: @_Z4funcDRi
12+
void func(signed long _Fract){} // CHECK: @_Z4funcDRl
13+
void func(unsigned short _Fract){} // CHECK: @_Z4funcDRt
14+
void func(unsigned _Fract){} // CHECK: @_Z4funcDRj
15+
void func(unsigned long _Fract){} // CHECK: @_Z4funcDRm
16+
17+
// Aliased
18+
void func2(short _Accum){} // CHECK: @_Z5func2DAs
19+
void func2(_Accum){} // CHECK: @_Z5func2DAi
20+
void func2(long _Accum){} // CHECK: @_Z5func2DAl
21+
void func2(short _Fract){} // CHECK: @_Z5func2DRs
22+
void func2(_Fract){} // CHECK: @_Z5func2DRi
23+
void func2(long _Fract){} // CHECK: @_Z5func2DRl
24+
25+
// Primary saturated
26+
void func(_Sat signed short _Accum){} // CHECK: @_Z4funcDSDAs
27+
void func(_Sat signed _Accum){} // CHECK: @_Z4funcDSDAi
28+
void func(_Sat signed long _Accum){} // CHECK: @_Z4funcDSDAl
29+
void func(_Sat unsigned short _Accum){} // CHECK: @_Z4funcDSDAt
30+
void func(_Sat unsigned _Accum){} // CHECK: @_Z4funcDSDAj
31+
void func(_Sat unsigned long _Accum){} // CHECK: @_Z4funcDSDAm
32+
void func(_Sat signed short _Fract){} // CHECK: @_Z4funcDSDRs
33+
void func(_Sat signed _Fract){} // CHECK: @_Z4funcDSDRi
34+
void func(_Sat signed long _Fract){} // CHECK: @_Z4funcDSDRl
35+
void func(_Sat unsigned short _Fract){} // CHECK: @_Z4funcDSDRt
36+
void func(_Sat unsigned _Fract){} // CHECK: @_Z4funcDSDRj
37+
void func(_Sat unsigned long _Fract){} // CHECK: @_Z4funcDSDRm
38+
39+
// Aliased saturated
40+
void func2(_Sat short _Accum){} // CHECK: @_Z5func2DSDAs
41+
void func2(_Sat _Accum){} // CHECK: @_Z5func2DSDAi
42+
void func2(_Sat long _Accum){} // CHECK: @_Z5func2DSDAl
43+
void func2(_Sat short _Fract){} // CHECK: @_Z5func2DSDRs
44+
void func2(_Sat _Fract){} // CHECK: @_Z5func2DSDRi
45+
void func2(_Sat long _Fract){} // CHECK: @_Z5func2DSDRl
Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,18 @@
1-
// RUN: %clang_cc1 -x c++ %s -verify
2-
// RUN: %clang_cc1 -x c++ -ffixed-point %s -verify
1+
// RUN: %clang_cc1 -x c++ %s -verify -DWITHOUT_FIXED_POINT
2+
// RUN: %clang_cc1 -x c++ %s -verify -ffixed-point
33

4-
// Name namgling is not provided for fixed point types in c++
5-
6-
_Accum accum; // expected-error{{unknown type name '_Accum'}}
7-
_Fract fract; // expected-error{{unknown type name '_Fract'}}
8-
_Sat _Accum sat_accum; // expected-error{{unknown type name '_Sat'}}
9-
// expected-error@-1{{expected ';' after top level declarator}}
4+
#ifdef WITHOUT_FIXED_POINT
5+
_Accum accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
6+
// expected-error@-1{{a type specifier is required for all declarations}}
7+
_Fract fract; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
8+
// expected-error@-1{{a type specifier is required for all declarations}}
9+
_Sat _Accum sat_accum; // expected-error 2{{compile with '-ffixed-point' to enable fixed point types}}
10+
// expected-error@-1{{a type specifier is required for all declarations}}
11+
#endif
1012

1113
int accum_int = 10k; // expected-error{{invalid suffix 'k' on integer constant}}
1214
int fract_int = 10r; // expected-error{{invalid suffix 'r' on integer constant}}
13-
float accum_flt = 10.0k; // expected-error{{invalid suffix 'k' on floating constant}}
14-
float fract_flt = 10.0r; // expected-error{{invalid suffix 'r' on floating constant}}
15+
#ifdef WITHOUT_FIXED_POINT
16+
float accum_flt = 0.0k; // expected-error{{invalid suffix 'k' on floating constant}}
17+
float fract_flt = 0.0r; // expected-error{{invalid suffix 'r' on floating constant}}
18+
#endif

0 commit comments

Comments
 (0)