[clang] 09d6ee7 - [Clang] Directly create opaque pointers
Nikita Popov via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 15 00:09:41 PDT 2023
Author: Nikita Popov
Date: 2023-06-15T09:09:33+02:00
New Revision: 09d6ee765780837d5156ac81f968465bdcec73ba
URL: https://github.com/llvm/llvm-project/commit/09d6ee765780837d5156ac81f968465bdcec73ba
DIFF: https://github.com/llvm/llvm-project/commit/09d6ee765780837d5156ac81f968465bdcec73ba.diff
LOG: [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
Added:
Modified:
clang/lib/CodeGen/CodeGenTypes.cpp
clang/test/CodeGenCXX/matrix-type-builtins.cpp
clang/test/CodeGenCXX/warn-all-padded-packed-packed-non-pod.cpp
clang/test/Modules/compare-record.c
clang/test/PCH/headersearch.cpp
clang/test/Sema/ms_class_layout.cpp
Removed:
################################################################################
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index 0ceab41cdd360..e4836c850a157 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -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;
}
diff --git a/clang/test/CodeGenCXX/matrix-type-builtins.cpp b/clang/test/CodeGenCXX/matrix-type-builtins.cpp
index 24bf797ab94a0..732fe1a18db3b 100644
--- a/clang/test/CodeGenCXX/matrix-type-builtins.cpp
+++ b/clang/test/CodeGenCXX/matrix-type-builtins.cpp
@@ -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)));
diff --git a/clang/test/CodeGenCXX/warn-all-padded-packed-packed-non-pod.cpp b/clang/test/CodeGenCXX/warn-all-padded-packed-packed-non-pod.cpp
index 5402e21e3a5b8..2a75498d87197 100644
--- a/clang/test/CodeGenCXX/warn-all-padded-packed-packed-non-pod.cpp
+++ b/clang/test/CodeGenCXX/warn-all-padded-packed-packed-non-pod.cpp
@@ -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){}
diff --git a/clang/test/Modules/compare-record.c b/clang/test/Modules/compare-record.c
index a07843341296d..c5ce285aa77ee 100644
--- a/clang/test/Modules/compare-record.c
+++ b/clang/test/Modules/compare-record.c
@@ -423,9 +423,10 @@ struct CompareDifferentFieldInIndirectStruct compareIndirectStruct;
// expected-error at second-nested-struct.h:* {{'IndirectStruct::mismatchingField' from module 'Second' is not present in definition of 'struct IndirectStruct' in module 'First.Hidden'}}
// expected-note at 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 at second-nested-struct.h:* {{'IndirectStruct::mismatchingField' from module 'Second' is not present in definition of 'struct IndirectStruct' in module 'First.Hidden'}}
-// expected-note at first-nested-struct.h:* {{declaration of 'mismatchingField' does not match}}
#endif
//--- include/first-anonymous.h
diff --git a/clang/test/PCH/headersearch.cpp b/clang/test/PCH/headersearch.cpp
index 3d16c3335341b..f089bfd9ed1de 100644
--- a/clang/test/PCH/headersearch.cpp
+++ b/clang/test/PCH/headersearch.cpp
@@ -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;}
diff --git a/clang/test/Sema/ms_class_layout.cpp b/clang/test/Sema/ms_class_layout.cpp
index cd0f04abd1398..73382a480f50e 100644
--- a/clang/test/Sema/ms_class_layout.cpp
+++ b/clang/test/Sema/ms_class_layout.cpp
@@ -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)
More information about the cfe-commits
mailing list