summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLeonard Chan <leonardchan@google.com>2018-06-04 16:07:52 +0000
committerLeonard Chan <leonardchan@google.com>2018-06-04 16:07:52 +0000
commite59be5df58ccbd518855bcd3e3216e744b7071e9 (patch)
tree60f0e5c3355011187e8c5336c71ee4bf4cfb6717
parent9f72894e31a3b8c5042f221ace91727a81391d80 (diff)
This diff includes changes for supporting the following types.
// 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; This diff only allows for declaration of the 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. The saturated versions of these types and the equivalent _Fract types will also be added in future patches. The tests included are for asserting that we can declare these types. Fixed the test that was failing by not checking for dso_local on some targets. Differential Revision: https://reviews.llvm.org/D46084 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@333923 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--include/clang-c/Index.h8
-rw-r--r--include/clang/AST/ASTContext.h3
-rw-r--r--include/clang/AST/BuiltinTypes.def20
-rw-r--r--include/clang/Basic/DiagnosticCommonKinds.td2
-rw-r--r--include/clang/Basic/LangOptions.def2
-rw-r--r--include/clang/Basic/Specifiers.h1
-rw-r--r--include/clang/Basic/TargetInfo.h18
-rw-r--r--include/clang/Basic/TokenKinds.def3
-rw-r--r--include/clang/Driver/Options.td5
-rw-r--r--include/clang/Sema/DeclSpec.h1
-rw-r--r--include/clang/Serialization/ASTBitCodes.h18
-rw-r--r--lib/AST/ASTContext.cpp29
-rw-r--r--lib/AST/ExprConstant.cpp5
-rw-r--r--lib/AST/ItaniumMangle.cpp7
-rw-r--r--lib/AST/MicrosoftMangle.cpp6
-rw-r--r--lib/AST/NSAPI.cpp6
-rw-r--r--lib/AST/Type.cpp12
-rw-r--r--lib/AST/TypeLoc.cpp6
-rw-r--r--lib/Analysis/PrintfFormatString.cpp6
-rw-r--r--lib/Basic/TargetInfo.cpp3
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp10
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp6
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp6
-rw-r--r--lib/Driver/ToolChains/Clang.cpp5
-rw-r--r--lib/Frontend/CompilerInvocation.cpp5
-rw-r--r--lib/Index/USRGeneration.cpp6
-rw-r--r--lib/Parse/ParseDecl.cpp13
-rw-r--r--lib/Sema/DeclSpec.cpp15
-rw-r--r--lib/Sema/SemaTemplateVariadic.cpp1
-rw-r--r--lib/Sema/SemaType.cpp33
-rw-r--r--lib/Serialization/ASTCommon.cpp18
-rw-r--r--lib/Serialization/ASTReader.cpp18
-rw-r--r--test/Frontend/fixed_point.c57
-rw-r--r--test/Frontend/fixed_point_bit_widths.c46
-rw-r--r--test/Frontend/fixed_point_errors.c27
-rw-r--r--test/Frontend/fixed_point_errors.cpp5
-rw-r--r--test/Frontend/fixed_point_not_enabled.c15
-rw-r--r--tools/libclang/CXType.cpp12
38 files changed, 453 insertions, 6 deletions
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index ff14d6e729..0973783a45 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -3182,8 +3182,14 @@ enum CXTypeKind {
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,
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index d70e455a5a..64160ebbac 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -1007,6 +1007,9 @@ public:
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;
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
index 4d4ed79220..b2fa49828a 100644
--- a/include/clang/AST/BuiltinTypes.def
+++ b/include/clang/AST/BuiltinTypes.def
@@ -122,6 +122,26 @@ SIGNED_TYPE(LongLong, LongLongTy)
// '__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.
diff --git a/include/clang/Basic/DiagnosticCommonKinds.td b/include/clang/Basic/DiagnosticCommonKinds.td
index 56c735a4b6..93f262361c 100644
--- a/include/clang/Basic/DiagnosticCommonKinds.td
+++ b/include/clang/Basic/DiagnosticCommonKinds.td
@@ -168,6 +168,8 @@ def ext_clang_enable_if : Extension<"'enable_if' is a clang extension">,
InGroup<GccCompat>;
def ext_clang_diagnose_if : Extension<"'diagnose_if' is a clang extension">,
InGroup<GccCompat>;
+def err_fixed_point_not_enabled : Error<"compile with "
+ "'-ffixed-point' to enable fixed point types">;
// SEH
def err_seh_expected_handler : Error<
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index 8605286f28..6bd8958e36 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -302,6 +302,8 @@ ENUM_LANGOPT(ClangABICompat, ClangABI, 4, ClangABI::Latest,
COMPATIBLE_VALUE_LANGOPT(FunctionAlignment, 5, 0, "Default alignment for functions")
+LANGOPT(FixedPoint, 1, 0, "fixed point types")
+
#undef LANGOPT
#undef COMPATIBLE_LANGOPT
#undef BENIGN_LANGOPT
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index ee57fc47fd..231b92ab79 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -54,6 +54,7 @@ namespace clang {
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,
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index b8e45e64d5..08e33f58f5 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -74,6 +74,9 @@ protected:
unsigned char LargeArrayMinWidth, LargeArrayAlign;
unsigned char LongWidth, LongAlign;
unsigned char LongLongWidth, LongLongAlign;
+ unsigned char ShortAccumWidth, ShortAccumAlign;
+ unsigned char AccumWidth, AccumAlign;
+ unsigned char LongAccumWidth, LongAccumAlign;
unsigned char SuitableAlign;
unsigned char DefaultAlignForAttributeAligned;
unsigned char MinGlobalAlign;
@@ -358,6 +361,21 @@ public:
unsigned getLongLongWidth() const { return LongLongWidth; }
unsigned getLongLongAlign() const { return LongLongAlign; }
+ /// getShortAccumWidth/Align - Return the size of 'signed short _Accum' and
+ /// 'unsigned short _Accum' for this target, in bits.
+ unsigned getShortAccumWidth() const { return ShortAccumWidth; }
+ unsigned getShortAccumAlign() const { return ShortAccumAlign; }
+
+ /// getAccumWidth/Align - Return the size of 'signed _Accum' and
+ /// 'unsigned _Accum' for this target, in bits.
+ unsigned getAccumWidth() const { return AccumWidth; }
+ unsigned getAccumAlign() const { return AccumAlign; }
+
+ /// getLongAccumWidth/Align - Return the size of 'signed long _Accum' and
+ /// 'unsigned long _Accum' for this target, in bits.
+ unsigned getLongAccumWidth() const { return LongAccumWidth; }
+ unsigned getLongAccumAlign() const { return LongAccumAlign; }
+
/// Determine whether the __int128 type is supported on this target.
virtual bool hasInt128Type() const {
return (getPointerWidth(0) >= 64) || getTargetOpts().ForceEnableInt128;
diff --git a/include/clang/Basic/TokenKinds.def b/include/clang/Basic/TokenKinds.def
index cc717f6128..867b8abfea 100644
--- a/include/clang/Basic/TokenKinds.def
+++ b/include/clang/Basic/TokenKinds.def
@@ -389,6 +389,9 @@ KEYWORD(char8_t , CHAR8SUPPORT)
// C11 Extension
KEYWORD(_Float16 , KEYALL)
+// ISO/IEC JTC1 SC22 WG14 N1169 Extension
+KEYWORD(_Accum , KEYNOCXX)
+
// GNU Extensions (in impl-reserved namespace)
KEYWORD(_Decimal32 , KEYALL)
KEYWORD(_Decimal64 , KEYALL)
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 94a5310fba..093706f279 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -887,6 +887,11 @@ def fno_force_enable_int128 : Flag<["-"], "fno-force-enable-int128">,
Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Disable support for int128_t type">;
+def ffixed_point : Flag<["-"], "ffixed-point">, Group<f_Group>,
+ Flags<[CC1Option]>, HelpText<"Enable fixed point types">;
+def fno_fixed_point : Flag<["-"], "fno-fixed-point">, Group<f_Group>,
+ HelpText<"Disable fixed point types">;
+
// Begin sanitizer flags. These should all be core options exposed in all driver
// modes.
let Flags = [CC1Option, CoreOption] in {
diff --git a/include/clang/Sema/DeclSpec.h b/include/clang/Sema/DeclSpec.h
index 4ae317bafd..50881426fd 100644
--- a/include/clang/Sema/DeclSpec.h
+++ b/include/clang/Sema/DeclSpec.h
@@ -282,6 +282,7 @@ public:
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;
diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h
index 4ddffe1192..24bdb644de 100644
--- a/include/clang/Serialization/ASTBitCodes.h
+++ b/include/clang/Serialization/ASTBitCodes.h
@@ -939,6 +939,24 @@ namespace serialization {
/// The C++ 'char8_t' type.
PREDEF_TYPE_CHAR8_ID = 45,
+ /// \brief The 'short _Accum' type
+ PREDEF_TYPE_SHORT_ACCUM_ID = 46,
+
+ /// \brief The '_Accum' type
+ PREDEF_TYPE_ACCUM_ID = 47,
+
+ /// \brief The 'long _Accum' type
+ PREDEF_TYPE_LONG_ACCUM_ID = 48,
+
+ /// \brief The 'unsigned short _Accum' type
+ PREDEF_TYPE_USHORT_ACCUM_ID = 49,
+
+ /// \brief The 'unsigned _Accum' type
+ PREDEF_TYPE_UACCUM_ID = 50,
+
+ /// \brief The 'unsigned long _Accum' type
+ PREDEF_TYPE_ULONG_ACCUM_ID = 51,
+
/// OpenCL image types with auto numeration
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
PREDEF_TYPE_##Id##_ID,
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index 2eec05c439..4956710b4f 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -1134,6 +1134,14 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
// 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);
@@ -1785,6 +1793,21 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = 128;
Align = 128; // int128_t is 128-bit aligned on all targets.
break;
+ case BuiltinType::ShortAccum:
+ case BuiltinType::UShortAccum:
+ Width = Target->getShortAccumWidth();
+ Align = Target->getShortAccumAlign();
+ break;
+ case BuiltinType::Accum:
+ case BuiltinType::UAccum:
+ Width = Target->getAccumWidth();
+ Align = Target->getAccumAlign();
+ break;
+ case BuiltinType::LongAccum:
+ case BuiltinType::ULongAccum:
+ Width = Target->getLongAccumWidth();
+ Align = Target->getLongAccumAlign();
+ break;
case BuiltinType::Float16:
case BuiltinType::Half:
Width = Target->getHalfWidth();
@@ -6222,6 +6245,12 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::Half:
+ case BuiltinType::ShortAccum:
+ case BuiltinType::Accum:
+ case BuiltinType::LongAccum:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::UAccum:
+ case BuiltinType::ULongAccum:
// FIXME: potentially need @encodes for these!
return ' ';
diff --git a/lib/AST/ExprConstant.cpp b/lib/AST/ExprConstant.cpp
index 7140537915..590ebba997 100644
--- a/lib/AST/ExprConstant.cpp
+++ b/lib/AST/ExprConstant.cpp
@@ -7355,6 +7355,11 @@ EvaluateBuiltinClassifyType(QualType T, const LangOptions &LangOpts) {
case BuiltinType::UInt128:
return GCCTypeClass::Integer;
+ case BuiltinType::UShortAccum:
+ case BuiltinType::UAccum:
+ case BuiltinType::ULongAccum:
+ return GCCTypeClass::None;
+
case BuiltinType::NullPtr:
case BuiltinType::ObjCId:
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index 1a656b5719..80b91dca7f 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -2552,6 +2552,13 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
case BuiltinType::Float16:
Out << "DF16_";
break;
+ case BuiltinType::ShortAccum:
+ case BuiltinType::Accum:
+ case BuiltinType::LongAccum:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::UAccum:
+ case BuiltinType::ULongAccum:
+ llvm_unreachable("Fixed point types are disabled for c++");
case BuiltinType::Half:
Out << "Dh";
break;
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index f7b80d5b27..e947479196 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -1926,6 +1926,12 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
mangleArtificalTagType(TTK_Struct, "_Half", {"__clang"});
break;
+ case BuiltinType::ShortAccum:
+ case BuiltinType::Accum:
+ case BuiltinType::LongAccum:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::UAccum:
+ case BuiltinType::ULongAccum:
case BuiltinType::Char8:
case BuiltinType::Float128: {
DiagnosticsEngine &Diags = Context.getDiags();
diff --git a/lib/AST/NSAPI.cpp b/lib/AST/NSAPI.cpp
index 030f2a0c9c..d61638e54a 100644
--- a/lib/AST/NSAPI.cpp
+++ b/lib/AST/NSAPI.cpp
@@ -441,6 +441,12 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
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:
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index 065a77aa50..6615ea88b6 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -2656,6 +2656,18 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
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:
diff --git a/lib/AST/TypeLoc.cpp b/lib/AST/TypeLoc.cpp
index dc325427b9..1aa7b5a3cd 100644
--- a/lib/AST/TypeLoc.cpp
+++ b/lib/AST/TypeLoc.cpp
@@ -344,6 +344,12 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
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.
diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp
index 2043970ccd..5884d33136 100644
--- a/lib/Analysis/PrintfFormatString.cpp
+++ b/lib/Analysis/PrintfFormatString.cpp
@@ -655,6 +655,12 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
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;
diff --git a/lib/Basic/TargetInfo.cpp b/lib/Basic/TargetInfo.cpp
index bacd85bc55..bf36effbe3 100644
--- a/lib/Basic/TargetInfo.cpp
+++ b/lib/Basic/TargetInfo.cpp
@@ -40,6 +40,9 @@ TargetInfo::TargetInfo(const llvm::Triple &T) : TargetOpts(), Triple(T) {
IntWidth = IntAlign = 32;
LongWidth = LongAlign = 32;
LongLongWidth = LongLongAlign = 64;
+ ShortAccumWidth = ShortAccumAlign = 16;
+ AccumWidth = AccumAlign = 32;
+ LongAccumWidth = LongAccumAlign = 64;
SuitableAlign = 64;
DefaultAlignForAttributeAligned = 128;
MinGlobalAlign = 0;
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 9e99a646b0..db6a82b415 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -702,6 +702,16 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
// floating point types of the same size.
Encoding = llvm::dwarf::DW_ATE_float;
break;
+ case BuiltinType::ShortAccum:
+ case BuiltinType::Accum:
+ case BuiltinType::LongAccum:
+ Encoding = llvm::dwarf::DW_ATE_signed_fixed;
+ break;
+ case BuiltinType::UShortAccum:
+ case BuiltinType::UAccum:
+ case BuiltinType::ULongAccum:
+ Encoding = llvm::dwarf::DW_ATE_unsigned_fixed;
+ break;
}
switch (BT->getKind()) {
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index ce1fdf9b12..c1ff9d2846 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -440,6 +440,12 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
case BuiltinType::Char8:
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<unsigned>(Context.getTypeSize(T)));
break;
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index 3e2c461d6a..d84a10c6ba 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -2724,6 +2724,12 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
case BuiltinType::OCLClkEvent:
case BuiltinType::OCLQueue:
case BuiltinType::OCLReserveID:
+ case BuiltinType::ShortAccum:
+ case BuiltinType::Accum:
+ case BuiltinType::LongAccum:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::UAccum:
+ case BuiltinType::ULongAccum:
return false;
case BuiltinType::Dependent:
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index 2347cfebf0..afcf45d9f8 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -3756,6 +3756,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_pedantic_errors);
Args.AddLastArg(CmdArgs, options::OPT_w);
+ // Fixed point flags
+ if (Args.hasFlag(options::OPT_ffixed_point, options::OPT_fno_fixed_point,
+ /*Default=*/false))
+ Args.AddLastArg(CmdArgs, options::OPT_ffixed_point);
+
// Handle -{std, ansi, trigraphs} -- take the last of -{std, ansi}
// (-ansi is equivalent to -std=c89 or -std=c++98).
//
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index b5396dd758..46f8c9f235 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -2333,6 +2333,11 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.ObjCExceptions = Args.hasArg(OPT_fobjc_exceptions);
Opts.CXXExceptions = Args.hasArg(OPT_fcxx_exceptions);
+ // -ffixed-point
+ Opts.FixedPoint =
+ Args.hasFlag(OPT_ffixed_point, OPT_fno_fixed_point, /*Default=*/false) &&
+ !Opts.CPlusPlus;
+
// Handle exception personalities
Arg *A = Args.getLastArg(options::OPT_fsjlj_exceptions,
options::OPT_fseh_exceptions,
diff --git a/lib/Index/USRGeneration.cpp b/lib/Index/USRGeneration.cpp
index ba536c748c..9c9600188f 100644
--- a/lib/Index/USRGeneration.cpp
+++ b/lib/Index/USRGeneration.cpp
@@ -709,6 +709,12 @@ void USRGenerator::VisitType(QualType T) {
case BuiltinType::OCLQueue:
case BuiltinType::OCLReserveID:
case BuiltinType::OCLSampler:
+ case BuiltinType::ShortAccum:
+ case BuiltinType::Accum:
+ case BuiltinType::LongAccum:
+ case BuiltinType::UShortAccum:
+ case BuiltinType::UAccum:
+ case BuiltinType::ULongAccum:
IgnoreResults = true;
return;
case BuiltinType::ObjCId:
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 456214f066..2b9c4afaaf 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -3580,6 +3580,16 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float16, Loc, PrevSpec,
DiagID, Policy);
break;
+ case tok::kw__Accum:
+ if (!getLangOpts().FixedPoint) {
+ DiagID = diag::err_fixed_point_not_enabled;
+ PrevSpec = ""; // Not used by diagnostic
+ isInvalid = true;
+ } else {
+ 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);
@@ -4606,6 +4616,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
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:
@@ -4683,6 +4694,7 @@ bool Parser::isTypeSpecifierQualifier() {
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:
@@ -4841,6 +4853,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
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:
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index dd2476ec37..aa5f197b54 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/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/lib/Sema/SemaTemplateVariadic.cpp b/lib/Sema/SemaTemplateVariadic.cpp
index c58e648bb3..dc67c8ef19 100644
--- a/lib/Sema/SemaTemplateVariadic.cpp
+++ b/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/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index 6839dd7de2..ac85e016ba 100644
--- a/lib/Sema/SemaType.cpp
+++ b/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)
diff --git a/lib/Serialization/ASTCommon.cpp b/lib/Serialization/ASTCommon.cpp
index 54cea92042..f5584cc04d 100644
--- a/lib/Serialization/ASTCommon.cpp
+++ b/lib/Serialization/ASTCommon.cpp
@@ -91,6 +91,24 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
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;
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 391e350445..4dd7972027 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -6819,6 +6819,24 @@ QualType ASTReader::GetType(TypeID ID) {
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;
diff --git a/test/Frontend/fixed_point.c b/test/Frontend/fixed_point.c
new file mode 100644
index 0000000000..d64bd55aa0
--- /dev/null
+++ b/test/Frontend/fixed_point.c
@@ -0,0 +1,57 @@
+// RUN: %clang_cc1 -x c -ffixed-point -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'
+
+#define MIX_TYPE_SPEC(SPEC, SIGN, SIZE, ID) \
+ SPEC SIGN SIZE _Accum ID; \
+ SIGN SPEC SIZE _Accum ID ## 2; \
+ SIGN SIZE SPEC _Accum ID ## 3; \
+ SIGN SIZE _Accum SPEC ID ## 4;
+
+/* Mixing fixed point types with other type specifiers */
+
+#define MIX_VOLATILE(SIGN, SIZE, ID) MIX_TYPE_SPEC(volatile, SIGN, SIZE, ID)
+#define MIX_ATOMIC(SIGN, SIZE, ID) MIX_TYPE_SPEC(_Atomic, SIGN, SIZE, ID)
+#define MIX_CONST(SIGN, SIZE, ID) MIX_TYPE_SPEC(const, SIGN, SIZE, ID)
+
+MIX_VOLATILE(signed, short, vol_s_short_accum)
+MIX_ATOMIC(signed, short, atm_s_short_accum)
+MIX_CONST(signed, short, const_s_short_accum)
+
+// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum 'volatile short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum2 'volatile short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum3 'volatile short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} vol_s_short_accum4 'volatile short _Accum'
+
+// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum '_Atomic(short _Accum)'
+// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum2 '_Atomic(short _Accum)'
+// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum3 '_Atomic(short _Accum)'
+// CHECK-NEXT: |-VarDecl {{.*}} atm_s_short_accum4 '_Atomic(short _Accum)'
+
+// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum 'const short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum2 'const short _Accum'
+// CHECK-NEXT: |-VarDecl {{.*}} const_s_short_accum3 'const short _Accum'
+// CHECK-NEXT: `-VarDecl {{.*}} const_s_short_accum4 'const short _Accum'
diff --git a/test/Frontend/fixed_point_bit_widths.c b/test/Frontend/fixed_point_bit_widths.c
new file mode 100644
index 0000000000..6b4eea90e6
--- /dev/null
+++ b/test/Frontend/fixed_point_bit_widths.c
@@ -0,0 +1,46 @@
+// RUN: %clang -x c -ffixed-point -S -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang -x c -ffixed-point -S -emit-llvm -o - --target=x86_64-scei-ps4-ubuntu-fast %s | FileCheck %s
+// RUN: %clang -x c -ffixed-point -S -emit-llvm -o - --target=ppc64 %s | FileCheck %s
+// RUN: %clang -x c -ffixed-point -S -emit-llvm -o - --target=x86_64-scei-ps4-windows10pro-fast %s | FileCheck %s
+
+int size_SsA = sizeof(signed short _Accum);
+int size_SA = sizeof(signed _Accum);
+int size_SlA = sizeof(signed long _Accum);
+int align_SsA = __alignof(signed short _Accum);
+int align_SA = __alignof(signed _Accum);
+int align_SlA = __alignof(signed long _Accum);
+
+int size_UsA = sizeof(unsigned short _Accum);
+int size_UA = sizeof(unsigned _Accum);
+int size_UlA = sizeof(unsigned long _Accum);
+int align_UsA = __alignof(unsigned short _Accum);
+int align_UA = __alignof(unsigned _Accum);
+int align_UlA = __alignof(unsigned long _Accum);
+
+int size_sA = sizeof(short _Accum);
+int size_A = sizeof(_Accum);
+int size_lA = sizeof(long _Accum);
+int align_sA = __alignof(short _Accum);
+int align_A = __alignof(_Accum);
+int align_lA = __alignof(long _Accum);
+
+// CHECK: @size_SsA = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @size_SA = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @size_SlA = {{.*}}global i{{[0-9]+}} 8
+// CHECK-NEXT: @align_SsA = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @align_SA = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @align_SlA = {{.*}}global i{{[0-9]+}} 8
+
+// CHECK-NEXT: @size_UsA = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @size_UA = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @size_UlA = {{.*}}global i{{[0-9]+}} 8
+// CHECK-NEXT: @align_UsA = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @align_UA = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @align_UlA = {{.*}}global i{{[0-9]+}} 8
+
+// CHECK-NEXT: @size_sA = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @size_A = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @size_lA = {{.*}}global i{{[0-9]+}} 8
+// CHECK-NEXT: @align_sA = {{.*}}global i{{[0-9]+}} 2
+// CHECK-NEXT: @align_A = {{.*}}global i{{[0-9]+}} 4
+// CHECK-NEXT: @align_lA = {{.*}}global i{{[0-9]+}} 8
diff --git a/test/Frontend/fixed_point_errors.c b/test/Frontend/fixed_point_errors.c
new file mode 100644
index 0000000000..0158dc68c4
--- /dev/null
+++ b/test/Frontend/fixed_point_errors.c
@@ -0,0 +1,27 @@
+// RUN: %clang_cc1 -verify -ffixed-point %s
+
+/* We do not yet support long long. No recommended bit widths are given for this
+ * size. */
+
+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}}
+
+/* Although _Complex types work with floating point numbers, the extension
+ * provides no info for complex fixed point types. */
+
+_Complex signed short _Accum cmplx_s_short_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex signed _Accum cmplx_s_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex signed long _Accum cmplx_s_long_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex unsigned short _Accum cmplx_u_short_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex unsigned _Accum cmplx_u_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex unsigned long _Accum cmplx_u_long_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex short _Accum cmplx_s_short_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex _Accum cmplx_s_accum; // expected-error{{'_Complex _Accum' is invalid}}
+_Complex long _Accum cmplx_s_long_accum; // expected-error{{'_Complex _Accum' is invalid}}
+
+/* Bad combinations */
+float _Accum f_accum; // expected-error{{cannot combine with previous 'float' declaration specifier}}
+double _Accum d_accum; // expected-error{{cannot combine with previous 'double' declaration specifier}}
+_Bool _Accum b_accum; // expected-error{{cannot combine with previous '_Bool' declaration specifier}}
+char _Accum c_accum; // expected-error{{cannot combine with previous 'char' declaration specifier}}
+int _Accum i_accum; // expected-error{{cannot combine with previous 'int' declaration specifier}}
diff --git a/test/Frontend/fixed_point_errors.cpp b/test/Frontend/fixed_point_errors.cpp
new file mode 100644
index 0000000000..aa95bb10c5
--- /dev/null
+++ b/test/Frontend/fixed_point_errors.cpp
@@ -0,0 +1,5 @@
+// RUN: %clang_cc1 -x c++ -ffixed-point %s -verify
+
+// Name namgling is not provided for fixed point types in c++
+
+_Accum accum; // expected-error{{unknown type name '_Accum'}}
diff --git a/test/Frontend/fixed_point_not_enabled.c b/test/Frontend/fixed_point_not_enabled.c
new file mode 100644
index 0000000000..e5c82f54b6
--- /dev/null
+++ b/test/Frontend/fixed_point_not_enabled.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -x c -verify %s
+
+// Primary fixed point types
+signed short _Accum s_short_accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+signed _Accum s_accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+signed long _Accum s_long_accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned short _Accum u_short_accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned _Accum u_accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+unsigned long _Accum u_long_accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+
+// Aliased fixed point types
+short _Accum short_accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+_Accum accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
+ // expected-warning@-1{{type specifier missing, defaults to 'int'}}
+long _Accum long_accum; // expected-error{{compile with '-ffixed-point' to enable fixed point types}}
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 0b678b0a2a..7c0f307944 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -53,6 +53,12 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
BTCASE(Float);
BTCASE(Double);
BTCASE(LongDouble);
+ BTCASE(ShortAccum);
+ BTCASE(Accum);
+ BTCASE(LongAccum);
+ BTCASE(UShortAccum);
+ BTCASE(UAccum);
+ BTCASE(ULongAccum);
BTCASE(Float16);
BTCASE(Float128);
BTCASE(NullPtr);
@@ -546,6 +552,12 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
TKIND(Float);
TKIND(Double);
TKIND(LongDouble);
+ TKIND(ShortAccum);
+ TKIND(Accum);
+ TKIND(LongAccum);
+ TKIND(UShortAccum);
+ TKIND(UAccum);
+ TKIND(ULongAccum);
TKIND(Float16);
TKIND(Float128);
TKIND(NullPtr);