forked from OSchip/llvm-project
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 llvm-svn: 333923
This commit is contained in:
parent
39e5a5695f
commit
f921d85422
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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<
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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 ' ';
|
||||
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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.
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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()) {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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).
|
||||
//
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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'
|
|
@ -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
|
|
@ -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}}
|
|
@ -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'}}
|
|
@ -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}}
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue