summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
authorLeonard Chan <leonardchan@google.com>2018-06-14 14:53:51 +0000
committerLeonard Chan <leonardchan@google.com>2018-06-14 14:53:51 +0000
commitab80f3c8b71e71e62d8b0f10a03bad4ee8d5ed00 (patch)
tree9b16d58c08edf24e787fa88d7473bbcc4cd8edcf /clang/lib/Sema
parent234c68168648d0bbcb514d337dd268d4dc3ed0c3 (diff)
downloadbcm5719-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.cpp26
-rw-r--r--clang/lib/Sema/SemaTemplateVariadic.cpp1
-rw-r--r--clang/lib/Sema/SemaType.cpp80
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)
OpenPOWER on IntegriCloud