diff options
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r-- | clang/lib/Sema/DeclSpec.cpp | 15 | ||||
-rw-r--r-- | clang/lib/Sema/SemaTemplateVariadic.cpp | 1 | ||||
-rw-r--r-- | clang/lib/Sema/SemaType.cpp | 33 |
3 files changed, 44 insertions, 5 deletions
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp index dd2476ec371..aa5f197b541 100644 --- a/clang/lib/Sema/DeclSpec.cpp +++ b/clang/lib/Sema/DeclSpec.cpp @@ -339,6 +339,7 @@ bool Declarator::isDeclarationOfFunction() const { case TST_decimal32: case TST_decimal64: case TST_double: + case TST_Accum: case TST_Float16: case TST_float128: case TST_enum: @@ -510,6 +511,7 @@ const char *DeclSpec::getSpecifierName(DeclSpec::TST T, case DeclSpec::TST_half: return "half"; case DeclSpec::TST_float: return "float"; case DeclSpec::TST_double: return "double"; + case DeclSpec::TST_accum: return "_Accum"; case DeclSpec::TST_float16: return "_Float16"; case DeclSpec::TST_float128: return "__float128"; case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool"; @@ -1100,12 +1102,13 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { } } - // signed/unsigned are only valid with int/char/wchar_t. + // 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) { + else if (TypeSpecType != TST_int && TypeSpecType != TST_int128 && + TypeSpecType != TST_char && TypeSpecType != TST_wchar && + TypeSpecType != TST_accum) { S.Diag(TSSLoc, diag::err_invalid_sign_spec) << getSpecifierName((TST)TypeSpecType, Policy); // signed double -> double. @@ -1120,7 +1123,8 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { case TSW_longlong: // long long int if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // short -> short int, long long -> long long int. - else if (TypeSpecType != TST_int) { + else if (!(TypeSpecType == TST_int || + (TypeSpecType == TST_accum && TypeSpecWidth != TSW_longlong))) { S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec) << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy); TypeSpecType = TST_int; @@ -1130,7 +1134,8 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) { case TSW_long: // long double, long int if (TypeSpecType == TST_unspecified) TypeSpecType = TST_int; // long -> long int. - else if (TypeSpecType != TST_int && TypeSpecType != TST_double) { + else if (TypeSpecType != TST_int && TypeSpecType != TST_double && + TypeSpecType != TST_accum) { S.Diag(TSWRange.getBegin(), diag::err_invalid_width_spec) << (int)TypeSpecWidth << getSpecifierName((TST)TypeSpecType, Policy); TypeSpecType = TST_int; diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp index c58e648bb3b..dc67c8ef19a 100644 --- a/clang/lib/Sema/SemaTemplateVariadic.cpp +++ b/clang/lib/Sema/SemaTemplateVariadic.cpp @@ -830,6 +830,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) { case TST_half: case TST_float: case TST_double: + case TST_Accum: case TST_Float16: case TST_float128: case TST_bool: diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp index 6839dd7de21..ac85e016ba0 100644 --- a/clang/lib/Sema/SemaType.cpp +++ b/clang/lib/Sema/SemaType.cpp @@ -1391,6 +1391,39 @@ 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"); + } + } + break; + } case DeclSpec::TST_int128: if (!S.Context.getTargetInfo().hasInt128Type()) S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) |