122 lines · cpp
1// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-cir %s -o %t.cir2// RUN: FileCheck --check-prefix=CIR --input-file=%t.cir %s3// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -fclangir -emit-llvm %s -o %t-cir.ll4// RUN: FileCheck --check-prefix=LLVM --input-file=%t-cir.ll %s5// RUN: %clang_cc1 -triple x86_64-unknown-linux-gnu -emit-llvm %s -o %t.ll6// RUN: FileCheck --check-prefix=OGCG --input-file=%t.ll %s7 8// CIR: !rec_IncompleteC = !cir.record<class "IncompleteC" incomplete>9// CIR: !rec_Base = !cir.record<class "Base" {!s32i}>10// CIR: !rec_CompleteC = !cir.record<class "CompleteC" {!s32i, !s8i}>11// CIR: !rec_Derived = !cir.record<class "Derived" {!rec_Base, !s32i}>12 13// Note: LLVM and OGCG do not emit the type for incomplete classes.14 15// LLVM: %class.CompleteC = type { i32, i8 }16// LLVM: %class.Derived = type { %class.Base, i32 }17// LLVM: %class.Base = type { i32 }18 19// OGCG: %class.CompleteC = type { i32, i8 }20// OGCG: %class.Derived = type { %class.Base, i32 }21// OGCG: %class.Base = type { i32 }22 23class IncompleteC;24IncompleteC *p;25 26// CIR: cir.global external @p = #cir.ptr<null> : !cir.ptr<!rec_IncompleteC>27// LLVM: @p = global ptr null28// OGCG: @p = global ptr null, align 829 30class CompleteC {31public: 32 int a;33 char b;34};35 36CompleteC cc;37 38// CIR: cir.global external @cc = #cir.zero : !rec_CompleteC39// LLVM: @cc = global %class.CompleteC zeroinitializer40// OGCG: @cc = global %class.CompleteC zeroinitializer41 42class Base {43public:44 int a;45};46 47class Derived : public Base {48public:49 int b;50};51 52int use(Derived *d) { return d->b; }53 54// CIR: cir.func{{.*}} @_Z3useP7Derived(%[[ARG0:.*]]: !cir.ptr<!rec_Derived>55// CIR: %[[D_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["d", init]56// CIR: cir.store %[[ARG0]], %[[D_ADDR]]57// CIR: %[[D_PTR:.*]] = cir.load align(8) %058// CIR: %[[D_B_ADDR:.*]] = cir.get_member %[[D_PTR]][1] {name = "b"}59// CIR: %[[D_B:.*]] = cir.load align(4) %[[D_B_ADDR]]60 61// LLVM: define{{.*}} i32 @_Z3useP7Derived62// LLVM: getelementptr %class.Derived, ptr %{{.*}}, i32 0, i32 163 64// OGCG: define{{.*}} i32 @_Z3useP7Derived65// OGCG: getelementptr inbounds nuw %class.Derived, ptr %{{.*}}, i32 0, i32 166 67int use_base() {68 Derived d;69 return d.a;70}71 72// CIR: cir.func{{.*}} @_Z8use_basev73// CIR: %[[D_ADDR:.*]] = cir.alloca !rec_Derived, !cir.ptr<!rec_Derived>, ["d"]74// CIR: %[[BASE_ADDR:.*]] cir.base_class_addr %[[D_ADDR]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>75// CIR: %[[D_A_ADDR:.*]] = cir.get_member %2[0] {name = "a"} : !cir.ptr<!rec_Base> -> !cir.ptr<!s32i>76// CIR: %[[D_A:.*]] = cir.load align(4) %3 : !cir.ptr<!s32i>, !s32i77 78// LLVM: define{{.*}} i32 @_Z8use_basev79// LLVM: %[[D:.*]] = alloca %class.Derived80// LLVM: %[[D_A_ADDR:.*]] = getelementptr %class.Base, ptr %[[D]], i32 0, i32 081 82// OGCG: define{{.*}} i32 @_Z8use_basev83// OGCG: %[[D:.*]] = alloca %class.Derived84// OGCG: %[[D_A_ADDR:.*]] = getelementptr inbounds nuw %class.Base, ptr %[[D]], i32 0, i32 085 86int use_base_via_pointer(Derived *d) {87 return d->a;88}89 90// CIR: cir.func{{.*}} @_Z20use_base_via_pointerP7Derived(%[[ARG0:.*]]: !cir.ptr<!rec_Derived>91// CIR: %[[D_ADDR:.*]] = cir.alloca !cir.ptr<!rec_Derived>, !cir.ptr<!cir.ptr<!rec_Derived>>, ["d", init]92// CIR: cir.store %[[ARG0]], %[[D_ADDR]]93// CIR: %[[D:.*]] = cir.load align(8) %[[D_ADDR]]94// CIR: %[[BASE_ADDR:.*]] = cir.base_class_addr %[[D]] : !cir.ptr<!rec_Derived> nonnull [0] -> !cir.ptr<!rec_Base>95// CIR: %[[D_A_ADDR:.*]] = cir.get_member %[[BASE_ADDR]][0] {name = "a"}96// CIR: %[[D_A:.*]] = cir.load align(4) %[[D_A_ADDR]]97 98// LLVM: define{{.*}} i32 @_Z20use_base_via_pointerP7Derived99// LLVM: %[[D_A_ADDR:.*]] = getelementptr %class.Base, ptr %{{.*}}, i32 0, i32 0100 101// OGCG: define{{.*}} i32 @_Z20use_base_via_pointerP7Derived102// OGCG: %[[D_A_ADDR:.*]] = getelementptr inbounds nuw %class.Base, ptr %{{.*}}, i32 0, i32 0103 104struct EmptyDerived : Base {};105struct EmptyDerived2 : EmptyDerived {};106 107void use_empty_derived2() {108 EmptyDerived2 d2;109}110 111// CIR: cir.func{{.*}} @_Z18use_empty_derived2v()112// CIR: %0 = cir.alloca !rec_EmptyDerived2, !cir.ptr<!rec_EmptyDerived2>, ["d2"]113// CIR: cir.return114 115// LLVM: define{{.*}} void @_Z18use_empty_derived2v116// LLVM: alloca %struct.EmptyDerived2117// LLVM: ret void118 119// OGCG: define{{.*}} void @_Z18use_empty_derived2v120// OGCG: alloca %struct.EmptyDerived2121// OGCG: ret void122