Recommit "Add _Float16 as a C/C++ source language type"

This is a recommit of r312781; in some build configurations
variable names are omitted, so changed the new regression
test accordingly.

llvm-svn: 312794
This commit is contained in:
Sjoerd Meijer 2017-09-08 15:15:00 +00:00
parent bd4a361739
commit cc623ad071
38 changed files with 578 additions and 9 deletions

View File

@ -3115,8 +3115,9 @@ enum CXTypeKind {
CXType_ObjCSel = 29,
CXType_Float128 = 30,
CXType_Half = 31,
CXType_Float16 = 32,
CXType_FirstBuiltin = CXType_Void,
CXType_LastBuiltin = CXType_Half,
CXType_LastBuiltin = CXType_Float16,
CXType_Complex = 100,
CXType_Pointer = 101,

View File

@ -973,6 +973,7 @@ public:
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
CanQualType Float128ComplexTy;
CanQualType VoidPtrTy, NullPtrTy;

View File

@ -133,6 +133,9 @@ FLOATING_TYPE(Double, DoubleTy)
// 'long double'
FLOATING_TYPE(LongDouble, LongDoubleTy)
// '_Float16'
FLOATING_TYPE(Float16, HalfTy)
// '__float128'
FLOATING_TYPE(Float128, Float128Ty)

View File

@ -52,6 +52,7 @@ namespace clang {
TST_int,
TST_int128,
TST_half, // OpenCL half, ARM NEON __fp16
TST_Float16, // C11 extension ISO/IEC TS 18661-3
TST_float,
TST_double,
TST_float128,

View File

@ -379,6 +379,9 @@ KEYWORD(co_yield , KEYCOROUTINES)
MODULES_KEYWORD(module)
MODULES_KEYWORD(import)
// C11 Extension
KEYWORD(_Float16 , KEYALL)
// GNU Extensions (in impl-reserved namespace)
KEYWORD(_Decimal32 , KEYALL)
KEYWORD(_Decimal64 , KEYALL)

View File

@ -65,6 +65,7 @@ public:
bool isHalf : 1; // 1.0h
bool isFloat : 1; // 1.0f
bool isImaginary : 1; // 1.0i
bool isFloat16 : 1; // 1.0f16
bool isFloat128 : 1; // 1.0q
uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.

View File

@ -280,6 +280,7 @@ public:
static const TST TST_half = clang::TST_half;
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_float128 = clang::TST_float128;
static const TST TST_bool = clang::TST_bool;
static const TST TST_decimal32 = clang::TST_decimal32;

View File

@ -826,6 +826,8 @@ namespace clang {
PREDEF_TYPE_OMP_ARRAY_SECTION = 42,
/// \brief The '__float128' type
PREDEF_TYPE_FLOAT128_ID = 43,
/// \brief The '_Float16' type
PREDEF_TYPE_FLOAT16_ID = 44,
/// \brief OpenCL image types with auto numeration
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
PREDEF_TYPE_##Id##_ID,

View File

@ -57,7 +57,7 @@ unsigned ASTContext::NumImplicitDestructors;
unsigned ASTContext::NumImplicitDestructorsDeclared;
enum FloatingRank {
HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank
Float16Rank, HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank
};
RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
@ -1093,6 +1093,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
// GNU extension, __float128 for IEEE quadruple precision
InitBuiltinType(Float128Ty, BuiltinType::Float128);
// C11 extension ISO/IEC TS 18661-3
InitBuiltinType(Float16Ty, BuiltinType::Float16);
// GNU extension, 128-bit integers.
InitBuiltinType(Int128Ty, BuiltinType::Int128);
InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128);
@ -1420,7 +1423,9 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
assert(BT && "Not a floating point type!");
switch (BT->getKind()) {
default: llvm_unreachable("Not a floating point type!");
case BuiltinType::Half: return Target->getHalfFormat();
case BuiltinType::Float16:
case BuiltinType::Half:
return Target->getHalfFormat();
case BuiltinType::Float: return Target->getFloatFormat();
case BuiltinType::Double: return Target->getDoubleFormat();
case BuiltinType::LongDouble: return Target->getLongDoubleFormat();
@ -1748,6 +1753,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
Width = 128;
Align = 128; // int128_t is 128-bit aligned on all targets.
break;
case BuiltinType::Float16:
case BuiltinType::Half:
Width = Target->getHalfWidth();
Align = Target->getHalfAlign();
@ -5047,6 +5053,7 @@ static FloatingRank getFloatingRank(QualType T) {
assert(T->getAs<BuiltinType>() && "getFloatingRank(): not a floating type");
switch (T->getAs<BuiltinType>()->getKind()) {
default: llvm_unreachable("getFloatingRank(): not a floating type");
case BuiltinType::Float16: return Float16Rank;
case BuiltinType::Half: return HalfRank;
case BuiltinType::Float: return FloatRank;
case BuiltinType::Double: return DoubleRank;
@ -5064,6 +5071,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,
FloatingRank EltRank = getFloatingRank(Size);
if (Domain->isComplexType()) {
switch (EltRank) {
case Float16Rank:
case HalfRank: llvm_unreachable("Complex half is not supported");
case FloatRank: return FloatComplexTy;
case DoubleRank: return DoubleComplexTy;
@ -5074,6 +5082,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,
assert(Domain->isRealFloatingType() && "Unknown domain!");
switch (EltRank) {
case Float16Rank: return HalfTy;
case HalfRank: return HalfTy;
case FloatRank: return FloatTy;
case DoubleRank: return DoubleTy;
@ -5931,6 +5940,7 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
case BuiltinType::LongDouble: return 'D';
case BuiltinType::NullPtr: return '*'; // like char*
case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::Half:
// FIXME: potentially need @encodes for these!

View File

@ -2445,6 +2445,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
// UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits)
// UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits)
// ::= Dh # IEEE 754r half-precision floating point (16 bits)
// ::= DF <number> _ # ISO/IEC TS 18661 binary floating point type _FloatN (N bits);
// ::= Di # char32_t
// ::= Ds # char16_t
// ::= Dn # std::nullptr_t (i.e., decltype(nullptr))
@ -2507,6 +2508,9 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
case BuiltinType::Int128:
Out << 'n';
break;
case BuiltinType::Float16:
Out << "DF16_";
break;
case BuiltinType::Half:
Out << "Dh";
break;

View File

@ -1866,6 +1866,7 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
Out << "$$T";
break;
case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::Half: {
DiagnosticsEngine &Diags = Context.getDiags();

View File

@ -441,6 +441,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
case BuiltinType::Int128:
case BuiltinType::LongDouble:
case BuiltinType::UInt128:
case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::NullPtr:
case BuiltinType::ObjCClass:

View File

@ -1500,6 +1500,7 @@ static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
default: llvm_unreachable("Unexpected type for float literal!");
case BuiltinType::Half: break; // FIXME: suffix?
case BuiltinType::Double: break; // no suffix.
case BuiltinType::Float16: OS << "F16"; break;
case BuiltinType::Float: OS << 'F'; break;
case BuiltinType::LongDouble: OS << 'L'; break;
case BuiltinType::Float128: OS << 'Q'; break;

View File

@ -2564,6 +2564,8 @@ StringRef BuiltinType::getName(const PrintingPolicy &Policy) const {
return "double";
case LongDouble:
return "long double";
case Float16:
return "_Float16";
case Float128:
return "__float128";
case WChar_S:

View File

@ -319,6 +319,7 @@ TypeSpecifierType BuiltinTypeLoc::getWrittenTypeSpec() const {
case BuiltinType::Float:
case BuiltinType::Double:
case BuiltinType::LongDouble:
case BuiltinType::Float16:
case BuiltinType::Float128:
llvm_unreachable("Builtin type needs extra local data!");
// Fall through, if the impossible happens.

View File

@ -654,6 +654,7 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
case BuiltinType::UInt128:
case BuiltinType::Int128:
case BuiltinType::Half:
case BuiltinType::Float16:
case BuiltinType::Float128:
// Various types which are non-trivial to correct.
return false;

View File

@ -667,6 +667,7 @@ llvm::DIType *CGDebugInfo::CreateType(const BuiltinType *BT) {
case BuiltinType::Half:
case BuiltinType::Float:
case BuiltinType::LongDouble:
case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::Double:
// FIXME: For targets where long double and __float128 have the same size,

View File

@ -1785,7 +1785,7 @@ Value *ScalarExprEmitter::VisitCastExpr(CastExpr *CE) {
}
case CK_IntToOCLSampler:
return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);
return CGF.CGM.createOpenCLIntToSamplerConversion(E, CGF);
} // end of switch

View File

@ -443,6 +443,12 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
static_cast<unsigned>(Context.getTypeSize(T)));
break;
case BuiltinType::Float16:
ResultType =
getTypeForFormat(getLLVMContext(), Context.getFloatTypeSemantics(T),
/* UseNativeHalf = */ true);
break;
case BuiltinType::Half:
// Half FP can either be storage-only (lowered to i16) or native.
ResultType =

View File

@ -2665,6 +2665,7 @@ static bool TypeInfoIsInStandardLibrary(const BuiltinType *Ty) {
case BuiltinType::Float:
case BuiltinType::Double:
case BuiltinType::LongDouble:
case BuiltinType::Float16:
case BuiltinType::Float128:
case BuiltinType::Char16:
case BuiltinType::Char32:

View File

@ -52,6 +52,7 @@ bool FormatToken::isSimpleTypeSpecifier() const {
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_wchar_t:
case tok::kw_bool:

View File

@ -680,6 +680,7 @@ void USRGenerator::VisitType(QualType T) {
c = 'K'; break;
case BuiltinType::Int128:
c = 'J'; break;
case BuiltinType::Float16:
case BuiltinType::Half:
c = 'h'; break;
case BuiltinType::Float:

View File

@ -544,6 +544,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
isHalf = false;
isFloat = false;
isImaginary = false;
isFloat16 = false;
isFloat128 = false;
MicrosoftInteger = 0;
hadError = false;
@ -588,6 +589,13 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
if (!isFPConstant) break; // Error for integer constant.
if (isHalf || isFloat || isLong || isFloat128)
break; // HF, FF, LF, QF invalid.
if (s + 2 < ThisTokEnd && s[1] == '1' && s[2] == '6') {
s += 2; // success, eat up 2 characters.
isFloat16 = true;
continue;
}
isFloat = true;
continue; // Success.
case 'q': // FP Suffix for "__float128"
@ -681,6 +689,7 @@ NumericLiteralParser::NumericLiteralParser(StringRef TokSpelling,
isUnsigned = false;
isLongLong = false;
isFloat = false;
isFloat16 = false;
isHalf = false;
isImaginary = false;
MicrosoftInteger = 0;

View File

@ -3522,6 +3522,10 @@ void Parser::ParseDeclarationSpecifiers(DeclSpec &DS,
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
DiagID, Policy);
break;
case tok::kw__Float16:
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float16, Loc, PrevSpec,
DiagID, Policy);
break;
case tok::kw___float128:
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec,
DiagID, Policy);
@ -4525,6 +4529,7 @@ bool Parser::isKnownToBeTypeSpecifier(const Token &Tok) const {
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_bool:
case tok::kw__Bool:
@ -4600,6 +4605,7 @@ bool Parser::isTypeSpecifierQualifier() {
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_bool:
case tok::kw__Bool:
@ -4756,6 +4762,7 @@ bool Parser::isDeclarationSpecifier(bool DisambiguatingWithExpression) {
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_bool:
case tok::kw__Bool:

View File

@ -1229,6 +1229,7 @@ ExprResult Parser::ParseCastExpression(bool isUnaryExpression,
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_void:
case tok::kw_typename:

View File

@ -1928,6 +1928,9 @@ void Parser::ParseCXXSimpleTypeSpecifier(DeclSpec &DS) {
case tok::kw_double:
DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID, Policy);
break;
case tok::kw__Float16:
DS.SetTypeSpecType(DeclSpec::TST_float16, Loc, PrevSpec, DiagID, Policy);
break;
case tok::kw___float128:
DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy);
break;

View File

@ -1026,6 +1026,7 @@ Parser::isExpressionOrTypeSpecifierSimple(tok::TokenKind Kind) {
case tok::kw_char:
case tok::kw_const:
case tok::kw_double:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_enum:
case tok::kw_half:
@ -1510,6 +1511,7 @@ Parser::isCXXDeclarationSpecifier(Parser::TPResult BracedCastResult,
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_void:
case tok::annot_decltype:
@ -1600,6 +1602,7 @@ bool Parser::isCXXDeclarationSpecifierAType() {
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_void:
case tok::kw___unknown_anytype:

View File

@ -336,6 +336,7 @@ bool Declarator::isDeclarationOfFunction() const {
case TST_decimal32:
case TST_decimal64:
case TST_double:
case TST_Float16:
case TST_float128:
case TST_enum:
case TST_error:
@ -505,6 +506,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_float16: return "_Float16";
case DeclSpec::TST_float128: return "__float128";
case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool";
case DeclSpec::TST_decimal32: return "_Decimal32";

View File

@ -132,6 +132,7 @@ bool Sema::isSimpleTypeSpecifier(tok::TokenKind Kind) const {
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
case tok::kw__Float16:
case tok::kw___float128:
case tok::kw_wchar_t:
case tok::kw_bool:

View File

@ -714,8 +714,10 @@ ExprResult Sema::DefaultArgumentPromotion(Expr *E) {
return ExprError();
E = Res.get();
// If this is a 'float' or '__fp16' (CVR qualified or typedef) promote to
// double.
// If this is a 'float' or '__fp16' (CVR qualified or typedef)
// promote to double.
// Note that default argument promotion applies only to float (and
// half/fp16); it does not apply to _Float16.
const BuiltinType *BTy = Ty->getAs<BuiltinType>();
if (BTy && (BTy->getKind() == BuiltinType::Half ||
BTy->getKind() == BuiltinType::Float)) {
@ -3321,6 +3323,8 @@ ExprResult Sema::ActOnNumericConstant(const Token &Tok, Scope *UDLScope) {
Ty = Context.FloatTy;
else if (Literal.isLong)
Ty = Context.LongDoubleTy;
else if (Literal.isFloat16)
Ty = Context.Float16Ty;
else if (Literal.isFloat128)
Ty = Context.Float128Ty;
else

View File

@ -819,6 +819,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
case TST_half:
case TST_float:
case TST_double:
case TST_Float16:
case TST_float128:
case TST_bool:
case TST_decimal32:

View File

@ -1392,8 +1392,9 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
else
Result = Context.Int128Ty;
break;
case DeclSpec::TST_half: Result = Context.HalfTy; break;
case DeclSpec::TST_float: Result = Context.FloatTy; break;
case DeclSpec::TST_float16: Result = Context.Float16Ty; break;
case DeclSpec::TST_half: Result = Context.HalfTy; break;
case DeclSpec::TST_float: Result = Context.FloatTy; break;
case DeclSpec::TST_double:
if (DS.getTypeSpecWidth() == DeclSpec::TSW_long)
Result = Context.LongDoubleTy;

View File

@ -91,6 +91,9 @@ serialization::TypeIdxFromBuiltin(const BuiltinType *BT) {
case BuiltinType::LongDouble:
ID = PREDEF_TYPE_LONGDOUBLE_ID;
break;
case BuiltinType::Float16:
ID = PREDEF_TYPE_FLOAT16_ID;
break;
case BuiltinType::Float128:
ID = PREDEF_TYPE_FLOAT128_ID;
break;

View File

@ -6683,6 +6683,9 @@ QualType ASTReader::GetType(TypeID ID) {
case PREDEF_TYPE_LONGDOUBLE_ID:
T = Context.LongDoubleTy;
break;
case PREDEF_TYPE_FLOAT16_ID:
T = Context.Float16Ty;
break;
case PREDEF_TYPE_FLOAT128_ID:
T = Context.Float128Ty;
break;

View File

@ -0,0 +1,156 @@
// RUN: %clang -std=c++11 --target=aarch64-arm--eabi -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-AARCH64
// RUN: %clang -std=c++11 --target=x86_64 -S -emit-llvm %s -o - | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-X86
/* Various contexts where type _Float16 can appear. */
/* Namespace */
namespace {
_Float16 f1n;
// CHECK-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global half 0xH0000, align 2
_Float16 f2n = 33.f16;
// CHECK-AARCH64-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global half 0xH5020, align 2
// CHECK-X86-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global i16 20512, align 2
_Float16 arr1n[10];
// CHECK-AARCH64-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 2
// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x half] zeroinitializer, align 16
_Float16 arr2n[] = { 1.2, 3.0, 3.e4 };
// CHECK-AARCH64-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x half] [half 0xH3CCD, half 0xH4200, half 0xH7753], align 2
// CHECK-X86-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x i16] [i16 15565, i16 16896, i16 30547], align 2
const volatile _Float16 func1n(const _Float16 &arg) {
return arg + f2n + arr1n[4] - arr2n[1];
}
}
/* File */
_Float16 f1f;
// CHECK-AARCH64-DAG: @f1f = global half 0xH0000, align 2
// CHECK-X86-DAG: @f1f = global half 0xH0000, align 2
_Float16 f2f = 32.4;
// CHECK-AARCH64-DAG: @f2f = global half 0xH500D, align 2
// CHECK-X86-DAG: @f2f = global i16 20493, align 2
_Float16 arr1f[10];
// CHECK-AARCH64-DAG: @arr1f = global [10 x half] zeroinitializer, align 2
// CHECK-X86-DAG: @arr1f = global [10 x half] zeroinitializer, align 16
_Float16 arr2f[] = { -1.2, -3.0, -3.e4 };
// CHECK-AARCH64-DAG: @arr2f = global [3 x half] [half 0xHBCCD, half 0xHC200, half 0xHF753], align 2
// CHECK-X86-DAG: @arr2f = global [3 x i16] [i16 -17203, i16 -15872, i16 -2221], align 2
_Float16 func1f(_Float16 arg);
/* Class */
class C1 {
_Float16 f1c;
static const _Float16 f2c;
// CHECK-DAG: @_ZN2C13f2cE = external constant half, align 2
volatile _Float16 f3c;
public:
C1(_Float16 arg) : f1c(arg), f3c(arg) { }
// Check that we mangle _Float16 to DF16_
// CHECK-DAG: define linkonce_odr void @_ZN2C1C2EDF16_(%class.C1*{{.*}}, half{{.*}})
_Float16 func1c(_Float16 arg ) {
return f1c + arg;
}
// CHECK-DAG: define linkonce_odr half @_ZN2C16func1cEDF16_(%class.C1*{{.*}}, half{{.*}})
static _Float16 func2c(_Float16 arg) {
return arg * C1::f2c;
}
// CHECK-DAG: define linkonce_odr half @_ZN2C16func2cEDF16_(half{{.*}})
};
/* Template */
template <class C> C func1t(C arg) {
return arg * 2.f16;
}
// CHECK-DAG: define linkonce_odr half @_Z6func1tIDF16_ET_S0_(half{{.*}})
template <class C> struct S1 {
C mem1;
};
template <> struct S1<_Float16> {
_Float16 mem2;
};
/* Local */
extern int printf (const char *__restrict __format, ...);
int main(void) {
_Float16 f1l = 1e3f16;
// CHECK-DAG: store half 0xH63D0, half* %{{.*}}, align 2
_Float16 f2l = -0.f16;
// CHECK-DAG: store half 0xH8000, half* %{{.*}}, align 2
_Float16 f3l = 1.000976562;
// CHECK-DAG: store half 0xH3C01, half* %{{.*}}, align 2
C1 c1(f1l);
// CHECK-DAG: [[F1L:%[a-z0-9]+]] = load half, half* %{{.*}}, align 2
// CHECK-DAG: call void @_ZN2C1C2EDF16_(%class.C1* %{{.*}}, half %{{.*}})
S1<_Float16> s1 = { 132.f16 };
// CHECK-AARCH64-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { half 0xH5820 }, align 2
// CHECK-X86-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant { i16 } { i16 22560 }, align 2
// CHECK-DAG: [[S1:%[0-9]+]] = bitcast %struct.S1* %{{.*}} to i8*
// CHECK-AARCH64-DAG: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[S1]], i8* bitcast (%struct.S1* @_ZZ4mainE2s1 to i8*), i64 2, i32 2, i1 false)
// CHECK-X86-DAG: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %{{.*}}, i8* bitcast ({ i16 }* @_ZZ4mainE2s1 to i8*), i64 2, i32 2, i1 false)
_Float16 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
func1t(f1l) + s1.mem2 - f1n + f2n;
auto f5l = -1.f16, *f6l = &f2l, f7l = func1t(f3l);
// CHECK-DAG: store half 0xHBC00, half* %{{.*}}, align 2
// CHECK-DAG: store half* %{{.*}}, half** %{{.*}}, align 8
_Float16 f8l = f4l++;
// CHECK-DAG: %{{.*}} = load half, half* %{{.*}}, align 2
// CHECK-DAG: [[INC:%[a-z0-9]+]] = fadd half {{.*}}, 0xH3C00
// CHECK-DAG: store half [[INC]], half* %{{.*}}, align 2
_Float16 arr1l[] = { -1.f16, -0.f16, -11.f16 };
// CHECK-AARCH64-DAG: @_ZZ4mainE5arr1l = private unnamed_addr constant [3 x half] [half 0xHBC00, half 0xH8000, half 0xHC980], align 2
// CHECK-X86-DAG: @_ZZ4mainE5arr1l = private unnamed_addr constant [3 x i16] [i16 -17408, i16 -32768, i16 -13952], align 2
float cvtf = f2n;
//CHECK-DAG: [[H2F:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to float
//CHECK-DAG: store float [[H2F]], float* %{{.*}}, align 4
double cvtd = f2n;
//CHECK-DAG: [[H2D:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to double
//CHECK-DAG: store double [[H2D]], double* %{{.*}}, align 8
long double cvtld = f2n;
//CHECK-AARCh64-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to fp128
//CHECK-AARCh64-DAG: store fp128 [[H2LD]], fp128* %{{.*}}, align 16
//CHECK-X86-DAG: [[H2LD:%[a-z0-9]+]] = fpext half {{%[0-9]+}} to x86_fp80
//CHECK-X86-DAG: store x86_fp80 [[H2LD]], x86_fp80* %{{.*}}, align 16
_Float16 f2h = 42.0f;
//CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
_Float16 d2h = 42.0;
//CHECK-DAG: store half 0xH5140, half* %{{.*}}, align 2
_Float16 ld2h = 42.0l;
//CHECK-DAG:store half 0xH5140, half* %{{.*}}, align 2
}

View File

@ -0,0 +1,326 @@
// RUN: %clang_cc1 -std=c++11 -ast-dump %s | FileCheck %s --strict-whitespace
// RUN: %clang_cc1 -std=c++11 -ast-dump -fnative-half-type %s | FileCheck %s --check-prefix=CHECK-NATIVE --strict-whitespace
/* Various contexts where type _Float16 can appear. */
/* Namespace */
namespace {
_Float16 f1n;
_Float16 f2n = 33.f16;
_Float16 arr1n[10];
_Float16 arr2n[] = { 1.2, 3.0, 3.e4 };
const volatile _Float16 func1n(const _Float16 &arg) {
return arg + f2n + arr1n[4] - arr2n[1];
}
}
//CHECK: |-NamespaceDecl
//CHECK-NEXT: | |-VarDecl {{.*}} f1n '_Float16'
//CHECK-NEXT: | |-VarDecl {{.*}} f2n '_Float16' cinit
//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 3.300000e+01
//CHECK-NEXT: | |-VarDecl {{.*}} arr1n '_Float16 [10]'
//CHECK-NEXT: | |-VarDecl {{.*}} arr2n '_Float16 [3]' cinit
//CHECK-NEXT: | | `-InitListExpr {{.*}} '_Float16 [3]'
//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00
//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
//CHECK-NEXT: | | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00
//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+04
//CHECK-NEXT: | `-FunctionDecl {{.*}} func1n 'const volatile _Float16 (const _Float16 &)'
/* File */
_Float16 f1f;
_Float16 f2f = 32.4;
_Float16 arr1f[10];
_Float16 arr2f[] = { -1.2, -3.0, -3.e4 };
_Float16 func1f(_Float16 arg);
//CHECK: |-VarDecl {{.*}} f1f '_Float16'
//CHECK-NEXT: |-VarDecl {{.*}} f2f '_Float16' cinit
//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.240000e+01
//CHECK-NEXT: |-VarDecl {{.*}} arr1f '_Float16 [10]'
//CHECK-NEXT: |-VarDecl {{.*}} arr2f '_Float16 [3]' cinit
//CHECK-NEXT: | `-InitListExpr {{.*}} '_Float16 [3]'
//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-'
//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 1.200000e+00
//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
//CHECK-NEXT: | | `-UnaryOperator {{.*}} 'double' prefix '-'
//CHECK-NEXT: | | `-FloatingLiteral {{.*}} 'double' 3.000000e+00
//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-'
//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 3.000000e+04
//CHECK-NEXT: |-FunctionDecl {{.*}} func1f '_Float16 (_Float16)'
//CHECK-NEXT: | `-ParmVarDecl {{.*}} arg '_Float16'
// Mixing __fp16 and Float16 types:
// The _Float16 type is first converted to __fp16 type and then the operation
// is completed as if both operands were of __fp16 type.
__fp16 B = -0.1;
auto C = -1.0f16 + B;
// When we do *not* have native half types, we expect __fp16 to be promoted to
// float, and consequently also _Float16 promotions to float:
//CHECK: -VarDecl {{.*}} used B '__fp16' cinit
//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
//CHECK-NEXT: | `-UnaryOperator {{.*}} 'double' prefix '-'
//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01
//CHECK-NEXT: |-VarDecl {{.*}} C 'float':'float' cinit
//CHECK-NEXT: | `-BinaryOperator {{.*}} 'float' '+'
//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue>
//CHECK-NEXT: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16'
// When do have native half types, we expect to see promotions to fp16:
//CHECK-NATIVE: |-VarDecl {{.*}} used B '__fp16' cinit
//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
//CHECK-NATIVE: | `-UnaryOperator {{.*}} 'double' prefix '-'
//CHECK-NATIVE: | `-FloatingLiteral {{.*}} 'double' 1.000000e-01
//CHECK-NATIVE: |-VarDecl {{.*}} C '__fp16':'__fp16' cinit
//CHECK-NATIVE: | `-BinaryOperator {{.*}} '__fp16' '+'
//CHECK-NATIVE: | |-ImplicitCastExpr {{.*}} '__fp16' <FloatingCast>
//CHECK-NATIVE: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
//CHECK-NATIVE: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
//CHECK-NATIVE: | `-ImplicitCastExpr {{.*}} '__fp16' <LValueToRValue>
//CHECK-NATIVE: | `-DeclRefExpr {{.*}} '__fp16' lvalue Var 0x{{.*}} 'B' '__fp16'
/* Class */
class C1 {
_Float16 f1c;
static const _Float16 f2c;
volatile _Float16 f3c;
public:
C1(_Float16 arg) : f1c(arg), f3c(arg) { }
_Float16 func1c(_Float16 arg ) {
return f1c + arg;
}
static _Float16 func2c(_Float16 arg) {
return arg * C1::f2c;
}
};
//CHECK: |-CXXRecordDecl {{.*}} referenced class C1 definition
//CHECK-NEXT: | |-CXXRecordDecl {{.*}} implicit referenced class C1
//CHECK-NEXT: | |-FieldDecl {{.*}} referenced f1c '_Float16'
//CHECK-NEXT: | |-VarDecl {{.*}} used f2c 'const _Float16' static
//CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile _Float16'
//CHECK-NEXT: | |-AccessSpecDecl
//CHECK-NEXT: | |-CXXConstructorDecl {{.*}} used C1 'void (_Float16)'
//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f1c' '_Float16'
//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
//CHECK-NEXT: | | |-CXXCtorInitializer Field {{.*}} 'f3c' 'volatile _Float16'
//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
//CHECK-NEXT: | | `-CompoundStmt
//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func1c '_Float16 (_Float16)'
//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
//CHECK-NEXT: | | `-CompoundStmt
//CHECK-NEXT: | | `-ReturnStmt
//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '+'
//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue ->f1c 0x{{.*}}
//CHECK-NEXT: | | | `-CXXThisExpr {{.*}} 'class C1 *' this
//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
//CHECK-NEXT: | |-CXXMethodDecl {{.*}} used func2c '_Float16 (_Float16)' static
//CHECK-NEXT: | | |-ParmVarDecl {{.*}} used arg '_Float16'
//CHECK-NEXT: | | `-CompoundStmt
//CHECK-NEXT: | | `-ReturnStmt
//CHECK-NEXT: | | `-BinaryOperator {{.*}} '_Float16' '*'
//CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} '_Float16' lvalue ParmVar 0x{{.*}} 'arg' '_Float16'
//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'const _Float16' lvalue Var 0x{{.*}} 'f2c' 'const _Float16'
/* Template */
template <class C> C func1t(C arg) {
return arg * 2.f16;
}
//CHECK: |-FunctionTemplateDecl {{.*}} func1t
//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} C
//CHECK-NEXT: | |-FunctionDecl {{.*}} func1t 'C (C)'
//CHECK-NEXT: | | |-ParmVarDecl {{.*}} referenced arg 'C'
//CHECK-NEXT: | | `-CompoundStmt
//CHECK-NEXT: | | `-ReturnStmt
//CHECK-NEXT: | | `-BinaryOperator {{.*}} '<dependent type>' '*'
//CHECK-NEXT: | | |-DeclRefExpr {{.*}} 'C' lvalue ParmVar {{.*}} 'arg' 'C'
//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00
//CHECK-NEXT: | `-FunctionDecl {{.*}} used func1t '_Float16 (_Float16)'
//CHECK-NEXT: | |-TemplateArgument type '_Float16'
//CHECK-NEXT: | |-ParmVarDecl {{.*}} used arg '_Float16':'_Float16'
//CHECK-NEXT: | `-CompoundStmt
//CHECK-NEXT: | `-ReturnStmt
//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '*'
//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16':'_Float16' <LValueToRValue>
//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16':'_Float16' lvalue ParmVar {{.*}} 'arg' '_Float16':'_Float16'
//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 2.000000e+00
template <class C> struct S1 {
C mem1;
};
//CHECK: |-ClassTemplateDecl {{.*}} S1
//CHECK-NEXT: | |-TemplateTypeParmDecl {{.*}} referenced class depth 0 index 0 C
//CHECK-NEXT: | |-CXXRecordDecl {{.*}} struct S1 definition
//CHECK-NEXT: | | |-CXXRecordDecl {{.*}} implicit struct S1
//CHECK-NEXT: | | `-FieldDecl {{.*}} mem1 'C'
//CHECK-NEXT: | `-ClassTemplateSpecialization {{.*}} 'S1'
template <> struct S1<_Float16> {
_Float16 mem2;
};
/* Local */
extern int printf (const char *__restrict __format, ...);
int main(void) {
_Float16 f1l = 1e3f16;
//CHECK: | `-VarDecl {{.*}} used f1l '_Float16' cinit
//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+03
_Float16 f2l = -0.f16;
//CHECK: | `-VarDecl {{.*}} used f2l '_Float16' cinit
//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' prefix '-'
//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00
_Float16 f3l = 1.000976562;
//CHECK: | `-VarDecl {{.*}} used f3l '_Float16' cinit
//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
//CHECK-NEXT: | `-FloatingLiteral {{.*}} 'double' 1.000977e+00
C1 c1(f1l);
//CHECK: | `-VarDecl{{.*}} used c1 'class C1' callinit
//CHECK-NEXT: | `-CXXConstructExpr {{.*}} 'class C1' 'void (_Float16)'
//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var 0x{{.*}} 'f1l' '_Float16'
S1<_Float16> s1 = { 132.f16 };
//CHECK: | `-VarDecl {{.*}} used s1 'S1<_Float16>':'struct S1<_Float16>' cinit
//CHECK-NEXT: | `-InitListExpr {{.*}} 'S1<_Float16>':'struct S1<_Float16>'
//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.320000e+02
_Float16 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
func1t(f1l) + s1.mem2 - f1n + f2n;
//CHECK: | `-VarDecl {{.*}} used f4l '_Float16' cinit
//CHECK-NEXT: | `-BinaryOperator {{.*}} '_Float16' '+'
//CHECK-NEXT: | |-BinaryOperator {{.*}} '_Float16' '-'
//CHECK-NEXT: | | |-BinaryOperator {{.*}} '_Float16' '+'
//CHECK-NEXT: | | | |-BinaryOperator {{.*}} '_Float16' '+'
//CHECK-NEXT: | | | | |-BinaryOperator {{.*}} '_Float16' '+'
//CHECK-NEXT: | | | | | |-BinaryOperator {{.*}} '_Float16' '+'
//CHECK-NEXT: | | | | | | |-BinaryOperator {{.*}} '_Float16' '+'
//CHECK-NEXT: | | | | | | | |-CallExpr {{.*}} '_Float16'
//CHECK-NEXT: | | | | | | | | |-ImplicitCastExpr {{.*}} 'const volatile _Float16 (*)(const _Float16 &)' <FunctionToPointerDecay>
//CHECK-NEXT: | | | | | | | | | `-DeclRefExpr {{.*}} 'const volatile _Float16 (const _Float16 &)' lvalue Function {{.*}} 'func1n' 'const volatile _Float16 (const _Float16 &)'
//CHECK-NEXT: | | | | | | | | `-ImplicitCastExpr {{.*}} 'const _Float16' lvalue <NoOp>
//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
//CHECK-NEXT: | | | | | | | `-CallExpr {{.*}} '_Float16'
//CHECK-NEXT: | | | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
//CHECK-NEXT: | | | | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1f' '_Float16 (_Float16)'
//CHECK-NEXT: | | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16'
//CHECK-NEXT: | | | | | | `-CXXMemberCallExpr {{.*}} '_Float16'
//CHECK-NEXT: | | | | | | |-MemberExpr {{.*}} '<bound member function type>' .func1c {{.*}}
//CHECK-NEXT: | | | | | | | `-DeclRefExpr {{.*}} 'class C1' lvalue Var {{.*}} 'c1' 'class C1'
//CHECK-NEXT: | | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16'
//CHECK-NEXT: | | | | | `-CallExpr {{.*}} '_Float16'
//CHECK-NEXT: | | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
//CHECK-NEXT: | | | | | | `-MemberExpr {{.*}} '_Float16 (_Float16)' lvalue .func2c {{.*}}
//CHECK-NEXT: | | | | | | `-DeclRefExpr {{.*}} 'class C1' lvalue Var {{.*}} 'c1' 'class C1'
//CHECK-NEXT: | | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
//CHECK-NEXT: | | | | `-CallExpr {{.*}} '_Float16':'_Float16'
//CHECK-NEXT: | | | | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
//CHECK-NEXT: | | | | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t')
//CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1l' '_Float16'
//CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | | `-MemberExpr {{.*}} '_Float16' lvalue .mem2 {{.*}}
//CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'S1<_Float16>':'struct S1<_Float16>' lvalue Var {{.*}} 's1' 'S1<_Float16>':'struct S1<_Float16>'
//CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f1n' '_Float16'
//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
auto f5l = -1.f16, *f6l = &f2l, f7l = func1t(f3l);
//CHECK: | |-VarDecl {{.*}} f5l '_Float16':'_Float16' cinit
//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16' prefix '-'
//CHECK-NEXT: | | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
//CHECK-NEXT: | |-VarDecl {{.*}} f6l '_Float16 *' cinit
//CHECK-NEXT: | | `-UnaryOperator {{.*}} '_Float16 *' prefix '&'
//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2l' '_Float16'
//CHECK-NEXT: | `-VarDecl {{.*}} f7l '_Float16':'_Float16' cinit
//CHECK-NEXT: | `-CallExpr {{.*}} '_Float16':'_Float16'
//CHECK-NEXT: | |-ImplicitCastExpr {{.*}} '_Float16 (*)(_Float16)' <FunctionToPointerDecay>
//CHECK-NEXT: | | `-DeclRefExpr {{.*}} '_Float16 (_Float16)' lvalue Function {{.*}} 'func1t' '_Float16 (_Float16)' (FunctionTemplate {{.*}} 'func1t')
//CHECK-NEXT: | `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f3l' '_Float16'
_Float16 f8l = f4l++;
//CHECK: | `-VarDecl {{.*}} f8l '_Float16' cinit
//CHECK-NEXT: | `-UnaryOperator {{.*}} '_Float16' postfix '++'
//CHECK-NEXT: | `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f4l' '_Float16'
_Float16 arr1l[] = { -1.f16, -0.f16, -11.f16 };
//CHECK: `-VarDecl {{.*}} arr1l '_Float16 [3]' cinit
//CHECK-NEXT: `-InitListExpr {{.*}} '_Float16 [3]'
//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-'
//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 1.000000e+00
//CHECK-NEXT: |-UnaryOperator {{.*}} '_Float16' prefix '-'
//CHECK-NEXT: | `-FloatingLiteral {{.*}} '_Float16' 0.000000e+00
//CHECK-NEXT: `-UnaryOperator {{.*}} '_Float16' prefix '-'
//CHECK-NEXT: `-FloatingLiteral {{.*}} '_Float16' 1.100000e+01
float cvtf = f2n;
//CHECK: `-VarDecl {{.*}} cvtf 'float' cinit
//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'float' <FloatingCast>
//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
double cvtd = f2n;
//CHECK: `-VarDecl {{.*}} cvtd 'double' cinit
//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'double' <FloatingCast>
//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
long double cvtld = f2n;
//CHECK: `-VarDecl {{.*}} cvtld 'long double' cinit
//CHECK-NEXT: `-ImplicitCastExpr {{.*}} 'long double' <FloatingCast>
//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <LValueToRValue>
//CHECK-NEXT: `-DeclRefExpr {{.*}} '_Float16' lvalue Var {{.*}} 'f2n' '_Float16'
_Float16 f2h = 42.0f;
//CHECK: `-VarDecl {{.*}} f2h '_Float16' cinit
//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
//CHECK-NEXT: `-FloatingLiteral {{.*}} 'float' 4.200000e+01
_Float16 d2h = 42.0;
//CHECK: `-VarDecl {{.*}} d2h '_Float16' cinit
//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
//CHECK-NEXT: `-FloatingLiteral {{.*}} 'double' 4.200000e+01
_Float16 ld2h = 42.0l;
//CHECK: `-VarDecl {{.*}} ld2h '_Float16' cinit
//CHECK-NEXT: `-ImplicitCastExpr {{.*}} '_Float16' <FloatingCast>
//CHECK-NEXT: `-FloatingLiteral {{.*}} 'long double' 4.200000e+01
}

View File

@ -1,3 +1,6 @@
// RUN: %clang_cc1 -fsyntax-only -verify -pedantic %s
float a = 1.0h; // expected-error{{invalid suffix 'h' on floating constant}}
float b = 1.0H; // expected-error{{invalid suffix 'H' on floating constant}}
_Float16 c = 1.f166; // expected-error{{invalid suffix 'f166' on floating constant}}
_Float16 d = 1.f1; // expected-error{{invalid suffix 'f1' on floating constant}}

View File

@ -53,6 +53,7 @@ static CXTypeKind GetBuiltinTypeKind(const BuiltinType *BT) {
BTCASE(Float);
BTCASE(Double);
BTCASE(LongDouble);
BTCASE(Float16);
BTCASE(Float128);
BTCASE(NullPtr);
BTCASE(Overload);
@ -520,7 +521,7 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
TKIND(Char_U);
TKIND(UChar);
TKIND(Char16);
TKIND(Char32);
TKIND(Char32);
TKIND(UShort);
TKIND(UInt);
TKIND(ULong);
@ -538,6 +539,7 @@ CXString clang_getTypeKindSpelling(enum CXTypeKind K) {
TKIND(Float);
TKIND(Double);
TKIND(LongDouble);
TKIND(Float16);
TKIND(Float128);
TKIND(NullPtr);
TKIND(Overload);