[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