79 lines · cpp
1// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-linux-gnu | FileCheck %s2// RUN: %clang_cc1 -emit-llvm %s -o - -triple i686-pc-win32 | FileCheck -check-prefix MSVC %s3 4struct A { int a; virtual int aa(); };5struct B { int b; virtual int bb(); };6struct C : virtual A, virtual B { int c; virtual int aa(); virtual int bb(); };7struct AA { int a; virtual int aa(); };8struct BB { int b; virtual int bb(); };9struct CC : AA, BB { virtual int aa(); virtual int bb(); virtual int cc(); };10struct D : virtual C, virtual CC { int e; };11 12D* x;13 14A* a() { return x; }15// CHECK: @_Z1av() [[NUW:#[0-9]+]]16// CHECK: [[VBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = getelementptr i8, ptr {{.*}}, i64 -1617// CHECK: load i32, ptr [[VBASEOFFSETPTRA]]18// CHECK: }19 20// MSVC: @"?a@@YAPAUA@@XZ"() [[NUW:#[0-9]+]] {21// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, ptr {{.*}}, i32 022// MSVC: %[[vbtable:.*]] = load ptr, ptr %[[vbptr_off]]23// MSVC: %[[entry:.*]] = getelementptr inbounds i32, ptr {{.*}}, i32 124// MSVC: %[[offset:.*]] = load i32, ptr %[[entry]]25// MSVC: add nsw i32 0, %[[offset]]26// MSVC: }27 28B* b() { return x; }29// CHECK: @_Z1bv() [[NUW]]30// CHECK: [[VBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = getelementptr i8, ptr {{.*}}, i64 -2031// CHECK: load i32, ptr [[VBASEOFFSETPTRA]]32// CHECK: }33 34// Same as 'a' except we use a different vbtable offset.35// MSVC: @"?b@@YAPAUB@@XZ"() [[NUW:#[0-9]+]] {36// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, ptr {{.*}}, i32 037// MSVC: %[[vbtable:.*]] = load ptr, ptr %[[vbptr_off]]38// MSVC: %[[entry:.*]] = getelementptr inbounds i32, ptr {{.*}}, i32 239// MSVC: %[[offset:.*]] = load i32, ptr %[[entry]]40// MSVC: add nsw i32 0, %[[offset]]41// MSVC: }42 43 44BB* c() { return x; }45// CHECK: @_Z1cv() [[NUW]]46// CHECK: [[VBASEOFFSETPTRC:%[a-zA-Z0-9\.]+]] = getelementptr i8, ptr {{.*}}, i64 -2447// CHECK: [[VBASEOFFSETC:%[a-zA-Z0-9\.]+]] = load i32, ptr [[VBASEOFFSETPTRC]]48// CHECK: add i32 [[VBASEOFFSETC]], 849// CHECK: }50 51// Same as 'a' except we use a different vbtable offset.52// MSVC: @"?c@@YAPAUBB@@XZ"() [[NUW:#[0-9]+]] {53// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, ptr {{.*}}, i32 054// MSVC: %[[vbtable:.*]] = load ptr, ptr %[[vbptr_off]]55// MSVC: %[[entry:.*]] = getelementptr inbounds i32, ptr {{.*}}, i32 456// MSVC: %[[offset:.*]] = load i32, ptr %[[entry]]57// MSVC: add nsw i32 0, %[[offset]]58// MSVC: }59 60// Put the vbptr at a non-zero offset inside a non-virtual base.61struct E { int e; };62struct F : E, D { int f; };63 64F* y;65 66BB* d() { return y; }67 68// Same as 'c' except the vbptr offset is 4, changing the initial GEP and the69// final add.70// MSVC: @"?d@@YAPAUBB@@XZ"() [[NUW:#[0-9]+]] {71// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, ptr {{.*}}, i32 472// MSVC: %[[vbtable:.*]] = load ptr, ptr %[[vbptr_off]]73// MSVC: %[[entry:.*]] = getelementptr inbounds i32, ptr {{.*}}, i32 474// MSVC: %[[offset:.*]] = load i32, ptr %[[entry]]75// MSVC: add nsw i32 4, %[[offset]]76// MSVC: }77 78// CHECK: attributes [[NUW]] = { mustprogress noinline nounwind{{.*}} }79