Skip to content

Commit

Permalink
Enable support for __float128 in Clang and enable it on pertinent pla…
Browse files Browse the repository at this point in the history
…tforms

This patch corresponds to reviews:
http://reviews.llvm.org/D15120
http://reviews.llvm.org/D19125

It adds support for the __float128 keyword, literals and target feature to
enable it. Based on the latter of the two aforementioned reviews, this feature
is enabled on Linux on i386/X86 as well as SystemZ.
This is also the second attempt in commiting this feature. The first attempt
did not enable it on required platforms which caused failures when compiling
type_traits with -std=gnu++11.

If you see failures with compiling this header on your platform after this
commit, it is likely that your platform needs to have this feature enabled.

llvm-svn: 268898
  • Loading branch information
nemanjai committed May 9, 2016
1 parent 0f450b6 commit bb1ea2d
Show file tree
Hide file tree
Showing 53 changed files with 462 additions and 82 deletions.
1 change: 1 addition & 0 deletions clang/bindings/python/clang/cindex.py
Original file line number Diff line number Diff line change
Expand Up @@ -1731,6 +1731,7 @@ def __repr__(self):
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)
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang-c/Index.h
Original file line number Diff line number Diff line change
Expand Up @@ -2929,6 +2929,7 @@ enum CXTypeKind {
CXType_ObjCId = 27,
CXType_ObjCClass = 28,
CXType_ObjCSel = 29,
CXType_Float128 = 30,
CXType_FirstBuiltin = CXType_Void,
CXType_LastBuiltin = CXType_ObjCSel,

Expand Down
9 changes: 2 additions & 7 deletions clang/include/clang/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -215,9 +215,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \brief The typedef for the __uint128_t type.
mutable TypedefDecl *UInt128Decl;

/// \brief The typedef for the __float128 stub type.
mutable TypeDecl *Float128StubDecl;

/// \brief The typedef for the target specific predefined
/// __builtin_va_list type.
mutable TypedefDecl *BuiltinVaListDecl;
Expand Down Expand Up @@ -893,9 +890,10 @@ class ASTContext : public RefCountedBase<ASTContext> {
CanQualType SignedCharTy, ShortTy, IntTy, LongTy, LongLongTy, Int128Ty;
CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy;
CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
CanQualType FloatTy, DoubleTy, LongDoubleTy;
CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
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;
Expand Down Expand Up @@ -968,9 +966,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// \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
//===--------------------------------------------------------------------===//
Expand Down
3 changes: 3 additions & 0 deletions clang/include/clang/AST/BuiltinTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,9 @@ FLOATING_TYPE(Double, DoubleTy)
// 'long double'
FLOATING_TYPE(LongDouble, LongDoubleTy)

// '__float128'
FLOATING_TYPE(Float128, Float128Ty)

//===- Language-specific types --------------------------------------------===//

// This is the type of C++0x 'nullptr'.
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -2051,7 +2051,7 @@ class BuiltinType : public Type {
}

bool isFloatingPoint() const {
return getKind() >= Half && getKind() <= LongDouble;
return getKind() >= Half && getKind() <= Float128;
}

/// Determines whether the given kind corresponds to a placeholder type.
Expand Down
2 changes: 1 addition & 1 deletion clang/include/clang/AST/TypeLoc.h
Original file line number Diff line number Diff line change
Expand Up @@ -538,7 +538,7 @@ class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
bool needsExtraLocalData() const {
BuiltinType::Kind bk = getTypePtr()->getKind();
return (bk >= BuiltinType::UShort && bk <= BuiltinType::UInt128)
|| (bk >= BuiltinType::Short && bk <= BuiltinType::LongDouble)
|| (bk >= BuiltinType::Short && bk <= BuiltinType::Float128)
|| bk == BuiltinType::UChar
|| bk == BuiltinType::SChar;
}
Expand Down
6 changes: 2 additions & 4 deletions clang/include/clang/Basic/DiagnosticSemaKinds.td
Original file line number Diff line number Diff line change
Expand Up @@ -5278,8 +5278,6 @@ def err_typecheck_pointer_arith_void_type : Error<
"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">>;
Expand Down Expand Up @@ -7636,8 +7634,8 @@ def err_c99_array_usage_cxx : Error<
"feature, not permitted in C++">;
def err_type_requires_extension : Error<
"use of type %0 requires %1 extension to be enabled">;
def err_int128_unsupported : Error<
"__int128 is not supported on this target">;
def err_type_unsupported : Error<
"%0 is not supported on this target">;
def err_nsconsumed_attribute_mismatch : Error<
"overriding method has mismatched ns_consumed attribute on its"
" parameter">;
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/Specifiers.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ namespace clang {
TST_half, // OpenCL half, ARM NEON __fp16
TST_float,
TST_double,
TST_float128,
TST_bool, // _Bool
TST_decimal32, // _Decimal32
TST_decimal64, // _Decimal64
Expand Down
19 changes: 16 additions & 3 deletions clang/include/clang/Basic/TargetInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,13 +58,14 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
bool BigEndian;
bool TLSSupported;
bool NoAsmVariants; // True if {|} are normal characters.
bool HasFloat128;
unsigned char PointerWidth, PointerAlign;
unsigned char BoolWidth, BoolAlign;
unsigned char IntWidth, IntAlign;
unsigned char HalfWidth, HalfAlign;
unsigned char FloatWidth, FloatAlign;
unsigned char DoubleWidth, DoubleAlign;
unsigned char LongDoubleWidth, LongDoubleAlign;
unsigned char LongDoubleWidth, LongDoubleAlign, Float128Align;
unsigned char LargeArrayMinWidth, LargeArrayAlign;
unsigned char LongWidth, LongAlign;
unsigned char LongLongWidth, LongLongAlign;
Expand All @@ -78,7 +79,7 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
std::unique_ptr<llvm::DataLayout> DataLayout;
const char *MCountName;
const llvm::fltSemantics *HalfFormat, *FloatFormat, *DoubleFormat,
*LongDoubleFormat;
*LongDoubleFormat, *Float128Format;
unsigned char RegParmMax, SSERegParmMax;
TargetCXXABI TheCXXABI;
const LangAS::Map *AddrSpaceMap;
Expand Down Expand Up @@ -136,7 +137,8 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
NoFloat = 255,
Float = 0,
Double,
LongDouble
LongDouble,
Float128
};

/// \brief The different kinds of __builtin_va_list types defined by
Expand Down Expand Up @@ -327,6 +329,9 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
return getPointerWidth(0) >= 64;
} // FIXME

/// \brief Determine whether the __float128 type is supported on this target.
virtual bool hasFloat128Type() const { return HasFloat128; }

/// \brief Return the alignment that is suitable for storing any
/// object with a fundamental alignment requirement.
unsigned getSuitableAlign() const { return SuitableAlign; }
Expand Down Expand Up @@ -379,6 +384,14 @@ class TargetInfo : public RefCountedBase<TargetInfo> {
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; }
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Basic/TokenKinds.def
Original file line number Diff line number Diff line change
Expand Up @@ -380,6 +380,7 @@ KEYWORD(__builtin_offsetof , KEYALL)
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)
Expand Down
4 changes: 4 additions & 0 deletions clang/include/clang/Driver/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -1507,6 +1507,10 @@ def minvariant_function_descriptors :
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">;
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Lex/LiteralSupport.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ class NumericLiteralParser {
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 {
Expand Down
1 change: 1 addition & 0 deletions clang/include/clang/Sema/DeclSpec.h
Original file line number Diff line number Diff line change
Expand Up @@ -280,6 +280,7 @@ class DeclSpec {
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;
Expand Down
2 changes: 2 additions & 0 deletions clang/include/clang/Serialization/ASTBitCodes.h
Original file line number Diff line number Diff line change
Expand Up @@ -794,6 +794,8 @@ namespace clang {
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,
Expand Down
32 changes: 19 additions & 13 deletions clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ unsigned ASTContext::NumImplicitDestructors;
unsigned ASTContext::NumImplicitDestructorsDeclared;

enum FloatingRank {
HalfRank, FloatRank, DoubleRank, LongDoubleRank
HalfRank, FloatRank, DoubleRank, LongDoubleRank, Float128Rank
};

RawComment *ASTContext::getRawCommentForDeclNoCache(const Decl *D) const {
Expand Down Expand Up @@ -734,10 +734,9 @@ ASTContext::ASTContext(LangOptions &LOpts, SourceManager &SM,
DependentTemplateSpecializationTypes(this_()),
SubstTemplateTemplateParmPacks(this_()),
GlobalNestedNameSpecifier(nullptr), Int128Decl(nullptr),
UInt128Decl(nullptr), Float128StubDecl(nullptr),
BuiltinVaListDecl(nullptr), BuiltinMSVaListDecl(nullptr),
ObjCIdDecl(nullptr), ObjCSelDecl(nullptr), ObjCClassDecl(nullptr),
ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr),
UInt128Decl(nullptr), BuiltinVaListDecl(nullptr),
BuiltinMSVaListDecl(nullptr), ObjCIdDecl(nullptr), ObjCSelDecl(nullptr),
ObjCClassDecl(nullptr), ObjCProtocolClassDecl(nullptr), BOOLDecl(nullptr),
CFConstantStringTagDecl(nullptr), CFConstantStringTypeDecl(nullptr),
ObjCInstanceTypeDecl(nullptr), FILEDecl(nullptr), jmp_bufDecl(nullptr),
sigjmp_bufDecl(nullptr), ucontext_tDecl(nullptr),
Expand Down Expand Up @@ -967,14 +966,6 @@ TypedefDecl *ASTContext::getUInt128Decl() 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));
Expand Down Expand Up @@ -1023,6 +1014,9 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
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);
Expand Down Expand Up @@ -1084,6 +1078,7 @@ void ASTContext::InitBuiltinTypes(const TargetInfo &Target,
FloatComplexTy = getComplexType(FloatTy);
DoubleComplexTy = getComplexType(DoubleTy);
LongDoubleComplexTy = getComplexType(LongDoubleTy);
Float128ComplexTy = getComplexType(Float128Ty);

// Builtin types for 'id', 'Class', and 'SEL'.
InitBuiltinType(ObjCBuiltinIdTy, BuiltinType::ObjCId);
Expand Down Expand Up @@ -1341,6 +1336,7 @@ const llvm::fltSemantics &ASTContext::getFloatTypeSemantics(QualType T) const {
case BuiltinType::Float: return Target->getFloatFormat();
case BuiltinType::Double: return Target->getDoubleFormat();
case BuiltinType::LongDouble: return Target->getLongDoubleFormat();
case BuiltinType::Float128: return Target->getFloat128Format();
}
}

Expand Down Expand Up @@ -1651,6 +1647,10 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
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*)
Expand Down Expand Up @@ -4635,6 +4635,7 @@ static FloatingRank getFloatingRank(QualType T) {
case BuiltinType::Float: return FloatRank;
case BuiltinType::Double: return DoubleRank;
case BuiltinType::LongDouble: return LongDoubleRank;
case BuiltinType::Float128: return Float128Rank;
}
}

