Index: include/clang-c/Index.h =================================================================== --- include/clang-c/Index.h +++ include/clang-c/Index.h @@ -3174,8 +3174,14 @@ CXType_Float128 = 30, CXType_Half = 31, CXType_Float16 = 32, + CXType_ShortAccum = 33, + CXType_Accum = 34, + CXType_LongAccum = 35, + CXType_UShortAccum = 36, + CXType_UAccum = 37, + CXType_ULongAccum = 38, CXType_FirstBuiltin = CXType_Void, - CXType_LastBuiltin = CXType_Float16, + CXType_LastBuiltin = CXType_ULongAccum, CXType_Complex = 100, CXType_Pointer = 101, Index: include/clang/AST/ASTContext.h =================================================================== --- include/clang/AST/ASTContext.h +++ include/clang/AST/ASTContext.h @@ -1005,6 +1005,8 @@ CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy; CanQualType UnsignedLongLongTy, UnsignedInt128Ty; CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty; + CanQualType ShortAccumTy, AccumTy, LongAccumTy; // ISO/IEC JTC1 SC22 WG14 N1169 Extension + CanQualType UnsignedShortAccumTy, UnsignedAccumTy, UnsignedLongAccumTy; CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; Index: include/clang/AST/BuiltinTypes.def =================================================================== --- include/clang/AST/BuiltinTypes.def +++ include/clang/AST/BuiltinTypes.def @@ -119,6 +119,26 @@ // '__int128_t' SIGNED_TYPE(Int128, Int128Ty) +//===- Fixed point types --------------------------------------------------===// + +// 'short _Accum' +SIGNED_TYPE(ShortAccum, ShortAccumTy) + +// '_Accum' +SIGNED_TYPE(Accum, AccumTy) + +// 'long _Accum' +SIGNED_TYPE(LongAccum, LongAccumTy) + +// 'unsigned short _Accum' +UNSIGNED_TYPE(UShortAccum, UnsignedShortAccumTy) + +// 'unsigned _Accum' +UNSIGNED_TYPE(UAccum, UnsignedAccumTy) + +// 'unsigned long _Accum' +UNSIGNED_TYPE(ULongAccum, UnsignedLongAccumTy) + //===- Floating point types -----------------------------------------------===// // 'half' in OpenCL, '__fp16' in ARM NEON. Index: include/clang/Basic/Specifiers.h =================================================================== --- include/clang/Basic/Specifiers.h +++ include/clang/Basic/Specifiers.h @@ -53,6 +53,7 @@ TST_int128, TST_half, // OpenCL half, ARM NEON __fp16 TST_Float16, // C11 extension ISO/IEC TS 18661-3 + TST_Accum, // ISO/IEC JTC1 SC22 WG14 N1169 Extension TST_float, TST_double, TST_float128, Index: include/clang/Basic/TokenKinds.def =================================================================== --- include/clang/Basic/TokenKinds.def +++ include/clang/Basic/TokenKinds.def @@ -383,6 +383,9 @@ // C11 Extension KEYWORD(_Float16 , KEYALL) +// ISO/IEC JTC1 SC22 WG14 N1169 Extension +KEYWORD(_Accum , KEYALL) + // GNU Extensions (in impl-reserved namespace) KEYWORD(_Decimal32 , KEYALL) KEYWORD(_Decimal64 , KEYALL) Index: include/clang/Sema/DeclSpec.h =================================================================== --- include/clang/Sema/DeclSpec.h +++ include/clang/Sema/DeclSpec.h @@ -281,6 +281,7 @@ static const TST TST_float = clang::TST_float; static const TST TST_double = clang::TST_double; static const TST TST_float16 = clang::TST_Float16; + static const TST TST_accum = clang::TST_Accum; static const TST TST_float128 = clang::TST_float128; static const TST TST_bool = clang::TST_bool; static const TST TST_decimal32 = clang::TST_decimal32; Index: include/clang/Serialization/ASTBitCodes.h =================================================================== --- include/clang/Serialization/ASTBitCodes.h +++ include/clang/Serialization/ASTBitCodes.h @@ -936,6 +936,24 @@ /// \brief The '_Float16' type PREDEF_TYPE_FLOAT16_ID = 44, + /// \brief The 'short _Accum' type + PREDEF_TYPE_SHORT_ACCUM_ID = 45, + + /// \brief The '_Accum' type + PREDEF_TYPE_ACCUM_ID = 46, + + /// \brief The 'long _Accum' type + PREDEF_TYPE_LONG_ACCUM_ID = 47, + + /// \brief The 'unsigned short _Accum' type + PREDEF_TYPE_USHORT_ACCUM_ID = 48, + + /// \brief The 'unsigned _Accum' type + PREDEF_TYPE_UACCUM_ID = 49, + + /// \brief The 'unsigned long _Accum' type + PREDEF_TYPE_ULONG_ACCUM_ID = 50, + /// \brief OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, Index: lib/AST/ASTContext.cpp =================================================================== --- lib/AST/ASTContext.cpp +++ lib/AST/ASTContext.cpp @@ -1133,6 +1133,14 @@ // C11 extension ISO/IEC TS 18661-3 InitBuiltinType(Float16Ty, BuiltinType::Float16); + // ISO/IEC JTC1 SC22 WG14 N1169 Extension + InitBuiltinType(ShortAccumTy, BuiltinType::ShortAccum); + InitBuiltinType(AccumTy, BuiltinType::Accum); + InitBuiltinType(LongAccumTy, BuiltinType::LongAccum); + InitBuiltinType(UnsignedShortAccumTy,BuiltinType::UShortAccum); + InitBuiltinType(UnsignedAccumTy, BuiltinType::UAccum); + InitBuiltinType(UnsignedLongAccumTy, BuiltinType::ULongAccum); + // GNU extension, 128-bit integers. InitBuiltinType(Int128Ty, BuiltinType::Int128); InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128); @@ -6238,6 +6246,14 @@ case BuiltinType::ObjCSel: llvm_unreachable("@encoding ObjC primitive type"); + case BuiltinType::ShortAccum: + case BuiltinType::Accum: + case BuiltinType::LongAccum: + case BuiltinType::UShortAccum: + case BuiltinType::UAccum: + case BuiltinType::ULongAccum: + llvm_unreachable("No ObjC encoding for fixed point types"); + // OpenCL and placeholder types don't need @encodings. #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ case BuiltinType::Id: Index: lib/AST/ExprConstant.cpp =================================================================== --- lib/AST/ExprConstant.cpp +++ lib/AST/ExprConstant.cpp @@ -7320,6 +7320,9 @@ case BuiltinType::ULong: case BuiltinType::ULongLong: case BuiltinType::UInt128: + case BuiltinType::UShortAccum: + case BuiltinType::UAccum: + case BuiltinType::ULongAccum: return integer_type_class; case BuiltinType::NullPtr: Index: lib/AST/ItaniumMangle.cpp =================================================================== --- lib/AST/ItaniumMangle.cpp +++ lib/AST/ItaniumMangle.cpp @@ -2543,6 +2543,24 @@ case BuiltinType::Float16: Out << "DF16_"; break; + case BuiltinType::ShortAccum: + Out << "DsA_"; + break; + case BuiltinType::Accum: + Out << "DA_"; + break; + case BuiltinType::LongAccum: + Out << "DlA_"; + break; + case BuiltinType::UShortAccum: + Out << "DusA_"; + break; + case BuiltinType::UAccum: + Out << "DuA_"; + break; + case BuiltinType::ULongAccum: + Out << "DulA_"; + break; case BuiltinType::Half: Out << "Dh"; break; Index: lib/AST/MicrosoftMangle.cpp =================================================================== --- lib/AST/MicrosoftMangle.cpp +++ lib/AST/MicrosoftMangle.cpp @@ -1922,6 +1922,12 @@ mangleArtificalTagType(TTK_Struct, "_Float16", {"__clang"}); break; + case BuiltinType::ShortAccum: + case BuiltinType::Accum: + case BuiltinType::LongAccum: + case BuiltinType::UShortAccum: + case BuiltinType::UAccum: + case BuiltinType::ULongAccum: case BuiltinType::Float128: case BuiltinType::Half: { DiagnosticsEngine &Diags = Context.getDiags(); Index: lib/AST/NSAPI.cpp =================================================================== --- lib/AST/NSAPI.cpp +++ lib/AST/NSAPI.cpp @@ -440,6 +440,12 @@ case BuiltinType::Char32: case BuiltinType::Int128: case BuiltinType::LongDouble: + case BuiltinType::ShortAccum: + case BuiltinType::Accum: + case BuiltinType::LongAccum: + case BuiltinType::UShortAccum: + case BuiltinType::UAccum: + case BuiltinType::ULongAccum: case BuiltinType::UInt128: case BuiltinType::Float16: case BuiltinType::Float128: Index: lib/AST/Type.cpp =================================================================== --- lib/AST/Type.cpp +++ lib/AST/Type.cpp @@ -2648,6 +2648,18 @@ return "double"; case LongDouble: return "long double"; + case ShortAccum: + return "short _Accum"; + case Accum: + return "_Accum"; + case LongAccum: + return "long _Accum"; + case UShortAccum: + return "unsigned short _Accum"; + case UAccum: + return "unsigned _Accum"; + case ULongAccum: + return "unsigned long _Accum"; case Float16: return "_Float16"; case Float128: Index: lib/AST/TypeLoc.cpp =================================================================== --- lib/AST/TypeLoc.cpp +++ lib/AST/TypeLoc.cpp @@ -342,6 +342,12 @@ case BuiltinType::LongDouble: case BuiltinType::Float16: case BuiltinType::Float128: + case BuiltinType::ShortAccum: + case BuiltinType::Accum: + case BuiltinType::LongAccum: + case BuiltinType::UShortAccum: + case BuiltinType::UAccum: + case BuiltinType::ULongAccum: llvm_unreachable("Builtin type needs extra local data!"); // Fall through, if the impossible happens. Index: lib/Analysis/PrintfFormatString.cpp =================================================================== --- lib/Analysis/PrintfFormatString.cpp +++ lib/Analysis/PrintfFormatString.cpp @@ -654,6 +654,12 @@ case BuiltinType::Half: case BuiltinType::Float16: case BuiltinType::Float128: + case BuiltinType::ShortAccum: + case BuiltinType::Accum: + case BuiltinType::LongAccum: + case BuiltinType::UShortAccum: + case BuiltinType::UAccum: + case BuiltinType::ULongAccum: // Various types which are non-trivial to correct. return false; Index: lib/CodeGen/CGDebugInfo.cpp =================================================================== --- lib/CodeGen/CGDebugInfo.cpp +++ lib/CodeGen/CGDebugInfo.cpp @@ -675,6 +675,9 @@ case BuiltinType::ULong: case BuiltinType::WChar_U: case BuiltinType::ULongLong: + case BuiltinType::UShortAccum: + case BuiltinType::UAccum: + case BuiltinType::ULongAccum: Encoding = llvm::dwarf::DW_ATE_unsigned; break; case BuiltinType::Short: @@ -683,6 +686,9 @@ case BuiltinType::Long: case BuiltinType::WChar_S: case BuiltinType::LongLong: + case BuiltinType::ShortAccum: + case BuiltinType::Accum: + case BuiltinType::LongAccum: Encoding = llvm::dwarf::DW_ATE_signed; break; case BuiltinType::Bool: Index: lib/CodeGen/CodeGenTypes.cpp =================================================================== --- lib/CodeGen/CodeGenTypes.cpp +++ lib/CodeGen/CodeGenTypes.cpp @@ -439,6 +439,12 @@ case BuiltinType::WChar_U: case BuiltinType::Char16: case BuiltinType::Char32: + case BuiltinType::ShortAccum: + case BuiltinType::Accum: + case BuiltinType::LongAccum: + case BuiltinType::UShortAccum: + case BuiltinType::UAccum: + case BuiltinType::ULongAccum: ResultType = llvm::IntegerType::get(getLLVMContext(), static_cast(Context.getTypeSize(T))); break; Index: lib/CodeGen/ItaniumCXXABI.cpp =================================================================== --- lib/CodeGen/ItaniumCXXABI.cpp +++ lib/CodeGen/ItaniumCXXABI.cpp @@ -2710,6 +2710,12 @@ case BuiltinType::Char32: case BuiltinType::Int128: case BuiltinType::UInt128: + case BuiltinType::ShortAccum: + case BuiltinType::Accum: + case BuiltinType::LongAccum: + case BuiltinType::UShortAccum: + case BuiltinType::UAccum: + case BuiltinType::ULongAccum: return true; #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ Index: lib/Index/USRGeneration.cpp =================================================================== --- lib/Index/USRGeneration.cpp +++ lib/Index/USRGeneration.cpp @@ -682,6 +682,13 @@ c = 'K'; break; case BuiltinType::Int128: c = 'J'; break; + case BuiltinType::ShortAccum: + case BuiltinType::Accum: + case BuiltinType::LongAccum: + case BuiltinType::UShortAccum: + case BuiltinType::UAccum: + case BuiltinType::ULongAccum: + llvm_unreachable("No USR name mangling for fixed point types."); case BuiltinType::Float16: case BuiltinType::Half: c = 'h'; break; Index: lib/Parse/ParseDecl.cpp =================================================================== --- lib/Parse/ParseDecl.cpp +++ lib/Parse/ParseDecl.cpp @@ -3579,6 +3579,10 @@ isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float16, Loc, PrevSpec, DiagID, Policy); break; + case tok::kw__Accum: + isInvalid = DS.SetTypeSpecType(DeclSpec::TST_accum, Loc, PrevSpec, + DiagID, Policy); + break; case tok::kw___float128: isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy); @@ -4591,6 +4595,7 @@ case tok::kw_half: case tok::kw_float: case tok::kw_double: + case tok::kw__Accum: case tok::kw__Float16: case tok::kw___float128: case tok::kw_bool: @@ -4667,6 +4672,7 @@ case tok::kw_half: case tok::kw_float: case tok::kw_double: + case tok::kw__Accum: case tok::kw__Float16: case tok::kw___float128: case tok::kw_bool: @@ -4824,6 +4830,7 @@ case tok::kw_half: case tok::kw_float: case tok::kw_double: + case tok::kw__Accum: case tok::kw__Float16: case tok::kw___float128: case tok::kw_bool: Index: lib/Sema/DeclSpec.cpp =================================================================== --- lib/Sema/DeclSpec.cpp +++ lib/Sema/DeclSpec.cpp @@ -336,6 +336,7 @@ case TST_decimal32: case TST_decimal64: case TST_double: + case TST_Accum: case TST_Float16: case TST_float128: case TST_enum: @@ -506,6 +507,7 @@ 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"; @@ -1096,12 +1098,13 @@ } } - // 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) { + TypeSpecType != TST_char && TypeSpecType != TST_wchar && + TypeSpecType != TST_accum) { S.Diag(TSSLoc, diag::err_invalid_sign_spec) << getSpecifierName((TST)TypeSpecType, Policy); // signed double -> double. @@ -1116,7 +1119,8 @@ 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; @@ -1126,7 +1130,8 @@ 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; Index: lib/Sema/SemaTemplateVariadic.cpp =================================================================== --- lib/Sema/SemaTemplateVariadic.cpp +++ lib/Sema/SemaTemplateVariadic.cpp @@ -829,6 +829,7 @@ case TST_half: case TST_float: case TST_double: + case TST_Accum: case TST_Float16: case TST_float128: case TST_bool: Index: lib/Sema/SemaType.cpp =================================================================== --- lib/Sema/SemaType.cpp +++ lib/Sema/SemaType.cpp @@ -1386,6 +1386,30 @@ } 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"); + break; + } + } 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: + // TODO: Replace with diag + llvm_unreachable("Unable to specify long long as _Accum width"); + break; + } + } + break; + } case DeclSpec::TST_int128: if (!S.Context.getTargetInfo().hasInt128Type()) S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported) Index: lib/Serialization/ASTCommon.cpp =================================================================== --- lib/Serialization/ASTCommon.cpp +++ lib/Serialization/ASTCommon.cpp @@ -91,6 +91,24 @@ case BuiltinType::LongDouble: ID = PREDEF_TYPE_LONGDOUBLE_ID; break; + case BuiltinType::ShortAccum: + ID = PREDEF_TYPE_SHORT_ACCUM_ID; + break; + case BuiltinType::Accum: + ID = PREDEF_TYPE_ACCUM_ID; + break; + case BuiltinType::LongAccum: + ID = PREDEF_TYPE_LONG_ACCUM_ID; + break; + case BuiltinType::UShortAccum: + ID = PREDEF_TYPE_USHORT_ACCUM_ID; + break; + case BuiltinType::UAccum: + ID = PREDEF_TYPE_UACCUM_ID; + break; + case BuiltinType::ULongAccum: + ID = PREDEF_TYPE_ULONG_ACCUM_ID; + break; case BuiltinType::Float16: ID = PREDEF_TYPE_FLOAT16_ID; break; Index: lib/Serialization/ASTReader.cpp =================================================================== --- lib/Serialization/ASTReader.cpp +++ lib/Serialization/ASTReader.cpp @@ -6816,6 +6816,24 @@ case PREDEF_TYPE_LONGDOUBLE_ID: T = Context.LongDoubleTy; break; + case PREDEF_TYPE_SHORT_ACCUM_ID: + T = Context.ShortAccumTy; + break; + case PREDEF_TYPE_ACCUM_ID: + T = Context.AccumTy; + break; + case PREDEF_TYPE_LONG_ACCUM_ID: + T = Context.LongAccumTy; + break; + case PREDEF_TYPE_USHORT_ACCUM_ID: + T = Context.UnsignedShortAccumTy; + break; + case PREDEF_TYPE_UACCUM_ID: + T = Context.UnsignedAccumTy; + break; + case PREDEF_TYPE_ULONG_ACCUM_ID: + T = Context.UnsignedLongAccumTy; + break; case PREDEF_TYPE_FLOAT16_ID: T = Context.Float16Ty; break; Index: test/Frontend/accum.cpp =================================================================== --- /dev/null +++ test/Frontend/accum.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace + +/* Various contexts where type _Accum can appear. */ + +// Primary fixed point types +signed short _Accum s_short_accum; +signed _Accum s_accum; +signed long _Accum s_long_accum; +unsigned short _Accum u_short_accum; +unsigned _Accum u_accum; +unsigned long _Accum u_long_accum; + +// Aliased fixed point types +short _Accum short_accum; +_Accum accum; +long _Accum long_accum; + +//CHECK: |-VarDecl {{.*}} s_short_accum 'short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} s_accum '_Accum' +//CHECK-NEXT: |-VarDecl {{.*}} s_long_accum 'long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} u_short_accum 'unsigned short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} u_accum 'unsigned _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} u_long_accum 'unsigned long _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} short_accum 'short _Accum' +//CHECK-NEXT: |-VarDecl {{.*}} accum '_Accum' +//CHECK-NEXT: `-VarDecl {{.*}} long_accum 'long _Accum' Index: test/Frontend/accum_errors.cpp =================================================================== --- /dev/null +++ test/Frontend/accum_errors.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s + +long long _Accum longlong_accum; // expected-error{{'long long _Accum' is invalid}} +unsigned long long _Accum u_longlong_accum; // expected-error{{'long long _Accum' is invalid}} Index: tools/libclang/CXType.cpp =================================================================== --- tools/libclang/CXType.cpp +++ tools/libclang/CXType.cpp @@ -53,6 +53,12 @@ BTCASE(Float); BTCASE(Double); BTCASE(LongDouble); + BTCASE(ShortAccum); + BTCASE(Accum); + BTCASE(LongAccum); + BTCASE(UShortAccum); + BTCASE(UAccum); + BTCASE(ULongAccum); BTCASE(Float16); BTCASE(Float128); BTCASE(NullPtr); @@ -542,6 +548,12 @@ TKIND(Float); TKIND(Double); TKIND(LongDouble); + TKIND(ShortAccum); + TKIND(Accum); + TKIND(LongAccum); + TKIND(UShortAccum); + TKIND(UAccum); + TKIND(ULongAccum); TKIND(Float16); TKIND(Float128); TKIND(NullPtr);