TypeKind.OBJCID = TypeKind(27)
TypeKind.OBJCCLASS = TypeKind(28)
TypeKind.OBJCSEL = TypeKind(29)
-TypeKind.FLOAT128 = TypeKind(30)
TypeKind.COMPLEX = TypeKind(100)
TypeKind.POINTER = TypeKind(101)
TypeKind.BLOCKPOINTER = TypeKind(102)
CXType_ObjCId = 27,
CXType_ObjCClass = 28,
CXType_ObjCSel = 29,
- CXType_Float128 = 30,
CXType_FirstBuiltin = CXType_Void,
CXType_LastBuiltin = CXType_ObjCSel,
CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
- CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
+ CanQualType FloatTy, DoubleTy, LongDoubleTy;
CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
- CanQualType Float128ComplexTy;
CanQualType VoidPtrTy, NullPtrTy;
CanQualType DependentTy, OverloadTy, BoundMemberTy, UnknownAnyTy;
CanQualType BuiltinFnTy;
/// \brief Retrieve the declaration for the 128-bit unsigned integer type.
TypedefDecl *getUInt128Decl() const;
+ /// \brief Retrieve the declaration for a 128-bit float stub type.
+ TypeDecl *getFloat128StubType() const;
+
//===--------------------------------------------------------------------===//
// Type Constructors
//===--------------------------------------------------------------------===//
// 'long double'
FLOATING_TYPE(LongDouble, LongDoubleTy)
-// '__float128'
-FLOATING_TYPE(Float128, Float128Ty)
-
//===- Language-specific types --------------------------------------------===//
// This is the type of C++0x 'nullptr'.
}
bool isFloatingPoint() const {
- return getKind() >= Half && getKind() <= Float128;
+ return getKind() >= Half && getKind() <= LongDouble;
}
/// Determines whether the given kind corresponds to a placeholder type.
bool needsExtraLocalData() const {
BuiltinType::Kind bk = getTypePtr()->getKind();
return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
- || (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
+ || (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
|| bk == BuiltinType::UChar
|| bk == BuiltinType::SChar;
}
"arithmetic on%select{ a|}0 pointer%select{|s}0 to void">;
def err_typecheck_decl_incomplete_type : Error<
"variable has incomplete type %0">;
+def err_typecheck_decl_incomplete_type___float128 : Error<
+ "support for type '__float128' is not yet implemented">;
def ext_typecheck_decl_incomplete_type : ExtWarn<
"tentative definition of variable with internal linkage has incomplete non-array type %0">,
InGroup<DiagGroup<"tentative-definition-incomplete-type">>;
"feature, not permitted in C++">;
def err_type_requires_extension : Error<
"use of type %0 requires %1 extension to be enabled">;
-def err_type_unsupported : Error<
- "%0 is not supported on this target">;
+def err_int128_unsupported : Error<
+ "__int128 is not supported on this target">;
def err_nsconsumed_attribute_mismatch : Error<
"overriding method has mismatched ns_consumed attribute on its"
" parameter">;
TST_half, // OpenCL half, ARM NEON __fp16
TST_float,
TST_double,
- TST_float128,
TST_bool, // _Bool
TST_decimal32, // _Decimal32
TST_decimal64, // _Decimal64
unsigned char HalfWidth, HalfAlign;
unsigned char FloatWidth, FloatAlign;
unsigned char DoubleWidth, DoubleAlign;
- unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align;
+ unsigned char LongDoubleWidth, LongDoubleAlign;
unsigned char LargeArrayMinWidth, LargeArrayAlign;
unsigned char LongWidth, LongAlign;
unsigned char LongLongWidth, LongLongAlign;
std::unique_ptr<llvm::DataLayout> DataLayout;
const char *MCountName;
const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat,
- *LongDoubleFormat, *Float128Format;
+ *LongDoubleFormat;
unsigned char RegParmMax, SSERegParmMax;
TargetCXXABI TheCXXABI;
const LangAS::Map *AddrSpaceMap;
NoFloat = 255,
Float = 0,
Double,
- LongDouble,
- Float128
+ LongDouble
};
/// \brief The different kinds of __builtin_va_list types defined by
return getPointerWidth(0) >= 64;
} // FIXME
- /// \brief Determine whether the __float128 type is supported on this target.
- virtual bool hasFloat128Type() const {
- return false;
- }
-
/// \brief Return the alignment that is suitable for storing any
/// object with a fundamental alignment requirement.
unsigned getSuitableAlign() const { return SuitableAlign; }
return *LongDoubleFormat;
}
- /// getFloat128Width/Align/Format - Return the size/align/format of
- /// '__float128'.
- unsigned getFloat128Width() const { return 128; }
- unsigned getFloat128Align() const { return Float128Align; }
- const llvm::fltSemantics &getFloat128Format() const {
- return *Float128Format;
- }
-
/// \brief Return true if the 'long double' type should be mangled like
/// __float128.
virtual bool useFloat128ManglingForLongDouble() const { return false; }
TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX)
KEYWORD(__builtin_va_arg , KEYALL)
KEYWORD(__extension__ , KEYALL)
-KEYWORD(__float128 , KEYALL)
KEYWORD(__imag , KEYALL)
KEYWORD(__int128 , KEYALL)
KEYWORD(__label__ , KEYALL)
def mno_invariant_function_descriptors :
Flag<["-"], "mno-invariant-function-descriptors">,
Group<m_ppc_Features_Group>;
-def mfloat128: Flag<["-"], "mfloat128">,
- Group<m_ppc_Features_Group>;
-def mno_float128 : Flag<["-"], "mno-float128">,
- Group<m_ppc_Features_Group>;
def faltivec : Flag<["-"], "faltivec">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Enable AltiVec vector initializer syntax">;
bool isHalf : 1; // 1.0h
bool isFloat : 1; // 1.0f
bool isImaginary : 1; // 1.0i
- bool isFloat128 : 1; // 1.0q
uint8_t MicrosoftInteger; // Microsoft suffix extension i8, i16, i32, or i64.
bool isIntegerLiteral() const {
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_float128 = clang::TST_float128;
static const TST TST_bool = clang::TST_bool;
static const TST TST_decimal32 = clang::TST_decimal32;
static const TST TST_decimal64 = clang::TST_decimal64;
PREDEF_TYPE_RESERVE_ID_ID = 42,
/// \brief The placeholder type for OpenMP array section.
PREDEF_TYPE_OMP_ARRAY_SECTION = 43,
- /// \brief The '__float128' type
- PREDEF_TYPE_FLOAT128_ID = 44,
/// \brief OpenCL image types with auto numeration
#define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \
PREDEF_TYPE_##Id##_ID,
unsigned ASTContext::NumImplicitDestructorsDeclared;
enum FloatingRank {
- HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank
+ HalfRank, FloatRank, DoubleRank, LongDoubleRank
};
RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
return UInt128Decl;
}
+TypeDecl *ASTContext::getFloat128StubType() const {
+ assert(LangOpts.CPlusPlus && "should only be called for c++");
+ if (!Float128StubDecl)
+ Float128StubDecl = buildImplicitRecord("__float128");
+
+ return Float128StubDecl;
+}
+
void ASTContext::InitBuiltinType(CanQualType &R, BuiltinType::Kind K) {
BuiltinType *Ty = new (*this, TypeAlignment) BuiltinType(K);
R = CanQualType::CreateUnsafe(QualType(Ty, 0));
InitBuiltinType(DoubleTy, BuiltinType::Double);
InitBuiltinType(LongDoubleTy, BuiltinType::LongDouble);
- // GNU extension, __float128 for IEEE quadruple precision
- InitBuiltinType(Float128Ty, BuiltinType::Float128);
-
// GNU extension, 128-bit integers.
InitBuiltinType(Int128Ty, BuiltinType::Int128);
InitBuiltinType(UnsignedInt128Ty, BuiltinType::UInt128);
FloatComplexTy = getComplexType(FloatTy);
DoubleComplexTy = getComplexType(DoubleTy);
LongDoubleComplexTy = getComplexType(LongDoubleTy);
- Float128ComplexTy = getComplexType(Float128Ty);
// Builtin types for 'id', 'Class', and 'SEL'.
InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId);
case BuiltinType::Float: return Target->getFloatFormat();
case BuiltinType::Double: return Target->getDoubleFormat();
case BuiltinType::LongDouble: return Target->getLongDoubleFormat();
- case BuiltinType::Float128: return Target->getFloat128Format();
}
}
Width = Target->getLongDoubleWidth();
Align = Target->getLongDoubleAlign();
break;
- case BuiltinType::Float128:
- Width = Target->getFloat128Width();
- Align = Target->getFloat128Align();
- break;
case BuiltinType::NullPtr:
Width = Target->getPointerWidth(0); // C++ 3.9.1p11: sizeof(nullptr_t)
Align = Target->getPointerAlign(0); // == sizeof(void*)
case BuiltinType::Float: return FloatRank;
case BuiltinType::Double: return DoubleRank;
case BuiltinType::LongDouble: return LongDoubleRank;
- case BuiltinType::Float128: return Float128Rank;
}
}
case FloatRank: return FloatComplexTy;
case DoubleRank: return DoubleComplexTy;
case LongDoubleRank: return LongDoubleComplexTy;
- case Float128Rank: return Float128ComplexTy;
}
}
case FloatRank: return FloatTy;
case DoubleRank: return DoubleTy;
case LongDoubleRank: return LongDoubleTy;
- case Float128Rank: return Float128Ty;
}
llvm_unreachable("getFloatingRank(): illegal value for rank");
}
case BuiltinType::LongDouble: return 'D';
case BuiltinType::NullPtr: return '*'; // like char*
- case BuiltinType::Float128:
case BuiltinType::Half:
// FIXME: potentially need @encodes for these!
return ' ';
return DoubleTy;
case TargetInfo::LongDouble:
return LongDoubleTy;
- case TargetInfo::Float128:
- return Float128Ty;
case TargetInfo::NoFloat:
return QualType();
}
// ::= f # float
// ::= d # double
// ::= e # long double, __float80
- // ::= g # __float128
+ // UNSUPPORTED: ::= g # __float128
// UNSUPPORTED: ::= Dd # IEEE 754r decimal floating point (64 bits)
// UNSUPPORTED: ::= De # IEEE 754r decimal floating point (128 bits)
// UNSUPPORTED: ::= Df # IEEE 754r decimal floating point (32 bits)
? 'g'
: 'e');
break;
- case BuiltinType::Float128:
- if (getASTContext().getTargetInfo().useFloat128ManglingForLongDouble())
- Out << "U10__float128"; // Match the GCC mangling
- else
- Out << 'g';
- break;
case BuiltinType::NullPtr:
Out << "Dn";
break;
Out << "$$T";
break;
- case BuiltinType::Float128:
case BuiltinType::Half: {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(
case BuiltinType::Int128:
case BuiltinType::LongDouble:
case BuiltinType::UInt128:
- case BuiltinType::Float128:
case BuiltinType::NullPtr:
case BuiltinType::ObjCClass:
case BuiltinType::ObjCId:
case BuiltinType::Double: break; // no suffix.
case BuiltinType::Float: OS << 'F'; break;
case BuiltinType::LongDouble: OS << 'L'; break;
- case BuiltinType::Float128: OS << 'Q'; break;
}
}
bool Type::isFloatingType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Half &&
- BT->getKind() <= BuiltinType::Float128;
+ BT->getKind() <= BuiltinType::LongDouble;
if (const ComplexType *CT = dyn_cast<ComplexType>(CanonicalType))
return CT->getElementType()->isFloatingType();
return false;
bool Type::isRealType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::Float128;
+ BT->getKind() <= BuiltinType::LongDouble;
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
return false;
bool Type::isArithmeticType() const {
if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Bool &&
- BT->getKind() <= BuiltinType::Float128;
+ BT->getKind() <= BuiltinType::LongDouble;
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
// GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
// If a body isn't seen by the time we get here, return false.
return "double";
case LongDouble:
return "long double";
- case Float128:
- return "__float128";
case WChar_S:
case WChar_U:
return Policy.MSWChar ? "__wchar_t" : "wchar_t";
case BuiltinType::Float:
case BuiltinType::Double:
case BuiltinType::LongDouble:
- case BuiltinType::Float128:
llvm_unreachable("Builtin type needs extra local data!");
// Fall through, if the impossible happens.
case BuiltinType::UInt128:
case BuiltinType::Int128:
case BuiltinType::Half:
- case BuiltinType::Float128:
// Various types which are non-trivial to correct.
return false;
DoubleAlign = 64;
LongDoubleWidth = 64;
LongDoubleAlign = 64;
- Float128Align = 128;
LargeArrayMinWidth = 0;
LargeArrayAlign = 0;
MaxAtomicPromoteWidth = MaxAtomicInlineWidth = 0;
FloatFormat = &llvm::APFloat::IEEEsingle;
DoubleFormat = &llvm::APFloat::IEEEdouble;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
- Float128Format = &llvm::APFloat::IEEEquad;
MCountName = "mcount";
RegParmMax = 0;
SSERegParmMax = 0;
if (&getLongDoubleFormat() == &llvm::APFloat::PPCDoubleDouble ||
&getLongDoubleFormat() == &llvm::APFloat::IEEEquad)
return LongDouble;
- if (hasFloat128Type())
- return Float128;
break;
}
bool HasHTM;
bool HasBPERMD;
bool HasExtDiv;
- bool HasFloat128;
protected:
std::string ABI;
PPCTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple), HasVSX(false), HasP8Vector(false),
HasP8Crypto(false), HasDirectMove(false), HasQPX(false), HasHTM(false),
- HasBPERMD(false), HasExtDiv(false), HasFloat128(false) {
+ HasBPERMD(false), HasExtDiv(false) {
BigEndian = (Triple.getArch() != llvm::Triple::ppc64le);
SimdDefaultAlign = 128;
LongDoubleWidth = LongDoubleAlign = 128;
LongDoubleFormat == &llvm::APFloat::PPCDoubleDouble &&
getTriple().isOSBinFormatELF();
}
- bool hasFloat128Type() const override {
- return HasFloat128;
- }
};
const Builtin::Info PPCTargetInfo::BuiltinInfo[] = {
HasQPX = true;
} else if (Feature == "+htm") {
HasHTM = true;
- } else if (Feature == "+float128") {
- HasFloat128 = true;
}
// TODO: Finish this list and add an assert that we've handled them
// all.
Builder.defineMacro("__CRYPTO__");
if (HasHTM)
Builder.defineMacro("__HTM__");
- if (HasFloat128)
- Builder.defineMacro("__FLOAT128__");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_1");
Builder.defineMacro("__GCC_HAVE_SYNC_COMPARE_AND_SWAP_2");
<< "-mno-vsx";
return false;
}
-
- if (std::find(FeaturesVec.begin(), FeaturesVec.end(), "+float128") !=
- FeaturesVec.end()) {
- Diags.Report(diag::err_opt_not_valid_with_opt) << "-mfloat128"
- << "-mno-vsx";
- return false;
- }
}
return true;
.Case("htm", HasHTM)
.Case("bpermd", HasBPERMD)
.Case("extdiv", HasExtDiv)
- .Case("float128", HasFloat128)
.Default(false);
}
// as well. Do the inverse if we're disabling vsx. We'll diagnose any user
// incompatible options.
if (Enabled) {
- if (Name == "direct-move") {
+ if (Name == "vsx") {
+ Features[Name] = true;
+ } else if (Name == "direct-move") {
Features[Name] = Features["vsx"] = true;
} else if (Name == "power8-vector") {
Features[Name] = Features["vsx"] = true;
- } else if (Name == "float128") {
- Features[Name] = Features["vsx"] = true;
} else {
Features[Name] = true;
}
} else {
if (Name == "vsx") {
Features[Name] = Features["direct-move"] = Features["power8-vector"] =
- Features["float128"] = false;
+ false;
} else {
Features[Name] = false;
}
case BuiltinType::Half:
case BuiltinType::Float:
case BuiltinType::LongDouble:
- case BuiltinType::Float128:
case BuiltinType::Double:
- // FIXME: For targets where long double and __float128 have the same size,
- // they are currently indistinguishable in the debugger without some
- // special treatment. However, there is currently no consensus on encoding
- // and this should be updated once a DWARF encoding exists for distinct
- // floating point types of the same size.
Encoding = llvm::dwarf::DW_ATE_float;
break;
}
amt = llvm::ConstantFP::get(VMContext,
llvm::APFloat(static_cast<double>(amount)));
else {
- // Remaining types are Half, LongDouble or __float128. Convert from float.
+ // Remaining types are either Half or LongDouble. Convert from float.
llvm::APFloat F(static_cast<float>(amount));
bool ignored;
- const llvm::fltSemantics *FS;
// Don't use getFloatTypeSemantics because Half isn't
// necessarily represented using the "half" LLVM type.
- if (value->getType()->isFP128Ty())
- FS = &CGF.getTarget().getFloat128Format();
- else if (value->getType()->isHalfTy())
- FS = &CGF.getTarget().getHalfFormat();
- else
- FS = &CGF.getTarget().getLongDoubleFormat();
- F.convert(*FS, llvm::APFloat::rmTowardZero, &ignored);
+ F.convert(value->getType()->isHalfTy()
+ ? CGF.getTarget().getHalfFormat()
+ : CGF.getTarget().getLongDoubleFormat(),
+ llvm::APFloat::rmTowardZero, &ignored);
amt = llvm::ConstantFP::get(VMContext, F);
}
value = Builder.CreateFAdd(value, amt, isInc ? "inc" : "dec");
case BuiltinType::Float:
case BuiltinType::Double:
case BuiltinType::LongDouble:
- case BuiltinType::Float128:
ResultType = getTypeForFormat(getLLVMContext(),
Context.getFloatTypeSemantics(T),
/* UseNativeHalf = */ false);
case BuiltinType::Float:
case BuiltinType::Double:
case BuiltinType::LongDouble:
- case BuiltinType::Float128:
case BuiltinType::Char16:
case BuiltinType::Char32:
case BuiltinType::Int128:
getContext().UnsignedLongLongTy, getContext().Int128Ty,
getContext().UnsignedInt128Ty, getContext().HalfTy,
getContext().FloatTy, getContext().DoubleTy,
- getContext().LongDoubleTy, getContext().Float128Ty,
- getContext().Char16Ty, getContext().Char32Ty
+ getContext().LongDoubleTy, getContext().Char16Ty,
+ getContext().Char32Ty,
};
for (const QualType &FundamentalType : FundamentalTypes)
EmitFundamentalRTTIDescriptor(FundamentalType);
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
- case tok::kw___float128:
case tok::kw_wchar_t:
case tok::kw_bool:
case tok::kw___underlying_type:
c = 'd'; break;
case BuiltinType::LongDouble:
c = 'D'; break;
- case BuiltinType::Float128:
- c = 'Q'; break;
case BuiltinType::NullPtr:
c = 'n'; break;
#define BUILTIN_TYPE(Id, SingletonId)
isHalf = false;
isFloat = false;
isImaginary = false;
- isFloat128 = false;
MicrosoftInteger = 0;
hadError = false;
case 'f': // FP Suffix for "float"
case 'F':
if (!isFPConstant) break; // Error for integer constant.
- if (isHalf || isFloat || isLong || isFloat128)
- break; // HF, FF, LF, QF invalid.
+ if (isHalf || isFloat || isLong) break; // HF, FF, LF invalid.
isFloat = true;
continue; // Success.
- case 'q': // FP Suffix for "__float128"
- case 'Q':
- if (!isFPConstant) break; // Error for integer constant.
- if (isHalf || isFloat || isLong || isFloat128)
- break; // HQ, FQ, LQ, QQ invalid.
- isFloat128 = true;
- continue; // Success.
case 'u':
case 'U':
if (isFPConstant) break; // Error for floating constant.
case 'l':
case 'L':
if (isLong || isLongLong) break; // Cannot be repeated.
- if (isHalf || isFloat || isFloat128) break; // LH, LF, LQ invalid.
+ if (isHalf || isFloat) break; // LH, LF invalid.
// Check for long long. The L's need to be adjacent and the same case.
if (s[1] == s[0]) {
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec,
DiagID, Policy);
break;
- case tok::kw___float128:
- isInvalid = DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec,
- DiagID, Policy);
- break;
case tok::kw_wchar_t:
isInvalid = DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec,
DiagID, Policy);
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
- case tok::kw___float128:
case tok::kw_bool:
case tok::kw__Bool:
case tok::kw__Decimal32:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
- case tok::kw___float128:
case tok::kw_bool:
case tok::kw__Bool:
case tok::kw__Decimal32:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
- case tok::kw___float128:
case tok::kw_bool:
case tok::kw__Bool:
case tok::kw__Decimal32:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
- case tok::kw___float128:
case tok::kw_void:
case tok::kw_typename:
case tok::kw_typeof:
case tok::kw_double:
DS.SetTypeSpecType(DeclSpec::TST_double, Loc, PrevSpec, DiagID, Policy);
break;
- case tok::kw___float128:
- DS.SetTypeSpecType(DeclSpec::TST_float128, Loc, PrevSpec, DiagID, Policy);
- break;
case tok::kw_wchar_t:
DS.SetTypeSpecType(DeclSpec::TST_wchar, Loc, PrevSpec, DiagID, Policy);
break;
case tok::kw_char:
case tok::kw_const:
case tok::kw_double:
- case tok::kw___float128:
case tok::kw_enum:
case tok::kw_half:
case tok::kw_float:
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
- case tok::kw___float128:
case tok::kw_void:
case tok::annot_decltype:
if (NextToken().is(tok::l_paren))
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
- case tok::kw___float128:
case tok::kw_void:
case tok::kw___unknown_anytype:
case tok::kw___auto_type:
case TST_decimal32:
case TST_decimal64:
case TST_double:
- case TST_float128:
case TST_enum:
case TST_error:
case TST_float:
case DeclSpec::TST_half: return "half";
case DeclSpec::TST_float: return "float";
case DeclSpec::TST_double: return "double";
- case DeclSpec::TST_float128: return "__float128";
case DeclSpec::TST_bool: return Policy.Bool ? "bool" : "_Bool";
case DeclSpec::TST_decimal32: return "_Decimal32";
case DeclSpec::TST_decimal64: return "_Decimal64";
case tok::kw_half:
case tok::kw_float:
case tok::kw_double:
- case tok::kw___float128:
case tok::kw_wchar_t:
case tok::kw_bool:
case tok::kw___underlying_type:
/*convertFloat=*/!IsCompAssign);
}
-/// \brief Diagnose attempts to convert between __float128 and long double if
-/// there is no support for such conversion. Helper function of
-/// UsualArithmeticConversions().
-static bool unsupportedTypeConversion(const Sema &S, QualType LHSType,
- QualType RHSType) {
- /* No issue converting if at least one of the types is not a floating point
- type or the two types have the same rank.
- */
- if (!LHSType->isFloatingType() || !RHSType->isFloatingType() ||
- S.Context.getFloatingTypeOrder(LHSType, RHSType) == 0)
- return false;
-
- assert(LHSType->isFloatingType() && RHSType->isFloatingType() &&
- "The remaining types must be floating point types.");
-
- auto *LHSComplex = LHSType->getAs<ComplexType>();
- auto *RHSComplex = RHSType->getAs<ComplexType>();
-
- QualType LHSElemType = LHSComplex ?
- LHSComplex->getElementType() : LHSType;
- QualType RHSElemType = RHSComplex ?
- RHSComplex->getElementType() : RHSType;
-
- // No issue if the two types have the same representation
- if (&S.Context.getFloatTypeSemantics(LHSElemType) ==
- &S.Context.getFloatTypeSemantics(RHSElemType))
- return false;
-
- bool Float128AndLongDouble = (LHSElemType == S.Context.Float128Ty &&
- RHSElemType == S.Context.LongDoubleTy);
- Float128AndLongDouble |= (LHSElemType == S.Context.LongDoubleTy &&
- RHSElemType == S.Context.Float128Ty);
-
- /* We've handled the situation where __float128 and long double have the same
- representation. The only other allowable conversion is if long double is
- really just double.
- */
- return Float128AndLongDouble &&
- (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) !=
- &llvm::APFloat::IEEEdouble);
-}
-
typedef ExprResult PerformCastFn(Sema &S, Expr *operand, QualType toType);
namespace {
// At this point, we have two different arithmetic types.
- // Diagnose attempts to convert between __float128 and long double where
- // such conversions currently can't be handled.
- if (unsupportedTypeConversion(*this, LHSType, RHSType))
- return QualType();
-
// Handle complex types first (C99 6.3.1.8p1).
if (LHSType->isComplexType() || RHSType->isComplexType())
return handleComplexFloatConversion(*this, LHS, RHS, LHSType, RHSType,
}
} else if (Literal.isFloat)
Ty = Context.FloatTy;
- else if (Literal.isLong)
- Ty = Context.LongDoubleTy;
- else if (Literal.isFloat128)
- Ty = Context.Float128Ty;
- else
+ else if (!Literal.isLong)
Ty = Context.DoubleTy;
+ else
+ Ty = Context.LongDoubleTy;
Res = BuildFloatingLiteral(*this, Literal, Ty, Tok.getLocation());
QualType LHSTy = LHS.get()->getType();
QualType RHSTy = RHS.get()->getType();
- // Diagnose attempts to convert between __float128 and long double where
- // such conversions currently can't be handled.
- if (unsupportedTypeConversion(*this, LHSTy, RHSTy)) {
- Diag(QuestionLoc,
- diag::err_typecheck_cond_incompatible_operands) << LHSTy << RHSTy
- << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
- return QualType();
- }
-
// OpenCL v2.0 s6.12.5 - Blocks cannot be used as expressions of the ternary
// selection operator (?:).
if (getLangOpts().OpenCL &&
return Incompatible;
}
- // Diagnose attempts to convert between __float128 and long double where
- // such conversions currently can't be handled.
- if (unsupportedTypeConversion(*this, LHSType, RHSType))
- return Incompatible;
-
// Arithmetic conversions.
if (LHSType->isArithmeticType() && RHSType->isArithmeticType() &&
!(getLangOpts().CPlusPlus && LHSType->isEnumeralType())) {
QualType ResTy = UsualArithmeticConversions(LHS, RHS);
if (LHS.isInvalid() || RHS.isInvalid())
return QualType();
- if (ResTy.isNull()) {
- Diag(QuestionLoc,
- diag::err_typecheck_cond_incompatible_operands) << LTy << RTy
- << LHS.get()->getSourceRange() << RHS.get()->getSourceRange();
- return QualType();
- }
LHS = ImpCastExprToType(LHS.get(), ResTy, PrepareScalarCast(LHS, ResTy));
RHS = ImpCastExprToType(RHS.get(), ResTy, PrepareScalarCast(RHS, ResTy));
NameKind == Sema::LookupRedeclarationWithLinkage) {
IdentifierInfo *II = R.getLookupName().getAsIdentifierInfo();
if (II) {
+ if (S.getLangOpts().CPlusPlus11 && S.getLangOpts().GNUMode &&
+ II == S.getFloat128Identifier()) {
+ // libstdc++4.7's type_traits expects type __float128 to exist, so
+ // insert a dummy type to make that header build in gnu++11 mode.
+ R.addDecl(S.getASTContext().getFloat128StubType());
+ return true;
+ }
if (S.getLangOpts().CPlusPlus && NameKind == Sema::LookupOrdinaryName &&
II == S.getASTContext().getMakeIntegerSeqName()) {
R.addDecl(S.getASTContext().getMakeIntegerSeqDecl());
SCS.Second = ICK_Complex_Real;
FromType = ToType.getUnqualifiedType();
} else if (FromType->isRealFloatingType() && ToType->isRealFloatingType()) {
- // FIXME: disable conversions between long double and __float128 if
- // their representation is different until there is back end support
- // We of course allow this conversion if long double is really double.
- if (&S.Context.getFloatTypeSemantics(FromType) !=
- &S.Context.getFloatTypeSemantics(ToType)) {
- bool Float128AndLongDouble = ((FromType == S.Context.Float128Ty &&
- ToType == S.Context.LongDoubleTy) ||
- (FromType == S.Context.LongDoubleTy &&
- ToType == S.Context.Float128Ty));
- if (Float128AndLongDouble &&
- (&S.Context.getFloatTypeSemantics(S.Context.LongDoubleTy) !=
- &llvm::APFloat::IEEEdouble))
- return false;
- }
// Floating point conversions (C++ 4.8).
SCS.Second = ICK_Floating_Conversion;
FromType = ToType.getUnqualifiedType();
if (!getLangOpts().CPlusPlus &&
(FromBuiltin->getKind() == BuiltinType::Float ||
FromBuiltin->getKind() == BuiltinType::Double) &&
- (ToBuiltin->getKind() == BuiltinType::LongDouble ||
- ToBuiltin->getKind() == BuiltinType::Float128))
+ (ToBuiltin->getKind() == BuiltinType::LongDouble))
return true;
// Half can be promoted to float.
// provided via the getArithmeticType() method below.
// The "promoted arithmetic types" are the arithmetic
// types are that preserved by promotion (C++ [over.built]p2).
- static const unsigned FirstIntegralType = 4;
- static const unsigned LastIntegralType = 21;
- static const unsigned FirstPromotedIntegralType = 4,
- LastPromotedIntegralType = 12;
+ static const unsigned FirstIntegralType = 3;
+ static const unsigned LastIntegralType = 20;
+ static const unsigned FirstPromotedIntegralType = 3,
+ LastPromotedIntegralType = 11;
static const unsigned FirstPromotedArithmeticType = 0,
- LastPromotedArithmeticType = 12;
- static const unsigned NumArithmeticTypes = 21;
+ LastPromotedArithmeticType = 11;
+ static const unsigned NumArithmeticTypes = 20;
/// \brief Get the canonical type for a given arithmetic type index.
CanQualType getArithmeticType(unsigned index) {
&ASTContext::FloatTy,
&ASTContext::DoubleTy,
&ASTContext::LongDoubleTy,
- &ASTContext::Float128Ty,
// Start of integral types.
&ASTContext::IntTy,
case TST_half:
case TST_float:
case TST_double:
- case TST_float128:
case TST_bool:
case TST_decimal32:
case TST_decimal64:
}
case DeclSpec::TST_int128:
if (!S.Context.getTargetInfo().hasInt128Type())
- S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported)
- << "__int128";
+ S.Diag(DS.getTypeSpecTypeLoc(), diag::err_int128_unsupported);
if (DS.getTypeSpecSign() == DeclSpec::TSS_unsigned)
Result = Context.UnsignedInt128Ty;
else
declarator.setInvalidType(true);
}
break;
- case DeclSpec::TST_float128:
- if (!S.Context.getTargetInfo().hasFloat128Type())
- S.Diag(DS.getTypeSpecTypeLoc(), diag::err_type_unsupported)
- << "__float128";
- Result = Context.Float128Ty;
- break;
case DeclSpec::TST_bool: Result = Context.BoolTy; break; // _Bool or bool
break;
case DeclSpec::TST_decimal32: // _Decimal32
if (!Diagnoser)
return true;
+ // We have an incomplete type. Produce a diagnostic.
+ if (Ident___float128 &&
+ T == Context.getTypeDeclType(Context.getFloat128StubType())) {
+ Diag(Loc, diag::err_typecheck_decl_incomplete_type___float128);
+ return true;
+ }
+
Diagnoser->diagnose(*this, Loc, T);
// If the type was a forward declaration of a class/struct/union
case BuiltinType::LongDouble:
ID = PREDEF_TYPE_LONGDOUBLE_ID;
break;
- case BuiltinType::Float128:
- ID = PREDEF_TYPE_FLOAT128_ID;
- break;
case BuiltinType::NullPtr:
ID = PREDEF_TYPE_NULLPTR_ID;
break;
case PREDEF_TYPE_LONGDOUBLE_ID:
T = Context.LongDoubleTy;
break;
- case PREDEF_TYPE_FLOAT128_ID:
- T = Context.Float128Ty;
- break;
case PREDEF_TYPE_OVERLOAD_ID:
T = Context.OverloadTy;
break;
+++ /dev/null
-// RUN: %clang_cc1 -emit-llvm -triple powerpc64-unknown-unknown \
-// RUN: -target-feature +float128 -std=c++11 %s -o - | FileCheck %s
-// RUN: %clang_cc1 -emit-llvm -triple powerpc64le-unknown-unknown \
-// RUN: -target-feature +float128 -std=c++11 %s -o - | FileCheck %s
-//
-/* Various contexts where type __float128 can appear. */
-
-/* Namespace */
-namespace {
- __float128 f1n;
- __float128 f2n = 33.q;
- __float128 arr1n[10];
- __float128 arr2n[] = { 1.2q, 3.0q, 3.e11q };
- const volatile __float128 func1n(const __float128 &arg) {
- return arg + f2n + arr1n[4] - arr2n[1];
- }
-}
-
-/* File */
-__float128 f1f;
-__float128 f2f = 32.4q;
-static __float128 f3f = f2f;
-__float128 arr1f[10];
-__float128 arr2f[] = { -1.2q, -3.0q, -3.e11q };
-__float128 func1f(__float128 arg);
-
-/* Class */
-class C1 {
- __float128 f1c;
- static const __float128 f2c;
- volatile __float128 f3c;
-public:
- C1(__float128 arg) : f1c(arg), f3c(arg) { }
- __float128 func1c(__float128 arg ) {
- return f1c + arg;
- }
- static __float128 func2c(__float128 arg) {
- return arg * C1::f2c;
- }
-};
-
-/* Template */
-template <class C> C func1t(C arg) { return arg * 2.q; }
-template <class C> struct S1 {
- C mem1;
-};
-template <> struct S1<__float128> {
- __float128 mem2;
-};
-
-/* Local */
-int main(void) {
- __float128 f1l = 123e220q;
- __float128 f2l = -0.q;
- __float128 f3l = 1.189731495357231765085759326628007e4932q;
- C1 c1(f1l);
- S1<__float128> s1 = { 132.q };
- __float128 f4l = func1n(f1l) + func1f(f2l) + c1.func1c(f3l) + c1.func2c(f1l) +
- func1t(f1l) + s1.mem2 - f1n + f2n;
-#if (__cplusplus >= 201103L)
- auto f5l = -1.q, *f6l = &f2l, f7l = func1t(f3l);
-#endif
- __float128 f8l = f4l++;
- __float128 arr1l[] = { -1.q, -0.q, -11.q };
-}
-// CHECK-DAG: @_ZN12_GLOBAL__N_13f1nE = internal global fp128 0xL00000000000000000000000000000000
-// CHECK-DAG: @_ZN12_GLOBAL__N_13f2nE = internal global fp128 0xL00000000000000004004080000000000
-// CHECK-DAG: @_ZN12_GLOBAL__N_15arr1nE = internal global [10 x fp128]
-// CHECK-DAG: @_ZN12_GLOBAL__N_15arr2nE = internal global [3 x fp128] [fp128 0xL33333333333333333FFF333333333333, fp128 0xL00000000000000004000800000000000, fp128 0xL00000000000000004025176592E00000]
-// CHECK-DAG: define internal fp128 @_ZN12_GLOBAL__N_16func1nERKU10__float128(fp128*
-// CHECK-DAG: @f1f = global fp128 0xL00000000000000000000000000000000
-// CHECK-DAG: @f2f = global fp128 0xL33333333333333334004033333333333
-// CHECK-DAG: @arr1f = global [10 x fp128]
-// CHECK-DAG: @arr2f = global [3 x fp128] [fp128 0xL3333333333333333BFFF333333333333, fp128 0xL0000000000000000C000800000000000, fp128 0xL0000000000000000C025176592E00000]
-// CHECK-DAG: declare fp128 @_Z6func1fU10__float128(fp128)
-// CHECK-DAG: define linkonce_odr void @_ZN2C1C2EU10__float128(%class.C1* %this, fp128 %arg)
-// CHECK-DAG: define linkonce_odr fp128 @_ZN2C16func2cEU10__float128(fp128 %arg)
-// CHECK-DAG: define linkonce_odr fp128 @_Z6func1tIU10__float128ET_S0_(fp128 %arg)
-// CHECK-DAG: @_ZZ4mainE2s1 = private unnamed_addr constant %struct.S1 { fp128 0xL00000000000000004006080000000000 }
-// CHECK-DAG: store fp128 0xLF0AFD0EBFF292DCE42E0B38CDD83F26F, fp128* %f1l, align 16
-// CHECK-DAG: store fp128 0xL00000000000000008000000000000000, fp128* %f2l, align 16
-// CHECK-DAG: store fp128 0xLFFFFFFFFFFFFFFFF7FFEFFFFFFFFFFFF, fp128* %f3l, align 16
-// CHECK-DAG: store fp128 0xL0000000000000000BFFF000000000000, fp128* %f5l, align 16
-// CHECK-DAG: [[F4L:%[a-z0-9]+]] = load fp128, fp128* %f4l
-// CHECK-DAG: [[INC:%[a-z0-9]+]] = fadd fp128 [[F4L]], 0xL00000000000000003FFF000000000000
-// CHECK-DAG: store fp128 [[INC]], fp128* %f4l
// PPCPOWER8:#define _ARCH_PWR7 1
// PPCPOWER8:#define _ARCH_PWR8 1
//
-// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-none-none -target-feature +float128 -target-cpu power8 -fno-signed-char < /dev/null | FileCheck -check-prefix PPC-FLOAT128 %s
-// PPC-FLOAT128:#define __FLOAT128__ 1
-//
// RUN: %clang_cc1 -E -dM -ffreestanding -triple=powerpc64-unknown-linux-gnu -fno-signed-char < /dev/null | FileCheck -match-full-lines -check-prefix PPC64-LINUX %s
//
// PPC64-LINUX:#define _ARCH_PPC 1
// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 %s
#if !defined(__STRICT_ANSI__)
-__float128 f; // expected-error {{__float128 is not supported on this target}}
+__float128 f; // expected-error {{support for type '__float128' is not yet implemented}}
// But this should work:
template<typename> struct __is_floating_point_helper {};
-template<> struct __is_floating_point_helper<__float128> {}; // expected-error {{__float128 is not supported on this target}}
+template<> struct __is_floating_point_helper<__float128> {};
// FIXME: This could have a better diag.
-int g(int x, __float128 *y) { // expected-error {{__float128 is not supported on this target}}
- return x + *y;
+void g(int x, __float128 *y) {
+ x + *y; // expected-error {{invalid operands to binary expression ('int' and '__float128')}}
}
#else
-__float128 f; // expected-error {{__float128 is not supported on this target}}
+__float128 f; // expected-error {{unknown type name '__float128'}}
template<typename> struct __is_floating_point_helper {};
-template<> struct __is_floating_point_helper<__float128> {}; // expected-error {{__float128 is not supported on this target}}
+template<> struct __is_floating_point_helper<__float128> {}; // expected-error {{use of undeclared identifier '__float128'}}
-int g(int x, __float128 *y) { // expected-error {{__float128 is not supported on this target}}
- return x + *y;
+void g(int x, __float128 *y) { // expected-error {{unknown type name '__float128'}}
+ x + *y;
}
#endif
+++ /dev/null
-// RUN: %clang_cc1 -fsyntax-only -verify -std=c++11 \
-// RUN: -triple powerpc64le-unknown-linux-gnu -target-cpu pwr8 \
-// RUN: -target-feature +float128 %s
-
-__float128 qf();
-long double ldf();
-
-// FIXME: once operations between long double and __float128 are implemented for
-// targets where the types are different, these next two will change
-long double ld{qf()}; // expected-error {{cannot initialize a variable of type 'long double' with an rvalue of type '__float128'}}
-__float128 q{ldf()}; // expected-error {{cannot initialize a variable of type '__float128' with an rvalue of type 'long double'}}
-
-auto test1(__float128 q, long double ld) -> decltype(q + ld) { // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
- return q + ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
-}
-
-auto test2(long double a, __float128 b) -> decltype(a + b) { // expected-error {{invalid operands to binary expression ('long double' and '__float128')}}
- return a + b; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}}
-}
-
-void test3(bool b) {
- long double ld;
- __float128 q;
-
- ld + q; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}}
- q + ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
- ld - q; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}}
- q - ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
- ld * q; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}}
- q * ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
- ld / q; // expected-error {{invalid operands to binary expression ('long double' and '__float128')}}
- q / ld; // expected-error {{invalid operands to binary expression ('__float128' and 'long double')}}
- ld = q; // expected-error {{assigning to 'long double' from incompatible type '__float128'}}
- q = ld; // expected-error {{assigning to '__float128' from incompatible type 'long double'}}
- q + b ? q : ld; // expected-error {{incompatible operand types ('__float128' and 'long double')}}
-}
PR10757 a1;
// FIXME: We get a ridiculous number of "built-in candidate" notes here...
if(~a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 8 {{built-in candidate}}
- if(a1==a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 144 {{built-in candidate}}
+ if(a1==a1) {} // expected-error {{overload resolution selected deleted operator}} expected-note 121 {{built-in candidate}}
}
struct DelOpDel {
// FIXME: lots of candidates here!
(void)(1.0f * a); // expected-error{{ambiguous}} \
// expected-note 4{{candidate}} \
- // expected-note {{remaining 140 candidates omitted; pass -fshow-overloads=all to show them}}
+ // expected-note {{remaining 117 candidates omitted; pass -fshow-overloads=all to show them}}
}
// pr5432
BTCASE(Float);
BTCASE(Double);
BTCASE(LongDouble);
- BTCASE(Float128);
BTCASE(NullPtr);
BTCASE(Overload);
BTCASE(Dependent);
TKIND(Float);
TKIND(Double);
TKIND(LongDouble);
- TKIND(Float128);
TKIND(NullPtr);
TKIND(Overload);
TKIND(Dependent);