diff options
Diffstat (limited to 'test/CodeGenCXX')
269 files changed, 5322 insertions, 2686 deletions
diff --git a/test/CodeGenCXX/2009-12-23-MissingSext.cpp b/test/CodeGenCXX/2009-12-23-MissingSext.cpp index 2b42367..bff6ac7 100644 --- a/test/CodeGenCXX/2009-12-23-MissingSext.cpp +++ b/test/CodeGenCXX/2009-12-23-MissingSext.cpp @@ -8,11 +8,11 @@ struct foo { }; int bar(struct foo p, int x) { // CHECK: bar -// CHECK: %[[val:.*]] = load i32* {{.*}} +// CHECK: %[[val:.*]] = load i32, i32* {{.*}} // CHECK-NEXT: ashr i32 %[[val]] -// CHECK: = load i32* {{.*}} -// CHECK: = load i32* {{.*}} -// CHECK: %[[val:.*]] = load i32* {{.*}} +// CHECK: = load i32, i32* {{.*}} +// CHECK: = load i32, i32* {{.*}} +// CHECK: %[[val:.*]] = load i32, i32* {{.*}} // CHECK-NEXT: ashr i32 %[[val]] x = (p.y > x ? x : p.y); return x; diff --git a/test/CodeGenCXX/2010-07-23-DeclLoc.cpp b/test/CodeGenCXX/2010-07-23-DeclLoc.cpp index 56c364c..3bd66da 100644 --- a/test/CodeGenCXX/2010-07-23-DeclLoc.cpp +++ b/test/CodeGenCXX/2010-07-23-DeclLoc.cpp @@ -1,9 +1,10 @@ // RUN: %clang_cc1 -emit-llvm -g %s -o - | FileCheck %s // Require the template function declaration refer to the correct filename. // First, locate the function decl in metadata, and pluck out the file handle: -// CHECK: !"0x2e\00extract_dwarf_data_from_header{{[^"]+}}", [[filehandle:![0-9]+]] +// CHECK: !DISubprogram(name: "extract_dwarf_data_from_header +// CHECK-SAME: file: [[FILE:![0-9]+]] // Second: Require that filehandle refer to the correct filename: -// CHECK: [[filehandle]] = {{.*}}decl_should_be_here.hpp" +// CHECK: [[FILE]] = !DIFile(filename: "decl_should_be_here.hpp" typedef long unsigned int __darwin_size_t; typedef __darwin_size_t size_t; typedef unsigned char uint8_t; diff --git a/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp b/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp index a853a57..84c4619 100644 --- a/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp +++ b/test/CodeGenCXX/2011-12-19-init-list-ctor.cpp @@ -6,8 +6,8 @@ struct A { // CHECK: @arr = global [3 x %struct.S] zeroinitializer // CHECK: @.str = {{.*}}constant [6 x i8] c"hello\00" -// CHECK: @.str1 = {{.*}}constant [6 x i8] c"world\00" -// CHECK: @.str2 = {{.*}}constant [8 x i8] c"goodbye\00" +// CHECK: @.str.1 = {{.*}}constant [6 x i8] c"world\00" +// CHECK: @.str.2 = {{.*}}constant [8 x i8] c"goodbye\00" struct S { int n; @@ -18,9 +18,9 @@ struct S { { 2, "goodbye" } }; -// CHECK: store i32 0, i32* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 0, i32 0) -// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 0, i32 1), i8* getelementptr inbounds ([6 x i8]* @.str, i32 0, i32 0)) -// CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 1, i32 0) -// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 1, i32 1), i8* getelementptr inbounds ([6 x i8]* @.str1, i32 0, i32 0)) -// CHECK: store i32 2, i32* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 2, i32 0) -// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S]* @arr, i64 0, i64 2, i32 1), i8* getelementptr inbounds ([8 x i8]* @.str2, i32 0, i32 0)) +// CHECK: store i32 0, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 0) +// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 0, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str, i32 0, i32 0)) +// CHECK: store i32 1, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 0) +// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 1, i32 1), i8* getelementptr inbounds ([6 x i8], [6 x i8]* @.str.1, i32 0, i32 0)) +// CHECK: store i32 2, i32* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 0) +// CHECK: call void @_ZN1AC1EPKc(%struct.A* getelementptr inbounds ([3 x %struct.S], [3 x %struct.S]* @arr, i64 0, i64 2, i32 1), i8* getelementptr inbounds ([8 x i8], [8 x i8]* @.str.2, i32 0, i32 0)) diff --git a/test/CodeGenCXX/2012-03-16-StoreAlign.cpp b/test/CodeGenCXX/2012-03-16-StoreAlign.cpp index a6375f8..7e82ca5 100644 --- a/test/CodeGenCXX/2012-03-16-StoreAlign.cpp +++ b/test/CodeGenCXX/2012-03-16-StoreAlign.cpp @@ -28,7 +28,7 @@ struct Foo { }; // CHECK: @_ZZN3Foo19getPageSizeFromNameERK6LengthE10legalWidth = linkonce_odr global %struct.Length zeroinitializer, align 4 -// CHECK: store float %{{.*}}, float* getelementptr inbounds (%struct.Length* @_ZZN3Foo19getPageSizeFromNameERK6LengthE10legalWidth, i32 0, i32 0), align 1 +// CHECK: store float %{{.*}}, float* getelementptr inbounds (%struct.Length, %struct.Length* @_ZZN3Foo19getPageSizeFromNameERK6LengthE10legalWidth, i32 0, i32 0), align 1 bool bar(Length &b) { Foo f; diff --git a/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp b/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp index 31a0261..17fa456 100644 --- a/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp +++ b/test/CodeGenCXX/Inputs/debug-info-class-limited.cpp @@ -1,5 +1,5 @@ -// CHECK-DAG: [ DW_TAG_structure_type ] [PR16214] [line [[@LINE+1]], {{.*}} [def] +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "PR16214",{{.*}} line: [[@LINE+1]],{{.*}} isDefinition: true struct PR16214 { int i; }; @@ -10,7 +10,7 @@ bar *a; bar b; namespace PR14467 { -// CHECK-DAG: [ DW_TAG_structure_type ] [foo] [line [[@LINE+1]], {{.*}} [def] +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+1]],{{.*}} isDefinition: true struct foo { }; @@ -21,7 +21,7 @@ foo *bar(foo *a) { } namespace test1 { -// CHECK-DAG: [ DW_TAG_structure_type ] [foo] [line [[@LINE+1]], {{.*}} [def] +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+1]],{{.*}} isDefinition: true struct foo { }; @@ -35,7 +35,7 @@ namespace test2 { // FIXME: if we were a bit fancier, we could realize that the 'foo' type is only // required because of the 'bar' type which is not required at all (or might // only be required to be declared) -// CHECK-DAG: [ DW_TAG_structure_type ] [foo] [line [[@LINE+1]], {{.*}} [def] +// CHECK-DAG: !DICompositeType(tag: DW_TAG_structure_type, name: "foo",{{.*}} line: [[@LINE+1]],{{.*}} isDefinition: true struct foo { }; diff --git a/test/CodeGenCXX/PR19955.cpp b/test/CodeGenCXX/PR19955.cpp index 9e10155..1001084 100644 --- a/test/CodeGenCXX/PR19955.cpp +++ b/test/CodeGenCXX/PR19955.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s -// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s --check-prefix X64 +// RUN: %clang_cc1 -triple i686-windows-msvc -fms-extensions -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -fms-extensions -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s --check-prefix X64 extern int __declspec(dllimport) var; extern void __declspec(dllimport) fun(); diff --git a/test/CodeGenCXX/PR20038.cpp b/test/CodeGenCXX/PR20038.cpp index 0936dfc..0a10244 100644 --- a/test/CodeGenCXX/PR20038.cpp +++ b/test/CodeGenCXX/PR20038.cpp @@ -6,9 +6,9 @@ struct C { extern bool b; // CHECK: call {{.*}}, !dbg [[DTOR_CALL1_LOC:![0-9]*]] // CHECK: call {{.*}}, !dbg [[DTOR_CALL2_LOC:![0-9]*]] -// CHECK: [[FUN1:.*]] = {{.*}}; [ DW_TAG_subprogram ] {{.*}} [def] [fun1] -// CHECK: [[FUN2:.*]] = {{.*}}; [ DW_TAG_subprogram ] {{.*}} [def] [fun2] -// CHECK: [[DTOR_CALL1_LOC]] = !MDLocation(line: [[@LINE+1]], scope: [[FUN1]]) +// CHECK: [[FUN1:.*]] = !DISubprogram(name: "fun1",{{.*}} isDefinition: true +// CHECK: [[FUN2:.*]] = !DISubprogram(name: "fun2",{{.*}} isDefinition: true +// CHECK: [[DTOR_CALL1_LOC]] = !DILocation(line: [[@LINE+1]], scope: [[FUN1]]) void fun1() { b && (C(), 1); } -// CHECK: [[DTOR_CALL2_LOC]] = !MDLocation(line: [[@LINE+1]], scope: [[FUN2]]) +// CHECK: [[DTOR_CALL2_LOC]] = !DILocation(line: [[@LINE+1]], scope: [[FUN2]]) bool fun2() { return (C(), b) && 0; } diff --git a/test/CodeGenCXX/aarch64-aapcs-zerolength-bitfield.cpp b/test/CodeGenCXX/aarch64-aapcs-zerolength-bitfield.cpp new file mode 100644 index 0000000..8b403fa --- /dev/null +++ b/test/CodeGenCXX/aarch64-aapcs-zerolength-bitfield.cpp @@ -0,0 +1,249 @@ +// REQUIRES: aarch64-registered-target +// RUN: %clang_cc1 -triple aarch64-linux-gnu -x c++ -std=c++1z %s -verify +// expected-no-diagnostics + +#include <stddef.h> + +struct t1 +{ + int foo : 1; + char : 0; + char bar; + +}; +static_assert(offsetof(struct t1, bar) == 1); +static_assert(sizeof(struct t1) == 4); + +struct t2 +{ + int foo : 1; + short : 0; + char bar; +}; +static_assert(offsetof(struct t2, bar) == 2); +static_assert(sizeof(struct t2) == 4); + +struct t3 +{ + int foo : 1; + int : 0; + char bar; +}; +static_assert(offsetof(struct t3, bar) == 4); +static_assert(sizeof(struct t3) == 8); + +struct t4 +{ + int foo : 1; + long : 0; + char bar; +}; +static_assert(offsetof(struct t4, bar) == 8); +static_assert(sizeof(struct t4) == 16); + +struct t5 +{ + int foo : 1; + long long : 0; + char bar; +}; +static_assert(offsetof(struct t5, bar) == 8); +static_assert(sizeof(struct t5) == 16); + +struct t6 +{ + int foo : 1; + char : 0; + char bar : 1; + char bar2; +}; +static_assert(offsetof(struct t6, bar2) == 2); +static_assert(sizeof(struct t6) == 4); + +struct t7 +{ + int foo : 1; + short : 0; + char bar1 : 1; + char bar2; +}; +static_assert(offsetof(struct t7, bar2) == 3); +static_assert(sizeof(struct t7) == 4); + +struct t8 +{ + int foo : 1; + int : 0; + char bar1 : 1; + char bar2; +}; +static_assert(offsetof(struct t8, bar2) == 5); +static_assert(sizeof(struct t8) == 8); + +struct t9 +{ + int foo : 1; + long : 0; + char bar1 : 1; + char bar2; +}; +static_assert(offsetof(struct t9, bar2) == 9); +static_assert(sizeof(struct t9) == 16); + +struct t10 +{ + int foo : 1; + long long : 0; + char bar1 : 1; + char bar2; +}; +static_assert(offsetof(struct t10, bar2) == 9); +static_assert(sizeof(struct t10) == 16); + +struct t11 +{ + int foo : 1; + long long : 0; + char : 0; + char bar1 : 1; + char bar2; +}; +static_assert(offsetof(struct t11, bar2) == 9); +static_assert(sizeof(struct t11) == 16); + +struct t12 +{ + int foo : 1; + char : 0; + long long : 0; + char : 0; + char bar; +}; +static_assert(offsetof(struct t12, bar) == 8); +static_assert(sizeof(struct t12) == 16); + +struct t13 +{ + char foo; + long : 0; + char bar; +}; +static_assert(offsetof(struct t13, bar) == 8); +static_assert(sizeof(struct t13) == 16); + +struct t14 +{ + char foo1; + int : 0; + char foo2 : 1; + short foo3 : 16; + char : 0; + short foo4 : 16; + char bar1; + int : 0; + char bar2; +}; +static_assert(offsetof(struct t14, bar1) == 10); +static_assert(offsetof(struct t14, bar2) == 12); +static_assert(sizeof(struct t14) == 16); + +struct t15 +{ + char foo; + char : 0; + int : 0; + char bar; + long : 0; + char : 0; +}; +static_assert(offsetof(struct t15, bar) == 4); +static_assert(sizeof(struct t15) == 8); + +struct t16 +{ + long : 0; + char bar; +}; +static_assert(offsetof(struct t16, bar) == 0); +static_assert(sizeof(struct t16) == 8); + +struct t17 +{ + char foo; + long : 0; + long : 0; + char : 0; + char bar; +}; +static_assert(offsetof(struct t17, bar) == 8); +static_assert(sizeof(struct t17) == 16); + +struct t18 +{ + long : 0; + long : 0; + char : 0; +}; +static_assert(sizeof(struct t18) == 8); + +struct t19 +{ + char foo1; + long foo2 : 1; + char : 0; + long foo3 : 32; + char bar; +}; +static_assert(offsetof(struct t19, bar) == 6); +static_assert(sizeof(struct t19) == 8); + +struct t20 +{ + short : 0; + int foo : 1; + long : 0; + char bar; +}; +static_assert(offsetof(struct t20, bar) == 8); +static_assert(sizeof(struct t20) == 16); + +struct t21 +{ + short : 0; + int foo1 : 1; + char : 0; + int foo2 : 16; + long : 0; + char bar1; + int bar2; + long bar3; + char foo3 : 8; + char : 0; + long : 0; + int foo4 : 32; + short foo5: 1; + long bar4; + short foo6: 16; + short foo7: 16; + short foo8: 16; +}; +static_assert(offsetof(struct t21, bar1) == 8); +static_assert(offsetof(struct t21, bar2) == 12); +static_assert(offsetof(struct t21, bar3) == 16); +static_assert(offsetof(struct t21, bar4) == 40); +static_assert(sizeof(struct t21) == 56); + +// The rules also apply to anonymous bitfields with non-zero length. +struct t22 +{ + char foo; + short :2; + char bar; +}; +static_assert(alignof(struct t22) == 2); +static_assert(offsetof(struct t22, bar) == 2); + +int main() { + return 0; +} + diff --git a/test/CodeGenCXX/aarch64-neon.cpp b/test/CodeGenCXX/aarch64-neon.cpp index d6f6b0e..fc8642d 100644 --- a/test/CodeGenCXX/aarch64-neon.cpp +++ b/test/CodeGenCXX/aarch64-neon.cpp @@ -1,6 +1,8 @@ // REQUIRES: aarch64-registered-target // RUN: %clang_cc1 -triple arm64-none-linux-gnu -target-feature +neon \ // RUN: -ffp-contract=fast -S -O3 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple arm64-none-netbsd-gnu -target-feature +neon \ +// RUN: -ffp-contract=fast -S -O3 -o - %s | FileCheck %s // Test whether arm_neon.h works as expected in C++. diff --git a/test/CodeGenCXX/align-avx-complete-objects.cpp b/test/CodeGenCXX/align-avx-complete-objects.cpp index 25f4ef1..6ab17f5 100644 --- a/test/CodeGenCXX/align-avx-complete-objects.cpp +++ b/test/CodeGenCXX/align-avx-complete-objects.cpp @@ -16,14 +16,14 @@ volatile float TestAlign(void) // CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @_Znwm(i64 32) // CHECK-NEXT: [[ZERO:%.*]] = bitcast i8* [[CALL]] to <8 x float>* // CHECK-NEXT: store <8 x float>* [[ZERO]], <8 x float>** [[P:%.*]], align 8 -// CHECK-NEXT: [[ONE:%.*]] = load <8 x float>** [[P]], align 8 -// CHECK-NEXT: [[TWO:%.*]] = load volatile <8 x float>* [[ONE]], align 16 -// CHECK-NEXT: [[THREE:%.*]] = load <8 x float>** [[P]], align 8 +// CHECK-NEXT: [[ONE:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8 +// CHECK-NEXT: [[TWO:%.*]] = load volatile <8 x float>, <8 x float>* [[ONE]], align 16 +// CHECK-NEXT: [[THREE:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8 // CHECK-NEXT: store volatile <8 x float> [[TWO]], <8 x float>* [[THREE]], align 16 -// CHECK-NEXT: [[FOUR:%.*]] = load <8 x float>** [[P]], align 8 -// CHECK-NEXT: [[FIVE:%.*]] = load volatile <8 x float>* [[FOUR]], align 16 +// CHECK-NEXT: [[FOUR:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8 +// CHECK-NEXT: [[FIVE:%.*]] = load volatile <8 x float>, <8 x float>* [[FOUR]], align 16 // CHECK-NEXT: store <8 x float> [[FIVE]], <8 x float>* [[R]], align 32 -// CHECK-NEXT: [[SIX:%.*]] = load <8 x float>* [[R]], align 32 +// CHECK-NEXT: [[SIX:%.*]] = load <8 x float>, <8 x float>* [[R]], align 32 // CHECK-NEXT: [[VECEXT:%.*]] = extractelement <8 x float> [[SIX]], i32 0 // CHECK-NEXT: ret float [[VECEXT]] @@ -45,13 +45,13 @@ volatile float TestAlign2(void) // CHECK-NEXT: [[CALL:%.*]] = call noalias i8* @_Znwm(i64 32) // CHECK-NEXT: [[ZERO:%.*]] = bitcast i8* [[CALL]] to <8 x float>* // CHECK-NEXT: store <8 x float>* [[ZERO]], <8 x float>** [[P:%.*]], align 8 -// CHECK-NEXT: [[ONE:%.*]] = load <8 x float>** [[P]], align 8 -// CHECK-NEXT: [[TWO:%.*]] = load volatile <8 x float>* [[ONE]], align 32 -// CHECK-NEXT: [[THREE:%.*]] = load <8 x float>** [[P]], align 8 +// CHECK-NEXT: [[ONE:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8 +// CHECK-NEXT: [[TWO:%.*]] = load volatile <8 x float>, <8 x float>* [[ONE]], align 32 +// CHECK-NEXT: [[THREE:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8 // CHECK-NEXT: store volatile <8 x float> [[TWO]], <8 x float>* [[THREE]], align 32 -// CHECK-NEXT: [[FOUR:%.*]] = load <8 x float>** [[P]], align 8 -// CHECK-NEXT: [[FIVE:%.*]] = load volatile <8 x float>* [[FOUR]], align 32 +// CHECK-NEXT: [[FOUR:%.*]] = load <8 x float>*, <8 x float>** [[P]], align 8 +// CHECK-NEXT: [[FIVE:%.*]] = load volatile <8 x float>, <8 x float>* [[FOUR]], align 32 // CHECK-NEXT: store <8 x float> [[FIVE]], <8 x float>* [[R]], align 32 -// CHECK-NEXT: [[SIX:%.*]] = load <8 x float>* [[R]], align 32 +// CHECK-NEXT: [[SIX:%.*]] = load <8 x float>, <8 x float>* [[R]], align 32 // CHECK-NEXT: [[VECEXT:%.*]] = extractelement <8 x float> [[SIX]], i32 0 // CHECK-NEXT: ret float [[VECEXT]] diff --git a/test/CodeGenCXX/anonymous-union-member-initializer.cpp b/test/CodeGenCXX/anonymous-union-member-initializer.cpp index 98e982d..69fa61c 100644 --- a/test/CodeGenCXX/anonymous-union-member-initializer.cpp +++ b/test/CodeGenCXX/anonymous-union-member-initializer.cpp @@ -82,7 +82,7 @@ namespace PR10512 { // CHECK-LABEL: define void @_ZN7PR105121AC2Ev // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca [[A:%"struct[A-Za-z0-9:.]+"]] // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]] - // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]] + // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]] // CHECK-NEXT: ret void A::A() {} @@ -91,11 +91,11 @@ namespace PR10512 { // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i32 // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]] // CHECK-NEXT: store i32 [[X:%[a-zA-z0-9.]+]], i32* [[XADDR]] - // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]] + // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]] // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} - // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i32* [[XADDR]] + // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i32, i32* [[XADDR]] // CHECK-NEXT: store i32 [[TMP]] // CHECK-NEXT: ret void A::A(int x) : x(x) { } @@ -105,11 +105,11 @@ namespace PR10512 { // CHECK-NEXT: [[XADDR:%[a-zA-z0-9.]+]] = alloca i64 // CHECK-NEXT: store [[A]]* [[THIS:%[a-zA-z0-9.]+]], [[A]]** [[THISADDR]] // CHECK-NEXT: store i64 [[X:%[a-zA-z0-9.]+]], i64* [[XADDR]] - // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]** [[THISADDR]] + // CHECK-NEXT: [[THIS1:%[a-zA-z0-9.]+]] = load [[A]]*, [[A]]** [[THISADDR]] // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 1}} // CHECK-NEXT: {{getelementptr inbounds.*i32 0, i32 0}} - // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i64* [[XADDR]] + // CHECK-NEXT: [[TMP:%[a-zA-z0-9.]+]] = load i64, i64* [[XADDR]] // CHECK-NEXT: [[CONV:%[a-zA-z0-9.]+]] = trunc i64 [[TMP]] to i32 // CHECK-NEXT: store i32 [[CONV]] // CHECK-NEXT: ret void diff --git a/test/CodeGenCXX/apple-kext-indirect-call-2.C b/test/CodeGenCXX/apple-kext-indirect-call-2.cpp index 7e25200..d441b78 100644 --- a/test/CodeGenCXX/apple-kext-indirect-call-2.C +++ b/test/CodeGenCXX/apple-kext-indirect-call-2.cpp @@ -1,9 +1,9 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s // CHECK: @_ZTV1A = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK1A3abcEv to i8*), i8* null] -// CHECK: @_ZTV4Base = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK4Base3abcEv to i8*), i8* null] -// CHECK: @_ZTV8Derived2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK8Derived23efgEv to i8*), i8* null] -// CHECK: @_ZTV2D2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.A*)* @_ZNK2D23abcEv to i8*), i8* null] +// CHECK: @_ZTV4Base = unnamed_addr constant [4 x i8*] [i8* null, i8* null, i8* bitcast (i8* (%struct.Base*)* @_ZNK4Base3abcEv to i8*), i8* null] +// CHECK: @_ZTV8Derived2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.Derived2*)* @_ZNK8Derived23efgEv to i8*), i8* null] +// CHECK: @_ZTV2D2 = unnamed_addr constant [5 x i8*] [i8* null, i8* null, i8* null, i8* bitcast (i8* (%struct.D2*)* @_ZNK2D23abcEv to i8*), i8* null] struct A { virtual const char* abc(void) const; @@ -18,7 +18,7 @@ struct B : virtual A { void B::VF() {} void FUNC(B* p) { -// CHECK: [[T1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV1A to i8* (%struct.A*)**), i64 2) +// CHECK: [[T1:%.*]] = load i8* (%struct.A*)*, i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)*, i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV1A to i8* (%struct.A*)**), i64 2) // CHECK-NEXT: [[T2:%.*]] = call i8* [[T1]] const char* c = p->A::abc(); } @@ -33,7 +33,7 @@ struct Derived : public Base { }; void FUNC1(Derived* p) { -// CHECK: [[U1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([4 x i8*]* @_ZTV4Base to i8* (%struct.A*)**), i64 2) +// CHECK: [[U1:%.*]] = load i8* (%struct.Base*)*, i8* (%struct.Base*)** getelementptr inbounds (i8* (%struct.Base*)*, i8* (%struct.Base*)** bitcast ([4 x i8*]* @_ZTV4Base to i8* (%struct.Base*)**), i64 2) // CHECK-NEXT: [[U2:%.*]] = call i8* [[U1]] char* c = p->Base::abc(); } @@ -49,7 +49,7 @@ struct Derived2 : virtual Base2 { char* Derived2::efg(void) const { return 0; } void FUNC2(Derived2* p) { -// CHECK: [[V1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([5 x i8*]* @_ZTV8Derived2 to i8* (%struct.A*)**), i64 3) +// CHECK: [[V1:%.*]] = load i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** getelementptr inbounds (i8* (%struct.Derived2*)*, i8* (%struct.Derived2*)** bitcast ([5 x i8*]* @_ZTV8Derived2 to i8* (%struct.Derived2*)**), i64 3) // CHECK-NEXT: [[V2:%.*]] = call i8* [[V1]] char* c = p->Derived2::efg(); } @@ -70,7 +70,7 @@ struct Sub : D1, D2 { char* D2::abc(void) const { return 0; } void FUNC3(Sub* p) { -// CHECK: [[W1:%.*]] = load i8* (%struct.A*)** getelementptr inbounds (i8* (%struct.A*)** bitcast ([5 x i8*]* @_ZTV2D2 to i8* (%struct.A*)**), i64 3) +// CHECK: [[W1:%.*]] = load i8* (%struct.D2*)*, i8* (%struct.D2*)** getelementptr inbounds (i8* (%struct.D2*)*, i8* (%struct.D2*)** bitcast ([5 x i8*]* @_ZTV2D2 to i8* (%struct.D2*)**), i64 3) // CHECK-NEXT: [[W2:%.*]] = call i8* [[W1]] char* c = p->D2::abc(); } diff --git a/test/CodeGenCXX/apple-kext-indirect-call.C b/test/CodeGenCXX/apple-kext-indirect-call.C deleted file mode 100644 index 2dbb0b8..0000000 --- a/test/CodeGenCXX/apple-kext-indirect-call.C +++ /dev/null @@ -1,14 +0,0 @@ -// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s - -struct Base { - virtual void abc(void) const; -}; - -void Base::abc(void) const {} - -void FUNC(Base* p) { - p->Base::abc(); -} - -// CHECK: getelementptr inbounds (void (%struct.Base*)** bitcast ([3 x i8*]* @_ZTV4Base to void (%struct.Base*)**), i64 2) -// CHECK-NOT: call void @_ZNK4Base3abcEv diff --git a/test/CodeGenCXX/apple-kext-indirect-call.cpp b/test/CodeGenCXX/apple-kext-indirect-call.cpp new file mode 100644 index 0000000..e4c03b5 --- /dev/null +++ b/test/CodeGenCXX/apple-kext-indirect-call.cpp @@ -0,0 +1,42 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -emit-llvm -o - %s | FileCheck %s + +// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant [5 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI5TemplIiE to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] + +struct Base { + virtual void abc(void) const; +}; + +void Base::abc(void) const {} + +void FUNC(Base* p) { + p->Base::abc(); +} + +// CHECK: getelementptr inbounds (void (%struct.Base*)*, void (%struct.Base*)** bitcast ([4 x i8*]* @_ZTV4Base to void (%struct.Base*)**), i64 2) +// CHECK-NOT: call void @_ZNK4Base3abcEv + +template<class T> +struct Templ { + virtual void f() {} + virtual void g() {} +}; +template<class T> +struct SubTempl : public Templ<T> { + virtual void f() {} // override + virtual void g() {} // override +}; + +void f(SubTempl<int>* t) { + // Qualified calls go through the (qualified) vtable in apple-kext mode. + // Since t's this pointer points to SubTempl's vtable, the call needs + // to load Templ<int>'s vtable. Hence, Templ<int>::g needs to be + // instantiated in this TU, for it's referenced by the vtable. + // (This happens only in apple-kext mode; elsewhere virtual calls can always + // use the vtable pointer off this instead of having to load the vtable + // symbol.) + t->Templ::f(); +} + +// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ([5 x i8*]* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2) +// CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this) +// CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this) diff --git a/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp b/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp index 7ac5b58..5f6bdb2 100644 --- a/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp +++ b/test/CodeGenCXX/apple-kext-indirect-virtual-dtor-call.cpp @@ -1,12 +1,6 @@ // RUN: %clang_cc1 -triple x86_64-apple-darwin10 -fapple-kext -fno-rtti -emit-llvm -o - %s | FileCheck %s -// CHECK-LABEL: define void @_ZN2B1D0Ev -// CHECK: [[T1:%.*]] = load void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2) -// CHECK-NEXT: call void [[T1]](%struct.B1* [[T2:%.*]]) -// CHECK-LABEL: define void @_Z6DELETEP2B1 -// CHECK: [[T3:%.*]] = load void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2) -// CHECK-NEXT: call void [[T3]](%struct.B1* [[T4:%.*]]) - +// CHECK: @_ZTV5TemplIiE = internal unnamed_addr constant [7 x i8*] [i8* null, i8* null, i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED1Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiED0Ev to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1fEv to i8*), i8* bitcast (void (%struct.Templ*)* @_ZN5TemplIiE1gEv to i8*), i8* null] struct B1 { virtual ~B1(); @@ -17,3 +11,38 @@ B1::~B1() {} void DELETE(B1 *pb1) { pb1->B1::~B1(); } +// CHECK-LABEL: define void @_ZN2B1D0Ev +// CHECK: [[T1:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2) +// CHECK-NEXT: call void [[T1]](%struct.B1* [[T2:%.*]]) +// CHECK-LABEL: define void @_Z6DELETEP2B1 +// CHECK: [[T3:%.*]] = load void (%struct.B1*)*, void (%struct.B1*)** getelementptr inbounds (void (%struct.B1*)*, void (%struct.B1*)** bitcast ([5 x i8*]* @_ZTV2B1 to void (%struct.B1*)**), i64 2) +// CHECK-NEXT: call void [[T3]](%struct.B1* [[T4:%.*]]) + +template<class T> +struct Templ { + virtual ~Templ(); // Out-of-line so that the destructor doesn't cause a vtable + virtual void f() {} + virtual void g() {} +}; +template<class T> +struct SubTempl : public Templ<T> { + virtual ~SubTempl() {} // override + virtual void f() {} // override + virtual void g() {} // override +}; + +void f(SubTempl<int>* t) { + // Qualified calls go through the (qualified) vtable in apple-kext mode. + // Since t's this pointer points to SubTempl's vtable, the call needs + // to load Templ<int>'s vtable. Hence, Templ<int>::g needs to be + // instantiated in this TU, for it's referenced by the vtable. + // (This happens only in apple-kext mode; elsewhere virtual calls can always + // use the vtable pointer off this instead of having to load the vtable + // symbol.) + t->Templ::~Templ(); +} + +// CHECK: getelementptr inbounds (void (%struct.Templ*)*, void (%struct.Templ*)** bitcast ([7 x i8*]* @_ZTV5TemplIiE to void (%struct.Templ*)**), i64 2) +// CHECK: declare void @_ZN5TemplIiED0Ev(%struct.Templ*) +// CHECK: define internal void @_ZN5TemplIiE1fEv(%struct.Templ* %this) +// CHECK: define internal void @_ZN5TemplIiE1gEv(%struct.Templ* %this) diff --git a/test/CodeGenCXX/apple-kext-linkage.C b/test/CodeGenCXX/apple-kext-linkage.cpp index e66b038..e66b038 100644 --- a/test/CodeGenCXX/apple-kext-linkage.C +++ b/test/CodeGenCXX/apple-kext-linkage.cpp diff --git a/test/CodeGenCXX/apple-kext-no-staticinit-section.C b/test/CodeGenCXX/apple-kext-no-staticinit-section.cpp index 0401d49..0401d49 100644 --- a/test/CodeGenCXX/apple-kext-no-staticinit-section.C +++ b/test/CodeGenCXX/apple-kext-no-staticinit-section.cpp diff --git a/test/CodeGenCXX/arm-vaarg.cpp b/test/CodeGenCXX/arm-vaarg.cpp index 9850fb3..0220ac8 100644 --- a/test/CodeGenCXX/arm-vaarg.cpp +++ b/test/CodeGenCXX/arm-vaarg.cpp @@ -9,7 +9,7 @@ int take_args(int a, ...) { // CHECK: call void @llvm.va_start emptyvar = __builtin_va_arg(l, Empty); -// CHECK: load i8** +// CHECK: load i8*, i8** // CHECK-NOT: getelementptr // CHECK: [[EMPTY_PTR:%[a-zA-Z0-9._]+]] = bitcast i8* {{%[a-zA-Z0-9._]+}} to %struct.Empty* @@ -17,10 +17,10 @@ int take_args(int a, ...) { // (e.g. it's at the very bottom of the stack and the next page is // invalid). This doesn't matter provided it's never loaded (there's no // well-defined way to tell), but it becomes a problem if we do try to use it. -// CHECK-NOT: load %struct.Empty* [[EMPTY_PTR]] +// CHECK-NOT: load %struct.Empty, %struct.Empty* [[EMPTY_PTR]] int i = __builtin_va_arg(l, int); -// CHECK: load i32* +// CHECK: load i32, i32* __builtin_va_end(l); return i; diff --git a/test/CodeGenCXX/arm.cpp b/test/CodeGenCXX/arm.cpp index b6629f4..7d94cba 100644 --- a/test/CodeGenCXX/arm.cpp +++ b/test/CodeGenCXX/arm.cpp @@ -56,14 +56,14 @@ namespace test1 { // CHECK: define linkonce_odr [[A]]* @_ZN5test11AC1Ei([[A]]* returned %this, i32 %i) unnamed_addr // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]] - // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]] + // CHECK: [[THIS1:%.*]] = load [[A]]*, [[A]]** [[THIS]] // CHECK: {{%.*}} = call [[A]]* @_ZN5test11AC2Ei( // CHECK: ret [[A]]* [[THIS1]] // CHECK: define linkonce_odr [[A]]* @_ZN5test11AD1Ev([[A]]* returned %this) unnamed_addr // CHECK: [[THIS:%.*]] = alloca [[A]]*, align 4 // CHECK: store [[A]]* {{.*}}, [[A]]** [[THIS]] - // CHECK: [[THIS1:%.*]] = load [[A]]** [[THIS]] + // CHECK: [[THIS1:%.*]] = load [[A]]*, [[A]]** [[THIS]] // CHECK: {{%.*}} = call [[A]]* @_ZN5test11AD2Ev( // CHECK: ret [[A]]* [[THIS1]] } @@ -117,7 +117,7 @@ namespace test3 { void b(int n) { // CHECK-LABEL: define void @_ZN5test31bEi( - // CHECK: [[N:%.*]] = load i32* + // CHECK: [[N:%.*]] = load i32, i32* // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4) // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) // CHECK: [[OR:%.*]] = or i1 @@ -138,7 +138,7 @@ namespace test3 { void d(int n) { // CHECK-LABEL: define void @_ZN5test31dEi( - // CHECK: [[N:%.*]] = load i32* + // CHECK: [[N:%.*]] = load i32, i32* // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80) // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) @@ -190,7 +190,7 @@ namespace test4 { void b(int n) { // CHECK-LABEL: define void @_ZN5test41bEi( - // CHECK: [[N:%.*]] = load i32* + // CHECK: [[N:%.*]] = load i32, i32* // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 4) // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) // CHECK: [[SZ:%.*]] = select @@ -210,7 +210,7 @@ namespace test4 { void d(int n) { // CHECK-LABEL: define void @_ZN5test41dEi( - // CHECK: [[N:%.*]] = load i32* + // CHECK: [[N:%.*]] = load i32, i32* // CHECK: @llvm.umul.with.overflow.i32(i32 [[N]], i32 80) // CHECK: [[NE:%.*]] = mul i32 [[N]], 20 // CHECK: @llvm.uadd.with.overflow.i32(i32 {{.*}}, i32 8) @@ -226,7 +226,7 @@ namespace test4 { // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8 // CHECK: getelementptr inbounds {{.*}}, i64 4 // CHECK: bitcast - // CHECK: [[T0:%.*]] = load i32* + // CHECK: [[T0:%.*]] = load i32, i32* // CHECK: [[T1:%.*]] = mul i32 4, [[T0]] // CHECK: [[T2:%.*]] = add i32 [[T1]], 8 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]]) @@ -238,7 +238,7 @@ namespace test4 { // CHECK: [[ALLOC:%.*]] = getelementptr inbounds {{.*}}, i64 -8 // CHECK: getelementptr inbounds {{.*}}, i64 4 // CHECK: bitcast - // CHECK: [[T0:%.*]] = load i32* + // CHECK: [[T0:%.*]] = load i32, i32* // CHECK: [[T1:%.*]] = mul i32 4, [[T0]] // CHECK: [[T2:%.*]] = add i32 [[T1]], 8 // CHECK: call void @_ZN5test41AdaEPvm(i8* [[ALLOC]], i32 [[T2]]) @@ -256,7 +256,7 @@ namespace test5 { void test(A *a) { // CHECK: [[PTR:%.*]] = alloca [[A:%.*]]*, align 4 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[PTR]], align 4 - // CHECK-NEXT: [[TMP:%.*]] = load [[A]]** [[PTR]], align 4 + // CHECK-NEXT: [[TMP:%.*]] = load [[A]]*, [[A]]** [[PTR]], align 4 // CHECK-NEXT: call [[A]]* @_ZN5test51AD1Ev([[A]]* [[TMP]]) // CHECK-NEXT: ret void a->~A(); @@ -272,13 +272,13 @@ namespace test6 { void test(A *a) { // CHECK: [[AVAR:%.*]] = alloca [[A:%.*]]*, align 4 // CHECK-NEXT: store [[A]]* {{.*}}, [[A]]** [[AVAR]], align 4 - // CHECK-NEXT: [[V:%.*]] = load [[A]]** [[AVAR]], align 4 + // CHECK-NEXT: [[V:%.*]] = load [[A]]*, [[A]]** [[AVAR]], align 4 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq [[A]]* [[V]], null // CHECK-NEXT: br i1 [[ISNULL]] // CHECK: [[T0:%.*]] = bitcast [[A]]* [[V]] to void ([[A]]*)*** - // CHECK-NEXT: [[T1:%.*]] = load void ([[A]]*)*** [[T0]] - // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds void ([[A]]*)** [[T1]], i64 1 - // CHECK-NEXT: [[T3:%.*]] = load void ([[A]]*)** [[T2]] + // CHECK-NEXT: [[T1:%.*]] = load void ([[A]]*)**, void ([[A]]*)*** [[T0]] + // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds void ([[A]]*)*, void ([[A]]*)** [[T1]], i64 1 + // CHECK-NEXT: [[T3:%.*]] = load void ([[A]]*)*, void ([[A]]*)** [[T2]] // CHECK-NEXT: call void [[T3]]([[A]]* [[V]]) // CHECK-NEXT: br label // CHECK: ret void @@ -293,7 +293,7 @@ namespace test7 { // CHECK-LABEL: define void @_ZN5test74testEv() void test() { - // CHECK: [[T0:%.*]] = load atomic i8* bitcast (i32* @_ZGVZN5test74testEvE1x to i8*) acquire, align 1 + // CHECK: [[T0:%.*]] = load atomic i8, i8* bitcast (i32* @_ZGVZN5test74testEvE1x to i8*) acquire, align 1 // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1 // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[T1]], 0 // CHECK-NEXT: br i1 [[T2]] @@ -328,7 +328,7 @@ namespace test8 { // CHECK-LABEL: define void @_ZN5test84testEv() void test() { - // CHECK: [[T0:%.*]] = load atomic i8* bitcast (i32* @_ZGVZN5test84testEvE1x to i8*) acquire, align 1 + // CHECK: [[T0:%.*]] = load atomic i8, i8* bitcast (i32* @_ZGVZN5test84testEvE1x to i8*) acquire, align 1 // CHECK-NEXT: [[T1:%.*]] = and i8 [[T0]], 1 // CHECK-NEXT: [[T2:%.*]] = icmp eq i8 [[T1]], 0 // CHECK-NEXT: br i1 [[T2]] @@ -374,7 +374,7 @@ namespace test9 { } // CHECK: define [[TEST9:%.*]]* @_ZN5test97testNewEj(i32 // CHECK: [[N_VAR:%.*]] = alloca i32, align 4 -// CHECK: [[N:%.*]] = load i32* [[N_VAR]], align 4 +// CHECK: [[N:%.*]] = load i32, i32* [[N_VAR]], align 4 // CHECK-NEXT: [[T0:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[N]], i32 16) // CHECK-NEXT: [[O0:%.*]] = extractvalue { i32, i1 } [[T0]], 1 // CHECK-NEXT: [[T1:%.*]] = extractvalue { i32, i1 } [[T0]], 0 @@ -386,9 +386,9 @@ namespace test9 { // CHECK-NEXT: [[ALLOC:%.*]] = call noalias i8* @_Znam(i32 [[T4]]) // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[ALLOC]] to i32* // CHECK-NEXT: store i32 16, i32* [[T0]] -// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i32* [[T0]], i32 1 +// CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i32, i32* [[T0]], i32 1 // CHECK-NEXT: store i32 [[N]], i32* [[T1]] -// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8* [[ALLOC]], i64 16 +// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8, i8* [[ALLOC]], i64 16 // CHECK-NEXT: bitcast i8* [[T0]] to [[TEST9]]* // Array allocation follows. @@ -396,15 +396,15 @@ namespace test9 { delete[] array; } // CHECK-LABEL: define void @_ZN5test910testDeleteEPNS_1AE( -// CHECK: [[BEGIN:%.*]] = load [[TEST9]]** +// CHECK: [[BEGIN:%.*]] = load [[TEST9]]*, [[TEST9]]** // CHECK-NEXT: [[T0:%.*]] = icmp eq [[TEST9]]* [[BEGIN]], null // CHECK-NEXT: br i1 [[T0]], // CHECK: [[T0:%.*]] = bitcast [[TEST9]]* [[BEGIN]] to i8* -// CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8* [[T0]], i64 -16 -// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8* [[ALLOC]], i64 4 +// CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 -16 +// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i8, i8* [[ALLOC]], i64 4 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i32* -// CHECK-NEXT: [[N:%.*]] = load i32* [[T1]] -// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[TEST9]]* [[BEGIN]], i32 [[N]] +// CHECK-NEXT: [[N:%.*]] = load i32, i32* [[T1]] +// CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[TEST9]], [[TEST9]]* [[BEGIN]], i32 [[N]] // CHECK-NEXT: [[T0:%.*]] = icmp eq [[TEST9]]* [[BEGIN]], [[END]] // CHECK-NEXT: br i1 [[T0]], // Array deallocation follows. diff --git a/test/CodeGenCXX/arm64-constructor-return.cpp b/test/CodeGenCXX/arm64-constructor-return.cpp index 0d5b3b3..3adc1b7 100644 --- a/test/CodeGenCXX/arm64-constructor-return.cpp +++ b/test/CodeGenCXX/arm64-constructor-return.cpp @@ -15,5 +15,5 @@ S::S() { // CHECK: %struct.S* @_ZN1SC1Ev(%struct.S* returned %this) // CHECK: [[THISADDR:%[a-zA-z0-9.]+]] = alloca %struct.S* // CHECK: store %struct.S* %this, %struct.S** [[THISADDR]] -// CHECK: [[THIS1:%.*]] = load %struct.S** [[THISADDR]] +// CHECK: [[THIS1:%.*]] = load %struct.S*, %struct.S** [[THISADDR]] // CHECK: ret %struct.S* [[THIS1]] diff --git a/test/CodeGenCXX/arm64-empty-struct.cpp b/test/CodeGenCXX/arm64-empty-struct.cpp index 6fa4e95..6053c4a 100644 --- a/test/CodeGenCXX/arm64-empty-struct.cpp +++ b/test/CodeGenCXX/arm64-empty-struct.cpp @@ -9,7 +9,7 @@ int take_args(int a, ...) { // CHECK: call void @llvm.va_start emptyvar = __builtin_va_arg(l, Empty); -// CHECK: load i8** +// CHECK: load i8*, i8** // CHECK-NOT: getelementptr // CHECK: [[EMPTY_PTR:%[a-zA-Z0-9._]+]] = bitcast i8* {{%[a-zA-Z0-9._]+}} to %struct.Empty* @@ -17,7 +17,7 @@ int take_args(int a, ...) { // (e.g. it's at the very bottom of the stack and the next page is // invalid). This doesn't matter provided it's never loaded (there's no // well-defined way to tell), but it becomes a problem if we do try to use it. -// CHECK-NOT: load %struct.Empty* [[EMPTY_PTR]] +// CHECK-NOT: load %struct.Empty, %struct.Empty* [[EMPTY_PTR]] int i = __builtin_va_arg(l, int); // CHECK: va_arg i8** {{%[a-zA-Z0-9._]+}}, i32 diff --git a/test/CodeGenCXX/arm64.cpp b/test/CodeGenCXX/arm64.cpp index d0d4f4f..19f7272 100644 --- a/test/CodeGenCXX/arm64.cpp +++ b/test/CodeGenCXX/arm64.cpp @@ -45,33 +45,34 @@ namespace test2 { virtual void foo(); }; void A::foo() {} - // Tested below because these globals get kindof oddly rearranged. + // CHECK-GLOBALS-DAG: @_ZTSN5test21AE = constant [11 x i8] + // CHECK-GLOBALS-DAG: @_ZTIN5test21AE = constant { {{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @_ZTSN5test21AE, i32 0, i32 0) } struct __attribute__((visibility("hidden"))) B {}; const std::type_info &b0 = typeid(B); - // CHECK-GLOBALS: @_ZTSN5test21BE = linkonce_odr hidden constant - // CHECK-GLOBALS: @_ZTIN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([11 x i8]* @_ZTSN5test21BE, i32 0, i32 0) } + // CHECK-GLOBALS-DAG: @_ZTSN5test21BE = linkonce_odr hidden constant + // CHECK-GLOBALS-DAG: @_ZTIN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @_ZTSN5test21BE, i32 0, i32 0) } const std::type_info &b1 = typeid(B*); - // CHECK-GLOBALS: @_ZTSPN5test21BE = linkonce_odr hidden constant - // CHECK-GLOBALS: @_ZTIPN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([12 x i8]* @_ZTSPN5test21BE, i32 0, i32 0), i32 0, i8* bitcast + // CHECK-GLOBALS-DAG: @_ZTSPN5test21BE = linkonce_odr hidden constant + // CHECK-GLOBALS-DAG: @_ZTIPN5test21BE = linkonce_odr hidden constant { {{.*}}, i8* getelementptr inbounds ([12 x i8], [12 x i8]* @_ZTSPN5test21BE, i32 0, i32 0), i32 0, i8* bitcast struct C {}; const std::type_info &c0 = typeid(C); - // CHECK-GLOBALS: @_ZTSN5test21CE = linkonce_odr hidden constant - // CHECK-GLOBALS: @_ZTIN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([11 x i8]* @_ZTSN5test21CE to i64), i64 -9223372036854775808) to i8*) } + // CHECK-GLOBALS-DAG: @_ZTSN5test21CE = linkonce_odr hidden constant + // CHECK-GLOBALS-DAG: @_ZTIN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([11 x i8]* @_ZTSN5test21CE to i64), i64 -9223372036854775808) to i8*) } const std::type_info &c1 = typeid(C*); - // CHECK-GLOBALS: @_ZTSPN5test21CE = linkonce_odr hidden constant - // CHECK-GLOBALS: @_ZTIPN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([12 x i8]* @_ZTSPN5test21CE to i64), i64 -9223372036854775808) to i8*), i32 0, i8* bitcast + // CHECK-GLOBALS-DAG: @_ZTSPN5test21CE = linkonce_odr hidden constant + // CHECK-GLOBALS-DAG: @_ZTIPN5test21CE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([12 x i8]* @_ZTSPN5test21CE to i64), i64 -9223372036854775808) to i8*), i32 0, i8* bitcast // This class is explicitly-instantiated, but that instantiation // doesn't guarantee to emit RTTI, so we can still demote the visibility. template <class T> class D {}; template class D<int>; const std::type_info &d0 = typeid(D<int>); - // CHECK-GLOBALS: @_ZTSN5test21DIiEE = linkonce_odr hidden constant - // CHECK-GLOBALS: @_ZTIN5test21DIiEE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21DIiEE to i64), i64 -9223372036854775808) to i8*) } + // CHECK-GLOBALS-DAG: @_ZTSN5test21DIiEE = linkonce_odr hidden constant + // CHECK-GLOBALS-DAG: @_ZTIN5test21DIiEE = linkonce_odr hidden constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21DIiEE to i64), i64 -9223372036854775808) to i8*) } // This class is explicitly-instantiated and *does* guarantee to // emit RTTI, so we're stuck with having to use default visibility. @@ -79,10 +80,7 @@ namespace test2 { virtual void foo() {} }; template class E<int>; - // CHECK-GLOBALS: @_ZTSN5test21EIiEE = weak_odr constant [14 x i8] - // CHECK-GLOBALS: @_ZTIN5test21EIiEE = weak_odr constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21EIiEE to i64), i64 -9223372036854775808) to i8*) } - - // CHECK-GLOBALS: @_ZTSN5test21AE = constant [11 x i8] - // CHECK-GLOBALS: @_ZTIN5test21AE = constant { {{.*}}, i8* getelementptr inbounds ([11 x i8]* @_ZTSN5test21AE, i32 0, i32 0) } + // CHECK-GLOBALS-DAG: @_ZTSN5test21EIiEE = weak_odr constant [14 x i8] + // CHECK-GLOBALS-DAG: @_ZTIN5test21EIiEE = weak_odr constant { {{.*}}, i8* inttoptr (i64 add (i64 ptrtoint ([14 x i8]* @_ZTSN5test21EIiEE to i64), i64 -9223372036854775808) to i8*) } } diff --git a/test/CodeGenCXX/atomicinit.cpp b/test/CodeGenCXX/atomicinit.cpp index 982396e..a47099c 100644 --- a/test/CodeGenCXX/atomicinit.cpp +++ b/test/CodeGenCXX/atomicinit.cpp @@ -81,8 +81,8 @@ namespace PR18097 { _Atomic(int) b; }; // CHECK-LABEL: define {{.*}} @__cxx_global_var_init - // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* getelementptr inbounds ({{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 0), i32 4) - // CHECK: store i32 5, i32* getelementptr inbounds ({{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 1) + // CHECK: call void @_ZN7PR180977dynamic1XC1Ei({{.*}}* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 0), i32 4) + // CHECK: store i32 5, i32* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN7PR180977dynamic1yE, i32 0, i32 1) Y y = { X(4), 5 }; } diff --git a/test/CodeGenCXX/auto-variable-template.cpp b/test/CodeGenCXX/auto-variable-template.cpp new file mode 100644 index 0000000..265d81d --- /dev/null +++ b/test/CodeGenCXX/auto-variable-template.cpp @@ -0,0 +1,14 @@ +// RUN: %clang_cc1 -std=c++14 %s -triple=x86_64-linux -emit-llvm -o - | FileCheck %s + +struct f { + void operator()() const {} +}; + +template <typename T> auto vtemplate = f{}; + +int main() { vtemplate<int>(); } + +// CHECK: @_Z9vtemplateIiE = linkonce_odr global %struct.f undef, comdat + +// CHECK: define i32 @main() +// CHECK: call void @_ZNK1fclEv(%struct.f* @_Z9vtemplateIiE) diff --git a/test/CodeGenCXX/bitfield.cpp b/test/CodeGenCXX/bitfield.cpp index fafeffe..7f55b4d 100644 --- a/test/CodeGenCXX/bitfield.cpp +++ b/test/CodeGenCXX/bitfield.cpp @@ -22,13 +22,13 @@ namespace N0 { unsigned read00(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N06read00 // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-X86-64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-X86-64: %[[and:.*]] = and i64 %[[val]], 16383 // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 // CHECK-X86-64: ret i32 %[[trunc]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read00 // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-PPC64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 50 // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[shr]] to i32 // CHECK-PPC64: ret i32 %[[trunc]] @@ -37,14 +37,14 @@ namespace N0 { unsigned read01(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N06read01 // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-X86-64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 14 // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 3 // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 // CHECK-X86-64: ret i32 %[[trunc]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read01 // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-PPC64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 48 // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 3 // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 @@ -54,14 +54,14 @@ namespace N0 { unsigned read20(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N06read20 // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-X86-64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 16 // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 63 // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 // CHECK-X86-64: ret i32 %[[trunc]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read20 // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-PPC64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 42 // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 63 // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 @@ -71,14 +71,14 @@ namespace N0 { unsigned read21(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N06read21 // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-X86-64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 22 // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 3 // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 // CHECK-X86-64: ret i32 %[[trunc]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read21 // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-PPC64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 40 // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 3 // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 @@ -88,14 +88,14 @@ namespace N0 { unsigned read30(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N06read30 // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-X86-64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 24 // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 1073741823 // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 // CHECK-X86-64: ret i32 %[[trunc]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read30 // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-PPC64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 10 // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 1073741823 // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 @@ -105,14 +105,14 @@ namespace N0 { unsigned read31(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N06read31 // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-X86-64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 54 // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 3 // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 // CHECK-X86-64: ret i32 %[[trunc]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read31 // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-PPC64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 8 // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 3 // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 @@ -122,14 +122,14 @@ namespace N0 { unsigned read70(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N06read70 // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-X86-64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 56 // CHECK-X86-64: %[[and:.*]] = and i64 %[[shr]], 63 // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 // CHECK-X86-64: ret i32 %[[trunc]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read70 // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-PPC64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-PPC64: %[[shr:.*]] = lshr i64 %[[val]], 2 // CHECK-PPC64: %[[and:.*]] = and i64 %[[shr]], 63 // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 @@ -139,13 +139,13 @@ namespace N0 { unsigned read71(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N06read71 // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-X86-64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-X86-64: %[[shr:.*]] = lshr i64 %[[val]], 62 // CHECK-X86-64: %[[trunc:.*]] = trunc i64 %[[shr]] to i32 // CHECK-X86-64: ret i32 %[[trunc]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N06read71 // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i64* - // CHECK-PPC64: %[[val:.*]] = load i64* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i64, i64* %[[ptr]] // CHECK-PPC64: %[[and:.*]] = and i64 %[[val]], 3 // CHECK-PPC64: %[[trunc:.*]] = trunc i64 %[[and]] to i32 // CHECK-PPC64: ret i32 %[[trunc]] @@ -167,14 +167,14 @@ namespace N1 { }; unsigned read(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N14read - // CHECK-X86-64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}* %{{.*}}, i32 0, i32 1 - // CHECK-X86-64: %[[val:.*]] = load i8* %[[ptr]] + // CHECK-X86-64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-X86-64: %[[val:.*]] = load i8, i8* %[[ptr]] // CHECK-X86-64: %[[and:.*]] = and i8 %[[val]], 1 // CHECK-X86-64: %[[ext:.*]] = zext i8 %[[and]] to i32 // CHECK-X86-64: ret i32 %[[ext]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N14read - // CHECK-PPC64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}* %{{.*}}, i32 0, i32 1 - // CHECK-PPC64: %[[val:.*]] = load i8* %[[ptr]] + // CHECK-PPC64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-PPC64: %[[val:.*]] = load i8, i8* %[[ptr]] // CHECK-PPC64: %[[shr:.*]] = lshr i8 %[[val]], 7 // CHECK-PPC64: %[[ext:.*]] = zext i8 %[[shr]] to i32 // CHECK-PPC64: ret i32 %[[ext]] @@ -182,17 +182,17 @@ namespace N1 { } void write(S* s, unsigned x) { // CHECK-X86-64-LABEL: define void @_ZN2N15write - // CHECK-X86-64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-X86-64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-X86-64: %[[x_trunc:.*]] = trunc i32 %{{.*}} to i8 - // CHECK-X86-64: %[[old:.*]] = load i8* %[[ptr]] + // CHECK-X86-64: %[[old:.*]] = load i8, i8* %[[ptr]] // CHECK-X86-64: %[[x_and:.*]] = and i8 %[[x_trunc]], 1 // CHECK-X86-64: %[[old_and:.*]] = and i8 %[[old]], -2 // CHECK-X86-64: %[[new:.*]] = or i8 %[[old_and]], %[[x_and]] // CHECK-X86-64: store i8 %[[new]], i8* %[[ptr]] // CHECK-PPC64-LABEL: define void @_ZN2N15write - // CHECK-PPC64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-PPC64: %[[ptr:.*]] = getelementptr inbounds %{{.*}}, %{{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-PPC64: %[[x_trunc:.*]] = trunc i32 %{{.*}} to i8 - // CHECK-PPC64: %[[old:.*]] = load i8* %[[ptr]] + // CHECK-PPC64: %[[old:.*]] = load i8, i8* %[[ptr]] // CHECK-PPC64: %[[x_and:.*]] = and i8 %[[x_trunc]], 1 // CHECK-PPC64: %[[x_shl:.*]] = shl i8 %[[x_and]], 7 // CHECK-PPC64: %[[old_and:.*]] = and i8 %[[old]], 127 @@ -212,12 +212,12 @@ namespace N2 { unsigned read(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N24read // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-X86-64: %[[val:.*]] = load i32* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i32, i32* %[[ptr]] // CHECK-X86-64: %[[and:.*]] = and i32 %[[val]], 16777215 // CHECK-X86-64: ret i32 %[[and]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N24read // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-PPC64: %[[val:.*]] = load i32* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i32, i32* %[[ptr]] // CHECK-PPC64: %[[shr:.*]] = lshr i32 %[[val]], 8 // CHECK-PPC64: ret i32 %[[shr]] return s->b; @@ -225,14 +225,14 @@ namespace N2 { void write(S* s, unsigned x) { // CHECK-X86-64-LABEL: define void @_ZN2N25write // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-X86-64: %[[old:.*]] = load i32* %[[ptr]] + // CHECK-X86-64: %[[old:.*]] = load i32, i32* %[[ptr]] // CHECK-X86-64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215 // CHECK-X86-64: %[[old_and:.*]] = and i32 %[[old]], -16777216 // CHECK-X86-64: %[[new:.*]] = or i32 %[[old_and]], %[[x_and]] // CHECK-X86-64: store i32 %[[new]], i32* %[[ptr]] // CHECK-PPC64-LABEL: define void @_ZN2N25write // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-PPC64: %[[old:.*]] = load i32* %[[ptr]] + // CHECK-PPC64: %[[old:.*]] = load i32, i32* %[[ptr]] // CHECK-PPC64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215 // CHECK-PPC64: %[[x_shl:.*]] = shl i32 %[[x_and]], 8 // CHECK-PPC64: %[[old_and:.*]] = and i32 %[[old]], 255 @@ -251,12 +251,12 @@ namespace N3 { unsigned read(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N34read // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-X86-64: %[[val:.*]] = load i32* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i32, i32* %[[ptr]] // CHECK-X86-64: %[[and:.*]] = and i32 %[[val]], 16777215 // CHECK-X86-64: ret i32 %[[and]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N34read // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-PPC64: %[[val:.*]] = load i32* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i32, i32* %[[ptr]] // CHECK-PPC64: %[[shr:.*]] = lshr i32 %[[val]], 8 // CHECK-PPC64: ret i32 %[[shr]] return s->b; @@ -264,14 +264,14 @@ namespace N3 { void write(S* s, unsigned x) { // CHECK-X86-64-LABEL: define void @_ZN2N35write // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-X86-64: %[[old:.*]] = load i32* %[[ptr]] + // CHECK-X86-64: %[[old:.*]] = load i32, i32* %[[ptr]] // CHECK-X86-64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215 // CHECK-X86-64: %[[old_and:.*]] = and i32 %[[old]], -16777216 // CHECK-X86-64: %[[new:.*]] = or i32 %[[old_and]], %[[x_and]] // CHECK-X86-64: store i32 %[[new]], i32* %[[ptr]] // CHECK-PPC64-LABEL: define void @_ZN2N35write // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-PPC64: %[[old:.*]] = load i32* %[[ptr]] + // CHECK-PPC64: %[[old:.*]] = load i32, i32* %[[ptr]] // CHECK-PPC64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215 // CHECK-PPC64: %[[x_shl:.*]] = shl i32 %[[x_and]], 8 // CHECK-PPC64: %[[old_and:.*]] = and i32 %[[old]], 255 @@ -301,27 +301,27 @@ namespace N4 { // instrumented by ThreadSanitizer. // // CHECK-X86-64-LABEL: define i32 @_ZN2N44read - // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-X86-64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24* - // CHECK-X86-64: %[[val:.*]] = load i24* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i24, i24* %[[ptr]] // CHECK-X86-64: %[[ext:.*]] = zext i24 %[[val]] to i32 // CHECK-X86-64: ret i32 %[[ext]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N44read - // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-PPC64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24* - // CHECK-PPC64: %[[val:.*]] = load i24* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i24, i24* %[[ptr]] // CHECK-PPC64: %[[ext:.*]] = zext i24 %[[val]] to i32 // CHECK-PPC64: ret i32 %[[ext]] return s->b; } void write(Base* s, unsigned x) { // CHECK-X86-64-LABEL: define void @_ZN2N45write - // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-X86-64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24* // CHECK-X86-64: %[[new:.*]] = trunc i32 %{{.*}} to i24 // CHECK-X86-64: store i24 %[[new]], i24* %[[ptr]] // CHECK-PPC64-LABEL: define void @_ZN2N45write - // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-PPC64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24* // CHECK-PPC64: %[[new:.*]] = trunc i32 %{{.*}} to i24 // CHECK-PPC64: store i24 %[[new]], i24* %[[ptr]] @@ -344,12 +344,12 @@ namespace N5 { unsigned read(U* u) { // CHECK-X86-64-LABEL: define i32 @_ZN2N54read // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-X86-64: %[[val:.*]] = load i32* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i32, i32* %[[ptr]] // CHECK-X86-64: %[[and:.*]] = and i32 %[[val]], 16777215 // CHECK-X86-64: ret i32 %[[and]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N54read // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-PPC64: %[[val:.*]] = load i32* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i32, i32* %[[ptr]] // CHECK-PPC64: %[[shr:.*]] = lshr i32 %[[val]], 8 // CHECK-PPC64: ret i32 %[[shr]] return u->y.b; @@ -357,14 +357,14 @@ namespace N5 { void write(U* u, unsigned x) { // CHECK-X86-64-LABEL: define void @_ZN2N55write // CHECK-X86-64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-X86-64: %[[old:.*]] = load i32* %[[ptr]] + // CHECK-X86-64: %[[old:.*]] = load i32, i32* %[[ptr]] // CHECK-X86-64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215 // CHECK-X86-64: %[[old_and:.*]] = and i32 %[[old]], -16777216 // CHECK-X86-64: %[[new:.*]] = or i32 %[[old_and]], %[[x_and]] // CHECK-X86-64: store i32 %[[new]], i32* %[[ptr]] // CHECK-PPC64-LABEL: define void @_ZN2N55write // CHECK-PPC64: %[[ptr:.*]] = bitcast %{{.*}}* %{{.*}} to i32* - // CHECK-PPC64: %[[old:.*]] = load i32* %[[ptr]] + // CHECK-PPC64: %[[old:.*]] = load i32, i32* %[[ptr]] // CHECK-PPC64: %[[x_and:.*]] = and i32 %{{.*}}, 16777215 // CHECK-PPC64: %[[x_shl:.*]] = shl i32 %[[x_and]], 8 // CHECK-PPC64: %[[old_and:.*]] = and i32 %[[old]], 255 @@ -389,19 +389,19 @@ namespace N6 { unsigned read(S* s) { // CHECK-X86-64-LABEL: define i32 @_ZN2N64read // CHECK-X86-64: %[[ptr1:.*]] = bitcast {{.*}}* %{{.*}} to i24* - // CHECK-X86-64: %[[val1:.*]] = load i24* %[[ptr1]] + // CHECK-X86-64: %[[val1:.*]] = load i24, i24* %[[ptr1]] // CHECK-X86-64: %[[ext1:.*]] = zext i24 %[[val1]] to i32 - // CHECK-X86-64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 - // CHECK-X86-64: %[[val2:.*]] = load i8* %[[ptr2]] + // CHECK-X86-64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-X86-64: %[[val2:.*]] = load i8, i8* %[[ptr2]] // CHECK-X86-64: %[[ext2:.*]] = zext i8 %[[val2]] to i32 // CHECK-X86-64: %[[add:.*]] = add nsw i32 %[[ext1]], %[[ext2]] // CHECK-X86-64: ret i32 %[[add]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N64read // CHECK-PPC64: %[[ptr1:.*]] = bitcast {{.*}}* %{{.*}} to i24* - // CHECK-PPC64: %[[val1:.*]] = load i24* %[[ptr1]] + // CHECK-PPC64: %[[val1:.*]] = load i24, i24* %[[ptr1]] // CHECK-PPC64: %[[ext1:.*]] = zext i24 %[[val1]] to i32 - // CHECK-PPC64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 - // CHECK-PPC64: %[[val2:.*]] = load i8* %[[ptr2]] + // CHECK-PPC64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-PPC64: %[[val2:.*]] = load i8, i8* %[[ptr2]] // CHECK-PPC64: %[[ext2:.*]] = zext i8 %[[val2]] to i32 // CHECK-PPC64: %[[add:.*]] = add nsw i32 %[[ext1]], %[[ext2]] // CHECK-PPC64: ret i32 %[[add]] @@ -413,14 +413,14 @@ namespace N6 { // CHECK-X86-64: %[[new1:.*]] = trunc i32 %{{.*}} to i24 // CHECK-X86-64: store i24 %[[new1]], i24* %[[ptr1]] // CHECK-X86-64: %[[new2:.*]] = trunc i32 %{{.*}} to i8 - // CHECK-X86-64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-X86-64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-X86-64: store i8 %[[new2]], i8* %[[ptr2]] // CHECK-PPC64-LABEL: define void @_ZN2N65write // CHECK-PPC64: %[[ptr1:.*]] = bitcast {{.*}}* %{{.*}} to i24* // CHECK-PPC64: %[[new1:.*]] = trunc i32 %{{.*}} to i24 // CHECK-PPC64: store i24 %[[new1]], i24* %[[ptr1]] // CHECK-PPC64: %[[new2:.*]] = trunc i32 %{{.*}} to i8 - // CHECK-PPC64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-PPC64: %[[ptr2:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-PPC64: store i8 %[[new2]], i8* %[[ptr2]] s->b1 = x; s->b2 = x; @@ -451,27 +451,27 @@ namespace N7 { // instrumented by ThreadSanitizer. // // CHECK-X86-64-LABEL: define i32 @_ZN2N74read - // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-X86-64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24* - // CHECK-X86-64: %[[val:.*]] = load i24* %[[ptr]] + // CHECK-X86-64: %[[val:.*]] = load i24, i24* %[[ptr]] // CHECK-X86-64: %[[ext:.*]] = zext i24 %[[val]] to i32 // CHECK-X86-64: ret i32 %[[ext]] // CHECK-PPC64-LABEL: define zeroext i32 @_ZN2N74read - // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-PPC64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24* - // CHECK-PPC64: %[[val:.*]] = load i24* %[[ptr]] + // CHECK-PPC64: %[[val:.*]] = load i24, i24* %[[ptr]] // CHECK-PPC64: %[[ext:.*]] = zext i24 %[[val]] to i32 // CHECK-PPC64: ret i32 %[[ext]] return s->b; } void write(B2* s, unsigned x) { // CHECK-X86-64-LABEL: define void @_ZN2N75write - // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-X86-64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-X86-64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24* // CHECK-X86-64: %[[new:.*]] = trunc i32 %{{.*}} to i24 // CHECK-X86-64: store i24 %[[new]], i24* %[[ptr]] // CHECK-PPC64-LABEL: define void @_ZN2N75write - // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}* %{{.*}}, i32 0, i32 1 + // CHECK-PPC64: %[[gep:.*]] = getelementptr inbounds {{.*}}, {{.*}}* %{{.*}}, i32 0, i32 1 // CHECK-PPC64: %[[ptr:.*]] = bitcast [3 x i8]* %[[gep]] to i24* // CHECK-PPC64: %[[new:.*]] = trunc i32 %{{.*}} to i24 // CHECK-PPC64: store i24 %[[new]], i24* %[[ptr]] diff --git a/test/CodeGenCXX/blocks-cxx11.cpp b/test/CodeGenCXX/blocks-cxx11.cpp index 10d1c65..c437ad8 100644 --- a/test/CodeGenCXX/blocks-cxx11.cpp +++ b/test/CodeGenCXX/blocks-cxx11.cpp @@ -51,7 +51,7 @@ namespace test_complex_int { // CHECK: store i32 500, // CHECK-NEXT: store i32 0, // CHECK-NEXT: [[COERCE:%.*]] = bitcast - // CHECK-NEXT: [[CVAL:%.*]] = load i64* [[COERCE]] + // CHECK-NEXT: [[CVAL:%.*]] = load i64, i64* [[COERCE]] // CHECK-NEXT: call void @_Z13takeItByValueICiEvT_(i64 [[CVAL]]) } } @@ -70,14 +70,14 @@ namespace test_complex_int_ref_mutable { void test() { const _Complex int &x = y; takeABlock(^{ takeItByValue(x); }); - // CHECK: [[R:%.*]] = load i32* getelementptr inbounds ({ i32, i32 }* @_ZN28test_complex_int_ref_mutable1yE, i32 0, i32 0) - // CHECK-NEXT: [[I:%.*]] = load i32* getelementptr inbounds ({ i32, i32 }* @_ZN28test_complex_int_ref_mutable1yE, i32 0, i32 1) - // CHECK-NEXT: [[RSLOT:%.*]] = getelementptr inbounds { i32, i32 }* [[CSLOT:%.*]], i32 0, i32 0 - // CHECK-NEXT: [[ISLOT:%.*]] = getelementptr inbounds { i32, i32 }* [[CSLOT]], i32 0, i32 1 + // CHECK: [[R:%.*]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZN28test_complex_int_ref_mutable1yE, i32 0, i32 0) + // CHECK-NEXT: [[I:%.*]] = load i32, i32* getelementptr inbounds ({ i32, i32 }, { i32, i32 }* @_ZN28test_complex_int_ref_mutable1yE, i32 0, i32 1) + // CHECK-NEXT: [[RSLOT:%.*]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[CSLOT:%.*]], i32 0, i32 0 + // CHECK-NEXT: [[ISLOT:%.*]] = getelementptr inbounds { i32, i32 }, { i32, i32 }* [[CSLOT]], i32 0, i32 1 // CHECK-NEXT: store i32 [[R]], i32* [[RSLOT]] // CHECK-NEXT: store i32 [[I]], i32* [[ISLOT]] // CHECK-NEXT: [[COERCE:%.*]] = bitcast { i32, i32 }* [[CSLOT]] to i64* - // CHECK-NEXT: [[CVAL:%.*]] = load i64* [[COERCE]], + // CHECK-NEXT: [[CVAL:%.*]] = load i64, i64* [[COERCE]], // CHECK-NEXT: call void @_Z13takeItByValueICiEvT_(i64 [[CVAL]]) } } @@ -102,10 +102,10 @@ namespace test_block_in_lambda { } // CHECK-LABEL: define internal void @"_ZZN20test_block_in_lambda4testENS_1AEENK3$_0clEv"( // CHECK: [[BLOCK:%.*]] = alloca [[BLOCK_T:<{.*}>]], align 8 - // CHECK: [[THIS:%.*]] = load [[LAMBDA_T:%.*]]** - // CHECK: [[TO_DESTROY:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 - // CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 - // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[LAMBDA_T]]* [[THIS]], i32 0, i32 0 + // CHECK: [[THIS:%.*]] = load [[LAMBDA_T:%.*]]*, [[LAMBDA_T:%.*]]** + // CHECK: [[TO_DESTROY:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 + // CHECK: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 + // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds [[LAMBDA_T]], [[LAMBDA_T]]* [[THIS]], i32 0, i32 0 // CHECK-NEXT: call void @_ZN20test_block_in_lambda1AC1ERKS0_({{.*}}* [[T0]], {{.*}}* dereferenceable({{[0-9]+}}) [[T1]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* // CHECK-NEXT: call void @_ZN20test_block_in_lambda9takeBlockEU13block_pointerFvvE(void ()* [[T0]]) diff --git a/test/CodeGenCXX/blocks.cpp b/test/CodeGenCXX/blocks.cpp index 6b11083..5b7c7e6 100644 --- a/test/CodeGenCXX/blocks.cpp +++ b/test/CodeGenCXX/blocks.cpp @@ -122,7 +122,7 @@ namespace test4 { // CHECK-LABEL: define internal void @___ZN5test44testEv_block_invoke // CHECK: [[TMP:%.*]] = alloca [[A:%.*]], align 1 // CHECK-NEXT: store i8* [[BLOCKDESC:%.*]], i8** {{.*}}, align 8 - // CHECK-NEXT: load i8* + // CHECK-NEXT: load i8*, i8** // CHECK-NEXT: bitcast i8* [[BLOCKDESC]] to <{ i8*, i32, i32, i8*, %struct.__block_descriptor* }>* // CHECK: call void @_ZN5test41AC1Ev([[A]]* [[TMP]]) // CHECK-NEXT: call void @_ZN5test43fooENS_1AE([[A]]* [[TMP]]) @@ -156,14 +156,14 @@ namespace test5 { // CHECK-NEXT: [[T0:%.*]] = zext i1 // CHECK-NEXT: store i8 [[T0]], i8* [[COND]], align 1 // CHECK-NEXT: call void @_ZN5test51AC1Ev([[A]]* [[X]]) - // CHECK-NEXT: [[CLEANUP_ADDR:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 - // CHECK-NEXT: [[T0:%.*]] = load i8* [[COND]], align 1 + // CHECK-NEXT: [[CLEANUP_ADDR:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 + // CHECK-NEXT: [[T0:%.*]] = load i8, i8* [[COND]], align 1 // CHECK-NEXT: [[T1:%.*]] = trunc i8 [[T0]] to i1 // CHECK-NEXT: store i1 false, i1* [[CLEANUP_ACTIVE]] // CHECK-NEXT: br i1 [[T1]], // CHECK-NOT: br - // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 + // CHECK: [[CAPTURE:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5 // CHECK-NEXT: call void @_ZN5test51AC1ERKS0_([[A]]* [[CAPTURE]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) // CHECK-NEXT: store i1 true, i1* [[CLEANUP_ACTIVE]] // CHECK-NEXT: bitcast [[BLOCK_T]]* [[BLOCK]] to void ()* @@ -173,7 +173,7 @@ namespace test5 { // CHECK-NEXT: store // CHECK-NEXT: load // CHECK-NEXT: call void @_ZN5test511doWithBlockEU13block_pointerFvvE( - // CHECK-NEXT: [[T0:%.*]] = load i1* [[CLEANUP_ACTIVE]] + // CHECK-NEXT: [[T0:%.*]] = load i1, i1* [[CLEANUP_ACTIVE]] // CHECK-NEXT: br i1 [[T0]] // CHECK: call void @_ZN5test51AD1Ev([[A]]* [[CLEANUP_ADDR]]) // CHECK-NEXT: br label diff --git a/test/CodeGenCXX/call-with-static-chain.cpp b/test/CodeGenCXX/call-with-static-chain.cpp index 7cf9291..ac1149b 100644 --- a/test/CodeGenCXX/call-with-static-chain.cpp +++ b/test/CodeGenCXX/call-with-static-chain.cpp @@ -21,7 +21,7 @@ A &f4(); void test() { A a; - // CHECK32: call i32 bitcast (i32 (%struct.A*, %struct.A*, %struct.A*, %struct.A*)* @f1 to i32 (i8*, %struct.A*, %struct.A*, %struct.A*, %struct.A*)*)(i8* nest bitcast (i32 (%struct.A*, %struct.A*, %struct.A*, %struct.A*)* @f1 to i8*) + // CHECK32: call i32 bitcast (i32 (i32, i32, i32, i32, i32, i32, i32, i32)* @f1 to i32 (i8*, i32, i32, i32, i32, i32, i32, i32, i32)*)(i8* nest bitcast (i32 (i32, i32, i32, i32, i32, i32, i32, i32)* @f1 to i8*) // CHECK64: call i32 bitcast (i32 (i64, i64, i64, i64, i64, i64, %struct.A*)* @f1 to i32 (i8*, i64, i64, i64, i64, i64, i64, %struct.A*)*)(i8* nest bitcast (i32 (i64, i64, i64, i64, i64, i64, %struct.A*)* @f1 to i8*) __builtin_call_with_static_chain(f1(a, a, a, a), f1); diff --git a/test/CodeGenCXX/captured-statements.cpp b/test/CodeGenCXX/captured-statements.cpp index fb35446..ebb3833 100644 --- a/test/CodeGenCXX/captured-statements.cpp +++ b/test/CodeGenCXX/captured-statements.cpp @@ -21,6 +21,8 @@ struct TestClass { Foo f; #pragma clang __debug captured { + static double inner = x; + (void)inner; f.y = x; } } @@ -29,22 +31,26 @@ struct TestClass { void test1() { TestClass c; c.MemberFunc(); - // CHECK-1: %[[Capture:struct\.anon[\.0-9]*]] = type { %struct.Foo*, %struct.TestClass* } + // CHECK-1: %[[Capture:struct\.anon[\.0-9]*]] = type { %struct.TestClass*, %struct.Foo* } + // CHECK-1: [[INNER:@.+]] = {{.+}} global double // CHECK-1: define {{.*}} void @_ZN9TestClass10MemberFuncEv // CHECK-1: alloca %struct.anon - // CHECK-1: getelementptr inbounds %[[Capture]]* %{{[^,]*}}, i32 0, i32 0 + // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 0 + // CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* %{{[^,]*}}, i32 0, i32 1 // CHECK-1: store %struct.Foo* %f, %struct.Foo** - // CHECK-1: getelementptr inbounds %[[Capture]]* %{{[^,]*}}, i32 0, i32 1 - // CHECK-1: call void @[[HelperName:[A-Za-z0-9_]+]](%[[Capture]]* + // CHECK-1: call void @[[HelperName:[\.A-Za-z0-9_]+]](%[[Capture]]* // CHECK-1: call {{.*}}FooD1Ev // CHECK-1: ret } // CHECK-1: define internal void @[[HelperName]] -// CHECK-1: getelementptr inbounds %[[Capture]]* {{[^,]*}}, i32 0, i32 1 -// CHECK-1: getelementptr inbounds %struct.TestClass* {{[^,]*}}, i32 0, i32 0 -// CHECK-1: getelementptr inbounds %[[Capture]]* {{[^,]*}}, i32 0, i32 0 +// CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 0 +// CHECK-1: call i32 @__cxa_guard_acquire( +// CHECK-1: store double %{{.+}}, double* [[INNER]], +// CHECK-1: call void @__cxa_guard_release( +// CHECK-1: getelementptr inbounds %struct.TestClass, %struct.TestClass* {{[^,]*}}, i32 0, i32 0 +// CHECK-1: getelementptr inbounds %[[Capture]], %[[Capture]]* {{[^,]*}}, i32 0, i32 1 void test2(int x) { int y = [&]() { @@ -62,9 +68,9 @@ void test2(int x) { // CHECK-2: call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]* // // CHECK-2: define internal void @[[HelperName]] - // CHECK-2: getelementptr inbounds %[[Capture]]* - // CHECK-2: load i32** - // CHECK-2: load i32* + // CHECK-2: getelementptr inbounds %[[Capture]], %[[Capture]]* + // CHECK-2: load i32*, i32** + // CHECK-2: load i32, i32* } void test3(int x) { @@ -88,7 +94,7 @@ void test4() { f.x = 5; } // CHECK-4-LABEL: define void @_Z5test4v - // CHECK-4: call void @[[HelperName:["$_A-Za-z0-9]+]](%[[Capture:.*]]* + // CHECK-4: call void @[[HelperName:[\."$_A-Za-z0-9]+]](%[[Capture:.*]]* // CHECK-4: ret void // // CHECK-4: define internal void @[[HelperName]] diff --git a/test/CodeGenCXX/catch-undef-behavior.cpp b/test/CodeGenCXX/catch-undef-behavior.cpp index 4120d0f..d08fe76 100644 --- a/test/CodeGenCXX/catch-undef-behavior.cpp +++ b/test/CodeGenCXX/catch-undef-behavior.cpp @@ -1,6 +1,9 @@ -// RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -fsanitize-recover=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s // RUN: %clang_cc1 -std=c++11 -fsanitize=vptr,address -fsanitize-recover=vptr,address -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=CHECK-ASAN // RUN: %clang_cc1 -std=c++11 -fsanitize=vptr -fsanitize-recover=vptr -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s --check-prefix=DOWNCAST-NULL +// RUN: %clang_cc1 -std=c++11 -fsanitize=function -emit-llvm %s -o - -triple x86_64-linux-gnux32 | FileCheck %s --check-prefix=CHECK-X32 +// RUN: %clang_cc1 -std=c++11 -fsanitize=function -emit-llvm %s -o - -triple i386-linux-gnu | FileCheck %s --check-prefix=CHECK-X86 +// REQUIRES: asserts struct S { double d; @@ -55,7 +58,7 @@ void member_access(S *p) { // (1b) Check that 'p' actually points to an 'S'. // CHECK: %[[VPTRADDR:.*]] = bitcast {{.*}} to i64* - // CHECK-NEXT: %[[VPTR:.*]] = load i64* %[[VPTRADDR]] + // CHECK-NEXT: %[[VPTR:.*]] = load i64, i64* %[[VPTRADDR]] // // hash_16_bytes: // @@ -79,8 +82,8 @@ void member_access(S *p) { // Check the hash against the table: // // CHECK-NEXT: %[[IDX:.*]] = and i64 %{{.*}}, 127 - // CHECK-NEXT: getelementptr inbounds [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 %[[IDX]] - // CHECK-NEXT: %[[CACHEVAL:.*]] = load i64* + // CHECK-NEXT: getelementptr inbounds [128 x i64], [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 %[[IDX]] + // CHECK-NEXT: %[[CACHEVAL:.*]] = load i64, i64* // CHECK-NEXT: icmp eq i64 %[[CACHEVAL]], %[[HASH]] // CHECK-NEXT: br i1 @@ -114,10 +117,10 @@ void member_access(S *p) { // (3b) Check that 'p' actually points to an 'S' - // CHECK: load i64* + // CHECK: load i64, i64* // CHECK-NEXT: xor i64 {{-4030275160588942838|2562089159}}, // [...] - // CHECK: getelementptr inbounds [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 % + // CHECK: getelementptr inbounds [128 x i64], [128 x i64]* @__ubsan_vptr_type_cache, i32 0, i64 % // CHECK: br i1 // CHECK: call void @__ubsan_handle_dynamic_type_cache_miss({{.*}}, i64 %{{.*}}, i64 %{{.*}}) // CHECK-NOT: unreachable @@ -128,10 +131,11 @@ void member_access(S *p) { // CHECK-LABEL: @_Z12lsh_overflow int lsh_overflow(int a, int b) { - // CHECK: %[[INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31 - // CHECK-NEXT: br i1 %[[INBOUNDS]] + // CHECK: %[[RHS_INBOUNDS:.*]] = icmp ule i32 %[[RHS:.*]], 31 + // CHECK-NEXT: br i1 %[[RHS_INBOUNDS]], label %[[CHECK_BB:.*]], label %[[CONT_BB:.*]], - // CHECK: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]] + // CHECK: [[CHECK_BB]]: + // CHECK-NEXT: %[[SHIFTED_OUT_WIDTH:.*]] = sub nuw nsw i32 31, %[[RHS]] // CHECK-NEXT: %[[SHIFTED_OUT:.*]] = lshr i32 %[[LHS:.*]], %[[SHIFTED_OUT_WIDTH]] // This is present for C++11 but not for C: C++ core issue 1457 allows a '1' @@ -139,8 +143,11 @@ int lsh_overflow(int a, int b) { // CHECK-NEXT: %[[SHIFTED_OUT_NOT_SIGN:.*]] = lshr i32 %[[SHIFTED_OUT]], 1 // CHECK-NEXT: %[[NO_OVERFLOW:.*]] = icmp eq i32 %[[SHIFTED_OUT_NOT_SIGN]], 0 + // CHECK-NEXT: br label %[[CONT_BB]] - // CHECK: %[[VALID:.*]] = phi i1 [ %[[INBOUNDS]], {{.*}} ], [ %[[NO_OVERFLOW]], {{.*}} ] + // CHECK: [[CONT_BB]]: + // CHECK-NEXT: %[[VALID_BASE:.*]] = phi i1 [ true, {{.*}} ], [ %[[NO_OVERFLOW]], %[[CHECK_BB]] ] + // CHECK-NEXT: %[[VALID:.*]] = and i1 %[[RHS_INBOUNDS]], %[[VALID_BASE]] // CHECK-NEXT: br i1 %[[VALID]] // CHECK: call void @__ubsan_handle_shift_out_of_bounds @@ -361,7 +368,7 @@ class C : public A, public B // align=16 void downcast_pointer(B *b) { (void) static_cast<C*>(b); // Alignment check from EmitTypeCheck(TCK_DowncastPointer, ...) - // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr i8* {{.*}}, i64 -16 + // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr i8, i8* {{.*}}, i64 -16 // CHECK-NEXT: [[C:%[0-9]*]] = bitcast i8* [[SUB]] to %class.C* // null check goes here // CHECK: [[FROM_PHI:%[0-9]*]] = phi %class.C* [ [[C]], {{.*}} ], {{.*}} @@ -378,7 +385,7 @@ void downcast_pointer(B *b) { void downcast_reference(B &b) { (void) static_cast<C&>(b); // Alignment check from EmitTypeCheck(TCK_DowncastReference, ...) - // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr i8* {{.*}}, i64 -16 + // CHECK: [[SUB:%[.a-z0-9]*]] = getelementptr i8, i8* {{.*}}, i64 -16 // CHECK-NEXT: [[C:%[0-9]*]] = bitcast i8* [[SUB]] to %class.C* // Objectsize check goes here // CHECK: [[C_INT:%[0-9]*]] = ptrtoint %class.C* [[C]] to i64 @@ -390,18 +397,20 @@ void downcast_reference(B &b) { } // CHECK-LABEL: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413876459, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }> +// CHECK-X32: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }> +// CHECK-X86: @_Z22indirect_function_callPFviE({{.*}} prologue <{ i32, i8* }> <{ i32 1413875435, i8* bitcast ({ i8*, i8* }* @_ZTIFvPFviEE to i8*) }> void indirect_function_call(void (*p)(int)) { // CHECK: [[PTR:%[0-9]*]] = bitcast void (i32)* {{.*}} to <{ i32, i8* }>* // Signature check - // CHECK-NEXT: [[SIGPTR:%[0-9]*]] = getelementptr <{ i32, i8* }>* [[PTR]], i32 0, i32 0 - // CHECK-NEXT: [[SIG:%[0-9]*]] = load i32* [[SIGPTR]] + // CHECK-NEXT: [[SIGPTR:%[0-9]*]] = getelementptr <{ i32, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 0 + // CHECK-NEXT: [[SIG:%[0-9]*]] = load i32, i32* [[SIGPTR]] // CHECK-NEXT: [[SIGCMP:%[0-9]*]] = icmp eq i32 [[SIG]], 1413876459 // CHECK-NEXT: br i1 [[SIGCMP]] // RTTI pointer check - // CHECK: [[RTTIPTR:%[0-9]*]] = getelementptr <{ i32, i8* }>* [[PTR]], i32 0, i32 1 - // CHECK-NEXT: [[RTTI:%[0-9]*]] = load i8** [[RTTIPTR]] + // CHECK: [[RTTIPTR:%[0-9]*]] = getelementptr <{ i32, i8* }>, <{ i32, i8* }>* [[PTR]], i32 0, i32 1 + // CHECK-NEXT: [[RTTI:%[0-9]*]] = load i8*, i8** [[RTTIPTR]] // CHECK-NEXT: [[RTTICMP:%[0-9]*]] = icmp eq i8* [[RTTI]], bitcast ({ i8*, i8* }* @_ZTIFviE to i8*) // CHECK-NEXT: br i1 [[RTTICMP]] p(42); @@ -446,11 +455,11 @@ namespace CopyValueRepresentation { // CHECK-NOT: call {{.*}} @__ubsan_handle_load_invalid_value // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S4aSEOS0_ // CHECK-NOT: call {{.*}} @__ubsan_handle_load_invalid_value - // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S5C2ERKS0_ + // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S1C2ERKS0_ // CHECK-NOT: call {{.*}} __ubsan_handle_load_invalid_value // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S2C2ERKS0_ // CHECK: __ubsan_handle_load_invalid_value - // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S1C2ERKS0_ + // CHECK-LABEL: define {{.*}} @_ZN23CopyValueRepresentation2S5C2ERKS0_ // CHECK-NOT: call {{.*}} __ubsan_handle_load_invalid_value struct CustomCopy { CustomCopy(); CustomCopy(const CustomCopy&); }; diff --git a/test/CodeGenCXX/catch-undef-behavior2.cpp b/test/CodeGenCXX/catch-undef-behavior2.cpp index b8b31ca..6e9ca0c 100644 --- a/test/CodeGenCXX/catch-undef-behavior2.cpp +++ b/test/CodeGenCXX/catch-undef-behavior2.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -fsanitize=signed-integer-overflow,integer-divide-by-zero,float-divide-by-zero,shift-base,shift-exponent,unreachable,return,vla-bound,alignment,null,vptr,object-size,float-cast-overflow,bool,enum,array-bounds,function -emit-llvm %s -o - -triple x86_64-linux-gnu | FileCheck %s bool GetOptionalBool(bool *value); bool GetBool(bool default_value) { diff --git a/test/CodeGenCXX/cfi-cast.cpp b/test/CodeGenCXX/cfi-cast.cpp new file mode 100644 index 0000000..c671bad --- /dev/null +++ b/test/CodeGenCXX/cfi-cast.cpp @@ -0,0 +1,109 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-derived-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-DCAST %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-unrelated-cast,cfi-cast-strict -emit-llvm -o - %s | FileCheck -check-prefix=CHECK-UCAST-STRICT %s + +// In this test the main thing we are searching for is something like +// 'metadata !"1B"' where "1B" is the mangled name of the class we are +// casting to (or maybe its base class in non-strict mode). + +struct A { + virtual void f(); +}; + +struct B : A { + virtual void f(); +}; + +struct C : A {}; + +// CHECK-DCAST-LABEL: define void @_Z3abpP1A +void abp(A *a) { + // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") + // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + + // CHECK-DCAST: [[TRAPBB]] + // CHECK-DCAST-NEXT: call void @llvm.trap() + // CHECK-DCAST-NEXT: unreachable + + // CHECK-DCAST: [[CONTBB]] + // CHECK-DCAST: ret + static_cast<B*>(a); +} + +// CHECK-DCAST-LABEL: define void @_Z3abrR1A +void abr(A &a) { + // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") + // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + + // CHECK-DCAST: [[TRAPBB]] + // CHECK-DCAST-NEXT: call void @llvm.trap() + // CHECK-DCAST-NEXT: unreachable + + // CHECK-DCAST: [[CONTBB]] + // CHECK-DCAST: ret + static_cast<B&>(a); +} + +// CHECK-DCAST-LABEL: define void @_Z4abrrO1A +void abrr(A &&a) { + // CHECK-DCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") + // CHECK-DCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + + // CHECK-DCAST: [[TRAPBB]] + // CHECK-DCAST-NEXT: call void @llvm.trap() + // CHECK-DCAST-NEXT: unreachable + + // CHECK-DCAST: [[CONTBB]] + // CHECK-DCAST: ret + static_cast<B&&>(a); +} + +// CHECK-UCAST-LABEL: define void @_Z3vbpPv +void vbp(void *p) { + // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") + // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + + // CHECK-UCAST: [[TRAPBB]] + // CHECK-UCAST-NEXT: call void @llvm.trap() + // CHECK-UCAST-NEXT: unreachable + + // CHECK-UCAST: [[CONTBB]] + // CHECK-UCAST: ret + static_cast<B*>(p); +} + +// CHECK-UCAST-LABEL: define void @_Z3vbrRc +void vbr(char &r) { + // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") + // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + + // CHECK-UCAST: [[TRAPBB]] + // CHECK-UCAST-NEXT: call void @llvm.trap() + // CHECK-UCAST-NEXT: unreachable + + // CHECK-UCAST: [[CONTBB]] + // CHECK-UCAST: ret + reinterpret_cast<B&>(r); +} + +// CHECK-UCAST-LABEL: define void @_Z4vbrrOc +void vbrr(char &&r) { + // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") + // CHECK-UCAST-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + + // CHECK-UCAST: [[TRAPBB]] + // CHECK-UCAST-NEXT: call void @llvm.trap() + // CHECK-UCAST-NEXT: unreachable + + // CHECK-UCAST: [[CONTBB]] + // CHECK-UCAST: ret + reinterpret_cast<B&&>(r); +} + +// CHECK-UCAST-LABEL: define void @_Z3vcpPv +// CHECK-UCAST-STRICT-LABEL: define void @_Z3vcpPv +void vcp(void *p) { + // CHECK-UCAST: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1A") + // CHECK-UCAST-STRICT: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1C") + static_cast<C*>(p); +} diff --git a/test/CodeGenCXX/cfi-nvcall.cpp b/test/CodeGenCXX/cfi-nvcall.cpp new file mode 100644 index 0000000..b0db478 --- /dev/null +++ b/test/CodeGenCXX/cfi-nvcall.cpp @@ -0,0 +1,35 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-nvcall -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-nvcall,cfi-cast-strict -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-STRICT %s + +struct A { + virtual void f(); +}; + +struct B : A { + int i; + void g(); +}; + +struct C : A { + void g(); +}; + +// CHECK-LABEL: @bg +// CHECK-STRICT-LABEL: @bg +extern "C" void bg(B *b) { + // CHECK: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") + // CHECK-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1B") + b->g(); +} + +// CHECK-LABEL: @cg +// CHECK-STRICT-LABEL: @cg +extern "C" void cg(C *c) { + // http://clang.llvm.org/docs/ControlFlowIntegrity.html#strictness + // In this case C's layout is the same as its base class, so we allow + // c to be of type A in non-strict mode. + + // CHECK: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1A") + // CHECK-STRICT: call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1C") + c->g(); +} diff --git a/test/CodeGenCXX/cfi-vcall.cpp b/test/CodeGenCXX/cfi-vcall.cpp new file mode 100644 index 0000000..b0f79d9 --- /dev/null +++ b/test/CodeGenCXX/cfi-vcall.cpp @@ -0,0 +1,90 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-linux -fsanitize=cfi-vcall -emit-llvm -o - %s | FileCheck %s + +struct A { + A(); + virtual void f(); +}; + +struct B : virtual A { + B(); +}; + +struct C : virtual A { + C(); +}; + +namespace { + +struct D : B, C { + D(); + virtual void f(); +}; + +} + +A::A() {} +B::B() {} +C::C() {} +D::D() {} + +void A::f() { +} + +void D::f() { +} + +// CHECK: define void @_Z2afP1A +void af(A *a) { + // CHECK: [[P:%[^ ]*]] = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"1A") + // CHECK-NEXT: br i1 [[P]], label %[[CONTBB:[^ ]*]], label %[[TRAPBB:[^ ]*]] + + // CHECK: [[TRAPBB]] + // CHECK-NEXT: call void @llvm.trap() + // CHECK-NEXT: unreachable + + // CHECK: [[CONTBB]] + // CHECK: call void % + a->f(); +} + +// CHECK: define internal void @_Z3df1PN12_GLOBAL__N_11DE +void df1(D *d) { + // CHECK: {{%[^ ]*}} = call i1 @llvm.bitset.test(i8* {{%[^ ]*}}, metadata !"[{{.*}}cfi-vcall.cpp]N12_GLOBAL__N_11DE") + d->f(); +} + +// CHECK: define internal void @_Z3df2PN12_GLOBAL__N_11DE +__attribute__((no_sanitize("cfi"))) +void df2(D *d) { + // CHECK-NOT: call i1 @llvm.bitset.test + d->f(); +} + +// CHECK: define internal void @_Z3df3PN12_GLOBAL__N_11DE +__attribute__((no_sanitize("address"))) __attribute__((no_sanitize("cfi-vcall"))) +void df3(D *d) { + // CHECK-NOT: call i1 @llvm.bitset.test + d->f(); +} + +D d; + +void foo() { + df1(&d); + df2(&d); + df3(&d); +} + +// CHECK-DAG: !{!"1A", [3 x i8*]* @_ZTV1A, i64 16} +// CHECK-DAG: !{!"1A", [5 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32} +// CHECK-DAG: !{!"1B", [5 x i8*]* @_ZTCN12_GLOBAL__N_11DE0_1B, i64 32} +// CHECK-DAG: !{!"1A", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 64} +// CHECK-DAG: !{!"1C", [9 x i8*]* @_ZTCN12_GLOBAL__N_11DE8_1C, i64 32} +// CHECK-DAG: !{!"1A", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} +// CHECK-DAG: !{!"1B", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} +// CHECK-DAG: !{!"1C", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 72} +// CHECK-DAG: !{!"[{{.*}}cfi-vcall.cpp]N12_GLOBAL__N_11DE", [10 x i8*]* @_ZTVN12_GLOBAL__N_11DE, i64 32} +// CHECK-DAG: !{!"1A", [5 x i8*]* @_ZTV1B, i64 32} +// CHECK-DAG: !{!"1B", [5 x i8*]* @_ZTV1B, i64 32} +// CHECK-DAG: !{!"1A", [5 x i8*]* @_ZTV1C, i64 32} +// CHECK-DAG: !{!"1C", [5 x i8*]* @_ZTV1C, i64 32} diff --git a/test/CodeGenCXX/compound-literals.cpp b/test/CodeGenCXX/compound-literals.cpp index e771093..69632a7 100644 --- a/test/CodeGenCXX/compound-literals.cpp +++ b/test/CodeGenCXX/compound-literals.cpp @@ -15,12 +15,12 @@ struct Y { // CHECK-LABEL: define i32 @_Z1fv() int f() { // CHECK: [[LVALUE:%[a-z0-9.]+]] = alloca - // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}}* [[LVALUE]], i32 0, i32 0 + // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}}, {{.*}}* [[LVALUE]], i32 0, i32 0 // CHECK-NEXT: store i32 17, i32* [[I]] // CHECK-NEXT: [[X:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 1 // CHECK-NEXT: call %struct.X* @_ZN1XC1EPKc({{.*}}[[X]] // CHECK-NEXT: [[I:%[a-z0-9]+]] = getelementptr inbounds {{.*}} [[LVALUE]], i32 0, i32 0 - // CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = load i32* + // CHECK-NEXT: [[RESULT:%[a-z0-9]+]] = load i32, i32* // CHECK-NEXT: call %struct.Y* @_ZN1YD1Ev // CHECK-NEXT: ret i32 [[RESULT]] return ((Y){17, "seventeen"}).i; @@ -31,9 +31,9 @@ int g() { // CHECK: store [2 x i32]* %{{[a-z0-9.]+}}, [2 x i32]** [[V:%[a-z0-9.]+]] const int (&v)[2] = (int [2]) {1,2}; - // CHECK: [[A:%[a-z0-9.]+]] = load [2 x i32]** [[V]] - // CHECK-NEXT: [[A0ADDR:%[a-z0-9.]+]] = getelementptr inbounds [2 x i32]* [[A]], i32 0, {{.*}} 0 - // CHECK-NEXT: [[A0:%[a-z0-9.]+]] = load i32* [[A0ADDR]] + // CHECK: [[A:%[a-z0-9.]+]] = load [2 x i32]*, [2 x i32]** [[V]] + // CHECK-NEXT: [[A0ADDR:%[a-z0-9.]+]] = getelementptr inbounds [2 x i32], [2 x i32]* [[A]], i32 0, {{.*}} 0 + // CHECK-NEXT: [[A0:%[a-z0-9.]+]] = load i32, i32* [[A0ADDR]] // CHECK-NEXT: ret i32 [[A0]] return v[0]; } @@ -41,17 +41,17 @@ int g() { struct Z { int i[3]; }; int *p = (Z){ {1, 2, 3} }.i; // CHECK: define {{.*}}__cxx_global_var_init() -// CHECK: store i32* getelementptr inbounds (%struct.Z* @.compoundliteral, i32 0, i32 0, i32 0), i32** @p +// CHECK: store i32* getelementptr inbounds (%struct.Z, %struct.Z* @.compoundliteral, i32 0, i32 0, i32 0), i32** @p int *PR21912_1 = (int []){}; -// CHECK-LABEL: define {{.*}}__cxx_global_var_init1() -// CHECK: store i32* getelementptr inbounds ([0 x i32]* @.compoundliteral2, i32 0, i32 0), i32** @PR21912_1 +// CHECK-LABEL: define {{.*}}__cxx_global_var_init.1() +// CHECK: store i32* getelementptr inbounds ([0 x i32], [0 x i32]* @.compoundliteral.2, i32 0, i32 0), i32** @PR21912_1 union PR21912Ty { long long l; double d; }; union PR21912Ty *PR21912_2 = (union PR21912Ty[]){{.d = 2.0}, {.l = 3}}; -// CHECK-LABEL: define {{.*}}__cxx_global_var_init3() -// CHECK: store %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral4 to [2 x %union.PR21912Ty]*), i32 0, i32 0), %union.PR21912Ty** @PR21912_2 +// CHECK-LABEL: define {{.*}}__cxx_global_var_init.3() +// CHECK: store %union.PR21912Ty* getelementptr inbounds ([2 x %union.PR21912Ty], [2 x %union.PR21912Ty]* bitcast (<{ { double }, %union.PR21912Ty }>* @.compoundliteral.4 to [2 x %union.PR21912Ty]*), i32 0, i32 0), %union.PR21912Ty** @PR21912_2 diff --git a/test/CodeGenCXX/condition.cpp b/test/CodeGenCXX/condition.cpp index 452f1c3..fbba077 100644 --- a/test/CodeGenCXX/condition.cpp +++ b/test/CodeGenCXX/condition.cpp @@ -116,7 +116,7 @@ void while_destruct(int z) { // Cleanup. // CHECK: call void @_ZN1XD1Ev - // CHECK-NEXT: [[DEST:%.*]] = load i32* [[CLEANUPDEST]] + // CHECK-NEXT: [[DEST:%.*]] = load i32, i32* [[CLEANUPDEST]] // CHECK-NEXT: switch i32 [[DEST]] } @@ -163,7 +163,7 @@ void for_destruct(int z) { z = 23; // %for.inc: - // CHECK: [[TMP:%.*]] = load i32* [[Z]] + // CHECK: [[TMP:%.*]] = load i32, i32* [[Z]] // CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP]], 1 // CHECK-NEXT: store i32 [[INC]], i32* [[Z]] // CHECK-NEXT: store i32 0, i32* [[CLEANUPDEST]] @@ -172,7 +172,7 @@ void for_destruct(int z) { // %cleanup: Destroys X. // CHECK: call void @_ZN1XD1Ev - // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32* [[CLEANUPDEST]] + // CHECK-NEXT: [[YDESTTMP:%.*]] = load i32, i32* [[CLEANUPDEST]] // CHECK-NEXT: switch i32 [[YDESTTMP]] // 0 -> %cleanup.cont, default -> %cleanup1 @@ -207,7 +207,7 @@ void for_destruct(int z) { // %for.inc11: // CHECK: call void @_Z4getXv - // CHECK-NEXT: load i32* [[I]] + // CHECK-NEXT: load i32, i32* [[I]] // CHECK-NEXT: add // CHECK-NEXT: store // CHECK-NEXT: call void @_ZN1XD1Ev diff --git a/test/CodeGenCXX/conditional-gnu-ext.cpp b/test/CodeGenCXX/conditional-gnu-ext.cpp index 3a61a63..b073e0c 100644 --- a/test/CodeGenCXX/conditional-gnu-ext.cpp +++ b/test/CodeGenCXX/conditional-gnu-ext.cpp @@ -5,7 +5,7 @@ extern "C" int printf(...); void test0() { -// CHECK: call i32 (...)* @printf({{.*}}, i8* inttoptr (i64 3735928559 to i8*)) +// CHECK: call i32 (...) @printf({{.*}}, i8* inttoptr (i64 3735928559 to i8*)) printf("%p\n", (void *)0xdeadbeef ? : (void *)0xaaaaaa); } @@ -80,7 +80,7 @@ namespace test3 { // CHECK-LABEL: define void @_ZN5test35test0ERNS_1BE( // CHECK: [[X:%.*]] = alloca [[B:%.*]]*, // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]] - // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]] + // CHECK-NEXT: [[T0:%.*]] = load [[B]]*, [[B]]** [[X]] // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]]) // CHECK-NEXT: br i1 [[BOOL]] // CHECK: call void @_ZN5test31BC1ERKS0_([[B]]* [[RESULT:%.*]], [[B]]* dereferenceable({{[0-9]+}}) [[T0]]) @@ -112,7 +112,7 @@ namespace test3 { // CHECK-LABEL: define void @_ZN5test35test2ERNS_1BE( // CHECK: [[X:%.*]] = alloca [[B]]*, // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]] - // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]] + // CHECK-NEXT: [[T0:%.*]] = load [[B]]*, [[B]]** [[X]] // CHECK-NEXT: [[BOOL:%.*]] = call zeroext i1 @_ZN5test31BcvbEv([[B]]* [[T0]]) // CHECK-NEXT: br i1 [[BOOL]] // CHECK: call void @_ZN5test31BcvNS_1AEEv([[A:%.*]]* sret [[RESULT:%.*]], [[B]]* [[T0]]) diff --git a/test/CodeGenCXX/const-init-cxx11.cpp b/test/CodeGenCXX/const-init-cxx11.cpp index f671e0a..5127c30 100644 --- a/test/CodeGenCXX/const-init-cxx11.cpp +++ b/test/CodeGenCXX/const-init-cxx11.cpp @@ -1,4 +1,4 @@ -// RUN: not %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s -std=c++11 | FileCheck %s +// RUN: %clang_cc1 -w -triple x86_64-elf-gnu -emit-llvm -o - %s -std=c++11 | FileCheck %s // FIXME: The padding in all these objects should be zero-initialized. namespace StructUnion { @@ -19,7 +19,7 @@ namespace StructUnion { // CHECK: @_ZN11StructUnion1aE = constant {{.*}} { i32 1, double 2.000000e+00, {{.*}} { i32 3, [4 x i8] undef } } extern constexpr A a(1, 2.0, 3); - // CHECK: @_ZN11StructUnion1bE = constant {{.*}} { i32 4, double 5.000000e+00, {{.*}} { i8* getelementptr inbounds ([6 x i8]* @{{.*}}, i32 0, i32 0) } } + // CHECK: @_ZN11StructUnion1bE = constant {{.*}} { i32 4, double 5.000000e+00, {{.*}} { i8* getelementptr inbounds ([6 x i8], [6 x i8]* @{{.*}}, i32 0, i32 0) } } extern constexpr A b(4, 5, "hello"); struct B { @@ -226,30 +226,30 @@ namespace LiteralReference { }; // This creates a non-const temporary and binds a reference to it. - // CHECK: @[[TEMP:.*]] = private global {{.*}} { i32 5 }, align 4 + // CHECK: @[[TEMP:.*]] = internal global {{.*}} { i32 5 }, align 4 // CHECK: @_ZN16LiteralReference3litE = constant {{.*}} @[[TEMP]], align 8 const Lit &lit = Lit(); // This creates a const temporary as part of the reference initialization. - // CHECK: @[[TEMP:.*]] = private constant {{.*}} { i32 5 }, align 4 + // CHECK: @[[TEMP:.*]] = internal constant {{.*}} { i32 5 }, align 4 // CHECK: @_ZN16LiteralReference4lit2E = constant {{.*}} @[[TEMP]], align 8 const Lit &lit2 = {}; struct A { int &&r1; const int &&r2; }; struct B { A &&a1; const A &&a2; }; B b = { { 0, 1 }, { 2, 3 } }; - // CHECK: @[[TEMP0:.*]] = private global i32 0, align 4 - // CHECK: @[[TEMP1:.*]] = private constant i32 1, align 4 - // CHECK: @[[TEMPA1:.*]] = private global {{.*}} { i32* @[[TEMP0]], i32* @[[TEMP1]] }, align 8 - // CHECK: @[[TEMP2:.*]] = private global i32 2, align 4 - // CHECK: @[[TEMP3:.*]] = private constant i32 3, align 4 - // CHECK: @[[TEMPA2:.*]] = private constant {{.*}} { i32* @[[TEMP2]], i32* @[[TEMP3]] }, align 8 + // CHECK: @[[TEMP0:.*]] = internal global i32 0, align 4 + // CHECK: @[[TEMP1:.*]] = internal constant i32 1, align 4 + // CHECK: @[[TEMPA1:.*]] = internal global {{.*}} { i32* @[[TEMP0]], i32* @[[TEMP1]] }, align 8 + // CHECK: @[[TEMP2:.*]] = internal global i32 2, align 4 + // CHECK: @[[TEMP3:.*]] = internal constant i32 3, align 4 + // CHECK: @[[TEMPA2:.*]] = internal constant {{.*}} { i32* @[[TEMP2]], i32* @[[TEMP3]] }, align 8 // CHECK: @_ZN16LiteralReference1bE = global {{.*}} { {{.*}}* @[[TEMPA1]], {{.*}}* @[[TEMPA2]] }, align 8 struct Subobj { int a, b, c; }; - // CHECK: @[[TEMP:.*]] = private global {{.*}} { i32 1, i32 2, i32 3 }, align 4 + // CHECK: @[[TEMP:.*]] = internal global {{.*}} { i32 1, i32 2, i32 3 }, align 4 // CHECK: @_ZN16LiteralReference2soE = constant {{.*}} (i8* getelementptr {{.*}} @[[TEMP]]{{.*}}, i64 4) constexpr int &&so = Subobj{ 1, 2, 3 }.b; @@ -258,11 +258,11 @@ namespace LiteralReference { constexpr Derived() : Dummy{200}, Subobj{4, 5, 6} {} }; using ConstDerived = const Derived; - // CHECK: @[[TEMPCOMMA:.*]] = private constant {{.*}} { i32 200, i32 4, i32 5, i32 6 } + // CHECK: @[[TEMPCOMMA:.*]] = internal constant {{.*}} { i32 200, i32 4, i32 5, i32 6 } // CHECK: @_ZN16LiteralReference5commaE = constant {{.*}} getelementptr {{.*}} @[[TEMPCOMMA]]{{.*}}, i64 8) constexpr const int &comma = (1, (2, ConstDerived{}).b); - // CHECK: @[[TEMPDERIVED:.*]] = private global {{.*}} { i32 200, i32 4, i32 5, i32 6 } + // CHECK: @[[TEMPDERIVED:.*]] = internal global {{.*}} { i32 200, i32 4, i32 5, i32 6 } // CHECK: @_ZN16LiteralReference4baseE = constant {{.*}} getelementptr {{.*}} @[[TEMPDERIVED]]{{.*}}, i64 4) constexpr Subobj &&base = Derived{}; @@ -343,15 +343,24 @@ namespace VirtualMembers { constexpr E() : B(3), c{'b','y','e'} {} char c[3]; }; - - // CHECK: @_ZN14VirtualMembers1eE = global { i8**, double, i32, i8**, double, [5 x i8], i16, i8**, double, [5 x i8], [3 x i8] } { i8** getelementptr inbounds ([11 x i8*]* @_ZTVN14VirtualMembers1EE, i64 0, i64 2), double 1.000000e+00, i32 64, i8** getelementptr inbounds ([11 x i8*]* @_ZTVN14VirtualMembers1EE, i64 0, i64 5), double 2.000000e+00, [5 x i8] c"hello", i16 5, i8** getelementptr inbounds ([11 x i8*]* @_ZTVN14VirtualMembers1EE, i64 0, i64 9), double 3.000000e+00, [5 x i8] c"world", [3 x i8] c"bye" } + // CHECK: @_ZN14VirtualMembers1eE = global { i8**, double, i32, i8**, double, [5 x i8], i16, i8**, double, [5 x i8], [3 x i8] } { i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTVN14VirtualMembers1EE, i64 0, i64 2), double 1.000000e+00, i32 64, i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTVN14VirtualMembers1EE, i64 0, i64 5), double 2.000000e+00, [5 x i8] c"hello", i16 5, i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTVN14VirtualMembers1EE, i64 0, i64 9), double 3.000000e+00, [5 x i8] c"world", [3 x i8] c"bye" } E e; struct nsMemoryImpl { virtual void f(); }; - // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ([3 x i8*]* @_ZTVN14VirtualMembers12nsMemoryImplE, i64 0, i64 2) } + // CHECK: @_ZN14VirtualMembersL13sGlobalMemoryE = internal global { i8** } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN14VirtualMembers12nsMemoryImplE, i64 0, i64 2) } static nsMemoryImpl sGlobalMemory; + + template<class T> + struct TemplateClass { + constexpr TemplateClass() : t{42} {} + virtual void templateMethod() {} + + T t; + }; + // CHECK: @_ZN14VirtualMembers1tE = global { i8**, i32 } { i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN14VirtualMembers13TemplateClassIiEE, i64 0, i64 2), i32 42 } + TemplateClass<int> t; } namespace PR13273 { @@ -371,10 +380,10 @@ namespace PR13273 { namespace ArrayTemporary { struct A { const int (&x)[3]; }; struct B { const A (&x)[2]; }; - // CHECK: @[[A1:_ZGRN14ArrayTemporary1bE.*]] = private constant [3 x i32] [i32 1, i32 2, i32 3] - // CHECK: @[[A2:_ZGRN14ArrayTemporary1bE.*]] = private constant [3 x i32] [i32 4, i32 5, i32 6] - // CHECK: @[[ARR:_ZGRN14ArrayTemporary1bE.*]] = private constant [2 x {{.*}}] [{{.*}} { [3 x i32]* @[[A1]] }, {{.*}} { [3 x i32]* @[[A2]] }] - // CHECK: @[[B:_ZGRN14ArrayTemporary1bE.*]] = private global {{.*}} { [2 x {{.*}}]* @[[ARR]] } + // CHECK: @[[A1:_ZGRN14ArrayTemporary1bE.*]] = internal constant [3 x i32] [i32 1, i32 2, i32 3] + // CHECK: @[[A2:_ZGRN14ArrayTemporary1bE.*]] = internal constant [3 x i32] [i32 4, i32 5, i32 6] + // CHECK: @[[ARR:_ZGRN14ArrayTemporary1bE.*]] = internal constant [2 x {{.*}}] [{{.*}} { [3 x i32]* @[[A1]] }, {{.*}} { [3 x i32]* @[[A2]] }] + // CHECK: @[[B:_ZGRN14ArrayTemporary1bE.*]] = internal global {{.*}} { [2 x {{.*}}]* @[[ARR]] } // CHECK: @_ZN14ArrayTemporary1bE = constant {{.*}}* @[[B]] B &&b = { { { { 1, 2, 3 } }, { { 4, 5, 6 } } } }; } @@ -382,7 +391,7 @@ namespace ArrayTemporary { namespace UnemittedTemporaryDecl { constexpr int &&ref = 0; extern constexpr int &ref2 = ref; - // CHECK: @_ZGRN22UnemittedTemporaryDecl3refE_ = private global i32 0 + // CHECK: @_ZGRN22UnemittedTemporaryDecl3refE_ = internal global i32 0 // FIXME: This declaration should not be emitted -- it isn't odr-used. // CHECK: @_ZN22UnemittedTemporaryDecl3refE @@ -393,11 +402,11 @@ namespace UnemittedTemporaryDecl { // CHECK: @_ZZN12LocalVarInit3aggEvE1a = internal constant {{.*}} i32 101 // CHECK: @_ZZN12LocalVarInit4ctorEvE1a = internal constant {{.*}} i32 102 // CHECK: @_ZZN12LocalVarInit8mutable_EvE1a = private unnamed_addr constant {{.*}} i32 103 -// CHECK: @_ZGRN33ClassTemplateWithStaticDataMember1SIvE1aE_ = linkonce_odr constant i32 5 +// CHECK: @_ZGRN33ClassTemplateWithStaticDataMember1SIvE1aE_ = linkonce_odr constant i32 5, comdat // CHECK: @_ZN33ClassTemplateWithStaticDataMember3useE = constant i32* @_ZGRN33ClassTemplateWithStaticDataMember1SIvE1aE_ -// CHECK: @_ZGRN39ClassTemplateWithHiddenStaticDataMember1SIvE1aE_ = linkonce_odr hidden constant i32 5 +// CHECK: @_ZGRN39ClassTemplateWithHiddenStaticDataMember1SIvE1aE_ = linkonce_odr hidden constant i32 5, comdat // CHECK: @_ZN39ClassTemplateWithHiddenStaticDataMember3useE = constant i32* @_ZGRN39ClassTemplateWithHiddenStaticDataMember1SIvE1aE_ -// CHECK: @_ZGRZN20InlineStaticConstRef3funEvE1i_ = linkonce_odr constant i32 10 +// CHECK: @_ZGRZN20InlineStaticConstRef3funEvE1i_ = linkonce_odr constant i32 10, comdat // Constant initialization tests go before this point, // dynamic initialization tests go after. @@ -488,7 +497,7 @@ namespace Unreferenced { // We must not emit a load of 'p' here, since it's not odr-used. int q = *p; // CHECK-NOT: _ZN12Unreferenced1pE - // CHECK: = load i32* @_ZN12Unreferenced1nE + // CHECK: = load i32, i32* @_ZN12Unreferenced1nE // CHECK-NEXT: store i32 {{.*}}, i32* @_ZN12Unreferenced1qE // CHECK-NOT: _ZN12Unreferenced1pE @@ -544,7 +553,7 @@ namespace InitFromConst { // CHECK: call void @_ZN13InitFromConst7consumeIMNS_1SEiEEvT_(i64 0) consume(mp); - // CHECK: call void @_ZN13InitFromConst7consumeIPKiEEvT_(i32* getelementptr inbounds ([3 x i32]* @_ZN13InitFromConstL1aE, i32 0, i32 0)) + // CHECK: call void @_ZN13InitFromConst7consumeIPKiEEvT_(i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZN13InitFromConstL1aE, i32 0, i32 0)) consume(a); } } @@ -586,3 +595,16 @@ namespace ClassTemplateWithHiddenStaticDataMember { const int &S<T>::a = 5; const int &use = S<void>::a; } + +namespace ClassWithStaticConstexprDataMember { +struct X { + static constexpr const char &p = 'c'; +}; + +// CHECK: @_ZGRN34ClassWithStaticConstexprDataMember1X1pE_ +const char *f() { return &X::p; } +} + +// VirtualMembers::TemplateClass::templateMethod() must be defined in this TU, +// not just declared. +// CHECK: define linkonce_odr void @_ZN14VirtualMembers13TemplateClassIiE14templateMethodEv(%"struct.VirtualMembers::TemplateClass"* %this) diff --git a/test/CodeGenCXX/const-init-cxx1y.cpp b/test/CodeGenCXX/const-init-cxx1y.cpp index 9348b43..c10cde8 100644 --- a/test/CodeGenCXX/const-init-cxx1y.cpp +++ b/test/CodeGenCXX/const-init-cxx1y.cpp @@ -23,18 +23,18 @@ namespace ModifyStaticTemporary { struct A { int &&temporary; int x; }; constexpr int f(int &r) { r *= 9; return r - 12; } A a = { 6, f(a.temporary) }; - // CHECK: @_ZGRN21ModifyStaticTemporary1aE_ = private global i32 54 + // CHECK: @_ZGRN21ModifyStaticTemporary1aE_ = internal global i32 54 // CHECK: @_ZN21ModifyStaticTemporary1aE = global {{.*}} i32* @_ZGRN21ModifyStaticTemporary1aE_, i32 42 A b = { 7, ++b.temporary }; - // CHECK: @_ZGRN21ModifyStaticTemporary1bE_ = private global i32 8 + // CHECK: @_ZGRN21ModifyStaticTemporary1bE_ = internal global i32 8 // CHECK: @_ZN21ModifyStaticTemporary1bE = global {{.*}} i32* @_ZGRN21ModifyStaticTemporary1bE_, i32 8 // Can't emit all of 'c' as a constant here, so emit the initial value of // 'c.temporary', not the value as modified by the partial evaluation within // the initialization of 'c.x'. A c = { 10, (++c.temporary, b.x) }; - // CHECK: @_ZGRN21ModifyStaticTemporary1cE_ = private global i32 10 + // CHECK: @_ZGRN21ModifyStaticTemporary1cE_ = internal global i32 10 // CHECK: @_ZN21ModifyStaticTemporary1cE = global {{.*}} zeroinitializer } diff --git a/test/CodeGenCXX/const-init.cpp b/test/CodeGenCXX/const-init.cpp index 05896ff..deb923a 100644 --- a/test/CodeGenCXX/const-init.cpp +++ b/test/CodeGenCXX/const-init.cpp @@ -1,4 +1,4 @@ -// RUN: not %clang_cc1 -verify -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -o - %s | FileCheck %s // CHECK: @a = global i32 10 int a = 10; @@ -74,5 +74,12 @@ void FoldableAddrLabelDiff() { static long x = (long)&&a-(long)&&b; a:b:return;} int &i = reinterpret_cast<int&>(PR9558); int arr[2]; -// CHECK: @pastEnd = constant i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @arr to i8*), i64 8) to i32*) +// CHECK: @pastEnd = constant i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @arr to i8*), i64 8) to i32*) int &pastEnd = arr[2]; + +struct X { + long n : 8; +}; +long k; +X x = {(long)&k}; +// CHECK: store i8 ptrtoint (i64* @k to i8), i8* getelementptr inbounds (%struct.X, %struct.X* @x, i32 0, i32 0) diff --git a/test/CodeGenCXX/constructor-destructor-return-this.cpp b/test/CodeGenCXX/constructor-destructor-return-this.cpp index dcd20fe..893e3a0 100644 --- a/test/CodeGenCXX/constructor-destructor-return-this.cpp +++ b/test/CodeGenCXX/constructor-destructor-return-this.cpp @@ -129,8 +129,8 @@ void test_destructor() { // Verify that virtual calls to destructors are not marked with a 'returned' // this parameter at the call site... -// CHECKARM: [[VFN:%.*]] = getelementptr inbounds %class.E* (%class.E*)** -// CHECKARM: [[THUNK:%.*]] = load %class.E* (%class.E*)** [[VFN]] +// CHECKARM: [[VFN:%.*]] = getelementptr inbounds %class.E* (%class.E*)*, %class.E* (%class.E*)** +// CHECKARM: [[THUNK:%.*]] = load %class.E* (%class.E*)*, %class.E* (%class.E*)** [[VFN]] // CHECKARM: call %class.E* [[THUNK]](%class.E* % // ...but static calls create declarations with 'returned' this diff --git a/test/CodeGenCXX/constructor-init.cpp b/test/CodeGenCXX/constructor-init.cpp index 9d029a3..d7ae220 100644 --- a/test/CodeGenCXX/constructor-init.cpp +++ b/test/CodeGenCXX/constructor-init.cpp @@ -95,14 +95,14 @@ namespace InitVTable { // CHECK-LABEL: define void @_ZN10InitVTable1BC2Ev(%"struct.InitVTable::B"* %this) unnamed_addr // CHECK: [[T0:%.*]] = bitcast [[B:%.*]]* [[THIS:%.*]] to i32 (...)*** - // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]] - // CHECK: [[VTBL:%.*]] = load i32 ([[B]]*)*** {{%.*}} - // CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds i32 ([[B]]*)** [[VTBL]], i64 0 - // CHECK-NEXT: [[FN:%.*]] = load i32 ([[B]]*)** [[FNP]] + // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]] + // CHECK: [[VTBL:%.*]] = load i32 ([[B]]*)**, i32 ([[B]]*)*** {{%.*}} + // CHECK-NEXT: [[FNP:%.*]] = getelementptr inbounds i32 ([[B]]*)*, i32 ([[B]]*)** [[VTBL]], i64 0 + // CHECK-NEXT: [[FN:%.*]] = load i32 ([[B]]*)*, i32 ([[B]]*)** [[FNP]] // CHECK-NEXT: [[ARG:%.*]] = call i32 [[FN]]([[B]]* [[THIS]]) // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* [[THIS]] to i32 (...)*** - // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]] + // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]] // CHECK-NEXT: ret void B::B() : A(foo()) {} @@ -110,7 +110,7 @@ namespace InitVTable { // CHECK: [[ARG:%.*]] = add nsw i32 {{%.*}}, 5 // CHECK-NEXT: call void @_ZN10InitVTable1AC2Ei({{.*}}* {{%.*}}, i32 [[ARG]]) // CHECK-NEXT: [[T0:%.*]] = bitcast [[B]]* {{%.*}} to i32 (...)*** - // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]] + // CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN10InitVTable1BE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]] // CHECK-NEXT: ret void B::B(int x) : A(x + 5) {} } @@ -200,33 +200,35 @@ namespace PR10720 { // CHECK-PR10720: ret pair2 &operator=(pair2&&) = default; - // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2EOS0_ + // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107204pairC2ERKS0_ + // CHECK-PR10720-NOT: ret + // CHECK-PR10720: call void @llvm.memcpy + // CHECK-PR10720-NEXT: ret void + + // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2ERKS0_ // CHECK-PR10720-NOT: ret // CHECK-PR10720: load // CHECK-PR10720: icmp ult // CHECK-PR10720-NEXT: br i1 - // CHECK-PR10720: call void @_ZN7PR107201XC1EOS0_ + // CHECK-PR10720: call void @_ZN7PR107201XC1ERKS0_ // CHECK-PR10720-NEXT: br label // CHECK-PR10720: ret void - pair2(pair2&&) = default; - // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2ERKS0_ + // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107205pair2C2EOS0_ // CHECK-PR10720-NOT: ret // CHECK-PR10720: load // CHECK-PR10720: icmp ult // CHECK-PR10720-NEXT: br i1 - // CHECK-PR10720: call void @_ZN7PR107201XC1ERKS0_ + // CHECK-PR10720: call void @_ZN7PR107201XC1EOS0_ // CHECK-PR10720-NEXT: br label // CHECK-PR10720: ret void + pair2(pair2&&) = default; + pair2(const pair2&) = default; }; struct pair : X { // Make the copy constructor non-trivial, so we actually generate it. int second[4]; - // CHECK-PR10720-LABEL: define linkonce_odr void @_ZN7PR107204pairC2ERKS0_ - // CHECK-PR10720-NOT: ret - // CHECK-PR10720: call void @llvm.memcpy - // CHECK-PR10720-NEXT: ret void pair(const pair&) = default; }; diff --git a/test/CodeGenCXX/constructor-template.cpp b/test/CodeGenCXX/constructor-template.cpp index 675e3cf..d1ae094 100644 --- a/test/CodeGenCXX/constructor-template.cpp +++ b/test/CodeGenCXX/constructor-template.cpp @@ -45,10 +45,10 @@ int main() { delete node; } +// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev: // CHECK-LP64: __ZN4NodeIP12BinomialNodeIiEEC2Ev: // CHECK-LP64: __ZN4ListIP12BinomialNodeIiEEC1Ev: -// CHECK-LP64: __ZN4ListIP12BinomialNodeIiEED1Ev: +// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev: // CHECK-LP32: __ZN4NodeIP12BinomialNodeIiEEC2Ev: // CHECK-LP32: __ZN4ListIP12BinomialNodeIiEEC1Ev: -// CHECK-LP32: __ZN4ListIP12BinomialNodeIiEED1Ev: diff --git a/test/CodeGenCXX/constructors.cpp b/test/CodeGenCXX/constructors.cpp index b99c5a1..ecbe5bb 100644 --- a/test/CodeGenCXX/constructors.cpp +++ b/test/CodeGenCXX/constructors.cpp @@ -106,6 +106,6 @@ namespace test1 { struct B { B(); int x; A a[0]; }; B::B() {} // CHECK-LABEL: define void @_ZN5test11BC2Ev( - // CHECK: [[THIS:%.*]] = load [[B:%.*]]** + // CHECK: [[THIS:%.*]] = load [[B:%.*]]*, [[B:%.*]]** // CHECK-NEXT: ret void } diff --git a/test/CodeGenCXX/convert-to-fptr.cpp b/test/CodeGenCXX/convert-to-fptr.cpp index c3be962..283493e 100644 --- a/test/CodeGenCXX/convert-to-fptr.cpp +++ b/test/CodeGenCXX/convert-to-fptr.cpp @@ -38,5 +38,5 @@ int main() return 0; } -// CHECK: call i32 (i32)* (%struct.A*)* @_ZN1AcvPFiiEEv -// CHECK: call i32 (i32)* (%struct.B*)* @_ZN1BcvRFiiEEv +// CHECK: call i32 (i32)* @_ZN1AcvPFiiEEv +// CHECK: call i32 (i32)* @_ZN1BcvRFiiEEv diff --git a/test/CodeGenCXX/copy-constructor-elim.cpp b/test/CodeGenCXX/copy-constructor-elim.cpp index 8e9bee9..d9b28ce 100644 --- a/test/CodeGenCXX/copy-constructor-elim.cpp +++ b/test/CodeGenCXX/copy-constructor-elim.cpp @@ -43,3 +43,17 @@ int main() { S s; Call(s); } + +struct V { + int x; +}; + +typedef V V_over_aligned __attribute((aligned(8))); +extern const V_over_aligned gv1 = {}; + +extern "C" V f() { return gv1; } + +// Make sure that we obey the destination's alignment requirements when emitting +// the copy. +// CHECK-LABEL: define {{.*}} @f( +// CHECK: call void @llvm.memcpy.p0i8.p0i8.{{i64|i32}}({{.*}}, i8* bitcast (%struct.V* @gv1 to i8*), {{i64|i32}} 4, i32 4, i1 false) diff --git a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp index 8fdc4df..02feed3 100644 --- a/test/CodeGenCXX/copy-constructor-synthesis-2.cpp +++ b/test/CodeGenCXX/copy-constructor-synthesis-2.cpp @@ -1,7 +1,27 @@ -// RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple %itanium_abi_triple -std=c++11 -emit-llvm -o - %s | FileCheck %s + +union PR23373 { + PR23373(PR23373&) = default; + PR23373 &operator=(PR23373&) = default; + int n; + float f; +}; +extern PR23373 pr23373_a; + +PR23373 pr23373_b(pr23373_a); +// CHECK-LABEL: define {{.*}} @__cxx_global_var_init( +// CHECK: call void @llvm.memcpy.p0i8.p0i8.{{i32|i64}}({{.*}} @pr23373_b{{.*}}, {{.*}} @pr23373_a{{.*}}, [[W:i32|i64]] 4, i32 4, i1 false) + +PR23373 pr23373_f() { return pr23373_a; } +// CHECK-LABEL: define {{.*}} @_Z9pr23373_fv( +// CHECK: call void @llvm.memcpy.p0i8.p0i8.[[W]]({{.*}}, [[W]] 4, i32 4, i1 false) + +void pr23373_g(PR23373 &a, PR23373 &b) { a = b; } +// CHECK-LABEL: define {{.*}} @_Z9pr23373_g +// CHECK: call void @llvm.memcpy.p0i8.p0i8.[[W]]({{.*}}, [[W]] 4, i32 4, i1 false) struct A { virtual void a(); }; A x(A& y) { return y; } // CHECK: define linkonce_odr {{.*}} @_ZN1AC1ERKS_(%struct.A* {{.*}}%this, %struct.A* dereferenceable({{[0-9]+}})) unnamed_addr -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**) +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**) diff --git a/test/CodeGenCXX/copy-constructor-synthesis.cpp b/test/CodeGenCXX/copy-constructor-synthesis.cpp index abbb7d0..2f0aa3b 100644 --- a/test/CodeGenCXX/copy-constructor-synthesis.cpp +++ b/test/CodeGenCXX/copy-constructor-synthesis.cpp @@ -137,27 +137,15 @@ void f(B b1) { } // CHECK: define linkonce_odr dereferenceable({{[0-9]+}}) [[A:%.*]]* @_ZN12rdar138169401AaSERKS0_( -// CHECK: [[THIS:%.*]] = load [[A]]** -// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1 -// CHECK-NEXT: [[OTHER:%.*]] = load [[A]]** -// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* [[OTHER]], i32 0, i32 1 +// CHECK: [[THIS:%.*]] = load [[A]]*, [[A]]** +// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 1 +// CHECK-NEXT: [[OTHER:%.*]] = load [[A]]*, [[A]]** +// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OTHER]], i32 0, i32 1 // CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T0]] to i8* // CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T2]] to i8* // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T4]], i8* [[T5]], i64 8, i32 8, i1 false) // CHECK-NEXT: ret [[A]]* [[THIS]] -// CHECK-LABEL: define linkonce_odr void @_ZN12rdar138169401AC2ERKS0_( -// CHECK: [[THIS:%.*]] = load [[A]]** -// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[THIS]] to i32 (...)*** -// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTVN12rdar138169401AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]] -// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]]* [[THIS]], i32 0, i32 1 -// CHECK-NEXT: [[OTHER:%.*]] = load [[A]]** -// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]]* [[OTHER]], i32 0, i32 1 -// CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T0]] to i8* -// CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T2]] to i8* -// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T4]], i8* [[T5]], i64 8, i32 8, i1 false) -// CHECK-NEXT: ret void - // CHECK-LABEL: define linkonce_odr void @_ZN6PR66281BC2ERKS0_(%"struct.PR6628::B"* %this, %"struct.PR6628::B"* dereferenceable({{[0-9]+}})) unnamed_addr // CHECK: call void @_ZN6PR66281TC1Ev // CHECK: call void @_ZN6PR66281TC1Ev @@ -174,6 +162,18 @@ void f(B b1) { // CHECK: call void @_ZN6PR66281AC1ERKS0_RKNS_1TES5_ // CHECK: call void @_ZN6PR66281TD1Ev // CHECK: call void @_ZN6PR66281TD1Ev + +// CHECK-LABEL: define linkonce_odr void @_ZN12rdar138169401AC2ERKS0_( +// CHECK: [[THIS:%.*]] = load [[A]]*, [[A]]** +// CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[THIS]] to i32 (...)*** +// CHECK-NEXT: store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN12rdar138169401AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** [[T0]] +// CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [[A]], [[A]]* [[THIS]], i32 0, i32 1 +// CHECK-NEXT: [[OTHER:%.*]] = load [[A]]*, [[A]]** +// CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[OTHER]], i32 0, i32 1 +// CHECK-NEXT: [[T4:%.*]] = bitcast i16* [[T0]] to i8* +// CHECK-NEXT: [[T5:%.*]] = bitcast i16* [[T2]] to i8* +// CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T4]], i8* [[T5]], i64 8, i32 8, i1 false) +// CHECK-NEXT: ret void } // rdar://13816940 diff --git a/test/CodeGenCXX/coverage.cpp b/test/CodeGenCXX/coverage.cpp index 3931b0c..4b23324 100644 --- a/test/CodeGenCXX/coverage.cpp +++ b/test/CodeGenCXX/coverage.cpp @@ -3,5 +3,7 @@ extern "C" void test_name1() {} void test_name2() {} -// CHECK: !"0x2e\00test_name1\00test_name1\00\00{{[^,]+}}", {{.*}} DW_TAG_subprogram -// CHECK: !"0x2e\00test_name2\00test_name2\00_Z10test_name2v\00{{[^,]+}}", {{.*}} DW_TAG_subprogram +// CHECK: !DISubprogram(name: "test_name1", +// CHECK-NOT: linkageName: +// CHECK-SAME: ){{$}} +// CHECK: !DISubprogram(name: "test_name2", linkageName: "_Z10test_name2v" diff --git a/test/CodeGenCXX/crash.cpp b/test/CodeGenCXX/crash.cpp index e1577a3..2785d8d 100644 --- a/test/CodeGenCXX/crash.cpp +++ b/test/CodeGenCXX/crash.cpp @@ -1,3 +1,4 @@ +// XFAIL: hexagon // RUN: %clang_cc1 %s -std=c++11 -emit-llvm-only // RUN: %clang_cc1 -emit-obj -o %t -gline-tables-only -std=c++11 %s // CHECK that we don't crash. @@ -34,13 +35,3 @@ template <class ELFT> void finalizeDefaultAtomValues() { void f() { finalizeDefaultAtomValues<int>(); } } - -namespace PR22096 { -template <class> struct c { - c(); - template <class U> __attribute__((__always_inline__)) c(c<U>) {} -}; -struct { - c<double> v = c<int>(); -} o; -} diff --git a/test/CodeGenCXX/ctor-dtor-alias.cpp b/test/CodeGenCXX/ctor-dtor-alias.cpp index 54dfe87..a7bafb8 100644 --- a/test/CodeGenCXX/ctor-dtor-alias.cpp +++ b/test/CodeGenCXX/ctor-dtor-alias.cpp @@ -22,7 +22,10 @@ namespace test1 { // CHECK1-NOT: comdat // COFF doesn't support comdats with arbitrary names (C5/D5). -// COFF-NOT: comdat +// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvEC2Ev({{.*}} comdat align +// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvEC1Ev({{.*}} comdat align +// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvED2Ev({{.*}} comdat align +// COFF: define weak_odr {{.*}} void @_ZN5test16foobarIvED0Ev({{.*}} comdat align template <typename T> struct foobar { @@ -39,7 +42,7 @@ namespace test2 { // CHECK1: define internal void @__cxx_global_var_init() // CHECK1: call void @_ZN5test26foobarIvEC2Ev -// CHECK1: define linkonce_odr void @_ZN5test26foobarIvEC2Ev( +// CHECK1: define linkonce_odr void @_ZN5test26foobarIvEC2Ev({{.*}} comdat align void g(); template <typename T> struct foobar { foobar() { g(); } @@ -51,7 +54,7 @@ namespace test3 { // test that instead of an internal alias we just use the other destructor // directly. -// CHECK1: define internal void @__cxx_global_var_init1() +// CHECK1: define internal void @__cxx_global_var_init.1() // CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test312_GLOBAL__N_11AD2Ev // CHECK1: define internal void @_ZN5test312_GLOBAL__N_11AD2Ev( namespace { @@ -70,15 +73,15 @@ namespace test4 { // guarantee that they will be present in every TU. Instead, we just call // A's destructor directly. - // CHECK1: define internal void @__cxx_global_var_init2() + // CHECK1: define internal void @__cxx_global_var_init.2() // CHECK1: call i32 @__cxa_atexit{{.*}}_ZN5test41AD2Ev - // CHECK1: define linkonce_odr void @_ZN5test41AD2Ev( + // CHECK1: define linkonce_odr void @_ZN5test41AD2Ev({{.*}} comdat align // test that we don't do this optimization at -O0 so that the debugger can // see both destructors. - // NOOPT: define internal void @__cxx_global_var_init2() + // NOOPT: define internal void @__cxx_global_var_init.2() // NOOPT: call i32 @__cxa_atexit{{.*}}@_ZN5test41BD2Ev - // NOOPT: define linkonce_odr void @_ZN5test41BD2Ev + // NOOPT: define linkonce_odr void @_ZN5test41BD2Ev({{.*}} comdat align struct A { virtual ~A() {} }; @@ -91,9 +94,9 @@ namespace test4 { namespace test5 { // similar to test4, but with an internal B. - // CHECK2: define internal void @__cxx_global_var_init3() + // CHECK2: define internal void @__cxx_global_var_init.3() // CHECK2: call i32 @__cxa_atexit{{.*}}_ZN5test51AD2Ev - // CHECK2: define linkonce_odr void @_ZN5test51AD2Ev( + // CHECK2: define linkonce_odr void @_ZN5test51AD2Ev({{.*}} comdat align struct A { virtual ~A() {} }; @@ -117,7 +120,7 @@ namespace test6 { }; } B X; - // CHECK3: define internal void @__cxx_global_var_init4() + // CHECK3: define internal void @__cxx_global_var_init.4() // CHECK3: call i32 @__cxa_atexit({{.*}}@_ZN5test61AD2Ev } @@ -139,7 +142,7 @@ namespace test7 { namespace test8 { // Test that we replace ~zed with ~bar which is an alias to ~foo. // CHECK4: @_ZN5test83barD2Ev = alias {{.*}} @_ZN5test83fooD2Ev - // CHECK4: define internal void @__cxx_global_var_init5() + // CHECK4: define internal void @__cxx_global_var_init.5() // CHECK4: call i32 @__cxa_atexit({{.*}}@_ZN5test83barD2Ev struct foo { ~foo(); diff --git a/test/CodeGenCXX/cxx0x-initializer-array.cpp b/test/CodeGenCXX/cxx0x-initializer-array.cpp index 49bc86f..de10aee 100644 --- a/test/CodeGenCXX/cxx0x-initializer-array.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-array.cpp @@ -42,10 +42,11 @@ namespace ValueInitArrayOfMemPtr { // CHECK: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %{{.*}}, i8* bitcast ([3 x i32]* @[[THREE_NULL_MEMPTRS]] to i8*), i32 12, i32 4, i1 false) } - // CHECK-LABEL: define void @_ZN22ValueInitArrayOfMemPtr1gEv - void g() { + // Test dynamic initialization. + // CHECK-LABEL: define void @_ZN22ValueInitArrayOfMemPtr1gEMNS_1SEi + void g(p ptr) { // CHECK: store i32 -1, - f(a{}); + f(a{ptr}); } } diff --git a/test/CodeGenCXX/cxx0x-initializer-references.cpp b/test/CodeGenCXX/cxx0x-initializer-references.cpp index 10586c1..318c8ea 100644 --- a/test/CodeGenCXX/cxx0x-initializer-references.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-references.cpp @@ -35,22 +35,30 @@ namespace reference { // CHECK-NEXT: ret } - void reference_to_aggregate() { + void reference_to_aggregate(int i) { // CHECK: getelementptr {{.*}}, i32 0, i32 0 // CHECK-NEXT: store i32 1 // CHECK-NEXT: getelementptr {{.*}}, i32 0, i32 1 - // CHECK-NEXT: store i32 2 + // CHECK-NEXT: %[[I1:.*]] = load i32, i32* + // CHECK-NEXT: store i32 %[[I1]] // CHECK-NEXT: store %{{.*}}* %{{.*}}, %{{.*}}** %{{.*}}, align - const A &ra1{1, 2}; + const A &ra1{1, i}; - // CHECK-NEXT: getelementptr inbounds [3 x i32]* %{{.*}}, i{{32|64}} 0, i{{32|64}} 0 + // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* %{{.*}}, i{{32|64}} 0, i{{32|64}} 0 // CHECK-NEXT: store i32 1 - // CHECK-NEXT: getelementptr inbounds i32* %{{.*}}, i{{32|64}} 1 + // CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1 // CHECK-NEXT: store i32 2 - // CHECK-NEXT: getelementptr inbounds i32* %{{.*}}, i{{32|64}} 1 - // CHECK-NEXT: store i32 3 + // CHECK-NEXT: getelementptr inbounds i32, i32* %{{.*}}, i{{32|64}} 1 + // CHECK-NEXT: %[[I2:.*]] = load i32, i32* + // CHECK-NEXT: store i32 %[[I2]] // CHECK-NEXT: store [3 x i32]* %{{.*}}, [3 x i32]** %{{.*}}, align - const int (&arrayRef)[] = {1, 2, 3}; + const int (&arrayRef)[] = {1, 2, i}; + + // CHECK: store %{{.*}}* @{{.*}}, %{{.*}}** %{{.*}}, align + const A &constra1{1, 2}; + + // CHECK-NEXT: store [3 x i32]* @{{.*}}, [3 x i32]** %{{.*}}, align + const int (&constarrayRef)[] = {1, 2, 3}; // CHECK-NEXT: ret } @@ -71,3 +79,33 @@ namespace reference { } } + +namespace PR23165 { +struct AbstractClass { + virtual void foo() const = 0; +}; + +struct ChildClass : public AbstractClass { + virtual void foo() const {} +}; + +void helper(const AbstractClass ¶m) { + param.foo(); +} + +void foo() { +// CHECK-LABEL: @_ZN7PR231653fooEv +// CHECK: call {{.*}} @_ZN7PR2316510ChildClassC1Ev +// CHECK: call void @_ZN7PR231656helperERKNS_13AbstractClassE + helper(ChildClass()); +} + +struct S { struct T { int a; } t; mutable int b; }; +void f() { +// CHECK-LABEL: _ZN7PR231651fEv +// CHECK: alloca +// CHECK: alloca +// CHECK: store + const S::T &r = S().t; +} +} diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp index 91e913e..da0c47b 100644 --- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-pr12086.cpp @@ -55,78 +55,78 @@ std::initializer_list<std::initializer_list<int>> nested = { {1, a}, {3, b}, {5, c} }; -// CHECK-STATIC-BL: @_ZGR6nested0_ = private constant [2 x i32] [i32 1, i32 2], align 4 -// CHECK-STATIC-BL: @_ZGR6nested1_ = private constant [2 x i32] [i32 3, i32 4], align 4 -// CHECK-STATIC-BL: @_ZGR6nested2_ = private constant [2 x i32] [i32 5, i32 6], align 4 -// CHECK-STATIC-BL: @_ZGR6nested_ = private constant [3 x {{.*}}] [ -// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i32 0, i32 0), i64 2 }, -// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i32 0, i32 0), i64 2 }, -// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i32 0, i32 0), i64 2 } +// CHECK-STATIC-BL: @_ZGR6nested0_ = internal constant [2 x i32] [i32 1, i32 2], align 4 +// CHECK-STATIC-BL: @_ZGR6nested1_ = internal constant [2 x i32] [i32 3, i32 4], align 4 +// CHECK-STATIC-BL: @_ZGR6nested2_ = internal constant [2 x i32] [i32 5, i32 6], align 4 +// CHECK-STATIC-BL: @_ZGR6nested_ = internal constant [3 x {{.*}}] [ +// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i32 0, i32 0), i64 2 }, +// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i32 0, i32 0), i64 2 }, +// CHECK-STATIC-BL: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i32 0, i32 0), i64 2 } // CHECK-STATIC-BL: ], align 8 -// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i32 0, i32 0), i64 3 }, align 8 +// CHECK-STATIC-BL: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i32 0, i32 0), i64 3 }, align 8 // CHECK-DYNAMIC-BL: @nested = global -// CHECK-DYNAMIC-BL: @_ZGR6nested_ = private global [3 x -// CHECK-DYNAMIC-BL: @_ZGR6nested0_ = private global [2 x i32] zeroinitializer -// CHECK-DYNAMIC-BL: @_ZGR6nested1_ = private global [2 x i32] zeroinitializer -// CHECK-DYNAMIC-BL: @_ZGR6nested2_ = private global [2 x i32] zeroinitializer -// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 0) -// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 1) -// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 0), -// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 0), align 8 -// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 1), align 8 -// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 0) -// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 1) -// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 0), -// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 0), align 8 -// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 1), align 8 -// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 0) -// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 1) -// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 0), -// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 0), align 8 -// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 1), align 8 -// CHECK-DYNAMIC-BL: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0), -// CHECK-DYNAMIC-BL: {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8 -// CHECK-DYNAMIC-BL: store i64 3, i64* getelementptr inbounds ({{.*}}* @nested, i32 0, i32 1), align 8 +// CHECK-DYNAMIC-BL: @_ZGR6nested_ = internal global [3 x +// CHECK-DYNAMIC-BL: @_ZGR6nested0_ = internal global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BL: @_ZGR6nested1_ = internal global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BL: @_ZGR6nested2_ = internal global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BL: store i32 1, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 0) +// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 1) +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 0), +// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 0), align 8 +// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 1), align 8 +// CHECK-DYNAMIC-BL: store i32 3, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 0) +// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 1) +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 0), +// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 0), align 8 +// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 1), align 8 +// CHECK-DYNAMIC-BL: store i32 5, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 0) +// CHECK-DYNAMIC-BL: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 1) +// CHECK-DYNAMIC-BL: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 0), +// CHECK-DYNAMIC-BL: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 0), align 8 +// CHECK-DYNAMIC-BL: store i64 2, i64* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 1), align 8 +// CHECK-DYNAMIC-BL: store {{.*}}* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0), +// CHECK-DYNAMIC-BL: {{.*}}** getelementptr inbounds ({{.*}}, {{.*}}* @nested, i32 0, i32 0), align 8 +// CHECK-DYNAMIC-BL: store i64 3, i64* getelementptr inbounds ({{.*}}, {{.*}}* @nested, i32 0, i32 1), align 8 -// CHECK-STATIC-BE: @_ZGR6nested0_ = private constant [2 x i32] [i32 1, i32 2], align 4 -// CHECK-STATIC-BE: @_ZGR6nested1_ = private constant [2 x i32] [i32 3, i32 4], align 4 -// CHECK-STATIC-BE: @_ZGR6nested2_ = private constant [2 x i32] [i32 5, i32 6], align 4 -// CHECK-STATIC-BE: @_ZGR6nested_ = private constant [3 x {{.*}}] [ -// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i32 0, i32 0), -// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested0_ to i8*), i64 8) to i32*) } -// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i32 0, i32 0), -// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested1_ to i8*), i64 8) to i32*) } -// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i32 0, i32 0), -// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8* bitcast ([2 x i32]* @_ZGR6nested2_ to i8*), i64 8) to i32*) } +// CHECK-STATIC-BE: @_ZGR6nested0_ = internal constant [2 x i32] [i32 1, i32 2], align 4 +// CHECK-STATIC-BE: @_ZGR6nested1_ = internal constant [2 x i32] [i32 3, i32 4], align 4 +// CHECK-STATIC-BE: @_ZGR6nested2_ = internal constant [2 x i32] [i32 5, i32 6], align 4 +// CHECK-STATIC-BE: @_ZGR6nested_ = internal constant [3 x {{.*}}] [ +// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i32 0, i32 0), +// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @_ZGR6nested0_ to i8*), i64 8) to i32*) } +// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i32 0, i32 0), +// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @_ZGR6nested1_ to i8*), i64 8) to i32*) } +// CHECK-STATIC-BE: {{.*}} { i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i32 0, i32 0), +// CHECK-STATIC-BE: i32* bitcast (i8* getelementptr (i8, i8* bitcast ([2 x i32]* @_ZGR6nested2_ to i8*), i64 8) to i32*) } // CHECK-STATIC-BE: ], align 8 -// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i32 0, i32 0), -// CHECK-STATIC-BE: {{.*}} bitcast ({{.*}}* getelementptr (i8* bitcast ([3 x {{.*}}]* @_ZGR6nested_ to i8*), i64 48) to {{.*}}*) } +// CHECK-STATIC-BE: @nested = global {{.*}} { {{.*}} getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i32 0, i32 0), +// CHECK-STATIC-BE: {{.*}} bitcast ({{.*}}* getelementptr (i8, i8* bitcast ([3 x {{.*}}]* @_ZGR6nested_ to i8*), i64 48) to {{.*}}*) } // CHECK-DYNAMIC-BE: @nested = global -// CHECK-DYNAMIC-BE: @_ZGR6nested_ = private global [3 x -// CHECK-DYNAMIC-BE: @_ZGR6nested0_ = private global [2 x i32] zeroinitializer -// CHECK-DYNAMIC-BE: @_ZGR6nested1_ = private global [2 x i32] zeroinitializer -// CHECK-DYNAMIC-BE: @_ZGR6nested2_ = private global [2 x i32] zeroinitializer -// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 0) -// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 1) -// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 0, i64 0), -// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 0), align 8 -// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested0_, i64 1, i64 0), -// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 1), align 8 -// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 0) -// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 1) -// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 0, i64 0), -// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 0), align 8 -// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested1_, i64 1, i64 0), -// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 1), align 8 -// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 0) -// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 1) -// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 0, i64 0), -// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 0), align 8 -// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32]* @_ZGR6nested2_, i64 1, i64 0), -// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 1), align 8 -// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0), -// CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 0), align 8 -// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}]* @_ZGR6nested_, i64 1, i64 0), -// CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}* @nested, i32 0, i32 1), align 8 +// CHECK-DYNAMIC-BE: @_ZGR6nested_ = internal global [3 x +// CHECK-DYNAMIC-BE: @_ZGR6nested0_ = internal global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BE: @_ZGR6nested1_ = internal global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BE: @_ZGR6nested2_ = internal global [2 x i32] zeroinitializer +// CHECK-DYNAMIC-BE: store i32 1, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 0) +// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 1) +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 0, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 0), align 8 +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested0_, i64 1, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0, i32 1), align 8 +// CHECK-DYNAMIC-BE: store i32 3, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 0) +// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 1) +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 0, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 0), align 8 +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested1_, i64 1, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 1, i32 1), align 8 +// CHECK-DYNAMIC-BE: store i32 5, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 0) +// CHECK-DYNAMIC-BE: store i32 {{.*}}, i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 1) +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 0, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 0), align 8 +// CHECK-DYNAMIC-BE: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @_ZGR6nested2_, i64 1, i64 0), +// CHECK-DYNAMIC-BE: i32** getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 2, i32 1), align 8 +// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 0, i64 0), +// CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}, {{.*}}* @nested, i32 0, i32 0), align 8 +// CHECK-DYNAMIC-BE: store {{.*}}* getelementptr inbounds ([3 x {{.*}}], [3 x {{.*}}]* @_ZGR6nested_, i64 1, i64 0), +// CHECK-DYNAMIC-BE: {{.*}}** getelementptr inbounds ({{.*}}, {{.*}}* @nested, i32 0, i32 1), align 8 diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp index 5a48346..46ad686 100644 --- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist-startend.cpp @@ -32,15 +32,15 @@ namespace std { }; } -// CHECK: @_ZGR15globalInitList1_ = private constant [3 x i32] [i32 1, i32 2, i32 3] -// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZGR15globalInitList1_, {{[^)]*}}), i32* +// CHECK: @_ZGR15globalInitList1_ = internal constant [3 x i32] [i32 1, i32 2, i32 3] +// CHECK: @globalInitList1 = global {{[^ ]+}} { i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZGR15globalInitList1_, {{[^)]*}}), i32* std::initializer_list<int> globalInitList1 = {1, 2, 3}; void fn1(int i) { // CHECK-LABEL: define void @_Z3fn1i // temporary array // CHECK: [[array:%[^ ]+]] = alloca [3 x i32] - // CHECK: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0 + // CHECK: getelementptr inbounds [3 x i32], [3 x i32]* [[array]], i{{32|64}} 0 // CHECK-NEXT: store i32 1, i32* // CHECK-NEXT: getelementptr // CHECK-NEXT: store @@ -49,10 +49,10 @@ void fn1(int i) { // CHECK-NEXT: store // init the list // CHECK-NEXT: getelementptr - // CHECK-NEXT: getelementptr inbounds [3 x i32]* + // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* // CHECK-NEXT: store i32* // CHECK-NEXT: getelementptr - // CHECK-NEXT: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0, i{{32|64}} 3 + // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* [[array]], i{{32|64}} 0, i{{32|64}} 3 // CHECK-NEXT: store i32* std::initializer_list<int> intlist{1, 2, i}; } diff --git a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp index 4d30344..6d5d397 100644 --- a/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp +++ b/test/CodeGenCXX/cxx0x-initializer-stdinitializerlist.cpp @@ -47,8 +47,8 @@ struct wantslist1 { ~wantslist1(); }; -// CHECK: @_ZGR15globalInitList1_ = private constant [3 x i32] [i32 1, i32 2, i32 3] -// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32]* @_ZGR15globalInitList1_, i32 0, i32 0), i{{32|64}} 3 } +// CHECK: @_ZGR15globalInitList1_ = internal constant [3 x i32] [i32 1, i32 2, i32 3] +// CHECK: @globalInitList1 = global %{{[^ ]+}} { i32* getelementptr inbounds ([3 x i32], [3 x i32]* @_ZGR15globalInitList1_, i32 0, i32 0), i{{32|64}} 3 } std::initializer_list<int> globalInitList1 = {1, 2, 3}; namespace thread_local_global_array { @@ -57,38 +57,41 @@ namespace thread_local_global_array { // objects aren't really a problem). // // CHECK: @_ZN25thread_local_global_array1xE = thread_local global - // CHECK: @_ZGRN25thread_local_global_array1xE_ = private thread_local constant [4 x i32] [i32 1, i32 2, i32 3, i32 4] + // CHECK: @_ZGRN25thread_local_global_array1xE_ = internal thread_local constant [4 x i32] [i32 1, i32 2, i32 3, i32 4] std::initializer_list<int> thread_local x = { 1, 2, 3, 4 }; } // CHECK: @globalInitList2 = global %{{[^ ]+}} zeroinitializer -// CHECK: @_ZGR15globalInitList2_ = private global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer +// CHECK: @_ZGR15globalInitList2_ = internal global [2 x %[[WITHARG:[^ ]*]]] zeroinitializer // CHECK: @_ZN15partly_constant1kE = global i32 0, align 4 // CHECK: @_ZN15partly_constant2ilE = global {{.*}} null, align 8 -// CHECK: @[[PARTLY_CONSTANT_OUTER:_ZGRN15partly_constant2ilE.*]] = private global {{.*}} zeroinitializer, align 8 -// CHECK: @[[PARTLY_CONSTANT_INNER:_ZGRN15partly_constant2ilE.*]] = private global [3 x {{.*}}] zeroinitializer, align 8 -// CHECK: @[[PARTLY_CONSTANT_FIRST:_ZGRN15partly_constant2ilE.*]] = private constant [3 x i32] [i32 1, i32 2, i32 3], align 4 -// CHECK: @[[PARTLY_CONSTANT_SECOND:_ZGRN15partly_constant2ilE.*]] = private global [2 x i32] zeroinitializer, align 4 -// CHECK: @[[PARTLY_CONSTANT_THIRD:_ZGRN15partly_constant2ilE.*]] = private constant [4 x i32] [i32 5, i32 6, i32 7, i32 8], align 4 +// CHECK: @[[PARTLY_CONSTANT_OUTER:_ZGRN15partly_constant2ilE.*]] = internal global {{.*}} zeroinitializer, align 8 +// CHECK: @[[PARTLY_CONSTANT_INNER:_ZGRN15partly_constant2ilE.*]] = internal global [3 x {{.*}}] zeroinitializer, align 8 +// CHECK: @[[PARTLY_CONSTANT_FIRST:_ZGRN15partly_constant2ilE.*]] = internal constant [3 x i32] [i32 1, i32 2, i32 3], align 4 +// CHECK: @[[PARTLY_CONSTANT_SECOND:_ZGRN15partly_constant2ilE.*]] = internal global [2 x i32] zeroinitializer, align 4 +// CHECK: @[[PARTLY_CONSTANT_THIRD:_ZGRN15partly_constant2ilE.*]] = internal constant [4 x i32] [i32 5, i32 6, i32 7, i32 8], align 4 + +// CHECK: @[[REFTMP1:.*]] = private constant [2 x i32] [i32 42, i32 43], align 4 +// CHECK: @[[REFTMP2:.*]] = private constant [3 x %{{.*}}] [%{{.*}} { i32 1 }, %{{.*}} { i32 2 }, %{{.*}} { i32 3 }], align 4 // CHECK: appending global // thread_local initializer: // CHECK-LABEL: define internal void -// CHECK: store i32* getelementptr inbounds ([4 x i32]* @_ZGRN25thread_local_global_array1xE_, i64 0, i64 0), -// CHECK: i32** getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 0), align 8 -// CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 1), align 8 +// CHECK: store i32* getelementptr inbounds ([4 x i32], [4 x i32]* @_ZGRN25thread_local_global_array1xE_, i64 0, i64 0), +// CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 0), align 8 +// CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}, {{.*}}* @_ZN25thread_local_global_array1xE, i32 0, i32 1), align 8 // CHECK-LABEL: define internal void -// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 0 -// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 1 +// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 0 +// CHECK: call void @_ZN8witharg1C1ERK10destroyme1(%[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i{{32|64}} 0, i{{32|64}} 1 // CHECK: __cxa_atexit -// CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i64 0, i64 0), -// CHECK: %[[WITHARG]]** getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 0), align 8 -// CHECK: store i64 2, i64* getelementptr inbounds (%{{.*}}* @globalInitList2, i32 0, i32 1), align 8 +// CHECK: store %[[WITHARG]]* getelementptr inbounds ([2 x %[[WITHARG]]], [2 x %[[WITHARG]]]* @_ZGR15globalInitList2_, i64 0, i64 0), +// CHECK: %[[WITHARG]]** getelementptr inbounds (%{{.*}}, %{{.*}}* @globalInitList2, i32 0, i32 0), align 8 +// CHECK: store i64 2, i64* getelementptr inbounds (%{{.*}}, %{{.*}}* @globalInitList2, i32 0, i32 1), align 8 // CHECK: call void @_ZN10destroyme1D1Ev // CHECK: call void @_ZN10destroyme1D1Ev std::initializer_list<witharg1> globalInitList2 = { @@ -99,7 +102,7 @@ void fn1(int i) { // CHECK-LABEL: define void @_Z3fn1i // temporary array // CHECK: [[array:%[^ ]+]] = alloca [3 x i32] - // CHECK: getelementptr inbounds [3 x i32]* [[array]], i{{32|64}} 0 + // CHECK: getelementptr inbounds [3 x i32], [3 x i32]* [[array]], i{{32|64}} 0 // CHECK-NEXT: store i32 1, i32* // CHECK-NEXT: getelementptr // CHECK-NEXT: store @@ -108,7 +111,7 @@ void fn1(int i) { // CHECK-NEXT: store // init the list // CHECK-NEXT: getelementptr - // CHECK-NEXT: getelementptr inbounds [3 x i32]* + // CHECK-NEXT: getelementptr inbounds [3 x i32], [3 x i32]* // CHECK-NEXT: store i32* // CHECK-NEXT: getelementptr // CHECK-NEXT: store i{{32|64}} 3 @@ -215,17 +218,16 @@ void fn9() { struct haslist1 { std::initializer_list<int> il; - haslist1(); + haslist1(int i); }; -// CHECK-LABEL: define void @_ZN8haslist1C2Ev -haslist1::haslist1() +// CHECK-LABEL: define void @_ZN8haslist1C2Ei +haslist1::haslist1(int i) // CHECK: alloca [3 x i32] -// CHECK: store i32 1 +// CHECK: store i32 % // CHECK: store i32 2 // CHECK: store i32 3 -// CHECK: store i{{32|64}} 3 - : il{1, 2, 3} + : il{i, 2, 3} { destroyme2 dm2; } @@ -244,16 +246,15 @@ haslist2::haslist2() // CHECK: call void @_ZN10destroyme1D1Ev } -void fn10() { - // CHECK-LABEL: define void @_Z4fn10v +void fn10(int i) { + // CHECK-LABEL: define void @_Z4fn10i // CHECK: alloca [3 x i32] // CHECK: call noalias i8* @_Znw{{[jm]}} - // CHECK: store i32 1 + // CHECK: store i32 % // CHECK: store i32 2 // CHECK: store i32 3 // CHECK: store i32* - // CHECK: store i{{32|64}} 3 - (void) new std::initializer_list<int> {1, 2, 3}; + (void) new std::initializer_list<int> {i, 2, 3}; } void fn11() { @@ -290,7 +291,7 @@ namespace rdar13325066 { // CHECK: br label // CHECK: br i1 // CHECK: br label - // CHECK call void @_ZN12rdar133250661XD1Ev + // CHECK: call void @_ZN12rdar133250661XD1Ev // CHECK: br label // CHECK: br label // CHECK: call void @_ZN12rdar133250661XD1Ev @@ -365,32 +366,32 @@ namespace partly_constant { std::initializer_list<std::initializer_list<int>> &&il = { { 1, 2, 3 }, { 4, k }, { 5, 6, 7, 8 } }; // First init list. // CHECK-NOT: @[[PARTLY_CONSTANT_FIRST]], - // CHECK: store i32* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_FIRST]], i64 0, i64 0), - // CHECK: i32** getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0, i32 0) - // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0, i32 1) + // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_FIRST]], i64 0, i64 0), + // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0, i32 0) + // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0, i32 1) // CHECK-NOT: @[[PARTLY_CONSTANT_FIRST]], // // Second init list array (non-constant). - // CHECK: store i32 4, i32* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 0) - // CHECK: load i32* @_ZN15partly_constant1kE - // CHECK: store i32 {{.*}}, i32* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 1) + // CHECK: store i32 4, i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 0) + // CHECK: load i32, i32* @_ZN15partly_constant1kE + // CHECK: store i32 {{.*}}, i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 1) // // Second init list. - // CHECK: store i32* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 0), - // CHECK: i32** getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 1, i32 0) - // CHECK: store i64 2, i64* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 1, i32 1) + // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_SECOND]], i64 0, i64 0), + // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 1, i32 0) + // CHECK: store i64 2, i64* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 1, i32 1) // // Third init list. // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]], - // CHECK: store i32* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_THIRD]], i64 0, i64 0), - // CHECK: i32** getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 2, i32 0) - // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}* @_ZGRN15partly_constant2ilE4_, i64 0, i64 2, i32 1) + // CHECK: store i32* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_THIRD]], i64 0, i64 0), + // CHECK: i32** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 2, i32 0) + // CHECK: store i64 4, i64* getelementptr inbounds ({{.*}}, {{.*}}* @_ZGRN15partly_constant2ilE4_, i64 0, i64 2, i32 1) // CHECK-NOT: @[[PARTLY_CONSTANT_THIRD]], // // Outer init list. - // CHECK: store {{.*}}* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0), - // CHECK: {{.*}}** getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_OUTER]], i32 0, i32 0) - // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}* @[[PARTLY_CONSTANT_OUTER]], i32 0, i32 1) + // CHECK: store {{.*}}* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_INNER]], i64 0, i64 0), + // CHECK: {{.*}}** getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_OUTER]], i32 0, i32 0) + // CHECK: store i64 3, i64* getelementptr inbounds ({{.*}}, {{.*}}* @[[PARTLY_CONSTANT_OUTER]], i32 0, i32 1) // // 'il' reference. // CHECK: store {{.*}}* @[[PARTLY_CONSTANT_OUTER]], {{.*}}** @_ZN15partly_constant2ilE, align 8 @@ -462,6 +463,55 @@ namespace PR20445 { template<int x> void f() { new MyClass({42, 43}); } template void f<0>(); // CHECK-LABEL: define {{.*}} @_ZN7PR204451fILi0EEEvv( + // CHECK: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @[[REFTMP1]], i64 0, i64 0) // CHECK: call void @_ZN7PR204456vectorC1ESt16initializer_listIiE( // CHECK: call void @_ZN7PR204457MyClassC1ERKNS_6vectorE( } + +namespace ConstExpr { + class C { + int x; + public: + constexpr C(int x) : x(x) {} + }; + void f(std::initializer_list<C>); + void g() { +// CHECK-LABEL: _ZN9ConstExpr1gEv +// CHECK: store %"class.ConstExpr::C"* getelementptr inbounds ([3 x %"class.ConstExpr::C"], [3 x %"class.ConstExpr::C"]* @[[REFTMP2]], i64 0, i64 0) +// CHECK: call void @_ZN9ConstExpr1fESt16initializer_listINS_1CEE + f({C(1), C(2), C(3)}); + } +} + +namespace B19773010 { + template <class T1, class T2> struct pair { + T1 first; + T2 second; + constexpr pair() : first(), second() {} + constexpr pair(T1 a, T2 b) : first(a), second(b) {} + }; + + enum E { ENUM_CONSTANT }; + struct testcase { + testcase(std::initializer_list<pair<const char *, E>>); + }; + void f1() { + // CHECK-LABEL: @_ZN9B197730102f1Ev + testcase a{{"", ENUM_CONSTANT}}; + // CHECK: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* bitcast ([1 x { i8*, i32 }]* @.ref.tmp{{.*}} to [1 x %"struct.B19773010::pair"]*), i64 0, i64 0), %"struct.B19773010::pair"** %{{.*}}, align 8 + } + void f2() { + // CHECK-LABEL: @_ZN9B197730102f2Ev + // CHECK: store %"struct.B19773010::pair"* getelementptr inbounds ([1 x %"struct.B19773010::pair"], [1 x %"struct.B19773010::pair"]* bitcast ([1 x { i8*, i32 }]* @_ZGRZN9B197730102f2EvE1p_ to [1 x %"struct.B19773010::pair"]*), i64 0, i64 0), %"struct.B19773010::pair"** getelementptr inbounds ([2 x %"class.std::initializer_list.10"], [2 x %"class.std::initializer_list.10"]* @_ZZN9B197730102f2EvE1p, i64 0, i64 1, i32 0), align 8 + static std::initializer_list<pair<const char *, E>> a, p[2] = + {a, {{"", ENUM_CONSTANT}}}; + } + + void PR22940_helper(const pair<void*, int>&) { } + void PR22940() { + // CHECK-LABEL: @_ZN9B197730107PR22940Ev + // CHECK: call {{.*}} @_ZN9B197730104pairIPviEC{{.}}Ev( + // CHECK: call {{.*}} @_ZN9B1977301014PR22940_helperERKNS_4pairIPviEE( + PR22940_helper(pair<void*, int>()); + } +} diff --git a/test/CodeGenCXX/cxx11-exception-spec.cpp b/test/CodeGenCXX/cxx11-exception-spec.cpp index 75f939f..3fb5c15 100644 --- a/test/CodeGenCXX/cxx11-exception-spec.cpp +++ b/test/CodeGenCXX/cxx11-exception-spec.cpp @@ -22,9 +22,9 @@ template<> void S<short>::f() { h(); } // CHECK: define {{.*}} @_ZN1SIA2_sE1fEv() [[NUW]] template<> void S<short[2]>::f() noexcept { h(); } -// CHECK: define {{.*}} @_Z1fIDsEvv() [[NONE]] { +// CHECK: define {{.*}} @_Z1fIDsEvv() [[NONE]] comdat { template void f<char16_t>(); -// CHECK: define {{.*}} @_Z1fIA2_DsEvv() [[NUW]] { +// CHECK: define {{.*}} @_Z1fIA2_DsEvv() [[NUW]] comdat { template void f<char16_t[2]>(); // CHECK: define {{.*}} @_ZN1SIDsE1fEv() @@ -34,9 +34,9 @@ template void S<char16_t>::f(); template void S<char16_t[2]>::f(); void h() { - // CHECK: define {{.*}} @_Z1fIiEvv() [[NUW]] { + // CHECK: define {{.*}} @_Z1fIiEvv() [[NUW]] comdat { f<int>(); - // CHECK: define {{.*}} @_Z1fIA2_iEvv() [[NONE]] { + // CHECK: define {{.*}} @_Z1fIA2_iEvv() [[NONE]] comdat { f<int[2]>(); // CHECK: define {{.*}} @_ZN1SIiE1fEv() [[NUW]] @@ -45,9 +45,9 @@ void h() { // CHECK-NOT: [[NUW]] S<int[2]>::f(); - // CHECK: define {{.*}} @_Z1fIfEvv() [[NUW]] { + // CHECK: define {{.*}} @_Z1fIfEvv() [[NUW]] comdat { void (*f1)() = &f<float>; - // CHECK: define {{.*}} @_Z1fIdEvv() [[NONE]] { + // CHECK: define {{.*}} @_Z1fIdEvv() [[NONE]] comdat { void (*f2)() = &f<double>; // CHECK: define {{.*}} @_ZN1SIfE1fEv() [[NUW]] @@ -56,9 +56,9 @@ void h() { // CHECK-NOT: [[NUW]] void (*f4)() = &S<double>::f; - // CHECK: define {{.*}} @_Z1fIA4_cEvv() [[NUW]] { + // CHECK: define {{.*}} @_Z1fIA4_cEvv() [[NUW]] comdat { (void)&f<char[4]>; - // CHECK: define {{.*}} @_Z1fIcEvv() [[NONE]] { + // CHECK: define {{.*}} @_Z1fIcEvv() [[NONE]] comdat { (void)&f<char>; // CHECK: define {{.*}} @_ZN1SIA4_cE1fEv() [[NUW]] diff --git a/test/CodeGenCXX/cxx11-initializer-aggregate.cpp b/test/CodeGenCXX/cxx11-initializer-aggregate.cpp index 789970b..be4fd73 100644 --- a/test/CodeGenCXX/cxx11-initializer-aggregate.cpp +++ b/test/CodeGenCXX/cxx11-initializer-aggregate.cpp @@ -5,9 +5,9 @@ struct A { int a, b; int f(); }; // CHECK: define {{.*}}@_Z3fn1i( int fn1(int x) { // CHECK: %[[INITLIST:.*]] = alloca %struct.A - // CHECK: %[[A:.*]] = getelementptr inbounds %struct.A* %[[INITLIST]], i32 0, i32 0 + // CHECK: %[[A:.*]] = getelementptr inbounds %struct.A, %struct.A* %[[INITLIST]], i32 0, i32 0 // CHECK: store i32 %{{.*}}, i32* %[[A]], align 4 - // CHECK: %[[B:.*]] = getelementptr inbounds %struct.A* %[[INITLIST]], i32 0, i32 1 + // CHECK: %[[B:.*]] = getelementptr inbounds %struct.A, %struct.A* %[[INITLIST]], i32 0, i32 1 // CHECK: store i32 5, i32* %[[B]], align 4 // CHECK: call i32 @_ZN1A1fEv(%struct.A* %[[INITLIST]]) return A{x, 5}.f(); @@ -18,7 +18,7 @@ struct B { int &r; int &f() { return r; } }; // CHECK: define {{.*}}@_Z3fn2Ri( int &fn2(int &v) { // CHECK: %[[INITLIST2:.*]] = alloca %struct.B, align 8 - // CHECK: %[[R:.*]] = getelementptr inbounds %struct.B* %[[INITLIST2:.*]], i32 0, i32 0 + // CHECK: %[[R:.*]] = getelementptr inbounds %struct.B, %struct.B* %[[INITLIST2:.*]], i32 0, i32 0 // CHECK: store i32* %{{.*}}, i32** %[[R]], align 8 // CHECK: call dereferenceable({{[0-9]+}}) i32* @_ZN1B1fEv(%struct.B* %[[INITLIST2:.*]]) return B{v}.f(); diff --git a/test/CodeGenCXX/cxx11-initializer-array-new.cpp b/test/CodeGenCXX/cxx11-initializer-array-new.cpp index 2393939..2beb44e 100644 --- a/test/CodeGenCXX/cxx11-initializer-array-new.cpp +++ b/test/CodeGenCXX/cxx11-initializer-array-new.cpp @@ -10,7 +10,7 @@ void *p = new S[2][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // CHECK: %[[ALLOC:.*]] = call noalias i8* @_Znam(i64 32) // CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64* // CHECK: store i64 6, i64* %[[COOKIE]] -// CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8* %[[ALLOC]], i64 8 +// CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8, i8* %[[ALLOC]], i64 8 // CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S:.*]]* // // Explicit initializers: @@ -19,22 +19,22 @@ void *p = new S[2][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // // CHECK: %[[S_0:.*]] = bitcast %[[S]]* %[[START_AS_S]] to [3 x %[[S]]]* // -// CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i64 0, i64 0 +// CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i64 0, i64 0 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_0]], i32 1) -// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]]* %[[S_0_0]], i64 1 +// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_0]], i64 1 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_1]], i32 2) -// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]]* %[[S_0_1]], i64 1 +// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_1]], i64 1 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_2]], i32 3) // // { 4, 5, 6 } // -// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i32 1 +// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i32 1 // -// CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i64 0, i64 0 +// CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_1]], i64 0, i64 0 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4) -// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]]* %[[S_1_0]], i64 1 +// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_0]], i64 1 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_1]], i32 5) -// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]]* %[[S_1_1]], i64 1 +// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_1]], i64 1 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6) // // CHECK-NOT: br i1 @@ -46,7 +46,7 @@ void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // CHECK-LABEL: define // -// CHECK: load i32* @n +// CHECK: load i32, i32* @n // CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12) // CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3 // CHECK: call {{.*}} @llvm.uadd.with.overflow.i64(i64 %{{.*}}, i64 8) @@ -54,7 +54,7 @@ void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // // CHECK: %[[COOKIE:.*]] = bitcast i8* %[[ALLOC]] to i64* // CHECK: store i64 %[[ELTS]], i64* %[[COOKIE]] -// CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8* %[[ALLOC]], i64 8 +// CHECK: %[[START_AS_i8:.*]] = getelementptr inbounds i8, i8* %[[ALLOC]], i64 8 // CHECK: %[[START_AS_S:.*]] = bitcast i8* %[[START_AS_i8]] to %[[S]]* // // Explicit initializers: @@ -63,39 +63,39 @@ void *q = new S[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // // CHECK: %[[S_0:.*]] = bitcast %[[S]]* %[[START_AS_S]] to [3 x %[[S]]]* // -// CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i64 0, i64 0 +// CHECK: %[[S_0_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i64 0, i64 0 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_0]], i32 1) -// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]]* %[[S_0_0]], i64 1 +// CHECK: %[[S_0_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_0]], i64 1 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_1]], i32 2) -// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]]* %[[S_0_1]], i64 1 +// CHECK: %[[S_0_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_0_1]], i64 1 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_0_2]], i32 3) // // { 4, 5, 6 } // -// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_0]], i32 1 +// CHECK: %[[S_1:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_0]], i32 1 // -// CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i64 0, i64 0 +// CHECK: %[[S_1_0:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_1]], i64 0, i64 0 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_0]], i32 4) -// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]]* %[[S_1_0]], i64 1 +// CHECK: %[[S_1_1:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_0]], i64 1 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_1]], i32 5) -// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]]* %[[S_1_1]], i64 1 +// CHECK: %[[S_1_2:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_1_1]], i64 1 // CHECK: call void @_ZN1SC1Ei(%[[S]]* %[[S_1_2]], i32 6) // // And the rest. // -// CHECK: %[[S_2:.*]] = getelementptr inbounds [3 x %[[S]]]* %[[S_1]], i32 1 +// CHECK: %[[S_2:.*]] = getelementptr inbounds [3 x %[[S]]], [3 x %[[S]]]* %[[S_1]], i32 1 // CHECK: %[[S_2_AS_S:.*]] = bitcast [3 x %[[S]]]* %[[S_2]] to %[[S]]* // // CHECK: %[[REST:.*]] = sub i64 %[[ELTS]], 6 // CHECK: icmp eq i64 %[[REST]], 0 // CHECK: br i1 // -// CHECK: %[[END:.*]] = getelementptr inbounds %[[S]]* %[[S_2_AS_S]], i64 %[[REST]] +// CHECK: %[[END:.*]] = getelementptr inbounds %[[S]], %[[S]]* %[[S_2_AS_S]], i64 %[[REST]] // CHECK: br label // // CHECK: %[[CUR:.*]] = phi %[[S]]* [ %[[S_2_AS_S]], {{.*}} ], [ %[[NEXT:.*]], {{.*}} ] // CHECK: call void @_ZN1SC1Ev(%[[S]]* %[[CUR]]) -// CHECK: %[[NEXT]] = getelementptr inbounds %[[S]]* %[[CUR]], i64 1 +// CHECK: %[[NEXT]] = getelementptr inbounds %[[S]], %[[S]]* %[[CUR]], i64 1 // CHECK: icmp eq %[[S]]* %[[NEXT]], %[[END]] // CHECK: br i1 // @@ -106,7 +106,7 @@ void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // CHECK-LABEL: define // -// CHECK: load i32* @n +// CHECK: load i32, i32* @n // CHECK: call {{.*}} @llvm.umul.with.overflow.i64(i64 %[[N:.*]], i64 12) // CHECK: %[[ELTS:.*]] = mul i64 %[[N]], 3 // @@ -123,33 +123,33 @@ void *r = new T[n][3]{ { 1, 2, 3 }, { 4, 5, 6 } }; // // CHECK: %[[T_0:.*]] = bitcast %[[T]]* %[[START_AS_T]] to [3 x %[[T]]]* // -// CHECK: %[[T_0_0:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_0]], i64 0, i64 0 -// CHECK: %[[T_0_0_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_0]], i32 0, i32 0 +// CHECK: %[[T_0_0:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_0]], i64 0, i64 0 +// CHECK: %[[T_0_0_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_0]], i32 0, i32 0 // CHECK: store i32 1, i32* %[[T_0_0_0]] -// CHECK: %[[T_0_1:.*]] = getelementptr inbounds %[[T]]* %[[T_0_0]], i64 1 -// CHECK: %[[T_0_1_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_1]], i32 0, i32 0 +// CHECK: %[[T_0_1:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_0]], i64 1 +// CHECK: %[[T_0_1_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_1]], i32 0, i32 0 // CHECK: store i32 2, i32* %[[T_0_1_0]] -// CHECK: %[[T_0_2:.*]] = getelementptr inbounds %[[T]]* %[[T_0_1]], i64 1 -// CHECK: %[[T_0_2_0:.*]] = getelementptr inbounds %[[T]]* %[[T_0_2]], i32 0, i32 0 +// CHECK: %[[T_0_2:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_1]], i64 1 +// CHECK: %[[T_0_2_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_0_2]], i32 0, i32 0 // CHECK: store i32 3, i32* %[[T_0_2_0]] // // { 4, 5, 6 } // -// CHECK: %[[T_1:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_0]], i32 1 +// CHECK: %[[T_1:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_0]], i32 1 // -// CHECK: %[[T_1_0:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_1]], i64 0, i64 0 -// CHECK: %[[T_1_0_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_0]], i32 0, i32 0 +// CHECK: %[[T_1_0:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_1]], i64 0, i64 0 +// CHECK: %[[T_1_0_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_0]], i32 0, i32 0 // CHECK: store i32 4, i32* %[[T_1_0_0]] -// CHECK: %[[T_1_1:.*]] = getelementptr inbounds %[[T]]* %[[T_1_0]], i64 1 -// CHECK: %[[T_1_1_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_1]], i32 0, i32 0 +// CHECK: %[[T_1_1:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_0]], i64 1 +// CHECK: %[[T_1_1_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_1]], i32 0, i32 0 // CHECK: store i32 5, i32* %[[T_1_1_0]] -// CHECK: %[[T_1_2:.*]] = getelementptr inbounds %[[T]]* %[[T_1_1]], i64 1 -// CHECK: %[[T_1_2_0:.*]] = getelementptr inbounds %[[T]]* %[[T_1_2]], i32 0, i32 0 +// CHECK: %[[T_1_2:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_1]], i64 1 +// CHECK: %[[T_1_2_0:.*]] = getelementptr inbounds %[[T]], %[[T]]* %[[T_1_2]], i32 0, i32 0 // CHECK: store i32 6, i32* %[[T_1_2_0]] // // And the rest gets memset to 0. // -// CHECK: %[[T_2:.*]] = getelementptr inbounds [3 x %[[T]]]* %[[T_1]], i32 1 +// CHECK: %[[T_2:.*]] = getelementptr inbounds [3 x %[[T]]], [3 x %[[T]]]* %[[T_1]], i32 1 // CHECK: %[[T_2_AS_T:.*]] = bitcast [3 x %[[T]]]* %[[T_2]] to %[[T]]* // // CHECK: %[[SIZE:.*]] = sub i64 %{{.*}}, 24 diff --git a/test/CodeGenCXX/cxx11-thread-local-reference.cpp b/test/CodeGenCXX/cxx11-thread-local-reference.cpp index 4143164..c3e165a 100644 --- a/test/CodeGenCXX/cxx11-thread-local-reference.cpp +++ b/test/CodeGenCXX/cxx11-thread-local-reference.cpp @@ -19,7 +19,7 @@ int &g() { return r; } // CHECK: define weak_odr hidden i32* @_ZTW1r() { // CHECK: call void @_ZTH1r() -// CHECK: load i32** @r, align 8 +// CHECK: load i32*, i32** @r, align 8 // CHECK: ret i32* %{{.*}} // CHECK-LABEL: define internal void @__tls_init() diff --git a/test/CodeGenCXX/cxx11-thread-local.cpp b/test/CodeGenCXX/cxx11-thread-local.cpp index a6f0106..9b16319 100644 --- a/test/CodeGenCXX/cxx11-thread-local.cpp +++ b/test/CodeGenCXX/cxx11-thread-local.cpp @@ -57,7 +57,7 @@ int e = V<int>::m; // CHECK-LABEL: define i32 @_Z1fv() int f() { - // CHECK: %[[GUARD:.*]] = load i8* @_ZGVZ1fvE1n, align 1 + // CHECK: %[[GUARD:.*]] = load i8, i8* @_ZGVZ1fvE1n, align 1 // CHECK: %[[NEED_INIT:.*]] = icmp eq i8 %[[GUARD]], 0 // CHECK: br i1 %[[NEED_INIT]] @@ -67,13 +67,13 @@ int f() { // CHECK: br label static thread_local int n = g(); - // CHECK: load i32* @_ZZ1fvE1n, align 4 + // CHECK: load i32, i32* @_ZZ1fvE1n, align 4 return n; } // CHECK: define {{.*}} @[[C_INIT:.*]]() // CHECK: call i32* @_ZTW1b() -// CHECK-NEXT: load i32* %{{.*}}, align 4 +// CHECK-NEXT: load i32, i32* %{{.*}}, align 4 // CHECK-NEXT: store i32 %{{.*}}, i32* @c, align 4 // CHECK-LABEL: define weak_odr hidden i32* @_ZTW1b() @@ -94,7 +94,7 @@ int f() { // CHECK: define {{.*}} @[[E_INIT:.*]]() // CHECK: call i32* @_ZTWN1VIiE1mE() -// CHECK-NEXT: load i32* %{{.*}}, align 4 +// CHECK-NEXT: load i32, i32* %{{.*}}, align 4 // CHECK-NEXT: store i32 %{{.*}}, i32* @e, align 4 // CHECK-LABEL: define weak_odr hidden i32* @_ZTWN1VIiE1mE() @@ -107,19 +107,19 @@ struct T { ~T(); }; // CHECK-LABEL: define void @_Z8tls_dtorv() void tls_dtor() { - // CHECK: load i8* @_ZGVZ8tls_dtorvE1s + // CHECK: load i8, i8* @_ZGVZ8tls_dtorvE1s // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZZ8tls_dtorvE1s) // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZZ8tls_dtorvE1s{{.*}} @__dso_handle // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1s static thread_local S s; - // CHECK: load i8* @_ZGVZ8tls_dtorvE1t + // CHECK: load i8, i8* @_ZGVZ8tls_dtorvE1t // CHECK-NOT: _ZN1T // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1TD1Ev {{.*}}@_ZZ8tls_dtorvE1t{{.*}} @__dso_handle // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1t static thread_local T t; - // CHECK: load i8* @_ZGVZ8tls_dtorvE1u + // CHECK: load i8, i8* @_ZGVZ8tls_dtorvE1u // CHECK: call void @_ZN1SC1Ev(%struct.S* @_ZGRZ8tls_dtorvE1u_) // CHECK: call i32 @__cxa_thread_atexit({{.*}}@_ZN1SD1Ev {{.*}} @_ZGRZ8tls_dtorvE1u_{{.*}} @__dso_handle // CHECK: store i8 1, i8* @_ZGVZ8tls_dtorvE1u @@ -154,7 +154,7 @@ void set_anon_i() { // CHECK-LABEL: define internal i32* @_ZTWN12_GLOBAL__N_16anon_iE() // CHECK: define {{.*}} @[[V_M_INIT:.*]]() -// CHECK: load i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*) +// CHECK: load i8, i8* bitcast (i64* @_ZGVN1VIiE1mE to i8*) // CHECK: %[[V_M_INITIALIZED:.*]] = icmp eq i8 %{{.*}}, 0 // CHECK: br i1 %[[V_M_INITIALIZED]], // need init: @@ -169,7 +169,7 @@ void set_anon_i() { // CHECK: define {{.*}}@__tls_init() -// CHECK: load i8* @__tls_guard +// CHECK: load i8, i8* @__tls_guard // CHECK: %[[NEED_TLS_INIT:.*]] = icmp eq i8 %{{.*}}, 0 // CHECK: store i8 1, i8* @__tls_guard // CHECK: br i1 %[[NEED_TLS_INIT]], diff --git a/test/CodeGenCXX/cxx11-user-defined-literal.cpp b/test/CodeGenCXX/cxx11-user-defined-literal.cpp index 347ffe9..05c04b1 100644 --- a/test/CodeGenCXX/cxx11-user-defined-literal.cpp +++ b/test/CodeGenCXX/cxx11-user-defined-literal.cpp @@ -16,8 +16,8 @@ template<char...Cs> S operator"" _t() { return S(); } // CHECK: @[[s_0xffffeeee:.*]] = {{.*}} constant [11 x i8] c"0xffffeeee\00" void f() { - // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8]* @[[s_foo]], i32 0, i32 0), i64 3) - // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8]* @[[s_bar]], i32 0, i32 0), i64 3) + // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_foo]], i32 0, i32 0), i64 3) + // CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_bar]], i32 0, i32 0), i64 3) // CHECK: call void @_Zli2_yw({{.*}} 97) // CHECK: call void @_Zli2_zy({{.*}} 42) // CHECK: call void @_Zli2_fe({{.*}} x86_fp80 0xK3FFF8000000000000000) @@ -28,9 +28,9 @@ void f() { // CHECK: call void @_ZN1SD1Ev({{.*}}) "foo"_x, "bar"_x, L'a'_y, 42_z, 1.0_f; - // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8]* @[[s_123]], i32 0, i32 0)) - // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8]* @[[s_4_9]], i32 0, i32 0)) - // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([11 x i8]* @[[s_0xffffeeee]], i32 0, i32 0)) + // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_123]], i32 0, i32 0)) + // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @[[s_4_9]], i32 0, i32 0)) + // CHECK: call void @_Zli2_rPKc({{.*}}, i8* getelementptr inbounds ([11 x i8], [11 x i8]* @[[s_0xffffeeee]], i32 0, i32 0)) // CHECK: call void @_ZN1SD1Ev({{.*}}) // CHECK: call void @_ZN1SD1Ev({{.*}}) // CHECK: call void @_ZN1SD1Ev({{.*}}) @@ -59,11 +59,11 @@ void h() { // CHECK: call void @_Z1iIiEDTclclL_Zli2_xPKcmELA4_S0_ELi3EEfp_EET_(i32 42) // CHECK: define {{.*}} @_Z1gIiEDTclclL_Zli2_xPKcmELA4_S0_ELm3EEfp_EET_(i32 -// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8]* @{{.*}}, i32 0, i32 0), i64 3) +// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i32 0, i32 0), i64 3) // CHECK: call void @_ZN1SclEi // CHECK: call void @_ZN1SD1Ev // CHECK: define {{.*}} @_Z1iIiEDTclclL_Zli2_xPKcmELA4_S0_ELi3EEfp_EET_(i32 -// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8]* @{{.*}}, i32 0, i32 0), i64 3) +// CHECK: call void @_Zli2_xPKcm({{.*}}, i8* getelementptr inbounds ([4 x i8], [4 x i8]* @{{.*}}, i32 0, i32 0), i64 3) // CHECK: call void @_ZN1SclEi // CHECK: call void @_ZN1SD1Ev diff --git a/test/CodeGenCXX/cxx11-vtable-key-function.cpp b/test/CodeGenCXX/cxx11-vtable-key-function.cpp index cd2ab59..a4a0002 100644 --- a/test/CodeGenCXX/cxx11-vtable-key-function.cpp +++ b/test/CodeGenCXX/cxx11-vtable-key-function.cpp @@ -10,7 +10,7 @@ struct X { X::~X() = default; // Verify that the vtable is emitted. -// CHECK: @_ZTVN5Test11XE = unnamed_addr constant +// CHECK-DAG: @_ZTVN5Test11XE = unnamed_addr constant } namespace Test2 { @@ -22,7 +22,7 @@ struct X { void X::f() {} // Verify that the vtable is emitted. -// CHECK: @_ZTVN5Test21XE = unnamed_addr constant +// CHECK-DAG: @_ZTVN5Test21XE = unnamed_addr constant } namespace Test3 { @@ -34,5 +34,5 @@ struct X { void X::f() {} // Verify that the vtable is emitted. -// CHECK: @_ZTVN5Test31XE = unnamed_addr constant +// CHECK-DAG: @_ZTVN5Test31XE = unnamed_addr constant } diff --git a/test/CodeGenCXX/cxx1y-generic-lambdas.cpp b/test/CodeGenCXX/cxx1y-generic-lambdas.cpp new file mode 100644 index 0000000..9ab44cd --- /dev/null +++ b/test/CodeGenCXX/cxx1y-generic-lambdas.cpp @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -o - %s -std=c++14 | FileCheck %s + +template<typename> struct custom_copy_ctor { + custom_copy_ctor() = default; + custom_copy_ctor(custom_copy_ctor const &) {} +}; + +// CHECK: define {{.*}} @_ZN16custom_copy_ctorIvEC2ERKS0_( +void pr22354() { + custom_copy_ctor<void> cc; + [cc](auto){}(1); +} + diff --git a/test/CodeGenCXX/cxx1y-init-captures.cpp b/test/CodeGenCXX/cxx1y-init-captures.cpp index a60269f..dcfe4d4 100644 --- a/test/CodeGenCXX/cxx1y-init-captures.cpp +++ b/test/CodeGenCXX/cxx1y-init-captures.cpp @@ -32,9 +32,10 @@ void g() { // CHECK-LABEL: define internal i32 @"_ZZ1gvENK3$_1clEv"( // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 0 -// CHECK: load i32* +// CHECK: load i32, i32* // CHECK: getelementptr inbounds {{.*}}, i32 0, i32 1 -// CHECK: load i32* +// CHECK: load i32, i32* + // CHECK: add nsw i32 int h(int a) { @@ -44,12 +45,12 @@ int h(int a) { // CHECK: store i32 {{.*}}, i32* %[[A_ADDR]], // // Initialize init-capture 'b(a)' by reference. - // CHECK: getelementptr inbounds {{.*}}* %[[OUTER]], i32 0, i32 0 + // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 0 // CHECK: store i32* %[[A_ADDR]], i32** {{.*}}, // // Initialize init-capture 'c(a)' by copy. - // CHECK: getelementptr inbounds {{.*}}* %[[OUTER]], i32 0, i32 1 - // CHECK: load i32* %[[A_ADDR]], + // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 1 + // CHECK: load i32, i32* %[[A_ADDR]], // CHECK: store i32 // // CHECK: call i32 @"_ZZ1hiENK3$_2clEv"({{.*}}* %[[OUTER]]) @@ -60,33 +61,36 @@ int h(int a) { // CHECK: store {{.*}}, {{.*}}** %[[OUTER_ADDR]], // // Capture outer 'c' by reference. - // CHECK: %[[OUTER:.*]] = load {{.*}}** %[[OUTER_ADDR]] - // CHECK: getelementptr inbounds {{.*}}* %[[INNER]], i32 0, i32 0 - // CHECK-NEXT: getelementptr inbounds {{.*}}* %[[OUTER]], i32 0, i32 1 + // CHECK: %[[OUTER:.*]] = load {{.*}}*, {{.*}}** %[[OUTER_ADDR]] + // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 0 + // CHECK-NEXT: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 1 // CHECK-NEXT: store i32* % // // Capture outer 'b' by copy. - // CHECK: getelementptr inbounds {{.*}}* %[[INNER]], i32 0, i32 1 - // CHECK-NEXT: getelementptr inbounds {{.*}}* %[[OUTER]], i32 0, i32 0 - // CHECK-NEXT: load i32** % - // CHECK-NEXT: load i32* % + // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 1 + // CHECK-NEXT: getelementptr inbounds {{.*}}, {{.*}}* %[[OUTER]], i32 0, i32 0 + // CHECK-NEXT: load i32*, i32** % + // CHECK-NEXT: load i32, i32* % // CHECK-NEXT: store i32 // // CHECK: call i32 @"_ZZZ1hiENK3$_2clEvENKUlvE_clEv"({{.*}}* %[[INNER]]) return [=, &c] { + // CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D2Ev"( + // CHECK: call void @_ZN1SD1Ev( + // CHECK-LABEL: define internal i32 @"_ZZZ1hiENK3$_2clEvENKUlvE_clEv"( // CHECK: %[[INNER_ADDR:.*]] = alloca // CHECK: store {{.*}}, {{.*}}** %[[INNER_ADDR]], - // CHECK: %[[INNER:.*]] = load {{.*}}** %[[INNER_ADDR]] + // CHECK: %[[INNER:.*]] = load {{.*}}*, {{.*}}** %[[INNER_ADDR]] // // Load capture of 'b' - // CHECK: getelementptr inbounds {{.*}}* %[[INNER]], i32 0, i32 1 - // CHECK: load i32* % + // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 1 + // CHECK: load i32, i32* % // // Load capture of 'c' - // CHECK: getelementptr inbounds {{.*}}* %[[INNER]], i32 0, i32 0 - // CHECK: load i32** % - // CHECK: load i32* % + // CHECK: getelementptr inbounds {{.*}}, {{.*}}* %[[INNER]], i32 0, i32 0 + // CHECK: load i32*, i32** % + // CHECK: load i32, i32* % // // CHECK: add nsw i32 return b + c; @@ -97,6 +101,3 @@ int h(int a) { // Ensure we can emit code for init-captures in global lambdas too. auto global_lambda = [a = 0] () mutable { return ++a; }; int get_incremented() { return global_lambda(); } - -// CHECK-LABEL: define internal void @"_ZZ1fvEN3$_0D2Ev"( -// CHECK: call void @_ZN1SD1Ev( diff --git a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp index 098a4b9..50629b5 100644 --- a/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp +++ b/test/CodeGenCXX/cxx1y-initializer-aggregate.cpp @@ -51,12 +51,12 @@ C n{}; // CHECK: store i32 0, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0) // CHECK: store i8* {{.*}} @[[STR_A]]{{.*}}, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1) -// CHECK: load i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0) -// CHECK: load i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1) -// CHECK: getelementptr inbounds i8* %{{.*}}, {{.*}} %{{.*}} +// CHECK: load i32, i32* getelementptr inbounds ({{.*}} @a, i32 0, i32 0) +// CHECK: load i8*, i8** getelementptr inbounds ({{.*}} @a, i32 0, i32 1) +// CHECK: getelementptr inbounds i8, i8* %{{.*}}, {{.*}} %{{.*}} // CHECK: store i8 %{{.*}}, i8* getelementptr inbounds ({{.*}} @a, i32 0, i32 2) // CHECK: call i32 @_ZN1A1fEv({{.*}} @a) -// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}* @a, i32 0, i32 3) +// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}, {{.*}}* @a, i32 0, i32 3) // CHECK: store double 1.000000e+00, double* getelementptr inbounds ({{.*}} @a, i32 0, i32 4, i32 0) // No dynamic initialization of 'b': @@ -70,7 +70,7 @@ C n{}; // CHECK-NOT: load // CHECK: store i8 65, i8* getelementptr inbounds ({{.*}} @c, i32 0, i32 2) // CHECK: call i32 @_Z1fv() -// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}* @c, i32 0, i32 3) +// CHECK: store i32 %{{.*}}, i32* getelementptr inbounds ({{.*}}, {{.*}}* @c, i32 0, i32 3) // CHECK-NOT: C1Ev // CHECK: store i8 3, i8* {{.*}} @c, i32 0, i32 4) diff --git a/test/CodeGenCXX/cxx1y-sized-deallocation.cpp b/test/CodeGenCXX/cxx1y-sized-deallocation.cpp index 7fd3ece..78cc713 100644 --- a/test/CodeGenCXX/cxx1y-sized-deallocation.cpp +++ b/test/CodeGenCXX/cxx1y-sized-deallocation.cpp @@ -1,6 +1,12 @@ -// RUN: %clang_cc1 -std=c++1y %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s +// Check that delete exprs call the sized deallocation function if +// -fsized-deallocation is passed in both C++11 and C++14. // RUN: %clang_cc1 -std=c++11 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s +// RUN: %clang_cc1 -std=c++14 -fsized-deallocation %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s + +// Check that we don't used sized deallocation without -fsized-deallocation and +// C++14. // RUN: %clang_cc1 -std=c++11 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED +// RUN: %clang_cc1 -std=c++14 %s -emit-llvm -triple x86_64-linux-gnu -o - | FileCheck %s --check-prefix=CHECK-UNSIZED // CHECK-UNSIZED-NOT: _ZdlPvm // CHECK-UNSIZED-NOT: _ZdaPvm @@ -50,8 +56,7 @@ D::D() {} // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4) // CHECK: call void @_ZdaPv(i8* %{{[^ ]*}}) -// CHECK-LABEL: define linkonce void @_ZdlPvm(i8* -// CHECK: call void @_ZdlPv(i8* %0) +// CHECK-LABEL: declare void @_ZdlPvm(i8* // CHECK-LABEL: define weak_odr void @_Z3delI1BEvv() // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 4) @@ -71,8 +76,7 @@ D::D() {} // CHECK: add i64 %{{[^ ]*}}, 8 // CHECK: call void @_ZdaPvm(i8* %{{[^ ]*}}, i64 %{{[^ ]*}}) -// CHECK-LABEL: define linkonce void @_ZdaPvm(i8* -// CHECK: call void @_ZdaPv(i8* %0) +// CHECK-LABEL: declare void @_ZdaPvm(i8* // CHECK-LABEL: define weak_odr void @_Z3delI1DEvv() // CHECK: call void @_ZdlPvm(i8* %{{[^ ]*}}, i64 8) diff --git a/test/CodeGenCXX/debug-info-access.cpp b/test/CodeGenCXX/debug-info-access.cpp index d6dfd87..86237b3 100644 --- a/test/CodeGenCXX/debug-info-access.cpp +++ b/test/CodeGenCXX/debug-info-access.cpp @@ -1,37 +1,39 @@ // RUN: %clang_cc1 -emit-llvm -g -triple %itanium_abi_triple %s -o - | FileCheck %s // Test the various accessibility flags in the debug info. struct A { - // CHECK-DAG: [ DW_TAG_subprogram ] [line [[@LINE+1]]] [pub_default] + // CHECK-DAG: !DISubprogram(name: "pub_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped, void pub_default(); - // CHECK-DAG: [ DW_TAG_member ] [pub_default_static] [line [[@LINE+1]]{{.*}}offset 0] [static] + // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "pub_default_static",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagStaticMember) static int pub_default_static; }; -// CHECK: [ DW_TAG_inheritance ] {{.*}} [public] [from {{.*}}A] +// CHECK: !DIDerivedType(tag: DW_TAG_inheritance,{{.*}} baseType: !"_ZTS1A",{{.*}} flags: DIFlagPublic) class B : public A { public: - // CHECK-DAG: [ DW_TAG_subprogram ] [line [[@LINE+1]]] [public] [pub] + // CHECK-DAG: !DISubprogram(name: "pub",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic | DIFlagPrototyped, void pub(); - // CHECK-DAG: [ DW_TAG_member ] [public_static] [line [[@LINE+1]]{{.*}} [public] [static] + // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "public_static",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPublic | DIFlagStaticMember) static int public_static; protected: - // CHECK: [ DW_TAG_subprogram ] [line [[@LINE+1]]] [protected] [prot] + // CHECK: !DISubprogram(name: "prot",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagProtected | DIFlagPrototyped, void prot(); private: - // CHECK: [ DW_TAG_subprogram ] [line [[@LINE+1]]] [priv_default] + // CHECK: !DISubprogram(name: "priv_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped, void priv_default(); }; union U { - // CHECK-DAG: [ DW_TAG_subprogram ] [line [[@LINE+1]]] [union_pub_default] + // CHECK-DAG: !DISubprogram(name: "union_pub_default",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrototyped, void union_pub_default(); private: - // CHECK-DAG: [ DW_TAG_member ] [union_priv] [line [[@LINE+1]]{{.*}} [private] + // CHECK-DAG: !DIDerivedType(tag: DW_TAG_member, name: "union_priv",{{.*}} line: [[@LINE+1]],{{.*}} flags: DIFlagPrivate) int union_priv; }; -// CHECK: {{.*}}\00256\00{{.*}} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [def] [free] +// CHECK: !DISubprogram(name: "free", +// CHECK-SAME: isDefinition: true +// CHECK-SAME: flags: DIFlagPrototyped, void free() {} A a; diff --git a/test/CodeGenCXX/debug-info-alias.cpp b/test/CodeGenCXX/debug-info-alias.cpp index dd4b00b..9047643 100644 --- a/test/CodeGenCXX/debug-info-alias.cpp +++ b/test/CodeGenCXX/debug-info-alias.cpp @@ -13,25 +13,27 @@ bar = foo<T*>; } -// CHECK: [[BINT:![0-9]*]], {{[^,]+, [^,]+}}} ; [ DW_TAG_variable ] [bi] -// CHECK: [[BINT]] = {{.*}} ; [ DW_TAG_typedef ] [bar<int>] [line 42 +// CHECK: !DIGlobalVariable(name: "bi",{{.*}} type: [[BINT:![0-9]+]] +// CHECK: [[BINT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<int>" +// CHECK-SAME: line: 42, x::bar<int> bi; -// CHECK: [[BFLOAT:![0-9]*]], {{[^,]+, [^,]+}}} ; [ DW_TAG_variable ] [bf] -// CHECK: [[BFLOAT]] = {{.*}} ; [ DW_TAG_typedef ] [bar<float>] [line 42 +// CHECK: !DIGlobalVariable(name: "bf",{{.*}} type: [[BFLOAT:![0-9]+]] +// CHECK: [[BFLOAT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "bar<float>" x::bar<float> bf; using -// CHECK: [[NARF:![0-9]*]], {{[^,]+, [^,]+}}} ; [ DW_TAG_variable ] [n] +// CHECK: !DIGlobalVariable(name: "n",{{.*}} type: [[NARF:![0-9]+]] # 142 -narf // CHECK: [[NARF]] = {{.*}} ; [ DW_TAG_typedef ] [narf] [line 142 +narf // CHECK: [[NARF]] = !DIDerivedType(tag: DW_TAG_typedef, name: "narf" +// CHECK-SAME: line: 142 = int; narf n; template <typename T> using tv = void; -// CHECK: null} ; [ DW_TAG_typedef ] [tv<int>] {{.*}} [from ] +// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "tv<int>" tv<int> *tvp; using v = void; -// CHECK: null} ; [ DW_TAG_typedef ] [v] {{.*}} [from ] +// CHECK: !DIDerivedType(tag: DW_TAG_typedef, name: "v" v *vp; diff --git a/test/CodeGenCXX/debug-info-anon-union-vars.cpp b/test/CodeGenCXX/debug-info-anon-union-vars.cpp index 396b7e9..ad3b6d4 100644 --- a/test/CodeGenCXX/debug-info-anon-union-vars.cpp +++ b/test/CodeGenCXX/debug-info-anon-union-vars.cpp @@ -21,8 +21,26 @@ int test_it() { return (c == 1); } -// CHECK: [[FILE:.*]] = {{.*}}[ DW_TAG_file_type ] [{{.*}}debug-info-anon-union-vars.cpp] -// CHECK: [[FILE]]{{.*}}[ DW_TAG_variable ] [c] [line 6] [local] [def] -// CHECK: [[FILE]]{{.*}}[ DW_TAG_variable ] [d] [line 6] [local] [def] -// CHECK: [[FILE]]{{.*}}[ DW_TAG_variable ] [a] [line 6] [local] [def] -// CHECK: [[FILE]]{{.*}}[ DW_TAG_variable ] [b] [line 6] [local] [def] +void foo() { + union { + int i; + char c; + }; + i = 8; +} + +// CHECK: [[FILE:.*]] = !DIFile(filename: "{{.*}}debug-info-anon-union-vars.cpp", +// CHECK: !DIGlobalVariable(name: "c",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true +// CHECK: !DIGlobalVariable(name: "d",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true +// CHECK: !DIGlobalVariable(name: "a",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true +// CHECK: !DIGlobalVariable(name: "b",{{.*}} file: [[FILE]], line: 6,{{.*}} isLocal: true, isDefinition: true +// CHECK: !DILocalVariable(tag: DW_TAG_auto_variable, name: "i", {{.*}}, flags: DIFlagArtificial +// CHECK: !DILocalVariable(tag: DW_TAG_auto_variable, name: "c", {{.*}}, flags: DIFlagArtificial +// CHECK: !DILocalVariable( +// CHECK-NOT: name: +// CHECK: type: ![[UNION:[0-9]+]] +// CHECK: ![[UNION]] = !DICompositeType(tag: DW_TAG_union_type, +// CHECK-NOT: name: +// CHECK: elements +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i", scope: ![[UNION]], +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "c", scope: ![[UNION]], diff --git a/test/CodeGenCXX/debug-info-artificial-arg.cpp b/test/CodeGenCXX/debug-info-artificial-arg.cpp index 9eb3c6f..dc3ac8a 100644 --- a/test/CodeGenCXX/debug-info-artificial-arg.cpp +++ b/test/CodeGenCXX/debug-info-artificial-arg.cpp @@ -22,8 +22,12 @@ int main(int argc, char **argv) { A reallyA (500); } -// CHECK: ![[CLASSTYPE:.*]] = {{.*}}, !"_ZTS1A"} ; [ DW_TAG_class_type ] [A] -// CHECK: ![[ARTARG:.*]] = {{.*}} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS1A] -// CHECK: !"_ZTS1A", {{.*}} ; [ DW_TAG_subprogram ] [line 12] [public] [A] -// CHECK: [[FUNCTYPE:![0-9]*]], null, null, null} ; [ DW_TAG_subroutine_type ] +// CHECK: ![[CLASSTYPE:.*]] = !DICompositeType(tag: DW_TAG_class_type, name: "A", +// CHECK-SAME: identifier: "_ZTS1A" +// CHECK: ![[ARTARG:.*]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1A", +// CHECK-SAME: DIFlagArtificial +// CHECK: !DISubprogram(name: "A", scope: !"_ZTS1A" +// CHECK-SAME: line: 12 +// CHECK-SAME: DIFlagPublic +// CHECK: !DISubroutineType(types: [[FUNCTYPE:![0-9]*]]) // CHECK: [[FUNCTYPE]] = !{null, ![[ARTARG]], !{{.*}}, !{{.*}}} diff --git a/test/CodeGenCXX/debug-info-blocks.cpp b/test/CodeGenCXX/debug-info-blocks.cpp index 5b20db5..7762726 100644 --- a/test/CodeGenCXX/debug-info-blocks.cpp +++ b/test/CodeGenCXX/debug-info-blocks.cpp @@ -10,5 +10,9 @@ void test() { __block A a; } -// CHECK: [ DW_TAG_subprogram ] [line 10] [local] [def] [__Block_byref_object_copy_] -// CHECK: [ DW_TAG_subprogram ] [line 10] [local] [def] [__Block_byref_object_dispose_] +// CHECK: !DISubprogram(name: "__Block_byref_object_copy_", +// CHECK-SAME: line: 10, +// CHECK-SAME: isLocal: true, isDefinition: true +// CHECK: !DISubprogram(name: "__Block_byref_object_dispose_", +// CHECK-SAME: line: 10, +// CHECK-SAME: isLocal: true, isDefinition: true diff --git a/test/CodeGenCXX/debug-info-char16.cpp b/test/CodeGenCXX/debug-info-char16.cpp index e6e2f15..912da6f 100644 --- a/test/CodeGenCXX/debug-info-char16.cpp +++ b/test/CodeGenCXX/debug-info-char16.cpp @@ -3,4 +3,5 @@ // 16 is DW_ATE_UTF (0x10) encoding attribute. char16_t char_a = u'h'; -// CHECK: !{{.*}} = {{.*}} ; [ DW_TAG_base_type ] [char16_t] +// CHECK: !{{.*}} = !DIBasicType(name: "char16_t" +// CHECK-SAME: encoding: DW_ATE_UTF) diff --git a/test/CodeGenCXX/debug-info-class-nolimit.cpp b/test/CodeGenCXX/debug-info-class-nolimit.cpp index 7a6ee4d..11d1792 100644 --- a/test/CodeGenCXX/debug-info-class-nolimit.cpp +++ b/test/CodeGenCXX/debug-info-class-nolimit.cpp @@ -6,7 +6,9 @@ namespace rdar14101097_1 { // see also PR16214 // Check that we emit debug info for the definition of a struct if the // definition is available, even if it's used via a pointer wrapped in a // typedef. -// CHECK: [ DW_TAG_structure_type ] [foo] {{.*}}[def] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} struct foo { }; @@ -21,7 +23,9 @@ namespace rdar14101097_2 { // As above, except trickier because we first encounter only a declaration of // the type and no debug-info related use after we see the definition of the // type. -// CHECK: [ DW_TAG_structure_type ] [foo] {{.*}}[def] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} struct foo; void bar() { foo *f; diff --git a/test/CodeGenCXX/debug-info-class.cpp b/test/CodeGenCXX/debug-info-class.cpp index 55d5653..a63efe5 100644 --- a/test/CodeGenCXX/debug-info-class.cpp +++ b/test/CodeGenCXX/debug-info-class.cpp @@ -90,33 +90,63 @@ int main(int argc, char **argv) { // CHECK: invoke {{.+}} @_ZN1BD1Ev(%class.B* %b) // CHECK-NEXT: unwind label %{{.+}}, !dbg ![[EXCEPTLOC:.*]] // CHECK: store i32 0, i32* %{{.+}}, !dbg ![[RETLOC:.*]] -// CHECK: DW_TAG_structure_type ] [foo] -// CHECK: DW_TAG_class_type ] [bar] -// CHECK: DW_TAG_union_type ] [baz] -// CHECK: DW_TAG_class_type ] [B] {{.*}} [def] -// CHECK: !"0xd\00_vptr$B\00{{.*}}\0064", {{.*}} ; [ DW_TAG_member ] - -// CHECK: [[C:![0-9]*]] = {{.*}} [[C_MEM:![0-9]*]], !"_ZTS1C", null, !"_ZTS1C"} ; [ DW_TAG_structure_type ] [C] {{.*}} [def] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo" +// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "bar" +// CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "baz" +// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "_vptr$B", +// CHECK-SAME: DIFlagArtificial + +// CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int" + +// CHECK: [[C:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "C", +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: elements: [[C_MEM:![0-9]*]] +// CHECK-SAME: vtableHolder: !"_ZTS1C" +// CHECK-SAME: identifier: "_ZTS1C" // CHECK: [[C_MEM]] = !{[[C_VPTR:![0-9]*]], [[C_S:![0-9]*]], [[C_DTOR:![0-9]*]]} -// CHECK: [[C_VPTR]] = {{.*}} ; [ DW_TAG_member ] [_vptr$C] {{.*}} [artificial] -// CHECK: [[C_S]] = {{.*}} ; [ DW_TAG_member ] [s] {{.*}} [static] [from int] -// CHECK: [[C_DTOR]] = {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [~C] - -// CHECK: null, null, null, !"_ZTS1D"} ; [ DW_TAG_structure_type ] [D] {{.*}} [decl] -// CHECK: null, null, null, !"_ZTS1E"} ; [ DW_TAG_structure_type ] [E] {{.*}} [decl] -// CHECK: [[F:![0-9]*]] = {{.*}} null, null, null, !"_ZTS1F"} ; [ DW_TAG_structure_type ] [F] {{.*}} [decl] - -// CHECK: null, null, null, !"_ZTS1G"} ; [ DW_TAG_structure_type ] [G] {{.*}} [decl] -// CHECK: [[G_INNER_MEM:![0-9]*]], null, null, !"_ZTSN1G5innerE"} ; [ DW_TAG_structure_type ] [inner] [line 50, {{.*}} [def] +// CHECK: [[C_VPTR]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$C" +// CHECK-SAME: DIFlagArtificial +// CHECK: [[C_S]] = !DIDerivedType(tag: DW_TAG_member, name: "s" +// CHECK-SAME: baseType: ![[INT]] +// CHECK-SAME: DIFlagStaticMember +// CHECK: [[C_DTOR]] = !DISubprogram(name: "~C" + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "D" +// CHECK-SAME: DIFlagFwdDecl +// CHECK-SAME: identifier: "_ZTS1D" +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "E" +// CHECK-SAME: DIFlagFwdDecl +// CHECK-SAME: identifier: "_ZTS1E" +// CHECK: [[F:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "F" +// CHECK-SAME: DIFlagFwdDecl +// CHECK-SAME: identifier: "_ZTS1F" + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "G" +// CHECK-SAME: DIFlagFwdDecl +// CHECK-SAME: identifier: "_ZTS1G" +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "inner" +// CHECK: line: 50 +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: elements: [[G_INNER_MEM:![0-9]*]] +// CHECK-SAME: identifier: "_ZTSN1G5innerE" // CHECK: [[G_INNER_MEM]] = !{[[G_INNER_I:![0-9]*]]} -// CHECK: [[G_INNER_I]] = {{.*}} ; [ DW_TAG_member ] [j] {{.*}} [from int] - -// CHECK: ; [ DW_TAG_structure_type ] [A] -// CHECK: HdrSize -// CHECK: ; [ DW_TAG_structure_type ] [I] {{.*}} [def] +// CHECK: [[G_INNER_I]] = !DIDerivedType(tag: DW_TAG_member, name: "j" +// CHECK-SAME: baseType: ![[INT]] + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "A" +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "HdrSize" +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "I" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} // -// CHECK: !"_ZTS1D", {{.*}}, [[D_FUNC_DECL:![0-9]*]], {{![0-9]*}}} ; [ DW_TAG_subprogram ] {{.*}} [def] [func] -// CHECK: [[D_FUNC_DECL]] = !{!"0x2e\00func\00{{.*}}\000\00{{[0-9]+}}"{{.*}}, !"_ZTS1D", {{.*}}, null} ; [ DW_TAG_subprogram ] {{.*}} [func] - -// CHECK: ![[EXCEPTLOC]] = !MDLocation(line: 84, -// CHECK: ![[RETLOC]] = !MDLocation(line: 83, +// CHECK: !DISubprogram(name: "func",{{.*}} scope: !"_ZTS1D" +// CHECK-SAME: isDefinition: true +// CHECK-SAME: declaration: [[D_FUNC_DECL:![0-9]*]] +// CHECK: [[D_FUNC_DECL]] = !DISubprogram(name: "func",{{.*}} scope: !"_ZTS1D" +// CHECK-SAME: isDefinition: false + +// CHECK: ![[EXCEPTLOC]] = !DILocation(line: 84, +// CHECK: ![[RETLOC]] = !DILocation(line: 83, diff --git a/test/CodeGenCXX/debug-info-cxx1y.cpp b/test/CodeGenCXX/debug-info-cxx1y.cpp index 261f965..026be3d 100644 --- a/test/CodeGenCXX/debug-info-cxx1y.cpp +++ b/test/CodeGenCXX/debug-info-cxx1y.cpp @@ -1,13 +1,20 @@ // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm-only -std=c++14 -emit-llvm -g %s -o - | FileCheck %s // CHECK: [[EMPTY:![0-9]*]] = !{} -// CHECK: \00foo\00{{.*}}, [[EMPTY]], {{.*}}} ; [ DW_TAG_structure_type ] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo", +// CHECK-SAME: elements: [[EMPTY]] // FIXME: The context of this definition should be the CU/file scope, not the class. -// CHECK: !"_ZTS3foo", [[SUBROUTINE_TYPE:![0-9]*]], {{.*}}, [[FUNC_DECL:![0-9]*]], {{![0-9]*}}} ; [ DW_TAG_subprogram ] {{.*}} [def] [func] -// CHECK: [[SUBROUTINE_TYPE]] = {{.*}}, [[TYPE_LIST:![0-9]*]], +// CHECK: !DISubprogram(name: "func", {{.*}} scope: !"_ZTS3foo" +// CHECK-SAME: type: [[SUBROUTINE_TYPE:![0-9]*]] +// CHECK-SAME: isDefinition: true +// CHECK-SAME: declaration: [[FUNC_DECL:![0-9]*]] +// CHECK: [[SUBROUTINE_TYPE]] = !DISubroutineType(types: [[TYPE_LIST:![0-9]*]]) // CHECK: [[TYPE_LIST]] = !{[[INT:![0-9]*]]} -// CHECK: [[INT]] = {{.*}} ; [ DW_TAG_base_type ] [int] -// CHECK: [[FUNC_DECL]] = {{.*}}, !"_ZTS3foo", [[SUBROUTINE_TYPE]], {{.*}}} ; [ DW_TAG_subprogram ] {{.*}} [func] +// CHECK: [[INT]] = !DIBasicType(name: "int" +// CHECK: [[FUNC_DECL]] = !DISubprogram(name: "func", +// CHECK-SAME: scope: !"_ZTS3foo" +// CHECK-SAME: type: [[SUBROUTINE_TYPE]] +// CHECK-SAME: isDefinition: false struct foo { static auto func(); diff --git a/test/CodeGenCXX/debug-info-decl-nested.cpp b/test/CodeGenCXX/debug-info-decl-nested.cpp index 95d32c4..2c35241 100644 --- a/test/CodeGenCXX/debug-info-decl-nested.cpp +++ b/test/CodeGenCXX/debug-info-decl-nested.cpp @@ -17,11 +17,16 @@ class OuterClass public: InnerClass(); // Here createContextChain() generates a limited type for OuterClass. } theInnerClass; -// CHECK0: [[DECL:[0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [OuterClass] +// CHECK0: ![[DECL:[0-9]+]] = !DISubprogram(name: "OuterClass" +// CHECK0-SAME: line: [[@LINE+2]] +// CHECK0-SAME: isDefinition: false OuterClass(const Foo *); // line 10 }; OuterClass::InnerClass OuterClass::theInnerClass; // This toplevel decl causes InnerClass to be generated. -// CHECK0: !"0x2e\00OuterClass\00{{.*}}\00[[@LINE+1]]"{{.*}}, ![[DECL]], {{![0-9]+}}} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [def] [OuterClass] +// CHECK0: !DISubprogram(name: "OuterClass" +// CHECK0-SAME: line: [[@LINE+3]] +// CHECK0-SAME: isDefinition: true +// CHECK0-SAME: declaration: ![[DECL]] OuterClass::OuterClass(const Foo *meta) { } // line 13 @@ -36,11 +41,16 @@ class OuterClass1 public: InnerClass1(); } theInnerClass1; -// CHECK1: [[DECL:[0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] [line [[@LINE+2]]] [Bar] -// CHECK1: !"0x2e\00Bar\00{{.*}}\00[[@LINE+4]]"{{.*}}, ![[DECL]], {{![0-9]+}}} ; [ DW_TAG_subprogram ] [line [[@LINE+4]]] [def] [Bar] +// CHECK1: ![[DECL:[0-9]+]] = !DISubprogram(name: "Bar" +// CHECK1-SAME: line: [[@LINE+2]] +// CHECK1-SAME: isDefinition: false void Bar(const Foo1 *); }; OuterClass1::InnerClass1 OuterClass1::theInnerClass1; +// CHECK1: !DISubprogram(name: "Bar" +// CHECK1-SAME: line: [[@LINE+3]] +// CHECK1-SAME: isDefinition: true +// CHECK1-SAME: declaration: ![[DECL]] void OuterClass1::Bar(const Foo1 *meta) { } @@ -54,9 +64,14 @@ class OuterClass2 public: InnerClass2(); } theInnerClass2; -// CHECK2: [[DECL:[0-9]+]] = {{.*}} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [~OuterClass2] +// CHECK2: ![[DECL:[0-9]+]] = !DISubprogram(name: "~OuterClass2" +// CHECK2-SAME: line: [[@LINE+2]] +// CHECK2-SAME: isDefinition: false ~OuterClass2(); // line 10 }; OuterClass2::InnerClass2 OuterClass2::theInnerClass2; -// CHECK2: !"0x2e\00~OuterClass2\00{{.*}}\00[[@LINE+1]]"{{.*}}, ![[DECL]], {{.*}}} ; [ DW_TAG_subprogram ] [line [[@LINE+1]]] [def] [~OuterClass2] +// CHECK4: !DISubprogram(name: "~OuterClass2" +// CHECK4-SAME: line: [[@LINE+3]] +// CHECK4-SAME: isDefinition: true +// CHECK4-SAME: declaration: ![[DECL]] OuterClass2::~OuterClass2() { } diff --git a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp index 1b9a055..db9d2e9 100644 --- a/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp +++ b/test/CodeGenCXX/debug-info-dup-fwd-decl.cpp @@ -19,6 +19,6 @@ protected: Test t; -// CHECK: ; [ DW_TAG_pointer_type ] -// CHECK: ; [ DW_TAG_structure_type ] [data] -// CHECK-NOT: ; [ DW_TAG_structure_type ] [data] +// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "data" +// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "data" diff --git a/test/CodeGenCXX/debug-info-enum-class.cpp b/test/CodeGenCXX/debug-info-enum-class.cpp index 28ffce0..ded18bf 100644 --- a/test/CodeGenCXX/debug-info-enum-class.cpp +++ b/test/CodeGenCXX/debug-info-enum-class.cpp @@ -9,9 +9,29 @@ B b; C c; D d; -// CHECK: ; [ DW_TAG_enumeration_type ] [A] [line 3, size 32, align 32, offset 0] [def] [from int] -// CHECK: ; [ DW_TAG_enumeration_type ] [B] [line 4, size 64, align 64, offset 0] [def] [from long unsigned int] -// CHECK: ; [ DW_TAG_enumeration_type ] [C] [line 5, size 32, align 32, offset 0] [def] [from ] +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "A" +// CHECK-SAME: line: 3 +// CHECK-SAME: baseType: ![[INT:[0-9]+]] +// CHECK-SAME: size: 32, align: 32 +// CHECK-NOT: offset: +// CHECK-NOT: flags: +// CHECK-SAME: ){{$}} +// CHECK: ![[INT]] = !DIBasicType(name: "int" +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "B" +// CHECK-SAME: line: 4 +// CHECK-SAME: baseType: ![[ULONG:[0-9]+]] +// CHECK-SAME: size: 64, align: 64 +// CHECK-NOT: offset: +// CHECK-NOT: flags: +// CHECK-SAME: ){{$}} +// CHECK: ![[ULONG]] = !DIBasicType(name: "long unsigned int" +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "C" +// CHECK-SAME: line: 5 +// CHECK-NOT: baseType: +// CHECK-SAME: size: 32, align: 32 +// CHECK-NOT: offset: +// CHECK-NOT: flags: +// CHECK-SAME: ){{$}} namespace PR14029 { // Make sure this doesn't crash/assert. @@ -29,10 +49,13 @@ namespace PR14029 { namespace test2 { // FIXME: this should just be a declaration under -fno-standalone-debug -// CHECK: !"0x4\00{{.*}}", {{[^,]*}}, [[TEST2:![0-9]*]], {{.*}}, [[TEST_ENUMS:![0-9]*]], null, null, !"_ZTSN5test21EE"} ; [ DW_TAG_enumeration_type ] [E] -// CHECK: [[TEST2]] = {{.*}} ; [ DW_TAG_namespace ] [test2] +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E" +// CHECK-SAME: scope: [[TEST2:![0-9]+]] +// CHECK-SAME: elements: [[TEST_ENUMS:![0-9]+]] +// CHECK-SAME: identifier: "_ZTSN5test21EE" +// CHECK: [[TEST2]] = !DINamespace(name: "test2" // CHECK: [[TEST_ENUMS]] = !{[[TEST_E:![0-9]*]]} -// CHECK: [[TEST_E]] = !{!"0x28\00e\000"} ; [ DW_TAG_enumerator ] [e :: 0] +// CHECK: [[TEST_E]] = !DIEnumerator(name: "e", value: 0) enum E : int; void func(E *) { } @@ -41,16 +64,22 @@ enum E : int { e }; namespace test3 { // FIXME: this should just be a declaration under -fno-standalone-debug -// CHECK: !"0x4\00{{.*}}", {{[^,]*}}, [[TEST3:![0-9]*]], {{.*}}, [[TEST_ENUMS]], null, null, !"_ZTSN5test31EE"} ; [ DW_TAG_enumeration_type ] [E] -// CHECK: [[TEST3]] = {{.*}} ; [ DW_TAG_namespace ] [test3] +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E" +// CHECK-SAME: scope: [[TEST3:![0-9]+]] +// CHECK-SAME: elements: [[TEST_ENUMS]] +// CHECK-SAME: identifier: "_ZTSN5test31EE" +// CHECK: [[TEST3]] = !DINamespace(name: "test3" enum E : int { e }; void func(E *) { } } namespace test4 { -// CHECK: !"0x4\00{{.*}}", {{[^,]*}}, [[TEST4:![0-9]*]], {{.*}}, [[TEST_ENUMS]], null, null, !"_ZTSN5test41EE"} ; [ DW_TAG_enumeration_type ] [E] -// CHECK: [[TEST4]] = {{.*}} ; [ DW_TAG_namespace ] [test4] +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E" +// CHECK-SAME: scope: [[TEST4:![0-9]+]] +// CHECK-SAME: elements: [[TEST_ENUMS]] +// CHECK-SAME: identifier: "_ZTSN5test41EE" +// CHECK: [[TEST4]] = !DINamespace(name: "test4" enum E : int; void f1(E *) { } @@ -59,11 +88,18 @@ void f2(E) { } } -// CHECK: ; [ DW_TAG_enumeration_type ] [D] [line 6, size 16, align 16, offset 0] [decl] [from ] +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "D" +// CHECK-SAME: line: 6 +// CHECK-SAME: size: 16, align: 16 +// CHECK-NOT: offset: +// CHECK-SAME: flags: DIFlagFwdDecl namespace test5 { -// CHECK: !"0x4\00{{.*}}", {{[^,]*}}, [[TEST5:![0-9]*]], {{.*}}, null, null, null, !"_ZTSN5test51EE"} ; [ DW_TAG_enumeration_type ] [E] -// CHECK: [[TEST5]] = {{.*}} ; [ DW_TAG_namespace ] [test5] +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "E" +// CHECK-SAME: scope: [[TEST5:![0-9]+]] +// CHECK-SAME: flags: DIFlagFwdDecl +// CHECK-SAME: identifier: "_ZTSN5test51EE" +// CHECK: [[TEST5]] = !DINamespace(name: "test5" enum E : int; void f1(E *) { } @@ -73,7 +109,7 @@ namespace test6 { // Ensure typedef'd enums aren't manifest by debug info generation. // This could cause "typedef changes linkage of anonymous type, but linkage was // already computed" errors. -// CHECK-NOT: test7 +// CHECK-NOT: test6 typedef enum { } E; } diff --git a/test/CodeGenCXX/debug-info-enum.cpp b/test/CodeGenCXX/debug-info-enum.cpp index 954f6f6..613ffef 100644 --- a/test/CodeGenCXX/debug-info-enum.cpp +++ b/test/CodeGenCXX/debug-info-enum.cpp @@ -1,13 +1,17 @@ // RUN: %clang_cc1 -triple %itanium_abi_triple -emit-llvm -g %s -o - | FileCheck %s -// CHECK: !"0x11\00{{.*}}", {{[^,]*}}, [[ENUMS:![0-9]*]], {{.*}}} ; [ DW_TAG_compile_unit ] +// CHECK: !DICompileUnit( +// CHECK-SAME: enums: [[ENUMS:![0-9]*]] // CHECK: [[ENUMS]] = !{[[E1:![0-9]*]], [[E2:![0-9]*]], [[E3:![0-9]*]]} namespace test1 { -// CHECK: [[E1]] = !{!"0x4\00{{.*}}", {{[^,]*}}, [[TEST1:![0-9]*]], {{.*}}, [[TEST1_ENUMS:![0-9]*]], null, null, !"_ZTSN5test11eE"} ; [ DW_TAG_enumeration_type ] [e] -// CHECK: [[TEST1]] = {{.*}} ; [ DW_TAG_namespace ] [test1] +// CHECK: [[E1]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "e" +// CHECK-SAME: scope: [[TEST1:![0-9]*]] +// CHECK-SAME: elements: [[TEST1_ENUMS:![0-9]*]] +// CHECK-SAME: identifier: "_ZTSN5test11eE" +// CHECK: [[TEST1]] = !DINamespace(name: "test1" // CHECK: [[TEST1_ENUMS]] = !{[[TEST1_E:![0-9]*]]} -// CHECK: [[TEST1_E]] = !{!"0x28\00E\000"} ; [ DW_TAG_enumerator ] [E :: 0] +// CHECK: [[TEST1_E]] = !DIEnumerator(name: "E", value: 0) enum e { E }; void foo() { int v = E; @@ -16,8 +20,11 @@ void foo() { namespace test2 { // rdar://8195980 -// CHECK: [[E2]] = !{!"0x4\00{{.*}}", {{[^,]*}}, [[TEST2:![0-9]*]], {{.*}}, [[TEST1_ENUMS]], null, null, !"_ZTSN5test21eE"} ; [ DW_TAG_enumeration_type ] [e] -// CHECK: [[TEST2]] = {{.*}} ; [ DW_TAG_namespace ] [test2] +// CHECK: [[E2]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "e" +// CHECK-SAME: scope: [[TEST2:![0-9]+]] +// CHECK-SAME: elements: [[TEST1_ENUMS]] +// CHECK-SAME: identifier: "_ZTSN5test21eE" +// CHECK: [[TEST2]] = !DINamespace(name: "test2" enum e { E }; bool func(int i) { return i == E; @@ -25,10 +32,13 @@ bool func(int i) { } namespace test3 { -// CHECK: [[E3]] = !{!"0x4\00{{.*}}", {{[^,]*}}, [[TEST3:![0-9]*]], {{.*}}, [[TEST3_ENUMS:![0-9]*]], null, null, !"_ZTSN5test31eE"} ; [ DW_TAG_enumeration_type ] [e] -// CHECK: [[TEST3]] = {{.*}} ; [ DW_TAG_namespace ] [test3] +// CHECK: [[E3]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "e" +// CHECK-SAME: scope: [[TEST3:![0-9]*]] +// CHECK-SAME: elements: [[TEST3_ENUMS:![0-9]*]] +// CHECK-SAME: identifier: "_ZTSN5test31eE" +// CHECK: [[TEST3]] = !DINamespace(name: "test3" // CHECK: [[TEST3_ENUMS]] = !{[[TEST3_E:![0-9]*]]} -// CHECK: [[TEST3_E]] = !{!"0x28\00E\00-1"} ; [ DW_TAG_enumerator ] [E :: -1] +// CHECK: [[TEST3_E]] = !DIEnumerator(name: "E", value: -1) enum e { E = -1 }; void func() { e x; diff --git a/test/CodeGenCXX/debug-info-flex-member.cpp b/test/CodeGenCXX/debug-info-flex-member.cpp index bc501c0..afc9d25 100644 --- a/test/CodeGenCXX/debug-info-flex-member.cpp +++ b/test/CodeGenCXX/debug-info-flex-member.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 -emit-llvm -g -triple x86_64-apple-darwin %s -o - | FileCheck %s -// CHECK: !"0x21\000\00-1"} ; [ DW_TAG_subrange_type ] +// CHECK: !DISubrange(count: -1) struct StructName { int member[]; diff --git a/test/CodeGenCXX/debug-info-fn-template.cpp b/test/CodeGenCXX/debug-info-fn-template.cpp index bef9fe14..2aed4be 100644 --- a/test/CodeGenCXX/debug-info-fn-template.cpp +++ b/test/CodeGenCXX/debug-info-fn-template.cpp @@ -10,6 +10,6 @@ T fx(XF<T> xi) { return xi.member; } -//CHECK: XF<int> -//CHECK: DW_TAG_template_type_parameter +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "XF<int>" +// CHECK: !DITemplateTypeParameter(name: "T" template int fx(XF<int>); diff --git a/test/CodeGenCXX/debug-info-function-context.cpp b/test/CodeGenCXX/debug-info-function-context.cpp index a6c5a11..9ae9611 100644 --- a/test/CodeGenCXX/debug-info-function-context.cpp +++ b/test/CodeGenCXX/debug-info-function-context.cpp @@ -25,12 +25,12 @@ int global_namespace_variable = 1; // functions that belong to the namespace have it as a context, and the global // function has the file as a context. -// CHECK: !"0x2e\00member_function\00{{.*}}", !{{[0-9]+}}, !"_ZTS1C"{{.*}} [ DW_TAG_subprogram ] [line 11] [def] [member_function] +// CHECK: ![[FILE:[0-9]+]] = !DIFile(filename: "{{.*}}context.cpp", +// CHECK: !DISubprogram(name: "member_function",{{.*}} scope: !"_ZTS1C",{{.*}} isDefinition: true -// CHECK: !"0x2e\00static_member_function\00{{.*}}", !{{[0-9]+}}, !"_ZTS1C"{{.*}} [ DW_TAG_subprogram ] [line 13] [def] [static_member_function] +// CHECK: !DISubprogram(name: "static_member_function",{{.*}} scope: !"_ZTS1C",{{.*}} isDefinition: true -// CHECK: !"0x2e\00global_function\00{{[^,]+}}", !{{[0-9]+}}, [[FILE:![0-9]*]]{{.*}} [ DW_TAG_subprogram ] [line 17] [def] [global_function] -// CHECK: [[FILE]] = {{.*}} [ DW_TAG_file_type ] +// CHECK: !DISubprogram(name: "global_function",{{.*}} scope: ![[FILE]],{{.*}} isDefinition: true -// CHECK: !"0x2e\00global_namespace_function\00{{[^,]+}}", !{{[0-9]+}}, [[NS:![0-9]*]]{{.*}} [ DW_TAG_subprogram ] [line 20] [def] [global_namespace_function] -// CHECK: [[NS]] = {{.*}} [ DW_TAG_namespace ] [ns] [line 19] +// CHECK: !DISubprogram(name: "global_namespace_function",{{.*}} scope: ![[NS:[0-9]+]],{{.*}} isDefinition: true +// CHECK: ![[NS]] = !DINamespace(name: "ns" diff --git a/test/CodeGenCXX/debug-info-fwd-ref.cpp b/test/CodeGenCXX/debug-info-fwd-ref.cpp index c479506..247d364 100644 --- a/test/CodeGenCXX/debug-info-fwd-ref.cpp +++ b/test/CodeGenCXX/debug-info-fwd-ref.cpp @@ -18,7 +18,8 @@ int main(int argc, char** argv) { // Make sure we have two DW_TAG_structure_types for baz and bar and no forward // references. -// CHECK-NOT: [fwd] -// CHECK: [ DW_TAG_structure_type ] [bar] -// CHECK: [ DW_TAG_structure_type ] [baz] -// CHECK-NOT: [fwd] +// CHECK-NOT: DIFlagFwdDecl +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "bar" +// CHECK-NOT: DIFlagFwdDecl +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "baz" +// CHECK-NOT: DIFlagFwdDecl diff --git a/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp index 28b1fab..a08045d 100644 --- a/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp +++ b/test/CodeGenCXX/debug-info-global-ctor-dtor.cpp @@ -16,12 +16,12 @@ void foo() { static A stat; } -// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 12] [local] [def] [__cxx_global_var_init] -// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 12] [local] [def] [__dtor_glob] -// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 13] [local] [def] [__cxx_global_var_init1] -// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 13] [local] [def] [__cxx_global_array_dtor] -// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 13] [local] [def] [__dtor_array] -// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line 16] [local] [def] [__dtor__ZZ3foovE4stat] -// CHECK-NOKEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def]{{$}} +// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init",{{.*}} line: 12,{{.*}} isLocal: true, isDefinition: true +// CHECK-NOKEXT: !DISubprogram(name: "__dtor_glob",{{.*}} line: 12,{{.*}} isLocal: true, isDefinition: true +// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_var_init.1",{{.*}} line: 13,{{.*}} isLocal: true, isDefinition: true +// CHECK-NOKEXT: !DISubprogram(name: "__cxx_global_array_dtor",{{.*}} line: 13,{{.*}} isLocal: true, isDefinition: true +// CHECK-NOKEXT: !DISubprogram(name: "__dtor_array",{{.*}} line: 13,{{.*}} isLocal: true, isDefinition: true +// CHECK-NOKEXT: !DISubprogram(name: "__dtor__ZZ3foovE4stat",{{.*}} line: 16,{{.*}} isLocal: true, isDefinition: true +// CHECK-NOKEXT: !DISubprogram({{.*}} isLocal: true, isDefinition: true -// CHECK-KEXT: [ DW_TAG_subprogram ] [line {{.*}}] [local] [def]{{$}} +// CHECK-KEXT: !DISubprogram({{.*}} isLocal: true, isDefinition: true diff --git a/test/CodeGenCXX/debug-info-global.cpp b/test/CodeGenCXX/debug-info-global.cpp index 5fc61c7..8292361 100644 --- a/test/CodeGenCXX/debug-info-global.cpp +++ b/test/CodeGenCXX/debug-info-global.cpp @@ -10,10 +10,12 @@ int f1() { return ns::cnst + ns::cnst; } -// CHECK: !"0x11\00{{.*}}"{{.*}}, [[GLOBALS:![0-9]*]], {{![0-9]*}}} ; [ DW_TAG_compile_unit ] +// CHECK: !DICompileUnit( +// CHECK-SAME: globals: [[GLOBALS:![0-9]*]] // CHECK: [[GLOBALS]] = !{[[CNST:![0-9]*]]} -// CHECK: [[CNST]] = !{!"0x34\00cnst\00{{.*}}", [[NS:![0-9]*]], {{[^,]+, [^,]+, [^,]+, [^,]+}}} ; [ DW_TAG_variable ] [cnst] -// CHECK: [[NS]] = {{.*}}; [ DW_TAG_namespace ] [ns] +// CHECK: [[CNST]] = !DIGlobalVariable(name: "cnst", +// CHECK-SAME: scope: [[NS:![0-9]*]] +// CHECK: [[NS]] = !DINamespace(name: "ns" diff --git a/test/CodeGenCXX/debug-info-globalinit.cpp b/test/CodeGenCXX/debug-info-globalinit.cpp index efba958..f8c0ebd 100644 --- a/test/CodeGenCXX/debug-info-globalinit.cpp +++ b/test/CodeGenCXX/debug-info-globalinit.cpp @@ -22,17 +22,17 @@ int main(void) {} // CHECK-NOT: __cxx_global_var_init // CHECK: store i32 %[[C0]], i32* @_ZL1i, align 4, !dbg // -// CHECK-LABEL: define internal void @__cxx_global_var_init1() +// CHECK-LABEL: define internal void @__cxx_global_var_init.1() // CHECK-NOT: dbg // CHECK: %[[C1:.+]] = call i32 @_Z4testv() // CHECK-NOT: dbg // CHECK: store i32 %[[C1]], i32* @_ZL1j, align 4 // -// CHECK-LABEL: define internal void @__cxx_global_var_init2() +// CHECK-LABEL: define internal void @__cxx_global_var_init.2() // CHECK-NOT: __cxx_global_var_init // CHECK: %[[C2:.+]] = call i32 @_Z4testv(), !dbg ![[LINE2:.*]] // CHECK-NOT: __cxx_global_var_init // CHECK: store i32 %[[C2]], i32* @_ZL1k, align 4, !dbg // -// CHECK: ![[LINE]] = !MDLocation(line: 13, -// CHECK: ![[LINE2]] = !MDLocation(line: 15, +// CHECK: ![[LINE]] = !DILocation(line: 13, +// CHECK: ![[LINE2]] = !DILocation(line: 15, diff --git a/test/CodeGenCXX/debug-info-indirect-field-decl.cpp b/test/CodeGenCXX/debug-info-indirect-field-decl.cpp index 131ceba..08f71d4 100644 --- a/test/CodeGenCXX/debug-info-indirect-field-decl.cpp +++ b/test/CodeGenCXX/debug-info-indirect-field-decl.cpp @@ -7,9 +7,18 @@ template <class T, int T::*ptr> class Foo { }; struct Bar { int i1; - // CHECK: [ DW_TAG_member ] [line [[@LINE+1]], size 32, align 32, offset 32] [from _ZTSN3BarUt_E] + // CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int" + // CHECK: !DIDerivedType(tag: DW_TAG_member, scope: + // CHECK-SAME: line: [[@LINE+3]] + // CHECK-SAME: baseType: !"_ZTSN3BarUt_E" + // CHECK-SAME: size: 32, align: 32, offset: 32 union { - // CHECK: [ DW_TAG_member ] [i2] [line [[@LINE+1]], size 32, align 32, offset 0] [from int] + // CHECK: !DIDerivedType(tag: DW_TAG_member, name: "i2", + // CHECK-SAME: line: [[@LINE+5]] + // CHECK-SAME: baseType: ![[INT]] + // CHECK-SAME: size: 32, align: 32 + // CHECK-NOT: offset: + // CHECK-SAME: ){{$}} int i2; }; }; diff --git a/test/CodeGenCXX/debug-info-limited.cpp b/test/CodeGenCXX/debug-info-limited.cpp index 294d1f6..d56e5b6 100644 --- a/test/CodeGenCXX/debug-info-limited.cpp +++ b/test/CodeGenCXX/debug-info-limited.cpp @@ -1,6 +1,8 @@ // RUN: %clang -flimit-debug-info -emit-llvm -g -S %s -o - | FileCheck %s -// CHECK: ; [ DW_TAG_class_type ] [A] {{.*}} [def] +// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} class A { public: int z; @@ -11,7 +13,9 @@ A *foo (A* x) { return a; } -// CHECK: ; [ DW_TAG_class_type ] [B] {{.*}} [def] +// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "B" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} class B { public: @@ -24,7 +28,8 @@ int baz(B *b) { } -// CHECK: ; [ DW_TAG_structure_type ] [C] {{.*}} [decl] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "C" +// CHECK-SAME: flags: DIFlagFwdDecl struct C { }; diff --git a/test/CodeGenCXX/debug-info-line-if.cpp b/test/CodeGenCXX/debug-info-line-if.cpp index d0205af..7109725 100644 --- a/test/CodeGenCXX/debug-info-line-if.cpp +++ b/test/CodeGenCXX/debug-info-line-if.cpp @@ -48,8 +48,8 @@ int main() { // CHECK: br label // CHECK: br label {{.*}}, !dbg [[DBG4:!.*]] - // CHECK: [[DBG1]] = !MDLocation(line: 100, scope: !{{.*}}) - // CHECK: [[DBG2]] = !MDLocation(line: 200, scope: !{{.*}}) - // CHECK: [[DBG3]] = !MDLocation(line: 300, scope: !{{.*}}) - // CHECK: [[DBG4]] = !MDLocation(line: 401, scope: !{{.*}}) + // CHECK: [[DBG1]] = !DILocation(line: 100, scope: !{{.*}}) + // CHECK: [[DBG2]] = !DILocation(line: 200, scope: !{{.*}}) + // CHECK: [[DBG3]] = !DILocation(line: 300, scope: !{{.*}}) + // CHECK: [[DBG4]] = !DILocation(line: 401, scope: !{{.*}}) } diff --git a/test/CodeGenCXX/debug-info-line.cpp b/test/CodeGenCXX/debug-info-line.cpp index 5b84711..0b1b43b 100644 --- a/test/CodeGenCXX/debug-info-line.cpp +++ b/test/CodeGenCXX/debug-info-line.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -gline-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s -// RUN: %clang_cc1 -gline-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - -triple i686-linux-gnu | FileCheck %s +// RUN: %clang_cc1 -w -gline-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - | FileCheck %s +// RUN: %clang_cc1 -w -gline-tables-only -std=c++11 -fexceptions -fcxx-exceptions -S -emit-llvm %s -o - -triple i686-linux-gnu | FileCheck %s // XFAIL: win32 @@ -10,11 +10,11 @@ extern "C" __complex float *complex_sink(); // CHECK-LABEL: define void f1() { -#line 100 - * // The store for the assignment should be attributed to the start of the - // assignment expression here, regardless of the location of subexpressions. - sink() = src(); + *sink() // CHECK: store {{.*}}, !dbg [[DBG_F1:!.*]] +#line 100 + = // + src(); } struct foo { @@ -38,16 +38,20 @@ foo::foo() // CHECK-LABEL: define {{.*}}f2{{.*}} void f2() { + // CHECK: store float {{.*}} !dbg [[DBG_F2:!.*]] + *complex_sink() #line 300 - * // CHECK: store float {{.*}} !dbg [[DBG_F2:!.*]] - complex_sink() = complex_src(); + = // + complex_src(); } // CHECK-LABEL: define void f3() { + // CHECK: store float {{.*}} !dbg [[DBG_F3:!.*]] + *complex_sink() #line 400 - * // CHECK: store float {{.*}} !dbg [[DBG_F3:!.*]] - complex_sink() += complex_src(); + += // + complex_src(); } // CHECK-LABEL: define @@ -70,9 +74,11 @@ agg agg_src(); // CHECK-LABEL: define void f6() { agg x; + // CHECK: call void @llvm.memcpy{{.*}} !dbg [[DBG_F6:!.*]] + x #line 700 - x // CHECK: call void @llvm.memcpy{{.*}} !dbg [[DBG_F6:!.*]] - = agg_src(); + = // + agg_src(); } // CHECK-LABEL: define @@ -107,7 +113,7 @@ inline void *operator new(decltype(sizeof(1)), void *p) noexcept { return p; } // CHECK-LABEL: define void f10() { void *void_src(); - ( // CHECK: icmp {{.*}} !dbg [[DBG_F10_ICMP:.*]] + ( // CHECK: store {{.*}} !dbg [[DBG_F10_STORE:!.*]] #line 1100 new (void_src()) int(src())); @@ -135,7 +141,7 @@ struct bar { // CHECK: invoke{{ }} // CHECK: invoke{{ }} // CHECK: to label {{.*}}, !dbg [[DBG_GLBL_DTOR_B:!.*]] -#line 1500 +#line 1200 bar b[1] = { // (fn(), // bar())}; @@ -144,7 +150,7 @@ bar b[1] = { // __complex double f11() { __complex double f; // CHECK: store {{.*}} !dbg [[DBG_F11:!.*]] -#line 1200 +#line 1300 return f; } @@ -153,7 +159,7 @@ void f12() { int f12_1(); void f12_2(int = f12_1()); // CHECK: call {{(signext )?}}i32 {{.*}} !dbg [[DBG_F12:!.*]] -#line 1300 +#line 1400 f12_2(); } @@ -162,27 +168,87 @@ void f13() { // CHECK: call {{.*}} !dbg [[DBG_F13:!.*]] #define F13_IMPL 1, src() 1, -#line 1400 +#line 1500 F13_IMPL; } -struct f14 { - f14(int); +struct f14_impl { + f14_impl(int); }; // CHECK-LABEL: define struct f14_use { -// CHECK: call {{.*}}, !dbg [[DBG_F14_CTOR_CALL:![0-9]*]] +// CHECK: call {{.*}}f14_impl{{.*}}, !dbg [[DBG_F14_CTOR_CALL:![0-9]*]] #line 1600 - f14 v - = - 1; + f14_impl v{// + 1}; f14_use(); }; f14_use::f14_use() = default; // CHECK-LABEL: define +// CHECK-LABEL: define +void func(foo); +void f15(foo *f) { + func( +// CHECK: getelementptr {{.*}}, !dbg [[DBG_F15:![0-9]*]] +#line 1700 + f[3]); +} + +// CHECK-LABEL: define +void f16(__complex float f) { + __complex float g = // +// CHECK: add {{.*}}, !dbg [[DBG_F16:![0-9]*]] +#line 1800 + f + 1; +} + +// CHECK-LABEL: define +void f17(int *x) { + 1, +// CHECK: getelementptr {{.*}}, !dbg [[DBG_F17:![0-9]*]] +#line 1900 + x[1]; +} + +// CHECK-LABEL: define +void f18(int a, int b) { +// CHECK: icmp {{.*}}, !dbg [[DBG_F18_1:![0-9]*]] +// CHECK: br {{.*}}, !dbg [[DBG_F18_2:![0-9]*]] +#line 2000 + if (a // + && // + b) + ; +} + +// CHECK-LABEL: define +void f19(int a, int b) { +// CHECK: icmp {{.*}}, !dbg [[DBG_F19_1:![0-9]*]] +// CHECK: br {{.*}}, !dbg [[DBG_F19_2:![0-9]*]] +#line 2100 + if (a // + || // + b) + ; +} + +// CHECK-LABEL: define +void f20(int a, int b, int c) { +// CHECK: icmp {{.*}}, !dbg [[DBG_F20_1:![0-9]*]] +// FIXME: Conditional operator's exprloc should be the '?' not the start of the +// expression, then this would go in the right place. (but adding getExprLoc to +// the ConditionalOperator breaks the ARC migration tool - need to investigate +// further). +// CHECK: br {{.*}}, !dbg [[DBG_F20_1]] +#line 2200 + if (a // + ? // + b : c) + ; +} // CHECK-LABEL: define int f21_a(int = 0); @@ -193,22 +259,66 @@ void f21() { f21_b(); } -// CHECK: [[DBG_F1]] = !MDLocation(line: 100, -// CHECK: [[DBG_FOO_VALUE]] = !MDLocation(line: 200, -// CHECK: [[DBG_FOO_REF]] = !MDLocation(line: 202, -// CHECK: [[DBG_FOO_COMPLEX]] = !MDLocation(line: 204, -// CHECK: [[DBG_F2]] = !MDLocation(line: 300, -// CHECK: [[DBG_F3]] = !MDLocation(line: 400, -// CHECK: [[DBG_F4]] = !MDLocation(line: 500, -// CHECK: [[DBG_F5]] = !MDLocation(line: 600, -// CHECK: [[DBG_F6]] = !MDLocation(line: 700, -// CHECK: [[DBG_F7]] = !MDLocation(line: 800, -// CHECK: [[DBG_F8]] = !MDLocation(line: 900, -// CHECK: [[DBG_F9]] = !MDLocation(line: 1000, -// CHECK: [[DBG_F10_ICMP]] = !MDLocation(line: 1100, -// CHECK: [[DBG_F10_STORE]] = !MDLocation(line: 1100, -// CHECK: [[DBG_GLBL_CTOR_B]] = !MDLocation(line: 1500, -// CHECK: [[DBG_GLBL_DTOR_B]] = !MDLocation(line: 1500, -// CHECK: [[DBG_F11]] = !MDLocation(line: 1200, -// CHECK: [[DBG_F12]] = !MDLocation(line: 1300, -// CHECK: [[DBG_F13]] = !MDLocation(line: 1400, +// CHECK-LABEL: define +struct f22_dtor { + ~f22_dtor(); +}; +void f22() { + { + f22_dtor f; + src(); +// CHECK: invoke {{.*}}src +// CHECK: call {{.*}}, !dbg [[DBG_F22:![0-9]*]] +// CHECK: call {{.*}}, !dbg [[DBG_F22]] +#line 2400 + } +} + +// CHECK-LABEL: define +struct f23_struct { +}; +f23_struct f23_a(); +void f23_b(f23_struct = f23_a()); +void f23() { +// CHECK: call {{.*}}f23_a{{.*}}, !dbg [[DBG_F23:![0-9]*]] +#line 2500 + f23_b(); +} + +// CHECK-LABEL: define +void f24_a(__complex float = complex_src()); +void f24() { +// CHECK: call {{.*}}complex_src{{.*}}, !dbg [[DBG_F24:![0-9]*]] +#line 2600 + f24_a(); +} + +// CHECK: [[DBG_F1]] = !DILocation(line: 100, +// CHECK: [[DBG_FOO_VALUE]] = !DILocation(line: 200, +// CHECK: [[DBG_FOO_REF]] = !DILocation(line: 202, +// CHECK: [[DBG_FOO_COMPLEX]] = !DILocation(line: 204, +// CHECK: [[DBG_F2]] = !DILocation(line: 300, +// CHECK: [[DBG_F3]] = !DILocation(line: 400, +// CHECK: [[DBG_F4]] = !DILocation(line: 500, +// CHECK: [[DBG_F5]] = !DILocation(line: 600, +// CHECK: [[DBG_F6]] = !DILocation(line: 700, +// CHECK: [[DBG_F7]] = !DILocation(line: 800, +// CHECK: [[DBG_F8]] = !DILocation(line: 900, +// CHECK: [[DBG_F9]] = !DILocation(line: 1000, +// CHECK: [[DBG_F10_STORE]] = !DILocation(line: 1100, +// CHECK: [[DBG_GLBL_CTOR_B]] = !DILocation(line: 1200, +// CHECK: [[DBG_GLBL_DTOR_B]] = !DILocation(line: 1200, +// CHECK: [[DBG_F11]] = !DILocation(line: 1300, +// CHECK: [[DBG_F12]] = !DILocation(line: 1400, +// CHECK: [[DBG_F13]] = !DILocation(line: 1500, +// CHECK: [[DBG_F14_CTOR_CALL]] = !DILocation(line: 1600, +// CHECK: [[DBG_F15]] = !DILocation(line: 1700, +// CHECK: [[DBG_F16]] = !DILocation(line: 1800, +// CHECK: [[DBG_F17]] = !DILocation(line: 1900, +// CHECK: [[DBG_F18_1]] = !DILocation(line: 2000, +// CHECK: [[DBG_F18_2]] = !DILocation(line: 2001, +// CHECK: [[DBG_F19_1]] = !DILocation(line: 2100, +// CHECK: [[DBG_F19_2]] = !DILocation(line: 2101, +// CHECK: [[DBG_F20_1]] = !DILocation(line: 2200, +// CHECK: [[DBG_F23]] = !DILocation(line: 2500, +// CHECK: [[DBG_F24]] = !DILocation(line: 2600, diff --git a/test/CodeGenCXX/debug-info-method.cpp b/test/CodeGenCXX/debug-info-method.cpp index bb69a65..3ce05bd 100644 --- a/test/CodeGenCXX/debug-info-method.cpp +++ b/test/CodeGenCXX/debug-info-method.cpp @@ -1,14 +1,16 @@ // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -std=c++11 -g %s -o - | FileCheck %s -// CHECK: !"_ZTS1A"} ; [ DW_TAG_class_type ] [A] -// CHECK: !"{{.*}}\00_ZN1A3fooEiS_3$_0\00{{.*}}", {{.*}} [protected] -// CHECK: ![[THISTYPE:[0-9]+]] = {{.*}} ; [ DW_TAG_pointer_type ] {{.*}} [artificial] [from _ZTS1A] -// CHECK: [ DW_TAG_ptr_to_member_type ] [line {{[0-9]+}}, size {{[1-9][0-9]+}}, align -// CHECK: {{.*}}![[MEMFUNTYPE:[0-9]+]], !{{.*}}} ; [ DW_TAG_ptr_to_member_type ] {{.*}} [from ] -// CHECK: ![[MEMFUNTYPE]] = {{.*}}![[MEMFUNARGS:[0-9]+]], null, null, null} ; [ DW_TAG_subroutine_type ] {{.*}} [from ] +// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "A",{{.*}} identifier: "_ZTS1A") +// CHECK: !DISubprogram(name: "foo", linkageName: "_ZN1A3fooEiS_3$_0" +// CHECK-SAME: DIFlagProtected +// CHECK: ![[THISTYPE:[0-9]+]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS1A" +// CHECK-SAME: DIFlagArtificial +// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type +// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: ![[MEMFUNTYPE:[0-9]+]] +// CHECK: ![[MEMFUNTYPE]] = !DISubroutineType(types: ![[MEMFUNARGS:[0-9]+]]) // CHECK: ![[MEMFUNARGS]] = {{.*}}, ![[THISTYPE]], -// CHECK: !"0x101\00\00{{.*}}"{{.*}} DW_TAG_arg_variable -// CHECK: !"0x101\00\00{{.*}}"{{.*}} DW_TAG_arg_variable -// CHECK: !"0x101\00\00{{.*}}"{{.*}} DW_TAG_arg_variable +// CHECK: !DILocalVariable(tag: DW_TAG_arg_variable +// CHECK: !DILocalVariable(tag: DW_TAG_arg_variable +// CHECK: !DILocalVariable(tag: DW_TAG_arg_variable union { int a; float b; diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp index 60d508b..d59b778 100644 --- a/test/CodeGenCXX/debug-info-namespace.cpp +++ b/test/CodeGenCXX/debug-info-namespace.cpp @@ -55,47 +55,61 @@ void B::func_fwd() {} // This should work even if 'i' and 'func' were declarations & not definitions, // but it doesn't yet. -// CHECK: [[CU:![0-9]*]] = !{!"0x11\00{{.*}}\001"{{.*}}, [[MODULES:![0-9]*]]} ; [ DW_TAG_compile_unit ] -// CHECK: [[FOO:![0-9]*]] {{.*}} ; [ DW_TAG_structure_type ] [foo] [line 5, size 0, align 0, offset 0] [decl] [from ] -// CHECK: [[FOOCPP:![0-9]*]] = !{!"foo.cpp", {{.*}} -// CHECK: [[NS:![0-9]*]] = !{!"0x39\00B\001", [[FILE2:![0-9]*]], [[CTXT:![0-9]*]]} ; [ DW_TAG_namespace ] [B] [line 1] -// CHECK: [[CTXT]] = !{!"0x39\00A\005", [[FILE:![0-9]*]], null} ; [ DW_TAG_namespace ] [A] [line 5] -// CHECK: [[FILE]] {{.*}}debug-info-namespace.cpp" -// CHECK: [[BAR:![0-9]*]] {{.*}} ; [ DW_TAG_structure_type ] [bar] [line 6, {{.*}}] [decl] [from ] -// CHECK: [[F1:![0-9]*]] {{.*}} ; [ DW_TAG_subprogram ] [line 4] [def] [f1] -// CHECK: [[FILE2]]} ; [ DW_TAG_file_type ] [{{.*}}foo.cpp] -// CHECK: [[FUNC:![0-9]*]] {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [def] [func] -// CHECK: [[FUNC_FWD:![0-9]*]] {{.*}} [ DW_TAG_subprogram ] [line 47] [def] [func_fwd] -// CHECK: [[I:![0-9]*]] = !{!"0x34\00i\00{{.*}}", [[NS]], {{.*}} ; [ DW_TAG_variable ] [i] -// CHECK: [[VAR_FWD:![0-9]*]] = !{!"0x34\00var_fwd\00{{.*}}", [[NS]], {{.*}}} ; [ DW_TAG_variable ] [var_fwd] [line 44] [def] +// CHECK: [[CU:![0-9]+]] = !DICompileUnit( +// CHECK-SAME: imports: [[MODULES:![0-9]*]] +// CHECK: [[FOO:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", +// CHECK-SAME: line: 5 +// CHECK-SAME: DIFlagFwdDecl +// CHECK: [[FOOCPP:![0-9]+]] = !DIFile(filename: "foo.cpp" +// CHECK: [[NS:![0-9]+]] = !DINamespace(name: "B", scope: [[CTXT:![0-9]+]], file: [[FOOCPP]], line: 1) +// CHECK: [[CTXT]] = !DINamespace(name: "A", scope: null, file: [[FILE:![0-9]+]], line: 5) +// CHECK: [[FILE]] = !DIFile(filename: "{{.*}}debug-info-namespace.cpp", +// CHECK: [[BAR:![0-9]+]] = !DICompositeType(tag: DW_TAG_structure_type, name: "bar", +// CHECK-SAME: line: 6 +// CHECK-SAME: DIFlagFwdDecl +// CHECK: [[F1:![0-9]+]] = !DISubprogram(name: "f1",{{.*}} line: 4 +// CHECK-SAME: isDefinition: true +// CHECK: [[FUNC:![0-9]+]] = !DISubprogram(name: "func",{{.*}} isDefinition: true +// CHECK: [[FUNC_FWD:![0-9]+]] = !DISubprogram(name: "func_fwd",{{.*}} line: 47,{{.*}} isDefinition: true +// CHECK: [[I:![0-9]+]] = !DIGlobalVariable(name: "i",{{.*}} scope: [[NS]], +// CHECK: [[VAR_FWD:![0-9]+]] = !DIGlobalVariable(name: "var_fwd",{{.*}} scope: [[NS]], +// CHECK-SAME: line: 44 +// CHECK-SAME: isDefinition: true -// CHECK: [[MODULES]] = !{[[M1:![0-9]*]], [[M2:![0-9]*]], [[M3:![0-9]*]], [[M4:![0-9]*]], [[M5:![0-9]*]], [[M6:![0-9]*]], [[M7:![0-9]*]], [[M8:![0-9]*]], [[M9:![0-9]*]], [[M10:![0-9]*]], [[M11:![0-9]*]], [[M12:![0-9]*]], [[M13:![0-9]*]], [[M14:![0-9]*]], [[M15:![0-9]*]], [[M16:![0-9]*]], [[M17:![0-9]*]]} -// CHECK: [[M1]] = !{!"0x3a\0015\00", [[CTXT]], [[NS]]} ; [ DW_TAG_imported_module ] -// CHECK: [[M2]] = !{!"0x3a\00{{[0-9]+}}\00", [[CU]], [[CTXT]]} ; [ DW_TAG_imported_module ] -// CHECK: [[M3]] = !{!"0x8\0019\00E", [[CU]], [[CTXT]]} ; [ DW_TAG_imported_declaration ] -// CHECK: [[M4]] = !{!"0x3a\0023\00", [[LEX2:![0-9]*]], [[NS]]} ; [ DW_TAG_imported_module ] -// CHECK: [[LEX2]] = !{!"0xb\00{{[0-9]*}}\000\00{{.*}}", [[FILE2]], [[LEX1:![0-9]+]]} ; [ DW_TAG_lexical_block ] -// CHECK: [[LEX1]] = !{!"0xb\00{{[0-9]*}}\000\00{{.*}}", [[FILE2]], [[FUNC]]} ; [ DW_TAG_lexical_block ] -// CHECK: [[M5]] = !{!"0x3a\00{{[0-9]+}}\00", [[FUNC]], [[CTXT]]} ; [ DW_TAG_imported_module ] -// CHECK: [[M6]] = !{!"0x8\0027\00", [[FUNC]], [[FOO:!"_ZTSN1A1B3fooE"]]} ; [ DW_TAG_imported_declaration ] -// CHECK: [[M7]] = !{!"0x8\00{{[0-9]+}}\00", [[FUNC]], [[BAR:!"_ZTSN1A1B3barE"]]} ; [ DW_TAG_imported_declaration ] -// CHECK: [[M8]] = !{!"0x8\00{{[0-9]+}}\00", [[FUNC]], [[F1]]} ; [ DW_TAG_imported_declaration ] -// CHECK: [[M9]] = !{!"0x8\00{{[0-9]+}}\00", [[FUNC]], [[I]]} ; [ DW_TAG_imported_declaration ] -// CHECK: [[M10]] = !{!"0x8\00{{[0-9]+}}\00", [[FUNC]], [[BAZ:![0-9]*]]} ; [ DW_TAG_imported_declaration ] -// CHECK: [[BAZ]] = !{!"0x16\00baz\00{{.*}}", [[FOOCPP]], [[NS]], !"_ZTSN1A1B3barE"} ; [ DW_TAG_typedef ] [baz] {{.*}} [from _ZTSN1A1B3barE] -// CHECK: [[M11]] = !{!"0x8\00{{[0-9]+}}\00X", [[FUNC]], [[CTXT]]} ; [ DW_TAG_imported_declaration ] -// CHECK: [[M12]] = !{!"0x8\00{{[0-9]+}}\00Y", [[FUNC]], [[M11]]} ; [ DW_TAG_imported_declaration ] -// CHECK: [[M13]] = !{!"0x8\00{{[0-9]+}}\00", [[FUNC]], [[VAR_DECL:![0-9]*]]} ; [ DW_TAG_imported_declaration ] -// CHECK [[VAR_DECL]] = !{!"0x34\00var_decl\00{{.*}}", [[NS]], {{.*}}} ; [ DW_TAG_variable ] [var_decl] [line 8] -// CHECK: [[M14]] = !{!"0x8\00{{[0-9]+}}\00", [[FUNC]], [[FUNC_DECL:![0-9]*]]} ; [ DW_TAG_imported_declaration ] -// CHECK: [[FUNC_DECL]] = !{!"0x2e\00func_decl\00{{.*}}", [[FOOCPP]], [[NS]], {{.*}}} ; [ DW_TAG_subprogram ] [line 9] [scope 0] [func_decl] -// CHECK: [[M15]] = !{!"0x8\00{{[0-9]+}}\00", [[FUNC]], [[VAR_FWD:![0-9]*]]} ; [ DW_TAG_imported_declaration ] -// CHECK: [[M16]] = !{!"0x8\00{{[0-9]+}}\00", [[FUNC]], [[FUNC_FWD:![0-9]*]]} ; [ DW_TAG_imported_declaration ] -// CHECK: [[M17]] = !{!"0x8\00{{[0-9]+}}\00", [[CTXT]], [[I]]} ; [ DW_TAG_imported_declaration ] -// CHECK-GMLT: [[CU:![0-9]*]] = !{!"0x11\00{{.*}}\002"{{.*}}, [[MODULES:![0-9]*]]} ; [ DW_TAG_compile_unit ] +// CHECK: [[MODULES]] = !{[[M1:![0-9]+]], [[M2:![0-9]+]], [[M3:![0-9]+]], [[M4:![0-9]+]], [[M5:![0-9]+]], [[M6:![0-9]+]], [[M7:![0-9]+]], [[M8:![0-9]+]], [[M9:![0-9]+]], [[M10:![0-9]+]], [[M11:![0-9]+]], [[M12:![0-9]+]], [[M13:![0-9]+]], [[M14:![0-9]+]], [[M15:![0-9]+]], [[M16:![0-9]+]], [[M17:![0-9]+]]} +// CHECK: [[M1]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CTXT]], entity: [[NS]], line: 15) +// CHECK: [[M2]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[CTXT]], +// CHECK: [[M3]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "E", scope: [[CU]], entity: [[CTXT]], line: 19) +// CHECK: [[M4]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[LEX2:![0-9]+]], entity: [[NS]], line: 23) +// CHECK: [[LEX2]] = distinct !DILexicalBlock(scope: [[LEX1:![0-9]+]], file: [[FOOCPP]], +// CHECK: [[LEX1]] = distinct !DILexicalBlock(scope: [[FUNC]], file: [[FOOCPP]], +// CHECK: [[M5]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[FUNC]], entity: [[CTXT]], +// CHECK: [[M6]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FOO:!"_ZTSN1A1B3fooE"]], line: 27) +// CHECK: [[M7]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[BAR:!"_ZTSN1A1B3barE"]] +// CHECK: [[M8]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[F1]] +// CHECK: [[M9]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[I]] +// CHECK: [[M10]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[BAZ:![0-9]+]] +// CHECK: [[BAZ]] = !DIDerivedType(tag: DW_TAG_typedef, name: "baz", scope: [[NS]], file: [[FOOCPP]], +// CHECK-SAME: baseType: !"_ZTSN1A1B3barE" +// CHECK: [[M11]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "X", scope: [[FUNC]], entity: [[CTXT]] +// CHECK: [[M12]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "Y", scope: [[FUNC]], entity: [[M11]] +// CHECK: [[M13]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[VAR_DECL:![0-9]+]] +// CHECK: [[VAR_DECL]] = !DIGlobalVariable(name: "var_decl", linkageName: "_ZN1A1B8var_declE", scope: [[NS]],{{.*}} line: 8, +// CHECK: [[M14]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FUNC_DECL:![0-9]+]] +// CHECK: [[FUNC_DECL]] = !DISubprogram(name: "func_decl", +// CHECK-SAME: scope: [[NS]], file: [[FOOCPP]], line: 9 +// CHECK: [[M15]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[VAR_FWD:![0-9]+]] +// CHECK: [[M16]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FUNC_FWD:![0-9]+]] +// CHECK: [[M17]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CTXT]], entity: [[I]] + +// CHECK-GMLT: [[CU:![0-9]+]] = !DICompileUnit( +// CHECK-GMLT-SAME: emissionKind: 2, +// CHECK-GMLT-SAME: imports: [[MODULES:![0-9]+]] // CHECK-GMLT: [[MODULES]] = !{} -// CHECK-NOLIMIT: ; [ DW_TAG_structure_type ] [bar] [line 6, {{.*}}] [def] [from ] +// CHECK-NOLIMIT: !DICompositeType(tag: DW_TAG_structure_type, name: "bar",{{.*}} line: 6, +// CHECK-NOLIMIT-NOT: DIFlagFwdDecl +// CHECK-NOLIMIT-SAME: ){{$}} // REQUIRES: shell-preserves-root // REQUIRES: dw2 diff --git a/test/CodeGenCXX/debug-info-nullptr.cpp b/test/CodeGenCXX/debug-info-nullptr.cpp index ef9b618..36baacc 100644 --- a/test/CodeGenCXX/debug-info-nullptr.cpp +++ b/test/CodeGenCXX/debug-info-nullptr.cpp @@ -4,4 +4,4 @@ void foo() { decltype(nullptr) t = 0; } -// CHECK: [ DW_TAG_unspecified_type ] [decltype(nullptr)] +// CHECK: !DIBasicType(tag: DW_TAG_unspecified_type, name: "decltype(nullptr)") diff --git a/test/CodeGenCXX/debug-info-ptr-to-member-function.cpp b/test/CodeGenCXX/debug-info-ptr-to-member-function.cpp index 656e6f4..1b2cb57 100644 --- a/test/CodeGenCXX/debug-info-ptr-to-member-function.cpp +++ b/test/CodeGenCXX/debug-info-ptr-to-member-function.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 %s -triple x86_64-apple-darwin -g -emit-llvm -o - | FileCheck %s +// RUN: %clang_cc1 %s -triple x86_64-apple-darwin -g -emit-llvm -o - | FileCheck -check-prefix=CHECK -check-prefix=DARWIN-X64 %s +// RUN: %clang_cc1 %s -triple x86_64-pc-win32 -g -emit-llvm -o - | FileCheck -check-prefix=CHECK -check-prefix=WIN32-X64 %s struct T { int method(); @@ -7,4 +8,14 @@ struct T { void foo(int (T::*method)()) {} // A pointer to a member function is a pair of function- and this-pointer. -// CHECK: [ DW_TAG_ptr_to_member_type ] {{.*}} size 128 +// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type, +// DARWIN-X64-SAME: size: 128 +// WIN32-X64-SAME: size: 64 + +struct Incomplete; + +int (Incomplete::**bar)(); +// CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type, +// DARWIN-X64-SAME: size: 128 +// WIN32-X64-NOT: size: +// CHECK-SAME: extraData: {{.*}}) diff --git a/test/CodeGenCXX/debug-info-qualifiers.cpp b/test/CodeGenCXX/debug-info-qualifiers.cpp index 2655bd9..9458e1f 100644 --- a/test/CodeGenCXX/debug-info-qualifiers.cpp +++ b/test/CodeGenCXX/debug-info-qualifiers.cpp @@ -2,25 +2,35 @@ // Test (r)value and CVR qualifiers on C++11 non-static member functions. class A { public: - // CHECK: !"0x2e\00l\00{{.*}}\00[[@LINE+2]]"{{, [^,]+, [^,]+}}, ![[PLSR:[0-9]+]], {{.*}}[ DW_TAG_subprogram ] [line [[@LINE+2]]] [public] [reference] [l] - // CHECK: ![[PLSR]] ={{.*}}[ DW_TAG_subroutine_type ]{{.*}}[reference] + // CHECK: !DISubprogram(name: "l", + // CHECK-SAME: line: [[@LINE+4]] + // CHECK-SAME: type: ![[PLSR:[0-9]+]] + // CHECK-SAME: flags: DIFlagPublic | DIFlagPrototyped | DIFlagLValueReference, + // CHECK: ![[PLSR]] = !DISubroutineType(flags: DIFlagLValueReference, types: ![[ARGS:[0-9]+]]) void l() const &; - // CHECK: ![[ARGS:[0-9]+]] = !{null, ![[THIS:[0-9]+]]} - // CHECK: ![[THIS]] = {{.*}} ![[CONST_A:.*]]} ; [ DW_TAG_pointer_type ] - // CHECK: ![[CONST_A]] = {{.*}} [ DW_TAG_const_type ] - // CHECK: !"0x2e\00r\00{{.*}}\00[[@LINE+2]]"{{, [^,]+, [^,]+}}, ![[PRSR:[0-9]+]], {{.*}}[ DW_TAG_subprogram ] [line [[@LINE+2]]] [public] [rvalue reference] [r] - // CHECK: ![[PRSR]] ={{.*}}![[ARGS]], null, null, null}{{.*}}[ DW_TAG_subroutine_type ]{{.*}}[rvalue reference] + // CHECK: ![[ARGS]] = !{null, ![[THIS:[0-9]+]]} + // CHECK: ![[THIS]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[CONST_A:[0-9]+]] + // CHECK: ![[CONST_A]] = !DIDerivedType(tag: DW_TAG_const_type + // CHECK: !DISubprogram(name: "r" + // CHECK-SAME: line: [[@LINE+4]] + // CHECK-SAME: type: ![[PRSR:[0-9]+]] + // CHECK-SAME: flags: DIFlagPublic | DIFlagPrototyped | DIFlagRValueReference, + // CHECK: ![[PRSR]] = !DISubroutineType(flags: DIFlagRValueReference, types: ![[ARGS]]) void r() const &&; }; void g() { A a; // The type of pl is "void (A::*)() const &". - // CHECK: ![[PL:[0-9]+]]} ; [ DW_TAG_auto_variable ] [pl] [line [[@LINE+2]]] - // CHECK: ![[PLSR]], !"{{.*}}"} ; [ DW_TAG_ptr_to_member_type ] + // CHECK: !DILocalVariable(tag: DW_TAG_auto_variable, name: "pl", + // CHECK-SAME: line: [[@LINE+3]] + // CHECK-SAME: type: ![[PL:[0-9]+]] + // CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: ![[PLSR]] auto pl = &A::l; - // CHECK: ![[PR:[0-9]+]]} ; [ DW_TAG_auto_variable ] [pr] [line [[@LINE+2]]] - // CHECK: ![[PRSR]], !"{{.*}}"} ; [ DW_TAG_ptr_to_member_type ] + // CHECK: !DILocalVariable(tag: DW_TAG_auto_variable, name: "pr", + // CHECK-SAME: line: [[@LINE+3]] + // CHECK-SAME: type: ![[PR:[0-9]+]] + // CHECK: !DIDerivedType(tag: DW_TAG_ptr_to_member_type, baseType: ![[PRSR]] auto pr = &A::r; } diff --git a/test/CodeGenCXX/debug-info-rvalue-ref.cpp b/test/CodeGenCXX/debug-info-rvalue-ref.cpp index 36e4aa3..00b5bcc 100644 --- a/test/CodeGenCXX/debug-info-rvalue-ref.cpp +++ b/test/CodeGenCXX/debug-info-rvalue-ref.cpp @@ -8,4 +8,5 @@ void foo (int &&i) printf("%d\n", i); } -// CHECK: !"0x42\00\000\000\000\000\000", null, null, !{{.*}}} ; [ DW_TAG_rvalue_reference_type ] +// CHECK: !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: ![[INT:[0-9]+]]) +// CHECK: ![[INT]] = !DIBasicType(name: "int" diff --git a/test/CodeGenCXX/debug-info-same-line.cpp b/test/CodeGenCXX/debug-info-same-line.cpp deleted file mode 100644 index 965a538..0000000 --- a/test/CodeGenCXX/debug-info-same-line.cpp +++ /dev/null @@ -1,64 +0,0 @@ -// RUN: %clang_cc1 -g -triple %itanium_abi_triple -emit-llvm -o - %s | FileCheck %s - -// Make sure that clang outputs distinct debug info for a function -// that is inlined twice on the same line. Otherwise it would appear -// as if the function was only inlined once. - -#define INLINE inline __attribute__((always_inline)) - -int i; - -INLINE void sum(int a, int b) { - i = a + b; -} - -void noinline(int x, int y) { - i = x + y; -} - -#define CALLS sum(9, 10), sum(11, 12) - -inline void inlsum(int t, int u) { - i = t + u; -} - -int main() { - sum(1, 2), sum(3, 4); - noinline(5, 6), noinline(7, 8); - CALLS; - inlsum(13, 14), inlsum(15, 16); -} - -// CHECK-LABEL: @main -// CHECK: = add {{.*}} !dbg [[FIRST_INLINE:![0-9]*]] -// CHECK: = add {{.*}} !dbg [[SECOND_INLINE:![0-9]*]] - -// Check that we don't give column information (and thus end up with distinct -// line entries) for two non-inlined calls on the same line. -// CHECK: call {{.*}}noinline{{.*}}({{i32[ ]?[a-z]*}} 5, {{i32[ ]?[a-z]*}} 6), !dbg [[NOINLINE:![0-9]*]] -// CHECK: call {{.*}}noinline{{.*}}({{i32[ ]?[a-z]*}} 7, {{i32[ ]?[a-z]*}} 8), !dbg [[NOINLINE]] - -// FIXME: These should be separate locations but because the two calls have the -// same line /and/ column, they get coalesced into a single inlined call by -// accident. We need discriminators or some other changes to LLVM to cope with -// this. (this is, unfortunately, an LLVM test disguised as a Clang test - since -// inlining is forced to happen here). It's possible this could be fixed in -// Clang, but I doubt it'll be the right place for the fix. -// CHECK: = add {{.*}} !dbg [[FIRST_MACRO_INLINE:![0-9]*]] -// CHECK: = add {{.*}} !dbg [[FIRST_MACRO_INLINE]] - -// Even if the functions are marked inline but do not get inlined, they -// shouldn't use column information, and thus should be at the same debug -// location. -// CHECK: call {{.*}}inlsum{{.*}}({{i32[ ]?[a-z]*}} 13, {{i32[ ]?[a-z]*}} 14), !dbg [[INL_FIRST:![0-9]*]] -// CHECK: call {{.*}}inlsum{{.*}}({{i32[ ]?[a-z]*}} 15, {{i32[ ]?[a-z]*}} 16), !dbg [[INL_SECOND:![0-9]*]] - -// [[FIRST_INLINE]] = -// [[SECOND_INLINE]] = - -// FIXME: These should be the same location since the functions appear on the -// same line and were not inlined - they needlessly have column information -// intended to disambiguate inlined calls, which is going to confuse GDB as it -// doesn't cope well with column information. -// [[INL_FIRST]] = -// [[INL_SECOND]] = diff --git a/test/CodeGenCXX/debug-info-scope.cpp b/test/CodeGenCXX/debug-info-scope.cpp index e66588d..478b789 100644 --- a/test/CodeGenCXX/debug-info-scope.cpp +++ b/test/CodeGenCXX/debug-info-scope.cpp @@ -9,47 +9,64 @@ int src(); void f(); void func() { - // CHECK: = !{!"0x100\00{{.*}}", [[IF1:![0-9]*]], {{.*}} ; [ DW_TAG_auto_variable ] [i] [line [[@LINE+2]]] - // CHECK: [[IF1]] = !{!"0xb\00[[@LINE+1]]\00{{.*}}", !{{.*}}} ; [ DW_TAG_lexical_block ] + // CHECK: = !DILocalVariable(tag: DW_TAG_auto_variable, name: "i" + // CHECK-SAME: scope: [[IF1:![0-9]*]] + // CHECK-SAME: line: [[@LINE+2]] + // CHECK: [[IF1]] = distinct !DILexicalBlock({{.*}}line: [[@LINE+1]]) if (int i = src()) f(); - // CHECK: = !{!"0x100\00{{.*}}", [[IF2:![0-9]*]], {{.*}} ; [ DW_TAG_auto_variable ] [i] [line [[@LINE+2]]] - // CHECK: [[IF2]] = !{!"0xb\00[[@LINE+1]]\00{{.*}}", !{{.*}}} ; [ DW_TAG_lexical_block ] + // CHECK: = !DILocalVariable(tag: DW_TAG_auto_variable, name: "i" + // CHECK-SAME: scope: [[IF2:![0-9]*]] + // CHECK-SAME: line: [[@LINE+2]] + // CHECK: [[IF2]] = distinct !DILexicalBlock({{.*}}line: [[@LINE+1]]) if (int i = src()) { f(); } else f(); - // CHECK: = !{!"0x100\00{{.*}}", [[FOR:![0-9]*]], {{.*}} ; [ DW_TAG_auto_variable ] [i] [line [[@LINE+2]]] - // CHECK: [[FOR]] = !{!"0xb\00[[@LINE+1]]\00{{.*}}", !{{.*}}} ; [ DW_TAG_lexical_block ] + // CHECK: = !DILocalVariable(tag: DW_TAG_auto_variable, name: "i" + // CHECK-SAME: scope: [[FOR:![0-9]*]] + // CHECK-SAME: line: [[@LINE+2]] + // CHECK: [[FOR]] = distinct !DILexicalBlock({{.*}}line: [[@LINE+1]]) for (int i = 0; - // CHECK: = !{!"0x100\00{{.*}}", [[FOR_BODY:![0-9]*]], {{.*}} ; [ DW_TAG_auto_variable ] [b] [line [[@LINE+6]]] + // CHECK: = !DILocalVariable(tag: DW_TAG_auto_variable, name: "b" + // CHECK-SAME: scope: [[FOR_BODY:![0-9]*]] + // CHECK-SAME: line: [[@LINE+6]] + // CHECK: [[FOR_BODY]] = distinct !DILexicalBlock({{.*}}line: [[@LINE-4]]) // The scope could be located at 'bool b', but LLVM drops line information for // scopes anyway, so it's not terribly important. // FIXME: change the debug info schema to not include locations of scopes, // since they're not used. - // CHECK: [[FOR_BODY]] = !{!"0xb\00[[@LINE-6]]\00{{.*}}", !{{.*}}} ; [ DW_TAG_lexical_block ] bool b = i != 10; ++i) f(); - // CHECK: = !{!"0x100\00{{.*}}", [[FOR:![0-9]*]], {{.*}} ; [ DW_TAG_auto_variable ] [i] [line [[@LINE+2]]] - // CHECK: [[FOR]] = !{!"0xb\00[[@LINE+1]]\00{{.*}}", !{{.*}}} ; [ DW_TAG_lexical_block ] + // CHECK: = !DILocalVariable(tag: DW_TAG_auto_variable, name: "i" + // CHECK-SAME: scope: [[FOR:![0-9]*]] + // CHECK-SAME: line: [[@LINE+2]] + // CHECK: [[FOR]] = distinct !DILexicalBlock({{.*}}line: [[@LINE+1]]) for (int i = 0; i != 10; ++i) { // FIXME: Do not include scopes that have only other scopes (and no variables // or using declarations) as direct children, they just waste // space/relocations/etc. - // CHECK: [[FOR_LOOP_INCLUDING_COND:!.*]] = !{!"0xb\00[[@LINE-4]]\00{{.*}}", !{{[0-9]+}}, [[FOR]]} ; [ DW_TAG_lexical_block ] - // CHECK: = !{!"0x100\00{{.*}}", [[FOR_COMPOUND:![0-9]*]], {{.*}} ; [ DW_TAG_auto_variable ] [b] [line [[@LINE+2]]] - // CHECK: [[FOR_COMPOUND]] = !{!"0xb\00[[@LINE-6]]\00{{.*}}", !{{[0-9]+}}, [[FOR_LOOP_INCLUDING_COND]]} ; [ DW_TAG_lexical_block ] + // CHECK: [[FOR_LOOP_INCLUDING_COND:!.*]] = distinct !DILexicalBlock(scope: [[FOR]],{{.*}} line: [[@LINE-4]]) + // CHECK: = !DILocalVariable(tag: DW_TAG_auto_variable, name: "b" + // CHECK-SAME: scope: [[FOR_COMPOUND:![0-9]*]] + // CHECK-SAME: line: [[@LINE+2]] + // CHECK: [[FOR_COMPOUND]] = distinct !DILexicalBlock(scope: [[FOR_LOOP_INCLUDING_COND]],{{.*}} line: [[@LINE-8]]) bool b = i % 2; } int x[] = {1, 2}; - // CHECK: = !{!"0x100\00{{.*}}", [[RANGE_FOR:![0-9]*]], {{.*}} ; [ DW_TAG_auto_variable ] [__range] [line 0] - // CHECK: [[RANGE_FOR]] = !{!"0xb\00[[@LINE+1]]\00{{.*}}", !{{.*}}} ; [ DW_TAG_lexical_block ] + // CHECK: = !DILocalVariable(tag: DW_TAG_auto_variable, name: "__range" + // CHECK-SAME: scope: [[RANGE_FOR:![0-9]*]] + // CHECK-NOT: line: + // CHECK-SAME: ){{$}} + // CHECK: [[RANGE_FOR]] = distinct !DILexicalBlock({{.*}}, line: [[@LINE+1]]) for (int i : x) { - // CHECK: = !{!"0x100\00{{.*}}", [[RANGE_FOR_BODY:![0-9]*]], {{.*}} ; [ DW_TAG_auto_variable ] [i] [line [[@LINE-1]]] - // CHECK: [[RANGE_FOR_BODY]] = !{!"0xb\00[[@LINE-2]]\00{{.*}}", !{{[0-9]+}}, [[RANGE_FOR]]} ; [ DW_TAG_lexical_block ] + // CHECK: = !DILocalVariable(tag: DW_TAG_auto_variable, name: "i" + // CHECK-SAME: scope: [[RANGE_FOR_BODY:![0-9]*]] + // CHECK-SAME: line: [[@LINE-3]] + // CHECK: [[RANGE_FOR_BODY]] = distinct !DILexicalBlock(scope: [[RANGE_FOR]],{{.*}} line: [[@LINE-4]]) } } diff --git a/test/CodeGenCXX/debug-info-static-fns.cpp b/test/CodeGenCXX/debug-info-static-fns.cpp index 41b713c..3f8d8e8 100644 --- a/test/CodeGenCXX/debug-info-static-fns.cpp +++ b/test/CodeGenCXX/debug-info-static-fns.cpp @@ -7,4 +7,7 @@ namespace A { } // Verify that a is present and mangled. -// CHECK: !"0x2e\00a\00a\00_ZN1AL1aEi\00{{.*}}", {{.*}}, i32 (i32)* @_ZN1AL1aEi, {{.*}} ; [ DW_TAG_subprogram ] [line 4] [local] [def] [a] +// CHECK: !DISubprogram(name: "a", linkageName: "_ZN1AL1aEi", +// CHECK-SAME: line: 4 +// CHECK-SAME: isDefinition: true +// CHECK-SAME: function: i32 (i32)* @_ZN1AL1aEi diff --git a/test/CodeGenCXX/debug-info-static-member.cpp b/test/CodeGenCXX/debug-info-static-member.cpp index 18fd691..8e5207d 100644 --- a/test/CodeGenCXX/debug-info-static-member.cpp +++ b/test/CodeGenCXX/debug-info-static-member.cpp @@ -33,20 +33,57 @@ int main() // why the definition of "a" comes before the declarations while // "b" and "c" come after. -// CHECK: !"_ZTS1X"} ; [ DW_TAG_enumeration_type ] [X] -// CHECK: !"_ZTS1C"} ; [ DW_TAG_class_type ] [C] -// CHECK: ![[DECL_A:[0-9]+]] = {{.*}} [ DW_TAG_member ] [a] [line {{.*}}, size 0, align 0, offset 0] [static] -// CHECK: !"0xd\00const_a\00{{.*}}", {{.*}}, i1 true} ; [ DW_TAG_member ] [const_a] [line {{.*}}, size 0, align 0, offset 0] [static] -// CHECK: ![[DECL_B:[0-9]+]] = !{!"0xd\00b\00{{.*}}", {{.*}} [ DW_TAG_member ] [b] [line {{.*}}, size 0, align 0, offset 0] [protected] [static] -// CHECK: !"0xd\00const_b\00{{.*}}", {{.*}}, float 0x{{.*}}} ; [ DW_TAG_member ] [const_b] [line {{.*}}, size 0, align 0, offset 0] [protected] [static] -// CHECK: ![[DECL_C:[0-9]+]] = !{!"0xd\00c\00{{.*}}", {{.*}} [ DW_TAG_member ] [c] [line {{.*}}, size 0, align 0, offset 0] [public] [static] -// CHECK: !"0xd\00const_c\00{{.*}}", {{.*}} [ DW_TAG_member ] [const_c] [line {{.*}}, size 0, align 0, offset 0] [public] [static] -// CHECK: !"0xd\00x_a\00{{.*}}", {{.*}} [ DW_TAG_member ] [x_a] {{.*}} [public] [static] - -// CHECK: ; [ DW_TAG_structure_type ] [static_decl_templ<int>] {{.*}} [def] -// CHECK: ; [ DW_TAG_member ] [static_decl_templ_var] - -// CHECK: [[NS_X:![0-9]+]] = {{.*}} ; [ DW_TAG_namespace ] [x] +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "X"{{.*}}, identifier: "_ZTS1X") +// CHECK: !DICompositeType(tag: DW_TAG_class_type, name: "C"{{.*}}, identifier: "_ZTS1C") +// +// CHECK: ![[DECL_A:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "a" +// CHECK-NOT: size: +// CHECK-NOT: align: +// CHECK-NOT: offset: +// CHECK-SAME: flags: DIFlagStaticMember) +// +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_a" +// CHECK-NOT: size: +// CHECK-NOT: align: +// CHECK-NOT: offset: +// CHECK-SAME: flags: DIFlagStaticMember, +// CHECK-SAME: extraData: i1 true) +// +// CHECK: ![[DECL_B:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "b" +// CHECK-NOT: size: +// CHECK-NOT: align: +// CHECK-NOT: offset: +// CHECK-SAME: flags: DIFlagProtected | DIFlagStaticMember) +// +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_b" +// CHECK-NOT: size: +// CHECK-NOT: align: +// CHECK-NOT: offset: +// CHECK-SAME: flags: DIFlagProtected | DIFlagStaticMember, +// CHECK-SAME: extraData: float 0x{{.*}}) +// +// CHECK: ![[DECL_C:[0-9]+]] = !DIDerivedType(tag: DW_TAG_member, name: "c" +// CHECK-NOT: size: +// CHECK-NOT: align: +// CHECK-NOT: offset: +// CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember) +// +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_c" +// CHECK-NOT: size: +// CHECK-NOT: align: +// CHECK-NOT: offset: +// CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember, +// CHECK-SAME: extraData: i32 18) +// +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x_a" +// CHECK-SAME: flags: DIFlagPublic | DIFlagStaticMember) + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "static_decl_templ<int>" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "static_decl_templ_var" + +// CHECK: [[NS_X:![0-9]+]] = !DINamespace(name: "x" // Test this in an anonymous namespace to ensure the type is retained even when // it doesn't get automatically retained by the string type reference machinery. @@ -57,8 +94,8 @@ struct anon_static_decl_struct { } -// CHECK: ; [ DW_TAG_structure_type ] [anon_static_decl_struct] {{.*}} [def] -// CHECK: ; [ DW_TAG_member ] [anon_static_decl_var] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "anon_static_decl_struct" +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "anon_static_decl_var" int ref() { return anon_static_decl_struct::anon_static_decl_var; @@ -76,11 +113,11 @@ int static_decl_templ_ref() { return static_decl_templ<int>::static_decl_templ_var; } -// CHECK: !"0x34\00a\00{{.*}}", null, {{.*}} @_ZN1C1aE, ![[DECL_A]]} ; [ DW_TAG_variable ] [a] {{.*}} [def] -// CHECK: !"0x34\00b\00{{.*}}", null, {{.*}} @_ZN1C1bE, ![[DECL_B]]} ; [ DW_TAG_variable ] [b] {{.*}} [def] -// CHECK: !"0x34\00c\00{{.*}}", null, {{.*}} @_ZN1C1cE, ![[DECL_C]]} ; [ DW_TAG_variable ] [c] {{.*}} [def] +// CHECK: !DIGlobalVariable(name: "a", {{.*}}variable: i32* @_ZN1C1aE, declaration: ![[DECL_A]]) +// CHECK: !DIGlobalVariable(name: "b", {{.*}}variable: i32* @_ZN1C1bE, declaration: ![[DECL_B]]) +// CHECK: !DIGlobalVariable(name: "c", {{.*}}variable: i32* @_ZN1C1cE, declaration: ![[DECL_C]]) -// CHECK-NOT: ; [ DW_TAG_variable ] [anon_static_decl_var] +// CHECK-NOT: !DIGlobalVariable(name: "anon_static_decl_var" // Verify that even when a static member declaration is created lazily when // creating the definition, the declaration line is that of the canonical @@ -91,7 +128,9 @@ struct V { virtual ~V(); // cause the definition of 'V' to be omitted by no-standalone-debug optimization static const int const_va = 42; }; -// CHECK: i32 42} ; [ DW_TAG_member ] [const_va] [line [[@LINE-2]], +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "const_va", +// CHECK-SAME: line: [[@LINE-3]] +// CHECK-SAME: extraData: i32 42 const int V::const_va; namespace x { @@ -101,4 +140,5 @@ struct y { int y::z; } -// CHECK: !"0x34\00z\00{{.*}}", [[NS_X]], {{.*}} ; [ DW_TAG_variable ] [z] {{.*}} [def] +// CHECK: !DIGlobalVariable(name: "z", +// CHECK-SAME: scope: [[NS_X]] diff --git a/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp b/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp index 4613038..4dadc4f 100644 --- a/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp +++ b/test/CodeGenCXX/debug-info-template-explicit-specialization.cpp @@ -4,20 +4,22 @@ // type info at all. // RUN: %clang_cc1 -emit-llvm -triple %itanium_abi_triple -g %s -o - -gline-tables-only | FileCheck %s -check-prefix LINES-ONLY -// LINES-ONLY-NOT: DW_TAG_structure_type +// LINES-ONLY-NOT: !DICompositeType(tag: DW_TAG_structure_type template <typename T> struct a { }; extern template class a<int>; -// CHECK-NOT: ; [ DW_TAG_structure_type ] [a<int>] +// CHECK-NOT: DICompositeType(tag: DW_TAG_structure_type, name: "a<int>" template <typename T> struct b { }; extern template class b<int>; b<int> bi; -// CHECK: ; [ DW_TAG_structure_type ] [b<int>] {{.*}} [def] +// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "b<int>" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} template <typename T> struct c { @@ -25,7 +27,8 @@ struct c { }; extern template class c<int>; c<int> ci; -// CHECK: ; [ DW_TAG_structure_type ] [c<int>] {{.*}} [decl] +// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "c<int>" +// CHECK-SAME: DIFlagFwdDecl template <typename T> struct d { @@ -33,7 +36,9 @@ struct d { }; extern template class d<int>; d<int> di; -// CHECK: ; [ DW_TAG_structure_type ] [d<int>] {{.*}} [def] +// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "d<int>" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} template <typename T> struct e { @@ -47,7 +52,9 @@ e<int> ei; // There's no guarantee that the out of line definition will appear before the // explicit template instantiation definition, so conservatively emit the type // definition here. -// CHECK: ; [ DW_TAG_structure_type ] [e<int>] {{.*}} [def] +// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "e<int>" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} template <typename T> struct f { @@ -58,7 +65,9 @@ template <typename T> void f<T>::g() { } f<int> fi; -// CHECK: ; [ DW_TAG_structure_type ] [f<int>] {{.*}} [def] +// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "f<int>" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} template <typename T> struct g { @@ -68,13 +77,17 @@ template <> void g<int>::f(); extern template class g<int>; g<int> gi; -// CHECK: ; [ DW_TAG_structure_type ] [g<int>] {{.*}} [def] +// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "g<int>" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} template <typename T> struct h { }; template class h<int>; -// CHECK: ; [ DW_TAG_structure_type ] [h<int>] {{.*}} [def] +// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "h<int>" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} template <typename T> struct i { @@ -83,14 +96,16 @@ struct i { template<> void i<int>::f(); extern template class i<int>; i<int> ii; -// CHECK: ; [ DW_TAG_structure_type ] [i<int>] {{.*}} [def] +// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "i<int>" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} template <typename T1, typename T2 = T1> struct j { }; extern template class j<int>; j<int> jj; -// CHECK: ; [ DW_TAG_structure_type ] [j<int, int>] +// CHECK: DICompositeType(tag: DW_TAG_structure_type, name: "j<int, int>" template <typename T> struct k { @@ -98,4 +113,4 @@ struct k { template <> struct k<int>; template struct k<int>; -// CHECK-NOT: ; [ DW_TAG_structure_type ] [k<int>] +// CHECK-NOT: !DICompositeType(tag: DW_TAG_structure_type, name: "k<int>" diff --git a/test/CodeGenCXX/debug-info-template-fwd.cpp b/test/CodeGenCXX/debug-info-template-fwd.cpp index b2b7073..25daabc 100644 --- a/test/CodeGenCXX/debug-info-template-fwd.cpp +++ b/test/CodeGenCXX/debug-info-template-fwd.cpp @@ -2,7 +2,9 @@ // This test is for a crash when emitting debug info for not-yet-completed // types. // Test that we don't actually emit a forward decl for the offending class: -// CHECK: [ DW_TAG_structure_type ] [Derived<int>] {{.*}} [def] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "Derived<int>" +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: ){{$}} // rdar://problem/15931354 template <class A> class Derived; diff --git a/test/CodeGenCXX/debug-info-template-limit.cpp b/test/CodeGenCXX/debug-info-template-limit.cpp index 8e05c7f..2b49303 100644 --- a/test/CodeGenCXX/debug-info-template-limit.cpp +++ b/test/CodeGenCXX/debug-info-template-limit.cpp @@ -1,8 +1,8 @@ // RUN: %clang_cc1 -emit-llvm -fno-standalone-debug -triple %itanium_abi_triple -g %s -o - | FileCheck %s // Check that this pointer type is TC<int> -// CHECK: ![[LINE:[0-9]+]] = !{!"0x2\00TC<int>\00{{.*}}", {{.*}} !"_ZTS2TCIiE"} ; [ DW_TAG_class_type ] -// CHECK: !"_ZTS2TCIiE"} ; [ DW_TAG_pointer_type ]{{.*}}[from _ZTS2TCIiE] +// CHECK: ![[LINE:[0-9]+]] = !DICompositeType(tag: DW_TAG_class_type, name: "TC<int>"{{.*}}, identifier: "_ZTS2TCIiE") +// CHECK: !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS2TCIiE" template<typename T> class TC { diff --git a/test/CodeGenCXX/debug-info-template-member.cpp b/test/CodeGenCXX/debug-info-template-member.cpp index 300b6db..dee82dc 100644 --- a/test/CodeGenCXX/debug-info-template-member.cpp +++ b/test/CodeGenCXX/debug-info-template-member.cpp @@ -16,34 +16,49 @@ inline int add3(int x) { return MyClass().add<3>(x); // even though add<3> is ODR used, don't emit it since we don't codegen it } -// CHECK: [[FOO_MEM:![0-9]*]], null, null, !"_ZTS3foo"} ; [ DW_TAG_structure_type ] [foo] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo" +// CHECK-SAME: elements: [[FOO_MEM:![0-9]*]] +// CHECK-SAME: identifier: "_ZTS3foo" // CHECK: [[FOO_MEM]] = !{[[FOO_FUNC:![0-9]*]]} -// CHECK: [[FOO_FUNC]] = !{!"0x2e\00func\00func\00_ZN3foo4funcEN5outerIS_E5innerE\00{{.*}}"{{, [^,]+, [^,]+}}, [[FOO_FUNC_TYPE:![0-9]*]], {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [func] -// CHECK: [[FOO_FUNC_TYPE]] = {{.*}}, [[FOO_FUNC_PARAMS:![0-9]*]], null, null, null} ; [ DW_TAG_subroutine_type ] +// CHECK: [[FOO_FUNC]] = !DISubprogram(name: "func", linkageName: "_ZN3foo4funcEN5outerIS_E5innerE", +// CHECK-SAME: type: [[FOO_FUNC_TYPE:![0-9]*]] +// CHECK: [[FOO_FUNC_TYPE]] = !DISubroutineType(types: [[FOO_FUNC_PARAMS:![0-9]*]]) // CHECK: [[FOO_FUNC_PARAMS]] = !{null, !{{[0-9]*}}, !"[[OUTER_FOO_INNER_ID:.*]]"} -// CHECK: !{{[0-9]*}} = {{.*}}, null, !"[[OUTER_FOO_INNER_ID]]"} ; [ DW_TAG_structure_type ] [inner] +// CHECK: !{{[0-9]*}} = !DICompositeType(tag: DW_TAG_structure_type, name: "inner"{{.*}}, identifier: "[[OUTER_FOO_INNER_ID]]") -// CHECK: [[VIRT_MEM:![0-9]*]], !"_ZTS4virtI4elemE", [[VIRT_TEMP_PARAM:![0-9]*]], !"_ZTS4virtI4elemE"} ; [ DW_TAG_structure_type ] [virt<elem>] {{.*}} [def] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "virt<elem>" +// CHECK-SAME: elements: [[VIRT_MEM:![0-9]*]] +// CHECK-SAME: vtableHolder: !"_ZTS4virtI4elemE" +// CHECK-SAME: templateParams: [[VIRT_TEMP_PARAM:![0-9]*]] +// CHECK-SAME: identifier: "_ZTS4virtI4elemE" // CHECK: [[VIRT_TEMP_PARAM]] = !{[[VIRT_T:![0-9]*]]} -// CHECK: [[VIRT_T]] = !{!"0x2f\00T\000\000"{{, [^,]+}}, !"_ZTS4elem", {{.*}} ; [ DW_TAG_template_type_parameter ] +// CHECK: [[VIRT_T]] = !DITemplateTypeParameter(name: "T", type: !"_ZTS4elem") -// CHECK: [[C:![0-9]*]] = {{.*}}, [[C_MEM:![0-9]*]], !"_ZTS7MyClass", null, !"_ZTS7MyClass"} ; [ DW_TAG_structure_type ] [MyClass] +// CHECK: [[C:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "MyClass" +// CHECK-SAME: elements: [[C_MEM:![0-9]*]] +// CHECK-SAME: vtableHolder: !"_ZTS7MyClass" +// CHECK-SAME: identifier: "_ZTS7MyClass") // CHECK: [[C_MEM]] = !{[[C_VPTR:![0-9]*]], [[C_FUNC:![0-9]*]]} -// CHECK: [[C_VPTR]] = {{.*}} ; [ DW_TAG_member ] [_vptr$MyClass] +// CHECK: [[C_VPTR]] = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$MyClass" -// CHECK: [[C_FUNC]] = {{.*}} ; [ DW_TAG_subprogram ] [line 7] [func] +// CHECK: [[C_FUNC]] = !DISubprogram(name: "func",{{.*}} line: 7, -// CHECK: [[ELEM:![0-9]*]] = {{.*}}, [[ELEM_MEM:![0-9]*]], null, null, !"_ZTS4elem"} ; [ DW_TAG_structure_type ] [elem] {{.*}} [def] +// CHECK: [[ELEM:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "elem" +// CHECK-SAME: elements: [[ELEM_MEM:![0-9]*]] +// CHECK-SAME: identifier: "_ZTS4elem" // CHECK: [[ELEM_MEM]] = !{[[ELEM_X:![0-9]*]]} -// CHECK: [[ELEM_X]] = {{.*}} ; [ DW_TAG_member ] [x] {{.*}} [static] [from _ZTS4virtI4elemE] +// CHECK: [[ELEM_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x", scope: !"_ZTS4elem" +// CHECK-SAME: baseType: !"_ZTS4virtI4elemE" // Check that the member function template specialization and implicit special // members (the default ctor) refer to their class by scope, even though they // didn't appear in the class's member list (C_MEM). This prevents the functions // from being added to type units, while still appearing in the type // declaration/reference in the compile unit. -// CHECK: !"_ZTS7MyClass", {{.*}} ; [ DW_TAG_subprogram ] [line 4] [add<2>] -// CHECK: !"_ZTS7MyClass", {{.*}} ; [ DW_TAG_subprogram ] [line 0] [MyClass] +// CHECK: !DISubprogram(name: "MyClass" +// CHECK-SAME: scope: !"_ZTS7MyClass" +// CHECK: !DISubprogram(name: "add<2>" +// CHECK-SAME: scope: !"_ZTS7MyClass" template<typename T> struct outer { @@ -65,7 +80,9 @@ inline void func() { outer<foo>::inner x; -// CHECK: !"0x34\00{{.*}}", {{.*}}, !"[[OUTER_FOO_INNER_ID]]", %"struct.outer<foo>::inner"* @x, {{.*}} ; [ DW_TAG_variable ] [x] +// CHECK: !DIGlobalVariable(name: "x", +// CHECK-SAME: type: !"[[OUTER_FOO_INNER_ID]]" +// CHECK-SAME: variable: %"struct.outer<foo>::inner"* @x template <typename T> struct virt { diff --git a/test/CodeGenCXX/debug-info-template-partial-specialization.cpp b/test/CodeGenCXX/debug-info-template-partial-specialization.cpp index 6940c0f..c184f04 100644 --- a/test/CodeGenCXX/debug-info-template-partial-specialization.cpp +++ b/test/CodeGenCXX/debug-info-template-partial-specialization.cpp @@ -3,7 +3,9 @@ namespace __pointer_type_imp { template <class _Tp, class _Dp, bool > struct __pointer_type1 {}; - // CHECK: ![[PARAMS:[0-9]+]], !"_ZTSN18__pointer_type_imp15__pointer_type1I1C14default_deleteIS1_ELb0EEE"} ; [ DW_TAG_structure_type ] [__pointer_type1<C, default_delete<C>, false>] [line [[@LINE+1]], size 8, align 8, offset 0] [def] [from ] + // CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "__pointer_type1<C, default_delete<C>, false>", + // CHECK-SAME: templateParams: ![[PARAMS:[0-9]+]] + // CHECK-SAME: identifier: "_ZTSN18__pointer_type_imp15__pointer_type1I1C14default_deleteIS1_ELb0EEE" template <class _Tp, class _Dp> struct __pointer_type1<_Tp, _Dp, false> { typedef _Tp* type; @@ -15,7 +17,7 @@ struct __pointer_type2 // Test that the bool template type parameter is emitted. // // CHECK: ![[PARAMS]] = !{!{{.*}}, !{{.*}}, ![[FALSE:[0-9]+]]} - // CHECK: ![[FALSE]] = {{.*}} i8 0, {{.*}}} ; [ DW_TAG_template_value_parameter ] + // CHECK: ![[FALSE]] = !DITemplateValueParameter(type: !{{[0-9]+}}, value: i8 0) typedef typename __pointer_type_imp::__pointer_type1<_Tp, _Dp, false>::type type; }; template <class _Tp> struct default_delete {}; diff --git a/test/CodeGenCXX/debug-info-template-quals.cpp b/test/CodeGenCXX/debug-info-template-quals.cpp index 15c096f..1f24911 100644 --- a/test/CodeGenCXX/debug-info-template-quals.cpp +++ b/test/CodeGenCXX/debug-info-template-quals.cpp @@ -15,13 +15,17 @@ void foo (const char *c) { str.assign(c, str); } -// CHECK: [[BS:.*]] = {{.*}} ; [ DW_TAG_structure_type ] [basic_string<char>] [line 4, size 8, align 8, offset 0] [def] [from ] -// CHECK: [[TYPE:![0-9]*]] = !{!"0x15\00{{.*}}"{{.*}}, [[ARGS:.*]], null, null, null} ; [ DW_TAG_subroutine_type ] +// CHECK: [[BS:.*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "basic_string<char>" +// CHECK-SAME: line: 4 +// CHECK-SAME: size: 8, align: 8 +// CHECK: [[TYPE:![0-9]*]] = !DISubroutineType(types: [[ARGS:.*]]) // CHECK: [[ARGS]] = !{!{{.*}}, !{{.*}}, [[P:![0-9]*]], [[R:.*]]} -// CHECK: [[P]] = {{.*}}, [[CON:![0-9]*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ] -// CHECK: [[CON]] = {{.*}}, [[CH:![0-9]*]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from char] -// CHECK: [[CH]] = {{.*}} ; [ DW_TAG_base_type ] [char] [line 0, size 8, align 8, offset 0, enc DW_ATE_signed_char] +// CHECK: [[P]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[CON:![0-9]*]] +// CHECK: [[CON]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: [[CH:![0-9]*]] +// CHECK: [[CH]] = !DIBasicType(name: "char", size: 8, align: 8, encoding: DW_ATE_signed_char) -// CHECK: [[R]] = {{.*}}, [[CON2:![0-9]*]]} ; [ DW_TAG_reference_type ] [line 0, size 0, align 0, offset 0] [from ] -// CHECK: [[CON2]] = {{.*}}, !"_ZTS12basic_stringIcE"} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from _ZTS12basic_stringIcE] -// CHECK: !"0x2e\00assign\00{{.*}}\008"{{, [^,]+, [^,]+}}, !8, {{.*}} ; [ DW_TAG_subprogram ] [line 7] [def] [scope 8] [assign] +// CHECK: [[R]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: [[CON2:![0-9]*]] +// CHECK: [[CON2]] = !DIDerivedType(tag: DW_TAG_const_type, baseType: !"_ZTS12basic_stringIcE" +// CHECK: !DISubprogram(name: "assign" +// CHECK-SAME: line: 7 +// CHECK-SAME: scopeLine: 8 diff --git a/test/CodeGenCXX/debug-info-template.cpp b/test/CodeGenCXX/debug-info-template.cpp index 17b9450..74adef9 100644 --- a/test/CodeGenCXX/debug-info-template.cpp +++ b/test/CodeGenCXX/debug-info-template.cpp @@ -1,96 +1,112 @@ // RUN: %clang -S -emit-llvm -target x86_64-unknown_unknown -g %s -o - -std=c++11 | FileCheck %s -// CHECK: !"0x11\00{{.*}}"{{, [^,]+, [^,]+}}, [[RETAIN:![0-9]*]], {{.*}} ; [ DW_TAG_compile_unit ] +// CHECK: !DICompileUnit( +// CHECK-SAME: retainedTypes: [[RETAIN:![0-9]*]] // CHECK: [[EMPTY:![0-9]*]] = !{} // CHECK: [[RETAIN]] = !{!{{[0-9]]*}}, [[FOO:![0-9]*]], -// CHECK: [[TC:![0-9]*]] = {{.*}}, [[TCARGS:![0-9]*]], !"{{.*}}"} ; [ DW_TAG_structure_type ] [TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>] +// CHECK: [[TC:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>" +// CHECK-SAME: templateParams: [[TCARGS:![0-9]*]] // CHECK: [[TCARGS]] = !{[[TCARG1:![0-9]*]], [[TCARG2:![0-9]*]], [[TCARG3:![0-9]*]], [[TCARG4:![0-9]*]], [[TCARG5:![0-9]*]], [[TCARG6:![0-9]*]], [[TCARG7:![0-9]*]]} // -// We seem to be missing file/line/col info on template value parameters - -// metadata supports it but it's not populated. GCC doesn't emit it either, -// perhaps we should just drop it from the metadata. -// -// CHECK: [[TCARG1]] = !{!"0x2f\00T\000\000", null, [[UINT:![0-9]*]], null} ; [ DW_TAG_template_type_parameter ] -// CHECK: [[UINT:![0-9]*]] = {{.*}} ; [ DW_TAG_base_type ] [unsigned int] -// CHECK: [[TCARG2]] = !{!"0x30\00\00{{.*}}", {{[^,]+}}, [[UINT]], i32 2, {{.*}} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[TCARG3]] = !{!"0x30\00x\00{{.*}}", {{[^,]+}}, [[CINTPTR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[CINTPTR]] = {{.*}}, [[CINT:![0-9]*]]} ; [ DW_TAG_pointer_type ] {{.*}} [from ] -// CHECK: [[CINT]] = {{.*}}, [[INT:![0-9]*]]} ; [ DW_TAG_const_type ] {{.*}} [from int] -// CHECK: [[INT]] = {{.*}} ; [ DW_TAG_base_type ] [int] -// CHECK: [[TCARG4]] = !{!"0x30\00a\00{{.*}}", {{[^,]+}}, [[MEMINTPTR:![0-9]*]], i64 8, {{.*}} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[MEMINTPTR]] = {{.*}}, !"_ZTS3foo"} ; [ DW_TAG_ptr_to_member_type ] {{.*}}[from int] +// CHECK: [[TCARG1]] = !DITemplateTypeParameter(name: "T", type: [[UINT:![0-9]*]]) +// CHECK: [[UINT:![0-9]*]] = !DIBasicType(name: "unsigned int" +// CHECK: [[TCARG2]] = !DITemplateValueParameter(type: [[UINT]], value: i32 2) +// CHECK: [[TCARG3]] = !DITemplateValueParameter(name: "x", type: [[CINTPTR:![0-9]*]], value: i32* @glb) +// CHECK: [[CINTPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, {{.*}}baseType: [[CINT:![0-9]+]] +// CHECK: [[CINT]] = !DIDerivedType(tag: DW_TAG_const_type, {{.*}}baseType: [[INT:![0-9]+]] +// CHECK: [[INT]] = !DIBasicType(name: "int" +// CHECK: [[TCARG4]] = !DITemplateValueParameter(name: "a", type: [[MEMINTPTR:![0-9]*]], value: i64 8) +// CHECK: [[MEMINTPTR]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, {{.*}}baseType: [[INT]], {{.*}}extraData: !"_ZTS3foo") // // Currently Clang emits the pointer-to-member-function value, but LLVM doesn't // use it (GCC doesn't emit a value for pointers to member functions either - so // it's not clear what, if any, format would be acceptable to GDB) // -// CHECK: [[TCARG5]] = !{!"0x30\00b\00{{.*}}", {{[^,]+}}, [[MEMFUNPTR:![0-9]*]], { i64, i64 } { i64 ptrtoint (void (%struct.foo*)* @_ZN3foo1fEv to i64), i64 0 }, {{.*}} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[MEMFUNPTR]] = {{.*}}, [[FTYPE:![0-9]*]], !"_ZTS3foo"} ; [ DW_TAG_ptr_to_member_type ] -// CHECK: [[FTYPE]] = {{.*}}, [[FARGS:![0-9]*]], null, null, null} ; [ DW_TAG_subroutine_type ] +// CHECK: [[TCARG5]] = !DITemplateValueParameter(name: "b", type: [[MEMFUNPTR:![0-9]*]], value: { i64, i64 } { i64 ptrtoint (void (%struct.foo*)* @_ZN3foo1fEv to i64), i64 0 }) +// CHECK: [[MEMFUNPTR]] = !DIDerivedType(tag: DW_TAG_ptr_to_member_type, {{.*}}baseType: [[FTYPE:![0-9]*]], {{.*}}extraData: !"_ZTS3foo") +// CHECK: [[FTYPE]] = !DISubroutineType(types: [[FARGS:![0-9]*]]) // CHECK: [[FARGS]] = !{null, [[FARG1:![0-9]*]]} -// CHECK: [[FARG1]] = {{.*}} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [artificial] [from _ZTS3foo] +// CHECK: [[FARG1]] = !DIDerivedType(tag: DW_TAG_pointer_type, +// CHECK-SAME: baseType: !"_ZTS3foo" +// CHECK-NOT: line: +// CHECK-SAME: size: 64, align: 64 +// CHECK-NOT: offset: 0 +// CHECK-SAME: DIFlagArtificial // -// CHECK: [[TCARG6]] = !{!"0x30\00f\00{{.*}}", {{[^,]+}}, [[FUNPTR:![0-9]*]], void ()* @_ZN3foo1gEv, {{.*}} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[FUNPTR]] = {{.*}}, [[FUNTYPE:![0-9]*]]} ; [ DW_TAG_pointer_type ] -// CHECK: [[FUNTYPE]] = {{.*}}, [[FUNARGS:![0-9]*]], null, null, null} ; [ DW_TAG_subroutine_type ] +// CHECK: [[TCARG6]] = !DITemplateValueParameter(name: "f", type: [[FUNPTR:![0-9]*]], value: void ()* @_ZN3foo1gEv) +// CHECK: [[FUNPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[FUNTYPE:![0-9]*]] +// CHECK: [[FUNTYPE]] = !DISubroutineType(types: [[FUNARGS:![0-9]*]]) // CHECK: [[FUNARGS]] = !{null} -// CHECK: [[TCARG7]] = !{!"0x4107\00Is\000\000", null, null, [[TCARG7_VALS:![0-9]*]], null} ; [ DW_TAG_GNU_template_parameter_pack ] +// CHECK: [[TCARG7]] = !DITemplateValueParameter(tag: DW_TAG_GNU_template_parameter_pack, name: "Is", value: [[TCARG7_VALS:![0-9]*]]) // CHECK: [[TCARG7_VALS]] = !{[[TCARG7_1:![0-9]*]], [[TCARG7_2:![0-9]*]], [[TCARG7_3:![0-9]*]]} -// CHECK: [[TCARG7_1]] = !{!"0x30\00\00{{.*}}", {{[^,]+}}, [[INT]], i32 1, {{.*}} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[TCARG7_2]] = !{!"0x30\00\00{{.*}}", {{[^,]+}}, [[INT]], i32 2, {{.*}} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[TCARG7_3]] = !{!"0x30\00\00{{.*}}", {{[^,]+}}, [[INT]], i32 3, {{.*}} ; [ DW_TAG_template_value_parameter ] +// CHECK: [[TCARG7_1]] = !DITemplateValueParameter(type: [[INT]], value: i32 1) +// CHECK: [[TCARG7_2]] = !DITemplateValueParameter(type: [[INT]], value: i32 2) +// CHECK: [[TCARG7_3]] = !DITemplateValueParameter(type: [[INT]], value: i32 3) // // We could just emit a declaration of 'foo' here, rather than the entire // definition (same goes for any time we emit a member (function or data) // pointer type) -// CHECK: [[FOO]] = {{.*}}, !"_ZTS3foo"} ; [ DW_TAG_structure_type ] [foo] -// CHECK: !"0x2e\00f\00f\00_ZN3foo1fEv\00{{.*}}", [[FTYPE:![0-9]*]], {{.*}} ; [ DW_TAG_subprogram ] +// CHECK: [[FOO]] = !DICompositeType(tag: DW_TAG_structure_type, name: "foo", {{.*}}identifier: "_ZTS3foo") +// CHECK: !DISubprogram(name: "f", linkageName: "_ZN3foo1fEv", {{.*}}type: [[FTYPE:![0-9]*]] // -// CHECK: !"0x13\00{{.*}}", !{{[0-9]*}}, !"_ZTS2TCIjLj2EXadL_Z3glbEEXadL_ZN3foo1eEEEXadL_ZNS0_1fEvEEXadL_ZNS0_1gEvEEJLi1ELi2ELi3EEE", {{.*}}, !"[[TCNESTED:.*]]"} ; [ DW_TAG_structure_type ] [nested] -// CHECK: [[TCNARGS:![0-9]*]], !"[[TCNT:.*]]"} ; [ DW_TAG_structure_type ] [TC<int, -3, nullptr, nullptr, nullptr, nullptr>] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "nested", +// CHECK-SAME: scope: !"_ZTS2TCIjLj2EXadL_Z3glbEEXadL_ZN3foo1eEEEXadL_ZNS0_1fEvEEXadL_ZNS0_1gEvEEJLi1ELi2ELi3EEE" +// CHECK-SAME: identifier: "[[TCNESTED:.*]]") +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "TC<int, -3, nullptr, nullptr, nullptr, nullptr>" +// CHECK-SAME: templateParams: [[TCNARGS:![0-9]*]] +// CHECK-SAME: identifier: "[[TCNT:.*]]") // CHECK: [[TCNARGS]] = !{[[TCNARG1:![0-9]*]], [[TCNARG2:![0-9]*]], [[TCNARG3:![0-9]*]], [[TCNARG4:![0-9]*]], [[TCNARG5:![0-9]*]], [[TCNARG6:![0-9]*]], [[TCNARG7:![0-9]*]]} -// CHECK: [[TCNARG1]] = !{!"0x2f\00T\000\000", null, [[INT]], null} ; [ DW_TAG_template_type_parameter ] -// CHECK: [[TCNARG2]] = !{!"0x30\00\000\000", null, [[INT]], i32 -3, null} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[TCNARG3]] = !{!"0x30\00x\000\000", null, [[CINTPTR]], i8 0, null} ; [ DW_TAG_template_value_parameter ] +// CHECK: [[TCNARG1]] = !DITemplateTypeParameter(name: "T", type: [[INT]]) +// CHECK: [[TCNARG2]] = !DITemplateValueParameter(type: [[INT]], value: i32 -3) +// CHECK: [[TCNARG3]] = !DITemplateValueParameter(name: "x", type: [[CINTPTR]], value: i8 0) // The interesting null pointer: -1 for member data pointers (since they are // just an offset in an object, they can be zero and non-null for the first // member) -// CHECK: [[TCNARG4]] = !{!"0x30\00a\000\000", null, [[MEMINTPTR]], i64 -1, null} ; [ DW_TAG_template_value_parameter ] +// CHECK: [[TCNARG4]] = !DITemplateValueParameter(name: "a", type: [[MEMINTPTR]], value: i64 -1) // // In some future iteration we could possibly emit the value of a null member // function pointer as '{ i64, i64 } zeroinitializer' as it may be handled // naturally from the LLVM CodeGen side once we decide how to handle non-null // member function pointers. For now, it's simpler just to emit the 'i8 0'. // -// CHECK: [[TCNARG5]] = !{!"0x30\00b\000\000", null, [[MEMFUNPTR]], i8 0, null} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[TCNARG6]] = !{!"0x30\00f\000\000", null, [[FUNPTR]], i8 0, null} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[TCNARG7]] = !{!"0x4107\00Is\000\000", null, null, [[EMPTY]], null} ; [ DW_TAG_GNU_template_parameter_pack ] +// CHECK: [[TCNARG5]] = !DITemplateValueParameter(name: "b", type: [[MEMFUNPTR]], value: i8 0) +// CHECK: [[TCNARG6]] = !DITemplateValueParameter(name: "f", type: [[FUNPTR]], value: i8 0) +// CHECK: [[TCNARG7]] = !DITemplateValueParameter(tag: DW_TAG_GNU_template_parameter_pack, name: "Is", value: [[EMPTY]]) // FIXME: these parameters should probably be rendered as 'glb' rather than // '&glb', since they're references, not pointers. -// CHECK: [[NNARGS:![0-9]*]], !"[[NNT:.*]]"} ; [ DW_TAG_structure_type ] [NN<tmpl_impl, &glb, &glb>] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "NN<tmpl_impl, &glb, &glb>", +// CHECK-SAME: templateParams: [[NNARGS:![0-9]*]] +// CHECK-SAME: identifier: "[[NNT:.*]]") // CHECK: [[NNARGS]] = !{[[NNARG1:![0-9]*]], [[NNARG2:![0-9]*]], [[NNARG3:![0-9]*]]} -// CHECK: [[NNARG1]] = !{!"0x4106\00tmpl\000\000", null, null, !"tmpl_impl", null} ; [ DW_TAG_GNU_template_template_param ] -// CHECK: [[NNARG2]] = !{!"0x30\00lvr\00{{.*}}", {{[^,]+}}, [[INTLVR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[INTLVR]] = {{.*}}, [[INT]]} ; [ DW_TAG_reference_type ] {{.*}} [from int] -// CHECK: [[NNARG3]] = !{!"0x30\00rvr\00{{.*}}", {{[^,]+}}, [[INTRVR:![0-9]*]], i32* @glb, {{.*}} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[INTRVR]] = {{.*}}, [[INT]]} ; [ DW_TAG_rvalue_reference_type ] {{.*}} [from int] - -// CHECK: [[PTOARGS:![0-9]*]], !"{{.*}}"} ; [ DW_TAG_structure_type ] [PaddingAtEndTemplate<&PaddedObj>] +// CHECK: [[NNARG1]] = !DITemplateValueParameter(tag: DW_TAG_GNU_template_template_param, name: "tmpl", value: !"tmpl_impl") +// CHECK: [[NNARG2]] = !DITemplateValueParameter(name: "lvr", type: [[INTLVR:![0-9]*]], value: i32* @glb) +// CHECK: [[INTLVR]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: [[INT]] +// CHECK: [[NNARG3]] = !DITemplateValueParameter(name: "rvr", type: [[INTRVR:![0-9]*]], value: i32* @glb) +// CHECK: [[INTRVR]] = !DIDerivedType(tag: DW_TAG_rvalue_reference_type, baseType: [[INT]] + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "PaddingAtEndTemplate<&PaddedObj>" +// CHECK-SAME: templateParams: [[PTOARGS:![0-9]*]] // CHECK: [[PTOARGS]] = !{[[PTOARG1:![0-9]*]]} -// CHECK: [[PTOARG1]] = !{!"0x30\00\000\000", null, [[CONST_PADDINGATEND_PTR:![0-9]*]], %struct.PaddingAtEnd* @PaddedObj, null} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[CONST_PADDINGATEND_PTR]] = {{.*}} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from _ZTS12PaddingAtEnd] +// CHECK: [[PTOARG1]] = !DITemplateValueParameter(type: [[CONST_PADDINGATEND_PTR:![0-9]*]], value: %struct.PaddingAtEnd* @PaddedObj) +// CHECK: [[CONST_PADDINGATEND_PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !"_ZTS12PaddingAtEnd", size: 64, align: 64) -// CHECK: !"[[TCNESTED]]", %"struct.TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>::nested"* @tci, null} ; [ DW_TAG_variable ] [tci] +// CHECK: !DIGlobalVariable(name: "tci", +// CHECK-SAME: type: !"[[TCNESTED]]" +// CHECK-SAME: variable: %"struct.TC<unsigned int, 2, &glb, &foo::e, &foo::f, &foo::g, 1, 2, 3>::nested"* @tci -// CHECK: !"[[TCNT]]", %struct.TC* @tcn, null} ; [ DW_TAG_variable ] [tcn] +// CHECK: !DIGlobalVariable(name: "tcn" +// CHECK-SAME: type: !"[[TCNT]]" +// CHECK-SAME: variable: %struct.TC* @tcn -// CHECK: !"[[NNT]]", %struct.NN* @nn, null} ; [ DW_TAG_variable ] [nn] +// CHECK: !DIGlobalVariable(name: "nn" +// CHECK-SAME: type: !"[[NNT]]" +// CHECK-SAME: variable: %struct.NN* @nn struct foo { char pad[8]; // make the member pointer to 'e' a bit more interesting (nonzero) int e; diff --git a/test/CodeGenCXX/debug-info-thunk.cpp b/test/CodeGenCXX/debug-info-thunk.cpp index 9f18790..935110f 100644 --- a/test/CodeGenCXX/debug-info-thunk.cpp +++ b/test/CodeGenCXX/debug-info-thunk.cpp @@ -14,4 +14,7 @@ struct C : A, B { void C::f() { } -// CHECK: !"0x2e\00\00\00_ZThn{{[48]}}_N1C1fEv\0015\00{{.*}}", {{.*}} ; [ DW_TAG_subprogram ] [line 15] [def]{{$}} +// CHECK: !DISubprogram(linkageName: "_ZThn{{[48]}}_N1C1fEv" +// CHECK-SAME: line: 15 +// CHECK-SAME: isDefinition: true +// CHECK-SAME: ){{$}} diff --git a/test/CodeGenCXX/debug-info-union-template.cpp b/test/CodeGenCXX/debug-info-union-template.cpp index aa66e3f..0616d72 100644 --- a/test/CodeGenCXX/debug-info-union-template.cpp +++ b/test/CodeGenCXX/debug-info-union-template.cpp @@ -10,6 +10,8 @@ namespace PR15637 { Value<float> f; } -// CHECK: !"0x17\00Value<float>\00{{.*}}", {{.*}}, [[TTPARAM:![0-9]+]], !"_ZTSN7PR156375ValueIfEE"} ; [ DW_TAG_union_type ] [Value<float>] +// CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "Value<float>", +// CHECK-SAME: templateParams: [[TTPARAM:![0-9]+]] +// CHECK-SAME: identifier: "_ZTSN7PR156375ValueIfEE" // CHECK: [[TTPARAM]] = !{[[PARAMS:.*]]} -// CHECK: [[PARAMS]] = !{!"0x2f\00T\000\000", {{.*}} ; [ DW_TAG_template_type_parameter ] +// CHECK: [[PARAMS]] = !DITemplateTypeParameter(name: "T" diff --git a/test/CodeGenCXX/debug-info-union.cpp b/test/CodeGenCXX/debug-info-union.cpp index 0aa48dc..a81a560 100644 --- a/test/CodeGenCXX/debug-info-union.cpp +++ b/test/CodeGenCXX/debug-info-union.cpp @@ -10,7 +10,11 @@ union E { E e; -// CHECK: {{.*}} ; [ DW_TAG_union_type ] [E] [line 3, size 32, align 32, offset 0] -// CHECK: {{.*}} ; [ DW_TAG_subprogram ] [line 6] [bb] -// CHECK: {{.*}} ; [ DW_TAG_subprogram ] [line 7] [aa] -// CHECK: {{.*}} ; [ DW_TAG_subprogram ] [line 8] [E] +// CHECK: !DICompositeType(tag: DW_TAG_union_type, name: "E" +// CHECK-SAME: line: 3 +// CHECK-SAME: size: 32, align: 32 +// CHECK-NOT: offset: +// CHECK-SAME: {{$}} +// CHECK: !DISubprogram(name: "bb"{{.*}}, line: 6 +// CHECK: !DISubprogram(name: "aa"{{.*}}, line: 7 +// CHECK: !DISubprogram(name: "E"{{.*}}, line: 8 diff --git a/test/CodeGenCXX/debug-info-uuid.cpp b/test/CodeGenCXX/debug-info-uuid.cpp index b7e532b..fd6e31d 100644 --- a/test/CodeGenCXX/debug-info-uuid.cpp +++ b/test/CodeGenCXX/debug-info-uuid.cpp @@ -1,20 +1,33 @@ // RUN: %clang_cc1 -emit-llvm -fms-extensions -triple=x86_64-pc-win32 -g %s -o - -std=c++11 | FileCheck %s // RUN: %clang_cc1 -emit-llvm -fms-extensions -triple=x86_64-unknown-unknown -g %s -o - -std=c++11 2>&1 | FileCheck %s --check-prefix=CHECK-ITANIUM -// CHECK: [[TGIARGS:![0-9]*]], null} ; [ DW_TAG_structure_type ] [tmpl_guid<&__uuidof(uuid)>] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid<&__uuidof(uuid)>" +// CHECK-SAME: templateParams: [[TGIARGS:![0-9]*]] // CHECK: [[TGIARGS]] = !{[[TGIARG1:![0-9]*]]} -// CHECK: [[TGIARG1]] = !{!"0x30\00\00{{.*}}", {{[^,]+}}, [[CONST_GUID_PTR:![0-9]*]], { i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab, {{.*}} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[CONST_GUID_PTR]] = {{.*}}, [[CONST_GUID:![0-9]*]]} ; [ DW_TAG_pointer_type ] [line 0, size 64, align 64, offset 0] [from ] -// CHECK: [[CONST_GUID]] = {{.*}}, [[GUID:![0-9]*]]} ; [ DW_TAG_const_type ] [line 0, size 0, align 0, offset 0] [from _GUID] -// CHECK: [[GUID]] = {{.*}} ; [ DW_TAG_structure_type ] [_GUID] +// CHECK: [[TGIARG1]] = !DITemplateValueParameter( +// CHECK-SAME: type: [[CONST_GUID_PTR:![0-9]*]] +// CHECK-SAME: value: { i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab +// CHECK: [[CONST_GUID_PTR]] = !DIDerivedType(tag: DW_TAG_pointer_type +// CHECK-SAME: baseType: [[CONST_GUID:![0-9]*]] +// CHECK-SAME: size: 64 +// CHECK-SAME: align: 64 +// CHECK: [[CONST_GUID]] = !DIDerivedType(tag: DW_TAG_const_type +// CHECK-SAME: baseType: [[GUID:![0-9]*]] +// CHECK: [[GUID]] = !DICompositeType(tag: DW_TAG_structure_type, name: "_GUID" -// CHECK: [[TGI2ARGS:![0-9]*]], null} ; [ DW_TAG_structure_type ] [tmpl_guid2<__uuidof(uuid)>] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid2<__uuidof(uuid)>" +// CHECK-SAME: templateParams: [[TGI2ARGS:![0-9]*]] // CHECK: [[TGI2ARGS]] = !{[[TGI2ARG1:![0-9]*]]} -// CHECK: [[TGI2ARG1]] = !{!"0x30\00\00{{.*}}", {{[^,]+}}, [[CONST_GUID_REF:![0-9]*]], { i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab, {{.*}} ; [ DW_TAG_template_value_parameter ] -// CHECK: [[CONST_GUID_REF]] = {{.*}}, [[CONST_GUID:![0-9]*]]} ; [ DW_TAG_reference_type ] [line 0, size 0, align 0, offset 0] [from ] +// CHECK: [[TGI2ARG1]] = !DITemplateValueParameter( +// CHECK-SAME: type: [[CONST_GUID_REF:![0-9]*]] +// CHECK-SAME: value: { i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab +// CHECK: [[CONST_GUID_REF]] = !DIDerivedType(tag: DW_TAG_reference_type, +// CHECK-SAME: baseType: [[CONST_GUID:![0-9]*]] -// CHECK-ITANIUM: !"_ZTS9tmpl_guidIXadu8__uuidoft4uuidEE"} ; [ DW_TAG_structure_type ] [tmpl_guid<&__uuidof(uuid)>] -// CHECK-ITANIUM: !"_ZTS10tmpl_guid2IXu8__uuidoft4uuidEE"} ; [ DW_TAG_structure_type ] [tmpl_guid2<__uuidof(uuid)>] +// CHECK-ITANIUM: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid<&__uuidof(uuid)>" +// CHECK-ITANIUM-SAME: identifier: "_ZTS9tmpl_guidIXadu8__uuidoft4uuidEE" +// CHECK-ITANIUM: !DICompositeType(tag: DW_TAG_structure_type, name: "tmpl_guid2<__uuidof(uuid)>" +// CHECK-ITANIUM-SAME: identifier: "_ZTS10tmpl_guid2IXu8__uuidoft4uuidEE" struct _GUID; template <const _GUID *> diff --git a/test/CodeGenCXX/debug-info-varargs.cpp b/test/CodeGenCXX/debug-info-varargs.cpp index 25e8f35..edcb0e5 100644 --- a/test/CodeGenCXX/debug-info-varargs.cpp +++ b/test/CodeGenCXX/debug-info-varargs.cpp @@ -2,21 +2,27 @@ struct A { - // CHECK-DAG: !"0x2e\00a\00a\00_ZN1A1aEiz\00[[@LINE+1]]\00{{[^,]*}}"{{, [^,]+, [^,]+}}, ![[ATY:[0-9]+]]{{.*}}[ DW_TAG_subprogram ]{{.*}}[a] + // CHECK: !DISubprogram(name: "a", linkageName: "_ZN1A1aEiz" + // CHECK-SAME: line: [[@LINE+2]] + // CHECK-SAME: type: ![[ATY:[0-9]+]] void a(int c, ...) {} - // CHECK: ![[ATY]] ={{.*}} ![[AARGS:[0-9]+]], null, null, null} ; [ DW_TAG_subroutine_type ] + // CHECK: ![[ATY]] = !DISubroutineType(types: ![[AARGS:[0-9]+]]) // We no longer use an explicit unspecified parameter. Instead we use a trailing null to mean the function is variadic. // CHECK: ![[AARGS]] = !{null, !{{[0-9]+}}, !{{[0-9]+}}, null} }; - // CHECK: !"0x2e\00b\00b\00_Z1biz\00[[@LINE+1]]\00{{[^,]*}}"{{, [^,]+, [^,]+}}, ![[BTY:[0-9]+]]{{.*}}[ DW_TAG_subprogram ]{{.*}}[b] + // CHECK: !DISubprogram(name: "b", linkageName: "_Z1biz" + // CHECK-SAME: line: [[@LINE+2]] + // CHECK-SAME: type: ![[BTY:[0-9]+]] void b(int c, ...) { - // CHECK: ![[BTY]] ={{.*}} ![[BARGS:[0-9]+]], null, null, null} ; [ DW_TAG_subroutine_type ] + // CHECK: ![[BTY]] = !DISubroutineType(types: ![[BARGS:[0-9]+]]) // CHECK: ![[BARGS]] = !{null, !{{[0-9]+}}, null} A a; - // CHECK: !"0x100\00fptr\00[[@LINE+1]]\000"{{, [^,]+, [^,]+}}, ![[PST:[0-9]+]]} ; [ DW_TAG_auto_variable ] [fptr] [line [[@LINE+1]]] + // CHECK: !DILocalVariable(tag: DW_TAG_auto_variable, name: "fptr" + // CHECK-SAME: line: [[@LINE+2]] + // CHECK-SAME: type: ![[PST:[0-9]+]] void (*fptr)(int, ...) = b; - // CHECK: ![[PST]] ={{.*}} ![[BTY]]} ; [ DW_TAG_pointer_type ] + // CHECK: ![[PST]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[BTY]], } diff --git a/test/CodeGenCXX/debug-info-vtable-optzn.cpp b/test/CodeGenCXX/debug-info-vtable-optzn.cpp index c693f79..f15571e 100644 --- a/test/CodeGenCXX/debug-info-vtable-optzn.cpp +++ b/test/CodeGenCXX/debug-info-vtable-optzn.cpp @@ -5,7 +5,7 @@ // module that has its vtable" optimization is disabled by default on // Darwin and FreeBSD. // -// CHECK: [ DW_TAG_member ] [lost] +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "lost" class A { virtual bool f() = 0; diff --git a/test/CodeGenCXX/debug-info-wchar.cpp b/test/CodeGenCXX/debug-info-wchar.cpp index 5b5fdcc..bb01f57 100644 --- a/test/CodeGenCXX/debug-info-wchar.cpp +++ b/test/CodeGenCXX/debug-info-wchar.cpp @@ -1,5 +1,5 @@ // RUN: %clang_cc1 -emit-llvm -g %s -o -| FileCheck %s void foo() { -// CHECK: !"0x24\00wchar_t\00{{.*}}", null, null} ; [ DW_TAG_base_type ] [wchar_t] +// CHECK: !DIBasicType(name: "wchar_t" const wchar_t w = L'x'; } diff --git a/test/CodeGenCXX/debug-info-windows-dtor.cpp b/test/CodeGenCXX/debug-info-windows-dtor.cpp index a94f2b0..2f425fd 100644 --- a/test/CodeGenCXX/debug-info-windows-dtor.cpp +++ b/test/CodeGenCXX/debug-info-windows-dtor.cpp @@ -18,5 +18,5 @@ template struct AB<int>; // CHECK: call {{.*}}@"\01??_G?$AB@H@@UAEPAXI@Z"({{.*}}) #{{[0-9]*}}, !dbg [[THUNK_LOC:![0-9]*]] // CHECK-LABEL: define -// CHECK: [[THUNK_VEC_DEL_DTOR:![0-9]*]] = {{.*}} @"\01??_E?$AB@H@@W3AEPAXI@Z", {{.*}}; [ DW_TAG_subprogram ] -// CHECK: [[THUNK_LOC]] = !MDLocation(line: 15, scope: [[THUNK_VEC_DEL_DTOR]]) +// CHECK: [[THUNK_VEC_DEL_DTOR:![0-9]*]] = !DISubprogram({{.*}}function: {{.*}}@"\01??_E?$AB@H@@W3AEPAXI@Z" +// CHECK: [[THUNK_LOC]] = !DILocation(line: 15, scope: [[THUNK_VEC_DEL_DTOR]]) diff --git a/test/CodeGenCXX/debug-info-zero-length-arrays.cpp b/test/CodeGenCXX/debug-info-zero-length-arrays.cpp index f1ba636..dc7558a 100644 --- a/test/CodeGenCXX/debug-info-zero-length-arrays.cpp +++ b/test/CodeGenCXX/debug-info-zero-length-arrays.cpp @@ -6,7 +6,11 @@ class A { }; A a; -// CHECK: [[ARRAY_TYPE:![0-9]*]]} ; [ DW_TAG_member ] [x] -// CHECK: !"0x1\00\000\000\0032\000\000\000", null, null, {{![0-9]+}}, [[ELEM_TYPE:![0-9]+]], null, null, null} ; [ DW_TAG_array_type ] [line 0, size 0, align 32, offset 0] [from int] +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "x" +// CHECK-SAME: baseType: [[ARRAY_TYPE:![0-9]+]] +// CHECK: [[ARRAY_TYPE]] = !DICompositeType(tag: DW_TAG_array_type, +// CHECK-NOT: size: +// CHECK-SAME: align: 32 +// CHECK-SAME: elements: [[ELEM_TYPE:![0-9]+]] // CHECK: [[ELEM_TYPE]] = !{[[SUBRANGE:.*]]} -// CHECK: [[SUBRANGE]] = !{!"0x21\000\00-1"} ; [ DW_TAG_subrange_type ] [unbounded] +// CHECK: [[SUBRANGE]] = !DISubrange(count: -1) diff --git a/test/CodeGenCXX/debug-info.cpp b/test/CodeGenCXX/debug-info.cpp index f4d1f00..13753684 100644 --- a/test/CodeGenCXX/debug-info.cpp +++ b/test/CodeGenCXX/debug-info.cpp @@ -53,17 +53,32 @@ namespace VirtualBase { } } -// MSVC: [[VBASE_B:![0-9]+]] = distinct !{!"0x13\00B\00{{[0-9]+}}\0096\0032\000\000\000", {{.*}}, null, [[VBASE_B_DEF:![0-9]+]], {{.*}}} ; [ DW_TAG_structure_type ] [B] [line 49, size 96, align 32, offset 0] [def] [from ] +// CHECK: define void @_ZN7pr147634funcENS_3fooE +// CHECK: call void @llvm.dbg.declare({{.*}}, metadata ![[F:.*]], metadata ![[EXPR:.*]]) + +// MSVC: [[VBASE_B:![0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "B",{{.*}} line: 49 +// MSVC-SAME: size: 96, align: 32 +// MSVC-NOT: offset: +// MSVC-NOT: DIFlagFwdDecl +// MSVC-SAME: elements: [[VBASE_B_DEF:![0-9]+]] // MSVC: [[VBASE_B_DEF]] = !{[[VBASE_A_IN_B:![0-9]+]], // // Look for the vbtable offset of A, which should be 4. -// MSVC: [[VBASE_A_IN_B]] = !{!"0x1c\00\000\000\000\004\0032", null, [[VBASE_B]], !{{[0-9]*}}} ; [ DW_TAG_inheritance ] [line 0, size 0, align 0, offset 4] [from A] - -// CHECK: !"0x13\00B\00{{[0-9]+}}\00128\0064\000\000\000", {{.*}}, null, [[VBASE_B_DEF:![0-9]+]], {{.*}}} ; [ DW_TAG_structure_type ] [B] [line 49, size 128, align 64, offset 0] [def] [from ] +// MSVC: [[VBASE_A_IN_B]] = !DIDerivedType(tag: DW_TAG_inheritance, scope: [[VBASE_B]], +// MSVC-SAME: baseType: !{{[0-9]*}} + +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "B",{{.*}} line: 49, +// CHECK-SAME: size: 128, align: 64, +// CHECK-NOT: offset: +// CHECK-NOT: DIFlagFwdDecl +// CHECK-SAME: elements: [[VBASE_B_DEF:![^,)]+]] // CHECK: [[VBASE_B_DEF]] = !{[[VBASE_A_IN_B:![0-9]+]], // // Look for the vtable offset offset, which should be -24. -// CHECK: [[VBASE_A_IN_B]] = !{!"0x1c\00\000\000\000\0024\0032", null, !"_ZTSN11VirtualBase1BE", !"_ZTSN11VirtualBase1AE"} ; [ DW_TAG_inheritance ] [line 0, size 0, align 0, offset 24] [from _ZTSN11VirtualBase1AE] +// CHECK: [[VBASE_A_IN_B]] = !DIDerivedType(tag: DW_TAG_inheritance +// CHECK-SAME: scope: !"_ZTSN11VirtualBase1BE" +// CHECK-SAME: baseType: !"_ZTSN11VirtualBase1AE" +// CHECK-SAME: offset: 24, namespace b5249287 { template <typename T> class A { struct B; @@ -85,15 +100,23 @@ foo func(foo f) { return f; // reference 'f' for now because otherwise we hit another bug } -// CHECK: !"0x13\00{{.*}}", !{{[0-9]*}}, [[PR14763:![0-9]*]], {{.*}}, !"[[FOO:.*]]"} ; [ DW_TAG_structure_type ] [foo] -// CHECK: [[PR14763]] = {{.*}} ; [ DW_TAG_namespace ] [pr14763] -// CHECK: [[INCTYPE:![0-9]*]] = {{.*}} ; [ DW_TAG_structure_type ] [incomplete]{{.*}} [decl] -// CHECK: [[A_MEM:![0-9]*]], null, null, !"_ZTSN7pr162141aE"} ; [ DW_TAG_structure_type ] [a] +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "foo" +// CHECK-SAME: scope: [[PR14763:![0-9]+]] +// CHECK-SAME: identifier: "[[FOO:.*]]" +// CHECK: [[PR14763]] = !DINamespace(name: "pr14763" +// CHECK: [[INCTYPE:![0-9]*]] = !DICompositeType(tag: DW_TAG_structure_type, name: "incomplete" +// CHECK-SAME: DIFlagFwdDecl +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "a" +// CHECK-SAME: elements: [[A_MEM:![0-9]+]] +// CHECK-SAME: identifier: "_ZTSN7pr162141aE" // CHECK: [[A_MEM]] = !{[[A_I:![0-9]*]]} -// CHECK: [[A_I]] = {{.*}} ; [ DW_TAG_member ] [i] {{.*}} [from int] -// CHECK: ; [ DW_TAG_structure_type ] [b] {{.*}}[decl] +// CHECK: [[A_I]] = !DIDerivedType(tag: DW_TAG_member, name: "i" +// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "b" +// CHECK-SAME: DIFlagFwdDecl -// CHECK: [[FUNC:![0-9]*]] = !{!"0x2e\00func\00func\00_ZN7pr147634funcENS_3fooE\00{{.*}}"{{, [^,]+, [^,]+}}, [[FUNC_TYPE:![0-9]*]], {{.*}} ; [ DW_TAG_subprogram ] {{.*}} [def] [func] +// CHECK: [[FUNC:![0-9]+]] = !DISubprogram(name: "func", linkageName: "_ZN7pr147634funcENS_3fooE" +// CHECK-SAME: type: [[FUNC_TYPE:![0-9]*]] +// CHECK-SAME: isDefinition: true } void foo() { @@ -101,20 +124,29 @@ void foo() { wchar_t d = c; } -// CHECK-NOT: ; [ DW_TAG_variable ] [c] +// CHECK-NOT: !DIGlobalVariable(name: "c" namespace pr9608 { // also pr9600 struct incomplete; incomplete (*x)[3]; -// CHECK: [[INCARRAYPTR:![0-9]*]], [3 x i8]** @_ZN6pr96081xE, null} ; [ DW_TAG_variable ] [x] -// CHECK: [[INCARRAYPTR]] = {{.*}}[[INCARRAY:![0-9]*]]} ; [ DW_TAG_pointer_type ] -// CHECK: [[INCARRAY]] = !{!"0x1\00\000\000\000\000\000\000", null, null, !"_ZTSN6pr960810incompleteE", {{![0-9]+}}, null, null, null} ; [ DW_TAG_array_type ] [line 0, size 0, align 0, offset 0] [from _ZTSN6pr960810incompleteE] +// CHECK: !DIGlobalVariable(name: "x", linkageName: "_ZN6pr96081xE" +// CHECK-SAME: type: [[INCARRAYPTR:![0-9]*]] +// CHECK-SAME: variable: [3 x i8]** @_ZN6pr96081xE +// CHECK: [[INCARRAYPTR]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: [[INCARRAY:![0-9]+]] +// CHECK: [[INCARRAY]] = !DICompositeType(tag: DW_TAG_array_type +// CHECK-NOT: line: +// CHECK-NOT: size: +// CHECK-NOT: align: +// CHECK-NOT: offset: +// CHECK-SAME: baseType: !"_ZTSN6pr960810incompleteE" } // For some reason function arguments ended up down here -// CHECK: = !{!"0x101\00f\00{{.*}}\008192", [[FUNC]], {{![0-9]+}}, !"[[FOO]]"} ; [ DW_TAG_arg_variable ] [f] +// CHECK: ![[F]] = !DILocalVariable(tag: DW_TAG_arg_variable, name: "f", arg: 1, scope: [[FUNC]] +// CHECK-SAME: type: !"[[FOO]]" +// CHECK: ![[EXPR]] = !DIExpression(DW_OP_deref) -// CHECK: ; [ DW_TAG_auto_variable ] [c] +// CHECK: !DILocalVariable(tag: DW_TAG_auto_variable, name: "c" namespace pr16214 { struct a { diff --git a/test/CodeGenCXX/debug-lambda-expressions.cpp b/test/CodeGenCXX/debug-lambda-expressions.cpp index feafcff..a53274a 100644 --- a/test/CodeGenCXX/debug-lambda-expressions.cpp +++ b/test/CodeGenCXX/debug-lambda-expressions.cpp @@ -15,53 +15,88 @@ struct D { D(); D(const D&); int x; }; int d(int x) { D y[10]; return [x,y] { return y[x].x; }(); } // Randomness for file. -- 6 -// CHECK: [[FILE:.*]] = {{.*}} [ DW_TAG_file_type ] [{{.*}}debug-lambda-expressions.cpp] +// CHECK: [[FILE:.*]] = !DIFile(filename: "{{.*}}debug-lambda-expressions.cpp", + +// CHECK: ![[INT:[0-9]+]] = !DIBasicType(name: "int" // A: 10 -// CHECK: [[A_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[A_LINE:.*]]] [def] [a] +// CHECK: ![[A_FUNC:.*]] = !DISubprogram(name: "a"{{.*}}, line: [[A_LINE:[0-9]+]]{{.*}}, isDefinition: true // B: 14 -// CHECK: [[B_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[B_LINE:.*]]] [def] [b] +// CHECK: ![[B_FUNC:.*]] = !DISubprogram(name: "b"{{.*}}, line: [[B_LINE:[0-9]+]]{{.*}}, isDefinition: true // C: 17 -// CHECK: [[C_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[C_LINE:.*]]] [def] [c] +// CHECK: ![[C_FUNC:.*]] = !DISubprogram(name: "c"{{.*}}, line: [[C_LINE:[0-9]+]]{{.*}}, isDefinition: true // D: 18 -// CHECK: [[D_FUNC:.*]] = {{.*}} [ DW_TAG_subprogram ] [line [[D_LINE:.*]]] [def] [d] - -// Back to D. -- 24 -// CHECK: [[LAM_D:.*]] = {{.*}}, [[D_FUNC]], {{.*}}, [[LAM_D_ARGS:.*]], null, null, null} ; [ DW_TAG_class_type ] [line [[D_LINE]], -// CHECK: [[LAM_D_ARGS]] = !{[[CAP_D_X:.*]], [[CAP_D_Y:.*]], [[CON_LAM_D:.*]]} -// CHECK: [[CAP_D_X]] = {{.*}}, [[LAM_D]], {{.*}} [ DW_TAG_member ] [x] [line [[D_LINE]], -// CHECK: [[CAP_D_Y]] = {{.*}}, [[LAM_D]], {{.*}} [ DW_TAG_member ] [y] [line [[D_LINE]], -// CHECK: [[CON_LAM_D]] = {{.*}}, [[LAM_D]], {{.*}} [ DW_TAG_subprogram ] [line [[D_LINE]]] [public] [operator()] +// CHECK: ![[D_FUNC:.*]] = !DISubprogram(name: "d"{{.*}}, line: [[D_LINE:[0-9]+]]{{.*}}, isDefinition: true -// Back to C. -- 55 -// CHECK: [[LAM_C:.*]] = {{.*}}, [[C_FUNC]], {{.*}}, [[LAM_C_ARGS:.*]], null, null, null} ; [ DW_TAG_class_type ] [line [[C_LINE]], -// CHECK: [[LAM_C_ARGS]] = !{[[CAP_C:.*]], [[CON_LAM_C:.*]]} -// Ignoring the member type for now. -// CHECK: [[CAP_C]] = {{.*}}, [[LAM_C]], {{.*}}} ; [ DW_TAG_member ] [x] [line [[C_LINE]], -// CHECK: [[CON_LAM_C]] = {{.*}}, [[LAM_C]], {{.*}} [ DW_TAG_subprogram ] [line [[C_LINE]]] [public] [operator()] - +// Back to A. -- 78 +// CHECK: ![[LAM_A:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[A_FUNC]]{{.*}}, line: [[A_LINE]], +// CHECK-SAME: elements: ![[LAM_A_ARGS:[0-9]+]] +// CHECK: ![[LAM_A_ARGS]] = !{![[CON_LAM_A:[0-9]+]]} +// CHECK: ![[CON_LAM_A]] = !DISubprogram(name: "operator()" +// CHECK-SAME: scope: ![[LAM_A]] +// CHECK-SAME: line: [[A_LINE]] +// CHECK-SAME: DIFlagPublic // Back to B. -- 67 -// CHECK: [[LAM_B:.*]] = {{.*}}, [[B_FUNC]], {{.*}}, [[LAM_B_ARGS:.*]], null, null, null} ; [ DW_TAG_class_type ] [line [[B_LINE]], -// CHECK: [[LAM_B_ARGS]] = !{[[CAP_B:.*]], [[CON_LAM_B:.*]]} -// CHECK: [[CAP_B]] = {{.*}}, [[LAM_B]], {{.*}}} ; [ DW_TAG_member ] [x] [line [[B_LINE]], -// CHECK: [[CON_LAM_B]] = {{.*}}, [[LAM_B]], {{.*}} [ DW_TAG_subprogram ] [line [[B_LINE]]] [public] [operator()] +// CHECK: ![[LAM_B:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[B_FUNC]]{{.*}}, line: [[B_LINE]], +// CHECK-SAME: elements: ![[LAM_B_ARGS:[0-9]+]] +// CHECK: ![[LAM_B_ARGS]] = !{![[CAP_B:[0-9]+]], ![[CON_LAM_B:[0-9]+]]} +// CHECK: ![[CAP_B]] = !DIDerivedType(tag: DW_TAG_member, name: "x" +// CHECK-SAME: scope: ![[LAM_B]] +// CHECK-SAME: line: [[B_LINE]], +// CHECK-SAME: baseType: ![[INT]] +// CHECK: ![[CON_LAM_B]] = !DISubprogram(name: "operator()" +// CHECK-SAME: scope: ![[LAM_B]] +// CHECK-SAME: line: [[B_LINE]] +// CHECK-SAME: DIFlagPublic -// Back to A. -- 78 -// CHECK: [[LAM_A:.*]] = {{.*}}, [[A_FUNC]], {{.*}}, [[LAM_A_ARGS:.*]], null, null, null} ; [ DW_TAG_class_type ] [line [[A_LINE]], -// CHECK: [[LAM_A_ARGS]] = !{[[CON_LAM_A:.*]]} -// CHECK: [[CON_LAM_A]] = {{.*}}, [[LAM_A]], {{.*}} [ DW_TAG_subprogram ] [line [[A_LINE]]] [public] [operator()] +// Back to C. -- 55 +// CHECK: ![[LAM_C:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[C_FUNC]]{{.*}}, line: [[C_LINE]], +// CHECK-SAME: elements: ![[LAM_C_ARGS:[0-9]+]] +// CHECK: ![[LAM_C_ARGS]] = !{![[CAP_C:[0-9]+]], ![[CON_LAM_C:[0-9]+]]} +// CHECK: ![[CAP_C]] = !DIDerivedType(tag: DW_TAG_member, name: "x" +// CHECK-SAME: scope: ![[LAM_C]] +// CHECK-SAME: line: [[C_LINE]], +// CHECK-SAME: baseType: ![[TYPE_C_x:[0-9]+]] +// CHECK: ![[TYPE_C_x]] = !DIDerivedType(tag: DW_TAG_reference_type, baseType: ![[INT]] +// CHECK: ![[CON_LAM_C]] = !DISubprogram(name: "operator()" +// CHECK-SAME: scope: ![[LAM_C]] +// CHECK-SAME: line: [[C_LINE]] +// CHECK-SAME: DIFlagPublic + +// Back to D. -- 24 +// CHECK: ![[LAM_D:.*]] = !DICompositeType(tag: DW_TAG_class_type{{.*}}, scope: ![[D_FUNC]]{{.*}}, line: [[D_LINE]], +// CHECK-SAME: elements: ![[LAM_D_ARGS:[0-9]+]] +// CHECK: ![[LAM_D_ARGS]] = !{![[CAP_D_X:[0-9]+]], ![[CAP_D_Y:[0-9]+]], ![[CON_LAM_D:[0-9]+]]} +// CHECK: ![[CAP_D_X]] = !DIDerivedType(tag: DW_TAG_member, name: "x" +// CHECK-SAME: scope: ![[LAM_D]] +// CHECK-SAME: line: [[D_LINE]], +// CHECK: ![[CAP_D_Y]] = !DIDerivedType(tag: DW_TAG_member, name: "y" +// CHECK-SAME: scope: ![[LAM_D]] +// CHECK-SAME: line: [[D_LINE]], +// CHECK: ![[CON_LAM_D]] = !DISubprogram(name: "operator()" +// CHECK-SAME: scope: ![[LAM_D]] +// CHECK-SAME: line: [[D_LINE]] +// CHECK-SAME: DIFlagPublic // CVAR: -// CHECK: {{.*}} [[CVAR_T:![0-9]*]], {{.*}} ; [ DW_TAG_variable ] [cvar] [line [[CVAR_LINE:[0-9]*]]] -// CHECK: [[CVAR_T]] = {{.*}}, ![[CVAR_ARGS:.*]], null, null, null} ; [ DW_TAG_class_type ] [line [[CVAR_LINE]], -// CHECK: [[CVAR_ARGS]] = !{!{{.*}}} +// CHECK: !DIGlobalVariable(name: "cvar" +// CHECK-SAME: line: [[CVAR_LINE:[0-9]+]] +// CHECK-SAME: type: ![[CVAR_T:[0-9]+]] +// CHECK: ![[CVAR_T]] = !DICompositeType(tag: DW_TAG_class_type +// CHECK-SAME: line: [[CVAR_LINE]], +// CHECK-SAME: elements: ![[CVAR_ARGS:[0-9]+]] +// CHECK: ![[CVAR_ARGS]] = !{!{{[0-9]+}}} // VAR: -// CHECK: {{.*}} [[VAR_T:![0-9]*]], {{.*}} ; [ DW_TAG_variable ] [var] [line [[VAR_LINE:[0-9]*]]] -// CHECK: [[VAR_T]] = {{.*}}, [[VAR_ARGS:![0-9]*]], null, null, null} ; [ DW_TAG_class_type ] [line [[VAR_LINE]], -// CHECK: [[VAR_ARGS]] = !{!{{.*}}} +// CHECK: !DIGlobalVariable(name: "var" +// CHECK-SAME: line: [[VAR_LINE:[0-9]+]] +// CHECK-SAME: type: ![[VAR_T:[0-9]+]] +// CHECK: ![[VAR_T]] = !DICompositeType(tag: DW_TAG_class_type +// CHECK-SAME: line: [[VAR_LINE]], +// CHECK-SAME: elements: ![[VAR_ARGS:[0-9]+]] +// CHECK: ![[VAR_ARGS]] = !{!{{[0-9]+}}} diff --git a/test/CodeGenCXX/debug-lambda-this.cpp b/test/CodeGenCXX/debug-lambda-this.cpp index 87a317d..e3ef670 100644 --- a/test/CodeGenCXX/debug-lambda-this.cpp +++ b/test/CodeGenCXX/debug-lambda-this.cpp @@ -12,4 +12,10 @@ int D::d(int x) { }(); } -// CHECK: {{.*}} [ DW_TAG_member ] [this] [line 11, size 64, align 64, offset 0] [from ] +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "this", +// CHECK-SAME: line: 11 +// CHECK-SAME: baseType: ![[POINTER:[0-9]+]] +// CHECK-SAME: size: 64, align: 64 +// CHECK-NOT: offset: 0 +// CHECK-SAME: ){{$}} +// CHECK: ![[POINTER]] = !DIDerivedType(tag: DW_TAG_pointer_type diff --git a/test/CodeGenCXX/deferred-global-init.cpp b/test/CodeGenCXX/deferred-global-init.cpp index f64f507..920037c 100644 --- a/test/CodeGenCXX/deferred-global-init.cpp +++ b/test/CodeGenCXX/deferred-global-init.cpp @@ -8,7 +8,7 @@ void* bar() { return a; } // CHECK: @_ZL1a = internal global i8* null // CHECK-LABEL: define internal void @__cxx_global_var_init -// CHECK: load i8** @foo +// CHECK: load i8*, i8** @foo // CHECK: ret void // CHECK-LABEL: define internal void @_GLOBAL__sub_I_deferred_global_init.cpp diff --git a/test/CodeGenCXX/delete-two-arg.cpp b/test/CodeGenCXX/delete-two-arg.cpp index be3cf1a..e5a4cfa 100644 --- a/test/CodeGenCXX/delete-two-arg.cpp +++ b/test/CodeGenCXX/delete-two-arg.cpp @@ -30,7 +30,7 @@ namespace test2 { // CHECK: [[NEW:%.*]] = call noalias i8* @_Znaj(i32 44) // CHECK-NEXT: [[T0:%.*]] = bitcast i8* [[NEW]] to i32* // CHECK-NEXT: store i32 10, i32* [[T0]] - // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8* [[NEW]], i64 4 + // CHECK-NEXT: [[T1:%.*]] = getelementptr inbounds i8, i8* [[NEW]], i64 4 // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to [[A]]* // CHECK-NEXT: ret [[A]]* [[T2]] return ::new A[10]; @@ -40,13 +40,13 @@ namespace test2 { void test(A *p) { // CHECK: [[P:%.*]] = alloca [[A]]*, align 4 // CHECK-NEXT: store [[A]]* {{%.*}}, [[A]]** [[P]], align 4 - // CHECK-NEXT: [[T0:%.*]] = load [[A]]** [[P]], align 4 + // CHECK-NEXT: [[T0:%.*]] = load [[A]]*, [[A]]** [[P]], align 4 // CHECK-NEXT: [[T1:%.*]] = icmp eq [[A]]* [[T0]], null // CHECK-NEXT: br i1 [[T1]], // CHECK: [[T2:%.*]] = bitcast [[A]]* [[T0]] to i8* - // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8* [[T2]], i64 -4 + // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i8, i8* [[T2]], i64 -4 // CHECK-NEXT: [[T4:%.*]] = bitcast i8* [[T3]] to i32* - // CHECK-NEXT: [[T5:%.*]] = load i32* [[T4]] + // CHECK-NEXT: [[T5:%.*]] = load i32, i32* [[T4]] // CHECK-NEXT: call void @_ZdaPv(i8* [[T3]]) // CHECK-NEXT: br label ::delete[] p; diff --git a/test/CodeGenCXX/delete.cpp b/test/CodeGenCXX/delete.cpp index cdd5a89..ff448f8 100644 --- a/test/CodeGenCXX/delete.cpp +++ b/test/CodeGenCXX/delete.cpp @@ -70,16 +70,16 @@ namespace test1 { // CHECK: icmp eq [10 x [20 x [[A:%.*]]]]* [[PTR:%.*]], null // CHECK-NEXT: br i1 - // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]]* [[PTR]], i32 0, i32 0, i32 0 + // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]], [10 x [20 x [[A]]]]* [[PTR]], i32 0, i32 0, i32 0 // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[BEGIN]] to i8* - // CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8* [[T0]], i64 -8 + // CHECK-NEXT: [[ALLOC:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 -8 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[ALLOC]] to i64* - // CHECK-NEXT: [[COUNT:%.*]] = load i64* [[T1]] - // CHECK: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 [[COUNT]] + // CHECK-NEXT: [[COUNT:%.*]] = load i64, i64* [[T1]] + // CHECK: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 [[COUNT]] // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[END]] // CHECK-NEXT: br i1 [[ISEMPTY]], // CHECK: [[PAST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] - // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[PAST]], i64 -1 + // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[PAST]], i64 -1 // CHECK-NEXT: call void @_ZN5test11AD1Ev([[A]]* [[CUR]]) // CHECK-NEXT: [[ISDONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] // CHECK-NEXT: br i1 [[ISDONE]] @@ -116,17 +116,17 @@ namespace test4 { // Load the offset-to-top from the vtable and apply it. // This has to be done first because the dtor can mess it up. // CHECK: [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to i64** - // CHECK-NEXT: [[VTABLE:%.*]] = load i64** [[T0]] - // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i64* [[VTABLE]], i64 -2 - // CHECK-NEXT: [[OFFSET:%.*]] = load i64* [[T0]], align 8 + // CHECK-NEXT: [[VTABLE:%.*]] = load i64*, i64** [[T0]] + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds i64, i64* [[VTABLE]], i64 -2 + // CHECK-NEXT: [[OFFSET:%.*]] = load i64, i64* [[T0]], align 8 // CHECK-NEXT: [[T0:%.*]] = bitcast [[X]]* [[XP]] to i8* - // CHECK-NEXT: [[ALLOCATED:%.*]] = getelementptr inbounds i8* [[T0]], i64 [[OFFSET]] + // CHECK-NEXT: [[ALLOCATED:%.*]] = getelementptr inbounds i8, i8* [[T0]], i64 [[OFFSET]] // Load the complete-object destructor (not the deleting destructor) // and call it. // CHECK-NEXT: [[T0:%.*]] = bitcast [[X:%.*]]* [[XP:%.*]] to void ([[X]]*)*** - // CHECK-NEXT: [[VTABLE:%.*]] = load void ([[X]]*)*** [[T0]] - // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds void ([[X]]*)** [[VTABLE]], i64 0 - // CHECK-NEXT: [[DTOR:%.*]] = load void ([[X]]*)** [[T0]] + // CHECK-NEXT: [[VTABLE:%.*]] = load void ([[X]]*)**, void ([[X]]*)*** [[T0]] + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds void ([[X]]*)*, void ([[X]]*)** [[VTABLE]], i64 0 + // CHECK-NEXT: [[DTOR:%.*]] = load void ([[X]]*)*, void ([[X]]*)** [[T0]] // CHECK-NEXT: call void [[DTOR]]([[X]]* [[OBJ:%.*]]) // Call the global operator delete. // CHECK-NEXT: call void @_ZdlPv(i8* [[ALLOCATED]]) [[NUW:#[0-9]+]] diff --git a/test/CodeGenCXX/derived-to-base-conv.cpp b/test/CodeGenCXX/derived-to-base-conv.cpp index f4ef0e5..402fa44 100644 --- a/test/CodeGenCXX/derived-to-base-conv.cpp +++ b/test/CodeGenCXX/derived-to-base-conv.cpp @@ -79,7 +79,7 @@ void test2(Test2b &x) { // CHECK: [[X:%.*]] = alloca [[B:%.*]]*, align 8 // CHECK-NEXT: [[Y:%.*]] = alloca [[A:%.*]]*, align 8 // CHECK-NEXT: store [[B]]* {{%.*}}, [[B]]** [[X]], align 8 - // CHECK-NEXT: [[T0:%.*]] = load [[B]]** [[X]], align 8 + // CHECK-NEXT: [[T0:%.*]] = load [[B]]*, [[B]]** [[X]], align 8 // CHECK-NEXT: [[T1:%.*]] = bitcast [[B]]* [[T0]] to [[A]]* // CHECK-NEXT: store [[A]]* [[T1]], [[A]]** [[Y]], align 8 // CHECK-NEXT: ret void diff --git a/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp b/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp index d859283..dd64e81 100644 --- a/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp +++ b/test/CodeGenCXX/derived-to-virtual-base-class-calls-final.cpp @@ -11,6 +11,6 @@ struct D final : virtual C { // CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.B* @_Z1fR1D B &f(D &d) { - // CHECK-NOT: load i8** + // CHECK-NOT: load i8*, i8** return d; } diff --git a/test/CodeGenCXX/destructor-debug-info.cpp b/test/CodeGenCXX/destructor-debug-info.cpp index a8abfde..2534364 100644 --- a/test/CodeGenCXX/destructor-debug-info.cpp +++ b/test/CodeGenCXX/destructor-debug-info.cpp @@ -19,4 +19,4 @@ void foo() { } } // Check there is a line number entry for line 19 where b1 is destructed. -// CHECK: !MDLocation(line: 19, +// CHECK: !DILocation(line: 19, diff --git a/test/CodeGenCXX/destructors.cpp b/test/CodeGenCXX/destructors.cpp index bc9a683..2918cf3 100644 --- a/test/CodeGenCXX/destructors.cpp +++ b/test/CodeGenCXX/destructors.cpp @@ -185,6 +185,11 @@ namespace test3 { new D; // Force emission of D's vtable } + // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr + // CHECK4: invoke void @_ZN5test31BD2Ev( + // CHECK4: call void @_ZN5test31AD2Ev( + // CHECK4: ret void + // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11DD0Ev(%"struct.test3::(anonymous namespace)::D"* %this) unnamed_addr // CHECK4: invoke void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev // CHECK4: call void @_ZdlPv({{.*}}) [[NUW:#[0-9]+]] @@ -195,24 +200,15 @@ namespace test3 { // CHECK4: resume { i8*, i32 } // CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD1Ev( - // CHECK4: getelementptr inbounds i8* {{.*}}, i64 -8 + // CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8 // CHECK4: call void {{.*}} @_ZN5test312_GLOBAL__N_11CD2Ev // CHECK4: ret void // CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11DD0Ev( - // CHECK4: getelementptr inbounds i8* {{.*}}, i64 -8 + // CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8 // CHECK4: call void @_ZN5test312_GLOBAL__N_11DD0Ev( // CHECK4: ret void - // CHECK4-LABEL: declare void @_ZN5test31BD2Ev( - // CHECK4-LABEL: declare void @_ZN5test31AD2Ev( - - // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD2Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr - // CHECK4: invoke void @_ZN5test31BD2Ev( - // CHECK4: call void @_ZN5test31AD2Ev( - // CHECK4: ret void - - // CHECK4-LABEL: define internal void @_ZN5test312_GLOBAL__N_11CD0Ev(%"struct.test3::(anonymous namespace)::C"* %this) unnamed_addr // CHECK4: invoke void @_ZN5test312_GLOBAL__N_11CD2Ev( // CHECK4: call void @_ZdlPv({{.*}}) [[NUW]] @@ -223,15 +219,18 @@ namespace test3 { // CHECK4: resume { i8*, i32 } // CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD1Ev( - // CHECK4: getelementptr inbounds i8* {{.*}}, i64 -8 + // CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8 // CHECK4: call void @_ZN5test312_GLOBAL__N_11CD2Ev( // CHECK4: ret void // CHECK4-LABEL: define internal void @_ZThn8_N5test312_GLOBAL__N_11CD0Ev( - // CHECK4: getelementptr inbounds i8* {{.*}}, i64 -8 + // CHECK4: getelementptr inbounds i8, i8* {{.*}}, i64 -8 // CHECK4: call void @_ZN5test312_GLOBAL__N_11CD0Ev( // CHECK4: ret void + // CHECK4-LABEL: declare void @_ZN5test31BD2Ev( + // CHECK4-LABEL: declare void @_ZN5test31AD2Ev( + // CHECK4: attributes [[NUW]] = {{[{].*}} nounwind {{.*[}]}} } @@ -255,12 +254,12 @@ namespace test4 { // CHECK5: [[X:%.*]] = alloca i32 // CHECK5-NEXT: [[A:%.*]] = alloca // CHECK5: br label - // CHECK5: [[TMP:%.*]] = load i32* [[X]] + // CHECK5: [[TMP:%.*]] = load i32, i32* [[X]] // CHECK5-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP]], 0 // CHECK5-NEXT: br i1 // CHECK5: call void @_ZN5test41AD1Ev( // CHECK5: br label - // CHECK5: [[TMP:%.*]] = load i32* [[X]] + // CHECK5: [[TMP:%.*]] = load i32, i32* [[X]] // CHECK5: [[TMP2:%.*]] = add nsw i32 [[TMP]], -1 // CHECK5: store i32 [[TMP2]], i32* [[X]] // CHECK5: br label @@ -280,20 +279,23 @@ namespace test5 { // CHECK5: [[ELEMS:%.*]] = alloca [5 x [[A:%.*]]], align // CHECK5-NEXT: [[EXN:%.*]] = alloca i8* // CHECK5-NEXT: [[SEL:%.*]] = alloca i32 - // CHECK5-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]]* [[ELEMS]], i32 0, i32 0 - // CHECK5-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5 + // CHECK5-NEXT: [[PELEMS:%.*]] = bitcast [5 x [[A]]]* [[ELEMS]] to i8* + // CHECK5-NEXT: call void @llvm.lifetime.start(i64 5, i8* [[PELEMS]]) + // CHECK5-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [5 x [[A]]], [5 x [[A]]]* [[ELEMS]], i32 0, i32 0 + // CHECK5-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 5 // CHECK5-NEXT: br label // CHECK5: [[POST:%.*]] = phi [[A]]* [ [[END]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ] - // CHECK5-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[POST]], i64 -1 + // CHECK5-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[POST]], i64 -1 // CHECK5-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[ELT]]) // CHECK5: [[T0:%.*]] = icmp eq [[A]]* [[ELT]], [[BEGIN]] // CHECK5-NEXT: br i1 [[T0]], - // CHECK5: ret void + // CHECK5: call void @llvm.lifetime.end + // CHECK5-NEXT: ret void // lpad // CHECK5: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[ELT]] // CHECK5-NEXT: br i1 [[EMPTY]] // CHECK5: [[AFTER:%.*]] = phi [[A]]* [ [[ELT]], {{%.*}} ], [ [[CUR:%.*]], {{%.*}} ] - // CHECK5-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1 + // CHECK5-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1 // CHECK5-NEXT: invoke void @_ZN5test51AD1Ev([[A]]* [[CUR]]) // CHECK5: [[DONE:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] // CHECK5-NEXT: br i1 [[DONE]], diff --git a/test/CodeGenCXX/dllexport-members.cpp b/test/CodeGenCXX/dllexport-members.cpp index d913c09..4038d0b 100644 --- a/test/CodeGenCXX/dllexport-members.cpp +++ b/test/CodeGenCXX/dllexport-members.cpp @@ -110,9 +110,10 @@ public: // MSC-DAG: @"\01?StaticField@ExportMembers@@2HA" = dllexport global i32 1, align 4 // MSC-DAG: @"\01?StaticConstField@ExportMembers@@2HB" = dllexport constant i32 1, align 4 - // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4 - // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4 - // MSC-DAG: @"\01?ConstexprField@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4 + // MSC-DAG: @"\01?StaticConstFieldEqualInit@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?StaticConstFieldBraceInit@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?StaticConstFieldRefNotDef@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?ConstexprField@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4 // GNU-DAG: @_ZN13ExportMembers11StaticFieldE = dllexport global i32 1, align 4 // GNU-DAG: @_ZN13ExportMembers16StaticConstFieldE = dllexport constant i32 1, align 4 // GNU-DAG: @_ZN13ExportMembers25StaticConstFieldEqualInitE = dllexport constant i32 1, align 4 @@ -122,6 +123,7 @@ public: __declspec(dllexport) static const int StaticConstField; __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; + __declspec(dllexport) static const int StaticConstFieldRefNotDef = 1; __declspec(dllexport) constexpr static int ConstexprField = 1; }; @@ -144,6 +146,7 @@ inline void ExportMembers::staticInlineDef() {} const int ExportMembers::StaticConstField = 1; const int ExportMembers::StaticConstFieldEqualInit; const int ExportMembers::StaticConstFieldBraceInit; +int foo() { return ExportMembers::StaticConstFieldRefNotDef; } constexpr int ExportMembers::ConstexprField; @@ -233,9 +236,10 @@ public: // MSC-DAG: @"\01?StaticField@Nested@ExportMembers@@2HA" = dllexport global i32 1, align 4 // MSC-DAG: @"\01?StaticConstField@Nested@ExportMembers@@2HB" = dllexport constant i32 1, align 4 - // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4 - // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4 - // MSC-DAG: @"\01?ConstexprField@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, align 4 + // MSC-DAG: @"\01?StaticConstFieldEqualInit@Nested@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?StaticConstFieldBraceInit@Nested@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?StaticConstFieldRefNotDef@Nested@ExportMembers@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 + // MSC-DAG: @"\01?ConstexprField@Nested@ExportMembers@@2HB" = dllexport constant i32 1, comdat, align 4 // GNU-DAG: @_ZN13ExportMembers6Nested11StaticFieldE = dllexport global i32 1, align 4 // GNU-DAG: @_ZN13ExportMembers6Nested16StaticConstFieldE = dllexport constant i32 1, align 4 // GNU-DAG: @_ZN13ExportMembers6Nested25StaticConstFieldEqualInitE = dllexport constant i32 1, align 4 @@ -245,6 +249,7 @@ public: __declspec(dllexport) static const int StaticConstField; __declspec(dllexport) static const int StaticConstFieldEqualInit = 1; __declspec(dllexport) static const int StaticConstFieldBraceInit{1}; + __declspec(dllexport) static const int StaticConstFieldRefNotDef = 1; __declspec(dllexport) constexpr static int ConstexprField = 1; }; @@ -267,6 +272,7 @@ inline void ExportMembers::Nested::staticInlineDef() {} const int ExportMembers::Nested::StaticConstField = 1; const int ExportMembers::Nested::StaticConstFieldEqualInit; const int ExportMembers::Nested::StaticConstFieldBraceInit; +int fooNested() { return ExportMembers::Nested::StaticConstFieldRefNotDef; } constexpr int ExportMembers::Nested::ConstexprField; @@ -599,21 +605,21 @@ template<typename T> const int MemVarTmpl::StaticVar; template<typename T> const int MemVarTmpl::ExportedStaticVar; // Export implicit instantiation of an exported member variable template. -// MSC-DAG: @"\01??$ExportedStaticVar@UImplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4 -// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ImplicitInst_ExportedEE = weak_odr dllexport constant i32 1, align 4 +// MSC-DAG: @"\01??$ExportedStaticVar@UImplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 +// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ImplicitInst_ExportedEE = weak_odr dllexport constant i32 1, comdat, align 4 int useMemVarTmpl() { return MemVarTmpl::ExportedStaticVar<ImplicitInst_Exported>; } // Export explicit instantiation declaration of an exported member variable // template. -// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4 -// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitDecl_ExportedEE = weak_odr dllexport constant i32 1, align 4 +// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 +// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitDecl_ExportedEE = weak_odr dllexport constant i32 1, comdat, align 4 extern template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>; template const int MemVarTmpl::ExportedStaticVar<ExplicitDecl_Exported>; // Export explicit instantiation definition of an exported member variable // template. -// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4 -// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitInst_ExportedEE = weak_odr dllexport constant i32 1, align 4 +// MSC-DAG: @"\01??$ExportedStaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 +// GNU-DAG: @_ZN10MemVarTmpl17ExportedStaticVarI21ExplicitInst_ExportedEE = weak_odr dllexport constant i32 1, comdat, align 4 template const int MemVarTmpl::ExportedStaticVar<ExplicitInst_Exported>; // Export specialization of an exported member variable template. @@ -630,15 +636,15 @@ template<> const int MemVarTmpl::ExportedStaticVar<ExplicitSpec_NotExported> = 1 // Export explicit instantiation declaration of a non-exported member variable // template. -// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4 -// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ExportedEE = weak_odr dllexport constant i32 1, align 4 +// MSC-DAG: @"\01??$StaticVar@UExplicitDecl_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 +// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitDecl_ExportedEE = weak_odr dllexport constant i32 1, comdat, align 4 extern template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>; template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitDecl_Exported>; // Export explicit instantiation definition of a non-exported member variable // template. -// MSC-DAG: @"\01??$StaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, align 4 -// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitInst_ExportedEE = weak_odr dllexport constant i32 1, align 4 +// MSC-DAG: @"\01??$StaticVar@UExplicitInst_Exported@@@MemVarTmpl@@2HB" = weak_odr dllexport constant i32 1, comdat, align 4 +// GNU-DAG: @_ZN10MemVarTmpl9StaticVarI21ExplicitInst_ExportedEE = weak_odr dllexport constant i32 1, comdat, align 4 template __declspec(dllexport) const int MemVarTmpl::StaticVar<ExplicitInst_Exported>; // Export specialization of a non-exported member variable template. diff --git a/test/CodeGenCXX/dllexport.cpp b/test/CodeGenCXX/dllexport.cpp index cfbc7e1..3a1a3ff 100644 --- a/test/CodeGenCXX/dllexport.cpp +++ b/test/CodeGenCXX/dllexport.cpp @@ -1,7 +1,7 @@ -// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -O1 -mconstructor-aliases -disable-llvm-optzns -o - %s -w | FileCheck --check-prefix=MSC --check-prefix=M32 %s -// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s -// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s -// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O1 -mconstructor-aliases -disable-llvm-optzns -o - %s -w | FileCheck --check-prefix=MSC --check-prefix=M32 %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -emit-llvm -std=c++1y -fno-threadsafe-statics -fms-extensions -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s // Helper structs to make templates more expressive. struct ImplicitInst_Exported {}; @@ -82,8 +82,8 @@ int __declspec(dllexport) nonInlineStaticLocalsFunc() { return x++; }; -// MSC-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = weak_odr dllexport global i32 0 -// MSC-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = weak_odr dllexport global i32 0 +// MSC-DAG: @"\01?x@?1??inlineStaticLocalsFunc@@YAHXZ@4HA" = weak_odr dllexport global i32 0, comdat +// MSC-DAG: @"\01??_B?1??inlineStaticLocalsFunc@@YAHXZ@51" = weak_odr dllexport global i32 0, comdat // Note: MinGW doesn't seem to export the static local here. inline int __declspec(dllexport) inlineStaticLocalsFunc() { static int x = f(); @@ -110,43 +110,43 @@ template<typename T> __declspec(dllexport) int VarTmplImplicitDef; USEVAR(VarTmplImplicitDef<ImplicitInst_Exported>) // Export definition. -// MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 -// GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +// MSC-DAG: @"\01??$VarTmplInit1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4 +// GNU-DAG: @_Z12VarTmplInit1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4 template<typename T> __declspec(dllexport) int VarTmplInit1 = 1; INSTVAR(VarTmplInit1<ExplicitInst_Exported>) -// MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 -// GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +// MSC-DAG: @"\01??$VarTmplInit2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4 +// GNU-DAG: @_Z12VarTmplInit2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4 template<typename T> int __declspec(dllexport) VarTmplInit2 = 1; INSTVAR(VarTmplInit2<ExplicitInst_Exported>) // Declare, then export definition. -// MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 -// GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +// MSC-DAG: @"\01??$VarTmplDeclInit@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4 +// GNU-DAG: @_Z15VarTmplDeclInitI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4 template<typename T> __declspec(dllexport) extern int VarTmplDeclInit; template<typename T> int VarTmplDeclInit = 1; INSTVAR(VarTmplDeclInit<ExplicitInst_Exported>) // Redeclarations -// MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 -// GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +// MSC-DAG: @"\01??$VarTmplRedecl1@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4 +// GNU-DAG: @_Z14VarTmplRedecl1I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4 template<typename T> __declspec(dllexport) extern int VarTmplRedecl1; template<typename T> __declspec(dllexport) int VarTmplRedecl1 = 1; INSTVAR(VarTmplRedecl1<ExplicitInst_Exported>) -// MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 -// GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +// MSC-DAG: @"\01??$VarTmplRedecl2@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4 +// GNU-DAG: @_Z14VarTmplRedecl2I21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4 template<typename T> __declspec(dllexport) extern int VarTmplRedecl2; template<typename T> int VarTmplRedecl2 = 1; INSTVAR(VarTmplRedecl2<ExplicitInst_Exported>) -// MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, align 4 -// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE = weak_odr dllexport global i32 1, align 4 +// MSC-DAG: @"\01??$ExternalVarTmpl@UExplicitInst_Exported@@@ns@@3HA" = weak_odr dllexport global i32 1, comdat, align 4 +// GNU-DAG: @_ZN2ns15ExternalVarTmplI21ExplicitInst_ExportedEE = weak_odr dllexport global i32 1, comdat, align 4 namespace ns { template<typename T> __declspec(dllexport) int ExternalVarTmpl = 1; } INSTVAR(ns::ExternalVarTmpl<ExplicitInst_Exported>) -// MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, align 4 -// GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global %struct.External zeroinitializer, align 4 +// MSC-DAG: @"\01??$ExternalAutoTypeVarTmpl@UExplicitInst_Exported@@@@3UExternal@@A" = weak_odr dllexport global %struct.External zeroinitializer, comdat, align 4 +// GNU-DAG: @_Z23ExternalAutoTypeVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global %struct.External zeroinitializer, comdat, align 4 template<typename T> __declspec(dllexport) auto ExternalAutoTypeVarTmpl = External(); template External ExternalAutoTypeVarTmpl<ExplicitInst_Exported>; @@ -155,19 +155,19 @@ template<typename T> int VarTmpl = 1; template<typename T> __declspec(dllexport) int ExportedVarTmpl = 1; // Export implicit instantiation of an exported variable template. -// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 -// GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4 +// GNU-DAG: @_Z15ExportedVarTmplI21ImplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4 USEVAR(ExportedVarTmpl<ImplicitInst_Exported>) // Export explicit instantiation declaration of an exported variable template. -// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 -// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, align 4 +// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4 +// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, comdat, align 4 extern template int ExportedVarTmpl<ExplicitDecl_Exported>; template int ExportedVarTmpl<ExplicitDecl_Exported>; // Export explicit instantiation definition of an exported variable template. -// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 -// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +// MSC-DAG: @"\01??$ExportedVarTmpl@UImplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4 +// GNU-DAG: @_Z15ExportedVarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4 template __declspec(dllexport) int ExportedVarTmpl<ExplicitInst_Exported>; // Export specialization of an exported variable template. @@ -187,14 +187,14 @@ template<> int ExportedVarTmpl<ExplicitSpec_NotExported>; // Export explicit instantiation declaration of a non-exported variable template. -// MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 -// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, align 4 +// MSC-DAG: @"\01??$VarTmpl@UExplicitDecl_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4 +// GNU-DAG: @_Z7VarTmplI21ExplicitDecl_ExportedE = weak_odr dllexport global i32 1, comdat, align 4 extern template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>; template __declspec(dllexport) int VarTmpl<ExplicitDecl_Exported>; // Export explicit instantiation definition of a non-exported variable template. -// MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, align 4 -// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, align 4 +// MSC-DAG: @"\01??$VarTmpl@UExplicitInst_Exported@@@@3HA" = weak_odr dllexport global i32 1, comdat, align 4 +// GNU-DAG: @_Z7VarTmplI21ExplicitInst_ExportedE = weak_odr dllexport global i32 1, comdat, align 4 template __declspec(dllexport) int VarTmpl<ExplicitInst_Exported>; // Export specialization of a non-exported variable template. @@ -484,6 +484,53 @@ struct S { }; }; +struct CtorWithClosure { + __declspec(dllexport) CtorWithClosure(...) {} +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FCtorWithClosure@@QAEXXZ" +// M32-DAG: %[[this_addr:.*]] = alloca %struct.CtorWithClosure*, align 4 +// M32-DAG: store %struct.CtorWithClosure* %this, %struct.CtorWithClosure** %[[this_addr]], align 4 +// M32-DAG: %[[this:.*]] = load %struct.CtorWithClosure*, %struct.CtorWithClosure** %[[this_addr]] +// M32-DAG: call %struct.CtorWithClosure* (%struct.CtorWithClosure*, ...) @"\01??0CtorWithClosure@@QAA@ZZ"(%struct.CtorWithClosure* %[[this]]) +// M32-DAG: ret void +}; + +#define DELETE_IMPLICIT_MEMBERS(ClassName) \ + ClassName(ClassName &&) = delete; \ + ClassName(ClassName &) = delete; \ + ~ClassName() = delete; \ + ClassName &operator=(ClassName &) = delete + +struct __declspec(dllexport) ClassWithClosure { + DELETE_IMPLICIT_MEMBERS(ClassWithClosure); + ClassWithClosure(...) {} +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FClassWithClosure@@QAEXXZ" +// M32-DAG: %[[this_addr:.*]] = alloca %struct.ClassWithClosure*, align 4 +// M32-DAG: store %struct.ClassWithClosure* %this, %struct.ClassWithClosure** %[[this_addr]], align 4 +// M32-DAG: %[[this:.*]] = load %struct.ClassWithClosure*, %struct.ClassWithClosure** %[[this_addr]] +// M32-DAG: call %struct.ClassWithClosure* (%struct.ClassWithClosure*, ...) @"\01??0ClassWithClosure@@QAA@ZZ"(%struct.ClassWithClosure* %[[this]]) +// M32-DAG: ret void +}; + +struct __declspec(dllexport) NestedOuter { + DELETE_IMPLICIT_MEMBERS(NestedOuter); + NestedOuter(void *p = 0) {} + struct __declspec(dllexport) NestedInner { + DELETE_IMPLICIT_MEMBERS(NestedInner); + NestedInner(void *p = 0) {} + }; +}; + +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedOuter@@QAEXXZ" +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_FNestedInner@NestedOuter@@QAEXXZ" + +template <typename T> +struct SomeTemplate { + SomeTemplate(T o = T()) : o(o) {} + T o; +}; +struct __declspec(dllexport) InheritFromTemplate : SomeTemplate<int> {}; + +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01??_F?$SomeTemplate@H@@QAEXXZ" struct __declspec(dllexport) T { // Copy assignment operator: @@ -511,15 +558,16 @@ struct __declspec(dllexport) V : public U<int> { }; // U<int>'s assignment operator is emitted. // M32-DAG: define weak_odr dllexport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.U* @"\01??4?$U@H@@QAEAAU0@ABU0@@Z" -struct __declspec(dllexport) W { virtual void foo() {} }; +struct __declspec(dllexport) W { virtual void foo(); }; +void W::foo() {} // Default ctor: // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@XZ" // Copy ctor: // M32-DAG: define weak_odr dllexport x86_thiscallcc %struct.W* @"\01??0W@@QAE@ABU0@@Z" // vftable: // M32-DAG: [[W_VTABLE:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast (%rtti.CompleteObjectLocator* @"\01??_R4W@@6B@" to i8*), i8* bitcast (void (%struct.W*)* @"\01?foo@W@@UAEXXZ" to i8*)], comdat($"\01??_7W@@6B@") -// M32-DAG: @"\01??_7W@@6B@" = dllexport unnamed_addr alias getelementptr inbounds ([2 x i8*]* [[W_VTABLE]], i32 0, i32 1) -// G32-DAG: @_ZTV1W = weak_odr dllexport unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] +// M32-DAG: @"\01??_7W@@6B@" = dllexport unnamed_addr alias getelementptr inbounds ([2 x i8*], [2 x i8*]* [[W_VTABLE]], i32 0, i32 1) +// G32-DAG: @_ZTV1W = dllexport unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTI1W to i8*), i8* bitcast (void (%struct.W*)* @_ZN1W3fooEv to i8*)] struct __declspec(dllexport) X : public virtual W {}; // vbtable: @@ -573,17 +621,19 @@ namespace ReferencedInlineMethodInNestedClass { // MS ignores DLL attributes on partial specializations. template <typename T> struct PartiallySpecializedClassTemplate {}; -template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f() {} }; +template <typename T> struct __declspec(dllexport) PartiallySpecializedClassTemplate<T*> { void f(); }; +template <typename T> void PartiallySpecializedClassTemplate<T*>::f() {} USEMEMFUNC(PartiallySpecializedClassTemplate<void*>, f); // M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?f@?$PartiallySpecializedClassTemplate@PAX@@QAEXXZ" // G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN33PartiallySpecializedClassTemplateIPvE1fEv // Attributes on explicit specializations are honored. template <typename T> struct ExplicitlySpecializedClassTemplate {}; -template <> struct __declspec(dllexport) ExplicitlySpecializedClassTemplate<void*> { void f() {} }; +template <> struct __declspec(dllexport) ExplicitlySpecializedClassTemplate<void*> { void f(); }; +void ExplicitlySpecializedClassTemplate<void*>::f() {} USEMEMFUNC(ExplicitlySpecializedClassTemplate<void*>, f); -// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ" -// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv +// M32-DAG: define dllexport x86_thiscallcc void @"\01?f@?$ExplicitlySpecializedClassTemplate@PAX@@QAEXXZ" +// G32-DAG: define dllexport x86_thiscallcc void @_ZN34ExplicitlySpecializedClassTemplateIPvE1fEv // MS inherits DLL attributes to partial specializations. template <typename T> struct __declspec(dllexport) PartiallySpecializedExportedClassTemplate {}; @@ -631,25 +681,56 @@ template <typename T> struct ExplicitInstConstexprMembers { }; template struct __declspec(dllexport) ExplicitInstConstexprMembers<void>; +template <typename T> struct ExplicitInstantiationDeclTemplate { void f() {} }; +extern template struct __declspec(dllexport) ExplicitInstantiationDeclTemplate<int>; +USEMEMFUNC(ExplicitInstantiationDeclTemplate<int>, f); +// M32-DAG: {{declare|define available_externally}} x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclTemplate@H@@QAEXXZ" + +template <typename T> struct __declspec(dllexport) ExplicitInstantiationDeclExportedTemplate { void f() {} }; +extern template struct ExplicitInstantiationDeclExportedTemplate<int>; +USEMEMFUNC(ExplicitInstantiationDeclExportedTemplate<int>, f); +// M32-DAG: {{declare|define available_externally}} x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedTemplate@H@@QAEXXZ" + +template <typename T> struct ExplicitInstantiationDeclExportedDefTemplate { void f() {} }; +extern template struct ExplicitInstantiationDeclExportedDefTemplate<int>; +template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefTemplate<int>; +// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedDefTemplate@H@@QAEXXZ" + +namespace { struct InternalLinkageType {}; } +struct __declspec(dllexport) PR23308 { + void f(InternalLinkageType*); +}; +void PR23308::f(InternalLinkageType*) {} +long use(PR23308* p) { p->f(nullptr); } +// M32-DAG: define internal x86_thiscallcc void @"\01?f@PR23308@@QAEXPAUInternalLinkageType@?A@@@Z" + + + //===----------------------------------------------------------------------===// // Classes with template base classes //===----------------------------------------------------------------------===// -template <typename T> struct ClassTemplate { void func() {} }; -template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} }; +template <typename T> struct ClassTemplate { void func(); }; +template <typename T> void ClassTemplate<T>::func() {} +template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); }; +template <typename T> void ExportedClassTemplate<T>::func() {} template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); }; template <typename T> void ImportedClassTemplate<T>::func() {} template <typename T> struct ExplicitlySpecializedTemplate { void func() {} }; -template <> struct ExplicitlySpecializedTemplate<int> { void func() {} }; +template <> struct ExplicitlySpecializedTemplate<int> { void func(); }; +void ExplicitlySpecializedTemplate<int>::func() {} template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} }; -template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} }; +template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); }; +void ExplicitlyExportSpecializedTemplate<int>::func() {} template <typename T> struct ExplicitlyImportSpecializedTemplate { void func(); }; template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); }; -template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} }; +template <typename T> struct ExplicitlyInstantiatedTemplate { void func(); }; +template <typename T> void ExplicitlyInstantiatedTemplate<T>::func() {} template struct ExplicitlyInstantiatedTemplate<int>; -template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} }; +template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); }; +template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {} template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>; template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); }; template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>; @@ -690,14 +771,14 @@ USEMEMFUNC(DerivedFromTemplateB2, func) // Base class already specialized without dll attribute. struct __declspec(dllexport) DerivedFromExplicitlySpecializedTemplate : public ExplicitlySpecializedTemplate<int> {}; USEMEMFUNC(DerivedFromExplicitlySpecializedTemplate, func) -// M32-DAG: define linkonce_odr x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ" -// G32-DAG: define linkonce_odr x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv +// M32-DAG: define x86_thiscallcc void @"\01?func@?$ExplicitlySpecializedTemplate@H@@QAEXXZ" +// G32-DAG: define x86_thiscallcc void @_ZN29ExplicitlySpecializedTemplateIiE4funcEv // Base class alredy specialized with export attribute. struct __declspec(dllexport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {}; USEMEMFUNC(DerivedFromExplicitlyExportSpecializedTemplate, func) -// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ" -// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv +// M32-DAG: define dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ" +// G32-DAG: define dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv // Base class already specialized with import attribute. struct __declspec(dllexport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {}; diff --git a/test/CodeGenCXX/dllimport-rtti.cpp b/test/CodeGenCXX/dllimport-rtti.cpp index b5a5d54..8c0f863 100644 --- a/test/CodeGenCXX/dllimport-rtti.cpp +++ b/test/CodeGenCXX/dllimport-rtti.cpp @@ -1,5 +1,5 @@ -// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -o - %s | FileCheck %s --check-prefix=MSVC -// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -O1 -disable-llvm-optzns -o - %s | FileCheck %s --check-prefix=GNU +// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-optzns -o - %s | FileCheck %s --check-prefix=MSVC +// RUN: %clang_cc1 -triple i686-windows-gnu -emit-llvm -std=c++1y -fms-extensions -O1 -disable-llvm-optzns -o - %s | FileCheck %s --check-prefix=GNU struct __declspec(dllimport) S { virtual void f() {} diff --git a/test/CodeGenCXX/dllimport.cpp b/test/CodeGenCXX/dllimport.cpp index ddd390a..6de8560 100644 --- a/test/CodeGenCXX/dllimport.cpp +++ b/test/CodeGenCXX/dllimport.cpp @@ -1,13 +1,14 @@ -// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M32 %s -// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s -// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s -// RUN: %clang_cc1 -triple x86_64-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s -// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 %s -// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O1 -o - %s -w | FileCheck --check-prefix=GO1 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M32 %s +// RUN: %clang_cc1 -triple x86_64-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC --check-prefix=M64 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G32 %s +// RUN: %clang_cc1 -triple x86_64-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU --check-prefix=G64 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=18.00 -emit-llvm -std=c++1y -O1 -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M18 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -fms-compatibility-version=19.00 -emit-llvm -std=c++1y -O1 -o - %s -DMSABI -w | FileCheck --check-prefix=MO1 --check-prefix=M19 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O1 -o - %s -w | FileCheck --check-prefix=GO1 %s // CHECK-NOT doesn't play nice with CHECK-DAG, so use separate run lines. -// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC2 %s -// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU2 %s +// RUN: %clang_cc1 -triple i686-windows-msvc -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -DMSABI -w | FileCheck --check-prefix=MSC2 %s +// RUN: %clang_cc1 -triple i686-windows-gnu -fno-rtti -fno-threadsafe-statics -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s -w | FileCheck --check-prefix=GNU2 %s // Helper structs to make templates more expressive. struct ImplicitInst_Imported {}; @@ -557,7 +558,8 @@ struct __declspec(dllimport) T { T& operator=(T&&) = default; // Note: Don't mark inline move operators dllimport because current MSVC versions don't export them. - // MO1-DAG: define linkonce_odr x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z" + // M18-DAG: define linkonce_odr x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z" + // M19-DAG: define available_externally dllimport x86_thiscallcc dereferenceable({{[0-9]+}}) %struct.T* @"\01??4T@@QAEAAU0@$$QAU0@@Z" }; USEMEMFUNC(T, a) USEVAR(T::b) @@ -722,25 +724,40 @@ template struct __declspec(dllimport) ExplicitlyInstantiatedWithDifferentAttr<in USEMEMFUNC(ExplicitlyInstantiatedWithDifferentAttr<int>, f); // M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitlyInstantiatedWithDifferentAttr@H@@QAEXXZ" +template <typename T> struct ExplicitInstantiationDeclImportedDefTemplate { void f() {} }; +extern template struct ExplicitInstantiationDeclImportedDefTemplate<int>; +template struct __declspec(dllimport) ExplicitInstantiationDeclImportedDefTemplate<int>; +USEMEMFUNC(ExplicitInstantiationDeclImportedDefTemplate<int>, f); +// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclImportedDefTemplate@H@@QAEXXZ" + +template <typename T> struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate { void f() {} }; +extern template struct __declspec(dllimport) ExplicitInstantiationDeclExportedDefImportedTemplate <int>; +template struct __declspec(dllexport) ExplicitInstantiationDeclExportedDefImportedTemplate<int>; +USEMEMFUNC(ExplicitInstantiationDeclExportedDefImportedTemplate<int>, f); +// M32-DAG: {{declare|define available_externally}} dllimport x86_thiscallcc void @"\01?f@?$ExplicitInstantiationDeclExportedDefImportedTemplate@H@@QAEXXZ" + //===----------------------------------------------------------------------===// // Classes with template base classes //===----------------------------------------------------------------------===// template <typename T> struct ClassTemplate { void func() {} }; -template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func() {} }; +template <typename T> struct __declspec(dllexport) ExportedClassTemplate { void func(); }; +template <typename T> void ExportedClassTemplate<T>::func() {} template <typename T> struct __declspec(dllimport) ImportedClassTemplate { void func(); }; template <typename T> struct ExplicitlySpecializedTemplate { void func() {} }; template <> struct ExplicitlySpecializedTemplate<int> { void func() {} }; template <typename T> struct ExplicitlyExportSpecializedTemplate { void func() {} }; -template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func() {} }; +template <> struct __declspec(dllexport) ExplicitlyExportSpecializedTemplate<int> { void func(); }; +void ExplicitlyExportSpecializedTemplate<int>::func() {} template <typename T> struct ExplicitlyImportSpecializedTemplate { void func() {} }; template <> struct __declspec(dllimport) ExplicitlyImportSpecializedTemplate<int> { void func(); }; template <typename T> struct ExplicitlyInstantiatedTemplate { void func() {} }; template struct ExplicitlyInstantiatedTemplate<int>; -template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func() {} }; +template <typename T> struct ExplicitlyExportInstantiatedTemplate { void func(); }; +template <typename T> void ExplicitlyExportInstantiatedTemplate<T>::func() {} template struct __declspec(dllexport) ExplicitlyExportInstantiatedTemplate<int>; template <typename T> struct ExplicitlyImportInstantiatedTemplate { void func(); }; template struct __declspec(dllimport) ExplicitlyImportInstantiatedTemplate<int>; @@ -787,8 +804,8 @@ USEMEMFUNC(ExplicitlySpecializedTemplate<int>, func) // Base class alredy specialized with export attribute. struct __declspec(dllimport) DerivedFromExplicitlyExportSpecializedTemplate : public ExplicitlyExportSpecializedTemplate<int> {}; USEMEMFUNC(ExplicitlyExportSpecializedTemplate<int>, func) -// M32-DAG: define weak_odr dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ" -// G32-DAG: define weak_odr dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv +// M32-DAG: define dllexport x86_thiscallcc void @"\01?func@?$ExplicitlyExportSpecializedTemplate@H@@QAEXXZ" +// G32-DAG: define dllexport x86_thiscallcc void @_ZN35ExplicitlyExportSpecializedTemplateIiE4funcEv // Base class already specialized with import attribute. struct __declspec(dllimport) DerivedFromExplicitlyImportSpecializedTemplate : public ExplicitlyImportSpecializedTemplate<int> {}; diff --git a/test/CodeGenCXX/eh.cpp b/test/CodeGenCXX/eh.cpp index cb07697..77655f0 100644 --- a/test/CodeGenCXX/eh.cpp +++ b/test/CodeGenCXX/eh.cpp @@ -123,14 +123,14 @@ namespace test7 { // CHECK-NEXT: [[SELECTOR:%.*]] = extractvalue { i8*, i32 } [[CAUGHTVAL]], 1 // CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]] // CHECK-NEXT: br label -// CHECK: [[SELECTOR:%.*]] = load i32* [[SELECTORVAR]] +// CHECK: [[SELECTOR:%.*]] = load i32, i32* [[SELECTORVAR]] // CHECK-NEXT: [[T0:%.*]] = call i32 @llvm.eh.typeid.for(i8* bitcast (i8** @_ZTIi to i8*)) // CHECK-NEXT: icmp eq i32 [[SELECTOR]], [[T0]] // CHECK-NEXT: br i1 -// CHECK: [[T0:%.*]] = load i8** [[CAUGHTEXNVAR]] +// CHECK: [[T0:%.*]] = load i8*, i8** [[CAUGHTEXNVAR]] // CHECK-NEXT: [[T1:%.*]] = call i8* @__cxa_begin_catch(i8* [[T0]]) // CHECK-NEXT: [[T2:%.*]] = bitcast i8* [[T1]] to i32* -// CHECK-NEXT: [[T3:%.*]] = load i32* [[T2]] +// CHECK-NEXT: [[T3:%.*]] = load i32, i32* [[T2]] // CHECK-NEXT: store i32 [[T3]], i32* {{%.*}}, align 4 // CHECK-NEXT: invoke void @__cxa_rethrow catch (int) { @@ -145,7 +145,7 @@ namespace test7 { // CHECK-NEXT: store i32 [[SELECTOR]], i32* [[SELECTORVAR]] // CHECK-NEXT: call void @__cxa_end_catch() // CHECK-NEXT: br label -// CHECK: load i8** [[CAUGHTEXNVAR]] +// CHECK: load i8*, i8** [[CAUGHTEXNVAR]] // CHECK-NEXT: call i8* @__cxa_begin_catch // CHECK-NEXT: call void @__cxa_end_catch catch (...) { @@ -221,7 +221,7 @@ namespace test10 { } catch (int i) { // CHECK: call i8* @__cxa_begin_catch // CHECK-NEXT: bitcast - // CHECK-NEXT: load i32* + // CHECK-NEXT: load i32, i32* // CHECK-NEXT: store i32 // CHECK-NEXT: call void @__cxa_end_catch() [[NUW:#[0-9]+]] } catch (B a) { @@ -251,9 +251,9 @@ namespace test11 { // CHECK: invoke void @_ZN6test116opaqueEv() opaque(); } catch (int**&p) { - // CHECK: [[EXN:%.*]] = load i8** + // CHECK: [[EXN:%.*]] = load i8*, i8** // CHECK-NEXT: call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]] - // CHECK-NEXT: [[ADJ1:%.*]] = getelementptr i8* [[EXN]], i32 32 + // CHECK-NEXT: [[ADJ1:%.*]] = getelementptr i8, i8* [[EXN]], i32 32 // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to i32*** // CHECK-NEXT: store i32*** [[ADJ2]], i32**** [[P:%.*]] // CHECK-NEXT: call void @__cxa_end_catch() [[NUW]] @@ -272,7 +272,7 @@ namespace test11 { // CHECK-NEXT: invoke void @_ZN6test116opaqueEv() opaque(); } catch (A*&p) { - // CHECK: [[EXN:%.*]] = load i8** [[EXNSLOT]] + // CHECK: [[EXN:%.*]] = load i8*, i8** [[EXNSLOT]] // CHECK-NEXT: [[ADJ1:%.*]] = call i8* @__cxa_begin_catch(i8* [[EXN]]) [[NUW]] // CHECK-NEXT: [[ADJ2:%.*]] = bitcast i8* [[ADJ1]] to [[A]]* // CHECK-NEXT: store [[A]]* [[ADJ2]], [[A]]** [[TMP]] @@ -384,7 +384,7 @@ namespace test15 { int x = 10; while (true) { - // CHECK: load i32* [[X]] + // CHECK: load i32, i32* [[X]] // CHECK-NEXT: [[COND:%.*]] = invoke zeroext i1 @_ZN6test156opaqueEi // CHECK: br i1 [[COND]] if (opaque(x)) @@ -438,9 +438,9 @@ namespace test16 { // CHECK: invoke void @_ZN6test161AD1Ev([[A]]* [[TEMP]]) // CHECK: ret void - // CHECK: [[T0:%.*]] = load i1* [[EXN_ACTIVE]] + // CHECK: [[T0:%.*]] = load i1, i1* [[EXN_ACTIVE]] // CHECK-NEXT: br i1 [[T0]] - // CHECK: [[T1:%.*]] = load i8** [[EXN_SAVE]] + // CHECK: [[T1:%.*]] = load i8*, i8** [[EXN_SAVE]] // CHECK-NEXT: call void @__cxa_free_exception(i8* [[T1]]) // CHECK-NEXT: br label } diff --git a/test/CodeGenCXX/empty-classes.cpp b/test/CodeGenCXX/empty-classes.cpp index 8491480..e27a961 100644 --- a/test/CodeGenCXX/empty-classes.cpp +++ b/test/CodeGenCXX/empty-classes.cpp @@ -1,5 +1,7 @@ // RUN: %clang_cc1 %s -I%S -triple=x86_64-apple-darwin10 -emit-llvm -O3 -o - | FileCheck %s +// CHECK: %"struct.rdar20621065::B" = type { float, float } + struct Empty { }; struct A { @@ -80,3 +82,17 @@ int main() { return result; } #endif + +namespace rdar20621065 { + struct A { + float array[0]; + }; + + struct B : A { + float left; + float right; + }; + + // Type checked at the top of the file. + B b; +}; diff --git a/test/CodeGenCXX/exceptions-seh-filter-captures.cpp b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp new file mode 100644 index 0000000..5df418a --- /dev/null +++ b/test/CodeGenCXX/exceptions-seh-filter-captures.cpp @@ -0,0 +1,80 @@ +// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \ +// RUN: -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | \ +// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CXXEH + +extern "C" int basic_filter(int v, ...); +extern "C" void might_crash(); + +extern "C" void test_freefunc(int p1) { + int l1 = 13; + static int s1 = 42; + __try { + might_crash(); + } __except(basic_filter(p1, l1, s1)) { + } +} + +// CHECK-LABEL: define void @test_freefunc(i32 %p1) +// CHECK: @llvm.frameescape(i32* %[[p1_ptr:[^, ]*]], i32* %[[l1_ptr:[^, ]*]]) +// CHECK: store i32 %p1, i32* %[[p1_ptr]], align 4 +// CHECK: store i32 13, i32* %[[l1_ptr]], align 4 +// CHECK: invoke void @might_crash() + +// CHECK-LABEL: define internal i32 @"\01?filt$0@0@test_freefunc@@"(i8* %exception_pointers, i8* %frame_pointer) +// CHECK: %[[p1_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 0) +// CHECK: %[[p1_ptr:[^ ]*]] = bitcast i8* %[[p1_i8]] to i32* +// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (i32)* @test_freefunc to i8*), i8* %frame_pointer, i32 1) +// CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32* +// CHECK: %[[s1:[^ ]*]] = load i32, i32* @"\01?s1@?1??test_freefunc@@9@4HA", align 4 +// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]] +// CHECK: %[[p1:[^ ]*]] = load i32, i32* %[[p1_ptr]] +// CHECK: call i32 (i32, ...) @basic_filter(i32 %[[p1]], i32 %[[l1]], i32 %[[s1]]) + +struct S { + int m1; + void test_method(void); +}; + +void S::test_method() { + int l1 = 13; + __try { + might_crash(); + } __except(basic_filter(l1)) { + // FIXME: Test capturing 'this' and 'm1'. + } +} + +// CHECK-LABEL: define void @"\01?test_method@S@@QEAAXXZ"(%struct.S* %this) +// CHECK: @llvm.frameescape(i32* %[[l1_addr:[^, ]*]]) +// CHECK: store i32 13, i32* %[[l1_addr]], align 4 +// CHECK: invoke void @might_crash() + +// CHECK-LABEL: define internal i32 @"\01?filt$0@0@test_method@S@@"(i8* %exception_pointers, i8* %frame_pointer) +// CHECK: %[[l1_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (%struct.S*)* @"\01?test_method@S@@QEAAXXZ" to i8*), i8* %frame_pointer, i32 0) +// CHECK: %[[l1_ptr:[^ ]*]] = bitcast i8* %[[l1_i8]] to i32* +// CHECK: %[[l1:[^ ]*]] = load i32, i32* %[[l1_ptr]] +// CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l1]]) + +void test_lambda() { + int l1 = 13; + auto lambda = [&]() { + int l2 = 42; + __try { + might_crash(); + } __except(basic_filter(l2)) { + // FIXME: Test 'l1' when we can capture the lambda's 'this' decl. + } + }; + lambda(); +} + +// CHECK-LABEL: define internal void @"\01??R<lambda_0>@?test_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this) +// CHECK: @llvm.frameescape(i32* %[[l2_addr:[^, ]*]]) +// CHECK: store i32 42, i32* %[[l2_addr]], align 4 +// CHECK: invoke void @might_crash() + +// CHECK-LABEL: define internal i32 @"\01?filt$0@0@?R<lambda_0>@?test_lambda@@YAXXZ@"(i8* %exception_pointers, i8* %frame_pointer) +// CHECK: %[[l2_i8:[^ ]*]] = call i8* @llvm.framerecover(i8* bitcast (void (%class.anon*)* @"\01??R<lambda_0>@?test_lambda@@YAXXZ@QEBAXXZ" to i8*), i8* %frame_pointer, i32 0) +// CHECK: %[[l2_ptr:[^ ]*]] = bitcast i8* %[[l2_i8]] to i32* +// CHECK: %[[l2:[^ ]*]] = load i32, i32* %[[l2_ptr]] +// CHECK: call i32 (i32, ...) @basic_filter(i32 %[[l2]]) diff --git a/test/CodeGenCXX/exceptions-seh.cpp b/test/CodeGenCXX/exceptions-seh.cpp new file mode 100644 index 0000000..3e77f12 --- /dev/null +++ b/test/CodeGenCXX/exceptions-seh.cpp @@ -0,0 +1,142 @@ +// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \ +// RUN: -o - -mconstructor-aliases -fcxx-exceptions -fexceptions | \ +// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=CXXEH +// RUN: %clang_cc1 -std=c++11 -fblocks -fms-extensions %s -triple=x86_64-windows-msvc -emit-llvm \ +// RUN: -o - -mconstructor-aliases -O1 -disable-llvm-optzns | \ +// RUN: FileCheck %s --check-prefix=CHECK --check-prefix=NOCXX + +extern "C" unsigned long _exception_code(); +extern "C" void might_throw(); + +struct HasCleanup { + HasCleanup(); + ~HasCleanup(); + int padding; +}; + +extern "C" void use_cxx() { + HasCleanup x; + might_throw(); +} + +// Make sure we use __CxxFrameHandler3 for C++ EH. + +// CXXEH-LABEL: define void @use_cxx() +// CXXEH: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) +// CXXEH: invoke void @might_throw() +// CXXEH: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] +// +// CXXEH: [[cont]] +// CXXEH: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) +// CXXEH: ret void +// +// CXXEH: [[lpad]] +// CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) +// CXXEH-NEXT: cleanup +// CXXEH: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) +// CXXEH: br label %[[resume:[^ ]*]] +// +// CXXEH: [[resume]] +// CXXEH: resume + +// NOCXX-LABEL: define void @use_cxx() +// NOCXX-NOT: invoke +// NOCXX: call %struct.HasCleanup* @"\01??0HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) +// NOCXX-NOT: invoke +// NOCXX: call void @might_throw() +// NOCXX-NOT: invoke +// NOCXX: call void @"\01??1HasCleanup@@QEAA@XZ"(%struct.HasCleanup* %{{.*}}) +// NOCXX-NOT: invoke +// NOCXX: ret void + +extern "C" void use_seh() { + __try { + might_throw(); + } __except(1) { + } +} + +// Make sure we use __C_specific_handler for SEH. + +// CHECK-LABEL: define void @use_seh() +// CHECK: invoke void @might_throw() #[[NOINLINE:[0-9]+]] +// CHECK: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] +// +// CHECK: [[cont]] +// CHECK: br label %[[ret:[^ ]*]] +// +// CHECK: [[lpad]] +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK-NEXT: catch i8* +// +// CHECK: br label %[[ret]] +// +// CHECK: [[ret]] +// CHECK: ret void + +void use_seh_in_lambda() { + ([]() { + __try { + might_throw(); + } __except(1) { + } + })(); + HasCleanup x; + might_throw(); +} + +// CXXEH-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"() +// CXXEH: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) + +// NOCXX-LABEL: define void @"\01?use_seh_in_lambda@@YAXXZ"() +// NOCXX-NOT: invoke +// NOCXX: ret void + +// CHECK-LABEL: define internal void @"\01??R<lambda_0>@?use_seh_in_lambda@@YAXXZ@QEBAXXZ"(%class.anon* %this) +// CHECK: invoke void @might_throw() #[[NOINLINE]] +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) + +static int my_unique_global; + +extern "C" inline void use_seh_in_inline_func() { + __try { + might_throw(); + } __except(_exception_code() == 424242) { + } + __try { + might_throw(); + } __finally { + my_unique_global = 1234; + } +} + +void use_inline() { + use_seh_in_inline_func(); +} + +// CHECK-LABEL: define linkonce_odr void @use_seh_in_inline_func() #{{[0-9]+}} comdat { +// CHECK: invoke void @might_throw() +// +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK-NEXT: catch i8* bitcast (i32 (i8*, i8*)* @"\01?filt$0@0@use_seh_in_inline_func@@" to i8*) +// +// CHECK: invoke void @might_throw() +// +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 0, i8* %[[fp]]) +// CHECK: ret void +// +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__C_specific_handler to i8*) +// CHECK-NEXT: cleanup +// CHECK: %[[fp:[^ ]*]] = call i8* @llvm.frameaddress(i32 0) +// CHECK: call void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 1, i8* %[[fp]]) + +// CHECK-LABEL: define internal i32 @"\01?filt$0@0@use_seh_in_inline_func@@"(i8* %exception_pointers, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func) +// CHECK: icmp eq i32 %{{.*}}, 424242 +// CHECK: zext i1 %{{.*}} to i32 +// CHECK: ret i32 + +// CHECK-LABEL: define internal void @"\01?fin$0@0@use_seh_in_inline_func@@"(i8 %abnormal_termination, i8* %frame_pointer) #{{[0-9]+}} comdat($use_seh_in_inline_func) +// CHECK: store i32 1234, i32* @my_unique_global + +// CHECK: attributes #[[NOINLINE]] = { {{.*noinline.*}} } diff --git a/test/CodeGenCXX/exceptions.cpp b/test/CodeGenCXX/exceptions.cpp index 5016e9a..e8f6c79 100644 --- a/test/CodeGenCXX/exceptions.cpp +++ b/test/CodeGenCXX/exceptions.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s +// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -o - -fcxx-exceptions -fexceptions | FileCheck %s typedef typeof(sizeof(0)) size_t; @@ -57,13 +57,13 @@ namespace test1 { // CHECK-NEXT: store i1 true, i1* [[ACTIVE]] // CHECK-NEXT: [[CAST:%.*]] = bitcast i8* [[NEW]] to [[A]]* // CHECK-NEXT: invoke void @_ZN5test11BC1Ev([[B:%.*]]* [[T0:%.*]]) - // CHECK: [[T1:%.*]] = getelementptr inbounds [[B]]* [[T0]], i32 0, i32 0 - // CHECK-NEXT: [[T2:%.*]] = load i32* [[T1]], align 4 + // CHECK: [[T1:%.*]] = getelementptr inbounds [[B]], [[B]]* [[T0]], i32 0, i32 0 + // CHECK-NEXT: [[T2:%.*]] = load i32, i32* [[T1]], align 4 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[CAST]], i32 [[T2]]) // CHECK: store i1 false, i1* [[ACTIVE]] // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) // CHECK: ret [[A]]* [[CAST]] - // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] + // CHECK: [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]] // CHECK-NEXT: br i1 [[ISACTIVE]] // CHECK: call void @_ZdlPv(i8* [[NEW]]) return new A(B().x); @@ -71,7 +71,7 @@ namespace test1 { // rdar://11904428 // Terminate landing pads should call __cxa_begin_catch first. - // CHECK: define linkonce_odr hidden void @__clang_call_terminate(i8*) [[NI_NR_NUW:#[0-9]+]] + // CHECK: define linkonce_odr hidden void @__clang_call_terminate(i8*) [[NI_NR_NUW:#[0-9]+]] comdat // CHECK-NEXT: [[T0:%.*]] = call i8* @__cxa_begin_catch(i8* %0) [[NUW:#[0-9]+]] // CHECK-NEXT: call void @_ZSt9terminatev() [[NR_NUW:#[0-9]+]] // CHECK-NEXT: unreachable @@ -88,7 +88,7 @@ namespace test1 { // CHECK: store i1 false, i1* [[ACTIVE]] // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) // CHECK: ret [[A]]* [[CAST]] - // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] + // CHECK: [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]] // CHECK-NEXT: br i1 [[ISACTIVE]] // CHECK: call void @_ZdlPv(i8* [[NEW]]) return new A(B()); @@ -109,7 +109,7 @@ namespace test1 { // CHECK-NEXT: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]]) // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) // CHECK: ret [[A]]* [[CAST]] - // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] + // CHECK: [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]] // CHECK-NEXT: br i1 [[ISACTIVE]] // CHECK: call void @_ZdlPv(i8* [[NEW]]) return new A(B(), B()); @@ -137,11 +137,11 @@ namespace test1 { // CHECK: store i1 false, i1* [[ACTIVE]] // CHECK-NEXT: store [[A]]* [[CAST]], [[A]]** [[X]], align 8 // CHECK: invoke void @_ZN5test15makeBEv([[B:%.*]]* sret [[T2:%.*]]) - // CHECK: [[RET:%.*]] = load [[A]]** [[X]], align 8 + // CHECK: [[RET:%.*]] = load [[A]]*, [[A]]** [[X]], align 8 // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T2]]) // CHECK: invoke void @_ZN5test11BD1Ev([[B]]* [[T0]]) // CHECK: ret [[A]]* [[RET]] - // CHECK: [[ISACTIVE:%.*]] = load i1* [[ACTIVE]] + // CHECK: [[ISACTIVE:%.*]] = load i1, i1* [[ACTIVE]] // CHECK-NEXT: br i1 [[ISACTIVE]] // CHECK: call void @_ZdlPv(i8* [[NEW]]) A *x; @@ -228,10 +228,10 @@ namespace test3 { // CHECK: ret [[A]]* [[RESULT]] // in the EH path: - // CHECK: [[ISACTIVE:%.*]] = load i1* [[CLEANUPACTIVE]] + // CHECK: [[ISACTIVE:%.*]] = load i1, i1* [[CLEANUPACTIVE]] // CHECK-NEXT: br i1 [[ISACTIVE]] - // CHECK: [[V0:%.*]] = load i8** [[SAVED0]] - // CHECK-NEXT: [[V1:%.*]] = load i8** [[SAVED1]] + // CHECK: [[V0:%.*]] = load i8*, i8** [[SAVED0]] + // CHECK-NEXT: [[V1:%.*]] = load i8*, i8** [[SAVED1]] // CHECK-NEXT: invoke void @_ZN5test31AdlEPvS1_d(i8* [[V0]], i8* [[V1]], double [[CONST]]) } } @@ -275,7 +275,7 @@ namespace test5 { // CHECK-NEXT: [[A:%.*]] = alloca [[A_T:%.*]], align 1 // CHECK-NEXT: [[T:%.*]] = alloca [[T_T:%.*]], align 1 // CHECK-NEXT: invoke void @_ZN5test53fooEv() - // CHECK: [[EXN:%.*]] = load i8** [[EXNSLOT]] + // CHECK: [[EXN:%.*]] = load i8*, i8** [[EXNSLOT]] // CHECK-NEXT: [[ADJ:%.*]] = call i8* @__cxa_get_exception_ptr(i8* [[EXN]]) // CHECK-NEXT: [[SRC:%.*]] = bitcast i8* [[ADJ]] to [[A_T]]* // CHECK-NEXT: invoke void @_ZN5test51TC1Ev([[T_T]]* [[T]]) @@ -375,12 +375,12 @@ namespace test7 { // CHECK-NEXT: store [[B]]* // Destroy the inner A object. - // CHECK-NEXT: load i1* [[INNER_A]] + // CHECK-NEXT: load i1, i1* [[INNER_A]] // CHECK-NEXT: br i1 // CHECK: invoke void @_ZN5test71AD1Ev( // Destroy the outer A object. - // CHECK: load i1* [[OUTER_A]] + // CHECK: load i1, i1* [[OUTER_A]] // CHECK-NEXT: br i1 // CHECK: invoke void @_ZN5test71AD1Ev( @@ -450,7 +450,7 @@ namespace test10 { // CHECK-LABEL: define void @_ZN6test101CD1Ev( // CHECK: invoke void @_ZN6test107cleanupEv() // CHECK: call i8* @__cxa_begin_catch - // CHECK-NEXT: load i8* @_ZN6test108suppressE, align 1 + // CHECK-NEXT: load i8, i8* @_ZN6test108suppressE, align 1 // CHECK-NEXT: trunc // CHECK-NEXT: br i1 // CHECK: call void @__cxa_end_catch() @@ -478,18 +478,18 @@ namespace test11 { throw 0; } // CHECK-LABEL: define void @_ZN6test111CC2Ev( - // CHECK: [[THIS:%.*]] = load [[C:%.*]]** {{%.*}} + // CHECK: [[THIS:%.*]] = load [[C:%.*]]*, [[C:%.*]]** {{%.*}} // Construct single. - // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[C]]* [[THIS]], i32 0, i32 0 + // CHECK-NEXT: [[SINGLE:%.*]] = getelementptr inbounds [[C]], [[C]]* [[THIS]], i32 0, i32 0 // CHECK-NEXT: call void @_ZN6test111AC1Ev([[A:%.*]]* [[SINGLE]]) // Construct array. - // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[C]]* [[THIS]], i32 0, i32 1 - // CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0 - // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]]* [[ARRAYBEGIN]], i64 6 + // CHECK-NEXT: [[ARRAY:%.*]] = getelementptr inbounds [[C]], [[C]]* [[THIS]], i32 0, i32 1 + // CHECK-NEXT: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]], [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0 + // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ARRAYBEGIN]], i64 6 // CHECK-NEXT: br label // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[ARRAYBEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] // CHECK-NEXT: invoke void @_ZN6test111AC1Ev([[A:%.*]]* [[CUR]]) - // CHECK: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1 + // CHECK: [[NEXT]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1 // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[ARRAYEND]] // CHECK-NEXT: br i1 [[DONE]], // throw 0; @@ -500,7 +500,7 @@ namespace test11 { // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[ARRAYBEGIN]], [[CUR]] // CHECK-NEXT: br i1 [[EMPTY]] // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ] - // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1 + // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1 // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]]) // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]] // CHECK-NEXT: br i1 [[DONE]], @@ -509,11 +509,11 @@ namespace test11 { // Landing pad 2, from throw site. // CHECK: landingpad // - First, destroy all of array. - // CHECK: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0 - // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]]* [[ARRAYBEGIN]], i64 6 + // CHECK: [[ARRAYBEGIN:%.*]] = getelementptr inbounds [2 x [3 x [[A]]]], [2 x [3 x [[A]]]]* [[ARRAY]], i32 0, i32 0, i32 0 + // CHECK-NEXT: [[ARRAYEND:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ARRAYBEGIN]], i64 6 // CHECK-NEXT: br label // CHECK: [[AFTER:%.*]] = phi [[A]]* [ [[ARRAYEND]], {{%.*}} ], [ [[ELT:%.*]], {{%.*}} ] - // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1 + // CHECK-NEXT: [[ELT]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1 // CHECK-NEXT: invoke void @_ZN6test111AD1Ev([[A]]* [[ELT]]) // CHECK: [[DONE:%.*]] = icmp eq [[A]]* [[ELT]], [[ARRAYBEGIN]] // CHECK-NEXT: br i1 [[DONE]], diff --git a/test/CodeGenCXX/field-access-debug-info.cpp b/test/CodeGenCXX/field-access-debug-info.cpp index 2b5b53d..38c06f1 100644 --- a/test/CodeGenCXX/field-access-debug-info.cpp +++ b/test/CodeGenCXX/field-access-debug-info.cpp @@ -1,7 +1,12 @@ // RUN: %clang -g -S -emit-llvm %s -o - | FileCheck %s -// CHECK: [ DW_TAG_member ] [p] [{{[^]]*}}] [public] [from int] -// CHECK: [ DW_TAG_member ] [pr] [{{[^]]*}}] [from int] +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "p" +// CHECK-SAME: baseType: ![[INT:[0-9]+]] +// CHECK-SAME: DIFlagPublic +// CHECK: ![[INT]] = !DIBasicType(name: "int" +// CHECK: !DIDerivedType(tag: DW_TAG_member, name: "pr" +// CHECK-NOT: flags: +// CHECK-SAME: baseType: ![[INT]] class A { public: diff --git a/test/CodeGenCXX/global-array-destruction.cpp b/test/CodeGenCXX/global-array-destruction.cpp index 0397851..cb3524b 100644 --- a/test/CodeGenCXX/global-array-destruction.cpp +++ b/test/CodeGenCXX/global-array-destruction.cpp @@ -56,7 +56,7 @@ using U = T[2][3]; U &&u = U{ {{1.0, 2}, {3.0, 4}, {5.0, 6}}, {{7.0, 8}, {9.0, 10}, {11.0, 12}} }; // CHECK: call {{.*}} @__cxa_atexit -// CHECK: getelementptr inbounds ({{.*}}* getelementptr inbounds ([2 x [3 x {{.*}}]]* @_ZGR1u_, i32 0, i32 0, i32 0), i64 6) +// CHECK: getelementptr inbounds ({{.*}}* getelementptr inbounds ([2 x [3 x {{.*}}]], [2 x [3 x {{.*}}]]* @_ZGR1u_, i32 0, i32 0, i32 0), i64 6) // CHECK: call void @_ZN1TD1Ev // CHECK: icmp eq {{.*}} @_ZGR1u_ // CHECK: br i1 {{.*}} diff --git a/test/CodeGenCXX/global-dtor-no-atexit.cpp b/test/CodeGenCXX/global-dtor-no-atexit.cpp index 9d35e84..9860412 100644 --- a/test/CodeGenCXX/global-dtor-no-atexit.cpp +++ b/test/CodeGenCXX/global-dtor-no-atexit.cpp @@ -43,4 +43,4 @@ void func() { static A a1, a2; } -// CHECK: attributes [[NUW]] = { nounwind } +// CHECK: attributes [[NUW]] = { nounwind{{.*}} } diff --git a/test/CodeGenCXX/global-init.cpp b/test/CodeGenCXX/global-init.cpp index 9c5b03a..e806af9 100644 --- a/test/CodeGenCXX/global-init.cpp +++ b/test/CodeGenCXX/global-init.cpp @@ -1,5 +1,8 @@ // RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm -fexceptions %s -o - |FileCheck %s // RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm %s -o - |FileCheck -check-prefix CHECK-NOEXC %s +// RUN: %clang_cc1 -triple=x86_64-apple-darwin10 -emit-llvm \ +// RUN: -momit-leaf-frame-pointer -mdisable-fp-elim %s -o - \ +// RUN: | FileCheck -check-prefix CHECK-FP %s struct A { A(); @@ -16,26 +19,26 @@ struct D { ~D(); }; // CHECK: @c = global %struct.C zeroinitializer, align 8 // It's okay if we ever implement the IR-generation optimization to remove this. -// CHECK: @_ZN5test3L3varE = internal constant i8* getelementptr inbounds ([7 x i8]* +// CHECK: @_ZN5test3L3varE = internal constant i8* getelementptr inbounds ([7 x i8], [7 x i8]* // PR6205: The casts should not require global initializers // CHECK: @_ZN6PR59741cE = external global %"struct.PR5974::C" -// CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* getelementptr inbounds (%"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0) -// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::B"* bitcast (i8* getelementptr (i8* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to i8*), i64 4) to %"struct.PR5974::B"*), align 8 +// CHECK: @_ZN6PR59741aE = global %"struct.PR5974::A"* getelementptr inbounds (%"struct.PR5974::C", %"struct.PR5974::C"* @_ZN6PR59741cE, i32 0, i32 0) +// CHECK: @_ZN6PR59741bE = global %"struct.PR5974::B"* bitcast (i8* getelementptr (i8, i8* bitcast (%"struct.PR5974::C"* @_ZN6PR59741cE to i8*), i64 4) to %"struct.PR5974::B"*), align 8 // CHECK: call void @_ZN1AC1Ev(%struct.A* @a) -// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @a, i32 0, i32 0), i8* @__dso_handle) +// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A, %struct.A* @a, i32 0, i32 0), i8* @__dso_handle) A a; // CHECK: call void @_ZN1BC1Ev(%struct.B* @b) -// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.B*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.B* @b, i32 0, i32 0), i8* @__dso_handle) +// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.B*)* @_ZN1BD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.B, %struct.B* @b, i32 0, i32 0), i8* @__dso_handle) B b; // PR6205: this should not require a global initializer // CHECK-NOT: call void @_ZN1CC1Ev(%struct.C* @c) C c; -// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.D*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.D* @d, i32 0, i32 0), i8* @__dso_handle) +// CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.D*)* @_ZN1DD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.D, %struct.D* @d, i32 0, i32 0), i8* @__dso_handle) D d; // <rdar://problem/7458115> @@ -77,7 +80,7 @@ namespace test4 { extern int foo(); // This needs an initialization function and guard variables. - // CHECK: load i8* bitcast (i64* @_ZGVN5test41xE + // CHECK: load i8, i8* bitcast (i64* @_ZGVN5test41xE // CHECK: [[CALL:%.*]] = call i32 @_ZN5test43fooEv // CHECK-NEXT: store i32 [[CALL]], i32* @_ZN5test41xE // CHECK-NEXT: store i64 1, i64* @_ZGVN5test41xE @@ -187,19 +190,23 @@ namespace test7 { // At the end of the file, we check that y is initialized before z. // CHECK: define internal void [[TEST1_Z_INIT:@.*]]() -// CHECK: load i32* @_ZN5test1L1yE +// CHECK: load i32, i32* @_ZN5test1L1yE // CHECK-NEXT: xor // CHECK-NEXT: store i32 {{.*}}, i32* @_ZN5test1L1zE // CHECK: define internal void [[TEST1_Y_INIT:@.*]]() -// CHECK: load i32* @_ZN5test1L1xE +// CHECK: load i32, i32* @_ZN5test1L1xE // CHECK-NEXT: sub // CHECK-NEXT: store i32 {{.*}}, i32* @_ZN5test1L1yE -// CHECK: define internal void @_GLOBAL__sub_I_global_init.cpp() section "__TEXT,__StaticInit,regular,pure_instructions" { +// CHECK: define internal void @_GLOBAL__sub_I_global_init.cpp() #{{[0-9]+}} section "__TEXT,__StaticInit,regular,pure_instructions" { // CHECK: call void [[TEST1_Y_INIT]] // CHECK: call void [[TEST1_Z_INIT]] // rdar://problem/8090834: this should be nounwind // CHECK-NOEXC: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUW:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" { -// CHECK-NOEXC: attributes [[NUW]] = { nounwind } +// CHECK-NOEXC: attributes [[NUW]] = { nounwind{{.*}} } + +// PR21811: attach the appropriate attribute to the global init function +// CHECK-FP: define internal void @_GLOBAL__sub_I_global_init.cpp() [[NUX:#[0-9]+]] section "__TEXT,__StaticInit,regular,pure_instructions" { +// CHECK-FP: attributes [[NUX]] = { nounwind {{.*}}"no-frame-pointer-elim-non-leaf"{{.*}} } diff --git a/test/CodeGenCXX/globalinit-loc.cpp b/test/CodeGenCXX/globalinit-loc.cpp index 583f9c7..813a890 100644 --- a/test/CodeGenCXX/globalinit-loc.cpp +++ b/test/CodeGenCXX/globalinit-loc.cpp @@ -6,8 +6,11 @@ // // CHECK: define internal void @_GLOBAL__sub_I_globalinit_loc.cpp // CHECK: !dbg ![[DBG:.*]] -// CHECK: !"0x2e\00\00\00_GLOBAL__sub_I_globalinit_loc.cpp\000\00{{.*}}\000", {{.*}} ; [ DW_TAG_subprogram ] [line 0] [local] [def] -// CHECK: ![[DBG]] = !MDLocation(line: 0, +// CHECK: !DISubprogram(linkageName: "_GLOBAL__sub_I_globalinit_loc.cpp" +// CHECK-NOT: line: +// CHECK-SAME: isLocal: true +// CHECK-SAME: isDefinition: true +// CHECK: ![[DBG]] = !DILocation(line: 0, # 99 "someheader.h" class A { public: diff --git a/test/CodeGenCXX/homogeneous-aggregates.cpp b/test/CodeGenCXX/homogeneous-aggregates.cpp index 94813f3..fbbb1eb 100644 --- a/test/CodeGenCXX/homogeneous-aggregates.cpp +++ b/test/CodeGenCXX/homogeneous-aggregates.cpp @@ -78,7 +78,7 @@ void call_D5(D5 *p) { // Check the call site. // // ARM64-LABEL: define void @_Z7call_D5P2D5(%struct.D5* %p) -// ARM64: load [3 x double]* +// ARM64: load [3 x double], [3 x double]* // ARM64: call %struct.D5 @_Z7func_D52D5([3 x double] %{{.*}}) struct Empty { }; diff --git a/test/CodeGenCXX/implicit-record-visibility.cpp b/test/CodeGenCXX/implicit-record-visibility.cpp new file mode 100644 index 0000000..701a203 --- /dev/null +++ b/test/CodeGenCXX/implicit-record-visibility.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 %s -I%S -fvisibility hidden -triple x86_64-linux-gnu -emit-llvm -o - | FileCheck %s + +#include <stdarg.h> +#include <typeinfo> + +// If struct __va_list_tag did not explicitly have default visibility, then +// under -fvisibility hidden the type of function f, due to its va_list (aka +// __builtin_va_list, aka __va_list_tag (*)[1]) parameter would be hidden: + +// CHECK: @_ZTSFvP13__va_list_tagE = linkonce_odr constant +// CHECK: @_ZTIFvP13__va_list_tagE = linkonce_odr constant +void f(va_list) { (void)typeid(f); } diff --git a/test/CodeGenCXX/inheriting-constructor.cpp b/test/CodeGenCXX/inheriting-constructor.cpp index 9394137..42080a2 100644 --- a/test/CodeGenCXX/inheriting-constructor.cpp +++ b/test/CodeGenCXX/inheriting-constructor.cpp @@ -21,8 +21,8 @@ D d(123); // CHECK-LABEL: define linkonce_odr void @_ZN1DC1IiEET_( // CHECK: call void @_ZN1DC2IiEET_( -// CHECK-LABEL: define linkonce_odr void @_ZN1DC2IiEET_( -// CHECK: call void @_ZN1CC2IiEET_( - // CHECK-LABEL: define linkonce_odr void @_ZN1BC2Ei( // CHECK: call void @_ZN1AC2Ei( + +// CHECK-LABEL: define linkonce_odr void @_ZN1DC2IiEET_( +// CHECK: call void @_ZN1CC2IiEET_( diff --git a/test/CodeGenCXX/inline-dllexport-member.cpp b/test/CodeGenCXX/inline-dllexport-member.cpp new file mode 100644 index 0000000..af9a536 --- /dev/null +++ b/test/CodeGenCXX/inline-dllexport-member.cpp @@ -0,0 +1,11 @@ +// RUN: %clang_cc1 -triple i686-windows-gnu -fms-compatibility -g -emit-llvm %s -o - \ +// RUN: | FileCheck %s + +struct __declspec(dllexport) s { + static const unsigned int ui = 0; +}; + +// CHECK: ![[SCOPE:[0-9]+]] = !DICompileUnit( +// CHECK: !DIGlobalVariable(name: "ui", linkageName: "_ZN1s2uiE", scope: ![[SCOPE]], +// CHECK-SAME: variable: i32* @_ZN1s2uiE + diff --git a/test/CodeGenCXX/key-function-vtable.cpp b/test/CodeGenCXX/key-function-vtable.cpp index 0ecd898..f6aa16e 100644 --- a/test/CodeGenCXX/key-function-vtable.cpp +++ b/test/CodeGenCXX/key-function-vtable.cpp @@ -41,13 +41,11 @@ struct X1 : X0 { inline void X1::f() { } -void use_X1(X1 *x1) { x1->f(); } - -// FIXME: The checks are extremely difficult to get right when the globals -// aren't alphabetized -// CHECK: @_ZTV2X1 = linkonce_odr unnamed_addr constant -// CHECK: @_ZTV5testa = unnamed_addr constant [3 x i8*] [i8* null -// CHECK: @_ZTV5testc = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null -// CHECK: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant [3 x i8*] [i8* null -// CHECK: @_ZTV5teste = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null -// CHECK: @_ZTV5testb = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null +void use_X1() { X1 x1; } + +// CHECK-DAG: @_ZTV2X1 = linkonce_odr unnamed_addr constant +// CHECK-DAG: @_ZTV5testa = unnamed_addr constant [3 x i8*] [i8* null +// CHECK-DAG: @_ZTV5testc = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null +// CHECK-DAG: @_ZTV5testb = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null +// CHECK-DAG: @_ZTV5teste = linkonce_odr unnamed_addr constant [3 x i8*] [i8* null +// CHECK-DAG: @_ZTVN12_GLOBAL__N_15testgE = internal unnamed_addr constant [3 x i8*] [i8* null diff --git a/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp b/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp index accc5d2..9a44987 100644 --- a/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp +++ b/test/CodeGenCXX/lambda-expressions-nested-linkage.cpp @@ -30,8 +30,16 @@ L<int> l; } // CHECK-LABEL: define linkonce_odr i32 @_ZN15inline_function3fooEv -// CHECK: define linkonce_odr void @_ZZN15inline_function3fooEvENKUliE_clEi -// CHECK: define linkonce_odr signext i8 @_ZZZN15inline_function3fooEvENKUliE_clEiENKUlcE_clEc + +// CHECK-LABEL: define linkonce_odr void @_ZNK12non_template1L1tMUliE_clEi(%class.anon +// CHECK-LABEL: define linkonce_odr i32 @_ZZNK12non_template1L1tMUliE_clEiENKUliE_clEi(%class.anon + + +// CHECK-LABEL: define linkonce_odr void @_ZNK32lambdas_in_NSDMIs_template_class1LIiEUliE_clEi(%class.anon +// CHECK-LABEL: define linkonce_odr i32 @_ZZNK32lambdas_in_NSDMIs_template_class1LIiEUliE_clEiENKUliE_clEi(%class.anon + +// CHECK-LABEL: define linkonce_odr void @_ZZN15inline_function3fooEvENKUliE_clEi +// CHECK-LABEL: define linkonce_odr signext i8 @_ZZZN15inline_function3fooEvENKUliE_clEiENKUlcE_clEc namespace inline_function { inline int foo() { auto L = [](int a) { @@ -43,8 +51,3 @@ inline int foo() { } int use = foo(); } -// CHECK: define linkonce_odr void @_ZNK32lambdas_in_NSDMIs_template_class1LIiEUliE_clEi(%class.anon -// CHECK: define linkonce_odr i32 @_ZZNK32lambdas_in_NSDMIs_template_class1LIiEUliE_clEiENKUliE_clEi(%class.anon - -// CHECK: define linkonce_odr void @_ZNK12non_template1L1tMUliE_clEi(%class.anon -// CHECK: define linkonce_odr i32 @_ZZNK12non_template1L1tMUliE_clEiENKUliE_clEi(%class.anon diff --git a/test/CodeGenCXX/lambda-expressions.cpp b/test/CodeGenCXX/lambda-expressions.cpp index 49b9efb..28a8841 100644 --- a/test/CodeGenCXX/lambda-expressions.cpp +++ b/test/CodeGenCXX/lambda-expressions.cpp @@ -19,11 +19,11 @@ int a() { return []{ return 1; }(); } int b(int x) { return [x]{return x;}(); } // CHECK-LABEL: define i32 @_Z1bi // CHECK: store i32 -// CHECK: load i32* +// CHECK: load i32, i32* // CHECK: store i32 // CHECK: call i32 @"_ZZ1biENK3$_1clEv" // CHECK-LABEL: define internal i32 @"_ZZ1biENK3$_1clEv" -// CHECK: load i32* +// CHECK: load i32, i32* // CHECK: ret i32 int c(int x) { return [&x]{return x;}(); } @@ -32,8 +32,8 @@ int c(int x) { return [&x]{return x;}(); } // CHECK: store i32* // CHECK: call i32 @"_ZZ1ciENK3$_2clEv" // CHECK-LABEL: define internal i32 @"_ZZ1ciENK3$_2clEv" -// CHECK: load i32** -// CHECK: load i32* +// CHECK: load i32*, i32** +// CHECK: load i32, i32* // CHECK: ret i32 struct D { D(); D(const D&); int x; }; @@ -45,8 +45,8 @@ int d(int x) { D y[10]; [x,y] { return y[x].x; }(); } // CHECK: call void @_ZN1DC1ERKS_ // CHECK: call i32 @"_ZZ1diENK3$_3clEv" // CHECK-LABEL: define internal i32 @"_ZZ1diENK3$_3clEv" -// CHECK: load i32* -// CHECK: load i32* +// CHECK: load i32, i32* +// CHECK: load i32, i32* // CHECK: ret i32 struct E { E(); E(const E&); ~E(); int x; }; @@ -60,7 +60,7 @@ int e(E a, E b, bool cond) { [a,b,cond](){ return (cond ? a : b).x; }(); } // CHECK-LABEL: define internal i32 @"_ZZ1e1ES_bENK3$_4clEv" // CHECK: trunc i8 -// CHECK: load i32* +// CHECK: load i32, i32* // CHECK: ret i32 void f() { @@ -76,12 +76,12 @@ int g() { int &r = k; // CHECK-LABEL: define internal i32 @"_ZZ1gvENK3$_6clEv"( // CHECK-NOT: } - // CHECK: load i32* @_ZL1k, + // CHECK: load i32, i32* @_ZL1k, return [] { return r; } (); }; // PR14773 -// CHECK: [[ARRVAL:%[0-9a-zA-Z]*]] = load i32* getelementptr inbounds ([0 x i32]* @_ZZ14staticarrayrefvE5array, i32 0, i64 0), align 4 +// CHECK: [[ARRVAL:%[0-9a-zA-Z]*]] = load i32, i32* getelementptr inbounds ([0 x i32], [0 x i32]* @_ZZ14staticarrayrefvE5array, i32 0, i64 0), align 4 // CHECK-NEXT: store i32 [[ARRVAL]] void staticarrayref(){ static int array[] = {}; @@ -99,24 +99,24 @@ int *PR22071_fun() { return [&] { return &y; }(); } -// CHECK: define internal void @"_ZZ1hvEN3$_98__invokeEv"(%struct.A* noalias sret %agg.result) {{.*}} { -// CHECK-NOT: = -// CHECK: call void @"_ZZ1hvENK3$_9clEv"(%struct.A* sret %agg.result, -// CHECK-NEXT: ret void -struct A { ~A(); }; -void h() { - A (*h)() = [] { return A(); }; -} +// CHECK-LABEL: define internal void @"_ZZ1e1ES_bEN3$_4D2Ev" // CHECK-LABEL: define internal i32 @"_ZZ1fvEN3$_58__invokeEii" // CHECK: store i32 // CHECK-NEXT: store i32 -// CHECK-NEXT: load i32* -// CHECK-NEXT: load i32* +// CHECK-NEXT: load i32, i32* +// CHECK-NEXT: load i32, i32* // CHECK-NEXT: call i32 @"_ZZ1fvENK3$_5clEii" // CHECK-NEXT: ret i32 -// CHECK-LABEL: define internal void @"_ZZ1e1ES_bEN3$_4D2Ev" +// CHECK-LABEL: define internal void @"_ZZ1hvEN3$_98__invokeEv"(%struct.A* noalias sret %agg.result) {{.*}} { +// CHECK-NOT: = +// CHECK: call void @"_ZZ1hvENK3$_9clEv"(%struct.A* sret %agg.result, +// CHECK-NEXT: ret void +struct A { ~A(); }; +void h() { + A (*h)() = [] { return A(); }; +} // <rdar://problem/12778708> struct XXX {}; @@ -128,3 +128,12 @@ void nestedCapture () { }; }; } + +// Ensure we don't assert here. +struct CaptureArrayAndThis { + CaptureArrayAndThis() { + char array[] = "floop"; + [array, this] {}; + } +} capture_array_and_this; + diff --git a/test/CodeGenCXX/linetable-cleanup.cpp b/test/CodeGenCXX/linetable-cleanup.cpp index 3a6aa88..99aa814 100644 --- a/test/CodeGenCXX/linetable-cleanup.cpp +++ b/test/CodeGenCXX/linetable-cleanup.cpp @@ -4,8 +4,8 @@ // simple return expressions. // CHECK: define {{.*}}foo -// CHECK: call void @_ZN1CD1Ev(%class.C* {{.*}}), !dbg ![[CLEANUP:[0-9]+]] -// CHECK: ret i32 0, !dbg ![[RET:[0-9]+]] +// CHECK: call void @_ZN1CD1Ev(%class.C* {{.*}}), !dbg ![[RET:[0-9]+]] +// CHECK: ret i32 0, !dbg ![[RET]] // CHECK: define {{.*}}bar // CHECK: ret void, !dbg ![[RETBAR:[0-9]+]] @@ -23,16 +23,15 @@ int foo() { C c; c.i = 42; - // This breakpoint should be at/before the cleanup code. - // CHECK: ![[CLEANUP]] = !MDLocation(line: [[@LINE+1]], scope: !{{.*}}) return 0; - // CHECK: ![[RET]] = !MDLocation(line: [[@LINE+1]], scope: !{{.*}}) + // This breakpoint should be at/before the cleanup code. + // CHECK: ![[RET]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}}) } void bar() { if (!foo()) - // CHECK: {{.*}} = !MDLocation(line: [[@LINE+1]], scope: !{{.*}}) + // CHECK: {{.*}} = !DILocation(line: [[@LINE+1]], scope: !{{.*}}) return; if (foo()) { @@ -40,21 +39,21 @@ void bar() c.i = foo(); } // Clang creates only a single ret instruction. Make sure it is at a useful line. - // CHECK: ![[RETBAR]] = !MDLocation(line: [[@LINE+1]], scope: !{{.*}}) + // CHECK: ![[RETBAR]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}}) } void baz() { if (!foo()) - // CHECK: ![[SCOPE1:.*]] = !{!"0xb\00[[@LINE-1]]\00{{.*}}", {{.*}} ; [ DW_TAG_lexical_block ] - // CHECK: {{.*}} = !MDLocation(line: [[@LINE+1]], scope: ![[SCOPE1]]) + // CHECK: ![[SCOPE1:.*]] = distinct !DILexicalBlock({{.*}}, line: [[@LINE-1]]) + // CHECK: {{.*}} = !DILocation(line: [[@LINE+1]], scope: ![[SCOPE1]]) return; if (foo()) { // no cleanup - // CHECK: {{.*}} = !MDLocation(line: [[@LINE+2]], scope: ![[SCOPE2:.*]]) - // CHECK: ![[SCOPE2]] = !{!"0xb\00[[@LINE-3]]\00{{.*}}", {{.*}} ; [ DW_TAG_lexical_block ] + // CHECK: {{.*}} = !DILocation(line: [[@LINE+2]], scope: ![[SCOPE2:.*]]) + // CHECK: ![[SCOPE2]] = distinct !DILexicalBlock({{.*}}, line: [[@LINE-3]]) return; } - // CHECK: ![[RETBAZ]] = !MDLocation(line: [[@LINE+1]], scope: !{{.*}}) + // CHECK: ![[RETBAZ]] = !DILocation(line: [[@LINE+1]], scope: !{{.*}}) } diff --git a/test/CodeGenCXX/linetable-eh.cpp b/test/CodeGenCXX/linetable-eh.cpp index 6d9b3a9..219aab1 100644 --- a/test/CodeGenCXX/linetable-eh.cpp +++ b/test/CodeGenCXX/linetable-eh.cpp @@ -10,12 +10,12 @@ // CHECK-NEXT: call void @llvm.dbg.declare(metadata {{.*}}, metadata ![[FOUND_IT:.*]], metadata !{{.*}}), !dbg ![[DBG2:.*]] // CHECK: = landingpad // CHECK-NEXT: cleanup, !dbg ![[DBG3:.*]] -// CHECK-DAG: ![[CURRENT_ADDR]] = {{.*}} [current_address] -// CHECK-DAG: ![[FOUND_IT]] = {{.*}} [found_it] -// CHECK-DAG: ![[DBG1]] = !MDLocation(line: 256, -// CHECK-DAG: ![[DBG2]] = !MDLocation(line: 257, -// CHECK-DAG: ![[DBG3]] = !MDLocation(line: 268, -// CHECK-DAG: ![[DBG4]] = !MDLocation(line: 256, +// CHECK-DAG: ![[CURRENT_ADDR]] = {{.*}}name: "current_address" +// CHECK-DAG: ![[FOUND_IT]] = {{.*}}name: "found_it" +// CHECK-DAG: ![[DBG1]] = !DILocation(line: 256, +// CHECK-DAG: ![[DBG2]] = !DILocation(line: 257, +// CHECK-DAG: ![[DBG3]] = !DILocation(line: 268, +// CHECK-DAG: ![[DBG4]] = !DILocation(line: 256, typedef unsigned long long uint64_t; template<class _Tp> class shared_ptr { public: diff --git a/test/CodeGenCXX/linetable-fnbegin.cpp b/test/CodeGenCXX/linetable-fnbegin.cpp index b0a03f7..1f752ff 100644 --- a/test/CodeGenCXX/linetable-fnbegin.cpp +++ b/test/CodeGenCXX/linetable-fnbegin.cpp @@ -4,10 +4,12 @@ // CHECK: define{{.*}}bar // CHECK-NOT: define // CHECK: ret {{.*}}, !dbg [[DBG:.*]] -// CHECK: [[HPP:.*]] = !{!"./template.hpp", -// CHECK: [[SP:.*]] = !{!"0x2e\00{{.*}}", [[HPP]],{{.*}}[ DW_TAG_subprogram ] [line 22] [def] [bar] +// CHECK: [[HPP:.*]] = !DIFile(filename: "./template.hpp", +// CHECK: [[SP:.*]] = !DISubprogram(name: "bar", +// CHECK-SAME: file: [[HPP]], line: 22 +// CHECK-SAME: isDefinition: true // We shouldn't need a lexical block for this function. -// CHECK: [[DBG]] = !MDLocation(line: 23, scope: [[SP]]) +// CHECK: [[DBG]] = !DILocation(line: 23, scope: [[SP]]) # 1 "./template.h" 1 diff --git a/test/CodeGenCXX/linetable-virtual-variadic.cpp b/test/CodeGenCXX/linetable-virtual-variadic.cpp new file mode 100644 index 0000000..c16c5e3 --- /dev/null +++ b/test/CodeGenCXX/linetable-virtual-variadic.cpp @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin -emit-llvm -gline-tables-only %s -o - | FileCheck %s +// Crasher for PR22929. +class Base { + virtual void VariadicFunction(...); +}; + +class Derived : public virtual Base { + virtual void VariadicFunction(...); +}; + +void Derived::VariadicFunction(...) { } + +// CHECK-LABEL: define void @_ZN7Derived16VariadicFunctionEz( +// CHECK: ret void, !dbg ![[LOC:[0-9]+]] +// CHECK-LABEL: define void @_ZT{{.+}}N7Derived16VariadicFunctionEz( +// CHECK: ret void, !dbg ![[LOC:[0-9]+]] +// +// CHECK: !llvm.dbg.cu = !{![[CU:[0-9]+]]} +// +// CHECK: ![[CU]] = !DICompileUnit({{.*}} subprograms: ![[SPs:[0-9]+]] +// CHECK: ![[SPs]] = !{![[SP:[0-9]+]]} +// CHECK: ![[SP]] = !DISubprogram(name: "VariadicFunction",{{.*}} function: {{[^:]+}} @_ZN7Derived16VariadicFunctionEz +// CHECK: ![[LOC]] = !DILocation({{.*}}scope: ![[SP]]) diff --git a/test/CodeGenCXX/lpad-linetable.cpp b/test/CodeGenCXX/lpad-linetable.cpp index c81191b..7f1d221 100644 --- a/test/CodeGenCXX/lpad-linetable.cpp +++ b/test/CodeGenCXX/lpad-linetable.cpp @@ -4,7 +4,7 @@ // CHECK: ret i32 // CHECK: landingpad {{.*}} // CHECK-NEXT: !dbg ![[LPAD:[0-9]+]] -// CHECK: ![[LPAD]] = !MDLocation(line: 24, scope: !{{.*}}) +// CHECK: ![[LPAD]] = !DILocation(line: 24, scope: !{{.*}}) # 1 "/usr/include/c++/4.2.1/vector" 1 3 typedef long unsigned int __darwin_size_t; diff --git a/test/CodeGenCXX/lvalue-bitcasts.cpp b/test/CodeGenCXX/lvalue-bitcasts.cpp index 86355b2..c9997bf 100644 --- a/test/CodeGenCXX/lvalue-bitcasts.cpp +++ b/test/CodeGenCXX/lvalue-bitcasts.cpp @@ -5,90 +5,90 @@ struct Y { X x; }; // CHECK-LABEL: define void @_Z21reinterpret_cast_testRiRfR1X void reinterpret_cast_test(int &ir, float &fr, X &xr) { - // CHECK: load float** + // CHECK: load float*, float** // CHECK: bitcast float* - // CHECK: load i32* + // CHECK: load i32, i32* ir = reinterpret_cast<int&>(fr); // CHECK: load // CHECK: {{bitcast.*to i32\*}} - // CHECK: load i32* + // CHECK: load i32, i32* ir = reinterpret_cast<int&>(xr); // CHECK: load i32 // CHECK: {{bitcast.*to float\*}} - // CHECK: load float* + // CHECK: load float, float* fr = reinterpret_cast<float&>(ir); // CHECK: load // CHECK: {{bitcast.*to float\*}} - // CHECK: load float* + // CHECK: load float, float* fr = reinterpret_cast<float&>(xr); - // CHECK: load i32** + // CHECK: load i32*, i32** // CHECK: bitcast i32* // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 xr = reinterpret_cast<X&>(ir); - // CHECK: load float** + // CHECK: load float*, float** // CHECK: bitcast float* // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 xr = reinterpret_cast<X&>(fr); _Complex float cf; _Complex float &cfr = cf; - // CHECK: load i32** + // CHECK: load i32*, i32** // CHECK: bitcast i32* - // CHECK: load float* - // CHECK: load float* + // CHECK: load float, float* + // CHECK: load float, float* cfr = reinterpret_cast<_Complex float&>(ir); - // CHECK: load float** + // CHECK: load float*, float** // CHECK: bitcast float* - // CHECK: load float* - // CHECK: load float* + // CHECK: load float, float* + // CHECK: load float, float* cfr = reinterpret_cast<_Complex float&>(fr); // CHECK: bitcast - // CHECK: load float* - // CHECK: load float* + // CHECK: load float, float* + // CHECK: load float, float* cfr = reinterpret_cast<_Complex float&>(xr); // CHECK: ret void } // CHECK-LABEL: define void @_Z6c_castRiRfR1X void c_cast(int &ir, float &fr, X &xr) { - // CHECK: load float** + // CHECK: load float*, float** // CHECK: bitcast float* - // CHECK: load i32* + // CHECK: load i32, i32* ir = (int&)fr; // CHECK: load // CHECK: {{bitcast.*to i32\*}} - // CHECK: load i32* + // CHECK: load i32, i32* ir = (int&)xr; // CHECK: load i32 // CHECK: {{bitcast.*to float\*}} - // CHECK: load float* + // CHECK: load float, float* fr = (float&)ir; // CHECK: load // CHECK: {{bitcast.*to float\*}} - // CHECK: load float* + // CHECK: load float, float* fr = (float&)xr; - // CHECK: load i32** + // CHECK: load i32*, i32** // CHECK: bitcast i32* // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 xr = (X&)ir; - // CHECK: load float** + // CHECK: load float*, float** // CHECK: bitcast float* // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 xr = (X&)fr; _Complex float cf; _Complex float &cfr = cf; - // CHECK: load i32** + // CHECK: load i32*, i32** // CHECK: bitcast i32* - // CHECK: load float* - // CHECK: load float* + // CHECK: load float, float* + // CHECK: load float, float* cfr = (_Complex float&)ir; - // CHECK: load float** + // CHECK: load float*, float** // CHECK: bitcast float* - // CHECK: load float* - // CHECK: load float* + // CHECK: load float, float* + // CHECK: load float, float* cfr = (_Complex float&)fr; // CHECK: bitcast - // CHECK: load float* - // CHECK: load float* + // CHECK: load float, float* + // CHECK: load float, float* cfr = (_Complex float&)xr; // CHECK: ret void } @@ -98,46 +98,46 @@ void functional_cast(int &ir, float &fr, X &xr) { typedef int &intref; typedef float &floatref; typedef X &Xref; - // CHECK: load float** + // CHECK: load float*, float** // CHECK: bitcast float* - // CHECK: load i32* + // CHECK: load i32, i32* ir = intref(fr); // CHECK: load // CHECK: {{bitcast.*to i32\*}} - // CHECK: load i32* + // CHECK: load i32, i32* ir = intref(xr); // CHECK: load i32 // CHECK: {{bitcast.*to float\*}} - // CHECK: load float* + // CHECK: load float, float* fr = floatref(ir); // CHECK: load // CHECK: {{bitcast.*to float\*}} - // CHECK: load float* + // CHECK: load float, float* fr = floatref(xr); - // CHECK: load i32** + // CHECK: load i32*, i32** // CHECK: bitcast i32* // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 xr = Xref(ir); - // CHECK: load float** + // CHECK: load float*, float** // CHECK: bitcast float* // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64 xr = Xref(fr); typedef _Complex float &complex_float_ref; _Complex float cf; _Complex float &cfr = cf; - // CHECK: load i32** + // CHECK: load i32*, i32** // CHECK: bitcast i32* - // CHECK: load float* - // CHECK: load float* + // CHECK: load float, float* + // CHECK: load float, float* cfr = complex_float_ref(ir); - // CHECK: load float** + // CHECK: load float*, float** // CHECK: bitcast float* - // CHECK: load float* - // CHECK: load float* + // CHECK: load float, float* + // CHECK: load float, float* cfr = complex_float_ref(fr); // CHECK: bitcast - // CHECK: load float* - // CHECK: load float* + // CHECK: load float, float* + // CHECK: load float, float* cfr = complex_float_ref(xr); // CHECK: ret void } diff --git a/test/CodeGenCXX/m64-ptr.cpp b/test/CodeGenCXX/m64-ptr.cpp index 29916bf..50ba6ae 100644 --- a/test/CodeGenCXX/m64-ptr.cpp +++ b/test/CodeGenCXX/m64-ptr.cpp @@ -12,7 +12,7 @@ public: void foo(StringRef X); void bar(StringRef &A) { // CHECK: @_Z3barR9StringRef -// CHECK: load i8** +// CHECK: load i8*, i8** foo(A); // CHECK: ret void } diff --git a/test/CodeGenCXX/mangle-abi-examples.cpp b/test/CodeGenCXX/mangle-abi-examples.cpp index 6fb82cf..832956f 100644 --- a/test/CodeGenCXX/mangle-abi-examples.cpp +++ b/test/CodeGenCXX/mangle-abi-examples.cpp @@ -1,7 +1,7 @@ // RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s -// CHECK: @_ZTVZ3foovEN1C1DE = // CHECK: @_ZTVZN1A3fooEiE1B = +// CHECK: @_ZTVZ3foovEN1C1DE = // CHECK: define {{.*}} @_ZZZ3foovEN1C3barEvEN1E3bazEv( // Itanium C++ ABI examples. diff --git a/test/CodeGenCXX/mangle-exprs.cpp b/test/CodeGenCXX/mangle-exprs.cpp index ee7f244..ee7594b 100644 --- a/test/CodeGenCXX/mangle-exprs.cpp +++ b/test/CodeGenCXX/mangle-exprs.cpp @@ -293,3 +293,51 @@ namespace test6 { // CHECK-LABEL: define weak_odr void @_ZN5test62f8IiEEvDTcvT_dtptL_ZNS_2zpEE4uuss1iE } +namespace test7 { + struct A { int x[3]; }; + struct B { B(int, int); } extern b; + struct C { C(B); }; + struct D { D(C); }; + struct E { E(std::initializer_list<int>); }; + struct F { F(E); }; + + template<class T> decltype(A{1,2},T()) fA1(T t) {} + template<class T> decltype(A({1,2}),T()) fA2(T t) {} + template<class T> decltype(B{1,2},T()) fB1(T t) {} + template<class T> decltype(B({1,2}),T()) fB2(T t) {} + template<class T> decltype(C{{1,2}},T()) fC1(T t) {} + template<class T> decltype(C({1,2}),T()) fC2(T t) {} + template<class T> decltype(D{b},T()) fD1(T t) {} + template<class T> decltype(D(b),T()) fD2(T t) {} + template<class T> decltype(E{1,2},T()) fE1(T t) {} + template<class T> decltype(E({1,2}),T()) fE2(T t) {} + template<class T> decltype(F{{1,2}},T()) fF1(T t) {} + template<class T> decltype(F({1,2}),T()) fF2(T t) {} + + int main() { + fA1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA1IiEEDTcmtlNS_1AELi1ELi2EEcvT__EES2_ + fA2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fA2IiEEDTcmcvNS_1AEilLi1ELi2EEcvT__EES2_ + fB1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB1IiEEDTcmtlNS_1BELi1ELi2EEcvT__EES2_ + fB2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fB2IiEEDTcmcvNS_1BEilLi1ELi2EEcvT__EES2_ + fC1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC1IiEEDTcmtlNS_1CEilLi1ELi2EEEcvT__EES2_ + fC2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fC2IiEEDTcmcvNS_1CEilLi1ELi2EEcvT__EES2_ + fD1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD1IiEEDTcmtlNS_1DEL_ZNS_1bEEEcvT__EES2_ + fD2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fD2IiEEDTcmcvNS_1DEL_ZNS_1bEEcvT__EES2_ + fE1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE1IiEEDTcmtlNS_1EELi1ELi2EEcvT__EES2_ + fE2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fE2IiEEDTcmcvNS_1EEilLi1ELi2EEcvT__EES2_ + fF1(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF1IiEEDTcmtlNS_1FEilLi1ELi2EEEcvT__EES2_ + fF2(1); // CHECK-LABEL: define {{.*}} @_ZN5test73fF2IiEEDTcmcvNS_1FEilLi1ELi2EEcvT__EES2_ + } +} + + +namespace test8 { + template <class> + struct X { + template<typename T> T foo() const { return 0; } + template <class T> auto bar() const -> decltype(foo<T>()) { return 0; } + }; + + // CHECK-LABEL: define weak_odr i32 @_ZNK5test81XIiE3barIiEEDTcl3fooIT_EEEv + template int X<int>::bar<int>() const; +} diff --git a/test/CodeGenCXX/mangle-fail.cpp b/test/CodeGenCXX/mangle-fail.cpp new file mode 100644 index 0000000..02548964 --- /dev/null +++ b/test/CodeGenCXX/mangle-fail.cpp @@ -0,0 +1,26 @@ +// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=1 +// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=2 +// RUN: %clang_cc1 -emit-llvm-only -x c++ -std=c++11 -triple %itanium_abi_triple -verify %s -DN=3 + +struct A { int a; }; + +#if N == 1 +// ChooseExpr +template<class T> void test(int (&)[sizeof(__builtin_choose_expr(true, 1, 1), T())]) {} // expected-error {{cannot yet mangle}} +template void test<int>(int (&)[sizeof(int)]); + +#elif N == 2 +// CompoundLiteralExpr +template<class T> void test(int (&)[sizeof((A){}, T())]) {} // expected-error {{cannot yet mangle}} +template void test<int>(int (&)[sizeof(A)]); + +#elif N == 3 +// DesignatedInitExpr +template<class T> void test(int (&)[sizeof(A{.a = 10}, T())]) {} // expected-error {{cannot yet mangle}} +template void test<int>(int (&)[sizeof(A)]); + +// FIXME: There are several more cases we can't yet mangle. + +#else +#error unknown N +#endif diff --git a/test/CodeGenCXX/mangle-lambdas.cpp b/test/CodeGenCXX/mangle-lambdas.cpp index e8d3f19..051cfdc 100644 --- a/test/CodeGenCXX/mangle-lambdas.cpp +++ b/test/CodeGenCXX/mangle-lambdas.cpp @@ -1,9 +1,4 @@ -// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s | FileCheck %s - -// CHECK: @_ZZNK7PR12917IJiiEE1nMUlvE_clEvE1n = linkonce_odr global i32 0 -// CHECK: @_ZZZN7PR12917IJicdEEC1EicdEd_NKUlvE_clEvE1n = linkonce_odr global i32 0 -// CHECK: @_ZZZN7PR12917IJicdEEC1EicdEd0_NKUlvE_clEvE1n = linkonce_odr global i32 0 -// CHECK: @_ZZZN7PR12917IJicdEEC1EicdEd1_NKUlvE_clEvE1n = linkonce_odr global i32 0 +// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-macosx10.7.0 -emit-llvm -o - %s -w | FileCheck %s // CHECK-LABEL: define linkonce_odr void @_Z11inline_funci inline void inline_func(int n) { @@ -133,23 +128,23 @@ int (*StaticMembers<T>::f)() = []{return 5;}; // CHECK: ret i32 2 template float StaticMembers<float>::x; -// CHECK-LABEL: define internal void @__cxx_global_var_init1() +// CHECK-LABEL: define internal void @__cxx_global_var_init.1() // CHECK: call i32 @_ZNK13StaticMembersIfE1yMUlvE_clEv // CHECK-LABEL: define linkonce_odr i32 @_ZNK13StaticMembersIfE1yMUlvE_clEv // CHECK: ret i32 3 template float StaticMembers<float>::y; -// CHECK-LABEL: define internal void @__cxx_global_var_init2() +// CHECK-LABEL: define internal void @__cxx_global_var_init.2() // CHECK: call i32 @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_ // CHECK: declare i32 @_Z13accept_lambdaIN13StaticMembersIfE1zMUlvE_EEiT_() template float StaticMembers<float>::z; -// CHECK-LABEL: define internal void @__cxx_global_var_init3() +// CHECK-LABEL: define internal void @__cxx_global_var_init.3() // CHECK: call {{.*}} @_ZNK13StaticMembersIfE1fMUlvE_cvPFivEEv // CHECK-LABEL: define linkonce_odr i32 ()* @_ZNK13StaticMembersIfE1fMUlvE_cvPFivEEv template int (*StaticMembers<float>::f)(); -// CHECK-LABEL: define internal void @__cxx_global_var_init4 +// CHECK-LABEL: define internal void @__cxx_global_var_init.4 // CHECK: call i32 @"_ZNK13StaticMembersIdE3$_2clEv" // CHECK-LABEL: define internal i32 @"_ZNK13StaticMembersIdE3$_2clEv" // CHECK: ret i32 42 @@ -164,23 +159,6 @@ void use_func_template() { func_template<int>(); } - -template<typename...T> struct PR12917 { - PR12917(T ...t = []{ static int n = 0; return ++n; }()); - - static int n[3]; -}; -template<typename...T> int PR12917<T...>::n[3] = { - []{ static int n = 0; return ++n; }() -}; - -// CHECK: call i32 @_ZZN7PR12917IJicdEEC1EicdEd1_NKUlvE_clEv( -// CHECK: call i32 @_ZZN7PR12917IJicdEEC1EicdEd0_NKUlvE_clEv( -// CHECK: call i32 @_ZZN7PR12917IJicdEEC1EicdEd_NKUlvE_clEv( -// CHECK: call void @_ZN7PR12917IJicdEEC1Eicd( -PR12917<int, char, double> pr12917; -int *pr12917_p = PR12917<int, int>::n; - namespace std { struct type_info; } @@ -192,8 +170,40 @@ namespace PR12123 { }; void B::h() { f(); } } + // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %"struct.PR12123::A"* @_ZZN7PR121231B1fERKSt9type_infoEd_NKUlvE_clEv +// Check linkage of the various lambdas. +// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE_clEv +// CHECK: ret i32 1 +// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE0_clEv +// CHECK: ret i32 +// CHECK-LABEL: define linkonce_odr double @_ZZ11inline_funciENKUlvE1_clEv +// CHECK: ret double +// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUliE_clEi +// CHECK: ret i32 +// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE2_clEv +// CHECK: ret i32 17 + +// CHECK-LABEL: define linkonce_odr void @_ZN7MembersC2Ev +// CHECK: call i32 @_ZNK7Members1xMUlvE_clEv +// CHECK-NEXT: call i32 @_ZNK7Members1xMUlvE0_clE +// CHECK-NEXT: add nsw i32 +// CHECK: call i32 @_ZNK7Members1yMUlvE_clEv +// CHECK: ret void + + +// Check the linkage of the lambdas used in test_Members. +// CHECK-LABEL: define linkonce_odr i32 @_ZNK7Members1xMUlvE_clEv +// CHECK: ret i32 1 +// CHECK-LABEL: define linkonce_odr i32 @_ZNK7Members1xMUlvE0_clEv +// CHECK: ret i32 2 +// CHECK-LABEL: define linkonce_odr i32 @_ZNK7Members1yMUlvE_clEv +// CHECK: ret i32 3 + +// CHECK-LABEL: define linkonce_odr void @_Z1fIZZNK23TestNestedInstantiationclEvENKUlvE_clEvEUlvE_EvT_ + + namespace PR12808 { template <typename> struct B { int a; @@ -209,7 +219,6 @@ namespace PR12808 { // CHECK-LABEL: define linkonce_odr i32 @_ZZZN7PR128081bIiEEviENKUlvE_clEvENKUlvE_clEv } -// CHECK-LABEL: define linkonce_odr void @_Z1fIZZNK23TestNestedInstantiationclEvENKUlvE_clEvEUlvE_EvT_ struct Members { int x = [] { return 1; }() + [] { return 2; }(); @@ -217,13 +226,7 @@ struct Members { }; void test_Members() { - // CHECK-LABEL: define linkonce_odr void @_ZN7MembersC2Ev - // CHECK: call i32 @_ZNK7Members1xMUlvE_clEv - // CHECK-NEXT: call i32 @_ZNK7Members1xMUlvE0_clE - // CHECK-NEXT: add nsw i32 - // CHECK: call i32 @_ZNK7Members1yMUlvE_clEv Members members; - // CHECK: ret void } template<typename P> void f(P) { } @@ -239,23 +242,3 @@ struct TestNestedInstantiation { void test_NestedInstantiation() { TestNestedInstantiation()(); } - -// Check the linkage of the lambdas used in test_Members. -// CHECK-LABEL: define linkonce_odr i32 @_ZNK7Members1xMUlvE_clEv -// CHECK: ret i32 1 -// CHECK-LABEL: define linkonce_odr i32 @_ZNK7Members1xMUlvE0_clEv -// CHECK: ret i32 2 -// CHECK-LABEL: define linkonce_odr i32 @_ZNK7Members1yMUlvE_clEv -// CHECK: ret i32 3 - -// Check linkage of the various lambdas. -// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE_clEv -// CHECK: ret i32 1 -// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE0_clEv -// CHECK: ret i32 -// CHECK-LABEL: define linkonce_odr double @_ZZ11inline_funciENKUlvE1_clEv -// CHECK: ret double -// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUliE_clEi -// CHECK: ret i32 -// CHECK-LABEL: define linkonce_odr i32 @_ZZ11inline_funciENKUlvE2_clEv -// CHECK: ret i32 17 diff --git a/test/CodeGenCXX/mangle-local-class-vtables.cpp b/test/CodeGenCXX/mangle-local-class-vtables.cpp index 078d735..c90353e 100644 --- a/test/CodeGenCXX/mangle-local-class-vtables.cpp +++ b/test/CodeGenCXX/mangle-local-class-vtables.cpp @@ -1,24 +1,24 @@ // RUN: %clang_cc1 %s -emit-llvm -triple %itanium_abi_triple -o - | FileCheck %s -// CHECK: @_ZTVZN1J1KEvE1C = {{.*}} @_ZTIZN1J1KEvE1C {{.*}} @_ZZN1J1KEvENK1C1FEv -// CHECK: @_ZTIZN1J1KEvE1C = {{.*}} @_ZTSZN1J1KEvE1C -// CHECK: @_ZTVZ1GvE1C_1 = {{.*}} @_ZTIZ1GvE1C_1 {{.*}} @_ZZ1GvENK1C1FE_1v -// CHECK: @_ZTIZ1GvE1C_1 = {{.*}} @_ZTSZ1GvE1C_1 -// CHECK: @_ZTVZ1GvE1C_0 = {{.*}} @_ZTIZ1GvE1C_0 {{.*}} @_ZZ1GvENK1C1FE_0v -// CHECK: @_ZTIZ1GvE1C_0 = {{.*}} @_ZTSZ1GvE1C_0 -// CHECK: @_ZTVZ1GvE1C = {{.*}} @_ZTIZ1GvE1C {{.*}} @_ZZ1GvENK1C1FEv +// CHECK: @_ZTVZ1GvE1C = {{.*}} @_ZTIZ1GvE1C {{.*}} @_ZZ1GvENK1C1FEv // CHECK: @_ZTIZ1GvE1C = {{.*}} @_ZTSZ1GvE1C +// CHECK: @_ZTVZ1GvE1C_0 = {{.*}} @_ZTIZ1GvE1C_0 {{.*}} @_ZZ1GvENK1C1FE_0v +// CHECK: @_ZTIZ1GvE1C_0 = {{.*}} @_ZTSZ1GvE1C_0 +// CHECK: @_ZTVZ1GvE1C_1 = {{.*}} @_ZTIZ1GvE1C_1 {{.*}} @_ZZ1GvENK1C1FE_1v +// CHECK: @_ZTIZ1GvE1C_1 = {{.*}} @_ZTSZ1GvE1C_1 +// CHECK: @_ZTVZN1J1KEvE1C = {{.*}} @_ZTIZN1J1KEvE1C {{.*}} @_ZZN1J1KEvENK1C1FEv +// CHECK: @_ZTIZN1J1KEvE1C = {{.*}} @_ZTSZN1J1KEvE1C -// CHECK: define {{.*}} @_ZZN1J1KEvEN1CC2Ev( -// CHECK: define {{.*}} @_ZZN1J1KEvENK1C1FEv( -// CHECK: define {{.*}} @_ZZ1GvEN1CC2E_1v( -// CHECK: define {{.*}} @_ZZ1GvENK1C1FE_1v( -// CHECK: define {{.*}} @_ZZ1GvENK1C1HE_1v( +// CHECK: define {{.*}} @_ZZ1GvEN1CC2Ev( +// CHECK: define {{.*}} @_ZZ1GvENK1C1FEv( // CHECK: define {{.*}} @_ZZ1GvEN1CC2E_0v( // CHECK: define {{.*}} @_ZZ1GvENK1C1FE_0v( // CHECK: define {{.*}} @_ZZ1GvENK1C1GE_0v( -// CHECK: define {{.*}} @_ZZ1GvEN1CC2Ev( -// CHECK: define {{.*}} @_ZZ1GvENK1C1FEv( +// CHECK: define {{.*}} @_ZZ1GvEN1CC2E_1v( +// CHECK: define {{.*}} @_ZZ1GvENK1C1FE_1v( +// CHECK: define {{.*}} @_ZZ1GvENK1C1HE_1v( +// CHECK: define {{.*}} @_ZZN1J1KEvEN1CC2Ev( +// CHECK: define {{.*}} @_ZZN1J1KEvENK1C1FEv( struct I { virtual void F() const = 0; diff --git a/test/CodeGenCXX/mangle-local-classes-nested.cpp b/test/CodeGenCXX/mangle-local-classes-nested.cpp index cee541f..5daf0c0 100644 --- a/test/CodeGenCXX/mangle-local-classes-nested.cpp +++ b/test/CodeGenCXX/mangle-local-classes-nested.cpp @@ -6,10 +6,10 @@ // CHECK: define {{.*}} @_ZZ2L1vEN1S2L2Ev( // CHECK: define {{.*}} @_ZZ2L1vEN1S2L2E_0v( // CHECK: define {{.*}} @_ZZ1FvEN1S1T1S1T1GEv( -// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3cEv( -// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3dE_0v( // CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2EvEN1S3L3aEv( // CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2EvEN1S3L3bE_0v( +// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3cEv( +// CHECK: define {{.*}} @_ZZZ2L1vEN1S2L2E_0vEN1S3L3dE_0v( void L1() { { diff --git a/test/CodeGenCXX/mangle-ms-abi-examples.cpp b/test/CodeGenCXX/mangle-ms-abi-examples.cpp index 5dc9d2e..6b6ad89 100644 --- a/test/CodeGenCXX/mangle-ms-abi-examples.cpp +++ b/test/CodeGenCXX/mangle-ms-abi-examples.cpp @@ -1,8 +1,10 @@ -// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s +// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2015 +// RUN: %clang_cc1 -fms-extensions -fno-rtti -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=18.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2013 -// CHECK: @"\01??_7D@C@?1??foo@@YAXXZ@6B@" = // CHECK: @"\01??_7B@?1??foo@A@@QAEXH@Z@6B@" = -// CHECK: define {{.*}} @"\01?baz@E@?3??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ"( +// CHECK: @"\01??_7D@C@?1??foo@@YAXXZ@6B@" = +// MSVC2013: define {{.*}} @"\01?baz@E@?3??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ"( +// MSVC2015: define {{.*}} @"\01?baz@E@?1??bar@C@?1??foo@@YAXXZ@QAEXXZ@QAEXXZ"( // Microsoft Visual C++ ABI examples. struct A { diff --git a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp index fae2e1a..ad0299e 100644 --- a/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp +++ b/test/CodeGenCXX/mangle-ms-arg-qualifiers.cpp @@ -258,3 +258,12 @@ void mangle_yes_backref3(ptr_to_fun_type *const, void (**const)(void)) {} void mangle_yes_backref4(int *const __restrict, int *const __restrict) {} // CHECK: "\01?mangle_yes_backref4@@YAXQIAH0@Z" // X64: "\01?mangle_yes_backref4@@YAXQEIAH0@Z" + +struct S {}; +void pr23325(const S[1], const S[]) {} +// CHECK: "\01?pr23325@@YAXQBUS@@0@Z" +// X64: "\01?pr23325@@YAXQEBUS@@0@Z" + +void vla_arg(int i, int a[][i]) {} +// CHECK: "\01?vla_arg@@YAXHQAY0A@H@Z" +// X64: "\01?vla_arg@@YAXHQEAY0A@H@Z" diff --git a/test/CodeGenCXX/mangle-ms-cxx11.cpp b/test/CodeGenCXX/mangle-ms-cxx11.cpp index fe7121e..3f4075f 100644 --- a/test/CodeGenCXX/mangle-ms-cxx11.cpp +++ b/test/CodeGenCXX/mangle-ms-cxx11.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s +// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2015 +// RUN: %clang_cc1 -std=c++11 -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=18.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2013 namespace FTypeWithQuals { template <typename T> @@ -171,7 +172,8 @@ inline int define_lambda() { // CHECK-DAG: @"\01??R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ" // Finally, we have the local which is inside of "<lambda_1>" which is inside of // "define_lambda". Hooray. -// CHECK-DAG: @"\01?local@?2???R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ@4HA" +// MSVC2013-DAG: @"\01?local@?2???R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ@4HA" +// MSVC2015-DAG: @"\01?local@?1???R<lambda_1>@?define_lambda@@YAHXZ@QBEHXZ@4HA" return lambda(); } @@ -218,13 +220,15 @@ template <typename...> void templ_fun_with_ty_pack() {} template void templ_fun_with_ty_pack<>(); -// CHECK-DAG: @"\01??$templ_fun_with_ty_pack@$$V@@YAXXZ" +// MSVC2013-DAG: @"\01??$templ_fun_with_ty_pack@$$$V@@YAXXZ" +// MSVC2015-DAG: @"\01??$templ_fun_with_ty_pack@$$V@@YAXXZ" template <template <class> class...> void templ_fun_with_templ_templ_pack() {} template void templ_fun_with_templ_templ_pack<>(); -// CHECK-DAG: @"\01??$templ_fun_with_templ_templ_pack@$$V@@YAXXZ" +// MSVC2013-DAG: @"\01??$templ_fun_with_templ_templ_pack@$$$V@@YAXXZ" +// MSVC2015-DAG: @"\01??$templ_fun_with_templ_templ_pack@$$V@@YAXXZ" namespace PR20047 { template <typename T> diff --git a/test/CodeGenCXX/mangle-ms-cxx14.cpp b/test/CodeGenCXX/mangle-ms-cxx14.cpp index c06efe2..51627dd 100644 --- a/test/CodeGenCXX/mangle-ms-cxx14.cpp +++ b/test/CodeGenCXX/mangle-ms-cxx14.cpp @@ -1,4 +1,5 @@ -// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s +// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=19.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2015 +// RUN: %clang_cc1 -std=c++1y -fms-extensions -emit-llvm %s -o - -triple=i386-pc-win32 -fms-compatibility-version=18.00 | FileCheck %s --check-prefix=CHECK --check-prefix=MSVC2013 template <typename> int x = 0; @@ -34,7 +35,10 @@ auto TemplateFuncionWithLocalLambda(T) { return LocalLambdaWithLocalType(); } -// CHECK: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?3@XZ@A" +// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A" +// MSVC2013-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?2???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A" +// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A" +// MSVC2015-DAG: "\01?ValueFromTemplateFuncionWithLocalLambda@@3ULocalType@?1???R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?3@XZ@A" // CHECK: "\01??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z" -// CHECK: "\01??R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBA?A?1@XZ" +// CHECK: "\01??R<lambda_1>@??$TemplateFuncionWithLocalLambda@H@@YA?A?<auto>@@H@Z@QBE?A?1@XZ" auto ValueFromTemplateFuncionWithLocalLambda = TemplateFuncionWithLocalLambda(0); diff --git a/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp index 37bbf09..8b666e4f 100644 --- a/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp +++ b/test/CodeGenCXX/mangle-ms-return-qualifiers.cpp @@ -183,3 +183,7 @@ function_pointer* g3() { return 0; } const function_pointer* g4() { return 0; } // CHECK: "\01?g4@@YAPBQ6AHH@ZXZ" + +extern int &z; +int & __restrict h1() { return z; } +// CHECK: "\01?h1@@YAAIAHXZ" diff --git a/test/CodeGenCXX/mangle-ms.cpp b/test/CodeGenCXX/mangle-ms.cpp index 662278b..0da5c6f 100644 --- a/test/CodeGenCXX/mangle-ms.cpp +++ b/test/CodeGenCXX/mangle-ms.cpp @@ -380,3 +380,12 @@ void TypedefNewDelete::operator delete[](void *) { } void __vectorcall vector_func() { } // CHECK-DAG: @"\01?vector_func@@YQXXZ" + +template <void (*)(void)> +void fn_tmpl() {} + +template void fn_tmpl<extern_c_func>(); +// CHECK-DAG: @"\01??$fn_tmpl@$1?extern_c_func@@YAXXZ@@YAXXZ" + +extern "C" void __attribute__((overloadable)) overloaded_fn() {} +// CHECK-DAG: @"\01?overloaded_fn@@$$J0YAXXZ" diff --git a/test/CodeGenCXX/mangle-subst-std.cpp b/test/CodeGenCXX/mangle-subst-std.cpp index 678956e..b06f798 100644 --- a/test/CodeGenCXX/mangle-subst-std.cpp +++ b/test/CodeGenCXX/mangle-subst-std.cpp @@ -3,14 +3,15 @@ // Check mangling of Vtables, VTTs, and construction vtables that // involve standard substitutions. + // CHECK: @_ZTVSd = linkonce_odr unnamed_addr constant // CHECK: @_ZTTSd = linkonce_odr unnamed_addr constant // CHECK: @_ZTCSd0_Si = linkonce_odr unnamed_addr constant // CHECK: @_ZTCSd16_So = linkonce_odr unnamed_addr constant -// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant -// CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant // CHECK: @_ZTVSi = linkonce_odr unnamed_addr constant // CHECK: @_ZTTSi = linkonce_odr unnamed_addr constant +// CHECK: @_ZTVSo = linkonce_odr unnamed_addr constant +// CHECK: @_ZTTSo = linkonce_odr unnamed_addr constant namespace std { struct A { A(); }; diff --git a/test/CodeGenCXX/mangle-subst.cpp b/test/CodeGenCXX/mangle-subst.cpp index 30360aea..09326e2 100644 --- a/test/CodeGenCXX/mangle-subst.cpp +++ b/test/CodeGenCXX/mangle-subst.cpp @@ -80,3 +80,19 @@ void f(void (B::*)(), A, A) { } void f(void (B::*)(), A, A, void (B::*)(A), void (A::*)()) { } } + +namespace ManglePrefix { +template <typename> +struct X { + template <typename> + struct Y { + typedef int type; + typedef int type2; + }; +}; +template <typename T> +typename X<T>::template Y<T>::type f(typename X<T>::template Y<T>::type2) { return 0; } + +// CHECK: @_ZN12ManglePrefix1fIiEENS_1XIT_E1YIS2_E4typeENS5_5type2E +template int f<int>(int); +} diff --git a/test/CodeGenCXX/mangle-template.cpp b/test/CodeGenCXX/mangle-template.cpp index 998096a..aaae4b2 100644 --- a/test/CodeGenCXX/mangle-template.cpp +++ b/test/CodeGenCXX/mangle-template.cpp @@ -4,7 +4,7 @@ namespace test1 { int x; template <int& D> class T { }; -// CHECK: void @_ZN5test12f0ENS_1TILZNS_1xEEEE( +// CHECK: void @_ZN5test12f0ENS_1TIL_ZNS_1xEEEE( void f0(T<x> a0) {} } @@ -12,7 +12,7 @@ namespace test1 { // CHECK: void @_ZN5test12f0Ef void f0(float) {} template<void (&)(float)> struct t1 {}; -// CHECK: void @_ZN5test12f1ENS_2t1ILZNS_2f0EfEEE( +// CHECK: void @_ZN5test12f1ENS_2t1IL_ZNS_2f0EfEEE( void f1(t1<f0> a0) {} } @@ -20,8 +20,7 @@ namespace test2 { // CHECK: void @_ZN5test22f0Ef void f0(float) {} template<void (*)(float)> struct t1 {}; -// FIXME: Fails because we don't treat as an expression. -// CHECK-FIXME: void @_ZN5test22f1ENS_2t1IXadL_ZNS_2f0EfEEEE( +// CHECK: void @_ZN5test22f1ENS_2t1IXadL_ZNS_2f0EfEEEE( void f1(t1<f0> a0) {} } @@ -29,8 +28,7 @@ namespace test3 { // CHECK: void @test3_f0 extern "C" void test3_f0(float) {} template<void (&)(float)> struct t1 {}; -// FIXME: Fails because we tack on a namespace. -// CHECK-FIXME: void @_ZN5test32f1ENS_2t1ILZ8test3_f0EEE( +// CHECK: void @_ZN5test32f1ENS_2t1IL_Z8test3_f0EEE( void f1(t1<test3_f0> a0) {} } @@ -38,8 +36,7 @@ namespace test4 { // CHECK: void @test4_f0 extern "C" void test4_f0(float) {} template<void (*)(float)> struct t1 {}; -// FIXME: Fails because we don't treat as an expression. -// CHECK-FIXME: void @_ZN5test42f1ENS_2t1IXadL_Z8test4_f0EEEE( +// CHECK: void @_ZN5test42f1ENS_2t1IXadL_Z8test4_f0EEEE( void f1(t1<test4_f0> a0) {} } @@ -49,22 +46,20 @@ int main(int) {} namespace test5 { template<void (&)(float)> struct t1 {}; -// CHECK: void @_ZN5test52f1ENS_2t1ILZ8test5_f0EEE( +// CHECK: void @_ZN5test52f1ENS_2t1IL_Z8test5_f0EEE( void f1(t1<test5_f0> a0) {} template<int (&)(int)> struct t2 {}; -// CHECK: void @_ZN5test52f2ENS_2t2ILZ4mainEEE +// CHECK: void @_ZN5test52f2ENS_2t2IL_Z4mainEEE void f2(t2<main> a0) {} } -// FIXME: This fails. namespace test6 { struct A { void im0(float); }; // CHECK: void @_ZN5test61A3im0Ef void A::im0(float) {} template <void(A::*)(float)> class T { }; -// FIXME: Fails because we don't treat as an expression. -// CHECK-FAIL: void @_ZN5test62f0ENS_1TIXadL_ZNS_1A3im0EfEEEE( +// CHECK: void @_ZN5test62f0ENS_1TIXadL_ZNS_1A3im0EfEEEE( void f0(T<&A::im0> a0) {} } @@ -164,11 +159,11 @@ namespace test12 { void use() { // CHECK-LABEL: define internal void @_ZN6test124testIFivEXadL_ZNS_L1fEvEEEEvv( test<int(), &f>(); - // CHECK-LABEL: define internal void @_ZN6test124testIRFivELZNS_L1fEvEEEvv( + // CHECK-LABEL: define internal void @_ZN6test124testIRFivEL_ZNS_L1fEvEEEvv( test<int(&)(), f>(); // CHECK-LABEL: define internal void @_ZN6test124testIPKiXadL_ZNS_L1nEEEEEvv( test<const int*, &n>(); - // CHECK-LABEL: define internal void @_ZN6test124testIRKiLZNS_L1nEEEEvv( + // CHECK-LABEL: define internal void @_ZN6test124testIRKiL_ZNS_L1nEEEEvv( test<const int&, n>(); } } diff --git a/test/CodeGenCXX/mangle.cpp b/test/CodeGenCXX/mangle.cpp index 9af0d9d..5012c3b 100644 --- a/test/CodeGenCXX/mangle.cpp +++ b/test/CodeGenCXX/mangle.cpp @@ -455,7 +455,7 @@ namespace test7 { void g(zed<&foo::bar>*) {} } -// CHECK-LABEL: define weak_odr void @_ZN5test81AILZNS_1B5valueEEE3incEv +// CHECK-LABEL: define weak_odr void @_ZN5test81AIL_ZNS_1B5valueEEE3incEv namespace test8 { template <int &counter> class A { void inc() { counter++; } }; class B { public: static int value; }; @@ -522,7 +522,7 @@ namespace test14 { static int a(), x; }; // CHECK-LABEL: define i32 @_ZN6test141S1aEv - // CHECK: load i32* @_ZN6test141S1xE + // CHECK: load i32, i32* @_ZN6test141S1xE int S::a() { return S::x; } } } @@ -577,10 +577,10 @@ namespace test18 { template <typename T> void f(S<&T::operator&>) {} template void f<A>(S<&A::operator&>); - // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_plEEE - // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_miEEE - // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_mlEEE - // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_anEEE + // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onplEEE + // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmiEEE + // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onmlEEE + // CHECK-LABEL: define weak_odr void @_ZN6test181fINS_1AEEEvNS_1SIXadsrT_onanEEE } // rdar://problem/8332117 @@ -601,11 +601,11 @@ namespace test19 { // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_1fIiEEEE( template void g<A>(S<&A::f<int> >); - // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_plEEE( + // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onplEEE( template void g<A>(S<&A::operator+>); - // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_cviEEE( + // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_oncviEEE( template void g<A>(S<&A::operator int>); - // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_miIdEEEE( + // CHECK-LABEL: define weak_odr void @_ZN6test191gINS_1AEEEvNS_1SIXadsrT_onmiIdEEEE( template void g<A>(S<&A::operator-<double> >); } @@ -839,7 +839,7 @@ namespace test35 { template<typename T> void f1(decltype(sizeof(&T::template operator+<int>))) {} - // CHECK-LABEL: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_plIiEE + // CHECK-LABEL: define weak_odr void @_ZN6test352f1INS_1AEEEvDTszadsrT_onplIiEE template void f1<A>(__SIZE_TYPE__); } @@ -1013,3 +1013,91 @@ namespace test50 { auto v = fin<S>; // CHECK-LABEL: declare void @_ZN6test503finINS_1SEEET_ILi3EES2_ILi4EE() } + +namespace test51 { + template <typename T> + decltype(T().~T()) fun() {} + template void fun<int>(); + // CHECK-LABEL: @_ZN6test513funIiEEDTcldtcvT__EdnS1_EEv + template void fun<X>(); + // CHECK-LABEL: @_ZN6test513funI1XEEDTcldtcvT__EdnS2_EEv + template void fun<S1<int> >(); + // CHECK-LABEL: @_ZN6test513funI2S1IiEEEDTcldtcvT__EdnS3_EEv + + enum E {}; + template <typename T> + struct X { + struct Y {}; + }; + + template <typename T> + decltype(S1<T>().~S1<T>()) fun1() {}; + template <typename U, typename T> + decltype(U().~S1<T>()) fun2() {} + template <typename U, typename T> + decltype(S1<T>().~U()) fun3() {} + template <typename T> + decltype(S1<T>().~S1<T>(), S1<T>().~S1<T>()) fun4() {}; + template <typename T> + decltype(S1<int>().~S1<T>()) fun5(){}; + template <template <typename T> class U> + decltype(S1<int>().~U<int>()) fun6(){}; + template <typename T> + decltype(E().E::~T()) fun7() {} + template <template <typename> class U> + decltype(X<int>::Y().U<int>::Y::~Y()) fun8() {} + template void fun1<int>(); + // CHECK-LABEL: @_ZN6test514fun1IiEEDTcldtcv2S1IT_E_Edn2S1IS2_EEEv + template void fun2<S1<int>, int>(); + // CHECK-LABEL: @_ZN6test514fun2I2S1IiEiEEDTcldtcvT__Edn2S1IT0_EEEv + template void fun3<S1<int>, int>(); + // CHECK-LABEL: @_ZN6test514fun3I2S1IiEiEEDTcldtcvS1_IT0_E_EdnT_EEv + template void fun4<int>(); + // CHECK-LABEL: @_ZN6test514fun4IiEEDTcmcldtcv2S1IT_E_Edn2S1IS2_EEcldtcvS3__Edn2S1IS2_EEEv + template void fun5<int>(); + // CHECK-LABEL: @_ZN6test514fun5IiEEDTcldtcv2S1IiE_Edn2S1IT_EEEv + template void fun6<S1>(); + // CHECK-LABEL: @_ZN6test514fun6I2S1EEDTcldtcvS1_IiE_EdnT_IiEEEv + template void fun7<E>(); + // CHECK-LABEL: @_ZN6test514fun7INS_1EEEEDTcldtcvS1__Esr1EEdnT_EEv + template void fun8<X>(); +} + +namespace test52 { +struct X {}; +void operator+(X); +template <typename... T> +auto f4(T... x) -> decltype(operator+(x...)); +// CHECK-LABEL: @_ZN6test522f4IJNS_1XEEEEDTclonplspfp_EEDpT_ +void use() { f4(X{}); } +} + +namespace test53 { +struct c { + using t1 = struct { int z; }; + using t2 = struct { double z; }; + using t3 = struct { float z; }; + using t4 = struct { float z; }; + + __attribute__((used)) c(t1) {} + __attribute__((used)) c(t2) {} + __attribute__((used)) c(t3) {} + __attribute__((used)) c(t4) {} + // CHECK-LABEL: @_ZN6test531cC2ENS0_2t1E + // CHECK-LABEL: @_ZN6test531cC2ENS0_2t2E + // CHECK-LABEL: @_ZN6test531cC2ENS0_2t3E + // CHECK-LABEL: @_ZN6test531cC2ENS0_2t4E +}; +} + +namespace test54 { +struct c { + using t1 = struct { int z; } *; + using t2 = struct { double z; } *; + + __attribute__((used)) c(t1) {} + __attribute__((used)) c(t2) {} + // CHECK-LABEL: @_ZN6test541cC2EPNS0_Ut_E + // CHECK-LABEL: @_ZN6test541cC2EPNS0_Ut0_E +}; +} diff --git a/test/CodeGenCXX/member-expressions.cpp b/test/CodeGenCXX/member-expressions.cpp index 4850272..bbfa51f 100644 --- a/test/CodeGenCXX/member-expressions.cpp +++ b/test/CodeGenCXX/member-expressions.cpp @@ -80,7 +80,7 @@ namespace test4 { // CHECK-NEXT: getelementptr // CHECK-NEXT: bitcast // CHECK-NEXT: getelementptr - // CHECK-NEXT: load i32* + // CHECK-NEXT: load i32, i32* return c_ptr->B::x; } } diff --git a/test/CodeGenCXX/member-function-pointers.cpp b/test/CodeGenCXX/member-function-pointers.cpp index 8ae57b2..7ffe4cd 100644 --- a/test/CodeGenCXX/member-function-pointers.cpp +++ b/test/CodeGenCXX/member-function-pointers.cpp @@ -43,14 +43,14 @@ void f() { // CODE-LP64: store volatile { i64, i64 } zeroinitializer, { i64, i64 }* @vpa vpa = 0; - // CODE-LP64: [[TMP:%.*]] = load { i64, i64 }* @pa, align 8 + // CODE-LP64: [[TMP:%.*]] = load { i64, i64 }, { i64, i64 }* @pa, align 8 // CODE-LP64: [[TMPADJ:%.*]] = extractvalue { i64, i64 } [[TMP]], 1 // CODE-LP64: [[ADJ:%.*]] = add nsw i64 [[TMPADJ]], 16 // CODE-LP64: [[RES:%.*]] = insertvalue { i64, i64 } [[TMP]], i64 [[ADJ]], 1 // CODE-LP64: store { i64, i64 } [[RES]], { i64, i64 }* @pc, align 8 pc = pa; - // CODE-LP64: [[TMP:%.*]] = load { i64, i64 }* @pc, align 8 + // CODE-LP64: [[TMP:%.*]] = load { i64, i64 }, { i64, i64 }* @pc, align 8 // CODE-LP64: [[TMPADJ:%.*]] = extractvalue { i64, i64 } [[TMP]], 1 // CODE-LP64: [[ADJ:%.*]] = sub nsw i64 [[TMPADJ]], 16 // CODE-LP64: [[RES:%.*]] = insertvalue { i64, i64 } [[TMP]], i64 [[ADJ]], 1 diff --git a/test/CodeGenCXX/member-functions.cpp b/test/CodeGenCXX/member-functions.cpp index 1773c67..58f709c 100644 --- a/test/CodeGenCXX/member-functions.cpp +++ b/test/CodeGenCXX/member-functions.cpp @@ -16,7 +16,7 @@ void test1() { // CHECK: call void @_ZN1C1fEv c.f(); - // CHECK: call void (%struct.C*, i32, ...)* @_ZN1C1gEiz + // CHECK: call void (%struct.C*, i32, ...) @_ZN1C1gEiz c.g(1, 2, 3); } @@ -74,12 +74,11 @@ void test3() { T result = t1 + t2; } -// S::~S() -// CHECK: define linkonce_odr void @_ZN1SD2Ev{{.*}} unnamed_addr - // S::S() // CHECK: define linkonce_odr void @_ZN1SC2Ev{{.*}} unnamed_addr // S::v() // CHECK: define linkonce_odr void @_ZN1S1vEv{{.*}}unnamed_addr +// S::~S() +// CHECK: define linkonce_odr void @_ZN1SD2Ev{{.*}} unnamed_addr diff --git a/test/CodeGenCXX/member-init-anon-union.cpp b/test/CodeGenCXX/member-init-anon-union.cpp index b488fa7..6c2f90d 100644 --- a/test/CodeGenCXX/member-init-anon-union.cpp +++ b/test/CodeGenCXX/member-init-anon-union.cpp @@ -43,6 +43,18 @@ union B { B b1; B b2(0); +// CHECK: define {{.*}}@"[[CONSTRUCT_GLOBAL]]C2Ev" +// CHECK-NOT: } +// CHECK: call {{.*}}@_Z6make_a + +// CHECK: define {{.*}}@"[[CONSTRUCT_LOCAL]]C2Ev" +// CHECK-NOT: } +// CHECK: store i32 81 + +// CHECK-LABEL: define {{.*}} @_ZN1BC2Ev( +// CHECK: call void @_ZN1AC1Ev( +// CHECK: store i32 123, +// CHECK: } // CHECK-LABEL: define {{.*}} @_ZN1BC2Ei( // CHECK-NOT: call void @_ZN1AC1Ev( @@ -51,17 +63,3 @@ B b2(0); // CHECK-NOT: call void @_ZN1AC1Ev( // CHECK-NOT: store i32 123, // CHECK: } - -// CHECK-LABEL: define {{.*}} @_ZN1BC2Ev( -// CHECK: call void @_ZN1AC1Ev( -// CHECK: store i32 123, -// CHECK: } - - -// CHECK: define {{.*}}@"[[CONSTRUCT_LOCAL]]C2Ev" -// CHECK-NOT: } -// CHECK: store i32 81 - -// CHECK: define {{.*}}@"[[CONSTRUCT_GLOBAL]]C2Ev" -// CHECK-NOT: } -// CHECK: call {{.*}}@_Z6make_a diff --git a/test/CodeGenCXX/microsoft-abi-arg-order.cpp b/test/CodeGenCXX/microsoft-abi-arg-order.cpp index b47508b..cbef104 100644 --- a/test/CodeGenCXX/microsoft-abi-arg-order.cpp +++ b/test/CodeGenCXX/microsoft-abi-arg-order.cpp @@ -15,9 +15,9 @@ void foo(A a, A b, A c) { // // X86-LABEL: define void @"\01?foo@@YAXUA@@00@Z" // X86: ([[argmem_ty:<{ %struct.A, %struct.A, %struct.A }>]]* inalloca) -// X86: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %0, i32 0, i32 0 -// X86: %[[b:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %0, i32 0, i32 1 -// X86: %[[c:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %0, i32 0, i32 2 +// X86: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 0 +// X86: %[[b:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 1 +// X86: %[[c:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %0, i32 0, i32 2 // X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[a]]) // X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[b]]) // X86: call x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[c]]) @@ -41,11 +41,11 @@ void call_foo() { // X86-LABEL: define void @"\01?call_foo@@YAXXZ"() // X86: call i8* @llvm.stacksave() // X86: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty]] -// X86: %[[arg3:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 2 +// X86: %[[arg3:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 2 // X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg3]], i32 3) -// X86: %[[arg2:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 1 +// X86: %[[arg2:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1 // X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg2]], i32 2) -// X86: %[[arg1:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 0 +// X86: %[[arg1:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0 // X86: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@H@Z"(%struct.A* %[[arg1]], i32 1) // X86: invoke void @"\01?foo@@YAXUA@@00@Z"([[argmem_ty]]* inalloca %[[argmem]]) // X86: call void @llvm.stackrestore diff --git a/test/CodeGenCXX/microsoft-abi-array-cookies.cpp b/test/CodeGenCXX/microsoft-abi-array-cookies.cpp index 8da4fcf..619b1b8 100644 --- a/test/CodeGenCXX/microsoft-abi-array-cookies.cpp +++ b/test/CodeGenCXX/microsoft-abi-array-cookies.cpp @@ -28,12 +28,12 @@ void check_array_cookies_simple() { // 46 = 42 + size of cookie (4) // CHECK: [[COOKIE:%.*]] = bitcast i8* [[ALLOCATED]] to i32* // CHECK: store i32 42, i32* [[COOKIE]] -// CHECK: [[ARRAY:%.*]] = getelementptr inbounds i8* [[ALLOCATED]], i64 4 +// CHECK: [[ARRAY:%.*]] = getelementptr inbounds i8, i8* [[ALLOCATED]], i64 4 // CHECK: bitcast i8* [[ARRAY]] to [[CLASS:%.*]]* delete [] array; // CHECK: [[ARRAY_AS_CHAR:%.*]] = bitcast [[CLASS]]* {{%.*}} to i8* -// CHECK: getelementptr inbounds i8* [[ARRAY_AS_CHAR]], i64 -4 +// CHECK: getelementptr inbounds i8, i8* [[ARRAY_AS_CHAR]], i64 -4 } struct __attribute__((aligned(8))) ClassWithAlignment { @@ -50,12 +50,12 @@ void check_array_cookies_aligned() { // 344 = 42*8 + size of cookie (8, due to alignment) // CHECK: [[COOKIE:%.*]] = bitcast i8* [[ALLOCATED]] to i32* // CHECK: store i32 42, i32* [[COOKIE]] -// CHECK: [[ARRAY:%.*]] = getelementptr inbounds i8* [[ALLOCATED]], i64 8 +// CHECK: [[ARRAY:%.*]] = getelementptr inbounds i8, i8* [[ALLOCATED]], i64 8 // CHECK: bitcast i8* [[ARRAY]] to [[CLASS:%.*]]* delete [] array; // CHECK: [[ARRAY_AS_CHAR:%.*]] = bitcast [[CLASS]]* -// CHECK: getelementptr inbounds i8* [[ARRAY_AS_CHAR]], i64 -8 +// CHECK: getelementptr inbounds i8, i8* [[ARRAY_AS_CHAR]], i64 -8 } // CHECK: attributes [[NUW]] = { nounwind{{.*}} } diff --git a/test/CodeGenCXX/microsoft-abi-byval-sret.cpp b/test/CodeGenCXX/microsoft-abi-byval-sret.cpp index a34a245..57ac795 100644 --- a/test/CodeGenCXX/microsoft-abi-byval-sret.cpp +++ b/test/CodeGenCXX/microsoft-abi-byval-sret.cpp @@ -20,8 +20,8 @@ A B::foo(A x) { // CHECK-LABEL: define x86_thiscallcc %struct.A* @"\01?foo@B@@QAE?AUA@@U2@@Z" // CHECK: (%struct.B* %this, <{ %struct.A*, %struct.A }>* inalloca) -// CHECK: getelementptr inbounds <{ %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 0 -// CHECK: load %struct.A** +// CHECK: getelementptr inbounds <{ %struct.A*, %struct.A }>, <{ %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 0 +// CHECK: load %struct.A*, %struct.A** // CHECK: ret %struct.A* A B::bar(A x) { @@ -30,8 +30,8 @@ A B::bar(A x) { // CHECK-LABEL: define %struct.A* @"\01?bar@B@@QAA?AUA@@U2@@Z" // CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca) -// CHECK: getelementptr inbounds <{ %struct.B*, %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 1 -// CHECK: load %struct.A** +// CHECK: getelementptr inbounds <{ %struct.B*, %struct.A*, %struct.A }>, <{ %struct.B*, %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 1 +// CHECK: load %struct.A*, %struct.A** // CHECK: ret %struct.A* A B::baz(A x) { @@ -40,8 +40,8 @@ A B::baz(A x) { // CHECK-LABEL: define x86_stdcallcc %struct.A* @"\01?baz@B@@QAG?AUA@@U2@@Z" // CHECK: (<{ %struct.B*, %struct.A*, %struct.A }>* inalloca) -// CHECK: getelementptr inbounds <{ %struct.B*, %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 1 -// CHECK: load %struct.A** +// CHECK: getelementptr inbounds <{ %struct.B*, %struct.A*, %struct.A }>, <{ %struct.B*, %struct.A*, %struct.A }>* %{{.*}}, i32 0, i32 1 +// CHECK: load %struct.A*, %struct.A** // CHECK: ret %struct.A* A B::qux(A x) { diff --git a/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp b/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp index 9bcfb9c..8ae85c0 100644 --- a/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp +++ b/test/CodeGenCXX/microsoft-abi-byval-thunks.cpp @@ -16,14 +16,14 @@ C::C() {} // force emission // CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"\01?foo@C@byval_thunk@@W3AEXUAgg@2@@Z" // CHECK32: (%"struct.byval_thunk::C"* %this, <{ %"struct.byval_thunk::Agg" }>* inalloca) -// CHECK32: getelementptr i8* %{{.*}}, i32 -4 +// CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4 // CHECK32: musttail call x86_thiscallcc void @"\01?foo@C@byval_thunk@@UAEXUAgg@2@@Z" // CHECK32: (%"struct.byval_thunk::C"* %{{.*}}, <{ %"struct.byval_thunk::Agg" }>* inalloca %0) // CHECK32-NEXT: ret void // CHECK64-LABEL: define linkonce_odr void @"\01?foo@C@byval_thunk@@W7EAAXUAgg@2@@Z" // CHECK64: (%"struct.byval_thunk::C"* %this, %"struct.byval_thunk::Agg"* %x) -// CHECK64: getelementptr i8* %{{.*}}, i32 -8 +// CHECK64: getelementptr i8, i8* %{{.*}}, i32 -8 // CHECK64: call void @"\01?foo@C@byval_thunk@@UEAAXUAgg@2@@Z" // CHECK64: (%"struct.byval_thunk::C"* %{{.*}}, %"struct.byval_thunk::Agg"* %x) // CHECK64-NOT: call @@ -45,9 +45,9 @@ C::C() {} // force emission // CHECK32-LABEL: define linkonce_odr x86_stdcallcc void @"\01?foo@C@stdcall_thunk@@W3AGXUAgg@2@@Z" // CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca) -// CHECK32: %[[this_slot:[^ ]*]] = getelementptr inbounds <{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* %0, i32 0, i32 0 -// CHECK32: load %"struct.stdcall_thunk::C"** %[[this_slot]] -// CHECK32: getelementptr i8* %{{.*}}, i32 -4 +// CHECK32: %[[this_slot:[^ ]*]] = getelementptr inbounds <{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>, <{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* %0, i32 0, i32 0 +// CHECK32: load %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::C"** %[[this_slot]] +// CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4 // CHECK32: store %"struct.stdcall_thunk::C"* %{{.*}}, %"struct.stdcall_thunk::C"** %[[this_slot]] // CHECK32: musttail call x86_stdcallcc void @"\01?foo@C@stdcall_thunk@@UAGXUAgg@2@@Z" // CHECK32: (<{ %"struct.stdcall_thunk::C"*, %"struct.stdcall_thunk::Agg" }>* inalloca %0) @@ -55,7 +55,7 @@ C::C() {} // force emission // CHECK64-LABEL: define linkonce_odr void @"\01?foo@C@stdcall_thunk@@W7EAAXUAgg@2@@Z" // CHECK64: (%"struct.stdcall_thunk::C"* %this, %"struct.stdcall_thunk::Agg"* %x) -// CHECK64: getelementptr i8* %{{.*}}, i32 -8 +// CHECK64: getelementptr i8, i8* %{{.*}}, i32 -8 // CHECK64: call void @"\01?foo@C@stdcall_thunk@@UEAAXUAgg@2@@Z" // CHECK64: (%"struct.stdcall_thunk::C"* %{{.*}}, %"struct.stdcall_thunk::Agg"* %x) // CHECK64-NOT: call @@ -77,9 +77,9 @@ C::C() {} // force emission // CHECK32-LABEL: define linkonce_odr %"struct.sret_thunk::Agg"* @"\01?foo@C@sret_thunk@@W3AA?AUAgg@2@U32@@Z" // CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca) -// CHECK32: %[[this_slot:[^ ]*]] = getelementptr inbounds <{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* %0, i32 0, i32 0 -// CHECK32: load %"struct.sret_thunk::C"** %[[this_slot]] -// CHECK32: getelementptr i8* %{{.*}}, i32 -4 +// CHECK32: %[[this_slot:[^ ]*]] = getelementptr inbounds <{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>, <{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* %0, i32 0, i32 0 +// CHECK32: load %"struct.sret_thunk::C"*, %"struct.sret_thunk::C"** %[[this_slot]] +// CHECK32: getelementptr i8, i8* %{{.*}}, i32 -4 // CHECK32: store %"struct.sret_thunk::C"* %{{.*}}, %"struct.sret_thunk::C"** %[[this_slot]] // CHECK32: %[[rv:[^ ]*]] = musttail call %"struct.sret_thunk::Agg"* @"\01?foo@C@sret_thunk@@UAA?AUAgg@2@U32@@Z" // CHECK32: (<{ %"struct.sret_thunk::C"*, %"struct.sret_thunk::Agg"*, %"struct.sret_thunk::Agg" }>* inalloca %0) @@ -87,7 +87,7 @@ C::C() {} // force emission // CHECK64-LABEL: define linkonce_odr void @"\01?foo@C@sret_thunk@@W7EAA?AUAgg@2@U32@@Z" // CHECK64: (%"struct.sret_thunk::C"* %this, %"struct.sret_thunk::Agg"* noalias sret %agg.result, %"struct.sret_thunk::Agg"* %x) -// CHECK64: getelementptr i8* %{{.*}}, i32 -8 +// CHECK64: getelementptr i8, i8* %{{.*}}, i32 -8 // CHECK64: call void @"\01?foo@C@sret_thunk@@UEAA?AUAgg@2@U32@@Z" // CHECK64: (%"struct.sret_thunk::C"* %{{.*}}, %"struct.sret_thunk::Agg"* sret %agg.result, %"struct.sret_thunk::Agg"* %x) // CHECK64-NOT: call diff --git a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp index f2e9da7..0fef625 100644 --- a/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp +++ b/test/CodeGenCXX/microsoft-abi-dynamic-cast.cpp @@ -20,25 +20,25 @@ T* test1(V* x) { return &dynamic_cast<T&>(*x); } T* test2(A* x) { return &dynamic_cast<T&>(*x); } // CHECK-LABEL: define %struct.T* @"\01?test2@@YAPAUT@@PAUA@@@Z"(%struct.A* %x) // CHECK: [[CAST:%.*]] = bitcast %struct.A* %x to i8* -// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A* %x, i32 0, i32 0 -// CHECK-NEXT: [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[VBOFFS]] +// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0 +// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 +// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[VBOFFS]] // CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 1) // CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T* // CHECK-NEXT: ret %struct.T* [[RET]] T* test3(B* x) { return &dynamic_cast<T&>(*x); } // CHECK-LABEL: define %struct.T* @"\01?test3@@YAPAUT@@PAUB@@@Z"(%struct.B* %x) -// CHECK: [[VOIDP:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0 -// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 4 +// CHECK: [[VOIDP:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0 +// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 4 // CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR:%.*]] to i32** -// CHECK-NEXT: [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4 +// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 // CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[DELTA]] +// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[DELTA]] // CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 1) // CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[CALL]] to %struct.T* // CHECK-NEXT: ret %struct.T* [[RET]] @@ -55,11 +55,11 @@ T* test5(A* x) { return dynamic_cast<T*>(x); } // CHECK: [[CHECK:%.*]] = icmp eq %struct.A* %x, null // CHECK-NEXT: br i1 [[CHECK]] // CHECK: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8* -// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A* %x, i32 0, i32 0 -// CHECK-NEXT: [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[VBOFFS]] +// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0 +// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 +// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]] // CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[VBOFFS]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0) // CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T* // CHECK-NEXT: br label @@ -70,14 +70,14 @@ T* test6(B* x) { return dynamic_cast<T*>(x); } // CHECK-LABEL: define %struct.T* @"\01?test6@@YAPAUT@@PAUB@@@Z"(%struct.B* %x) // CHECK: [[CHECK:%.*]] = icmp eq %struct.B* %x, null // CHECK-NEXT: br i1 [[CHECK]] -// CHECK: [[CAST:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0 -// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8* [[CAST]], i32 4 +// CHECK: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0 +// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4 // CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32** -// CHECK-NEXT: [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4 +// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 // CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[DELTA]] +// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]] // CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTDynamicCast(i8* [[ADJ]], i32 [[DELTA]], i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUT@@@8" to i8*), i32 0) // CHECK-NEXT: [[RES:%.*]] = bitcast i8* [[CALL]] to %struct.T* // CHECK-NEXT: br label @@ -95,11 +95,11 @@ void* test8(A* x) { return dynamic_cast<void*>(x); } // CHECK: [[CHECK:%.*]] = icmp eq %struct.A* %x, null // CHECK-NEXT: br i1 [[CHECK]] // CHECK: [[VOIDP:%.*]] = bitcast %struct.A* %x to i8* -// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A* %x, i32 0, i32 0 -// CHECK-NEXT: [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8* [[VOIDP]], i32 [[VBOFFS]] +// CHECK-NEXT: [[VBPTRPTR:%.*]] = getelementptr inbounds %struct.A, %struct.A* %x, i32 0, i32 0 +// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 +// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[VOIDP]], i32 [[VBOFFS]] // CHECK-NEXT: [[RES:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]]) // CHECK-NEXT: br label // CHECK: [[RET:%.*]] = phi i8* @@ -109,14 +109,14 @@ void* test9(B* x) { return dynamic_cast<void*>(x); } // CHECK-LABEL: define i8* @"\01?test9@@YAPAXPAUB@@@Z"(%struct.B* %x) // CHECK: [[CHECK:%.*]] = icmp eq %struct.B* %x, null // CHECK-NEXT: br i1 [[CHECK]] -// CHECK: [[CAST:%.*]] = getelementptr inbounds %struct.B* %x, i32 0, i32 0, i32 0 -// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8* [[CAST]], i32 4 +// CHECK: [[CAST:%.*]] = getelementptr inbounds %struct.B, %struct.B* %x, i32 0, i32 0, i32 0 +// CHECK-NEXT: [[VBPTR:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 4 // CHECK-NEXT: [[VBPTRPTR:%.*]] = bitcast i8* [[VBPTR]] to i32** -// CHECK-NEXT: [[VBTBL:%.*]] = load i32** [[VBPTRPTR]], align 4 -// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBOFFS:%.*]] = load i32* [[VBOFFP]], align 4 +// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBPTRPTR]], align 4 +// CHECK-NEXT: [[VBOFFP:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-NEXT: [[VBOFFS:%.*]] = load i32, i32* [[VBOFFP]], align 4 // CHECK-NEXT: [[DELTA:%.*]] = add nsw i32 [[VBOFFS]], 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8* [[CAST]], i32 [[DELTA]] +// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[CAST]], i32 [[DELTA]] // CHECK-NEXT: [[CALL:%.*]] = tail call i8* @__RTCastToVoid(i8* [[ADJ]]) // CHECK-NEXT: br label // CHECK: [[RET:%.*]] = phi i8* diff --git a/test/CodeGenCXX/microsoft-abi-eh-catch.cpp b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp new file mode 100644 index 0000000..d7268bf --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-eh-catch.cpp @@ -0,0 +1,154 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc -mconstructor-aliases -fexceptions -fcxx-exceptions | FileCheck -check-prefix WIN64 %s + +extern "C" void might_throw(); + +// Simplify the generated IR with noexcept. +extern "C" void recover() noexcept(true); +extern "C" void handle_exception(void *e) noexcept(true); + +extern "C" void catch_all() { + try { + might_throw(); + } catch (...) { + recover(); + } +} + +// WIN64-LABEL: define void @catch_all() +// WIN64: invoke void @might_throw() +// WIN64-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] +// +// WIN64: [[cont]] +// WIN64: br label %[[ret:[^ ]*]] +// +// WIN64: [[lpad]] +// WIN64: landingpad { i8*, i32 } +// WIN64-NEXT: catch i8* null +// WIN64: call void @llvm.eh.begincatch(i8* %{{[^,]*}}, i8* null) +// WIN64: call void @recover() +// WIN64: call void @llvm.eh.endcatch() +// WIN64: br label %[[ret]] +// +// WIN64: [[ret]] +// WIN64: ret void + +extern "C" void catch_int() { + try { + might_throw(); + } catch (int e) { + handle_exception(&e); + } +} + +// WIN64-LABEL: define void @catch_int() +// WIN64: landingpad { i8*, i32 } +// WIN64: %[[e_i8:[^ ]*]] = bitcast i32* %[[e_addr:[^ ]*]] to i8* +// WIN64: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* %[[e_i8]]) +// WIN64: %[[e_i8:[^ ]*]] = bitcast i32* %[[e_addr]] to i8* +// WIN64: call void @handle_exception(i8* %[[e_i8]]) +// WIN64: call void @llvm.eh.endcatch() + +extern "C" void catch_int_unnamed() { + try { + might_throw(); + } catch (int) { + } +} + +// WIN64-LABEL: define void @catch_int_unnamed() +// WIN64: landingpad { i8*, i32 } +// WIN64: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* null) +// WIN64: call void @llvm.eh.endcatch() + +struct A { + A(); + A(const A &o); + ~A(); + int a; +}; + +struct B : A { + B(); + B(const B &o); + ~B(); + int b; +}; + +extern "C" void catch_a_byval() { + try { + might_throw(); + } catch (A e) { + handle_exception(&e); + } +} + +// WIN64-LABEL: define void @catch_a_byval() +// WIN64: %[[e_addr:[^ ]*]] = alloca %struct.A +// WIN64: landingpad { i8*, i32 } +// WIN64: %[[e_i8:[^ ]*]] = bitcast %struct.A* %[[e_addr]] to i8* +// WIN64: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* %[[e_i8]]) +// WIN64: %[[e_i8:[^ ]*]] = bitcast %struct.A* %[[e_addr]] to i8* +// WIN64: call void @handle_exception(i8* %[[e_i8]]) +// WIN64: call void @llvm.eh.endcatch() + +extern "C" void catch_a_ref() { + try { + might_throw(); + } catch (A &e) { + handle_exception(&e); + } +} + +// WIN64-LABEL: define void @catch_a_ref() +// WIN64: %[[e_addr:[^ ]*]] = alloca %struct.A* +// WIN64: landingpad { i8*, i32 } +// WIN64: %[[e_i8:[^ ]*]] = bitcast %struct.A** %[[e_addr]] to i8* +// WIN64: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* %[[e_i8]]) +// WIN64: %[[eptr:[^ ]*]] = load %struct.A*, %struct.A** %[[e_addr]] +// WIN64: %[[eptr_i8:[^ ]*]] = bitcast %struct.A* %[[eptr]] to i8* +// WIN64: call void @handle_exception(i8* %[[eptr_i8]]) +// WIN64: call void @llvm.eh.endcatch() + +extern "C" void fn_with_exc_spec() throw(int) { + might_throw(); +} + +// WIN64-LABEL: define void @fn_with_exc_spec() +// WIN64: call void @might_throw() +// WIN64-NEXT: ret void + +extern "C" void catch_nested() { + try { + might_throw(); + } catch (int) { + try { + might_throw(); + } catch (int) { + might_throw(); + } + } +} + +// WIN64-LABEL: define void @catch_nested() +// WIN64: invoke void @might_throw() +// WIN64-NEXT: to label %[[cont1:[^ ]*]] unwind label %[[lp1:[^ ]*]] +// WIN64: [[cont1]] +// +// WIN64: [[lp1]] +// WIN64: landingpad { i8*, i32 } +// WIN64: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* null) +// WIN64: invoke void @might_throw() +// WIN64-NEXT: to label %[[cont2:[^ ]*]] unwind label %[[lp2:[^ ]*]] +// +// WIN64: [[cont2]] +// WIN64-NEXT: br label %[[trycont:[^ ]*]] +// +// WIN64: [[lp2]] +// WIN64: landingpad { i8*, i32 } +// WIN64: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* null) +// WIN64-NEXT: call void @might_throw() +// WIN64-NEXT: call void @llvm.eh.endcatch() +// WIN64-NEXT: br label %[[trycont]] +// +// WIN64: [[trycont]] +// WIN64: call void @llvm.eh.endcatch() diff --git a/test/CodeGenCXX/microsoft-abi-exceptions.cpp b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp index 60a3514..68f1430 100644 --- a/test/CodeGenCXX/microsoft-abi-exceptions.cpp +++ b/test/CodeGenCXX/microsoft-abi-eh-cleanups.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fno-rtti | FileCheck -check-prefix WIN32 %s +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fexceptions -fcxx-exceptions -fno-rtti | FileCheck -check-prefix WIN32 %s struct A { A(); @@ -40,14 +40,14 @@ int HasDeactivatedCleanups() { // WIN32: %[[isactive:.*]] = alloca i1 // WIN32: call i8* @llvm.stacksave() // WIN32: %[[argmem:.*]] = alloca inalloca [[argmem_ty:<{ %struct.A, %struct.A }>]] -// WIN32: %[[arg1:.*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 1 +// WIN32: %[[arg1:.*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1 // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" // WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" // // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ"(%struct.A* %[[arg1]]) // WIN32: store i1 true, i1* %[[isactive]] // -// WIN32: %[[arg0:.*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 0 +// WIN32: %[[arg0:.*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0 // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" // WIN32: invoke void @"\01?TakeRef@@YAXABUA@@@Z" // WIN32: invoke x86_thiscallcc %struct.A* @"\01??0A@@QAE@XZ" @@ -61,7 +61,7 @@ int HasDeactivatedCleanups() { // WIN32: ret i32 // // Conditionally destroy arg1. -// WIN32: %[[cond:.*]] = load i1* %[[isactive]] +// WIN32: %[[cond:.*]] = load i1, i1* %[[isactive]] // WIN32: br i1 %[[cond]] // WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ"(%struct.A* %[[arg1]]) // WIN32: } @@ -125,7 +125,7 @@ int HasConditionalDeactivatedCleanups(bool cond) { // WIN32: ret i32 // // Somewhere in the landing pad soup, we conditionally destroy arg1. -// WIN32: %[[isactive:.*]] = load i1* %[[arg1_cond]] +// WIN32: %[[isactive:.*]] = load i1, i1* %[[arg1_cond]] // WIN32: br i1 %[[isactive]] // WIN32: invoke x86_thiscallcc void @"\01??1A@@QAE@XZ" // WIN32: } @@ -154,7 +154,7 @@ C::C() { foo(); } // // We shouldn't do any vbptr loads, just constant GEPs. // WIN32-NOT: load -// WIN32: getelementptr i8* %{{.*}}, i32 4 +// WIN32: getelementptr i8, i8* %{{.*}}, i32 4 // WIN32-NOT: load // WIN32: bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::B"* // WIN32: invoke x86_thiscallcc void @"\01??1B@crash_on_partial_destroy@@UAE@XZ" @@ -162,9 +162,32 @@ C::C() { foo(); } // WIN32-NOT: load // WIN32: bitcast %"struct.crash_on_partial_destroy::C"* %{{.*}} to i8* // WIN32-NOT: load -// WIN32: getelementptr inbounds i8* %{{.*}}, i64 4 +// WIN32: getelementptr inbounds i8, i8* %{{.*}}, i64 4 // WIN32-NOT: load // WIN32: bitcast i8* %{{.*}} to %"struct.crash_on_partial_destroy::A"* -// WIN32: invoke x86_thiscallcc void @"\01??1A@crash_on_partial_destroy@@UAE@XZ" +// WIN32: call x86_thiscallcc void @"\01??1A@crash_on_partial_destroy@@UAE@XZ" // WIN32: } } + +namespace dont_call_terminate { +struct C { + ~C(); +}; +void g(); +void f() { + C c; + g(); +} + +// WIN32-LABEL: define void @"\01?f@dont_call_terminate@@YAXXZ"() +// WIN32: invoke void @"\01?g@dont_call_terminate@@YAXXZ"() +// WIN32-NEXT: to label %[[cont:[^ ]*]] unwind label %[[lpad:[^ ]*]] +// +// WIN32: [[cont]] +// WIN32: call x86_thiscallcc void @"\01??1C@dont_call_terminate@@QAE@XZ"({{.*}}) +// +// WIN32: [[lpad]] +// WIN32-NEXT: landingpad +// WIN32-NEXT: cleanup +// WIN32: call x86_thiscallcc void @"\01??1C@dont_call_terminate@@QAE@XZ"({{.*}}) +} diff --git a/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp b/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp new file mode 100644 index 0000000..cbc1686 --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-eh-terminate.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc -mconstructor-aliases -fexceptions -fcxx-exceptions -fms-compatibility-version=18.00 | FileCheck -check-prefix=MSVC2013 %s +// RUN: %clang_cc1 -std=c++11 -emit-llvm %s -o - -triple=x86_64-pc-windows-msvc -mconstructor-aliases -fexceptions -fcxx-exceptions -fms-compatibility-version=19.00 | FileCheck -check-prefix=MSVC2015 %s + +void may_throw(); +void never_throws() noexcept(true) { + may_throw(); +} + +// CHECK-LABEL: define void @"\01?never_throws@@YAXXZ" +// CHECK: invoke void @"\01?may_throw@@YAXXZ"() + +// CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) +// MSVC2013: call void @"\01?terminate@@YAXXZ"() +// MSVC2015: call void @__std_terminate() +// CHECK-NEXT: unreachable diff --git a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp index 719cb70..c12ceae 100755 --- a/test/CodeGenCXX/microsoft-abi-member-pointers.cpp +++ b/test/CodeGenCXX/microsoft-abi-member-pointers.cpp @@ -80,20 +80,20 @@ int UnspecSingle::*us_d_memptr; // CHECK: @"\01?p_d_memptr@@3PQPolymorphic@@HQ1@" = global i32 0, align 4 // CHECK: @"\01?m_d_memptr@@3PQMultiple@@HQ1@" = global i32 -1, align 4 // CHECK: @"\01?v_d_memptr@@3PQVirtual@@HQ1@" = global { i32, i32 } -// CHECK: { i32 0, i32 -1 }, align 8 +// CHECK: { i32 0, i32 -1 }, align 4 // CHECK: @"\01?n_d_memptr@@3PQNonZeroVBPtr@@HQ1@" = global { i32, i32 } -// CHECK: { i32 0, i32 -1 }, align 8 +// CHECK: { i32 0, i32 -1 }, align 4 // CHECK: @"\01?u_d_memptr@@3PQUnspecified@@HQ1@" = global { i32, i32, i32 } -// CHECK: { i32 0, i32 0, i32 -1 }, align 8 +// CHECK: { i32 0, i32 0, i32 -1 }, align 4 // CHECK: @"\01?us_d_memptr@@3PQUnspecSingle@@HQ1@" = global { i32, i32, i32 } -// CHECK: { i32 0, i32 0, i32 -1 }, align 8 +// CHECK: { i32 0, i32 0, i32 -1 }, align 4 void (Single ::*s_f_memptr)(); void (Multiple::*m_f_memptr)(); void (Virtual ::*v_f_memptr)(); // CHECK: @"\01?s_f_memptr@@3P8Single@@AEXXZQ1@" = global i8* null, align 4 -// CHECK: @"\01?m_f_memptr@@3P8Multiple@@AEXXZQ1@" = global { i8*, i32 } zeroinitializer, align 8 -// CHECK: @"\01?v_f_memptr@@3P8Virtual@@AEXXZQ1@" = global { i8*, i32, i32 } zeroinitializer, align 8 +// CHECK: @"\01?m_f_memptr@@3P8Multiple@@AEXXZQ1@" = global { i8*, i32 } zeroinitializer, align 4 +// CHECK: @"\01?v_f_memptr@@3P8Virtual@@AEXXZQ1@" = global { i8*, i32, i32 } zeroinitializer, align 4 // We can define Unspecified after locking in the inheritance model. struct Unspecified : Multiple, Virtual { @@ -115,13 +115,13 @@ void (UnspecSingle::*us_f_mp)() = &UnspecSingle::foo; // CHECK: @"\01?s_f_mp@Const@@3P8Single@@AEXXZQ2@" = // CHECK: global i8* bitcast ({{.*}} @"\01?foo@Single@@QAEXXZ" to i8*), align 4 // CHECK: @"\01?m_f_mp@Const@@3P8Multiple@@AEXXZQ2@" = -// CHECK: global { i8*, i32 } { i8* bitcast ({{.*}} @"\01?foo@B2@@QAEXXZ" to i8*), i32 4 }, align 8 +// CHECK: global { i8*, i32 } { i8* bitcast ({{.*}} @"\01?foo@B2@@QAEXXZ" to i8*), i32 4 }, align 4 // CHECK: @"\01?v_f_mp@Const@@3P8Virtual@@AEXXZQ2@" = -// CHECK: global { i8*, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, align 8 +// CHECK: global { i8*, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, align 4 // CHECK: @"\01?u_f_mp@Const@@3P8Unspecified@@AEXXZQ2@" = -// CHECK: global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 12, i32 0 }, align 8 +// CHECK: global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 12, i32 0 }, align 4 // CHECK: @"\01?us_f_mp@Const@@3P8UnspecSingle@@AEXXZQ2@" = -// CHECK: global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@UnspecSingle@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, align 8 +// CHECK: global { i8*, i32, i32, i32 } { i8* bitcast ({{.*}} @"\01?foo@UnspecSingle@@QAEXXZ" to i8*), i32 0, i32 0, i32 0 }, align 4 } namespace CastParam { @@ -143,11 +143,11 @@ void (A::*ptr1)(void *) = (void (A::*)(void *)) &A::foo; // Try a reinterpret_cast followed by a memptr conversion. void (C::*ptr2)(void *) = (void (C::*)(void *)) (void (A::*)(void *)) &A::foo; // CHECK: @"\01?ptr2@CastParam@@3P8C@1@AEXPAX@ZQ21@" = -// CHECK: global { i8*, i32 } { i8* bitcast (void ({{.*}})* @"\01?foo@A@CastParam@@QAEXPAU12@@Z" to i8*), i32 4 }, align 8 +// CHECK: global { i8*, i32 } { i8* bitcast (void ({{.*}})* @"\01?foo@A@CastParam@@QAEXPAU12@@Z" to i8*), i32 4 }, align 4 void (C::*ptr3)(void *) = (void (C::*)(void *)) (void (A::*)(void *)) (void (A::*)(A *)) 0; // CHECK: @"\01?ptr3@CastParam@@3P8C@1@AEXPAX@ZQ21@" = -// CHECK: global { i8*, i32 } zeroinitializer, align 8 +// CHECK: global { i8*, i32 } zeroinitializer, align 4 struct D : C { virtual void isPolymorphic(); @@ -180,23 +180,23 @@ void EmitNonVirtualMemberPointers() { void (UnspecWithVBPtr::*u2_f_memptr)() = &UnspecWithVBPtr::foo; // CHECK: define void @"\01?EmitNonVirtualMemberPointers@@YAXXZ"() {{.*}} { // CHECK: alloca i8*, align 4 -// CHECK: alloca { i8*, i32 }, align 8 -// CHECK: alloca { i8*, i32, i32 }, align 8 -// CHECK: alloca { i8*, i32, i32, i32 }, align 8 +// CHECK: alloca { i8*, i32 }, align 4 +// CHECK: alloca { i8*, i32, i32 }, align 4 +// CHECK: alloca { i8*, i32, i32, i32 }, align 4 // CHECK: store i8* bitcast (void (%{{.*}}*)* @"\01?foo@Single@@QAEXXZ" to i8*), i8** %{{.*}}, align 4 // CHECK: store { i8*, i32 } // CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Multiple@@QAEXXZ" to i8*), i32 0 }, -// CHECK: { i8*, i32 }* %{{.*}}, align 8 +// CHECK: { i8*, i32 }* %{{.*}}, align 4 // CHECK: store { i8*, i32, i32 } // CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Virtual@@QAEXXZ" to i8*), i32 0, i32 0 }, -// CHECK: { i8*, i32, i32 }* %{{.*}}, align 8 +// CHECK: { i8*, i32, i32 }* %{{.*}}, align 4 // CHECK: store { i8*, i32, i32, i32 } // CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@Unspecified@@QAEXXZ" to i8*), i32 0, i32 12, i32 0 }, -// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 8 +// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4 // CHECK: store { i8*, i32, i32, i32 } // CHECK: { i8* bitcast (void (%{{.*}}*)* @"\01?foo@UnspecWithVBPtr@@QAEXXZ" to i8*), // CHECK: i32 0, i32 4, i32 0 }, -// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 8 +// CHECK: { i8*, i32, i32, i32 }* %{{.*}}, align 4 // CHECK: ret void // CHECK: } } @@ -212,7 +212,7 @@ void podMemPtrs() { // CHECK: %[[memptr:.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 0, i32* %[[memptr]], align 4 // CHECK-NEXT: store i32 4, i32* %[[memptr]], align 4 -// CHECK-NEXT: %[[memptr_val:.*]] = load i32* %[[memptr]], align 4 +// CHECK-NEXT: %[[memptr_val:.*]] = load i32, i32* %[[memptr]], align 4 // CHECK-NEXT: %{{.*}} = icmp ne i32 %[[memptr_val]], -1 // CHECK-NEXT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} // CHECK: store i32 -1, i32* %[[memptr]], align 4 @@ -232,7 +232,7 @@ void polymorphicMemPtrs() { // CHECK: %[[memptr:.*]] = alloca i32, align 4 // CHECK-NEXT: store i32 4, i32* %[[memptr]], align 4 // CHECK-NEXT: store i32 8, i32* %[[memptr]], align 4 -// CHECK-NEXT: %[[memptr_val:.*]] = load i32* %[[memptr]], align 4 +// CHECK-NEXT: %[[memptr_val:.*]] = load i32, i32* %[[memptr]], align 4 // CHECK-NEXT: %{{.*}} = icmp ne i32 %[[memptr_val]], 0 // CHECK-NEXT: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} // CHECK: store i32 0, i32* %[[memptr]], align 4 @@ -243,9 +243,9 @@ void polymorphicMemPtrs() { bool nullTestDataUnspecified(int Unspecified::*mp) { return mp; // CHECK: define zeroext i1 @"\01?nullTestDataUnspecified@@YA_NPQUnspecified@@H@Z"{{.*}} { -// CHECK: %{{.*}} = load { i32, i32, i32 }* %{{.*}}, align 8 -// CHECK: store { i32, i32, i32 } {{.*}} align 8 -// CHECK: %[[mp:.*]] = load { i32, i32, i32 }* %{{.*}}, align 8 +// CHECK: %{{.*}} = load { i32, i32, i32 }, { i32, i32, i32 }* %{{.*}}, align 4 +// CHECK: store { i32, i32, i32 } {{.*}} align 4 +// CHECK: %[[mp:.*]] = load { i32, i32, i32 }, { i32, i32, i32 }* %{{.*}}, align 4 // CHECK: %[[mp0:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 0 // CHECK: %[[cmp0:.*]] = icmp ne i32 %[[mp0]], 0 // CHECK: %[[mp1:.*]] = extractvalue { i32, i32, i32 } %[[mp]], 1 @@ -265,9 +265,9 @@ bool nullTestDataUnspecified(int Unspecified::*mp) { bool nullTestFunctionUnspecified(void (Unspecified::*mp)()) { return mp; // CHECK: define zeroext i1 @"\01?nullTestFunctionUnspecified@@YA_NP8Unspecified@@AEXXZ@Z"{{.*}} { -// CHECK: %{{.*}} = load { i8*, i32, i32, i32 }* %{{.*}}, align 8 -// CHECK: store { i8*, i32, i32, i32 } {{.*}} align 8 -// CHECK: %[[mp:.*]] = load { i8*, i32, i32, i32 }* %{{.*}}, align 8 +// CHECK: %{{.*}} = load { i8*, i32, i32, i32 }, { i8*, i32, i32, i32 }* %{{.*}}, align 4 +// CHECK: store { i8*, i32, i32, i32 } {{.*}} align 4 +// CHECK: %[[mp:.*]] = load { i8*, i32, i32, i32 }, { i8*, i32, i32, i32 }* %{{.*}}, align 4 // CHECK: %[[mp0:.*]] = extractvalue { i8*, i32, i32, i32 } %[[mp]], 0 // CHECK: %[[cmp0:.*]] = icmp ne i8* %[[mp0]], null // CHECK: ret i1 %[[cmp0]] @@ -279,21 +279,21 @@ int loadDataMemberPointerVirtual(Virtual *o, int Virtual::*memptr) { // Test that we can unpack this aggregate member pointer and load the member // data pointer. // CHECK: define i32 @"\01?loadDataMemberPointerVirtual@@YAHPAUVirtual@@PQ1@H@Z"{{.*}} { -// CHECK: %[[o:.*]] = load %{{.*}}** %{{.*}}, align 4 -// CHECK: %[[memptr:.*]] = load { i32, i32 }* %{{.*}}, align 8 +// CHECK: %[[o:.*]] = load %{{.*}}*, %{{.*}}** %{{.*}}, align 4 +// CHECK: %[[memptr:.*]] = load { i32, i32 }, { i32, i32 }* %{{.*}}, align 4 // CHECK: %[[memptr0:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 0 // CHECK: %[[memptr1:.*]] = extractvalue { i32, i32 } %[[memptr:.*]], 1 // CHECK: %[[v6:.*]] = bitcast %{{.*}}* %[[o]] to i8* -// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8* %[[v6]], i32 0 +// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, i8* %[[v6]], i32 0 // CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32** -// CHECK: %[[vbtable:.*]] = load i32** %[[vbptr_a:.*]] +// CHECK: %[[vbtable:.*]] = load i32*, i32** %[[vbptr_a:.*]] // CHECK: %[[memptr1_shr:.*]] = ashr exact i32 %[[memptr1]], 2 -// CHECK: %[[v7:.*]] = getelementptr inbounds i32* %[[vbtable]], i32 %[[memptr1_shr]] -// CHECK: %[[vbase_offs:.*]] = load i32* %[[v7]] -// CHECK: %[[v10:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]] -// CHECK: %[[offset:.*]] = getelementptr inbounds i8* %[[v10]], i32 %[[memptr0]] +// CHECK: %[[v7:.*]] = getelementptr inbounds i32, i32* %[[vbtable]], i32 %[[memptr1_shr]] +// CHECK: %[[vbase_offs:.*]] = load i32, i32* %[[v7]] +// CHECK: %[[v10:.*]] = getelementptr inbounds i8, i8* %[[vbptr]], i32 %[[vbase_offs]] +// CHECK: %[[offset:.*]] = getelementptr inbounds i8, i8* %[[v10]], i32 %[[memptr0]] // CHECK: %[[v11:.*]] = bitcast i8* %[[offset]] to i32* -// CHECK: %[[v12:.*]] = load i32* %[[v11]] +// CHECK: %[[v12:.*]] = load i32, i32* %[[v11]] // CHECK: ret i32 %[[v12]] // CHECK: } @@ -308,8 +308,8 @@ int loadDataMemberPointerUnspecified(Unspecified *o, int Unspecified::*memptr) { // Test that we can unpack this aggregate member pointer and load the member // data pointer. // CHECK: define i32 @"\01?loadDataMemberPointerUnspecified@@YAHPAUUnspecified@@PQ1@H@Z"{{.*}} { -// CHECK: %[[o:.*]] = load %{{.*}}** %{{.*}}, align 4 -// CHECK: %[[memptr:.*]] = load { i32, i32, i32 }* %{{.*}}, align 8 +// CHECK: %[[o:.*]] = load %{{.*}}*, %{{.*}}** %{{.*}}, align 4 +// CHECK: %[[memptr:.*]] = load { i32, i32, i32 }, { i32, i32, i32 }* %{{.*}}, align 4 // CHECK: %[[memptr0:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 0 // CHECK: %[[memptr1:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 1 // CHECK: %[[memptr2:.*]] = extractvalue { i32, i32, i32 } %[[memptr:.*]], 2 @@ -318,19 +318,19 @@ int loadDataMemberPointerUnspecified(Unspecified *o, int Unspecified::*memptr) { // CHECK: br i1 %[[is_vbase]], label %[[vadjust:.*]], label %[[skip:.*]] // // CHECK: [[vadjust]] -// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8* %[[base]], i32 %[[memptr1]] +// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, i8* %[[base]], i32 %[[memptr1]] // CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32** -// CHECK: %[[vbtable:.*]] = load i32** %[[vbptr_a:.*]] +// CHECK: %[[vbtable:.*]] = load i32*, i32** %[[vbptr_a:.*]] // CHECK: %[[memptr2_shr:.*]] = ashr exact i32 %[[memptr2]], 2 -// CHECK: %[[v7:.*]] = getelementptr inbounds i32* %[[vbtable]], i32 %[[memptr2_shr]] -// CHECK: %[[vbase_offs:.*]] = load i32* %[[v7]] -// CHECK: %[[base_adj:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]] +// CHECK: %[[v7:.*]] = getelementptr inbounds i32, i32* %[[vbtable]], i32 %[[memptr2_shr]] +// CHECK: %[[vbase_offs:.*]] = load i32, i32* %[[v7]] +// CHECK: %[[base_adj:.*]] = getelementptr inbounds i8, i8* %[[vbptr]], i32 %[[vbase_offs]] // // CHECK: [[skip]] // CHECK: %[[new_base:.*]] = phi i8* [ %[[base]], %{{.*}} ], [ %[[base_adj]], %[[vadjust]] ] -// CHECK: %[[offset:.*]] = getelementptr inbounds i8* %[[new_base]], i32 %[[memptr0]] +// CHECK: %[[offset:.*]] = getelementptr inbounds i8, i8* %[[new_base]], i32 %[[memptr0]] // CHECK: %[[v11:.*]] = bitcast i8* %[[offset]] to i32* -// CHECK: %[[v12:.*]] = load i32* %[[v11]] +// CHECK: %[[v12:.*]] = load i32, i32* %[[v11]] // CHECK: ret i32 %[[v12]] // CHECK: } } @@ -354,7 +354,7 @@ void callMemberPointerMultiple(Multiple *o, void (Multiple::*memptr)()) { // CHECK: define void @"\01?callMemberPointerMultiple@@{{.*}} { // CHECK: %[[memptr0:.*]] = extractvalue { i8*, i32 } %{{.*}}, 0 // CHECK: %[[memptr1:.*]] = extractvalue { i8*, i32 } %{{.*}}, 1 -// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8* %{{.*}}, i32 %[[memptr1]] +// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8, i8* %{{.*}}, i32 %[[memptr1]] // CHECK: %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}} // CHECK: %[[fptr:.*]] = bitcast i8* %[[memptr0]] to {{.*}} // CHECK: call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]]) @@ -369,14 +369,14 @@ void callMemberPointerVirtualBase(Virtual *o, void (Virtual::*memptr)()) { // CHECK: %[[memptr0:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 0 // CHECK: %[[memptr1:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 1 // CHECK: %[[memptr2:.*]] = extractvalue { i8*, i32, i32 } %{{.*}}, 2 -// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8* %{{.*}}, i32 0 +// CHECK: %[[vbptr:.*]] = getelementptr inbounds i8, i8* %{{.*}}, i32 0 // CHECK: %[[vbptr_a:.*]] = bitcast i8* %[[vbptr]] to i32** -// CHECK: %[[vbtable:.*]] = load i32** %[[vbptr_a:.*]] +// CHECK: %[[vbtable:.*]] = load i32*, i32** %[[vbptr_a:.*]] // CHECK: %[[memptr2_shr:.*]] = ashr exact i32 %[[memptr2]], 2 -// CHECK: %[[v7:.*]] = getelementptr inbounds i32* %[[vbtable]], i32 %[[memptr2_shr]] -// CHECK: %[[vbase_offs:.*]] = load i32* %[[v7]] -// CHECK: %[[v10:.*]] = getelementptr inbounds i8* %[[vbptr]], i32 %[[vbase_offs]] -// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8* %[[v10]], i32 %[[memptr1]] +// CHECK: %[[v7:.*]] = getelementptr inbounds i32, i32* %[[vbtable]], i32 %[[memptr2_shr]] +// CHECK: %[[vbase_offs:.*]] = load i32, i32* %[[v7]] +// CHECK: %[[v10:.*]] = getelementptr inbounds i8, i8* %[[vbptr]], i32 %[[vbase_offs]] +// CHECK: %[[this_adjusted:.*]] = getelementptr inbounds i8, i8* %[[v10]], i32 %[[memptr1]] // CHECK: %[[fptr:.*]] = bitcast i8* %[[memptr0]] to void ({{.*}}) // CHECK: %[[this:.*]] = bitcast i8* %[[this_adjusted]] to {{.*}} // CHECK: call x86_thiscallcc void %[[fptr]](%{{.*}} %[[this]]) @@ -485,7 +485,7 @@ void (Multiple::*convertB2FuncToMultiple(void (B2::*mp)()))() { return mp; // CHECK: define i64 @"\01?convertB2FuncToMultiple@@YAP8Multiple@@AEXXZP8B2@@AEXXZ@Z"{{.*}} { // CHECK: store -// CHECK: %[[mp:.*]] = load i8** %{{.*}}, align 4 +// CHECK: %[[mp:.*]] = load i8*, i8** %{{.*}}, align 4 // CHECK: icmp ne i8* %[[mp]], null // CHECK: br i1 %{{.*}} label %{{.*}}, label %{{.*}} // @@ -509,7 +509,7 @@ void (B2::*convertMultipleFuncToB2(void (Multiple::*mp)()))() { // // CHECK: define i32 @"\01?convertMultipleFuncToB2@@YAP8B2@@AEXXZP8Multiple@@AEXXZ@Z"{{.*}} { // CHECK: store -// CHECK: %[[src:.*]] = load { i8*, i32 }* %{{.*}}, align 8 +// CHECK: %[[src:.*]] = load { i8*, i32 }, { i8*, i32 }* %{{.*}}, align 4 // CHECK: extractvalue { i8*, i32 } %[[src]], 0 // CHECK: icmp ne i8* %{{.*}}, null // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} @@ -534,7 +534,7 @@ void (D::*convertCToD(void (C::*mp)()))() { return mp; // CHECK: define void @"\01?convertCToD@Test1@@YAP8D@1@AEXXZP8C@1@AEXXZ@Z"{{.*}} { // CHECK: store -// CHECK: load { i8*, i32, i32 }* %{{.*}}, align 8 +// CHECK: load { i8*, i32, i32 }, { i8*, i32, i32 }* %{{.*}}, align 4 // CHECK: extractvalue { i8*, i32, i32 } %{{.*}}, 0 // CHECK: icmp ne i8* %{{.*}}, null // CHECK: br i1 %{{.*}}, label %{{.*}}, label %{{.*}} @@ -577,7 +577,7 @@ int A::*reinterpret(int B::*mp) { int A::*reinterpret(int C::*mp) { return reinterpret_cast<int A::*>(mp); // CHECK: define i32 @"\01?reinterpret@Test2@@YAPQA@1@HPQC@1@H@Z"{{.*}} { -// CHECK: %[[mp:.*]] = load i32* +// CHECK: %[[mp:.*]] = load i32, i32* // CHECK: %[[cmp:.*]] = icmp ne i32 %[[mp]], 0 // CHECK: select i1 %[[cmp]], i32 %[[mp]], i32 -1 // CHECK: } @@ -596,10 +596,10 @@ struct A { int *load_data(A *a, int A::*mp) { return &(a->*mp); // CHECK-LABEL: define i32* @"\01?load_data@Test3@@YAPAHPAUA@1@PQ21@H@Z"{{.*}} { -// CHECK: %[[a:.*]] = load %"struct.Test3::A"** %{{.*}}, align 4 -// CHECK: %[[mp:.*]] = load i32* %{{.*}}, align 4 +// CHECK: %[[a:.*]] = load %"struct.Test3::A"*, %"struct.Test3::A"** %{{.*}}, align 4 +// CHECK: %[[mp:.*]] = load i32, i32* %{{.*}}, align 4 // CHECK: %[[a_i8:.*]] = bitcast %"struct.Test3::A"* %[[a]] to i8* -// CHECK: getelementptr inbounds i8* %[[a_i8]], i32 %[[mp]] +// CHECK: getelementptr inbounds i8, i8* %[[a_i8]], i32 %[[mp]] // CHECK: } } @@ -618,12 +618,12 @@ void (C::*getmp())() { // CHECK: store { i8*, i32 } { i8* bitcast (void (%"struct.Test4::C"*, ...)* @"\01??_9C@Test4@@$BA@AE" to i8*), i32 4 }, { i8*, i32 }* %{{.*}} // -// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@Test4@@$BA@AE"(%"struct.Test4::C"* %this, ...) +// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@Test4@@$BA@AE"(%"struct.Test4::C"* %this, ...) {{.*}} comdat // CHECK-NOT: getelementptr -// CHECK: load void (%"struct.Test4::C"*, ...)*** %{{.*}} -// CHECK: getelementptr inbounds void (%"struct.Test4::C"*, ...)** %{{.*}}, i64 0 +// CHECK: load void (%"struct.Test4::C"*, ...)**, void (%"struct.Test4::C"*, ...)*** %{{.*}} +// CHECK: getelementptr inbounds void (%"struct.Test4::C"*, ...)*, void (%"struct.Test4::C"*, ...)** %{{.*}}, i64 0 // CHECK-NOT: getelementptr -// CHECK: musttail call x86_thiscallcc void (%"struct.Test4::C"*, ...)* % +// CHECK: musttail call x86_thiscallcc void (%"struct.Test4::C"*, ...) % } diff --git a/test/CodeGenCXX/microsoft-abi-methods.cpp b/test/CodeGenCXX/microsoft-abi-methods.cpp index 579e549..e58d103 100644 --- a/test/CodeGenCXX/microsoft-abi-methods.cpp +++ b/test/CodeGenCXX/microsoft-abi-methods.cpp @@ -42,7 +42,7 @@ void call_vararg_method() { C instance; instance.vararg_method("Hello"); // Make sure that the call uses the right calling convention: -// CHECK: call void (%class.C*, i8*, ...)* @"\01?vararg_method@C@@QAAXPBDZZ" +// CHECK: call void (%class.C*, i8*, ...) @"\01?vararg_method@C@@QAAXPBDZZ" // CHECK: ret // Make sure that the definition uses the right calling convention: @@ -75,6 +75,9 @@ void constructors() { // CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc %class.Base* @"\01??0Base@@QAE@XZ" // CHECK: ret +// Make sure that the Base constructor definition uses the right CC: +// CHECK: define linkonce_odr x86_thiscallcc %class.Base* @"\01??0Base@@QAE@XZ" + // Make sure that the Base destructor call in the Child denstructor uses // the right calling convention: // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1Child@@QAE@XZ" @@ -83,7 +86,4 @@ void constructors() { // Make sure that the Base destructor definition uses the right CC: // CHECK: define linkonce_odr x86_thiscallcc void @"\01??1Base@@QAE@XZ" - -// Make sure that the Base constructor definition uses the right CC: -// CHECK: define linkonce_odr x86_thiscallcc %class.Base* @"\01??0Base@@QAE@XZ" } diff --git a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp index b5293e0..34cb85e 100644 --- a/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp +++ b/test/CodeGenCXX/microsoft-abi-multiple-nonvirtual-inheritance.cpp @@ -26,9 +26,9 @@ void call_left_no_override(ChildNoOverride *child) { // Only need to cast 'this' to Left*. // CHECK: %[[LEFT:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to %struct.Left* // CHECK: %[[VFPTR:.*]] = bitcast %struct.Left* %[[LEFT]] to void (%struct.Left*)*** -// CHECK: %[[VFTABLE:.*]] = load void (%struct.Left*)*** %[[VFPTR]] -// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Left*)** %[[VFTABLE]], i64 0 -// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Left*)** %[[VFUN]] +// CHECK: %[[VFTABLE:.*]] = load void (%struct.Left*)**, void (%struct.Left*)*** %[[VFPTR]] +// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Left*)*, void (%struct.Left*)** %[[VFTABLE]], i64 0 +// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Left*)*, void (%struct.Left*)** %[[VFUN]] // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Left* %[[LEFT]]) // CHECK: ret } @@ -41,7 +41,7 @@ void ChildOverride::left() { // CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4 foo(this); -// CHECK: %[[THIS:.*]] = load %struct.ChildOverride** %[[THIS_ADDR]] +// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]] // CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8* // CHECK: call void @foo(i8* %[[THIS_i8]]) // CHECK: ret @@ -53,9 +53,9 @@ void call_left_override(ChildOverride *child) { child->left(); // CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to void (%struct.ChildOverride*)*** -// CHECK: %[[VFTABLE:.*]] = load void (%struct.ChildOverride*)*** %[[VFPTR]] -// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.ChildOverride*)** %[[VFTABLE]], i64 0 -// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.ChildOverride*)** %[[VFUN]] +// CHECK: %[[VFTABLE:.*]] = load void (%struct.ChildOverride*)**, void (%struct.ChildOverride*)*** %[[VFPTR]] +// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFTABLE]], i64 0 +// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.ChildOverride*)*, void (%struct.ChildOverride*)** %[[VFUN]] // // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.ChildOverride* %[[CHILD]]) // CHECK: ret @@ -70,13 +70,13 @@ void call_right_no_override(ChildNoOverride *child) { // the caller site. // // CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildNoOverride* %[[CHILD]] to i8* -// CHECK: %[[RIGHT_i8:.*]] = getelementptr inbounds i8* %[[CHILD_i8]], i32 4 +// CHECK: %[[RIGHT_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4 // CHECK: %[[RIGHT:.*]] = bitcast i8* %[[RIGHT_i8]] to %struct.Right* // // CHECK: %[[VFPTR:.*]] = bitcast %struct.Right* %[[RIGHT]] to void (%struct.Right*)*** -// CHECK: %[[VFTABLE:.*]] = load void (%struct.Right*)*** %[[VFPTR]] -// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Right*)** %[[VFTABLE]], i64 0 -// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Right*)** %[[VFUN]] +// CHECK: %[[VFTABLE:.*]] = load void (%struct.Right*)**, void (%struct.Right*)*** %[[VFPTR]] +// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (%struct.Right*)*, void (%struct.Right*)** %[[VFTABLE]], i64 0 +// CHECK: %[[VFUN_VALUE:.*]] = load void (%struct.Right*)*, void (%struct.Right*)** %[[VFUN]] // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](%struct.Right* %[[RIGHT]]) // CHECK: ret } @@ -88,12 +88,12 @@ void ChildOverride::right() { // need to adjust 'this' before use. // // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.ChildOverride*, align 4 -// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8* %[[ECX:.*]], i32 -4 +// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.ChildOverride* // CHECK: store %struct.ChildOverride* %[[THIS]], %struct.ChildOverride** %[[THIS_ADDR]], align 4 foo(this); -// CHECK: %[[THIS:.*]] = load %struct.ChildOverride** %[[THIS_ADDR]] +// CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** %[[THIS_ADDR]] // CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8* // CHECK: call void @foo(i8* %[[THIS_PARAM]]) // CHECK: ret @@ -109,14 +109,14 @@ void call_right_override(ChildOverride *child) { // // CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8* // -// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[CHILD_i8]], i32 4 +// CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4 // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to void (i8*)*** -// CHECK: %[[VFTABLE:.*]] = load void (i8*)*** %[[VFPTR]] -// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)** %[[VFTABLE]], i64 0 -// CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)** %[[VFUN]] +// CHECK: %[[VFTABLE:.*]] = load void (i8*)**, void (i8*)*** %[[VFPTR]] +// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)*, void (i8*)** %[[VFTABLE]], i64 0 +// CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]] // // CHECK: %[[CHILD_i8:.*]] = bitcast %struct.ChildOverride* %[[CHILD]] to i8* -// CHECK: %[[RIGHT:.*]] = getelementptr inbounds i8* %[[CHILD_i8]], i32 4 +// CHECK: %[[RIGHT:.*]] = getelementptr inbounds i8, i8* %[[CHILD_i8]], i32 4 // // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* %[[RIGHT]]) // CHECK: ret @@ -130,12 +130,12 @@ void GrandchildOverride::right() { // CHECK: define x86_thiscallcc void @"\01?right@GrandchildOverride@@UAEXXZ"(i8* // // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.GrandchildOverride*, align 4 -// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8* %[[ECX:.*]], i32 -4 +// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -4 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.GrandchildOverride* // CHECK: store %struct.GrandchildOverride* %[[THIS]], %struct.GrandchildOverride** %[[THIS_ADDR]], align 4 foo(this); -// CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride** %[[THIS_ADDR]] +// CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** %[[THIS_ADDR]] // CHECK: %[[THIS_PARAM:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8* // CHECK: call void @foo(i8* %[[THIS_PARAM]]) // CHECK: ret @@ -161,22 +161,22 @@ void emit_ctors() { ChildOverride co; // CHECK: define {{.*}} @"\01??0ChildOverride@@QAE@XZ" - // CHECK: %[[THIS:.*]] = load %struct.ChildOverride** + // CHECK: %[[THIS:.*]] = load %struct.ChildOverride*, %struct.ChildOverride** // CHECK: %[[VFPTR:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i32 (...)*** // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]] // CHECK: %[[THIS_i8:.*]] = bitcast %struct.ChildOverride* %[[THIS]] to i8* - // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 4 + // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4 // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)*** // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7ChildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]] // CHECK: ret GrandchildOverride gc; // CHECK: define {{.*}} @"\01??0GrandchildOverride@@QAE@XZ" - // CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride** + // CHECK: %[[THIS:.*]] = load %struct.GrandchildOverride*, %struct.GrandchildOverride** // CHECK: %[[VFPTR:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i32 (...)*** // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BLeft@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]] // CHECK: %[[THIS_i8:.*]] = bitcast %struct.GrandchildOverride* %[[THIS]] to i8* - // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 4 + // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 4 // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)*** // CHECK: store i32 (...)** bitcast ([1 x i8*]* @"\01??_7GrandchildOverride@@6BRight@@@" to i32 (...)**), i32 (...)*** %[[VFPTR]] // CHECK: ret diff --git a/test/CodeGenCXX/microsoft-abi-rtti.cpp b/test/CodeGenCXX/microsoft-abi-rtti.cpp index 062f597..5738b60 100644 --- a/test/CodeGenCXX/microsoft-abi-rtti.cpp +++ b/test/CodeGenCXX/microsoft-abi-rtti.cpp @@ -26,242 +26,242 @@ struct Y2 { virtual void f() {} }; struct A2 : Z2, Y2 {}; struct B2 : virtual A2 { B2() {} virtual void f() {} } b2; -// CHECK: @"\01??_R4B2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" } -// CHECK: @"\01??_R0?AUB2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB2@@\00" } -// CHECK: @"\01??_R3B2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 4, %rtti.BaseClassDescriptor** getelementptr inbounds ([5 x %rtti.BaseClassDescriptor*]* @"\01??_R2B2@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2B2@@8" = linkonce_odr constant [5 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@Z2@@8", %rtti.BaseClassDescriptor* @"\01??_R13A@3EA@Y2@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@B2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), i32 3, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" } -// CHECK: @"\01??_R1A@A@3FA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" } -// CHECK: @"\01??_R0?AUA2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA2@@\00" } -// CHECK: @"\01??_R3A2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 1, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*]* @"\01??_R2A2@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2A2@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@Y2@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" } -// CHECK: @"\01??_R1A@?0A@EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" } -// CHECK: @"\01??_R0?AUZ2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUZ2@@\00" } -// CHECK: @"\01??_R3Z2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Z2@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2Z2@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R13?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" } -// CHECK: @"\01??_R0?AUY2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY2@@\00" } -// CHECK: @"\01??_R3Y2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y2@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2Y2@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y2@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" } -// CHECK: @"\01??_R1A@A@3EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" } -// CHECK: @"\01??_R13A@3EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" } -// CHECK: @"\01??_R4B2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 12, i32 8, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" } -// CHECK: @"\01??_R4A2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" } -// CHECK: @"\01??_R4A2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" } -// CHECK: @"\01??_R4Y2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" } -// CHECK: @"\01??_R4Z2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" } -// CHECK: @"\01??_R4B1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" } -// CHECK: @"\01??_R0?AUB1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB1@@\00" } -// CHECK: @"\01??_R3B1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2B1@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2B1@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A1@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@B1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" } -// CHECK: @"\01??_R1A@A@3FA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" } -// CHECK: @"\01??_R0?AUA1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA1@@\00" } -// CHECK: @"\01??_R3A1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2A1@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2A1@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A1@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" } -// CHECK: @"\01??_R4A1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" } -// CHECK: @"\01??_R4Y1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" } -// CHECK: @"\01??_R0?AUY1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY1@@\00" } -// CHECK: @"\01??_R3Y1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 6, %rtti.BaseClassDescriptor** getelementptr inbounds ([7 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y1@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2Y1@@8" = linkonce_odr constant [7 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@Y1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i8*), i32 5, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" } -// CHECK: @"\01??_R1A@?0A@EA@W1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" } -// CHECK: @"\01??_R0?AUW1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUW1@@\00" } -// CHECK: @"\01??_R3W1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*]* @"\01??_R2W1@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2W1@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@A@3FA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" } -// CHECK: @"\01??_R0?AUV1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUV1@@\00" } -// CHECK: @"\01??_R3V1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2V1@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2V1@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" } -// CHECK: @"\01??_R1A@?0A@EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" } -// CHECK: @"\01??_R0?AUX1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUX1@@\00" } -// CHECK: @"\01??_R3X1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2X1@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2X1@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@A@3EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" } -// CHECK: @"\01??_R4W1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" } -// CHECK: @"\01??_R4V1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" } -// CHECK: @"\01??_R4X1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" } -// CHECK: @"\01??_R4C@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" } -// CHECK: @"\01??_R0?AUC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" } -// CHECK: @"\01??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*]* @"\01??_R2C@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2C@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@C@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@B@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@A@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@C@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" } -// CHECK: @"\01??_R13?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" } -// CHECK: @"\01??_R0?AUB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" } -// CHECK: @"\01??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2B@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2B@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" } -// CHECK: @"\01??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" } -// CHECK: @"\01??_R0?AUA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" } -// CHECK: @"\01??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2A@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2A@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R13?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" } -// CHECK: @"\01??_R4Y@@6BZ@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" } -// CHECK: @"\01??_R0?AVY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVY@@\00" } -// CHECK: @"\01??_R3Y@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 9, %rtti.BaseClassDescriptor** getelementptr inbounds ([10 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2Y@@8" = linkonce_odr constant [10 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@Z@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@W@@8", %rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@M@@8", %rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@N@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33EJ@X@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33EJ@X@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@Y@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), i32 8, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" } -// CHECK: @"\01??_R1A@?0A@EN@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" } -// CHECK: @"\01??_R0?AVZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVZ@@\00" } -// CHECK: @"\01??_R3Z@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Z@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2Z@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" } -// CHECK: @"\01??_R13?0A@EN@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), i32 4, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" } -// CHECK: @"\01??_R0?AVW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVW@@\00" } -// CHECK: @"\01??_R3W@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 5, %rtti.BaseClassDescriptor** getelementptr inbounds ([6 x %rtti.BaseClassDescriptor*]* @"\01??_R2W@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2W@@8" = linkonce_odr constant [6 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@M@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@N@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EJ@X@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), i32 4, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" } -// CHECK: @"\01??_R13?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" } -// CHECK: @"\01??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" } -// CHECK: @"\01??_R3M@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2M@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2M@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@M@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@N@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" } -// CHECK: @"\01??_R1A@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" } -// CHECK: @"\01??_R0?AUN@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUN@@\00" } -// CHECK: @"\01??_R3N@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2N@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2N@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@N@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" } -// CHECK: @"\01??_R13?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" } -// CHECK: @"\01??_R1A@A@3FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 93, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" } -// CHECK: @"\01??_R0?AVV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVV@@\00" } -// CHECK: @"\01??_R3V@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*]* @"\01??_R2V@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2V@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@?0A@EA@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" } -// CHECK: @"\01??_R1A@?0A@EA@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" } -// CHECK: @"\01??_R0?AUX@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUX@@\00" } -// CHECK: @"\01??_R3X@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*]* @"\01??_R2X@@8", i32 0, i32 0) } -// CHECK: @"\01??_R2X@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8", %rtti.BaseClassDescriptor* null] -// CHECK: @"\01??_R1A@A@3EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 73, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" } -// CHECK: @"\01??_R17?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 8, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" } -// CHECK: @"\01??_R17?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 8, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" } -// CHECK: @"\01??_R1A@33FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 4, i32 4, i32 93, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" } -// CHECK: @"\01??_R1A@33EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 4, i32 4, i32 73, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" } -// CHECK: @"\01??_R4Y@@6BW@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" } -// CHECK: @"\01??_R4W@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" } -// CHECK: @"\01??_R4Z@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" } -// CHECK: @"\01??_R4V@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" } -// CHECK: @"\01??_R4X@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" } +// CHECK-DAG: @"\01??_R4B2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUB2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB2@@\00" }, comdat +// CHECK-DAG: @"\01??_R3B2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 4, %rtti.BaseClassDescriptor** getelementptr inbounds ([5 x %rtti.BaseClassDescriptor*], [5 x %rtti.BaseClassDescriptor*]* @"\01??_R2B2@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2B2@@8" = linkonce_odr constant [5 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@Z2@@8", %rtti.BaseClassDescriptor* @"\01??_R13A@3EA@Y2@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@B2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), i32 3, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@A@3FA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUA2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA2@@\00" }, comdat +// CHECK-DAG: @"\01??_R3A2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 1, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*], [4 x %rtti.BaseClassDescriptor*]* @"\01??_R2A2@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2A2@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A2@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@Y2@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUZ2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUZ2@@\00" }, comdat +// CHECK-DAG: @"\01??_R3Z2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Z2@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2Z2@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R13?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUY2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY2@@\00" }, comdat +// CHECK-DAG: @"\01??_R3Y2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y2@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2Y2@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y2@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@A@3EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" }, comdat +// CHECK-DAG: @"\01??_R13A@3EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), i32 0, i32 4, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }, comdat +// CHECK-DAG: @"\01??_R4B2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 12, i32 8, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" }, comdat +// CHECK-DAG: @"\01??_R4A2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }, comdat +// CHECK-DAG: @"\01??_R4A2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" }, comdat +// CHECK-DAG: @"\01??_R4Y2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" }, comdat +// CHECK-DAG: @"\01??_R4Z2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" }, comdat +// CHECK-DAG: @"\01??_R4B1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 4, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUB1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB1@@\00" }, comdat +// CHECK-DAG: @"\01??_R3B1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*], [3 x %rtti.BaseClassDescriptor*]* @"\01??_R2B1@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2B1@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A1@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@B1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@A@3FA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUA1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA1@@\00" }, comdat +// CHECK-DAG: @"\01??_R3A1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"\01??_R2A1@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2A1@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A1@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" }, comdat +// CHECK-DAG: @"\01??_R4A1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" }, comdat +// CHECK-DAG: @"\01??_R4Y1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUY1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY1@@\00" }, comdat +// CHECK-DAG: @"\01??_R3Y1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 6, %rtti.BaseClassDescriptor** getelementptr inbounds ([7 x %rtti.BaseClassDescriptor*], [7 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y1@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2Y1@@8" = linkonce_odr constant [7 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@Y1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i8*), i32 5, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@W1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUW1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUW1@@\00" }, comdat +// CHECK-DAG: @"\01??_R3W1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*], [4 x %rtti.BaseClassDescriptor*]* @"\01??_R2W1@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2W1@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@A@3FA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 80, %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUV1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUV1@@\00" }, comdat +// CHECK-DAG: @"\01??_R3V1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*], [3 x %rtti.BaseClassDescriptor*]* @"\01??_R2V1@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2V1@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V1@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUX1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUX1@@\00" }, comdat +// CHECK-DAG: @"\01??_R3X1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"\01??_R2X1@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2X1@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@A@3EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" }, comdat +// CHECK-DAG: @"\01??_R4W1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" }, comdat +// CHECK-DAG: @"\01??_R4V1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" }, comdat +// CHECK-DAG: @"\01??_R4X1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" }, comdat +// CHECK-DAG: @"\01??_R4C@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" }, comdat +// CHECK-DAG: @"\01??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, %rtti.BaseClassDescriptor** getelementptr inbounds ([4 x %rtti.BaseClassDescriptor*], [4 x %rtti.BaseClassDescriptor*]* @"\01??_R2C@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2C@@8" = linkonce_odr constant [4 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@C@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@B@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EA@A@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@C@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i8*), i32 2, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" }, comdat +// CHECK-DAG: @"\01??_R13?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" }, comdat +// CHECK-DAG: @"\01??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*], [3 x %rtti.BaseClassDescriptor*]* @"\01??_R2B@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2B@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" }, comdat +// CHECK-DAG: @"\01??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"\01??_R2A@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2A@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R13?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" }, comdat +// CHECK-DAG: @"\01??_R4Y@@6BZ@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AVY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVY@@\00" }, comdat +// CHECK-DAG: @"\01??_R3Y@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 9, %rtti.BaseClassDescriptor** getelementptr inbounds ([10 x %rtti.BaseClassDescriptor*], [10 x %rtti.BaseClassDescriptor*]* @"\01??_R2Y@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2Y@@8" = linkonce_odr constant [10 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@Z@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@W@@8", %rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@M@@8", %rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@N@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33EJ@X@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@33EJ@X@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@Y@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), i32 8, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@?0A@EN@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AVZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVZ@@\00" }, comdat +// CHECK-DAG: @"\01??_R3Z@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"\01??_R2Z@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2Z@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" }, comdat +// CHECK-DAG: @"\01??_R13?0A@EN@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), i32 4, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AVW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVW@@\00" }, comdat +// CHECK-DAG: @"\01??_R3W@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 5, %rtti.BaseClassDescriptor** getelementptr inbounds ([6 x %rtti.BaseClassDescriptor*], [6 x %rtti.BaseClassDescriptor*]* @"\01??_R2W@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2W@@8" = linkonce_odr constant [6 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@M@@8", %rtti.BaseClassDescriptor* @"\01??_R13?0A@EN@N@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3FN@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@A@3EJ@X@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), i32 4, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" }, comdat +// CHECK-DAG: @"\01??_R13?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }, comdat +// CHECK-DAG: @"\01??_R3M@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*], [3 x %rtti.BaseClassDescriptor*]* @"\01??_R2M@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2M@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@M@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@N@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUN@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUN@@\00" }, comdat +// CHECK-DAG: @"\01??_R3N@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"\01??_R2N@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2N@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@N@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }, comdat +// CHECK-DAG: @"\01??_R13?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 4, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@A@3FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 0, i32 4, i32 93, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AVV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVV@@\00" }, comdat +// CHECK-DAG: @"\01??_R3V@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, %rtti.BaseClassDescriptor** getelementptr inbounds ([3 x %rtti.BaseClassDescriptor*], [3 x %rtti.BaseClassDescriptor*]* @"\01??_R2V@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2V@@8" = linkonce_odr constant [3 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V@@8", %rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@?0A@EA@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 -1, i32 0, i32 64, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }, comdat +// CHECK-DAG: @"\01??_R0?AUX@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUX@@\00" }, comdat +// CHECK-DAG: @"\01??_R3X@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, %rtti.BaseClassDescriptor** getelementptr inbounds ([2 x %rtti.BaseClassDescriptor*], [2 x %rtti.BaseClassDescriptor*]* @"\01??_R2X@@8", i32 0, i32 0) }, comdat +// CHECK-DAG: @"\01??_R2X@@8" = linkonce_odr constant [2 x %rtti.BaseClassDescriptor*] [%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8", %rtti.BaseClassDescriptor* null], comdat +// CHECK-DAG: @"\01??_R1A@A@3EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 0, i32 4, i32 73, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }, comdat +// CHECK-DAG: @"\01??_R17?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 1, i32 8, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" }, comdat +// CHECK-DAG: @"\01??_R17?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i8*), i32 0, i32 8, i32 -1, i32 0, i32 77, %rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@33FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), i32 1, i32 0, i32 4, i32 4, i32 93, %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }, comdat +// CHECK-DAG: @"\01??_R1A@33EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), i32 0, i32 0, i32 4, i32 4, i32 73, %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }, comdat +// CHECK-DAG: @"\01??_R4Y@@6BW@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 8, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" }, comdat +// CHECK-DAG: @"\01??_R4W@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 4, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" }, comdat +// CHECK-DAG: @"\01??_R4Z@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" }, comdat +// CHECK-DAG: @"\01??_R4V@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" }, comdat +// CHECK-DAG: @"\01??_R4X@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 0, i32 0, i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i8*), %rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" }, comdat -// X64: @"\01??_R4B2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B2@@6BZ2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUB2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB2@@\00" } -// X64: @"\01??_R3B2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([5 x i32]* @"\01??_R2B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2B2@@8" = linkonce_odr constant [5 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17A@3EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@B2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 3, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@A@3FA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUA2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA2@@\00" } -// X64: @"\01??_R3A2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 1, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2A2@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@?0A@EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUZ2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUZ2@@\00" } -// X64: @"\01??_R3Z2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2Z2@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R17?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUY2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY2@@\00" } -// X64: @"\01??_R3Y2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2Y2@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@A@3EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R17A@3EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4B2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 24, i32 12, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B2@@6BY2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4A2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A2@@6BZ2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4A2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A2@@6BY2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4Y2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y2@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4Z2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Z2@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4B1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUB1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB1@@\00" } -// X64: @"\01??_R3B1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2B1@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@B1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@A@3FA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUA1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA1@@\00" } -// X64: @"\01??_R3A1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2A1@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4A1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4Y1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUY1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY1@@\00" } -// X64: @"\01??_R3Y1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 6, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([7 x i32]* @"\01??_R2Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2Y1@@8" = linkonce_odr constant [7 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@Y1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 5, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@?0A@EA@W1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUW1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUW1@@\00" } -// X64: @"\01??_R3W1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2W1@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@A@3FA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUV1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUV1@@\00" } -// X64: @"\01??_R3V1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2V1@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@?0A@EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUX1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUX1@@\00" } -// X64: @"\01??_R3X1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2X1@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@A@3EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4W1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4W1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4V1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4V1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4X1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4X1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4C@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4C@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" } -// X64: @"\01??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2C@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@C@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R17?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" } -// X64: @"\01??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2B@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" } -// X64: @"\01??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2A@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R17?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4Y@@6BZ@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y@@6BZ@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AVY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVY@@\00" } -// X64: @"\01??_R3Y@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 9, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([10 x i32]* @"\01??_R2Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2Y@@8" = linkonce_odr constant [10 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1BA@?0A@EN@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1BA@?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@Y@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 8, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@?0A@EN@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AVZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVZ@@\00" } -// X64: @"\01??_R3Z@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2Z@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R17?0A@EN@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 4, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AVW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVW@@\00" } -// X64: @"\01??_R3W@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 5, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([6 x i32]* @"\01??_R2W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2W@@8" = linkonce_odr constant [6 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 4, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R17?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" } -// X64: @"\01??_R3M@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2M@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUN@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUN@@\00" } -// X64: @"\01??_R3N@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2N@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R17?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@A@3FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 0, i32 4, i32 93, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AVV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVV@@\00" } -// X64: @"\01??_R3V@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2V@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@?0A@EA@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@?0A@EA@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R0?AUX@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUX@@\00" } -// X64: @"\01??_R3X@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R2X@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0] -// X64: @"\01??_R1A@A@3EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 73, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1BA@?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 16, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1BA@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 16, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@73FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 8, i32 4, i32 93, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R1A@73EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 8, i32 4, i32 73, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4Y@@6BW@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y@@6BW@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4W@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4W@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4Z@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Z@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4V@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4V@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } -// X64: @"\01??_R4X@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4X@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) } +// X64-DAG: @"\01??_R4B2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B2@@6BZ2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUB2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB2@@\00" }, comdat +// X64-DAG: @"\01??_R3B2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([5 x i32]* @"\01??_R2B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2B2@@8" = linkonce_odr constant [5 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17A@3EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@B2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 3, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@A@3FA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUA2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA2@@\00" }, comdat +// X64-DAG: @"\01??_R3A2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 1, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2A2@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@A2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@?0A@EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUZ2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUZ2@@\00" }, comdat +// X64-DAG: @"\01??_R3Z2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2Z2@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R17?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUY2@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY2@@\00" }, comdat +// X64-DAG: @"\01??_R3Y2@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2Y2@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@A@3EA@Z2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R17A@3EA@Y2@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4B2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 24, i32 12, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B2@@6BY2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4A2@@6BZ2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A2@@6BZ2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4A2@@6BY2@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A2@@6BY2@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4Y2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y2@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4Z2@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUZ2@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z2@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Z2@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4B1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 4, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4B1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUB1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUB1@@\00" }, comdat +// X64-DAG: @"\01??_R3B1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2B1@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@B1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUB1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@A@3FA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUA1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUA1@@\00" }, comdat +// X64-DAG: @"\01??_R3A1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2A1@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@A1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4A1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUA1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4A1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4Y1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUY1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUY1@@\00" }, comdat +// X64-DAG: @"\01??_R3Y1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 6, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([7 x i32]* @"\01??_R2Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2Y1@@8" = linkonce_odr constant [7 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@Y1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUY1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 5, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@?0A@EA@W1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUW1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUW1@@\00" }, comdat +// X64-DAG: @"\01??_R3W1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2W1@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@A@3FA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 0, i32 4, i32 80, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUV1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUV1@@\00" }, comdat +// X64-DAG: @"\01??_R3V1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2V1@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@V1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@?0A@EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUX1@@@8" = linkonce_odr global %rtti.TypeDescriptor8 { i8** @"\01??_7type_info@@6B@", i8* null, [9 x i8] c".?AUX1@@\00" }, comdat +// X64-DAG: @"\01??_R3X1@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2X1@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@A@3EA@X1@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4W1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUW1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4W1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4V1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUV1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4V1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4X1@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor8* @"\01??_R0?AUX1@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X1@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4X1@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4C@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4C@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUC@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUC@@\00" }, comdat +// X64-DAG: @"\01??_R3C@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 3, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([4 x i32]* @"\01??_R2C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2C@@8" = linkonce_odr constant [4 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@C@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUC@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 2, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3C@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R17?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUB@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUB@@\00" }, comdat +// X64-DAG: @"\01??_R3B@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2B@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@B@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUB@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3B@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUA@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUA@@\00" }, comdat +// X64-DAG: @"\01??_R3A@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2A@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R17?0A@EA@A@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUA@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3A@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4Y@@6BZ@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y@@6BZ@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AVY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVY@@\00" }, comdat +// X64-DAG: @"\01??_R3Y@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 9, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([10 x i32]* @"\01??_R2Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2Y@@8" = linkonce_odr constant [10 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1BA@?0A@EN@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1BA@?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@73EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@Y@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 8, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@?0A@EN@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AVZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVZ@@\00" }, comdat +// X64-DAG: @"\01??_R3Z@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2Z@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@Z@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R17?0A@EN@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 4, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AVW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVW@@\00" }, comdat +// X64-DAG: @"\01??_R3W@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 3, i32 5, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([6 x i32]* @"\01??_R2W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2W@@8" = linkonce_odr constant [6 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R17?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3FN@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@A@3EJ@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@W@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 4, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R17?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }, comdat +// X64-DAG: @"\01??_R3M@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2M@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EN@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUN@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUN@@\00" }, comdat +// X64-DAG: @"\01??_R3N@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2N@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R17?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 8, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@A@3FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 0, i32 4, i32 93, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AVV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AVV@@\00" }, comdat +// X64-DAG: @"\01??_R3V@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 2, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([3 x i32]* @"\01??_R2V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2V@@8" = linkonce_odr constant [3 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@?0A@EA@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@?0A@EA@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 -1, i32 0, i32 64, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R0?AUX@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUX@@\00" }, comdat +// X64-DAG: @"\01??_R3X@@8" = linkonce_odr constant %rtti.ClassHierarchyDescriptor { i32 0, i32 0, i32 1, i32 trunc (i64 sub nuw nsw (i64 ptrtoint ([2 x i32]* @"\01??_R2X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R2X@@8" = linkonce_odr constant [2 x i32] [i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.BaseClassDescriptor* @"\01??_R1A@?0A@EA@X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0], comdat +// X64-DAG: @"\01??_R1A@A@3EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 0, i32 4, i32 73, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1BA@?0A@EN@M@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 16, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3M@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1BA@?0A@EN@N@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUN@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 16, i32 -1, i32 0, i32 77, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3N@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@73FN@V@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 1, i32 0, i32 8, i32 4, i32 93, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R1A@73EJ@X@@8" = linkonce_odr constant %rtti.BaseClassDescriptor { i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 0, i32 0, i32 8, i32 4, i32 73, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4Y@@6BW@@@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 16, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVY@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Y@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Y@@6BW@@@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4W@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 8, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVW@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3W@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4W@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4Z@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVZ@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3Z@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4Z@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4V@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AVV@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3V@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4V@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat +// X64-DAG: @"\01??_R4X@@6B@" = linkonce_odr constant %rtti.CompleteObjectLocator { i32 1, i32 0, i32 0, i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.TypeDescriptor7* @"\01??_R0?AUX@@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.ClassHierarchyDescriptor* @"\01??_R3X@@8" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32), i32 trunc (i64 sub nuw nsw (i64 ptrtoint (%rtti.CompleteObjectLocator* @"\01??_R4X@@6B@" to i64), i64 ptrtoint (i8* @__ImageBase to i64)) to i32) }, comdat diff --git a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp index 96c23c6..4c2d850 100644 --- a/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp +++ b/test/CodeGenCXX/microsoft-abi-sret-and-byval.cpp @@ -101,12 +101,12 @@ Big big_return() { return Big(); } void small_arg(Small s) {} -// LINUX-LABEL: define void @_Z9small_arg5Small(%struct.Small* byval align 4 %s) +// LINUX-LABEL: define void @_Z9small_arg5Small(i32 %s.0) // WIN32: define void @"\01?small_arg@@YAXUSmall@@@Z"(%struct.Small* byval align 4 %s) // WIN64: define void @"\01?small_arg@@YAXUSmall@@@Z"(i32 %s.coerce) void medium_arg(Medium s) {} -// LINUX-LABEL: define void @_Z10medium_arg6Medium(%struct.Medium* byval align 4 %s) +// LINUX-LABEL: define void @_Z10medium_arg6Medium(i32 %s.0, i32 %s.1) // WIN32: define void @"\01?medium_arg@@YAXUMedium@@@Z"(%struct.Medium* byval align 4 %s) // WIN64: define void @"\01?medium_arg@@YAXUMedium@@@Z"(i64 %s.coerce) @@ -229,7 +229,7 @@ class Class { // WIN64: define linkonce_odr void @"\01?thiscall_method_arg@Class@@QEAAXUEmptyWithCtor@@@Z"(%class.Class* %this, i8 %s.coerce) void thiscall_method_arg(Small s) {} - // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Small(%class.Class* %this, %struct.Small* byval align 4 %s) + // LINUX: define {{.*}} void @_ZN5Class19thiscall_method_argE5Small(%class.Class* %this, i32 %s.0) // WIN32: define {{.*}} void @"\01?thiscall_method_arg@Class@@QAEXUSmall@@@Z"(%class.Class* %this, %struct.Small* byval align 4 %s) // WIN64: define linkonce_odr void @"\01?thiscall_method_arg@Class@@QEAAXUSmall@@@Z"(%class.Class* %this, i32 %s.coerce) @@ -296,9 +296,9 @@ void bar() { } // WIN32-LABEL: define void @"\01?bar@test2@@YAXXZ"() {{.*}} { // WIN32: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty:<{ %"struct.test2::NonTrivial", %"struct.test2::POD" }>]] -// WIN32: getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 1 +// WIN32: getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1 // WIN32: call void @llvm.memcpy -// WIN32: getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 0 +// WIN32: getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0 // WIN32: call x86_thiscallcc %"struct.test2::NonTrivial"* @"\01??0NonTrivial@test2@@QAE@XZ" // WIN32: call i32 @"\01?foo@test2@@YAHUNonTrivial@1@UPOD@1@@Z"([[argmem_ty]]* inalloca %argmem) // WIN32: ret void @@ -332,14 +332,14 @@ struct ForwardDeclare1 {}; void fn2(FnPtr1 a, SmallWithDtor b) { fn1(a, b); }; // WIN32-LABEL: define void @"\01?fn2@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z" -// WIN32: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty:<{ {}\*, %struct.SmallWithDtor }>]]* %{{.*}}, i32 0, i32 0 +// WIN32: %[[a:[^ ]*]] = getelementptr inbounds [[argmem_ty:<{ {}\*, %struct.SmallWithDtor }>]], [[argmem_ty:<{ {}\*, %struct.SmallWithDtor }>]]* %{{.*}}, i32 0, i32 0 // WIN32: %[[a1:[^ ]*]] = bitcast {}** %[[a]] to void [[dst_ty:\(%struct.ForwardDeclare1\*\)\*]]* // WIN32: %[[argmem:[^ ]*]] = alloca inalloca [[argmem_ty]] -// WIN32: %[[gep1:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 1 +// WIN32: %[[gep1:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 1 // WIN32: %[[bc1:[^ ]*]] = bitcast %struct.SmallWithDtor* %[[gep1]] to i8* // WIN32: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %[[bc1]], i8* {{.*}}, i32 4, i32 4, i1 false) -// WIN32: %[[a2:[^ ]*]] = load void [[dst_ty]]* %[[a1]], align 4 -// WIN32: %[[gep2:[^ ]*]] = getelementptr inbounds [[argmem_ty]]* %[[argmem]], i32 0, i32 0 +// WIN32: %[[a2:[^ ]*]] = load void [[dst_ty]], void [[dst_ty]]* %[[a1]], align 4 +// WIN32: %[[gep2:[^ ]*]] = getelementptr inbounds [[argmem_ty]], [[argmem_ty]]* %[[argmem]], i32 0, i32 0 // WIN32: %[[addr:[^ ]*]] = bitcast {}** %[[gep2]] to void [[dst_ty]]* // WIN32: store void [[dst_ty]] %[[a2]], void [[dst_ty]]* %[[addr]], align 4 // WIN32: call void @"\01?fn1@@YAXP6AXUForwardDeclare1@@@ZUSmallWithDtor@@@Z"([[argmem_ty]]* inalloca %[[argmem]]) diff --git a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp index 76d7e9e..57a72d4 100644 --- a/test/CodeGenCXX/microsoft-abi-static-initializers.cpp +++ b/test/CodeGenCXX/microsoft-abi-static-initializers.cpp @@ -1,9 +1,9 @@ -// RUN: %clang_cc1 -fms-extensions -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s +// RUN: %clang_cc1 -fms-extensions -fno-threadsafe-statics -emit-llvm %s -o - -mconstructor-aliases -triple=i386-pc-win32 | FileCheck %s // CHECK: @llvm.global_ctors = appending global [5 x { i32, void ()*, i8* }] [ -// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Eselectany1@@YAXXZ", i8* getelementptr inbounds (%struct.S* @"\01?selectany1@@3US@@A", i32 0, i32 0) }, -// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Eselectany2@@YAXXZ", i8* getelementptr inbounds (%struct.S* @"\01?selectany2@@3US@@A", i32 0, i32 0) }, -// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Es@?$ExportedTemplate@H@@2US@@A@YAXXZ", i8* getelementptr inbounds (%struct.S* @"\01?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0) }, +// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Eselectany1@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"\01?selectany1@@3US@@A", i32 0, i32 0) }, +// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Eselectany2@@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"\01?selectany2@@3US@@A", i32 0, i32 0) }, +// CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Es@?$ExportedTemplate@H@@2US@@A@YAXXZ", i8* getelementptr inbounds (%struct.S, %struct.S* @"\01?s@?$ExportedTemplate@H@@2US@@A", i32 0, i32 0) }, // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ", i8* bitcast (%class.A* @"\01?foo@?$B@H@@2VA@@A" to i8*) }, // CHECK: { i32, void ()*, i8* } { i32 65535, void ()* @_GLOBAL__sub_I_microsoft_abi_static_initializers.cpp, i8* null } // CHECK: ] @@ -28,11 +28,11 @@ S s; // See @llvm.global_ctors above. __declspec(selectany) S selectany1; __declspec(selectany) S selectany2; -// CHECK: define linkonce_odr void @"\01??__Eselectany1@@YAXXZ"() +// CHECK: define linkonce_odr void @"\01??__Eselectany1@@YAXXZ"() {{.*}} comdat // CHECK-NOT: @"\01??_Bselectany1 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ" // CHECK: ret void -// CHECK: define linkonce_odr void @"\01??__Eselectany2@@YAXXZ"() +// CHECK: define linkonce_odr void @"\01??__Eselectany2@@YAXXZ"() {{.*}} comdat // CHECK-NOT: @"\01??_Bselectany2 // CHECK: call x86_thiscallcc %struct.S* @"\01??0S@@QAE@XZ" // CHECK: ret void @@ -52,7 +52,7 @@ void StaticLocal() { } // CHECK-LABEL: define void @"\01?StaticLocal@@YAXXZ"() -// CHECK: load i32* @"\01?$S1@?1??StaticLocal@@YAXXZ@4IA" +// CHECK: load i32, i32* @"\01?$S1@?1??StaticLocal@@YAXXZ@4IA" // CHECK: store i32 {{.*}}, i32* @"\01?$S1@?1??StaticLocal@@YAXXZ@4IA" // CHECK: ret @@ -94,7 +94,7 @@ void MultipleStatics() { static S S35; } // CHECK-LABEL: define void @"\01?MultipleStatics@@YAXXZ"() -// CHECK: load i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ@4IA" +// CHECK: load i32, i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ@4IA" // CHECK: and i32 {{.*}}, 1 // CHECK: and i32 {{.*}}, 2 // CHECK: and i32 {{.*}}, 4 @@ -102,7 +102,7 @@ void MultipleStatics() { // CHECK: and i32 {{.*}}, 16 // ... // CHECK: and i32 {{.*}}, -2147483648 -// CHECK: load i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ@4IA1" +// CHECK: load i32, i32* @"\01?$S1@?1??MultipleStatics@@YAXXZ@4IA.1" // CHECK: and i32 {{.*}}, 1 // CHECK: and i32 {{.*}}, 2 // CHECK: and i32 {{.*}}, 4 @@ -133,7 +133,7 @@ inline S &UnreachableStatic() { return s; } -// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?UnreachableStatic@@YAAAUS@@XZ"() +// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?UnreachableStatic@@YAAAUS@@XZ"() {{.*}} comdat // CHECK: and i32 {{.*}}, 2 // CHECK: or i32 {{.*}}, 2 // CHECK: ret @@ -143,8 +143,8 @@ inline S &getS() { return TheS; } -// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?getS@@YAAAUS@@XZ" -// CHECK: load i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51" +// CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.S* @"\01?getS@@YAAAUS@@XZ"() {{.*}} comdat +// CHECK: load i32, i32* @"\01??_B?1??getS@@YAAAUS@@XZ@51" // CHECK: and i32 {{.*}}, 1 // CHECK: icmp ne i32 {{.*}}, 0 // CHECK: br i1 @@ -158,7 +158,7 @@ inline S &getS() { // CHECK: ret %struct.S* @"\01?TheS@?1??getS@@YAAAUS@@XZ@4U2@A" inline int enum_in_function() { - // CHECK-LABEL: define linkonce_odr i32 @"\01?enum_in_function@@YAHXZ"() + // CHECK-LABEL: define linkonce_odr i32 @"\01?enum_in_function@@YAHXZ"() {{.*}} comdat static enum e { foo, bar, baz } x; // CHECK: @"\01?x@?1??enum_in_function@@YAHXZ@4W4e@?1??1@YAHXZ@A" static int y; @@ -169,7 +169,7 @@ inline int enum_in_function() { struct T { enum e { foo, bar, baz }; int enum_in_struct() { - // CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @"\01?enum_in_struct@T@@QAEHXZ" + // CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @"\01?enum_in_struct@T@@QAEHXZ"({{.*}}) {{.*}} comdat static int x; // CHECK: @"\01?x@?1??enum_in_struct@T@@QAEHXZ@4HA" return x++; @@ -177,7 +177,7 @@ struct T { }; inline int switch_test(int x) { - // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test@@YAHH@Z"(i32 %x) + // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test@@YAHH@Z"(i32 %x) {{.*}} comdat switch (x) { static int a; // CHECK: @"\01?a@?3??switch_test@@YAHH@Z@4HA" @@ -198,7 +198,7 @@ inline int switch_test(int x) { int f(); inline void switch_test2() { - // CHECK-LABEL: define linkonce_odr void @"\01?switch_test2@@YAXXZ"() + // CHECK-LABEL: define linkonce_odr void @"\01?switch_test2@@YAXXZ"() {{.*}} comdat // CHECK: @"\01?x@?2??switch_test2@@YAXXZ@4HA" switch (1) default: static int x = f(); } @@ -213,7 +213,7 @@ namespace DynamicDLLImportInitVSMangling { template struct __declspec(dllimport) A<int>; inline int switch_test3() { - // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ" + // CHECK-LABEL: define linkonce_odr i32 @"\01?switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ"() {{.*}} comdat static int local; // CHECK: @"\01?local@?1??switch_test3@DynamicDLLImportInitVSMangling@@YAHXZ@4HA" return local++; @@ -231,16 +231,16 @@ void force_usage() { DynamicDLLImportInitVSMangling::switch_test3(); } -// CHECK: define linkonce_odr void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"() +// CHECK: define linkonce_odr void @"\01??__Efoo@?$B@H@@2VA@@A@YAXXZ"() {{.*}} comdat // CHECK-NOT: and // CHECK-NOT: ?_Bfoo@ // CHECK: call x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ" // CHECK: call i32 @atexit(void ()* @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ") // CHECK: ret void -// CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ" +// CHECK: define linkonce_odr x86_thiscallcc %class.A* @"\01??0A@@QAE@XZ"({{.*}}) {{.*}} comdat -// CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ" +// CHECK: define linkonce_odr x86_thiscallcc void @"\01??1A@@QAE@XZ"({{.*}}) {{.*}} comdat // CHECK: define internal void @"\01??__Ffoo@?$B@H@@2VA@@A@YAXXZ" // CHECK: call x86_thiscallcc void @"\01??1A@@QAE@XZ"{{.*}}foo diff --git a/test/CodeGenCXX/microsoft-abi-structors.cpp b/test/CodeGenCXX/microsoft-abi-structors.cpp index 01d72e0..594dea4 100644 --- a/test/CodeGenCXX/microsoft-abi-structors.cpp +++ b/test/CodeGenCXX/microsoft-abi-structors.cpp @@ -19,10 +19,10 @@ class A { void no_constructor_destructor_infinite_recursion() { A a; -// CHECK: define linkonce_odr x86_thiscallcc %"class.basic::A"* @"\01??0A@basic@@QAE@XZ"(%"class.basic::A"* returned %this) +// CHECK: define linkonce_odr x86_thiscallcc %"class.basic::A"* @"\01??0A@basic@@QAE@XZ"(%"class.basic::A"* returned %this) {{.*}} comdat {{.*}} { // CHECK: [[THIS_ADDR:%[.0-9A-Z_a-z]+]] = alloca %"class.basic::A"*, align 4 // CHECK-NEXT: store %"class.basic::A"* %this, %"class.basic::A"** [[THIS_ADDR]], align 4 -// CHECK-NEXT: [[T1:%[.0-9A-Z_a-z]+]] = load %"class.basic::A"** [[THIS_ADDR]] +// CHECK-NEXT: [[T1:%[.0-9A-Z_a-z]+]] = load %"class.basic::A"*, %"class.basic::A"** [[THIS_ADDR]] // CHECK-NEXT: ret %"class.basic::A"* [[T1]] // CHECK-NEXT: } } @@ -46,10 +46,10 @@ B::B() { struct C { virtual ~C() { -// DTORS: define linkonce_odr x86_thiscallcc i8* @"\01??_GC@basic@@UAEPAXI@Z"(%"struct.basic::C"* %this, i32 %should_call_delete) +// DTORS: define linkonce_odr x86_thiscallcc i8* @"\01??_GC@basic@@UAEPAXI@Z"(%"struct.basic::C"* %this, i32 %should_call_delete) {{.*}} comdat {{.*}} { // DTORS: store i32 %should_call_delete, i32* %[[SHOULD_DELETE_VAR:[0-9a-z._]+]], align 4 // DTORS: store i8* %{{.*}}, i8** %[[RETVAL:[0-9a-z._]+]] -// DTORS: %[[SHOULD_DELETE_VALUE:[0-9a-z._]+]] = load i32* %[[SHOULD_DELETE_VAR]] +// DTORS: %[[SHOULD_DELETE_VALUE:[0-9a-z._]+]] = load i32, i32* %[[SHOULD_DELETE_VAR]] // DTORS: call x86_thiscallcc void @"\01??1C@basic@@UAE@XZ"(%"struct.basic::C"* %[[THIS:[0-9a-z]+]]) // DTORS-NEXT: %[[CONDITION:[0-9]+]] = icmp eq i32 %[[SHOULD_DELETE_VALUE]], 0 // DTORS-NEXT: br i1 %[[CONDITION]], label %[[CONTINUE_LABEL:[0-9a-z._]+]], label %[[CALL_DELETE_LABEL:[0-9a-z._]+]] @@ -60,7 +60,7 @@ struct C { // DTORS-NEXT: br label %[[CONTINUE_LABEL]] // // DTORS: [[CONTINUE_LABEL]] -// DTORS-NEXT: %[[RET:.*]] = load i8** %[[RETVAL]] +// DTORS-NEXT: %[[RET:.*]] = load i8*, i8** %[[RETVAL]] // DTORS-NEXT: ret i8* %[[RET]] // Check that we do the mangling correctly on x64. @@ -82,11 +82,11 @@ void check_vftable_offset() { void call_complete_dtor(C *obj_ptr) { // CHECK: define void @"\01?call_complete_dtor@basic@@YAXPAUC@1@@Z"(%"struct.basic::C"* %obj_ptr) obj_ptr->~C(); -// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"** %{{.*}}, align 4 +// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"*, %"struct.basic::C"** %{{.*}}, align 4 // CHECK-NEXT: %[[PVTABLE:.*]] = bitcast %"struct.basic::C"* %[[OBJ_PTR_VALUE]] to i8* (%"struct.basic::C"*, i32)*** -// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]] -// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0 -// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]] +// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)**, i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]] +// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0 +// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]] // CHECK-NEXT: call x86_thiscallcc i8* %[[VDTOR]](%"struct.basic::C"* %[[OBJ_PTR_VALUE]], i32 0) // CHECK-NEXT: ret void } @@ -94,14 +94,14 @@ void call_complete_dtor(C *obj_ptr) { void call_deleting_dtor(C *obj_ptr) { // CHECK: define void @"\01?call_deleting_dtor@basic@@YAXPAUC@1@@Z"(%"struct.basic::C"* %obj_ptr) delete obj_ptr; -// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"** %{{.*}}, align 4 +// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"*, %"struct.basic::C"** %{{.*}}, align 4 // CHECK: br i1 {{.*}}, label %[[DELETE_NULL:.*]], label %[[DELETE_NOTNULL:.*]] // CHECK: [[DELETE_NOTNULL]] // CHECK-NEXT: %[[PVTABLE:.*]] = bitcast %"struct.basic::C"* %[[OBJ_PTR_VALUE]] to i8* (%"struct.basic::C"*, i32)*** -// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]] -// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0 -// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]] +// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)**, i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]] +// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0 +// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]] // CHECK-NEXT: call x86_thiscallcc i8* %[[VDTOR]](%"struct.basic::C"* %[[OBJ_PTR_VALUE]], i32 1) // CHECK: ret void } @@ -109,14 +109,14 @@ void call_deleting_dtor(C *obj_ptr) { void call_deleting_dtor_and_global_delete(C *obj_ptr) { // CHECK: define void @"\01?call_deleting_dtor_and_global_delete@basic@@YAXPAUC@1@@Z"(%"struct.basic::C"* %obj_ptr) ::delete obj_ptr; -// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"** %{{.*}}, align 4 +// CHECK: %[[OBJ_PTR_VALUE:.*]] = load %"struct.basic::C"*, %"struct.basic::C"** %{{.*}}, align 4 // CHECK: br i1 {{.*}}, label %[[DELETE_NULL:.*]], label %[[DELETE_NOTNULL:.*]] // CHECK: [[DELETE_NOTNULL]] // CHECK-NEXT: %[[PVTABLE:.*]] = bitcast %"struct.basic::C"* %[[OBJ_PTR_VALUE]] to i8* (%"struct.basic::C"*, i32)*** -// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]] -// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0 -// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]] +// CHECK-NEXT: %[[VTABLE:.*]] = load i8* (%"struct.basic::C"*, i32)**, i8* (%"struct.basic::C"*, i32)*** %[[PVTABLE]] +// CHECK-NEXT: %[[PVDTOR:.*]] = getelementptr inbounds i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[VTABLE]], i64 0 +// CHECK-NEXT: %[[VDTOR:.*]] = load i8* (%"struct.basic::C"*, i32)*, i8* (%"struct.basic::C"*, i32)** %[[PVDTOR]] // CHECK-NEXT: %[[CALL:.*]] = call x86_thiscallcc i8* %[[VDTOR]](%"struct.basic::C"* %[[OBJ_PTR_VALUE]], i32 0) // CHECK-NEXT: call void @"\01??3@YAXPAX@Z"(i8* %[[CALL]]) // CHECK: ret void @@ -158,10 +158,10 @@ C::~C() { // CHECK: (%"struct.dtor_in_second_nvbase::C"* %this) // No this adjustment! // CHECK-NOT: getelementptr -// CHECK: load %"struct.dtor_in_second_nvbase::C"** %{{.*}} +// CHECK: load %"struct.dtor_in_second_nvbase::C"*, %"struct.dtor_in_second_nvbase::C"** %{{.*}} // Now we this-adjust before calling ~B. // CHECK: bitcast %"struct.dtor_in_second_nvbase::C"* %{{.*}} to i8* -// CHECK: getelementptr inbounds i8* %{{.*}}, i64 4 +// CHECK: getelementptr inbounds i8, i8* %{{.*}}, i64 4 // CHECK: bitcast i8* %{{.*}} to %"struct.dtor_in_second_nvbase::B"* // CHECK: call x86_thiscallcc void @"\01??1B@dtor_in_second_nvbase@@UAE@XZ" // CHECK: (%"struct.dtor_in_second_nvbase::B"* %{{.*}}) @@ -174,7 +174,7 @@ void foo() { // DTORS2-LABEL: define linkonce_odr x86_thiscallcc i8* @"\01??_EC@dtor_in_second_nvbase@@W3AEPAXI@Z" // DTORS2: (%"struct.dtor_in_second_nvbase::C"* %this, i32 %should_call_delete) // Do an adjustment from B* to C*. -// DTORS2: getelementptr i8* %{{.*}}, i32 -4 +// DTORS2: getelementptr i8, i8* %{{.*}}, i32 -4 // DTORS2: bitcast i8* %{{.*}} to %"struct.dtor_in_second_nvbase::C"* // DTORS2: %[[CALL:.*]] = call x86_thiscallcc i8* @"\01??_GC@dtor_in_second_nvbase@@UAEPAXI@Z" // DTORS2: ret i8* %[[CALL]] @@ -198,7 +198,7 @@ F::~F() { // CHECK-LABEL: define x86_thiscallcc void @"\01??1F@test2@@UAE@XZ"(%"struct.test2::F"*) // Do an adjustment from C vbase subobject to F as though F was the // complete type. -// CHECK: getelementptr inbounds i8* %{{.*}}, i32 -20 +// CHECK: getelementptr inbounds i8, i8* %{{.*}}, i32 -20 // CHECK: bitcast i8* %{{.*}} to %"struct.test2::F"* // CHECK: store %"struct.test2::F"* } @@ -206,9 +206,9 @@ F::~F() { void foo() { F f; } -// DTORS3-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DF@test2@@UAE@XZ" +// DTORS3-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DF@test2@@UAE@XZ"({{.*}} {{.*}} comdat // Do an adjustment from C* to F*. -// DTORS3: getelementptr i8* %{{.*}}, i32 20 +// DTORS3: getelementptr i8, i8* %{{.*}}, i32 20 // DTORS3: bitcast i8* %{{.*}} to %"struct.test2::F"* // DTORS3: call x86_thiscallcc void @"\01??1F@test2@@UAE@XZ" // DTORS3: ret void @@ -240,17 +240,17 @@ C::C() { // CHECK: define x86_thiscallcc %"struct.constructors::C"* @"\01??0C@constructors@@QAE@XZ"(%"struct.constructors::C"* returned %this, i32 %is_most_derived) // TODO: make sure this works in the Release build too; // CHECK: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4 - // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32* %[[IS_MOST_DERIVED_VAR]] + // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]] // CHECK: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0 // CHECK: br i1 %[[SHOULD_CALL_VBASE_CTORS]], label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]] // // CHECK: [[INIT_VBASES]] // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::C"* %{{.*}} to i8* - // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8* %[[this_i8]], i64 0 + // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i64 0 // CHECK-NEXT: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32** - // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32]* @"\01??_8C@constructors@@7B@", i32 0, i32 0), i32** %[[vbptr]] + // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"\01??_8C@constructors@@7B@", i32 0, i32 0), i32** %[[vbptr]] // CHECK-NEXT: bitcast %"struct.constructors::C"* %{{.*}} to i8* - // CHECK-NEXT: getelementptr inbounds i8* %{{.*}}, i64 4 + // CHECK-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i64 4 // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"* // CHECK-NEXT: call x86_thiscallcc %"struct.constructors::A"* @"\01??0A@constructors@@QAE@XZ"(%"struct.constructors::A"* %{{.*}}) // CHECK-NEXT: br label %[[SKIP_VBASES]] @@ -275,17 +275,17 @@ struct D : C { D::D() { // CHECK: define x86_thiscallcc %"struct.constructors::D"* @"\01??0D@constructors@@QAE@XZ"(%"struct.constructors::D"* returned %this, i32 %is_most_derived) unnamed_addr // CHECK: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4 - // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32* %[[IS_MOST_DERIVED_VAR]] + // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]] // CHECK: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0 // CHECK: br i1 %[[SHOULD_CALL_VBASE_CTORS]], label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]] // // CHECK: [[INIT_VBASES]] // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::D"* %{{.*}} to i8* - // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8* %[[this_i8]], i64 0 + // CHECK-NEXT: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i64 0 // CHECK-NEXT: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32** - // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32]* @"\01??_8D@constructors@@7B@", i32 0, i32 0), i32** %[[vbptr]] + // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"\01??_8D@constructors@@7B@", i32 0, i32 0), i32** %[[vbptr]] // CHECK-NEXT: bitcast %"struct.constructors::D"* %{{.*}} to i8* - // CHECK-NEXT: getelementptr inbounds i8* %{{.*}}, i64 4 + // CHECK-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i64 4 // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"* // CHECK-NEXT: call x86_thiscallcc %"struct.constructors::A"* @"\01??0A@constructors@@QAE@XZ"(%"struct.constructors::A"* %{{.*}}) // CHECK-NEXT: br label %[[SKIP_VBASES]] @@ -302,20 +302,20 @@ struct E : virtual C { E::E() { // CHECK: define x86_thiscallcc %"struct.constructors::E"* @"\01??0E@constructors@@QAE@XZ"(%"struct.constructors::E"* returned %this, i32 %is_most_derived) unnamed_addr // CHECK: store i32 %is_most_derived, i32* %[[IS_MOST_DERIVED_VAR:.*]], align 4 - // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32* %[[IS_MOST_DERIVED_VAR]] + // CHECK: %[[IS_MOST_DERIVED_VAL:.*]] = load i32, i32* %[[IS_MOST_DERIVED_VAR]] // CHECK: %[[SHOULD_CALL_VBASE_CTORS:.*]] = icmp ne i32 %[[IS_MOST_DERIVED_VAL]], 0 // CHECK: br i1 %[[SHOULD_CALL_VBASE_CTORS]], label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]] // // CHECK: [[INIT_VBASES]] // CHECK-NEXT: %[[this_i8:.*]] = bitcast %"struct.constructors::E"* %{{.*}} to i8* - // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8* %[[this_i8]], i64 0 + // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i64 0 // CHECK-NEXT: %[[vbptr_E:.*]] = bitcast i8* %[[offs]] to i32** - // CHECK-NEXT: store i32* getelementptr inbounds ([3 x i32]* @"\01??_8E@constructors@@7B01@@", i32 0, i32 0), i32** %[[vbptr_E]] - // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8* %[[this_i8]], i64 4 + // CHECK-NEXT: store i32* getelementptr inbounds ([3 x i32], [3 x i32]* @"\01??_8E@constructors@@7B01@@", i32 0, i32 0), i32** %[[vbptr_E]] + // CHECK-NEXT: %[[offs:.*]] = getelementptr inbounds i8, i8* %[[this_i8]], i64 4 // CHECK-NEXT: %[[vbptr_C:.*]] = bitcast i8* %[[offs]] to i32** - // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32]* @"\01??_8E@constructors@@7BC@1@@", i32 0, i32 0), i32** %[[vbptr_C]] + // CHECK-NEXT: store i32* getelementptr inbounds ([2 x i32], [2 x i32]* @"\01??_8E@constructors@@7BC@1@@", i32 0, i32 0), i32** %[[vbptr_C]] // CHECK-NEXT: bitcast %"struct.constructors::E"* %{{.*}} to i8* - // CHECK-NEXT: getelementptr inbounds i8* %{{.*}}, i64 4 + // CHECK-NEXT: getelementptr inbounds i8, i8* %{{.*}}, i64 4 // CHECK-NEXT: bitcast i8* %{{.*}} to %"struct.constructors::A"* // CHECK-NEXT: call x86_thiscallcc %"struct.constructors::A"* @"\01??0A@constructors@@QAE@XZ"(%"struct.constructors::A"* %{{.*}}) // CHECK: call x86_thiscallcc %"struct.constructors::C"* @"\01??0C@constructors@@QAE@XZ"(%"struct.constructors::C"* %{{.*}}, i32 0) @@ -365,7 +365,7 @@ void call_vbase_complete(D *d) { } // The complete dtor should call the base dtors for D and the vbase A (once). -// CHECK: define linkonce_odr x86_thiscallcc void @"\01??_DD@dtors@@QAE@XZ" +// CHECK: define linkonce_odr x86_thiscallcc void @"\01??_DD@dtors@@QAE@XZ"({{.*}}) {{.*}} comdat // CHECK-NOT: call // CHECK: call x86_thiscallcc void @"\01??1D@dtors@@QAE@XZ" // CHECK-NOT: call @@ -420,7 +420,7 @@ void construct_b() { // CHECK-LABEL: define void @"\01?construct_b@test1@@YAXXZ"() // CHECK: call x86_thiscallcc %"struct.test1::B"* @"\01??0B@test1@@QAE@PAH@Z" // CHECK: (%"struct.test1::B"* {{.*}}, i32* {{.*}}, i32 1) -// CHECK: call %"struct.test1::B"* (%"struct.test1::B"*, i32, i8*, ...)* @"\01??0B@test1@@QAA@PBDZZ" +// CHECK: call %"struct.test1::B"* (%"struct.test1::B"*, i32, i8*, ...) @"\01??0B@test1@@QAA@PBDZZ" // CHECK: (%"struct.test1::B"* {{.*}}, i32 1, i8* {{.*}}, i32 1, i32 2) } diff --git a/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp b/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp new file mode 100644 index 0000000..5f6849d --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-thread-safe-statics.cpp @@ -0,0 +1,93 @@ +// RUN: %clang_cc1 -fexceptions -fcxx-exceptions -fms-extensions -fms-compatibility -fms-compatibility-version=19 -std=c++11 -emit-llvm %s -o - -triple=i386-pc-win32 | FileCheck %s +// REQUIRES: asserts + +struct S { + S(); + ~S(); +}; + +// CHECK-DAG: @"\01?s@?1??f@@YAAAUS@@XZ@4U2@A" = linkonce_odr thread_local global %struct.S zeroinitializer +// CHECK-DAG: @"\01??__J?1??f@@YAAAUS@@XZ@51" = linkonce_odr thread_local global i32 0 +// CHECK-DAG: @"\01?s@?1??g@@YAAAUS@@XZ@4U2@A" = linkonce_odr global %struct.S zeroinitializer +// CHECK-DAG: @"\01?$TSS0@?1??g@@YAAAUS@@XZ" = linkonce_odr global i32 0 +// CHECK-DAG: @_Init_thread_epoch = external thread_local global i32, align 4 +// CHECK-DAG: @"\01?j@?1??h@@YAAAUS@@_N@Z@4U2@A" = linkonce_odr thread_local global %struct.S zeroinitializer +// CHECK-DAG: @"\01??__J?1??h@@YAAAUS@@_N@Z@51" = linkonce_odr thread_local global i32 0 +// CHECK-DAG: @"\01?i@?1??h@@YAAAUS@@_N@Z@4U2@A" = linkonce_odr global %struct.S zeroinitializer +// CHECK-DAG: @"\01?$TSS0@?1??h@@YAAAUS@@_N@Z" = linkonce_odr global i32 0 + +// CHECK-LABEL: define {{.*}} @"\01?f@@YAAAUS@@XZ"() +extern inline S &f() { + static thread_local S s; +// CHECK: %[[guard:.*]] = load i32, i32* @"\01??__J?1??f@@YAAAUS@@XZ@51" +// CHECK-NEXT: %[[mask:.*]] = and i32 %[[guard]], 1 +// CHECK-NEXT: %[[cmp:.*]] = icmp ne i32 %[[mask]], 0 +// CHECK-NEXT: br i1 %[[cmp]], label %[[init_end:.*]], label %[[init:.*]] +// +// CHECK: [[init]]: +// CHECK-NEXT: %[[or:.*]] = or i32 %[[guard]], 1 +// CHECK-NEXT: store i32 %[[or]], i32* @"\01??__J?1??f@@YAAAUS@@XZ@51" +// CHECK-NEXT: invoke {{.*}} @"\01??0S@@QAE@XZ"(%struct.S* @"\01?s@?1??f@@YAAAUS@@XZ@4U2@A") +// CHECK-NEXT: to label %[[invoke_cont:.*]] unwind label %[[lpad:.*]] +// +// CHECK: [[invoke_cont]]: +// CHECK-NEXT: call i32 @__tlregdtor(void ()* @"\01??__Fs@?1??f@@YAAAUS@@XZ@YAXXZ") +// CHECK-NEXT: br label %[[init_end:.*]] + +// CHECK: [[init_end]]: +// CHECK-NEXT: ret %struct.S* @"\01?s@?1??f@@YAAAUS@@XZ@4U2@A" + +// CHECK: [[lpad:.*]]: +// CHECK-NEXT: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__CxxFrameHandler3 to i8*) +// CHECK-NEXT: cleanup +// CHECK: %[[guard:.*]] = load i32, i32* @"\01??__J?1??f@@YAAAUS@@XZ@51" +// CHECK-NEXT: %[[mask:.*]] = and i32 %[[guard]], -2 +// CHECK-NEXT: store i32 %[[mask]], i32* @"\01??__J?1??f@@YAAAUS@@XZ@51" +// CHECK-NEXT: br label %[[eh_resume:.*]] +// +// CHECK: [[eh_resume]]: +// CHECK: resume { i8*, i32 } + return s; +} + + +// CHECK-LABEL: define {{.*}} @"\01?g@@YAAAUS@@XZ"() +extern inline S &g() { + static S s; +// CHECK: %[[guard:.*]] = load atomic i32, i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ" unordered, align 4 +// CHECK-NEXT: %[[epoch:.*]] = load i32, i32* @_Init_thread_epoch +// CHECK-NEXT: %[[cmp:.*]] = icmp sgt i32 %[[guard]], %[[epoch]] +// CHECK-NEXT: br i1 %[[cmp]], label %[[init_attempt:.*]], label %[[init_end:.*]] +// +// CHECK: [[init_attempt]]: +// CHECK-NEXT: call void @_Init_thread_header(i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ") +// CHECK-NEXT: %[[guard2:.*]] = load atomic i32, i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ" unordered, align 4 +// CHECK-NEXT: %[[cmp2:.*]] = icmp eq i32 %[[guard2]], -1 +// CHECK-NEXT: br i1 %[[cmp2]], label %[[init:.*]], label %[[init_end:.*]] +// +// CHECK: [[init]]: +// CHECK-NEXT: invoke {{.*}} @"\01??0S@@QAE@XZ"(%struct.S* @"\01?s@?1??g@@YAAAUS@@XZ@4U2@A") +// CHECK-NEXT: to label %[[invoke_cont:.*]] unwind label %[[lpad:.*]] +// +// CHECK: [[invoke_cont]]: +// CHECK-NEXT: call i32 @atexit(void ()* @"\01??__Fs@?1??g@@YAAAUS@@XZ@YAXXZ") +// CHECK-NEXT: call void @_Init_thread_footer(i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ") +// CHECK-NEXT: br label %init.end +// +// CHECK: [[init_end]]: +// CHECK-NEXT: ret %struct.S* @"\01?s@?1??g@@YAAAUS@@XZ@4U2@A" +// +// CHECK: [[lpad]]: +// CHECK: call void @_Init_thread_abort(i32* @"\01?$TSS0@?1??g@@YAAAUS@@XZ") +// CHECK-NEXT: br label %[[eh_resume:.*]] +// +// CHECK: [[eh_resume]]: +// CHECK: resume { i8*, i32 } + return s; +} + +extern inline S&h(bool b) { + static thread_local S j; + static S i; + return b ? j : i; +} diff --git a/test/CodeGenCXX/microsoft-abi-throw.cpp b/test/CodeGenCXX/microsoft-abi-throw.cpp new file mode 100644 index 0000000..080f1a0 --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-throw.cpp @@ -0,0 +1,115 @@ +// RUN: %clang_cc1 -emit-llvm -o - -triple=i386-pc-win32 -std=c++11 %s -fcxx-exceptions -fms-extensions | FileCheck %s + +// CHECK-DAG: @"\01??_R0?AUY@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUY@@\00" }, comdat +// CHECK-DAG: @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUY@@@8" to i8*), i32 0, i32 -1, i32 0, i32 8, i8* bitcast (%struct.Y* (%struct.Y*, %struct.Y*, i32)* @"\01??0Y@@QAE@ABU0@@Z" to i8*) }, section ".xdata", comdat +// CHECK-DAG: @"\01??_R0?AUZ@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUZ@@\00" }, comdat +// CHECK-DAG: @"_CT??_R0?AUZ@@@81" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUZ@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* null }, section ".xdata", comdat +// CHECK-DAG: @"\01??_R0?AUW@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUW@@\00" }, comdat +// CHECK-DAG: @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 4, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUW@@@8" to i8*), i32 4, i32 -1, i32 0, i32 4, i8* bitcast (%struct.W* (%struct.W*, %struct.W*, i32)* @"\01??0W@@QAE@ABU0@@Z" to i8*) }, section ".xdata", comdat +// CHECK-DAG: @"\01??_R0?AUM@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUM@@\00" }, comdat +// CHECK-DAG: @"_CT??_R0?AUM@@@818" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUM@@@8" to i8*), i32 8, i32 -1, i32 0, i32 1, i8* null }, section ".xdata", comdat +// CHECK-DAG: @"\01??_R0?AUV@@@8" = linkonce_odr global %rtti.TypeDescriptor7 { i8** @"\01??_7type_info@@6B@", i8* null, [8 x i8] c".?AUV@@\00" }, comdat +// CHECK-DAG: @"_CT??_R0?AUV@@@81044" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0?AUV@@@8" to i8*), i32 0, i32 4, i32 4, i32 1, i8* null }, section ".xdata", comdat +// CHECK-DAG: @"_CTA5?AUY@@" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.5 { i32 5, [5 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0?AUY@@@8??0Y@@QAE@ABU0@@Z8", %eh.CatchableType* @"_CT??_R0?AUZ@@@81", %eh.CatchableType* @"_CT??_R0?AUW@@@8??0W@@QAE@ABU0@@Z44", %eh.CatchableType* @"_CT??_R0?AUM@@@818", %eh.CatchableType* @"_CT??_R0?AUV@@@81044"] }, section ".xdata", comdat +// CHECK-DAG: @"_TI5?AUY@@" = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* bitcast (void (%struct.Y*)* @"\01??_DY@@QAE@XZ" to i8*), i8* null, i8* bitcast (%eh.CatchableTypeArray.5* @"_CTA5?AUY@@" to i8*) }, section ".xdata", comdat +// CHECK-DAG: @"_CT??_R0?AUDefault@@@8??_ODefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor13* @"\01??_R0?AUDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Default*, %struct.Default*)* @"\01??_ODefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat +// CHECK-DAG: @"_CT??_R0?AUVariadic@@@8??_OVariadic@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor14* @"\01??_R0?AUVariadic@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.Variadic*, %struct.Variadic*)* @"\01??_OVariadic@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat +// CHECK-DAG: @"_CT??_R0?AUTemplateWithDefault@@@8??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z1" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 0, i8* bitcast (%rtti.TypeDescriptor25* @"\01??_R0?AUTemplateWithDefault@@@8" to i8*), i32 0, i32 -1, i32 0, i32 1, i8* bitcast (void (%struct.TemplateWithDefault*, %struct.TemplateWithDefault*)* @"\01??$?_OH@TemplateWithDefault@@QAEXAAU0@@Z" to i8*) }, section ".xdata", comdat +// CHECK-DAG: @"_CTA2$$T" = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.2 { i32 2, [2 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0$$T@84", %eh.CatchableType* @"_CT??_R0PAX@84"] }, section ".xdata", comdat +// CHECK-DAG: @"_CT??_R0P6AXXZ@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i8* bitcast (%rtti.TypeDescriptor7* @"\01??_R0P6AXXZ@8" to i8*), i32 0, i32 -1, i32 0, i32 4, i8* null }, section ".xdata", comdat +// CHECK-DAG: @_CTA1P6AXXZ = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0P6AXXZ@84"] }, section ".xdata", comdat +// CHECK-DAG: @_TI1P6AXXZ = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1P6AXXZ to i8*) }, section ".xdata", comdat + + +struct N { ~N(); }; +struct M : private N {}; +struct X {}; +struct Z {}; +struct V : private X {}; +struct W : M, virtual V {}; +struct Y : Z, W, virtual V {}; + +void f(const Y &y) { + // CHECK-LABEL: @"\01?f@@YAXABUY@@@Z" + // CHECK: call x86_thiscallcc %struct.Y* @"\01??0Y@@QAE@ABU0@@Z"(%struct.Y* %[[mem:.*]], %struct.Y* + // CHECK: %[[cast:.*]] = bitcast %struct.Y* %[[mem]] to i8* + // CHECK: call void @_CxxThrowException(i8* %[[cast]], %eh.ThrowInfo* @"_TI5?AUY@@") + throw y; +} + +void g(const int *const *y) { + // CHECK-LABEL: @"\01?g@@YAXPBQBH@Z" + // CHECK: call void @_CxxThrowException(i8* %{{.*}}, %eh.ThrowInfo* @_TIC2PAPBH) + throw y; +} + +struct Default { + Default(Default &, int = 42); +}; + +// CHECK-LABEL: @"\01??_ODefault@@QAEXAAU0@@Z" +// CHECK: %[[src_addr:.*]] = alloca +// CHECK: %[[this_addr:.*]] = alloca +// CHECK: store {{.*}} %src, {{.*}} %[[src_addr]], align 4 +// CHECK: store {{.*}} %this, {{.*}} %[[this_addr]], align 4 +// CHECK: %[[this:.*]] = load {{.*}} %[[this_addr]] +// CHECK: %[[src:.*]] = load {{.*}} %[[src_addr]] +// CHECK: call x86_thiscallcc {{.*}} @"\01??0Default@@QAE@AAU0@H@Z"({{.*}} %[[this]], {{.*}} %[[src]], i32 42) +// CHECK: ret void + +void h(Default &d) { + throw d; +} + +struct Variadic { + Variadic(Variadic &, ...); +}; + +void i(Variadic &v) { + throw v; +} + +// CHECK-LABEL: @"\01??_OVariadic@@QAEXAAU0@@Z" +// CHECK: %[[src_addr:.*]] = alloca +// CHECK: %[[this_addr:.*]] = alloca +// CHECK: store {{.*}} %src, {{.*}} %[[src_addr:.*]], align +// CHECK: store {{.*}} %this, {{.*}} %[[this_addr:.*]], align +// CHECK: %[[this:.*]] = load {{.*}} %[[this_addr]] +// CHECK: %[[src:.*]] = load {{.*}} %[[src_addr]] +// CHECK: call {{.*}} @"\01??0Variadic@@QAA@AAU0@ZZ"({{.*}} %[[this]], {{.*}} %[[src]]) +// CHECK: ret void + +struct TemplateWithDefault { + template <typename T> + static int f() { + return 0; + } + template <typename T = int> + TemplateWithDefault(TemplateWithDefault &, T = f<T>()); +}; + +void j(TemplateWithDefault &twd) { + throw twd; +} + + +void h() { + throw nullptr; +} + +namespace std { +template <typename T> +void *__GetExceptionInfo(T); +} + +void *GetExceptionInfo_test0() { +// CHECK-LABEL: @"\01?GetExceptionInfo_test0@@YAPAXXZ" +// CHECK: ret i8* bitcast (%eh.ThrowInfo* @_TI1H to i8*) + return std::__GetExceptionInfo(0); +} + +void *GetExceptionInfo_test1() { +// CHECK-LABEL: @"\01?GetExceptionInfo_test1@@YAPAXXZ" +// CHECK: ret i8* bitcast (%eh.ThrowInfo* @_TI1P6AXXZ to i8*) + return std::__GetExceptionInfo<void (*)()>(&h); +} diff --git a/test/CodeGenCXX/microsoft-abi-thunks.cpp b/test/CodeGenCXX/microsoft-abi-thunks.cpp index 843bc89..8cbea5c 100644 --- a/test/CodeGenCXX/microsoft-abi-thunks.cpp +++ b/test/CodeGenCXX/microsoft-abi-thunks.cpp @@ -31,12 +31,12 @@ struct C : A, B { C(); virtual ~C(); - // MANGLING-DAG: @"\01??1C@@UAE@XZ" - // MANGLING-DAG: @"\01??_GC@@UAEPAXI@Z" - // MANGLING-DAG: @"\01??_EC@@W3AEPAXI@Z" - // MANGLING-X64-DAG: @"\01??1C@@UEAA@XZ" - // MANGLING-X64-DAG: @"\01??_GC@@UEAAPEAXI@Z" - // MANGLING-X64-DAG: @"\01??_EC@@W7EAAPEAXI@Z" + // MANGLING-DAG: declare {{.*}} @"\01??1C@@UAE@XZ"({{.*}}) + // MANGLING-DAG: define {{.*}} @"\01??_GC@@UAEPAXI@Z"({{.*}}) + // MANGLING-DAG: define {{.*}} @"\01??_EC@@W3AEPAXI@Z"({{.*}}) {{.*}} comdat + // MANGLING-X64-DAG: declare {{.*}} @"\01??1C@@UEAA@XZ"({{.*}}) + // MANGLING-X64-DAG: define {{.*}} @"\01??_GC@@UEAAPEAXI@Z"({{.*}}) + // MANGLING-X64-DAG: define {{.*}} @"\01??_EC@@W7EAAPEAXI@Z"({{.*}}) {{.*}} comdat // Overrides public_f() of two subobjects with distinct vfptrs, thus needs a thunk. virtual void public_f(); @@ -61,14 +61,14 @@ struct C : A, B { C::C() {} // Emits vftable and forces thunk generation. -// CODEGEN-LABEL: define linkonce_odr x86_thiscallcc i8* @"\01??_EC@@W3AEPAXI@Z"(%struct.C* %this, i32 %should_call_delete) -// CODEGEN: getelementptr i8* {{.*}}, i32 -4 +// CODEGEN-LABEL: define linkonce_odr x86_thiscallcc i8* @"\01??_EC@@W3AEPAXI@Z"(%struct.C* %this, i32 %should_call_delete) {{.*}} comdat +// CODEGEN: getelementptr i8, i8* {{.*}}, i32 -4 // FIXME: should actually call _EC, not _GC. // CODEGEN: call x86_thiscallcc i8* @"\01??_GC@@UAEPAXI@Z" // CODEGEN: ret // CODEGEN-LABEL: define linkonce_odr x86_thiscallcc void @"\01?public_f@C@@W3AEXXZ"(%struct.C* -// CODEGEN: getelementptr i8* {{.*}}, i32 -4 +// CODEGEN: getelementptr i8, i8* {{.*}}, i32 -4 // CODEGEN: call x86_thiscallcc void @"\01?public_f@C@@UAEXXZ"(%struct.C* // CODEGEN: ret @@ -93,7 +93,7 @@ E::E() {} // Emits vftable and forces thunk generation. // CODEGEN-LABEL: define weak_odr x86_thiscallcc %struct.C* @"\01?goo@E@@QAEPAUB@@XZ" // CODEGEN: call x86_thiscallcc %struct.C* @"\01?goo@E@@UAEPAUC@@XZ" -// CODEGEN: getelementptr inbounds i8* {{.*}}, i32 4 +// CODEGEN: getelementptr inbounds i8, i8* {{.*}}, i32 4 // CODEGEN: ret struct F : virtual A, virtual B { @@ -127,12 +127,12 @@ I::I() {} // Emits vftable and forces thunk generation. // CODEGEN-LABEL: define weak_odr x86_thiscallcc %struct.{{[BF]}}* @"\01?goo@I@@QAEPAUB@@XZ" // CODEGEN: %[[ORIG_RET:.*]] = call x86_thiscallcc %struct.F* @"\01?goo@I@@UAEPAUF@@XZ" // CODEGEN: %[[ORIG_RET_i8:.*]] = bitcast %struct.F* %[[ORIG_RET]] to i8* -// CODEGEN: %[[VBPTR_i8:.*]] = getelementptr inbounds i8* %[[ORIG_RET_i8]], i32 4 +// CODEGEN: %[[VBPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[ORIG_RET_i8]], i32 4 // CODEGEN: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i32** -// CODEGEN: %[[VBTABLE:.*]] = load i32** %[[VBPTR]] -// CODEGEN: %[[VBASE_OFFSET_PTR:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 2 -// CODEGEN: %[[VBASE_OFFSET:.*]] = load i32* %[[VBASE_OFFSET_PTR]] -// CODEGEN: %[[RES_i8:.*]] = getelementptr inbounds i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]] +// CODEGEN: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR]] +// CODEGEN: %[[VBASE_OFFSET_PTR:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 2 +// CODEGEN: %[[VBASE_OFFSET:.*]] = load i32, i32* %[[VBASE_OFFSET_PTR]] +// CODEGEN: %[[RES_i8:.*]] = getelementptr inbounds i8, i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]] // CODEGEN: %[[RES:.*]] = bitcast i8* %[[RES_i8]] to %struct.F* // CODEGEN: phi %struct.F* {{.*}} %[[RES]] // CODEGEN: ret %struct.{{[BF]}}* diff --git a/test/CodeGenCXX/microsoft-abi-try-throw.cpp b/test/CodeGenCXX/microsoft-abi-try-throw.cpp index 95c2cbd..fed3976 100644 --- a/test/CodeGenCXX/microsoft-abi-try-throw.cpp +++ b/test/CodeGenCXX/microsoft-abi-try-throw.cpp @@ -1,5 +1,12 @@ -// RUN: %clang_cc1 -emit-llvm-only %s -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -verify -DTRY -// RUN: %clang_cc1 -emit-llvm-only %s -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -verify -DTHROW +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -DTRY | FileCheck %s -check-prefix=TRY +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=i386-pc-win32 -mconstructor-aliases -fcxx-exceptions -fexceptions -fno-rtti -DTHROW | FileCheck %s -check-prefix=THROW + +// THROW-DAG: @"\01??_R0H@8" = linkonce_odr global %rtti.TypeDescriptor2 { i8** @"\01??_7type_info@@6B@", i8* null, [3 x i8] c".H\00" }, comdat +// THROW-DAG: @"_CT??_R0H@84" = linkonce_odr unnamed_addr constant %eh.CatchableType { i32 1, i8* bitcast (%rtti.TypeDescriptor2* @"\01??_R0H@8" to i8*), i32 0, i32 -1, i32 0, i32 4, i8* null }, section ".xdata", comdat +// THROW-DAG: @_CTA1H = linkonce_odr unnamed_addr constant %eh.CatchableTypeArray.1 { i32 1, [1 x %eh.CatchableType*] [%eh.CatchableType* @"_CT??_R0H@84"] }, section ".xdata", comdat +// THROW-DAG: @_TI1H = linkonce_odr unnamed_addr constant %eh.ThrowInfo { i32 0, i8* null, i8* null, i8* bitcast (%eh.CatchableTypeArray.1* @_CTA1H to i8*) }, section ".xdata", comdat + +// TRY-DAG: @llvm.eh.handlertype.PAH.1 = private unnamed_addr constant %eh.CatchHandlerType { i32 1, i8* bitcast (%rtti.TypeDescriptor4* @"\01??_R0PAH@8" to i8*) }, section "llvm.metadata" void external(); @@ -10,14 +17,31 @@ inline void not_emitted() { int main() { int rv = 0; #ifdef TRY - try { // expected-error {{cannot compile this try statement yet}} - external(); + try { + external(); // TRY: invoke void @"\01?external@@YAXXZ" } catch (int) { rv = 1; + // TRY: call void @llvm.eh.begincatch(i8* %{{.*}}, i8* null) + // TRY: call void @llvm.eh.endcatch() } #endif #ifdef THROW - throw int(42); // expected-error {{cannot compile this throw expression yet}} + // THROW: store i32 42, i32* %[[mem_for_throw:.*]] + // THROW: %[[cast:.*]] = bitcast i32* %[[mem_for_throw]] to i8* + // THROW: call void @_CxxThrowException(i8* %[[cast]], %eh.ThrowInfo* @_TI1H) + throw int(42); #endif return rv; } + +#ifdef TRY +// TRY-LABEL: define void @"\01?qual_catch@@YAXXZ" +void qual_catch() { + try { + external(); + } catch (const int *) { + } + // TRY: catch %eh.CatchHandlerType* @llvm.eh.handlertype.PAH.1 + // TRY: call i32 @llvm.eh.typeid.for(i8* bitcast (%eh.CatchHandlerType* @llvm.eh.handlertype.PAH.1 to i8*)) +} +#endif diff --git a/test/CodeGenCXX/microsoft-abi-typeid.cpp b/test/CodeGenCXX/microsoft-abi-typeid.cpp index 1beb211..60c31ab 100644 --- a/test/CodeGenCXX/microsoft-abi-typeid.cpp +++ b/test/CodeGenCXX/microsoft-abi-typeid.cpp @@ -31,11 +31,11 @@ const std::type_info* test3_typeid() { return &typeid(*fn()); } // CHECK: tail call i8* @__RTtypeid(i8* null) // CHECK-NEXT: unreachable // CHECK: [[THIS:%.*]] = bitcast %struct.A* [[CALL]] to i8* -// CHECK-NEXT: [[VBTBLP:%.*]] = getelementptr inbounds %struct.A* [[CALL]], i32 0, i32 0 -// CHECK-NEXT: [[VBTBL:%.*]] = load i32** [[VBTBLP]], align 4 -// CHECK-NEXT: [[VBSLOT:%.*]] = getelementptr inbounds i32* [[VBTBL]], i32 1 -// CHECK-NEXT: [[VBASE_OFFS:%.*]] = load i32* [[VBSLOT]], align 4 -// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8* [[THIS]], i32 [[VBASE_OFFS]] +// CHECK-NEXT: [[VBTBLP:%.*]] = getelementptr inbounds %struct.A, %struct.A* [[CALL]], i32 0, i32 0 +// CHECK-NEXT: [[VBTBL:%.*]] = load i32*, i32** [[VBTBLP]], align 4 +// CHECK-NEXT: [[VBSLOT:%.*]] = getelementptr inbounds i32, i32* [[VBTBL]], i32 1 +// CHECK-NEXT: [[VBASE_OFFS:%.*]] = load i32, i32* [[VBSLOT]], align 4 +// CHECK-NEXT: [[ADJ:%.*]] = getelementptr inbounds i8, i8* [[THIS]], i32 [[VBASE_OFFS]] // CHECK-NEXT: [[RT:%.*]] = tail call i8* @__RTtypeid(i8* [[ADJ]]) // CHECK-NEXT: [[RET:%.*]] = bitcast i8* [[RT]] to %struct.type_info* // CHECK-NEXT: ret %struct.type_info* [[RET]] diff --git a/test/CodeGenCXX/microsoft-abi-vbtables.cpp b/test/CodeGenCXX/microsoft-abi-vbtables.cpp index 8b86d6b..9cce6f8 100644 --- a/test/CodeGenCXX/microsoft-abi-vbtables.cpp +++ b/test/CodeGenCXX/microsoft-abi-vbtables.cpp @@ -528,3 +528,14 @@ D d; // CHECK-DAG: @"\01??_8D@Test29@@7BB@1@@" = linkonce_odr unnamed_addr constant [2 x i32] zeroinitializer } + +namespace Test30 { +struct A {}; +template <class> struct B : virtual A { + B() {} +}; + +extern template class B<int>; +template B<int>::B(); +// CHECK-DAG: @"\01??_8?$B@H@Test30@@7B@" = external unnamed_addr constant [2 x i32]{{$}} +} diff --git a/test/CodeGenCXX/microsoft-abi-vftables.cpp b/test/CodeGenCXX/microsoft-abi-vftables.cpp index 14bd6c3..1a48411 100644 --- a/test/CodeGenCXX/microsoft-abi-vftables.cpp +++ b/test/CodeGenCXX/microsoft-abi-vftables.cpp @@ -1,16 +1,15 @@ -// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=NO-RTTI -// RUN: %clang_cc1 %s -triple=i386-pc-win32 -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=RTTI +// RUN: %clang_cc1 %s -fno-rtti -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=NO-RTTI +// RUN: %clang_cc1 %s -triple=i386-pc-win32 -fms-extensions -emit-llvm -o - -O1 -disable-llvm-optzns | FileCheck %s -check-prefix=RTTI // RTTI-DAG: $"\01??_7S@@6B@" = comdat largest // RTTI-DAG: $"\01??_7V@@6B@" = comdat largest -// RTTI-DAG: $"\01??_7W@?A@@6B@" = comdat largest struct S { virtual ~S(); } s; // RTTI-DAG: [[VTABLE_S:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4S@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)], comdat($"\01??_7S@@6B@") -// RTTI-DAG: @"\01??_7S@@6B@" = unnamed_addr alias getelementptr inbounds ([2 x i8*]* [[VTABLE_S]], i32 0, i32 1) +// RTTI-DAG: @"\01??_7S@@6B@" = unnamed_addr alias getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_S]], i32 0, i32 1) // NO-RTTI-DAG: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)] @@ -27,7 +26,7 @@ struct __declspec(dllexport) V { } v; // RTTI-DAG: [[VTABLE_V:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4V@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GV@@UAEPAXI@Z" to i8*)], comdat($"\01??_7V@@6B@") -// RTTI-DAG: @"\01??_7V@@6B@" = dllexport unnamed_addr alias getelementptr inbounds ([2 x i8*]* [[VTABLE_V]], i32 0, i32 1) +// RTTI-DAG: @"\01??_7V@@6B@" = dllexport unnamed_addr alias getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_V]], i32 0, i32 1) // NO-RTTI-DAG: @"\01??_7V@@6B@" = weak_odr dllexport unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GV@@UAEPAXI@Z" to i8*)] @@ -36,7 +35,18 @@ struct W { virtual ~W(); } w; } -// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4W@?A@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)], comdat($"\01??_7W@?A@@6B@") -// RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr alias getelementptr inbounds ([2 x i8*]* @1, i32 0, i32 1) +// RTTI-DAG: [[VTABLE_W:@.*]] = private unnamed_addr constant [2 x i8*] [i8* bitcast ({{.*}} @"\01??_R4W@?A@@6B@" to i8*), i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)] +// RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr alias getelementptr inbounds ([2 x i8*], [2 x i8*]* [[VTABLE_W]], i32 0, i32 1) // NO-RTTI-DAG: @"\01??_7W@?A@@6B@" = internal unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GW@?A@@UAEPAXI@Z" to i8*)] + +struct X {}; +template <class> struct Y : virtual X { + Y() {} + virtual ~Y(); +}; + +extern template class Y<int>; +template Y<int>::Y(); +// RTTI-DAG: @"\01??_7?$Y@H@@6B@" = external unnamed_addr constant [1 x i8*] +// NO-RTTI-DAG: @"\01??_7?$Y@H@@6B@" = external unnamed_addr constant [1 x i8*] diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp index 26eb012..204da8d 100644 --- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp +++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance-vtordisps.cpp @@ -24,25 +24,25 @@ struct D : virtual C { D::D() {} // Forces vftable emission. // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPPPPPM@A@AEXXZ" -// CHECK: %[[ECX:.*]] = load %struct.D** %{{.*}} +// CHECK: %[[ECX:.*]] = load %struct.D*, %struct.D** %{{.*}} // CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8* -// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -4 +// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 -4 // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32* -// CHECK: %[[VTORDISP:.*]] = load i32* %[[VTORDISP_PTR]] +// CHECK: %[[VTORDISP:.*]] = load i32, i32* %[[VTORDISP_PTR]] // CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]] -// CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]] +// CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]] // CHECK: call x86_thiscallcc void @"\01?f@D@@UAEXXZ"(i8* %[[ADJUSTED_i8]]) // CHECK: ret void // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@D@@$4PPPPPPPI@3AEXXZ" -// CHECK: %[[ECX:.*]] = load %struct.D** %{{.*}} +// CHECK: %[[ECX:.*]] = load %struct.D*, %struct.D** %{{.*}} // CHECK: %[[ECX_i8:.*]] = bitcast %struct.D* %[[ECX]] to i8* -// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -8 +// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 -8 // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32* -// CHECK: %[[VTORDISP:.*]] = load i32* %[[VTORDISP_PTR]] +// CHECK: %[[VTORDISP:.*]] = load i32, i32* %[[VTORDISP_PTR]] // CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]] -// CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]] -// CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8* %[[VTORDISP_ADJUSTED_i8]], i32 -4 +// CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]] +// CHECK: %[[ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[VTORDISP_ADJUSTED_i8]], i32 -4 // CHECK: call x86_thiscallcc void @"\01?f@D@@UAEXXZ"(i8* %[[ADJUSTED_i8]]) // CHECK: ret void @@ -64,19 +64,19 @@ struct G : virtual F, virtual E { G::G() {} // Forces vftable emission. // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01?f@E@@$R4BA@M@PPPPPPPM@7AEXXZ"(i8*) -// CHECK: %[[ECX:.*]] = load %struct.E** %{{.*}} +// CHECK: %[[ECX:.*]] = load %struct.E*, %struct.E** %{{.*}} // CHECK: %[[ECX_i8:.*]] = bitcast %struct.E* %[[ECX]] to i8* -// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 -4 +// CHECK: %[[VTORDISP_PTR_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 -4 // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_PTR_i8]] to i32* -// CHECK: %[[VTORDISP:.*]] = load i32* %[[VTORDISP_PTR]] +// CHECK: %[[VTORDISP:.*]] = load i32, i32* %[[VTORDISP_PTR]] // CHECK: %[[VTORDISP_NEG:.*]] = sub i32 0, %[[VTORDISP]] -// CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]] -// CHECK: %[[VBPTR_i8:.*]] = getelementptr inbounds i8* %[[VTORDISP_ADJUSTED_i8]], i32 -16 +// CHECK: %[[VTORDISP_ADJUSTED_i8:.*]] = getelementptr i8, i8* %[[ECX_i8]], i32 %[[VTORDISP_NEG]] +// CHECK: %[[VBPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[VTORDISP_ADJUSTED_i8]], i32 -16 // CHECK: %[[VBPTR:.*]] = bitcast i8* %[[VBPTR_i8]] to i32** -// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR]] -// CHECK: %[[VBOFFSET_PTR:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 3 -// CHECK: %[[VBASE_OFFSET:.*]] = load i32* %[[VBOFFSET_PTR]] -// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]] -// CHECK: %[[ARG_i8:.*]] = getelementptr i8* %[[VBASE]], i32 8 +// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR]] +// CHECK: %[[VBOFFSET_PTR:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 3 +// CHECK: %[[VBASE_OFFSET:.*]] = load i32, i32* %[[VBOFFSET_PTR]] +// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, i8* %[[VBPTR_i8]], i32 %[[VBASE_OFFSET]] +// CHECK: %[[ARG_i8:.*]] = getelementptr i8, i8* %[[VBASE]], i32 8 // CHECK: call x86_thiscallcc void @"\01?f@E@@UAEXXZ"(i8* %[[ARG_i8]]) // CHECK: ret void diff --git a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp index 7a00a73..b868d1f 100644 --- a/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp +++ b/test/CodeGenCXX/microsoft-abi-virtual-inheritance.cpp @@ -21,29 +21,29 @@ struct B : virtual VBase { B::B() { // CHECK-LABEL: define x86_thiscallcc %struct.B* @"\01??0B@@QAE@XZ" - // CHECK: %[[THIS:.*]] = load %struct.B** + // CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B** // CHECK: br i1 %{{.*}}, label %[[INIT_VBASES:.*]], label %[[SKIP_VBASES:.*]] // Don't check the INIT_VBASES case as it's covered by the ctor tests. // CHECK: %[[SKIP_VBASES]] // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* - // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 0 + // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0 // ... // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* - // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 %{{.*}} + // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}} // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)*** // CHECK: store i32 (...)** bitcast ([3 x i8*]* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]] // Initialize vtorDisp: // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* - // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 0 + // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0 // ... // CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}} // CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* - // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]] - // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8* %[[VBASE_i8]], i32 -4 + // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]] + // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, i8* %[[VBASE_i8]], i32 -4 // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32* // CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]] @@ -54,29 +54,29 @@ B::~B() { // CHECK-LABEL: define x86_thiscallcc void @"\01??1B@@UAE@XZ" // Adjust the this parameter: // CHECK: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8* - // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8* %[[THIS_PARAM_i8]], i32 -8 + // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8]], i32 -8 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B* // CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4 - // CHECK: %[[THIS:.*]] = load %struct.B** %[[THIS_ADDR]] + // CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]] // Restore the vfptr that could have been changed by a subclass. // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* - // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 0 + // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0 // ... // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* - // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 %{{.*}} + // CHECK: %[[VFPTR_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %{{.*}} // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VFPTR_i8]] to i32 (...)*** // CHECK: store i32 (...)** bitcast ([3 x i8*]* @"\01??_7B@@6B@" to i32 (...)**), i32 (...)*** %[[VFPTR]] // Initialize vtorDisp: // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* - // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 0 + // CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 0 // ... // CHECK: %[[VBASE_OFFSET:.*]] = add nsw i32 0, %{{.*}} // CHECK: %[[VTORDISP_VAL:.*]] = sub i32 %[[VBASE_OFFSET]], 8 // CHECK: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* - // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]] - // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8* %[[VBASE_i8]], i32 -4 + // CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i32 %[[VBASE_OFFSET]] + // CHECK: %[[VTORDISP_i8:.*]] = getelementptr i8, i8* %[[VBASE_i8]], i32 -4 // CHECK: %[[VTORDISP_PTR:.*]] = bitcast i8* %[[VTORDISP_i8]] to i32* // CHECK: store i32 %[[VTORDISP_VAL]], i32* %[[VTORDISP_PTR]] @@ -85,23 +85,23 @@ B::~B() { // CHECK: ret // CHECK2-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* - // CHECK2: %[[THIS:.*]] = load %struct.B** {{.*}} + // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** {{.*}} // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* - // CHECK2: %[[B_i8:.*]] = getelementptr i8* %[[THIS_i8]], i32 8 + // CHECK2: %[[B_i8:.*]] = getelementptr i8, i8* %[[THIS_i8]], i32 8 // CHECK2: %[[B:.*]] = bitcast i8* %[[B_i8]] to %struct.B* // CHECK2: call x86_thiscallcc void @"\01??1B@@UAE@XZ"(%struct.B* %[[B]]) // CHECK2: %[[THIS_i8:.*]] = bitcast %struct.B* %[[THIS]] to i8* - // CHECK2: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[THIS_i8]], i64 8 + // CHECK2: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_i8]], i64 8 // CHECK2: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase* // CHECK2: call x86_thiscallcc void @"\01??1VBase@@UAE@XZ"(%struct.VBase* %[[VBASE]]) // CHECK2: ret // CHECK2-LABEL: define linkonce_odr x86_thiscallcc i8* @"\01??_GB@@UAEPAXI@Z" // CHECK2: %[[THIS_PARAM_i8:.*]] = bitcast %struct.B* {{.*}} to i8* - // CHECK2: %[[THIS_i8:.*]] = getelementptr inbounds i8* %[[THIS_PARAM_i8:.*]], i32 -8 + // CHECK2: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS_PARAM_i8:.*]], i32 -8 // CHECK2: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B* // CHECK2: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR:.*]], align 4 - // CHECK2: %[[THIS:.*]] = load %struct.B** %[[THIS_ADDR]] + // CHECK2: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]] // CHECK2: call x86_thiscallcc void @"\01??_DB@@UAE@XZ"(%struct.B* %[[THIS]]) // ... // CHECK2: ret @@ -114,23 +114,23 @@ void B::foo() { // need to adjust 'this' before use. // // CHECK: %[[THIS_ADDR:.*]] = alloca %struct.B*, align 4 -// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8* %[[ECX:.*]], i32 -8 +// CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ECX:.*]], i32 -8 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %struct.B* // CHECK: store %struct.B* %[[THIS]], %struct.B** %[[THIS_ADDR]], align 4 field = 42; -// CHECK: %[[THIS:.*]] = load %struct.B** %[[THIS_ADDR]] +// CHECK: %[[THIS:.*]] = load %struct.B*, %struct.B** %[[THIS_ADDR]] // CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8* -// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[THIS8]], i32 0 +// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 0 // CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32** -// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR8]] -// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 1 -// CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]] +// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]] +// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1 +// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]] // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]] // CHECK: %[[THIS8:.*]] = bitcast %struct.B* %[[THIS]] to i8* -// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[THIS8]], i32 %[[VBOFFSET]] +// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[THIS8]], i32 %[[VBOFFSET]] // CHECK: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.VBase* -// CHECK: %[[FIELD:.*]] = getelementptr inbounds %struct.VBase* %[[VBASE]], i32 0, i32 1 +// CHECK: %[[FIELD:.*]] = getelementptr inbounds %struct.VBase, %struct.VBase* %[[VBASE]], i32 0, i32 1 // CHECK: store i32 42, i32* %[[FIELD]], align 4 // // CHECK: ret void @@ -145,26 +145,26 @@ void call_vbase_bar(B *obj) { // at the caller site. // // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8* -// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0 +// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0 // CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32** -// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR8]] -// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 1 -// CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]] +// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]] +// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1 +// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]] // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]] -// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] +// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to void (i8*)*** -// CHECK: %[[VFTABLE:.*]] = load void (i8*)*** %[[VFPTR]] -// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)** %[[VFTABLE]], i64 2 -// CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)** %[[VFUN]] +// CHECK: %[[VFTABLE:.*]] = load void (i8*)**, void (i8*)*** %[[VFPTR]] +// CHECK: %[[VFUN:.*]] = getelementptr inbounds void (i8*)*, void (i8*)** %[[VFTABLE]], i64 2 +// CHECK: %[[VFUN_VALUE:.*]] = load void (i8*)*, void (i8*)** %[[VFUN]] // // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8* -// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0 +// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0 // CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32** -// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR8]] -// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 1 -// CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]] +// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]] +// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1 +// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]] // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]] -// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] +// CHECK: %[[VBASE:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] // // CHECK: call x86_thiscallcc void %[[VFUN_VALUE]](i8* %[[VBASE]]) // @@ -177,26 +177,26 @@ void delete_B(B *obj) { delete obj; // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8* -// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0 +// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0 // CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32** -// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR8]] -// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 1 -// CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]] +// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]] +// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1 +// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]] // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]] -// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] +// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] // CHECK: %[[VFPTR:.*]] = bitcast i8* %[[VBASE_i8]] to i8* (%struct.B*, i32)*** -// CHECK: %[[VFTABLE:.*]] = load i8* (%struct.B*, i32)*** %[[VFPTR]] -// CHECK: %[[VFUN:.*]] = getelementptr inbounds i8* (%struct.B*, i32)** %[[VFTABLE]], i64 0 -// CHECK: %[[VFUN_VALUE:.*]] = load i8* (%struct.B*, i32)** %[[VFUN]] +// CHECK: %[[VFTABLE:.*]] = load i8* (%struct.B*, i32)**, i8* (%struct.B*, i32)*** %[[VFPTR]] +// CHECK: %[[VFUN:.*]] = getelementptr inbounds i8* (%struct.B*, i32)*, i8* (%struct.B*, i32)** %[[VFTABLE]], i64 0 +// CHECK: %[[VFUN_VALUE:.*]] = load i8* (%struct.B*, i32)*, i8* (%struct.B*, i32)** %[[VFUN]] // // CHECK: %[[OBJ_i8:.*]] = bitcast %struct.B* %[[OBJ]] to i8* -// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 0 +// CHECK: %[[VBPTR:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 0 // CHECK: %[[VBPTR8:.*]] = bitcast i8* %[[VBPTR]] to i32** -// CHECK: %[[VBTABLE:.*]] = load i32** %[[VBPTR8]] -// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32* %[[VBTABLE]], i32 1 -// CHECK: %[[VBOFFSET32:.*]] = load i32* %[[VBENTRY]] +// CHECK: %[[VBTABLE:.*]] = load i32*, i32** %[[VBPTR8]] +// CHECK: %[[VBENTRY:.*]] = getelementptr inbounds i32, i32* %[[VBTABLE]], i32 1 +// CHECK: %[[VBOFFSET32:.*]] = load i32, i32* %[[VBENTRY]] // CHECK: %[[VBOFFSET:.*]] = add nsw i32 0, %[[VBOFFSET32]] -// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] +// CHECK: %[[VBASE_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 %[[VBOFFSET]] // CHECK: %[[VBASE:.*]] = bitcast i8* %[[VBASE_i8]] to %struct.B* // // CHECK: call x86_thiscallcc i8* %[[VFUN_VALUE]](%struct.B* %[[VBASE]], i32 1) @@ -285,22 +285,22 @@ struct D : virtual Z, B, C { D::~D() { // CHECK-LABEL: define x86_thiscallcc void @"\01??1D@diamond@@UAE@XZ"(%"struct.diamond::D"*) // CHECK: %[[ARG_i8:.*]] = bitcast %"struct.diamond::D"* %{{.*}} to i8* - // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8* %[[ARG_i8]], i32 -24 + // CHECK: %[[THIS_i8:.*]] = getelementptr inbounds i8, i8* %[[ARG_i8]], i32 -24 // CHECK: %[[THIS:.*]] = bitcast i8* %[[THIS_i8]] to %"struct.diamond::D"* // CHECK: store %"struct.diamond::D"* %[[THIS]], %"struct.diamond::D"** %[[THIS_VAL:.*]], align 4 - // CHECK: %[[THIS:.*]] = load %"struct.diamond::D"** %[[THIS_VAL]] + // CHECK: %[[THIS:.*]] = load %"struct.diamond::D"*, %"struct.diamond::D"** %[[THIS_VAL]] // CHECK: %[[D_i8:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to i8* - // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8* %[[D_i8]], i64 4 + // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[D_i8]], i64 4 // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.diamond::C"* // CHECK: %[[C_i8:.*]] = bitcast %"struct.diamond::C"* %[[C]] to i8* - // CHECK: %[[ARG_i8:.*]] = getelementptr i8* %{{.*}}, i32 16 + // CHECK: %[[ARG_i8:.*]] = getelementptr i8, i8* %{{.*}}, i32 16 // FIXME: We might consider changing the dtor this parameter type to i8*. // CHECK: %[[ARG:.*]] = bitcast i8* %[[ARG_i8]] to %"struct.diamond::C"* // CHECK: call x86_thiscallcc void @"\01??1C@diamond@@UAE@XZ"(%"struct.diamond::C"* %[[ARG]]) // CHECK: %[[B:.*]] = bitcast %"struct.diamond::D"* %[[THIS]] to %"struct.diamond::B"* // CHECK: %[[B_i8:.*]] = bitcast %"struct.diamond::B"* %[[B]] to i8* - // CHECK: %[[ARG_i8:.*]] = getelementptr i8* %[[B_i8]], i32 4 + // CHECK: %[[ARG_i8:.*]] = getelementptr i8, i8* %[[B_i8]], i32 4 // CHECK: %[[ARG:.*]] = bitcast i8* %[[ARG_i8]] to %"struct.diamond::B"* // CHECK: call x86_thiscallcc void @"\01??1B@diamond@@UAE@XZ"(%"struct.diamond::B"* %[[ARG]]) // CHECK: ret void @@ -362,12 +362,12 @@ void D::bar() { C::foo(); // Shouldn't need any vbtable lookups. All we have to do is adjust to C*, // then compensate for the adjustment performed in the C::foo() prologue. - // CHECK-NOT: load i8** + // CHECK-NOT: load i8*, i8** // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test3::D"* %{{.*}} to i8* - // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 8 + // CHECK: %[[C_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 8 // CHECK: %[[C:.*]] = bitcast i8* %[[C_i8]] to %"struct.test3::C"* // CHECK: %[[C_i8:.*]] = bitcast %"struct.test3::C"* %[[C]] to i8* - // CHECK: %[[ARG:.*]] = getelementptr i8* %[[C_i8]], i32 4 + // CHECK: %[[ARG:.*]] = getelementptr i8, i8* %[[C_i8]], i32 4 // CHECK: call x86_thiscallcc void @"\01?foo@C@test3@@UAEXXZ"(i8* %[[ARG]]) // CHECK: ret } @@ -408,9 +408,9 @@ void destroy(C *obj) { delete obj; // CHECK: %[[VPTR:.*]] = bitcast %"struct.test4::C"* %[[OBJ:.*]] to i8* (%"struct.test4::C"*, i32)*** - // CHECK: %[[VFTABLE:.*]] = load i8* (%"struct.test4::C"*, i32)*** %[[VPTR]] - // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (%"struct.test4::C"*, i32)** %[[VFTABLE]], i64 0 - // CHECK: %[[VFUN:.*]] = load i8* (%"struct.test4::C"*, i32)** %[[VFTENTRY]] + // CHECK: %[[VFTABLE:.*]] = load i8* (%"struct.test4::C"*, i32)**, i8* (%"struct.test4::C"*, i32)*** %[[VPTR]] + // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (%"struct.test4::C"*, i32)*, i8* (%"struct.test4::C"*, i32)** %[[VFTABLE]], i64 0 + // CHECK: %[[VFUN:.*]] = load i8* (%"struct.test4::C"*, i32)*, i8* (%"struct.test4::C"*, i32)** %[[VFTENTRY]] // CHECK: call x86_thiscallcc i8* %[[VFUN]](%"struct.test4::C"* %[[OBJ]], i32 1) // CHECK: ret } @@ -441,13 +441,13 @@ void destroy(E *obj) { // CHECK-NOT: getelementptr // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ:.*]] to i8* - // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 4 + // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 4 // CHECK: %[[VPTR:.*]] = bitcast i8* %[[B_i8]] to i8* (%"struct.test4::E"*, i32)*** - // CHECK: %[[VFTABLE:.*]] = load i8* (%"struct.test4::E"*, i32)*** %[[VPTR]] - // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (%"struct.test4::E"*, i32)** %[[VFTABLE]], i64 0 - // CHECK: %[[VFUN:.*]] = load i8* (%"struct.test4::E"*, i32)** %[[VFTENTRY]] + // CHECK: %[[VFTABLE:.*]] = load i8* (%"struct.test4::E"*, i32)**, i8* (%"struct.test4::E"*, i32)*** %[[VPTR]] + // CHECK: %[[VFTENTRY:.*]] = getelementptr inbounds i8* (%"struct.test4::E"*, i32)*, i8* (%"struct.test4::E"*, i32)** %[[VFTABLE]], i64 0 + // CHECK: %[[VFUN:.*]] = load i8* (%"struct.test4::E"*, i32)*, i8* (%"struct.test4::E"*, i32)** %[[VFTENTRY]] // CHECK: %[[OBJ_i8:.*]] = bitcast %"struct.test4::E"* %[[OBJ]] to i8* - // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8* %[[OBJ_i8]], i32 4 + // CHECK: %[[B_i8:.*]] = getelementptr inbounds i8, i8* %[[OBJ_i8]], i32 4 // FIXME: in fact, the call should take i8* and the bitcast is redundant. // CHECK: %[[B_as_E:.*]] = bitcast i8* %[[B_i8]] to %"struct.test4::E"* // CHECK: call x86_thiscallcc i8* %[[VFUN]](%"struct.test4::E"* %[[B_as_E]], i32 1) diff --git a/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp b/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp index 937c4c0..f6f7583 100644 --- a/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp +++ b/test/CodeGenCXX/microsoft-abi-virtual-member-pointers.cpp @@ -18,6 +18,7 @@ struct C { virtual int bar(int, double); virtual S baz(int); virtual S qux(U); + virtual void thud(...); }; namespace { @@ -43,6 +44,9 @@ void f() { S (C::*ptr5)(U); ptr5 = &C::qux; + void (C::*ptr6)(...); + ptr6 = &C::thud; + // CHECK32-LABEL: define void @"\01?f@@YAXXZ"() // CHECK32: store i8* bitcast (void (%struct.C*, ...)* @"\01??_9C@@$BA@AE" to i8*), i8** %ptr @@ -64,85 +68,102 @@ void f() { // CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$BA@AE"(%struct.C* %this, ...) // CHECK32: #[[ATTR:[0-9]+]] // CHECK32-NOT: unnamed_addr -// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)** %{{.*}}, i64 0 -// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)** [[VPTR]] -// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK32: comdat +// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 0 +// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK32-NEXT: ret void // CHECK32: } // // CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BA@AA"(%struct.C* %this, ...) // CHECK64: #[[ATTR:[0-9]+]] // CHECK64-NOT: unnamed_addr -// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)** %{{.*}}, i64 0 -// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)** [[VPTR]] -// CHECK64: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK64: comdat +// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 0 +// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK64-NEXT: ret void // CHECK64: } // Thunk for calling the 2nd virtual function in C, taking int and double as parameters, returning int. // CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$B3AE"(%struct.C* %this, ...) -// CHECK32: #[[ATTR]] -// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)** %{{.*}}, i64 1 -// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)** [[VPTR]] -// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK32: #[[ATTR]] comdat +// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 1 +// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK32-NEXT: ret void // CHECK32: } // // CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$B7AA"(%struct.C* %this, ...) -// CHECK64: #[[ATTR]] -// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)** %{{.*}}, i64 1 -// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)** [[VPTR]] -// CHECK64: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK64: #[[ATTR]] comdat +// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 1 +// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK64-NEXT: ret void // CHECK64: } // Thunk for calling the 3rd virtual function in C, taking an int parameter, returning a struct. // CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$B7AE"(%struct.C* %this, ...) -// CHECK32: #[[ATTR]] -// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)** %{{.*}}, i64 2 -// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)** [[VPTR]] -// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK32: #[[ATTR]] comdat +// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 2 +// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK32-NEXT: ret void // CHECK32: } // // CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BBA@AA"(%struct.C* %this, ...) -// CHECK64: #[[ATTR]] -// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)** %{{.*}}, i64 2 -// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)** [[VPTR]] -// CHECK64: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK64: #[[ATTR]] comdat +// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 2 +// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK64-NEXT: ret void // CHECK64: } // Thunk for calling the virtual function in internal class D. // CHECK32-LABEL: define internal x86_thiscallcc void @"\01??_9D@?A@@$BA@AE"(%"struct.(anonymous namespace)::D"* %this, ...) // CHECK32: #[[ATTR]] -// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0 -// CHECK32: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]] -// CHECK32: musttail call x86_thiscallcc void (%"struct.(anonymous namespace)::D"*, ...)* [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...) +// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0 +// CHECK32: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]] +// CHECK32: musttail call x86_thiscallcc void (%"struct.(anonymous namespace)::D"*, ...) [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...) // CHECK32-NEXT: ret void // CHECK32: } // // CHECK64-LABEL: define internal void @"\01??_9D@?A@@$BA@AA"(%"struct.(anonymous namespace)::D"* %this, ...) // CHECK64: #[[ATTR]] -// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0 -// CHECK64: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]] -// CHECK64: musttail call void (%"struct.(anonymous namespace)::D"*, ...)* [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...) +// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** %{{.*}}, i64 0 +// CHECK64: [[CALLEE:%.*]] = load void (%"struct.(anonymous namespace)::D"*, ...)*, void (%"struct.(anonymous namespace)::D"*, ...)** [[VPTR]] +// CHECK64: musttail call void (%"struct.(anonymous namespace)::D"*, ...) [[CALLEE]](%"struct.(anonymous namespace)::D"* %{{.*}}, ...) // CHECK64-NEXT: ret void // CHECK64: } // Thunk for calling the fourth virtual function in C, taking a struct parameter // and returning a struct. -// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$BM@AE"(%struct.C* %this, ...) -// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)** %{{.*}}, i64 3 -// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)** [[VPTR]] -// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK32-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@@$BM@AE"(%struct.C* %this, ...) {{.*}} comdat +// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 3 +// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK32: musttail call x86_thiscallcc void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK32-NEXT: ret void // CHECK32: } // -// CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BBI@AA"(%struct.C* %this, ...) -// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)** %{{.*}}, i64 3 -// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)** [[VPTR]] -// CHECK64: musttail call void (%struct.C*, ...)* [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BBI@AA"(%struct.C* %this, ...) {{.*}} comdat +// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 3 +// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK64: ret void +// CHECK64: } + +// Thunk for calling the fifth virtual function in C which uses the __cdecl calling convention. +// CHECK32-LABEL: define linkonce_odr void @"\01??_9C@@$BBA@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 { +// CHECK32: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 4 +// CHECK32: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK32: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) +// CHECK32: ret void +// CHECK32: } +// +// CHECK64-LABEL: define linkonce_odr void @"\01??_9C@@$BCA@AA"(%struct.C* %this, ...) {{.*}} comdat align 2 { +// CHECK64: [[VPTR:%.*]] = getelementptr inbounds void (%struct.C*, ...)*, void (%struct.C*, ...)** %{{.*}}, i64 4 +// CHECK64: [[CALLEE:%.*]] = load void (%struct.C*, ...)*, void (%struct.C*, ...)** [[VPTR]] +// CHECK64: musttail call void (%struct.C*, ...) [[CALLEE]](%struct.C* %{{.*}}, ...) // CHECK64: ret void // CHECK64: } diff --git a/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp b/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp index 35ff4f3..f8a12e6 100644 --- a/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp +++ b/test/CodeGenCXX/microsoft-abi-vmemptr-conflicts.cpp @@ -23,8 +23,8 @@ void f(C *c) { // CHECK: call x86_thiscallcc void bitcast (void (%"struct.num_params::C"*, ...)* @"\01??_9C@num_params@@$BA@AE" to void (%"struct.num_params::C"*, i32)*)(%"struct.num_params::C"* %{{.*}}, i32 0) // CHECK: call x86_thiscallcc void bitcast (void (%"struct.num_params::C"*, ...)* @"\01??_9C@num_params@@$BA@AE" to void (%"struct.num_params::C"*, i32, i32)*)(%"struct.num_params::C"* %{{.*}}, i32 0, i32 0) -// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@num_params@@$BA@AE"(%"struct.num_params::C"* %this, ...) -// CHECK: musttail call x86_thiscallcc void (%"struct.num_params::C"*, ...)* %{{.*}}(%"struct.num_params::C"* %{{.*}}, ...) +// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@num_params@@$BA@AE"(%"struct.num_params::C"* %this, ...) {{.*}} comdat +// CHECK: musttail call x86_thiscallcc void (%"struct.num_params::C"*, ...) %{{.*}}(%"struct.num_params::C"* %{{.*}}, ...) // CHECK-NEXT: ret void namespace i64_return { @@ -45,8 +45,8 @@ long long f(C *c) { // CHECK: call x86_thiscallcc i32 bitcast (void (%"struct.i64_return::C"*, ...)* @"\01??_9C@i64_return@@$BA@AE" to i32 (%"struct.i64_return::C"*)*)(%"struct.i64_return::C"* %{{.*}}) // CHECK: call x86_thiscallcc i64 bitcast (void (%"struct.i64_return::C"*, ...)* @"\01??_9C@i64_return@@$BA@AE" to i64 (%"struct.i64_return::C"*)*)(%"struct.i64_return::C"* %{{.*}}) -// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@i64_return@@$BA@AE"(%"struct.i64_return::C"* %this, ...) -// CHECK: musttail call x86_thiscallcc void (%"struct.i64_return::C"*, ...)* %{{.*}}(%"struct.i64_return::C"* %{{.*}}, ...) +// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@i64_return@@$BA@AE"(%"struct.i64_return::C"* %this, ...) {{.*}} comdat +// CHECK: musttail call x86_thiscallcc void (%"struct.i64_return::C"*, ...) %{{.*}}(%"struct.i64_return::C"* %{{.*}}, ...) // CHECK-NEXT: ret void namespace sret { @@ -67,8 +67,8 @@ void f(C *c) { // CHECK: call x86_thiscallcc i32 bitcast (void (%"struct.sret::C"*, ...)* @"\01??_9C@sret@@$BA@AE" to i32 (%"struct.sret::C"*)*)(%"struct.sret::C"* %{{.*}}) // CHECK: call x86_thiscallcc void bitcast (void (%"struct.sret::C"*, ...)* @"\01??_9C@sret@@$BA@AE" to void (%"struct.sret::C"*, %"struct.sret::Big"*)*)(%"struct.sret::C"* %{{.*}}, %"struct.sret::Big"* sret %{{.*}}) -// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@sret@@$BA@AE"(%"struct.sret::C"* %this, ...) -// CHECK: musttail call x86_thiscallcc void (%"struct.sret::C"*, ...)* %{{.*}}(%"struct.sret::C"* %{{.*}}, ...) +// CHECK-LABEL: define linkonce_odr x86_thiscallcc void @"\01??_9C@sret@@$BA@AE"(%"struct.sret::C"* %this, ...) {{.*}} comdat +// CHECK: musttail call x86_thiscallcc void (%"struct.sret::C"*, ...) %{{.*}}(%"struct.sret::C"* %{{.*}}, ...) // CHECK-NEXT: ret void namespace cdecl_inalloca { @@ -93,9 +93,9 @@ void f(C *c) { } // CHECK-LABEL: define void @"\01?f@cdecl_inalloca@@YAXPAUC@1@@Z"(%"struct.cdecl_inalloca::C"* %c) -// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"\01??_9C@cdecl_inalloca@@$BA@AE" to void (%"struct.cdecl_inalloca::C"*)*)(%"struct.cdecl_inalloca::C"* %{{.*}}) -// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"\01??_9C@cdecl_inalloca@@$BA@AE" to void (<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>*)*)(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>* inalloca %{{.*}}) +// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"\01??_9C@cdecl_inalloca@@$BA@AA" to void (%"struct.cdecl_inalloca::C"*)*)(%"struct.cdecl_inalloca::C"* %{{.*}}) +// CHECK: call void bitcast (void (%"struct.cdecl_inalloca::C"*, ...)* @"\01??_9C@cdecl_inalloca@@$BA@AA" to void (<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>*)*)(<{ %"struct.cdecl_inalloca::C"*, %"struct.cdecl_inalloca::Big" }>* inalloca %{{.*}}) -// CHECK-LABEL: define linkonce_odr void @"\01??_9C@cdecl_inalloca@@$BA@AE"(%"struct.cdecl_inalloca::C"* %this, ...) -// CHECK: musttail call void (%"struct.cdecl_inalloca::C"*, ...)* %{{.*}}(%"struct.cdecl_inalloca::C"* %{{.*}}, ...) +// CHECK-LABEL: define linkonce_odr void @"\01??_9C@cdecl_inalloca@@$BA@AA"(%"struct.cdecl_inalloca::C"* %this, ...) {{.*}} comdat +// CHECK: musttail call void (%"struct.cdecl_inalloca::C"*, ...) %{{.*}}(%"struct.cdecl_inalloca::C"* %{{.*}}, ...) // CHECK-NEXT: ret void diff --git a/test/CodeGenCXX/microsoft-abi-vmemptr-vbase.cpp b/test/CodeGenCXX/microsoft-abi-vmemptr-vbase.cpp new file mode 100644 index 0000000..85cc84f --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-vmemptr-vbase.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -fno-rtti -emit-llvm -triple=i386-pc-win32 -fms-extensions -fms-compatibility -std=c++11 %s -o - | FileCheck %s + +namespace PR23452 { +struct A { + virtual void f(); +}; +struct B : virtual A { + virtual void f(); +}; +void (B::*MemPtr)(void) = &B::f; +// CHECK-DAG: @"\01?MemPtr@PR23452@@3P8B@1@AEXXZQ21@" = global { i8*, i32, i32 } { i8* bitcast ({{.*}} @"\01??_9B@PR23452@@$BA@AE" to i8*), i32 0, i32 4 } +} diff --git a/test/CodeGenCXX/microsoft-abi-vtables-ambiguous.cpp b/test/CodeGenCXX/microsoft-abi-vtables-ambiguous.cpp new file mode 100644 index 0000000..c05fc17 --- /dev/null +++ b/test/CodeGenCXX/microsoft-abi-vtables-ambiguous.cpp @@ -0,0 +1,44 @@ +// RUN: %clang_cc1 %s -emit-llvm-only -triple=i386-pc-win32 -verify -DTEST1 +// RUN: %clang_cc1 %s -emit-llvm-only -triple=i386-pc-win32 -verify -DTEST2 + +#ifdef TEST1 +struct A { + virtual A *foo(); // in vftable slot #0. + virtual A *bar(); // in vftable slot #1. +}; + +struct B : virtual A { + // appended to the A subobject's vftable in slot #2. + virtual B *foo(); // expected-note{{covariant thunk required by 'foo'}} +}; + +struct C : virtual A { + // appended to the A subobject's vftable in slot #2. + virtual C *bar(); // expected-note{{covariant thunk required by 'bar'}} +}; + +struct D : B, C { D(); }; // expected-error{{ambiguous vftable component}} +D::D() {} +#endif + +#ifdef TEST2 +struct A { + virtual A *foo(); // in vftable slot #0 +}; + +struct B : virtual A { + // appended to the A subobject's vftable in slot #1. + virtual B *foo(); // expected-note{{covariant thunk required by 'foo'}} +}; + +struct C : virtual A { + // appended to the A subobject's vftable in slot #1. + virtual C *foo(); // expected-note{{covariant thunk required by 'foo'}} +}; + +struct D : B, C { // expected-error{{ambiguous vftable component}} + virtual D *foo(); + D(); +}; +D::D() {} +#endif diff --git a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp index d71f40a..aaee39c 100644 --- a/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp +++ b/test/CodeGenCXX/microsoft-abi-vtables-multiple-nonvirtual-inheritance-this-adjustment.cpp @@ -160,7 +160,7 @@ void ffun(C &c) { // BITCODE: bitcast // BITCODE: bitcast // BITCODE: [[THIS1:%.+]] = bitcast %"struct.test4::C"* {{.*}} to i8* - // BITCODE: [[THIS2:%.+]] = getelementptr inbounds i8* [[THIS1]], i32 4 + // BITCODE: [[THIS2:%.+]] = getelementptr inbounds i8, i8* [[THIS1]], i32 4 // BITCODE-NEXT: call x86_thiscallcc {{.*}}(i8* [[THIS2]]) c.bar(); } @@ -171,7 +171,7 @@ void fop(C &c) { // BITCODE: bitcast // BITCODE: bitcast // BITCODE: [[THIS1:%.+]] = bitcast %"struct.test4::C"* {{.*}} to i8* - // BITCODE: [[THIS2:%.+]] = getelementptr inbounds i8* [[THIS1]], i32 4 + // BITCODE: [[THIS2:%.+]] = getelementptr inbounds i8, i8* [[THIS1]], i32 4 // BITCODE-NEXT: call x86_thiscallcc {{.*}}(i8* [[THIS2]]) -c; } diff --git a/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp index 072cb95..d223448 100644 --- a/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp +++ b/test/CodeGenCXX/microsoft-abi-vtables-return-thunks.cpp @@ -128,3 +128,76 @@ C::C() {} // GLOBALS: @"\01?f@B@pr20479@@QAEPAUA@2@XZ" // GLOBALS: @"\01?f@B@pr20479@@UAEPAU12@XZ" } + +namespace pr21073 { +struct A { + virtual A *f(); +}; + +struct B : virtual A { + virtual B *f(); +}; + +struct C : virtual A, virtual B { +// VFTABLES-LABEL: VFTable for 'pr21073::A' in 'pr21073::B' in 'pr21073::C' (2 entries). +// VFTABLES-NEXT: 0 | pr21073::B *pr21073::B::f() +// VFTABLES-NEXT: [return adjustment (to type 'struct pr21073::A *'): vbase #1, 0 non-virtual] +// VFTABLES-NEXT: [this adjustment: 8 non-virtual] +// VFTABLES-NEXT: 1 | pr21073::B *pr21073::B::f() +// VFTABLES-NEXT: [return adjustment (to type 'struct pr21073::B *'): 0 non-virtual] +// VFTABLES-NEXT: [this adjustment: 8 non-virtual] + C(); +}; + +C::C() {} + +// GLOBALS-LABEL: @"\01??_7C@pr21073@@6B@" = linkonce_odr unnamed_addr constant [2 x i8*] +// GLOBALS: @"\01?f@B@pr21073@@WPPPPPPPI@AEPAUA@2@XZ" +// GLOBALS: @"\01?f@B@pr21073@@WPPPPPPPI@AEPAU12@XZ" +} + +namespace pr21073_2 { +struct A { virtual A *foo(); }; +struct B : virtual A {}; +struct C : virtual A { virtual C *foo(); }; +struct D : B, C { D(); }; +D::D() {} + +// VFTABLES-LABEL: VFTable for 'pr21073_2::A' in 'pr21073_2::C' in 'pr21073_2::D' (2 entries) +// VFTABLES-NEXT: 0 | pr21073_2::C *pr21073_2::C::foo() +// VFTABLES-NEXT: [return adjustment (to type 'struct pr21073_2::A *'): vbase #1, 0 non-virtual] +// VFTABLES-NEXT: 1 | pr21073_2::C *pr21073_2::C::foo() + +// GLOBALS-LABEL: @"\01??_7D@pr21073_2@@6B@" = {{.*}} constant [2 x i8*] +// GLOBALS: @"\01?foo@C@pr21073_2@@QAEPAUA@2@XZ" +// GLOBALS: @"\01?foo@C@pr21073_2@@UAEPAU12@XZ" +} + +namespace test3 { +struct A { virtual A *fn(); }; +struct B : virtual A { virtual B *fn(); }; +struct X : virtual B {}; +struct Y : virtual B {}; +struct C : X, Y {}; +struct D : virtual B, virtual A, C { + D *fn(); + D(); +}; +D::D() {} + +// VFTABLES-LABEL: VFTable for 'test3::A' in 'test3::B' in 'test3::X' in 'test3::C' in 'test3::D' (3 entries). +// VFTABLES-NEXT: 0 | test3::D *test3::D::fn() +// VFTABLES-NEXT: [return adjustment (to type 'struct test3::A *'): vbase #1, 0 non-virtual] +// VFTABLES-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual] +// VFTABLES-NEXT: 1 | test3::D *test3::D::fn() +// VFTABLES-NEXT: [return adjustment (to type 'struct test3::B *'): vbase #2, 0 non-virtual] +// VFTABLES-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual] +// VFTABLES-NEXT: 2 | test3::D *test3::D::fn() +// VFTABLES-NEXT: [return adjustment (to type 'struct test3::D *'): 0 non-virtual] +// VFTABLES-NEXT: [this adjustment: vtordisp at -4, 0 non-virtual] + +// GLOBALS-LABEL: @"\01??_7D@test3@@6B@" = {{.*}} constant [3 x i8*] +// GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAUA@2@XZ" +// GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAUB@2@XZ" +// GLOBALS: @"\01?fn@D@test3@@$4PPPPPPPM@A@AEPAU12@XZ" +} diff --git a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp index 65d6a9d..83f8114 100644 --- a/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp +++ b/test/CodeGenCXX/microsoft-abi-vtables-virtual-inheritance.cpp @@ -807,3 +807,41 @@ C::C() {} // MANGLING-DAG: @"\01??_7C@pr21031_2@@6BA@1@@" = {{.*}} constant [1 x i8*] // MANGLING-DAG: @"\01??_7C@pr21031_2@@6BB@1@@" = {{.*}} constant [1 x i8*] } + +namespace pr21062_1 { +struct A { virtual void f(); }; +struct B {}; +struct C : virtual B {}; +struct D : virtual C, virtual B, virtual A { D();}; +D::D() {} + +// CHECK-LABEL: VFTable for 'pr21062_1::A' in 'pr21062_1::D' (1 entry) +// CHECK-NEXT: 0 | void pr21062_1::A::f() + +// MANGLING-DAG: @"\01??_7D@pr21062_1@@6B@" = {{.*}} constant [1 x i8*] +} + +namespace pr21062_2 { +struct A { virtual void f(); }; +struct B {}; +struct C : virtual B {}; +struct D : C, virtual B, virtual A { D(); }; +D::D() {} + +// CHECK-LABEL: VFTable for 'pr21062_2::A' in 'pr21062_2::D' (1 entry) +// CHECK-NEXT: 0 | void pr21062_2::A::f() + +// MANGLING-DAG: @"\01??_7D@pr21062_2@@6B@" = {{.*}} constant [1 x i8*] +} + +namespace pr21064 { +struct A {}; +struct B { virtual void f(); }; +struct C : virtual A, virtual B {}; +struct D : virtual A, virtual C { D(); }; +D::D() {} +// CHECK-LABEL: VFTable for 'pr21064::B' in 'pr21064::C' in 'pr21064::D' (1 entry) +// CHECK-NEXT: 0 | void pr21064::B::f() + +// MANGLING-DAG: @"\01??_7D@pr21064@@6B@" = {{.*}} constant [1 x i8*] +} diff --git a/test/CodeGenCXX/microsoft-interface.cpp b/test/CodeGenCXX/microsoft-interface.cpp index ec558a4..a2dfb69 100644 --- a/test/CodeGenCXX/microsoft-interface.cpp +++ b/test/CodeGenCXX/microsoft-interface.cpp @@ -29,12 +29,12 @@ int fn() { // CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @_ZN1S4testEv(%struct.S* %this) // CHECK: %{{[.0-9A-Z_a-z]+}} = call x86_thiscallcc i32 @_ZN1I4testEv(%__interface.I* %{{[.0-9A-Z_a-z]+}}) -// CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @_ZN1I4testEv(%__interface.I* %this) -// CHECK: ret i32 1 - // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @_ZN1SC2Ev(%struct.S* %this) // CHECK: call x86_thiscallcc void @_ZN1IC2Ev(%__interface.I* %{{[.0-9A-Z_a-z]+}}) -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1S, i64 0, i64 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}} +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1S, i64 0, i64 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}} // CHECK-LABEL: define linkonce_odr x86_thiscallcc void @_ZN1IC2Ev(%__interface.I* %this) -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1I, i64 0, i64 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}} +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1I, i64 0, i64 2) to i32 (...)**), i32 (...)*** %{{[.0-9A-Z_a-z]+}} + +// CHECK-LABEL: define linkonce_odr x86_thiscallcc i32 @_ZN1I4testEv(%__interface.I* %this) +// CHECK: ret i32 1 diff --git a/test/CodeGenCXX/microsoft-no-rtti-data.cpp b/test/CodeGenCXX/microsoft-no-rtti-data.cpp index fded4c9..68fdf05 100644 --- a/test/CodeGenCXX/microsoft-no-rtti-data.cpp +++ b/test/CodeGenCXX/microsoft-no-rtti-data.cpp @@ -2,7 +2,7 @@ // vftable shouldn't have RTTI data in it. // CHECK-NOT: @"\01??_R4S@@6B@" -// CHECK: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)] +// CHECK: @"\01??_7S@@6B@" = linkonce_odr unnamed_addr constant [1 x i8*] [i8* bitcast ({{.*}} @"\01??_GS@@UAEPAXI@Z" to i8*)], comdat struct type_info; namespace std { using ::type_info; } diff --git a/test/CodeGenCXX/microsoft-uuidof.cpp b/test/CodeGenCXX/microsoft-uuidof.cpp index d57ca83..2ac5f1b 100644 --- a/test/CodeGenCXX/microsoft-uuidof.cpp +++ b/test/CodeGenCXX/microsoft-uuidof.cpp @@ -19,6 +19,7 @@ typedef struct _GUID GUID; struct __declspec(uuid("12345678-1234-1234-1234-1234567890aB")) S1 { } s1; struct __declspec(uuid("87654321-4321-4321-4321-ba0987654321")) S2 { }; struct __declspec(uuid("{12345678-1234-1234-1234-1234567890ac}")) Curly; +struct __declspec(uuid("{12345678-1234-1234-1234-1234567890ac}")) Curly; #ifdef DEFINE_GUID // Make sure we can properly generate code when the UUID has curly braces on it. @@ -33,7 +34,7 @@ GUID g = __uuidof(S1); #endif // First global use of __uuidof(S1) forces the creation of the global. -// CHECK: @_GUID_12345678_1234_1234_1234_1234567890ab = linkonce_odr constant { i32, i16, i16, [8 x i8] } { i32 305419896, i16 4660, i16 4660, [8 x i8] c"\124\124Vx\90\AB" } +// CHECK: @_GUID_12345678_1234_1234_1234_1234567890ab = linkonce_odr constant { i32, i16, i16, [8 x i8] } { i32 305419896, i16 4660, i16 4660, [8 x i8] c"\124\124Vx\90\AB" }, comdat // CHECK: @gr = constant %struct._GUID* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ab to %struct._GUID*), align 4 const GUID& gr = __uuidof(S1); @@ -49,7 +50,7 @@ const GUID& zeroiid = __uuidof(0); // __uuidof(S2) hasn't been used globally yet, so it's emitted when it's used // in a function and is emitted at the end of the globals section. -// CHECK: @_GUID_87654321_4321_4321_4321_ba0987654321 = linkonce_odr constant { i32, i16, i16, [8 x i8] } { i32 -2023406815, i16 17185, i16 17185, [8 x i8] c"C!\BA\09\87eC!" } +// CHECK: @_GUID_87654321_4321_4321_4321_ba0987654321 = linkonce_odr constant { i32, i16, i16, [8 x i8] } { i32 -2023406815, i16 17185, i16 17185, [8 x i8] c"C!\BA\09\87eC!" }, comdat // The static initializer for thing. // CHECK-DEFINE-GUID: call void @llvm.memcpy.p0i8.p0i8.i32(i8* bitcast (%struct._GUID* @thing to i8*), i8* bitcast ({ i32, i16, i16, [8 x i8] }* @_GUID_12345678_1234_1234_1234_1234567890ac to i8*), i32 16, i32 4, i1 false) diff --git a/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp b/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp index 869fded..1ff0182 100644 --- a/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp +++ b/test/CodeGenCXX/mips-size_t-ptrdiff_t.cpp @@ -10,10 +10,10 @@ long *alloc_long() { return rv; } // O32-LABEL: define i32* @_Z10alloc_longv() -// O32: call noalias i8* @_Znwj(i32 zeroext 4) +// O32: call noalias i8* @_Znwj(i32 signext 4) // N32-LABEL: define i32* @_Z10alloc_longv() -// N32: call noalias i8* @_Znwj(i32 zeroext 4) +// N32: call noalias i8* @_Znwj(i32 signext 4) // N64-LABEL: define i64* @_Z10alloc_longv() // N64: call noalias i8* @_Znwm(i64 zeroext 8) @@ -24,10 +24,10 @@ long *alloc_long_array() { } // O32-LABEL: define i32* @_Z16alloc_long_arrayv() -// O32: call noalias i8* @_Znaj(i32 zeroext 8) +// O32: call noalias i8* @_Znaj(i32 signext 8) // N32-LABEL: define i32* @_Z16alloc_long_arrayv() -// N32: call noalias i8* @_Znaj(i32 zeroext 8) +// N32: call noalias i8* @_Znaj(i32 signext 8) // N64-LABEL: define i64* @_Z16alloc_long_arrayv() // N64: call noalias i8* @_Znam(i64 zeroext 16) diff --git a/test/CodeGenCXX/ms-inline-asm-return.cpp b/test/CodeGenCXX/ms-inline-asm-return.cpp index 26fc426..1219c61 100644 --- a/test/CodeGenCXX/ms-inline-asm-return.cpp +++ b/test/CodeGenCXX/ms-inline-asm-return.cpp @@ -58,7 +58,7 @@ bool f_i1() { // CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$1\0A\09mov edx, $$1", "={eax},~{eax},{{.*}}" // CHECK: %[[r_i8:[^ ]*]] = trunc i32 %[[r]] to i8 // CHECK: store i8 %[[r_i8]], i8* %{{.*}} -// CHECK: %[[r_i1:[^ ]*]] = load i1* %{{.*}} +// CHECK: %[[r_i1:[^ ]*]] = load i1, i1* %{{.*}} // CHECK: ret i1 %[[r_i1]] struct FourChars { @@ -72,7 +72,7 @@ FourChars f_s4() { // CHECK-LABEL: define i32 @f_s4() // CHECK: %[[r:[^ ]*]] = call i32 asm sideeffect inteldialect "mov eax, $$0x01010101", "={eax},~{eax},{{.*}}" // CHECK: store i32 %[[r]], i32* %{{.*}} -// CHECK: %[[r_i32:[^ ]*]] = load i32* %{{.*}} +// CHECK: %[[r_i32:[^ ]*]] = load i32, i32* %{{.*}} // CHECK: ret i32 %[[r_i32]] struct EightChars { @@ -87,7 +87,7 @@ EightChars f_s8() { // CHECK-LABEL: define i64 @f_s8() // CHECK: %[[r:[^ ]*]] = call i64 asm sideeffect inteldialect "mov eax, $$0x01010101\0A\09mov edx, $$0x01010101", "=A,~{eax},{{.*}}" // CHECK: store i64 %[[r]], i64* %{{.*}} -// CHECK: %[[r_i64:[^ ]*]] = load i64* %{{.*}} +// CHECK: %[[r_i64:[^ ]*]] = load i64, i64* %{{.*}} // CHECK: ret i64 %[[r_i64]] } // extern "C" diff --git a/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp b/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp index 3f868f3..78bb3a2 100644 --- a/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp +++ b/test/CodeGenCXX/ms-integer-static-data-members-exported.cpp @@ -17,6 +17,6 @@ struct __declspec(dllexport) S { }; }; -// CHECK: @"\01?x@S@@2FB" = weak_odr dllexport constant i16 42, align 2 -// CHECK: @"\01?y@S@@2W4Enum@@B" = weak_odr dllexport constant i32 2, align 4 +// CHECK: @"\01?x@S@@2FB" = weak_odr dllexport constant i16 42, comdat, align 2 +// CHECK: @"\01?y@S@@2W4Enum@@B" = weak_odr dllexport constant i32 2, comdat, align 4 // CHECK-NOT: NonExported diff --git a/test/CodeGenCXX/ms-integer-static-data-members.cpp b/test/CodeGenCXX/ms-integer-static-data-members.cpp index b02b679..5e5b81d 100644 --- a/test/CodeGenCXX/ms-integer-static-data-members.cpp +++ b/test/CodeGenCXX/ms-integer-static-data-members.cpp @@ -1,35 +1,52 @@ // RUN: %clang_cc1 -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s -// RUN: %clang_cc1 -DINLINE_INIT -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-INLINE -// RUN: %clang_cc1 -DREAL_DEFINITION -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-OUTOFLINE -// RUN: %clang_cc1 -DINLINE_INIT -DREAL_DEFINITION -emit-llvm -triple=i386-pc-win32 -fms-compatibility %s -o - | FileCheck %s --check-prefix=CHECK-INLINE struct S { - // For MS ABI, we emit a linkonce_odr definition here, even though it's really just a declaration. -#ifdef INLINE_INIT - static const int x = 5; -#else - static const int x; -#endif + static const int NoInit_Ref; + static const int Inline_NotDef_NotRef = 5; + static const int Inline_NotDef_Ref = 5; + static const int Inline_Def_NotRef = 5; + static const int Inline_Def_Ref = 5; + static const int OutOfLine_Def_NotRef; + static const int OutOfLine_Def_Ref; }; -const int *f() { - return &S::x; +const int *foo1() { + return &S::NoInit_Ref; }; -#ifdef REAL_DEFINITION -#ifdef INLINE_INIT -const int S::x; -#else -const int S::x = 5; -#endif -#endif +const int *foo2() { + return &S::Inline_NotDef_Ref; +}; + +const int *foo3() { + return &S::Inline_Def_Ref; +}; +const int *foo4() { + return &S::OutOfLine_Def_Ref; +}; -// Inline initialization. -// CHECK-INLINE: @"\01?x@S@@2HB" = linkonce_odr constant i32 5, align 4 +const int S::Inline_Def_NotRef; +const int S::Inline_Def_Ref; +const int S::OutOfLine_Def_NotRef = 5; +const int S::OutOfLine_Def_Ref = 5; -// Out-of-line initialization. -// CHECK-OUTOFLINE: @"\01?x@S@@2HB" = constant i32 5, align 4 // No initialization. -// CHECK: @"\01?x@S@@2HB" = external constant i32 +// CHECK-DAG: @"\01?NoInit_Ref@S@@2HB" = external constant i32 + +// Inline initialization, no real definiton, not referenced. +// CHECK-NOT: @"\01?Inline_NotDef_NotRef@S@@2HB" = {{.*}} constant i32 5 + +// Inline initialization, no real definiton, referenced. +// CHECK-DAG: @"\01?Inline_NotDef_Ref@S@@2HB" = linkonce_odr constant i32 5, comdat, align 4 + +// Inline initialization, real definiton, not referenced. +// CHECK-DAG: @"\01?Inline_Def_NotRef@S@@2HB" = constant i32 5, align 4 + +// Inline initialization, real definiton, referenced. +// CHECK-DAG: @"\01?Inline_Def_Ref@S@@2HB" = constant i32 5, comdat, align 4 + +// Out-of-line initialization. +// CHECK-DAG: @"\01?OutOfLine_Def_NotRef@S@@2HB" = constant i32 5, align 4 +// CHECK-DAG: @"\01?OutOfLine_Def_Ref@S@@2HB" = constant i32 5, align 4 diff --git a/test/CodeGenCXX/ms-novtable.cpp b/test/CodeGenCXX/ms-novtable.cpp new file mode 100644 index 0000000..8d54878 --- /dev/null +++ b/test/CodeGenCXX/ms-novtable.cpp @@ -0,0 +1,21 @@ +// RUN: %clang_cc1 -triple i386-pc-win32 %s -emit-llvm -fms-extensions -fms-compatibility -fno-rtti -o - | FileCheck %s + +// CHECK-NOT: @"\01??_7C@@6B@" + +// CHECK-DAG: @"\01??_7A2@@6B@" + +// CHECK-DAG: @"\01??_7B2@@6B@" + +// CHECK-NOT: @"\01??_7B1@@6B@" + +// CHECK-NOT: @"\01??_7A1@@6B@" + +struct __declspec(novtable) A1 { + virtual void a(); +} a1; +struct A2 { + virtual void a(); +}; +struct __declspec(novtable) B1 : virtual A1 {} b1; +struct B2 : virtual A1 {} b2; +struct __declspec(novtable) C : virtual A2 {} c; diff --git a/test/CodeGenCXX/ms_struct.cpp b/test/CodeGenCXX/ms_struct.cpp new file mode 100644 index 0000000..32307ba --- /dev/null +++ b/test/CodeGenCXX/ms_struct.cpp @@ -0,0 +1,33 @@ +// RUN: %clang_cc1 -triple x86_64-apple-darwin10 -emit-llvm %s -o - | FileCheck %s + +// rdar://20636558 + +#pragma GCC diagnostic ignored "-Wincompatible-ms-struct" +#define ATTR __attribute__((__ms_struct__)) + +struct ATTR VBase { + virtual void foo() = 0; +}; + +struct ATTR Base : virtual VBase { + virtual void bar() = 0; +}; + +struct ATTR Derived : Base { + Derived(); + void foo(); + void bar(); + int value; +}; + +// CHECK: [[DERIVED:%.*]] = type <{ [[BASE:%.*]], i32, [4 x i8] }> +// CHECK: [[BASE]] = type { [[VBASE:%.*]] } +// CHECK: [[VBASE]] = type { i32 (...)** } + +// CHECK: define void @_ZN7DerivedC2Ev +// CHECK: [[SELF:%.*]] = load [[DERIVED]]* +// CHECK: [[T0:%.*]] = bitcast [[DERIVED]]* [[SELF]] to [[BASE]]* +// CHECK: call void @_ZN4BaseC2Ev([[BASE]]* [[T0]], i8** +// CHECK: [[T0:%.*]] = getelementptr inbounds {{.*}} [[SELF]], i32 0, i32 1 +// CHECK: store i32 20, i32* [[T0]], +Derived::Derived() : value(20) {} diff --git a/test/CodeGenCXX/ms_wide_predefined_expr.cpp b/test/CodeGenCXX/ms_wide_predefined_expr.cpp index 3949d39..03c78d9 100644 --- a/test/CodeGenCXX/ms_wide_predefined_expr.cpp +++ b/test/CodeGenCXX/ms_wide_predefined_expr.cpp @@ -1,6 +1,6 @@ // RUN: %clang_cc1 %s -fms-extensions -triple i686-pc-win32 -emit-llvm -o - | FileCheck %s -// CHECK: @"\01??_C@_19DPFBEKIN@?$AAf?$AAu?$AAn?$AAc?$AA?$AA@" = linkonce_odr unnamed_addr constant [5 x i16] [i16 102, i16 117, i16 110, i16 99, i16 0], align 2 +// CHECK: @"\01??_C@_19DPFBEKIN@?$AAf?$AAu?$AAn?$AAc?$AA?$AA@" = linkonce_odr unnamed_addr constant [5 x i16] [i16 102, i16 117, i16 110, i16 99, i16 0], comdat, align 2 void wprint(const wchar_t*); diff --git a/test/CodeGenCXX/new-array-init.cpp b/test/CodeGenCXX/new-array-init.cpp index 65123ea..6b76f47 100644 --- a/test/CodeGenCXX/new-array-init.cpp +++ b/test/CodeGenCXX/new-array-init.cpp @@ -38,11 +38,11 @@ void check_array_value_init() { new (int S::*[3][4][5]) (); // CHECK: call noalias i8* @_Zna{{.}}(i{{32 240|64 480}}) - // CHECK: getelementptr inbounds i{{32|64}}* {{.*}}, i{{32|64}} 60 + // CHECK: getelementptr inbounds i{{32|64}}, i{{32|64}}* {{.*}}, i{{32|64}} 60 // CHECK: phi // CHECK: store i{{32|64}} -1, - // CHECK: getelementptr inbounds i{{32|64}}* {{.*}}, i{{32|64}} 1 + // CHECK: getelementptr inbounds i{{32|64}}, i{{32|64}}* {{.*}}, i{{32|64}} 1 // CHECK: icmp eq // CHECK: br i1 } diff --git a/test/CodeGenCXX/new-overflow.cpp b/test/CodeGenCXX/new-overflow.cpp index 68f89c3..9057e04 100644 --- a/test/CodeGenCXX/new-overflow.cpp +++ b/test/CodeGenCXX/new-overflow.cpp @@ -103,7 +103,7 @@ namespace test5 { typedef A elt; // CHECK: define [[A:%.*]]* @_ZN5test54testEi(i32 - // CHECK: [[N:%.*]] = load i32* + // CHECK: [[N:%.*]] = load i32, i32* // CHECK-NEXT: [[T0:%.*]] = icmp slt i32 [[N]], 0 // CHECK-NEXT: [[T1:%.*]] = select i1 [[T0]], i32 -1, i32 [[N]] // CHECK-NEXT: call noalias i8* @_Znaj(i32 [[T1]]) @@ -168,7 +168,7 @@ namespace test8 { typedef A elt; // CHECK: define [[A:%.*]]* @_ZN5test84testEx(i64 - // CHECK: [[N:%.*]] = load i64* + // CHECK: [[N:%.*]] = load i64, i64* // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296 // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32 // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4) @@ -193,7 +193,7 @@ namespace test9 { typedef A elt; // CHECK: define [[A:%.*]]* @_ZN5test94testEy(i64 - // CHECK: [[N:%.*]] = load i64* + // CHECK: [[N:%.*]] = load i64, i64* // CHECK-NEXT: [[T0:%.*]] = icmp uge i64 [[N]], 4294967296 // CHECK-NEXT: [[T1:%.*]] = trunc i64 [[N]] to i32 // CHECK-NEXT: [[T2:%.*]] = call { i32, i1 } @llvm.umul.with.overflow.i32(i32 [[T1]], i32 4) diff --git a/test/CodeGenCXX/new.cpp b/test/CodeGenCXX/new.cpp index 862161b..c8e0acb 100644 --- a/test/CodeGenCXX/new.cpp +++ b/test/CodeGenCXX/new.cpp @@ -36,6 +36,10 @@ void *operator new[](size_t, const std::nothrow_t &) throw(); void operator delete(void *, const std::nothrow_t &) throw(); void operator delete[](void *, const std::nothrow_t &) throw(); +// Declare some other placemenet operators. +void *operator new(size_t, void*, bool) throw(); +void *operator new[](size_t, void*, bool) throw(); + void t2(int* a) { int* b = new (a) int; } @@ -191,46 +195,73 @@ void f() { namespace test15 { struct A { A(); ~A(); }; - // CHECK-LABEL: define void @_ZN6test155test0EPv( - // CHECK: [[P:%.*]] = load i8* - // CHECK-NEXT: icmp eq i8* [[P]], null - // CHECK-NEXT: br i1 + // CHECK-LABEL: define void @_ZN6test156test0aEPv( + // CHECK: [[P:%.*]] = load i8*, i8** + // CHECK-NOT: icmp eq i8* [[P]], null + // CHECK-NOT: br i1 // CHECK: [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]* // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T0]]) - void test0(void *p) { + void test0a(void *p) { new (p) A(); } - // CHECK-LABEL: define void @_ZN6test155test1EPv( - // CHECK: [[P:%.*]] = load i8** + // CHECK-LABEL: define void @_ZN6test156test0bEPv( + // CHECK: [[P0:%.*]] = load i8*, i8** + // CHECK: [[P:%.*]] = call i8* @_ZnwmPvb(i64 1, i8* [[P0]] // CHECK-NEXT: icmp eq i8* [[P]], null // CHECK-NEXT: br i1 + // CHECK: [[T0:%.*]] = bitcast i8* [[P]] to [[A:%.*]]* + // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[T0]]) + void test0b(void *p) { + new (p, true) A(); + } + + // CHECK-LABEL: define void @_ZN6test156test1aEPv( + // CHECK: [[P:%.*]] = load i8*, i8** + // CHECK-NOT: icmp eq i8* [[P]], null + // CHECK-NOT: br i1 // CHECK: [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]* - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 5 + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 5 // CHECK-NEXT: br label // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]]) - // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1 + // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1 // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]] // CHECK-NEXT: br i1 [[DONE]] - void test1(void *p) { + void test1a(void *p) { new (p) A[5]; } + // CHECK-LABEL: define void @_ZN6test156test1bEPv( + // CHECK: [[P0:%.*]] = load i8*, i8** + // CHECK: [[P:%.*]] = call i8* @_ZnamPvb(i64 13, i8* [[P0]] + // CHECK-NEXT: icmp eq i8* [[P]], null + // CHECK-NEXT: br i1 + // CHECK: [[AFTER_COOKIE:%.*]] = getelementptr inbounds i8, i8* [[P]], i64 8 + // CHECK: [[BEGIN:%.*]] = bitcast i8* [[AFTER_COOKIE]] to [[A:%.*]]* + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 5 + // CHECK-NEXT: br label + // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] + // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]]) + // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1 + // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]] + // CHECK-NEXT: br i1 [[DONE]] + void test1b(void *p) { + new (p, true) A[5]; + } + // TODO: it's okay if all these size calculations get dropped. // FIXME: maybe we should try to throw on overflow? // CHECK-LABEL: define void @_ZN6test155test2EPvi( - // CHECK: [[N:%.*]] = load i32* + // CHECK: [[N:%.*]] = load i32, i32* // CHECK-NEXT: [[T0:%.*]] = sext i32 [[N]] to i64 // CHECK-NEXT: [[T1:%.*]] = icmp slt i64 [[T0]], 0 // CHECK-NEXT: [[T2:%.*]] = select i1 [[T1]], i64 -1, i64 [[T0]] - // CHECK-NEXT: [[P:%.*]] = load i8* - // CHECK-NEXT: icmp eq i8* [[P]], null - // CHECK-NEXT: br i1 + // CHECK-NEXT: [[P:%.*]] = load i8*, i8** // CHECK: [[BEGIN:%.*]] = bitcast i8* [[P]] to [[A:%.*]]* // CHECK-NEXT: [[ISEMPTY:%.*]] = icmp eq i64 [[T0]], 0 // CHECK-NEXT: br i1 [[ISEMPTY]], - // CHECK: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 [[T0]] + // CHECK: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 [[T0]] // CHECK-NEXT: br label // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], // CHECK-NEXT: call void @_ZN6test151AC1Ev([[A]]* [[CUR]]) @@ -290,14 +321,14 @@ namespace N3664 { // CHECK-LABEL: define void @_ZN5N36641fEv void f() { // CHECK: call noalias i8* @_Znwm(i64 4) [[ATTR_BUILTIN_NEW:#[^ ]*]] - int *p = new int; + int *p = new int; // expected-note {{allocated with 'new' here}} // CHECK: call void @_ZdlPv({{.*}}) [[ATTR_BUILTIN_DELETE:#[^ ]*]] delete p; // CHECK: call noalias i8* @_Znam(i64 12) [[ATTR_BUILTIN_NEW]] int *q = new int[3]; // CHECK: call void @_ZdaPv({{.*}}) [[ATTR_BUILTIN_DELETE]] - delete [] p; + delete[] p; // expected-warning {{'delete[]' applied to a pointer that was allocated with 'new'; did you mean 'delete'?}} // CHECK: call i8* @_ZnamRKSt9nothrow_t(i64 3, {{.*}}) [[ATTR_BUILTIN_NOTHROW_NEW:#[^ ]*]] (void) new (nothrow) S[3]; diff --git a/test/CodeGenCXX/no-opt-volatile-memcpy.cpp b/test/CodeGenCXX/no-opt-volatile-memcpy.cpp index d1e2e1d..a061daa 100644 --- a/test/CodeGenCXX/no-opt-volatile-memcpy.cpp +++ b/test/CodeGenCXX/no-opt-volatile-memcpy.cpp @@ -19,9 +19,9 @@ void foo (void) { // CHECK-NEXT: %[[ZERO:.*]] = bitcast %struct.s* %[[LS]] to i8* // CHECK-NEXT: %[[ONE:.*]] = bitcast %struct.s* %[[LS]] to i8* // CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* %[[ZERO]], i8* %[[ONE]], i64 132, i32 4, i1 true) -// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* getelementptr inbounds (%struct.s* @gs, i32 0, i32 0, i32 0), i8* getelementptr inbounds (%struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true) +// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* getelementptr inbounds (%struct.s, %struct.s* @gs, i32 0, i32 0, i32 0), i8* getelementptr inbounds (%struct.s, %struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true) // CHECK-NEXT: %[[TWO:.*]] = bitcast %struct.s* %[[LS]] to i8* -// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* %[[TWO]], i8* getelementptr inbounds (%struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true) +// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* %[[TWO]], i8* getelementptr inbounds (%struct.s, %struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true) struct s1 { @@ -35,8 +35,8 @@ void fee (void) { s.y = gs; } // CHECK-LABEL: define void @_Z3feev() -// CHECK: call void @llvm.memcpy.{{.*}}(i8* getelementptr inbounds (%struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i8* getelementptr inbounds (%struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true) -// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* getelementptr inbounds (%struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i8* getelementptr inbounds (%struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true) +// CHECK: call void @llvm.memcpy.{{.*}}(i8* getelementptr inbounds (%struct.s1, %struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i8* getelementptr inbounds (%struct.s1, %struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true) +// CHECK-NEXT: call void @llvm.memcpy.{{.*}}(i8* getelementptr inbounds (%struct.s1, %struct.s1* @s, i32 0, i32 0, i32 0, i32 0), i8* getelementptr inbounds (%struct.s, %struct.s* @gs, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true) struct d : s1 { }; @@ -47,4 +47,4 @@ void gorf(void) { gd = gd; } // CHECK-LABEL: define void @_Z4gorfv() -// CHECK: call void @llvm.memcpy.{{.*}}(i8* getelementptr inbounds (%struct.d* @gd, i32 0, i32 0, i32 0, i32 0, i32 0), i8* getelementptr inbounds (%struct.d* @gd, i32 0, i32 0, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true) +// CHECK: call void @llvm.memcpy.{{.*}}(i8* getelementptr inbounds (%struct.d, %struct.d* @gd, i32 0, i32 0, i32 0, i32 0, i32 0), i8* getelementptr inbounds (%struct.d, %struct.d* @gd, i32 0, i32 0, i32 0, i32 0, i32 0), i64 132, i32 4, i1 true) diff --git a/test/CodeGenCXX/noexcept.cpp b/test/CodeGenCXX/noexcept.cpp index dd4cfda..9d90484 100644 --- a/test/CodeGenCXX/noexcept.cpp +++ b/test/CodeGenCXX/noexcept.cpp @@ -39,7 +39,7 @@ namespace test0 { // CHECK-NEXT: call void @__clang_call_terminate(i8* [[T1]]) // CHECK-NEXT: unreachable // The terminate handler chained to by the cleanup lpad. -// CHECK: [[T0:%.*]] = load i8** [[EXN]] +// CHECK: [[T0:%.*]] = load i8*, i8** [[EXN]] // CHECK-NEXT: call void @__clang_call_terminate(i8* [[T0]]) // CHECK-NEXT: unreachable diff --git a/test/CodeGenCXX/nrvo.cpp b/test/CodeGenCXX/nrvo.cpp index aad287d..f4ed7cd 100644 --- a/test/CodeGenCXX/nrvo.cpp +++ b/test/CodeGenCXX/nrvo.cpp @@ -54,16 +54,22 @@ X test2(bool B) { return x; // CHECK: call {{.*}} @_ZN1XC1Ev + // CHECK-NEXT: {{.*}} getelementptr inbounds %class.X, %class.X* %y, i32 0, i32 0 + // CHECK-NEXT: call void @llvm.lifetime.start // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev // CHECK: call {{.*}} @_ZN1XC1ERKS_ // CHECK: call {{.*}} @_ZN1XC1ERKS_ // CHECK: call {{.*}} @_ZN1XD1Ev + // CHECK-NEXT: call void @llvm.lifetime.end // CHECK: call {{.*}} @_ZN1XD1Ev + // CHECK-NEXT: call void @llvm.lifetime.end // CHECK: ret void // The block ordering in the -fexceptions IR is unfortunate. - // CHECK-EH: call {{.*}} @_ZN1XC1Ev + // CHECK-EH: call void @llvm.lifetime.start + // CHECK-EH-NEXT: call {{.*}} @_ZN1XC1Ev + // CHECK-EH: call void @llvm.lifetime.start // CHECK-EH-NEXT: invoke {{.*}} @_ZN1XC1Ev // -> %invoke.cont, %lpad @@ -96,7 +102,9 @@ X test2(bool B) { // -> %invoke.cont11, %lpad // %invoke.cont11: normal cleanup for 'x' - // CHECK-EH: call {{.*}} @_ZN1XD1Ev + // CHECK-EH: call void @llvm.lifetime.end + // CHECK-EH-NEXT: call {{.*}} @_ZN1XD1Ev + // CHECK-EH-NEXT: call void @llvm.lifetime.end // CHECK-EH-NEXT: ret void // %eh.cleanup: EH cleanup for 'x' @@ -168,9 +176,12 @@ X test6() { X a __attribute__((aligned(8))); return a; // CHECK: [[A:%.*]] = alloca [[X:%.*]], align 8 + // CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds %class.X, %class.X* [[A]], i32 0, i32 0 + // CHECK-NEXT: call void @llvm.lifetime.start(i64 1, i8* [[PTR]]) // CHECK-NEXT: call {{.*}} @_ZN1XC1Ev([[X]]* [[A]]) // CHECK-NEXT: call {{.*}} @_ZN1XC1ERKS_([[X]]* {{%.*}}, [[X]]* dereferenceable({{[0-9]+}}) [[A]]) // CHECK-NEXT: call {{.*}} @_ZN1XD1Ev([[X]]* [[A]]) + // CHECK-NEXT: call void @llvm.lifetime.end(i64 1, i8* [[PTR]]) // CHECK-NEXT: ret void } diff --git a/test/CodeGenCXX/override-layout.cpp b/test/CodeGenCXX/override-layout.cpp index 418c4ff..a3c4bb4 100644 --- a/test/CodeGenCXX/override-layout.cpp +++ b/test/CodeGenCXX/override-layout.cpp @@ -1,6 +1,6 @@ -// RUN: %clang_cc1 -fdump-record-layouts-simple %s > %t.layouts -// RUN: %clang_cc1 -fdump-record-layouts-simple %s > %t.before -// RUN: %clang_cc1 -DPACKED= -DALIGNED16= -fdump-record-layouts-simple -foverride-record-layout=%t.layouts %s > %t.after +// RUN: %clang_cc1 -w -fdump-record-layouts-simple %s > %t.layouts +// RUN: %clang_cc1 -w -fdump-record-layouts-simple %s > %t.before +// RUN: %clang_cc1 -w -DPACKED= -DALIGNED16= -fdump-record-layouts-simple -foverride-record-layout=%t.layouts %s > %t.after // RUN: diff -u %t.before %t.after // RUN: FileCheck %s < %t.after diff --git a/test/CodeGenCXX/partial-destruction.cpp b/test/CodeGenCXX/partial-destruction.cpp index 22daebe..01e2894 100644 --- a/test/CodeGenCXX/partial-destruction.cpp +++ b/test/CodeGenCXX/partial-destruction.cpp @@ -18,19 +18,19 @@ namespace test0 { // CHECK-NEXT: [[SEL:%.*]] = alloca i32 // Initialize. - // CHECK-NEXT: [[E_BEGIN:%.*]] = getelementptr inbounds [10 x [[A]]]* [[AS]], i64 0, i64 0 + // CHECK-NEXT: [[E_BEGIN:%.*]] = getelementptr inbounds [10 x [[A]]], [10 x [[A]]]* [[AS]], i64 0, i64 0 // CHECK-NEXT: store [[A]]* [[E_BEGIN]], [[A]]** [[ENDVAR]] // CHECK-NEXT: invoke void @_ZN5test01AC1Ei([[A]]* [[E_BEGIN]], i32 5) - // CHECK: [[E1:%.*]] = getelementptr inbounds [[A]]* [[E_BEGIN]], i64 1 + // CHECK: [[E1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[E_BEGIN]], i64 1 // CHECK-NEXT: store [[A]]* [[E1]], [[A]]** [[ENDVAR]] // CHECK-NEXT: invoke void @_ZN5test01AC1Ei([[A]]* [[E1]], i32 7) - // CHECK: [[E2:%.*]] = getelementptr inbounds [[A]]* [[E1]], i64 1 + // CHECK: [[E2:%.*]] = getelementptr inbounds [[A]], [[A]]* [[E1]], i64 1 // CHECK-NEXT: store [[A]]* [[E2]], [[A]]** [[ENDVAR]] - // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]]* [[E_BEGIN]], i64 10 + // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[E_BEGIN]], i64 10 // CHECK-NEXT: br label // CHECK: [[E_CUR:%.*]] = phi [[A]]* [ [[E2]], {{%.*}} ], [ [[E_NEXT:%.*]], {{%.*}} ] // CHECK-NEXT: invoke void @_ZN5test01AC1Ev([[A]]* [[E_CUR]]) - // CHECK: [[E_NEXT]] = getelementptr inbounds [[A]]* [[E_CUR]], i64 1 + // CHECK: [[E_NEXT]] = getelementptr inbounds [[A]], [[A]]* [[E_CUR]], i64 1 // CHECK-NEXT: store [[A]]* [[E_NEXT]], [[A]]** [[ENDVAR]] // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[E_NEXT]], [[E_END]] // CHECK-NEXT: br i1 [[T0]], @@ -39,11 +39,11 @@ namespace test0 { // CHECK: invoke void @_Z6opaquev() // Normal destroy. - // CHECK: [[ED_BEGIN:%.*]] = getelementptr inbounds [10 x [[A]]]* [[AS]], i32 0, i32 0 - // CHECK-NEXT: [[ED_END:%.*]] = getelementptr inbounds [[A]]* [[ED_BEGIN]], i64 10 + // CHECK: [[ED_BEGIN:%.*]] = getelementptr inbounds [10 x [[A]]], [10 x [[A]]]* [[AS]], i32 0, i32 0 + // CHECK-NEXT: [[ED_END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ED_BEGIN]], i64 10 // CHECK-NEXT: br label // CHECK: [[ED_AFTER:%.*]] = phi [[A]]* [ [[ED_END]], {{%.*}} ], [ [[ED_CUR:%.*]], {{%.*}} ] - // CHECK-NEXT: [[ED_CUR]] = getelementptr inbounds [[A]]* [[ED_AFTER]], i64 -1 + // CHECK-NEXT: [[ED_CUR]] = getelementptr inbounds [[A]], [[A]]* [[ED_AFTER]], i64 -1 // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[ED_CUR]]) // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ED_CUR]], [[ED_BEGIN]] // CHECK-NEXT: br i1 [[T0]], @@ -52,11 +52,11 @@ namespace test0 { // Partial destroy for initialization. // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) // CHECK-NEXT: cleanup - // CHECK: [[PARTIAL_END:%.*]] = load [[A]]** [[ENDVAR]] + // CHECK: [[PARTIAL_END:%.*]] = load [[A]]*, [[A]]** [[ENDVAR]] // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[E_BEGIN]], [[PARTIAL_END]] // CHECK-NEXT: br i1 [[T0]], // CHECK: [[E_AFTER:%.*]] = phi [[A]]* [ [[PARTIAL_END]], {{%.*}} ], [ [[E_CUR:%.*]], {{%.*}} ] - // CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]]* [[E_AFTER]], i64 -1 + // CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]], [[A]]* [[E_AFTER]], i64 -1 // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]]) // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[E_CUR]], [[E_BEGIN]] // CHECK-NEXT: br i1 [[T0]], @@ -64,8 +64,8 @@ namespace test0 { // Primary EH destructor. // CHECK: landingpad { i8*, i32 } personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) // CHECK-NEXT: cleanup - // CHECK: [[E0:%.*]] = getelementptr inbounds [10 x [[A]]]* [[AS]], i32 0, i32 0 - // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]]* [[E0]], i64 10 + // CHECK: [[E0:%.*]] = getelementptr inbounds [10 x [[A]]], [10 x [[A]]]* [[AS]], i32 0, i32 0 + // CHECK-NEXT: [[E_END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[E0]], i64 10 // CHECK-NEXT: br label // Partial destructor for primary normal destructor. @@ -77,14 +77,14 @@ namespace test0 { // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[ED_BEGIN]], [[ED_CUR]] // CHECK-NEXT: br i1 [[T0]] // CHECK: [[EDD_AFTER:%.*]] = phi [[A]]* [ [[ED_CUR]], {{%.*}} ], [ [[EDD_CUR:%.*]], {{%.*}} ] - // CHECK-NEXT: [[EDD_CUR]] = getelementptr inbounds [[A]]* [[EDD_AFTER]], i64 -1 + // CHECK-NEXT: [[EDD_CUR]] = getelementptr inbounds [[A]], [[A]]* [[EDD_AFTER]], i64 -1 // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[EDD_CUR]]) // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[EDD_CUR]], [[ED_BEGIN]] // CHECK-NEXT: br i1 [[T0]] // Back to the primary EH destructor. // CHECK: [[E_AFTER:%.*]] = phi [[A]]* [ [[E_END]], {{%.*}} ], [ [[E_CUR:%.*]], {{%.*}} ] - // CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]]* [[E_AFTER]], i64 -1 + // CHECK-NEXT: [[E_CUR]] = getelementptr inbounds [[A]], [[A]]* [[E_AFTER]], i64 -1 // CHECK-NEXT: invoke void @_ZN5test01AD1Ev([[A]]* [[E_CUR]]) // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[E_CUR]], [[E0]] // CHECK-NEXT: br i1 [[T0]], @@ -102,13 +102,13 @@ namespace test1 { // CHECK: [[V:%.*]] = alloca [[B:%.*]], align 4 // CHECK-NEXT: alloca i8* // CHECK-NEXT: alloca i32 - // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[B]]* [[V]], i32 0, i32 0 + // CHECK-NEXT: [[X:%.*]] = getelementptr inbounds [[B]], [[B]]* [[V]], i32 0, i32 0 // CHECK-NEXT: call void @_ZN5test11AC1Ei([[A:%.*]]* [[X]], i32 5) - // CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds [[B]]* [[V]], i32 0, i32 1 + // CHECK-NEXT: [[Y:%.*]] = getelementptr inbounds [[B]], [[B]]* [[V]], i32 0, i32 1 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[Y]], i32 6) - // CHECK: [[Z:%.*]] = getelementptr inbounds [[B]]* [[V]], i32 0, i32 2 + // CHECK: [[Z:%.*]] = getelementptr inbounds [[B]], [[B]]* [[V]], i32 0, i32 2 // CHECK-NEXT: invoke void @_ZN5test11AC1Ei([[A]]* [[Z]], i32 7) - // CHECK: [[W:%.*]] = getelementptr inbounds [[B]]* [[V]], i32 0, i32 3 + // CHECK: [[W:%.*]] = getelementptr inbounds [[B]], [[B]]* [[V]], i32 0, i32 3 // CHECK-NEXT: store i32 8, i32* [[W]], align 4 // CHECK-NEXT: call void @_ZN5test11BD1Ev([[B]]* [[V]]) // CHECK-NEXT: ret void @@ -134,12 +134,12 @@ namespace test2 { // CHECK-NEXT: alloca i32 // Main initialization loop. - // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x [7 x [[A]]]]* [[V]], i32 0, i32 0, i32 0 - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 28 + // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [4 x [7 x [[A]]]], [4 x [7 x [[A]]]]* [[V]], i32 0, i32 0, i32 0 + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 28 // CHECK-NEXT: br label // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] // CHECK-NEXT: invoke void @_ZN5test21AC1Ev([[A]]* [[CUR]]) - // CHECK: [[NEXT:%.*]] = getelementptr inbounds [[A]]* [[CUR]], i64 1 + // CHECK: [[NEXT:%.*]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1 // CHECK-NEXT: [[DONE:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]] // CHECK-NEXT: br i1 [[DONE]], @@ -149,7 +149,7 @@ namespace test2 { // CHECK: [[EMPTY:%.*]] = icmp eq [[A]]* [[BEGIN]], [[CUR]] // CHECK-NEXT: br i1 [[EMPTY]], // CHECK: [[PAST:%.*]] = phi [[A]]* [ [[CUR]], {{%.*}} ], [ [[DEL:%.*]], {{%.*}} ] - // CHECK-NEXT: [[DEL]] = getelementptr inbounds [[A]]* [[PAST]], i64 -1 + // CHECK-NEXT: [[DEL]] = getelementptr inbounds [[A]], [[A]]* [[PAST]], i64 -1 // CHECK-NEXT: invoke void @_ZN5test21AD1Ev([[A]]* [[DEL]]) // CHECK: [[T0:%.*]] = icmp eq [[A]]* [[DEL]], [[BEGIN]] // CHECK-NEXT: br i1 [[T0]], diff --git a/test/CodeGenCXX/pod-member-memcpys.cpp b/test/CodeGenCXX/pod-member-memcpys.cpp index a3ee990..97d203f 100644 --- a/test/CodeGenCXX/pod-member-memcpys.cpp +++ b/test/CodeGenCXX/pod-member-memcpys.cpp @@ -145,7 +145,7 @@ CALL_AO(PackedMembers) // VolatileMember copy-assignment: // CHECK-LABEL: define linkonce_odr dereferenceable({{[0-9]+}}) %struct.VolatileMember* @_ZN14VolatileMemberaSERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}})) // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) -// CHECK: load volatile i32* {{.*}}, align 4 +// CHECK: load volatile i32, i32* {{.*}}, align 4 // CHECK: store volatile i32 {{.*}}, align 4 // CHECK: call dereferenceable({{[0-9]+}}) %struct.NonPOD* @_ZN6NonPODaSERKS_ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) @@ -180,90 +180,89 @@ CALL_AO(PackedMembers) #define CALL_CC(T) T callCC##T(const T& b) { return b; } CALL_CC(PackedMembers) +// PackedMembers copy-assignment: +// CHECK-LABEL: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* dereferenceable({{[0-9]+}})) +// CHECK: call void @_ZN6NonPODC1ERKS_ +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}}) +// CHECK: ret void + CALL_CC(BitfieldMember2) +// BitfieldMember2 copy-constructor: +// CHECK-2-LABEL: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2* dereferenceable({{[0-9]+}})) +// CHECK-2: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4, i1 false) +// CHECK-2: call void @_ZN6NonPODC1ERKS_ +// CHECK-2: ret void + CALL_CC(BitfieldMember3) -CALL_CC(ReferenceMember) -CALL_CC(InnerClassMember) -CALL_CC(BitfieldMember) -CALL_CC(VolatileMember) -CALL_CC(ArrayMember) -CALL_CC(PODLikeMember) -CALL_CC(PODMember) -CALL_CC(Basic) +// BitfieldMember3 copy-constructor: +// CHECK-LABEL: define linkonce_odr void @_ZN15BitfieldMember3C2ERKS_(%struct.BitfieldMember3* %this, %struct.BitfieldMember3* dereferenceable({{[0-9]+}})) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 8, i32 8, i1 false) +// CHECK: ret void -// Basic copy-constructor: -// CHECK-LABEL: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic* dereferenceable({{[0-9]+}})) -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) +CALL_CC(ReferenceMember) +// ReferenceMember copy-constructor: +// CHECK-LABEL: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember* dereferenceable({{[0-9]+}})) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}}) // CHECK: call void @_ZN6NonPODC1ERKS_ -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}}) // CHECK: ret void -// PODMember copy-constructor: -// CHECK-LABEL: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember* dereferenceable({{[0-9]+}})) +CALL_CC(InnerClassMember) +// InnerClass copy-constructor: +// CHECK-LABEL: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* dereferenceable({{[0-9]+}})) // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}}) // CHECK: call void @_ZN6NonPODC1ERKS_ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) // CHECK: ret void -// PODLikeMember copy-constructor: -// CHECK-LABEL: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* dereferenceable({{[0-9]+}})) -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}}) -// CHECK: invoke void @_ZN6NonPODC1ERKS_ +CALL_CC(BitfieldMember) +// BitfieldMember copy-constructor: +// CHECK-LABEL: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* dereferenceable({{[0-9]+}})) // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) -// CHECK: ret void -// CHECK: landingpad -// CHECK: invoke void @_ZN7PODLikeD1Ev - -// ArrayMember copy-constructor: -// CHECK-LABEL: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* dereferenceable({{[0-9]+}})) -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}}) // CHECK: call void @_ZN6NonPODC1ERKS_ -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}}) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}}) // CHECK: ret void +CALL_CC(VolatileMember) // VolatileMember copy-constructor: // CHECK-LABEL: define linkonce_odr void @_ZN14VolatileMemberC2ERKS_(%struct.VolatileMember* %this, %struct.VolatileMember* dereferenceable({{[0-9]+}})) // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) -// CHECK: load volatile i32* {{.*}}, align 4 +// CHECK: load volatile i32, i32* {{.*}}, align 4 // CHECK: store volatile i32 {{.*}}, align 4 // CHECK: call void @_ZN6NonPODC1ERKS_ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) // CHECK: ret void -// BitfieldMember copy-constructor: -// CHECK-LABEL: define linkonce_odr void @_ZN14BitfieldMemberC2ERKS_(%struct.BitfieldMember* %this, %struct.BitfieldMember* dereferenceable({{[0-9]+}})) -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) +CALL_CC(ArrayMember) +// ArrayMember copy-constructor: +// CHECK-LABEL: define linkonce_odr void @_ZN11ArrayMemberC2ERKS_(%struct.ArrayMember* %this, %struct.ArrayMember* dereferenceable({{[0-9]+}})) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}}) // CHECK: call void @_ZN6NonPODC1ERKS_ -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 3, i32 1{{.*}}) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 64, i32 4{{.*}}) // CHECK: ret void -// InnerClass copy-constructor: -// CHECK-LABEL: define linkonce_odr void @_ZN16InnerClassMemberC2ERKS_(%struct.InnerClassMember* %this, %struct.InnerClassMember* dereferenceable({{[0-9]+}})) +CALL_CC(PODLikeMember) +// PODLikeMember copy-constructor: +// CHECK-LABEL: define linkonce_odr void @_ZN13PODLikeMemberC2ERKS_(%struct.PODLikeMember* %this, %struct.PODLikeMember* dereferenceable({{[0-9]+}})) // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}}) -// CHECK: call void @_ZN6NonPODC1ERKS_ +// CHECK: invoke void @_ZN6NonPODC1ERKS_ // CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) // CHECK: ret void +// CHECK: landingpad +// CHECK: invoke void @_ZN7PODLikeD1Ev -// ReferenceMember copy-constructor: -// CHECK-LABEL: define linkonce_odr void @_ZN15ReferenceMemberC2ERKS_(%struct.ReferenceMember* %this, %struct.ReferenceMember* dereferenceable({{[0-9]+}})) -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}}) +CALL_CC(PODMember) +// PODMember copy-constructor: +// CHECK-LABEL: define linkonce_odr void @_ZN9PODMemberC2ERKS_(%struct.PODMember* %this, %struct.PODMember* dereferenceable({{[0-9]+}})) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 32, i32 4{{.*}}) // CHECK: call void @_ZN6NonPODC1ERKS_ -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 8{{.*}}) -// CHECK: ret void - -// BitfieldMember3 copy-constructor: -// CHECK-LABEL: define linkonce_odr void @_ZN15BitfieldMember3C2ERKS_(%struct.BitfieldMember3* %this, %struct.BitfieldMember3* dereferenceable({{[0-9]+}})) -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 8, i32 8, i1 false) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) // CHECK: ret void -// BitfieldMember2 copy-constructor: -// CHECK-2-LABEL: define linkonce_odr void @_ZN15BitfieldMember2C2ERKS_(%struct.BitfieldMember2* %this, %struct.BitfieldMember2* dereferenceable({{[0-9]+}})) -// CHECK-2: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4, i1 false) -// CHECK-2: call void @_ZN6NonPODC1ERKS_ -// CHECK-2: ret void - -// PackedMembers copy-assignment: -// CHECK-LABEL: define linkonce_odr void @_ZN13PackedMembersC2ERKS_(%struct.PackedMembers* %this, %struct.PackedMembers* dereferenceable({{[0-9]+}})) +CALL_CC(Basic) +// Basic copy-constructor: +// CHECK-LABEL: define linkonce_odr void @_ZN5BasicC2ERKS_(%struct.Basic* %this, %struct.Basic* dereferenceable({{[0-9]+}})) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) // CHECK: call void @_ZN6NonPODC1ERKS_ -// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 1{{.*}}) +// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64({{.*}}i64 16, i32 4{{.*}}) // CHECK: ret void diff --git a/test/CodeGenCXX/pointers-to-data-members.cpp b/test/CodeGenCXX/pointers-to-data-members.cpp index 0b99fea..0f2ddaa 100644 --- a/test/CodeGenCXX/pointers-to-data-members.cpp +++ b/test/CodeGenCXX/pointers-to-data-members.cpp @@ -75,14 +75,14 @@ void f() { // CHECK: store i64 -1, i64* @_ZN5Casts2paE pa = 0; - // CHECK-NEXT: [[TMP:%.*]] = load i64* @_ZN5Casts2paE, align 8 + // CHECK-NEXT: [[TMP:%.*]] = load i64, i64* @_ZN5Casts2paE, align 8 // CHECK-NEXT: [[ADJ:%.*]] = add nsw i64 [[TMP]], 4 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1 // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]] // CHECK-NEXT: store i64 [[RES]], i64* @_ZN5Casts2pcE pc = pa; - // CHECK-NEXT: [[TMP:%.*]] = load i64* @_ZN5Casts2pcE, align 8 + // CHECK-NEXT: [[TMP:%.*]] = load i64, i64* @_ZN5Casts2pcE, align 8 // CHECK-NEXT: [[ADJ:%.*]] = sub nsw i64 [[TMP]], 4 // CHECK-NEXT: [[ISNULL:%.*]] = icmp eq i64 [[TMP]], -1 // CHECK-NEXT: [[RES:%.*]] = select i1 [[ISNULL]], i64 [[TMP]], i64 [[ADJ]] @@ -205,7 +205,7 @@ namespace BoolPtrToMember { // CHECK-LABEL: define dereferenceable({{[0-9]+}}) i8* @_ZN15BoolPtrToMember1fERNS_1XEMS0_b bool &f(X &x, bool X::*member) { // CHECK: {{bitcast.* to i8\*}} - // CHECK-NEXT: getelementptr inbounds i8* + // CHECK-NEXT: getelementptr inbounds i8, i8* // CHECK-NEXT: ret i8* return x.*member; } @@ -277,4 +277,12 @@ U u; // CHECK-GLOBAL: @_ZN7PR212821uE = global %"union.PR21282::U" { i64 -1, [8 x i8] zeroinitializer }, align 8 } +namespace FlexibleArrayMember { +struct S { + int S::*x[]; +}; +S s; +// CHECK-GLOBAL: @_ZN19FlexibleArrayMember1sE = global %"struct.FlexibleArrayMember::S" zeroinitializer, align 8 +} + // CHECK-O3: attributes [[NUW]] = { nounwind readnone{{.*}} } diff --git a/test/CodeGenCXX/powerpc-byval.cpp b/test/CodeGenCXX/powerpc-byval.cpp new file mode 100644 index 0000000..ff87618 --- /dev/null +++ b/test/CodeGenCXX/powerpc-byval.cpp @@ -0,0 +1,12 @@ +// RUN: %clang_cc1 -emit-llvm %s -o - -triple=powerpc-unknown-linux | FileCheck %s + +struct S { + S(); + ~S(); +}; + +void byval(S one, S two) { + one = two; +} + +// CHECK: define void @_Z5byval1SS_(%struct.S* %one, %struct.S* %two) diff --git a/test/CodeGenCXX/pr12251.cpp b/test/CodeGenCXX/pr12251.cpp index 5b1ef9a..49e61ca 100644 --- a/test/CodeGenCXX/pr12251.cpp +++ b/test/CodeGenCXX/pr12251.cpp @@ -5,12 +5,12 @@ bool f(bool *x) { return *x; } // CHECK-LABEL: define zeroext i1 @_Z1fPb -// CHECK: load i8* %{{[^ ]*}}, align 1, !range [[RANGE_i8_0_2:![^ ]*]] +// CHECK: load i8, i8* %{{[^ ]*}}, align 1, !range [[RANGE_i8_0_2:![^ ]*]] // Only enum-tests follow. Ensure that after the bool test, no further range // metadata shows up when strict enums are disabled. // NO-STRICT-ENUMS-LABEL: define zeroext i1 @_Z1fPb -// NO-STRICT-ENUMS: load i8* %{{[^ ]*}}, align 1, !range +// NO-STRICT-ENUMS: load i8, i8* %{{[^ ]*}}, align 1, !range // NO-STRICT-ENUMS-NOT: !range enum e1 { }; @@ -32,70 +32,70 @@ e3 g3(e3 *x) { return *x; } // CHECK-LABEL: define i32 @_Z2g3P2e3 -// CHECK: load i32* %x, align 4, !range [[RANGE_i32_0_32:![^ ]*]] +// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_0_32:![^ ]*]] enum e4 { e4_a = -16}; e4 g4(e4 *x) { return *x; } // CHECK-LABEL: define i32 @_Z2g4P2e4 -// CHECK: load i32* %x, align 4, !range [[RANGE_i32_m16_16:![^ ]*]] +// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m16_16:![^ ]*]] enum e5 { e5_a = -16, e5_b = 16}; e5 g5(e5 *x) { return *x; } // CHECK-LABEL: define i32 @_Z2g5P2e5 -// CHECK: load i32* %x, align 4, !range [[RANGE_i32_m32_32:![^ ]*]] +// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m32_32:![^ ]*]] enum e6 { e6_a = -1 }; e6 g6(e6 *x) { return *x; } // CHECK-LABEL: define i32 @_Z2g6P2e6 -// CHECK: load i32* %x, align 4, !range [[RANGE_i32_m1_1:![^ ]*]] +// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m1_1:![^ ]*]] enum e7 { e7_a = -16, e7_b = 2}; e7 g7(e7 *x) { return *x; } // CHECK-LABEL: define i32 @_Z2g7P2e7 -// CHECK: load i32* %x, align 4, !range [[RANGE_i32_m16_16]] +// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m16_16]] enum e8 { e8_a = -17}; e8 g8(e8 *x) { return *x; } // CHECK-LABEL: define i32 @_Z2g8P2e8 -// CHECK: load i32* %x, align 4, !range [[RANGE_i32_m32_32:![^ ]*]] +// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m32_32:![^ ]*]] enum e9 { e9_a = 17}; e9 g9(e9 *x) { return *x; } // CHECK-LABEL: define i32 @_Z2g9P2e9 -// CHECK: load i32* %x, align 4, !range [[RANGE_i32_0_32]] +// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_0_32]] enum e10 { e10_a = -16, e10_b = 32}; e10 g10(e10 *x) { return *x; } // CHECK-LABEL: define i32 @_Z3g10P3e10 -// CHECK: load i32* %x, align 4, !range [[RANGE_i32_m64_64:![^ ]*]] +// CHECK: load i32, i32* %x, align 4, !range [[RANGE_i32_m64_64:![^ ]*]] enum e11 {e11_a = 4294967296 }; enum e11 g11(enum e11 *x) { return *x; } // CHECK-LABEL: define i64 @_Z3g11P3e11 -// CHECK: load i64* %x, align {{[84]}}, !range [[RANGE_i64_0_2pow33:![^ ]*]] +// CHECK: load i64, i64* %x, align {{[84]}}, !range [[RANGE_i64_0_2pow33:![^ ]*]] enum e12 {e12_a = 9223372036854775808U }; enum e12 g12(enum e12 *x) { return *x; } // CHECK-LABEL: define i64 @_Z3g12P3e12 -// CHECK: load i64* %x, align {{[84]}} +// CHECK: load i64, i64* %x, align {{[84]}} // CHECK-NOT: range // CHECK: ret @@ -104,7 +104,7 @@ e13 g13(e13 *x) { return *x; } // CHECK-LABEL: define signext i8 @_Z3g13P3e13 -// CHECK: load i8* %x, align 1 +// CHECK: load i8, i8* %x, align 1 // CHECK-NOT: range // CHECK: ret @@ -113,7 +113,7 @@ e14 g14(e14 *x) { return *x; } // CHECK-LABEL: define i32 @_Z3g14P3e14 -// CHECK: load i32* %x, align 4 +// CHECK: load i32, i32* %x, align 4 // CHECK-NOT: range // CHECK: ret @@ -122,7 +122,7 @@ e15 g15(e15 *x) { return *x; } // CHECK-LABEL: define i32 @_Z3g15P3e15 -// CHECK: load i32* %x, align 4 +// CHECK: load i32, i32* %x, align 4 // CHECK-NOT: range // CHECK: ret @@ -131,7 +131,7 @@ e16 g16(e16 *x) { return *x; } // CHECK-LABEL: define i32 @_Z3g16P3e16 -// CHECK: load i32* %x, align 4 +// CHECK: load i32, i32* %x, align 4 // CHECK-NOT: range // CHECK: ret diff --git a/test/CodeGenCXX/pr20897.cpp b/test/CodeGenCXX/pr20897.cpp index 49d669b..9a7fdb9 100644 --- a/test/CodeGenCXX/pr20897.cpp +++ b/test/CodeGenCXX/pr20897.cpp @@ -1,16 +1,16 @@ -// RUN: %clang_cc1 -triple i686-windows-msvc -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s +// RUN: %clang_cc1 -triple i686-windows-msvc -fms-extensions -emit-llvm -std=c++1y -O0 -o - %s | FileCheck %s struct Base {}; // __declspec(dllexport) causes us to export the implicit constructor. struct __declspec(dllexport) Derived : virtual Base { // CHECK-LABEL: define weak_odr dllexport x86_thiscallcc %struct.Derived* @"\01??0Derived@@QAE@ABU0@@Z" -// CHECK: %[[this:.*]] = load %struct.Derived** {{.*}} +// CHECK: %[[this:.*]] = load %struct.Derived*, %struct.Derived** {{.*}} // CHECK-NEXT: store %struct.Derived* %[[this]], %struct.Derived** %[[retval:.*]] -// CHECK: %[[dest_a_gep:.*]] = getelementptr inbounds %struct.Derived* %[[this]], i32 0, i32 1 -// CHECK-NEXT: %[[src_load:.*]] = load %struct.Derived** {{.*}} -// CHECK-NEXT: %[[src_a_gep:.*]] = getelementptr inbounds %struct.Derived* %[[src_load:.*]], i32 0, i32 1 +// CHECK: %[[dest_a_gep:.*]] = getelementptr inbounds %struct.Derived, %struct.Derived* %[[this]], i32 0, i32 1 +// CHECK-NEXT: %[[src_load:.*]] = load %struct.Derived*, %struct.Derived** {{.*}} +// CHECK-NEXT: %[[src_a_gep:.*]] = getelementptr inbounds %struct.Derived, %struct.Derived* %[[src_load:.*]], i32 0, i32 1 // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* %[[dest_a_gep]], i8* %[[src_a_gep]], i64 1, i32 4, i1 false) -// CHECK-NEXT: %[[dest_this:.*]] = load %struct.Derived** %[[retval]] +// CHECK-NEXT: %[[dest_this:.*]] = load %struct.Derived*, %struct.Derived** %[[retval]] // CHECK-NEXT: ret %struct.Derived* %[[dest_this]] bool a : 1; bool b : 1; @@ -19,15 +19,15 @@ struct __declspec(dllexport) Derived : virtual Base { // __declspec(dllexport) causes us to export the implicit copy constructor. struct __declspec(dllexport) Derived2 : virtual Base { // CHECK-LABEL: define weak_odr dllexport x86_thiscallcc %struct.Derived2* @"\01??0Derived2@@QAE@ABU0@@Z" -// CHECK: %[[this:.*]] = load %struct.Derived2** {{.*}} +// CHECK: %[[this:.*]] = load %struct.Derived2*, %struct.Derived2** {{.*}} // CHECK-NEXT: store %struct.Derived2* %[[this]], %struct.Derived2** %[[retval:.*]] -// CHECK: %[[dest_a_gep:.*]] = getelementptr inbounds %struct.Derived2* %[[this]], i32 0, i32 1 -// CHECK-NEXT: %[[src_load:.*]] = load %struct.Derived2** {{.*}} -// CHECK-NEXT: %[[src_a_gep:.*]] = getelementptr inbounds %struct.Derived2* %[[src_load:.*]], i32 0, i32 1 +// CHECK: %[[dest_a_gep:.*]] = getelementptr inbounds %struct.Derived2, %struct.Derived2* %[[this]], i32 0, i32 1 +// CHECK-NEXT: %[[src_load:.*]] = load %struct.Derived2*, %struct.Derived2** {{.*}} +// CHECK-NEXT: %[[src_a_gep:.*]] = getelementptr inbounds %struct.Derived2, %struct.Derived2* %[[src_load:.*]], i32 0, i32 1 // CHECK-NEXT: %[[dest_a_bitcast:.*]] = bitcast [1 x i32]* %[[dest_a_gep]] to i8* // CHECK-NEXT: %[[src_a_bitcast:.*]] = bitcast [1 x i32]* %[[src_a_gep]] to i8* // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* %[[dest_a_bitcast]], i8* %[[src_a_bitcast]], i32 4, i32 4, i1 false) -// CHECK-NEXT: %[[dest_this:.*]] = load %struct.Derived2** %[[retval]] +// CHECK-NEXT: %[[dest_this:.*]] = load %struct.Derived2*, %struct.Derived2** %[[retval]] // CHECK-NEXT: ret %struct.Derived2* %[[dest_this]] int Array[1]; }; diff --git a/test/CodeGenCXX/pragma-init_seg.cpp b/test/CodeGenCXX/pragma-init_seg.cpp index cc4d018..1ed841f 100644 --- a/test/CodeGenCXX/pragma-init_seg.cpp +++ b/test/CodeGenCXX/pragma-init_seg.cpp @@ -15,7 +15,7 @@ int x = f(); #pragma init_seg(lib) int y = f(); // CHECK: @"\01?y@simple_init@@3HA" = global i32 0, align 4 -// CHECK: @__cxx_init_fn_ptr1 = private constant void ()* @"\01??__Ey@simple_init@@YAXXZ", section ".CRT$XCL" +// CHECK: @__cxx_init_fn_ptr.1 = private constant void ()* @"\01??__Ey@simple_init@@YAXXZ", section ".CRT$XCL" #pragma init_seg(user) int z = f(); @@ -29,14 +29,14 @@ namespace internal_init { namespace { int x = f(); // CHECK: @"\01?x@?A@internal_init@@3HA" = internal global i32 0, align 4 -// CHECK: @__cxx_init_fn_ptr2 = private constant void ()* @"\01??__Ex@?A@internal_init@@YAXXZ", section ".asdf" +// CHECK: @__cxx_init_fn_ptr.2 = private constant void ()* @"\01??__Ex@?A@internal_init@@YAXXZ", section ".asdf" } } namespace selectany_init { int __declspec(selectany) x = f(); // CHECK: @"\01?x@selectany_init@@3HA" = weak_odr global i32 0, comdat, align 4 -// CHECK: @__cxx_init_fn_ptr3 = private constant void ()* @"\01??__Ex@selectany_init@@YAXXZ", section ".asdf", comdat($"\01?x@selectany_init@@3HA") +// CHECK: @__cxx_init_fn_ptr.3 = private constant void ()* @"\01??__Ex@selectany_init@@YAXXZ", section ".asdf", comdat($"\01?x@selectany_init@@3HA") } namespace explicit_template_instantiation { @@ -44,7 +44,7 @@ template <typename T> struct A { static const int x; }; template <typename T> const int A<T>::x = f(); template struct A<int>; // CHECK: @"\01?x@?$A@H@explicit_template_instantiation@@2HB" = weak_odr global i32 0, comdat, align 4 -// CHECK: @__cxx_init_fn_ptr4 = private constant void ()* @"\01??__Ex@?$A@H@explicit_template_instantiation@@2HB@YAXXZ", section ".asdf", comdat($"\01?x@?$A@H@explicit_template_instantiation@@2HB") +// CHECK: @__cxx_init_fn_ptr.4 = private constant void ()* @"\01??__Ex@?$A@H@explicit_template_instantiation@@2HB@YAXXZ", section ".asdf", comdat($"\01?x@?$A@H@explicit_template_instantiation@@2HB") } namespace implicit_template_instantiation { @@ -52,7 +52,7 @@ template <typename T> struct A { static const int x; }; template <typename T> const int A<T>::x = f(); int g() { return A<int>::x; } // CHECK: @"\01?x@?$A@H@implicit_template_instantiation@@2HB" = linkonce_odr global i32 0, comdat, align 4 -// CHECK: @__cxx_init_fn_ptr5 = private constant void ()* @"\01??__Ex@?$A@H@implicit_template_instantiation@@2HB@YAXXZ", section ".asdf", comdat($"\01?x@?$A@H@implicit_template_instantiation@@2HB") +// CHECK: @__cxx_init_fn_ptr.5 = private constant void ()* @"\01??__Ex@?$A@H@implicit_template_instantiation@@2HB@YAXXZ", section ".asdf", comdat($"\01?x@?$A@H@implicit_template_instantiation@@2HB") } // ... and here's where we emitted user level ctors. @@ -65,8 +65,8 @@ int g() { return A<int>::x; } // // CHECK: @llvm.used = appending global [6 x i8*] // CHECK: [i8* bitcast (void ()** @__cxx_init_fn_ptr to i8*), -// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr1 to i8*), -// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr2 to i8*), -// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr3 to i8*), -// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr4 to i8*), -// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr5 to i8*)], section "llvm.metadata" +// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.1 to i8*), +// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.2 to i8*), +// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.3 to i8*), +// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.4 to i8*), +// CHECK: i8* bitcast (void ()** @__cxx_init_fn_ptr.5 to i8*)], section "llvm.metadata" diff --git a/test/CodeGenCXX/predefined-expr.cpp b/test/CodeGenCXX/predefined-expr.cpp index 6bdc2ce..4c0a886 100644 --- a/test/CodeGenCXX/predefined-expr.cpp +++ b/test/CodeGenCXX/predefined-expr.cpp @@ -1,102 +1,102 @@ // RUN: %clang_cc1 -std=c++11 -fblocks %s -triple %itanium_abi_triple -emit-llvm -o - | FileCheck %s -// CHECK: private unnamed_addr constant [15 x i8] c"externFunction\00" -// CHECK: private unnamed_addr constant [26 x i8] c"void NS::externFunction()\00" -// CHECK: private unnamed_addr constant [49 x i8] c"void functionTemplateExplicitSpecialization(int)\00" +// CHECK-DAG: private unnamed_addr constant [15 x i8] c"externFunction\00" +// CHECK-DAG: private unnamed_addr constant [26 x i8] c"void NS::externFunction()\00" +// CHECK-DAG: private unnamed_addr constant [49 x i8] c"void functionTemplateExplicitSpecialization(int)\00" -// CHECK: private unnamed_addr constant [95 x i8] c"void SpecializedClassTemplate<char>::memberFunctionTemplate(T, U) const [T = char, U = double]\00" -// CHECK: private unnamed_addr constant [85 x i8] c"void SpecializedClassTemplate<int>::memberFunctionTemplate(int, U) const [U = float]\00" -// CHECK: private unnamed_addr constant [57 x i8] c"void NonTypeTemplateParam<42>::size() const [Count = 42]\00" -// CHECK: private unnamed_addr constant [122 x i8] c"static void ClassWithTemplateTemplateParam<char, NS::ClassTemplate>::staticMember() [T = char, Param = NS::ClassTemplate]\00" -// CHECK: private unnamed_addr constant [106 x i8] c"void OuterClass<int *>::MiddleClass::InnerClass<float>::memberFunction(T, U) const [T = int *, U = float]\00" -// CHECK: private unnamed_addr constant [51 x i8] c"void functionTemplateWithCapturedStmt(T) [T = int]\00" -// CHECK: private unnamed_addr constant [76 x i8] c"auto functionTemplateWithLambda(int)::(anonymous class)::operator()() const\00" -// CHECK: private unnamed_addr constant [65 x i8] c"void functionTemplateWithUnnamedTemplateParameter(T) [T = float]\00" +// CHECK-DAG: private unnamed_addr constant [95 x i8] c"void SpecializedClassTemplate<char>::memberFunctionTemplate(T, U) const [T = char, U = double]\00" +// CHECK-DAG: private unnamed_addr constant [85 x i8] c"void SpecializedClassTemplate<int>::memberFunctionTemplate(int, U) const [U = float]\00" +// CHECK-DAG: private unnamed_addr constant [57 x i8] c"void NonTypeTemplateParam<42>::size() const [Count = 42]\00" +// CHECK-DAG: private unnamed_addr constant [122 x i8] c"static void ClassWithTemplateTemplateParam<char, NS::ClassTemplate>::staticMember() [T = char, Param = NS::ClassTemplate]\00" +// CHECK-DAG: private unnamed_addr constant [106 x i8] c"void OuterClass<int *>::MiddleClass::InnerClass<float>::memberFunction(T, U) const [T = int *, U = float]\00" +// CHECK-DAG: private unnamed_addr constant [51 x i8] c"void functionTemplateWithCapturedStmt(T) [T = int]\00" +// CHECK-DAG: private unnamed_addr constant [76 x i8] c"auto functionTemplateWithLambda(int)::(anonymous class)::operator()() const\00" +// CHECK-DAG: private unnamed_addr constant [65 x i8] c"void functionTemplateWithUnnamedTemplateParameter(T) [T = float]\00" -// CHECK: private unnamed_addr constant [60 x i8] c"void functionTemplateExplicitSpecialization(T) [T = double]\00" -// CHECK: private unnamed_addr constant [52 x i8] c"T *functionTemplateWithCompoundTypes(T *) [T = int]\00" -// CHECK: private unnamed_addr constant [54 x i8] c"T functionTemplateWithTemplateReturnType() [T = char]\00" -// CHECK: private unnamed_addr constant [57 x i8] c"void functionTemplateWithoutParameterList() [T = double]\00" -// CHECK: private unnamed_addr constant [62 x i8] c"void functionTemplateWithTwoParams(T, U) [T = int, U = float]\00" +// CHECK-DAG: private unnamed_addr constant [60 x i8] c"void functionTemplateExplicitSpecialization(T) [T = double]\00" +// CHECK-DAG: private unnamed_addr constant [52 x i8] c"T *functionTemplateWithCompoundTypes(T *) [T = int]\00" +// CHECK-DAG: private unnamed_addr constant [54 x i8] c"T functionTemplateWithTemplateReturnType() [T = char]\00" +// CHECK-DAG: private unnamed_addr constant [57 x i8] c"void functionTemplateWithoutParameterList() [T = double]\00" +// CHECK-DAG: private unnamed_addr constant [62 x i8] c"void functionTemplateWithTwoParams(T, U) [T = int, U = float]\00" -// CHECK: private unnamed_addr constant [22 x i8] c"classTemplateFunction\00" -// CHECK: private unnamed_addr constant [77 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction() [T = NS::Base *]\00" -// CHECK: private unnamed_addr constant [63 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction() [T = int]\00" +// CHECK-DAG: private unnamed_addr constant [22 x i8] c"classTemplateFunction\00" +// CHECK-DAG: private unnamed_addr constant [77 x i8] c"void NS::ClassTemplate<NS::Base *>::classTemplateFunction() [T = NS::Base *]\00" +// CHECK-DAG: private unnamed_addr constant [63 x i8] c"void NS::ClassTemplate<int>::classTemplateFunction() [T = int]\00" -// CHECK: private unnamed_addr constant [18 x i8] c"functionTemplate1\00" -// CHECK: private unnamed_addr constant [53 x i8] c"void NS::Base::functionTemplate1(T) [T = NS::Base *]\00" -// CHECK: private unnamed_addr constant [46 x i8] c"void NS::Base::functionTemplate1(T) [T = int]\00" +// CHECK-DAG: private unnamed_addr constant [18 x i8] c"functionTemplate1\00" +// CHECK-DAG: private unnamed_addr constant [53 x i8] c"void NS::Base::functionTemplate1(T) [T = NS::Base *]\00" +// CHECK-DAG: private unnamed_addr constant [46 x i8] c"void NS::Base::functionTemplate1(T) [T = int]\00" -// CHECK: private unnamed_addr constant [23 x i8] c"anonymousUnionFunction\00" -// CHECK: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous union)::anonymousUnionFunction()\00" +// CHECK-DAG: private unnamed_addr constant [23 x i8] c"anonymousUnionFunction\00" +// CHECK-DAG: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous union)::anonymousUnionFunction()\00" -// CHECK: private unnamed_addr constant [24 x i8] c"anonymousStructFunction\00" -// CHECK: private unnamed_addr constant [85 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous struct)::anonymousStructFunction()\00" +// CHECK-DAG: private unnamed_addr constant [24 x i8] c"anonymousStructFunction\00" +// CHECK-DAG: private unnamed_addr constant [85 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous struct)::anonymousStructFunction()\00" -// CHECK: private unnamed_addr constant [23 x i8] c"anonymousClassFunction\00" -// CHECK: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous class)::anonymousClassFunction()\00" +// CHECK-DAG: private unnamed_addr constant [23 x i8] c"anonymousClassFunction\00" +// CHECK-DAG: private unnamed_addr constant [83 x i8] c"void NS::ContainerForAnonymousRecords::(anonymous class)::anonymousClassFunction()\00" -// CHECK: private unnamed_addr constant [12 x i8] c"~Destructor\00" -// CHECK: private unnamed_addr constant [30 x i8] c"NS::Destructor::~Destructor()\00" +// CHECK-DAG: private unnamed_addr constant [12 x i8] c"~Destructor\00" +// CHECK-DAG: private unnamed_addr constant [30 x i8] c"NS::Destructor::~Destructor()\00" -// CHECK: private unnamed_addr constant [12 x i8] c"Constructor\00" -// CHECK: private unnamed_addr constant [41 x i8] c"NS::Constructor::Constructor(NS::Base *)\00" -// CHECK: private unnamed_addr constant [34 x i8] c"NS::Constructor::Constructor(int)\00" -// CHECK: private unnamed_addr constant [31 x i8] c"NS::Constructor::Constructor()\00" +// CHECK-DAG: private unnamed_addr constant [12 x i8] c"Constructor\00" +// CHECK-DAG: private unnamed_addr constant [41 x i8] c"NS::Constructor::Constructor(NS::Base *)\00" +// CHECK-DAG: private unnamed_addr constant [34 x i8] c"NS::Constructor::Constructor(int)\00" +// CHECK-DAG: private unnamed_addr constant [31 x i8] c"NS::Constructor::Constructor()\00" -// CHECK: private unnamed_addr constant [16 x i8] c"virtualFunction\00" -// CHECK: private unnamed_addr constant [44 x i8] c"virtual void NS::Derived::virtualFunction()\00" +// CHECK-DAG: private unnamed_addr constant [16 x i8] c"virtualFunction\00" +// CHECK-DAG: private unnamed_addr constant [44 x i8] c"virtual void NS::Derived::virtualFunction()\00" -// CHECK: private unnamed_addr constant [21 x i8] c"refQualifiedFunction\00" -// CHECK: private unnamed_addr constant [41 x i8] c"void NS::Base::refQualifiedFunction() &&\00" -// CHECK: private unnamed_addr constant [40 x i8] c"void NS::Base::refQualifiedFunction() &\00" +// CHECK-DAG: private unnamed_addr constant [21 x i8] c"refQualifiedFunction\00" +// CHECK-DAG: private unnamed_addr constant [41 x i8] c"void NS::Base::refQualifiedFunction() &&\00" +// CHECK-DAG: private unnamed_addr constant [40 x i8] c"void NS::Base::refQualifiedFunction() &\00" -// CHECK: private unnamed_addr constant [22 x i8] c"constVolatileFunction\00" -// CHECK: private unnamed_addr constant [54 x i8] c"void NS::Base::constVolatileFunction() const volatile\00" +// CHECK-DAG: private unnamed_addr constant [22 x i8] c"constVolatileFunction\00" +// CHECK-DAG: private unnamed_addr constant [54 x i8] c"void NS::Base::constVolatileFunction() const volatile\00" -// CHECK: private unnamed_addr constant [17 x i8] c"volatileFunction\00" -// CHECK: private unnamed_addr constant [43 x i8] c"void NS::Base::volatileFunction() volatile\00" +// CHECK-DAG: private unnamed_addr constant [17 x i8] c"volatileFunction\00" +// CHECK-DAG: private unnamed_addr constant [43 x i8] c"void NS::Base::volatileFunction() volatile\00" -// CHECK: private unnamed_addr constant [14 x i8] c"constFunction\00" -// CHECK: private unnamed_addr constant [37 x i8] c"void NS::Base::constFunction() const\00" +// CHECK-DAG: private unnamed_addr constant [14 x i8] c"constFunction\00" +// CHECK-DAG: private unnamed_addr constant [37 x i8] c"void NS::Base::constFunction() const\00" -// CHECK: private unnamed_addr constant [26 x i8] c"functionReturingTemplate2\00" -// CHECK: private unnamed_addr constant [64 x i8] c"ClassTemplate<NS::Base *> NS::Base::functionReturingTemplate2()\00" +// CHECK-DAG: private unnamed_addr constant [26 x i8] c"functionReturingTemplate2\00" +// CHECK-DAG: private unnamed_addr constant [64 x i8] c"ClassTemplate<NS::Base *> NS::Base::functionReturingTemplate2()\00" -// CHECK: private unnamed_addr constant [26 x i8] c"functionReturingTemplate1\00" -// CHECK: private unnamed_addr constant [57 x i8] c"ClassTemplate<int> NS::Base::functionReturingTemplate1()\00" +// CHECK-DAG: private unnamed_addr constant [26 x i8] c"functionReturingTemplate1\00" +// CHECK-DAG: private unnamed_addr constant [57 x i8] c"ClassTemplate<int> NS::Base::functionReturingTemplate1()\00" -// CHECK: private unnamed_addr constant [23 x i8] c"withTemplateParameter2\00" -// CHECK: private unnamed_addr constant [65 x i8] c"void NS::Base::withTemplateParameter2(ClassTemplate<NS::Base *>)\00" +// CHECK-DAG: private unnamed_addr constant [23 x i8] c"withTemplateParameter2\00" +// CHECK-DAG: private unnamed_addr constant [65 x i8] c"void NS::Base::withTemplateParameter2(ClassTemplate<NS::Base *>)\00" -// CHECK: private unnamed_addr constant [23 x i8] c"withTemplateParameter1\00" -// CHECK: private unnamed_addr constant [58 x i8] c"void NS::Base::withTemplateParameter1(ClassTemplate<int>)\00" +// CHECK-DAG: private unnamed_addr constant [23 x i8] c"withTemplateParameter1\00" +// CHECK-DAG: private unnamed_addr constant [58 x i8] c"void NS::Base::withTemplateParameter1(ClassTemplate<int>)\00" -// CHECK: private unnamed_addr constant [23 x i8] c"functionReturningClass\00" -// CHECK: private unnamed_addr constant [45 x i8] c"NS::Base *NS::Base::functionReturningClass()\00" +// CHECK-DAG: private unnamed_addr constant [23 x i8] c"functionReturningClass\00" +// CHECK-DAG: private unnamed_addr constant [45 x i8] c"NS::Base *NS::Base::functionReturningClass()\00" -// CHECK: private unnamed_addr constant [23 x i8] c"functionWithParameters\00" -// CHECK: private unnamed_addr constant [64 x i8] c"void NS::Base::functionWithParameters(int, float *, NS::Base *)\00" +// CHECK-DAG: private unnamed_addr constant [23 x i8] c"functionWithParameters\00" +// CHECK-DAG: private unnamed_addr constant [64 x i8] c"void NS::Base::functionWithParameters(int, float *, NS::Base *)\00" -// CHECK: private unnamed_addr constant [17 x i8] c"variadicFunction\00" -// CHECK: private unnamed_addr constant [42 x i8] c"void NS::Base::variadicFunction(int, ...)\00" +// CHECK-DAG: private unnamed_addr constant [17 x i8] c"variadicFunction\00" +// CHECK-DAG: private unnamed_addr constant [42 x i8] c"void NS::Base::variadicFunction(int, ...)\00" -// CHECK: private unnamed_addr constant [41 x i8] c"virtual void NS::Base::virtualFunction()\00" +// CHECK-DAG: private unnamed_addr constant [41 x i8] c"virtual void NS::Base::virtualFunction()\00" -// CHECK: private unnamed_addr constant [15 x i8] c"inlineFunction\00" -// CHECK: private unnamed_addr constant [32 x i8] c"void NS::Base::inlineFunction()\00" +// CHECK-DAG: private unnamed_addr constant [15 x i8] c"inlineFunction\00" +// CHECK-DAG: private unnamed_addr constant [32 x i8] c"void NS::Base::inlineFunction()\00" -// CHECK: private unnamed_addr constant [15 x i8] c"staticFunction\00" -// CHECK: private unnamed_addr constant [39 x i8] c"static void NS::Base::staticFunction()\00" +// CHECK-DAG: private unnamed_addr constant [15 x i8] c"staticFunction\00" +// CHECK-DAG: private unnamed_addr constant [39 x i8] c"static void NS::Base::staticFunction()\00" -// CHECK: private unnamed_addr constant [26 x i8] c"topLevelNamespaceFunction\00" -// CHECK: private unnamed_addr constant [59 x i8] c"void ClassInTopLevelNamespace::topLevelNamespaceFunction()\00" +// CHECK-DAG: private unnamed_addr constant [26 x i8] c"topLevelNamespaceFunction\00" +// CHECK-DAG: private unnamed_addr constant [59 x i8] c"void ClassInTopLevelNamespace::topLevelNamespaceFunction()\00" -// CHECK: private unnamed_addr constant [27 x i8] c"anonymousNamespaceFunction\00" -// CHECK: private unnamed_addr constant [84 x i8] c"void (anonymous namespace)::ClassInAnonymousNamespace::anonymousNamespaceFunction()\00" +// CHECK-DAG: private unnamed_addr constant [27 x i8] c"anonymousNamespaceFunction\00" +// CHECK-DAG: private unnamed_addr constant [84 x i8] c"void (anonymous namespace)::ClassInAnonymousNamespace::anonymousNamespaceFunction()\00" -// CHECK: private unnamed_addr constant [19 x i8] c"localClassFunction\00" -// CHECK: private unnamed_addr constant [59 x i8] c"void NS::localClass(int)::LocalClass::localClassFunction()\00" +// CHECK-DAG: private unnamed_addr constant [19 x i8] c"localClassFunction\00" +// CHECK-DAG: private unnamed_addr constant [59 x i8] c"void NS::localClass(int)::LocalClass::localClassFunction()\00" diff --git a/test/CodeGenCXX/reference-cast.cpp b/test/CodeGenCXX/reference-cast.cpp index c4be5b7..02498a3 100644 --- a/test/CodeGenCXX/reference-cast.cpp +++ b/test/CodeGenCXX/reference-cast.cpp @@ -174,10 +174,10 @@ unsigned pr10592(const int &v) { // CHECK: [[VADDR:%[a-zA-Z0-9.]+]] = alloca i32* // CHECK-NEXT: [[REFTMP:%[a-zA-Z0-9.]+]] = alloca i32 // CHECK-NEXT: store i32* [[V:%[a-zA-Z0-9.]+]], i32** [[VADDR]] - // CHECK-NEXT: [[VADDR_1:%[a-zA-Z0-9.]+]] = load i32** [[VADDR]] - // CHECK-NEXT: [[VVAL:%[a-zA-Z0-9.]+]] = load i32* [[VADDR_1]] + // CHECK-NEXT: [[VADDR_1:%[a-zA-Z0-9.]+]] = load i32*, i32** [[VADDR]] + // CHECK-NEXT: [[VVAL:%[a-zA-Z0-9.]+]] = load i32, i32* [[VADDR_1]] // CHECK-NEXT: store i32 [[VVAL]], i32* [[REFTMP]] - // CHECK-NEXT: [[VVAL_I:%[a-zA-Z0-9.]+]] = load i32* [[REFTMP]] + // CHECK-NEXT: [[VVAL_I:%[a-zA-Z0-9.]+]] = load i32, i32* [[REFTMP]] // CHECK-NEXT: ret i32 [[VVAL_I]] return static_cast<const unsigned &>(v); } diff --git a/test/CodeGenCXX/references.cpp b/test/CodeGenCXX/references.cpp index 454c306..180e0cf 100644 --- a/test/CodeGenCXX/references.cpp +++ b/test/CodeGenCXX/references.cpp @@ -1,16 +1,16 @@ // RUN: not %clang_cc1 -triple x86_64-apple-darwin -verify -emit-llvm -o - %s | FileCheck %s void t1() { // CHECK-LABEL: define void @_Z2t1v - // CHECK: [[REFLOAD:%.*]] = load i32** @a, align 8 - // CHECK: load i32* [[REFLOAD]], align 4 + // CHECK: [[REFLOAD:%.*]] = load i32*, i32** @a, align 8 + // CHECK: load i32, i32* [[REFLOAD]], align 4 extern int& a; int b = a; } void t2(int& a) { // CHECK-LABEL: define void @_Z2t2Ri - // CHECK: [[REFLOAD2:%.*]] = load i32** {{.*}}, align 8 - // CHECK: load i32* [[REFLOAD2]], align 4 + // CHECK: [[REFLOAD2:%.*]] = load i32*, i32** {{.*}}, align 8 + // CHECK: load i32, i32* [[REFLOAD2]], align 4 int b = a; } @@ -307,6 +307,6 @@ namespace N6 { extern struct x {char& x;}y; int a() { return y.x; } // CHECK-LABEL: define i32 @_ZN2N61aEv - // CHECK: [[REFLOAD3:%.*]] = load i8** getelementptr inbounds (%"struct.N6::x"* @_ZN2N61yE, i32 0, i32 0), align 8 - // CHECK: load i8* [[REFLOAD3]], align 1 + // CHECK: [[REFLOAD3:%.*]] = load i8*, i8** getelementptr inbounds (%"struct.N6::x", %"struct.N6::x"* @_ZN2N61yE, i32 0, i32 0), align 8 + // CHECK: load i8, i8* [[REFLOAD3]], align 1 } diff --git a/test/CodeGenCXX/rtti-linkage.cpp b/test/CodeGenCXX/rtti-linkage.cpp index 3b06d42..b6b72aa 100644 --- a/test/CodeGenCXX/rtti-linkage.cpp +++ b/test/CodeGenCXX/rtti-linkage.cpp @@ -33,12 +33,12 @@ // CHECK-WITH-HIDDEN: @_ZTIPK2T4 = linkonce_odr hidden constant // CHECK-WITH-HIDDEN: @_ZTSZ2t5vE1A = internal constant // CHECK-WITH-HIDDEN: @_ZTIZ2t5vE1A = internal constant +// CHECK-WITH-HIDDEN: @_ZTSZ2t6vE1A = linkonce_odr hidden constant +// CHECK-WITH-HIDDEN: @_ZTIZ2t6vE1A = linkonce_odr hidden constant // CHECK-WITH-HIDDEN: @_ZTSPZ2t7vE1A = linkonce_odr hidden constant // CHECK-WITH-HIDDEN: @_ZTSZ2t7vE1A = linkonce_odr hidden constant // CHECK-WITH-HIDDEN: @_ZTIZ2t7vE1A = linkonce_odr hidden constant // CHECK-WITH-HIDDEN: @_ZTIPZ2t7vE1A = linkonce_odr hidden constant -// CHECK-WITH-HIDDEN: @_ZTSZ2t6vE1A = linkonce_odr hidden constant -// CHECK-WITH-HIDDEN: @_ZTIZ2t6vE1A = linkonce_odr hidden constant // CHECK: _ZTSN12_GLOBAL__N_11DE = internal constant // CHECK: _ZTIN12_GLOBAL__N_11DE = internal constant @@ -64,12 +64,12 @@ // CHECK: _ZTS1B = constant // CHECK: _ZTI1B = constant // CHECK: _ZTS1F = linkonce_odr constant +// CHECK: _ZTSZ2t6vE1A = linkonce_odr constant +// CHECK: _ZTIZ2t6vE1A = linkonce_odr constant // CHECK: _ZTSPZ2t7vE1A = linkonce_odr constant // CHECK: _ZTSZ2t7vE1A = linkonce_odr constant // CHECK: _ZTIZ2t7vE1A = linkonce_odr constant // CHECK: _ZTIPZ2t7vE1A = linkonce_odr constant -// CHECK: _ZTSZ2t6vE1A = linkonce_odr constant -// CHECK: _ZTIZ2t6vE1A = linkonce_odr constant // CHECK: _ZTIN12_GLOBAL__N_11DE to diff --git a/test/CodeGenCXX/rvalue-references.cpp b/test/CodeGenCXX/rvalue-references.cpp index 66705bf..47e5745 100644 --- a/test/CodeGenCXX/rvalue-references.cpp +++ b/test/CodeGenCXX/rvalue-references.cpp @@ -10,7 +10,7 @@ B &getB(); // CHECK-LABEL: define dereferenceable({{[0-9]+}}) %struct.A* @_Z4getAv() // CHECK: call dereferenceable({{[0-9]+}}) %struct.B* @_Z4getBv() // CHECK-NEXT: bitcast %struct.B* -// CHECK-NEXT: getelementptr inbounds i8* +// CHECK-NEXT: getelementptr inbounds i8, i8* // CHECK-NEXT: bitcast i8* {{.*}} to %struct.A* // CHECK-NEXT: ret %struct.A* A &&getA() { return static_cast<A&&>(getB()); } @@ -96,7 +96,7 @@ namespace test1 { // CHECK-LABEL: define void @_ZN5test11BC2Ei( // CHECK: [[T0:%.*]] = call dereferenceable({{[0-9]+}}) i32* @_ZN5test14moveERi( - // CHECK-NEXT: [[T1:%.*]] = load i32* [[T0]] + // CHECK-NEXT: [[T1:%.*]] = load i32, i32* [[T0]] // CHECK-NEXT: call void @_ZN5test11AC1Ei({{.*}}, i32 [[T1]]) // CHECK-NEXT: ret void B::B(int i) : a(move(i)) {} diff --git a/test/CodeGenCXX/scoped-enums-debug-info.cpp b/test/CodeGenCXX/scoped-enums-debug-info.cpp index d3ef9f7..52658fc 100644 --- a/test/CodeGenCXX/scoped-enums-debug-info.cpp +++ b/test/CodeGenCXX/scoped-enums-debug-info.cpp @@ -1,7 +1,9 @@ // RUN: %clang_cc1 -std=c++11 -emit-llvm -g -o - %s | FileCheck %s // Test that we are emitting debug info and base types for scoped enums. -// CHECK: [ DW_TAG_enumeration_type ] [Color] {{.*}} [from int] +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Color" +// CHECK-SAME: baseType: ![[INT:[0-9]+]] +// CHECK: ![[INT]] = !DIBasicType(name: "int" enum class Color { gray }; void f(Color); @@ -9,7 +11,8 @@ void g() { f(Color::gray); } -// CHECK: [ DW_TAG_enumeration_type ] [Colour] {{.*}} [from int] +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Colour" +// CHECK-SAME: baseType: ![[INT]] enum struct Colour { grey }; void h(Colour); @@ -17,7 +20,9 @@ void i() { h(Colour::grey); } -// CHECK: [ DW_TAG_enumeration_type ] [Couleur] {{.*}} [from unsigned char] +// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Couleur" +// CHECK-SAME: baseType: ![[UCHAR:[0-9]+]] +// CHECK: ![[UCHAR]] = !DIBasicType(name: "unsigned char" enum class Couleur : unsigned char { gris }; void j(Couleur); diff --git a/test/CodeGenCXX/sections.cpp b/test/CodeGenCXX/sections.cpp index f84f9d9..bec2e2d 100644 --- a/test/CodeGenCXX/sections.cpp +++ b/test/CodeGenCXX/sections.cpp @@ -55,7 +55,7 @@ __declspec(allocate("short_section")) short short_var = 42; //CHECK: @a = global i32 1, section ".data" //CHECK: @b = constant i32 1, section ".my_const" //CHECK: @[[MYSTR:.*]] = {{.*}} unnamed_addr constant [11 x i8] c"my string!\00" -//CHECK: @s = global i8* getelementptr inbounds ([11 x i8]* @[[MYSTR]], i32 0, i32 0), section ".data2" +//CHECK: @s = global i8* getelementptr inbounds ([11 x i8], [11 x i8]* @[[MYSTR]], i32 0, i32 0), section ".data2" //CHECK: @c = global i32 1, section ".my_seg" //CHECK: @d = global i32 1, section ".data" //CHECK: @e = global i32 0, section ".my_bss" diff --git a/test/CodeGenCXX/sizeof-unwind-exception.cpp b/test/CodeGenCXX/sizeof-unwind-exception.cpp index 95bb9d0..d2a1c33 100644 --- a/test/CodeGenCXX/sizeof-unwind-exception.cpp +++ b/test/CodeGenCXX/sizeof-unwind-exception.cpp @@ -16,15 +16,15 @@ void test() { // PR10789: different platforms have different sizes for struct UnwindException. // X86-64: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) [[NUW:#[0-9]+]] -// X86-64-NEXT: [[T1:%.*]] = getelementptr i8* [[EXN]], i64 32 +// X86-64-NEXT: [[T1:%.*]] = getelementptr i8, i8* [[EXN]], i64 32 // X86-32: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) [[NUW:#[0-9]+]] -// X86-32-NEXT: [[T1:%.*]] = getelementptr i8* [[EXN]], i64 32 +// X86-32-NEXT: [[T1:%.*]] = getelementptr i8, i8* [[EXN]], i64 32 // ARM-DARWIN: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) [[NUW:#[0-9]+]] -// ARM-DARWIN-NEXT: [[T1:%.*]] = getelementptr i8* [[EXN]], i64 32 +// ARM-DARWIN-NEXT: [[T1:%.*]] = getelementptr i8, i8* [[EXN]], i64 32 // ARM-EABI: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) [[NUW:#[0-9]+]] -// ARM-EABI-NEXT: [[T1:%.*]] = getelementptr i8* [[EXN]], i32 88 +// ARM-EABI-NEXT: [[T1:%.*]] = getelementptr i8, i8* [[EXN]], i32 88 // MIPS: [[T0:%.*]] = tail call i8* @__cxa_begin_catch(i8* [[EXN:%.*]]) [[NUW:#[0-9]+]] -// MIPS-NEXT: [[T1:%.*]] = getelementptr i8* [[EXN]], i32 24 +// MIPS-NEXT: [[T1:%.*]] = getelementptr i8, i8* [[EXN]], i32 24 // X86-64: attributes [[NUW]] = { nounwind } // X86-32: attributes [[NUW]] = { nounwind } diff --git a/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp index 6b50075..f6f9098 100644 --- a/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp +++ b/test/CodeGenCXX/skip-vtable-pointer-initialization.cpp @@ -11,7 +11,7 @@ struct A { }; // CHECK-LABEL: define void @_ZN5Test11AD2Ev -// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** +// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test11AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** A::~A() { } @@ -27,7 +27,7 @@ struct A { }; // CHECK-LABEL: define void @_ZN5Test21AD2Ev -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test21AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test21AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** A::~A() { f(); } @@ -50,7 +50,7 @@ struct A { }; // CHECK-LABEL: define void @_ZN5Test31AD2Ev -// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test31AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** +// CHECK-NOT: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test31AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** A::~A() { } @@ -76,7 +76,7 @@ struct A { }; // CHECK-LABEL: define void @_ZN5Test41AD2Ev -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test41AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test41AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** A::~A() { } @@ -100,7 +100,7 @@ struct A { }; // CHECK-LABEL: define void @_ZN5Test51AD2Ev -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test51AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test51AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** A::~A() { } @@ -128,7 +128,7 @@ struct A { }; // CHECK-LABEL: define void @_ZN5Test61AD2Ev -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test61AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test61AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** A::~A() { } @@ -154,7 +154,7 @@ struct A { }; // CHECK-LABEL: define void @_ZN5Test71AD2Ev -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test71AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test71AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** A::~A() { } @@ -180,7 +180,7 @@ struct A { }; // CHECK-LABEL: define void @_ZN5Test81AD2Ev -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTVN5Test81AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTVN5Test81AE, i64 0, i64 2) to i32 (...)**), i32 (...)*** A::~A() { } diff --git a/test/CodeGenCXX/split-stacks.cpp b/test/CodeGenCXX/split-stacks.cpp index 3e12034..76e1b79 100644 --- a/test/CodeGenCXX/split-stacks.cpp +++ b/test/CodeGenCXX/split-stacks.cpp @@ -18,7 +18,7 @@ int nosplit() { // CHECK-SEGSTK: define i32 @_Z3foov() [[SS:#[0-9]+]] { // CHECK-SEGSTK: define i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] { -// CHECK-SEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] { +// CHECK-SEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] comdat { // CHECK-SEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} } // CHECK-SEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} } // CHECK-SEGSTK: [[SS]] = { {{.*}} "split-stack" {{.*}} } @@ -27,7 +27,7 @@ int nosplit() { // CHECK-NOSEGSTK: define i32 @_Z3foov() [[NSS0:#[0-9]+]] { // CHECK-NOSEGSTK: define i32 @_Z7nosplitv() [[NSS1:#[0-9]+]] { -// CHECK-NOSEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] { +// CHECK-NOSEGSTK: define linkonce_odr i32 @_Z8tnosplitIiEiv() [[NSS2:#[0-9]+]] comdat { // CHECK-NOSEGSTK-NOT: [[NSS1]] = { {{.*}} "split-stack" {{.*}} } // CHECK-NOSEGSTK-NOT: [[NSS2]] = { {{.*}} "split-stack" {{.*}} } // CHECK-NOSEGSTK-NOT: [[NSS3]] = { {{.*}} "split-stack" {{.*}} } diff --git a/test/CodeGenCXX/static-data-member-single-emission.cpp b/test/CodeGenCXX/static-data-member-single-emission.cpp new file mode 100644 index 0000000..8c04fab --- /dev/null +++ b/test/CodeGenCXX/static-data-member-single-emission.cpp @@ -0,0 +1,31 @@ +// RUN: %clang_cc1 %s -emit-llvm -o - | FileCheck %s + +template <typename T> +struct HasStaticInit { +static const int index; +}; +extern "C" +int the_count = 0; +template <typename T> +const int HasStaticInit<T>::index = the_count++; + +template <typename T> int func_tmpl1() { return HasStaticInit<T>::index; } +template <typename T> int func_tmpl2() { return HasStaticInit<T>::index; } +template <typename T> int func_tmpl3() { return HasStaticInit<T>::index; } +void useit() { + func_tmpl1<int>(); + func_tmpl2<int>(); + func_tmpl3<int>(); +} + +// Throw in a final explicit instantiation to see that it doesn't screw things +// up. +template struct HasStaticInit<int>; + +// There should only be one entry, not 3. +// CHECK: @llvm.global_ctors = appending global [1 x { i32, void ()*, i8* }] + +// There should only be one update to @the_count. +// CHECK-NOT: store i32 %{{.*}}, i32* @the_count +// CHECK: store i32 %{{.*}}, i32* @the_count +// CHECK-NOT: store i32 %{{.*}}, i32* @the_count diff --git a/test/CodeGenCXX/static-data-member.cpp b/test/CodeGenCXX/static-data-member.cpp index d41ac8f..5ffd83f 100644 --- a/test/CodeGenCXX/static-data-member.cpp +++ b/test/CodeGenCXX/static-data-member.cpp @@ -64,10 +64,10 @@ namespace test3 { template <class T> int A<T>::x = foo(); template struct A<int>; - // CHECK-LABEL: define internal void @__cxx_global_var_init1() {{.*}} comdat($_ZN5test31AIiE1xE) - // MACHO-LABEL: define internal void @__cxx_global_var_init1() + // CHECK-LABEL: define internal void @__cxx_global_var_init.1() {{.*}} comdat($_ZN5test31AIiE1xE) + // MACHO-LABEL: define internal void @__cxx_global_var_init.1() // MACHO-NOT: comdat - // CHECK: [[GUARDBYTE:%.*]] = load i8* bitcast (i64* @_ZGVN5test31AIiE1xE to i8*) + // CHECK: [[GUARDBYTE:%.*]] = load i8, i8* bitcast (i64* @_ZGVN5test31AIiE1xE to i8*) // CHECK-NEXT: [[UNINITIALIZED:%.*]] = icmp eq i8 [[GUARDBYTE]], 0 // CHECK-NEXT: br i1 [[UNINITIALIZED]] // CHECK: [[TMP:%.*]] = call i32 @_ZN5test33fooEv() diff --git a/test/CodeGenCXX/static-init-pnacl.cpp b/test/CodeGenCXX/static-init-pnacl.cpp index de35ec3..ba06420 100644 --- a/test/CodeGenCXX/static-init-pnacl.cpp +++ b/test/CodeGenCXX/static-init-pnacl.cpp @@ -9,6 +9,6 @@ int f(); void g() { static int a = f(); } -// CHECK: [[LOAD:%.*]] = load atomic i8* bitcast (i64* @_ZGVZ1gvE1a to i8*) acquire +// CHECK: [[LOAD:%.*]] = load atomic i8, i8* bitcast (i64* @_ZGVZ1gvE1a to i8*) acquire // CHECK-NEXT: [[GUARD:%.*]] = icmp eq i8 [[LOAD]], 0 // CHECK-NEXT: br i1 [[GUARD]] diff --git a/test/CodeGenCXX/static-init.cpp b/test/CodeGenCXX/static-init.cpp index a9debe3..25489f0 100644 --- a/test/CodeGenCXX/static-init.cpp +++ b/test/CodeGenCXX/static-init.cpp @@ -5,12 +5,10 @@ // CHECK: @base_req_uchar = global [4 x i8] c"bar\00", align 1 // CHECK: @_ZZN5test31BC1EvE1u = internal global { i8, [3 x i8] } { i8 97, [3 x i8] undef }, align 4 -// CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16 -// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0 -// CHECK-NOT: comdat -// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0 -// CHECK-NOT: comdat +// CHECK: @_ZZ2h2vE1i = linkonce_odr global i32 0, comdat, align +// CHECK: @_ZGVZ2h2vE1i = linkonce_odr global i64 0, comdat{{$}} +// CHECK: @_ZZN5test1L6getvarEiE3var = internal constant [4 x i32] [i32 1, i32 0, i32 2, i32 4], align 16 struct A { A(); @@ -18,10 +16,10 @@ struct A { }; void f() { - // CHECK: load atomic i8* bitcast (i64* @_ZGVZ1fvE1a to i8*) acquire, align 1 + // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZ1fvE1a to i8*) acquire, align 1 // CHECK: call i32 @__cxa_guard_acquire // CHECK: call void @_ZN1AC1Ev - // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A* @_ZZ1fvE1a, i32 0, i32 0), i8* @__dso_handle) + // CHECK: call i32 @__cxa_atexit(void (i8*)* bitcast (void (%struct.A*)* @_ZN1AD1Ev to void (i8*)*), i8* getelementptr inbounds (%struct.A, %struct.A* @_ZZ1fvE1a, i32 0, i32 0), i8* @__dso_handle) // CHECK: call void @__cxa_guard_release static A a; } @@ -37,8 +35,7 @@ void h() { static const int i = a(); } -// CHECK: define linkonce_odr void @_Z2h2v() -// CHECK-NOT: comdat +// CHECK: define linkonce_odr void @_Z2h2v() {{.*}} comdat { inline void h2() { static int i = a(); } @@ -109,14 +106,14 @@ namespace test2 { static int x = foo(); } // CHECK-LABEL: define void @_ZN5test21BC2Ev - // CHECK: load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire, + // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire, // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x) // CHECK: [[T0:%.*]] = call i32 @_ZN5test23fooEv() // CHECK: store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x, // CHECK: call void @__cxa_guard_release(i64* @_ZGVZN5test21BC1EvE1x) // CHECK-LABEL: define void @_ZN5test21BC1Ev - // CHECK: load atomic i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire, + // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZN5test21BC1EvE1x to i8*) acquire, // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BC1EvE1x) // CHECK: [[T0:%.*]] = call i32 @_ZN5test23fooEv() // CHECK: store i32 [[T0]], i32* @_ZZN5test21BC1EvE1x, @@ -128,7 +125,7 @@ namespace test2 { static int y = foo(); } // CHECK-LABEL: define void @_ZN5test21BD2Ev( - // CHECK: load atomic i8* bitcast (i64* @_ZGVZN5test21BD1EvE1y to i8*) acquire, + // CHECK: load atomic i8, i8* bitcast (i64* @_ZGVZN5test21BD1EvE1y to i8*) acquire, // CHECK: call i32 @__cxa_guard_acquire(i64* @_ZGVZN5test21BD1EvE1y) // CHECK: [[T0:%.*]] = call i32 @_ZN5test23fooEv() // CHECK: store i32 [[T0]], i32* @_ZZN5test21BD1EvE1y, diff --git a/test/CodeGenCXX/static-local-in-local-class.cpp b/test/CodeGenCXX/static-local-in-local-class.cpp index 729b937..a70afcd 100644 --- a/test/CodeGenCXX/static-local-in-local-class.cpp +++ b/test/CodeGenCXX/static-local-in-local-class.cpp @@ -1,11 +1,11 @@ // RUN: %clang_cc1 -triple x86_64-linux -fblocks -emit-llvm -o - %s -std=c++1y | FileCheck %s -// CHECK: @"_ZZNK3$_2clEvE1x" = internal global i32 42 -// CHECK: @_ZZ18static_local_labelPvE1q = linkonce_odr global i8* blockaddress(@_Z18static_local_labelPv, %{{.*}}) -// CHECK: @_ZZZL20block_deduced_returnvEUb_E1n = internal global i32 42 -// CHECK: @_ZZL14deduced_returnvE1n = internal global i32 42 // CHECK: @"_ZZZNK17pr18020_constexpr3$_1clEvENKUlvE_clEvE2l2" = // CHECK: internal global i32* @"_ZZNK17pr18020_constexpr3$_1clEvE2l1" +// CHECK: @_ZZL14deduced_returnvE1n = internal global i32 42 +// CHECK: @_ZZZL20block_deduced_returnvEUb_E1n = internal global i32 42 +// CHECK: @_ZZ18static_local_labelPvE1q = linkonce_odr global i8* blockaddress(@_Z18static_local_labelPv, %{{.*}}) +// CHECK: @"_ZZNK3$_2clEvE1x" = internal global i32 42 namespace pr6769 { struct X { @@ -56,7 +56,7 @@ int f() { return x()(); } } // CHECK-LABEL: define internal i32 @"_ZZNK14pr18020_lambda3$_0clEvENKUlvE_clEv" -// CHECK: load i32* @"_ZZNK14pr18020_lambda3$_0clEvE2l1" +// CHECK: load i32, i32* @"_ZZNK14pr18020_lambda3$_0clEvE2l1" namespace pr18020_constexpr { // Taking the address of l1 in a constant expression used to crash. @@ -71,7 +71,7 @@ int f() { return x()(); } } // CHECK-LABEL: define internal i32 @"_ZZNK17pr18020_constexpr3$_1clEvENKUlvE_clEv" -// CHECK: load i32** @"_ZZZNK17pr18020_constexpr3$_1clEvENKUlvE_clEvE2l2" +// CHECK: load i32*, i32** @"_ZZZNK17pr18020_constexpr3$_1clEvENKUlvE_clEvE2l2" // Lambda-less reduction that references l1 before emitting it. This didn't // crash if you put it in a namespace. @@ -88,7 +88,7 @@ static pr18020_class x; int pr18020_f() { return x()(); } // CHECK-LABEL: define linkonce_odr i32 @_ZZN13pr18020_classclEvEN1UclEv -// CHECK: load i32* @_ZZN13pr18020_classclEvE2l1 +// CHECK: load i32, i32* @_ZZN13pr18020_classclEvE2l1 // In this test case, the function containing the static local will not be // emitted because it is unneeded. However, the operator call of the inner class @@ -104,7 +104,7 @@ extern "C" int call_deduced_return_operator() { // CHECK-LABEL: define i32 @call_deduced_return_operator() // CHECK: call i32* @_ZZL14deduced_returnvEN1SclEv( -// CHECK: load i32* % +// CHECK: load i32, i32* % // CHECK: ret i32 % // CHECK-LABEL: define internal i32* @_ZZL14deduced_returnvEN1SclEv(%struct.S* %this) @@ -124,7 +124,7 @@ extern "C" int call_block_deduced_return() { // CHECK-LABEL: define i32 @call_block_deduced_return() // CHECK: call i32* @_ZZZL20block_deduced_returnvEUb_EN1SclEv( -// CHECK: load i32* % +// CHECK: load i32, i32* % // CHECK: ret i32 % // CHECK-LABEL: define internal i32* @_ZZZL20block_deduced_returnvEUb_EN1SclEv(%struct.S.6* %this) #0 align 2 { @@ -142,7 +142,7 @@ label: void *global_label = decltype(static_local_label(0))::get(); // CHECK-LABEL: define linkonce_odr i8* @_ZZ18static_local_labelPvEN1S3getEv() -// CHECK: %[[lbl:[^ ]*]] = load i8** @_ZZ18static_local_labelPvE1q +// CHECK: %[[lbl:[^ ]*]] = load i8*, i8** @_ZZ18static_local_labelPvE1q // CHECK: ret i8* %[[lbl]] auto global_lambda = []() { diff --git a/test/CodeGenCXX/switch-case-folding-2.cpp b/test/CodeGenCXX/switch-case-folding-2.cpp index 930bfeb..b0bbf32 100644 --- a/test/CodeGenCXX/switch-case-folding-2.cpp +++ b/test/CodeGenCXX/switch-case-folding-2.cpp @@ -18,4 +18,4 @@ int main(void) { return test(5); } -// CHECK: call i32 (i8*, ...)* @_Z6printfPKcz +// CHECK: call i32 (i8*, ...) @_Z6printfPKcz diff --git a/test/CodeGenCXX/template-anonymous-types.cpp b/test/CodeGenCXX/template-anonymous-types.cpp index f4d6549..63685ef 100644 --- a/test/CodeGenCXX/template-anonymous-types.cpp +++ b/test/CodeGenCXX/template-anonymous-types.cpp @@ -24,14 +24,13 @@ void test() { // CHECK-LABEL: define linkonce_odr i32 @_Z1fIN1SUt0_EEiT_(i32 %t) (void)f(S::BAR); - // Now check for the class template instantiations. Annoyingly, they are in - // reverse order. + // Now check for the class template instantiations. // // BAR's instantiation of X: - // CHECK-LABEL: define linkonce_odr i32 @_ZN1XIN1SUt0_EE1fEv(%struct.X* %this) - // CHECK-LABEL: define linkonce_odr void @_ZN1XIN1SUt0_EEC2ES1_(%struct.X* %this, i32 %t) unnamed_addr + // CHECK-LABEL: define linkonce_odr i32 @_ZN1XIN1SUt_EE1fEv(%struct.X* %this) + // CHECK-LABEL: define linkonce_odr void @_ZN1XIN1SUt_EEC2ES1_(%struct.X* %this, i32 %t) unnamed_addr // // FOO's instantiation of X: - // CHECK-LABEL: define linkonce_odr i32 @_ZN1XIN1SUt_EE1fEv(%struct.X.0* %this) - // CHECK-LABEL: define linkonce_odr void @_ZN1XIN1SUt_EEC2ES1_(%struct.X.0* %this, i32 %t) unnamed_addr + // CHECK-LABEL: define linkonce_odr i32 @_ZN1XIN1SUt0_EE1fEv(%struct.X.0* %this) + // CHECK-LABEL: define linkonce_odr void @_ZN1XIN1SUt0_EEC2ES1_(%struct.X.0* %this, i32 %t) unnamed_addr } diff --git a/test/CodeGenCXX/temporaries.cpp b/test/CodeGenCXX/temporaries.cpp index 89677cb..c537124 100644 --- a/test/CodeGenCXX/temporaries.cpp +++ b/test/CodeGenCXX/temporaries.cpp @@ -3,7 +3,7 @@ namespace PR16263 { const unsigned int n = 1234; extern const int &r = (const int&)n; - // CHECK: @_ZGRN7PR162631rE_ = private constant i32 1234, + // CHECK: @_ZGRN7PR162631rE_ = internal constant i32 1234, // CHECK: @_ZN7PR162631rE = constant i32* @_ZGRN7PR162631rE_, extern const int &s = reinterpret_cast<const int&>(n); @@ -14,16 +14,16 @@ namespace PR16263 { struct B { int n; }; struct C : A, B {}; extern const A &&a = (A&&)(A&&)(C&&)(C{}); - // CHECK: @_ZGRN7PR162631aE_ = private global {{.*}} zeroinitializer, + // CHECK: @_ZGRN7PR162631aE_ = internal global {{.*}} zeroinitializer, // CHECK: @_ZN7PR162631aE = constant {{.*}} bitcast ({{.*}}* @_ZGRN7PR162631aE_ to extern const int &&t = ((B&&)C{}).n; - // CHECK: @_ZGRN7PR162631tE_ = private global {{.*}} zeroinitializer, + // CHECK: @_ZGRN7PR162631tE_ = internal global {{.*}} zeroinitializer, // CHECK: @_ZN7PR162631tE = constant i32* {{.*}}* @_ZGRN7PR162631tE_ {{.*}} 4 struct D { double d; C c; }; extern const int &&u = (123, static_cast<B&&>(0, ((D&&)D{}).*&D::c).n); - // CHECK: @_ZGRN7PR162631uE_ = private global {{.*}} zeroinitializer + // CHECK: @_ZGRN7PR162631uE_ = internal global {{.*}} zeroinitializer // CHECK: @_ZN7PR162631uE = constant i32* {{.*}} @_ZGRN7PR162631uE_ {{.*}} 12 } @@ -33,19 +33,19 @@ namespace PR20227 { struct C : B {}; A &&a = dynamic_cast<A&&>(A{}); - // CHECK: @_ZGRN7PR202271aE_ = private global + // CHECK: @_ZGRN7PR202271aE_ = internal global B &&b = dynamic_cast<C&&>(dynamic_cast<B&&>(C{})); - // CHECK: @_ZGRN7PR202271bE_ = private global + // CHECK: @_ZGRN7PR202271bE_ = internal global B &&c = static_cast<C&&>(static_cast<B&&>(C{})); - // CHECK: @_ZGRN7PR202271cE_ = private global + // CHECK: @_ZGRN7PR202271cE_ = internal global } namespace BraceInit { typedef const int &CIR; CIR x = CIR{3}; - // CHECK: @_ZGRN9BraceInit1xE_ = private constant i32 3 + // CHECK: @_ZGRN9BraceInit1xE_ = internal constant i32 3 // CHECK: @_ZN9BraceInit1xE = constant i32* @_ZGRN9BraceInit1xE_ } @@ -475,17 +475,17 @@ namespace Elision { // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[X]]) A x; - // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i64 0, i64 0 + // CHECK-NEXT: [[XS0:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i64 0, i64 0 // CHECK-NEXT: call void @_ZN7Elision1AC1Ev([[A]]* [[XS0]]) - // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]]* [[XS0]], i64 1 + // CHECK-NEXT: [[XS1:%.*]] = getelementptr inbounds [[A]], [[A]]* [[XS0]], i64 1 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[XS1]], [[A]]* dereferenceable({{[0-9]+}}) [[X]]) A xs[] = { A(), x }; - // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]]* [[XS]], i32 0, i32 0 - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 2 + // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [2 x [[A]]], [2 x [[A]]]* [[XS]], i32 0, i32 0 + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 2 // CHECK-NEXT: br label // CHECK: [[AFTER:%.*]] = phi [[A]]* - // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]]* [[AFTER]], i64 -1 + // CHECK-NEXT: [[CUR:%.*]] = getelementptr inbounds [[A]], [[A]]* [[AFTER]], i64 -1 // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[CUR]]) // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[CUR]], [[BEGIN]] // CHECK-NEXT: br i1 [[T0]], @@ -504,7 +504,7 @@ namespace Elision { // CHECK-NEXT: [[BT2:%.*]] = alloca [[B]], align 8 // CHECK: call void @_ZN7Elision1BC1Ev([[B]]* [[BT0]]) - // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT0]], i32 0, i32 0 + // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT0]], i32 0, i32 0 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[AT0]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) // CHECK-NEXT: call void @_ZN7Elision5takeAENS_1AE([[A]]* [[AT0]]) // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[AT0]]) @@ -512,13 +512,13 @@ namespace Elision { takeA(B().a); // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT1]]) - // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT1]], i32 0, i32 0 + // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT1]], i32 0, i32 0 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[X]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT1]]) A x = B().a; // CHECK-NEXT: call void @_ZN7Elision1BC1Ev([[B]]* [[BT2]]) - // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]]* [[BT2]], i32 0, i32 0 + // CHECK-NEXT: [[AM:%.*]] = getelementptr inbounds [[B]], [[B]]* [[BT2]], i32 0, i32 0 // CHECK-NEXT: call void @_ZN7Elision1AC1ERKS0_([[A]]* [[RET:%.*]], [[A]]* dereferenceable({{[0-9]+}}) [[AM]]) // CHECK-NEXT: call void @_ZN7Elision1BD1Ev([[B]]* [[BT2]]) return B().a; @@ -531,7 +531,7 @@ namespace Elision { struct C { operator A() const; }; void test6(const C *x) { // CHECK: [[T0:%.*]] = alloca [[A]], align 8 - // CHECK: [[X:%.*]] = load [[C]]** {{%.*}}, align 8 + // CHECK: [[X:%.*]] = load [[C]]*, [[C]]** {{%.*}}, align 8 // CHECK-NEXT: call void @_ZNK7Elision1CcvNS_1AEEv([[A]]* sret [[T0]], [[C]]* [[X]]) // CHECK-NEXT: call void @_ZNK7Elision1A3fooEv([[A]]* [[T0]]) // CHECK-NEXT: call void @_ZN7Elision1AD1Ev([[A]]* [[T0]]) @@ -557,11 +557,11 @@ namespace PR8623 { // CHECK: call void @_ZN6PR86231AC1Ei([[A]]* [[TMP]], i32 3) // CHECK-NEXT: store i1 true, i1* [[RCONS]] // CHECK-NEXT: br label - // CHECK: load i1* [[RCONS]] + // CHECK: load i1, i1* [[RCONS]] // CHECK-NEXT: br i1 // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) // CHECK-NEXT: br label - // CHECK: load i1* [[LCONS]] + // CHECK: load i1, i1* [[LCONS]] // CHECK-NEXT: br i1 // CHECK: call void @_ZN6PR86231AD1Ev([[A]]* [[TMP]]) // CHECK-NEXT: br label @@ -575,12 +575,12 @@ namespace PR11365 { // CHECK-LABEL: define void @_ZN7PR113653fooEv( void foo() { - // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [3 x [[A:%.*]]]* {{.*}}, i32 0, i32 0 - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[BEGIN]], i64 3 + // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [3 x [[A:%.*]]], [3 x [[A:%.*]]]* {{.*}}, i32 0, i32 0 + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[BEGIN]], i64 3 // CHECK-NEXT: br label // CHECK: [[PHI:%.*]] = phi - // CHECK-NEXT: [[ELEM:%.*]] = getelementptr inbounds [[A]]* [[PHI]], i64 -1 + // CHECK-NEXT: [[ELEM:%.*]] = getelementptr inbounds [[A]], [[A]]* [[PHI]], i64 -1 // CHECK-NEXT: call void @_ZN7PR113651AD1Ev([[A]]* [[ELEM]]) // CHECK-NEXT: icmp eq [[A]]* [[ELEM]], [[BEGIN]] // CHECK-NEXT: br i1 diff --git a/test/CodeGenCXX/throw-expressions.cpp b/test/CodeGenCXX/throw-expressions.cpp index 4dd5322..3fe2038 100644 --- a/test/CodeGenCXX/throw-expressions.cpp +++ b/test/CodeGenCXX/throw-expressions.cpp @@ -34,7 +34,7 @@ int test5(bool x, bool y, int z) { // CHECK: br i1 // // y.true: -// CHECK: load i32* +// CHECK: load i32, i32* // CHECK: br label // // y.false: @@ -58,7 +58,7 @@ int test6(bool x, bool y, int z) { // CHECK: br i1 // // y.true: -// CHECK: load i32* +// CHECK: load i32, i32* // CHECK: br label // // y.false: diff --git a/test/CodeGenCXX/thunks.cpp b/test/CodeGenCXX/thunks.cpp index 89e4db3..2287d65 100644 --- a/test/CodeGenCXX/thunks.cpp +++ b/test/CodeGenCXX/thunks.cpp @@ -227,7 +227,7 @@ namespace Test8 { void C::helper(NonPOD var) {} // CHECK-LABEL: define void @_ZThn8_N5Test81C3barENS_6NonPODE( - // CHECK-NOT: load [[NONPODTYPE]]* + // CHECK-NOT: load [[NONPODTYPE]], [[NONPODTYPE]]* // CHECK-NOT: memcpy // CHECK: ret void void C::bar(NonPOD var) {} @@ -295,8 +295,8 @@ namespace Test12 { // Varargs thunk; check that both the this and covariant adjustments // are generated. // CHECK: define {{.*}} @_ZTchn8_h8_N6Test121C1fEiz - // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 - // CHECK: getelementptr inbounds i8* {{.*}}, i64 8 + // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -8 + // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 8 } // PR13832 @@ -318,10 +318,10 @@ namespace Test13 { return *this; } // CHECK: define {{.*}} @_ZTcvn8_n32_v8_n24_N6Test131D4foo1Ev - // CHECK: getelementptr inbounds i8* {{.*}}, i64 -8 - // CHECK: getelementptr inbounds i8* {{.*}}, i64 -32 - // CHECK: getelementptr inbounds i8* {{.*}}, i64 -24 - // CHECK: getelementptr inbounds i8* {{.*}}, i64 8 + // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -8 + // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -32 + // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 -24 + // CHECK: getelementptr inbounds i8, i8* {{.*}}, i64 8 // CHECK: ret %"struct.Test13::D"* } @@ -363,12 +363,12 @@ namespace Test15 { /**** The following has to go at the end of the file ****/ +// This is from Test5: +// CHECK-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv( +// CHECK-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv + // This is from Test10: // CHECK-LABEL: define linkonce_odr void @_ZN6Test101C3fooEv // CHECK-LABEL: define linkonce_odr void @_ZThn8_N6Test101C3fooEv -// This is from Test5: -// CHECK-LABEL: define linkonce_odr void @_ZTv0_n24_N5Test51B1fEv -// CHECK-LABEL: define internal void @_ZThn8_N6Test4B12_GLOBAL__N_11C1fEv( - // CHECK: attributes [[NUW]] = { nounwind uwtable{{.*}} } diff --git a/test/CodeGenCXX/uncopyable-args.cpp b/test/CodeGenCXX/uncopyable-args.cpp index 77996f6..814cb62 100644 --- a/test/CodeGenCXX/uncopyable-args.cpp +++ b/test/CodeGenCXX/uncopyable-args.cpp @@ -12,7 +12,7 @@ void bar() { } // CHECK-LABEL: define void @_ZN7trivial3barEv() // CHECK: alloca %"struct.trivial::A" -// CHECK: load i8** +// CHECK: load i8*, i8** // CHECK: call void @_ZN7trivial3fooENS_1AE(i8* %{{.*}}) // CHECK-LABEL: declare void @_ZN7trivial3fooENS_1AE(i8*) @@ -33,7 +33,7 @@ void bar() { // CHECK-LABEL: define void @_ZN12default_ctor3barEv() // CHECK: alloca %"struct.default_ctor::A" // CHECK: call void @_Z{{.*}}C1Ev( -// CHECK: load i8** +// CHECK: load i8*, i8** // CHECK: call void @_ZN12default_ctor3fooENS_1AE(i8* %{{.*}}) // CHECK-LABEL: declare void @_ZN12default_ctor3fooENS_1AE(i8*) @@ -136,7 +136,7 @@ void bar() { } // CHECK-LABEL: define void @_ZN14copy_defaulted3barEv() // CHECK: call void @_Z{{.*}}C1Ev( -// CHECK: load i8** +// CHECK: load i8*, i8** // CHECK: call void @_ZN14copy_defaulted3fooENS_1AE(i8* %{{.*}}) // CHECK-LABEL: declare void @_ZN14copy_defaulted3fooENS_1AE(i8*) @@ -156,7 +156,7 @@ void bar() { } // CHECK-LABEL: define void @_ZN14move_defaulted3barEv() // CHECK: call void @_Z{{.*}}C1Ev( -// CHECK: load i8** +// CHECK: load i8*, i8** // CHECK: call void @_ZN14move_defaulted3fooENS_1AE(i8* %{{.*}}) // CHECK-LABEL: declare void @_ZN14move_defaulted3fooENS_1AE(i8*) @@ -175,7 +175,7 @@ void bar() { } // CHECK-LABEL: define void @_ZN17trivial_defaulted3barEv() // CHECK: call void @_Z{{.*}}C1Ev( -// CHECK: load i8** +// CHECK: load i8*, i8** // CHECK: call void @_ZN17trivial_defaulted3fooENS_1AE(i8* %{{.*}}) // CHECK-LABEL: declare void @_ZN17trivial_defaulted3fooENS_1AE(i8*) diff --git a/test/CodeGenCXX/unknown-anytype.cpp b/test/CodeGenCXX/unknown-anytype.cpp index e6f887b..42ed472 100644 --- a/test/CodeGenCXX/unknown-anytype.cpp +++ b/test/CodeGenCXX/unknown-anytype.cpp @@ -12,7 +12,7 @@ int test0() { extern __unknown_anytype test0_any; - // COMMON: load i32* @test0_any + // COMMON: load i32, i32* @test0_any return (int) test0_any; } @@ -24,21 +24,21 @@ int test1() { extern "C" __unknown_anytype test2_any(...); float test2() { - // X86_64: call float (double, ...)* @test2_any(double {{[^,]+}}) - // I386: call float (double, ...)* @test2_any(double {{[^,]+}}) + // X86_64: call float (double, ...) @test2_any(double {{[^,]+}}) + // I386: call float (double, ...) @test2_any(double {{[^,]+}}) return (float) test2_any(0.5f); } extern "C" __unknown_anytype test2a_any(...); float test2a() { - // X86_64: call float (float, ...)* @test2a_any(float {{[^,]+}}) - // I386: call float (float, ...)* @test2a_any(float {{[^,]+}}) + // X86_64: call float (float, ...) @test2a_any(float {{[^,]+}}) + // I386: call float (float, ...) @test2a_any(float {{[^,]+}}) return (float) test2a_any((float) 0.5f); } float test3() { extern __unknown_anytype test3_any; - // COMMON: [[FN:%.*]] = load float (i32)** @test3_any, + // COMMON: [[FN:%.*]] = load float (i32)*, float (i32)** @test3_any, // COMMON: call float [[FN]](i32 5) return ((float(*)(int)) test3_any)(5); } @@ -48,8 +48,8 @@ namespace test4 { extern __unknown_anytype test4_any2; int test() { - // COMMON: load i32* @_ZN5test410test4_any1E - // COMMON: load i8* @_ZN5test410test4_any2E + // COMMON: load i32, i32* @_ZN5test410test4_any1E + // COMMON: load i8, i8* @_ZN5test410test4_any2E return (int) test4_any1 + (char) test4_any2; } } @@ -119,7 +119,7 @@ void test10() { extern "C" __unknown_anytype malloc(...); void test11() { void *s = (void*)malloc(12); - // COMMON: call i8* (i32, ...)* @malloc(i32 12) + // COMMON: call i8* (i32, ...) @malloc(i32 12) void *d = (void*)malloc(435); - // COMMON: call i8* (i32, ...)* @malloc(i32 435) + // COMMON: call i8* (i32, ...) @malloc(i32 435) } diff --git a/test/CodeGenCXX/value-init.cpp b/test/CodeGenCXX/value-init.cpp index 423d973..735dc61 100644 --- a/test/CodeGenCXX/value-init.cpp +++ b/test/CodeGenCXX/value-init.cpp @@ -204,34 +204,34 @@ namespace test6 { // CHECK-LABEL: define void @_ZN5test64testEv() // CHECK: [[ARR:%.*]] = alloca [10 x [20 x [[A:%.*]]]], - // CHECK-NEXT: [[INNER:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]]* [[ARR]], i64 0, i64 0 - // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 0, i64 0 + // CHECK-NEXT: [[INNER:%.*]] = getelementptr inbounds [10 x [20 x [[A]]]], [10 x [20 x [[A]]]]* [[ARR]], i64 0, i64 0 + // CHECK-NEXT: [[T0:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[INNER]], i64 0, i64 0 // CHECK-NEXT: call void @_ZN5test61AC1Ei([[A]]* [[T0]], i32 5) - // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [[A]]* [[T0]], i64 1 - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]]* [[T0]], i64 20 + // CHECK-NEXT: [[BEGIN:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i64 1 + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [[A]], [[A]]* [[T0]], i64 20 // CHECK-NEXT: br label // CHECK: [[CUR:%.*]] = phi [[A]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[CUR]]) - // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]]* [[CUR]], i64 1 + // CHECK-NEXT: [[NEXT]] = getelementptr inbounds [[A]], [[A]]* [[CUR]], i64 1 // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[NEXT]], [[END]] // CHECK-NEXT: br i1 - // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 1 - // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [20 x [[A]]]* [[INNER]], i64 10 + // CHECK: [[BEGIN:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[INNER]], i64 1 + // CHECK-NEXT: [[END:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[INNER]], i64 10 // CHECK-NEXT: br label // CHECK: [[CUR:%.*]] = phi [20 x [[A]]]* [ [[BEGIN]], {{%.*}} ], [ [[NEXT:%.*]], {{%.*}} ] // Inner loop. - // CHECK-NEXT: [[IBEGIN:%.*]] = getelementptr inbounds [20 x [[A]]]* [[CUR]], i32 0, i32 0 - // CHECK-NEXT: [[IEND:%.*]] = getelementptr inbounds [[A]]* [[IBEGIN]], i64 20 + // CHECK-NEXT: [[IBEGIN:%.*]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[CUR]], i32 0, i32 0 + // CHECK-NEXT: [[IEND:%.*]] = getelementptr inbounds [[A]], [[A]]* [[IBEGIN]], i64 20 // CHECK-NEXT: br label // CHECK: [[ICUR:%.*]] = phi [[A]]* [ [[IBEGIN]], {{%.*}} ], [ [[INEXT:%.*]], {{%.*}} ] // CHECK-NEXT: call void @_ZN5test61AC1Ev([[A]]* [[ICUR]]) - // CHECK-NEXT: [[INEXT:%.*]] = getelementptr inbounds [[A]]* [[ICUR]], i64 1 + // CHECK-NEXT: [[INEXT:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ICUR]], i64 1 // CHECK-NEXT: [[T0:%.*]] = icmp eq [[A]]* [[INEXT]], [[IEND]] // CHECK-NEXT: br i1 [[T0]], - // CHECK: [[NEXT]] = getelementptr inbounds [20 x [[A]]]* [[CUR]], i64 1 + // CHECK: [[NEXT]] = getelementptr inbounds [20 x [[A]]], [20 x [[A]]]* [[CUR]], i64 1 // CHECK-NEXT: [[T0:%.*]] = icmp eq [20 x [[A]]]* [[NEXT]], [[END]] // CHECK-NEXT: br i1 [[T0]] // CHECK: ret void diff --git a/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp b/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp index 668fadf..530a428 100644 --- a/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp +++ b/test/CodeGenCXX/vararg-non-pod-ms-compat.cpp @@ -13,14 +13,14 @@ void test(X x) { // CHECK-LABEL: define void @"\01?test@@YAXUX@@@Z" // X86: %[[argmem:[^ ]*]] = alloca inalloca <{ %struct.X }> - // X86: call void (<{ %struct.X }>*, ...)* bitcast (void (...)* @"\01?vararg@@YAXZZ" to void (<{ %struct.X }>*, ...)*)(<{ %struct.X }>* inalloca %[[argmem]]) + // X86: call void (<{ %struct.X }>*, ...) bitcast (void (...)* @"\01?vararg@@YAXZZ" to void (<{ %struct.X }>*, ...)*)(<{ %struct.X }>* inalloca %[[argmem]]) // X64: alloca %struct.X // X64: %[[agg:[^ ]*]] = alloca %struct.X - // X64: %[[valptr:[^ ]*]] = getelementptr %struct.X* %[[agg]], i32 0, i32 0 - // X64: %[[val:[^ ]*]] = load i32* %[[valptr]] - // X64: call void (...)* @"\01?vararg@@YAXZZ"(i32 %[[val]]) + // X64: %[[valptr:[^ ]*]] = getelementptr %struct.X, %struct.X* %[[agg]], i32 0, i32 0 + // X64: %[[val:[^ ]*]] = load i32, i32* %[[valptr]] + // X64: call void (...) @"\01?vararg@@YAXZZ"(i32 %[[val]]) // CHECK-NOT: llvm.trap vararg(x); diff --git a/test/CodeGenCXX/varargs.cpp b/test/CodeGenCXX/varargs.cpp index 31bbee98..1ea072e 100644 --- a/test/CodeGenCXX/varargs.cpp +++ b/test/CodeGenCXX/varargs.cpp @@ -12,7 +12,7 @@ namespace test0 { return -1; } - // CHECK: call i32 (...)* @_ZN5test05test1Ez(i32 0) + // CHECK: call i32 (...) @_ZN5test05test1Ez(i32 0) void test() { test1(0); } @@ -37,7 +37,7 @@ namespace test1 { // CHECK-NEXT: [[T1:%.*]] = bitcast [[A]]* [[X]] to i8* // CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i64(i8* [[T0]], i8* [[T1]], i64 8, i32 4, i1 false) // CHECK-NEXT: [[T0:%.*]] = bitcast [[A]]* [[TMP]] to i64* - // CHECK-NEXT: [[T1:%.*]] = load i64* [[T0]], align 1 - // CHECK-NEXT: call void (...)* @_ZN5test13fooEz(i64 [[T1]]) + // CHECK-NEXT: [[T1:%.*]] = load i64, i64* [[T0]], align 1 + // CHECK-NEXT: call void (...) @_ZN5test13fooEz(i64 [[T1]]) // CHECK-NEXT: ret void } diff --git a/test/CodeGenCXX/vector-splat-conversion.cpp b/test/CodeGenCXX/vector-splat-conversion.cpp new file mode 100644 index 0000000..410df3d --- /dev/null +++ b/test/CodeGenCXX/vector-splat-conversion.cpp @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 %s -triple arm64-apple-ios8.1.0 -std=c++11 -emit-llvm -o - | FileCheck %s +// rdar://20000762 + +typedef __attribute__((__ext_vector_type__(8))) float vector_float8; + +typedef vector_float8 float8; + +void MandelbrotPolyCalcSIMD8() +{ + constexpr float8 v4 = 4.0; // value to compare against abs(z)^2, to see if bounded + float8 vABS; + auto vLT = vABS < v4; +} + +// CHECK: store <8 x float> +// CHECK: [[ZERO:%.*]] = load <8 x float>, <8 x float>* [[VARBS:%.*]] +// CHECK: [[CMP:%.*]] = fcmp olt <8 x float> [[ZERO]] +// CHECK: [[SEXT:%.*]] = sext <8 x i1> [[CMP]] to <8 x i32> +// CHECK: store <8 x i32> [[SEXT]], <8 x i32>* [[VLT:%.*]] diff --git a/test/CodeGenCXX/virtual-base-cast.cpp b/test/CodeGenCXX/virtual-base-cast.cpp index 0dcf319..554e80d 100644 --- a/test/CodeGenCXX/virtual-base-cast.cpp +++ b/test/CodeGenCXX/virtual-base-cast.cpp @@ -13,53 +13,53 @@ D* x; A* a() { return x; } // CHECK: @_Z1av() [[NUW:#[0-9]+]] -// CHECK: [[VBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = getelementptr i8* {{.*}}, i64 -16 +// CHECK: [[VBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = getelementptr i8, i8* {{.*}}, i64 -16 // CHECK: [[CASTVBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = bitcast i8* [[VBASEOFFSETPTRA]] to i32* -// CHECK: load i32* [[CASTVBASEOFFSETPTRA]] +// CHECK: load i32, i32* [[CASTVBASEOFFSETPTRA]] // CHECK: } // MSVC: @"\01?a@@YAPAUA@@XZ"() [[NUW:#[0-9]+]] { -// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 0 +// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* {{.*}}, i32 0 // MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32** -// MSVC: %[[vbtable:.*]] = load i32** %[[vbptr]] -// MSVC: %[[entry:.*]] = getelementptr inbounds i32* {{.*}}, i32 1 -// MSVC: %[[offset:.*]] = load i32* %[[entry]] +// MSVC: %[[vbtable:.*]] = load i32*, i32** %[[vbptr]] +// MSVC: %[[entry:.*]] = getelementptr inbounds i32, i32* {{.*}}, i32 1 +// MSVC: %[[offset:.*]] = load i32, i32* %[[entry]] // MSVC: add nsw i32 0, %[[offset]] // MSVC: } B* b() { return x; } // CHECK: @_Z1bv() [[NUW]] -// CHECK: [[VBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = getelementptr i8* {{.*}}, i64 -20 +// CHECK: [[VBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = getelementptr i8, i8* {{.*}}, i64 -20 // CHECK: [[CASTVBASEOFFSETPTRA:%[a-zA-Z0-9\.]+]] = bitcast i8* [[VBASEOFFSETPTRA]] to i32* -// CHECK: load i32* [[CASTVBASEOFFSETPTRA]] +// CHECK: load i32, i32* [[CASTVBASEOFFSETPTRA]] // CHECK: } // Same as 'a' except we use a different vbtable offset. // MSVC: @"\01?b@@YAPAUB@@XZ"() [[NUW:#[0-9]+]] { -// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 0 +// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* {{.*}}, i32 0 // MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32** -// MSVC: %[[vbtable:.*]] = load i32** %[[vbptr]] -// MSVC: %[[entry:.*]] = getelementptr inbounds i32* {{.*}}, i32 2 -// MSVC: %[[offset:.*]] = load i32* %[[entry]] +// MSVC: %[[vbtable:.*]] = load i32*, i32** %[[vbptr]] +// MSVC: %[[entry:.*]] = getelementptr inbounds i32, i32* {{.*}}, i32 2 +// MSVC: %[[offset:.*]] = load i32, i32* %[[entry]] // MSVC: add nsw i32 0, %[[offset]] // MSVC: } BB* c() { return x; } // CHECK: @_Z1cv() [[NUW]] -// CHECK: [[VBASEOFFSETPTRC:%[a-zA-Z0-9\.]+]] = getelementptr i8* {{.*}}, i64 -24 +// CHECK: [[VBASEOFFSETPTRC:%[a-zA-Z0-9\.]+]] = getelementptr i8, i8* {{.*}}, i64 -24 // CHECK: [[CASTVBASEOFFSETPTRC:%[a-zA-Z0-9\.]+]] = bitcast i8* [[VBASEOFFSETPTRC]] to i32* -// CHECK: [[VBASEOFFSETC:%[a-zA-Z0-9\.]+]] = load i32* [[CASTVBASEOFFSETPTRC]] +// CHECK: [[VBASEOFFSETC:%[a-zA-Z0-9\.]+]] = load i32, i32* [[CASTVBASEOFFSETPTRC]] // CHECK: add i32 [[VBASEOFFSETC]], 8 // CHECK: } // Same as 'a' except we use a different vbtable offset. // MSVC: @"\01?c@@YAPAUBB@@XZ"() [[NUW:#[0-9]+]] { -// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 0 +// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* {{.*}}, i32 0 // MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32** -// MSVC: %[[vbtable:.*]] = load i32** %[[vbptr]] -// MSVC: %[[entry:.*]] = getelementptr inbounds i32* {{.*}}, i32 4 -// MSVC: %[[offset:.*]] = load i32* %[[entry]] +// MSVC: %[[vbtable:.*]] = load i32*, i32** %[[vbptr]] +// MSVC: %[[entry:.*]] = getelementptr inbounds i32, i32* {{.*}}, i32 4 +// MSVC: %[[offset:.*]] = load i32, i32* %[[entry]] // MSVC: add nsw i32 0, %[[offset]] // MSVC: } @@ -74,11 +74,11 @@ BB* d() { return y; } // Same as 'c' except the vbptr offset is 4, changing the initial GEP and the // final add. // MSVC: @"\01?d@@YAPAUBB@@XZ"() [[NUW:#[0-9]+]] { -// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8* {{.*}}, i32 4 +// MSVC: %[[vbptr_off:.*]] = getelementptr inbounds i8, i8* {{.*}}, i32 4 // MSVC: %[[vbptr:.*]] = bitcast i8* %[[vbptr_off]] to i32** -// MSVC: %[[vbtable:.*]] = load i32** %[[vbptr]] -// MSVC: %[[entry:.*]] = getelementptr inbounds i32* {{.*}}, i32 4 -// MSVC: %[[offset:.*]] = load i32* %[[entry]] +// MSVC: %[[vbtable:.*]] = load i32*, i32** %[[vbptr]] +// MSVC: %[[entry:.*]] = getelementptr inbounds i32, i32* {{.*}}, i32 4 +// MSVC: %[[offset:.*]] = load i32, i32* %[[entry]] // MSVC: add nsw i32 4, %[[offset]] // MSVC: } diff --git a/test/CodeGenCXX/virtual-base-destructor-call.cpp b/test/CodeGenCXX/virtual-base-destructor-call.cpp index 3d79071..29f1f5c 100644 --- a/test/CodeGenCXX/virtual-base-destructor-call.cpp +++ b/test/CodeGenCXX/virtual-base-destructor-call.cpp @@ -22,11 +22,6 @@ int main() { // CHECK: call {{.*}} @_ZN14basic_iostreamIcED2Ev // CHECK: call {{.*}} @_ZN9basic_iosD2Ev -// basic_iostream's base dtor calls its non-virtual base dtor. -// CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED2Ev(%struct.basic_iostream* {{.*}}%this, i8** %vtt) unnamed_addr -// CHECK: call {{.*}} @_ZN13basic_istreamIcED2Ev -// CHECK: } - // basic_istream's complete dtor calls the base dtor, // then its virtual base's base dtor. // CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED1Ev(%struct.basic_istream* {{.*}}%this) unnamed_addr @@ -49,3 +44,8 @@ int main() { // CHECK: define linkonce_odr {{.*}} @_ZN13basic_istreamIcED2Ev(%struct.basic_istream* {{.*}}%this, i8** %vtt) unnamed_addr // CHECK-NOT: call // CHECK: } + +// basic_iostream's base dtor calls its non-virtual base dtor. +// CHECK: define linkonce_odr {{.*}} @_ZN14basic_iostreamIcED2Ev(%struct.basic_iostream* {{.*}}%this, i8** %vtt) unnamed_addr +// CHECK: call {{.*}} @_ZN13basic_istreamIcED2Ev +// CHECK: } diff --git a/test/CodeGenCXX/visibility.cpp b/test/CodeGenCXX/visibility.cpp index 1c4d5bb..7239cbe 100644 --- a/test/CodeGenCXX/visibility.cpp +++ b/test/CodeGenCXX/visibility.cpp @@ -135,17 +135,22 @@ namespace test27 { // CHECK-HIDDEN: _ZTVN6test271CIiE1DE = unnamed_addr constant } -// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global -// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64 -// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global -// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64 +// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant + +// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant +// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant + // CHECK: @_ZZN6test681fC1EvE4test = linkonce_odr global -// CHECK: @_ZGVZN6test681fC1EvE4test = linkonce_odr global // CHECK-HIDDEN: @_ZZN6test681fC1EvE4test = linkonce_odr hidden global + +// CHECK: @_ZGVZN6test681fC1EvE4test = linkonce_odr global // CHECK-HIDDEN: @_ZGVZN6test681fC1EvE4test = linkonce_odr hidden global -// CHECK-HIDDEN: @_ZTVN6Test161AIcEE = external unnamed_addr constant -// CHECK-HIDDEN: @_ZTTN6Test161AIcEE = external unnamed_addr constant -// CHECK: @_ZTVN5Test63fooE = linkonce_odr hidden unnamed_addr constant + +// CHECK: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr global +// CHECK-HIDDEN: @_ZZN6Test193fooIiEEvvE1a = linkonce_odr hidden global + +// CHECK: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr global i64 +// CHECK-HIDDEN: @_ZGVZN6Test193fooIiEEvvE1a = linkonce_odr hidden global i64 namespace Test1 { // CHECK-LABEL: define hidden void @_ZN5Test11fEv @@ -235,7 +240,7 @@ namespace Test7 { class B : public A {}; B b; // top of file - // CHECK-LABEL: define linkonce_odr hidden void @_ZN5Test74ArefILZNS_1aEEE3fooEv() + // CHECK-LABEL: define linkonce_odr hidden void @_ZN5Test74ArefIL_ZNS_1aEEE3fooEv() void test() { Aref<a>::foo(); } diff --git a/test/CodeGenCXX/vla-lambda-capturing.cpp b/test/CodeGenCXX/vla-lambda-capturing.cpp index e8fd0a1..f2332bf 100644 --- a/test/CodeGenCXX/vla-lambda-capturing.cpp +++ b/test/CodeGenCXX/vla-lambda-capturing.cpp @@ -15,14 +15,14 @@ typedef __INTPTR_TYPE__ intptr_t; // CHECK: define void [[G:@.+]]( // CHECK: [[N_ADDR:%.+]] = alloca [[INTPTR_T]] // CHECK: store [[INTPTR_T]] %{{.+}}, [[INTPTR_T]]* [[N_ADDR]] -// CHECK: [[N_VAL:%.+]] = load [[INTPTR_T]]* [[N_ADDR]] -// CHECK: [[CAP_EXPR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE1]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[N_VAL:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[N_ADDR]] +// CHECK: [[CAP_EXPR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE1]], [[CAP_TYPE1]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0 // CHECK: store [[INTPTR_T]] [[N_VAL]], [[INTPTR_T]]* [[CAP_EXPR_REF]] -// CHECK: [[CAP_BUFFER_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[CAP_BUFFER_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]], [[CAP_TYPE1]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1 // CHECK: store [[INTPTR_T]]* %{{.+}}, [[INTPTR_T]]** [[CAP_BUFFER_ADDR]] -// CHECK: [[CAP_N_REF:%.+]] = getelementptr inbounds [[CAP_TYPE1]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[CAP_N_REF:%.+]] = getelementptr inbounds [[CAP_TYPE1]], [[CAP_TYPE1]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 2 // CHECK: store [[INTPTR_T]]* [[N_ADDR]], [[INTPTR_T]]** [[CAP_N_REF]] -// CHECK: call void [[G_LAMBDA:@.+]]([[CAP_TYPE1]]* [[CAP_ARG]]) +// CHECK: call{{( x86_thiscallcc)?}} void [[G_LAMBDA:@.+]]([[CAP_TYPE1]]* [[CAP_ARG]]) // CHECK: ret void void g(intptr_t n) { intptr_t buffer[n]; @@ -32,11 +32,11 @@ void g(intptr_t n) { } // CHECK: void [[G_LAMBDA]]([[CAP_TYPE1]]* -// CHECK: [[THIS:%.+]] = load [[CAP_TYPE1]]** -// CHECK: [[N_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]]* [[THIS]], i{{.+}} 0, i{{.+}} 0 -// CHECK: [[N:%.+]] = load [[INTPTR_T]]* [[N_ADDR]] -// CHECK: [[BUFFER_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]]* [[THIS]], i{{.+}} 0, i{{.+}} 1 -// CHECK: [[BUFFER:%.+]] = load [[INTPTR_T]]** [[BUFFER_ADDR]] +// CHECK: [[THIS:%.+]] = load [[CAP_TYPE1]]*, [[CAP_TYPE1]]** +// CHECK: [[N_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]], [[CAP_TYPE1]]* [[THIS]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[N:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[N_ADDR]] +// CHECK: [[BUFFER_ADDR:%.+]] = getelementptr inbounds [[CAP_TYPE1]], [[CAP_TYPE1]]* [[THIS]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[BUFFER:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER_ADDR]] // CHECK: call i{{.+}}* @llvm.stacksave() // CHECK: alloca [[INTPTR_T]], [[INTPTR_T]] [[N]] // CHECK: call void @llvm.stackrestore( @@ -80,15 +80,15 @@ int main() { return 0; } -// CHECK: void [[F_INT]]([[INTPTR_T]] +// CHECK: define linkonce_odr void [[F_INT]]([[INTPTR_T]] // CHECK: [[SIZE:%.+]] = add // CHECK: call i{{.+}}* @llvm.stacksave() // CHECK: [[BUFFER_ADDR:%.+]] = alloca [[INTPTR_T]], [[INTPTR_T]] [[SIZE]] -// CHECK: [[CAP_SIZE_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[CAP_SIZE_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]], [[CAP_TYPE2]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0 // CHECK: store [[INTPTR_T]] [[SIZE]], [[INTPTR_T]]* [[CAP_SIZE_REF]] -// CHECK: [[CAP_BUFFER_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[CAP_BUFFER_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]], [[CAP_TYPE2]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1 // CHECK: store [[INTPTR_T]]* [[BUFFER_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER_ADDR_REF]] -// CHECK: call void [[F_INT_LAMBDA:@.+]]([[CAP_TYPE2]]* [[CAP_ARG]]) +// CHECK: call{{( x86_thiscallcc)?}} void [[F_INT_LAMBDA:@.+]]([[CAP_TYPE2]]* [[CAP_ARG]]) // CHECK: call void @llvm.stackrestore( // CHECK: ret void // CHECK: void [[B_INT]]([[INTPTR_T]] @@ -97,75 +97,75 @@ int main() { // CHECK: [[BUFFER2_ADDR:%.+]] = alloca [[INTPTR_T]], [[INTPTR_T]] [[SIZE1]] // CHECK: [[SIZE2:%.+]] = add // CHECK: [[BUFFER1_ADDR:%.+]] = alloca [[INTPTR_T]], [[INTPTR_T]] -// CHECK: [[CAP_N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[CAP_N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[CAP_ARG:%.+]], i{{.+}} 0, i{{.+}} 0 // CHECK: store [[INTPTR_T]]* {{%.+}}, [[INTPTR_T]]** [[CAP_N_ADDR_REF]] -// CHECK: [[CAP_SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1 +// CHECK: [[CAP_SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 1 // CHECK: store i{{[0-9]+}} [[SIZE2]], i{{[0-9]+}}* [[CAP_SIZE2_REF]] -// CHECK: [[CAP_SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 2 +// CHECK: [[CAP_SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 2 // CHECK: store i{{[0-9]+}} [[SIZE1]], i{{[0-9]+}}* [[CAP_SIZE1_REF]] -// CHECK: [[CAP_BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 3 +// CHECK: [[CAP_BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 3 // CHECK: store [[INTPTR_T]]* [[BUFFER1_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER1_ADDR_REF]] -// CHECK: [[CAP_BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 4 +// CHECK: [[CAP_BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[CAP_ARG]], i{{.+}} 0, i{{.+}} 4 // CHECK: store [[INTPTR_T]]* [[BUFFER2_ADDR]], [[INTPTR_T]]** [[CAP_BUFFER2_ADDR_REF]] -// CHECK: call void [[B_INT_LAMBDA:@.+]]([[CAP_TYPE3]]* [[CAP_ARG]]) +// CHECK: call{{( x86_thiscallcc)?}} void [[B_INT_LAMBDA:@.+]]([[CAP_TYPE3]]* [[CAP_ARG]]) // CHECK: call void @llvm.stackrestore( // CHECK: ret void -// CHECK: define {{.*}} void [[B_INT_LAMBDA]]([[CAP_TYPE3]]* -// CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[SIZE2:%.+]] = load i{{[0-9]+}}* [[SIZE2_REF]] -// CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[SIZE1:%.+]] = load i{{[0-9]+}}* [[SIZE1_REF]] -// CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[N_ADDR:%.+]] = load [[INTPTR_T]]** [[N_ADDR_REF]] -// CHECK: [[N:%.+]] = load [[INTPTR_T]]* [[N_ADDR]] -// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 -// CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]** [[BUFFER1_ADDR_REF]] +// CHECK: define linkonce_odr{{( x86_thiscallcc)?}} void [[F_INT_LAMBDA]]([[CAP_TYPE2]]* +// CHECK: [[THIS:%.+]] = load [[CAP_TYPE2]]*, [[CAP_TYPE2]]** +// CHECK: [[SIZE_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]], [[CAP_TYPE2]]* [[THIS]], i{{.+}} 0, i{{.+}} 0 +// CHECK: [[SIZE:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[SIZE_REF]] +// CHECK: call i{{.+}}* @llvm.stacksave() +// CHECK: alloca [[INTPTR_T]], [[INTPTR_T]] [[SIZE]] +// CHECK: call void @llvm.stackrestore( +// CHECK: ret void + +// CHECK: define linkonce_odr{{( x86_thiscallcc)?}} void [[B_INT_LAMBDA]]([[CAP_TYPE3]]* +// CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[SIZE2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE2_REF]] +// CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[SIZE1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE1_REF]] +// CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[N_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[N_ADDR_REF]] +// CHECK: [[N:%.+]] = load [[INTPTR_T]], [[INTPTR_T]]* [[N_ADDR]] +// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER1_ADDR_REF]] // CHECK: [[ELEM_OFFSET:%.+]] = mul {{.*}} i{{[0-9]+}} [[N]], [[SIZE1]] -// CHECK: [[ELEM_ADDR:%.+]] = getelementptr inbounds [[INTPTR_T]]* [[BUFFER1_ADDR]], i{{[0-9]+}} [[ELEM_OFFSET]] +// CHECK: [[ELEM_ADDR:%.+]] = getelementptr inbounds [[INTPTR_T]], [[INTPTR_T]]* [[BUFFER1_ADDR]], i{{[0-9]+}} [[ELEM_OFFSET]] // CHECK: [[SIZEOF:%.+]] = mul {{.*}} i{{[0-9]+}} {{[0-9]+}}, [[SIZE1]] -// CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[N_ADDR:%.+]] = load [[INTPTR_T]]** [[N_ADDR_REF]] +// CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[N_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[N_ADDR_REF]] // CHECK: store [[INTPTR_T]] {{%.+}}, [[INTPTR_T]]* [[N_ADDR]] -// CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[CAP:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[N_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 -// CHECK: [[N_ADDR_ORIG:%.+]] = load [[INTPTR_T]]** [[N_ADDR_REF_ORIG]] +// CHECK: [[N_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[CAP:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[N_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 0 +// CHECK: [[N_ADDR_ORIG:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[N_ADDR_REF_ORIG]] // CHECK: store [[INTPTR_T]]* [[N_ADDR_ORIG]], [[INTPTR_T]]** [[N_ADDR_REF]] -// CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 // CHECK: store i{{[0-9]+}} [[SIZE1]], i{{[0-9]+}}* [[SIZE1_REF]] -// CHECK: [[BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[BUFFER2_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 -// CHECK: [[BUFFER2_ADDR_ORIG:%.+]] = load [[INTPTR_T]]** [[BUFFER2_ADDR_REF_ORIG]] +// CHECK: [[BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[BUFFER2_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: [[BUFFER2_ADDR_ORIG:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER2_ADDR_REF_ORIG]] // CHECK: store [[INTPTR_T]]* [[BUFFER2_ADDR_ORIG]], [[INTPTR_T]]** [[BUFFER2_ADDR_REF]] -// CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 // CHECK: store i{{[0-9]+}} [[SIZE2]], i{{[0-9]+}}* [[SIZE2_REF]] -// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 -// CHECK: [[BUFFER1_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 -// CHECK: [[BUFFER1_ADDR_ORIG:%.+]] = load [[INTPTR_T]]** [[BUFFER1_ADDR_REF_ORIG]] +// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[CAP]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: [[BUFFER1_ADDR_REF_ORIG:%.+]] = getelementptr inbounds [[CAP_TYPE3]], [[CAP_TYPE3]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[BUFFER1_ADDR_ORIG:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER1_ADDR_REF_ORIG]] // CHECK: store [[INTPTR_T]]* [[BUFFER1_ADDR_ORIG]], [[INTPTR_T]]** [[BUFFER1_ADDR_REF]] -// CHECK: call void [[B_INT_LAMBDA_LAMBDA:@.+]]([[CAP_TYPE4]]* [[CAP]]) +// CHECK: call{{( x86_thiscallcc)?}} void [[B_INT_LAMBDA_LAMBDA:@.+]]([[CAP_TYPE4]]* [[CAP]]) // CHECK: ret void -// CHECK: define {{.*}} void [[B_INT_LAMBDA_LAMBDA]]([[CAP_TYPE4]]* -// CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[THIS:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 -// CHECK: [[SIZE1:%.+]] = load i{{[0-9]+}}* [[SIZE1_REF]] -// CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 -// CHECK: [[SIZE2:%.+]] = load i{{[0-9]+}}* [[SIZE2_REF]] -// CHECK: [[BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 -// CHECK: [[BUFFER2_ADDR:%.+]] = load [[INTPTR_T]]** [[BUFFER2_ADDR_REF]] +// CHECK: define linkonce_odr{{( x86_thiscallcc)?}} void [[B_INT_LAMBDA_LAMBDA]]([[CAP_TYPE4]]* +// CHECK: [[SIZE1_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[THIS:%.+]], i{{[0-9]+}} 0, i{{[0-9]+}} 1 +// CHECK: [[SIZE1:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE1_REF]] +// CHECK: [[SIZE2_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 3 +// CHECK: [[SIZE2:%.+]] = load i{{[0-9]+}}, i{{[0-9]+}}* [[SIZE2_REF]] +// CHECK: [[BUFFER2_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 2 +// CHECK: [[BUFFER2_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER2_ADDR_REF]] // CHECK: [[SIZEOF_BUFFER2:%.+]] = mul {{.*}} i{{[0-9]+}} {{[0-9]+}}, [[SIZE1]] -// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 -// CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]** [[BUFFER1_ADDR_REF]] +// CHECK: [[BUFFER1_ADDR_REF:%.+]] = getelementptr inbounds [[CAP_TYPE4]], [[CAP_TYPE4]]* [[THIS]], i{{[0-9]+}} 0, i{{[0-9]+}} 4 +// CHECK: [[BUFFER1_ADDR:%.+]] = load [[INTPTR_T]]*, [[INTPTR_T]]** [[BUFFER1_ADDR_REF]] // CHECK: [[MUL:%.+]] = mul {{.*}} i{{[0-9]+}} [[SIZE2]], [[SIZE1]] // CHECK: mul {{.*}} i{{[0-9]+}} {{[0-9]+}}, [[MUL]] // CHECK: ret void - -// CHECK: void [[F_INT_LAMBDA]]([[CAP_TYPE2]]* -// CHECK: [[THIS:%.+]] = load [[CAP_TYPE2]]** -// CHECK: [[SIZE_REF:%.+]] = getelementptr inbounds [[CAP_TYPE2]]* [[THIS]], i{{.+}} 0, i{{.+}} 0 -// CHECK: [[SIZE:%.+]] = load [[INTPTR_T]]* [[SIZE_REF]] -// CHECK: call i{{.+}}* @llvm.stacksave() -// CHECK: alloca [[INTPTR_T]], [[INTPTR_T]] [[SIZE]] -// CHECK: call void @llvm.stackrestore( -// CHECK: ret void #endif diff --git a/test/CodeGenCXX/vla.cpp b/test/CodeGenCXX/vla.cpp index a6616d3..4e22bba 100644 --- a/test/CodeGenCXX/vla.cpp +++ b/test/CodeGenCXX/vla.cpp @@ -25,30 +25,30 @@ void test0(void *array, int n) { // CHECK-NEXT: store i32 // Capture the bounds. - // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[N]], align 4 // CHECK-NEXT: [[DIM0:%.*]] = zext i32 [[T0]] to i64 - // CHECK-NEXT: [[T0:%.*]] = load i32* [[N]], align 4 + // CHECK-NEXT: [[T0:%.*]] = load i32, i32* [[N]], align 4 // CHECK-NEXT: [[T1:%.*]] = add nsw i32 [[T0]], 1 // CHECK-NEXT: [[DIM1:%.*]] = zext i32 [[T1]] to i64 typedef short array_t[n][n+1]; - // CHECK-NEXT: [[T0:%.*]] = load i8** [[ARRAY]], align 8 + // CHECK-NEXT: [[T0:%.*]] = load i8*, i8** [[ARRAY]], align 8 // CHECK-NEXT: [[T1:%.*]] = bitcast i8* [[T0]] to i16* // CHECK-NEXT: store i16* [[T1]], i16** [[REF]], align 8 array_t &ref = *(array_t*) array; - // CHECK-NEXT: [[T0:%.*]] = load i16** [[REF]] + // CHECK-NEXT: [[T0:%.*]] = load i16*, i16** [[REF]] // CHECK-NEXT: [[T1:%.*]] = mul nsw i64 1, [[DIM1]] - // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i16* [[T0]], i64 [[T1]] - // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i16* [[T2]], i64 2 + // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i16, i16* [[T0]], i64 [[T1]] + // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i16, i16* [[T2]], i64 2 // CHECK-NEXT: store i16 3, i16* [[T3]] ref[1][2] = 3; - // CHECK-NEXT: [[T0:%.*]] = load i16** [[REF]] + // CHECK-NEXT: [[T0:%.*]] = load i16*, i16** [[REF]] // CHECK-NEXT: [[T1:%.*]] = mul nsw i64 4, [[DIM1]] - // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i16* [[T0]], i64 [[T1]] - // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i16* [[T2]], i64 5 - // CHECK-NEXT: [[T4:%.*]] = load i16* [[T3]] + // CHECK-NEXT: [[T2:%.*]] = getelementptr inbounds i16, i16* [[T0]], i64 [[T1]] + // CHECK-NEXT: [[T3:%.*]] = getelementptr inbounds i16, i16* [[T2]], i64 5 + // CHECK-NEXT: [[T4:%.*]] = load i16, i16* [[T3]] // CHECK-NEXT: store i16 [[T4]], i16* [[S]], align 2 short s = ref[4][5]; diff --git a/test/CodeGenCXX/volatile-1.cpp b/test/CodeGenCXX/volatile-1.cpp index 2038936..65eb9f6 100644 --- a/test/CodeGenCXX/volatile-1.cpp +++ b/test/CodeGenCXX/volatile-1.cpp @@ -26,8 +26,8 @@ void test() { i; (float)(ci); - // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) // CHECK-NEXT: sitofp [[INT]] // These are not uses in C++: @@ -37,40 +37,40 @@ void test() { (void)a; (void)(ci=ci); - // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) (void)(i=j); - // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* @j + // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* @j // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* @i ci+=ci; - // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) // Not sure why they're ordered this way. // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]] // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]] - // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) // Note that C++ requires an extra load volatile over C from the LHS of the '+'. (ci += ci) + ci; - // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) // CHECK-NEXT: [[R:%.*]] = add [[INT]] [[R2]], [[R1]] // CHECK-NEXT: [[I:%.*]] = add [[INT]] [[I2]], [[I1]] - // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 0) - // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[R]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: store volatile [[INT]] [[I]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I1:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[R2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 0) + // CHECK-NEXT: [[I2:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) // These additions can be elided. // CHECK-NEXT: add [[INT]] [[R1]], [[R2]] // CHECK-NEXT: add [[INT]] [[I1]], [[I2]] @@ -160,17 +160,17 @@ void test() { // CHECK-NEXT: store volatile i=i,k; - // CHECK-NEXT: load volatile [[INT]]* @i + // CHECK-NEXT: load volatile [[INT]], [[INT]]* @i // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i (i=j,k=j); - // CHECK-NEXT: load volatile [[INT]]* @j + // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i - // CHECK-NEXT: load volatile [[INT]]* @j + // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @k (i=j,k); - // CHECK-NEXT: load volatile [[INT]]* @j + // CHECK-NEXT: load volatile [[INT]], [[INT]]* @j // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i (i,j); @@ -225,10 +225,10 @@ void test() { // CHECK-NEXT: store volatile __imag ci = __imag ci = __imag ci; - // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) - // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: [[T:%.*]] = load volatile [[INT]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) + // CHECK-NEXT: store volatile [[INT]] [[T]], [[INT]]* getelementptr inbounds ([[CINT]], [[CINT]]* @ci, i32 0, i32 1) __real (i = j); // CHECK-NEXT: load volatile @@ -339,12 +339,12 @@ void test() { // CHECK-NEXT: add (i,j)=k; - // CHECK-NEXT: load volatile [[INT]]* @k + // CHECK-NEXT: load volatile [[INT]], [[INT]]* @k // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j (j=k,i)=i; - // CHECK-NEXT: load volatile [[INT]]* @i - // CHECK-NEXT: load volatile [[INT]]* @k + // CHECK-NEXT: load volatile [[INT]], [[INT]]* @i + // CHECK-NEXT: load volatile [[INT]], [[INT]]* @k // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @j // CHECK-NEXT: store volatile {{.*}}, [[INT]]* @i diff --git a/test/CodeGenCXX/volatile.cpp b/test/CodeGenCXX/volatile.cpp index f6ae0c5..ea7429f 100644 --- a/test/CodeGenCXX/volatile.cpp +++ b/test/CodeGenCXX/volatile.cpp @@ -13,8 +13,8 @@ namespace test0 { // CHECK-LABEL: define void @_ZN5test04testENS_1AE( void test(A t) { - // CHECK: [[ARR:%.*]] = load [[A:%.*]]** @_ZN5test05arrayE, align 8 - // CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [[A]]* [[ARR]], i64 0 + // CHECK: [[ARR:%.*]] = load [[A:%.*]]*, [[A:%.*]]** @_ZN5test05arrayE, align 8 + // CHECK-NEXT: [[IDX:%.*]] = getelementptr inbounds [[A]], [[A]]* [[ARR]], i64 0 // CHECK-NEXT: [[TMP:%.*]] = call dereferenceable({{[0-9]+}}) [[A]]* @_ZNV5test01AaSERVKS0_([[A]]* [[IDX]], [[A]]* dereferenceable({{[0-9]+}}) [[T:%.*]]) // CHECK-NEXT: ret void array[0] = t; @@ -26,7 +26,7 @@ namespace test1 { // CHECK-LABEL: define void @_ZN5test14testEv() void test() { - // CHECK: [[TMP:%.*]] = load i32** @_ZN5test11xE, align 8 + // CHECK: [[TMP:%.*]] = load i32*, i32** @_ZN5test11xE, align 8 // CHECK-NEXT: ret void *x; } diff --git a/test/CodeGenCXX/vtable-holder-self-reference.cpp b/test/CodeGenCXX/vtable-holder-self-reference.cpp index 05e6d71..8f5314e 100644 --- a/test/CodeGenCXX/vtable-holder-self-reference.cpp +++ b/test/CodeGenCXX/vtable-holder-self-reference.cpp @@ -4,7 +4,8 @@ // rid of self-referenceing structure_types (PR21902), then it should be safe // to just kill this test. // -// CHECK: ![[SELF:[0-9]+]] = distinct !{!"0x13\00B\00{{[^"]*}}", {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, {{[^,]+}}, ![[SELF]], {{[^}]+}}} ; [ DW_TAG_structure_type ] [B] +// CHECK: ![[SELF:[0-9]+]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "B", +// CHECK-SAME: vtableHolder: ![[SELF]] void foo() { struct V { diff --git a/test/CodeGenCXX/vtable-linkage.cpp b/test/CodeGenCXX/vtable-linkage.cpp index 9c08b30..5cbd389 100644 --- a/test/CodeGenCXX/vtable-linkage.cpp +++ b/test/CodeGenCXX/vtable-linkage.cpp @@ -1,4 +1,4 @@ -// RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -emit-llvm -o %t +// RUN: %clang_cc1 %s -triple=x86_64-pc-linux -emit-llvm -o %t // RUN: %clang_cc1 %s -triple=x86_64-apple-darwin10 -disable-llvm-optzns -O3 -emit-llvm -o %t.opt // RUN: FileCheck --check-prefix=CHECK %s < %t // RUN: FileCheck --check-prefix=CHECK-OPT %s < %t.opt @@ -89,10 +89,10 @@ void use_F() { // C has no key function, so its vtable should have weak_odr linkage // and hidden visibility (rdar://problem/7523229). -// CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant -// CHECK-DAG: @_ZTS1C = linkonce_odr constant -// CHECK-DAG: @_ZTI1C = linkonce_odr constant -// CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant +// CHECK-DAG: @_ZTV1C = linkonce_odr unnamed_addr constant {{.*}}, comdat, +// CHECK-DAG: @_ZTS1C = linkonce_odr constant {{.*}}, comdat{{$}} +// CHECK-DAG: @_ZTI1C = linkonce_odr constant {{.*}}, comdat{{$}} +// CHECK-DAG: @_ZTT1C = linkonce_odr unnamed_addr constant {{.*}}, comdat{{$}} // D has a key function that is defined in this translation unit so its vtable is // defined in the translation unit. @@ -110,28 +110,28 @@ void use_F() { // E<short> is an explicit template instantiation with a key function // defined in this translation unit, so its vtable should have // weak_odr linkage. -// CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant -// CHECK-DAG: @_ZTS1EIsE = weak_odr constant -// CHECK-DAG: @_ZTI1EIsE = weak_odr constant +// CHECK-DAG: @_ZTV1EIsE = weak_odr unnamed_addr constant {{.*}}, comdat, +// CHECK-DAG: @_ZTS1EIsE = weak_odr constant {{.*}}, comdat{{$}} +// CHECK-DAG: @_ZTI1EIsE = weak_odr constant {{.*}}, comdat{{$}} // F<short> is an explicit template instantiation without a key // function, so its vtable should have weak_odr linkage -// CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant -// CHECK-DAG: @_ZTS1FIsE = weak_odr constant -// CHECK-DAG: @_ZTI1FIsE = weak_odr constant +// CHECK-DAG: @_ZTV1FIsE = weak_odr unnamed_addr constant {{.*}}, comdat, +// CHECK-DAG: @_ZTS1FIsE = weak_odr constant {{.*}}, comdat{{$}} +// CHECK-DAG: @_ZTI1FIsE = weak_odr constant {{.*}}, comdat{{$}} // E<long> is an implicit template instantiation with a key function // defined in this translation unit, so its vtable should have // linkonce_odr linkage. -// CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr constant -// CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant -// CHECK-DAG: @_ZTI1EIlE = linkonce_odr constant +// CHECK-DAG: @_ZTV1EIlE = linkonce_odr unnamed_addr constant {{.*}}, comdat, +// CHECK-DAG: @_ZTS1EIlE = linkonce_odr constant {{.*}}, comdat{{$}} +// CHECK-DAG: @_ZTI1EIlE = linkonce_odr constant {{.*}}, comdat{{$}} // F<long> is an implicit template instantiation with no key function, // so its vtable should have linkonce_odr linkage. -// CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr constant -// CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant -// CHECK-DAG: @_ZTI1FIlE = linkonce_odr constant +// CHECK-DAG: @_ZTV1FIlE = linkonce_odr unnamed_addr constant {{.*}}, comdat, +// CHECK-DAG: @_ZTS1FIlE = linkonce_odr constant {{.*}}, comdat{{$}} +// CHECK-DAG: @_ZTI1FIlE = linkonce_odr constant {{.*}}, comdat{{$}} // F<int> is an explicit template instantiation declaration without a // key function, so its vtable should have external linkage. @@ -158,11 +158,11 @@ void use_F() { // F<char> is an explicit specialization without a key function, so // its vtable should have linkonce_odr linkage. -// CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr constant -// CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant -// CHECK-DAG: @_ZTI1FIcE = linkonce_odr constant +// CHECK-DAG: @_ZTV1FIcE = linkonce_odr unnamed_addr constant {{.*}}, comdat, +// CHECK-DAG: @_ZTS1FIcE = linkonce_odr constant {{.*}}, comdat{{$}} +// CHECK-DAG: @_ZTI1FIcE = linkonce_odr constant {{.*}}, comdat{{$}} -// CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr constant +// CHECK-DAG: @_ZTV1GIiE = linkonce_odr unnamed_addr constant {{.*}}, comdat, template <typename T> class G { public: @@ -178,7 +178,7 @@ void G_f0() { new G<int>(); } // H<int> has a key function without a body but it's a template instantiation // so its VTable must be emitted. -// CHECK-DAG: @_ZTV1HIiE = linkonce_odr unnamed_addr constant +// CHECK-DAG: @_ZTV1HIiE = linkonce_odr unnamed_addr constant {{.*}}, comdat, template <typename T> class H { public: diff --git a/test/CodeGenCXX/vtable-pointer-initialization.cpp b/test/CodeGenCXX/vtable-pointer-initialization.cpp index 835760d..2854291 100644 --- a/test/CodeGenCXX/vtable-pointer-initialization.cpp +++ b/test/CodeGenCXX/vtable-pointer-initialization.cpp @@ -21,13 +21,13 @@ struct A : Base { // CHECK-LABEL: define void @_ZN1AC2Ev(%struct.A* %this) unnamed_addr // CHECK: call void @_ZN4BaseC2Ev( -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**) +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**) // CHECK: call void @_ZN5FieldC1Ev( // CHECK: ret void A::A() { } // CHECK-LABEL: define void @_ZN1AD2Ev(%struct.A* %this) unnamed_addr -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**) +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**) // CHECK: call void @_ZN5FieldD1Ev( // CHECK: call void @_ZN4BaseD2Ev( // CHECK: ret void @@ -45,13 +45,16 @@ void f() { B b; } // CHECK: call void @_ZN1BC2Ev( // CHECK-LABEL: define linkonce_odr void @_ZN1BD1Ev(%struct.B* %this) unnamed_addr -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**) -// CHECK: call void @_ZN5FieldD1Ev( -// CHECK: call void @_ZN4BaseD2Ev( -// CHECK: ret void +// CHECK: call void @_ZN1BD2Ev( // CHECK-LABEL: define linkonce_odr void @_ZN1BC2Ev(%struct.B* %this) unnamed_addr // CHECK: call void @_ZN4BaseC2Ev( -// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**) +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**) // CHECK: call void @_ZN5FieldC1Ev // CHECK: ret void + +// CHECK-LABEL: define linkonce_odr void @_ZN1BD2Ev(%struct.B* %this) unnamed_addr +// CHECK: store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**) +// CHECK: call void @_ZN5FieldD1Ev( +// CHECK: call void @_ZN4BaseD2Ev( +// CHECK: ret void diff --git a/test/CodeGenCXX/vtt-layout.cpp b/test/CodeGenCXX/vtt-layout.cpp index abc2477..2f441ff 100644 --- a/test/CodeGenCXX/vtt-layout.cpp +++ b/test/CodeGenCXX/vtt-layout.cpp @@ -78,9 +78,9 @@ namespace Test6 { } } -// CHECK: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ([4 x i8*]* @_ZTVN5Test11BE, i64 0, i64 3) to i8*)] +// CHECK: @_ZTTN5Test11BE = unnamed_addr constant [1 x i8*] [i8* bitcast (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTVN5Test11BE, i64 0, i64 3) to i8*)] // CHECK: @_ZTVN5Test51AE = unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test51AE to i8*), i8* bitcast (void ()* @__cxa_pure_virtual to i8*), i8* bitcast (void (%"struct.Test5::A"*)* @_ZN5Test51A6anchorEv to i8*)] // CHECK: @_ZTVN5Test61AE = unnamed_addr constant [4 x i8*] [i8* null, i8* bitcast ({ i8*, i8* }* @_ZTIN5Test61AE to i8*), i8* bitcast (void ()* @__cxa_deleted_virtual to i8*), i8* bitcast (void (%"struct.Test6::A"*)* @_ZN5Test61A6anchorEv to i8*)] -// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 12) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 18) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 17) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 20) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*]* @_ZTVN5Test41DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 10) to i8*)] -// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 5) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*]* @_ZTVN5Test31DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 6) to i8*)] -// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*)] +// CHECK: @_ZTTN5Test21CE = linkonce_odr unnamed_addr constant [2 x i8*] [i8* bitcast (i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @_ZTVN5Test21CE, i64 0, i64 4) to i8*)] +// CHECK: @_ZTTN5Test31DE = linkonce_odr unnamed_addr constant [13 x i8*] [i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 5) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE0_NS_2C1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([14 x i8*], [14 x i8*]* @_ZTCN5Test31DE16_NS_2C2E, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i64 0, i64 11) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTVN5Test31DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test31DE64_NS_2V2E, i64 0, i64 6) to i8*)] +// CHECK: @_ZTTN5Test41DE = linkonce_odr unnamed_addr constant [19 x i8*] [i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE0_NS_2C1E, i64 0, i64 10) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 12) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 15) to i8*), i8* bitcast (i8** getelementptr inbounds ([19 x i8*], [19 x i8*]* @_ZTCN5Test41DE16_NS_2C2E, i64 0, i64 18) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 17) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 20) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i64 0, i64 13) to i8*), i8* bitcast (i8** getelementptr inbounds ([25 x i8*], [25 x i8*]* @_ZTVN5Test41DE, i64 1, i64 0) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 3) to i8*), i8* bitcast (i8** getelementptr inbounds ([7 x i8*], [7 x i8*]* @_ZTCN5Test41DE40_NS_2V1E, i64 0, i64 6) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 4) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 7) to i8*), i8* bitcast (i8** getelementptr inbounds ([11 x i8*], [11 x i8*]* @_ZTCN5Test41DE72_NS_2V2E, i64 0, i64 10) to i8*)] diff --git a/test/CodeGenCXX/windows-itanium-exceptions.cpp b/test/CodeGenCXX/windows-itanium-exceptions.cpp index e2c4190..3694d2c 100644 --- a/test/CodeGenCXX/windows-itanium-exceptions.cpp +++ b/test/CodeGenCXX/windows-itanium-exceptions.cpp @@ -36,7 +36,7 @@ void attempt() { // CHECK: store i32 %2, i32* %ehselector.slot // CHECK: br label %catch // CHECK: catch: -// CHECK: %exn = load i8** %exn.slot +// CHECK: %exn = load i8*, i8** %exn.slot // CHECK: %3 = call {{.*}}i8* @__cxa_begin_catch(i8* %{{2|exn}}) // CHECK: call {{.*}}void @__cxa_end_catch() // CHECK: br label %try.cont diff --git a/test/CodeGenCXX/x86_64-arguments-avx.cpp b/test/CodeGenCXX/x86_64-arguments-avx.cpp new file mode 100644 index 0000000..1b1c642 --- /dev/null +++ b/test/CodeGenCXX/x86_64-arguments-avx.cpp @@ -0,0 +1,15 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s -target-feature +avx | FileCheck %s + +namespace test1 { +typedef double __m256d __attribute__((__vector_size__(32))); + +class PR22753 { +public: + __m256d data; +}; + +// CHECK: define <4 x double> @_ZN5test14testENS_7PR22753E(<4 x double> +PR22753 test(PR22753 x) { + return x; +} +} |