Expand All @@ -4651,6 +4652,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,
case FloatRank: return FloatComplexTy;
case DoubleRank: return DoubleComplexTy;
case LongDoubleRank: return LongDoubleComplexTy;
case Float128Rank: return Float128ComplexTy;
}
}

Expand All @@ -4660,6 +4662,7 @@ QualType ASTContext::getFloatingTypeOfSizeWithinDomain(QualType Size,
case FloatRank: return FloatTy;
case DoubleRank: return DoubleTy;
case LongDoubleRank: return LongDoubleTy;
case Float128Rank: return Float128Ty;
}
llvm_unreachable("getFloatingRank(): illegal value for rank");
}
Expand Down Expand Up @@ -5489,6 +5492,7 @@ static char getObjCEncodingForPrimitiveKind(const ASTContext *C,
case BuiltinType::LongDouble: return 'D';
case BuiltinType::NullPtr: return '*'; // like char*

case BuiltinType::Float128:
case BuiltinType::Half:
// FIXME: potentially need @encodes for these!
return ' ';
Expand Down Expand Up @@ -8695,6 +8699,8 @@ QualType ASTContext::getRealTypeForBitwidth(unsigned DestWidth) const {
return DoubleTy;
case TargetInfo::LongDouble:
return LongDoubleTy;
case TargetInfo::Float128:
return Float128Ty;
case TargetInfo::NoFloat:
return QualType();
}
Expand Down
8 changes: 7 additions & 1 deletion clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1992,7 +1992,7 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
// ::= f # float
// ::= d # double
// ::= e # long double, __float80
// UNSUPPORTED: ::= g # __float128
// ::= 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)
Expand Down Expand Up @@ -2073,6 +2073,12 @@ void CXXNameMangler::mangleType(const BuiltinType *T) {
? '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;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/MicrosoftMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1751,6 +1751,7 @@ void MicrosoftCXXNameMangler::mangleType(const BuiltinType *T, Qualifiers,
Out << "$$T";
break;

case BuiltinType::Float128:
case BuiltinType::Half: {
DiagnosticsEngine &Diags = Context.getDiags();
unsigned DiagID = Diags.getCustomDiagID(
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/NSAPI.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -441,6 +441,7 @@ NSAPI::getNSNumberFactoryMethodKind(QualType T) const {
case BuiltinType::Int128:
case BuiltinType::LongDouble:
case BuiltinType::UInt128:
case BuiltinType::Float128:
case BuiltinType::NullPtr:
case BuiltinType::ObjCClass:
case BuiltinType::ObjCId:
Expand Down
1 change: 1 addition & 0 deletions clang/lib/AST/StmtPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1310,6 +1310,7 @@ static void PrintFloatingLiteral(raw_ostream &OS, FloatingLiteral *Node,
case BuiltinType::Double: break; // no suffix.
case BuiltinType::Float: OS << 'F'; break;
case BuiltinType::LongDouble: OS << 'L'; break;
case BuiltinType::Float128: OS << 'Q'; break;
}
}

Expand Down
Loading

0 comments on commit bb1ea2d

Please sign in to comment.