summaryrefslogtreecommitdiff
path: root/development/qt-creator-llvm
diff options
context:
space:
mode:
Diffstat (limited to 'development/qt-creator-llvm')
-rw-r--r--development/qt-creator-llvm/patches/220_Support-std-has_unique_object_represesentations.patch739
-rw-r--r--development/qt-creator-llvm/patches/230_D40673_Add-Float128-as-alias-to-__float128.patch122
-rw-r--r--development/qt-creator-llvm/patches/README.md18
-rw-r--r--development/qt-creator-llvm/qt-creator-llvm.SlackBuild2
4 files changed, 880 insertions, 1 deletions
diff --git a/development/qt-creator-llvm/patches/220_Support-std-has_unique_object_represesentations.patch b/development/qt-creator-llvm/patches/220_Support-std-has_unique_object_represesentations.patch
new file mode 100644
index 0000000000..71ae413dd2
--- /dev/null
+++ b/development/qt-creator-llvm/patches/220_Support-std-has_unique_object_represesentations.patch
@@ -0,0 +1,739 @@
+diff --git a/tools/clang/include/clang/AST/ASTContext.h b/tools/clang/include/clang/AST/ASTContext.h
+index 703f588c56..d7beffa25e 100644
+--- a/tools/clang/include/clang/AST/ASTContext.h
++++ b/tools/clang/include/clang/AST/ASTContext.h
+@@ -2072,6 +2072,10 @@ public:
+ void CollectInheritedProtocols(const Decl *CDecl,
+ llvm::SmallPtrSet<ObjCProtocolDecl*, 8> &Protocols);
+
++ /// \brief Return true if the specified type has unique object representations
++ /// according to (C++17 [meta.unary.prop]p9)
++ bool hasUniqueObjectRepresentations(QualType Ty) const;
++
+ //===--------------------------------------------------------------------===//
+ // Type Operators
+ //===--------------------------------------------------------------------===//
+diff --git a/tools/clang/include/clang/Basic/TokenKinds.def b/tools/clang/include/clang/Basic/TokenKinds.def
+index be67663a10..90ac33b9ea 100644
+--- a/tools/clang/include/clang/Basic/TokenKinds.def
++++ b/tools/clang/include/clang/Basic/TokenKinds.def
+@@ -448,6 +448,8 @@ TYPE_TRAIT_1(__is_pod, IsPOD, KEYCXX)
+ TYPE_TRAIT_1(__is_polymorphic, IsPolymorphic, KEYCXX)
+ TYPE_TRAIT_1(__is_trivial, IsTrivial, KEYCXX)
+ TYPE_TRAIT_1(__is_union, IsUnion, KEYCXX)
++TYPE_TRAIT_1(__has_unique_object_representations,
++ HasUniqueObjectRepresentations, KEYCXX)
+
+ // Clang-only C++ Type Traits
+ TYPE_TRAIT_N(__is_trivially_constructible, IsTriviallyConstructible, KEYCXX)
+diff --git a/tools/clang/include/clang/Basic/TypeTraits.h b/tools/clang/include/clang/Basic/TypeTraits.h
+index 6aadf795d8..8ecd63f9c3 100644
+--- a/tools/clang/include/clang/Basic/TypeTraits.h
++++ b/tools/clang/include/clang/Basic/TypeTraits.h
+@@ -70,7 +70,8 @@ namespace clang {
+ UTT_IsUnsigned,
+ UTT_IsVoid,
+ UTT_IsVolatile,
+- UTT_Last = UTT_IsVolatile,
++ UTT_HasUniqueObjectRepresentations,
++ UTT_Last = UTT_HasUniqueObjectRepresentations,
+ BTT_IsBaseOf,
+ BTT_IsConvertible,
+ BTT_IsConvertibleTo,
+diff --git a/tools/clang/lib/AST/ASTContext.cpp b/tools/clang/lib/AST/ASTContext.cpp
+index c60373c5a9..1ce7d51857 100644
+--- a/tools/clang/lib/AST/ASTContext.cpp
++++ b/tools/clang/lib/AST/ASTContext.cpp
+@@ -1823,7 +1823,9 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
+ }
+ case Type::MemberPointer: {
+ const MemberPointerType *MPT = cast<MemberPointerType>(T);
+- std::tie(Width, Align) = ABI->getMemberPointerWidthAndAlign(MPT);
++ CXXABI::MemberPointerInfo MPI = ABI->getMemberPointerInfo(MPT);
++ Width = MPI.Width;
++ Align = MPI.Align;
+ break;
+ }
+ case Type::Complex: {
+@@ -2107,6 +2109,171 @@ void ASTContext::CollectInheritedProtocols(const Decl *CDecl,
+ }
+ }
+
++static bool unionHasUniqueObjectRepresentations(const ASTContext &Context,
++ const RecordDecl *RD) {
++ assert(RD->isUnion() && "Must be union type");
++ CharUnits UnionSize = Context.getTypeSizeInChars(RD->getTypeForDecl());
++
++ for (const auto *Field : RD->fields()) {
++ if (!Context.hasUniqueObjectRepresentations(Field->getType()))
++ return false;
++ CharUnits FieldSize = Context.getTypeSizeInChars(Field->getType());
++ if (FieldSize != UnionSize)
++ return false;
++ }
++ return !RD->field_empty();
++}
++
++bool isStructEmpty(QualType Ty) {
++ const RecordDecl *RD = Ty->castAs<RecordType>()->getDecl();
++
++ if (!RD->field_empty())
++ return false;
++
++ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RD))
++ return ClassDecl->isEmpty();
++
++ return true;
++}
++
++static llvm::Optional<int64_t>
++structHasUniqueObjectRepresentations(const ASTContext &Context,
++ const RecordDecl *RD) {
++ assert(!RD->isUnion() && "Must be struct/class type");
++ const auto &Layout = Context.getASTRecordLayout(RD);
++
++ int64_t CurOffsetInBits = 0;
++ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RD)) {
++ if (ClassDecl->isDynamicClass())
++ return llvm::None;
++
++ SmallVector<std::pair<QualType, int64_t>, 4> Bases;
++ for (const auto Base : ClassDecl->bases()) {
++ // Empty types can be inherited from, and non-empty types can potentially
++ // have tail padding, so just make sure there isn't an error.
++ if (!isStructEmpty(Base.getType())) {
++ llvm::Optional<int64_t> Size = structHasUniqueObjectRepresentations(
++ Context, Base.getType()->getAs<RecordType>()->getDecl());
++ if (!Size)
++ return llvm::None;
++ Bases.emplace_back(Base.getType(), Size.getValue());
++ }
++ }
++
++ std::sort(
++ Bases.begin(), Bases.end(), [&](const std::pair<QualType, int64_t> &L,
++ const std::pair<QualType, int64_t> &R) {
++ return Layout.getBaseClassOffset(L.first->getAsCXXRecordDecl()) <
++ Layout.getBaseClassOffset(R.first->getAsCXXRecordDecl());
++ });
++
++ for (const auto Base : Bases) {
++ int64_t BaseOffset = Context.toBits(
++ Layout.getBaseClassOffset(Base.first->getAsCXXRecordDecl()));
++ int64_t BaseSize = Base.second;
++ if (BaseOffset != CurOffsetInBits)
++ return llvm::None;
++ CurOffsetInBits = BaseOffset + BaseSize;
++ }
++ }
++
++ for (const auto *Field : RD->fields()) {
++ if (!Field->getType()->isReferenceType() &&
++ !Context.hasUniqueObjectRepresentations(Field->getType()))
++ return llvm::None;
++
++ int64_t FieldSizeInBits =
++ Context.toBits(Context.getTypeSizeInChars(Field->getType()));
++ if (Field->isBitField()) {
++ int64_t BitfieldSize = Field->getBitWidthValue(Context);
++
++ if (BitfieldSize > FieldSizeInBits)
++ return llvm::None;
++ FieldSizeInBits = BitfieldSize;
++ }
++
++ int64_t FieldOffsetInBits = Context.getFieldOffset(Field);
++
++ if (FieldOffsetInBits != CurOffsetInBits)
++ return llvm::None;
++
++ CurOffsetInBits = FieldSizeInBits + FieldOffsetInBits;
++ }
++
++ return CurOffsetInBits;
++}
++
++bool ASTContext::hasUniqueObjectRepresentations(QualType Ty) const {
++ // C++17 [meta.unary.prop]:
++ // The predicate condition for a template specialization
++ // has_unique_object_representations<T> shall be
++ // satisfied if and only if:
++ // (9.1) - T is trivially copyable, and
++ // (9.2) - any two objects of type T with the same value have the same
++ // object representation, where two objects
++ // of array or non-union class type are considered to have the same value
++ // if their respective sequences of
++ // direct subobjects have the same values, and two objects of union type
++ // are considered to have the same
++ // value if they have the same active member and the corresponding members
++ // have the same value.
++ // The set of scalar types for which this condition holds is
++ // implementation-defined. [ Note: If a type has padding
++ // bits, the condition does not hold; otherwise, the condition holds true
++ // for unsigned integral types. -- end note ]
++ assert(!Ty.isNull() && "Null QualType sent to unique object rep check");
++
++ // Arrays are unique only if their element type is unique.
++ if (Ty->isArrayType())
++ return hasUniqueObjectRepresentations(getBaseElementType(Ty));
++
++ // (9.1) - T is trivially copyable...
++ if (!Ty.isTriviallyCopyableType(*this))
++ return false;
++
++ // All integrals and enums are unique.
++ if (Ty->isIntegralOrEnumerationType())
++ return true;
++
++ // All other pointers are unique.
++ if (Ty->isPointerType())
++ return true;
++
++ if (Ty->isMemberPointerType()) {
++ const MemberPointerType *MPT = Ty->getAs<MemberPointerType>();
++ return !ABI->getMemberPointerInfo(MPT).HasPadding;
++ }
++
++ if (Ty->isRecordType()) {
++ const RecordDecl *Record = Ty->getAs<RecordType>()->getDecl();
++
++ if (Record->isInvalidDecl())
++ return false;
++
++ if (Record->isUnion())
++ return unionHasUniqueObjectRepresentations(*this, Record);
++
++ Optional<int64_t> StructSize =
++ structHasUniqueObjectRepresentations(*this, Record);
++
++ return StructSize &&
++ StructSize.getValue() == static_cast<int64_t>(getTypeSize(Ty));
++ }
++
++ // FIXME: More cases to handle here (list by rsmith):
++ // vectors (careful about, eg, vector of 3 foo)
++ // _Complex int and friends
++ // _Atomic T
++ // Obj-C block pointers
++ // Obj-C object pointers
++ // and perhaps OpenCL's various builtin types (pipe, sampler_t, event_t,
++ // clk_event_t, queue_t, reserve_id_t)
++ // There're also Obj-C class types and the Obj-C selector type, but I think it
++ // makes sense for those to return false here.
++
++ return false;
++}
++
+ unsigned ASTContext::CountNonClassIvars(const ObjCInterfaceDecl *OI) const {
+ unsigned count = 0;
+ // Count ivars declared in class extension.
+diff --git a/tools/clang/lib/AST/CXXABI.h b/tools/clang/lib/AST/CXXABI.h
+index 924ef00e81..06295b5817 100644
+--- a/tools/clang/lib/AST/CXXABI.h
++++ b/tools/clang/lib/AST/CXXABI.h
+@@ -31,9 +31,16 @@ class CXXABI {
+ public:
+ virtual ~CXXABI();
+
+- /// Returns the width and alignment of a member pointer in bits.
+- virtual std::pair<uint64_t, unsigned>
+- getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const = 0;
++ struct MemberPointerInfo {
++ uint64_t Width;
++ unsigned Align;
++ bool HasPadding;
++ };
++
++ /// Returns the width and alignment of a member pointer in bits, as well as
++ /// whether it has padding.
++ virtual MemberPointerInfo
++ getMemberPointerInfo(const MemberPointerType *MPT) const = 0;
+
+ /// Returns the default calling convention for C++ methods.
+ virtual CallingConv getDefaultMethodCallConv(bool isVariadic) const = 0;
+diff --git a/tools/clang/lib/AST/ItaniumCXXABI.cpp b/tools/clang/lib/AST/ItaniumCXXABI.cpp
+index 692a455eaf..d6bc16b635 100644
+--- a/tools/clang/lib/AST/ItaniumCXXABI.cpp
++++ b/tools/clang/lib/AST/ItaniumCXXABI.cpp
+@@ -101,15 +101,17 @@ protected:
+ public:
+ ItaniumCXXABI(ASTContext &Ctx) : Context(Ctx) { }
+
+- std::pair<uint64_t, unsigned>
+- getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override {
++ MemberPointerInfo
++ getMemberPointerInfo(const MemberPointerType *MPT) const override {
+ const TargetInfo &Target = Context.getTargetInfo();
+ TargetInfo::IntType PtrDiff = Target.getPtrDiffType(0);
+- uint64_t Width = Target.getTypeWidth(PtrDiff);
+- unsigned Align = Target.getTypeAlign(PtrDiff);
++ MemberPointerInfo MPI;
++ MPI.Width = Target.getTypeWidth(PtrDiff);
++ MPI.Align = Target.getTypeAlign(PtrDiff);
++ MPI.HasPadding = false;
+ if (MPT->isMemberFunctionPointer())
+- Width = 2 * Width;
+- return std::make_pair(Width, Align);
++ MPI.Width *= 2;
++ return MPI;
+ }
+
+ CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
+diff --git a/tools/clang/lib/AST/MicrosoftCXXABI.cpp b/tools/clang/lib/AST/MicrosoftCXXABI.cpp
+index 73324e40f3..b19491f313 100644
+--- a/tools/clang/lib/AST/MicrosoftCXXABI.cpp
++++ b/tools/clang/lib/AST/MicrosoftCXXABI.cpp
+@@ -76,8 +76,8 @@ class MicrosoftCXXABI : public CXXABI {
+ public:
+ MicrosoftCXXABI(ASTContext &Ctx) : Context(Ctx) { }
+
+- std::pair<uint64_t, unsigned>
+- getMemberPointerWidthAndAlign(const MemberPointerType *MPT) const override;
++ MemberPointerInfo
++ getMemberPointerInfo(const MemberPointerType *MPT) const override;
+
+ CallingConv getDefaultMethodCallConv(bool isVariadic) const override {
+ if (!isVariadic &&
+@@ -227,7 +227,7 @@ getMSMemberPointerSlots(const MemberPointerType *MPT) {
+ return std::make_pair(Ptrs, Ints);
+ }
+
+-std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
++CXXABI::MemberPointerInfo MicrosoftCXXABI::getMemberPointerInfo(
+ const MemberPointerType *MPT) const {
+ // The nominal struct is laid out with pointers followed by ints and aligned
+ // to a pointer width if any are present and an int width otherwise.
+@@ -237,22 +237,25 @@ std::pair<uint64_t, unsigned> MicrosoftCXXABI::getMemberPointerWidthAndAlign(
+
+ unsigned Ptrs, Ints;
+ std::tie(Ptrs, Ints) = getMSMemberPointerSlots(MPT);
+- uint64_t Width = Ptrs * PtrSize + Ints * IntSize;
+- unsigned Align;
++ MemberPointerInfo MPI;
++ MPI.HasPadding = false;
++ MPI.Width = Ptrs * PtrSize + Ints * IntSize;
+
+ // When MSVC does x86_32 record layout, it aligns aggregate member pointers to
+ // 8 bytes. However, __alignof usually returns 4 for data memptrs and 8 for
+ // function memptrs.
+ if (Ptrs + Ints > 1 && Target.getTriple().isArch32Bit())
+- Align = 64;
++ MPI.Align = 64;
+ else if (Ptrs)
+- Align = Target.getPointerAlign(0);
++ MPI.Align = Target.getPointerAlign(0);
+ else
+- Align = Target.getIntAlign();
++ MPI.Align = Target.getIntAlign();
+
+- if (Target.getTriple().isArch64Bit())
+- Width = llvm::alignTo(Width, Align);
+- return std::make_pair(Width, Align);
++ if (Target.getTriple().isArch64Bit()) {
++ MPI.Width = llvm::alignTo(MPI.Width, MPI.Align);
++ MPI.HasPadding = MPI.Width != (Ptrs * PtrSize + Ints * IntSize);
++ }
++ return MPI;
+ }
+
+ CXXABI *clang::CreateMicrosoftCXXABI(ASTContext &Ctx) {
+diff --git a/tools/clang/lib/Parse/ParseExpr.cpp b/tools/clang/lib/Parse/ParseExpr.cpp
+index 44b87af01a..73aac10c23 100644
+--- a/tools/clang/lib/Parse/ParseExpr.cpp
++++ b/tools/clang/lib/Parse/ParseExpr.cpp
+@@ -716,6 +716,7 @@ class CastExpressionIdValidator : public CorrectionCandidateCallback {
+ /// '__is_sealed' [MS]
+ /// '__is_trivial'
+ /// '__is_union'
++/// '__has_unique_object_representations'
+ ///
+ /// [Clang] unary-type-trait:
+ /// '__is_aggregate'
+diff --git a/tools/clang/lib/Sema/SemaExprCXX.cpp b/tools/clang/lib/Sema/SemaExprCXX.cpp
+index a9cf3ec799..a7d75ad977 100644
+--- a/tools/clang/lib/Sema/SemaExprCXX.cpp
++++ b/tools/clang/lib/Sema/SemaExprCXX.cpp
+@@ -4141,6 +4141,7 @@ static bool CheckUnaryTypeTraitTypeCompleteness(Sema &S, TypeTrait UTT,
+ case UTT_IsDestructible:
+ case UTT_IsNothrowDestructible:
+ case UTT_IsTriviallyDestructible:
++ case UTT_HasUniqueObjectRepresentations:
+ if (ArgTy->isIncompleteArrayType() || ArgTy->isVoidType())
+ return true;
+
+@@ -4580,6 +4581,8 @@ static bool EvaluateUnaryTypeTrait(Sema &Self, TypeTrait UTT,
+ // Returns True if and only if T is a complete type at the point of the
+ // function call.
+ return !T->isIncompleteType();
++ case UTT_HasUniqueObjectRepresentations:
++ return C.hasUniqueObjectRepresentations(T);
+ }
+ }
+
+diff --git a/tools/clang/test/SemaCXX/has_unique_object_reps_member_ptr.cpp b/tools/clang/test/SemaCXX/has_unique_object_reps_member_ptr.cpp
+new file mode 100644
+index 0000000000..b8e27f82ff
+--- /dev/null
++++ b/tools/clang/test/SemaCXX/has_unique_object_reps_member_ptr.cpp
+@@ -0,0 +1,32 @@
++// RUN: %clang_cc1 -triple x86_64-linux-pc -DIS64 -fsyntax-only -verify -std=c++17 %s
++// RUN: %clang_cc1 -triple x86_64-windows-pc -DIS64 -fsyntax-only -verify -std=c++17 %s
++// RUN: %clang_cc1 -triple i386-linux-pc -fsyntax-only -verify -std=c++17 %s
++// RUN: %clang_cc1 -triple i386-windows-pc -DW32 -fsyntax-only -verify -std=c++17 %s
++// expected-no-diagnostics
++
++struct Base {};
++struct A : virtual Base {
++ virtual void n() {}
++};
++
++auto p = &A::n;
++static_assert(__has_unique_object_representations(decltype(p)));
++
++struct B {
++ decltype(p) x;
++ int b;
++#ifdef IS64
++ // required on 64 bit to fill out the tail padding.
++ int c;
++#endif
++};
++static_assert(__has_unique_object_representations(B));
++
++struct C { // has padding on Win32, but nothing else.
++ decltype(p) x;
++};
++#ifdef W32
++static_assert(!__has_unique_object_representations(C));
++#else
++static_assert(__has_unique_object_representations(C));
++#endif
+diff --git a/tools/clang/test/SemaCXX/type-traits.cpp b/tools/clang/test/SemaCXX/type-traits.cpp
+index 5879a77dd5..3c2f9c7f0f 100644
+--- a/tools/clang/test/SemaCXX/type-traits.cpp
++++ b/tools/clang/test/SemaCXX/type-traits.cpp
+@@ -2352,3 +2352,321 @@ void is_trivially_destructible_test() {
+ { int arr[F(__is_trivially_destructible(void))]; }
+ { int arr[F(__is_trivially_destructible(const volatile void))]; }
+ }
++
++// Instantiation of __has_unique_object_representations
++template <typename T>
++struct has_unique_object_representations {
++ static const bool value = __has_unique_object_representations(T);
++};
++
++static_assert(!has_unique_object_representations<void>::value, "void is never unique");
++static_assert(!has_unique_object_representations<const void>::value, "void is never unique");
++static_assert(!has_unique_object_representations<volatile void>::value, "void is never unique");
++static_assert(!has_unique_object_representations<const volatile void>::value, "void is never unique");
++
++static_assert(has_unique_object_representations<int>::value, "integrals are");
++static_assert(has_unique_object_representations<const int>::value, "integrals are");
++static_assert(has_unique_object_representations<volatile int>::value, "integrals are");
++static_assert(has_unique_object_representations<const volatile int>::value, "integrals are");
++
++static_assert(has_unique_object_representations<void *>::value, "as are pointers");
++static_assert(has_unique_object_representations<const void *>::value, "as are pointers");
++static_assert(has_unique_object_representations<volatile void *>::value, "are pointers");
++static_assert(has_unique_object_representations<const volatile void *>::value, "as are pointers");
++
++static_assert(has_unique_object_representations<int *>::value, "as are pointers");
++static_assert(has_unique_object_representations<const int *>::value, "as are pointers");
++static_assert(has_unique_object_representations<volatile int *>::value, "as are pointers");
++static_assert(has_unique_object_representations<const volatile int *>::value, "as are pointers");
++
++class C {};
++using FP = int (*)(int);
++using PMF = int (C::*)(int);
++using PMD = int C::*;
++
++static_assert(has_unique_object_representations<FP>::value, "even function pointers");
++static_assert(has_unique_object_representations<const FP>::value, "even function pointers");
++static_assert(has_unique_object_representations<volatile FP>::value, "even function pointers");
++static_assert(has_unique_object_representations<const volatile FP>::value, "even function pointers");
++
++static_assert(has_unique_object_representations<PMF>::value, "and pointer to members");
++static_assert(has_unique_object_representations<const PMF>::value, "and pointer to members");
++static_assert(has_unique_object_representations<volatile PMF>::value, "and pointer to members");
++static_assert(has_unique_object_representations<const volatile PMF>::value, "and pointer to members");
++
++static_assert(has_unique_object_representations<PMD>::value, "and pointer to members");
++static_assert(has_unique_object_representations<const PMD>::value, "and pointer to members");
++static_assert(has_unique_object_representations<volatile PMD>::value, "and pointer to members");
++static_assert(has_unique_object_representations<const volatile PMD>::value, "and pointer to members");
++
++static_assert(has_unique_object_representations<bool>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<char>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<signed char>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<unsigned char>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<short>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<unsigned short>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<int>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<unsigned int>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<long>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<unsigned long>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<long long>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<unsigned long long>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<wchar_t>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<char16_t>::value, "yes, all integral types");
++static_assert(has_unique_object_representations<char32_t>::value, "yes, all integral types");
++
++static_assert(!has_unique_object_representations<void>::value, "but not void!");
++static_assert(!has_unique_object_representations<decltype(nullptr)>::value, "or nullptr_t");
++static_assert(!has_unique_object_representations<float>::value, "definitely not Floating Point");
++static_assert(!has_unique_object_representations<double>::value, "definitely not Floating Point");
++static_assert(!has_unique_object_representations<long double>::value, "definitely not Floating Point");
++
++struct NoPadding {
++ int a;
++ int b;
++};
++
++static_assert(has_unique_object_representations<NoPadding>::value, "types without padding are");
++
++struct InheritsFromNoPadding : NoPadding {
++ int c;
++ int d;
++};
++
++static_assert(has_unique_object_representations<InheritsFromNoPadding>::value, "types without padding are");
++
++struct VirtuallyInheritsFromNoPadding : virtual NoPadding {
++ int c;
++ int d;
++};
++
++static_assert(!has_unique_object_representations<VirtuallyInheritsFromNoPadding>::value, "No virtual inheritence");
++
++struct Padding {
++ char a;
++ int b;
++};
++
++//static_assert(!has_unique_object_representations<Padding>::value, "but not with padding");
++
++struct InheritsFromPadding : Padding {
++ int c;
++ int d;
++};
++
++static_assert(!has_unique_object_representations<InheritsFromPadding>::value, "or its subclasses");
++
++struct TailPadding {
++ int a;
++ char b;
++};
++
++static_assert(!has_unique_object_representations<TailPadding>::value, "even at the end");
++
++struct TinyStruct {
++ char a;
++};
++
++static_assert(has_unique_object_representations<TinyStruct>::value, "Should be no padding");
++
++struct InheritsFromTinyStruct : TinyStruct {
++ int b;
++};
++
++static_assert(!has_unique_object_representations<InheritsFromTinyStruct>::value, "Inherit causes padding");
++
++union NoPaddingUnion {
++ int a;
++ unsigned int b;
++};
++
++static_assert(has_unique_object_representations<NoPaddingUnion>::value, "unions follow the same rules as structs");
++
++union PaddingUnion {
++ int a;
++ long long b;
++};
++
++static_assert(!has_unique_object_representations<PaddingUnion>::value, "unions follow the same rules as structs");
++
++struct NotTriviallyCopyable {
++ int x;
++ NotTriviallyCopyable(const NotTriviallyCopyable &) {}
++};
++
++static_assert(!has_unique_object_representations<NotTriviallyCopyable>::value, "must be trivially copyable");
++
++struct HasNonUniqueMember {
++ float x;
++};
++
++static_assert(!has_unique_object_representations<HasNonUniqueMember>::value, "all members must be unique");
++
++enum ExampleEnum { xExample,
++ yExample };
++enum LLEnum : long long { xLongExample,
++ yLongExample };
++
++static_assert(has_unique_object_representations<ExampleEnum>::value, "Enums are integrals, so unique!");
++static_assert(has_unique_object_representations<LLEnum>::value, "Enums are integrals, so unique!");
++
++enum class ExampleEnumClass { xExample,
++ yExample };
++enum class LLEnumClass : long long { xLongExample,
++ yLongExample };
++
++static_assert(has_unique_object_representations<ExampleEnumClass>::value, "Enums are integrals, so unique!");
++static_assert(has_unique_object_representations<LLEnumClass>::value, "Enums are integrals, so unique!");
++
++// because references aren't trivially copyable.
++static_assert(!has_unique_object_representations<int &>::value, "No references!");
++static_assert(!has_unique_object_representations<const int &>::value, "No references!");
++static_assert(!has_unique_object_representations<volatile int &>::value, "No references!");
++static_assert(!has_unique_object_representations<const volatile int &>::value, "No references!");
++static_assert(!has_unique_object_representations<Empty>::value, "No empty types!");
++static_assert(!has_unique_object_representations<EmptyUnion>::value, "No empty types!");
++
++class Compressed : Empty {
++ int x;
++};
++
++static_assert(has_unique_object_representations<Compressed>::value, "But inheriting from one is ok");
++
++class EmptyInheritor : Compressed {};
++
++static_assert(has_unique_object_representations<EmptyInheritor>::value, "As long as the base has items, empty is ok");
++
++class Dynamic {
++ virtual void A();
++ int i;
++};
++
++static_assert(!has_unique_object_representations<Dynamic>::value, "Dynamic types are not valid");
++
++class InheritsDynamic : Dynamic {
++ int j;
++};
++
++static_assert(!has_unique_object_representations<InheritsDynamic>::value, "Dynamic types are not valid");
++
++static_assert(has_unique_object_representations<int[42]>::value, "Arrays are fine, as long as their value type is");
++static_assert(has_unique_object_representations<int[]>::value, "Arrays are fine, as long as their value type is");
++static_assert(has_unique_object_representations<int[][42]>::value, "Arrays are fine, as long as their value type is");
++static_assert(!has_unique_object_representations<double[42]>::value, "So no array of doubles!");
++static_assert(!has_unique_object_representations<double[]>::value, "So no array of doubles!");
++static_assert(!has_unique_object_representations<double[][42]>::value, "So no array of doubles!");
++
++struct __attribute__((aligned(16))) WeirdAlignment {
++ int i;
++};
++union __attribute__((aligned(16))) WeirdAlignmentUnion {
++ int i;
++};
++static_assert(!has_unique_object_representations<WeirdAlignment>::value, "Alignment causes padding");
++static_assert(!has_unique_object_representations<WeirdAlignmentUnion>::value, "Alignment causes padding");
++static_assert(!has_unique_object_representations<WeirdAlignment[42]>::value, "Also no arrays that have padding");
++
++static_assert(!has_unique_object_representations<int(int)>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int) const>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int) volatile>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int) const volatile>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int) &>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int) const &>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int) volatile &>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int) const volatile &>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int) &&>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int) const &&>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int) volatile &&>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int) const volatile &&>::value, "Functions are not unique");
++
++static_assert(!has_unique_object_representations<int(int, ...)>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int, ...) const>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int, ...) volatile>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int, ...) const volatile>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int, ...) &>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int, ...) const &>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int, ...) volatile &>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int, ...) const volatile &>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int, ...) &&>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int, ...) const &&>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int, ...) volatile &&>::value, "Functions are not unique");
++static_assert(!has_unique_object_representations<int(int, ...) const volatile &&>::value, "Functions are not unique");
++
++void foo(){
++ static auto lambda = []() {};
++ static_assert(!has_unique_object_representations<decltype(lambda)>::value, "Lambdas follow struct rules");
++ int i;
++ static auto lambda2 = [i]() {};
++ static_assert(has_unique_object_representations<decltype(lambda2)>::value, "Lambdas follow struct rules");
++}
++
++struct PaddedBitfield {
++ char c : 6;
++ char d : 1;
++};
++
++struct UnPaddedBitfield {
++ char c : 6;
++ char d : 2;
++};
++
++struct AlignedPaddedBitfield {
++ char c : 6;
++ __attribute__((aligned(1)))
++ char d : 2;
++};
++
++static_assert(!has_unique_object_representations<PaddedBitfield>::value, "Bitfield padding");
++static_assert(has_unique_object_representations<UnPaddedBitfield>::value, "Bitfield padding");
++static_assert(!has_unique_object_representations<AlignedPaddedBitfield>::value, "Bitfield padding");
++
++struct BoolBitfield {
++ bool b : 8;
++};
++
++static_assert(has_unique_object_representations<BoolBitfield>::value, "Bitfield bool");
++
++struct BoolBitfield2 {
++ bool b : 16;
++};
++
++static_assert(!has_unique_object_representations<BoolBitfield2>::value, "Bitfield bool");
++
++struct GreaterSizeBitfield {
++ //expected-warning@+1 {{width of bit-field 'n'}}
++ int n : 1024;
++};
++
++static_assert(sizeof(GreaterSizeBitfield) == 128, "Bitfield Size");
++static_assert(!has_unique_object_representations<GreaterSizeBitfield>::value, "Bitfield padding");
++
++struct StructWithRef {
++ int &I;
++};
++
++static_assert(has_unique_object_representations<StructWithRef>::value, "References are still unique");
++
++struct NotUniqueBecauseTailPadding {
++ int &r;
++ char a;
++};
++struct CanBeUniqueIfNoPadding : NotUniqueBecauseTailPadding {
++ char b[7];
++};
++
++static_assert(!has_unique_object_representations<NotUniqueBecauseTailPadding>::value,
++ "non trivial");
++// Can be unique on Itanium, since the is child class' data is 'folded' into the
++// parent's tail padding.
++static_assert(sizeof(CanBeUniqueIfNoPadding) != 16 ||
++ has_unique_object_representations<CanBeUniqueIfNoPadding>::value,
++ "inherit from std layout");
++
++namespace ErrorType {
++ struct S; //expected-note{{forward declaration of 'ErrorType::S'}}
++
++ struct T {
++ S t; //expected-error{{field has incomplete type 'ErrorType::S'}}
++ };
++ bool b = __has_unique_object_representations(T);
++};
+--
+2.14.1
+
diff --git a/development/qt-creator-llvm/patches/230_D40673_Add-Float128-as-alias-to-__float128.patch b/development/qt-creator-llvm/patches/230_D40673_Add-Float128-as-alias-to-__float128.patch
new file mode 100644
index 0000000000..b1ca72f0f1
--- /dev/null
+++ b/development/qt-creator-llvm/patches/230_D40673_Add-Float128-as-alias-to-__float128.patch
@@ -0,0 +1,122 @@
+diff --git a/tools/clang/include/clang/Basic/TokenKinds.def b/tools/clang/include/clang/Basic/TokenKinds.def
+index 90ac33b9ea..67fea10788 100644
+--- a/tools/clang/include/clang/Basic/TokenKinds.def
++++ b/tools/clang/include/clang/Basic/TokenKinds.def
+@@ -390,6 +390,7 @@ TYPE_TRAIT_2(__builtin_types_compatible_p, TypeCompatible, KEYNOCXX)
+ KEYWORD(__builtin_va_arg , KEYALL)
+ KEYWORD(__extension__ , KEYALL)
+ KEYWORD(__float128 , KEYALL)
++ALIAS("_Float128", __float128 , KEYNOCXX)
+ KEYWORD(__imag , KEYALL)
+ KEYWORD(__int128 , KEYALL)
+ KEYWORD(__label__ , KEYALL)
+diff --git a/tools/clang/lib/Frontend/InitPreprocessor.cpp b/tools/clang/lib/Frontend/InitPreprocessor.cpp
+index 92d61369b4..8edc06fe93 100644
+--- a/tools/clang/lib/Frontend/InitPreprocessor.cpp
++++ b/tools/clang/lib/Frontend/InitPreprocessor.cpp
+@@ -790,6 +790,10 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
+ DefineFloatMacros(Builder, "FLT", &TI.getFloatFormat(), "F");
+ DefineFloatMacros(Builder, "DBL", &TI.getDoubleFormat(), "");
+ DefineFloatMacros(Builder, "LDBL", &TI.getLongDoubleFormat(), "L");
++ if (TI.hasFloat128Type())
++ // FIXME: Switch away from the non-standard "Q" when we can
++ DefineFloatMacros(Builder, "FLT128", &TI.getFloat128Format(), "Q");
++
+
+ // Define a __POINTER_WIDTH__ macro for stdint.h.
+ Builder.defineMacro("__POINTER_WIDTH__",
+diff --git a/tools/clang/test/Preprocessor/cuda-types.cu b/tools/clang/test/Preprocessor/cuda-types.cu
+index 5f7b91655c..9e96f6a15e 100644
+--- a/tools/clang/test/Preprocessor/cuda-types.cu
++++ b/tools/clang/test/Preprocessor/cuda-types.cu
+@@ -5,42 +5,44 @@
+ // FIXME: We really should make __GCC_HAVE_SYNC_COMPARE_AND_SWAP identical on
+ // host and device, but architecturally this is difficult at the moment.
+
++// RUN: mkdir -p %t
++
+ // RUN: %clang --cuda-host-only -nocudainc -target i386-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
+ // RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-host-defines-filtered
++// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/i386-host-defines-filtered
+ // RUN: %clang --cuda-device-only -nocudainc -nocudalib -target i386-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
+ // RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-device-defines-filtered
+-// RUN: diff %T/i386-host-defines-filtered %T/i386-device-defines-filtered
++// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/i386-device-defines-filtered
++// RUN: diff %t/i386-host-defines-filtered %t/i386-device-defines-filtered
+
+ // RUN: %clang --cuda-host-only -nocudainc -target x86_64-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
+ // RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-host-defines-filtered
++// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/x86_64-host-defines-filtered
+ // RUN: %clang --cuda-device-only -nocudainc -nocudalib -target x86_64-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
+ // RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-device-defines-filtered
+-// RUN: diff %T/x86_64-host-defines-filtered %T/x86_64-device-defines-filtered
++// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/x86_64-device-defines-filtered
++// RUN: diff %t/x86_64-host-defines-filtered %t/x86_64-device-defines-filtered
+
+ // RUN: %clang --cuda-host-only -nocudainc -target powerpc64-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
+ // RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/powerpc64-host-defines-filtered
++// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/powerpc64-host-defines-filtered
+ // RUN: %clang --cuda-device-only -nocudainc -nocudalib -target powerpc64-unknown-linux-gnu -x cuda -E -dM -o - /dev/null \
+ // RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/powerpc64-device-defines-filtered
+-// RUN: diff %T/powerpc64-host-defines-filtered %T/powerpc64-device-defines-filtered
++// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/powerpc64-device-defines-filtered
++// RUN: diff %t/powerpc64-host-defines-filtered %t/powerpc64-device-defines-filtered
+
+ // RUN: %clang --cuda-host-only -nocudainc -target i386-windows-msvc -x cuda -E -dM -o - /dev/null \
+ // RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-msvc-host-defines-filtered
++// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/i386-msvc-host-defines-filtered
+ // RUN: %clang --cuda-device-only -nocudainc -nocudalib -target i386-windows-msvc -x cuda -E -dM -o - /dev/null \
+ // RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/i386-msvc-device-defines-filtered
+-// RUN: diff %T/i386-msvc-host-defines-filtered %T/i386-msvc-device-defines-filtered
++// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/i386-msvc-device-defines-filtered
++// RUN: diff %t/i386-msvc-host-defines-filtered %t/i386-msvc-device-defines-filtered
+
+ // RUN: %clang --cuda-host-only -nocudainc -target x86_64-windows-msvc -x cuda -E -dM -o - /dev/null \
+ // RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-msvc-host-defines-filtered
++// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/x86_64-msvc-host-defines-filtered
+ // RUN: %clang --cuda-device-only -nocudainc -nocudalib -target x86_64-windows-msvc -x cuda -E -dM -o - /dev/null \
+ // RUN: | grep 'define __[^ ]*\(TYPE\|MAX\|SIZEOF|WIDTH\)\|define __GCC_ATOMIC' \
+-// RUN: | grep -v '__LDBL\|_LONG_DOUBLE' > %T/x86_64-msvc-device-defines-filtered
+-// RUN: diff %T/x86_64-msvc-host-defines-filtered %T/x86_64-msvc-device-defines-filtered
++// RUN: | grep -v '__FLT128\|__LDBL\|_LONG_DOUBLE' > %t/x86_64-msvc-device-defines-filtered
++// RUN: diff %t/x86_64-msvc-host-defines-filtered %t/x86_64-msvc-device-defines-filtered
+diff --git a/tools/clang/test/Sema/_Float128.c b/tools/clang/test/Sema/_Float128.c
+new file mode 100644
+index 0000000000..f0c3c6d555
+--- /dev/null
++++ b/tools/clang/test/Sema/_Float128.c
+@@ -0,0 +1,22 @@
++// RUN: %clang_cc1 -verify %s
++// RUN: %clang_cc1 -triple powerpc64-linux -verify %s
++// RUN: %clang_cc1 -triple i686-windows-gnu -verify %s
++// RUN: %clang_cc1 -triple x86_64-windows-gnu -verify %s
++// RUN: %clang_cc1 -triple x86_64-windows-msvc -verify %s
++
++#if defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
++_Float128 f;
++_Float128 tiny = __FLT128_EPSILON__;
++int g(int x, _Float128 *y) {
++ return x + *y;
++}
++
++// expected-no-diagnostics
++#else
++_Float128 f; // expected-error {{__float128 is not supported on this target}}
++float tiny = __FLT128_EPSILON__; // expected-error{{use of undeclared identifier}}
++int g(int x, _Float128 *y) { // expected-error {{__float128 is not supported on this target}}
++ return x + *y;
++}
++
++#endif // defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
+--
+2.14.1
+
diff --git a/development/qt-creator-llvm/patches/README.md b/development/qt-creator-llvm/patches/README.md
index 86e84e74de..d57bb1d5ef 100644
--- a/development/qt-creator-llvm/patches/README.md
+++ b/development/qt-creator-llvm/patches/README.md
@@ -94,6 +94,24 @@ Some classes have totally broken highlighting (like classes inside texteditor.cp
Improves pretty printing for tooltips.
+##### 220_Support-std-has_unique_object_represesentations.patch
+
+* https://reviews.llvm.org/D39064 mplement __has_unique_object_representations
+* https://reviews.llvm.org/D39347 Fix __has_unique_object_representations implementation
+* (without review, git sha1 133cba2f9263f63f44b6b086a500f374bff13eee) Fix ICE when __has_unqiue_object_representations called with invalid decl
+* (without review, git cb61fc53dc997bca3bee98d898d3406d0acb221c) Revert unintended hunk from ICE-Change
+* https://reviews.llvm.org/D42863 Make __has_unique_object_representations reject empty union types.
+
+Backport patches implementing std::has_unique_object_representations for
+parsing type_traits header of stdlibc++ 7.
+
+
+##### 230_D40673_Add-Float128-as-alias-to-__float128.patch
+
+* https://reviews.llvm.org/D40673
+
+Fixes parsing stdlib.h with -DGNU_SOURCE for GCC 7.2 (and maybe others).
+
Additional changes
------------------
diff --git a/development/qt-creator-llvm/qt-creator-llvm.SlackBuild b/development/qt-creator-llvm/qt-creator-llvm.SlackBuild
index a05bc9d5f1..4a8d471699 100644
--- a/development/qt-creator-llvm/qt-creator-llvm.SlackBuild
+++ b/development/qt-creator-llvm/qt-creator-llvm.SlackBuild
@@ -26,7 +26,7 @@ PRGNAM=qt-creator-llvm
VERSION=${VERSION:-5.0.1_427ad76}
VERSION_CLAZY=${VERSION_CLAZY:-427ad7689ac65bc4106c0a420c1165cc57f1eef7}
VERSION_LLVM=$( echo $VERSION | cut -f1 -d_ )
-BUILD=${BUILD:-1}
+BUILD=${BUILD:-2}
TAG=${TAG:-_SBo}
if [ -z "$ARCH" ]; then