if (!RD->getNumBases())
return;
- llvm::Type *LongLTy =
- CGM.getTypes().ConvertType(CGM.getContext().LongTy);
-
// Now add the base class descriptions.
// Itanium C++ ABI 2.9.5p6c:
// __offset_shift = 8
// };
// };
+
+ // If we're in mingw and 'long' isn't wide enough for a pointer, use 'long
+ // long' instead of 'long' for __offset_flags. libstdc++abi uses long long on
+ // LLP64 platforms.
+ // FIXME: Consider updating libc++abi to match, and extend this logic to all
+ // LLP64 platforms.
+ QualType OffsetFlagsTy = CGM.getContext().LongTy;
+ const TargetInfo &TI = CGM.getContext().getTargetInfo();
+ if (TI.getTriple().isOSCygMing() && TI.getPointerWidth(0) > TI.getLongWidth())
+ OffsetFlagsTy = CGM.getContext().LongLongTy;
+ llvm::Type *OffsetFlagsLTy =
+ CGM.getTypes().ConvertType(OffsetFlagsTy);
+
for (const auto &Base : RD->bases()) {
// The __base_type member points to the RTTI for the base type.
Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType()));
if (Base.getAccessSpecifier() == AS_public)
OffsetFlags |= BCTI_Public;
- Fields.push_back(llvm::ConstantInt::get(LongLTy, OffsetFlags));
+ Fields.push_back(llvm::ConstantInt::get(OffsetFlagsLTy, OffsetFlags));
}
}
--- /dev/null
+// RUN: %clang_cc1 -triple x86_64-windows-gnu %s -emit-llvm -o - | FileCheck %s
+struct A { int a; };
+struct B : virtual A { int b; };
+B b;
+
+// CHECK: @_ZTI1B = linkonce_odr constant { i8*, i8*, i32, i32, i8*, i64 }
+// CHECK-SAME: i8* bitcast (i8** getelementptr inbounds (i8*, i8** @_ZTVN10__cxxabiv121__vmi_class_type_infoE, i64 2) to i8*),
+// CHECK-SAME: i8* getelementptr inbounds ([3 x i8], [3 x i8]* @_ZTS1B, i32 0, i32 0),
+// CHECK-SAME: i32 0,
+// CHECK-SAME: i32 1,
+// CHECK-SAME: i8* bitcast ({ i8*, i8* }* @_ZTI1A to i8*),
+// This i64 is important, it should be an i64, not an i32.
+// CHECK-SAME: i64 -6141 }, comdat