mirror of
https://github.com/capstone-engine/llvm-capstone.git
synced 2024-11-23 22:00:10 +00:00
[Clang] Directly create opaque pointers
In CGTypes, directly create opaque pointers, without computing the LLVM element type. This is not as straightforward as I though it would be, because apparently computing the LLVM type also causes a number of side effects. In particular, we no longer produce diagnostics like -Wpacked for typed (only) behind pointers, because we no longer depend on their layout. Differential Revision: https://reviews.llvm.org/D152505
This commit is contained in:
parent
742040a7f4
commit
09d6ee7657
@ -675,19 +675,15 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
||||
case Type::RValueReference: {
|
||||
const ReferenceType *RTy = cast<ReferenceType>(Ty);
|
||||
QualType ETy = RTy->getPointeeType();
|
||||
llvm::Type *PointeeType = ConvertTypeForMem(ETy);
|
||||
unsigned AS = getTargetAddressSpace(ETy);
|
||||
ResultType = llvm::PointerType::get(PointeeType, AS);
|
||||
ResultType = llvm::PointerType::get(getLLVMContext(), AS);
|
||||
break;
|
||||
}
|
||||
case Type::Pointer: {
|
||||
const PointerType *PTy = cast<PointerType>(Ty);
|
||||
QualType ETy = PTy->getPointeeType();
|
||||
llvm::Type *PointeeType = ConvertTypeForMem(ETy);
|
||||
if (PointeeType->isVoidTy())
|
||||
PointeeType = llvm::Type::getInt8Ty(getLLVMContext());
|
||||
unsigned AS = getTargetAddressSpace(ETy);
|
||||
ResultType = llvm::PointerType::get(PointeeType, AS);
|
||||
ResultType = llvm::PointerType::get(getLLVMContext(), AS);
|
||||
break;
|
||||
}
|
||||
|
||||
@ -764,15 +760,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
||||
break;
|
||||
}
|
||||
|
||||
case Type::ObjCObjectPointer: {
|
||||
// Protocol qualifications do not influence the LLVM type, we just return a
|
||||
// pointer to the underlying interface type. We don't need to worry about
|
||||
// recursive conversion.
|
||||
llvm::Type *T =
|
||||
ConvertTypeForMem(cast<ObjCObjectPointerType>(Ty)->getPointeeType());
|
||||
ResultType = T->getPointerTo();
|
||||
case Type::ObjCObjectPointer:
|
||||
ResultType = llvm::PointerType::getUnqual(getLLVMContext());
|
||||
break;
|
||||
}
|
||||
|
||||
case Type::Enum: {
|
||||
const EnumDecl *ED = cast<EnumType>(Ty)->getDecl();
|
||||
@ -786,18 +776,15 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
||||
}
|
||||
|
||||
case Type::BlockPointer: {
|
||||
const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType();
|
||||
llvm::Type *PointeeType = CGM.getLangOpts().OpenCL
|
||||
? CGM.getGenericBlockLiteralType()
|
||||
: ConvertTypeForMem(FTy);
|
||||
// Block pointers lower to function type. For function type,
|
||||
// getTargetAddressSpace() returns default address space for
|
||||
// function pointer i.e. program address space. Therefore, for block
|
||||
// pointers, it is important to pass the pointee AST address space when
|
||||
// calling getTargetAddressSpace(), to ensure that we get the LLVM IR
|
||||
// address space for data pointers and not function pointers.
|
||||
const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType();
|
||||
unsigned AS = Context.getTargetAddressSpace(FTy.getAddressSpace());
|
||||
ResultType = llvm::PointerType::get(PointeeType, AS);
|
||||
ResultType = llvm::PointerType::get(getLLVMContext(), AS);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -31,20 +31,20 @@ void test_transpose_template1() {
|
||||
|
||||
void test_transpose_template2(MyMatrix<double, 7, 6> &M) {
|
||||
// CHECK-LABEL: define{{.*}} void @_Z24test_transpose_template2R8MyMatrixIdLj7ELj6EE(
|
||||
// CHECK: call void @_Z9transposeIdLj7ELj6EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr sret(%struct.MyMatrix.2) align 8 %ref.tmp1, ptr noundef nonnull align 8 dereferenceable(336) %0)
|
||||
// CHECK-NEXT: call void @_Z9transposeIdLj6ELj7EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr sret(%struct.MyMatrix.1) align 8 %ref.tmp, ptr noundef nonnull align 8 dereferenceable(336) %ref.tmp1)
|
||||
// CHECK-NEXT: call void @_Z9transposeIdLj7ELj6EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr sret(%struct.MyMatrix.2) align 8 %M2_t, ptr noundef nonnull align 8 dereferenceable(336) %ref.tmp)
|
||||
// CHECK: call void @_Z9transposeIdLj7ELj6EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr sret(%struct.MyMatrix.1) align 8 %ref.tmp1, ptr noundef nonnull align 8 dereferenceable(336) %0)
|
||||
// CHECK-NEXT: call void @_Z9transposeIdLj6ELj7EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr sret(%struct.MyMatrix.2) align 8 %ref.tmp, ptr noundef nonnull align 8 dereferenceable(336) %ref.tmp1)
|
||||
// CHECK-NEXT: call void @_Z9transposeIdLj7ELj6EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(ptr sret(%struct.MyMatrix.1) align 8 %M2_t, ptr noundef nonnull align 8 dereferenceable(336) %ref.tmp)
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_Z9transposeIdLj7ELj6EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(
|
||||
// CHECK: [[M:%.*]] = load <42 x double>, ptr {{.*}}, align 8
|
||||
// CHECK-NEXT: [[M_T:%.*]] = call <42 x double> @llvm.matrix.transpose.v42f64(<42 x double> [[M]], i32 7, i32 6)
|
||||
// CHECK-NEXT: [[RES_ADDR:%.*]] = getelementptr inbounds %struct.MyMatrix.2, ptr %agg.result, i32 0, i32 0
|
||||
// CHECK-NEXT: [[RES_ADDR:%.*]] = getelementptr inbounds %struct.MyMatrix.1, ptr %agg.result, i32 0, i32 0
|
||||
// CHECK-NEXT: store <42 x double> [[M_T]], ptr [[RES_ADDR]], align 8
|
||||
|
||||
// CHECK-LABEL: define linkonce_odr void @_Z9transposeIdLj6ELj7EE8MyMatrixIT_XT1_EXT0_EERKS0_IS1_XT0_EXT1_EE(
|
||||
// CHECK: [[M:%.*]] = load <42 x double>, ptr {{.*}}, align 8
|
||||
// CHECK-NEXT: [[M_T:%.*]] = call <42 x double> @llvm.matrix.transpose.v42f64(<42 x double> [[M]], i32 6, i32 7)
|
||||
// CHECK-NEXT: [[RES_ADDR:%.*]] = getelementptr inbounds %struct.MyMatrix.1, ptr %agg.result, i32 0, i32 0
|
||||
// CHECK-NEXT: [[RES_ADDR:%.*]] = getelementptr inbounds %struct.MyMatrix.2, ptr %agg.result, i32 0, i32 0
|
||||
// CHECK-NEXT: store <42 x double> [[M_T]], ptr [[RES_ADDR]], align 8
|
||||
|
||||
MyMatrix<double, 6, 7> M2_t = transpose(transpose(transpose(M)));
|
||||
|
@ -184,6 +184,6 @@ struct S30_use { // abi15-warning {{packed attribute is unnecessary for 'S30_use
|
||||
static_assert(sizeof(S30_use) == 3, "");
|
||||
|
||||
// The warnings are emitted when the layout of the structs is computed, so we have to use them.
|
||||
void f(S1*, S2*, S3*, S4*, S5*, S6*, S7*, S8*, S9*, S10*, S11*, S12*, S13*,
|
||||
S14*, S15*, S16*, S17*, S18*, S19*, S20*, S21*, S22*, S23*, S24*, S25*,
|
||||
S26*, S27*, S28*, S29*){}
|
||||
void f(S1, S2, S3, S4, S5, S6, S7, S8, S9, S10, S11, S12, S13,
|
||||
S14, S15, S16, S17, S18, S19, S20, S21, S22, S23, S24, S25,
|
||||
S26, S27, S28, S29){}
|
||||
|
@ -423,9 +423,10 @@ struct CompareDifferentFieldInIndirectStruct compareIndirectStruct;
|
||||
// expected-error@second-nested-struct.h:* {{'IndirectStruct::mismatchingField' from module 'Second' is not present in definition of 'struct IndirectStruct' in module 'First.Hidden'}}
|
||||
// expected-note@first-nested-struct.h:* {{declaration of 'mismatchingField' does not match}}
|
||||
#elif defined(CASE3)
|
||||
// This currently doesn't produce an error, because there is no dependency
|
||||
// on the layout of DirectStruct.
|
||||
// expected-no-diagnostics
|
||||
struct CompareIndirectStructPointer compareIndirectStructPointer;
|
||||
// expected-error@second-nested-struct.h:* {{'IndirectStruct::mismatchingField' from module 'Second' is not present in definition of 'struct IndirectStruct' in module 'First.Hidden'}}
|
||||
// expected-note@first-nested-struct.h:* {{declaration of 'mismatchingField' does not match}}
|
||||
#endif
|
||||
|
||||
//--- include/first-anonymous.h
|
||||
|
@ -33,7 +33,7 @@
|
||||
// RUN: not %clang_cc1 -triple %itanium_abi_triple -DINSTANTIATION -include-pch all.h.pch -I%t_moved -I%t_moved/sub2 -emit-llvm-only %s 2> %t.stderr
|
||||
// RUN: grep 'orig_sub2_1' %t.stderr
|
||||
|
||||
void qq(orig_sub*) {all();}
|
||||
void qq(orig_sub) {all();}
|
||||
|
||||
#ifdef REDECL
|
||||
float foo() {return 0;}
|
||||
|
@ -147,16 +147,16 @@ int main() {
|
||||
// This avoid "Can't yet mangle constructors!" for MS ABI.
|
||||
C* c;
|
||||
c->foo();
|
||||
DerivedStruct* v;
|
||||
H* g;
|
||||
DerivedStruct v;
|
||||
H g;
|
||||
BaseStruct* u;
|
||||
I* i;
|
||||
N* n;
|
||||
O* o;
|
||||
P* p;
|
||||
R* r;
|
||||
sd *h;
|
||||
EV *j;
|
||||
I i;
|
||||
N n;
|
||||
O o;
|
||||
P p;
|
||||
R r;
|
||||
sd h;
|
||||
EV j;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -206,15 +206,6 @@ int main() {
|
||||
// CHECK-NEXT: sizeof=80, align=8
|
||||
// CHECK-NEXT: nvsize=64, nvalign=8
|
||||
|
||||
// CHECK: %class.D = type { ptr, double }
|
||||
|
||||
// CHECK: %class.B = type { ptr, i32 }
|
||||
|
||||
// CHECK: %class.A = type { %class.B, i32, i8 }
|
||||
|
||||
// CHECK: %class.C = type { %class.D, %class.B, ptr, double, i32, double, i32, [4 x i8], %class.A }
|
||||
// CHECK: %class.C.base = type { %class.D, %class.B, ptr, double, i32, double, i32 }
|
||||
|
||||
// CHECK-LABEL: 0 | struct BaseStruct{{$}}
|
||||
// CHECK-NEXT: 0 | double v0
|
||||
// CHECK-NEXT: 8 | float v1
|
||||
@ -239,8 +230,6 @@ int main() {
|
||||
// CHECK-NEXT: sizeof=96, align=8
|
||||
// CHECK-NEXT: nvsize=96, nvalign=8
|
||||
|
||||
// CHECK: %struct.BaseStruct = type { double, float, %class.C }
|
||||
|
||||
// CHECK-LABEL: 0 | struct DerivedStruct{{$}}
|
||||
// CHECK-NEXT: 0 | struct BaseStruct (base)
|
||||
// CHECK-NEXT: 0 | double v0
|
||||
@ -267,8 +256,6 @@ int main() {
|
||||
// CHECK-NEXT: sizeof=104, align=8
|
||||
// CHECK-NEXT: nvsize=104, nvalign=8
|
||||
|
||||
// CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 }
|
||||
|
||||
// CHECK-LABEL:0 | struct G
|
||||
// CHECK-NEXT: 0 | int g_field
|
||||
// CHECK-NEXT: sizeof=4, align=4
|
||||
@ -284,8 +271,6 @@ int main() {
|
||||
// CHECK-NEXT: sizeof=24, align=8
|
||||
// CHECK-NEXT: nvsize=8, nvalign=8
|
||||
|
||||
// CHECK: %struct.H = type { %struct.G, ptr, %class.D }
|
||||
|
||||
// CHECK-LABEL: 0 | struct I{{$}}
|
||||
// CHECK-NEXT: 0 | (I vftable pointer)
|
||||
// CHECK-NEXT: 8 | (I vbtable pointer)
|
||||
@ -296,9 +281,6 @@ int main() {
|
||||
// CHECK-NEXT: sizeof=40, align=8
|
||||
// CHECK-NEXT: nvsize=24, nvalign=8
|
||||
|
||||
// CHECK: %struct.I = type { ptr, [4 x i8], ptr, double, %class.D }
|
||||
// CHECK: %struct.I.base = type { ptr, [4 x i8], ptr, double }
|
||||
|
||||
// CHECK-LABEL: 0 | struct L{{$}}
|
||||
// CHECK-NEXT: 0 | int l
|
||||
// CHECK-NEXT: sizeof=4, align=4
|
||||
@ -316,9 +298,6 @@ int main() {
|
||||
// CHECK-NEXT: 8 | int k
|
||||
// CHECK-NEXT: sizeof=12, align=4
|
||||
|
||||
//CHECK: %struct.M = type { ptr, i32, %struct.K }
|
||||
//CHECK: %struct.M.base = type { ptr, i32 }
|
||||
|
||||
// CHECK-LABEL: 0 | struct N{{$}}
|
||||
// CHECK-NEXT: 0 | (N vftable pointer)
|
||||
// CHECK-NEXT: 4 | struct L (base)
|
||||
@ -331,8 +310,6 @@ int main() {
|
||||
// CHECK-NEXT: sizeof=20, align=4
|
||||
// CHECK-NEXT: nvsize=16, nvalign=4
|
||||
|
||||
//CHECK: %struct.N = type { ptr, %struct.L, %struct.M.base, %struct.K }
|
||||
|
||||
// CHECK-LABEL: 0 | struct O{{$}}
|
||||
// CHECK-NEXT: 0 | (O vftable pointer)
|
||||
// CHECK-NEXT: 8 | struct H (base)
|
||||
@ -347,9 +324,6 @@ int main() {
|
||||
// CHECK-NEXT: | [sizeof=40, align=8
|
||||
// CHECK-NEXT: | nvsize=24, nvalign=8]
|
||||
|
||||
// CHECK: struct.O = type { ptr, [4 x i8], %struct.H.base, %struct.G, %class.D }
|
||||
// CHECK: struct.O.base = type { ptr, [4 x i8], %struct.H.base, %struct.G, [4 x i8] }
|
||||
|
||||
// CHECK-LABEL: 0 | struct P{{$}}
|
||||
// CHECK-NEXT: 0 | struct M (base)
|
||||
// CHECK-NEXT: 0 | (M vbtable pointer)
|
||||
@ -362,14 +336,10 @@ int main() {
|
||||
// CHECK-NEXT: sizeof=20, align=4
|
||||
// CHECK-NEXT: nvsize=12, nvalign=4
|
||||
|
||||
//CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L }
|
||||
|
||||
// CHECK-LABEL: 0 | struct R (empty){{$}}
|
||||
// CHECK-NEXT: sizeof=1, align=1
|
||||
// CHECK-NEXT: nvsize=0, nvalign=1
|
||||
|
||||
//CHECK: %struct.R = type { i8 }
|
||||
|
||||
// CHECK-LABEL: 0 | struct f{{$}}
|
||||
// CHECK-NEXT: 0 | (f vftable pointer)
|
||||
// CHECK-NEXT: sizeof=4, align=4
|
||||
@ -419,12 +389,6 @@ int main() {
|
||||
// CHECK-NEXT: sizeof=48, align=4
|
||||
// CHECK-NEXT: nvsize=12, nvalign=4
|
||||
|
||||
// CHECK: %struct.f = type { ptr }
|
||||
// CHECK: %struct.s = type { ptr, ptr, i32, i32, %struct.f }
|
||||
// CHECK: %class.IA = type { ptr }
|
||||
// CHECK: %class.ICh = type { ptr, ptr, i32, %class.IA }
|
||||
// CHECK: %struct.sd = type { ptr, i32, i8, i32, %struct.f, %struct.s.base, i32, %class.IA, %class.ICh.base }
|
||||
|
||||
// CHECK-LABEL: 0 | struct AV{{$}}
|
||||
// CHECK-NEXT: 0 | (AV vftable pointer)
|
||||
// CHECK-NEXT: sizeof=4, align=4
|
||||
@ -445,11 +409,6 @@ int main() {
|
||||
// CHECK-NEXT: sizeof=12, align=4
|
||||
// CHECK-NEXT: nvsize=4, nvalign=4
|
||||
|
||||
// CHECK: %struct.AV = type { ptr }
|
||||
// CHECK: %struct.BV = type { %struct.AV }
|
||||
// CHECK: %struct.CV = type { ptr, i32, %struct.BV }
|
||||
// CHECK: %struct.CV.base = type { ptr }
|
||||
|
||||
// CHECK-LABEL: 0 | struct DV{{$}}
|
||||
// CHECK-NEXT: 0 | struct BV (primary base)
|
||||
// CHECK-NEXT: 0 | struct AV (primary base)
|
||||
@ -457,8 +416,6 @@ int main() {
|
||||
// CHECK-NEXT: sizeof=4, align=4
|
||||
// CHECK-NEXT: nvsize=4, nvalign=4
|
||||
|
||||
// CHECK: %struct.DV = type { %struct.BV }
|
||||
|
||||
// CHECK-LABEL: 0 | struct EV{{$}}
|
||||
// CHECK-NEXT: 0 | struct DV (primary base)
|
||||
// CHECK-NEXT: 0 | struct BV (primary base)
|
||||
@ -473,6 +430,33 @@ int main() {
|
||||
// CHECK-NEXT: sizeof=16, align=4
|
||||
// CHECK-NEXT: nvsize=8, nvalign=4
|
||||
|
||||
// CHECK: %class.D = type { ptr, double }
|
||||
// CHECK: %class.B = type { ptr, i32 }
|
||||
// CHECK: %class.A = type { %class.B, i32, i8 }
|
||||
// CHECK: %class.C = type { %class.D, %class.B, ptr, double, i32, double, i32, [4 x i8], %class.A }
|
||||
// CHECK: %class.C.base = type { %class.D, %class.B, ptr, double, i32, double, i32 }
|
||||
// CHECK: %struct.BaseStruct = type { double, float, %class.C }
|
||||
// CHECK: %struct.DerivedStruct = type { %struct.BaseStruct, i32 }
|
||||
// CHECK: %struct.H = type { %struct.G, ptr, %class.D }
|
||||
// CHECK: %struct.I = type { ptr, [4 x i8], ptr, double, %class.D }
|
||||
// CHECK: %struct.I.base = type { ptr, [4 x i8], ptr, double }
|
||||
// CHECK: %struct.M = type { ptr, i32, %struct.K }
|
||||
// CHECK: %struct.M.base = type { ptr, i32 }
|
||||
// CHECK: %struct.N = type { ptr, %struct.L, %struct.M.base, %struct.K }
|
||||
// CHECK: %struct.O = type { ptr, [4 x i8], %struct.H.base, %struct.G, %class.D }
|
||||
// CHECK: %struct.O.base = type { ptr, [4 x i8], %struct.H.base, %struct.G, [4 x i8] }
|
||||
// CHECK: %struct.P = type { %struct.M.base, i32, %struct.K, %struct.L }
|
||||
// CHECK: %struct.R = type { i8 }
|
||||
// CHECK: %struct.f = type { ptr }
|
||||
// CHECK: %struct.s = type { ptr, ptr, i32, i32, %struct.f }
|
||||
// CHECK: %class.IA = type { ptr }
|
||||
// CHECK: %class.ICh = type { ptr, ptr, i32, %class.IA }
|
||||
// CHECK: %struct.sd = type { ptr, i32, i8, i32, %struct.f, %struct.s.base, i32, %class.IA, %class.ICh.base }
|
||||
// CHECK: %struct.AV = type { ptr }
|
||||
// CHECK: %struct.BV = type { %struct.AV }
|
||||
// CHECK: %struct.CV = type { ptr, i32, %struct.BV }
|
||||
// CHECK: %struct.CV.base = type { ptr }
|
||||
// CHECK: %struct.DV = type { %struct.BV }
|
||||
// CHECK: %struct.EV = type { %struct.DV, %struct.CV.base, i32, %struct.BV }
|
||||
// CHECK: %struct.EV.base = type { %struct.DV, %struct.CV.base }
|
||||
|
||||
@ -482,7 +466,7 @@ namespace test1 {
|
||||
struct A { virtual void foo(); };
|
||||
struct B : A {};
|
||||
struct C : virtual A, virtual B { C(); virtual void foo(); };
|
||||
void test() { C *c; }
|
||||
void test() { C c; }
|
||||
|
||||
// CHECK-LABEL: 0 | struct test1::C{{$}}
|
||||
// CHECK-NEXT: 0 | (C vbtable pointer)
|
||||
|
Loading…
Reference in New Issue
Block a user