diff options
| author | Leonard Chan <leonardchan@google.com> | 2018-06-14 14:53:51 +0000 |
|---|---|---|
| committer | Leonard Chan <leonardchan@google.com> | 2018-06-14 14:53:51 +0000 |
| commit | ab80f3c8b71e71e62d8b0f10a03bad4ee8d5ed00 (patch) | |
| tree | 9b16d58c08edf24e787fa88d7473bbcc4cd8edcf /clang/lib/Sema | |
| parent | 234c68168648d0bbcb514d337dd268d4dc3ed0c3 (diff) | |
| download | bcm5719-llvm-ab80f3c8b71e71e62d8b0f10a03bad4ee8d5ed00.tar.gz bcm5719-llvm-ab80f3c8b71e71e62d8b0f10a03bad4ee8d5ed00.zip | |
[Fixed Point Arithmetic] Addition of the remaining fixed point types and their saturated equivalents
This diff includes changes for the remaining _Fract and _Sat fixed point types.
```
signed short _Fract s_short_fract;
signed _Fract s_fract;
signed long _Fract s_long_fract;
unsigned short _Fract u_short_fract;
unsigned _Fract u_fract;
unsigned long _Fract u_long_fract;
// Aliased fixed point types
short _Accum short_accum;
_Accum accum;
long _Accum long_accum;
short _Fract short_fract;
_Fract fract;
long _Fract long_fract;
// Saturated fixed point types
_Sat signed short _Accum sat_s_short_accum;
_Sat signed _Accum sat_s_accum;
_Sat signed long _Accum sat_s_long_accum;
_Sat unsigned short _Accum sat_u_short_accum;
_Sat unsigned _Accum sat_u_accum;
_Sat unsigned long _Accum sat_u_long_accum;
_Sat signed short _Fract sat_s_short_fract;
_Sat signed _Fract sat_s_fract;
_Sat signed long _Fract sat_s_long_fract;
_Sat unsigned short _Fract sat_u_short_fract;
_Sat unsigned _Fract sat_u_fract;
_Sat unsigned long _Fract sat_u_long_fract;
// Aliased saturated fixed point types
_Sat short _Accum sat_short_accum;
_Sat _Accum sat_accum;
_Sat long _Accum sat_long_accum;
_Sat short _Fract sat_short_fract;
_Sat _Fract sat_fract;
_Sat long _Fract sat_long_fract;
```
This diff only allows for declaration of these fixed point types. Assignment and other operations done on fixed point types according to http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1169.pdf will be added in future patches.
Differential Revision: https://reviews.llvm.org/D46911
llvm-svn: 334718
Diffstat (limited to 'clang/lib/Sema')
| -rw-r--r-- | clang/lib/Sema/DeclSpec.cpp | 26 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaTemplateVariadic.cpp | 1 | ||||
| -rw-r--r-- | clang/lib/Sema/SemaType.cpp | 80 |
3 files changed, 75 insertions, 32 deletions
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index aa5f197b541..fe111a5ddea 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -340,6 +340,7 @@ bool Declarator::isDeclarationOfFunction() const { case TST_decimal64: case TST_double: case TST_Accum: + case TST_Fract: case TST_Float16: case TST_float128: case TST_enum: @@ -512,6 +513,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T, case DeclSpec::TST_float: return "float"; case DeclSpec::TST_double: return "double"; case DeclSpec::TST_accum: return "_Accum"; + case DeclSpec::TST_fract: return "_Fract"; case DeclSpec::TST_float16: return "_Float16"; case DeclSpec::TST_float128: return "__float128"; case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool"; @@ -767,6 +769,19 @@ bool DeclSpec::SetTypeSpecType(TST T, SourceLocation Loc, return false; } +bool DeclSpec::SetTypeSpecSat(SourceLocation Loc, const char *&PrevSpec, + unsigned &DiagID) { + // Cannot set twice + if (TypeSpecSat) { + DiagID = diag::warn_duplicate_declspec; + PrevSpec = "_Sat"; + return true; + } + TypeSpecSat = true; + TSSatLoc = Loc; + return false; +} + bool DeclSpec::SetTypeAltiVecVector(bool isAltiVecVector, SourceLocation Loc, const char *&PrevSpec, unsigned &DiagID, const PrintingPolicy &Policy) { @@ -1102,13 +1117,16 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { } } + bool IsFixedPointType = + TypeSpecType == TST_accum || TypeSpecType == TST_fract; + // signed/unsigned are only valid with int/char/wchar_t/_Accum. if (TypeSpecSign != TSS_unspecified) { if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // unsigned -> unsigned int, signed -> signed int. else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 && TypeSpecType != TST_char && TypeSpecType != TST_wchar && - TypeSpecType != TST_accum) { + !IsFixedPointType) { S.Diag(TSSLoc, diag::err_invalid_sign_spec) << getSpecifierName((TST)TypeSpecType, Policy); // signed double -> double. @@ -1124,10 +1142,11 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // short -> short int, long long -> long long int. else if (!(TypeSpecType == TST_int || - (TypeSpecType == TST_accum && TypeSpecWidth != TSW_longlong))) { + (IsFixedPointType && TypeSpecWidth != TSW_longlong))) { S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec) << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy); TypeSpecType = TST_int; + TypeSpecSat = false; TypeSpecOwned = false; } break; @@ -1135,10 +1154,11 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // long -> long int. else if (TypeSpecType != TST_int && TypeSpecType != TST_double && - TypeSpecType != TST_accum) { + !IsFixedPointType) { S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec) << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy); TypeSpecType = TST_int; + TypeSpecSat = false; TypeSpecOwned = false; } break; diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index dc67c8ef19a..71c583367bd 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -831,6 +831,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { case TST_float: case TST_double: case TST_Accum: + case TST_Fract: case TST_Float16: case TST_float128: case TST_bool: diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 1f6034a07d3..9ee947b80a3 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1392,36 +1392,49 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { break; } case DeclSpec::TST_accum: { - if (DS.getTypeSpecSign() != DeclSpec::TSS_unsigned) { - switch (DS.getTypeSpecWidth()) { - case DeclSpec::TSW_short: - Result = Context.ShortAccumTy; - break; - case DeclSpec::TSW_unspecified: - Result = Context.AccumTy; - break; - case DeclSpec::TSW_long: - Result = Context.LongAccumTy; - break; - case DeclSpec::TSW_longlong: - // Unreachable b/c this is caught in final analysis of the DeclSpec. - llvm_unreachable("Unable to specify long long as _Accum width"); - } - } else { - switch (DS.getTypeSpecWidth()) { - case DeclSpec::TSW_short: - Result = Context.UnsignedShortAccumTy; - break; - case DeclSpec::TSW_unspecified: - Result = Context.UnsignedAccumTy; - break; - case DeclSpec::TSW_long: - Result = Context.UnsignedLongAccumTy; - break; - case DeclSpec::TSW_longlong: - llvm_unreachable("Unable to specify long long as _Accum width"); - } + switch (DS.getTypeSpecWidth()) { + case DeclSpec::TSW_short: + Result = Context.ShortAccumTy; + break; + case DeclSpec::TSW_unspecified: + Result = Context.AccumTy; + break; + case DeclSpec::TSW_long: + Result = Context.LongAccumTy; + break; + case DeclSpec::TSW_longlong: + llvm_unreachable("Unable to specify long long as _Accum width"); } + + if (DS.getTypeSpecSign() == DeclSpec::TSS_unsigned) + Result = Context.getCorrespondingUnsignedType(Result); + + if (DS.isTypeSpecSat()) + Result = Context.getCorrespondingSaturatedType(Result); + + break; + } + case DeclSpec::TST_fract: { + switch (DS.getTypeSpecWidth()) { + case DeclSpec::TSW_short: + Result = Context.ShortFractTy; + break; + case DeclSpec::TSW_unspecified: + Result = Context.FractTy; + break; + case DeclSpec::TSW_long: + Result = Context.LongFractTy; + break; + case DeclSpec::TSW_longlong: + llvm_unreachable("Unable to specify long long as _Fract width"); + } + + if (DS.getTypeSpecSign() == DeclSpec::TSS_unsigned) + Result = Context.getCorrespondingUnsignedType(Result); + + if (DS.isTypeSpecSat()) + Result = Context.getCorrespondingSaturatedType(Result); + break; } case DeclSpec::TST_int128: @@ -1592,6 +1605,15 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) { S.checkOpenCLDisabledTypeDeclSpec(DS, Result)) declarator.setInvalidType(true); + bool IsFixedPointType = DS.getTypeSpecType() == DeclSpec::TST_accum || + DS.getTypeSpecType() == DeclSpec::TST_fract; + + // Only fixed point types can be saturated + if (DS.isTypeSpecSat() && !IsFixedPointType) + S.Diag(DS.getTypeSpecSatLoc(), diag::err_invalid_saturation_spec) + << DS.getSpecifierName(DS.getTypeSpecType(), + Context.getPrintingPolicy()); + // Handle complex types. if (DS.getTypeSpecComplex() == DeclSpec::TSC_complex) { if (S.getLangOpts().Freestanding) |

