summaryrefslogtreecommitdiffstats
path: root/clang/lib/Sema
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/Sema')
-rw-r--r--clang/lib/Sema/DeclSpec.cpp15
-rw-r--r--clang/lib/Sema/SemaTemplateVariadic.cpp1
-rw-r--r--clang/lib/Sema/SemaType.cpp33
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)
OpenPOWER on IntegriCloud